From 2041ae0a7c2155b3f1b7c3bceee34427e5d10727 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 2 May 2023 19:55:38 -0700 Subject: [PATCH 01/98] Control file parser --- pom.xml | 7 + vdyp-core/pom.xml | 20 ++ .../nrs/vdyp/io/parse/ControlFileParser.java | 125 ++++++++ .../vdyp/io/parse/ControlFileParserTest.java | 273 ++++++++++++++++++ 4 files changed, 425 insertions(+) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java diff --git a/pom.xml b/pom.xml index b238c1c9d..99cf07be3 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,13 @@ ${junit.version} test + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + org.hamcrest diff --git a/vdyp-core/pom.xml b/vdyp-core/pom.xml index 4a8ac58be..7df41334a 100644 --- a/vdyp-core/pom.xml +++ b/vdyp-core/pom.xml @@ -14,6 +14,26 @@ 0.0.1-SNAPSHOT + + + org.junit.jupiter + junit-jupiter-api + test + + + + org.hamcrest + hamcrest + test + + + + org.easymock + easymock + test + + + diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java new file mode 100644 index 000000000..953f02a84 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -0,0 +1,125 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ControlFileParser { + + public static final int INDEX_LENGTH = 3; + public static final int EXTEND_LENGTH = 1; + public static final int CONTROL_LENGTH_EXTENDED = 120; + public static final int CONTROL_LENGTH = 50; + public static final int NEWLINE_LENGTH = 2; + + public static final int RECORD_BUFFER_LENGTH = INDEX_LENGTH + EXTEND_LENGTH + CONTROL_LENGTH + NEWLINE_LENGTH; + + public static final List EXTEND_FLAGS = Arrays.asList("X", ">"); + public static final List COMMENT_FLAGS = Arrays.asList("C"); + public static final String COMMENT_MARKER = "!"; + + private Map identifiers; + private Map> parsers; + private Function defaultParser; + + public static class Entry { + public final int index; + public final String extend; + public final String control; + + public int getIndex() { + return index; + } + + public String getExtend() { + return extend; + } + + public String getControl() { + return control; + } + + public Entry(int index, String extend, String control) { + super(); + this.index = index; + this.extend = extend; + this.control = control; + } + } + + public ControlFileParser( + Map identifiers, Map> parsers, Function defaultParser + ) { + this.identifiers = identifiers; + this.parsers = parsers; + this.defaultParser = defaultParser; + } + + public ControlFileParser( + Map identifiers, Map> parsers) { + this(identifiers, parsers, String::strip); + } + + public Stream parseEntries(InputStream input) { + return new BufferedReader(new InputStreamReader(input, StandardCharsets.US_ASCII), RECORD_BUFFER_LENGTH).lines() + .flatMap(line -> { + // + if(line.isBlank()) { + return Stream.empty(); + } + final String indexString = line.substring(0, INDEX_LENGTH); + final String extendString = line.substring(INDEX_LENGTH, INDEX_LENGTH + EXTEND_LENGTH); + + // Ignore comments marked with exend flag C + if(COMMENT_FLAGS.contains(extendString)) { + return Stream.empty(); + } + // Ignore comments marked with a blank index + final int index; + if (indexString.isBlank()) { + return Stream.empty(); + } else { + index = Integer.valueOf(indexString); + } + // Ignore comment marked with index 0 + if(index==0) { + return Stream.empty(); + } + + // How long is the control value + int controlLength = Math.min( + EXTEND_FLAGS.contains(extendString) ? + CONTROL_LENGTH_EXTENDED : + CONTROL_LENGTH, + line.length( ) - (INDEX_LENGTH + EXTEND_LENGTH)); + String controlString = line + .substring(INDEX_LENGTH + EXTEND_LENGTH, INDEX_LENGTH + EXTEND_LENGTH + controlLength); + + // Inline comments marked with ! + int startOfComment = controlString.indexOf(COMMENT_MARKER); + if(startOfComment>-1) { + controlString = controlString.substring(0,startOfComment); + } + + return Stream.of(new Entry(index, extendString, controlString)); + }); + } + + public Map parseToMap(InputStream input) { + try(Stream parseEntries = parseEntries(input);) { + return parseEntries.collect( + Collectors.toMap( + e->identifiers.getOrDefault(e.getIndex(), String.format("%03d", e.getIndex())), + e->{ + return parsers.getOrDefault(e.getIndex(), defaultParser).apply(e.getControl()); + } )); + } + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java new file mode 100644 index 000000000..66bfc4999 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -0,0 +1,273 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser.Entry; + +public class ControlFileParserTest { + + @Test + void testParsesEntriesSimple() throws Exception { + var parser = makeParser(); + + try (InputStream is = new ByteArrayInputStream("001 Control".getBytes()); var stream = parser.parseEntries(is);) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); + } + } + + @Test + void testParsesEntriesExtended() throws Exception { + var parser = makeParser(); + + try ( + InputStream is = new ByteArrayInputStream( + "001XControl that is longer than 50 characters. Blah Blah Blah Blah.".getBytes() + ); + var stream = parser.parseEntries(is) + ) { + var result = stream.collect(Collectors.toList()); + + assertThat( + result, + contains( + controlEntry( + equalTo(1), equalTo("X"), equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") + ) + ) + ); + } + } + + @Test + void testParsesEntriesExtendedAlternate() throws Exception { + var parser = makeParser(); + + try ( + InputStream is = new ByteArrayInputStream( + "001>Control that is longer than 50 characters. Blah Blah Blah Blah.".getBytes() + ); + var stream = parser.parseEntries(is) + ) { + var result = stream.collect(Collectors.toList()); + + assertThat( + result, + contains( + controlEntry( + equalTo(1), equalTo(">"), equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") + ) + ) + ); + } + } + + @Test + void testParsesEntriesWithDistantComment() throws Exception { + var parser = makeParser(); + + try ( + InputStream is = new ByteArrayInputStream( + "001 Control Comment".getBytes() + ); + var stream = parser.parseEntries(is) + ) { + var result = stream.collect(Collectors.toList()); + + assertThat( + result, + contains( + controlEntry(equalTo(1), equalTo(" "), equalTo("Control ")) + ) + ); + } + } + + @Test + void testParsesEntriesExtendedWithDistantComment() throws Exception { + var parser = makeParser(); + + try ( + InputStream is = new ByteArrayInputStream( + "001XControl Comment" + .getBytes() + ); + var stream = parser.parseEntries(is) + ) { + var result = stream.collect(Collectors.toList()); + + assertThat( + result, + contains( + controlEntry( + equalTo(1), equalTo("X"), + equalTo( + "Control " + ) + ) + ) + ); + } + } + + @Test + void testParsesEntriesWithMarkedComment() throws Exception { + var parser = makeParser(); + + try ( + InputStream is = new ByteArrayInputStream("001 Control!Comment".getBytes()); + var stream = parser.parseEntries(is) + ) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); + } + } + + @Test + void testParsesEntriesExtendedWithMarkedComment() throws Exception { + var parser = makeParser(); + + try ( + InputStream is = new ByteArrayInputStream("001XControl!Comment".getBytes()); + var stream = parser.parseEntries(is) + ) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, contains(controlEntry(equalTo(1), equalTo("X"), equalTo("Control")))); + } + } + + @Test + void testParsesEntriesIgnoreCommentLinesByExtendedMarker() throws Exception { + var parser = makeParser(); + + try (InputStream is = new ByteArrayInputStream("001CComment".getBytes()); var stream = parser.parseEntries(is)) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, empty()); + } + } + + @Test + void testParsesEntriesIgnoreCommentLinesByZeroIndex() throws Exception { + var parser = makeParser(); + + try (InputStream is = new ByteArrayInputStream("000 Comment".getBytes()); var stream = parser.parseEntries(is);) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, empty()); + } + } + + @Test + void testParsesEntriesIgnoreCommentLinesByNullIndex() throws Exception { + var parser = makeParser(); + + try (InputStream is = new ByteArrayInputStream(" Comment".getBytes()); var stream = parser.parseEntries(is);) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, empty()); + } + } + + @Test + void testParsesEntriesIgnoreEmptyLines() throws Exception { + var parser = makeParser(); + + try ( + InputStream is = new ByteArrayInputStream("\n \n \n \n ".getBytes()); + var stream = parser.parseEntries(is); + ) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, empty()); + } + } + + @Test + void testParsesMultipleEntries() throws Exception { + var parser = makeParser(); + + try ( + var is = new ByteArrayInputStream("001 Control 1\n002 Control 2".getBytes()); + var stream = parser.parseEntries(is); + ) { + var result = stream.collect(Collectors.toList()); + + assertThat( + result, + contains( + controlEntry(equalTo(1), equalTo(" "), equalTo("Control 1")), + controlEntry(equalTo(2), equalTo(" "), equalTo("Control 2")) + ) + ); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + void testParseToMap() throws Exception { + var parser = makeParser(); + String file = + "097 coe\\vetdq2.dat DQ for Vet layer RD_YDQV\n" + + "098 coe\\REGBAV01.coe VET BA, IPSJF168.doc RD_E098\n" + + "\n" + + "197 5.0 0.0 2.0 Minimum Height, Minimum BA, Min BA fully stocked.\n" + + "\n" + + "198 coe\\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198\n" + + "199 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155, App IX\n" + + " 1st: 1: Do NOT apply BA limits from SEQ043\n" + + " 2nd: 1: Do NOT apply DQ limits from SEQ043\n"; + try( + var is = new ByteArrayInputStream(file.getBytes()); + ) { + var result = parser.parseToMap(is); + + + assertThat(result, hasEntry(equalTo("097"), equalTo("coe\\vetdq2.dat"))); + + assertThat(result, hasEntry(equalTo("098"), equalTo("coe\\REGBAV01.coe"))); + assertThat(result, hasEntry(equalTo("minimums"), (Matcher)contains(5.0f, 0.0f, 2.0f))); + assertThat(result, hasEntry(equalTo("modifier_file"), equalTo("coe\\MOD19813.prm"))); + assertThat(result, hasEntry(equalTo("debugSwitches"), (Matcher)contains(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0))); + } + } + + private static Matcher controlEntry(Matcher index, Matcher extend, Matcher control) { + return allOf(hasProperty("index", index), hasProperty("extend", extend), hasProperty("control", control)); + } + + private ControlFileParser makeParser() { + var identifiers = new HashMap(); + var parsers = new HashMap>(); + + identifiers.put(197, "minimums"); + parsers.put(197, (String s) -> Arrays.stream(s.strip().split("\s+")).map(Float::valueOf).collect(Collectors.toList())); + + identifiers.put(198, "modifier_file"); + + identifiers.put(199, "debugSwitches"); + parsers.put(199, (String s) -> Arrays.stream(s.strip().split("\s+")).map(Integer::valueOf).collect(Collectors.toList())); + + return new ControlFileParser(identifiers, parsers); + } + +} From 37e085b33bccff0196a2639c621d094d296ec878 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 3 May 2023 12:54:06 -0700 Subject: [PATCH 02/98] Docs, new test, refinements to configuring control file parser --- .../nrs/vdyp/io/parse/ControlFileParser.java | 59 ++++++++++++++++--- .../vdyp/io/parse/ControlFileParserTest.java | 41 ++++++++++++- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index 953f02a84..f488c5378 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -5,12 +5,19 @@ import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +/** + * Parser for control files + * + * @author Kevin Smith, Vivid Solutions + * + */ public class ControlFileParser { public static final int INDEX_LENGTH = 3; @@ -26,8 +33,8 @@ public class ControlFileParser { public static final String COMMENT_MARKER = "!"; private Map identifiers; - private Map> parsers; - private Function defaultParser; + private Map> valueParsers; + private Function defaultValueParser; public static class Entry { public final int index; @@ -54,17 +61,25 @@ public Entry(int index, String extend, String control) { } } + /** + * + * @param identifiers a map from control file sequence index to meaningful names + * @param parsers a map of parsers for control values based on the sequence index + * @param defaultParser a default value parser to use when one can't be found in the value parser map + */ public ControlFileParser( Map identifiers, Map> parsers, Function defaultParser ) { this.identifiers = identifiers; - this.parsers = parsers; - this.defaultParser = defaultParser; + this.valueParsers = parsers; + this.defaultValueParser = defaultParser; } - public ControlFileParser( - Map identifiers, Map> parsers) { - this(identifiers, parsers, String::strip); + /** + * Create a control file parser which does not remap control sequence indexes and which strips leading and trailing whitepsace from values. + */ + public ControlFileParser() { + this(Collections.emptyMap(), Collections.emptyMap(), String::strip); } public Stream parseEntries(InputStream input) { @@ -112,14 +127,42 @@ public Stream parseEntries(InputStream input) { }); } + /** + * Parse a control file into a map. Known index values will be replaced with meaningful identifiers. + * @param input + * @return + */ public Map parseToMap(InputStream input) { try(Stream parseEntries = parseEntries(input);) { return parseEntries.collect( Collectors.toMap( e->identifiers.getOrDefault(e.getIndex(), String.format("%03d", e.getIndex())), e->{ - return parsers.getOrDefault(e.getIndex(), defaultParser).apply(e.getControl()); + return valueParsers.getOrDefault(e.getIndex(), defaultValueParser).apply(e.getControl()); } )); } } + + /** + * Set a map from control file sequence index to meaningful names + */ + public void setIdentifiers(Map identifiers) { + this.identifiers = identifiers; + } + + /** + * Set a map of parsers for control values based on the sequence index + */ + public void setValueParsers(Map> parsers) { + this.valueParsers = parsers; + } + + /** + * Set a default value parser to use when one can't be found in the parser map + */ + public void setDefaultValueParser(Function defaultParser) { + this.defaultValueParser = defaultParser; + } + + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index 66bfc4999..7c8c75334 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -222,7 +222,6 @@ void testParsesMultipleEntries() throws Exception { } } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test void testParseToMap() throws Exception { var parser = makeParser(); @@ -242,6 +241,35 @@ void testParseToMap() throws Exception { var result = parser.parseToMap(is); + assertThat(result, hasEntry(equalTo("097"), equalTo("coe\\vetdq2.dat"))); + + assertThat(result, hasEntry(equalTo("098"), equalTo("coe\\REGBAV01.coe"))); + assertThat(result, hasEntry(equalTo("197"), equalTo("5.0 0.0 2.0"))); + assertThat(result, hasEntry(equalTo("198"), equalTo("coe\\MOD19813.prm"))); + assertThat(result, hasEntry(equalTo("199"), equalTo("0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0"))); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + void testParseToMapWithConfiguration() throws Exception { + var parser = makeConfiguredParser(); + String file = + "097 coe\\vetdq2.dat DQ for Vet layer RD_YDQV\n" + + "098 coe\\REGBAV01.coe VET BA, IPSJF168.doc RD_E098\n" + + "\n" + + "197 5.0 0.0 2.0 Minimum Height, Minimum BA, Min BA fully stocked.\n" + + "\n" + + "198 coe\\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198\n" + + "199 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155, App IX\n" + + " 1st: 1: Do NOT apply BA limits from SEQ043\n" + + " 2nd: 1: Do NOT apply DQ limits from SEQ043\n"; + try( + var is = new ByteArrayInputStream(file.getBytes()); + ) { + var result = parser.parseToMap(is); + + assertThat(result, hasEntry(equalTo("097"), equalTo("coe\\vetdq2.dat"))); assertThat(result, hasEntry(equalTo("098"), equalTo("coe\\REGBAV01.coe"))); @@ -256,6 +284,12 @@ private static Matcher controlEntry(Matcher index, Matcher(); var parsers = new HashMap>(); @@ -267,7 +301,10 @@ private ControlFileParser makeParser() { identifiers.put(199, "debugSwitches"); parsers.put(199, (String s) -> Arrays.stream(s.strip().split("\s+")).map(Integer::valueOf).collect(Collectors.toList())); - return new ControlFileParser(identifiers, parsers); + parser.setIdentifiers(identifiers); + parser.setValueParsers(parsers); + + return parser; } } From dcb48f2e642614480ba3b894435699a99f32a05d Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 8 May 2023 14:37:00 -0700 Subject: [PATCH 03/98] Write control file --- .../nrs/vdyp/io/parse/ControlFileWriter.java | 101 ++++++++++ .../vdyp/io/parse/ControlFileWriterTest.java | 180 ++++++++++++++++++ 2 files changed, 281 insertions(+) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java new file mode 100644 index 000000000..f6b59b0a6 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java @@ -0,0 +1,101 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.Closeable; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.regex.Pattern; + +/** + * Writer for control files + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class ControlFileWriter implements Closeable { + private final OutputStream os; + + static final Charset CHARSET = StandardCharsets.US_ASCII; + public static final String NEW_LINE = "\r\n"; // Always use Window line separator to write + public static final Pattern NEW_LINE_PATTERN = Pattern.compile("[\r\n]"); + public static final String NORMAL_FORMAT = "%03d %-50s%s"+NEW_LINE; + public static final String EXTENDED_FORMAT = "%03dX%-120s%s"+NEW_LINE; + public static final String COMMENT_FORMAT = " %s"+NEW_LINE; + + public ControlFileWriter(OutputStream os) { + super(); + this.os = os; + } + + /** + * Write an entry for a control file + * + * @param index Control file index (1 to 200 inclusive) + * @param control Value of the control (Max 120 characters, May not contain '!' or newlines) + * @param comment A human readable comment (May not contain newlines) + * @throws IOException + * @throws IllegalArgumentException + */ + public void writeEntry(int index, String control, String comment) throws IOException { + if (index<1) { + throw new IllegalArgumentException("Control file index "+index+" is less than 1"); + } + if (index>200) { + throw new IllegalArgumentException("Control file index "+index+" is greater than 200"); + } + // There's no mechanism for extending past 120 so simply disallow this + if (control.length()>ControlFileParser.CONTROL_LENGTH_EXTENDED) { + throw new IllegalArgumentException("Control file value is longer than "+ControlFileParser.CONTROL_LENGTH_EXTENDED); + } + // There's no mechanism for escaping so simply disallow this. + if (control.contains(ControlFileParser.COMMENT_MARKER)) { + throw new IllegalArgumentException("Control file value contains a comment marker ("+ControlFileParser.COMMENT_MARKER+")"); + } + // There's no mechanism for escaping so simply disallow this. + if (NEW_LINE_PATTERN.matcher(control).find()) { + throw new IllegalArgumentException("Control file value contains a line break"); + } + // Could use additional comment lines instead + if (NEW_LINE_PATTERN.matcher(comment).find()) { + throw new IllegalArgumentException("Control file comment contains a line break"); + } + + String format = control.length()>ControlFileParser.CONTROL_LENGTH ? EXTENDED_FORMAT : NORMAL_FORMAT; + + os.write(String.format(format, index, control, comment).getBytes(CHARSET)); + } + + /** + * Write an entry for a control file + * + * @param index Control file index (1 to 200 inclusive) + * @param control Value of the control (Max 120 characters, May not contain '!' or newlines) + * @throws IOException + * @throws IllegalArgumentException + */ + public void writeEntry(int index, String control) throws IOException { + writeEntry(index, control, ""); + } + + /** + * Write a comment line for a control file + * @param comment A human readable comment (May not contain newlines) + * @throws IOException + * @throws IllegalArgumentException + */ + public void writeComment(String comment) throws IOException { + // Could use additional comment lines instead + if (NEW_LINE_PATTERN.matcher(comment).find()) { + throw new IllegalArgumentException("Control file comment contains a line break"); + } + + os.write(String.format(COMMENT_FORMAT, comment).getBytes(CHARSET)); + } + + @Override + public void close() throws IOException { + os.close(); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java new file mode 100644 index 000000000..f2bc9af83 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java @@ -0,0 +1,180 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.ByteArrayOutputStream; + +import org.junit.jupiter.api.Test; + +public class ControlFileWriterTest { + + @Test + public void testWriteEntry() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeEntry(1, "Value"); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 Value \r\n")); + + } + } + + @Test + public void testWriteEntryWithComment() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeEntry(1, "Value", "Comment"); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 Value Comment\r\n")); + + } + } + + @Test + public void testWriteExtendedEntry() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeEntry(1, "Long Value........................................."); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001XLong Value......................................... \r\n")); + + } + } + + @Test + public void testWriteExtendedEntryWithComment() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeEntry(1, "Long Value.........................................","Comment"); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001XLong Value......................................... Comment\r\n")); + + } + } + + @Test + public void testWriteComment() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeComment("Comment"); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo(" Comment\r\n")); + + } + } + + @Test + public void testValidateIndex() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeEntry(1, "Low"); + writer.writeEntry(200, "High"); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(0, "Anything"); + }); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(-1, "Anything"); + }); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(201, "Anything"); + }); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 Low \r\n200 High \r\n")); + + } + } + + @Test + public void testValidateValue() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeEntry(1, ""); + writer.writeEntry(2, "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(3, "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789X"); + }); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(4, "No ! Bang"); + }); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(5, "No \r\n windows newline"); + }); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(6, "No \n POSIX newline"); + }); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 \r\n002X012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n")); + + } + } + + @Test + public void testValidateComment() throws Exception { + + try ( + var output = new ByteArrayOutputStream(); + var writer = new ControlFileWriter(output); + ) { + + writer.writeEntry(1, "Value", ""); + writer.writeEntry(2, "Value", "Comment"); + writer.writeEntry(3, "Value", "! Comment"); + writer.writeComment(""); + writer.writeComment("Comment"); + writer.writeComment("! Comment"); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(4, "Value", "Comment with \r\n Windows newline"); + }); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeEntry(5, "Value", "Comment with \n POSIX newline"); + }); + // Could write comments with line breaks as multiple comment lines + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeComment("Comment with \r\n Windows newline"); + }); + assertThrows(IllegalArgumentException.class, ()->{ + writer.writeComment("Comment with \n POSIX newline"); + }); + + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo( + "001 Value \r\n"+ + "002 Value Comment\r\n"+ + "003 Value ! Comment\r\n"+ + " \r\n"+ + " Comment\r\n"+ + " ! Comment\r\n")); + + } + } + +} From a410ac72c8e509c0c2e5e8888b01e4b47d0440ae Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 8 May 2023 14:37:41 -0700 Subject: [PATCH 04/98] Parsing Fip control file --- .../nrs/vdyp/io/parse/ControlFileParser.java | 8 +- .../vdyp/io/parse/ControlFileParserTest.java | 28 + vdyp-fip/pom.xml | 26 + .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 53 ++ .../nrs/vdyp/fip/FipControlParserTest.java | 13 + .../ca/bc/gov/nrs/vdyp/fip/FIPSTART.CTR | 76 +++ .../resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ctr | 124 +++++ .../resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ini | 423 ++++++++++++++ .../resources/ca/bc/gov/nrs/vdyp/fip/VDYP.tcl | 132 +++++ .../gov/nrs/vdyp/fip/VDYP7LoggingConfig.txt | 521 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/VDYPBACK.CTR | 92 ++++ .../ca/bc/gov/nrs/vdyp/fip/VRIADJST.CTR | 45 ++ .../ca/bc/gov/nrs/vdyp/fip/VRISTART.CTR | 83 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/BACOE12A.DAT | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/BACOE269.DAT | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/BAFIP16.COE | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/BASP05.COE | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/BASP06.COE | 134 +++++ .../ca/bc/gov/nrs/vdyp/fip/coe/BEC0.DAT | 13 + .../ca/bc/gov/nrs/vdyp/fip/coe/BGRP.DAT | 224 ++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/Becdef.dat | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/COMPLIM.COE | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/CVADJ.PRM | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/DGRP.DAT | 224 ++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/DQCOE12A.DAT | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/DQFIP16Z.COE | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/DQSP05.COE | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/DQSP06.COE | 134 +++++ .../ca/bc/gov/nrs/vdyp/fip/coe/EMP111A1.PRM | 3 + .../ca/bc/gov/nrs/vdyp/fip/coe/EMP117A1.prm | 3 + .../ca/bc/gov/nrs/vdyp/fip/coe/FIPSTKR.PRM | 12 + .../ca/bc/gov/nrs/vdyp/fip/coe/GB01.COE | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/GD19.COE | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/GD20.coe | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/GD23.coe | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/GMODBA1.DAT | 61 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/GROWBA11.coe | 2 + .../ca/bc/gov/nrs/vdyp/fip/coe/GROWBA27.COE | 112 ++++ .../ca/bc/gov/nrs/vdyp/fip/coe/GRPBA1.DAT | 192 +++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/PCT_40.COE | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/PCT_407.coe | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/REG01.DAT | 73 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGBA25.coe | 126 +++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGBA2C.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGBAC.DAT | 114 ++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGBAV01.COE | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGBREAK.COE | 25 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGDQ18.COE | 98 ++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGDQ24.COE | 112 ++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGDQ26.coe | 112 ++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGDQ4C.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGDQC.DAT | 152 +++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGDQI04.COE | 3 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGDQL2.coe | 15 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGHL.COE | 302 ++++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGHL.DAT | 260 +++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGHL1C.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGPR1C.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGV1C.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGVCU.COE | 292 ++++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.COE | 252 +++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.DAT | 252 +++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGVU.COE | 292 ++++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGVU.DAT | 292 ++++++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.COE | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.COE | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.DAT | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.COE | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.DAT | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPB.DAT | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPC.COE | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/SIAGEMAX.PRM | 3 + .../ca/bc/gov/nrs/vdyp/fip/coe/SIEQN.PRM | 4 + .../ca/bc/gov/nrs/vdyp/fip/coe/SP0.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF_v0.dat | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/TOP309.COE | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/TOP98.COE | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/UPPERB02.COE | 32 ++ .../ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI1.DAT | 128 +++++ .../ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI2.DAT | 128 +++++ .../ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI3.DAT | 128 +++++ .../ca/bc/gov/nrs/vdyp/fip/coe/VETDQ2.DAT | 20 + .../ca/bc/gov/nrs/vdyp/fip/coe/VETVOL1.DAT | 16 + .../ca/bc/gov/nrs/vdyp/fip/coe/VGRPDEF1.DAT | 208 +++++++ .../ca/bc/gov/nrs/vdyp/fip/coe/VTOTREG4.COE | 74 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/YLDBA309.COE | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/YLDBA405.COE | 98 ++++ .../ca/bc/gov/nrs/vdyp/fip/coe/YLDBA407.COE | 98 ++++ .../ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ259.DAT | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ309.COE | 79 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ45.COE | 84 +++ .../ca/bc/gov/nrs/vdyp/fip/coe/mod19813.prm | 8 + 94 files changed, 8036 insertions(+), 4 deletions(-) create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java create mode 100644 vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/FIPSTART.CTR create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ctr create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ini create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.tcl create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP7LoggingConfig.txt create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYPBACK.CTR create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRIADJST.CTR create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRISTART.CTR create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE12A.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE269.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BAFIP16.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP05.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP06.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BEC0.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BGRP.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/Becdef.dat create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/COMPLIM.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/CVADJ.PRM create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DGRP.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQCOE12A.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQFIP16Z.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP05.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP06.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP111A1.PRM create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP117A1.prm create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/FIPSTKR.PRM create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GB01.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD19.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD20.coe create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD23.coe create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GMODBA1.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA11.coe create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA27.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GRPBA1.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_40.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_407.coe create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REG01.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA25.coe create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA2C.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAC.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAV01.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBREAK.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ18.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ24.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ26.coe create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ4C.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQC.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQI04.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQL2.coe create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL1C.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGPR1C.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGV1C.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVCU.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPB.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPC.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIAGEMAX.PRM create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIEQN.PRM create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF_v0.dat create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP309.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP98.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/UPPERB02.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI1.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI2.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI3.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETDQ2.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETVOL1.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VGRPDEF1.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VTOTREG4.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA309.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA405.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA407.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ259.DAT create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ309.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ45.COE create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/mod19813.prm diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index f488c5378..060bf875e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -101,7 +101,7 @@ public Stream parseEntries(InputStream input) { if (indexString.isBlank()) { return Stream.empty(); } else { - index = Integer.valueOf(indexString); + index = Integer.valueOf(indexString.strip()); } // Ignore comment marked with index 0 if(index==0) { @@ -137,9 +137,9 @@ public Stream parseEntries(InputStream input) { return parseEntries.collect( Collectors.toMap( e->identifiers.getOrDefault(e.getIndex(), String.format("%03d", e.getIndex())), - e->{ - return valueParsers.getOrDefault(e.getIndex(), defaultValueParser).apply(e.getControl()); - } )); + e->valueParsers.getOrDefault(e.getIndex(), defaultValueParser).apply(e.getControl()), + (x,y)->y // On duplicates, keep the last value + )); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index 7c8c75334..c81c72332 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -32,6 +32,17 @@ void testParsesEntriesSimple() throws Exception { assertThat(result, contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); } } + + @Test + void testParsesEntriesSpacePadding() throws Exception { + var parser = makeParser(); + + try (InputStream is = new ByteArrayInputStream(" 1 Control".getBytes()); var stream = parser.parseEntries(is);) { + var result = stream.collect(Collectors.toList()); + + assertThat(result, contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); + } + } @Test void testParsesEntriesExtended() throws Exception { @@ -278,7 +289,24 @@ void testParseToMapWithConfiguration() throws Exception { assertThat(result, hasEntry(equalTo("debugSwitches"), (Matcher)contains(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0))); } } + + @Test + void testParseToMapLastOfDuplicates() throws Exception { + var parser = makeParser(); + String file = + "097 value1\n" + + "097 value2\n"; + try( + var is = new ByteArrayInputStream(file.getBytes()); + ) { + var result = parser.parseToMap(is); + + + assertThat(result, hasEntry(equalTo("097"), equalTo("value2"))); + } + } + private static Matcher controlEntry(Matcher index, Matcher extend, Matcher control) { return allOf(hasProperty("index", index), hasProperty("extend", extend), hasProperty("control", control)); } diff --git a/vdyp-fip/pom.xml b/vdyp-fip/pom.xml index 84d1d1e14..745f6ad43 100644 --- a/vdyp-fip/pom.xml +++ b/vdyp-fip/pom.xml @@ -13,6 +13,32 @@ vdyp-parent 0.0.1-SNAPSHOT + + + + ca.bc.gov.nrs.vdyp + vdyp-core + ${project.version} + + + + org.junit.jupiter + junit-jupiter-api + test + + + + org.hamcrest + hamcrest + test + + + + org.easymock + easymock + test + + diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java new file mode 100644 index 000000000..39fbc3138 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -0,0 +1,53 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.function.Function; + +import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; + +/** + * Parser for FIP control files + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class FipControlParser { + + ControlFileParser controlParser = new ControlFileParser(); + + Map parse (Path inputFile) throws IOException { + try(var is = Files.newInputStream(inputFile)) { + return parse(is, fileName->Files.newInputStream(inputFile.resolveSibling(fileName))); + } + } + + Map parse (Class klazz, String resourceName) throws IOException { + try(var is = klazz.getResourceAsStream(resourceName)) { + return parse(is, ioExceptionOnNull(klazz::getResourceAsStream)); + } + } + + Map parse(InputStream is, FileResolver fileResolver) { + var map = controlParser.parseToMap(is); + return map; + } + + @FunctionalInterface + static interface FileResolver { + InputStream resolve(String filename) throws IOException; + } + + static FileResolver ioExceptionOnNull(Function baseResolver) { + return fileName->{ + var result = baseResolver.apply(fileName); + if(result==null) { + throw new IOException("Could not find "+fileName); + } + return result; + }; + } +} diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java new file mode 100644 index 000000000..28c5d3bb8 --- /dev/null +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -0,0 +1,13 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import org.junit.jupiter.api.Test; + +public class FipControlParserTest { + + @Test + public void testParse() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(FipControlParserTest.class, "FIPSTART.CTR"); + + } +} diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/FIPSTART.CTR b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/FIPSTART.CTR new file mode 100755 index 000000000..478b0e018 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/FIPSTART.CTR @@ -0,0 +1,76 @@ + 0 FIPSTART.ctr + 0 General Format is col 1-3 0 OR a parameter number + 0 (note: zero or balnk implies COMMENT) + 0 col 5-54 Parameters or file names + 0 + 0 *********** BA and DQ = f(CC and FIP caracteristics) + +001 00999999 Max # of Polygons to process (I8) + (poly's with MODE = -1 NOT counted) +009 coe\becdef.dat BEC Zone Definitions RD_BECD +010 coe\SP0DEF_V0.dat Standard SP0 Codes (with order) RD_SP0 + +011 fip_p01.dat FIP YIELD INPUT (poly) GET_FIPP +012 fip_l01.dat FIP YIELD INPUT (layer) GET_FIPL +013 fip_ls01.dat FIP YIELD INPUT (LxSP0) GET_FIPS + +015 vp_01.dat VDYP7 Polygon +016 vs_01.dat VDYP7 Layer by Species +018 vu_01.dat VDYP7 Layer by SP0 by Util + +020 coe\vgrpdef1.dat Defines Volume Eqn groups RD_VGRP +021 coe\dgrp.dat Defines Decay Groups RD_DGRP +022 coe\bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 + +025 coe\SIEQN.prm Site Curve Numbers (SCN) assigned RD_E025 +025 Nullifies above siteCurve # +026 coe\SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 + +030 coe\grpba1.dat Default Eq # BA=f(CC) RD_GRBA1 +031 coe\gmodba1.dat Eqn modifiers for above RD_GMBA1 +033 coe\fipstkr.prm Stocking class factors RD_STK33 + +040 coe\regba25.coe Coe BA=f(CC) RD_E040 IPSJF128 +041 coe\regdq26.coe Coe DQ=f(CC) RD_E041 IPSJF129 +043 coe\upperb02.coe Upper BA by C/I SP0_P RD_E043 IPSJF128 + +050 coe\regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 +051 coe\regyhlpa.coe HL, Primary SP, Eqn P2 RD_YHL2 +052 coe\regyhlpb.dat HL, Primary SP, Eqn P3 RD_YHL3 +053 coe\reghl.coe HL, Non-primary Species RD_YHL4 + +060 coe\REGDQI04.coe By-species DQ RD_E060 IPFJF125 +061 coe\complim.coe Species component size limits RD_E061 IPSJF158 + +070 coe\regbac.dat Util. Comp, BA RD_UBA1 +071 coe\regdqc.dat Util. Comp, DQ RD_UDQ1 + +080 coe\regpr1c.dat Small Comp., Probability RD_SBA1 +081 coe\regba2c.dat Small Comp., BA RD_SBA2 +082 coe\regdq4c.dat Small Comp., DQ RD_SDQ1 +085 coe\reghl1c.dat Small Comp., HL RD_SHL1 +086 coe\regv1c.dat Small Comp., WS Volume RD_SVT1 + +090 coe\VTOTREG4.coe Total stand WholeStem Vol RD_YVT1 IPSJF117 +091 coe\REGVU.coe Util Comp, WS volume RD_YVT2 IPSJF121 +092 coe\regvcu.coe Close Utilization Vol RD_YVC1 IPSJF122 +093 coe\regvdu.coe Vol net of Decay RD_YVD1 IPSJF123 +094 coe\regvwu.coe Vol net of (Decay+Waste) RD_YVW1 IPSJF123 +095 coe\regbreak.coe Breakage RD_EMP95 IPSJF157 + +096 coe\vetvol1.dat Vet-layer volume adjust RD_YVET +097 coe\vetdq2.dat DQ for Vet layer RD_YDQV +098 coe\REGBAV01.coe VET BA, IPSJF168.doc RD_E098 + +197 5.0 0.0 2.0 Minimum Height, Minimum BA, Min BA fully stocked. + +198 coe\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198 +199 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155, App IX + 1st: 1: Do NOT apply BA limits from SEQ043 + 2nd: 1: Do NOT apply DQ limits from SEQ043 + 4th: Future Development. Choice of upper limits + 9th: 0: Normal - Suppress MATH77 error messages. + 1: show some MATH77 errors; 2: show all. + 22nd 1: extra preference for preferred sp (SEQ 010). + + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ctr b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ctr new file mode 100755 index 000000000..fc559b611 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ctr @@ -0,0 +1,124 @@ + 0 VDYP.CTR input file for VDYP7.for (Revision date 26MAY2002) + 0 General Format is col 1-3 0 OR a parameter number + 0 (note: zero or blank implies COMMENT) + 0 col 5-54 Parameters or file names + + +001 00999999 Max # of Polygons to process (I8) +009 coe\becdef.dat BEC Zone Definitions +010 coe\sp0def_V0.dat Standard SP0 Codes RD_SP0 + +011 vp_fip2.dat VDYP7 Polygon input +012 vs_fip2.dat VDYP7 Layer by Species, input +013 vu_fip2.dat VDYP7 Layer by SP0 by Util, input +014 growto.dat Grow-to years + +015 vp_grow2.dat VDYP7 Polygon out +016 vs_grow2.dat VDYP7 Layer by SP0 out +018 vu_grow2.dat VDYP7 Layer by SP0 by Util out +019 vc_grow2.dat Compatibility variables (output file, if any) + (note: Linkage between this and SEQ101) + +020 coe\vgrpdef1.dat Defines Volume Eqn groups RD_VGRP IPSJF117 +021 coe\dgrp.dat Defines Decay Groups RD_DGRP IPSJF123 +022 coe\bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 + +025 coe\sieqn.prm Site Curve Numbers assigned +025 Nullifies above siteCurve # +026 coe\siagemax.prm Maximum ages for ht incr, by site curve number (SIAGEMAX.prm=140) +028 coe\cvadj.prm CV adjustment and relalted parameters + +030 coe\grpba1.dat Default Eq # BA=f(CC) RD_GRBA1 +031 coe\gmodba1.dat Eqn modifiers for above RD_GMBA1 + +043 coe\upperb02.coe Upper BA, DQ by C/I SP0_P RD_E043 IPSJF128 + +050 coe\regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 +051 coe\regyhlpa.coe HL, Primary SP, Eqn P2 RD_YHL2 +052 coe\regyhlpb.dat HL, Primary SP, Eqn P3 RD_YHL3 +053 coe\reghl.coe HL, Non-primary Species RD_YHL4 + +060 coe\REGDQI04.coe By-species DQ RD_E060 IPFJF125 +061 coe\COMPLIM.coe Species component size limits RD_E061 IPSJF158 + +070 coe\regbac.dat Util. Comp, BA RD_UBA1 +071 coe\regdqc.dat Util. Comp, DQ RD_UDQ1 + +080 coe\regpr1c.dat Small Comp., Probability RD_SBA1 +081 coe\regba2c.dat Small Comp., BA RD_SBA2 +082 coe\regdq4c.dat Small Comp., DQ RD_SDQ1 +085 coe\reghl1c.dat Small Comp., HL RD_SHL1 +086 coe\regv1c.dat Small Comp., WS Volume RD_SVT1 + +090 coe\VTOTREG4.coe Total stand WholeStem Vol RD_YVT1 IPSJF117 +091 coe\regvu.coe Util Comp, WS volume RD_YVT2 IPSJF121 +092 coe\regvcu.coe Close Utilization Vol RD_YVC1 IPSJF122 +093 coe\regvdu.coe Vol net of Decay RD_YVD1 IPSJF123 +094 coe\regvwu.coe Vol net of (Decay+Waste) RD_YVW1 IPSJF123 +095 coe\regbreak.coe Breakage RD_EMP95 IPSJF157 + +096 coe\vetvol1.dat Vet-layer volume adjust RD_YVET +097 coe\vetdq2.dat DQ for Vet layer RD_YDQV + +101 -1 1 2 2 1 1 Contol variables (10I4) + 1st 4 col: IYR_CNTR =i i=0 for NO GROWTH + -1 to use SEQ014 (specifies end yr, each poly) + i =1 to 400 grow i yrs + i = 1920-2400 grow to yr i (A.D.) + 2nd: Compatibility Variable output + 0 None + 1 First yr only + 2 All yrs + Note: Output can occur ONLY in yrs also selected + by 4th option + 3rd: CV application + 0 Do not apply + 1 All variables except Vol + 2 All variables (STANDARD USAGE) + 4th: OUTPUT Files + 0 None + 1 First yr + 2 First and last year + 3 All years + 4 First, 1st+10, 1st+20 .. last + 5th: ALLOW COMPATIBILITY (CV) Compuations + 0: Always + 1: Only when basis exceeds limits (.1 for vol, .01 BA for DQ) + 6th: Update Site sp, ITG during growth + 0:NO 1:YES (normal) +106 coe\YLDBA407.coe BA Yield (Primary layer) RD_E106 ipsjf160 +107 coe\YLDDQ45.coe DQ Yield (Primary layer) RD_E107 ipsjf161 +108 coe\PCT_407.coe Upper bounds (BA, DQ) RD_E108 ipsjf160 (emp106, emp107) +111 coe\emp111A1.PRM Growth in BA (Prim layer) Fiat Model (EMP111A) IPSJF162 +117 coe\emp117A1.prm DQ growth (Pri. L) IPSJF178, fiat and mixed model. +121 coe\growba27.coe Growth in BA (Prim layer) Emp. Model (EMP121) IPSJF162 +122 coe\GD23.coe DQ growth EMP122 IPSJF178, empirical model +123 coe\REGDQL2.coe Limits on DQ growth EMP123 IPSJF178 +148 coe\basp05.coe BA growth Primary SP IPSJF148 +149 coe\basp06.coe BA growth NONPrimary SP IPSJF149 +150 coe\dqsp05.coe DQ growth Primary SP IPSJF150 +151 coe\dqsp06.coe DQ growth NONPrimary Sp. IPSJF151 + +198 coe\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198 + + +199 2 3 2 2 0 2 0 1 1 0 415 5 713 3 0 0 0 0 0 1 0 0 0Debug switches (25) 0=default See IPSJF155, App. IX + (1) = 1 to DIASABLE species dynamics + (2) = n, maximum BH age in BA and DQ eqns = 100*n. + (3) = 0 Fiat BA growth model (approach to yield curves) + = 1 to invoke empirical BA growth model (see IPSJF176) + = 2 invoke empirical growth model PLUS mixing with fiat model. + (4) = (1,2) to use limits (SEQ108-GRPBA1, SEQ043-(CI,Pri)) + = 0, defaults to option 2 at present. + (5) MATH77 Error message control. Should be zero. + or 1 will show some errors, 2 shows all errors. + (6) = 0 for fiat DQ growth model (see IPSJF176, and SEQ 117) + =1 for empirical, 2 for mixed . Recommend: 0 or 2. + (7) Not used + (8) = 1 to force growth in non-primary HL to zero when del HD=0 + -2 same as 1, but also applies to primary species. + (9) =1 for limited BA incr if DQ upper limit hit, else 0 (2009.03.18) + (10) Not used. + (11-20) Controls Ht/Age/SI fillin. See IPSJF174.doc + Above values f. Cam bartram 14MAR2002 + (22) 1 implies a preferred sp is primary if ba >.9995 of other. diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ini b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ini new file mode 100755 index 000000000..5d199db42 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ini @@ -0,0 +1,423 @@ +[Environment Variables] +; Version Control System: {{VERSION_CONTROL_SYSTEM}} {{VERSION_CONTROL_VERSION}} +; Branch Name: {{BRANCH_NAME}} +; Commit ID: {{LAST_COMMIT_REFERENCE}} +; Commit Timestamp: {{LAST_COMMIT_DATE}} +; Build Machine: {{BUILD_MACHINE}} +; +; +; Create arbitrary environment variable specifications that can be used +; later in this file, in command line parameters, debug log file config +; file or anywhere else you have that requires string input. +; +; All environment variable definitions are of the form: +; +; VarNm=Some Value +; +; Once defined, a substitution variable may be referenced using the +; following syntax (on the command line, this INI file, or anywhere else): +; +; Some text $(VarNm) and then some. +; +; In this example, the above line would expand as: +; +; Some text Some Value and then some. +; +; +; All process environment variables are available for use. In addition, +; the following environment variables are defined at start up: +; The EXE directory name is available as: $(EXEDir) +; The Current directory name is available as: $(CurDir) +; The VDY7 Installation directory is available as: $(InstallDir) +; +; NOTE: The 'InstallDir' environment variable is currently a synonym +; for the 'EXEDir' variable; they will always point to the same +; directory. In the future however, they may differ as this +; application evolves. +; +; You may define as many environment variables as desired or required +; within this section. An example is provided below for 'ConfigDir'. +; +; + +ConfigDir=$(InstallDir)\VDYP_CFG + + +[PREFERENCES] +STARTUP_DIALOG=0 +GRAPH_TOOLBAR=0 +MaxSiteSpecies=2 +FAQ_URL=http://www.for.gov.bc.ca/hts/vri/biometric/help/VDYP7_help.pdf + +DebugMode=False + +EnableSuppliedBATPHSubstitution=False +EnableWinVDYPMoFBiomass=False +EnableWinVDYPCFSBiomass=True +DisplaySecondaryHeights=False + +; VVVV PURGE for Distribution +; +; Enable Right Click +; Not to be distibuted globally. +; Enables or disables the special Right Mouse Button click handler. +; It is on by default but causes the IDE to crash if not cleaned up +; before the program is terminated while debugging. +; +; + +EnableRightClick=False + +; ~~~~ + +[Logging] +EnableLogMode=False +LoggingConfigurationFile=$(ConfigDir)\VDYP7LoggingConfig.txt + + +[VDYPCore Configuration] +ConfigurationFilePath=$(ConfigDir) +LogFileName=$(ConfigDir)\vdyp7.log +SaveIntermediateData=False + +; VVVV PURGE for Distribution +; +; UseFileIO +; Not to be distributed globally. +; Turns on File I/O as opposed to Memory I/O. +; The default is False. We do not want to give +; outside users this option as it means another item to +; test. +; +; + +UseFileIO=False + +; ~~~~ + + +[PLOTSY] + +; +; Launch PLOTSY +; Yes - If PLOTSY is not already running, attempt to start it. +; No - Make no attempt to launch PLOTSY +; +; + +LaunchPLOTSY=Yes + +; +; PLOTSY Start Command +; Registry Key - +; The windows registry key that contains the command to launch PLOTSY +; +; Fallback command +; The command to use if the attempt to launch PLOTSY via the registry +; key fails. +; +; + +PLOTSYOpenRegistryKey=HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Open Plotsy\shell\open\command +PLOTSYFallbackOpenCmd=PLOTSY.EXE + +; +; PLOTSY Window Detection search strings. +; +; + +PLOTSYApplicationWindowSubstring=Plotsy* +PLOTSYApplicationWindowClass=*Form* + +; +; PLOTSY Watch directory +; +; + +PLOTSYWatchDir=$(TEMP)\Plotsy + +; +; TCL File is expected to be found in the VDYP_CFG directory +; and will be posted into the PLOTSY Watch Directory +; +; + +VDYP7TCLFile=VDYP.tcl + +DefaultGraphTitle=Sample VDYP7 Graph Title +OutputAgeColumnID=0 + + +[PLOT] +EXEPathName=C:\WINVDYP + + +[Format Patterns] +SpeciesPercent="##0.0" +IntegerAge="##0" +FloatAge="##0.0" +Diameter="##0.0" +Height="##0.00" +TPH="####0.00" +MAI="#0.00" +Volume="###0.0" +Biomass="###0.0" +BiomassProportion="#0.0000" +BasalArea="##0.0000" +UtilLevel="#0.0" +SiteIndex="#0.00" +YTBH="#0.00" +CC="##0" +PctForest="##0" +YieldFactor="#0.00" + + +[Table Property Ranges] +PctCompositionHigh=100.0 +PctCompositionLow=0.0 +PctCompositionInc=5.0 + +PctForestedLandHigh=100.0 +PctForestedLandLow=0.0 +PctForestedLandInc=5.0 + +StandTotalAgeHigh=500 +StandTotalAgeLow=0 +StandTotalAgeInc=10 + +StandHeightHigh=99.9 +StandHeightLow=0.0 +StandHeightInc=1.0 + +StandBHHigh=60.0 +StandBHLow=0.0 +StandBHInc=1.0 + +StandBHAHigh=500 +StandBHALow=0 +StandBHAInc=25 + +CCHigh=100.0 +CCLow=0.0 +CCInc=5.0 + +BAHigh=250.0 +BALow=0.1 +BAInc=2.5 + +TreesPerHectareHigh=9999.9 +TreesPerHectareLow=0.1 +TreesPerHectareInc=250.0 + +VolumeHigh=2500.0 +VolumeLow=0.0 +VolumeInc=250.0 + +StartAgeHigh=600 +StartAgeLow=0 +StartAgeInc=10 + +FinishAgeHigh=1200 +FinishAgeLow=1 +FinishAgeInc=10 + +AgeIncrementHigh=350 +AgeIncrementLow=1 +AgeIncrementInc=5 + +EnableCulminationLow=10 +EnableCulminatioHigh=300 +MaximumYearsToProject=400 +MaximumYearsToBackGrow=400 + + +[Batch Age Ranges] +StartAge=20 +EndAge=550 +AgeIncrement=1 + + +[Operating Defaults] +DefaultPctForestedLand=0.0 +DefaultProjectedValueOutput=Volume + + +[Species] +; These species represent those displayed by WinVDYP Interactive +AC=Poplar +AT=Aspen +B=True Fir +BA=Amabilis Fir +BG=Grand Fir +BL=Alpine Fir +CW=Western Red Cedar +DR=Red Alder +E=Birch +EA=Alaska Paper Birch +EP=Common Paper Birch +FD=Douglas Fir +H=Hemlock +HM=Mountain Hemlock +HW=Western Hemlock +L=Larch +LA=Alpine Larch +LT=Tamarack +LW=Western Larch +MB=Bigleaf Maple +PA=Whitebark Pine +PF=Limber Pine +PJ=Jack Pine +PL=Lodgepole Pine +PW=Western White Pine +PY=Ponderosa (Yellow) Pine +S=Spruce +SB=Black Spruce +SE=Engelmann Spruce +SS=Sitka Spruce +SW=White Spruce +YC=Yellow Cedar + +[Batch Species Report Utilization Levels] +; These correspond to the SP0 codes only. +AC= 12.5 cm+ +AT =12.5 cm+ +B =12.5 cm+ +C=12.5 cm+ +D=12.5 cm+ +E=12.5 cm+ +F=12.5 cm+ +H=12.5 cm+ +L=12.5 cm+ +MB=12.5 cm+ +PA=12.5 cm+ +PL=12.5 cm+ +PW=12.5 cm+ +PY=12.5 cm+ +S=12.5 cm+ +Y=12.5 cm+ + +[BECs] +1=AT -Alpine Tundra +2=BG -Bunch Grass +3=BWBS-Boreal White and Black Spruce +4=CDF -Coastal Douglas Fir +5=CWH -Coastal Western Hemlock +6=ESSF-Engelmann Spruce +7=ICH -Interior Cedar Hemlock +8=IDF -Interior Douglas Fir +9=MH -Mountain Hemlock +10=MS -Montane Spruce +11=PP -Ponderosa Pine +12=SBPS-Sub-Boreal Pine-Spruce +13=SBS -Sub-Boreal Spruce +14=SWB -Spruce-Willow-Birch + + +[CFS Eco Zones] +1=Boreal Cordillera +2=Boreal Plains +3=Montane Cordillera +4=Pacific Maritime +5=Taiga Plains + + +[SI Limits] +CoastLowRangeLow=13 +CoastLowRangeHigh=50 +CoastMidRangeLow=12 +CoastMidRangeHigh=40 +CoastHighRangeLow=7 +CoastHighRangeHigh=32 +CoastAgeLow=50 +CoastAgeHigh=140 +InteriorLowRangeLow=12 +InteriorLowRangeHigh=35 +InteriorMidRangeLow=8 +InteriorMidRangeHigh=30 +InteriorHighRangeLow=4 +InteriorHighRangeHigh=26 +InteriorAgeLow=50 +InteriorAgeHigh=140 + +[BA Limit Coefficients] +ACCoast=AC 107.240519 -14.377881 +ACInterior=AC 118.629456 -19.159803 +ATInterior=AT 98.298267 -15.823783 +ATCoast=AT -999 -999 +BCoast=B 134.265995 -10.723979 +BInterior=B 103.717551 -12.032769 +CCoast=C 199.942910 -14.931348 +CInterior=C 393.759340 -35.402660 +DCoast=D 107.240519 -14.377881 +DInterior=D -999 -999 +ECoast=E 107.240519 -14.377881 +EInterior=E 118.629456 -19.159803 +FCoast=F 213.706529 -28.643038 +FInterior=F 132.594246 -20.216383 +HCoast=H 144.825311 -13.110869 +HInterior=H 122.420409 -10.923619 +LCoast=L -999 -999 +LInterior=L 119.642742 -21.246736 +MBCoast=MB 107.240519 -14.377881 +MBInterior=MB -999 -999 +PLCoast=PL185.048127 -19.900699 +PLInterior=PL 95.118542 -12.154888 +PWCoast=PW -999 -999 +PWInterior=PW 158.465684 -26.781112 +PYCoast=PY -999 -999 +PYInterior=PY 71.943238 -14.264704 +SCoast=S 177.814415 -13.714547 +SInterior=S 96.841270 -12.607810 +EquationConstant1=5 +EquationConstant2=1.3 +EquationConstant3=-1 + +[TPH Limits] +AC_P10_C=7.500000 0.184064 0.005592 +B_P10_C=7.500000 0.229925 0.005735 +C_P10_C=7.500000 0.387454 0.002709 +D_P10_C=7.500000 0.184064 0.005592 +E_P10_C=7.500000 0.184064 0.005592 +F_P10_C=7.500000 0.116002 0.006594 +H_P10_C=7.500000 0.126113 0.007561 +MB_P10_C=7.500000 0.184064 0.005592 +PL_P10_C=7.500000 -0.083294 0.014145 +S_P10_C=7.500000 0.168790 0.008936 +AC_P90_C=7.500000 0.963730 0.004530 +B_P90_C=7.500000 1.226133 -0.002427 +C_P90_C=7.500000 1.450610 -0.000679 +D_P90_C=7.500000 0.963730 0.004530 +E_P90_C=7.500000 0.963730 0.004530 +F_P90_C=7.500000 0.682690 0.008622 +H_P90_C=7.500000 1.207655 -0.001023 +MB_P90_C=7.500000 0.963730 0.004530 +PL_P90_C=7.500000 0.938361 -0.003504 +S_P90_C=7.500000 0.871400 0.011812 +AC_P10_I=7.500000 -0.084114 0.016436 +AT_P10_I=7.500000 0.005440 0.010618 +B_P10_I=7.500000 0.184201 0.006065 +C_P10_I=7.500000 0.103056 0.012318 +E_P10_I=7.500000 -0.084114 0.016436 +F_P10_I=7.500000 0.123477 0.005786 +H_P10_I=7.500000 0.014342 0.012198 +L_P10_I=7.500000 0.068930 0.005579 +PL_P10_I=7.500000 -0.083294 0.014145 +PW_P10_I=7.500000 0.031801 0.007887 +PY_P10_I=7.500000 0.267422 0.009514 +S_P10_I=7.500000 0.124051 0.007309 +AC_P90_I=7.500000 0.587140 0.022826 +AT_P90_I=7.500000 0.660157 0.011754 +B_P90_I=7.500000 1.059981 -0.000686 +C_P90_I=7.500000 0.269900 0.042869 +E_P90_I=7.500000 0.587140 0.022826 +F_P90_I=7.500000 1.193114 -0.006459 +H_P90_I=7.500000 0.799310 0.013942 +L_P90_I=7.500000 0.314230 0.015952 +PL_P90_I=7.500000 0.938361 -0.003504 +PW_P90_I=7.500000 0.909946 -0.005477 +PY_P90_I=7.500000 1.922409 -0.008496 +S_P90_I=.500000 0.910138 0.002576 +EquationConstant1=5.0 +EquationConstant2=1.3 +EquationConstant3=0.00007854 + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.tcl b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.tcl new file mode 100755 index 000000000..7cbf2f398 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.tcl @@ -0,0 +1,132 @@ +*COLUMNS +'ID Name Units Decimals Description Width Header ID +0 Table Num - 0 Table Number 8 0 +1 Forest Cover ID 0 Forest Cover ID 12 1 +2 Mapsheet 0 Mapsheet 7 2 +3 Polygon Num 0 Polygon Number 10 3 +4 Layer ID 0 Layer ID 1 4 +5 VDYP7 Layer ID 0 VDYP7 Layer ID 1 5 +6 Year 0 Year 4 6 +7 Age yr 0 Age 4 7 +8 Spcs 1 Cd 0 Species 1 Code 3 8 +9 Spcs 1 Pct % 0 Species 1 Pcnt 3 9 +10 Spcs 2 Cd 0 Species 2 Code 3 8 +11 Spcs 2 Pct % 0 Species 2 Pcnt 3 9 +12 Spcs 3 Cd 0 Species 3 Code 3 8 +13 Spcs 3 Pct % 0 Species 3 Pcnt 3 9 +14 Spcs 4 Cd 0 Species 4 Code 3 8 +15 Spcs 4 Pct % 0 Species 4 Pcnt 3 9 +16 Spcs 5 Cd 0 Species 5 Code 3 8 +17 Spcs 5 Pct % 0 Species 5 Pcnt 3 9 +18 Spcs 6 Cd 0 Species 6 Code 3 8 +19 Spcs 6 Pct % 0 Species 6 Pcnt 3 9 +20 Pct Stk % 0 Pcnt Stockable 3 10 +21 SI m 1 Site Index 4 11 +22 Dom Ht m 1 Dom Ht 5 11 +23 Scnd Ht m 1 Dom Ht 5 11 +24 Lorey Ht m 1 Lorey Ht 5 11 +25 Dia cm 1 Diameter 5 12 +26 TPH t/ha 2 TPH 8 13 +27 BA m2/ha 2 BA 8 14 +28 Vol ws m3/ha 1 Vol ws 8 15 +29 Vol cu m3/ha 1 Vol cu 8 15 +30 Vol d m3/ha 1 Vol d 8 15 +31 Vol dw m3/ha 1 Vol dw 8 15 +32 Vol dwb m3/ha 1 Vol dwb 8 15 +33 MoF Bio ws tons/ha 1 MoF Bio ws 8 16 +34 MoF Bio cu tons/ha 1 MoF Bio cu 8 16 +35 MoF Bio d tons/ha 1 MoF Bio d 8 16 +36 MoF Bio dw tons/ha 1 MoF Bio dw 8 16 +37 MoF Bio dwb tons/ha 1 MoF Bio dwb 8 16 +38 Spcs 1 Vol ws m3/ha 1 Spcs 1 Vol ws 8 15 +39 Spcs 1 Vol cu m3/ha 1 Spcs 1 Vol cu 8 15 +40 Spcs 1 Vol d m3/ha 1 Spcs 1 Vol d 8 15 +41 Spcs 1 Vol dw m3/ha 1 Spcs 1 Vol dw 8 15 +42 Spcs 1 Vol dwb m3/ha 1 Spcs 1 Vol dwb 8 15 +43 Spcs 2 Vol ws m3/ha 1 Spcs 2 Vol ws 8 15 +44 Spcs 2 Vol cu m3/ha 1 Spcs 2 Vol cu 8 15 +45 Spcs 2 Vol d m3/ha 1 Spcs 2 Vol d 8 15 +46 Spcs 2 Vol dw m3/ha 1 Spcs 2 Vol dw 8 15 +47 Spcs 2 Vol dwb m3/ha 1 Spcs 2 Vol dwb 8 15 +48 Spcs 3 Vol ws m3/ha 1 Spcs 3 Vol ws 8 15 +49 Spcs 3 Vol cu m3/ha 1 Spcs 3 Vol cu 8 15 +50 Spcs 3 Vol d m3/ha 1 Spcs 3 Vol d 8 15 +51 Spcs 3 Vol dw m3/ha 1 Spcs 3 Vol dw 8 15 +52 Spcs 3 Vol dwb m3/ha 1 Spcs 3 Vol dwb 8 15 +53 Spcs 4 Vol ws m3/ha 1 Spcs 4 Vol ws 8 15 +54 Spcs 4 Vol cu m3/ha 1 Spcs 4 Vol cu 8 15 +55 Spcs 4 Vol d m3/ha 1 Spcs 4 Vol d 8 15 +56 Spcs 4 Vol dw m3/ha 1 Spcs 4 Vol dw 8 15 +57 Spcs 4 Vol dwb m3/ha 1 Spcs 4 Vol dwb 8 15 +58 Spcs 5 Vol ws m3/ha 1 Spcs 5 Vol ws 8 15 +59 Spcs 5 Vol cu m3/ha 1 Spcs 5 Vol cu 8 15 +60 Spcs 5 Vol d m3/ha 1 Spcs 5 Vol d 8 15 +61 Spcs 5 Vol dw m3/ha 1 Spcs 5 Vol dw 8 15 +62 Spcs 5 Vol dwb m3/ha 1 Spcs 5 Vol dwb 8 15 +63 Spcs 6 Vol ws m3/ha 1 Spcs 6 Vol ws 8 15 +64 Spcs 6 Vol cu m3/ha 1 Spcs 6 Vol cu 8 15 +65 Spcs 6 Vol d m3/ha 1 Spcs 6 Vol d 8 15 +66 Spcs 6 Vol dw m3/ha 1 Spcs 6 Vol dw 8 15 +67 Spcs 6 Vol dwb m3/ha 1 Spcs 6 Vol dwb 8 15 +68 Spcs 1 MoF Bio ws tons/ha 1 Spcs 1 MoF Bio ws 8 16 +69 Spcs 1 MoF Bio cu tons/ha 1 Spcs 1 MoF Bio cu 8 16 +70 Spcs 1 MoF Bio d tons/ha 1 Spcs 1 MoF Bio d 8 16 +71 Spcs 1 MoF Bio dw tons/ha 1 Spcs 1 MoF Bio dw 8 16 +72 Spcs 1 MoF Bio dwb tons/ha 1 Spcs 1 MoF Bio dwb 8 16 +73 Spcs 2 MoF Bio ws tons/ha 1 Spcs 2 MoF Bio ws 8 16 +74 Spcs 2 MoF Bio cu tons/ha 1 Spcs 2 MoF Bio cu 8 16 +75 Spcs 2 MoF Bio d tons/ha 1 Spcs 2 MoF Bio d 8 16 +76 Spcs 2 MoF Bio dw tons/ha 1 Spcs 2 MoF Bio dw 8 16 +77 Spcs 2 MoF Bio dwb tons/ha 1 Spcs 2 MoF Bio dwb 8 16 +78 Spcs 3 MoF Bio ws tons/ha 1 Spcs 3 MoF Bio ws 8 16 +79 Spcs 3 MoF Bio cu tons/ha 1 Spcs 3 MoF Bio cu 8 16 +80 Spcs 3 MoF Bio d tons/ha 1 Spcs 3 MoF Bio d 8 16 +81 Spcs 3 MoF Bio dw tons/ha 1 Spcs 3 MoF Bio dw 8 16 +82 Spcs 3 MoF Bio dwb tons/ha 1 Spcs 3 MoF Bio dwb 8 16 +83 Spcs 4 MoF Bio ws tons/ha 1 Spcs 4 MoF Bio ws 8 16 +84 Spcs 4 MoF Bio cu tons/ha 1 Spcs 4 MoF Bio cu 8 16 +85 Spcs 4 MoF Bio d tons/ha 1 Spcs 4 MoF Bio d 8 16 +86 Spcs 4 MoF Bio dw tons/ha 1 Spcs 4 MoF Bio dw 8 16 +87 Spcs 4 MoF Bio dwb tons/ha 1 Spcs 4 MoF Bio dwb 8 16 +88 Spcs 5 MoF Bio ws tons/ha 1 Spcs 5 MoF Bio ws 8 16 +89 Spcs 5 MoF Bio cu tons/ha 1 Spcs 5 MoF Bio cu 8 16 +90 Spcs 5 MoF Bio d tons/ha 1 Spcs 5 MoF Bio d 8 16 +91 Spcs 5 MoF Bio dw tons/ha 1 Spcs 5 MoF Bio dw 8 16 +92 Spcs 5 MoF Bio dwb tons/ha 1 Spcs 5 MoF Bio dwb 8 16 +93 Spcs 6 MoF Bio ws tons/ha 1 Spcs 6 MoF Bio ws 8 16 +94 Spcs 6 MoF Bio cu tons/ha 1 Spcs 6 MoF Bio cu 8 16 +95 Spcs 6 MoF Bio d tons/ha 1 Spcs 6 MoF Bio d 8 16 +96 Spcs 6 MoF Bio dw tons/ha 1 Spcs 6 MoF Bio dw 8 16 +97 Spcs 6 MoF Bio dwb tons/ha 1 Spcs 6 MoF Bio dwb 8 16 +98 CFS Bio stem tons/ha 1 CFS Bio stem 8 17 +99 CFS Bio bark tons/ha 1 CFS Bio bark 8 17 +100 CFS Bio branch tons/ha 1 CFS Bio branch 8 17 +101 CFS Bio foliage tons/ha 1 CFS Bio foliage 8 17 + + +*HEADERS +'ID Description +0 Table Num| +1 Forest Cover ID| +2 Mapsheet| +3 Polygon Number| +4 Layer ID| +5 VDYP7 Layer| +6 Year| +7 Age|yr +8 Spcs| +9 Spcs Pct|% +10 Stk Pct|% +11 Ht|m +12 Dia|cm +13 TPH|t/ha +14 BA|m2/ha +15 Vol|m3/ha +16 MoFBio|tons/ha +17 CFSBio|tons/ha + + +*GROUPS +'Groups Range Dont sort +WinVDYP7 7,21-32,98-101 1 +All 0-101 1 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP7LoggingConfig.txt b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP7LoggingConfig.txt new file mode 100755 index 000000000..68d758b57 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP7LoggingConfig.txt @@ -0,0 +1,521 @@ +# +# Dynamic Logging Library template configuration file. +# +# Example, and basic, VDYP7 logging file. +# +# This logging configuration file creates a single appender that logs +# every logged message that is presented to it into a file found +# in the current directory. +# +# For details on how to modify or otherwise extend this sample, refer +# to the 'DynLogConfigTemplate.txt' for a complete rundown of the +# technical capabilities available to you. +# +# This file is loaded through the VDYP.INI file in the [Logging] section +# under the 'LoggingConfigurationFile' item. +# +# You can modify the INI file to point to a new configuration file +# or else you can supply the following command line parameter after the +# INI file has been loaded: +# +# -dbgCfg +# +# +# The INI file also disables logging by default. You can override +# this behaviour by modifying the INI file directly or supplying the +# following command line parameter after the INI file has been loaded: +# +# -dbg +# +# You can also modify the logging configuration file as well to disable +# logging by setting the 'context.Enabled' property to 'No' or 'False'. +# + + +#=============================================================== +# +# Environment/Substitution variable definitions. +# +# Define environment/substitution variables for use throughout +# the Dynamic Logging library and outside into the application +# itself. +# +# All Environment/Substitution variables have the form: +# +# env.varName = value +# +# This would define a substition variable named 'varName' and +# any occurrence of it would be substituted for its +# substitution value: 'value'. +# +# Any environment variable/substitution variables are scanned +# in this file prior to loading Appenders, Loggers, Context or +# other information and therefore may be scattered throughout +# this file. +# +# Process environment variables are inherited and available for +# reference in this file in the same way as if you had defined +# them locally. +# +# An environment/substitution variable is referred to by +# wrapping the variable name as such: $(varNm) +# +# Substitution variable names are not case sensistive and so +# $(varNm) and $(VARNM) and $(varnm) all refer to the same +# variable. +# +# Substitution variabled may contain a reference to another +# substitution variable. Therefore, for the following +# definitions: +# +# env.varBase = def +# env.varContain = abc$(varBase)ghi +# env.overAll = 12$(varContain)34 +# +# The variable $(overAll) would expand out to: 12abcdefghi +# +# A Substitution variable may have multiple references to +# other substitution variables: +# +# env.Multi = -$(varContain)-$(varBase)- +# +# would expand out to: -abcdefghi-def- +# +# IMPORTANT: Recursive definitions will cause the application +# to die without grace. Ensure you do not create a +# variable definition that does refers to itself +# either directly or indirectly through an embedded +# variable's definition. +# +# env.Var1 = very$(Var2) +# env.Var2 = something-$(Var1)-bad +# + +# env.sample = sampleEnvVal + + +#=============================================================== +# +# Context Wide Configuration Points +# +# The following properties are essentially 'global variables' +# within the logging context and apply to all parts of the +# logging library. +# +# The only context wide configuration item you would be likely +# to change would be the 'Enabled' flag but each is described +# fully. +# +# Enabled +# A master switch to turn all logging on or off. +# This switch applies and overrides any other +# 'Enabled' setting. You may enable or disable the +# global context as often as you want. +# +# If disabled and then switched to enabled within +# the application, all individual 'Enabled' settings +# are then considered. +# +# Setting this value to 'No' does not affect the +# value of the corresponding setting of any other +# property setting. +# +# MaxLineLength +# Sets the default maximum line length for internal buffers +# when formatting and generating lines. This value sets the +# of allocated buffers, and where feasible, truncates lines +# to that number of characters. +# +# The value used here may be overriden bu individual loggers +# by providing a logger specific 'MaxLineLength' +# configuration value. +# +# If this value is not specified, a default value of 512 is used. +# +# NOTE: There is an important consideration to keep in mind that +# using a large value for the maximum log line length has +# tradeoff in allocated memory and unused process memory +# will increase as this value gets larger. +# +# IMPORTANT: While efforts are made to keep formatted messages +# within the bounds of the message buffer, it may +# not be possible to predict that when data is in +# its final formatted form, will fit within the +# bounds of the buffer. +# +# EstimatedNumAppenderTypes +# This controls the estimated total number of appender +# types that will ever be defined in the configuration +# file. Typically you should never need to change this +# value. The default is provided. Making smaller to +# match the true value will have a negligible effect +# on application performance. You would want to increase +# this value if a number of new Appender Types were to be +# declared. +# +# In any run involving Dynamic Logging, there will always +# be at least two built-in Appender Types defined: the +# 'Default' appender type and the 'Null' appender type. +# +# Some power of 2 are good choices for this value. +# +# EstimatedNumAppenders +# This controls the estimated total number of appenders +# that will ever be defined in the configuration file. +# Typically you should never need to change this value. +# The default is provided. Making it smaller to match +# the true value will have a negligible effect on application +# performance. You would want to increase this value if +# a large number of Appenders were to be declared. +# +# Some power of 2 are good choices for this value. +# +# EstimatedNumLoggers +# This controls the estimated number of loggers that will +# ever be defined through the application lifetime. +# Loggers are created as code is executed and so the total +# number of potential loggers might be hard to estimate +# depending on total code coverage through execution. +# +# Like the other estimates, it is OK to underestimate the +# total number if that is how execution works. +# +# Finding a true value for this estimate requires a fair +# bit of inside knowledge of the application to know how many +# routines have been instrumented for logging and how likely +# any of those loggers are going to be required. +# +# Some power of 2 are good choices for this value. +# +# + +context.Enabled = Yes +context.MaxLineLength = 512 +# context.EstmatedNumAppenderTypes = 16 +# context.EstimatedNumAppenders = 32 +# context.EstimatedNumLoggers = 512 + + + +#=============================================================== +# +# Appender Types +# +# Define a new appender type that can be dynamically hooked +# into the Dynamic Logging System at run time so long as +# sufficient hooks are provided. +# +# A new appender type is created with by referring to it with +# any declaration. +# +# Once defined, the appender type is used in an appender +# definition using the 'AppenderType' declaration. +# +# Appender Type Names are case insensitive. +# +# 'Default' appender type is created when the logging library +# is launched. If you do not supply an appender type for a +# particular appender, it is assumed to be of the 'Default' +# appender type. +# +# 'Null' appender type is also created when the logging library +# is launched and operates as a No-Operation appender. It works +# similarly as if an appender were disabled. The difference here +# is that enabled or not, the appenders of the Null type immediately +# return without logging anything (data goes into a black hole). +# +# The Null appender type is used when a user supplied Appender +# Type is not correctly specified or some part of the initialization +# of an instance fails for some reason. +# +# You can not change the hooks associated with the 'Default' or +# 'Null' appender types. +# +# You are free to create appenders of the Default and Null types. +# +# This section does not create appenders, it defines the basic +# capabilities of an appender. These capabilities are identified +# by naming hooks from a DLL or shared library that can be loaded +# at runtime. +# +# Appenders have the following operations that must be supplied +# for new appender types. These operations are provided by references +# to a routine within a DLL the user identifies in this configuration +# file. +# +# The function prototypes for these functions can be found in the +# "dynlog.h" header file. +# +# How these routines go about performing the individual tasks are +# immaterial: +# +# InitializeLibrary +# Initializes any background resources and/or checks for +# basic requirements before any instances of a particular +# Appender Type are created. +# +# This hook may be at least once and perhaps numerous times, but +# the first call must result in a prepared library for the +# Appender Type and any subsequent calls must not interfere +# with that initialization (i.e. the first call is the +# important one and subsequent calls are unimportant). +# +# CreateInstance +# This hook, when called, will create and return a handle +# to a new instance of the appender type ready to be used +# to log messages in a manner defined by the appender type. +# +# SetProperty +# Provides a property name and a value that the hook routine can +# use to change characteristics of an appender instance. +# +# A property may be set or reset at any time, before or after +# an appender instance has started logging messages. +# +# Some properties for an appender instance will define a destination +# for logged messages. +# +# There are certain properties that are common across all appender +# types and these properties should not be handled by this 'SetProperty' +# hook. Those properties are: +# Enabled +# MinMsgPriority +# MaxMsgPriority +# +# The above properties are intercepted and handled by the Dynamic +# Logging library. +# +# All other properties are supplied through this hook with their +# associated value and it is the responsibility of this hook to deal +# with them with respect to the appender instance. +# +# StartOutput +# This hook will prepare the output stream to accept new messages +# and send them on. This hook is called once per instance. If +# messages are requested to be sent prior to the output being +# 'started', they should either be quietly ignored or cause an implied +# 'StartOutput' call to occur. +# +# Any instructions on how to start the output for a particular instance +# are expected to have been provided through properties for that +# instance. +# +# LogMessage +# The appender is presented with formatted text to be sent through +# the appender's output stream. +# +# StopOutput +# This hooks stops further output by closing the output stream. +# If any attempts to log messages occurs once the the output is closed, +# these attempts should be quietly ignored. +# +# DestroyInstance +# This hook will destroy a specific instance of an appender +# type. +# +# ShutdownLibrary +# Releases all remaining resources held by the library including +# any remaining appenders that may still be in existance. +# +# +# The specification of routines providing the hook the activity type is +# provided by a DLL name, a vertical bar, and the name of the routine +# within the DLL providing the functionality. +# +# The hooks may be scattered across DLLs. +# +# The DLL must be on the process PATH, or it must be fully qualified. +# The DLL path name can be built with environment variables such as +# $(EXEDir)\YOUR.DLL|RoutineHook +# +# + + +# +# Create a new Appender Type named 'newApndrType' and identify all +# all the hooks for that appender. +# +# Once specified this way, new instances of that appender type can be +# used as any other appender and is transparent to the dynamic logging +# framework. +# + +# appenderType.InitializeLibrary.newApndrType = YOUR.DLL|InitializeLibraryHook +# appenderType.CreateInstance.newApndrType = YOUR.DLL|CreateInstanceHook +# appenderType.StartOutput.newApndrType = YOUR.DLL|StartOutputHook +# appenderType.LogMessage.newApndrType = YOUR.DLL|LogMessageHook +# appenderType.StopOutput.newApndrType = YOUR.DLL|StopOutput +# appenderType.DestroyInstance.newApndrType = YOUR.DLL|DestroyInstanceHook +# appenderType.ShutdownLibrary.newApndrType = YOUR.DLL|ShutdownLibraryHook + + + + +#=============================================================== +# +# Environment/Substitution variable definitions. +# +# Define environment/substitution variables for use throughout +# the Dynamic Logging library and outside into the application +# itself. +# +# All Environment/Substitution variables have the form: +# +# env.varName = value +# +# This would define a substition variable named 'varName' and +# any occurrence of it would be substituted for its +# substitution value: 'value'. +# +# Any environment variable/substitution variables are scanned +# in this file prior to loading Appenders, Loggers, Context or +# other information and therefore may be scattered throughout +# this file. +# +# Process environment variables are inherited and available for +# reference in this file in the same way as if you had defined +# them locally. +# +# An environment/substitution variable is referred to by +# wrapping the variable name as such: $(varNm) +# +# Substitution variable names are not case sensistive and so +# $(varNm) and $(VARNM) and $(varnm) all refer to the same +# variable. +# +# Substitution variabled may contain a reference to another +# substitution variable. Therefore, for the following +# definitions: +# +# env.varBase = def +# env.varContain = abc$(varBase)ghi +# env.overAll = 12$(varContain)34 +# +# The variable $(overAll) would expand out to: 12abcdefghi +# +# A Substitution variable may have multiple references to +# other substitution variables: +# +# env.Multi = -$(varContain)-$(varBase)- +# +# would expand out to: -abcdefghi-def- +# +# IMPORTANT: Recursive definitions will cause the application +# to die without grace. Ensure you do not create a +# variable definition that does refers to itself +# either directly or indirectly through an embedded +# variable's definition. +# +# env.Var1 = very$(Var2) +# env.Var2 = something-$(Var1)-bad +# + +# env.sample = sampleEnvVal + + + +#=============================================================== +# +# Appender Configuration: +# +# Create a single appender named 'standard' that will be +# attached to the 'rootLogger' that will dump all messages +# received by the root logger. No filtering by message priority +# will take place. +# +# The default output location is a file named 'loggingOutput.txt' +# but you can supply a different file name here or use the +# special names 'stdout' or 'stderr' to log to the standard +# output or standard error output streams. +# +# An appender may be declared to be of a certain type if that +# 'appenderType' has been declared. There is a default +# appender type of 'Default' (case insensitive). If an +# appender is not defined to be of a specific appender type, +# it is assumed to be the 'Default' appender type. +# +# + + +appender.AppenderType.standard = Default +appender.Enabled.standard = Yes +appender.Destination.standard = loggingOutput.txt +appender.AppendMode.standard = No +appender.MinMsgPriority.standard = INFO +appender.MaxMsgPriority.standard = HIGHEST +appender.RequiresMarkers.standard = NotMarked +appender.PreventMarkers.standard = SomeOtherMarkerName, AnotherMarkerToPrevent +appender.TimeStamps.standard = Yes +appender.LibEXEName.standard = No +appender.ModuleName.standard = No +appender.FunctionName.standard = No +appender.QualifyingName.standard = No +appender.FullyQualifiedName.standard = No +appender.AbbreviatedName.standard = No +appender.LocalName.standard = Yes +appender.LineNumbers.standard = No +appender.Indent.standard = Yes +appender.MsgPriority.standard = No +appender.FlushImmediate.standard = No + + + +appender.AppenderType.v7Log = Default +appender.Enabled.v7Log = No +appender.Destination.v7Log = $(InstallDir)/VDYP_CFG/v7Log.txt +appender.AppendMode.v7Log = No +appender.MinMsgPriority.v7Log = INFO +appender.MaxMsgPriority.v7Log = HIGHEST +appender.RequiresMarkers.v7Log = V7Log +appender.PreventMarkers.v7Log = NotMarked +appender.TimeStamps.v7Log = Yes +appender.LibEXEName.v7Log = No +appender.ModuleName.v7Log = No +appender.FunctionName.v7Log = No +appender.QualifyingName.v7Log = No +appender.FullyQualifiedName.v7Log = No +appender.AbbreviatedName.v7Log = No +appender.LocalName.v7Log = Yes +appender.LineNumbers.v7Log = No +appender.Indent.v7Log = Yes +appender.MsgPriority.v7Log = No +appender.FlushImmediate.v7Log = Yes + + + +#=============================================================== +# +# Logger Configuration: +# +# All that is required is to set a number of properties of the +# root logger (named 'rootlogger' or 'root') to display all +# messages that are created. +# +# To this root logger, we will attach the appender named +# 'standard' so that the messages can be output. +# +# With no further configuration, all messages generated in the +# code will find their way to the root logger. +# +# + +logger.Enabled.rootLogger = Yes + +logger.MinMsgPriority.rootLogger = LOWEST +logger.MaxMsgPriority.root = HIGHEST + +logger.Appender.rootLogger = standard +logger.Appender.rootLogger = v7Log + + +# The following loggers for 'Unexpanded Env Vars' and 'Expanded Env Vars' +# Must be given internal buffers of approx 8K characters in length to +# accommodate individual system environment variables having very long +# definitions. + +logger.Enabled.vdyp7console.cmdline.cmdline_logcommandlineparams.unexpandedenvvars = No +logger.MaxLineLen.vdyp7console.cmdline.cmdline_logcommandlineparams.unexpandedenvvars = 8191 + +logger.Enabled.vdyp7console.cmdline.cmdline_logcommandlineparams.expandedenvvars = No +logger.MaxLineLen.vdyp7console.cmdline.cmdline_logcommandlineparams.expandedenvvars = 8191 + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYPBACK.CTR b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYPBACK.CTR new file mode 100755 index 000000000..19f3589be --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYPBACK.CTR @@ -0,0 +1,92 @@ + 0 VDYPBACK.CTR input file for VDYPBACK.for + 0 General Format is col 1-3 0 OR a parameter number + 0 (note: zero or blank implies COMMENT) + 0 col 5-54 Parameters or file names + +001 00999999 Max # of Polygons to process (I8) +009 coe\becdef.dat BEC Zone Definitions +010 coe\SP0DEF_V0.dat Standard SP0 Codes (with order) RD_SP0 + +011 \bcgrow\backtst\VP_IN36.dat VDYP7 Polygon input +012 \bcgrow\backtst\VS_IN36.dat VDYP7 Layer by Species, input +013 \bcgrow\backtst\VU_IN36.dat VDYP7 Layer by SP0 by Util, input +014 Grow-to years (DISABLED) + +015 \bcgrow\backtst\VP_OUT36.dat VDYP7 Polygon out +016 \bcgrow\backtst\VS_OUT36.dat VDYP7 Layer by SP0 out +018 \bcgrow\backtst\VU_OUT36.dat VDYP7 Layer by SP0 by Util out + +020 coe\vgrpdef1.dat Defines Volume Eqn groups RD_VGRP +021 coe\dgrp.dat Defines Decay Groups RD_DGRP +022 coe\bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 + +025 coe\sieqn.prm Site Curve Numbers assigned +025 Nullifies above siteCurve # +026 coe\siagemax.prm Maximum ages for ht incr, by site curve number +028 coe\cvadj.prm CV adjustment and relalted parameters + +030 coe\grpba1.dat Default Eq # BA=f(CC) RD_GRBA1 +031 coe\gmodba1.dat Eqn modifiers for above RD_GMBA1 + +043 coe\upperb02.coe Upper BA, DQ by C/I SP0_P RD_E043 IPSJF128 + +050 coe\regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 +051 coe\regyhlpa.coe HL, Primary SP, Eqn P2 RD_YHL2 +052 coe\regyhlpb.dat HL, Primary SP, Eqn P3 RD_YHL3 +053 coe\reghl.coe HL, Non-primary Species RD_YHL4 + +060 coe\REGDQI04.coe By-species DQ RD_E060 IPFJF125 +061 coe\COMPLIM.coe Species component size limits RD_E061 IPSJF158 + +070 coe\regbac.dat Util. Comp, BA RD_UBA1 +071 coe\regdqc.dat Util. Comp, DQ RD_UDQ1 + +080 coe\regpr1c.dat Small Comp., Probability RD_SBA1 +081 coe\regba2c.dat Small Comp., BA RD_SBA2 +082 coe\regdq4c.dat Small Comp., DQ RD_SDQ1 +085 coe\reghl1c.dat Small Comp., HL RD_SHL1 +086 coe\regv1c.dat Small Comp., WS Volume RD_SVT1 + +090 coe\VTOTREG4.coe Total stand WholeStem Vol RD_YVT1 IPSJF117 +091 coe\REGVU.coe Util Comp, WS volume RD_YVT2 IPSJF121 +092 coe\regvcu.coe Close Utilization Vol RD_YVC1 IPSJF122 +093 coe\regvdu.coe Vol net of Decay RD_YVD1 IPSJF123 +094 coe\regvwu.coe Vol net of (Decay+Waste) RD_YVW1 IPSJF123 +095 coe\regbreak.coe Breakage RD_EMP95 IPSJF157 + +096 coe\vetvol1.dat Vet-layer volume adjust RD_YVET +097 coe\vetdq2.dat DQ for Vet layer RD_YDQV + +101 1800 0 2 4 1 0 Contol variables (10I4) + 1st 4 col: IYR_CNTR =i i=0 for NO GROWTH + -1 to use SEQ014 (specifies end yr, DISABLED) + i =1 to 400 regress i yrs + i = 1600-2020 regress to to yr i (A.D.) + 4th: OUTPUT Files + 3 All years + 4 ... Last-30, Last-20, Last-10, Last + 5 Earliest, Last + 5th: ALLOW COMPATIBILITY (CV) Computations + 0: Always + 1: Only when basis exceeds limits (.1 for vol, .01 BA for DQ) + Others (2nd: 0, 3rd: 2, 6th: 0) + +106 coe\YLDBA407.coe BA Yield (Primary layer) RD_E106 ipsjf160 +107 coe\YLDDQ45.coe DQ Yield (Primary layer) RD_E107 ipsjf161 +108 coe\PCT_407.coe Upper bounds (BA, DQ) RD_E108 ipsjf160 (emp106, emp107) +111 coe\emp111A1.prm BA growth IPSJF173, fiat model. To be removed later. +117 coe\emp117A1.prm DQ growth (Pri. L) IPSJF173, fiat model. +121 coe\growba11.coe Growth in BA (Prim layer) Emp. Model (EMP121) IPSJF162 +122 coe\GD20.coe DQ growth EMP122 IPSJF173, empirical model +148 coe\basp05.coe BA growth Primary SP IPSJF148 +149 coe\basp06.coe BA growth NONPrimary SP IPSJF149 +150 coe\dqsp05.coe DQ growth Primary SP IPSJF150 +151 coe\dqsp06.coe DQ growth NONPrimary Sp. IPSJF151 + +198 coe\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198 + +199 0 0 0 0 0 0 0 0 0 0 415 5 713 3 0 0 0 0 0 1 0 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155 App IX. + (5) MATH77 errors 0-suppress (recommended). (1,2)-show. + (11-20) Controls Ht/Age/SI fillin. See IPSJF174.doc + (22) 1: extra preference for preferred sp as primary + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRIADJST.CTR b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRIADJST.CTR new file mode 100755 index 000000000..134489f1b --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRIADJST.CTR @@ -0,0 +1,45 @@ + 0 VRIADJST control input file for VRIADJST (Revision date 29MAR2002) + 0 General Format is col 1-3 0 OR a parameter number + 0 (note: zero or blank implies COMMENT) + 0 col 5-54 Parameters or file names + +001 00999999 Max # of Adjustment records to process (I8) + +009 coe\BECDEF.dat List of BECs +010 coe\SP0DEF_V0.dat Standard SP0 Codes (with order) RD_SP0 + +011 vp.dat VDYP7 Polygon input +012 vs.dat VDYP7 Layer by Species (ht and Age), input +013 vu_.dat VDYP7 Layer by SP0 by Util, input +014 Adjustment.dat ADJUSTMENT file + +015 vp_adj.dat VDYP7 Polygon out +016 vs_adj.dat VDYP7 Layer by SP0 (Ht and Age) out +018 vu_adj.dat VDYP7 Layer by SP0 by Util out + +022 coe\bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 + +095 coe\regbreak.coe Breakage RD_EMP95 IPSJF157 + +101 1 0 2 1 0 Control Switches (10I4) + First value 1: 1 input record/polygon (P or X) + 2: Multiple records/poly incl separator + Second Value 0: Ignore polygon data which lacks adj records. + 1: Copy these data to output files (unchanged). + Third Value 0: Changes in TPH by sp Not allowed. + 1: Allowed if absolutely required. + 2: Allowed if better DBH distrs result. + Fourth Value: 0: Changes >0.05 in BA12.5 Not allowed + 1: Changes allowed. (Warning) + 2: Changes allowed. (No warning) + Fifth Value 0: Unmatched adjustment records sets ADJ_SUB err 1 + 1: Unmatched adjustment records ignored. +199 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 Debug switches (0 by default) See IPSJF155 App IX + (5) = 0 does full suppresion of MATH77 messages. + 1 shows some errors. 2 shows all. + (7) = 0 Stop on errors; 1 - continue to next poly. + (1 can bypass computational problems, not I/O errors) + (22) 1: extra preference for preferred sp. as primary. + + + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRISTART.CTR b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRISTART.CTR new file mode 100755 index 000000000..ff8bc32c3 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRISTART.CTR @@ -0,0 +1,83 @@ + 0 VRISTART.ctr + 0 General Format is col 1-3 0 OR a parameter number + 0 (note: zero or blank implies COMMENT) + 0 col 5-54 Parameters or file names + 0 + 0 *********** BA and DQ = f(CC and FIP caracteristics) + +001 00999999 Max # of Polygons to process (I8) + (poly's with MODE = -1 NOT counted) +009 coe\BECDEF.dat List of BECs [are ALSO hardcoded] +010 coe\SP0DEF_v0.dat Standard SP0 Codes but H preferred over F, RD_SP0 + +011 \bcgrow\vritest\VRINP01.dat +012 \bcgrow\vritest\VRINL01.dat Layer: BA, TPH, CC (VRIGETL) +013 \bcgrow\vritest\VRINSI01.dat Height-age-SI data (VRIGETSI) +014 \bcgrow\vritest\VRINSP01.dat Species distribution file (VRIGETSP) + +015 \bcgrow\vritest\VP_01.dat VDYP7 Polygon +016 \bcgrow\vritest\VS_01.dat VDYP7 Layer by Species +018 \bcgrow\vritest\VU_01.dat VDYP7 Layer by SP0 by Util + +020 coe\VGRPDEF1.dat Defines Volume Eqn groups RD_VGRP +021 coe\DGRP.dat Defines Decay Groups RD_DGRP +022 coe\BGRP.dat Defines Breakage Groups RD_BGRP +025 coe\SIEQN.prm Site Curve Numbers (SCN) assigned RD_E025 +025 Nullifies above siteCurve # +026 coe\SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 + +030 coe\GRPBA1.dat Default Eq # BA=f(CC) RD_GRBA1 +031 coe\GMODBA1.dat Eqn modifiers for above RD_GMBA1 +033 coe\fipstkR.prm Stocking class factors RD_STK33 + +040 coe\regba25.coe Coe BA=f(CC) RD_E040 IPSJF128 +041 coe\regdq26.coe Coe DQ=f(CC) RD_E041 IPSJF129 +043 coe\upperb02.coe Upper BA by C/I SP0_P RD_E043 IPSJF128 + +050 coe\REGYHLP.coe HL, Primary SP, Eqn P1 RD_YHL1 +051 coe\REGYHLPA.coe HL, Primary SP, Eqn P2 RD_YHL2 +052 coe\REGYHLPB.dat HL, Primary SP, Eqn P3 RD_YHL3 +053 coe\REGHL.coe HL, Non-primary Species RD_YHL4 + +060 coe\REGDQI04.coe By-species DQ RD_E060 IPFJF125 +061 coe\COMPLIM.coe Species component size limits RD_E061 IPSJF158 + +070 coe\REGBAC.dat Util. Comp, BA RD_UBA1 +071 coe\REGDQC.dat Util. Comp, DQ RD_UDQ1 + +080 coe\REGPR1C.dat Small Comp., Probability RD_SBA1 +081 coe\REGBA2C.dat Small Comp., BA RD_SBA2 +082 coe\REGDQ4C.dat Small Comp., DQ RD_SDQ1 +085 coe\REGHL1C.dat Small Comp., HL RD_SHL1 +086 coe\REGV1C.dat Small Comp., WS Volume RD_SVT1 + +090 coe\VTOTREG4.coe Total stand WholeStem Vol RD_YVT1 IPSJF117 +091 coe\REGVU.coe Util Comp, WS volume RD_YVT2 IPSJF121 +092 coe\REGVCU.coe Close Utilization Vol RD_YVC1 IPSJF122 +093 coe\regvdu.coe Vol net of Decay RD_YVD1 IPSJF123 +094 coe\regvwu.coe Vol net of (Decay+Waste) RD_YVW1 IPSJF123 +095 coe\REGBREAK.coe Breakage RD_EMP95 + +096 coe\VETVOL1.dat Vet-layer volume adjust RD_YVET +097 coe\VETDQ2.dat DQ for Vet layer RD_YDQV +098 coe\REGBAV01.coe VET BA, IPSJF168.doc RD_E098 +106 coe\YLDBA407.coe BA Yield (Primary layer) RD_E106 ipsjf160 +107 coe\YLDDQ45.coe DQ Yield (Primary layer) RD_E107 ipsjf161 +108 coe\PCT_407.coe Upper bounds (BA, DQ) RD_E108 ipsjf160 (emp106, emp107) + + +197 6.0 0.0 2.0 10.0 Min Ht, Min BA, Min Pred BA, Min Vet Ht (or 0); BA'a fully stocked. + (3rd parameter should ALWAYS be at least 0.5) +198 coe\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198 + +199 0 0 0 0 0 0 0 050 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 Debug switches (0 by default) See IPSJF155 App IX + (1) Controls where BA,TPH errors (Mode 1)are fatal + 0=NO 2=Yes + (switch 9 can lessen the probability of errors) + (2) Calculation of HL for nonprimary species + 0= from its HD, 1=from primary HD + (5) MATH77 error messages 0:suppress + 1: show some 2:show all. + (9) Percentage expansion of by-species DQ + limits if needed for TPH recovery. + (22) 0 default; 1 primary sp from preferred list if ba > .9995 other diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE12A.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE12A.DAT new file mode 100755 index 000000000..ad9bae4f0 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE12A.DAT @@ -0,0 +1,79 @@ + 1 0.8766 0.97607 -0.015981 -0.06153 2.71436 60.0 100.0 D + 11 0.8509 0.65239 -0.012062 -0.11619 7.17556 50.0 95.0 AT + 12 0.9214 0.32605 -0.008901 -0.08454 4.57301 50.0 95.0 AT + 13 1.0065 0.36817 -0.006293 -0.11836 8.00000 50.0 95.0 AT + 14 0.9462 0.47339 -0.003554 -0.12846 8.00000 50.0 95.0 AT + 21 1.5000 0.15000 -0.000357 -0.01422 0.97245 105.0 87.5 B + 22 0.8654 0.15000 -0.000100 -0.04556 1.35091 105.0 87.5 B + 23 0.9716 0.34946 -0.000100 -0.06382 1.88017 70.0 85.0 B + 24 0.8585 0.30101 -0.000100 -0.09437 2.93908 70.0 85.0 B + 25 1.5000 0.33775 -0.000351 -0.01804 0.87126 70.0 85.0 B + 26 1.5000 0.35792 -0.000478 -0.02271 1.07690 70.0 85.0 B + 27 1.5000 0.23711 -0.000202 -0.02621 1.29646 70.0 85.0 B + 31 0.9809 0.21266 -0.001730 -0.04665 2.90582 155.0 90.0 C + 32 1.5000 0.15000 -0.000833 -0.03812 3.34283 155.0 85.0 C + 33 1.5000 0.15000 -0.000704 -0.02506 2.09809 155.0 85.0 C + 34 1.5000 0.15000 -0.000862 -0.05096 5.18297 155.0 85.0 C + 35 1.5000 0.15000 -0.000410 -0.01703 1.49824 155.0 85.0 C + 41 0.9448 0.99966 -0.013427 -0.12375 8.00000 45.0 95.0 E + 42 1.3852 0.44497 -0.001159 -0.08830 5.36782 45.0 95.0 E + 51 1.5000 0.25284 -0.001001 -0.01824 1.54402 115.0 90.0 F + 52 1.5000 0.39724 -0.000491 -0.02044 1.63232 115.0 90.0 F + 53 1.2035 0.41047 -0.000100 -0.04430 1.90030 70.0 85.0 F + 54 1.2102 0.23208 -0.000484 -0.03943 1.78694 70.0 85.0 F + 55 1.5000 0.24668 -0.000515 -0.04223 2.23338 70.0 85.0 F + 56 1.5000 0.28960 -0.000100 -0.03823 2.08557 70.0 85.0 F + 57 1.5000 0.23267 -0.000100 -0.02578 1.58113 70.0 85.0 F + 58 1.5000 0.23451 -0.000100 -0.02805 1.58331 70.0 85.0 F + 60 1.5000 0.21286 -0.000296 -0.03126 2.06677 70.0 85.0 F + 61 1.5000 0.34717 -0.001861 -0.03699 2.64808 70.0 85.0 F + 62 1.3300 0.24015 -0.000859 -0.04768 2.32271 70.0 85.0 F + 63 1.5000 0.25010 -0.000705 -0.03840 1.99819 70.0 85.0 F + 71 1.1375 0.30166 -0.001320 -0.03597 1.96483 110.0 90.0 H + 72 1.5000 0.15000 -0.000386 -0.00911 0.83195 110.0 90.0 H + 73 1.5000 0.15000 -0.000607 -0.01466 1.06570 110.0 90.0 H + 74 1.5000 0.19424 -0.000833 -0.02047 1.48829 110.0 90.0 H + 75 1.1210 0.15000 -0.001069 -0.02201 1.18254 110.0 90.0 H + 76 1.5000 0.15000 -0.000493 -0.01505 0.87618 90.0 90.0 H + 77 1.4227 0.16716 -0.000232 -0.02134 1.01946 90.0 90.0 H + 78 0.8650 0.38086 -0.001069 -0.07834 2.66721 90.0 90.0 H + 79 0.6934 0.17918 -0.001591 -0.13307 4.92208 90.0 90.0 H + 80 1.5000 0.15000 -0.000805 -0.01735 1.10983 90.0 90.0 H + 91 1.2632 0.22696 -0.000100 -0.05315 2.79699 60.0 90.0 L + 92 1.3088 0.48251 -0.000119 -0.05046 2.53560 60.0 90.0 L + 101 0.8293 0.39153 -0.000100 -0.20000 5.20997 70.0 80.0 PA + 111 1.4259 1.53941 -0.002188 -0.08317 3.41455 60.0 90.0 PL + 112 1.0264 0.43643 -0.000568 -0.07710 2.63552 60.0 90.0 PL + 113 1.2194 0.34344 -0.001075 -0.05696 2.24626 60.0 90.0 PL + 114 0.8850 0.42310 -0.002991 -0.08202 3.64832 60.0 90.0 PL + 115 0.8650 0.31216 -0.019519 -0.08781 5.21510 60.0 90.0 PL + 116 0.9346 0.34153 -0.009535 -0.09215 4.33307 60.0 90.0 PL + 117 0.8328 0.35262 -0.008124 -0.13746 6.96974 60.0 90.0 PL + 118 0.8888 0.39220 -0.006483 -0.13065 8.00000 60.0 90.0 PL + 119 1.0387 0.64149 -0.001191 -0.07912 3.32380 60.0 90.0 PL + 120 1.5000 0.47889 -0.000726 -0.04381 2.21860 60.0 90.0 PL + 121 0.9156 0.47510 -0.007356 -0.09194 4.30563 60.0 90.0 PL + 122 0.8965 0.69506 -0.011958 -0.06686 3.32585 60.0 90.0 PL + 123 0.9406 0.50544 -0.000976 -0.13333 6.05582 60.0 90.0 PL + 131 0.9050 0.54450 -0.009975 -0.08015 5.05350 70.0 90.0 PW + 141 1.5000 0.28656 -0.000100 -0.03652 1.69040 45.0 75.0 PY + 151 1.0466 0.23254 -0.001008 -0.02336 1.49692 135.0 90.0 S + 152 0.7440 0.21754 -0.000100 -0.11353 4.29268 65.0 90.0 S + 153 0.6876 0.27098 -0.000100 -0.16038 8.00000 65.0 90.0 S + 154 0.6753 0.18396 -0.000100 -0.15054 4.75356 65.0 90.0 S + 155 0.7644 0.38093 -0.000100 -0.12146 4.32480 65.0 90.0 S + 156 1.1516 0.51884 -0.000100 -0.03998 1.24720 65.0 90.0 S + 157 0.8696 0.54322 -0.001515 -0.10725 4.85925 65.0 90.0 S + 158 1.0418 0.34668 -0.000100 -0.04196 1.25404 65.0 90.0 S + 159 1.1043 0.25035 -0.000100 -0.03751 1.40119 65.0 90.0 S + 160 0.9651 0.32237 -0.000477 -0.06628 1.93971 65.0 90.0 S + 161 1.1161 0.37381 -0.000100 -0.04872 1.66844 65.0 90.0 S + 162 1.5000 0.16548 -0.000615 -0.02869 1.42639 65.0 90.0 S + 163 1.5000 0.36618 -0.000100 -0.02132 0.89298 65.0 90.0 S + 164 1.5000 0.28267 -0.000100 -0.02277 1.01555 65.0 90.0 S + 165 1.1525 0.25118 -0.000100 -0.03738 1.04857 65.0 90.0 S + 166 1.5000 0.33159 -0.000100 -0.04023 1.74622 65.0 90.0 S + 167 1.5000 0.17564 -0.000100 -0.01632 0.93459 65.0 90.0 S + 168 1.1959 0.17154 -0.000100 -0.03989 1.55345 65.0 90.0 S + 169 1.5000 0.29180 -0.000139 -0.02499 1.25023 65.0 90.0 S + 171 1.4831 0.16579 -0.000437 -0.02949 1.66675 130.0 90.0 Y diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE269.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE269.DAT new file mode 100755 index 000000000..5c4a356e8 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE269.DAT @@ -0,0 +1,79 @@ + 1 6.908 6.52600 0.00000 1.54500 -0.22670 0.00000 0.00000 65.68000 + 11 45.484 -2.91900 7.41600 2.25700 -0.40000 0.00000 0.00000 49.35000 + 12 23.101 2.89800 7.16400 2.03100 -0.35380 0.00000 -0.01734 51.34000 + 13 38.003 1.99700 8.04200 1.74900 -0.24360 -0.00470 -0.04892 54.42000 + 14 67.823 -2.75800 9.22400 1.69600 -0.22920 -0.01177 -0.05000 50.90000 + 21 82.184 -0.79400 8.99900 0.31600 0.04310 -0.00656 -0.00196106.39000 + 22 140.809-10.00000 7.77400 0.98500 -0.06520 -0.01227 -0.01371102.01000 + 23 80.150 -6.43600 6.26900 0.94900 -0.04810 -0.00516 -0.01136 64.77000 + 24 92.021 -4.66800 6.86100 0.94600 -0.02650 -0.01613 -0.00413 68.83000 + 25 47.447 -0.63700 7.58800 0.48300 -0.00360 0.00000 -0.00867 69.54000 + 26 18.327 5.40600 9.01800 0.00000 0.08710 0.00000 -0.01110 70.58000 + 27 61.101 -3.15500 8.58800 0.66100 -0.01350 0.00000 -0.01207 73.60000 + 31 61.748 10.00000 7.32000 0.64300 0.03650 -0.01257 -0.01426147.21000 + 32 18.122 5.00500 0.00000 0.09900 0.23430 0.00000 0.00000167.44000 + 33 13.599 8.74300 0.00000 1.34200 0.01250 -0.01136 -0.01074127.62000 + 34 115.347 -2.62400 0.00000 2.10300 0.20500 -0.05000 -0.00038207.39000 + 35 40.134 0.67400 0.00000 0.00000 0.22290 -0.00083 -0.01151103.76000 + 41 180.697-10.00000 8.94900 2.45600 -0.35550 -0.05000 -0.01091 49.71000 + 42 40.521 -0.60700 6.71900 1.47300 -0.11620 0.00000 -0.02240 44.43000 + 51 13.010 8.58100 7.18800 0.50100 0.01860 -0.00009 -0.00589115.69000 + 52 20.035 6.70800 9.01600 0.07900 0.13690 0.00000 -0.00545 95.56000 + 53 98.148 -7.38600 9.73200 0.27100 0.11910 -0.01258 -0.02174 64.12000 + 54 142.025-10.00000 8.08200 0.00000 0.27270 -0.02822 -0.02401 66.74000 + 55 88.569 -1.18400 0.00000 1.25700 0.24180 -0.04919 -0.00090 74.51000 + 56 166.429-10.00000 7.44800 0.00000 0.35320 -0.03865 -0.00732 67.29000 + 57 66.121 -5.38000 5.07400 0.96200 0.04120 -0.00976 -0.01188 48.52000 + 58 27.820 0.60100 2.07100 0.00000 0.22180 0.00000 -0.00773 54.34000 + 60 31.413 0.47900 7.42800 0.00000 0.19670 0.00000 0.00000 58.10000 + 61 1.920 8.49200 10.00000 0.00000 0.15180 0.00000 0.00000 89.28000 + 62 29.914 -0.35900 0.00000 1.28100 -0.02360 0.00000 0.00000 72.32000 + 63 57.664 0.97600 7.50100 0.46500 0.10620 -0.01032 -0.00480 78.88000 + 71 94.839 -1.85900 6.43000 0.83100 0.00690 -0.01062 -0.00270122.45000 + 72 65.957 0.38200 8.24800 0.58900 -0.01890 -0.00461 -0.00938 98.31000 + 73 60.420 0.00000 8.21400 0.55200 0.00000 0.00000 -0.01177104.36000 + 74 47.774 8.72300 9.79000 0.14200 0.10680 -0.01098 -0.01078111.94000 + 75 55.052 2.43500 9.65100 0.37800 -0.00500 -0.00084 -0.01159102.62000 + 76 32.748 5.11000 7.91200 0.22700 0.02690 0.00000 0.00000 90.35000 + 77 67.342 -1.15600 10.00000 0.00000 0.08090 0.00000 -0.00995 87.35000 + 78 110.883 3.21000 9.72800 0.09800 0.13420 -0.02583 -0.00516 86.17000 + 79 65.444 3.85700 9.32600 0.59600 -0.02930 -0.01385 -0.00848 72.59000 + 80 28.808 5.62300 7.71400 0.34000 0.02160 -0.00046 -0.00748 93.79000 + 91 39.318 -1.18200 6.10100 1.67500 -0.16910 0.00000 -0.00529 69.35000 + 92 27.007 -1.13300 0.00000 2.66400 -0.28450 0.00000 0.00000 57.67000 +101 103.402-10.00000 2.52600 2.67900 -0.40000 0.00000 0.00000 72.27000 +111 2.393 10.00000 4.39000 0.63500 0.04660 0.00000 0.00000 74.95000 +112 36.536 10.00000 8.32500 0.00900 0.18760 -0.02547 -0.05000 55.00000 +113 39.263 6.60100 5.95100 0.56800 0.09190 -0.02136 -0.02360 62.68000 +114 44.618 10.00000 2.03400 2.17400 -0.06520 -0.05000 -0.05000 49.92000 +115 8.359 10.00000 7.98100 0.78900 -0.09640 -0.00740 -0.02934 65.58000 +116 3.227 7.31300 0.00000 2.47800 -0.40000 0.00000 0.00000 65.51000 +117 40.295 1.02800 7.32200 1.30800 -0.19070 -0.00221 -0.03059 58.06000 +118 54.309 -1.95100 8.70100 1.64000 -0.24860 0.00000 -0.03524 62.84000 +119 36.579 0.00000 6.29100 0.86700 0.00000 -0.00320 -0.03232 49.49000 +120 38.247 0.00000 7.83600 0.75000 0.00000 0.00000 -0.02603 53.18000 +121 42.778 10.00000 10.00000 0.74100 -0.02040 -0.02604 -0.03016 52.02000 +122 8.550 7.41900 8.33000 1.43900 -0.23910 0.00000 0.00000 60.32000 +123 65.677 -2.53400 7.33500 1.67300 -0.22790 -0.00856 0.00000 64.12000 +131 0.000 8.72900 3.79300 1.63700 -0.20280 0.00000 0.00000 76.56000 +141 44.136 -5.12500 0.00000 0.29400 0.22960 0.00000 -0.02862 45.47000 +151 140.002-10.00000 7.00500 0.46400 0.11690 -0.01266 -0.01563142.56000 +152 43.322 -0.33000 9.77300 0.00000 0.11950 0.00000 0.00000 52.77000 +153 101.004-10.00000 9.23500 0.95800 -0.05420 -0.00705 -0.05000 54.58000 +154 69.531 -5.82700 10.00000 0.24500 0.01830 0.00000 -0.05000 57.21000 +155 111.536-10.00000 7.91800 0.95800 -0.04200 -0.01692 -0.03732 57.61000 +156 61.670 -4.33400 8.32900 0.51300 -0.01320 0.00000 0.00000 56.81000 +157 173.767 -8.23400 5.10300 1.57000 0.01920 -0.05000 -0.02221 61.45000 +158 87.077-10.00000 9.22700 0.47700 0.01740 0.00000 0.00000 60.23000 +159 85.728-10.00000 8.03700 0.83800 -0.05250 0.00000 -0.04965 61.31000 +160 52.516 -2.21800 7.99500 0.78300 -0.07280 0.00000 -0.03438 59.55000 +161 85.607-10.00000 8.11100 0.89300 -0.05680 0.00000 -0.02712 59.00000 +162 31.950 0.54800 0.00000 0.71000 0.00490 0.00000 0.00000 81.42000 +163 48.829 -1.49500 7.80900 0.63300 -0.03420 0.00000 0.00000 69.55000 +164 59.781 -3.96100 7.48500 0.18700 0.08380 0.00000 -0.00501 68.96000 +165 55.796 -2.47500 8.19000 0.75900 -0.07300 0.00000 -0.00604 64.15000 +166 76.714 -3.76000 10.00000 0.00000 0.16370 -0.00655 -0.00942 83.59000 +167 54.578 -4.30500 5.36000 0.00000 0.13320 0.00000 -0.02088 70.54000 +168 45.166 -2.96400 0.00000 2.02700 -0.24700 0.00000 -0.00801 68.68000 +169 54.179 -2.12800 8.26300 0.00000 0.16260 -0.00422 0.00000 63.58000 +171 186.104 -8.14400 6.71600 0.29100 0.13750 -0.02011 -0.01232132.78000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BAFIP16.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BAFIP16.COE new file mode 100755 index 000000000..7b0de6e27 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BAFIP16.COE @@ -0,0 +1,79 @@ + 1 1.1744 0.73045 -0.006912 -0.03267 1.50682 61.23 100.0 D + 11 0.9257 0.57259 -0.012073 -0.09719 5.54891 50.92 95.0 AT + 12 0.9825 0.33539 -0.008879 -0.08049 4.34055 50.92 95.0 AT + 13 1.0364 0.35100 -0.006705 -0.11693 7.98684 50.92 95.0 AT + 14 0.9781 0.46945 -0.005033 -0.12528 8.00000 50.92 95.0 AT + 21 0.7661 0.15000 -0.003821 -0.06651 2.45440 103.16 85.0 B + 22 0.8010 0.17301 -0.000406 -0.06957 2.10604 103.16 85.0 B + 23 0.8465 0.39513 -0.000286 -0.09902 2.76748 69.15 85.0 B + 24 0.8908 0.28486 -0.000100 -0.09297 2.94622 69.15 85.0 B + 25 2.0000 0.33875 -0.000213 -0.00677 0.62258 69.15 85.0 B + 26 2.0000 0.33739 -0.000353 -0.01136 0.84692 69.15 85.0 B + 27 0.9312 0.28341 -0.001900 -0.05182 1.53108 69.15 85.0 B + 31 0.9556 0.23462 -0.002205 -0.03391 2.18730 150.38 90.0 C + 32 2.0000 0.15000 -0.000958 -0.01851 2.27385 159.38 85.0 C + 33 1.3536 0.15000 -0.000948 -0.01913 1.74958 159.38 85.0 C + 34 1.3191 0.15000 -0.001280 -0.06314 8.00000 159.38 85.0 C + 35 2.0000 0.15000 -0.000276 -0.00200 0.72222 159.38 85.0 C + 41 1.0896 0.93989 -0.014193 -0.11672 8.00000 45.55 95.0 E + 42 1.7981 0.29101 -0.001223 -0.05982 3.54753 45.55 95.0 E + 51 2.0000 0.34946 -0.000637 -0.01021 1.21568 117.02 90.0 F + 52 1.9889 0.63317 -0.000596 -0.01246 1.33908 117.02 90.0 F + 53 0.9330 0.47616 -0.000100 -0.07851 2.51759 68.51 85.0 F + 54 1.2636 0.43186 -0.001315 -0.02531 1.08165 68.51 85.0 F + 55 1.6036 0.31261 -0.000647 -0.03297 1.70857 68.51 85.0 F + 56 1.7812 0.40834 -0.000100 -0.02223 1.32014 68.51 85.0 F + 57 0.8506 0.43454 -0.000354 -0.03410 1.12731 68.51 85.0 F + 58 1.8936 0.22640 -0.000100 -0.01099 0.93459 68.51 85.0 F + 60 2.0000 0.38043 -0.000360 -0.01521 1.34308 68.51 85.0 F + 61 2.0000 0.48950 -0.001179 -0.01599 1.38488 68.51 85.0 F + 62 1.2727 0.38567 -0.000100 -0.04086 1.87465 68.51 85.0 F + 63 1.4486 0.28184 -0.001094 -0.03557 1.73395 68.51 85.0 F + 71 1.1618 0.41527 -0.001085 -0.02960 1.33523 107.00 90.0 H + 72 1.2193 0.19318 -0.000572 -0.00989 0.67650 107.00 90.0 H + 73 2.0000 0.15000 -0.000402 -0.00722 0.85054 107.00 90.0 H + 74 1.4066 0.25677 -0.000871 -0.01386 0.97514 107.00 90.0 H + 75 0.7402 0.15000 -0.005541 -0.06102 2.57230 107.00 90.0 H + 76 2.0000 0.15000 -0.000347 -0.00652 0.71488 89.51 90.0 H + 77 1.0083 0.22577 -0.000885 -0.04023 1.19448 89.51 90.0 H + 78 0.8011 0.27738 -0.002073 -0.11019 4.14899 89.51 90.0 H + 79 0.7017 0.23037 -0.006003 -0.09952 3.44383 89.51 90.0 H + 80 1.4148 0.15000 -0.001045 -0.01014 0.77853 89.51 90.0 H + 91 1.1230 0.22512 -0.000680 -0.05722 2.93720 62.02 90.0 L + 92 0.9647 0.56123 -0.000100 -0.08474 3.97487 62.02 90.0 L + 101 0.8310 0.41845 -0.001645 -0.20000 5.77642 71.69 80.0 PA + 111 2.0000 1.32952 -0.001699 -0.06430 3.09476 60.39 90.0 PL + 112 1.1171 0.41605 -0.000975 -0.06762 2.37678 60.39 90.0 PL + 113 1.1702 0.32875 -0.001379 -0.06563 2.50663 60.39 90.0 PL + 114 1.0717 0.40200 -0.002565 -0.06425 2.97322 60.39 90.0 PL + 115 0.8758 0.28555 -0.019196 -0.08669 4.95447 60.39 90.0 PL + 116 0.9645 0.34499 -0.009865 -0.09239 4.36283 60.39 90.0 PL + 117 0.8692 0.33365 -0.007551 -0.12771 6.07566 60.39 90.0 PL + 118 0.9036 0.36931 -0.007286 -0.13117 8.00000 60.39 90.0 PL + 119 1.4592 0.62868 -0.001589 -0.04860 2.39545 60.39 90.0 PL + 120 1.5068 0.50649 -0.000951 -0.04236 2.07267 60.39 90.0 PL + 121 0.9630 0.36080 -0.005268 -0.08784 4.02249 60.39 90.0 PL + 122 0.9837 0.50089 -0.009194 -0.06123 3.03384 60.39 90.0 PL + 123 0.9299 0.40087 -0.002060 -0.13905 6.65114 60.39 90.0 PL + 131 0.9595 0.58128 -0.014268 -0.07833 5.92872 69.01 90.0 PW + 141 1.0413 0.41441 -0.000100 -0.05476 1.60821 44.68 75.0 PY + 151 2.0000 0.34126 -0.000100 -0.00656 0.89557 134.00 90.0 S + 152 1.2405 0.29481 -0.000100 -0.03657 1.48970 63.66 90.0 S + 153 0.6995 0.27894 -0.000100 -0.16527 8.00000 63.66 90.0 S + 154 0.6871 0.21231 -0.000100 -0.17706 6.46060 63.66 90.0 S + 155 0.8486 0.39909 -0.000100 -0.10979 3.67019 63.66 90.0 S + 156 1.2139 0.44893 -0.000100 -0.03678 1.13583 63.66 90.0 S + 157 0.8985 0.49678 -0.002667 -0.10864 4.84194 63.66 90.0 S + 158 0.8713 0.37974 -0.000100 -0.08461 1.99150 63.66 90.0 S + 159 1.0252 0.28778 -0.000100 -0.05019 1.51768 63.66 90.0 S + 160 0.9208 0.32202 -0.000815 -0.08860 2.55054 63.66 90.0 S + 161 0.9611 0.36881 -0.000100 -0.08110 2.49030 63.66 90.0 S + 162 2.0000 0.15177 -0.000540 -0.00896 0.79229 63.66 90.0 S + 163 2.0000 0.38836 -0.000178 -0.01032 0.69623 63.66 90.0 S + 164 1.6042 0.34949 -0.000100 -0.01013 0.54656 63.66 90.0 S + 165 0.9644 0.26893 -0.000150 -0.06209 1.19984 63.66 90.0 S + 166 1.8675 0.41123 -0.000339 -0.02225 1.13126 63.66 90.0 S + 167 2.0000 0.25058 -0.000100 -0.01248 0.92220 63.66 90.0 S + 168 0.8718 0.19603 -0.000100 -0.08360 2.42818 63.66 90.0 S + 169 1.8514 0.34500 -0.000100 -0.01337 0.89184 63.66 90.0 S + 171 1.8285 0.24301 -0.000496 -0.01571 1.28960 127.15 90.0 Y diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP05.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP05.COE new file mode 100755 index 000000000..aa9a591f7 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP05.COE @@ -0,0 +1,15 @@ + 1 9 -0.08960 0.007892 0.00105 + 2 3 -0.05273 0.001709 0.00000 + 3 9 -0.02297 -0.001055 0.00025 + 4 8 0.02023 0.000111 -0.02833 + 5 8 -0.05678 -0.000127 0.07092 + 6 3 -0.01000 0.000223 0.00000 + 7 8 -0.02067 -0.000127 0.02083 + 8 9 -0.03183 -0.003662 0.00037 + 9 8 0.24103 -0.000604 -0.26078 +10 8 0.00391 -0.000101 0.00933 +23 3 0.04173 -0.002125 0.00000 +24 8 0.03763 -0.000270 -0.00478 +25 3 0.01685 -0.000531 0.00000 +26 9 0.04081 0.000097 -0.00054 +30 8 0.00579 -0.000076 0.00449 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP06.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP06.COE new file mode 100755 index 000000000..f88b889a7 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP06.COE @@ -0,0 +1,134 @@ +AC 0 -0.08787 0.016335 0.00907 DX +AC 2 -0.19900 -0.015408 0.22493 DX +AC 4 -0.15254 0.026762 0.02679 DX +AC 5 -0.06512 -0.004209 0.05697 DX +AC 6 -0.13568 0.032767 -0.00048 DX +AC 10 -0.00711 -0.003913 0.00388 DX +AC 25 -0.00568 0.012505 -0.03588 DX +AT 0 -0.04849 0.013457 0.00039 AT +AT 8 -0.03716 0.005623 0.01747 AT +AT 25 -0.09818 0.010564 0.05092 AT +AT 26 -0.18884 0.051559 0.00430 AT +AT 30 -0.11434 0.038416 -0.00916 AT +B 0 0.02622 -0.003110 -0.01897 B +B 5 -0.01016 -0.004042 0.02392 B +B 6 -0.03938 -0.003665 0.04711 B +B 8 0.05236 -0.001011 -0.04654 B +B 25 0.03125 -0.009094 -0.00399 B +B 30 0.14363 -0.056420 0.01488 B +C 0 0.04693 -0.007508 -0.01676 CX +C 1 0.05344 -0.019839 0.06398 CX +C 3 -0.10023 0.002357 0.10656 CX +C 5 0.04201 -0.007773 -0.01069 CX +C 6 -0.03133 0.004779 0.02147 CX +C 7 0.06404 0.004626 -0.08018 CX +C 8 -0.02354 0.047450 -0.10983 CX +C 9 -0.06764 0.051836 -0.03823 CX +C 10 -0.00275 0.003127 -0.00928 CX +C 25 0.04960 -0.000518 -0.03707 CX +C 26 0.00222 0.005026 -0.00114 CX +C 30 0.05873 -0.011052 -0.02011 CX +D 0 -0.08787 0.016335 0.00907 DX +D 2 -0.19900 -0.015408 0.22493 DX +D 4 -0.15254 0.026762 0.02679 DX +D 5 -0.06512 -0.004209 0.05697 DX +D 6 -0.13568 0.032767 -0.00048 DX +D 10 -0.00711 -0.003913 0.00388 DX +D 25 -0.00568 0.012505 -0.03588 DX +E 0 0.01268 -0.002216 -0.01387 E +E 2 0.05576 -0.030702 0.03269 E +E 5 -0.01651 -0.014764 0.03906 E +E 7 -0.04976 0.029359 -0.03900 E +E 8 0.08939 -0.011921 -0.05545 E +E 24 -0.14025 0.025753 0.04059 E +E 25 -0.00995 -0.002573 0.01100 E +E 26 -0.08006 0.041149 -0.04910 E +E 30 0.00625 0.001513 -0.01340 E +F 0 0.00979 -0.004511 0.01211 F +F 1 0.03683 0.005512 -0.03353 F +F 3 0.03500 -0.008239 0.00479 F +F 4 -0.07767 0.011020 0.03413 F +F 6 -0.08244 0.000095 0.07854 F +F 7 0.02376 0.012878 -0.05804 F +F 8 0.02726 0.011469 -0.04280 F +F 9 -0.07311 0.016131 0.03763 F +F 24 -0.02937 0.002733 0.01591 F +F 26 -0.08003 0.027574 -0.00651 F +F 30 -0.01477 -0.002521 0.03665 F +H 0 0.02658 -0.004368 -0.01185 H +H 1 -0.00219 0.026455 -0.05827 H +H 3 -0.00968 -0.009031 0.04400 H +H 4 -0.06116 -0.003067 0.06997 H +H 5 0.02243 -0.004652 -0.00536 H +H 7 0.15812 -0.058345 0.01628 H +H 8 0.15897 -0.024747 -0.09256 H +H 9 0.04347 -0.044896 0.14824 H +H 10 -0.01542 0.008256 -0.01650 H +H 24 -0.00496 0.001049 0.01351 H +H 25 -0.00320 0.014218 -0.03400 H +L 0 0.01280 0.001388 -0.01765 L +L 8 -0.00323 0.003745 -0.00084 L +L 24 0.04705 0.035724 -0.14283 L +L 25 -0.03857 0.004281 0.01460 L +L 26 -0.08753 0.016009 0.02235 L +MB 0 -0.08787 0.016335 0.00907 DX +MB 2 -0.19900 -0.015408 0.22493 DX +MB 4 -0.15254 0.026762 0.02679 DX +MB 5 -0.06512 -0.004209 0.05697 DX +MB 6 -0.13568 0.032767 -0.00048 DX +MB 10 -0.00711 -0.003913 0.00388 DX +MB 25 -0.00568 0.012505 -0.03588 DX +PA 0 -0.05262 0.002444 0.02945 P1 +PA 2 0.02640 -0.006698 -0.00854 P1 +PA 5 -0.10352 0.015486 0.03152 P1 +PA 7 0.03058 -0.017284 0.00223 P1 +PA 23 0.03746 -0.016979 0.01168 P1 +PA 25 -0.05920 0.002485 0.02882 P1 +PA 26 -0.03242 -0.007011 0.03649 P1 +PA 30 -0.03182 0.001072 0.01787 P1 +PL 0 -0.05262 0.002444 0.02945 P1 +PL 2 0.02640 -0.006698 -0.00854 P1 +PL 5 -0.10352 0.015486 0.03152 P1 +PL 7 0.03058 -0.017284 0.00223 P1 +PL 23 0.03746 -0.016979 0.01168 P1 +PL 25 -0.05920 0.002485 0.02882 P1 +PL 26 -0.03242 -0.007011 0.03649 P1 +PL 30 -0.03182 0.001072 0.01787 P1 +PW 0 -0.02248 0.006379 -0.02304 P2 +PW 5 -0.27652 0.031517 0.11537 P2 +PW 6 -0.20412 0.039290 0.02923 P2 +PW 7 -0.22064 0.099217 -0.08885 P2 +PW 8 -0.02221 0.031338 -0.08532 P2 +PW 24 -0.06793 -0.020593 0.08010 P2 +PW 25 0.00039 0.001702 -0.02771 P2 +PW 26 -0.18664 0.025352 0.04978 P2 +PY 0 -0.02248 0.006379 -0.02304 P2 +PY 5 -0.27652 0.031517 0.11537 P2 +PY 6 -0.20412 0.039290 0.02923 P2 +PY 7 -0.22064 0.099217 -0.08885 P2 +PY 8 -0.02221 0.031338 -0.08532 P2 +PY 24 -0.06793 -0.020593 0.08010 P2 +PY 25 0.00039 0.001702 -0.02771 P2 +PY 26 -0.18664 0.025352 0.04978 P2 +S 0 0.03094 -0.002652 -0.01323 S +S 2 0.14688 -0.050415 0.02519 S +S 4 -0.07044 0.000191 0.06782 S +S 6 -0.00084 -0.003482 0.01902 S +S 7 0.13488 -0.032720 -0.02759 S +S 8 0.09698 -0.016878 -0.03910 S +S 23 -0.03863 0.024461 -0.02489 S +S 24 -0.11853 0.008998 0.06400 S +S 25 -0.00562 0.003700 -0.00965 S +S 26 -0.07323 0.016900 0.01558 S +Y 0 0.04693 -0.007508 -0.01676 CX +Y 1 0.05344 -0.019839 0.06398 CX +Y 3 -0.10023 0.002357 0.10656 CX +Y 5 0.04201 -0.007773 -0.01069 CX +Y 6 -0.03133 0.004779 0.02147 CX +Y 7 0.06404 0.004626 -0.08018 CX +Y 8 -0.02354 0.047450 -0.10983 CX +Y 9 -0.06764 0.051836 -0.03823 CX +Y 10 -0.00275 0.003127 -0.00928 CX +Y 25 0.04960 -0.000518 -0.03707 CX +Y 26 0.00222 0.005026 -0.00114 CX +Y 30 0.05873 -0.011052 -0.02011 CX diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BEC0.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BEC0.DAT new file mode 100755 index 000000000..7872132fb --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BEC0.DAT @@ -0,0 +1,13 @@ +AT +BWBS +CDF +CWH +ESSF +ICH +IDF +MH +MS +PP +SBPS +SBS +SWB diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BGRP.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BGRP.DAT new file mode 100755 index 000000000..142d601ce --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BGRP.DAT @@ -0,0 +1,224 @@ +AC AT 2 BGRP.dat Breakage Groups (Seq ____) +AC BG 2 SP0 BEC DGRP (11 columns) +AC BWBS 2 224 records (16 SP0 by 14 BEC's +AC CDF 1 +AC CWH 1 +AC ESSF 2 +AC ICH 2 +AC IDF 2 +AC MH 1 +AC MS 2 +AC PP 2 +AC SBPS 2 +AC SBS 2 +AC SWB 2 +AT AT 3 +AT BG 3 +AT BWBS 3 +AT CDF 3 +AT CWH 3 +AT ESSF 3 +AT ICH 3 +AT IDF 3 +AT MH 3 +AT MS 3 +AT PP 3 +AT SBPS 3 +AT SBS 3 +AT SWB 3 +B AT 4 +B BG 4 +B BWBS 4 +B CDF 5 +B CWH 5 +B ESSF 4 +B ICH 4 +B IDF 4 +B MH 5 +B MS 4 +B PP 4 +B SBPS 4 +B SBS 4 +B SWB 4 +C AT 10 +C BG 10 +C BWBS 10 +C CDF 6 +C CWH 6 +C ESSF 10 +C ICH 10 +C IDF 10 +C MH 6 +C MS 10 +C PP 10 +C SBPS 10 +C SBS 10 +C SWB 10 +D AT 12 +D BG 12 +D BWBS 12 +D CDF 12 +D CWH 12 +D ESSF 12 +D ICH 12 +D IDF 12 +D MH 12 +D MS 12 +D PP 12 +D SBPS 12 +D SBS 12 +D SWB 12 +E AT 14 +E BG 14 +E BWBS 14 +E CDF 13 +E CWH 13 +E ESSF 14 +E ICH 14 +E IDF 14 +E MH 13 +E MS 14 +E PP 14 +E SBPS 14 +E SBS 14 +E SWB 14 +F AT 16 +F BG 16 +F BWBS 16 +F CDF 15 +F CWH 15 +F ESSF 16 +F ICH 16 +F IDF 16 +F MH 15 +F MS 16 +F PP 16 +F SBPS 16 +F SBS 16 +F SWB 16 +H AT 19 +H BG 19 +H BWBS 19 +H CDF 17 +H CWH 17 +H ESSF 19 +H ICH 19 +H IDF 19 +H MH 17 +H MS 19 +H PP 19 +H SBPS 19 +H SBS 19 +H SWB 19 +L AT 20 +L BG 20 +L BWBS 20 +L CDF 20 +L CWH 20 +L ESSF 20 +L ICH 20 +L IDF 20 +L MH 20 +L MS 20 +L PP 20 +L SBPS 20 +L SBS 20 +L SWB 20 +MB AT 21 +MB BG 21 +MB BWBS 21 +MB CDF 21 +MB CWH 21 +MB ESSF 21 +MB ICH 21 +MB IDF 21 +MB MH 21 +MB MS 21 +MB PP 21 +MB SBPS 21 +MB SBS 21 +MB SWB 21 +PA AT 23 +PA BG 23 +PA BWBS 23 +PA CDF 22 +PA CWH 22 +PA ESSF 23 +PA ICH 23 +PA IDF 23 +PA MH 22 +PA MS 23 +PA PP 23 +PA SBPS 23 +PA SBS 23 +PA SWB 23 +PL AT 24 +PL BG 24 +PL BWBS 24 +PL CDF 24 +PL CWH 24 +PL ESSF 24 +PL ICH 24 +PL IDF 24 +PL MH 24 +PL MS 24 +PL PP 24 +PL SBPS 24 +PL SBS 24 +PL SWB 24 +PW AT 26 +PW BG 26 +PW BWBS 26 +PW CDF 25 +PW CWH 25 +PW ESSF 26 +PW ICH 26 +PW IDF 26 +PW MH 25 +PW MS 26 +PW PP 26 +PW SBPS 26 +PW SBS 26 +PW SWB 26 +PY AT 27 +PY BG 27 +PY BWBS 27 +PY CDF 27 +PY CWH 27 +PY ESSF 27 +PY ICH 27 +PY IDF 27 +PY MH 27 +PY MS 27 +PY PP 27 +PY SBPS 27 +PY SBS 27 +PY SWB 27 +S AT 30 +S BG 30 +S BWBS 30 +S CDF 28 +S CWH 28 +S ESSF 30 +S ICH 30 +S IDF 30 +S MH 28 +S MS 30 +S PP 30 +S SBPS 30 +S SBS 30 +S SWB 30 +Y AT 31 +Y BG 31 +Y BWBS 31 +Y CDF 31 +Y CWH 31 +Y ESSF 31 +Y ICH 31 +Y IDF 31 +Y MH 31 +Y MS 31 +Y PP 31 +Y SBPS 31 +Y SBS 31 +Y SWB 31 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/Becdef.dat b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/Becdef.dat new file mode 100755 index 000000000..6740351e2 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/Becdef.dat @@ -0,0 +1,15 @@ +AT I Alpine Tundra +BG I Bunchgrass +BWBS I Boreal White and Black Spruce +CDF C Coastal Dougfir +CWH C Coastal Western Hemlock +ESSF I Englemann Sruce -SubAlpine Fir +ICH I Interior Cedar-Hemlock +IDF I Interior DougFir +MH C Mountain Hemlock +MS I Montane Spruce +PP I Ponderosa Pine +SBPS I SubBoreal Pine-Spruce +SBS I SubBoreal Spruce +SWB I Spruce-Willow-Birch + Z diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/COMPLIM.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/COMPLIM.COE new file mode 100755 index 000000000..ad5170777 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/COMPLIM.COE @@ -0,0 +1,32 @@ +AC C 49.4 153.3 0.726 3.647 SEQ061 +AC I 44.2 111.6 0.793 2.977 Created by expl\complim.sas +AT C 31.7 43.5 0.714 1.611 as complim.coe Aug 30, 2000 +AT I 31.7 43.5 0.714 1.611 Component size limits. see IPSJF158.doc +B C 48.3 68.7 0.729 1.718 Used by RD_E061.for and EMP061.for +B I 32.4 38.4 0.744 1.541 +C C 48.7 134.0 0.695 3.129 +C I 41.2 89.5 0.811 2.381 +D C 37.3 51.3 0.737 1.929 +D I 37.3 51.3 0.737 1.929 +E C 28.9 41.6 0.707 1.858 +E I 27.4 38.1 0.679 1.661 +F C 55.6 130.7 0.782 2.773 +F I 39.9 75.8 0.792 2.155 +H C 46.2 61.0 0.706 1.696 +H I 37.4 50.0 0.739 1.791 +L C 41.5 68.6 0.702 1.800 +L I 41.5 68.6 0.702 1.800 +MB C 39.5 66.2 0.685 2.188 +MB I 39.5 66.2 0.685 2.188 +PA C 27.0 57.5 1.001 2.697 +PA I 27.0 57.5 1.001 2.697 +PL C 33.4 51.9 0.822 2.204 +PL I 32.0 40.7 0.757 1.705 +PW C 50.5 100.3 0.846 2.319 +PW I 45.5 91.6 0.747 2.277 +PY C 34.3 63.1 1.007 2.487 +PY I 34.3 63.1 1.007 2.487 +S C 57.6 130.7 0.853 2.670 +S I 39.1 57.2 0.796 1.809 +Y C 42.4 108.9 0.976 2.991 +Y I 42.4 108.9 0.976 2.991 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/CVADJ.PRM b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/CVADJ.PRM new file mode 100755 index 000000000..cf65e23da --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/CVADJ.PRM @@ -0,0 +1,32 @@ + 01 0.98 Small utl class, BA CVADJ.prm Comp Var adjustment & related parms + 02 0.98 DQ + 03 0.98 HL + 04 0.98 VOL + 05 0.98 BA Adj, Utl Class 1 (7.5-12.5 cm) + 06 0.98 Utl Class 2 + 07 0.98 Utl Class 3 + 08 0.98 Utl Class 4 (22.5+ cm) + 15 0.98 DQ Adj, Utl Class 1 + 16 0.98 Utl Class 2 + 17 0.98 Utl Class 3 + 18 0.98 Utl Class 4 + 11 0.98 Util Class 1 ( 7.5-12.5), Whole-stem vol + 12 0.98 Close Util Vol + 13 0.98 Close U, less decay + 14 0.98 Close U, less waste and decay + 21 0.98 Util Class 2 (12.5-17.5), Whole-stem volume + 22 0.98 + 23 0.98 + 24 0.98 + 31 0.98 Util Class 3 (17.5-22.5), Whole-stem volume + 32 0.98 + 33 0.98 + 34 0.98 + 41 0.98 Util Class 4 (22.5+ ), Whole-stem volume + 42 0.98 Close Util vol + 43 0.98 Close U vol, less decay + 44 0.98 Close U vol, less decay and waste + 51 0.98 Lorey height, primary species + 52 0.98 Lorey height, other species +999 End of usuable info + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DGRP.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DGRP.DAT new file mode 100755 index 000000000..3888c9e67 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DGRP.DAT @@ -0,0 +1,224 @@ +AC AT 3 DGRP.dat +AC BG 2 SP0 in cc 1-2 (left justify) +AC BWBS 2 BEC in cc 4-7 (left justify) +AC CDF 1 DGRP in cc 9-11 (right justify) +AC CWH 1 +AC ESSF 3 All records with the same DGRP have similar decay pred eqns. +AC ICH 3 (created by \bcvol\lemay\fitb\dgrp.sas) +AC IDF 3 Basis are the tree level stratifications (JWF, 2000). +AC MH 1 +AC MS 3 +AC PP 3 +AC SBPS 3 +AC SBS 3 +AC SWB 2 +AT AT 5 +AT BG 4 +AT BWBS 4 +AT CDF 5 +AT CWH 5 +AT ESSF 5 +AT ICH 5 +AT IDF 5 +AT MH 5 +AT MS 5 +AT PP 5 +AT SBPS 5 +AT SBS 5 +AT SWB 4 +B AT 11 +B BG 13 +B BWBS 12 +B CDF 6 +B CWH 7 +B ESSF 8 +B ICH 10 +B IDF 11 +B MH 6 +B MS 11 +B PP 11 +B SBPS 11 +B SBS 9 +B SWB 13 +C AT 15 +C BG 15 +C BWBS 15 +C CDF 14 +C CWH 14 +C ESSF 17 +C ICH 18 +C IDF 15 +C MH 14 +C MS 16 +C PP 15 +C SBPS 15 +C SBS 15 +C SWB 15 +D AT 19 +D BG 19 +D BWBS 19 +D CDF 19 +D CWH 19 +D ESSF 19 +D ICH 19 +D IDF 19 +D MH 19 +D MS 19 +D PP 19 +D SBPS 19 +D SBS 19 +D SWB 19 +E AT 22 +E BG 20 +E BWBS 20 +E CDF 22 +E CWH 22 +E ESSF 22 +E ICH 22 +E IDF 22 +E MH 22 +E MS 22 +E PP 22 +E SBPS 22 +E SBS 21 +E SWB 20 +F AT 28 +F BG 28 +F BWBS 28 +F CDF 24 +F CWH 24 +F ESSF 28 +F ICH 23 +F IDF 27 +F MH 24 +F MS 25 +F PP 26 +F SBPS 28 +F SBS 29 +F SWB 28 +H AT 33 +H BG 33 +H BWBS 33 +H CDF 30 +H CWH 31 +H ESSF 32 +H ICH 34 +H IDF 33 +H MH 30 +H MS 33 +H PP 33 +H SBPS 33 +H SBS 33 +H SWB 33 +L AT 35 +L BG 39 +L BWBS 39 +L CDF 35 +L CWH 35 +L ESSF 35 +L ICH 36 +L IDF 38 +L MH 35 +L MS 37 +L PP 35 +L SBPS 35 +L SBS 35 +L SWB 39 +MB AT 40 +MB BG 40 +MB BWBS 40 +MB CDF 40 +MB CWH 40 +MB ESSF 40 +MB ICH 40 +MB IDF 40 +MB MH 40 +MB MS 40 +MB PP 40 +MB SBPS 40 +MB SBS 40 +MB SWB 40 +PA AT 41 +PA BG 41 +PA BWBS 41 +PA CDF 41 +PA CWH 41 +PA ESSF 41 +PA ICH 41 +PA IDF 41 +PA MH 41 +PA MS 41 +PA PP 41 +PA SBPS 41 +PA SBS 41 +PA SWB 41 +PL AT 43 +PL BG 49 +PL BWBS 45 +PL CDF 43 +PL CWH 43 +PL ESSF 43 +PL ICH 47 +PL IDF 42 +PL MH 43 +PL MS 46 +PL PP 43 +PL SBPS 48 +PL SBS 44 +PL SWB 49 +PW AT 50 +PW BG 50 +PW BWBS 50 +PW CDF 50 +PW CWH 50 +PW ESSF 50 +PW ICH 50 +PW IDF 50 +PW MH 50 +PW MS 50 +PW PP 50 +PW SBPS 50 +PW SBS 50 +PW SWB 50 +PY AT 53 +PY BG 53 +PY BWBS 53 +PY CDF 53 +PY CWH 53 +PY ESSF 53 +PY ICH 51 +PY IDF 52 +PY MH 53 +PY MS 53 +PY PP 53 +PY SBPS 53 +PY SBS 53 +PY SWB 53 +S AT 60 +S BG 62 +S BWBS 61 +S CDF 54 +S CWH 54 +S ESSF 55 +S ICH 56 +S IDF 59 +S MH 54 +S MS 58 +S PP 60 +S SBPS 60 +S SBS 57 +S SWB 62 +Y AT 63 +Y BG 63 +Y BWBS 63 +Y CDF 63 +Y CWH 63 +Y ESSF 63 +Y ICH 63 +Y IDF 63 +Y MH 63 +Y MS 63 +Y PP 63 +Y SBPS 63 +Y SBS 63 +Y SWB 63 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQCOE12A.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQCOE12A.DAT new file mode 100755 index 000000000..28266e814 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQCOE12A.DAT @@ -0,0 +1,79 @@ + 1 49.40 0.47712 -0.015770 -0.06321 4.56396 DQCOE12A SEQ 041 + 11 400.00 0.33572 -0.001087 -0.00669 1.96423 DQ=f(CC, ht, age) + 12 103.38 0.42122 -0.002196 -0.02705 2.75511 + 13 40.02 0.29256 -0.006984 -0.05941 5.15784 + 14 69.32 0.42401 -0.005076 -0.03681 3.78016 + 21 59.67 0.12849 -0.000663 -0.05420 3.72825 + 22 75.73 0.31737 -0.001211 -0.04717 4.00052 + 23 136.65 0.42475 -0.000050 -0.01625 1.63175 + 24 161.42 0.43731 -0.000050 -0.01747 1.95913 + 25 190.46 0.35714 -0.000050 -0.00916 1.38470 + 26 313.72 0.46184 -0.000072 -0.00825 1.59725 + 27 400.00 0.37404 -0.000079 -0.00584 1.49903 + 31 129.61 0.27413 -0.000267 -0.02154 1.70320 + 32 350.00 0.25939 -0.000151 -0.01030 1.72566 + 33 210.05 0.40660 -0.000381 -0.02014 2.21816 + 34 350.00 0.50000 -0.000100 -0.01527 1.87373 + 35 400.00 0.19201 -0.000100 -0.00682 1.63250 + 41 400.00 0.27217 -0.000755 -0.01233 2.53389 + 42 32.71 0.31307 -0.011154 -0.05380 3.94945 + 51 139.89 0.00000 -0.000544 -0.01305 1.98283 + 52 101.96 0.36508 -0.002034 -0.02246 2.27969 + 53 45.14 0.31107 -0.002879 -0.03339 2.12437 + 54 202.23 0.40077 -0.000100 -0.01088 1.68971 + 55 167.75 0.00000 -0.000131 -0.00459 1.10620 + 56 61.03 0.41741 -0.001885 -0.03374 2.29902 + 57 32.29 0.42980 -0.007887 -0.05006 2.82752 + 58 400.00 0.40572 -0.000073 -0.00449 1.36057 + 60 60.01 0.33066 -0.002431 -0.03434 2.56181 + 61 400.00 0.10086 -0.000165 -0.00400 1.48644 + 62 255.54 0.40506 -0.000471 -0.00569 1.44656 + 63 191.06 0.36159 -0.000363 -0.00606 1.38460 + 71 127.20 0.18892 -0.000699 -0.02156 2.13804 + 72 56.80 0.00000 -0.001902 -0.04203 3.82362 + 73 127.25 0.28007 -0.001077 -0.02661 3.11243 + 74 55.15 0.00000 -0.001618 -0.05251 4.49317 + 75 52.51 0.18632 -0.001567 -0.06550 4.59450 + 76 138.89 0.26886 -0.000350 -0.01852 1.88341 + 77 61.97 0.28563 -0.002430 -0.03757 2.99972 + 78 45.66 0.00000 -0.001923 -0.05946 5.15962 + 79 166.56 0.35254 -0.000958 -0.00944 1.73455 + 80 92.20 0.20023 -0.001106 -0.02979 2.91354 + 91 113.30 0.15116 -0.000222 -0.01168 1.69138 + 92 400.00 0.50000 -0.000259 -0.00813 1.94451 + 101 20.17 0.12558 -0.000357 -0.18470 5.49371 + 111 64.98 0.26406 -0.001230 -0.01663 1.66177 + 112 400.00 0.44013 -0.000234 -0.00645 1.73711 + 113 333.11 0.37638 -0.000139 -0.00468 1.37818 + 114 205.78 0.30345 -0.000487 -0.00651 1.46839 + 115 400.00 0.50000 -0.000136 -0.00521 1.47212 + 116 86.40 0.31644 -0.000151 -0.00933 1.00000 + 117 64.88 0.44400 -0.001194 -0.02962 2.38646 + 118 109.74 0.17011 -0.000050 -0.00649 1.07691 + 119 40.70 0.37527 -0.002248 -0.04679 3.01912 + 120 28.62 0.27687 -0.003306 -0.05966 3.11706 + 121 256.27 0.48127 -0.000182 -0.01100 1.93633 + 122 400.00 0.50000 -0.000159 -0.00583 1.55826 + 123 350.00 0.34478 -0.000100 -0.00387 1.32482 + 131 36.36 0.50000 -0.003940 -0.05007 2.34604 + 141 63.66 0.50000 -0.002772 -0.04239 2.31511 + 151 103.18 0.27254 -0.002750 -0.02604 2.56513 + 152 84.21 0.33255 -0.000050 -0.01402 1.21118 + 153 35.62 0.49396 -0.000921 -0.07583 2.89210 + 154 36.93 0.05401 -0.000050 -0.04749 2.42071 + 155 279.93 0.43982 -0.000170 -0.01373 2.20898 + 156 171.12 0.50000 -0.000050 -0.01503 1.75305 + 157 400.00 0.50000 -0.000177 -0.01012 1.95321 + 158 34.10 0.39384 -0.000762 -0.08443 3.89550 + 159 79.32 0.33762 -0.000511 -0.02539 1.96249 + 160 78.91 0.20663 -0.000050 -0.01767 1.47773 + 161 400.00 0.33440 -0.000370 -0.00325 1.32337 + 162 211.62 0.32822 -0.000050 -0.00980 1.56261 + 163 245.22 0.25570 -0.000050 -0.00436 1.13188 + 164 56.18 0.29748 -0.000100 -0.02390 1.31742 + 165 115.60 0.25294 -0.000050 -0.00862 1.12674 + 166 50.50 0.13844 -0.002830 -0.03023 2.44797 + 167 400.00 0.00000 -0.000324 -0.00933 2.29306 + 168 400.00 0.19981 -0.000050 -0.00240 1.09292 + 169 400.00 0.16582 -0.000197 -0.00401 1.42428 + 171 54.89 0.00340 -0.000769 -0.03740 2.06434 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQFIP16Z.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQFIP16Z.COE new file mode 100755 index 000000000..101bf669b --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQFIP16Z.COE @@ -0,0 +1,79 @@ + 1 52.07 0.41830 -0.010587 -0.04265 3.11586 39.7 + 11 384.73 0.45511 -0.001170 -0.00766 2.05889 32.3 + 12 380.24 0.47391 -0.000905 -0.00871 2.10707 32.3 + 13 40.57 0.33249 -0.006889 -0.05382 4.85152 32.3 + 14 74.16 0.50000 -0.004852 -0.03317 3.59753 32.3 + 21 49.56 0.18080 -0.001537 -0.05997 4.61094 60.6 + 22 66.11 0.31046 -0.001750 -0.04649 3.96415 60.6 + 23 62.20 0.42528 -0.000051 -0.03117 1.87887 39.0 + 24 149.70 0.50000 -0.000050 -0.01713 1.92649 39.0 + 25 236.49 0.37921 -0.000050 -0.00620 1.30908 39.0 + 26 83.76 0.50000 -0.000223 -0.02868 2.12131 39.0 + 27 382.91 0.32522 -0.000093 -0.00490 1.47317 39.0 + 31 140.38 0.24304 -0.000291 -0.01427 1.57968 71.7 + 32 383.88 0.17465 -0.000249 -0.00900 1.94674 82.5 + 33 387.91 0.43410 -0.000241 -0.01203 2.19438 82.5 + 34 384.44 0.50000 -0.000150 -0.01809 2.61376 82.5 + 35 396.16 0.28535 -0.000194 -0.00378 1.36815 82.5 + 41 382.67 0.29694 -0.000674 -0.01105 2.37800 32.1 + 42 36.56 0.48750 -0.009531 -0.05018 3.70513 32.1 + 51 151.68 0.00000 -0.000404 -0.01011 1.78563 58.7 + 52 158.45 0.32578 -0.001047 -0.01264 1.90015 58.7 + 53 36.91 0.31142 -0.003052 -0.04163 2.53637 40.3 + 54 179.25 0.31872 -0.000050 -0.00896 1.53804 40.3 + 55 43.35 0.00000 -0.000847 -0.02604 1.70267 40.3 + 56 39.00 0.28877 -0.002605 -0.04481 2.76673 40.3 + 57 26.72 0.34608 -0.006847 -0.04294 2.32511 40.3 + 58 37.05 0.40231 -0.001290 -0.04765 2.39952 40.3 + 60 42.40 0.19372 -0.003135 -0.03937 2.93894 40.3 + 61 380.95 0.00000 -0.000105 -0.00200 1.19742 40.3 + 62 117.18 0.50000 -0.000976 -0.01536 1.87137 40.3 + 63 386.96 0.30990 -0.000142 -0.00350 1.41925 40.3 + 71 124.29 0.04781 -0.000459 -0.01622 1.87011 61.1 + 72 53.32 0.05213 -0.002268 -0.03907 3.50415 61.1 + 73 120.72 0.08616 -0.000939 -0.01777 2.41172 61.1 + 74 45.79 0.00000 -0.002213 -0.05298 4.47352 61.1 + 75 46.92 0.21864 -0.002283 -0.06071 4.43343 61.1 + 76 127.40 0.44091 -0.000689 -0.02006 2.05514 53.9 + 77 57.56 0.37075 -0.003094 -0.03871 3.45028 53.9 + 78 51.32 0.00000 -0.002049 -0.04372 4.24100 53.9 + 79 390.57 0.29132 -0.000414 -0.00348 1.52779 53.9 + 80 66.34 0.22938 -0.001824 -0.03603 3.40205 53.9 + 91 28.63 0.19799 -0.002785 -0.04355 2.80697 37.8 + 92 39.43 0.43794 -0.003071 -0.04258 3.05387 37.8 + 101 18.96 0.08003 -0.001147 -0.18876 6.69115 30.7 + 111 35.89 0.27681 -0.003069 -0.04020 2.80181 30.1 + 112 378.31 0.48170 -0.000262 -0.00667 1.78967 30.1 + 113 260.05 0.39371 -0.000199 -0.00603 1.47659 30.1 + 114 319.67 0.30613 -0.000327 -0.00599 1.63995 30.1 + 115 370.67 0.50000 -0.000181 -0.00523 1.53368 30.1 + 116 384.66 0.39072 -0.000050 -0.00200 1.03848 30.1 + 117 103.47 0.50000 -0.000779 -0.01802 2.08825 30.1 + 118 376.33 0.27613 -0.000088 -0.00299 1.27970 30.1 + 119 39.91 0.44103 -0.002455 -0.04424 3.02378 30.1 + 120 20.47 0.31550 -0.006223 -0.09914 6.13686 30.1 + 121 119.76 0.50000 -0.000313 -0.01910 2.13761 30.1 + 122 377.09 0.50000 -0.000160 -0.00606 1.61825 30.1 + 123 246.34 0.36709 -0.000167 -0.00571 1.43467 30.1 + 131 29.18 0.50000 -0.005960 -0.06180 3.24664 33.5 + 141 35.68 0.34241 -0.005651 -0.06327 3.42196 53.6 + 151 380.56 0.12244 -0.000222 -0.00420 1.38124 95.5 + 152 46.20 0.31757 -0.000116 -0.02778 1.45002 40.3 + 153 27.88 0.50000 -0.001752 -0.09645 4.24599 40.3 + 154 58.61 0.15735 -0.000076 -0.02490 1.84643 40.3 + 155 382.67 0.50000 -0.000146 -0.01163 2.27639 40.3 + 156 167.51 0.50000 -0.000050 -0.01468 1.83272 40.3 + 157 379.90 0.50000 -0.000088 -0.00976 1.94553 40.3 + 158 33.31 0.37262 -0.000050 -0.07550 3.68524 40.3 + 159 166.39 0.32129 -0.000096 -0.01268 1.78623 40.3 + 160 58.84 0.21142 -0.000050 -0.02276 1.56267 40.3 + 161 381.42 0.34762 -0.000269 -0.00427 1.44691 40.3 + 162 148.28 0.38697 -0.000050 -0.01152 1.52098 40.3 + 163 64.56 0.23121 -0.000381 -0.02213 1.62087 40.3 + 164 65.03 0.23679 -0.000050 -0.01618 1.22983 40.3 + 165 49.95 0.29455 -0.000118 -0.02525 1.39567 40.3 + 166 386.35 0.16478 -0.000242 -0.00419 1.53988 40.3 + 167 386.48 0.35818 -0.000111 -0.00722 1.75317 40.3 + 168 131.34 0.25191 -0.000050 -0.01192 1.55233 40.3 + 169 380.47 0.22144 -0.000118 -0.00435 1.46391 40.3 + 171 46.80 0.00000 -0.000967 -0.04023 2.23841 50.6 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP05.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP05.COE new file mode 100755 index 000000000..4e4e95990 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP05.COE @@ -0,0 +1,15 @@ + 1 9 0.008306 -0.007918 -0.000214 + 2 9 0.009631 0.011721 -0.000207 + 3 1 0.001207 -0.002604 0.000000 + 4 8 0.026572 0.000018 -0.032466 + 5 9 0.004901 -0.000545 -0.000045 + 6 8 0.012345 0.000006 -0.014524 + 7 8 0.018029 -0.000029 -0.014843 + 8 9 0.004735 0.000310 -0.000086 + 9 9 0.001586 0.017334 -0.000098 +10 8 -0.027473 0.000010 0.030042 +23 8 0.029133 -0.000014 -0.032908 +24 8 0.020369 0.000001 -0.022038 +25 9 -0.003810 0.000223 0.000128 +26 9 0.009271 -0.007602 -0.000133 +30 9 0.004418 0.010218 -0.000047 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP06.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP06.COE new file mode 100755 index 000000000..5e4e61b00 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP06.COE @@ -0,0 +1,134 @@ +AC 0 -0.010264 0.005373 -0.016904 DX +AC 2 0.010244 -0.000858 -0.006264 DX +AC 4 -0.039114 0.010995 -0.008793 DX +AC 5 0.019442 0.000818 -0.032623 DX +AC 6 0.012310 0.002578 -0.030741 DX +AC 10 0.021425 -0.005432 -0.008359 DX +AC 25 -0.085711 0.009950 0.049612 DX +AT 0 0.036240 -0.008862 -0.005818 AT +AT 8 0.027501 -0.005217 -0.006549 AT +AT 25 0.007891 -0.004688 0.011740 AT +AT 26 0.025416 -0.012787 0.015280 AT +AT 30 0.054582 -0.012904 -0.013656 AT +B 0 0.016129 -0.002196 -0.010258 B +B 5 0.045944 -0.001605 -0.039214 B +B 6 0.030561 -0.006670 -0.007062 B +B 8 0.017964 0.003312 -0.031354 B +B 25 0.019578 -0.002443 -0.013978 B +B 30 -0.001267 -0.008415 0.021710 B +C 0 0.006949 0.002080 -0.016324 CX +C 1 0.034143 -0.002506 -0.021639 CX +C 3 -0.023919 0.001833 0.017982 CX +C 5 0.012323 -0.000837 -0.011907 CX +C 6 0.004656 0.003592 -0.019539 CX +C 7 0.032153 -0.005863 -0.016986 CX +C 8 -0.018946 0.019264 -0.041307 CX +C 9 0.037082 0.000148 -0.029175 CX +C 10 0.011242 0.002647 -0.026624 CX +C 25 0.020869 0.002083 -0.031379 CX +C 26 0.028192 -0.002536 -0.021693 CX +C 30 0.069221 -0.024821 0.001982 CX +D 0 -0.010264 0.005373 -0.016904 DX +D 2 0.010244 -0.000858 -0.006264 DX +D 4 -0.039114 0.010995 -0.008793 DX +D 5 0.019442 0.000818 -0.032623 DX +D 6 0.012310 0.002578 -0.030741 DX +D 10 0.021425 -0.005432 -0.008359 DX +D 25 -0.085711 0.009950 0.049612 DX +E 0 0.021608 -0.006832 -0.000074 E +E 2 -0.003916 0.007703 -0.021049 E +E 5 0.025112 -0.010114 0.003341 E +E 7 -0.004093 0.007178 -0.014958 E +E 8 0.019601 -0.004946 -0.002528 E +E 24 0.034815 -0.013044 0.006236 E +E 25 0.015214 -0.006090 0.005273 E +E 26 0.011500 0.007205 -0.029410 E +E 30 0.014331 0.000732 -0.019817 E +F 0 0.013841 -0.001856 -0.007191 F +F 1 0.102226 -0.025524 -0.000388 F +F 3 -0.041912 0.003287 0.024220 F +F 4 0.026757 -0.006326 -0.003905 F +F 6 0.009251 0.000540 -0.012390 F +F 7 0.010735 0.001188 -0.009126 F +F 8 0.004261 0.008864 -0.028959 F +F 9 0.048879 -0.026647 0.038823 F +F 24 0.030704 -0.004146 -0.012158 F +F 26 0.024472 -0.008326 0.005086 F +F 30 -0.033459 0.014937 -0.016162 F +H 0 0.014548 -0.002489 -0.007251 H +H 1 0.051629 -0.010993 -0.010240 H +H 3 -0.005987 0.003703 -0.008288 H +H 4 0.025522 0.001429 -0.030202 H +H 5 0.011340 -0.000381 -0.010094 H +H 7 0.005439 0.004006 -0.011162 H +H 8 0.047407 -0.008699 -0.022779 H +H 9 0.024025 -0.001013 -0.013283 H +H 10 -0.006341 0.001122 0.000318 H +H 24 0.044361 -0.011718 -0.005839 H +H 25 0.017812 0.000719 -0.019934 H +L 0 0.016452 -0.005242 0.002341 L +L 8 0.024534 -0.000781 -0.017773 L +L 24 0.026644 -0.010816 0.010884 L +L 25 0.011598 -0.005123 0.006309 L +L 26 -0.002851 -0.001640 0.005734 L +MB 0 -0.010264 0.005373 -0.016904 DX +MB 2 0.010244 -0.000858 -0.006264 DX +MB 4 -0.039114 0.010995 -0.008793 DX +MB 5 0.019442 0.000818 -0.032623 DX +MB 6 0.012310 0.002578 -0.030741 DX +MB 10 0.021425 -0.005432 -0.008359 DX +MB 25 -0.085711 0.009950 0.049612 DX +PA 0 0.034458 -0.007755 -0.009677 P1 +PA 2 0.022953 -0.014581 0.016971 P1 +PA 5 0.024556 -0.005302 -0.010611 P1 +PA 7 0.015715 -0.003041 -0.004238 P1 +PA 23 0.027309 -0.004971 -0.012039 P1 +PA 25 0.015658 -0.005429 0.001644 P1 +PA 26 0.058579 -0.016447 -0.004946 P1 +PA 30 0.044594 -0.007225 -0.020523 P1 +PL 0 0.034458 -0.007755 -0.009677 P1 +PL 2 0.022953 -0.014581 0.016971 P1 +PL 5 0.024556 -0.005302 -0.010611 P1 +PL 7 0.015715 -0.003041 -0.004238 P1 +PL 23 0.027309 -0.004971 -0.012039 P1 +PL 25 0.015658 -0.005429 0.001644 P1 +PL 26 0.058579 -0.016447 -0.004946 P1 +PL 30 0.044594 -0.007225 -0.020523 P1 +PW 0 -0.002897 -0.001467 0.008486 P2 +PW 5 -0.034463 0.010505 -0.004158 P2 +PW 6 0.022609 -0.011045 0.014254 P2 +PW 7 0.029327 -0.009172 0.007299 P2 +PW 8 -0.042334 0.024723 -0.032107 P2 +PW 24 0.000470 0.003882 -0.008065 P2 +PW 25 -0.005601 -0.003194 0.016546 P2 +PW 26 -0.008917 -0.003181 0.016800 P2 +PY 0 -0.002897 -0.001467 0.008486 P2 +PY 5 -0.034463 0.010505 -0.004158 P2 +PY 6 0.022609 -0.011045 0.014254 P2 +PY 7 0.029327 -0.009172 0.007299 P2 +PY 8 -0.042334 0.024723 -0.032107 P2 +PY 24 0.000470 0.003882 -0.008065 P2 +PY 25 -0.005601 -0.003194 0.016546 P2 +PY 26 -0.008917 -0.003181 0.016800 P2 +S 0 0.030560 -0.001880 -0.020174 S +S 2 0.042195 -0.009876 -0.014429 S +S 4 0.029177 -0.014527 0.024143 S +S 6 0.039352 -0.001425 -0.029867 S +S 7 0.012700 -0.001116 -0.003272 S +S 8 0.016169 -0.000523 -0.010976 S +S 23 -0.031210 0.014361 -0.011143 S +S 24 0.019071 -0.004601 0.000441 S +S 25 0.000068 -0.000363 0.004746 S +S 26 0.019143 -0.013733 0.023678 S +Y 0 0.006949 0.002080 -0.016324 CX +Y 1 0.034143 -0.002506 -0.021639 CX +Y 3 -0.023919 0.001833 0.017982 CX +Y 5 0.012323 -0.000837 -0.011907 CX +Y 6 0.004656 0.003592 -0.019539 CX +Y 7 0.032153 -0.005863 -0.016986 CX +Y 8 -0.018946 0.019264 -0.041307 CX +Y 9 0.037082 0.000148 -0.029175 CX +Y 10 0.011242 0.002647 -0.026624 CX +Y 25 0.020869 0.002083 -0.031379 CX +Y 26 0.028192 -0.002536 -0.021693 CX +Y 30 0.069221 -0.024821 0.001982 CX diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP111A1.PRM b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP111A1.PRM new file mode 100755 index 000000000..7bc22cd73 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP111A1.PRM @@ -0,0 +1,3 @@ + 1 1 .02 100 .01 200 0 0 0 100 150 1.0 + 2 1 .02 100 .01 200 0 0 0 100 150 1.0 + End of usuable info diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP117A1.prm b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP117A1.prm new file mode 100755 index 000000000..f079cb8cf --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP117A1.prm @@ -0,0 +1,3 @@ + 1 1 .02 100 .01 200 0 0 0 100 150 1.0 + 2 1 .02 100 .01 200 0 0 0 100 150 1.0 + End of usuable info diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/FIPSTKR.PRM b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/FIPSTKR.PRM new file mode 100755 index 000000000..99542e5ad --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/FIPSTKR.PRM @@ -0,0 +1,12 @@ +R I P 0 1.00 100 +R C P 0 1.00 100 +2 I P 0 1.00 100 +2 C P 0 1.00 100 +3 I P 0 1.00 100 +3 C P 0 1.00 100 +4 I P 0 1.00 100 +4 C P 0 1.00 100 +Z Z P 0 1.00 100 (end of usable info) + + + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GB01.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GB01.COE new file mode 100755 index 000000000..45d02cdfd --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GB01.COE @@ -0,0 +1,15 @@ + 1 10 -1.00000 0.00000 0.64573 0.00000 0.00000 0.79310 -0.00697 0.20000 + 2 12 0.00000 0.13080 -0.83470 0.71661 -0.01993 -0.02350 0.90711 1.00000 + 3 9 0.00000 -2.89557 0.14717 0.00000 0.00000 7.81965 -0.10332 1.00000 + 4 13 0.00000 0.24603 -1.00000 0.52724 -0.41843 -0.01227 0.89850 1.00000 + 5 13 -1.00000 0.95888 -1.00000 0.18885 -0.51018 -0.00252 -1.00000 1.00000 + 6 9 0.00000 0.00000 0.24486 0.00000 0.00000 2.85060 -0.10527 1.00000 + 7 12 -0.17820 0.51551 -1.00000 0.12092 -0.46102 0.00000 1.00000 1.00000 + 8 9 -1.00000 0.00000 0.35626 0.00000 -0.00099 10.95840 -0.05245 0.48321 + 9 9 -1.00000 0.00000 0.26257 -0.00190 0.00000 20.00000 -0.01541 0.20000 + 10 10 0.00000 -0.73620 0.34746 0.00000 0.00000 1.56420 -0.08175 1.00000 + 23 9 -1.00000 0.00000 0.01312 0.00000 -0.00403 20.00000 -0.00958 1.00000 + 24 9 -1.00000 -6.00000 0.00025 -0.01778 0.00000 9.72326 -0.14653 3.51067 + 25 9 -1.00000 0.00000 0.02015 0.00000 0.00000 20.00000 -0.06058 1.00000 + 26 9 0.00000 0.00000 0.73527 0.00000 0.00000 11.12396 -0.21838 1.00000 + 30 9 -1.00000 -4.71982 0.47729 0.00000 -0.00050 2.04458 -0.13475 1.00000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD19.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD19.COE new file mode 100755 index 000000000..2b68c1014 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD19.COE @@ -0,0 +1,15 @@ + 1 -0.88773 0.76254 -0.30308 0.02814 -0.01815 0.01145 -0.39846 -0.00200 -0.01000 0.01000 + 2 -1.50238 7.10798 -0.43964 0.10157 -0.10413 0.02651 -3.49648 -0.00200 -0.01000 0.01000 + 3 0.20969 3.06749 -0.84103 0.14007 -0.10895 0.01079 -1.62309 -0.00200 -0.25250 0.25514 + 4 -1.63678 1.86767 -0.20076 0.02782 -0.00536 0.00578 -0.86608 -0.00200 -0.01000 0.01000 + 5 0.07572 0.94061 -0.67300 0.03067 0.00450 0.00263 -0.01873 -0.00200 -0.01000 0.01000 + 6 -0.58048 0.00000 -0.54188 0.01825 0.01940 0.00325 0.79404 -0.00200 -0.01350 0.01000 + 7 -1.62345 0.00000 -0.86413 0.24089 -0.09615 0.02815 0.72683 -0.00200 -0.18836 0.01000 + 8 -1.54864 2.75839 -0.80540 0.09925 0.01113 0.01256 -1.05055 -0.00200 -0.06266 0.01000 + 9 -0.69608 0.00000 -0.87937 0.10922 -0.03993 0.02021 0.77299 -0.00200 -0.01000 0.01000 + 10 -0.70545 0.00000 -0.62581 0.01066 0.03497 0.00337 1.39038 -0.00200 -0.07704 0.01000 + 23 1.46640 0.00000 -1.26495 0.10705 -0.03171 0.00814 -1.30367 -0.00200 -0.19813 0.01000 + 24 1.91460 0.89514 -1.72958 0.16872 -0.02493 -0.00231 0.73442 -0.00200 -0.31763 0.01000 + 25 1.15071 0.00000 -1.32817 0.07976 0.00232 0.00669 0.97017 -0.00200 -0.06170 0.01000 + 26 1.78191 0.00000 -2.04608 0.11425 0.03436 0.02139 0.97975 -0.00200 -0.01000 0.06460 + 30 -0.92060 2.35243 -0.83131 0.05799 0.01732 0.01081 -0.22269 -0.00200 -0.01000 0.01000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD20.coe b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD20.coe new file mode 100755 index 000000000..49c7ef4b9 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD20.coe @@ -0,0 +1,15 @@ + 1 -0.68211 0.00000 -0.21059 0.02459 -0.00900 -0.00323 0.36280 -0.00200 -0.01000 0.01000 + 2 -0.33897 3.58272 -0.47300 0.07827 -0.07338 0.01125 -1.04410 -0.00200 -0.01000 0.01000 + 3 -1.36609 1.79150 -0.26154 0.01193 0.01204 0.00437 -0.17529 -0.00200 -0.02144 0.01000 + 4 -1.14595 0.90515 -0.36756 0.03173 0.00896 0.00451 0.29220 -0.00200 -0.01000 0.01000 + 5 -0.10450 1.29976 -0.56824 0.03058 -0.00145 0.00298 -0.03063 -0.00200 -0.01000 0.01000 + 6 -0.17165 0.56098 -0.48372 0.01939 0.01310 0.00015 0.15057 -0.00200 -0.03465 0.01000 + 7 -0.12173 0.00000 -1.04106 0.21260 -0.08998 0.02317 0.85721 -0.00200 -0.13708 0.01000 + 8 -0.35878 0.00000 -0.70342 0.06081 0.00571 0.00086 0.16947 -0.00200 -0.02935 0.01000 + 9 1.77171 0.00000 -1.71493 0.17402 0.01955 -0.02172 -0.32696 -0.00200 -0.25881 0.01000 + 10 0.07159 0.37615 -0.43162 0.02880 -0.01103 0.00359 0.06212 -0.00200 -0.09168 0.01000 + 23 -1.38606 8.09726 -0.19228 0.02589 -0.01177 -0.01165 -3.04598 -0.00200 -0.01000 0.01000 + 24 0.61150 2.48806 -0.86130 0.08558 -0.03427 -0.00075 -0.00124 -0.00200 -0.09577 0.01000 + 25 -0.65044 0.00000 -0.59496 0.06273 -0.00575 -0.00078 1.01796 -0.00200 -0.01282 0.01000 + 26 -0.62518 2.18357 -0.67446 0.02013 0.04435 -0.00135 -0.88421 -0.00200 -0.01000 0.01000 + 30 0.38528 2.38373 -0.99457 0.07352 -0.01362 0.01108 -0.59671 -0.00200 -0.03352 0.01000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD23.coe b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD23.coe new file mode 100755 index 000000000..4be1cc413 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD23.coe @@ -0,0 +1,15 @@ + 1 -0.76723 0.00000 -0.18524 0.02194 -0.00752 -0.00339 0.41806 + 2 -0.09691 0.40737 -0.58007 0.08900 -0.08116 0.01350 0.00000 + 3 -1.31972 0.52697 -0.43644 0.00000 0.03604 0.00539 0.09705 + 4 -1.16813 0.70068 -0.56212 0.05029 0.00442 0.00494 0.00000 + 5 0.40383 0.52005 -0.86238 0.04317 -0.00192 0.00487 0.01265 + 6 0.36789 0.43192 -0.73431 0.01266 0.02527 0.00007 0.00000 + 7 -0.22355 0.00000 -0.87885 0.11000 -0.03216 0.01609 0.71484 + 8 -0.42327 0.05508 -0.70201 0.04243 0.01622 0.00132 0.36771 + 9 -1.40151 0.00000 -0.58095 0.11000 -0.00285 -0.00941 0.35061 + 10 0.80117 0.25562 -0.92758 0.00177 0.03419 0.00563 0.45566 + 23 -1.65307 0.68910 -0.11528 0.02393 -0.00417 -0.02486 0.00000 + 24 2.00190 0.68221 -1.20000 0.11000 -0.10000 -0.00261 1.31775 + 25 -0.81028 0.05163 -0.55874 0.05008 0.00197 -0.00130 1.14357 + 26 -0.90190 0.23852 -0.72404 0.01820 0.06303 -0.00229 0.00000 + 30 0.54463 0.20881 -1.16629 0.06061 0.00743 0.01324 0.99554 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GMODBA1.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GMODBA1.DAT new file mode 100755 index 000000000..621fd895f --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GMODBA1.DAT @@ -0,0 +1,61 @@ + 11 42 12 Each line is: Default Group, ITG, Reassigned Group GMODBA1.dat + 13 42 14 SORTED by DEFAULT GROUP Number (and NOT ITG) Seq 031 + 21 18 22 61 records + 23 18 24 + 25 18 26 + 33 9 34 + 33 10 35 + 51 1 52 + 53 4 54 + 57 1 60 + 57 7 60 + 57 8 60 + 57 2 61 + 57 3 61 + 57 4 61 + 58 1 62 + 58 7 62 + 58 8 62 + 58 2 63 + 58 3 63 + 58 4 63 + 71 12 72 + 71 17 72 + 71 13 73 + 71 14 74 + 71 15 75 + 77 12 78 + 77 17 78 + 77 13 79 + 77 14 80 + 91 33 92 +112 29 113 +112 30 113 +112 31 114 +115 29 116 +115 30 116 +115 31 116 +117 29 118 +117 30 118 +117 31 118 +119 29 120 +119 30 120 +119 31 120 +121 29 122 +121 31 122 +121 30 123 +152 21 153 +154 21 155 +154 25 156 +154 26 157 +158 21 159 +158 25 160 +158 26 161 +162 21 163 +162 24 164 +162 25 165 +162 26 165 +166 21 167 +166 24 168 +166 25 169 +166 26 169 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA11.coe b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA11.coe new file mode 100755 index 000000000..64d326707 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA11.coe @@ -0,0 +1,2 @@ +C 0.1269 0.0384 -0.00720 0.2951 +I 0.0304 0.0124 -0.00010 1.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA27.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA27.COE new file mode 100755 index 000000000..9a71c643a --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA27.COE @@ -0,0 +1,112 @@ +AT B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +AT B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +AT B4 1 -1.0999 0.0766 1.9933 0.5708 -2.1998 0.0766 0.7635 4.8774 -0.5294 -2.1998 0.1461 0.1461 4.7808 4.7808 6.7174 0.5708 +AT B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +AT B6 0 0.82063 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +AT B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BG B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BG B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BG B4 1 -1.1527 0.0238 1.9404 0.5180 -2.3054 0.0238 0.7107 4.8245 -0.5822 -2.3054 0.0933 0.0933 4.7280 4.7280 6.6646 0.5180 +BG B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +BG B6 0 0.85946 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BG B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BWBS B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BWBS B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BWBS B4 1 -1.0999 0.0766 1.9933 0.5708 -2.1998 0.0766 0.7635 4.8774 -0.5294 -2.1998 0.1461 0.1461 4.7808 4.7808 6.7174 0.5708 +BWBS B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +BWBS B6 0 0.82063 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +BWBS B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CDF B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CDF B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CDF B4 1 -0.8550 0.3215 2.2381 0.8157 -1.7100 0.3215 1.0084 5.1222 -0.2845 -1.7100 0.3910 0.3910 5.0257 5.0257 6.9623 0.8157 +CDF B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +CDF B6 0 0.79224 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CDF B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CWH B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CWH B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CWH B4 1 -0.8550 0.3215 2.2381 0.8157 -1.7100 0.3215 1.0084 5.1222 -0.2845 -1.7100 0.3910 0.3910 5.0257 5.0257 6.9623 0.8157 +CWH B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +CWH B6 0 0.79224 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +CWH B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ESSF B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ESSF B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ESSF B4 1 -0.1360 1.0405 2.9572 1.5347 -0.2720 1.0405 1.7274 5.8413 0.4345 -0.2720 1.1100 1.1100 5.7447 5.7447 7.6813 1.5347 +ESSF B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +ESSF B6 0 0.29383 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ESSF B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ICH B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ICH B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ICH B4 1 -0.5592 0.6173 2.5339 1.1114 -1.1185 0.6173 1.3041 5.4180 0.0113 -1.1185 0.6868 0.6868 5.3214 5.3214 7.2581 1.1114 +ICH B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +ICH B6 0 0.55920 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +ICH B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +IDF B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +IDF B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +IDF B4 1 -1.1527 0.0238 1.9404 0.5180 -2.3054 0.0238 0.7107 4.8245 -0.5822 -2.3054 0.0933 0.0933 4.7280 4.7280 6.6646 0.5180 +IDF B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +IDF B6 0 0.85946 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +IDF B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MH B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MH B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MH B4 1 -0.8550 0.3215 2.2381 0.8157 -1.7100 0.3215 1.0084 5.1222 -0.2845 -1.7100 0.3910 0.3910 5.0257 5.0257 6.9623 0.8157 +MH B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +MH B6 0 0.79224 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MH B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MS B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MS B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MS B4 1 -0.1360 1.0405 2.9572 1.5347 -0.2720 1.0405 1.7274 5.8413 0.4345 -0.2720 1.1100 1.1100 5.7447 5.7447 7.6813 1.5347 +MS B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +MS B6 0 0.29383 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +MS B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +PP B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +PP B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +PP B4 1 -1.1527 0.0238 1.9404 0.5180 -2.3054 0.0238 0.7107 4.8245 -0.5822 -2.3054 0.0933 0.0933 4.7280 4.7280 6.6646 0.5180 +PP B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +PP B6 0 0.85946 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +PP B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBPS B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBPS B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBPS B4 1 -1.0999 0.0766 1.9933 0.5708 -2.1998 0.0766 0.7635 4.8774 -0.5294 -2.1998 0.1461 0.1461 4.7808 4.7808 6.7174 0.5708 +SBPS B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +SBPS B6 0 0.82063 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBPS B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBS B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBS B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBS B4 1 -0.4267 0.7498 2.6665 1.2440 -0.8533 0.7498 1.4367 5.5506 0.1439 -0.8533 0.8194 0.8194 5.4540 5.4540 7.3907 1.2440 +SBS B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +SBS B6 0 0.45254 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SBS B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SWB B0 0 7.9550 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB B1 0 -0.5818 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB B2 0 0.00538 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SWB B3 0 3.90488 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SWB B4 1 -1.0999 0.0766 1.9933 0.5708 -2.1998 0.0766 0.7635 4.8774 -0.5294 -2.1998 0.1461 0.1461 4.7808 4.7808 6.7174 0.5708 +SWB B5 1 0.01348-0.01473-0.02201-0.00269 0.02696-0.01473-0.03063-0.08516-0.02660 0.02696-0.05222-0.05222-0.21581-0.21581-0.08255-0.00269 +SWB B6 0 0.82063 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +SWB B7 0 0.69837 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GRPBA1.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GRPBA1.DAT new file mode 100755 index 000000000..56c7f76f7 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GRPBA1.DAT @@ -0,0 +1,192 @@ +AC CDF 1 GRPBA1.DAT Seq 30 Defines group # = f(SP0_P, BEC) +AC CWH 1 Note Leading AC D and MB all common group +AC MH 1 +AC SWB 1 +AC BWBS 1 +AC SBPS 1 +AC SBS 1 +AC ESSF 1 +AC MS 1 +AC PP 1 +AC IDF 1 +AC ICH 1 +AT CDF 11 Break out ITG 42 separately as group 12 +AT CWH 11 +AT MH 11 +AT SWB 13 Break out ITG 42 separately as group 14 +AT BWBS 13 +AT SBPS 13 +AT SBS 12 +AT ESSF 12 +AT MS 11 +AT PP 11 +AT IDF 11 +AT ICH 11 +B CDF 21 Break out ITG 18 as group 22 +B CWH 21 +B MH 21 +B SWB 23 Break out ITG 18 as group 24 +B BWBS 23 +B SBPS 23 +B SBS 23 +B ESSF 25 Break out ITG 18 as group 26 +B MS 27 +B PP 27 +B IDF 27 +B ICH 27 +C CDF 31 +C CWH 31 +C MH 31 +C SWB 32 +C BWBS 32 +C SBPS 32 +C SBS 32 +C ESSF 32 +C MS 32 +C PP 33 Break out ITG 9 as 34 and ITG 10 as 35 +C IDF 33 +C ICH 33 +D CDF 1 +D CWH 1 +D MH 1 +D SWB 1 +D BWBS 1 +D SBPS 1 +D SBS 1 +D ESSF 1 +D MS 1 +D PP 1 +D IDF 1 +D ICH 1 +E CDF 41 +E CWH 41 +E MH 41 +E SWB 42 +E BWBS 42 +E SBPS 42 +E SBS 42 +E ESSF 41 +E MS 41 +E PP 41 +E IDF 41 +E ICH 41 +F CDF 51 Break out ITG 1 as group 52 +F CWH 51 +F MH 51 +F SWB 53 Break out ITG 4 as group 54 +F BWBS 53 +F SBPS 53 +F SBS 53 +F ESSF 55 +F MS 56 +F PP 57 Break out ITG's 1 7 and 8 as group 60; 2 3 and 4 as 61 +F IDF 57 +F ICH 58 Break out ITG's 1 7 and 8 as group 62; 2 3 and 4 as 63 +H CDF 71 12 and 17 to 72; 13 to 73 14 to 74 15 to 75 +H CWH 71 +H MH 71 +H SWB 76 +H BWBS 76 +H SBPS 76 +H SBS 76 +H ESSF 76 +H MS 76 +H PP 76 +H IDF 76 +H ICH 77 12 and 17 to 78 13 to 79 14 to 80 +L CDF 91 ITG 33 will get group 92 +L CWH 91 +L MH 91 +L SWB 91 +L BWBS 91 +L SBPS 91 +L SBS 91 +L ESSF 91 +L MS 91 +L PP 91 +L IDF 91 +L ICH 91 +MB CDF 1 +MB CWH 1 +MB MH 1 +MB SWB 1 +MB BWBS 1 +MB SBPS 1 +MB SBS 1 +MB ESSF 1 +MB MS 1 +MB PP 1 +MB IDF 1 +MB ICH 1 +PA CDF 101 Note: Alt design: Match PL +PA CWH 101 +PA MH 101 +PA SWB 101 +PA BWBS 101 +PA SBPS 101 +PA SBS 101 +PA ESSF 101 +PA MS 101 +PA PP 101 +PA IDF 101 +PA ICH 101 +PL CDF 111 +PL CWH 111 +PL MH 111 +PL SWB 112 ITGs 29 and 30 use group 113 ITG 31 uses 114 +PL BWBS 112 +PL SBPS 112 +PL SBS 112 +PL ESSF 115 ITG 29 30 and 31 use group 116 +PL MS 117 ITG 29 30 and 31 use group 118 +PL PP 119 ITG 29 30 and 31 use group 120 +PL IDF 119 +PL ICH 121 ITG 29 and 31 use group 122 ITG 30 uses 123 +PW CDF 131 +PW CWH 131 +PW MH 131 +PW SWB 131 +PW BWBS 131 +PW SBPS 131 +PW SBS 131 +PW ESSF 131 +PW MS 131 +PW PP 131 +PW IDF 131 +PW ICH 131 +PY CDF 141 +PY CWH 141 +PY MH 141 +PY SWB 141 +PY BWBS 141 +PY SBPS 141 +PY SBS 141 +PY ESSF 141 +PY MS 141 +PY PP 141 +PY IDF 141 +PY ICH 141 +S CDF 151 +S CWH 151 +S MH 151 +S SWB 152 itg 21 gets 153 +S BWBS 154 itg 21 to 155 itg 25 to 156 itg 26 to 157 +S SBPS 154 +S SBS 158 itg 21 to 159 itg 25 to 160 itg 26 to 161 +S ESSF 162 itg 21 to 163 itg 24 to 164 25 and 26 to 165 +S MS 162 +S PP 162 +S IDF 166 +S ICH 166 itg 21 to 167 itg 24 to 168 25 and 26 to 169 +Y CDF 171 Alt Same as C 31/32/33 +Y CWH 171 +Y MH 171 +Y SWB 171 +Y BWBS 171 +Y SBPS 171 +Y SBS 171 +Y ESSF 171 +Y MS 171 +Y PP 171 +Y IDF 171 +Y ICH 171 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_40.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_40.COE new file mode 100755 index 000000000..9f6b1a927 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_40.COE @@ -0,0 +1,79 @@ + 1 75.29 76.10 AC + 11 50.77 34.70 AT + 12 47.42 31.50 AT + 13 53.77 32.40 AT + 14 50.93 32.30 AT + 21 103.81 58.00 B + 22 94.64 57.00 B + 23 64.47 37.70 B + 24 67.47 38.30 B + 25 69.72 37.60 B + 26 72.00 39.90 B + 27 70.29 44.20 B + 31 144.19 69.50 C + 32 165.15 79.30 C + 33 126.82 72.10 C + 34 211.56 104.90 C + 35 99.97 47.60 C + 41 48.50 32.10 E + 42 40.61 31.00 E + 51 112.06 54.30 F + 52 82.78 50.50 F + 53 62.07 38.90 F + 54 66.79 36.90 F + 55 74.72 41.60 F + 56 66.23 38.80 F + 57 45.83 41.00 F + 58 54.12 32.10 F + 60 56.03 42.00 F + 61 89.34 47.80 F + 62 64.48 36.60 F + 63 75.33 33.70 F + 71 108.83 64.20 H + 72 92.09 56.30 H + 73 100.09 55.70 H + 74 108.02 58.20 H + 75 100.34 59.10 H + 76 89.69 53.60 H + 77 87.29 52.60 H + 78 85.97 54.20 H + 79 72.17 36.20 H + 80 91.60 54.60 H + 91 62.87 32.50 L + 92 56.17 39.00 L +101 72.89 30.70 PA +111 74.95 24.90 PL +112 54.32 27.60 PL +113 62.71 32.30 PL +114 49.55 31.00 PL +115 65.46 28.60 PL +116 65.35 31.10 PL +117 55.95 27.20 PL +118 60.76 29.80 PL +119 49.04 25.20 PL +120 52.72 26.90 PL +121 50.42 23.70 PL +122 52.64 27.60 PL +123 64.72 29.80 PL +131 68.89 32.10 PW +141 44.06 51.00 PY +151 120.89 76.70 S +152 52.84 28.20 S +153 54.83 30.00 S +154 54.34 32.70 S +155 57.87 40.30 S +156 56.55 32.60 S +157 61.52 40.70 S +158 59.63 37.70 S +159 61.05 41.70 S +160 58.66 34.30 S +161 58.06 40.40 S +162 81.95 46.10 S +163 69.28 42.70 S +164 66.79 38.80 S +165 64.71 33.20 S +166 77.17 45.60 S +167 64.58 50.70 S +168 69.20 49.20 S +169 63.50 45.30 S +171 124.68 49.00 Y diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_407.coe b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_407.coe new file mode 100755 index 000000000..36ae8e3c8 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_407.coe @@ -0,0 +1,79 @@ + 1 74.78 76.10 AC + 11 50.77 34.70 AT + 12 47.20 31.50 AT + 13 53.67 32.40 AT + 14 50.93 32.30 AT + 21 103.44 58.00 B + 22 94.19 57.00 B + 23 64.47 37.70 B + 24 67.47 38.30 B + 25 69.55 37.60 B + 26 72.00 39.90 B + 27 70.29 44.20 B + 31 143.83 69.50 C + 32 165.15 79.30 C + 33 126.83 72.10 C + 34 211.56 104.90 C + 35 100.18 47.70 C + 41 48.50 32.10 E + 42 40.88 31.00 E + 51 112.06 54.30 F + 52 83.54 50.60 F + 53 62.07 38.90 F + 54 66.79 36.90 F + 55 74.72 41.60 F + 56 66.23 38.80 F + 57 45.83 41.00 F + 58 54.31 32.40 F + 60 56.02 42.00 F + 61 89.34 48.30 F + 62 64.43 36.90 F + 63 75.36 33.80 F + 71 108.72 64.80 H + 72 91.59 56.70 H + 73 100.17 55.70 H + 74 108.02 58.20 H + 75 100.34 59.10 H + 76 89.69 53.60 H + 77 87.27 52.60 H + 78 85.97 54.20 H + 79 72.17 36.20 H + 80 91.60 54.60 H + 91 62.29 32.50 L + 92 56.24 39.10 L +101 74.17 30.70 PA +111 75.13 24.90 PL +112 54.32 27.60 PL +113 62.71 32.30 PL +114 49.55 31.00 PL +115 65.46 28.60 PL +116 65.49 31.10 PL +117 55.94 27.00 PL +118 60.76 29.80 PL +119 49.03 25.10 PL +120 52.76 27.00 PL +121 50.38 23.70 PL +122 52.64 27.60 PL +123 64.73 29.80 PL +131 68.80 32.10 PW +141 44.06 51.00 PY +151 121.66 76.70 S +152 52.84 28.20 S +153 54.83 30.00 S +154 54.34 32.70 S +155 57.87 40.30 S +156 56.55 32.60 S +157 61.52 40.70 S +158 59.63 37.70 S +159 61.05 41.70 S +160 58.66 34.30 S +161 58.08 40.40 S +162 80.36 46.20 S +163 69.28 42.70 S +164 66.79 38.80 S +165 64.73 33.20 S +166 77.17 45.60 S +167 64.58 50.70 S +168 71.04 49.20 S +169 63.50 45.30 S +171 125.12 49.80 Y diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REG01.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REG01.DAT new file mode 100755 index 000000000..d42b11733 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REG01.DAT @@ -0,0 +1,73 @@ + 1 -10.6286 0.000682 1.31053 1.72803 + 2 -9.8141 0.001544 1.12576 1.69034 + 3 -10.5724 0.000291 1.25470 1.76613 + 4 -10.9650 -0.003653 1.25533 1.94141 + 5 -10.6692 -0.000693 1.25498 1.80507 + 6 -10.5107 0.006287 1.44004 1.57335 + 7 -10.4421 0.001698 1.27074 1.74910 + 8 -10.3488 0.001844 1.23315 1.75488 + 9 -10.3995 0.002362 1.26581 1.73380 + 11 -10.6241 -0.006561 1.21713 1.93363 + 12 -9.9463 -0.001010 0.96341 1.94350 + 13 -9.5405 0.008579 1.16296 1.51958 + 14 -9.8651 0.002352 1.07540 1.75452 + 15 -9.4505 0.012086 1.18894 1.44311 + 16 -10.0339 0.000109 0.96400 1.94357 + 17 -9.4532 0.015702 1.18150 1.41474 + 18 -9.7351 0.001575 1.12220 1.67586 + 19 -10.3211 -0.002588 1.24787 1.77874 + 20 -9.2795 0.002170 1.16660 1.48084 + 21 -9.2617 0.003871 1.11608 1.49858 + 22 -9.5165 -0.000006 1.09432 1.63001 + 23 -9.4093 0.003556 0.89445 1.74306 + 24 -9.1143 0.005495 1.03391 1.52972 + 25 -10.8560 -0.002230 1.50765 1.69992 + 26 -11.0295 0.019049 1.72878 1.36018 + 27 -11.8340 -0.004877 1.71170 1.80893 + 28 -10.6139 0.005521 1.42476 1.61899 + 29 -12.4982 -0.028084 1.62433 2.26863 + 30 -9.9882 0.000346 1.12050 1.72938 + 31 -10.2959 0.001506 1.25955 1.66706 + 32 -10.1057 0.003780 1.36197 1.50676 + 33 -9.9049 0.005008 1.18210 1.59762 + 34 -9.8900 0.005188 1.29282 1.48285 + 35 -9.9350 0.003582 1.16387 1.63704 + 36 -10.2684 0.000383 1.19845 1.73664 + 37 -10.3153 -0.001677 1.24267 1.76517 + 38 -10.0361 0.004167 1.06935 1.78009 + 39 -10.3896 -0.002263 1.12891 1.88555 + 40 -10.4020 0.000332 1.05513 1.93773 + 41 -10.5190 -0.006602 0.99808 2.07149 + 42 -9.9101 0.005024 1.09644 1.71633 + 43 -9.6267 0.019060 1.49367 1.15633 + 44 -10.3164 -0.003982 1.08602 1.88229 + 45 -10.3677 0.000901 1.30086 1.65806 + 46 -10.2591 -0.005265 1.13507 1.83215 + 47 -10.0123 -0.000333 1.10290 1.73875 + 48 -10.5829 0.007799 1.35886 1.64782 + 49 -9.8708 0.004690 1.25319 1.62063 + 50 -10.2652 -0.003014 1.26791 1.78808 + 51 -10.0837 0.002151 1.34004 1.59331 + 52 -10.2712 0.002507 1.50413 1.49997 + 53 -10.0580 0.001951 1.31271 1.61419 + 54 -10.3710 0.002989 1.29098 1.75190 + 55 -9.7406 0.011302 1.46536 1.31465 + 56 -9.7197 0.004728 1.23727 1.59015 + 57 -10.2861 -0.003396 1.24421 1.79596 + 58 -9.2302 0.013264 0.97658 1.63558 + 59 -10.0233 -0.000664 1.05892 1.85753 + 60 -10.0460 -0.001129 1.07435 1.85152 + 61 -9.9939 0.001282 1.12570 1.76291 + 62 -10.2685 0.004250 1.46237 1.49344 + 63 -10.0706 0.008450 1.28149 1.55481 + 64 -10.0128 0.007050 1.21513 1.64246 + 65 -10.0549 0.001599 1.24072 1.65719 + 66 -10.3818 -0.000956 1.28646 1.72744 + 67 -9.8178 0.001713 1.13475 1.69013 + 68 -10.0070 -0.000568 1.20779 1.69622 + 69 -9.9945 0.001187 1.10210 1.77633 + 70 -10.1551 0.000229 1.26023 1.68588 + 71 -9.9413 0.005360 1.19960 1.62700 + 72 -10.1155 0.000389 1.19653 1.72545 + 73 -9.4597 0.014832 1.19403 1.40691 + 74 -9.8363 0.000320 1.11007 1.73525 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA25.coe b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA25.coe new file mode 100755 index 000000000..ece8aea42 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA25.coe @@ -0,0 +1,126 @@ +AT A0 1 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +AT A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +AT A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A3 1 -0.9042 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +AT A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +AT A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A0 1 1.7356 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +BG A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +BG A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A3 1 -0.9007 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +BG A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +BG A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A0 1 1.6941 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +BWBS A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +BWBS A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A3 1 -0.7167 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +BWBS A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +BWBS A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A0 1 2.1471 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +CDF A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +CDF A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A3 1 -0.9922 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +CDF A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +CDF A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A0 1 2.1471 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +CWH A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +CWH A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A3 1 -0.9922 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +CWH A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +CWH A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A0 1 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +ESSF A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +ESSF A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A3 1 -0.9042 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +ESSF A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +ESSF A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A0 1 1.8357 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +ICH A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +ICH A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A3 1 -0.8071 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +ICH A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +ICH A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A0 1 1.7356 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +IDF A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +IDF A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A3 1 -0.9007 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +IDF A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +IDF A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A0 1 2.2142 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +MH A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +MH A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A3 1 -0.9827 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +MH A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +MH A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A0 1 1.9822 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +MS A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +MS A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A3 1 -0.9479 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +MS A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +MS A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A0 1 1.7356 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +PP A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +PP A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A3 1 -0.9007 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +PP A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +PP A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A0 1 1.6446 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +SBPS A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +SBPS A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A3 1 -0.7543 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +SBPS A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +SBPS A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A0 1 1.8705 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +SBS A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +SBS A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A3 1 -0.8349 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +SBS A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +SBS A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A0 1 1.5986 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507 +SWB A1 1 0.2426 0.0785 -0.2586 0.1563 -0.0926 -0.2348 -0.1759 0.1785 -0.1060 -0.0926 -0.0167 -0.0167 -0.0167 -0.0167 -0.2900 0.1563 +SWB A2 0 10.1668 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A3 1 -0.6848 0.2870 -0.5904 0.4180 0.3348 -0.2167 0.2545 -0.0952 -0.0796 0.3348 -0.4364 -0.4364 -0.4364 -0.4364 -0.1087 0.4180 +SWB A4 1 -5.0012-50.0000 0.9571 1.0096-13.8394-50.0000 0.2937 -0.9292 -2.3651-13.8394 0.7249 0.7249 0.7249 0.7249 -1.1866 1.0096 +SWB A5 1 -0.0068 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A6 0 -0.0095 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A7 0 1.1938 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A8 0 -0.2749 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA2C.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA2C.DAT new file mode 100755 index 000000000..4a0d65de1 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA2C.DAT @@ -0,0 +1,16 @@ +AC 0.7531 0.0000 0.06545 -0.10137 REGBA2C.dat SEQ081 +AT 0.4571 0.0000 0.93841 -0.18128 Small Component BA +B -1.3504 9.5806 3.35173 -0.27311 (A2, 4F10) +C -4.3294 8.0078 3.34377 -0.26731 +D 0.7531 0.0000 0.06545 -0.10137 +E 0.5573 0.0000 0.31120 -0.14551 +F -64.3760 63.4929 7.44543 -0.28850 +H -18.0346 21.5178 2.25084 -0.20967 +L 0.8924 0.1000 0.64927 -0.19473 +MB 0.1183 0.0000 0.03896 -0.04348 +PA 0.0847 0.0000 0.00299 -0.00528 +PL -6.7746 7.1014 0.94846 -0.20617 +PW 0.3610 -0.1110 0.09293 -0.11041 +PY 1.3556 0.0000 0.12980 -0.14018 +S 0.6642 2.0522 0.75468 -0.19631 +Y 7.3034 0.0000 8.56296 -0.40000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAC.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAC.DAT new file mode 100755 index 000000000..01d6323e0 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAC.DAT @@ -0,0 +1,114 @@ +BA12 AC C -23.22790 12.60472 +BA17 AC C -3.45337 0.23954 +BA22 AC C -3.70342 0.20671 +BA12 AC I -22.86095 12.32735 +BA17 AC I -3.74863 0.26424 +BA22 AC I -3.56574 0.20635 +BA12 AT C -27.35336 14.74860 +BA17 AT C -5.87924 0.37909 +BA22 AT C -5.54057 0.28342 +BA12 AT I -25.70366 13.84400 +BA17 AT I -4.78384 0.31940 +BA22 AT I -4.62207 0.24390 +BA12 AT ICH -26.68771 14.38811 +BA17 AT ICH -5.27193 0.34145 +BA22 AT ICH -5.10793 0.26129 +BA12 AT IDF -24.68579 13.32113 +BA17 AT IDF -5.13847 0.33939 +BA22 AT IDF -4.32846 0.23001 +BA12 B C -15.03309 8.18929 +BA17 B C -1.47901 0.15283 +BA22 B C -1.51515 0.13565 +BA12 B I -16.02822 8.73071 +BA17 B I -2.45889 0.20800 +BA22 B I -2.21863 0.16774 +BA12 B ICH -15.14662 8.29071 +BA17 B ICH -2.52076 0.21038 +BA22 B ICH -1.91941 0.15093 +BA12 B IDF -16.11571 8.75903 +BA17 B IDF -3.21701 0.24894 +BA22 B IDF -2.36890 0.17733 +BA12 C C -13.88747 7.64000 +BA17 C C -1.11391 0.13742 +BA22 C C -0.52893 0.09390 +BA12 C I -12.57352 6.99816 +BA17 C I -1.41421 0.14988 +BA22 C I -0.73490 0.10763 +BA12 C ICH -15.97627 8.72503 +BA17 C ICH -2.27190 0.19217 +BA22 C ICH -1.18927 0.11871 +BA12 C IDF -17.14205 9.29490 +BA17 C IDF -1.90012 0.17220 +BA22 C IDF -1.74332 0.14325 +BA12 D -23.54138 12.72758 +BA17 D -4.42658 0.29914 +BA22 D -4.41937 0.23774 +BA12 E C -24.28744 13.12384 +BA17 E C -4.89631 0.32437 +BA22 E C -4.73535 0.25456 +BA12 E I -26.11939 14.05470 +BA17 E I -4.71898 0.31824 +BA22 E I -4.74094 0.24930 +BA12 F C -19.19175 10.41164 +BA17 F C -2.72435 0.21330 +BA22 F C -2.33377 0.16006 +BA12 F I -16.05282 8.76921 +BA17 F I -2.36579 0.19678 +BA22 F I -2.48897 0.17653 +BA12 F ICH -17.70729 9.65089 +BA17 F ICH -2.99928 0.23002 +BA22 F ICH -2.60966 0.17829 +BA12 F IDF -14.40759 7.93291 +BA17 F IDF -2.24311 0.19399 +BA22 F IDF -2.11565 0.16581 +BA12 H C -16.15279 8.81402 +BA17 H C -1.87138 0.17130 +BA22 H C -1.65691 0.13580 +BA12 H I -15.22363 8.31888 +BA17 H I -1.82657 0.16477 +BA22 H I -2.00282 0.15343 +BA12 L -23.02476 12.42275 +BA17 L -4.06268 0.28064 +BA22 L -3.29129 0.19387 +BA12 MB -16.24188 8.90624 +BA17 MB -2.26063 0.19507 +BA22 MB -3.22504 0.19034 +BA12 PA -19.59861 10.69280 +BA17 PA -3.11235 0.23545 +BA22 PA -3.53994 0.20557 +BA12 PL C -26.86345 14.48965 +BA17 PL C -5.05485 0.33163 +BA22 PL C -4.85961 0.25765 +BA12 PL I -26.72320 14.42563 +BA17 PL I -5.36428 0.35021 +BA22 PL I -5.20117 0.26871 +BA12 PL ICH -27.42946 14.80730 +BA17 PL ICH -5.81110 0.37412 +BA22 PL ICH -5.89085 0.29712 +BA12 PL IDF -25.66220 13.84609 +BA17 PL IDF -5.11343 0.34178 +BA22 PL IDF -4.69160 0.25135 +BA12 PW C -21.10051 11.40779 +BA17 PW C -3.38380 0.25667 +BA22 PW C -3.42192 0.19584 +BA12 PW I -17.07521 9.35699 +BA17 PW I -3.23149 0.24425 +BA22 PW I -2.98803 0.19608 +BA12 PY -18.41905 9.99933 +BA17 PY -2.51727 0.20120 +BA22 PY -2.29720 0.16396 +BA12 S C -16.96199 9.27783 +BA17 S C -1.98282 0.18094 +BA22 S C -1.60114 0.13130 +BA12 S I -20.52121 11.05856 +BA17 S I -3.05063 0.22987 +BA22 S I -2.62335 0.17269 +BA12 S ICH -19.24995 10.42365 +BA17 S ICH -2.91315 0.22598 +BA22 S ICH -2.65785 0.17124 +BA12 S IDF -16.83095 9.15036 +BA17 S IDF -2.33165 0.20050 +BA22 S IDF -2.13428 0.15840 +BA12 Y -13.83829 7.58769 +BA17 Y -0.71750 0.12206 +BA22 Y -1.05921 0.11910 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAV01.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAV01.COE new file mode 100755 index 000000000..7ae7eca8e --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAV01.COE @@ -0,0 +1,32 @@ +AC C 0.07962 6.60231 1.37998 +AC I 0.07962 6.60231 1.37998 +AT C 1.96175 8.00000 0.10636 +AT I 1.96175 8.00000 0.10636 +B C 0.12874 8.00000 1.26982 +B I 0.70932 7.63269 0.62545 +C C 0.37707 8.00000 1.10125 +C I 0.08657 5.24418 1.43720 +D C 0.07962 6.60231 1.37998 +D I 0.07962 6.60231 1.37998 +E C 1.96175 8.00000 0.10636 +E I 1.96175 8.00000 0.10636 +F C 0.17560 8.00000 1.27558 +F I 0.20543 0.00000 1.00683 +H C 0.43898 8.00000 0.96435 +H I 0.01149 0.00000 1.95333 +L C 0.01649 0.00000 1.61767 +L I 0.01649 0.00000 1.61767 +MB C 0.07962 6.60231 1.37998 +MB I 0.07962 6.60231 1.37998 +PA C 0.61692 7.90662 0.56527 +PA I 0.61692 7.90662 0.56527 +PL C 0.61692 7.90662 0.56527 +PL I 0.61692 7.90662 0.56527 +PW C 0.65006 8.00000 0.58403 +PW I 0.65006 8.00000 0.58403 +PY C 0.65006 8.00000 0.58403 +PY I 0.65006 8.00000 0.58403 +S C 0.00968 7.82553 2.00000 +S I 0.00968 7.82553 2.00000 +Y C 0.37707 8.00000 1.10125 +Y I 0.08657 5.24418 1.43720 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBREAK.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBREAK.COE new file mode 100755 index 000000000..328811150 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBREAK.COE @@ -0,0 +1,25 @@ + 1 3.3922 0.8370 5.00 7.00 + 2 4.0000 0.0000 4.00 4.00 + 3 4.0000 0.0000 4.00 4.00 + 4 1.8808 0.0422 2.00 3.00 + 5 2.2269 0.7506 4.00 6.00 + 6 2.1087 1.0934 5.00 7.00 +10 -0.7153 2.0108 4.00 8.00 +12 2.8953 0.5462 4.00 5.00 +13 5.0000 0.0000 5.00 5.00 +14 4.0000 0.0000 4.00 4.00 +15 1.8561 0.6409 4.00 5.00 +16 1.1064 0.2951 2.00 3.00 +17 0.0206 1.2904 4.00 6.00 +19 2.2151 0.2752 3.00 4.00 +20 1.9115 0.3526 3.00 4.00 +21 4.1616 0.2036 4.00 5.00 +22 4.8321 0.0426 4.00 5.00 +23 2.0000 0.0000 2.00 2.00 +24 2.0000 0.0000 2.00 2.00 +25 2.3797 0.5529 4.00 5.00 +26 2.0000 0.0000 2.00 2.00 +27 2.0000 0.0000 2.00 2.00 +28 1.5279 0.7104 4.00 5.00 +30 2.0000 0.0000 2.00 2.00 +31 6.2571 0.1706 5.00 7.00 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ18.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ18.COE new file mode 100755 index 000000000..8191662b4 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ18.COE @@ -0,0 +1,98 @@ +AT A0 1 7.5517 0.2539 2.6562 2.9483 0.2250 2.9483 2.0156 2.9483 2.4208 0.2250 1.5748 1.5748 1.5748 1.5748 -0.0517 2.9483 +AT A1 1 7.3400 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +AT A2 1 -1.1094 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +AT A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +AT A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +AT A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A0 1 7.5517 0.2022 2.6044 2.8966 0.1733 2.8966 1.9639 2.8966 2.3691 0.1733 1.5231 1.5231 1.5231 1.5231 -0.1034 2.8966 +BG A1 1 7.0522 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +BG A2 1 -1.0512 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +BG A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +BG A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +BG A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A0 1 7.5517 0.1505 2.5527 2.8448 0.1216 2.8448 1.9122 2.8448 2.3174 0.1216 1.4714 1.4714 1.4714 1.4714 -0.1552 2.8448 +BWBS A1 1 6.9085 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +BWBS A2 1 -1.0190 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +BWBS A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +BWBS A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +BWBS A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A0 1 7.5517 0.0988 2.5010 2.7931 0.0699 2.7931 1.8605 2.7931 2.2656 0.0699 1.4196 1.4196 1.4196 1.4196 -0.2069 2.7931 +CDF A1 1 7.6829 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +CDF A2 1 -1.1663 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +CDF A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +CDF A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +CDF A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A0 1 7.5517 0.0471 2.4493 2.7414 0.0182 2.7414 1.8088 2.7414 2.2139 0.0182 1.3679 1.3679 1.3679 1.3679 -0.2586 2.7414 +CWH A1 1 7.6829 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +CWH A2 1 -1.1663 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +CWH A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +CWH A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +CWH A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A0 1 7.5517 -0.0047 2.3976 2.6897 -0.0336 2.6897 1.7571 2.6897 2.1622 -0.0336 1.3162 1.3162 1.3162 1.3162 -0.3103 2.6897 +ESSF A1 1 7.3400 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +ESSF A2 1 -1.1094 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +ESSF A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +ESSF A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +ESSF A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A0 1 7.5517 -0.0564 2.3459 2.6380 -0.0853 2.6380 1.7053 2.6380 2.1105 -0.0853 1.2645 1.2645 1.2645 1.2645 -0.3620 2.6380 +ICH A1 1 7.2458 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +ICH A2 1 -1.1001 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +ICH A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +ICH A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +ICH A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A0 1 7.5517 -0.1081 2.2941 2.5863 -0.1370 2.5863 1.6536 2.5863 2.0588 -0.1370 1.2128 1.2128 1.2128 1.2128 -0.4137 2.5863 +IDF A1 1 7.0522 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +IDF A2 1 -1.0512 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +IDF A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +IDF A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +IDF A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A0 1 7.5517 -0.1598 2.2424 2.5345 -0.1887 2.5345 1.6019 2.5345 2.0071 -0.1887 1.1611 1.1611 1.1611 1.1611 -0.4655 2.5345 +MH A1 1 7.6829 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +MH A2 1 -1.1663 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +MH A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +MH A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +MH A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A0 1 7.5517 -0.2115 2.1907 2.4828 -0.2404 2.4828 1.5502 2.4828 1.9553 -0.2404 1.1093 1.1093 1.1093 1.1093 -0.5172 2.4828 +MS A1 1 7.2709 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +MS A2 1 -1.1087 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +MS A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +MS A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +MS A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A0 1 7.5517 -0.2633 2.1390 2.4311 -0.2921 2.4311 1.4985 2.4311 1.9036 -0.2921 1.0576 1.0576 1.0576 1.0576 -0.5689 2.4311 +PP A1 1 7.0522 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +PP A2 1 -1.0512 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +PP A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +PP A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +PP A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A0 1 7.5517 -0.3150 2.0873 2.3794 -0.3439 2.3794 1.4468 2.3794 1.8519 -0.3439 1.0059 1.0059 1.0059 1.0059 -0.6206 2.3794 +SBPS A1 1 7.2852 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +SBPS A2 1 -1.1090 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +SBPS A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +SBPS A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +SBPS A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A0 1 7.5517 -0.3667 2.0356 2.3277 -0.3956 2.3277 1.3950 2.3277 1.8002 -0.3956 0.9542 0.9542 0.9542 0.9542 -0.6723 2.3277 +SBS A1 1 7.2852 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +SBS A2 1 -1.1090 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +SBS A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +SBS A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +SBS A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A0 1 7.5517 -0.4184 1.9838 2.2760 -0.4473 2.2760 1.3433 2.2760 1.7485 -0.4473 0.9025 0.9025 0.9025 0.9025 -0.7240 2.2760 +SWB A1 1 6.9085 -0.6062 -7.2314 -9.0245 -3.4425 -6.9545 -6.7439 -7.8727 -6.3736 -3.4425 -7.3253 -7.3253 -7.2169 -6.8271 -5.5511 -9.6424 +SWB A2 1 -1.0190 -0.0162 1.1736 1.6980 0.6249 1.2078 1.1587 1.3483 1.0839 0.6249 1.1851 1.1851 1.1851 1.1851 0.9226 1.7548 +SWB A3 1 -0.6166 -0.9531 1.9092 1.8803 0.5611 1.2576 1.2793 1.2937 0.8399 0.5611 1.6687 1.6687 1.6687 1.6687 1.2336 1.8803 +SWB A4 1 0.3332 0.2073 -0.3430 -0.3785 -0.0933 -0.2746 -0.2565 -0.2461 -0.1966 -0.0933 -0.2876 -0.2876 -0.2876 -0.2876 -0.2473 -0.3785 +SWB A5 0 -0.0043 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A6 0 0.5011 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ24.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ24.COE new file mode 100755 index 000000000..4127e41f6 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ24.COE @@ -0,0 +1,112 @@ +AT A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +AT A1 1 -0.3582 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +AT A2 1 -3.0484 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +AT A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +AT A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +AT A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +BG A1 1 -0.6314 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +BG A2 1 -2.5846 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +BG A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +BG A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +BG A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +BWBS A1 1 -5.4595 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +BWBS A2 1 -1.5826 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +BWBS A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +BWBS A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +BWBS A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +CDF A1 1 -0.0352 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +CDF A2 1 -3.7726 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +CDF A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +CDF A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +CDF A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +CWH A1 1 -0.0352 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +CWH A2 1 -3.7726 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +CWH A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +CWH A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +CWH A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +ESSF A1 1 -0.3582 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +ESSF A2 1 -3.0484 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +ESSF A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +ESSF A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +ESSF A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +ICH A1 1 -0.3160 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +ICH A2 1 -3.4920 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +ICH A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +ICH A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +ICH A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +IDF A1 1 -0.6314 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +IDF A2 1 -2.5846 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +IDF A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +IDF A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +IDF A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +MH A1 1 -0.0352 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +MH A2 1 -3.7726 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +MH A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +MH A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +MH A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +MS A1 1 -0.3092 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +MS A2 1 -3.9188 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +MS A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +MS A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +MS A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +PP A1 1 -0.6314 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +PP A2 1 -2.5846 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +PP A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +PP A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +PP A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +SBPS A1 1 -0.3298 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +SBPS A2 1 -3.4706 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +SBPS A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +SBPS A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +SBPS A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +SBS A1 1 -0.3298 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +SBS A2 1 -3.4706 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +SBS A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +SBS A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +SBS A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A0 1 9.7616 -2.2616 0.4138 0.7384 0.7384 0.1231 -2.2616 -1.5554 0.7384 0.7384 -2.2616 -2.2616 -2.2616 -2.2616 -1.0920 0.7384 +SWB A1 1 -5.4595 -0.2858 -0.4855 -0.4046 -1.1322 -0.3402 0.5798 -1.5858 0.4085 -1.1322 -0.1419 -0.1419 0.0161 0.6860 -0.1481 0.2390 +SWB A2 1 -1.5826 -0.4332 -0.9026 1.8043 0.5601 0.0212 0.6316 -0.2471 -1.6785 0.5601 -0.0885 -0.0885 -0.0885 -0.0885 -0.4111 -0.3281 +SWB A3 1 -0.0756 0.0218 -0.0891 -0.1065 0.0862 0.1613 -0.5647 -0.0008 -0.6702 0.0862 -0.1246 -0.1246 -0.1246 -0.1246 -0.0068 -0.1065 +SWB A4 1 -3.0895 0.0698 0.3189 -0.0364 0.4633 -1.9677 0.4474 0.8559 0.5461 0.4633 -0.0252 -0.0252 -0.0252 -0.0252 -0.2546 -0.0364 +SWB A5 0 4.5844 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A6 0 0.4731 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A7 0 -0.0048 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ26.coe b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ26.coe new file mode 100755 index 000000000..b787c47af --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ26.coe @@ -0,0 +1,112 @@ +AT A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +AT A1 1 -0.5579 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +AT A2 1 -1.9421 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +AT A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +AT A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +AT A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +BG A1 1 -0.5819 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +BG A2 1 -1.9639 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +BG A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +BG A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +BG A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +BWBS A1 1 -0.2602 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +BWBS A2 1 -2.6067 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +BWBS A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +BWBS A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +BWBS A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +CDF A1 1 -0.2602 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +CDF A2 1 -2.1848 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +CDF A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +CDF A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +CDF A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +CWH A1 1 -0.2602 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +CWH A2 1 -2.1848 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +CWH A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +CWH A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +CWH A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +ESSF A1 1 -0.5579 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +ESSF A2 1 -1.9421 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +ESSF A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +ESSF A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +ESSF A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +ICH A1 1 -0.5373 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +ICH A2 1 -1.9757 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +ICH A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +ICH A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +ICH A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +IDF A1 1 -0.5819 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +IDF A2 1 -1.9639 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +IDF A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +IDF A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +IDF A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +MH A1 1 -0.2602 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +MH A2 1 -2.1848 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +MH A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +MH A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +MH A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +MS A1 1 -0.5115 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +MS A2 1 -2.0933 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +MS A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +MS A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +MS A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +PP A1 1 -0.5819 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +PP A2 1 -1.9639 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +PP A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +PP A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +PP A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +SBPS A1 1 -0.4485 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +SBPS A2 1 -2.1371 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +SBPS A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +SBPS A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +SBPS A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +SBS A1 1 -0.4485 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +SBS A2 1 -2.1371 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +SBS A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +SBS A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +SBS A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A0 1 6.6190 0.0000 0.0000 3.5641 3.5641 3.5641 0.0000 0.0000 0.0000 3.5641 0.0000 0.0000 0.0000 0.0000 1.9878 3.5641 +SWB A1 1 -0.2602 -0.2072 0.4604 -0.7289 -0.6717 -0.3156 0.0765 -0.0258 0.3613 0.5623 0.4186 0.0710 0.0937 0.6017 -0.1564 0.2494 +SWB A2 1 -2.6067 -0.3403 -0.1902 0.2855 0.5074 -2.4631 -0.2966 0.0664 0.1622 0.5074 -0.3797 -0.3797 -0.3797 -0.3797 -0.6217 -1.2406 +SWB A3 1 -0.7092 0.0685 -0.2843 0.0370 -0.0829 0.3200 -0.1497 -0.1226 -0.5799 -0.0829 -0.1145 -0.1145 -0.1145 -0.1145 0.0628 0.0370 +SWB A4 1 -5.2290 -0.5314 -5.1765 -7.7054-22.4879 0.7141 0.7571-16.8311 0.7041-22.4879 -0.5713 -0.5713 -0.5713 -0.5713 -1.6500 -7.7054 +SWB A5 0 4.8473 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A6 0 0.2629 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A7 0 -0.0062 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ4C.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ4C.DAT new file mode 100755 index 000000000..25aabe2e7 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ4C.DAT @@ -0,0 +1,16 @@ +AC -0.08066 0.02808 REGDQ4C.dat SEQ082 +AT 0.46547 0.06338 (A2 2f10.5) +B -0.33485 0.02029 Small Component DQ +C -0.45758 0.03221 +D -0.08066 0.02808 +E -0.42814 0.07656 +F -0.54705 0.04008 +H -0.45326 0.03212 +L 1.06929 0.00000 +MB -1.29653 0.06417 +PA 1.47874 0.03000 +PL -0.42357 0.05798 +PW -0.82376 0.10926 +PY -0.55688 0.03000 +S -0.43631 0.03576 +Y -0.51697 0.03178 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQC.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQC.DAT new file mode 100755 index 000000000..85bd56cc4 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQC.DAT @@ -0,0 +1,152 @@ +07.5 to 12.5 AC C 2.94768 -0.99977 1.00000 0.00000 +07.5 to 12.5 AC I 2.84794 -1.64157 1.00000 0.00000 +07.5 to 12.5 AT C 3.63113 -1.16547 1.00000 0.00000 +07.5 to 12.5 AT I 3.07541 -1.29300 1.00000 0.00000 +07.5 to 12.5 AT ICH 3.16773 -1.29927 1.00000 0.00000 +07.5 to 12.5 AT IDF 2.91977 -1.57828 1.14388 0.00000 +07.5 to 12.5 B C 2.55947 -1.57989 1.15066 0.00000 +07.5 to 12.5 B I 2.55722 -1.50320 1.00000 0.00000 +07.5 to 12.5 B ICH 2.61567 -1.52670 1.00000 0.00000 +07.5 to 12.5 B IDF 2.63772 -1.58233 1.00000 0.00000 +07.5 to 12.5 C C 2.62796 -1.33160 1.00000 0.00000 +07.5 to 12.5 C I 2.51093 -2.08920 1.00000 0.00000 +07.5 to 12.5 C ICH 2.00000 -5.18669 1.00000 0.00000 +07.5 to 12.5 C IDF 2.58772 -1.24362 1.00000 0.00000 +07.5 to 12.5 D 3.00321 -1.46471 1.00000 0.00000 +07.5 to 12.5 E C 3.03616 -1.67129 1.33986 0.00000 +07.5 to 12.5 E I 3.03867 -1.41930 1.00000 0.00000 +07.5 to 12.5 F C 2.82073 -1.10199 1.00000 0.00000 +07.5 to 12.5 F I 2.60267 -1.52715 1.00000 0.00000 +07.5 to 12.5 F ICH 2.70157 -1.25268 1.00000 0.00000 +07.5 to 12.5 F IDF 2.45041 -1.54571 1.13439 0.00000 +07.5 to 12.5 H C 2.68609 -1.19151 1.00000 0.00000 +07.5 to 12.5 H I 2.00000 -3.39142 1.00000 0.00000 +07.5 to 12.5 L 2.91940 -1.54346 1.16718 0.00000 +07.5 to 12.5 MB 2.79862 -1.58506 1.00000 0.00000 +07.5 to 12.5 PA 2.71924 -1.26726 1.00000 0.00000 +07.5 to 12.5 PL C 2.88420 -1.46711 1.06643 0.00000 +07.5 to 12.5 PL I 2.96993 -1.34558 1.00000 0.00000 +07.5 to 12.5 PL ICH 3.15490 -1.29599 1.00000 0.00000 +07.5 to 12.5 PL IDF 2.75284 -1.51613 1.07579 0.00000 +07.5 to 12.5 PW C 2.84841 -3.17384 2.83442 0.00000 +07.5 to 12.5 PW I 2.75690 -1.49519 1.00000 0.00000 +07.5 to 12.5 PY 2.74495 -1.29349 1.00000 0.00000 +07.5 to 12.5 S C 2.77415 -1.16681 1.00000 0.00000 +07.5 to 12.5 S I 2.75926 -1.44927 1.00000 0.00000 +07.5 to 12.5 S ICH 2.81063 -1.49717 1.00000 0.00000 +07.5 to 12.5 S IDF 2.61108 -1.52554 1.00000 0.00000 +07.5 to 12.5 Y 2.67013 -1.90495 1.52419 0.00000 +12.5 to 17.5 AC C 0.21357 -3.81109 -3.77355 0.00000 +12.5 to 17.5 AC I 0.32155 -5.10313 -3.67071 0.00000 +12.5 to 17.5 AT C 1.60072 -3.57908 -0.89876 0.00000 +12.5 to 17.5 AT I 0.61997 -3.00694 -2.14037 0.00000 +12.5 to 17.5 AT ICH 0.79376 -3.31801 -1.94705 0.00000 +12.5 to 17.5 AT IDF 0.76270 -3.14065 -1.94071 0.00000 +12.5 to 17.5 B C -0.01797 -2.29965 -3.87948 0.00000 +12.5 to 17.5 B I -0.00870 -4.10188 -5.00799 0.00000 +12.5 to 17.5 B ICH 0.03444 -4.84398 -5.19250 0.00000 +12.5 to 17.5 B IDF 0.28385 -2.85486 -2.58430 0.00000 +12.5 to 17.5 C C -0.02583 -3.12718 -4.55609 0.00000 +12.5 to 17.5 C I -0.03229 -3.56010 -3.98904 0.00000 +12.5 to 17.5 C ICH 0.00604 -3.54970 -4.44579 0.00000 +12.5 to 17.5 C IDF 0.09497 -1.34795 -2.21021 0.00000 +12.5 to 17.5 D 0.61778 -2.79251 -2.07545 0.00000 +12.5 to 17.5 E C 0.51933 -3.65882 -2.72820 0.00000 +12.5 to 17.5 E I 0.54714 -3.43309 -2.52990 0.00000 +12.5 to 17.5 F C 0.18968 -2.25813 -2.88487 0.00000 +12.5 to 17.5 F I 0.03288 -4.49433 -4.96693 0.00000 +12.5 to 17.5 F ICH 0.20225 -1.77368 -2.30486 0.00000 +12.5 to 17.5 F IDF -0.05271 -3.33749 -4.75265 0.00000 +12.5 to 17.5 H C 0.01704 -2.35234 -3.87038 0.00000 +12.5 to 17.5 H I -0.02027 -3.18824 -4.88139 0.00000 +12.5 to 17.5 L 0.40604 -2.79216 -2.42663 0.00000 +12.5 to 17.5 MB 0.24542 -5.47933 -4.44171 0.00000 +12.5 to 17.5 PA 0.49563 -2.39714 -1.76858 0.00000 +12.5 to 17.5 PL C 0.43189 -3.52943 -2.69352 0.00000 +12.5 to 17.5 PL I 0.61615 -3.24780 -2.13283 0.00000 +12.5 to 17.5 PL ICH 0.52786 -3.62765 -2.53813 0.00000 +12.5 to 17.5 PL IDF 0.51261 -3.02161 -2.19688 0.00000 +12.5 to 17.5 PW C 0.13879 -9.02538 -5.30226 0.00000 +12.5 to 17.5 PW I 0.21216 -4.15326 -3.77871 0.00000 +12.5 to 17.5 PY 0.07452 -2.24847 -3.41217 0.00000 +12.5 to 17.5 S C 0.14046 -3.07473 -3.52452 0.00000 +12.5 to 17.5 S I 0.11386 -3.45837 -3.94680 0.00000 +12.5 to 17.5 S ICH 0.16514 -3.01722 -3.44155 0.00000 +12.5 to 17.5 S IDF 0.09881 -4.11833 -4.32094 0.00000 +12.5 to 17.5 Y 0.07886 -2.58611 -3.12890 0.00000 +17.5 to 22.5 AC C 1.37756 -2.59836 -0.55955 0.00000 +17.5 to 22.5 AC I 0.62425 -2.74627 -1.45192 0.00000 +17.5 to 22.5 AT C 0.37402 -10.53067 -3.48494 0.00000 +17.5 to 22.5 AT I 2.72412 -4.37156 -0.47042 0.00000 +17.5 to 22.5 AT ICH 13.09097 -14.34563 -0.08319 0.00000 +17.5 to 22.5 AT IDF 16.67721 -18.05676 -0.07383 0.00000 +17.5 to 22.5 B C -0.02824 -3.36291 -3.74114 0.00000 +17.5 to 22.5 B I 0.10807 -2.17008 -2.59999 0.00000 +17.5 to 22.5 B ICH 0.05726 -4.55194 -4.03302 0.00000 +17.5 to 22.5 B IDF 6.36368 -7.39820 -0.13272 0.00000 +17.5 to 22.5 C C 0.03442 -3.02781 -3.42144 0.00000 +17.5 to 22.5 C I -0.05597 -71.24195 -9.18003 0.00000 +17.5 to 22.5 C ICH 0.04782 -2.61411 -3.15794 0.00000 +17.5 to 22.5 C IDF 0.24611 -1.52542 -1.73470 0.00000 +17.5 to 22.5 D 1.12247 -3.20713 -1.01526 0.00000 +17.5 to 22.5 E C 0.58955 -2.35228 -1.19894 0.00000 +17.5 to 22.5 E I 2.54222 -4.38854 -0.55256 0.00000 +17.5 to 22.5 F C 0.24603 -2.01511 -1.88109 0.00000 +17.5 to 22.5 F I 0.08231 -4.24080 -3.72605 0.00000 +17.5 to 22.5 F ICH 0.20837 -2.22176 -2.14442 0.00000 +17.5 to 22.5 F IDF 0.08708 -1.70258 -2.32250 0.00000 +17.5 to 22.5 H C -0.00430 -3.22468 -3.67287 0.00000 +17.5 to 22.5 H I -0.03432 -4.91183 -4.47489 0.00000 +17.5 to 22.5 L 0.43562 -2.44456 -1.66013 0.00000 +17.5 to 22.5 MB 0.18235 -6.93096 -3.61541 0.00000 +17.5 to 22.5 PA 1.75685 -3.09131 -0.60146 0.00000 +17.5 to 22.5 PL C 0.83009 -3.27768 -1.37211 0.00000 +17.5 to 22.5 PL I 1.36510 -3.83917 -1.05647 0.00000 +17.5 to 22.5 PL ICH 2.13315 -4.58474 -0.78682 0.00000 +17.5 to 22.5 PL IDF 1.03567 -3.06791 -1.09990 0.00000 +17.5 to 22.5 PW C 0.33065 -8.24017 -3.49965 0.00000 +17.5 to 22.5 PW I 0.70591 -2.14478 -1.04428 0.00000 +17.5 to 22.5 PY 0.00123 -3.27216 -3.85773 0.00000 +17.5 to 22.5 S C 0.03680 -3.87340 -3.73026 0.00000 +17.5 to 22.5 S I 0.19409 -2.86752 -2.46264 0.00000 +17.5 to 22.5 S ICH 0.22422 -4.02303 -2.92386 0.00000 +17.5 to 22.5 S IDF 0.23098 -2.33926 -2.21762 0.00000 +17.5 to 22.5 Y 1.12393 -1.47571 -0.25839 0.00000 +22.5 to inf. AC C 15.00000 0.52178 -4.45782 0.68969 +22.5 to inf. AC I 39.60397 1.00672 -3.10693 0.50000 +22.5 to inf. AT C 100.00000 0.12892 -0.06796 1.04232 +22.5 to inf. AT I 27.20069 0.03066 -0.92432 1.37518 +22.5 to inf. AT ICH 15.40229 1.10543 -6.54631 0.60336 +22.5 to inf. AT IDF 25.20030 0.83791 -4.63524 0.62538 +22.5 to inf. B C 23.65230 0.00547 -1.18372 1.41327 +22.5 to inf. B I 23.23886 0.02484 -0.83888 1.11682 +22.5 to inf. B ICH 16.35080 0.05141 -1.19796 0.81995 +22.5 to inf. B IDF 100.00000 0.17372 0.74928 0.68165 +22.5 to inf. C C 15.00000 0.18964 -2.51612 0.50000 +22.5 to inf. C I 15.65050 0.13206 -2.12437 0.57958 +22.5 to inf. C ICH 16.38386 0.05461 -1.89519 0.69632 +22.5 to inf. C IDF 15.00000 0.06383 -1.73974 0.50000 +22.5 to inf. D 34.31064 0.16500 -1.64407 0.96321 +22.5 to inf. E C 18.34650 0.29883 -3.41061 0.84577 +22.5 to inf. E I 17.83268 0.61478 -4.43228 0.68140 +22.5 to inf. F C 100.00000 0.50504 0.07244 0.50000 +22.5 to inf. F I 15.00000 1.00941 -5.87651 0.50000 +22.5 to inf. F ICH 21.29861 0.81680 -3.46942 0.50000 +22.5 to inf. F IDF 16.29815 0.34704 -3.51598 0.61759 +22.5 to inf. H C 37.10071 0.02334 0.80899 0.50000 +22.5 to inf. H I 15.11470 0.01067 -2.87614 1.18332 +22.5 to inf. L 100.00000 0.60305 -0.24398 0.50000 +22.5 to inf. MB 22.57442 0.03156 -0.59557 1.08954 +22.5 to inf. PA 15.00000 0.06828 -2.89577 1.21283 +22.5 to inf. PL C 24.36040 0.11065 -1.63720 1.02919 +22.5 to inf. PL I 100.00000 0.00299 1.44262 2.00000 +22.5 to inf. PL ICH 49.06109 0.03654 0.00771 1.32690 +22.5 to inf. PL IDF 27.30913 0.02771 -0.89270 1.40320 +22.5 to inf. PW C 15.00000 1.24589 -6.09804 0.50000 +22.5 to inf. PW I 16.57139 1.16418 -6.68646 0.56150 +22.5 to inf. PY 17.62779 0.73315 -3.51964 0.50000 +22.5 to inf. S C 15.00000 0.35277 -1.40654 0.50000 +22.5 to inf. S I 100.00000 0.38176 0.54687 0.50000 +22.5 to inf. S ICH 64.96105 0.07512 1.28314 0.72813 +22.5 to inf. S IDF 15.45513 0.38618 -3.05808 0.61088 +22.5 to inf. Y 47.85577 0.04422 0.53112 0.78542 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQI04.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQI04.COE new file mode 100755 index 000000000..0b5c726b4 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQI04.COE @@ -0,0 +1,3 @@ +A0 1 -0.65484 -0.48275 -0.75134 0.04482 -0.31195 -0.53012 -0.12645 -0.64668 -0.43538 -0.31134 -0.03435 -0.27833 -0.32476 0.10819 -0.38103 -0.12273 +A1 2 2.26389 0.19886 -0.25704 0.18579 -0.38547 -0.14115 -0.10146 0.09067 0.54304 -0.02947 0.08473 -0.39934 0.02206 -0.18235 0.01411 -0.21683 +A2 0 0.23162 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQL2.coe b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQL2.coe new file mode 100755 index 000000000..952a6472f --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQL2.coe @@ -0,0 +1,15 @@ + 1 0.30997 -0.00717 -0.01070 0.38206 0.01038 0.00000 0.08 0.70 + 2 0.09353 -0.00123 0.00000 0.15000 0.01075 -0.00297 0.03 0.30 + 3 0.00167 0.03096 -0.09803 0.15076 0.04556 -0.10159 -0.10 0.68 + 4 0.00156 0.01161 -0.01494 0.17493 0.03175 -0.04000 0.02 0.80 + 5 0.09135 0.00402 -0.00909 0.34182 0.01547 -0.02321 0.10 0.60 + 6 0.08063 0.01063 -0.02029 0.34819 0.01763 -0.02567 0.13 0.69 + 7 0.02377 0.00806 -0.03765 0.15000 0.00940 0.00000 0.03 0.36 + 8 0.06831 -0.00084 0.00000 0.15000 0.00534 0.00000 0.04 0.25 + 9 -0.30195 0.04944 -0.16461 0.15000 0.01566 0.00000 0.00 0.61 + 10 0.19592 0.01100 -0.03747 0.81072 0.00092 -0.00051 -0.40 0.94 + 23 -0.02628 0.02280 -0.10888 0.15000 0.00808 0.00000 0.06 0.31 + 24 -0.53351 0.07497 -0.21404 0.15000 0.00802 0.00000 0.05 0.33 + 25 0.03206 0.00338 0.00000 0.15000 0.00760 0.00000 0.04 0.36 + 26 0.00757 0.00949 -0.03222 0.15000 0.00693 0.00000 0.05 0.34 + 30 0.08197 -0.00249 0.00000 0.15000 0.00949 0.00000 -0.05 0.38 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.COE new file mode 100755 index 000000000..b59dd5243 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.COE @@ -0,0 +1,302 @@ +AC AT C 1 0.86323 1.00505 +AC AT I 1 0.86323 1.00505 +AC B C 1 3.12163 0.68647 +AC B I 1 3.12163 0.68647 +AC C C 1 4.05529 0.64233 +AC C I 1 4.05529 0.64233 +AC D C 1 0.58303 1.24679 +AC D I 1 0.58303 1.24679 +AC E C 1 0.40814 1.36641 +AC E I 1 0.40814 1.36641 +AC F C 1 0.76405 1.06454 +AC F I 1 0.76405 1.06454 +AC H C 1 2.74196 0.74463 +AC H I 1 2.74196 0.74463 +AC L C 2 1.64419 0.84732 +AC L I 2 1.64419 0.84732 +AC PL C 1 0.78556 1.07104 +AC PL I 1 0.78556 1.07104 +AC S C 1 0.92684 1.01162 +AC S I 1 0.92684 1.01162 +AT AC C 1 1.49918 0.85644 +AT AC I 1 1.49918 0.85644 +AT B C 1 0.47209 1.21181 +AT B I 1 0.47209 1.21181 +AT C C 1 6.37377 0.44148 +AT C I 1 6.37377 0.44148 +AT E C 1 0.65425 1.17130 +AT E I 1 0.65425 1.17130 +AT F C 1 0.87028 0.96416 +AT F I 1 0.87028 0.96416 +AT H C 1 0.93026 1.03968 +AT H I 1 0.93026 1.03968 +AT L C 1 0.85410 0.99869 +AT L I 1 0.85410 0.99869 +AT PL C 1 0.93909 0.95258 +AT PL I 1 0.93909 0.95258 +AT PW C 1 1.78034 0.77778 +AT PW I 1 1.78034 0.77778 +AT PY C 2 3.13189 0.50000 +AT PY I 2 3.13189 0.50000 +AT S C 1 1.59468 0.81310 +AT S I 1 1.59468 0.81310 +B AC C 1 0.39238 1.15654 +B AC I 1 0.39238 1.15654 +B AT C 1 1.83289 0.71606 +B AT I 1 1.83289 0.71606 +B C C 1 4.52484 0.54029 +B C I 1 7.48807 0.36371 +B D C 2 2.09540 0.82901 +B D I 2 2.09540 0.82901 +B E C 1 0.34485 1.32555 +B E I 1 0.34485 1.32555 +B F C 1 0.50682 1.15930 +B F I 1 2.49118 0.61189 +B H C 1 0.91725 0.98671 +B H I 1 1.34358 0.88260 +B L C 1 1.21510 0.78817 +B L I 1 1.21510 0.78817 +B PA C 1 3.36258 0.49184 +B PA I 1 3.36258 0.49184 +B PL C 1 1.30902 0.81001 +B PL I 1 1.30902 0.81001 +B PW C 2 0.75737 1.03019 +B PW I 2 0.75737 1.03019 +B S C 1 1.55174 0.75747 +B S I 1 1.55174 0.75747 +B Y C 1 4.22705 0.51396 +B Y I 1 4.22705 0.51396 +C AC C 1 0.04697 1.74174 +C AC I 1 0.04697 1.74174 +C AT C 1 0.82964 0.91571 +C AT I 1 0.82964 0.91571 +C B C 1 0.34242 1.29388 +C B I 1 0.95643 0.92006 +C D C 1 1.54251 0.74713 +C D I 1 1.54251 0.74713 +C E C 1 0.82121 0.95885 +C E I 1 0.82121 0.95885 +C F C 1 0.52832 1.05183 +C F I 1 0.64717 0.95665 +C H C 1 0.32327 1.27513 +C H I 1 0.42749 1.20095 +C L C 1 0.26453 1.18053 +C L I 1 0.26453 1.18053 +C MB C 2 4.32723 0.50000 +C MB I 2 4.32723 0.50000 +C PL C 1 1.91186 0.61654 +C PL I 1 1.91186 0.61654 +C PW C 1 1.20744 0.79848 +C PW I 1 1.20744 0.79848 +C S C 1 0.41639 1.13663 +C S I 1 0.55704 1.02545 +C Y C 1 1.87226 0.76806 +C Y I 1 1.87226 0.76806 +D AC C 1 2.63278 0.59536 +D AC I 1 2.63278 0.59536 +D B C 2 3.35882 0.58940 +D B I 2 3.35882 0.58940 +D C C 1 11.01035 0.24242 +D C I 1 11.01035 0.24242 +D F C 1 2.45773 0.64968 +D F I 1 2.45773 0.64968 +D H C 1 3.14397 0.60767 +D H I 1 3.14397 0.60767 +D MB C 1 1.96186 0.76281 +D MB I 1 1.96186 0.76281 +D S C 1 3.28319 0.60447 +D S I 1 3.28319 0.60447 +E AC C 1 2.71368 0.59591 +E AC I 1 2.71368 0.59591 +E AT C 1 2.11716 0.67155 +E AT I 1 2.11716 0.67155 +E B C 1 2.42390 0.66104 +E B I 1 2.42390 0.66104 +E C C 1 10.45025 0.21251 +E C I 1 10.45025 0.21251 +E D C 2 1.39441 0.86705 +E D I 2 1.39441 0.86705 +E F C 1 1.78894 0.68831 +E F I 1 1.86622 0.69810 +E H C 1 2.05230 0.72352 +E H I 1 2.05230 0.72352 +E L C 1 2.07229 0.63827 +E L I 1 2.07229 0.63827 +E PL C 1 1.51326 0.77088 +E PL I 1 1.51326 0.77088 +E PW C 1 6.53431 0.32222 +E PW I 1 6.53431 0.32222 +E S C 1 2.39379 0.64081 +E S I 1 2.39379 0.64081 +F AC C 2 1.08057 0.92143 +F AC I 2 1.08057 0.92143 +F AT C 1 1.86649 0.79986 +F AT I 1 1.86649 0.79986 +F B C 1 1.13251 0.98388 +F B I 1 0.93740 1.03223 +F C C 1 2.09295 0.83624 +F C I 1 3.44643 0.68013 +F D C 1 0.70528 1.12793 +F D I 1 0.70528 1.12793 +F E C 1 0.58328 1.20011 +F E I 1 0.58328 1.20011 +F H C 1 0.91540 1.03714 +F H I 1 1.89880 0.82989 +F L C 1 0.77419 0.98311 +F L I 1 0.77419 0.98311 +F MB C 2 0.74911 1.15686 +F MB I 2 0.74911 1.15686 +F PL C 1 0.84096 1.01087 +F PL I 1 0.84096 1.01087 +F PW C 1 1.31677 0.88415 +F PW I 1 1.31677 0.88415 +F PY C 1 1.58380 0.80009 +F PY I 1 1.58380 0.80009 +F S C 1 1.10745 0.95685 +F S I 1 1.10745 0.95685 +H AC C 2 0.26235 1.25000 +H AC I 2 0.26235 1.25000 +H AT C 1 0.91289 0.92092 +H AT I 1 0.91289 0.92092 +H B C 1 0.81825 1.01430 +H B I 1 0.59192 1.05614 +H C C 1 1.36279 0.84395 +H C I 1 1.60411 0.81689 +H D C 1 1.29704 0.81596 +H D I 1 1.29704 0.81596 +H E C 1 0.90555 0.88893 +H E I 1 0.90555 0.88893 +H F C 1 0.83135 0.96205 +H F I 1 1.05316 0.83320 +H L C 1 0.34399 1.13158 +H L I 1 0.34399 1.13158 +H MB C 2 4.34835 0.50000 +H MB I 2 4.34835 0.50000 +H PL C 1 0.35260 1.19003 +H PL I 1 0.35260 1.19003 +H PW C 1 0.59436 1.00859 +H PW I 1 0.59436 1.00859 +H S C 1 1.20499 0.88005 +H S I 1 0.99925 0.86409 +H Y C 1 1.48954 0.81828 +H Y I 1 1.48954 0.81828 +L AT C 1 1.06152 1.00400 +L AT I 1 1.06152 1.00400 +L B C 1 0.93621 1.05092 +L B I 1 0.93621 1.05092 +L C C 1 5.33354 0.57469 +L C I 1 5.33354 0.57469 +L E C 2 2.70825 0.79073 +L E I 2 2.70825 0.79073 +L F C 1 1.38829 0.90582 +L F I 1 1.38829 0.90582 +L H C 1 2.91215 0.73627 +L H I 1 2.91215 0.73627 +L PL C 1 0.75839 1.08444 +L PL I 1 0.75839 1.08444 +L PW C 1 1.95726 0.79528 +L PW I 1 1.95726 0.79528 +L PY C 2 1.21900 0.95555 +L PY I 2 1.21900 0.95555 +L S C 1 0.96371 1.02369 +L S I 1 0.96371 1.02369 +MB C C 2 5.95178 0.50000 +MB C I 2 5.95178 0.50000 +MB D C 1 1.58476 0.82180 +MB D I 1 1.58476 0.82180 +MB F C 1 1.16823 0.87108 +MB F I 1 1.16823 0.87108 +MB H C 1 5.45304 0.46011 +MB H I 1 5.45304 0.46011 +PA B C 1 0.68053 1.04905 +PA B I 1 0.68053 1.04905 +PA PL C 1 0.51712 1.08953 +PA PL I 1 0.51712 1.08953 +PA S C 1 1.43630 0.78293 +PA S I 1 1.43630 0.78293 +PL AC C 1 0.64422 1.10963 +PL AC I 1 0.64422 1.10963 +PL AT C 1 1.73626 0.81230 +PL AT I 1 1.73626 0.81230 +PL B C 1 1.48204 0.85848 +PL B I 1 1.48204 0.85848 +PL C C 1 2.09056 0.70875 +PL C I 1 8.28804 0.37626 +PL E C 1 1.89996 0.83613 +PL E I 1 1.89996 0.83613 +PL F C 1 1.59203 0.79578 +PL F I 1 1.88678 0.75120 +PL H C 1 2.57727 0.68332 +PL H I 1 3.66402 0.58551 +PL L C 1 2.06195 0.70742 +PL L I 1 2.06195 0.70742 +PL PA C 1 2.20535 0.72447 +PL PA I 1 2.20535 0.72447 +PL PW C 1 3.26675 0.60023 +PL PW I 1 3.26675 0.60023 +PL PY C 2 0.93829 0.99702 +PL PY I 2 0.93829 0.99702 +PL S C 1 1.60433 0.82373 +PL S I 1 1.60433 0.82373 +PL Y C 1 3.85495 0.47621 +PL Y I 1 3.85495 0.47621 +PW AT C 1 0.83159 1.01958 +PW AT I 1 0.83159 1.01958 +PW B C 1 1.00314 0.99044 +PW B I 1 1.00314 0.99044 +PW C C 1 2.90526 0.74153 +PW C I 1 2.90526 0.74153 +PW E C 2 1.76883 0.88933 +PW E I 2 1.76883 0.88933 +PW F C 1 0.85725 1.04196 +PW F I 1 0.92584 1.00134 +PW H C 1 2.37224 0.79225 +PW H I 1 1.61188 0.91054 +PW L C 1 0.72605 1.04024 +PW L I 1 0.72605 1.04024 +PW PL C 1 0.78255 1.04413 +PW PL I 1 0.78255 1.04413 +PW S C 1 1.62489 0.86408 +PW S I 1 1.62489 0.86408 +PY F C 1 0.53286 1.17078 +PY F I 1 0.53286 1.17078 +PY L C 2 1.11678 0.96051 +PY L I 2 1.11678 0.96051 +PY PL C 1 0.60085 1.14092 +PY PL I 1 0.60085 1.14092 +S AC C 1 3.43701 0.58282 +S AC I 1 3.43701 0.58282 +S AT C 1 1.12066 0.90196 +S AT I 1 1.12066 0.90196 +S B C 1 0.99409 1.01064 +S B I 1 1.07434 0.97860 +S C C 1 1.13201 0.99333 +S C I 1 4.00382 0.62946 +S D C 1 0.49041 1.19691 +S D I 1 0.49041 1.19691 +S E C 1 0.23788 1.47593 +S E I 1 0.23788 1.47593 +S F C 1 0.58189 1.13370 +S F I 1 1.00868 0.93039 +S H C 1 0.63387 1.14191 +S H I 1 0.90214 1.06585 +S L C 1 0.38182 1.16825 +S L I 1 0.38182 1.16825 +S PA C 1 5.61504 0.41738 +S PA I 1 5.61504 0.41738 +S PL C 1 0.66557 1.06405 +S PL I 1 0.66557 1.06405 +S PW C 1 0.17165 1.41602 +S PW I 1 0.17165 1.41602 +S Y C 2 3.66722 0.65028 +S Y I 2 3.66722 0.65028 +Y B C 1 0.46189 1.16125 +Y B I 1 0.46189 1.16125 +Y C C 1 1.63994 0.78984 +Y C I 1 1.63994 0.78984 +Y F C 2 0.77694 0.97952 +Y F I 2 0.77694 0.97952 +Y H C 1 0.74856 1.06315 +Y H I 1 0.74856 1.06315 +Y S C 2 4.29526 0.50000 +Y S I 2 4.29526 0.50000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.DAT new file mode 100755 index 000000000..559c862c3 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.DAT @@ -0,0 +1,260 @@ +AC AT C 2 0.20592 0.90403 REGHL.dat SEQ 053 +AC AT I 2 0.20592 0.90403 HL Non-primary Sp +AC B C 2 1.49979 0.60655 (260 records, 30 columns) +AC B I 2 1.49979 0.60655 +AC C C 2 1.92907 0.49448 +AC C I 2 1.92907 0.49448 +AC E C 2 0.11297 1.04999 +AC E I 2 0.11297 1.04999 +AC F C 2 0.28310 0.91494 +AC F I 2 0.28310 0.91494 +AC H C 2 1.48626 0.62253 +AC H I 2 1.48626 0.62253 +AC PL C 1 -0.10191 1.00764 +AC PL I 1 -0.10191 1.00764 +AC S C 2 0.42782 0.88219 +AC S I 2 0.42782 0.88219 +AT AC C 1 0.64215 0.77982 +AT AC I 1 0.64215 0.77982 +AT B C 1 0.05262 0.96299 +AT B I 1 0.05262 0.96299 +AT C C 1 1.63263 0.51580 +AT C I 1 1.63263 0.51580 +AT E C 2 0.02389 1.04556 +AT E I 2 0.02389 1.04556 +AT F C 1 0.44456 0.78336 +AT F I 1 0.44456 0.78336 +AT H C 2 1.34258 0.60512 +AT H I 2 1.34258 0.60512 +AT L C 1 -0.18119 0.97870 +AT L I 1 -0.18119 0.97870 +AT PL C 1 0.03725 0.91411 +AT PL I 1 0.03725 0.91411 +AT PW C 2 0.83167 0.70529 +AT PW I 2 0.83167 0.70529 +AT S C 1 0.53139 0.79034 +AT S I 1 0.53139 0.79034 +B AC C 2 0.59274 0.71410 +B AC I 2 0.59274 0.71410 +B AT C 2 0.66917 0.68418 +B AT I 2 0.66917 0.68418 +B C C 2 1.10252 0.62250 +B C I 2 2.10164 0.32118 +B E C 1 -0.03388 0.95357 +B E I 1 -0.03388 0.95357 +B F C 1 -0.77364 1.15642 +B F I 1 1.32696 0.45670 +B H C 2 0.44191 0.84988 +B H I 2 1.09445 0.64989 +B L C 1 0.83607 0.58032 +B L I 1 0.83607 0.58032 +B PA C 1 1.26867 0.45481 +B PA I 1 1.26867 0.45481 +B PL C 2 0.94797 0.57416 +B PL I 2 0.94797 0.57416 +B S C 2 0.96727 0.59527 +B S I 2 0.96727 0.59527 +B Y C 2 0.92920 0.62800 +B Y I 2 0.92920 0.62800 +C AT C 2 0.06205 0.83318 +C AT I 2 0.06205 0.83318 +C B C 2 0.09122 0.98701 +C B I 2 0.44782 0.81261 +C D C 2 0.01151 0.87824 +C D I 2 0.01151 0.87824 +C E C 2 0.38044 0.76449 +C E I 2 0.38044 0.76449 +C F C 2 -0.06339 0.89137 +C F I 2 0.36300 0.72130 +C H C 2 -0.20435 1.04781 +C H I 2 0.13251 0.94501 +C L C 2 -0.37717 0.90669 +C L I 2 -0.37717 0.90669 +C PL C 1 1.01481 0.47892 +C PL I 1 1.01481 0.47892 +C PW C 2 0.92507 0.55029 +C PW I 2 0.92507 0.55029 +C S C 2 -0.31514 0.99076 +C S I 2 0.07885 0.84918 +C Y C 2 0.73601 0.75744 +C Y I 2 0.73601 0.75744 +D B C 2 2.85515 0.02134 +D B I 2 2.85515 0.02134 +D C C 1 1.63542 0.46629 +D C I 1 1.63542 0.46629 +D F C 1 0.70816 0.70654 +D F I 1 0.70816 0.70654 +D H C 1 0.61404 0.77503 +D H I 1 0.61404 0.77503 +D S C 1 0.92202 0.67128 +D S I 1 0.92202 0.67128 +E AC C 2 1.54726 0.43043 +E AC I 2 1.54726 0.43043 +E AT C 2 1.10980 0.56901 +E AT I 2 1.10980 0.56901 +E B C 2 1.42558 0.53174 +E B I 2 1.42558 0.53174 +E C C 1 2.04011 0.32042 +E C I 1 2.04011 0.32042 +E F C 1 1.23183 0.48677 +E F I 1 0.95348 0.59105 +E H C 2 1.30941 0.57581 +E H I 2 1.31013 0.56988 +E L C 2 0.74012 0.65700 +E L I 2 0.74012 0.65700 +E PL C 2 0.75984 0.66991 +E PL I 2 0.75984 0.66991 +E S C 2 1.27069 0.53561 +E S I 2 1.27069 0.53561 +E Y C 2 3.38208 -0.17312 +E Y I 2 3.38208 -0.17312 +F AT C 2 0.65966 0.79857 +F AT I 2 0.65966 0.79857 +F B C 2 0.32819 0.96824 +F B I 1 0.29132 0.93643 +F C C 2 1.30503 0.68772 +F C I 1 1.43952 0.62132 +F D C 1 -0.24208 1.07623 +F D I 1 -0.24208 1.07623 +F E C 1 -0.44397 1.15752 +F E I 1 -0.44397 1.15752 +F H C 2 0.65528 0.85836 +F H I 2 1.22220 0.69380 +F L C 2 0.23991 0.85093 +F L I 2 0.23991 0.85093 +F PL C 2 0.88502 0.69582 +F PL I 2 0.38022 0.84905 +F PW C 2 0.00288 0.97493 +F PW I 2 0.00288 0.97493 +F PY C 2 0.74437 0.72448 +F PY I 2 0.74437 0.72448 +F S C 2 0.77459 0.78209 +F S I 2 0.77459 0.78209 +H B C 2 0.27989 0.90463 +H B I 1 -0.02244 0.89131 +H C C 2 0.45248 0.80331 +H C I 2 1.07252 0.64096 +H D C 2 0.50018 0.73519 +H D I 2 0.50018 0.73519 +H E C 2 0.45630 0.72293 +H E I 2 0.45630 0.72293 +H F C 2 0.37307 0.80247 +H F I 2 0.60473 0.67401 +H L C 2 -0.18699 0.88207 +H L I 2 -0.18699 0.88207 +H PL C 2 0.33313 0.75210 +H PL I 2 0.33313 0.75210 +H PW C 2 0.20510 0.78342 +H PW I 2 0.20510 0.78342 +H S C 2 0.66926 0.74710 +H S I 2 0.76227 0.63164 +H Y C 2 0.35371 0.84458 +H Y I 2 0.35371 0.84458 +L B C 1 0.63949 0.85052 +L B I 1 0.63949 0.85052 +L C C 2 2.22698 0.42672 +L C I 2 2.22698 0.42672 +L F C 2 0.91977 0.75045 +L F I 2 0.91977 0.75045 +L H C 2 1.63796 0.59221 +L H I 2 1.63796 0.59221 +L PL C 1 -0.31806 1.09697 +L PL I 1 -0.31806 1.09697 +L PW C 2 1.09667 0.68101 +L PW I 2 1.09667 0.68101 +L S C 2 0.52339 0.88713 +L S I 2 0.52339 0.88713 +L Y C 2 2.63188 0.20057 +L Y I 2 2.63188 0.20057 +MB C C 2 2.29543 0.27177 +MB C I 2 2.29543 0.27177 +MB D C 2 0.67861 0.76964 +MB D I 2 0.67861 0.76964 +MB F C 1 0.46601 0.77702 +MB F I 1 0.46601 0.77702 +MB H C 2 1.82975 0.43923 +MB H I 2 1.82975 0.43923 +PA B C 1 -0.27282 1.02724 +PA B I 1 -0.27282 1.02724 +PA C C 2 2.12184 0.21740 +PA C I 2 2.12184 0.21740 +PA H C 2 1.46793 0.38362 +PA H I 2 1.46793 0.38362 +PA PL C 2 0.23810 0.80214 +PA PL I 2 0.23810 0.80214 +PA S C 1 0.61689 0.69776 +PA S I 1 0.61689 0.69776 +PL AT C 2 0.77877 0.75819 +PL AT I 2 0.77877 0.75819 +PL B C 1 0.53691 0.82403 +PL B I 1 0.53691 0.82403 +PL C C 1 0.42308 0.80455 +PL C I 1 2.56030 0.22296 +PL E C 1 0.36031 0.92097 +PL E I 1 0.36031 0.92097 +PL F C 1 0.57672 0.74822 +PL F I 1 0.51328 0.79711 +PL H C 1 0.67589 0.76142 +PL H I 2 1.63423 0.51897 +PL L C 1 0.53102 0.76502 +PL L I 1 0.53102 0.76502 +PL S C 2 0.87397 0.73172 +PL S I 2 0.87397 0.73172 +PL Y C 2 3.24217 -0.13278 +PL Y I 2 3.24217 -0.13278 +PW B C 2 0.53677 0.89054 +PW B I 2 0.53677 0.89054 +PW C C 1 0.00278 1.04765 +PW C I 2 1.85722 0.51942 +PW F C 1 -0.03944 0.99228 +PW F I 2 0.59271 0.81863 +PW H C 1 0.35847 0.92951 +PW H I 2 1.19598 0.72518 +PW L C 2 0.00542 0.95085 +PW L I 2 0.00542 0.95085 +PW PL C 2 0.42241 0.83507 +PW PL I 2 0.42241 0.83507 +PW S C 2 0.97872 0.72378 +PW S I 2 0.97872 0.72378 +PW Y C 2 3.60704 -0.29622 +PW Y I 2 3.60704 -0.29622 +PY C C 2 2.51082 0.13018 +PY C I 2 2.51082 0.13018 +PY F C 2 -0.01582 1.01427 +PY F I 2 -0.01582 1.01427 +PY H C 2 2.41463 0.20675 +PY H I 2 2.41463 0.20675 +PY PL C 2 2.19327 0.24633 +PY PL I 2 2.19327 0.24633 +PY Y C 2 2.57767 0.15272 +PY Y I 2 2.57767 0.15272 +S AC C 2 1.28730 0.55614 +S AC I 2 1.28730 0.55614 +S AT C 2 0.30953 0.85128 +S AT I 2 0.30953 0.85128 +S B C 2 0.81410 0.80864 +S B I 1 0.24476 0.93159 +S C C 2 0.42295 0.90951 +S C I 2 1.88574 0.48043 +S D C 1 -1.39819 1.40113 +S D I 1 -1.39819 1.40113 +S E C 1 -0.73332 1.22477 +S E I 1 -0.73332 1.22477 +S F C 2 0.35720 0.86094 +S F I 2 0.60680 0.75748 +S H C 2 0.12935 1.00531 +S H I 2 0.83755 0.80767 +S L C 1 -0.45601 0.99596 +S L I 1 -0.45601 0.99596 +S PL C 2 0.09626 0.91453 +S PL I 2 0.09626 0.91453 +S PW C 2 1.14047 0.57709 +S PW I 2 1.14047 0.57709 +S Y C 2 4.44647 -0.50336 +S Y I 2 4.44647 -0.50336 +Y B C 1 0.00957 0.96417 +Y B I 1 0.00957 0.96417 +Y C C 2 0.49388 0.81046 +Y C I 2 0.49388 0.81046 +Y H C 2 0.35242 0.89090 +Y H I 2 0.35242 0.89090 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL1C.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL1C.DAT new file mode 100755 index 000000000..82e9edeb4 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL1C.DAT @@ -0,0 +1,16 @@ +AT -6.9119 -0.20000 REGHL1C.dat SEQ085 +B -8.5269 -0.20000 Small Component, HL (Lorey Height) +C -7.7759 -0.20000 (A2, 2F10.*) +D -6.2408 -0.20000 16 records, 1 per SP0 +AC -6.2408 -0.20000 +E -6.2126 -0.70245 +F -6.9926 -0.20000 +H -7.9645 -0.20000 +L -7.4537 -0.20000 +MB -7.1832 -0.20000 +PA -10.7871 -0.20000 +PL -5.7981 -0.20000 +PW -9.9470 -0.20000 +PY -7.7999 -0.20000 +S -7.6915 -0.20000 +Y -6.4483 -0.20000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGPR1C.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGPR1C.DAT new file mode 100755 index 000000000..473fcccf1 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGPR1C.DAT @@ -0,0 +1,16 @@ +AC 0.00000 0.00000 -0.021591 -0.13228 REGPR1C SEQ080 +AT -1.76158 2.50045 -0.030447 -0.11746 (A2, 4F10) +B -0.51884 2.15580 -0.019591 -0.03092 Small Component Probability +C 0.53123 1.39276 -0.018261 -0.04809 +D 1.61583 0.00000 -0.021591 -0.13228 +E -1.94304 -0.21575 -0.010551 -0.01210 +F 0.68728 1.99231 -0.015214 -0.09966 +H 0.37977 1.90975 -0.019961 -0.03868 +L -1.30616 0.00000 -0.005855 -0.05188 +MB 0.48205 0.00000 -0.011862 -0.10014 +PA -1.41326 0.00000 -0.050608 0.15992 +PL -2.38872 2.01236 -0.027956 0.00541 +PW 0.91871 -0.31356 -0.026857 -0.06163 +PY 2.91949 0.00000 0.011032 -0.66440 +S -1.04043 1.58714 -0.012369 -0.04910 +Y 2.16702 0.00000 -0.029074 -0.12360 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGV1C.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGV1C.DAT new file mode 100755 index 000000000..dcbb88e0f --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGV1C.DAT @@ -0,0 +1,16 @@ +AT -10.2252 1.51357 1.26623 0.04033 REGV1C.dat SEQ086 +B -9.6020 1.09191 1.26171 0.10841 Small Comp WS Vol +C -10.3643 2.38660 1.51991 -0.20184 A2, 4F10. +D -10.2075 1.02640 1.46095 0.11503 16 records, 1 per SP0 +AC -10.2075 1.02640 1.46095 0.11503 +E -11.2407 1.02431 1.72045 0.12485 +F -9.2914 0.56286 1.22118 0.20209 +H -11.6580 3.52612 1.25930 -0.30886 +L -10.6195 2.04757 1.26971 -0.05456 +MB -10.1836 0.93804 1.51004 0.11133 +PA -10.4013 2.15684 1.32768 -0.07664 +PL -11.9478 3.41028 1.44839 -0.26396 +PW -9.9954 1.72846 1.16313 0.00293 +PY -9.4416 0.75755 1.25417 0.15183 +S -9.2099 -0.15130 1.37076 0.34781 +Y -9.2555 0.88849 1.24108 0.14141 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVCU.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVCU.COE new file mode 100755 index 000000000..9b95ef06b --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVCU.COE @@ -0,0 +1,292 @@ + 1 1 -7.425 0.0000 0.15032 + 1 2 -9.326 0.6387 0.05382 + 1 3 -16.303 1.0868 0.07465 + 1 4 -12.862 0.5777 0.15467 + 1 5 -55.410 4.0000 0.22373 + 1 6 -11.959 0.6937 0.13555 + 1 7 -15.043 0.9911 0.11911 + 1 8 -15.676 0.9972 0.15149 + 1 9 -13.348 0.8274 0.12236 + 1 11 -18.482 1.0965 0.19228 + 1 12 -10.634 0.8355 0.00000 + 1 13 -12.554 0.8910 0.05498 + 1 14 -13.314 1.0125 0.02253 + 1 15 -17.402 1.3266 0.08804 + 1 16 -13.165 0.8896 0.01206 + 1 17 -11.142 0.7576 0.08023 + 1 18 -12.510 0.9387 0.04510 + 1 19 -16.634 1.0280 0.17645 + 1 20 -8.447 0.6223 0.03062 + 1 21 -7.378 0.4798 0.00212 + 1 22 -7.419 0.3613 0.02894 + 1 23 -8.086 0.2880 0.04644 + 1 24 -6.341 0.3877 0.00454 + 1 25 -11.051 0.7114 0.10935 + 1 26 -15.464 0.7515 0.26102 + 1 27 -14.420 0.7637 0.19682 + 1 28 -13.678 0.8242 0.16199 + 1 29 -14.916 0.7854 0.18024 + 1 30 -14.060 0.9070 0.05322 + 1 31 -16.886 1.2071 0.00033 + 1 32 -12.318 0.7821 0.07057 + 1 33 -19.435 1.3365 0.05798 + 1 34 -11.551 0.5832 0.07774 + 1 35 -10.464 0.4980 0.02581 + 1 36 -27.798 1.8375 0.09048 + 1 37 -11.642 0.8954 0.01569 + 1 38 -8.466 0.3600 0.03120 + 1 39 -12.072 0.7826 0.01444 + 1 40 -16.766 0.9839 0.00000 + 1 41 -20.351 0.7453 0.05605 + 1 42 -19.168 1.2958 0.04294 + 1 43 -19.168 1.0556 0.40914 + 1 44 -19.641 0.7694 0.05709 + 1 45 -14.967 0.8424 0.09472 + 1 46 -18.517 1.3615 0.00719 + 1 47 -19.665 0.7709 0.05733 + 1 48 -16.074 1.1513 0.04178 + 1 49 -15.985 1.0022 0.15114 + 1 50 -9.538 0.5155 0.15669 + 1 51 -10.772 0.6450 0.13077 + 1 52 -10.433 0.5802 0.17047 + 1 53 -10.217 0.6641 0.10914 + 1 54 -11.297 0.7202 0.11666 + 1 55 -9.886 0.6094 0.15077 + 1 56 -8.863 0.5729 0.10851 + 1 57 -10.713 0.6932 0.08549 + 1 58 -11.340 0.8614 0.08157 + 1 59 -46.202 3.6653 0.07930 + 1 60 -13.265 1.0103 0.03016 + 1 61 -13.062 0.7828 0.09911 + 1 62 -6.812 0.1360 0.02529 + 1 63 -51.418 3.9114 0.11942 + 1 64 -11.420 0.5072 0.07578 + 1 65 -12.207 0.7932 0.08135 + 1 66 -10.245 0.6794 0.05321 + 1 67 -10.578 0.7549 0.01064 + 1 68 -11.317 0.8439 0.00489 + 1 69 -11.904 0.7972 0.05206 + 1 70 -11.115 0.6754 0.07670 + 1 71 -11.663 0.7037 0.06905 + 1 72 -10.808 0.7031 0.04124 + 1 73 -11.976 0.5845 0.14841 + 1 74 -24.867 1.8776 0.02549 + 2 1 -8.359 0.5124 0.05910 + 2 2 -2.862 0.2587 0.01372 + 2 3 -7.455 0.4621 0.05384 + 2 4 -10.549 0.6534 0.06736 + 2 5 -9.275 0.5758 0.05681 + 2 6 -4.569 0.2895 0.06887 + 2 7 -4.692 0.3260 0.03994 + 2 8 -5.324 0.3560 0.05167 + 2 9 -4.978 0.3398 0.04440 + 2 11 -6.901 0.4524 0.05696 + 2 12 -4.450 0.3734 0.00000 + 2 13 -4.436 0.3340 0.02068 + 2 14 -3.937 0.3190 0.00716 + 2 15 -4.101 0.2951 0.03852 + 2 16 -5.921 0.4305 0.01266 + 2 17 -3.231 0.2548 0.02439 + 2 18 -3.614 0.2904 0.01966 + 2 19 -8.663 0.5229 0.11403 + 2 20 -3.842 0.3155 0.00712 + 2 21 -5.757 0.4379 0.00000 + 2 22 -5.844 0.4425 0.00000 + 2 23 -6.545 0.4834 0.00000 + 2 24 -6.031 0.4712 0.00000 + 2 25 -4.372 0.2923 0.06006 + 2 26 -5.738 0.2601 0.14515 + 2 27 -6.217 0.3491 0.09844 + 2 28 -4.618 0.2843 0.07219 + 2 29 -7.283 0.4085 0.10737 + 2 30 -7.037 0.4880 0.02436 + 2 31 -8.923 0.5617 0.04221 + 2 32 -5.836 0.4076 0.02999 + 2 33 -8.189 0.5585 0.02161 + 2 34 -7.619 0.5065 0.02825 + 2 35 -6.614 0.4393 0.03051 + 2 36 -9.138 0.5990 0.03070 + 2 37 -5.465 0.4176 0.01178 + 2 38 -8.279 0.5575 0.02663 + 2 39 -6.588 0.4881 0.00000 + 2 40 -9.108 0.6308 0.01019 + 2 41 -13.974 0.9444 0.00000 + 2 42 -9.160 0.6085 0.01969 + 2 43 -3.843 0.1723 0.14469 + 2 44 -10.545 0.6837 0.03369 + 2 45 -6.114 0.4097 0.03555 + 2 46 -5.753 0.4182 0.01170 + 2 47 -10.218 0.6899 0.01925 + 2 48 -7.381 0.4832 0.03406 + 2 49 -9.273 0.5555 0.12755 + 2 50 -3.066 0.2233 0.06046 + 2 51 -4.261 0.2616 0.08135 + 2 52 -2.785 0.1304 0.11328 + 2 53 -3.249 0.2426 0.04621 + 2 54 -3.291 0.2464 0.04548 + 2 55 -1.760 0.1261 0.07382 + 2 56 -1.611 0.1506 0.04070 + 2 57 -3.508 0.2658 0.03595 + 2 58 -2.342 0.2383 0.01576 + 2 59 -5.775 0.3911 0.05285 + 2 60 -3.772 0.3041 0.01465 + 2 61 -3.796 0.2984 0.01897 + 2 62 -5.025 0.3730 0.01011 + 2 63 -10.447 0.6462 0.06235 + 2 64 -10.473 0.7111 0.03396 + 2 65 -4.116 0.2943 0.03344 + 2 66 -6.251 0.4099 0.04627 + 2 67 -4.615 0.3582 0.00774 + 2 68 -4.514 0.3500 0.01093 + 2 69 -4.631 0.3604 0.00789 + 2 70 -5.234 0.3820 0.02058 + 2 71 -4.293 0.3217 0.01638 + 2 72 -4.637 0.3502 0.01370 + 2 73 -4.013 0.2676 0.04285 + 2 74 -8.027 0.5510 0.02279 + 3 1 -1.426 0.1316 0.02808 + 3 2 -0.219 0.1046 0.01229 + 3 3 -1.450 0.1400 0.02231 + 3 4 -0.852 0.1107 0.02468 + 3 5 -1.485 0.1415 0.02170 + 3 6 -0.535 0.0878 0.04368 + 3 7 -0.963 0.1202 0.02984 + 3 8 -1.026 0.1187 0.03460 + 3 9 -0.946 0.1192 0.02984 + 3 11 -1.107 0.1294 0.02491 + 3 12 -0.796 0.1413 0.00335 + 3 13 -0.639 0.1141 0.01217 + 3 14 -0.697 0.1238 0.00647 + 3 15 -0.496 0.0990 0.02383 + 3 16 -0.723 0.1258 0.00662 + 3 17 -0.656 0.1072 0.02041 + 3 18 -0.521 0.1137 0.01260 + 3 19 -0.854 0.1106 0.03312 + 3 20 -0.138 0.0931 0.00724 + 3 21 -0.365 0.1022 0.00189 + 3 22 -0.512 0.1107 0.00295 + 3 23 -0.525 0.1103 0.00049 + 3 24 -0.555 0.1163 0.00175 + 3 25 -0.653 0.0931 0.04333 + 3 26 -1.550 0.0941 0.07872 + 3 27 -1.300 0.1022 0.06038 + 3 28 -0.752 0.0916 0.04357 + 3 29 -1.062 0.0965 0.05404 + 3 30 -1.112 0.1393 0.01339 + 3 31 -1.526 0.1390 0.02234 + 3 32 -1.139 0.1324 0.02094 + 3 33 -0.943 0.1256 0.01333 + 3 34 -0.932 0.1176 0.01866 + 3 35 -1.176 0.1372 0.01381 + 3 36 -1.292 0.1429 0.01551 + 3 37 -1.040 0.1408 0.01255 + 3 38 -0.834 0.1226 0.00680 + 3 39 -1.129 0.1511 0.00000 + 3 40 -1.153 0.1414 0.00369 + 3 41 -0.971 0.1304 0.00308 + 3 42 -0.834 0.1242 0.00824 + 3 43 -0.891 0.0898 0.05145 + 3 44 -1.145 0.1335 0.01554 + 3 45 -1.144 0.1321 0.01906 + 3 46 -1.221 0.1416 0.01344 + 3 47 -0.813 0.1235 0.01051 + 3 48 -1.342 0.1223 0.02938 + 3 49 -0.227 0.0755 0.04020 + 3 50 0.236 0.0686 0.03481 + 3 51 -0.385 0.0825 0.04298 + 3 52 0.161 0.0375 0.06265 + 3 53 -0.105 0.0803 0.03376 + 3 54 -0.107 0.0823 0.03604 + 3 55 0.862 0.0264 0.04664 + 3 56 0.515 0.0534 0.03280 + 3 57 -0.120 0.0880 0.02545 + 3 58 0.299 0.0855 0.01724 + 3 59 -0.801 0.1224 0.01529 + 3 60 -0.698 0.1231 0.01117 + 3 61 -0.484 0.1054 0.01716 + 3 62 -1.514 0.1515 0.02466 + 3 63 -1.747 0.1547 0.02086 + 3 64 -1.356 0.1491 0.01607 + 3 65 -0.739 0.1135 0.01787 + 3 66 -1.323 0.1365 0.02217 + 3 67 -0.727 0.1206 0.00845 + 3 68 -0.762 0.1258 0.00740 + 3 69 -0.992 0.1350 0.00943 + 3 70 -0.878 0.1263 0.01289 + 3 71 -1.038 0.1325 0.01231 + 3 72 -0.852 0.1255 0.01022 + 3 73 -0.472 0.0903 0.02112 + 3 74 -0.543 0.1063 0.01043 + 4 1 1.534 0.0065 0.04168 + 4 2 1.975 0.0017 0.03685 + 4 3 1.897 0.0010 0.03804 + 4 4 1.706 0.0023 0.04420 + 4 5 1.689 0.0015 0.04401 + 4 6 1.292 0.0150 0.04544 + 4 7 1.277 0.0247 0.03316 + 4 8 1.248 0.0260 0.03292 + 4 9 1.287 0.0228 0.03525 + 4 11 1.392 0.0236 0.03086 + 4 12 2.354 0.0042 0.02477 + 4 13 1.552 0.0167 0.03309 + 4 14 1.669 0.0195 0.02314 + 4 15 1.457 0.0227 0.02859 + 4 16 2.348 0.0032 0.02710 + 4 17 1.111 0.0360 0.02264 + 4 18 1.651 0.0202 0.02607 + 4 19 1.174 0.0274 0.03571 + 4 20 2.100 0.0000 0.02268 + 4 21 1.976 0.0000 0.02533 + 4 22 1.973 0.0000 0.02534 + 4 23 1.936 0.0003 0.02711 + 4 24 1.969 0.0000 0.02747 + 4 25 1.333 0.0108 0.04876 + 4 26 0.490 0.0203 0.06804 + 4 27 0.994 0.0106 0.05795 + 4 28 0.883 0.0267 0.04234 + 4 29 1.195 0.0055 0.05209 + 4 30 1.970 0.0030 0.03382 + 4 31 1.676 0.0029 0.04297 + 4 32 1.703 0.0036 0.04159 + 4 33 1.646 0.0131 0.03329 + 4 34 1.646 0.0074 0.03692 + 4 35 1.460 0.0152 0.04180 + 4 36 1.762 0.0052 0.03953 + 4 37 2.045 0.0071 0.02830 + 4 38 1.736 0.0144 0.02896 + 4 39 1.775 0.0144 0.02901 + 4 40 1.723 0.0195 0.02294 + 4 41 2.040 0.0026 0.03403 + 4 42 1.636 0.0136 0.03648 + 4 43 0.819 0.0246 0.04113 + 4 44 1.634 0.0123 0.03055 + 4 45 1.365 0.0130 0.03951 + 4 46 1.524 0.0147 0.03125 + 4 47 1.558 0.0159 0.02851 + 4 48 1.440 0.0073 0.03904 + 4 49 1.516 0.0046 0.05062 + 4 50 1.583 0.0173 0.03599 + 4 51 1.416 0.0168 0.03897 + 4 52 1.322 0.0093 0.05387 + 4 53 1.372 0.0214 0.03519 + 4 54 1.231 0.0334 0.03564 + 4 55 1.527 0.0160 0.04108 + 4 56 1.331 0.0310 0.03193 + 4 57 1.509 0.0187 0.03436 + 4 58 1.654 0.0265 0.02412 + 4 59 1.935 0.0039 0.03099 + 4 60 1.821 0.0055 0.03250 + 4 61 1.744 0.0095 0.02987 + 4 62 1.853 0.0030 0.04454 + 4 63 1.461 0.0098 0.04737 + 4 64 1.519 0.0143 0.04265 + 4 65 1.591 0.0134 0.03029 + 4 66 2.018 0.0000 0.03103 + 4 67 1.830 0.0060 0.03115 + 4 68 1.920 0.0035 0.03004 + 4 69 1.763 0.0154 0.02051 + 4 70 1.694 0.0130 0.02676 + 4 71 1.391 0.0232 0.02668 + 4 72 1.637 0.0100 0.03292 + 4 73 1.203 0.0188 0.03971 + 4 74 1.926 0.0001 0.03826 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.COE new file mode 100755 index 000000000..d5c3b354b --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.COE @@ -0,0 +1,252 @@ + 1 1 12.9114 -0.98108 -1.81686 + 1 2 5.8646 -0.04975 -0.98449 + 1 3 8.1934 0.07031 -1.58859 + 1 4 7.7682 -0.10935 -1.38915 + 1 5 5.7942 -0.05627 -1.12295 + 1 6 9.5094 -0.36067 -0.66124 + 1 7 9.8482 -0.22421 -0.81495 + 1 8 5.2805 -0.06738 -0.44256 + 1 9 5.9378 -0.02594 -0.66087 + 1 10 6.2582 -0.14765 -0.63035 + 1 11 5.6201 -0.00631 -0.61500 + 1 12 7.4819 -0.13635 -0.69639 + 1 13 4.8725 0.17985 -0.53506 + 1 14 7.3374 0.04057 -0.89831 + 1 15 5.9945 -0.02068 -0.52218 + 1 16 5.7256 -0.09639 -0.59284 + 1 17 5.7902 -0.00503 -0.63835 + 1 18 6.7916 0.24999 -1.16334 + 1 19 9.6410 -0.28430 -0.98762 + 1 20 10.8678 -0.52856 -1.38281 + 1 21 12.3263 -0.58161 -1.42503 + 1 22 11.6334 -0.44054 -1.34122 + 1 23 12.7247 -0.83525 -1.22759 + 1 24 13.0287 -0.21474 -1.42922 + 1 25 13.7047 -0.74479 -1.36781 + 1 26 12.4110 -0.54734 -1.31038 + 1 27 11.5919 -0.40277 -1.29087 + 1 28 12.9784 -0.30738 -1.69931 + 1 29 12.6553 -0.54138 -1.43272 + 1 30 8.2745 -0.68130 -0.25550 + 1 31 8.5700 -0.15012 -0.76536 + 1 32 6.1363 -0.14194 -0.30058 + 1 33 3.0349 -0.00548 -0.04079 + 1 34 7.0400 -0.19125 -0.71932 + 1 35 9.3201 -0.98422 -0.37065 + 1 36 11.4035 0.22268 -2.01775 + 1 37 9.4201 -0.20182 -1.08195 + 1 38 10.2215 -0.49043 -1.13799 + 1 39 9.7641 -0.83810 -0.78930 + 1 40 9.2650 -0.40019 -0.80264 + 1 41 6.9713 0.26380 -0.74645 + 1 42 10.4624 -0.28600 -1.22969 + 1 43 10.4423 -0.35008 -1.21219 + 1 44 10.9848 -0.40012 -1.32744 + 1 45 10.1685 -0.04660 -1.51326 + 1 46 10.3059 -0.41284 -1.15470 + 1 47 19.0570 -0.82179 -2.21873 + 1 48 9.8993 -0.21804 -1.22690 + 1 49 8.4404 -0.16088 -1.17904 + 1 50 9.8445 -0.09059 -1.23768 + 1 51 13.0817 -0.54837 -1.23056 + 1 52 13.7939 -0.04847 -1.73650 + 1 53 12.7054 0.14984 -1.73471 + 1 54 9.4898 -0.18014 -0.88284 + 1 55 8.6164 -0.23994 -0.70933 + 1 56 8.2842 -0.27457 -0.69396 + 1 57 9.4307 -0.38254 -0.84822 + 1 58 8.8770 -0.48090 -0.69596 + 1 59 8.7241 -0.47324 -0.65071 + 1 60 8.5778 -0.37592 -0.83237 + 1 61 11.9638 -0.03053 -1.54637 + 1 62 10.3280 0.11239 -1.30891 + 1 63 5.6037 0.36445 -0.52321 + 2 1 13.6347 -0.98108 -1.81686 + 2 2 5.8646 -0.04975 -0.98449 + 2 3 8.1934 0.07031 -1.58859 + 2 4 7.7592 -0.10935 -1.38915 + 2 5 5.8612 -0.05627 -1.12295 + 2 6 9.5431 -0.36067 -0.66124 + 2 7 9.6133 -0.22421 -0.81495 + 2 8 5.2482 -0.06738 -0.44256 + 2 9 5.9554 -0.02594 -0.66087 + 2 10 6.1705 -0.14765 -0.63035 + 2 11 5.6017 -0.00631 -0.61500 + 2 12 7.2117 -0.13635 -0.69639 + 2 13 4.7276 0.17985 -0.53506 + 2 14 6.9996 0.04057 -0.89831 + 2 15 5.8887 -0.02068 -0.52218 + 2 16 5.7256 -0.09639 -0.59284 + 2 17 5.6645 -0.00503 -0.63835 + 2 18 6.6802 0.24999 -1.16334 + 2 19 9.7528 -0.28430 -0.98762 + 2 20 10.9709 -0.52856 -1.38281 + 2 21 12.1147 -0.58161 -1.42503 + 2 22 11.2357 -0.44054 -1.34122 + 2 23 12.6723 -0.83525 -1.22759 + 2 24 12.3499 -0.21474 -1.42922 + 2 25 13.8659 -0.74479 -1.36781 + 2 26 12.4110 -0.54734 -1.31038 + 2 27 11.7789 -0.40277 -1.29087 + 2 28 12.9784 -0.30738 -1.69931 + 2 29 12.6553 -0.54138 -1.43272 + 2 30 7.9413 -0.68130 -0.25550 + 2 31 8.4661 -0.15012 -0.76536 + 2 32 5.8754 -0.14194 -0.30058 + 2 33 3.0349 -0.00548 -0.04079 + 2 34 6.9584 -0.19125 -0.71932 + 2 35 9.3201 -0.98422 -0.37065 + 2 36 11.4035 0.22268 -2.01775 + 2 37 9.4075 -0.20182 -1.08195 + 2 38 10.0375 -0.49043 -1.13799 + 2 39 9.5029 -0.83810 -0.78930 + 2 40 8.7909 -0.40019 -0.80264 + 2 41 6.7736 0.26380 -0.74645 + 2 42 10.4146 -0.28600 -1.22969 + 2 43 10.4632 -0.35008 -1.21219 + 2 44 10.9750 -0.40012 -1.32744 + 2 45 10.2049 -0.04660 -1.51326 + 2 46 10.2385 -0.41284 -1.15470 + 2 47 18.5608 -0.82179 -2.21873 + 2 48 9.8604 -0.21804 -1.22690 + 2 49 8.4950 -0.16088 -1.17904 + 2 50 9.6990 -0.09059 -1.23768 + 2 51 13.0817 -0.54837 -1.23056 + 2 52 13.7939 -0.04847 -1.73650 + 2 53 12.7054 0.14984 -1.73471 + 2 54 9.3361 -0.18014 -0.88284 + 2 55 8.5187 -0.23994 -0.70933 + 2 56 8.0301 -0.27457 -0.69396 + 2 57 9.3554 -0.38254 -0.84822 + 2 58 8.8685 -0.48090 -0.69596 + 2 59 8.5727 -0.47324 -0.65071 + 2 60 8.6446 -0.37592 -0.83237 + 2 61 11.8923 -0.03053 -1.54637 + 2 62 10.1170 0.11239 -1.30891 + 2 63 5.4196 0.36445 -0.52321 + 3 1 13.5754 -0.98108 -1.81686 + 3 2 5.9691 -0.04975 -0.98449 + 3 3 8.2227 0.07031 -1.58859 + 3 4 7.9504 -0.10935 -1.38915 + 3 5 6.0542 -0.05627 -1.12295 + 3 6 9.2868 -0.36067 -0.66124 + 3 7 9.4058 -0.22421 -0.81495 + 3 8 5.1983 -0.06738 -0.44256 + 3 9 5.8972 -0.02594 -0.66087 + 3 10 6.0451 -0.14765 -0.63035 + 3 11 5.5473 -0.00631 -0.61500 + 3 12 6.8736 -0.13635 -0.69639 + 3 13 4.3490 0.17985 -0.53506 + 3 14 6.8836 0.04057 -0.89831 + 3 15 5.6113 -0.02068 -0.52218 + 3 16 5.4286 -0.09639 -0.59284 + 3 17 5.4224 -0.00503 -0.63835 + 3 18 6.5724 0.24999 -1.16334 + 3 19 9.8059 -0.28430 -0.98762 + 3 20 10.9497 -0.52856 -1.38281 + 3 21 11.5752 -0.58161 -1.42503 + 3 22 10.6941 -0.44054 -1.34122 + 3 23 12.7309 -0.83525 -1.22759 + 3 24 12.1958 -0.21474 -1.42922 + 3 25 13.8282 -0.74479 -1.36781 + 3 26 12.3663 -0.54734 -1.31038 + 3 27 11.6921 -0.40277 -1.29087 + 3 28 12.8976 -0.30738 -1.69931 + 3 29 12.5844 -0.54138 -1.43272 + 3 30 7.7057 -0.68130 -0.25550 + 3 31 8.2644 -0.15012 -0.76536 + 3 32 5.6385 -0.14194 -0.30058 + 3 33 2.8077 -0.00548 -0.04079 + 3 34 6.7807 -0.19125 -0.71932 + 3 35 9.0596 -0.98422 -0.37065 + 3 36 11.5294 0.22268 -2.01775 + 3 37 9.3201 -0.20182 -1.08195 + 3 38 9.7012 -0.49043 -1.13799 + 3 39 9.7896 -0.83810 -0.78930 + 3 40 8.7913 -0.40019 -0.80264 + 3 41 6.6996 0.26380 -0.74645 + 3 42 10.2722 -0.28600 -1.22969 + 3 43 10.3393 -0.35008 -1.21219 + 3 44 10.9014 -0.40012 -1.32744 + 3 45 10.3737 -0.04660 -1.51326 + 3 46 10.1078 -0.41284 -1.15470 + 3 47 17.9077 -0.82179 -2.21873 + 3 48 9.7449 -0.21804 -1.22690 + 3 49 8.6684 -0.16088 -1.17904 + 3 50 9.6758 -0.09059 -1.23768 + 3 51 12.7456 -0.54837 -1.23056 + 3 52 13.8186 -0.04847 -1.73650 + 3 53 12.6102 0.14984 -1.73471 + 3 54 9.2655 -0.18014 -0.88284 + 3 55 8.3215 -0.23994 -0.70933 + 3 56 7.9086 -0.27457 -0.69396 + 3 57 9.1591 -0.38254 -0.84822 + 3 58 8.6958 -0.48090 -0.69596 + 3 59 8.3915 -0.47324 -0.65071 + 3 60 8.4548 -0.37592 -0.83237 + 3 61 11.6450 -0.03053 -1.54637 + 3 62 9.9001 0.11239 -1.30891 + 3 63 5.2818 0.36445 -0.52321 + 4 1 8.0553 -0.77408 -0.70591 + 4 2 1.7642 0.96739 -0.69857 + 4 3 3.3140 0.20419 -0.55024 + 4 4 4.8830 0.72588 -1.24449 + 4 5 3.8947 0.36139 -0.88147 + 4 6 8.2633 -0.99918 -0.31213 + 4 7 10.7091 -0.95288 -0.80831 + 4 8 6.3403 -0.79548 -0.22662 + 4 9 6.8618 -0.80701 -0.36234 + 4 10 5.7937 -0.50452 -0.39552 + 4 11 6.9447 -0.82968 -0.37332 + 4 12 10.0496 -1.42161 -0.59283 + 4 13 9.4926 -1.59470 -0.51868 + 4 14 4.8441 -0.18862 -0.45278 + 4 15 6.2521 -0.67236 -0.37806 + 4 16 6.8605 -0.83481 -0.47678 + 4 17 5.1393 -0.78801 -0.20902 + 4 18 4.6808 -0.40807 -0.39939 + 4 19 17.8899 -2.68742 -1.03951 + 4 20 11.5506 -0.98775 -1.21947 + 4 21 11.0484 -0.98751 -1.19893 + 4 22 13.3401 -1.62911 -1.21360 + 4 23 10.7247 -0.52699 -1.05261 + 4 24 9.8091 -0.39480 -0.89168 + 4 25 13.4839 -0.88029 -1.21283 + 4 26 10.3514 -0.42319 -1.08246 + 4 27 12.0784 -0.83014 -1.11050 + 4 28 10.2688 -0.24884 -1.26076 + 4 29 11.4431 -0.59600 -1.22238 + 4 30 8.1776 -1.20462 -0.19222 + 4 31 11.4363 -1.08053 -0.92260 + 4 32 10.0331 -1.67788 -0.37873 + 4 33 9.1248 -1.82357 -0.28015 + 4 34 8.3256 -0.92504 -0.68519 + 4 35 6.1545 -0.35941 -0.26453 + 4 36 8.1869 -0.24944 -0.84387 + 4 37 8.7889 -1.55674 0.00000 + 4 38 3.4029 0.19920 -0.33211 + 4 39 17.1877 -2.55996 -1.21161 + 4 40 9.4857 -1.09718 -0.46974 + 4 41 9.4308 -0.64128 -0.74899 + 4 42 11.1724 -0.69668 -1.15696 + 4 43 9.3329 -0.39489 -1.00945 + 4 44 11.3596 -0.75745 -1.20131 + 4 45 8.4249 0.36221 -1.33806 + 4 46 11.6428 -1.06480 -1.05178 + 4 47 19.5746 -2.02356 -1.98333 + 4 48 11.0896 -0.82163 -1.12279 + 4 49 6.3236 0.46151 -1.07200 + 4 50 9.8404 -0.45809 -1.08476 + 4 51 18.7448 -1.37426 -1.87725 + 4 52 13.8618 -0.57807 -1.48142 + 4 53 14.4865 -0.73306 -1.61405 + 4 54 8.7789 -0.47329 -0.57134 + 4 55 8.7350 -0.91923 -0.42737 + 4 56 7.2236 -0.75820 -0.29938 + 4 57 10.5901 -1.14841 -0.67287 + 4 58 9.4002 -0.95790 -0.58440 + 4 59 8.7322 -0.95193 -0.45842 + 4 60 11.7417 -1.55080 -0.75616 + 4 61 14.1515 -1.16367 -1.35062 + 4 62 12.4031 -1.02059 -1.15868 + 4 63 7.4002 -1.11129 -0.24771 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.DAT new file mode 100755 index 000000000..04592bc18 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.DAT @@ -0,0 +1,252 @@ + 1 1 13.2699 -1.12847 -1.73545 + 1 2 5.5808 -0.02158 -0.93854 + 1 3 7.9266 0.03706 -1.49981 + 1 4 7.7311 -0.09633 -1.38827 + 1 5 5.8988 -0.08533 -1.11814 + 1 6 9.0557 -0.35619 -0.59432 + 1 7 8.6892 -0.20956 -0.63541 + 1 8 5.0058 -0.05371 -0.40039 + 1 9 5.6127 -0.01376 -0.60701 + 1 10 6.0412 -0.16311 -0.57990 + 1 11 5.6221 -0.01341 -0.61302 + 1 12 7.4272 -0.13321 -0.69138 + 1 13 4.8790 0.18102 -0.53754 + 1 14 6.4609 0.06590 -0.75131 + 1 15 5.7809 -0.02092 -0.50377 + 1 16 5.5840 -0.08676 -0.57326 + 1 17 5.6356 -0.00035 -0.62015 + 1 18 6.2815 0.20577 -1.05347 + 1 19 8.7557 -0.02404 -0.95791 + 1 20 10.6977 -0.55499 -1.33001 + 1 21 11.6565 -0.53534 -1.35810 + 1 22 11.1403 -0.38358 -1.28169 + 1 23 12.2124 -0.80392 -1.14815 + 1 24 11.9043 -0.17586 -1.24853 + 1 25 13.8094 -0.78314 -1.36158 + 1 26 11.3135 -0.50280 -1.13770 + 1 27 11.5027 -0.42114 -1.25810 + 1 28 12.8029 -0.28117 -1.68936 + 1 29 12.6465 -0.60589 -1.38536 + 1 30 7.8203 -0.48876 -0.29527 + 1 31 8.1117 -0.14893 -0.69011 + 1 32 5.8849 -0.17598 -0.25344 + 1 33 2.6967 0.02155 -0.00031 + 1 34 6.5607 -0.18668 -0.64123 + 1 35 8.6979 -0.81996 -0.34440 + 1 36 10.8236 0.40968 -1.93892 + 1 37 9.9310 -0.00694 -1.12322 + 1 38 8.5099 -0.24134 -0.93512 + 1 39 9.5067 -0.35326 -1.01131 + 1 40 9.4590 -0.41297 -0.69939 + 1 41 6.3966 0.37747 -0.71254 + 1 42 10.1659 -0.24566 -1.18804 + 1 43 10.2965 -0.40543 -1.15612 + 1 44 10.8470 -0.42367 -1.28582 + 1 45 9.9798 -0.03502 -1.48111 + 1 46 10.0498 -0.40267 -1.11392 + 1 47 18.6116 -0.86568 -2.10369 + 1 48 9.7158 -0.22910 -1.18038 + 1 49 8.3707 -0.21459 -1.13229 + 1 50 9.1958 -0.06803 -1.13702 + 1 51 15.5665 -1.34648 -1.11320 + 1 52 13.1249 0.05388 -1.66863 + 1 53 12.6847 0.19148 -1.76459 + 1 54 8.7904 -0.11054 -0.76626 + 1 55 8.4434 -0.24327 -0.68846 + 1 56 7.9540 -0.29785 -0.62864 + 1 57 9.1442 -0.41085 -0.79747 + 1 58 8.8691 -0.49232 -0.69447 + 1 59 8.4254 -0.44501 -0.61723 + 1 60 8.5372 -0.43250 -0.79683 + 1 61 11.9424 -0.03728 -1.54547 + 1 62 10.3005 0.12350 -1.31673 + 1 63 4.7341 0.34900 -0.36748 + 2 1 13.8345 -1.12847 -1.73545 + 2 2 5.5808 -0.02158 -0.93854 + 2 3 7.9266 0.03706 -1.49981 + 2 4 7.7175 -0.09633 -1.38827 + 2 5 5.9402 -0.08533 -1.11814 + 2 6 9.1551 -0.35619 -0.59432 + 2 7 8.5259 -0.20956 -0.63541 + 2 8 4.9798 -0.05371 -0.40039 + 2 9 5.6382 -0.01376 -0.60701 + 2 10 5.9591 -0.16311 -0.57990 + 2 11 5.6194 -0.01341 -0.61302 + 2 12 7.1839 -0.13321 -0.69138 + 2 13 4.7362 0.18102 -0.53754 + 2 14 6.1213 0.06590 -0.75131 + 2 15 5.7679 -0.02092 -0.50377 + 2 16 5.5840 -0.08676 -0.57326 + 2 17 5.5462 -0.00035 -0.62015 + 2 18 6.2440 0.20577 -1.05347 + 2 19 8.8813 -0.02404 -0.95791 + 2 20 10.8028 -0.55499 -1.33001 + 2 21 11.6389 -0.53534 -1.35810 + 2 22 10.7918 -0.38358 -1.28169 + 2 23 12.2018 -0.80392 -1.14815 + 2 24 11.2079 -0.17586 -1.24853 + 2 25 13.9886 -0.78314 -1.36158 + 2 26 11.3135 -0.50280 -1.13770 + 2 27 11.6843 -0.42114 -1.25810 + 2 28 12.8029 -0.28117 -1.68936 + 2 29 12.6465 -0.60589 -1.38536 + 2 30 7.5380 -0.48876 -0.29527 + 2 31 8.0509 -0.14893 -0.69011 + 2 32 5.7189 -0.17598 -0.25344 + 2 33 2.6967 0.02155 -0.00031 + 2 34 6.5615 -0.18668 -0.64123 + 2 35 8.6979 -0.81996 -0.34440 + 2 36 10.8236 0.40968 -1.93892 + 2 37 9.0064 -0.00694 -1.12322 + 2 38 8.4441 -0.24134 -0.93512 + 2 39 9.3029 -0.35326 -1.01131 + 2 40 8.3167 -0.41297 -0.69939 + 2 41 6.2161 0.37747 -0.71254 + 2 42 10.0996 -0.24566 -1.18804 + 2 43 10.3279 -0.40543 -1.15612 + 2 44 10.8344 -0.42367 -1.28582 + 2 45 10.0209 -0.03502 -1.48111 + 2 46 9.9860 -0.40267 -1.11392 + 2 47 18.1532 -0.86568 -2.10369 + 2 48 9.6682 -0.22910 -1.18038 + 2 49 8.4271 -0.21459 -1.13229 + 2 50 9.1028 -0.06803 -1.13702 + 2 51 15.5665 -1.34648 -1.11320 + 2 52 13.1249 0.05388 -1.66863 + 2 53 12.6847 0.19148 -1.76459 + 2 54 8.5393 -0.11054 -0.76626 + 2 55 8.4075 -0.24327 -0.68846 + 2 56 7.7779 -0.29785 -0.62864 + 2 57 9.1736 -0.41085 -0.79747 + 2 58 8.9238 -0.49232 -0.69447 + 2 59 8.3358 -0.44501 -0.61723 + 2 60 8.6360 -0.43250 -0.79683 + 2 61 11.9013 -0.03728 -1.54547 + 2 62 10.1257 0.12350 -1.31673 + 2 63 4.5873 0.34900 -0.36748 + 3 1 13.8067 -1.12847 -1.73545 + 3 2 5.6816 -0.02158 -0.93854 + 3 3 7.9555 0.03706 -1.49981 + 3 4 7.9095 -0.09633 -1.38827 + 3 5 6.1302 -0.08533 -1.11814 + 3 6 8.9196 -0.35619 -0.59432 + 3 7 8.3219 -0.20956 -0.63541 + 3 8 4.9317 -0.05371 -0.40039 + 3 9 5.5829 -0.01376 -0.60701 + 3 10 5.8386 -0.16311 -0.57990 + 3 11 5.5673 -0.01341 -0.61302 + 3 12 6.8417 -0.13321 -0.69138 + 3 13 4.3559 0.18102 -0.53754 + 3 14 5.9962 0.06590 -0.75131 + 3 15 5.5135 -0.02092 -0.50377 + 3 16 5.2905 -0.08676 -0.57326 + 3 17 5.3090 -0.00035 -0.62015 + 3 18 6.1557 0.20577 -1.05347 + 3 19 8.9622 -0.02404 -0.95791 + 3 20 10.7819 -0.55499 -1.33001 + 3 21 11.1012 -0.53534 -1.35810 + 3 22 10.2571 -0.38358 -1.28169 + 3 23 12.2425 -0.80392 -1.14815 + 3 24 11.1305 -0.17586 -1.24853 + 3 25 13.9311 -0.78314 -1.36158 + 3 26 11.3231 -0.50280 -1.13770 + 3 27 11.5902 -0.42114 -1.25810 + 3 28 12.7212 -0.28117 -1.68936 + 3 29 12.5584 -0.60589 -1.38536 + 3 30 7.2871 -0.48876 -0.29527 + 3 31 7.8366 -0.14893 -0.69011 + 3 32 5.4929 -0.17598 -0.25344 + 3 33 2.5163 0.02155 -0.00031 + 3 34 6.3818 -0.18668 -0.64123 + 3 35 8.4675 -0.81996 -0.34440 + 3 36 10.6179 0.40968 -1.93892 + 3 37 8.9189 -0.00694 -1.12322 + 3 38 7.9920 -0.24134 -0.93512 + 3 39 9.4224 -0.35326 -1.01131 + 3 40 8.2363 -0.41297 -0.69939 + 3 41 6.1514 0.37747 -0.71254 + 3 42 9.9558 -0.24566 -1.18804 + 3 43 10.2042 -0.40543 -1.15612 + 3 44 10.7634 -0.42367 -1.28582 + 3 45 10.1893 -0.03502 -1.48111 + 3 46 9.8657 -0.40267 -1.11392 + 3 47 17.4839 -0.86568 -2.10369 + 3 48 9.5514 -0.22910 -1.18038 + 3 49 8.6019 -0.21459 -1.13229 + 3 50 9.1026 -0.06803 -1.13702 + 3 51 14.9717 -1.34648 -1.11320 + 3 52 13.1550 0.05388 -1.66863 + 3 53 12.5282 0.19148 -1.76459 + 3 54 8.4951 -0.11054 -0.76626 + 3 55 8.2169 -0.24327 -0.68846 + 3 56 7.6634 -0.29785 -0.62864 + 3 57 8.9916 -0.41085 -0.79747 + 3 58 8.7481 -0.49232 -0.69447 + 3 59 8.1532 -0.44501 -0.61723 + 3 60 8.4569 -0.43250 -0.79683 + 3 61 11.6533 -0.03728 -1.54547 + 3 62 9.9102 0.12350 -1.31673 + 3 63 4.4676 0.34900 -0.36748 + 4 1 7.6654 -0.80791 -0.60379 + 4 2 1.9836 0.88539 -0.68187 + 4 3 3.3096 0.14669 -0.50083 + 4 4 4.9141 0.71603 -1.24450 + 4 5 4.0958 0.27033 -0.85752 + 4 6 8.6528 -1.04497 -0.34644 + 4 7 9.8255 -0.87679 -0.70813 + 4 8 6.1738 -0.78776 -0.20095 + 4 9 6.7208 -0.81569 -0.33025 + 4 10 5.5085 -0.48048 -0.35566 + 4 11 7.0704 -0.88240 -0.36356 + 4 12 10.1025 -1.42677 -0.59929 + 4 13 9.5199 -1.58923 -0.52851 + 4 14 3.9055 -0.14713 -0.31801 + 4 15 6.0714 -0.63486 -0.37556 + 4 16 6.7848 -0.81675 -0.47715 + 4 17 4.9029 -0.74105 -0.20165 + 4 18 4.0729 -0.39365 -0.29932 + 4 19 17.7368 -2.93704 -0.82939 + 4 20 10.9376 -0.84705 -1.19070 + 4 21 11.0115 -1.12252 -1.10221 + 4 22 13.1716 -1.67004 -1.15110 + 4 23 10.2438 -0.53067 -0.96273 + 4 24 9.2297 -0.42081 -0.77983 + 4 25 13.3021 -0.87426 -1.18706 + 4 26 9.6339 -0.31856 -1.03354 + 4 27 12.0523 -0.82886 -1.10816 + 4 28 9.9919 -0.21519 -1.23749 + 4 29 11.2468 -0.60421 -1.18333 + 4 30 7.9476 -1.15008 -0.19038 + 4 31 10.3078 -1.02376 -0.76486 + 4 32 9.9641 -1.65029 -0.38906 + 4 33 9.0021 -1.81273 -0.26724 + 4 34 7.8590 -0.84448 -0.65702 + 4 35 5.6895 -0.30309 -0.21382 + 4 36 7.6889 -0.41741 -0.61487 + 4 37 8.4962 -1.48976 0.00000 + 4 38 3.3473 0.14354 -0.26104 + 4 39 16.9807 -2.40230 -1.27758 + 4 40 8.2678 -0.88260 -0.41069 + 4 41 9.3936 -0.63663 -0.74536 + 4 42 10.8194 -0.62546 -1.13375 + 4 43 9.0000 -0.36973 -0.96555 + 4 44 11.1752 -0.74839 -1.17250 + 4 45 8.3427 0.36889 -1.32479 + 4 46 11.1687 -0.93945 -1.03987 + 4 47 19.0615 -1.96048 -1.92755 + 4 48 10.8352 -0.77617 -1.10315 + 4 49 6.2306 0.44403 -1.04121 + 4 50 9.4000 -0.42475 -1.03083 + 4 51 18.3524 -1.34799 -1.82819 + 4 52 14.0551 -0.62899 -1.47549 + 4 53 13.9167 -0.64045 -1.57760 + 4 54 8.0427 -0.51515 -0.39424 + 4 55 8.5658 -0.90173 -0.40905 + 4 56 7.0059 -0.73915 -0.27354 + 4 57 10.3401 -1.12298 -0.64468 + 4 58 9.2496 -0.91013 -0.59044 + 4 59 8.9470 -1.00889 -0.45924 + 4 60 11.6775 -1.54505 -0.74792 + 4 61 13.9911 -1.16994 -1.31748 + 4 62 12.4448 -1.01286 -1.17277 + 4 63 6.9236 -1.08827 -0.18165 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.COE new file mode 100755 index 000000000..5d8090e8b --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.COE @@ -0,0 +1,292 @@ + 1 1 -1.14241 1.35050 0.82758 -1.14570 + 1 2 -0.69696 1.24493 0.57101 -0.85802 + 1 3 -1.46426 1.44329 0.80111 -1.08494 + 1 4 -1.10923 1.06295 0.75835 -0.82759 + 1 5 -1.33242 1.46494 0.77446 -1.15008 + 1 6 -1.26557 1.24455 0.62856 -0.71449 + 1 7 -1.32056 1.20035 0.72401 -0.73924 + 1 8 -1.10744 1.14357 0.59451 -0.64179 + 1 9 -0.99592 1.15820 0.55692 -0.66920 + 1 11 -1.61154 1.30202 1.46420 -1.46666 + 1 12 -1.20776 0.67000 1.43023 -0.88679 + 1 13 -1.11304 0.98821 1.17773 -1.02972 + 1 14 -1.05258 0.92598 1.24117 -1.05836 + 1 15 -0.41765 1.06763 0.98457 -1.19421 + 1 16 -1.50370 0.33779 1.09926 -0.27298 + 1 17 -0.88564 1.19041 1.26557 -1.41335 + 1 18 -1.21310 1.10208 1.34394 -1.25011 + 1 19 -2.08938 1.27990 1.48640 -1.24841 + 1 20 0.08915 1.24919 0.64487 -1.19941 + 1 21 -0.39700 0.69047 0.87153 -0.71220 + 1 22 -0.48567 0.91973 0.89602 -0.95435 + 1 23 -0.21969 0.64712 0.76942 -0.69486 + 1 24 -0.02422 0.83220 0.77772 -0.88036 + 1 25 -2.04035 1.45702 0.93855 -0.90797 + 1 26 -1.96099 1.68744 0.68919 -1.03359 + 1 27 -2.63944 1.65081 0.96424 -1.00511 + 1 28 -1.68927 1.37393 0.83144 -0.90550 + 1 29 -3.05396 1.63492 1.11330 -0.98391 + 1 30 -1.77949 1.36754 1.27118 -1.22848 + 1 31 -1.52607 1.29013 1.13605 -1.18505 + 1 32 -1.60808 1.31252 1.20490 -1.19684 + 1 33 -1.81444 0.97811 1.38715 -0.98325 + 1 34 -1.14115 1.12963 1.05214 -1.08514 + 1 35 -1.82661 1.02667 1.36233 -1.01922 + 1 36 -1.32630 0.90150 0.99667 -0.75207 + 1 37 -2.04636 1.21916 1.72192 -1.39268 + 1 38 -0.95437 1.03805 0.97118 -1.03355 + 1 39 -1.16143 1.09136 1.18638 -1.19926 + 1 40 -2.01095 0.54352 1.47040 -0.62410 + 1 41 -1.28471 0.61284 1.14251 -0.70357 + 1 42 -1.82143 0.74754 1.50390 -0.92091 + 1 43 -0.75777 1.55127 0.38024 -0.94486 + 1 44 -0.70457 1.07164 0.73006 -0.91137 + 1 45 -1.18115 1.40378 0.83280 -1.15304 + 1 46 -1.54465 1.14298 1.19136 -1.05511 + 1 47 -1.30374 1.25931 0.98432 -1.09603 + 1 48 -1.20675 1.29978 0.82160 -1.03587 + 1 49 -1.29786 1.13413 0.94484 -0.83297 + 1 50 -1.33571 1.34796 0.83711 -0.91651 + 1 51 -1.87711 1.50975 1.23118 -1.25056 + 1 52 -1.49311 1.63388 0.75989 -1.09087 + 1 53 -1.31806 1.40181 0.66856 -0.83089 + 1 54 -1.87542 1.33126 1.25219 -1.10944 + 1 55 -1.43664 1.64866 0.95433 -1.27645 + 1 56 -0.80072 1.45243 0.76330 -1.14932 + 1 57 -0.96784 1.27427 0.68352 -0.87840 + 1 58 -0.34269 1.02902 0.60709 -0.71685 + 1 59 -0.67957 1.08424 0.82890 -0.95194 + 1 60 -1.25267 0.83921 1.08484 -0.72211 + 1 61 -0.62458 0.95533 0.78068 -0.82209 + 1 62 -1.06844 1.43038 0.91652 -1.25601 + 1 63 -0.95754 1.13877 0.92323 -1.04581 + 1 64 -1.21683 1.05339 1.07993 -0.96578 + 1 65 -1.03654 1.33407 0.94219 -1.19180 + 1 66 -2.03025 1.40605 1.31680 -1.18684 + 1 67 -0.78312 0.80492 1.00818 -0.81422 + 1 68 -0.81740 1.04514 1.07824 -1.11174 + 1 69 -1.06221 1.00702 1.30228 -1.20729 + 1 70 -1.41824 1.14091 1.39959 -1.29581 + 1 71 -1.40878 1.04869 1.35590 -1.15261 + 1 72 -0.98208 1.03779 0.99738 -0.96826 + 1 73 -0.82928 1.07911 0.90590 -0.97825 + 1 74 -0.17352 0.46333 0.61891 -0.39576 + 2 1 -1.49408 1.33227 0.73898 -0.92929 + 2 2 -0.58080 1.19141 0.33137 -0.62805 + 2 3 -1.65903 1.32594 0.73210 -0.84905 + 2 4 -2.89365 1.22992 1.14632 -0.72805 + 2 5 -1.33657 1.35627 0.58758 -0.86089 + 2 6 -1.54464 1.37517 0.47155 -0.61957 + 2 7 -1.21945 1.21001 0.48510 -0.58390 + 2 8 -1.19302 1.19981 0.45601 -0.55130 + 2 9 -1.38258 1.21757 0.50783 -0.55453 + 2 11 -1.44375 1.20115 1.14639 -1.17521 + 2 12 -1.58211 0.67720 1.36449 -0.78177 + 2 13 -1.31062 1.02189 1.12698 -1.00892 + 2 14 -1.32875 1.00043 1.19396 -1.04980 + 2 15 -0.67724 1.14186 0.86349 -1.09176 + 2 16 -1.63062 0.46887 1.11737 -0.40693 + 2 17 -0.83884 1.17661 1.01244 -1.23288 + 2 18 -1.31525 1.09863 1.19487 -1.14273 + 2 19 -1.34608 1.20949 1.03338 -1.09204 + 2 20 -0.45383 1.24614 0.73548 -1.09886 + 2 21 -0.63882 0.79333 0.83827 -0.73322 + 2 22 -0.51445 0.98986 0.81215 -0.94802 + 2 23 -0.87017 0.61086 1.00540 -0.65884 + 2 24 -0.25051 0.47281 0.85560 -0.56117 + 2 25 -2.04557 1.47071 0.73118 -0.76827 + 2 26 -2.03857 1.72250 0.44636 -0.81104 + 2 27 -2.62543 1.70150 0.72246 -0.84611 + 2 28 -1.51173 1.42025 0.50119 -0.72025 + 2 29 -2.94829 1.67520 0.86743 -0.84815 + 2 30 -2.00543 1.26485 1.01989 -0.90010 + 2 31 -1.52028 1.21620 0.91071 -0.96083 + 2 32 -1.76917 1.39071 0.95841 -1.05942 + 2 33 -2.22587 1.07177 1.32299 -0.95863 + 2 34 -1.55306 1.26751 1.00951 -1.08312 + 2 35 -1.73807 1.01970 1.20687 -0.97966 + 2 36 -1.60773 1.01543 0.94827 -0.75448 + 2 37 -2.60921 1.40716 1.54675 -1.33401 + 2 38 -1.70965 1.01010 1.15693 -0.93718 + 2 39 -1.60228 1.13599 1.26705 -1.19562 + 2 40 0.10092 0.43364 0.54322 -0.44951 + 2 41 -3.80638 0.79730 2.01416 -0.83541 + 2 42 -1.09211 0.78888 1.13356 -0.93713 + 2 43 -0.68173 1.47232 0.16653 -0.69553 + 2 44 -0.88806 1.07166 0.66902 -0.79959 + 2 45 -1.49897 1.34369 0.69465 -0.87070 + 2 46 -1.29116 1.15284 0.81644 -0.86256 + 2 47 -1.18389 1.17955 0.76068 -0.88372 + 2 48 -4.04083 1.24008 1.75518 -0.88943 + 2 49 -1.71552 1.18135 0.94217 -0.77467 + 2 50 -1.18869 1.29327 0.60816 -0.72919 + 2 51 -2.51661 1.50934 1.13210 -1.00710 + 2 52 -1.58706 1.60284 0.59748 -0.90375 + 2 53 -1.18741 1.34380 0.44560 -0.63883 + 2 54 -1.86706 1.35624 0.94222 -0.90266 + 2 55 -1.56199 1.58392 0.69015 -0.96860 + 2 56 -1.13438 1.32023 0.72620 -0.88148 + 2 57 -1.15378 1.26319 0.62614 -0.75729 + 2 58 -0.42689 1.00407 0.53051 -0.61784 + 2 59 -0.32561 0.96711 0.60054 -0.75922 + 2 60 -1.19139 0.99641 0.87163 -0.73876 + 2 61 -1.93915 1.01813 1.28184 -0.90114 + 2 62 0.02096 1.55203 0.35570 -1.24715 + 2 63 -1.38024 1.30174 0.93085 -1.07962 + 2 64 -2.02420 1.09792 1.13056 -0.82420 + 2 65 -1.13428 1.30743 0.81830 -1.04178 + 2 66 -2.02894 1.40596 0.96840 -0.95131 + 2 67 -0.83837 0.90995 0.88944 -0.82179 + 2 68 -0.94390 1.15185 0.95508 -1.08946 + 2 69 -1.30098 0.91758 1.19026 -0.97764 + 2 70 -1.43610 1.19557 1.08359 -1.09736 + 2 71 -0.67077 1.06324 0.84998 -1.01710 + 2 72 -1.27898 1.09964 0.95069 -0.91732 + 2 73 -0.34739 1.11148 0.58105 -0.91160 + 2 74 -0.87179 0.68681 0.84634 -0.57142 + 3 1 -1.37328 1.32258 0.54129 -0.76728 + 3 2 -0.97150 1.24222 0.38241 -0.60355 + 3 3 -1.88524 1.26317 0.64476 -0.64016 + 3 4 -1.41700 1.24437 0.59819 -0.71681 + 3 5 -1.56203 1.27501 0.61175 -0.72318 + 3 6 -1.31302 1.44454 0.22090 -0.52473 + 3 7 -1.05410 1.27277 0.26048 -0.48395 + 3 8 -0.63806 1.27547 0.09269 -0.45463 + 3 9 -0.96684 1.28648 0.21439 -0.48008 + 3 11 -1.72863 1.10284 1.04433 -0.88948 + 3 12 -1.61995 0.65103 1.17783 -0.60738 + 3 13 -0.62595 1.03744 0.74823 -0.91039 + 3 14 -1.02775 1.02308 0.92192 -0.93431 + 3 15 -0.60101 1.15354 0.61145 -0.88132 + 3 16 -0.71376 0.53011 0.74612 -0.42103 + 3 17 -0.43273 1.17999 0.61989 -0.99160 + 3 18 -0.71985 1.03454 0.81540 -0.93560 + 3 19 -0.45151 1.13085 0.55715 -0.85353 + 3 20 -0.41078 1.23117 0.60840 -0.99277 + 3 21 -0.75058 0.94459 0.77414 -0.79600 + 3 22 -0.42529 1.03077 0.68221 -0.89388 + 3 23 -1.20504 0.68419 1.01684 -0.66368 + 3 24 -1.76019 0.66763 1.21849 -0.63442 + 3 25 -1.72327 1.49316 0.44951 -0.64722 + 3 26 -2.13948 1.73063 0.30729 -0.63662 + 3 27 -2.06173 1.70306 0.35064 -0.67295 + 3 28 -1.01491 1.42564 0.19734 -0.59137 + 3 29 -2.24399 1.61706 0.43203 -0.60601 + 3 30 -1.17253 1.18837 0.56123 -0.69482 + 3 31 -1.26478 1.20262 0.67056 -0.81978 + 3 32 -1.33528 1.38200 0.61291 -0.88758 + 3 33 -1.34378 1.10497 0.83836 -0.86248 + 3 34 -0.97595 1.28447 0.63826 -0.95461 + 3 35 -1.22365 1.00952 0.89263 -0.86988 + 3 36 -1.20347 1.10156 0.67526 -0.72646 + 3 37 -2.65265 1.42371 1.27260 -1.13515 + 3 38 -0.74791 0.90809 0.75420 -0.78783 + 3 39 -1.18956 1.07216 0.99595 -1.03266 + 3 40 -0.22173 0.60031 0.71244 -0.64026 + 3 41 -1.63505 0.76427 1.08773 -0.70472 + 3 42 -0.46916 0.87400 0.90167 -0.99612 + 3 43 -1.18167 1.44591 0.34400 -0.68262 + 3 44 -1.36400 1.11498 0.65851 -0.67663 + 3 45 -1.13402 1.33340 0.42359 -0.72785 + 3 46 -1.33414 1.18947 0.61106 -0.70083 + 3 47 0.34200 0.99311 0.15489 -0.61822 + 3 48 -0.72480 1.29414 0.34689 -0.74192 + 3 49 -0.24675 1.28487 0.31659 -0.76031 + 3 50 -0.80726 1.26460 0.36761 -0.60175 + 3 51 -1.74212 1.47201 0.64957 -0.80441 + 3 52 -1.12619 1.51071 0.32406 -0.71150 + 3 53 -0.90000 1.30640 0.25224 -0.52093 + 3 54 -0.81476 1.31752 0.38202 -0.68024 + 3 55 -0.64466 1.48771 0.19873 -0.71268 + 3 56 -0.46524 1.21781 0.37218 -0.67049 + 3 57 -0.79396 1.24213 0.38931 -0.63168 + 3 58 0.04176 0.98021 0.26509 -0.49568 + 3 59 -0.88600 1.07874 0.66597 -0.73996 + 3 60 -0.81568 1.03601 0.62490 -0.67983 + 3 61 0.42928 1.07818 0.14062 -0.66144 + 3 62 -2.10383 1.64526 0.86181 -1.10784 + 3 63 -0.65149 1.23025 0.54029 -0.89546 + 3 64 -2.47878 1.12874 1.15299 -0.77147 + 3 65 -0.57185 1.25142 0.49148 -0.86132 + 3 66 -1.89825 1.40863 0.74145 -0.81720 + 3 67 -1.19609 0.99028 0.87371 -0.77835 + 3 68 -1.30971 1.15524 0.93590 -0.96502 + 3 69 -1.82950 0.91579 1.10120 -0.73094 + 3 70 -1.45921 1.18143 0.93417 -0.94034 + 3 71 -1.23168 1.12933 0.84165 -0.89041 + 3 72 -0.92724 1.12992 0.69650 -0.83696 + 3 73 -0.64328 1.12635 0.58408 -0.82691 + 3 74 -1.03790 0.77751 0.82602 -0.59837 + 4 1 -1.01415 1.13057 -0.10130 -0.00279 + 4 2 0.19571 1.03825 -0.37489 0.00222 + 4 3 -0.75858 1.18733 -0.26252 0.00049 + 4 4 -0.91751 1.09002 -0.05602 -0.00393 + 4 5 -0.76217 1.17303 -0.23761 -0.00034 + 4 6 -2.08281 1.42394 0.07483 -0.01411 + 4 7 -1.65067 1.21187 0.12696 -0.01203 + 4 8 -1.44910 1.21317 0.05656 -0.01103 + 4 9 -1.53776 1.22277 0.07370 -0.01105 + 4 11 0.08109 1.02359 -0.13286 -0.01937 + 4 12 -0.17253 0.93262 -0.06979 -0.00362 + 4 13 -0.53040 1.06649 -0.02653 -0.01509 + 4 14 -0.34073 0.93385 -0.00541 -0.00887 + 4 15 -0.61972 1.08500 0.01951 -0.01992 + 4 16 -0.30132 0.98061 -0.08041 -0.00432 + 4 17 -0.76055 0.99058 0.16247 -0.02390 + 4 18 -0.25658 0.94608 0.01913 -0.01709 + 4 19 -0.45649 1.11026 0.00806 -0.03006 + 4 20 0.76285 1.11195 -0.57699 0.00151 + 4 21 0.63648 1.02056 -0.46689 0.00133 + 4 22 1.14511 0.89018 -0.47403 0.00044 + 4 23 0.39145 0.64832 -0.06867 0.00024 + 4 24 -0.46210 1.00827 -0.05495 -0.00800 + 4 25 -1.65093 1.45513 -0.09278 -0.01070 + 4 26 -3.24553 1.66477 0.26073 -0.02174 + 4 27 -2.20060 1.59101 -0.01881 -0.01677 + 4 28 -1.64898 1.37871 0.00863 -0.01789 + 4 29 -0.86430 1.52032 -0.38902 -0.01392 + 4 30 0.14605 0.97214 -0.30181 0.00062 + 4 31 -0.59812 1.18344 -0.26390 -0.00261 + 4 32 -0.26067 1.07529 -0.24647 -0.00247 + 4 33 -0.45038 1.11083 -0.20559 -0.00510 + 4 34 -0.39366 1.18780 -0.29432 -0.00560 + 4 35 -0.56300 1.08800 -0.11290 -0.01019 + 4 36 -0.29681 1.09084 -0.25079 -0.00274 + 4 37 -0.21526 1.09546 -0.22336 -0.00391 + 4 38 -0.81450 0.93914 0.08569 -0.00664 + 4 39 -0.27866 1.05042 -0.14702 -0.00708 + 4 40 -0.98972 0.79601 0.26898 -0.00676 + 4 41 0.13870 1.19107 -0.42287 -0.00357 + 4 42 -0.36821 1.08361 -0.10934 -0.01202 + 4 43 -1.75723 1.29674 0.12732 -0.01837 + 4 44 -0.47252 1.00076 -0.12132 -0.00527 + 4 45 -0.60121 1.04131 -0.11575 -0.00417 + 4 46 -0.04945 1.04677 -0.28123 -0.00492 + 4 47 -0.11230 0.95899 -0.19179 -0.00413 + 4 48 -2.16730 1.26089 0.17747 -0.00605 + 4 49 -0.93071 1.09308 0.02539 -0.00736 + 4 50 -1.37494 1.18087 0.17281 -0.01860 + 4 51 -1.16296 1.22287 0.00680 -0.01380 + 4 52 -1.24411 1.42226 -0.13251 -0.01535 + 4 53 -1.18741 1.23197 0.00127 -0.01328 + 4 54 -1.32187 1.21072 0.14201 -0.01988 + 4 55 -1.36427 1.30685 0.05129 -0.01929 + 4 56 -0.68544 1.05430 0.08432 -0.01826 + 4 57 -1.17915 1.19061 0.05974 -0.01533 + 4 58 -1.03076 0.92282 0.28820 -0.01412 + 4 59 -0.35193 0.97270 -0.10555 -0.00142 + 4 60 -0.33311 0.97851 -0.09940 -0.00289 + 4 61 -0.79528 1.08128 -0.03283 -0.00620 + 4 62 -1.06212 1.31276 -0.20142 -0.00409 + 4 63 -1.44200 1.18848 0.01268 -0.00459 + 4 64 -1.31323 1.16228 0.07066 -0.00913 + 4 65 -0.65458 1.03485 0.01356 -0.01265 + 4 66 -0.26371 1.18633 -0.35389 -0.00002 + 4 67 -0.27325 1.08607 -0.20263 -0.00477 + 4 68 0.12921 0.98918 -0.24353 -0.00271 + 4 69 -0.56578 0.98004 0.03349 -0.01122 + 4 70 -0.57709 1.06013 -0.02973 -0.01158 + 4 71 -0.61695 1.11083 -0.01824 -0.01986 + 4 72 -0.57910 1.10064 -0.09539 -0.00941 + 4 73 -0.94475 1.17300 0.00835 -0.01904 + 4 74 0.13638 1.09674 -0.35451 -0.00034 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.DAT new file mode 100755 index 000000000..c43b3017d --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.DAT @@ -0,0 +1,292 @@ + 1 1 -1.13947 1.29519 0.80892 -1.078402 + 1 2 -0.74859 1.26394 0.56369 -0.858056 + 1 3 -1.35747 1.36575 0.72553 -0.985071 + 1 4 -2.02677 1.22874 1.09238 -0.951477 + 1 5 -1.39976 1.42550 0.76996 -1.084186 + 1 6 -1.15610 1.21374 0.58347 -0.683531 + 1 7 -1.26059 1.17497 0.69732 -0.711232 + 1 8 -1.00155 1.13371 0.53333 -0.616055 + 1 9 -0.93910 1.13328 0.52582 -0.636857 + 1 11 -1.66534 1.30098 1.48878 -1.466917 + 1 12 -0.88770 0.46009 1.21167 -0.628101 + 1 13 -1.13999 0.97735 1.17199 -1.006358 + 1 14 -1.03751 0.90887 1.21552 -1.026753 + 1 15 -0.78185 1.06139 1.07022 -1.132957 + 1 16 -1.51276 0.31362 1.10404 -0.250486 + 1 17 -0.80305 1.19459 1.23416 -1.422010 + 1 18 -1.13650 1.08973 1.29519 -1.227845 + 1 19 -2.15445 1.29357 1.51256 -1.258901 + 1 20 0.09279 1.14718 0.61179 -1.083228 + 1 21 -0.18445 0.67855 0.71894 -0.653327 + 1 22 -0.30629 0.84846 0.79149 -0.864902 + 1 23 -0.49045 0.58797 0.87426 -0.626517 + 1 24 0.13421 0.79498 0.69582 -0.833817 + 1 25 -2.07614 1.49475 0.92421 -0.917545 + 1 26 -2.11392 1.67987 0.75399 -1.028539 + 1 27 -2.71800 1.64031 0.98111 -0.978512 + 1 28 -1.78207 1.38603 0.83243 -0.882750 + 1 29 -3.05475 1.62387 1.15103 -1.007257 + 1 30 -1.68994 1.35752 1.20544 -1.198791 + 1 31 -1.87751 1.21141 1.21622 -1.063033 + 1 32 -1.72653 1.32857 1.25328 -1.211603 + 1 33 -2.20912 0.92241 1.54263 -0.918394 + 1 34 -1.38124 1.12849 1.15740 -1.088905 + 1 35 -1.39491 0.89086 1.12413 -0.859435 + 1 36 -1.11868 0.85724 0.89992 -0.704807 + 1 37 -1.84365 1.14030 1.60668 -1.299890 + 1 38 -0.81914 1.02611 0.88873 -1.004762 + 1 39 -1.06608 1.09093 1.13078 -1.189142 + 1 40 -1.11108 0.67656 1.08380 -0.750308 + 1 41 -1.02105 0.56705 1.01772 -0.656126 + 1 42 -1.71088 0.75098 1.46142 -0.928564 + 1 43 -0.85057 1.48544 0.44703 -0.908026 + 1 44 -2.35657 0.75711 1.33205 -0.527444 + 1 45 -1.30644 1.40402 0.89584 -1.162374 + 1 46 -1.65202 0.93889 1.30451 -0.900843 + 1 47 -1.34914 1.17871 1.02582 -1.034819 + 1 48 -1.39710 1.27114 0.92305 -1.022608 + 1 49 -1.43905 1.12804 0.98300 -0.810915 + 1 50 -1.38088 1.36492 0.84870 -0.927448 + 1 51 -1.74359 1.48020 1.25801 -1.302871 + 1 52 -1.43406 1.66651 0.69747 -1.094846 + 1 53 -1.43158 1.44036 0.69682 -0.853708 + 1 54 -1.91408 1.35583 1.26445 -1.133451 + 1 55 -1.36958 1.63624 0.93494 -1.276703 + 1 56 -0.99477 1.52171 0.81636 -1.194593 + 1 57 -0.85976 1.28059 0.62549 -0.877235 + 1 58 -0.41747 1.02032 0.64882 -0.717148 + 1 59 -0.58155 1.02468 0.76942 -0.877423 + 1 60 -1.29586 0.83532 1.10397 -0.719305 + 1 61 0.15360 0.74491 0.48689 -0.641479 + 1 62 -0.61526 1.33256 0.70774 -1.151905 + 1 63 -0.92105 1.09921 0.93943 -1.037790 + 1 64 -1.49090 0.83105 1.19166 -0.764825 + 1 65 -1.05372 1.32331 0.93599 -1.170303 + 1 66 -2.23410 1.38767 1.48545 -1.243144 + 1 67 -0.66758 0.73200 0.93750 -0.730892 + 1 68 -0.67464 1.00353 1.00272 -1.059510 + 1 69 -1.09717 0.90688 1.27682 -1.081508 + 1 70 -1.23983 1.08717 1.30318 -1.229798 + 1 71 -1.28257 1.15321 1.29181 -1.257170 + 1 72 -0.91299 1.02270 0.97397 -0.961131 + 1 73 -0.74069 1.07265 0.86165 -0.967221 + 1 74 -0.22565 0.40806 0.63475 -0.343761 + 2 1 -1.59791 1.31762 0.77895 -0.916977 + 2 2 -1.05760 1.17422 0.52856 -0.629889 + 2 3 -1.88033 1.34295 0.78015 -0.836378 + 2 4 -2.89176 1.35882 1.12399 -0.837870 + 2 5 -1.31500 1.35713 0.56810 -0.852462 + 2 6 -1.53206 1.35692 0.47263 -0.606502 + 2 7 -1.25227 1.20678 0.49888 -0.582447 + 2 8 -1.25954 1.18670 0.47436 -0.531824 + 2 9 -1.37534 1.21091 0.50516 -0.547156 + 2 11 -1.62148 1.19557 1.21077 -1.169105 + 2 12 -1.40162 0.49846 1.27144 -0.592420 + 2 13 -1.30974 0.99979 1.11282 -0.977131 + 2 14 -1.24973 0.97373 1.15574 -1.016488 + 2 15 -0.65010 1.14059 0.87070 -1.109907 + 2 16 -1.51346 0.44508 1.06602 -0.377176 + 2 17 -0.72308 1.17906 1.00185 -1.272722 + 2 18 -1.36739 1.07952 1.20867 -1.121422 + 2 19 -1.33358 1.21246 1.01879 -1.084498 + 2 20 -0.40385 1.14260 0.72315 -1.013745 + 2 21 -0.48544 0.78168 0.74818 -0.691697 + 2 22 -0.59331 0.95214 0.82672 -0.898751 + 2 23 -0.77945 0.59457 0.95170 -0.629834 + 2 24 -0.67177 0.45576 1.01108 -0.544495 + 2 25 -1.99876 1.47104 0.70415 -0.758712 + 2 26 -2.21115 1.72374 0.52530 -0.826678 + 2 27 -2.55253 1.70224 0.67572 -0.826642 + 2 28 -1.44317 1.40955 0.47140 -0.704107 + 2 29 -2.98922 1.65339 0.91675 -0.859344 + 2 30 -2.29493 1.28217 1.12910 -0.920599 + 2 31 -2.22453 1.24689 1.16335 -0.989809 + 2 32 -1.76877 1.40916 0.96101 -1.081500 + 2 33 -2.57251 1.06281 1.46165 -0.961417 + 2 34 -1.54363 1.22064 1.01490 -1.050422 + 2 35 -2.26072 0.95950 1.42294 -0.953524 + 2 36 -1.63539 0.97763 0.96871 -0.728444 + 2 37 -2.83769 1.33989 1.66235 -1.302849 + 2 38 -1.79797 0.98643 1.17117 -0.900199 + 2 39 -1.47995 1.10731 1.22514 -1.172799 + 2 40 -0.23795 0.63491 0.66504 -0.643331 + 2 41 -4.39674 0.75902 2.22264 -0.794632 + 2 42 -0.90683 0.79583 1.08236 -0.959739 + 2 43 -0.58255 1.47658 0.14111 -0.711797 + 2 44 -1.85537 1.02586 1.02990 -0.759059 + 2 45 -1.60233 1.35576 0.74996 -0.900657 + 2 46 -1.75570 1.05812 1.05096 -0.826175 + 2 47 -1.11913 1.16349 0.76807 -0.900039 + 2 48 -3.31421 1.27885 1.45633 -0.895244 + 2 49 -1.40409 1.21223 0.83144 -0.806091 + 2 50 -1.19006 1.29425 0.61125 -0.732663 + 2 51 -2.35710 1.49560 1.16893 -1.092018 + 2 52 -1.50536 1.62169 0.56804 -0.924333 + 2 53 -1.21410 1.35183 0.45232 -0.644269 + 2 54 -1.97532 1.35987 1.01066 -0.935108 + 2 55 -1.47431 1.57204 0.70468 -1.003779 + 2 56 -1.11974 1.33676 0.71965 -0.897503 + 2 57 -1.15163 1.26521 0.63247 -0.767059 + 2 58 -0.49179 1.00574 0.55729 -0.622137 + 2 59 -0.57577 1.00621 0.71281 -0.818325 + 2 60 -1.15277 0.98598 0.85296 -0.725060 + 2 61 -2.26969 1.02570 1.41063 -0.916847 + 2 62 -0.11620 1.54400 0.40496 -1.237444 + 2 63 -1.40814 1.31482 0.97245 -1.121743 + 2 64 -3.34160 0.98631 1.62570 -0.734078 + 2 65 -1.10917 1.30390 0.80441 -1.033888 + 2 66 -2.18796 1.44571 1.09515 -1.054597 + 2 67 -0.87609 0.82712 0.90433 -0.746931 + 2 68 -1.16582 1.13979 1.02613 -1.067515 + 2 69 -1.82535 0.88286 1.38296 -0.946006 + 2 70 -1.31788 1.12954 1.07369 -1.070565 + 2 71 -0.68460 1.15735 0.86953 -1.128654 + 2 72 -1.31422 1.07910 0.98189 -0.915435 + 2 73 -0.32988 1.11186 0.56973 -0.907578 + 2 74 -0.66061 0.61593 0.75539 -0.499285 + 3 1 -1.35434 1.31639 0.54148 -0.767875 + 3 2 -0.60071 1.23949 0.26609 -0.606176 + 3 3 -1.90165 1.21234 0.63809 -0.577350 + 3 4 -1.14145 1.27329 0.50450 -0.742468 + 3 5 -1.39587 1.29817 0.54922 -0.739616 + 3 6 -1.33784 1.43864 0.23586 -0.525558 + 3 7 -1.01077 1.27303 0.24446 -0.482783 + 3 8 -0.55350 1.28352 0.06239 -0.461153 + 3 9 -0.96285 1.28837 0.20801 -0.477025 + 3 11 -1.68926 1.09301 1.02238 -0.871401 + 3 12 -1.60540 0.52292 1.18085 -0.497024 + 3 13 -0.70396 1.00700 0.77552 -0.883716 + 3 14 -0.95932 1.01606 0.91379 -0.943480 + 3 15 -0.87661 1.12327 0.76235 -0.916871 + 3 16 -0.82951 0.52736 0.77421 -0.408932 + 3 17 -0.51480 1.13104 0.69612 -0.998074 + 3 18 -0.75316 1.01469 0.82560 -0.916976 + 3 19 -0.48869 1.12685 0.56415 -0.843545 + 3 20 -0.43270 1.13741 0.65036 -0.942949 + 3 21 0.34135 0.93305 0.37537 -0.751182 + 3 22 -0.47145 1.00455 0.69423 -0.866361 + 3 23 -1.49683 0.68739 1.09199 -0.648514 + 3 24 -1.74897 0.62746 1.23089 -0.613443 + 3 25 -1.84766 1.47945 0.47559 -0.618227 + 3 26 -2.18052 1.72841 0.34729 -0.660884 + 3 27 -2.07333 1.69843 0.35734 -0.670517 + 3 28 -1.19061 1.44137 0.23941 -0.589887 + 3 29 -2.21106 1.62257 0.42375 -0.614446 + 3 30 -1.32735 1.21938 0.62462 -0.737825 + 3 31 -1.40314 1.21856 0.70549 -0.828002 + 3 32 -1.33013 1.40863 0.61381 -0.917700 + 3 33 -1.34649 1.10660 0.86232 -0.889482 + 3 34 -1.19719 1.26752 0.73600 -0.964922 + 3 35 -1.35755 0.96608 0.93966 -0.837886 + 3 36 -1.24642 1.08048 0.70553 -0.722816 + 3 37 -3.00359 1.40192 1.42757 -1.156743 + 3 38 -0.88021 0.88938 0.78480 -0.758075 + 3 39 -1.14614 1.04005 0.99414 -1.015338 + 3 40 0.64573 0.75330 0.43118 -0.794768 + 3 41 -1.50143 0.72660 1.03813 -0.667019 + 3 42 -0.50716 0.85375 0.91900 -0.983598 + 3 43 -1.24099 1.46844 0.36760 -0.707210 + 3 44 -1.31396 1.11565 0.71517 -0.747214 + 3 45 -1.18124 1.31891 0.46011 -0.734367 + 3 46 -1.36651 1.13084 0.69270 -0.715833 + 3 47 0.16552 0.97678 0.27239 -0.661120 + 3 48 -1.02971 1.33009 0.44715 -0.776619 + 3 49 -0.38204 1.29752 0.36421 -0.774169 + 3 50 -0.84888 1.26326 0.38504 -0.603956 + 3 51 -2.01280 1.47897 0.83150 -0.906653 + 3 52 -1.17944 1.54297 0.34638 -0.748543 + 3 53 -0.90683 1.31054 0.25185 -0.522746 + 3 54 -0.79060 1.32674 0.39117 -0.707758 + 3 55 -0.68244 1.48628 0.26174 -0.763433 + 3 56 -0.57924 1.21073 0.42555 -0.678929 + 3 57 -0.77917 1.24347 0.39030 -0.638943 + 3 58 0.05238 0.98396 0.25769 -0.495336 + 3 59 -0.68264 1.01375 0.61663 -0.695762 + 3 60 -0.77907 1.03404 0.61753 -0.683363 + 3 61 0.41273 1.05345 0.16834 -0.664175 + 3 62 -1.59313 1.65091 0.69136 -1.111374 + 3 63 -0.74436 1.20843 0.59984 -0.905285 + 3 64 -2.88195 1.11401 1.23376 -0.704062 + 3 65 -0.59424 1.25384 0.49804 -0.862705 + 3 66 -1.66623 1.42627 0.72686 -0.896241 + 3 67 -1.04658 0.89758 0.83200 -0.701456 + 3 68 -1.77098 1.20616 1.06896 -0.992733 + 3 69 -1.81723 0.90400 1.13961 -0.764595 + 3 70 -1.37978 1.10223 0.95526 -0.914064 + 3 71 -1.10705 1.06485 0.86659 -0.894121 + 3 72 -0.99012 1.11664 0.73449 -0.841563 + 3 73 -0.70415 1.12929 0.60332 -0.828445 + 3 74 -0.94460 0.70283 0.77740 -0.518897 + 4 1 -0.93491 1.13536 -0.13497 -0.002067 + 4 2 0.19201 1.05053 -0.38790 0.002400 + 4 3 -0.75953 1.19731 -0.27357 0.000632 + 4 4 -0.77162 1.09200 -0.10796 -0.002973 + 4 5 -0.75463 1.18236 -0.25023 -0.000156 + 4 6 -2.11033 1.42655 0.07933 -0.013951 + 4 7 -1.65448 1.22335 0.11804 -0.012143 + 4 8 -1.46165 1.22812 0.04755 -0.011250 + 4 9 -1.55221 1.22975 0.07010 -0.010910 + 4 11 0.07957 1.01419 -0.12713 -0.018938 + 4 12 -0.15654 0.92925 -0.07175 -0.003532 + 4 13 -0.51214 1.06110 -0.03086 -0.014527 + 4 14 -0.33215 0.93333 -0.00958 -0.008539 + 4 15 -0.55434 1.07993 0.00654 -0.020130 + 4 16 -0.29192 0.98030 -0.08573 -0.003967 + 4 17 -0.67987 0.96526 0.15687 -0.023228 + 4 18 -0.23268 0.93543 0.01855 -0.016573 + 4 19 -0.41986 1.10323 -0.00033 -0.029521 + 4 20 0.70586 1.11416 -0.56598 0.001502 + 4 21 0.67335 1.02829 -0.48802 0.001762 + 4 22 1.15283 0.92487 -0.51071 0.000867 + 4 23 0.38552 0.64599 -0.06760 0.000407 + 4 24 -0.42098 1.01148 -0.07373 -0.007493 + 4 25 -1.63209 1.45563 -0.10187 -0.010381 + 4 26 -3.29611 1.66996 0.26890 -0.021454 + 4 27 -2.08824 1.57525 -0.04639 -0.015636 + 4 28 -1.71593 1.36842 0.04224 -0.018621 + 4 29 -0.93599 1.52956 -0.37643 -0.013927 + 4 30 0.18381 0.98873 -0.33158 0.000973 + 4 31 -0.55336 1.17445 -0.27319 -0.002189 + 4 32 -0.21280 1.07158 -0.26257 -0.001832 + 4 33 -0.50208 1.13543 -0.21158 -0.005439 + 4 34 -0.36407 1.21057 -0.32617 -0.005270 + 4 35 -0.65687 1.13631 -0.12545 -0.010593 + 4 36 -0.27970 1.10414 -0.27165 -0.002363 + 4 37 -0.16757 1.09148 -0.23622 -0.003499 + 4 38 -0.82275 0.93273 0.09041 -0.006320 + 4 39 -0.25079 1.05308 -0.16222 -0.006440 + 4 40 -0.93352 0.72921 0.30169 -0.005305 + 4 41 0.14207 1.20091 -0.43406 -0.003390 + 4 42 -0.37727 1.08324 -0.10866 -0.011749 + 4 43 -1.77615 1.27519 0.14559 -0.017477 + 4 44 -0.41899 1.01050 -0.15627 -0.004336 + 4 45 -0.50851 1.04253 -0.15044 -0.003387 + 4 46 0.03372 1.02694 -0.29603 -0.003914 + 4 47 -0.13870 0.97469 -0.19980 -0.004087 + 4 48 -2.35090 1.29543 0.20936 -0.007438 + 4 49 -0.88805 1.08428 0.01644 -0.006918 + 4 50 -1.36258 1.17866 0.16938 -0.018373 + 4 51 -1.06913 1.22054 -0.02150 -0.013310 + 4 52 -1.24701 1.41560 -0.12665 -0.015207 + 4 53 -1.16728 1.22409 -0.00026 -0.012882 + 4 54 -1.26078 1.19939 0.13247 -0.019567 + 4 55 -1.38891 1.30252 0.06784 -0.019906 + 4 56 -0.65867 1.04314 0.08335 -0.017808 + 4 57 -1.19903 1.18861 0.06813 -0.015397 + 4 58 -1.04571 0.92771 0.29040 -0.014402 + 4 59 -0.29405 0.97319 -0.12213 -0.001270 + 4 60 -0.26651 0.97072 -0.11520 -0.002425 + 4 61 -0.94627 1.10014 0.01171 -0.008200 + 4 62 -0.97718 1.32568 -0.24328 -0.003401 + 4 63 -1.46274 1.18778 0.01499 -0.004264 + 4 64 -1.49116 1.16650 0.11274 -0.008925 + 4 65 -0.65797 1.03191 0.01101 -0.011821 + 4 66 -0.27560 1.20275 -0.36753 0.000090 + 4 67 -0.26436 1.08695 -0.20901 -0.004462 + 4 68 0.17169 0.99572 -0.26660 -0.002174 + 4 69 -0.54207 0.97380 0.03128 -0.010992 + 4 70 -0.58987 1.04080 -0.01235 -0.011051 + 4 71 -0.52763 1.05773 -0.00231 -0.018812 + 4 72 -0.54319 1.10426 -0.11435 -0.008779 + 4 73 -0.94124 1.17361 0.00660 -0.019031 + 4 74 0.13959 1.09619 -0.35534 -0.000300 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.COE new file mode 100755 index 000000000..a9da9339c --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.COE @@ -0,0 +1,16 @@ +AC -2.1298 7.4955 -10.9712 0.6848 -1.1240 -0.1668 +AT -4.5111 8.3547 -2.5839 0.5583 -0.2699 0.0166 +B -4.2025 11.2235 -33.0270 0.1246 -0.2318 -0.1259 +C -2.2326 5.7695 -8.9840 0.7684 -1.1459 -0.3687 +D -1.0655 13.4481 -35.0000 0.3928 -1.8258 0.7978 +E -2.8728 8.4563 -15.9861 1.0717 -1.5619 -0.1889 +F -3.3221 19.0987 -35.0000 0.8225 -1.3213 -0.3497 +H -3.7249 6.3475 -12.5810 1.2485 -1.2350 -0.4361 +L -0.7816 17.8208 -35.0000 -0.0372 -1.2770 0.1230 +MB -2.5076 21.1132 -35.0000 0.8467 -1.8301 -0.1579 +PA 0.9206 30.0000 -1.4774 0.0492 -1.7615 -0.0358 +PL -5.0293 12.0594 -25.8179 0.4772 -0.3402 0.0160 +PW -2.0972 12.8672 -25.9435 0.9650 -1.7632 -0.1159 +PY -3.4939 25.8580 -35.0000 0.8321 -1.6933 -0.5520 +S -3.8592 18.1570 -35.0000 0.9571 -1.3053 -0.3328 +Y 3.4204 11.4815 -1.4716 0.1994 -2.0358 -0.4266 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.DAT new file mode 100755 index 000000000..e89b58849 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.DAT @@ -0,0 +1,16 @@ +AC -1.8280 6.7661 -7.8486 0.6502 -1.0880 -0.1639 +AT -4.5186 8.3855 -2.4233 0.5759 -0.2678 0.0126 +B -4.1959 11.2350 -35.0000 0.1114 -0.2242 -0.1144 +C -1.9906 5.5317 -8.3336 0.7467 -1.1530 -0.4021 +D -0.9574 12.2811 -30.3128 0.4818 -1.9218 0.8826 +E -2.8809 8.3122 -15.9250 1.0821 -1.5635 -0.1800 +F -3.2656 19.0887 -35.0000 0.8239 -1.3222 -0.4011 +H -3.6132 6.3346 -12.9181 1.2059 -1.2086 -0.4723 +L -0.7255 16.9990 -35.0000 0.0405 -1.3386 0.0687 +MB -3.2433 19.8320 -35.0000 0.9567 -1.6877 -0.2623 +PA 0.8306 30.0000 -1.4762 0.0578 -1.7545 0.0041 +PL -5.0379 11.8658 -25.1408 0.4961 -0.3473 0.0054 +PW -2.0988 12.4629 -25.0386 0.9849 -1.7651 -0.1316 +PY -2.9342 30.0000 -35.0000 0.4224 -1.4683 -0.4640 +S -3.8309 17.5417 -35.0000 0.9652 -1.3088 -0.3423 +Y 3.5149 11.7525 -1.4054 0.2226 -2.0778 -0.4728 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.COE new file mode 100755 index 000000000..970cf0407 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.COE @@ -0,0 +1,32 @@ +AC C 1.00160 0.20508-0.0013743 +AC I 1.00337 0.26975-0.0012802 +AT C 0.98946 0.15312-0.0013087 +AT I 0.98946 0.15312-0.0013087 +B C 0.97183 0.18096-0.0018580 +B I 0.95942 0.31474-0.0011697 +C C 0.99412 0.18010-0.0021747 +C I 1.01352 0.43532-0.0009144 +D C 1.00358 0.09603-0.0038217 +D I 1.00358 0.09603-0.0038217 +E C 1.01384 0.13520-0.0031488 +E I 1.01384 0.13520-0.0031488 +F C 0.99518 0.18193-0.0017202 +F I 0.98020 0.24054-0.0016229 +H C 0.96537 0.16792-0.0011664 +H I 0.99065 0.29502-0.0012500 +L C 0.99315 0.17747-0.0022617 +L I 0.99315 0.17747-0.0022617 +MB C 0.99951 0.11329-0.0068948 +MB I 0.99951 0.11329-0.0068948 +PA C 0.99952 0.20278-0.0020051 +PA I 0.99952 0.20278-0.0020051 +PL C 0.95856 0.13349-0.0009818 +PL I 0.97312 0.17339-0.0010287 +PW C 0.98775 0.17671-0.0029754 +PW I 0.98775 0.17671-0.0029754 +PY C 0.95955 0.17742-0.0019664 +PY I 0.95955 0.17742-0.0019664 +S C 0.99424 0.12502-0.0020471 +S I 0.97776 0.25630-0.0014480 +Y C 0.97184 0.24781-0.0014371 +Y I 0.97184 0.24781-0.0014371 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.DAT new file mode 100755 index 000000000..6a9a1fed8 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.DAT @@ -0,0 +1,32 @@ +AC C 1.00416 0.19358-0.0016424 REGYHLP.dat SEQ 050 +AC I 1.00740 0.25581-0.0013697 HL Primary Sp Eqn P1 +AT C 1.00000 0.15743-0.0014972 +AT I 1.00000 0.15743-0.0014972 +B C 1.13650 0.32035-0.0030708 +B I 1.05050 0.34948-0.0018378 +C C 1.17279 0.36437-0.0028910 +C I 1.12866 0.29913-0.0044024 +D C 1.01075 0.09816-0.0044014 +D I 1.01075 0.09816-0.0044014 +E C 1.02060 0.14030-0.0034212 +E I 1.02060 0.14030-0.0034212 +F C 1.03116 0.19819-0.0025365 +F I 1.06942 0.27843-0.0026998 +H C 1.19700 0.33880-0.0047977 +H I 1.04807 0.31736-0.0016795 +L C 1.05922 0.22643-0.0035548 +L I 1.05922 0.22643-0.0035548 +MB C 1.10712 0.24515-0.0055001 +MB I 1.10712 0.24515-0.0055001 +PA C 1.01000 0.20000-0.0022471 +PA I 1.01333 0.20399-0.0023066 +PL C 1.00000 0.16441-0.0016021 +PL I 1.00000 0.18264-0.0015008 +PW C 1.05287 0.21791-0.0049228 +PW I 1.05287 0.21791-0.0049228 +PY I 1.11685 0.27809-0.0062194 +PY C 1.11685 0.27809-0.0062194 +S C 1.07788 0.18841-0.0054762 +S I 1.08250 0.29300-0.0036091 +Y C 1.13713 0.33402-0.0028200 +Y I 1.13713 0.33402-0.0028200 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.COE new file mode 100755 index 000000000..7874b2c5b --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.COE @@ -0,0 +1,32 @@ +AC C 0.49722 1.18403 +AC I 0.49786 1.18373 +AT C 0.74327 1.06260 +AT I 0.74327 1.06260 +B C 0.61932 1.10093 +B I 0.47521 1.15928 +C C 0.65398 1.10534 +C I 0.39440 1.24410 +D C 0.74653 1.06913 +D I 0.74653 1.06913 +E C 0.65675 1.10988 +E I 0.65675 1.10988 +F C 0.50869 1.16396 +F I 0.50103 1.16718 +H C 0.53213 1.14524 +H I 0.42947 1.20298 +L C 0.44511 1.21520 +L I 0.44511 1.21520 +MB C 1.22757 0.92088 +MB I 1.22757 0.92088 +PA C 0.54033 1.17527 +PA I 0.54033 1.17527 +PL C 0.56534 1.14516 +PL I 0.57635 1.13539 +PW C 0.83979 1.01907 +PW I 0.83979 1.01907 +PY C 0.56488 1.15354 +PY I 0.56488 1.15354 +S C 0.64097 1.10811 +S I 0.44745 1.20038 +Y C 0.70275 1.07949 +Y I 0.70275 1.07949 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.DAT new file mode 100755 index 000000000..ae353f9f0 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.DAT @@ -0,0 +1,32 @@ +AC C 0.53045 1.16703 REGYHLPA.dat SEQ 051 +AC I 0.56063 1.15260 HL Primary SP Eqn P2 +AT C 0.74213 1.06387 +AT I 0.74213 1.06387 +B C 0.45680 1.20595 +B I 0.45395 1.18480 +C C 1.12784 0.98658 +C I 0.86370 1.03716 +D C 0.77062 1.06028 +D I 0.77062 1.06028 +E C 0.67916 1.09911 +E I 0.67916 1.09911 +F C 0.52557 1.15946 +F I 0.65980 1.09707 +H C 0.60826 1.11981 +H I 0.44050 1.20440 +L C 0.47803 1.20255 +L I 0.47803 1.20255 +MB C 0.85363 1.05055 +MB I 0.85363 1.05055 +PA C 0.90000 1.00938 +PA I 0.57467 1.15650 +PL C 0.58098 1.13630 +PL I 0.58855 1.12942 +PW C 1.14817 0.93157 +PW I 1.14817 0.93157 +PY I 1.09727 0.96642 +PY C 1.09727 0.96642 +S C 0.69605 1.09280 +S I 0.50069 1.17594 +Y C 0.82053 1.07048 +Y I 0.82053 1.07048 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPB.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPB.DAT new file mode 100755 index 000000000..902dc1f97 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPB.DAT @@ -0,0 +1,32 @@ +AC C 1.04422 0.93010 -0.05745 -2.50000 REGYHLPB.dat SEQ 052 +AC I 1.08347 0.29949 -0.33001 -2.50000 HL Primary Sp Eqn P3 +AT C 1.09735 0.21789 -0.85538 -2.50000 +AT I 1.09735 0.21789 -0.85538 -2.50000 +B C 1.28658 0.47007 -0.35452 -2.02799 +B I 1.05021 0.31050 -0.48195 -2.50000 +C C 1.10770 0.06834 -0.01255 -0.25000 +C I 1.00000 0.00000 -0.29935 -2.46392 +D C 1.08103 0.15523 -1.36281 -2.50000 +D I 1.08103 0.15523 -1.36281 -2.50000 +E C 1.19530 0.30081 -1.34623 -2.50000 +E I 1.19530 0.30081 -1.34623 -2.50000 +F C 1.10375 0.26035 -0.59965 -2.50000 +F I 1.14083 0.33109 -0.31741 -1.92636 +H C 1.03865 0.27862 -0.17445 -2.31017 +H I 1.00000 0.29192 -0.19701 -2.50000 +L C 1.17454 0.34914 -0.84813 -2.50000 +L I 1.17454 0.34914 -0.84813 -2.50000 +MB C 1.17116 0.52884 -0.09678 -1.69323 +MB I 1.17116 0.52884 -0.09678 -1.69323 +PA C 1.11079 0.30000 -0.12000 -1.80000 +PA I 1.05175 0.24162 -0.14862 -2.21900 +PL C 1.00000 0.16965 -0.33130 -2.50000 +PL I 1.04499 0.21652 -0.44848 -2.46304 +PW C 1.38894 0.53379 -0.47547 -1.24465 +PW I 1.38894 0.53379 -0.47547 -1.24465 +PY I 1.48023 0.68433 -0.15697 -1.01647 +PY C 1.48023 0.68433 -0.15697 -1.01647 +S C 1.17613 0.31336 -0.14412 -1.62791 +S I 1.18509 0.42282 -0.33694 -1.99774 +Y C 1.15153 1.00000 -0.01146 -1.44943 +Y I 1.15153 1.00000 -0.01146 -1.44943 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPC.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPC.COE new file mode 100755 index 000000000..78994778d --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPC.COE @@ -0,0 +1,32 @@ +AC C 0.42795 1.23429 -0.000222 +AC I 0.45294 1.21886 -0.000212 +AT C 0.67048 1.11015 -0.000533 +AT I 0.67048 1.11015 -0.000533 +B C 0.61219 1.08879 0.000297 +B I 0.47559 1.15888 0.000004 +C C 0.70572 1.07551 0.000122 +C I 0.43012 1.21592 0.000045 +D C 0.75997 1.05914 0.000159 +D I 0.75997 1.05914 0.000159 +E C 0.63341 1.13056 -0.000477 +E I 0.63341 1.13056 -0.000477 +F C 0.49366 1.17506 -0.000051 +F I 0.47106 1.19155 -0.000185 +H C 0.56066 1.12123 0.000171 +H I 0.46741 1.16489 0.000293 +L C 0.41264 1.25140 -0.000652 +L I 0.41264 1.25140 -0.000652 +MB C 0.85549 1.05506 -0.001084 +MB I 0.85549 1.05506 -0.001084 +PA C 0.52773 1.20583 -0.000766 +PA I 0.52773 1.20583 -0.000766 +PL C 0.54347 1.16469 -0.000220 +PL I 0.53915 1.18054 -0.000770 +PW C 0.60264 1.14541 -0.001314 +PW I 0.60264 1.14541 -0.001314 +PY C 0.53843 1.18156 -0.000624 +PY I 0.53843 1.18156 -0.000624 +S C 0.62887 1.11842 -0.000073 +S I 0.41516 1.23774 -0.000485 +Y C 0.70843 1.06665 0.000215 +Y I 0.70843 1.06665 0.000215 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIAGEMAX.PRM b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIAGEMAX.PRM new file mode 100755 index 000000000..29a573136 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIAGEMAX.PRM @@ -0,0 +1,3 @@ + -1 140.0 140.0 20.0 60.0 +999 End of usuable info + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIEQN.PRM b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIEQN.PRM new file mode 100755 index 000000000..0aa0b037c --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIEQN.PRM @@ -0,0 +1,4 @@ + + +## Start of unrestricted comments + diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0.DAT new file mode 100755 index 000000000..334ab7396 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0.DAT @@ -0,0 +1,16 @@ +AC +AT +B +C +D +E +F +H +L +MB +PA +PL +PW +PY +S +Y diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF.DAT new file mode 100755 index 000000000..e911a06eb --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF.DAT @@ -0,0 +1,16 @@ +AC Cottonwood SP0DEF.dat (Seq 010) +AT Aspen +B Balsam +C Cedar (X yellow) +D Alder +E Birch +F Douglas Fir +H Hemlock +L Larch +MB Maple +PA White-bark pine +PL Lodgepole Pine +PW White pine +PY Yellow pine +S Spruce +Y Yellow cedar diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF_v0.dat b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF_v0.dat new file mode 100755 index 000000000..ed3f522d6 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF_v0.dat @@ -0,0 +1,16 @@ +AC Cottonwood 01 SP0DEF_v0.dat (Seq 010) JWF 4/15/2019 +AT Aspen 02 cc 1-2 species code, +B Balsam 03 1 or 2 upper case +C Cedar (X yellow) 04 letters, left justified. +D Alder 05 4-35 Species name, left +E Birch 06 justified. +F Douglas Fir 07 37-38 Preference order for primary +H Hemlock 08 species, integer value or blank +L Larch 09 or zero, right justified. +MB Maple 10 Either all the integers +PA White-bark pine 11 1-16 must be assigned or +PL Lodgepole Pine 12 no assignments should be +PW White pine 13 given (use 0 or blank for all). +PY Yellow pine 14 +S Spruce 15 +Y Yellow cedar 16 \ No newline at end of file diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP309.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP309.COE new file mode 100755 index 000000000..fb086ad29 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP309.COE @@ -0,0 +1,79 @@ + 1 76.5 78.2 + 11 50.0 35.6 + 12 49.3 32.5 + 13 54.2 32.6 + 14 51.3 32.5 + 21 108.7 60.6 + 22 103.2 64.4 + 23 64.3 38.0 + 24 67.6 39.4 + 25 69.9 37.9 + 26 72.1 39.9 + 27 73.1 43.3 + 31 150.5 71.0 + 32 167.3 79.0 + 33 127.3 72.7 + 34 207.0 105.4 + 35 100.5 48.3 + 41 51.3 32.0 + 42 42.5 32.8 + 51 126.8 62.8 + 52 94.9 60.3 + 53 62.2 40.1 + 54 67.0 39.9 + 55 74.6 41.5 + 56 67.6 38.8 + 57 46.8 43.7 + 58 55.3 32.5 + 60 57.3 42.1 + 61 92.5 43.9 + 62 68.9 38.5 + 63 79.3 34.2 + 71 111.2 70.9 + 72 101.2 61.9 + 73 109.5 59.3 + 74 110.3 59.3 + 75 104.1 60.4 + 76 89.7 53.5 + 77 88.5 52.5 + 78 89.1 54.4 + 79 75.4 37.9 + 80 95.0 55.1 + 91 64.6 36.2 + 92 58.8 42.4 +101 72.8 30.7 +111 88.7 25.9 +112 55.4 28.2 +113 62.8 32.3 +114 50.7 32.0 +115 64.9 28.6 +116 65.5 30.9 +117 70.1 27.4 +118 64.4 29.9 +119 52.3 25.1 +120 57.9 27.7 +121 58.0 24.2 +122 58.8 28.2 +123 64.7 32.4 +131 69.1 33.6 +141 43.7 52.5 +151 133.2 94.8 +152 52.8 28.2 +153 54.6 29.8 +154 57.1 32.7 +155 57.9 40.8 +156 56.5 32.6 +157 61.7 40.9 +158 60.0 37.9 +159 61.1 42.1 +160 59.1 34.6 +161 58.9 40.6 +162 81.3 47.0 +163 69.4 43.3 +164 67.7 38.8 +165 65.7 34.1 +166 78.9 47.0 +167 78.3 52.8 +168 69.0 48.6 +169 63.5 45.2 +171 125.7 51.3 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP98.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP98.COE new file mode 100755 index 000000000..7e358c040 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP98.COE @@ -0,0 +1,79 @@ + 1 65.7 37.5 + 11 49.3 33.9 + 12 51.3 31.5 + 13 54.4 32.4 + 14 50.9 32.0 + 21 106.4 58.3 + 22 102.0 57.8 + 23 64.8 37.0 + 24 68.8 38.9 + 25 69.5 37.1 + 26 70.6 39.8 + 27 73.6 43.3 + 31 147.2 70.1 + 32 167.4 79.2 + 33 127.6 72.2 + 34 207.4 105.7 + 35 103.8 47.3 + 41 49.7 31.9 + 42 44.4 31.0 + 51 115.7 55.8 + 52 95.6 51.1 + 53 64.1 38.8 + 54 66.7 39.7 + 55 74.5 41.6 + 56 67.3 38.7 + 57 48.5 39.6 + 58 54.3 32.5 + 60 58.1 41.6 + 61 89.3 48.0 + 62 72.3 36.1 + 63 78.9 33.9 + 71 122.5 63.5 + 72 98.3 56.4 + 73 104.4 56.6 + 74 111.9 58.3 + 75 102.6 59.1 + 76 90.4 53.3 + 77 87.3 47.6 + 78 86.2 53.5 + 79 72.6 36.6 + 80 93.8 54.8 + 91 69.4 32.9 + 92 57.7 38.5 +101 72.3 30.8 +111 74.9 24.0 +112 55.0 27.6 +113 62.7 32.1 +114 49.9 31.7 +115 65.6 28.8 +116 65.5 30.7 +117 58.1 27.0 +118 62.8 29.8 +119 49.5 25.2 +120 53.2 27.0 +121 52.0 23.9 +122 60.3 27.6 +123 64.1 28.9 +131 76.6 31.8 +141 45.5 52.1 +151 142.6 76.7 +152 52.8 28.2 +153 54.6 29.8 +154 57.2 32.7 +155 57.6 40.7 +156 56.8 32.6 +157 61.4 40.7 +158 60.2 37.7 +159 61.3 41.2 +160 59.6 34.4 +161 59.0 40.2 +162 81.4 47.1 +163 69.6 42.8 +164 69.0 38.7 +165 64.2 33.9 +166 83.6 44.8 +167 70.5 49.7 +168 68.7 46.7 +169 63.6 45.5 +171 132.8 50.8 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/UPPERB02.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/UPPERB02.COE new file mode 100755 index 000000000..d4c6b28a7 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/UPPERB02.COE @@ -0,0 +1,32 @@ +AC C 109.27 96.0 +AC I 76.02 81.7 +AT C 50.93 32.3 +AT I 50.93 32.3 +B C 104.00 60.4 +B I 69.15 39.0 +C C 150.85 71.1 +C I 159.18 83.0 +D C 61.68 39.4 +D I 61.68 39.4 +E C 46.45 32.1 +E I 46.45 32.1 +F C 117.61 58.7 +F I 68.53 40.8 +H C 106.68 61.1 +H I 89.47 53.9 +L C 62.00 37.7 +L I 62.00 37.7 +MB C 63.33 49.3 +MB I 63.33 49.3 +PA C 74.10 30.7 +PA I 74.10 30.7 +PL C 61.24 30.0 +PL I 61.24 30.0 +PW C 69.03 33.6 +PW I 69.03 33.6 +PY C 44.43 51.8 +PY I 44.43 51.8 +S C 133.49 95.0 +S I 63.78 40.3 +Y C 127.34 50.6 +Y I 127.34 50.6 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI1.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI1.DAT new file mode 100755 index 000000000..f232e90f1 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI1.DAT @@ -0,0 +1,128 @@ +082E082 1 1997 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1997 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1997 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1997 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1997 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1997 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1997 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1997 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1997 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1997 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1997 +082E082 1 1998 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1998 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1998 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1998 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1998 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1998 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1998 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1998 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1998 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1998 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1998 +082E082 1 1999 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1999 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1999 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1999 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1999 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1999 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1999 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1999 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1999 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1999 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1999 +082E082 1 2000 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 2000 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 2000 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 2000 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 2000 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 2000 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 2000 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 2000 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 2000 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 2000 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 2000 +082E082 2 1997 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1997 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1997 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1997 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1997 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1997 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1997 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1997 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1997 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1997 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1997 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1997 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 +082E082 2 1998 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1998 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1998 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1998 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1998 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1998 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1998 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1998 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1998 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1998 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1998 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1998 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 +082E082 2 1999 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1999 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1999 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1999 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1999 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1999 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1999 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1999 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1999 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1999 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1999 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1999 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 +082E082 2 2000 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 2000 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 2000 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 2000 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 2000 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 2000 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 2000 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 2000 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 2000 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 2000 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 2000 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 2000 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI2.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI2.DAT new file mode 100755 index 000000000..f232e90f1 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI2.DAT @@ -0,0 +1,128 @@ +082E082 1 1997 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1997 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1997 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1997 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1997 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1997 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1997 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1997 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1997 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1997 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1997 +082E082 1 1998 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1998 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1998 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1998 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1998 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1998 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1998 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1998 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1998 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1998 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1998 +082E082 1 1999 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1999 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1999 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1999 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1999 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1999 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1999 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1999 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1999 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1999 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1999 +082E082 1 2000 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 2000 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 2000 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 2000 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 2000 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 2000 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 2000 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 2000 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 2000 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 2000 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 2000 +082E082 2 1997 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1997 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1997 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1997 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1997 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1997 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1997 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1997 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1997 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1997 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1997 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1997 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 +082E082 2 1998 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1998 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1998 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1998 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1998 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1998 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1998 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1998 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1998 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1998 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1998 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1998 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 +082E082 2 1999 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1999 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1999 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1999 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1999 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1999 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1999 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1999 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1999 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1999 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1999 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1999 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 +082E082 2 2000 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 2000 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 2000 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 2000 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 2000 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 2000 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 2000 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 2000 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 2000 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 2000 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 2000 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 2000 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI3.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI3.DAT new file mode 100755 index 000000000..f232e90f1 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI3.DAT @@ -0,0 +1,128 @@ +082E082 1 1997 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1997 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1997 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1997 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1997 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1997 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1997 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1997 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1997 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1997 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1997 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1997 +082E082 1 1998 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1998 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1998 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1998 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1998 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1998 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1998 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1998 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1998 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1998 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1998 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1998 +082E082 1 1999 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 1999 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 1999 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 1999 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 1999 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 1999 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 1999 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 1999 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 1999 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 1999 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 1999 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 1999 +082E082 1 2000 P 3 B -1 0.951 -0.061 -0.847 0.576 0.000 0.000 +082E082 1 2000 P 3 B 1 0.041 0.047 0.431 -3.646 0.000 0.000 +082E082 1 2000 P 3 B 2 0.014 4.251 -1.033 -8.511 0.000 0.000 +082E082 1 2000 P 3 B 3 -0.058 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 3 B 4 0.002 11.395 1.712 1.010 -0.168 -1.106 +082E082 1 2000 P 7 F -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 7 F 1 0.300 1.244 -0.338 2.572 2.173 0.450 +082E082 1 2000 P 7 F 2 -0.016 1.965 -0.760 -7.596 0.000 0.000 +082E082 1 2000 P 7 F 3 -0.175 0.000 0.000 -1.368 2.247 0.962 +082E082 1 2000 P 7 F 4 -0.108 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S -1 -0.041 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S 1 0.170 -0.630 0.951 3.792 2.558 0.603 +082E082 1 2000 P 15 S 2 -0.240 -1.748 1.322 0.295 2.982 1.100 +082E082 1 2000 P 15 S 3 -0.417 0.000 0.000 0.000 0.000 0.000 +082E082 1 2000 P 15 S 4 0.487 5.837 0.488 0.608 -0.219 2.743 +082E082 1 2000 +082E082 2 1997 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1997 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1997 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1997 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1997 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1997 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1997 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1997 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1997 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1997 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1997 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1997 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1997 +082E082 2 1998 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1998 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1998 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1998 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1998 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1998 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1998 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1998 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1998 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1998 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1998 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1998 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1998 +082E082 2 1999 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 1999 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 1999 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 1999 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 1999 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 1999 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 1999 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 1999 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 1999 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 1999 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 1999 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 1999 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 1999 +082E082 2 2000 P 3 B -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 3 B 1 0.065 0.044 -0.419 1.898 2.502 2.427 +082E082 2 2000 P 3 B 2 0.007 4.665 -0.472 -0.688 -2.080 2.655 +082E082 2 2000 P 3 B 3 -0.048 4.927 0.425 -0.100 4.037 2.881 +082E082 2 2000 P 3 B 4 -0.024 11.938 2.111 1.402 -0.073 -0.980 +082E082 2 2000 P 7 F -1 0.000 1.240 -0.946 0.000 0.000 0.000 +082E082 2 2000 P 7 F 1 0.365 1.209 0.582 7.681 2.481 0.605 +082E082 2 2000 P 7 F 2 0.450 2.111 -0.036 -3.253 2.464 0.802 +082E082 2 2000 P 7 F 3 -0.461 2.493 0.891 -1.660 2.555 1.155 +082E082 2 2000 P 7 F 4 -0.355 2.921 0.268 -1.266 3.026 1.848 +082E082 2 2000 P 12 PL -1 0.000 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 12 PL 1 0.191 1.239 -1.429 -7.827 0.000 0.000 +082E082 2 2000 P 12 PL 2 0.039 -0.093 -0.370 -3.914 3.441 2.539 +082E082 2 2000 P 12 PL 3 -0.198 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 P 12 PL 4 -0.032 0.000 0.000 0.000 0.000 0.000 +082E082 2 2000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETDQ2.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETDQ2.DAT new file mode 100755 index 000000000..27e207d6e --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETDQ2.DAT @@ -0,0 +1,20 @@ +AC 22.500 0.01154 2.33042 +AT 22.500 0.03382 2.01469 +B C 22.500 0.24855 1.46089 +B I 19.417 0.04354 1.96395 +C C 0.000 1.17308 1.26504 +C I 22.500 0.00157 2.96382 +D 22.500 0.80260 1.00000 +E 22.500 0.05290 1.86126 +F C 0.000 1.69879 1.09720 +F I 7.982 1.63676 1.03399 +H C 0.000 1.44195 1.10719 +H I 22.500 0.04657 1.93433 +L 22.500 0.13850 1.57421 +MB 22.500 1.71112 1.00000 +PA 22.500 1.20702 1.00000 +PL 22.500 0.01214 2.20938 +PW 0.000 0.61192 1.28876 +PY 22.500 0.80072 1.16250 +S 12.641 0.04390 2.03481 +Y 22.500 0.10270 1.80254 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETVOL1.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETVOL1.DAT new file mode 100755 index 000000000..f35ac1c2a --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETVOL1.DAT @@ -0,0 +1,16 @@ +AC 0.00152 0.01250 -0.14467 -0.17505 +AT 0.05156 -0.07337 0.05412 0.14865 +B 0.10881 -0.09818 0.00048 -0.00295 +C 0.02671 0.00608 0.05467 0.06558 +D 0.00761 0.00903 -0.31609 -0.44869 +E 0.07337 -0.03144 -0.07635 -0.18300 +F 0.03265 -0.09899 -0.22553 -0.33799 +H 0.12095 -0.10514 0.28497 0.37597 +L 0.00996 -0.06548 -0.19408 -0.18185 +MB 0.24121 -0.32052 0.13451 0.15169 +PA 0.01162 -0.03428 0.11151 1.00000 +PL 0.03495 -0.06265 -0.12651 -0.14343 +PW 0.00116 0.01048 -0.27302 -0.37258 +PY 0.04452 -0.07819 -0.41112 -0.54858 +S 0.05484 -0.05427 -0.22463 -0.29799 +Y -0.01293 -0.01125 -0.07776 -0.06091 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VGRPDEF1.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VGRPDEF1.DAT new file mode 100755 index 000000000..8c1e65d0a --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VGRPDEF1.DAT @@ -0,0 +1,208 @@ +AC AT 1 VGRPDEF1.DAT (Seq. 020) +AC BWBS 1 SP0 BEC and VGRP (A2,1x,A4,1x,I3) +AC CDF 2 +AC CWH 2 +AC ESSF 1 +AC ICH 3 +AC IDF 4 +AC MH 2 +AC MS 4 +AC PP 4 +AC SBPS 4 +AC SBS 5 +AC SWB 1 +AT AT 6 +AT BWBS 6 +AT CDF 7 +AT CWH 7 +AT ESSF 8 +AT ICH 7 +AT IDF 8 +AT MH 6 +AT MS 6 +AT PP 8 +AT SBPS 9 +AT SBS 9 +AT SWB 6 +B AT 10 +B BWBS 11 +B CDF 12 +B CWH 12 +B ESSF 13 +B ICH 14 +B IDF 15 +B MH 16 +B MS 17 +B PP 15 +B SBPS 17 +B SBS 18 +B SWB 19 +C AT 21 +C BWBS 21 +C CDF 20 +C CWH 20 +C ESSF 21 +C ICH 22 +C IDF 23 +C MH 20 +C MS 24 +C PP 23 +C SBPS 23 +C SBS 23 +C SWB 21 +D AT 25 +D BWBS 25 +D CDF 25 +D CWH 25 +D ESSF 25 +D ICH 25 +D IDF 25 +D MH 25 +D MS 25 +D PP 25 +D SBPS 25 +D SBS 25 +D SWB 25 +E AT 26 +E BWBS 26 +E CDF 27 +E CWH 27 +E ESSF 26 +E ICH 27 +E IDF 28 +E MH 26 +E MS 29 +E PP 28 +E SBPS 29 +E SBS 29 +E SWB 26 +F AT 31 +F BWBS 31 +F CDF 30 +F CWH 30 +F ESSF 31 +F ICH 32 +F IDF 33 +F MH 30 +F MS 34 +F PP 35 +F SBPS 36 +F SBS 36 +F SWB 31 +H AT 39 +H BWBS 39 +H CDF 37 +H CWH 37 +H ESSF 38 +H ICH 39 +H IDF 40 +H MH 41 +H MS 38 +H PP 40 +H SBPS 38 +H SBS 42 +H SWB 39 +L AT 43 +L BWBS 43 +L CDF 45 +L CWH 45 +L ESSF 44 +L ICH 45 +L IDF 46 +L MH 44 +L MS 47 +L PP 46 +L SBPS 47 +L SBS 47 +L SWB 43 +MB AT 48 +MB BWBS 48 +MB CDF 48 +MB CWH 48 +MB ESSF 48 +MB ICH 48 +MB IDF 48 +MB MH 48 +MB MS 48 +MB PP 48 +MB SBPS 48 +MB SBS 48 +MB SWB 48 +PA AT 49 +PA BWBS 49 +PA CDF 49 +PA CWH 49 +PA ESSF 49 +PA ICH 49 +PA IDF 49 +PA MH 49 +PA MS 49 +PA PP 49 +PA SBPS 49 +PA SBS 49 +PA SWB 49 +PL AT 52 +PL BWBS 50 +PL CDF 51 +PL CWH 51 +PL ESSF 52 +PL ICH 53 +PL IDF 54 +PL MH 52 +PL MS 55 +PL PP 54 +PL SBPS 56 +PL SBS 57 +PL SWB 58 +PW AT 60 +PW BWBS 60 +PW CDF 59 +PW CWH 59 +PW ESSF 60 +PW ICH 60 +PW IDF 61 +PW MH 60 +PW MS 61 +PW PP 61 +PW SBPS 61 +PW SBS 61 +PW SWB 60 +PY AT 63 +PY BWBS 62 +PY CDF 62 +PY CWH 62 +PY ESSF 62 +PY ICH 62 +PY IDF 63 +PY MH 62 +PY MS 63 +PY PP 64 +PY SBPS 63 +PY SBS 62 +PY SWB 63 +S AT 67 +S BWBS 65 +S CDF 66 +S CWH 66 +S ESSF 67 +S ICH 68 +S IDF 69 +S MH 67 +S MS 70 +S PP 69 +S SBPS 71 +S SBS 72 +S SWB 73 +Y AT 74 +Y BWBS 74 +Y CDF 74 +Y CWH 74 +Y ESSF 74 +Y ICH 74 +Y IDF 74 +Y MH 74 +Y MS 74 +Y PP 74 +Y SBPS 74 +Y SBS 74 +Y SWB 74 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VTOTREG4.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VTOTREG4.COE new file mode 100755 index 000000000..44a86c3c6 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VTOTREG4.COE @@ -0,0 +1,74 @@ + 1 -10.73883 1.84003 1.19257 0.000000 0.00000 0.001308 0.0000000 0.0000000 0.11213 + 2 -10.41832 1.94182 0.99414 0.000000 1.11329 0.000000 0.0000000 0.0000000 0.19884 + 3 -10.69881 1.84040 1.19208 0.000000 -0.68376 0.000000 0.0000000 0.0000000 0.12312 + 4 -11.12631 1.93159 1.27268 0.000000 1.39319 0.000000-0.0000285 0.0000000 0.00000 + 5 -10.96732 1.95781 1.14341 -0.001400 0.00000 0.000000 0.0000000 0.0000000 0.18697 + 6 -11.40262 1.94303 1.33111 0.000000 2.41443 0.000000 0.0000000 0.0000000 0.11323 + 7 -10.39996 1.83813 1.13079 0.000000 0.00000 0.004304 0.0000000 0.0000000 0.05546 + 8 -11.43244 2.09012 1.25413 -0.006063 3.48654 0.000000 0.0000000 0.0000000 0.00000 + 9 -10.53723 1.82135 1.20458 0.000000 0.77700 0.003243 0.0000000 0.0000000 0.00000 + 10 -10.42564 1.73604 1.36171 0.000000 0.00000 -0.008343 0.0000000 0.0000000 0.00000 + 11 -10.81873 1.73239 1.57738 0.000000 0.00000 -0.023526 0.0000000 0.0001255 0.00000 + 12 -11.15178 1.71451 1.70479 0.000000 6.21921 -0.011602 0.0000000 0.0000000 -0.42473 + 13 -9.55523 1.52149 1.16677 0.008427 0.00000 0.000000 0.0000000 0.0000000 0.00000 + 14 -9.60709 1.53787 1.26928 0.003170 0.00000 0.000000 0.0000000 0.0000000 -0.20656 + 15 -11.15800 1.97921 1.20376 0.000000 5.87165 0.000000 0.0000000 0.0000000 0.00000 + 16 -10.25295 1.90413 1.12235 0.000000 0.00000 -0.007156 0.0000000 0.0000384 0.00000 + 17 -11.36909 2.14875 1.05469 0.000000 5.59019 0.000000 0.0000000 0.0000000 0.12857 + 18 -10.99575 1.90223 1.35492 0.000000 3.57512 -0.013106 0.0000000 0.0000000 0.00000 + 19 -10.42564 1.73604 1.36171 0.000000 0.00000 -0.008343 0.0000000 0.0000000 0.00000 + 20 -9.17885 1.32846 1.28375 0.007225 0.00000 -0.004368-0.0000144 0.0000000 0.00000 + 21 -10.67067 1.75687 1.27720 0.000000 8.06169 0.000000 0.0000000 0.0000000 -0.18526 + 22 -9.66338 1.70434 1.04825 0.000000 1.18210 0.000000-0.0000036 0.0000000 0.00000 + 23 -8.91273 1.93491 0.46212 0.000000 0.00000 0.013649 0.0000000 0.0000000 0.00000 + 24 -12.05042 2.28187 1.06110 0.000000 13.87683 0.000000 0.0000000 0.0000000 0.00000 + 25 -10.34604 1.70521 1.22640 0.000000 0.00000 0.015385 0.0000000-0.0001082 0.00000 + 26 -11.58372 2.02896 1.17574 0.000000 0.00000 0.000000 0.0000000 0.0003586 0.44104 + 27 -11.33385 1.78255 1.43886 0.000000 0.00000 0.018473 0.0000000-0.0001887 0.00000 + 28 -10.38817 1.71771 1.20606 0.000000 0.00000 0.012161 0.0000000 0.0000000 0.00000 + 29 -11.93293 2.03367 1.40168 0.000000 0.00000 0.028326 0.0000000-0.0008040 0.00000 + 30 -10.25548 1.77216 1.15610 0.000000 1.06241 -0.000888 0.0000000 0.0000000 0.00000 + 31 -10.72519 1.47224 1.69744 0.000000 5.02831 0.000000 0.0000000 0.0000000 -0.52967 + 32 -11.15252 1.72842 1.45844 0.000000 5.00206 0.000000 0.0000000 0.0000000 -0.09154 + 33 -11.01177 1.78998 1.36742 0.000000 5.76091 0.000000 0.0000000 0.0000000 -0.22568 + 34 -10.87036 1.56078 1.59524 0.000000 5.77507 0.000000 0.0000000 0.0000000 -0.35287 + 35 -10.68239 1.90985 1.08028 0.000000 2.10272 0.000000 0.0000000 0.0000000 0.15152 + 36 -10.45815 1.60254 1.44973 0.000000 2.86009 0.000000 0.0000000 0.0000000 -0.30016 + 37 -10.13264 1.73961 1.16297 0.000000 0.00000 0.006069 0.0000353-0.0001076 0.00000 + 38 -11.18416 2.07526 1.12892 0.000000 4.40473 -0.002817 0.0000000 0.0000000 0.00000 + 39 -10.84897 1.78642 1.50594 0.000000 0.00000 -0.024433-0.0000923 0.0002791 0.00000 + 40 -10.41575 1.93403 1.06663 0.000000 0.00000 0.000000 0.0000000 0.0000000 0.00000 + 41 -10.27075 1.36134 1.90262 0.000000 0.00000 -0.017009 0.0000000 0.0000000 -0.59108 + 42 -10.30824 1.65750 1.46620 0.000000 0.00000 -0.028163 0.0000000 0.0003499 0.00000 + 43 -10.92762 2.18743 0.78381 0.000000 0.00000 0.000000 0.0000000 0.0000000 0.71485 + 44 -10.31691 1.77092 1.17025 0.002073 0.00000 0.000000 0.0000000-0.0000916 0.00000 + 45 -10.58608 1.71039 1.31201 0.000000 0.85797 0.000000 0.0000000 0.0000000 0.00000 + 46 -10.60876 1.38595 1.88253 0.000000 0.00000 -0.017570 0.0000000 0.0000000 -0.30460 + 47 -9.98895 1.73549 1.09584 0.000000 0.00000 0.000000 0.0000000 0.0000000 0.00000 + 48 -11.43740 2.07553 1.11891 0.000000 4.51723 0.010112 0.0000000 0.0000000 0.00000 + 49 -11.10460 2.10739 1.03739 0.000000 3.49154 0.000000 0.0000000 0.0000000 0.37334 + 50 -10.38181 1.85130 1.20078 0.000000 0.00000 0.000000 0.0000000-0.0000747 0.09712 + 51 -10.39243 1.73903 1.27276 0.000000 0.56779 0.000000 0.0000000 0.0000000 0.08787 + 52 -10.48010 1.77753 1.18673 0.000000 0.00000 0.005557 0.0000000 0.0000000 0.26414 + 53 -10.37133 1.77893 1.22473 0.000000 0.63439 0.000000 0.0000000 0.0000000 0.08867 + 54 -10.08580 1.83273 1.03800 0.000000 0.00000 0.016423 0.0000000-0.0000997 0.00000 + 55 -11.31168 2.01942 1.20251 0.000000 3.92549 0.000000 0.0000000 0.0000000 0.27280 + 56 -9.65234 1.36267 1.35881 0.025338 0.00000 0.000000 0.0000000-0.0004071 0.00000 + 57 -10.41890 1.91437 1.10238 0.000000 0.00000 0.000000-0.0000462 0.0000000 0.15177 + 58 -9.21370 1.52522 1.04568 0.023733 0.00000 0.000000 0.0000000-0.0002693 0.00000 + 59 -9.85882 1.63997 1.32358 0.000000 0.00000 -0.002669 0.0000000 0.0000000 -0.26924 + 60 -9.93198 1.74134 1.17311 0.000000 0.00000 0.000000 0.0000000-0.0000115 -0.09706 + 61 -10.22996 1.84440 1.10554 0.000000 0.00000 0.000000 0.0000000 0.0000000 0.07606 + 62 -10.27702 1.44095 1.51473 0.004780 0.00000 0.000000 0.0000000 0.0000000 0.00000 + 63 -11.27866 1.95239 1.25352 0.000000 4.78372 0.000000 0.0000000 0.0000533 0.00000 + 64 -10.71616 1.90536 1.18211 0.000000 2.49026 0.000000 0.0000000 0.0000612 0.00000 + 65 -11.05502 1.84206 1.40572 0.000000 2.97202 -0.008197 0.0000000 0.0000000 0.00000 + 66 -10.56439 1.69443 1.39852 0.000000 0.00000 -0.003524 0.0000000-0.0000051 0.00000 + 67 -10.31437 1.80106 1.17491 0.000000 1.95426 -0.000870 0.0000000 0.0000000 0.00000 + 68 -10.16789 1.69413 1.29311 0.000000 0.00000 -0.005339 0.0000000 0.0000128 0.00000 + 69 -10.11818 1.70690 1.25518 0.000000 1.18096 0.000000 0.0000000 0.0000000 -0.16244 + 70 -10.99731 1.88777 1.29322 0.000000 3.25364 0.000000 0.0000000-0.0000687 0.00000 + 71 -10.93963 2.13015 0.92532 0.000000 2.22250 0.000000 0.0000000 0.0000000 0.30658 + 72 -10.51375 1.78746 1.27205 0.000000 1.18847 -0.003285 0.0000000 0.0000000 0.00000 + 73 -11.52764 2.24628 0.95086 0.000000 5.67370 0.000000 0.0000000 0.0000000 0.29727 + 74 -10.06580 1.58704 1.40926 0.000000 4.43148 0.000000 0.0000000 0.0000000 -0.46117 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA309.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA309.COE new file mode 100755 index 000000000..994043b9e --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA309.COE @@ -0,0 +1,79 @@ + 1 11.872 6.28400 10.00000 0.44400 0.00000 0.00000 -0.00094 76.50000 + 11 2.303 10.00000 8.00000 0.68000 0.00000 -0.01084 -0.00893 50.04000 + 12 0.000 10.00000 8.00000 0.69200 0.00000 -0.00834 -0.00841 49.25000 + 13 14.598 10.00000 8.00000 0.82600 0.00000 -0.01398 -0.04294 54.20000 + 14 45.078 10.00000 8.00000 1.12100 0.00000 -0.03050 -0.05000 51.27000 + 21 60.775 8.46700 7.00000 0.74500 0.00000 -0.01910 -0.00714108.71000 + 22 70.749 0.00000 7.00000 0.65800 0.00000 -0.00853 -0.01262103.21000 + 23 70.238 0.00000 7.00000 0.81700 0.00000 -0.02067 -0.01170 64.32000 + 24 68.622 0.00000 7.00000 0.85000 0.00000 -0.01735 0.00000 67.56000 + 25 30.777 2.14700 7.00000 0.36800 0.00000 0.00000 -0.00451 69.94000 + 26 17.103 5.12300 7.00000 0.40500 0.00000 0.00000 -0.01080 72.10000 + 27 49.612 1.87700 7.00000 0.66900 0.00000 -0.01307 -0.01424 73.11000 + 31 22.853 10.00000 2.00000 0.76200 0.00000 -0.00744 -0.01871150.52000 + 32 0.000 9.30000 2.00000 1.10700 0.00000 0.00000 -0.01478167.28000 + 33 0.000 10.00000 2.00000 0.85500 0.00000 -0.00072 -0.01500127.34000 + 34 67.619 10.00000 2.00000 3.12700 0.00000 -0.05000 0.00000207.03000 + 35 0.000 9.59100 2.00000 0.59400 0.00000 0.00000 -0.01080100.54000 + 41 96.584 10.00000 9.00000 1.10600 0.00000 -0.05000 0.00000 51.29000 + 42 21.645 3.92400 9.00000 0.80800 0.00000 0.00000 -0.03266 42.53000 + 51 7.687 8.13300 5.00000 0.67800 0.00000 0.00000 -0.00934126.79000 + 52 19.119 4.32700 5.00000 0.78200 0.00000 0.00000 -0.02052 94.85000 + 53 57.601 0.00000 5.00000 0.99500 0.00000 -0.01887 -0.02229 62.22000 + 54 47.868 0.78100 5.00000 0.81500 0.00000 -0.01257 -0.01800 66.97000 + 55 44.445 3.58600 5.00000 1.16400 0.00000 -0.01736 -0.00087 74.56000 + 56 32.929 0.00000 5.00000 0.87000 0.00000 0.00000 -0.00272 67.59000 + 57 23.599 0.00000 5.00000 0.65400 0.00000 0.00000 -0.01453 46.81000 + 58 33.149 0.00000 5.00000 0.64900 0.00000 0.00000 -0.01701 55.27000 + 60 17.946 1.77600 5.00000 0.89900 0.00000 0.00000 -0.01072 57.32000 + 61 13.337 4.74800 5.00000 0.91400 0.00000 -0.00222 -0.00379 92.49000 + 62 51.545 0.00000 5.00000 1.13100 0.00000 -0.01680 0.00000 68.90000 + 63 38.635 4.52800 5.00000 1.02900 0.00000 -0.01423 -0.00454 79.29000 + 71 66.076 5.86900 9.00000 0.66300 0.00000 -0.01390 -0.01027111.19000 + 72 49.342 4.96700 9.00000 0.49400 0.00000 -0.00832 -0.01194101.16000 + 73 17.489 9.25600 9.00000 0.37900 0.00000 0.00000 -0.01230109.53000 + 74 34.806 10.00000 9.00000 0.60700 0.00000 -0.01052 -0.01139110.31000 + 75 43.453 10.00000 9.00000 0.49500 0.00000 -0.01337 -0.00723104.12000 + 76 18.299 7.76500 9.00000 0.32400 0.00000 0.00000 -0.00559 89.71000 + 77 53.265 2.36500 9.00000 0.42800 0.00000 -0.00419 -0.00999 88.50000 + 78 48.261 8.41200 9.00000 0.58000 0.00000 -0.01612 0.00000 89.11000 + 79 64.569 10.00000 9.00000 0.63100 0.00000 -0.02532 -0.01052 75.41000 + 80 5.783 10.00000 9.00000 0.27100 0.00000 0.00000 -0.00694 95.03000 + 91 70.636 0.00000 7.00000 1.38100 0.00000 -0.02682 -0.03055 64.57000 + 92 43.084 0.00000 7.00000 0.84000 0.00000 -0.01343 -0.01524 58.82000 +101 171.214 0.00000 5.00000 1.05200 0.00000 -0.05000 -0.05000 72.78000 +111 4.277 10.00000 6.00000 0.79100 0.00000 -0.00064 -0.00191 88.68000 +112 41.451 3.40600 6.00000 0.92700 0.00000 -0.01596 -0.05000 55.39000 +113 35.558 6.95000 6.00000 0.98400 0.00000 -0.02028 -0.02217 62.84000 +114 37.491 8.14400 6.00000 1.19500 0.00000 -0.03028 -0.04255 50.72000 +115 0.000 9.58600 6.00000 0.38200 0.00000 0.00000 -0.03369 64.86000 +116 9.249 10.00000 6.00000 0.57300 0.00000 -0.00999 -0.00783 65.51000 +117 56.142 10.00000 6.00000 0.98000 0.00000 -0.03405 -0.05000 70.10000 +118 114.635 7.97600 6.00000 1.34100 0.00000 -0.05000 -0.03964 64.41000 +119 19.751 2.75100 6.00000 0.74100 0.00000 0.00000 -0.02909 52.28000 +120 28.133 1.54500 6.00000 0.81800 0.00000 0.00000 -0.03193 57.91000 +121 7.154 7.28500 6.00000 0.49600 0.00000 0.00000 -0.05000 57.97000 +122 0.000 8.54500 6.00000 0.61700 0.00000 0.00000 0.00000 58.76000 +123 130.325 5.29600 6.00000 1.39100 0.00000 -0.05000 0.00000 64.72000 +131 15.151 6.07000 7.00000 0.61000 0.00000 -0.00083 -0.00926 69.06000 +141 16.789 0.00000 4.00000 0.71900 0.00000 0.00000 0.00000 43.69000 +151 48.521 0.01000 7.00000 0.59800 0.00000 0.00000 -0.01399133.18000 +152 35.624 0.00000 7.00000 0.68200 0.00000 0.00000 -0.05000 52.75000 +153 138.178 0.00000 7.00000 1.32000 0.00000 -0.05000 -0.05000 54.57000 +154 79.250 0.00000 7.00000 0.78200 0.00000 -0.02684 -0.03057 57.08000 +155 88.773 0.00000 7.00000 1.02800 0.00000 -0.03094 -0.02877 57.93000 +156 42.371 0.00000 7.00000 0.53100 0.00000 -0.00286 -0.04317 56.50000 +157 106.185 2.01100 7.00000 1.21800 0.00000 -0.03911 -0.02977 61.73000 +158 51.778 0.00000 7.00000 0.60700 0.00000 -0.01286 -0.00835 60.02000 +159 37.631 0.00000 7.00000 0.56000 0.00000 -0.00253 -0.02542 61.13000 +160 67.637 0.00000 7.00000 0.83900 0.00000 -0.01959 -0.01948 59.06000 +161 59.722 0.00000 7.00000 0.85800 0.00000 -0.01658 -0.01902 58.94000 +162 21.908 4.47600 7.00000 0.40900 0.00000 -0.00085 -0.01743 81.28000 +163 40.208 0.00000 7.00000 0.37600 0.00000 0.00000 -0.03588 69.37000 +164 38.421 0.00000 7.00000 0.32500 0.00000 0.00000 0.00000 67.69000 +165 58.903 0.00000 7.00000 0.62500 0.00000 -0.01235 0.00000 65.74000 +166 44.506 0.00000 7.00000 0.60400 0.00000 -0.00147 -0.01137 78.85000 +167 36.331 0.00000 7.00000 0.49800 0.00000 0.00000 -0.01457 78.25000 +168 54.081 0.00000 7.00000 0.72600 0.00000 -0.01342 0.00000 69.00000 +169 35.630 0.00000 7.00000 0.56400 0.00000 0.00000 0.00000 63.45000 +171 21.989 10.00000 5.00000 0.70800 0.00000 -0.00533 0.00000125.69000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA405.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA405.COE new file mode 100755 index 000000000..022a63ca9 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA405.COE @@ -0,0 +1,98 @@ +AT A0 1 -6.9379 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +AT A1 1 2.8939 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +AT A2 1 2.8210 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +AT A3 1 0.8470 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +AT A4 1 -0.0415 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +AT A5 1 -0.0100 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +AT A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A0 1 -1.0101 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +BG A1 1 1.7892 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +BG A2 1 7.7854 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +BG A3 1 0.5106 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +BG A4 1 -0.0090 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +BG A5 1 0.0130 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +BG A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A0 1 -9.1843 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +BWBS A1 1 3.5926 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +BWBS A2 1 7.3956 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +BWBS A3 1 1.2656 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +BWBS A4 1 -0.1401 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +BWBS A5 1 -0.0096 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +BWBS A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A0 1 -6.1886 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +CDF A1 1 3.1815 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +CDF A2 1 7.6496 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +CDF A3 1 0.8236 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +CDF A4 1 -0.0467 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +CDF A5 1 -0.0090 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +CDF A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A0 1 -5.4065 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +CWH A1 1 3.1815 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +CWH A2 1 7.6496 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +CWH A3 1 0.8236 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +CWH A4 1 -0.0467 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +CWH A5 1 -0.0090 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +CWH A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A0 1 -6.9379 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +ESSF A1 1 2.8939 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +ESSF A2 1 2.8210 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +ESSF A3 1 0.8470 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +ESSF A4 1 -0.0415 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +ESSF A5 1 -0.0100 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +ESSF A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A0 1 -5.5072 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +ICH A1 1 2.5336 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +ICH A2 1 3.6916 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +ICH A3 1 0.7594 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +ICH A4 1 -0.0391 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +ICH A5 1 -0.0009 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +ICH A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A0 1 -0.4517 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +IDF A1 1 1.7892 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +IDF A2 1 7.7854 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +IDF A3 1 0.5106 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +IDF A4 1 -0.0090 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +IDF A5 1 0.0130 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +IDF A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A0 1 -4.7364 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +MH A1 1 3.1815 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +MH A2 1 7.6496 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +MH A3 1 0.8236 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +MH A4 1 -0.0467 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +MH A5 1 -0.0090 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +MH A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A0 1 -6.9786 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +MS A1 1 2.9605 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +MS A2 1 5.0572 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +MS A3 1 0.9693 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +MS A4 1 -0.0637 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +MS A5 1 -0.0144 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +MS A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A0 1 -1.0101 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +PP A1 1 1.7892 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +PP A2 1 7.7854 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +PP A3 1 0.5106 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +PP A4 1 -0.0090 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +PP A5 1 0.0130 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +PP A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A0 1 -6.1125 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +SBPS A1 1 2.5539 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +SBPS A2 1 3.6120 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +SBPS A3 1 0.8886 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +SBPS A4 1 -0.0672 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +SBPS A5 1 0.0081 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +SBPS A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A0 1 -5.7232 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +SBS A1 1 2.5539 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +SBS A2 1 3.6120 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +SBS A3 1 0.8886 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +SBS A4 1 -0.0672 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +SBS A5 1 0.0081 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +SBS A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A0 1 -9.5030 -2.3745 6.0431 9.4180 -0.9251 -5.2126 17.1866 11.3717 0.7622 -0.9251 0.1461 0.1461 -0.7605 -4.5989 7.6738 8.1378 +SWB A1 1 3.5926 0.7338 -2.0785 -1.6102 -0.0679 1.0369 -3.8393 -1.7204 -0.5330 -0.0679 0.1444 0.1444 0.1444 0.1444 -2.4852 -1.6102 +SWB A2 1 7.3956 1.6564 -3.4927 0.7928 -1.0338 1.9146 3.5000 -0.5511 1.4506 -1.0338 -0.0225 -0.0225 -0.0225 -0.0225 -2.6926 0.7928 +SWB A3 1 1.2656 0.1393 0.2898 -0.3076 0.9405 1.5910 -0.5824 -0.1507 0.3591 0.9405 0.2066 0.2066 0.2066 0.2066 0.3871 -0.3076 +SWB A4 1 -0.1401 -0.0538 0.0025 0.0911 -0.2234 -0.3778 0.1353 0.0287 -0.0792 -0.2234 -0.0519 -0.0519 -0.0519 -0.0519 -0.0322 0.0911 +SWB A5 1 -0.0096 0.0096 -0.0107 -0.0012 -0.0121 -0.0087 0.0022 -0.0035 0.0064 -0.0121 0.0022 0.0022 0.0022 0.0022 0.0003 -0.0012 +SWB A6 0 -0.0089 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA407.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA407.COE new file mode 100755 index 000000000..8ad69dc32 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA407.COE @@ -0,0 +1,98 @@ +AT A0 1 -4.8137 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +AT A1 1 3.2029 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +AT A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +AT A3 1 0.5142 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +AT A4 1 -0.0026 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +AT A5 1 -0.0054 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +AT A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A0 1 -3.5103 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +BG A1 1 2.4562 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +BG A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A3 1 0.5074 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +BG A4 1 -0.0150 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +BG A5 1 0.0120 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +BG A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A0 1-11.7832 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +BWBS A1 1 4.8785 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +BWBS A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A3 1 1.0047 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +BWBS A4 1 -0.1303 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +BWBS A5 1 0.0017 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +BWBS A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A0 1 -9.5631 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +CDF A1 1 4.6950 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +CDF A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A3 1 0.6405 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +CDF A4 1 -0.0542 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +CDF A5 1 0.0039 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +CDF A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A0 1 -8.6587 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +CWH A1 1 4.6950 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +CWH A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A3 1 0.6405 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +CWH A4 1 -0.0542 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +CWH A5 1 0.0039 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +CWH A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A0 1 -4.8137 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +ESSF A1 1 3.2029 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +ESSF A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A3 1 0.5142 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +ESSF A4 1 -0.0026 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +ESSF A5 1 -0.0054 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +ESSF A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A0 1 -4.7878 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +ICH A1 1 2.9269 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +ICH A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A3 1 0.6326 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +ICH A4 1 -0.0345 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +ICH A5 1 0.0032 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +ICH A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A0 1 -2.9907 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +IDF A1 1 2.4562 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +IDF A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A3 1 0.5074 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +IDF A4 1 -0.0150 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +IDF A5 1 0.0120 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +IDF A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A0 1 -7.5724 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +MH A1 1 4.6950 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +MH A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A3 1 0.6405 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +MH A4 1 -0.0542 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +MH A5 1 0.0039 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +MH A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A0 1 -7.3799 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +MS A1 1 3.9547 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +MS A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A3 1 0.6109 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +MS A4 1 -0.0404 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +MS A5 1 -0.0041 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +MS A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A0 1 -3.5103 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +PP A1 1 2.4562 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +PP A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A3 1 0.5074 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +PP A4 1 -0.0150 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +PP A5 1 0.0120 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +PP A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A0 1 -4.4714 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +SBPS A1 1 2.8886 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +SBPS A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A3 1 0.5315 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +SBPS A4 1 -0.0183 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +SBPS A5 1 0.0028 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +SBPS A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A0 1 -3.9346 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +SBS A1 1 2.8886 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +SBS A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A3 1 0.5315 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +SBS A4 1 -0.0183 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +SBS A5 1 0.0028 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +SBS A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A0 1-12.4629 -0.8603 11.2376 7.6975 -1.5588-16.3758 12.6180 11.6395 -2.8281 -1.5588 0.3191 0.3191 -0.9866 -4.2533 10.7814 5.2548 +SWB A1 1 4.8785 -0.2732 -3.2149 -0.8761 0.1580 3.5650 -3.2740 -1.1113 0.0753 0.1580 -0.1094 -0.1094 -0.1094 -0.1094 -3.4182 -0.8761 +SWB A2 0 7.2295 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A3 1 1.0047 0.1973 0.3763 -0.2670 0.9394 1.9790 -0.2719 -0.0981 0.5953 0.9394 0.3486 0.3486 0.3486 0.3486 0.4846 -0.2670 +SWB A4 1 -0.1303 -0.0272 0.0300 0.0771 -0.2438 -0.4795 0.0804 0.0051 -0.1269 -0.2438 -0.0723 -0.0723 -0.0723 -0.0723 -0.0337 0.0771 +SWB A5 1 0.0017 -0.0007 -0.0364 -0.0030 -0.0069 -0.0023 -0.0010 -0.0010 0.0081 -0.0069 0.0054 0.0054 0.0054 0.0054 -0.0106 -0.0030 +SWB A6 0 -0.0090 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ259.DAT b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ259.DAT new file mode 100755 index 000000000..b939ccda2 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ259.DAT @@ -0,0 +1,79 @@ + 1 34.194-0.0078777 -0.043350 2.61515 -0.00607 37.52 + 11 500.000-0.0009006 -0.004427 1.91763 0.00000 33.95 + 12 430.211-0.0007549 -0.006587 2.08158 0.00000 31.48 + 13 26.983-0.0090483 -0.064751 5.97184 -0.03172 32.35 + 14 37.220-0.0069021 -0.042914 4.48841 -0.02704 32.02 + 21 57.871-0.0012665 -0.046347 3.72351 -0.00130 58.28 + 22 77.353-0.0009407 -0.030618 2.82864 -0.01562 57.77 + 23 96.417-0.0000831 -0.016439 1.63004 -0.01120 36.98 + 24 403.635 0.0000000 -0.005749 1.64977 0.00000 38.87 + 25 500.000-0.0000262 -0.002671 1.25066 -0.01820 37.10 + 26 137.674-0.0001000 -0.012872 1.68136 0.00000 39.78 + 27 500.000-0.0000771 -0.003735 1.46264 0.00000 43.30 + 31 81.538-0.0006284 -0.032013 2.32709 -0.00383 70.12 + 32 500.000-0.0001000 -0.006326 1.62416 0.00000 79.15 + 33 154.260-0.0004400 -0.020110 2.29156 -0.01562 72.24 + 34 500.000-0.0000787 -0.008204 1.78022 -0.01836 105.68 + 35 500.000-0.0001000 -0.003274 1.37758 0.00000 47.30 + 41 535.703-0.0003596 -0.011266 2.71587 0.00000 31.89 + 42 46.635-0.0059313 -0.025160 2.65608 -0.03239 31.02 + 51 117.328-0.0007321 -0.015048 2.09219 0.00000 55.76 + 52 153.139-0.0010886 -0.009983 1.84062 -0.00343 51.11 + 53 35.188-0.0036370 -0.035521 2.38730 -0.00666 38.76 + 54 334.116-0.0001000 -0.005251 1.57427 0.00000 39.74 + 55 224.190-0.0001000 -0.003545 1.11465 0.00000 41.62 + 56 42.413-0.0020401 -0.033034 2.14632 -0.01109 38.70 + 57 26.240-0.0081275 -0.027520 1.94799 -0.01735 39.62 + 58 151.887-0.0000710 -0.007870 1.40248 -0.02526 32.50 + 60 42.964-0.0032315 -0.036808 2.75118 0.00000 41.57 + 61 665.605-0.0001048 -0.002673 1.49757 0.00000 47.97 + 62 500.000-0.0002707 -0.003806 1.64478 -0.00471 36.14 + 63 339.378-0.0001876 -0.003282 1.42478 0.00000 33.89 + 71 1162.658-0.0001498 -0.002946 1.69743 0.00000 63.53 + 72 187.832-0.0005508 -0.012600 2.19837 -0.00100 56.37 + 73 500.000-0.0003080 -0.007091 2.13208 -0.00224 56.56 + 74 58.505-0.0018006 -0.046983 4.34599 -0.00601 58.32 + 75 47.410-0.0021813 -0.060509 5.05548 -0.00769 59.12 + 76 113.808-0.0003625 -0.017427 1.82034 0.00000 53.30 + 77 45.020-0.0032238 -0.042343 3.59600 0.00000 47.59 + 78 46.205-0.0021872 -0.057368 5.32549 -0.03013 53.51 + 79 351.795-0.0003514 -0.003195 1.46735 -0.01055 36.61 + 80 85.459-0.0011653 -0.026897 2.86649 -0.00397 54.76 + 91 39.495-0.0013966 -0.030670 2.43680 -0.00676 32.87 + 92 56.968-0.0016802 -0.021506 2.25280 -0.01019 38.52 +101 18.334-0.0004443 -0.200000 6.59710 -0.07939 30.76 +111 20.118-0.0048355 -0.067741 3.63528 -0.00355 24.00 +112 415.545-0.0002094 -0.005309 1.78098 -0.00851 27.56 +113 92.081-0.0003901 -0.012642 1.55999 -0.01673 32.11 +114 1191.770-0.0001448 -0.002000 1.57938 0.00000 31.73 +115 107.049-0.0004146 -0.011550 1.59962 -0.01953 28.75 +116 204.933-0.0000502 -0.002000 0.89326 0.00000 30.73 +117 41.895-0.0016051 -0.035123 2.75241 -0.02254 26.99 +118 500.000-0.0000488 -0.002000 1.23266 -0.01135 29.84 +119 28.002-0.0031256 -0.054824 3.59289 -0.01609 25.16 +120 25.931-0.0029209 -0.049364 2.60651 -0.01646 27.02 +121 500.000-0.0002012 -0.006680 2.11095 -0.02284 23.94 +122 500.000-0.0001319 -0.003889 1.63291 -0.00820 27.58 +123 500.000-0.0000940 -0.002000 1.29092 -0.01328 28.91 +131 19.724-0.0092518 -0.048768 2.45539 -0.02789 31.78 +141 41.654-0.0051418 -0.049575 2.82957 -0.01620 52.15 +151 109.958-0.0018927 -0.019825 2.29827 -0.00068 76.66 +152 68.292-0.0001000 -0.011613 1.13327 0.00000 28.22 +153 28.232-0.0012750 -0.060658 2.69605 0.00000 29.83 +154 36.582 0.0000000 -0.045861 2.37164 -0.00603 32.70 +155 500.000-0.0001454 -0.008112 2.21478 0.00000 40.70 +156 334.153-0.0000444 -0.006241 1.64016 -0.01454 32.61 +157 500.000-0.0001819 -0.006269 1.91118 0.00000 40.73 +158 25.990-0.0021030 -0.080982 4.04752 -0.01543 37.67 +159 56.146-0.0008332 -0.028836 2.08706 -0.03820 41.17 +160 184.685 0.0000000 -0.006141 1.28345 -0.01861 34.41 +161 500.000-0.0002799 -0.002000 1.29648 0.00000 40.19 +162 149.645-0.0001000 -0.011178 1.63873 0.00000 47.10 +163 140.818-0.0001305 -0.007193 1.23620 -0.03048 42.79 +164 75.609-0.0000308 -0.010962 1.06003 -0.00983 38.74 +165 217.085-0.0000254 -0.002938 1.00565 -0.01391 33.95 +166 46.198-0.0024691 -0.033291 2.60035 -0.00552 44.76 +167 92.982-0.0008544 -0.021075 2.30841 0.00000 49.73 +168 618.588-0.0000787 -0.002000 1.27024 0.00000 46.65 +169 500.000-0.0001585 -0.002957 1.40250 -0.00418 45.47 +171 55.777-0.0005719 -0.038363 2.01576 -0.05387 50.81 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ309.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ309.COE new file mode 100755 index 000000000..bf20f7161 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ309.COE @@ -0,0 +1,79 @@ + 1 500.000-0.0006100 -0.005150 1.80328 -0.00095 78.20 + 11 500.000-0.0008121 -0.003958 1.81267 -0.02236 35.60 + 12 77.550-0.0025153 -0.022854 2.56097 -0.02147 32.50 + 13 30.627-0.0073318 -0.057361 5.00000 -0.02972 32.60 + 14 37.732-0.0063457 -0.041673 4.10777 -0.03692 32.50 + 21 44.009-0.0014565 -0.065558 5.00000 -0.00885 60.60 + 22 50.467-0.0018484 -0.057572 5.00000 -0.01784 64.40 + 23 65.808 0.0000000 -0.021003 1.58206 -0.01060 38.00 + 24 433.724 0.0000000 -0.004793 1.55935 -0.00269 39.40 + 25 75.514-0.0001374 -0.016673 1.43354 -0.02030 37.90 + 26 258.992-0.0000328 -0.006096 1.42256 -0.02940 39.90 + 27 389.500-0.0001144 -0.004410 1.50898 -0.00328 43.30 + 31 97.804-0.0002891 -0.019326 1.69720 -0.00935 71.00 + 32 500.000-0.0001940 -0.006846 1.84524 -0.01035 79.00 + 33 164.542-0.0003358 -0.020980 2.57560 -0.02256 72.70 + 34 500.000-0.0001154 -0.010885 2.22126 -0.00725 105.40 + 35 500.000-0.0001337 -0.002000 1.23105 -0.01295 48.30 + 41 500.000-0.0005724 -0.009086 2.38125 -0.01317 32.00 + 42 32.121-0.0076283 -0.041352 3.11950 -0.03002 32.80 + 51 112.324-0.0005567 -0.014649 1.94947 -0.00333 62.80 + 52 52.455-0.0037270 -0.034284 2.99428 -0.00569 60.30 + 53 30.916-0.0043188 -0.041477 2.69822 -0.00803 40.10 + 54 180.955 0.0000000 -0.007713 1.49659 -0.01786 39.90 + 55 71.923-0.0004566 -0.014176 1.40199 0.00000 41.50 + 56 29.274-0.0038520 -0.052048 3.00274 -0.01087 38.80 + 57 25.035-0.0103940 -0.029986 2.43416 -0.03006 43.70 + 58 46.867-0.0003666 -0.023407 1.52017 -0.03263 32.50 + 60 28.187-0.0074511 -0.059401 4.69094 -0.01465 42.10 + 61 361.784-0.0001822 -0.003102 1.40730 -0.00865 43.90 + 62 37.606-0.0032262 -0.039846 2.98849 -0.00586 38.50 + 63 318.353-0.0001761 -0.003487 1.43400 -0.00391 34.20 + 71 61.776-0.0008483 -0.042748 2.92035 0.00000 70.90 + 72 51.047-0.0022879 -0.046717 4.20050 -0.00363 61.90 + 73 67.857-0.0016730 -0.036648 3.79435 -0.00825 59.30 + 74 45.229-0.0020762 -0.061146 5.00000 -0.00865 59.30 + 75 42.915-0.0020164 -0.057461 3.87271 -0.01010 60.40 + 76 67.500-0.0010405 -0.030257 2.37195 -0.00170 53.50 + 77 41.078-0.0039318 -0.048179 4.40030 0.00000 52.50 + 78 47.739-0.0019306 -0.055944 5.00000 -0.05069 54.40 + 79 111.236-0.0010262 -0.009092 1.68142 -0.01193 37.90 + 80 53.345-0.0020681 -0.043030 3.93138 -0.00429 55.10 + 91 51.112-0.0006161 -0.021898 1.96467 -0.02828 36.20 + 92 41.360-0.0018007 -0.031835 2.50858 -0.03964 42.40 +101 18.580-0.0011669 -0.167944 5.00000 -0.06546 30.70 +111 26.798-0.0030629 -0.041725 2.58694 0.00000 25.90 +112 500.000-0.0001079 -0.002000 1.30421 -0.01820 28.20 +113 87.523-0.0004044 -0.013022 1.55053 -0.01826 32.30 +114 467.336-0.0003286 -0.003738 1.62138 0.00000 32.00 +115 43.081-0.0013118 -0.022092 1.64319 -0.03606 28.60 +116 226.806-0.0000526 -0.002000 0.92978 -0.03363 30.90 +117 35.878-0.0017831 -0.038869 2.72840 -0.04209 27.40 +118 500.000 0.0000000 -0.002000 1.18769 -0.01798 29.90 +119 26.240-0.0036325 -0.052963 3.37763 -0.01887 25.10 +120 17.493-0.0080370 -0.086195 5.00000 -0.01402 27.70 +121 500.000-0.0000890 -0.004261 1.67565 -0.01139 24.20 +122 500.000 0.0000000 -0.002995 1.39206 -0.04737 28.20 +123 500.000-0.0000771 -0.002000 1.26646 -0.03364 32.40 +131 20.567-0.0083836 -0.057823 3.09825 -0.03458 33.60 +141 33.835-0.0072738 -0.067465 4.03541 -0.01380 52.50 +151 124.979-0.0006434 -0.015672 1.82653 -0.00622 94.80 +152 30.979-0.0003095 -0.035275 1.51396 -0.00281 28.20 +153 22.006-0.0017682 -0.089138 3.83285 0.00000 29.80 +154 44.321 0.0000000 -0.033160 1.98571 -0.00568 32.70 +155 500.000-0.0001380 -0.008561 2.28710 0.00000 40.80 +156 500.000-0.0000157 -0.004378 1.58044 -0.02560 32.60 +157 500.000-0.0001464 -0.006885 1.99148 0.00000 40.90 +158 27.304-0.0007645 -0.080404 4.26363 -0.01432 37.90 +159 52.288-0.0005758 -0.038120 2.66484 -0.03069 42.10 +160 91.050 0.0000000 -0.011774 1.32274 -0.01942 34.60 +161 500.000-0.0002472 -0.002878 1.42884 -0.00880 40.60 +162 500.000-0.0000046 -0.002990 1.33598 -0.00336 47.00 +163 65.780-0.0003049 -0.019286 1.51495 -0.02654 43.30 +164 157.230 0.0000000 -0.004702 1.04552 -0.00903 38.80 +165 500.000 0.0000000 -0.002000 1.15705 -0.01978 34.10 +166 57.236-0.0016725 -0.024291 2.19122 -0.00238 47.00 +167 159.245 0.0000000 -0.018631 2.45952 -0.01301 52.80 +168 500.000 0.0000000 -0.002000 1.13895 -0.00459 48.60 +169 500.000-0.0001205 -0.004155 1.60112 0.00000 45.20 +171 44.104-0.0011009 -0.047135 2.50387 -0.03048 51.30 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ45.COE b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ45.COE new file mode 100755 index 000000000..faaf9e620 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ45.COE @@ -0,0 +1,84 @@ +AT A0 1 7.5065 -0.0065 2.6824 2.9935 2.1957 2.9935 2.9935 2.9935 2.0331 2.1957 1.9704 1.9704 1.9704 1.9704 -0.0065 2.9935 +AT A1 1 2.9903 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +AT A2 1 -0.4081 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +AT A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +AT A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +AT A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BG A0 1 7.5065 -0.0129 2.6760 2.9871 2.1893 2.9871 2.9871 2.9871 2.0266 2.1893 1.9639 1.9639 1.9639 1.9639 -0.0129 2.9871 +BG A1 1 2.8211 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +BG A2 1 -0.3703 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +BG A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +BG A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +BG A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +BWBS A0 1 7.5065 -0.0194 2.6695 2.9806 2.1828 2.9806 2.9806 2.9806 2.0202 2.1828 1.9575 1.9575 1.9575 1.9575 -0.0194 2.9806 +BWBS A1 1 2.7629 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +BWBS A2 1 -0.3641 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +BWBS A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +BWBS A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +BWBS A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CDF A0 1 7.5065 -0.0258 2.6631 2.9742 2.1764 2.9742 2.9742 2.9742 2.0137 2.1764 1.9510 1.9510 1.9510 1.9510 -0.0258 2.9742 +CDF A1 1 3.1924 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +CDF A2 1 -0.4491 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +CDF A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +CDF A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +CDF A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +CWH A0 1 7.5065 -0.0323 2.6566 2.9677 2.1699 2.9677 2.9677 2.9677 2.0073 2.1699 1.9445 1.9445 1.9445 1.9445 -0.0323 2.9677 +CWH A1 1 3.1924 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +CWH A2 1 -0.4491 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +CWH A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +CWH A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +CWH A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ESSF A0 1 7.5065 -0.0388 2.6501 2.9612 2.1635 2.9612 2.9612 2.9612 2.0008 2.1635 1.9381 1.9381 1.9381 1.9381 -0.0388 2.9612 +ESSF A1 1 2.9903 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +ESSF A2 1 -0.4081 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +ESSF A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +ESSF A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +ESSF A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +ICH A0 1 7.5065 -0.0452 2.6437 2.9548 2.1570 2.9548 2.9548 2.9548 1.9943 2.1570 1.9316 1.9316 1.9316 1.9316 -0.0452 2.9548 +ICH A1 1 2.9481 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +ICH A2 1 -0.4078 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +ICH A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +ICH A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +ICH A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +IDF A0 1 7.5065 -0.0517 2.6372 2.9483 2.1505 2.9483 2.9483 2.9483 1.9879 2.1505 1.9252 1.9252 1.9252 1.9252 -0.0517 2.9483 +IDF A1 1 2.8211 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +IDF A2 1 -0.3703 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +IDF A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +IDF A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +IDF A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MH A0 1 7.5065 -0.0581 2.6308 2.9419 2.1441 2.9419 2.9419 2.9419 1.9814 2.1441 1.9187 1.9187 1.9187 1.9187 -0.0581 2.9419 +MH A1 1 3.1924 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +MH A2 1 -0.4491 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +MH A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +MH A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +MH A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +MS A0 1 7.5065 -0.0646 2.6243 2.9354 2.1376 2.9354 2.9354 2.9354 1.9750 2.1376 1.9123 1.9123 1.9123 1.9123 -0.0646 2.9354 +MS A1 1 2.9499 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +MS A2 1 -0.4063 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +MS A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +MS A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +MS A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +PP A0 1 7.5065 -0.0710 2.6179 2.9290 2.1312 2.9290 2.9290 2.9290 1.9685 2.1312 1.9058 1.9058 1.9058 1.9058 -0.0710 2.9290 +PP A1 1 2.8211 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +PP A2 1 -0.3703 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +PP A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +PP A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +PP A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBPS A0 1 7.5065 -0.0775 2.6114 2.9225 2.1247 2.9225 2.9225 2.9225 1.9620 2.1247 1.8993 1.8993 1.8993 1.8993 -0.0775 2.9225 +SBPS A1 1 2.9683 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +SBPS A2 1 -0.4106 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +SBPS A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +SBPS A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +SBPS A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SBS A0 1 7.5065 -0.0840 2.6049 2.9160 2.1182 2.9160 2.9160 2.9160 1.9556 2.1182 1.8929 1.8929 1.8929 1.8929 -0.0840 2.9160 +SBS A1 1 2.9683 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +SBS A2 1 -0.4106 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +SBS A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +SBS A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +SBS A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 +SWB A0 1 7.5065 -0.0904 2.5985 2.9096 2.1118 2.9096 2.9096 2.9096 1.9491 2.1118 1.8864 1.8864 1.8864 1.8864 -0.0904 2.9096 +SWB A1 1 2.7629 -0.1558 -3.4935 -3.2935 -2.4549 -2.3135 -2.9351 -3.0830 -2.3345 -2.4549 -3.0784 -3.0784 -3.0301 -2.6275 -2.2808 -3.6251 +SWB A2 1 -0.3641 -0.0026 0.5824 0.5622 0.4026 0.3184 0.4607 0.4640 0.3500 0.4026 0.4705 0.4705 0.4705 0.4705 0.3681 0.6269 +SWB A3 1 -0.4935 -0.6237 2.1812 1.5919 0.8704 0.4944 1.3227 1.3673 0.6714 0.8704 1.7923 1.7923 1.7923 1.7923 1.3556 1.5919 +SWB A4 1 0.3187 0.1224 -0.4178 -0.3002 -0.1409 -0.0719 -0.2410 -0.2159 -0.1367 -0.1409 -0.3131 -0.3131 -0.3131 -0.3131 -0.2691 -0.3002 +SWB A5 0 -0.0028 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/mod19813.prm b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/mod19813.prm new file mode 100755 index 000000000..e680788c2 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/mod19813.prm @@ -0,0 +1,8 @@ +000 SEQ 198 MODIFIER FILE MOD19802.prm (23JAN03) + + 098 VetBA Cam Bartram files DEC 20, 2002 +098 1 1 0 0 0 0 0.311 0.374 vet BA alters coef SEQ098, Cam Bartram + + +999 END + \ No newline at end of file From a08c0a0023cf1d98e50fd77d56415e31551fba6d Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 9 May 2023 21:21:35 -0700 Subject: [PATCH 05/98] Progress on parsing data files --- .../vdyp/io/parse/BecDefinitionParser.java | 47 +++ .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 242 +++++++++++++++ .../vdyp/io/parse/ResourceParseException.java | 38 +++ .../gov/nrs/vdyp/io/parse/ResourceParser.java | 23 ++ .../vdyp/io/parse/ValueParseException.java | 39 +++ .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 6 + .../bc/gov/nrs/vdyp/model/BecDefinition.java | 25 ++ .../java/ca/bc/gov/nrs/vdyp/model/Region.java | 24 ++ .../io/parse/BecDefinitionParserTest.java | 14 + .../gov/nrs/vdyp/io/parse/LineParserTest.java | 292 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse}/FIPSTART.CTR | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/VDYP.ctr | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/VDYP.ini | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/VDYP.tcl | 0 .../nrs/vdyp/io/parse}/VDYP7LoggingConfig.txt | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/VDYPBACK.CTR | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/VRIADJST.CTR | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/VRISTART.CTR | 0 .../gov/nrs/vdyp/io/parse}/coe/BACOE12A.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/BACOE269.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/BAFIP16.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/BASP05.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/BASP06.COE | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/BEC0.DAT | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/BGRP.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/Becdef.dat | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/COMPLIM.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/CVADJ.PRM | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/DGRP.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/DQCOE12A.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/DQFIP16Z.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/DQSP05.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/DQSP06.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/EMP111A1.PRM | 0 .../gov/nrs/vdyp/io/parse}/coe/EMP117A1.prm | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/FIPSTKR.PRM | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/GB01.COE | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/GD19.COE | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/GD20.coe | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/GD23.coe | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/GMODBA1.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/GROWBA11.coe | 0 .../gov/nrs/vdyp/io/parse}/coe/GROWBA27.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/GRPBA1.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/PCT_40.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/PCT_407.coe | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REG01.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGBA25.coe | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGBA2C.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGBAC.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/REGBAV01.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/REGBREAK.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGDQ18.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGDQ24.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGDQ26.coe | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGDQ4C.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGDQC.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/REGDQI04.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGDQL2.coe | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGHL.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGHL.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGHL1C.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGPR1C.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGV1C.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGVCU.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGVDU.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGVDU.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGVU.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGVU.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGVWU.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGVWU.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGYHLP.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/REGYHLP.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/REGYHLPA.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/REGYHLPA.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/REGYHLPB.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/REGYHLPC.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/SIAGEMAX.PRM | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/SIEQN.PRM | 0 .../ca/bc/gov/nrs/vdyp/io/parse}/coe/SP0.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/SP0DEF.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/SP0DEF_v0.dat | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/TOP309.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/TOP98.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/UPPERB02.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/VCG_VRI1.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/VCG_VRI2.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/VCG_VRI3.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/VETDQ2.DAT | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/VETVOL1.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/VGRPDEF1.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/VTOTREG4.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/YLDBA309.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/YLDBA405.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/YLDBA407.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/YLDDQ259.DAT | 0 .../gov/nrs/vdyp/io/parse}/coe/YLDDQ309.COE | 0 .../bc/gov/nrs/vdyp/io/parse}/coe/YLDDQ45.COE | 0 .../gov/nrs/vdyp/io/parse}/coe/mod19813.prm | 0 vdyp-fip/pom.xml | 8 + .../nrs/vdyp/fip/FipControlParserTest.java | 4 +- 101 files changed, 761 insertions(+), 1 deletion(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/FIPSTART.CTR (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/VDYP.ctr (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/VDYP.ini (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/VDYP.tcl (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/VDYP7LoggingConfig.txt (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/VDYPBACK.CTR (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/VRIADJST.CTR (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/VRISTART.CTR (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/BACOE12A.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/BACOE269.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/BAFIP16.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/BASP05.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/BASP06.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/BEC0.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/BGRP.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/Becdef.dat (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/COMPLIM.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/CVADJ.PRM (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/DGRP.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/DQCOE12A.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/DQFIP16Z.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/DQSP05.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/DQSP06.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/EMP111A1.PRM (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/EMP117A1.prm (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/FIPSTKR.PRM (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GB01.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GD19.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GD20.coe (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GD23.coe (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GMODBA1.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GROWBA11.coe (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GROWBA27.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/GRPBA1.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/PCT_40.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/PCT_407.coe (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REG01.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGBA25.coe (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGBA2C.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGBAC.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGBAV01.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGBREAK.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGDQ18.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGDQ24.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGDQ26.coe (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGDQ4C.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGDQC.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGDQI04.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGDQL2.coe (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGHL.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGHL.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGHL1C.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGPR1C.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGV1C.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGVCU.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGVDU.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGVDU.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGVU.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGVU.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGVWU.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGVWU.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGYHLP.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGYHLP.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGYHLPA.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGYHLPA.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGYHLPB.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/REGYHLPC.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/SIAGEMAX.PRM (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/SIEQN.PRM (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/SP0.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/SP0DEF.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/SP0DEF_v0.dat (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/TOP309.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/TOP98.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/UPPERB02.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/VCG_VRI1.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/VCG_VRI2.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/VCG_VRI3.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/VETDQ2.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/VETVOL1.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/VGRPDEF1.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/VTOTREG4.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/YLDBA309.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/YLDBA405.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/YLDBA407.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/YLDDQ259.DAT (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/YLDDQ309.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/YLDDQ45.COE (100%) rename {vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip => vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse}/coe/mod19813.prm (100%) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java new file mode 100644 index 000000000..93971c505 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -0,0 +1,47 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.Region; + +public class BecDefinitionParser implements ResourceParser>{ + + LineParser lineParser = new LineParser() { + + @Override + public boolean isStopSegment(List segments) { + return "Z".equalsIgnoreCase(segments.get(2)); + } + + } + .string(4, "alias") + .space(1) + .parse(1, "region", (s)->{ + return Region.fromAlias(Character.toUpperCase(s.charAt(0))) + .orElseThrow(()->new ValueParseException(s, s+" is not a valid region identifier")); + }) + .space(1) + .string("name"); + + @Override + public Map parse(InputStream is) throws IOException, ResourceParseException { + Map result = new HashMap<>(); + result = lineParser.parse(is, result, (v, r)->{ + String alias = (String) v.get("alias"); + Region region = (Region) v.get("region"); + String name = (String) v.get("name"); + var defn = new BecDefinition(alias, region, name); + r.put(alias, defn); + return r; + }); + + return Collections.unmodifiableMap(result); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java new file mode 100644 index 000000000..91d12a94b --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -0,0 +1,242 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; + +public class LineParser { + + List segments = new ArrayList<>(); + Charset charset = StandardCharsets.US_ASCII; + + static abstract class LineParserSegment { + int length; + + public int getLength() { + return length; + } + + public LineParserSegment(int length) { + super(); + this.length = length; + } + + public abstract void parseIntoMap(String toParse, Map map) throws ValueParseException; + } + + static class LineParserNullSegment extends LineParserSegment { + + public LineParserNullSegment(int length) { + super(length); + } + + @Override + public void parseIntoMap(String toParse, Map map) { + // do nothing + } + } + + static abstract class LineParserValueSegment extends LineParserSegment { + String name; + abstract T parse(String value) throws ValueParseException; + + public String getName() { + return name; + } + + @Override + public void parseIntoMap(String toParse, Map map) throws ValueParseException { + var value = this.parse(toParse); + map.put(this.getName(), value); + } + + public LineParserValueSegment(int length, String name) { + super(length); + this.name = name; + } + } + + public LineParser space(int length) { + segments.add(new LineParserNullSegment(length)); + return this; + } + + public LineParser integer(int length, String name) { + segments.add(new LineParserValueSegment(length, name) { + + @Override + Integer parse(String value) throws ValueParseException { + String stripped = value.strip(); + try { + return Integer.parseInt(stripped); + } catch (NumberFormatException ex) { + throw new ValueParseException(stripped, ex); + } + } + + }); + return this; + } + + public LineParser floating(int length, String name) { + segments.add(new LineParserValueSegment(length, name) { + + @Override + Float parse(String value) throws ValueParseException { + String stripped = value.strip(); + try { + return Float.parseFloat(stripped); + } catch (NumberFormatException ex) { + throw new ValueParseException(stripped, ex); + } + } + + }); + return this; + } + + public LineParser string(int length, String name) { + segments.add(new LineParserValueSegment(length, name) { + + @Override + String parse(String value) throws ValueParseException { + return value.strip(); + } + + }); + return this; + } + + public LineParser string(String name) { + segments.add(new LineParserValueSegment(-1, name) { + + @Override + String parse(String value) throws ValueParseException { + return value.strip(); + } + + }); + return this; + } + + public LineParser parse(int length, String name, ValueParser parser) { + segments.add(new LineParserValueSegment(length, name) { + + @Override + T parse(String value) throws ValueParseException { + return parser.parse(value); + } + + }); + return this; + } + + public LineParser parse(String name, ValueParser parser) { + segments.add(new LineParserValueSegment(-1, name) { + + @Override + T parse(String value) throws ValueParseException { + return parser.parse(value); + } + + }); + return this; + } + + List segmentize(String line) { + List result = new ArrayList<>(segments.size()); + + int i = 0; + for(var segment: segments) { + if(i>=line.length()) { + result.add(null); + continue; + }; + String segmentString; + if(segment.getLength()>=0 && i+segment.getLength() parse(String line) throws ValueParseException { + var segments = segmentize(line); + return parse(segments); + } + + private Map parse(List segmentStrings) throws ValueParseException { + if(segmentStrings.size() != segments.size()) { + throw new IllegalStateException("segment strings and segment halders must have the same size"); + } + + var result = new HashMap(); + + for(int i=0; i T parse (InputStream is, T result, BiFunction, T, T> addToResult) throws IOException, ResourceParseException { + var reader = new BufferedReader(new InputStreamReader(is, charset)); + String line; + int lineNumber = 0; + while((line = reader.readLine())!=null) { + lineNumber++; + try { + if(isStopLine(line)) { + break; + } + var segments = segmentize(line); + if(isStopSegment(segments)) { + break; + } + var entry = parse(segments); + if(isStopEntry(entry)) { + break; + } + result = addToResult.apply(entry, result); + } catch (ValueParseException ex) { + throw new ResourceParseException(lineNumber, ex); + } + } + return result; + } + + public List> parse (InputStream is) throws IOException, ResourceParseException { + var result = new ArrayList> (); + result = this.parse(is, result, (v, r)->{r.add(v); return r;}); + return result; + } + + public boolean isStopEntry(Map entry) { + return false; + } + + public boolean isStopSegment(List entry) { + return false; + } + + public boolean isStopLine(String line) { + return false; + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java new file mode 100644 index 000000000..c02360241 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java @@ -0,0 +1,38 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +public class ResourceParseException extends Exception { + + private static final long serialVersionUID = 5188546056230073563L; + + int line; + + public int getLine() { + return line; + } + + public ResourceParseException(int line, + String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace + ) { + super(message(line, message), cause, enableSuppression, writableStackTrace); + this.line = line; + } + + public ResourceParseException(int line, String message, Throwable cause) { + super(message, cause); + this.line = line; + } + + public ResourceParseException(int line, String message) { + super(message(line, message)); + this.line = line; + } + + public ResourceParseException(int line, Throwable cause) { + super(message(line, cause.getMessage()), cause); + this.line = line; + } + + private static String message(int line, String message) { + return String.format("Error at line %d: %s",line,message); + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java new file mode 100644 index 000000000..aaca8c197 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java @@ -0,0 +1,23 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +@FunctionalInterface +public interface ResourceParser { + T parse(InputStream is) throws IOException, ResourceParseException; + + default T parse (Class klazz, String resourcePath) throws IOException, ResourceParseException { + try (var is = klazz.getResourceAsStream(resourcePath)) { + return parse(is); + } + } + + default T parse (Path resourcePath) throws IOException, ResourceParseException { + try (InputStream is = Files.newInputStream(resourcePath)) { + return parse(is); + } + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java new file mode 100644 index 000000000..495548567 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java @@ -0,0 +1,39 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +public class ValueParseException extends Exception { + + private static final long serialVersionUID = 4181384333196602044L; + String value; + + public String getValue() { + return value; + } + + public ValueParseException(String value) { + super(); + this.value = value; + } + + public ValueParseException(String value, + String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace + ) { + super(message, cause, enableSuppression, writableStackTrace); + this.value = value; + } + + public ValueParseException(String value, String message, Throwable cause) { + super(message, cause); + this.value = value; + } + + public ValueParseException(String value, String message) { + super(message); + this.value = value; + } + + public ValueParseException(String value, Throwable cause) { + super(cause); + this.value = value; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java new file mode 100644 index 000000000..3d179f9a5 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -0,0 +1,6 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +@FunctionalInterface +public interface ValueParser { + T parse(String string) throws ValueParseException; +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java new file mode 100644 index 000000000..7f0b37f0a --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java @@ -0,0 +1,25 @@ +package ca.bc.gov.nrs.vdyp.model; + +public class BecDefinition { + + final String alias; + final Region region; + final String name; + + public BecDefinition(String alias, Region region, String name) { + super(); + this.alias = alias; + this.region = region; + this.name = name; + } + + public String getAlias() { + return alias; + } + public Region getRegion() { + return region; + } + public String getName() { + return name; + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java new file mode 100644 index 000000000..2ff4aa408 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java @@ -0,0 +1,24 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Arrays; +import java.util.Optional; + +public enum Region { + COASTAL('C'), + INTERIOR('I'); + + final char characterAlias; + + private Region(char characterAlias) { + this.characterAlias = characterAlias; + } + + public static Optional fromAlias(char alias) { + return Arrays.stream(Region.values()).filter(x->x.getCharacterAlias()==alias).findFirst(); + } + + public char getCharacterAlias() { + return characterAlias; + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java new file mode 100644 index 000000000..0b43ea053 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -0,0 +1,14 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import org.junit.jupiter.api.Test; + +public class BecDefinitionParserTest { + + @Test + public void testParse() throws Exception { + var parser = new BecDefinitionParser(); + + parser.parse(ControlFileParserTest.class, "coe/Becdef.dat"); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java new file mode 100644 index 000000000..38d8d5a0d --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -0,0 +1,292 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasKey; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isA; +import static org.hamcrest.Matchers.not; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +public class LineParserTest { + + @Test + public void testBasic() throws Exception { + var parser = new LineParser(); + parser + .string(3, "part1") + .space(1) + .string(4, "part2"); + + var result1 = parser.parse("042 Blah"); + + assertThat(result1, hasEntry("part1", "042")); + assertThat(result1, hasEntry("part2", "Blah")); + + } + + @Test + public void testNumbers() throws Exception { + var parser = new LineParser(); + parser + .integer(4, "part1") + .space(1) + .floating(5, "part2"); + + var result1 = parser.parse(" 4 0.5 "); + + assertThat(result1, hasEntry("part1", 4)); + assertThat(result1, hasEntry("part2", 0.5f)); + + } + + @Test + public void testIncomplete() throws Exception { + var parser = new LineParser(); + parser + .integer(4, "part1") + .space(1) + .floating(5, "part2"); + + var result1 = parser.parse(" 4 "); + + assertThat(result1, hasEntry("part1", 4)); + assertThat(result1, not(hasKey("part2"))); + + } + + @Test + public void testIncompleteSegment() throws Exception { + var parser = new LineParser(); + parser + .integer(4, "part1") + .space(1) + .floating(5, "part2"); + + var result1 = parser.parse(" 4 5.0"); + + assertThat(result1, hasEntry("part1", 4)); + assertThat(result1, hasEntry("part2", 5.0f)); + + } + + @Test + public void testNumberParseErrors() throws Exception { + var parser = new LineParser(); + parser + .integer(4, "part1") + .space(1) + .floating(5, "part2"); + + var ex1 = assertThrows(ValueParseException.class, ()->parser.parse(" X 0.5 ")); + + assertThat(ex1, hasProperty("value", is("X"))); + assertThat(ex1, hasProperty("cause", isA(NumberFormatException.class))); + + var ex2 = assertThrows(ValueParseException.class, ()->parser.parse(" 4 0.x ")); + + assertThat(ex2, hasProperty("value", is("0.x"))); + assertThat(ex2, hasProperty("cause", isA(NumberFormatException.class))); + + + } + + @Test + public void testValueParser() throws Exception { + var parser = new LineParser(); + parser + .parse(4, "part1", (s)->Integer.valueOf(s.strip())+1) + .space(1) + .parse("part2", (s)->Float.valueOf(s.strip())+1); + + var result1 = parser.parse(" 4 0.5 "); + + assertThat(result1, hasEntry("part1", 5)); + assertThat(result1, hasEntry("part2", 1.5f)); + + } + + @Test + public void testValueParserError() throws Exception { + var parser = new LineParser(); + parser + .parse(4, "part1", (s)->{throw new ValueParseException(s, "Testing");}) + .space(1) + .parse(4, "part2", (s)->Float.valueOf(s.strip())+1); + + var ex1 = assertThrows(ValueParseException.class, ()->parser.parse(" X 0.5 ")); + assertThat(ex1, hasProperty("value", is(" X "))); + assertThat(ex1, hasProperty("message", is("Testing"))); + + } + + @Test + public void testUnbounded() throws Exception { + var parser = new LineParser(); + parser + .string(4, "part1") + .string("part2"); + + var result1 = parser.parse("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + + assertThat(result1, hasEntry("part1", "1234")); + assertThat(result1, hasEntry("part2", "567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")); + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testMultiLine() throws Exception { + var parser = new LineParser(); + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + List> result = new ArrayList<>(); + try( + var is = new ByteArrayInputStream("0042 Value1\r\n0043 Value2".getBytes()); + ) { + result = parser.parse(is); + } + + assertThat(result, contains( + allOf( + (Matcher)hasEntry("part1", 42), + (Matcher)hasEntry("part2", "Value1") + ), + allOf( + (Matcher)hasEntry("part1", 43), + (Matcher)hasEntry("part2", "Value2") + ) + )); + } + + @Test + public void testMultiLineException() throws Exception { + var parser = new LineParser(); + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + try( + var is = new ByteArrayInputStream("0042 Value1\r\n004x Value2".getBytes()); + ) { + + var ex1 = assertThrows(ResourceParseException.class, ()-> parser.parse(is)); + + assertThat(ex1, hasProperty("line", is(2))); // Line numbers indexed from 1 so the error is line 2 + assertThat(ex1, hasProperty("cause", isA(ValueParseException.class))); + assertThat(ex1, hasProperty("cause", hasProperty("value", is("004x")))); + assertThat(ex1, hasProperty("cause", hasProperty("cause", isA(NumberFormatException.class)))); + + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testMultiLineWithStopEntry() throws Exception { + var parser = new LineParser() { + + @Override + public boolean isStopEntry(Map entry) { + return 0 == (int) entry.get("part1"); + } + + }; + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + List> result = new ArrayList<>(); + try( + var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes()); + ) { + result = parser.parse(is); + } + + assertThat(result, contains( + allOf( + (Matcher)hasEntry("part1", 42), + (Matcher)hasEntry("part2", "Value1") + ) + )); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testMultiLineWithStopLine() throws Exception { + var parser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.length()>4 && 'X' == Character.toUpperCase(line.charAt(4)); + } + + }; + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + List> result = new ArrayList<>(); + try( + var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); + ) { + result = parser.parse(is); + } + + assertThat(result, contains( + allOf( + (Matcher)hasEntry("part1", 42), + (Matcher)hasEntry("part2", "Value1") + ) + )); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testMultiLineWithStopSegment() throws Exception { + var parser = new LineParser() { + + @Override + public boolean isStopSegment(List segments) { + return 'X' == Character.toUpperCase(segments.get(1).charAt(0)); + } + + }; + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + List> result = new ArrayList<>(); + try( + var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); + ) { + result = parser.parse(is); + } + + assertThat(result, contains( + allOf( + (Matcher)hasEntry("part1", 42), + (Matcher)hasEntry("part2", "Value1") + ) + )); + } + +} diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/FIPSTART.CTR rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ctr b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP.ctr similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ctr rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP.ctr diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ini b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP.ini similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.ini rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP.ini diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.tcl b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP.tcl similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP.tcl rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP.tcl diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP7LoggingConfig.txt b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP7LoggingConfig.txt similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYP7LoggingConfig.txt rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYP7LoggingConfig.txt diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYPBACK.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYPBACK.CTR similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VDYPBACK.CTR rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VDYPBACK.CTR diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRIADJST.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VRIADJST.CTR similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRIADJST.CTR rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VRIADJST.CTR diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRISTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VRISTART.CTR similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/VRISTART.CTR rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/VRISTART.CTR diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE12A.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BACOE12A.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE12A.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BACOE12A.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE269.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BACOE269.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BACOE269.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BACOE269.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BAFIP16.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BAFIP16.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BAFIP16.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BAFIP16.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP05.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BASP05.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP05.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BASP05.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP06.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BASP06.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BASP06.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BASP06.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BEC0.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BEC0.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BEC0.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BEC0.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BGRP.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BGRP.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/BGRP.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/BGRP.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/Becdef.dat b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/Becdef.dat similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/Becdef.dat rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/Becdef.dat diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/COMPLIM.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/COMPLIM.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/COMPLIM.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/COMPLIM.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/CVADJ.PRM b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/CVADJ.PRM similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/CVADJ.PRM rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/CVADJ.PRM diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DGRP.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DGRP.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DGRP.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DGRP.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQCOE12A.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQCOE12A.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQCOE12A.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQCOE12A.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQFIP16Z.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQFIP16Z.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQFIP16Z.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQFIP16Z.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP05.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQSP05.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP05.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQSP05.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP06.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQSP06.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/DQSP06.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/DQSP06.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP111A1.PRM b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/EMP111A1.PRM similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP111A1.PRM rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/EMP111A1.PRM diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP117A1.prm b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/EMP117A1.prm similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/EMP117A1.prm rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/EMP117A1.prm diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/FIPSTKR.PRM b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/FIPSTKR.PRM similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/FIPSTKR.PRM rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/FIPSTKR.PRM diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GB01.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GB01.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GB01.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GB01.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD19.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GD19.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD19.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GD19.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD20.coe b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GD20.coe similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD20.coe rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GD20.coe diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD23.coe b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GD23.coe similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GD23.coe rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GD23.coe diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GMODBA1.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GMODBA1.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GMODBA1.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GMODBA1.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA11.coe b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GROWBA11.coe similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA11.coe rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GROWBA11.coe diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA27.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GROWBA27.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GROWBA27.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GROWBA27.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GRPBA1.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GRPBA1.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/GRPBA1.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/GRPBA1.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_40.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/PCT_40.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_40.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/PCT_40.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_407.coe b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/PCT_407.coe similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/PCT_407.coe rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/PCT_407.coe diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REG01.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REG01.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REG01.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REG01.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA25.coe b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBA25.coe similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA25.coe rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBA25.coe diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA2C.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBA2C.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBA2C.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBA2C.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAC.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBAC.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAC.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBAC.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAV01.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBAV01.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBAV01.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBAV01.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBREAK.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBREAK.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGBREAK.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGBREAK.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ18.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ18.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ18.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ18.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ24.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ24.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ24.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ24.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ26.coe b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ26.coe similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ26.coe rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ26.coe diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ4C.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ4C.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQ4C.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQ4C.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQC.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQC.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQC.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQC.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQI04.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQI04.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQI04.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQI04.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQL2.coe b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQL2.coe similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGDQL2.coe rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGDQL2.coe diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGHL.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGHL.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGHL.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGHL.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL1C.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGHL1C.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGHL1C.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGHL1C.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGPR1C.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGPR1C.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGPR1C.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGPR1C.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGV1C.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGV1C.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGV1C.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGV1C.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVCU.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVCU.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVCU.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVCU.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVDU.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVDU.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVDU.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVDU.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVDU.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVU.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVU.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVU.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVU.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVU.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVWU.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVWU.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVWU.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGVWU.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGVWU.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLP.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLP.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLP.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLP.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLP.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPA.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPA.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPA.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPA.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPA.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPB.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPB.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPB.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPB.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPC.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPC.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/REGYHLPC.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/REGYHLPC.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIAGEMAX.PRM b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIAGEMAX.PRM similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIAGEMAX.PRM rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIAGEMAX.PRM diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIEQN.PRM b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIEQN.PRM similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SIEQN.PRM rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIEQN.PRM diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SP0.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SP0.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SP0DEF.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SP0DEF.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF_v0.dat b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SP0DEF_v0.dat similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/SP0DEF_v0.dat rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SP0DEF_v0.dat diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP309.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/TOP309.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP309.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/TOP309.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP98.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/TOP98.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/TOP98.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/TOP98.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/UPPERB02.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/UPPERB02.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/UPPERB02.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/UPPERB02.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI1.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VCG_VRI1.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI1.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VCG_VRI1.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI2.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VCG_VRI2.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI2.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VCG_VRI2.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI3.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VCG_VRI3.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VCG_VRI3.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VCG_VRI3.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETDQ2.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VETDQ2.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETDQ2.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VETDQ2.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETVOL1.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VETVOL1.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VETVOL1.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VETVOL1.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VGRPDEF1.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VGRPDEF1.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VGRPDEF1.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VGRPDEF1.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VTOTREG4.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VTOTREG4.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/VTOTREG4.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/VTOTREG4.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA309.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDBA309.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA309.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDBA309.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA405.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDBA405.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA405.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDBA405.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA407.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDBA407.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDBA407.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDBA407.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ259.DAT b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDDQ259.DAT similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ259.DAT rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDDQ259.DAT diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ309.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDDQ309.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ309.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDDQ309.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ45.COE b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDDQ45.COE similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/YLDDQ45.COE rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/YLDDQ45.COE diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/mod19813.prm b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/mod19813.prm similarity index 100% rename from vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/coe/mod19813.prm rename to vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/mod19813.prm diff --git a/vdyp-fip/pom.xml b/vdyp-fip/pom.xml index 745f6ad43..27b3d89dc 100644 --- a/vdyp-fip/pom.xml +++ b/vdyp-fip/pom.xml @@ -21,6 +21,14 @@ ${project.version} + + ca.bc.gov.nrs.vdyp + vdyp-core + ${project.version} + test-jar + test + + org.junit.jupiter junit-jupiter-api diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 28c5d3bb8..b7de5fcb8 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -2,12 +2,14 @@ import org.junit.jupiter.api.Test; +import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; + public class FipControlParserTest { @Test public void testParse() throws Exception { var parser = new FipControlParser(); - var result = parser.parse(FipControlParserTest.class, "FIPSTART.CTR"); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); } } From 92487aca0d493e5cc766ef850933607465dbc9e9 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 10 May 2023 22:34:36 -0700 Subject: [PATCH 06/98] Rewrite control file parser to use LineParser --- .../nrs/vdyp/io/parse/ControlFileParser.java | 137 ++++++----------- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 52 ++++++- .../nrs/vdyp/io/parse/ParseEntryHandler.java | 6 + .../vdyp/io/parse/ControlFileParserTest.java | 145 ++++++++---------- .../gov/nrs/vdyp/io/parse/LineParserTest.java | 125 ++++++++++++++- .../ca/bc/gov/nrs/vdyp/test/VydpMatchers.java | 28 ++++ 6 files changed, 316 insertions(+), 177 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index 060bf875e..eac555e1f 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -1,16 +1,13 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * Parser for control files @@ -24,9 +21,6 @@ public class ControlFileParser { public static final int EXTEND_LENGTH = 1; public static final int CONTROL_LENGTH_EXTENDED = 120; public static final int CONTROL_LENGTH = 50; - public static final int NEWLINE_LENGTH = 2; - - public static final int RECORD_BUFFER_LENGTH = INDEX_LENGTH + EXTEND_LENGTH + CONTROL_LENGTH + NEWLINE_LENGTH; public static final List EXTEND_FLAGS = Arrays.asList("X", ">"); public static final List COMMENT_FLAGS = Arrays.asList("C"); @@ -36,30 +30,21 @@ public class ControlFileParser { private Map> valueParsers; private Function defaultValueParser; - public static class Entry { - public final int index; - public final String extend; - public final String control; - - public int getIndex() { - return index; - } + LineParser lineParser = new LineParser() { - public String getExtend() { - return extend; + @Override + public boolean isIgnoredLine(String line) { + return line.isBlank(); } - - public String getControl() { - return control; - } - - public Entry(int index, String extend, String control) { - super(); - this.index = index; - this.extend = extend; - this.control = control; + @Override + public boolean isIgnoredSegment(List segments) { + return segments.get(0).isBlank(); } + } + .integer(3, "index") + .string(1, "extend") + .string("restOfLine"); /** * @@ -82,65 +67,43 @@ public ControlFileParser() { this(Collections.emptyMap(), Collections.emptyMap(), String::strip); } - public Stream parseEntries(InputStream input) { - return new BufferedReader(new InputStreamReader(input, StandardCharsets.US_ASCII), RECORD_BUFFER_LENGTH).lines() - .flatMap(line -> { - // - if(line.isBlank()) { - return Stream.empty(); - } - final String indexString = line.substring(0, INDEX_LENGTH); - final String extendString = line.substring(INDEX_LENGTH, INDEX_LENGTH + EXTEND_LENGTH); - - // Ignore comments marked with exend flag C - if(COMMENT_FLAGS.contains(extendString)) { - return Stream.empty(); - } - // Ignore comments marked with a blank index - final int index; - if (indexString.isBlank()) { - return Stream.empty(); - } else { - index = Integer.valueOf(indexString.strip()); - } - // Ignore comment marked with index 0 - if(index==0) { - return Stream.empty(); - } - - // How long is the control value - int controlLength = Math.min( - EXTEND_FLAGS.contains(extendString) ? - CONTROL_LENGTH_EXTENDED : - CONTROL_LENGTH, - line.length( ) - (INDEX_LENGTH + EXTEND_LENGTH)); - String controlString = line - .substring(INDEX_LENGTH + EXTEND_LENGTH, INDEX_LENGTH + EXTEND_LENGTH + controlLength); - - // Inline comments marked with ! - int startOfComment = controlString.indexOf(COMMENT_MARKER); - if(startOfComment>-1) { - controlString = controlString.substring(0,startOfComment); - } - - return Stream.of(new Entry(index, extendString, controlString)); - }); - } - - /** - * Parse a control file into a map. Known index values will be replaced with meaningful identifiers. - * @param input - * @return - */ - public Map parseToMap(InputStream input) { - try(Stream parseEntries = parseEntries(input);) { - return parseEntries.collect( - Collectors.toMap( - e->identifiers.getOrDefault(e.getIndex(), String.format("%03d", e.getIndex())), - e->valueParsers.getOrDefault(e.getIndex(), defaultValueParser).apply(e.getControl()), - (x,y)->y // On duplicates, keep the last value - )); - } + public Map parse(InputStream input) throws IOException, ResourceParseException { + Map result = new HashMap<>(); + return lineParser.parse(input, result, (map,r)->{ + Integer index = (Integer) map.get("index"); + String extend = (String) map.get("extend"); + String restOfLine = (String) map.get("restOfLine"); + // Ignore comments marked with exend flag C + if(COMMENT_FLAGS.contains(extend)) return r; + // Ignore comments marked with a blank index + if(index==null) return r; + // Ignore comment marked with index 0 + if(index==0) return r; + + // How long is the control value + int controlLength = Math.min( + EXTEND_FLAGS.contains(extend) ? + CONTROL_LENGTH_EXTENDED : + CONTROL_LENGTH, + restOfLine.length( )); + + // Trim inline comments + int commentMarkerPosition = restOfLine.indexOf(COMMENT_MARKER); + if(commentMarkerPosition>=0) { + controlLength = Math.min(controlLength, commentMarkerPosition); + } + + // Find the string representation of the value of the control + String controlString = restOfLine + .substring(0, controlLength); + + String key = identifiers.getOrDefault(index, String.format("%03d", index)); + Object value = valueParsers.getOrDefault(index, defaultValueParser).apply(controlString); + + result.put(key, value); + + return result; + }); } /** diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 91d12a94b..136ee65b3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -10,7 +10,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.BiFunction; public class LineParser { @@ -108,7 +107,7 @@ public LineParser string(int length, String name) { @Override String parse(String value) throws ValueParseException { - return value.strip(); + return value; } }); @@ -118,6 +117,18 @@ String parse(String value) throws ValueParseException { public LineParser string(String name) { segments.add(new LineParserValueSegment(-1, name) { + @Override + String parse(String value) throws ValueParseException { + return value; + } + + }); + return this; + } + + public LineParser strippedString(int length, String name) { + segments.add(new LineParserValueSegment(length, name) { + @Override String parse(String value) throws ValueParseException { return value.strip(); @@ -127,6 +138,18 @@ String parse(String value) throws ValueParseException { return this; } + public LineParser strippedString(String name) { + segments.add(new LineParserValueSegment(-1, name) { + + @Override + String parse(String value) throws ValueParseException { + return value.strip(); + } + + }); + return this; + } + public LineParser parse(int length, String name, ValueParser parser) { segments.add(new LineParserValueSegment(length, name) { @@ -196,7 +219,7 @@ private Map parse(List segmentStrings) throws ValueParseE return result; } - public T parse (InputStream is, T result, BiFunction, T, T> addToResult) throws IOException, ResourceParseException { + public T parse (InputStream is, T result, ParseEntryHandler, T> addToResult) throws IOException, ResourceParseException { var reader = new BufferedReader(new InputStreamReader(is, charset)); String line; int lineNumber = 0; @@ -206,15 +229,24 @@ public T parse (InputStream is, T result, BiFunction, T, if(isStopLine(line)) { break; } + if(isIgnoredLine(line)) { + continue; + } var segments = segmentize(line); if(isStopSegment(segments)) { break; } + if(isIgnoredSegment(segments)) { + continue; + } var entry = parse(segments); if(isStopEntry(entry)) { break; } - result = addToResult.apply(entry, result); + if(isIgnoredEntry(entry)) { + continue; + } + result = addToResult.addTo(entry, result); } catch (ValueParseException ex) { throw new ResourceParseException(lineNumber, ex); } @@ -239,4 +271,16 @@ public boolean isStopSegment(List entry) { public boolean isStopLine(String line) { return false; } + + public boolean isIgnoredEntry(Map entry) { + return false; + } + + public boolean isIgnoredSegment(List entry) { + return false; + } + + public boolean isIgnoredLine(String line) { + return false; + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java new file mode 100644 index 000000000..e4d570d3b --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java @@ -0,0 +1,6 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +@FunctionalInterface +public interface ParseEntryHandler { + public Result addTo(Entry entry, Result result) throws ValueParseException; +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index c81c72332..2fe06e883 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -1,5 +1,6 @@ package ca.bc.gov.nrs.vdyp.io.parse; +import static ca.bc.gov.nrs.vdyp.test.VydpMatchers.parseAs; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; @@ -12,24 +13,24 @@ import java.io.InputStream; import java.util.Arrays; import java.util.HashMap; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser.Entry; - public class ControlFileParserTest { @Test void testParsesEntriesSimple() throws Exception { var parser = makeParser(); + + String file = "001 Control"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - try (InputStream is = new ByteArrayInputStream("001 Control".getBytes()); var stream = parser.parseEntries(is);) { - var result = stream.collect(Collectors.toList()); - - assertThat(result, contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); + assertThat(result.entrySet(), contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); } } @@ -37,10 +38,11 @@ void testParsesEntriesSimple() throws Exception { void testParsesEntriesSpacePadding() throws Exception { var parser = makeParser(); - try (InputStream is = new ByteArrayInputStream(" 1 Control".getBytes()); var stream = parser.parseEntries(is);) { - var result = stream.collect(Collectors.toList()); + String file = " 1 Control"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - assertThat(result, contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); + assertThat(result.entrySet(), contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); } } @@ -48,16 +50,12 @@ void testParsesEntriesSpacePadding() throws Exception { void testParsesEntriesExtended() throws Exception { var parser = makeParser(); - try ( - InputStream is = new ByteArrayInputStream( - "001XControl that is longer than 50 characters. Blah Blah Blah Blah.".getBytes() - ); - var stream = parser.parseEntries(is) - ) { - var result = stream.collect(Collectors.toList()); + String file = "001XControl that is longer than 50 characters. Blah Blah Blah Blah."; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); assertThat( - result, + result.entrySet(), contains( controlEntry( equalTo(1), equalTo("X"), equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") @@ -71,16 +69,12 @@ void testParsesEntriesExtended() throws Exception { void testParsesEntriesExtendedAlternate() throws Exception { var parser = makeParser(); - try ( - InputStream is = new ByteArrayInputStream( - "001>Control that is longer than 50 characters. Blah Blah Blah Blah.".getBytes() - ); - var stream = parser.parseEntries(is) - ) { - var result = stream.collect(Collectors.toList()); + String file = "001>Control that is longer than 50 characters. Blah Blah Blah Blah."; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); assertThat( - result, + result.entrySet(), contains( controlEntry( equalTo(1), equalTo(">"), equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") @@ -94,18 +88,14 @@ void testParsesEntriesExtendedAlternate() throws Exception { void testParsesEntriesWithDistantComment() throws Exception { var parser = makeParser(); - try ( - InputStream is = new ByteArrayInputStream( - "001 Control Comment".getBytes() - ); - var stream = parser.parseEntries(is) - ) { - var result = stream.collect(Collectors.toList()); + String file = "001 Control Comment"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); assertThat( - result, + result.entrySet(), contains( - controlEntry(equalTo(1), equalTo(" "), equalTo("Control ")) + controlEntry(equalTo(1), equalTo(" "), equalTo("Control")) ) ); } @@ -115,22 +105,17 @@ void testParsesEntriesWithDistantComment() throws Exception { void testParsesEntriesExtendedWithDistantComment() throws Exception { var parser = makeParser(); - try ( - InputStream is = new ByteArrayInputStream( - "001XControl Comment" - .getBytes() - ); - var stream = parser.parseEntries(is) - ) { - var result = stream.collect(Collectors.toList()); + String file = "001XControl Comment"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); assertThat( - result, + result.entrySet(), contains( controlEntry( equalTo(1), equalTo("X"), equalTo( - "Control " + "Control" ) ) ) @@ -142,13 +127,11 @@ void testParsesEntriesExtendedWithDistantComment() throws Exception { void testParsesEntriesWithMarkedComment() throws Exception { var parser = makeParser(); - try ( - InputStream is = new ByteArrayInputStream("001 Control!Comment".getBytes()); - var stream = parser.parseEntries(is) - ) { - var result = stream.collect(Collectors.toList()); + String file = "001 Control!Comment"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - assertThat(result, contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); + assertThat(result.entrySet(), contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); } } @@ -156,13 +139,11 @@ void testParsesEntriesWithMarkedComment() throws Exception { void testParsesEntriesExtendedWithMarkedComment() throws Exception { var parser = makeParser(); - try ( - InputStream is = new ByteArrayInputStream("001XControl!Comment".getBytes()); - var stream = parser.parseEntries(is) - ) { - var result = stream.collect(Collectors.toList()); + String file = "001XControl!Comment"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - assertThat(result, contains(controlEntry(equalTo(1), equalTo("X"), equalTo("Control")))); + assertThat(result.entrySet(), contains(controlEntry(equalTo(1), equalTo("X"), equalTo("Control")))); } } @@ -170,10 +151,11 @@ void testParsesEntriesExtendedWithMarkedComment() throws Exception { void testParsesEntriesIgnoreCommentLinesByExtendedMarker() throws Exception { var parser = makeParser(); - try (InputStream is = new ByteArrayInputStream("001CComment".getBytes()); var stream = parser.parseEntries(is)) { - var result = stream.collect(Collectors.toList()); + String file = "001CComment"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - assertThat(result, empty()); + assertThat(result.entrySet(), empty()); } } @@ -181,10 +163,11 @@ void testParsesEntriesIgnoreCommentLinesByExtendedMarker() throws Exception { void testParsesEntriesIgnoreCommentLinesByZeroIndex() throws Exception { var parser = makeParser(); - try (InputStream is = new ByteArrayInputStream("000 Comment".getBytes()); var stream = parser.parseEntries(is);) { - var result = stream.collect(Collectors.toList()); + String file = "000 Comment"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - assertThat(result, empty()); + assertThat(result.entrySet(), empty()); } } @@ -192,10 +175,11 @@ void testParsesEntriesIgnoreCommentLinesByZeroIndex() throws Exception { void testParsesEntriesIgnoreCommentLinesByNullIndex() throws Exception { var parser = makeParser(); - try (InputStream is = new ByteArrayInputStream(" Comment".getBytes()); var stream = parser.parseEntries(is);) { - var result = stream.collect(Collectors.toList()); + String file = " Comment"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - assertThat(result, empty()); + assertThat(result.entrySet(), empty()); } } @@ -203,13 +187,11 @@ void testParsesEntriesIgnoreCommentLinesByNullIndex() throws Exception { void testParsesEntriesIgnoreEmptyLines() throws Exception { var parser = makeParser(); - try ( - InputStream is = new ByteArrayInputStream("\n \n \n \n ".getBytes()); - var stream = parser.parseEntries(is); - ) { - var result = stream.collect(Collectors.toList()); + String file = "\n \n \n \n "; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); - assertThat(result, empty()); + assertThat(result.entrySet(), empty()); } } @@ -217,14 +199,12 @@ void testParsesEntriesIgnoreEmptyLines() throws Exception { void testParsesMultipleEntries() throws Exception { var parser = makeParser(); - try ( - var is = new ByteArrayInputStream("001 Control 1\n002 Control 2".getBytes()); - var stream = parser.parseEntries(is); - ) { - var result = stream.collect(Collectors.toList()); + String file = "001 Control 1\n002 Control 2"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); assertThat( - result, + result.entrySet(), contains( controlEntry(equalTo(1), equalTo(" "), equalTo("Control 1")), controlEntry(equalTo(2), equalTo(" "), equalTo("Control 2")) @@ -249,7 +229,7 @@ void testParseToMap() throws Exception { try( var is = new ByteArrayInputStream(file.getBytes()); ) { - var result = parser.parseToMap(is); + var result = parser.parse(is); assertThat(result, hasEntry(equalTo("097"), equalTo("coe\\vetdq2.dat"))); @@ -278,7 +258,7 @@ void testParseToMapWithConfiguration() throws Exception { try( var is = new ByteArrayInputStream(file.getBytes()); ) { - var result = parser.parseToMap(is); + var result = parser.parse(is); assertThat(result, hasEntry(equalTo("097"), equalTo("coe\\vetdq2.dat"))); @@ -299,7 +279,7 @@ void testParseToMapLastOfDuplicates() throws Exception { try( var is = new ByteArrayInputStream(file.getBytes()); ) { - var result = parser.parseToMap(is); + var result = parser.parse(is); assertThat(result, hasEntry(equalTo("097"), equalTo("value2"))); @@ -307,8 +287,9 @@ void testParseToMapLastOfDuplicates() throws Exception { } - private static Matcher controlEntry(Matcher index, Matcher extend, Matcher control) { - return allOf(hasProperty("index", index), hasProperty("extend", extend), hasProperty("control", control)); + private static Matcher> controlEntry(Matcher index, Matcher extend, Matcher control) { + + return allOf(hasProperty("key", parseAs(index, Integer::valueOf)), hasProperty("value", control)); } private ControlFileParser makeParser() { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 38d8d5a0d..5ab2b5402 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -17,7 +17,6 @@ import java.util.Map; import org.hamcrest.Matcher; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; public class LineParserTest { @@ -139,10 +138,24 @@ public void testUnbounded() throws Exception { .string(4, "part1") .string("part2"); - var result1 = parser.parse("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + var result1 = parser.parse("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); - assertThat(result1, hasEntry("part1", "1234")); - assertThat(result1, hasEntry("part2", "567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")); + assertThat(result1, hasEntry("part1", "123 ")); + assertThat(result1, hasEntry("part2", " 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ")); + + } + + @Test + public void testStripped() throws Exception { + var parser = new LineParser(); + parser + .strippedString(4, "part1") + .strippedString("part2"); + + var result1 = parser.parse("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); + + assertThat(result1, hasEntry("part1", "123")); + assertThat(result1, hasEntry("part2", "67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")); } @@ -288,5 +301,109 @@ public boolean isStopSegment(List segments) { ) )); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testMultiLineWithIgnoredEntry() throws Exception { + var parser = new LineParser() { + + @Override + public boolean isIgnoredEntry(Map entry) { + return 0 == (int) entry.get("part1"); + } + + }; + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + List> result = new ArrayList<>(); + try( + var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes()); + ) { + result = parser.parse(is); + } + + assertThat(result, contains( + allOf( + (Matcher)hasEntry("part1", 42), + (Matcher)hasEntry("part2", "Value1") + ), + allOf( + (Matcher)hasEntry("part1", 43), + (Matcher)hasEntry("part2", "Value2") + ) + )); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testMultiLineWithIgnoredLine() throws Exception { + var parser = new LineParser() { + + @Override + public boolean isIgnoredLine(String line) { + return line.length()>4 && 'X' == Character.toUpperCase(line.charAt(4)); + } + + }; + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + List> result = new ArrayList<>(); + try( + var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); + ) { + result = parser.parse(is); + } + + assertThat(result, contains( + allOf( + (Matcher)hasEntry("part1", 42), + (Matcher)hasEntry("part2", "Value1") + ), + allOf( + (Matcher)hasEntry("part1", 43), + (Matcher)hasEntry("part2", "Value2") + ) + )); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testMultiLineWithIgnoredSegment() throws Exception { + var parser = new LineParser() { + + @Override + public boolean isIgnoredSegment(List segments) { + return 'X' == Character.toUpperCase(segments.get(1).charAt(0)); + } + + }; + parser + .integer(4, "part1") + .space(1) + .string("part2"); + + List> result = new ArrayList<>(); + try( + var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); + ) { + result = parser.parse(is); + } + + assertThat(result, contains( + allOf( + (Matcher)hasEntry("part1", 42), + (Matcher)hasEntry("part2", "Value1") + ), + allOf( + (Matcher)hasEntry("part1", 43), + (Matcher)hasEntry("part2", "Value2") + ) + )); + } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java new file mode 100644 index 000000000..75f1a4c69 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java @@ -0,0 +1,28 @@ +package ca.bc.gov.nrs.vdyp.test; + +import java.util.function.Function; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +public class VydpMatchers { + + public static Matcher parseAs(Matcher parsedMatcher, Function parser) { + return new BaseMatcher() { + + @Override + public boolean matches(Object actual) { + return parsedMatcher.matches(parser.apply(actual.toString())); + } + + @Override + public void describeTo(Description description) { + description.appendText("parses as "); + parsedMatcher.describeTo(description); + } + + }; + } + +} From 262164da9380a3dc3b767ebd0195c16125339db9 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 10 May 2023 23:07:40 -0700 Subject: [PATCH 07/98] BecParserTest --- .../vdyp/io/parse/BecDefinitionParser.java | 4 +- .../io/parse/BecDefinitionParserTest.java | 83 ++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index 93971c505..7a636000a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -20,14 +20,14 @@ public boolean isStopSegment(List segments) { } } - .string(4, "alias") + .strippedString(4, "alias") .space(1) .parse(1, "region", (s)->{ return Region.fromAlias(Character.toUpperCase(s.charAt(0))) .orElseThrow(()->new ValueParseException(s, s+" is not a valid region identifier")); }) .space(1) - .string("name"); + .strippedString("name"); @Override public Map parse(InputStream is) throws IOException, ResourceParseException { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index 0b43ea053..639f90026 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -1,14 +1,95 @@ package ca.bc.gov.nrs.vdyp.io.parse; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; + + +import static org.hamcrest.Matchers.equalTo; + import org.junit.jupiter.api.Test; +import ca.bc.gov.nrs.vdyp.model.Region; + public class BecDefinitionParserTest { @Test public void testParse() throws Exception { var parser = new BecDefinitionParser(); - parser.parse(ControlFileParserTest.class, "coe/Becdef.dat"); + var result = parser.parse(ControlFileParserTest.class, "coe/Becdef.dat"); + + assertThat(result, hasEntry(equalTo("AT"), allOf( + hasProperty("alias", equalTo("AT")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Alpine Tundra")) + ))); + assertThat(result, hasEntry(equalTo("BG"), allOf( + hasProperty("alias", equalTo("BG")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Bunchgrass")) + ))); + assertThat(result, hasEntry(equalTo("BWBS"), allOf( + hasProperty("alias", equalTo("BWBS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Boreal White and Black Spruce")) + ))); + assertThat(result, hasEntry(equalTo("CDF"), allOf( + hasProperty("alias", equalTo("CDF")), + hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Coastal Dougfir")) + ))); + assertThat(result, hasEntry(equalTo("CWH"), allOf( + hasProperty("alias", equalTo("CWH")), + hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Coastal Western Hemlock")) + ))); + assertThat(result, hasEntry(equalTo("ESSF"), allOf( + hasProperty("alias", equalTo("ESSF")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Englemann Sruce -SubAlpine Fir")) + ))); + assertThat(result, hasEntry(equalTo("ICH"), allOf( + hasProperty("alias", equalTo("ICH")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Interior Cedar-Hemlock")) + ))); + assertThat(result, hasEntry(equalTo("IDF"), allOf( + hasProperty("alias", equalTo("IDF")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Interior DougFir")) + ))); + assertThat(result, hasEntry(equalTo("MH"), allOf( + hasProperty("alias", equalTo("MH")), + hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Mountain Hemlock")) + ))); + assertThat(result, hasEntry(equalTo("MS"), allOf( + hasProperty("alias", equalTo("MS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Montane Spruce")) + ))); + assertThat(result, hasEntry(equalTo("PP"), allOf( + hasProperty("alias", equalTo("PP")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Ponderosa Pine")) + ))); + assertThat(result, hasEntry(equalTo("SBPS"), allOf( + hasProperty("alias", equalTo("SBPS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("SubBoreal Pine-Spruce")) + ))); + assertThat(result, hasEntry(equalTo("SBS"), allOf( + hasProperty("alias", equalTo("SBS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("SubBoreal Spruce")) + ))); + assertThat(result, hasEntry(equalTo("SWB"), allOf( + hasProperty("alias", equalTo("SWB")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Spruce-Willow-Birch")) + ))); } } From 3e93b27b21544aa0cdaa5ae3009d29247c0c964f Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 11 May 2023 01:26:41 -0700 Subject: [PATCH 08/98] Docs and refinements --- .../vdyp/io/parse/BecDefinitionParser.java | 8 +- .../nrs/vdyp/io/parse/ControlFileParser.java | 28 ++- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 193 ++++++++++-------- .../nrs/vdyp/io/parse/ParseEntryHandler.java | 15 ++ .../vdyp/io/parse/ResourceParseException.java | 6 + .../gov/nrs/vdyp/io/parse/ResourceParser.java | 29 +++ .../vdyp/io/parse/ValueParseException.java | 6 + .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 86 ++++++++ .../vdyp/io/parse/ControlFileParserTest.java | 46 ++++- .../gov/nrs/vdyp/io/parse/LineParserTest.java | 28 +-- .../ca/bc/gov/nrs/vdyp/test/VydpMatchers.java | 25 ++- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 5 +- 12 files changed, 349 insertions(+), 126 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index 7a636000a..cc3cacf05 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -10,6 +10,12 @@ import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; +/** + * Parser for a BEC Definition data file + * + * @author Kevin Smith, Vivid Solutions + * + */ public class BecDefinitionParser implements ResourceParser>{ LineParser lineParser = new LineParser() { @@ -22,7 +28,7 @@ public boolean isStopSegment(List segments) { } .strippedString(4, "alias") .space(1) - .parse(1, "region", (s)->{ + .value(1, "region", (s)->{ return Region.fromAlias(Character.toUpperCase(s.charAt(0))) .orElseThrow(()->new ValueParseException(s, s+" is not a valid region identifier")); }) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index eac555e1f..7909dcb0e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -7,7 +7,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; /** * Parser for control files @@ -15,7 +14,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class ControlFileParser { +public class ControlFileParser implements ResourceParser> { public static final int INDEX_LENGTH = 3; public static final int EXTEND_LENGTH = 1; @@ -27,8 +26,8 @@ public class ControlFileParser { public static final String COMMENT_MARKER = "!"; private Map identifiers; - private Map> valueParsers; - private Function defaultValueParser; + private Map> valueParsers; + private ValueParser defaultValueParser; LineParser lineParser = new LineParser() { @@ -40,6 +39,10 @@ public boolean isIgnoredLine(String line) { public boolean isIgnoredSegment(List segments) { return segments.get(0).isBlank(); } + @Override + public boolean isIgnoredEntry(Map segments) { + return 0==(Integer)segments.get("index") || COMMENT_FLAGS.contains(segments.get("extend")); + } } .integer(3, "index") @@ -53,7 +56,7 @@ public boolean isIgnoredSegment(List segments) { * @param defaultParser a default value parser to use when one can't be found in the value parser map */ public ControlFileParser( - Map identifiers, Map> parsers, Function defaultParser + Map identifiers, Map> parsers, ValueParser defaultParser ) { this.identifiers = identifiers; this.valueParsers = parsers; @@ -66,19 +69,14 @@ public ControlFileParser( public ControlFileParser() { this(Collections.emptyMap(), Collections.emptyMap(), String::strip); } - + + @Override public Map parse(InputStream input) throws IOException, ResourceParseException { Map result = new HashMap<>(); return lineParser.parse(input, result, (map,r)->{ Integer index = (Integer) map.get("index"); String extend = (String) map.get("extend"); String restOfLine = (String) map.get("restOfLine"); - // Ignore comments marked with exend flag C - if(COMMENT_FLAGS.contains(extend)) return r; - // Ignore comments marked with a blank index - if(index==null) return r; - // Ignore comment marked with index 0 - if(index==0) return r; // How long is the control value int controlLength = Math.min( @@ -98,7 +96,7 @@ public Map parse(InputStream input) throws IOException, Resource .substring(0, controlLength); String key = identifiers.getOrDefault(index, String.format("%03d", index)); - Object value = valueParsers.getOrDefault(index, defaultValueParser).apply(controlString); + Object value = valueParsers.getOrDefault(index, defaultValueParser).parse(controlString); result.put(key, value); @@ -116,14 +114,14 @@ public void setIdentifiers(Map identifiers) { /** * Set a map of parsers for control values based on the sequence index */ - public void setValueParsers(Map> parsers) { + public void setValueParsers(Map> parsers) { this.valueParsers = parsers; } /** * Set a default value parser to use when one can't be found in the parser map */ - public void setDefaultValueParser(Function defaultParser) { + public void setDefaultValueParser(ValueParser defaultParser) { this.defaultValueParser = defaultParser; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 136ee65b3..8574ca619 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -11,12 +11,18 @@ import java.util.List; import java.util.Map; +/** + * Parse a file with records consisting of lines with fixed width fields. + * + * @author Kevin Smith, Vivid Solutions + * + */ public class LineParser { - List segments = new ArrayList<>(); - Charset charset = StandardCharsets.US_ASCII; + private List segments = new ArrayList<>(); + public static final Charset charset = StandardCharsets.US_ASCII; - static abstract class LineParserSegment { + static private abstract class LineParserSegment { int length; public int getLength() { @@ -31,7 +37,7 @@ public LineParserSegment(int length) { public abstract void parseIntoMap(String toParse, Map map) throws ValueParseException; } - static class LineParserNullSegment extends LineParserSegment { + static private class LineParserNullSegment extends LineParserSegment { public LineParserNullSegment(int length) { super(length); @@ -63,107 +69,85 @@ public LineParserValueSegment(int length, String name) { } } + /** + * ignore a segment of characters + * @param length + * @return + */ public LineParser space(int length) { segments.add(new LineParserNullSegment(length)); return this; } + /** + * A decimal integer segment + */ public LineParser integer(int length, String name) { - segments.add(new LineParserValueSegment(length, name) { - - @Override - Integer parse(String value) throws ValueParseException { - String stripped = value.strip(); - try { - return Integer.parseInt(stripped); - } catch (NumberFormatException ex) { - throw new ValueParseException(stripped, ex); - } - } - - }); - return this; + return this.value(length, name, ValueParser.INTEGER); } + /** + * A floating point segment + */ public LineParser floating(int length, String name) { - segments.add(new LineParserValueSegment(length, name) { - - @Override - Float parse(String value) throws ValueParseException { - String stripped = value.strip(); - try { - return Float.parseFloat(stripped); - } catch (NumberFormatException ex) { - throw new ValueParseException(stripped, ex); - } - } - - }); - return this; + return this.value(length, name, ValueParser.FLOAT); } + /** + * A string segment + */ public LineParser string(int length, String name) { - segments.add(new LineParserValueSegment(length, name) { - - @Override - String parse(String value) throws ValueParseException { - return value; - } - - }); - return this; + return this.value(length, name, s->s); } + /** + * A string segment with no bounds. No further segments may be added. + */ public LineParser string(String name) { - segments.add(new LineParserValueSegment(-1, name) { - - @Override - String parse(String value) throws ValueParseException { - return value; - } - - }); - return this; + return this.value(name, s->s); } + /** + * A string segment stripped of leading and trailing whitespace. + */ public LineParser strippedString(int length, String name) { - segments.add(new LineParserValueSegment(length, name) { - - @Override - String parse(String value) throws ValueParseException { - return value.strip(); - } - - }); - return this; + return this.value(length, name, String::strip); } + /** + * A string segment stripped of leading and trailing whitespace with no bounds. No further segments may be added. + */ public LineParser strippedString(String name) { - segments.add(new LineParserValueSegment(-1, name) { - - @Override - String parse(String value) throws ValueParseException { - return value.strip(); - } - - }); - return this; + return this.value(name, String::strip); } - public LineParser parse(int length, String name, ValueParser parser) { - segments.add(new LineParserValueSegment(length, name) { - - @Override - T parse(String value) throws ValueParseException { - return parser.parse(value); - } - - }); - return this; + /** + * Add a segment + * @param type the segment will be parsed too + * @param length length of the segment + * @param name name of the segment + * @param parser parser to convert the string + */ + public LineParser value(int length, String name, ValueParser parser) { + if (length<0) throw new IllegalArgumentException("length can not be negative"); + return doValue(length, name, parser); } - public LineParser parse(String name, ValueParser parser) { - segments.add(new LineParserValueSegment(-1, name) { + /** + * Add an unbounded segment. No further segments may be added. + * @param type the segment will be parsed too + * @param length length of the segment + * @param name name of the segment + * @param parser parser to convert the string + */ + public LineParser value(String name, ValueParser parser) { + return doValue(-1, name, parser); + } + + private LineParser doValue(int length, String name, ValueParser parser) { + if (segments.size()>0 && segments.get(segments.size()-1).length<0) + throw new IllegalStateException("Can not add a segment after an unbounded segment"); + segments.add(new LineParserValueSegment(length, name) { @Override T parse(String value) throws ValueParseException { @@ -174,7 +158,7 @@ T parse(String value) throws ValueParseException { return this; } - List segmentize(String line) { + private List segmentize(String line) { List result = new ArrayList<>(segments.size()); int i = 0; @@ -196,7 +180,13 @@ List segmentize(String line) { return result; } - public Map parse(String line) throws ValueParseException { + /** + * Parse an individual line + * @param line + * @return + * @throws ValueParseException + */ + public Map parseLine(String line) throws ValueParseException { var segments = segmentize(line); return parse(segments); } @@ -219,7 +209,17 @@ private Map parse(List segmentStrings) throws ValueParseE return result; } - public T parse (InputStream is, T result, ParseEntryHandler, T> addToResult) throws IOException, ResourceParseException { + /** + * Parse an input stream + * @param Type of the resulting object + * @param is Input stream to parse + * @param result Starting state for the resulting object + * @param addToResult Add a record from the file to the result object and return it + * @return The result object after parsing + * @throws IOException if an error occurs while reading from the stream + * @throws ResourceParseException if the content of the stream could not be parsed + */ + public T parse(InputStream is, T result, ParseEntryHandler, T> addToResult) throws IOException, ResourceParseException { var reader = new BufferedReader(new InputStreamReader(is, charset)); String line; int lineNumber = 0; @@ -254,32 +254,57 @@ public T parse (InputStream is, T result, ParseEntryHandler> parse (InputStream is) throws IOException, ResourceParseException { var result = new ArrayList> (); result = this.parse(is, result, (v, r)->{r.add(v); return r;}); return result; } - public boolean isStopEntry(Map entry) { + /** + * If this returns true for a parsed line, parsing will stop and that line will not be included in the result. + */ + protected boolean isStopEntry(Map entry) { return false; } + /** + * If this returns true for a segmented line, parsing will stop and that line will not be included in the result. + */ public boolean isStopSegment(List entry) { return false; } + /** + * If this returns true for an unparsed line, parsing will stop and that line will not be included in the result. + */ public boolean isStopLine(String line) { return false; } + /** + * If this returns true for a parsed line, that line will not be included in the result. + */ public boolean isIgnoredEntry(Map entry) { return false; } + /** + * If this returns true for a segmented line, that line will not be included in the result. + */ public boolean isIgnoredSegment(List entry) { return false; } + /** + * If this returns true for an unparsed line, that line will not be included in the result. + */ public boolean isIgnoredLine(String line) { return false; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java index e4d570d3b..0bec76ec1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java @@ -1,6 +1,21 @@ package ca.bc.gov.nrs.vdyp.io.parse; +/** + * Handler to apply the result of parsing to an under construction object + * + * @author Kevin Smith, Vivid Solutions + * + * @param + * @param + */ @FunctionalInterface public interface ParseEntryHandler { + /** + * Apply the result of parsing to an under construction object + * @param entry parsed record + * @param result object under construction + * @return the object under construction + * @throws ValueParseException if there was a problem with the parsed value + */ public Result addTo(Entry entry, Result result) throws ValueParseException; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java index c02360241..2d6e6f356 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java @@ -1,5 +1,11 @@ package ca.bc.gov.nrs.vdyp.io.parse; +/** + * An error parsing a particular line of a multi-line resource + * + * @author Kevin Smith, Vivid Solutions + * + */ public class ResourceParseException extends Exception { private static final long serialVersionUID = 5188546056230073563L; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java index aaca8c197..26ae89e81 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java @@ -5,16 +5,45 @@ import java.nio.file.Files; import java.nio.file.Path; +/** + * A parser for a multi-line recource + * + * @author Kevin Smith, Vivid Solutions + * + * @param + */ @FunctionalInterface public interface ResourceParser { + /** + * Parse an InputStream + * @param is + * @return The parsed resource + * @throws IOException if there is an error communicating with the input stream + * @throws ResourceParseException if there is a problem with the content of the resource + */ T parse(InputStream is) throws IOException, ResourceParseException; + /** + * Parse a resource from the classpath + * @param klazz + * @param resourcePath + * @return The parsed resource + * @throws IOException if there is an error communicating with the input stream + * @throws ResourceParseException if there is a problem with the content of the resource + */ default T parse (Class klazz, String resourcePath) throws IOException, ResourceParseException { try (var is = klazz.getResourceAsStream(resourcePath)) { return parse(is); } } + /** + * Parse a resource from a file + * @param resourcePath + * @return The parsed resource + * @throws IOException if there is an error communicating with the input stream + * @throws ResourceParseException if there is a problem with the content of the resource + */ default T parse (Path resourcePath) throws IOException, ResourceParseException { try (InputStream is = Files.newInputStream(resourcePath)) { return parse(is); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java index 495548567..af80c0499 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java @@ -1,5 +1,11 @@ package ca.bc.gov.nrs.vdyp.io.parse; +/** + * An error while parsing a simple value from a string. + * + * @author Kevin Smith, Vivid Solutions + * + */ public class ValueParseException extends Exception { private static final long serialVersionUID = 4181384333196602044L; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 3d179f9a5..3f7c86e65 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -1,6 +1,92 @@ package ca.bc.gov.nrs.vdyp.io.parse; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +/** + * Parses a string to a value + * @author Kevin Smith, Vivid Solutions + * + * @param + */ @FunctionalInterface public interface ValueParser { + /** + * Parse a string to a value + * @param string + * @return The parsed value + * @throws ValueParseException if the string could not be parsed + */ T parse(String string) throws ValueParseException; + + public static interface JavaNumberParser { + U parse(String s) throws NumberFormatException; + } + + /** + * Adapts a parse method that throws NumerFormatException + * @param parser method that parses a string into the required type and throws NumerFormatException + * @param klazz the type to parse into + */ + public static ValueParser numberParser(JavaNumberParser parser, Class klazz) { + return s->{ + String stripped = s.strip(); + try { + return parser.parse(stripped); + } catch(NumberFormatException ex) { + throw new ValueParseException(stripped, String.format("\"%s\" is not a valid %s", stripped, klazz.getSimpleName()), ex); + } + }; + } + + /** + * Parser for long integers + */ + public static final ValueParser LONG = numberParser(Long::parseLong, Long.class); + + /** + * Parser for integers + */ + public static final ValueParser INTEGER = numberParser(Integer::parseInt, Integer.class); + + /** + * Parser for short integers + */ + public static final ValueParser SHORT = numberParser(Short::parseShort, Short.class); + + /** + * Parser for double precision floats + */ + public static final ValueParser DOUBLE = numberParser(Double::parseDouble, Double.class); + + /** + * Parser for single precision floats + */ + public static final ValueParser FLOAT = numberParser(Float::parseFloat, Float.class); + + public static ValueParser> list(ValueParser delegate) { + return s-> { + var elementStrings = s.strip().split("\s+"); + List result = new ArrayList<>(); + for(String elementString : elementStrings) { + result.add(delegate.parse(elementString)); + } + return Collections.unmodifiableList(result); + }; + } + + /** + * Makes a parser that parses if the string is not blank, and returns an empty Optional otherwise. + * @param delegate Parser to use if the string is not blank + */ + public static ValueParser> optional(ValueParser delegate) { + return (s)->{ + if(!s.isBlank()) { + return Optional.of(delegate.parse(s)); + } + return Optional.empty(); + }; + } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index 2fe06e883..3a9a23ae3 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -8,16 +8,18 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.stringContainsInOrder; import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; import org.hamcrest.Matcher; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; public class ControlFileParserTest { @@ -212,6 +214,38 @@ void testParsesMultipleEntries() throws Exception { ); } } + + @Test + void testException() throws Exception { + var parser = makeParser(); + + String file = "00X Control 1\n002 Control 2"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + + assertThat(ex1, hasProperty("line", is(1))); + assertThat(ex1, hasProperty("cause", instanceOf(ValueParseException.class))); + assertThat(ex1, hasProperty("cause", hasProperty("cause", instanceOf(NumberFormatException.class)))); + assertThat(ex1, hasProperty("cause", hasProperty("value", is("00X")))); + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "00X"))); + } + } + + @Test + void testExceptionInControlValueParser() throws Exception { + var parser = makeParser(); + parser.setValueParsers(Collections.singletonMap(2, s->{throw new ValueParseException(s,"Test Exception");})); + + String file = "001 Control 1\n002 Control 2"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + + assertThat(ex1, hasProperty("line", is(2))); + assertThat(ex1, hasProperty("cause", instanceOf(ValueParseException.class))); + assertThat(ex1, hasProperty("cause", hasProperty("value", is("Control 2")))); + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Test Exception"))); + } + } @Test void testParseToMap() throws Exception { @@ -300,15 +334,15 @@ private ControlFileParser makeConfiguredParser() { var parser = makeParser(); var identifiers = new HashMap(); - var parsers = new HashMap>(); + var parsers = new HashMap>(); identifiers.put(197, "minimums"); - parsers.put(197, (String s) -> Arrays.stream(s.strip().split("\s+")).map(Float::valueOf).collect(Collectors.toList())); + parsers.put(197, ValueParser.list(ValueParser.FLOAT)); identifiers.put(198, "modifier_file"); identifiers.put(199, "debugSwitches"); - parsers.put(199, (String s) -> Arrays.stream(s.strip().split("\s+")).map(Integer::valueOf).collect(Collectors.toList())); + parsers.put(199, ValueParser.list(ValueParser.INTEGER)); parser.setIdentifiers(identifiers); parser.setValueParsers(parsers); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 5ab2b5402..db9170f2b 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -29,7 +29,7 @@ public void testBasic() throws Exception { .space(1) .string(4, "part2"); - var result1 = parser.parse("042 Blah"); + var result1 = parser.parseLine("042 Blah"); assertThat(result1, hasEntry("part1", "042")); assertThat(result1, hasEntry("part2", "Blah")); @@ -44,7 +44,7 @@ public void testNumbers() throws Exception { .space(1) .floating(5, "part2"); - var result1 = parser.parse(" 4 0.5 "); + var result1 = parser.parseLine(" 4 0.5 "); assertThat(result1, hasEntry("part1", 4)); assertThat(result1, hasEntry("part2", 0.5f)); @@ -59,7 +59,7 @@ public void testIncomplete() throws Exception { .space(1) .floating(5, "part2"); - var result1 = parser.parse(" 4 "); + var result1 = parser.parseLine(" 4 "); assertThat(result1, hasEntry("part1", 4)); assertThat(result1, not(hasKey("part2"))); @@ -74,7 +74,7 @@ public void testIncompleteSegment() throws Exception { .space(1) .floating(5, "part2"); - var result1 = parser.parse(" 4 5.0"); + var result1 = parser.parseLine(" 4 5.0"); assertThat(result1, hasEntry("part1", 4)); assertThat(result1, hasEntry("part2", 5.0f)); @@ -89,12 +89,12 @@ public void testNumberParseErrors() throws Exception { .space(1) .floating(5, "part2"); - var ex1 = assertThrows(ValueParseException.class, ()->parser.parse(" X 0.5 ")); + var ex1 = assertThrows(ValueParseException.class, ()->parser.parseLine(" X 0.5 ")); assertThat(ex1, hasProperty("value", is("X"))); assertThat(ex1, hasProperty("cause", isA(NumberFormatException.class))); - var ex2 = assertThrows(ValueParseException.class, ()->parser.parse(" 4 0.x ")); + var ex2 = assertThrows(ValueParseException.class, ()->parser.parseLine(" 4 0.x ")); assertThat(ex2, hasProperty("value", is("0.x"))); assertThat(ex2, hasProperty("cause", isA(NumberFormatException.class))); @@ -106,11 +106,11 @@ public void testNumberParseErrors() throws Exception { public void testValueParser() throws Exception { var parser = new LineParser(); parser - .parse(4, "part1", (s)->Integer.valueOf(s.strip())+1) + .value(4, "part1", (s)->Integer.valueOf(s.strip())+1) .space(1) - .parse("part2", (s)->Float.valueOf(s.strip())+1); + .value("part2", (s)->Float.valueOf(s.strip())+1); - var result1 = parser.parse(" 4 0.5 "); + var result1 = parser.parseLine(" 4 0.5 "); assertThat(result1, hasEntry("part1", 5)); assertThat(result1, hasEntry("part2", 1.5f)); @@ -121,11 +121,11 @@ public void testValueParser() throws Exception { public void testValueParserError() throws Exception { var parser = new LineParser(); parser - .parse(4, "part1", (s)->{throw new ValueParseException(s, "Testing");}) + .value(4, "part1", (s)->{throw new ValueParseException(s, "Testing");}) .space(1) - .parse(4, "part2", (s)->Float.valueOf(s.strip())+1); + .value(4, "part2", (s)->Float.valueOf(s.strip())+1); - var ex1 = assertThrows(ValueParseException.class, ()->parser.parse(" X 0.5 ")); + var ex1 = assertThrows(ValueParseException.class, ()->parser.parseLine(" X 0.5 ")); assertThat(ex1, hasProperty("value", is(" X "))); assertThat(ex1, hasProperty("message", is("Testing"))); @@ -138,7 +138,7 @@ public void testUnbounded() throws Exception { .string(4, "part1") .string("part2"); - var result1 = parser.parse("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); + var result1 = parser.parseLine("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); assertThat(result1, hasEntry("part1", "123 ")); assertThat(result1, hasEntry("part2", " 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ")); @@ -152,7 +152,7 @@ public void testStripped() throws Exception { .strippedString(4, "part1") .strippedString("part2"); - var result1 = parser.parse("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); + var result1 = parser.parseLine("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); assertThat(result1, hasEntry("part1", "123")); assertThat(result1, hasEntry("part2", "67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java index 75f1a4c69..2b2f7fd46 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java @@ -1,19 +1,36 @@ package ca.bc.gov.nrs.vdyp.test; -import java.util.function.Function; - import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; + +/** + * Custom Hamcrest Matchers + * + * @author Kevin Smith, Vivid Solutions + * + */ public class VydpMatchers { - public static Matcher parseAs(Matcher parsedMatcher, Function parser) { + /** + * Matches a string if when parsed by the parser method it matches the given matcher + * @param parsedMatcher matcher for the parsed value + * @param parser parser + * @return + */ + public static Matcher parseAs(Matcher parsedMatcher, ValueParser parser) { return new BaseMatcher() { @Override public boolean matches(Object actual) { - return parsedMatcher.matches(parser.apply(actual.toString())); + try { + return parsedMatcher.matches(parser.parse(actual.toString())); + } catch (ValueParseException e) { + return false; + } } @Override diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 39fbc3138..d0680c86b 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -8,6 +8,7 @@ import java.util.function.Function; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; /** * Parser for FIP control files @@ -31,8 +32,8 @@ public class FipControlParser { } } - Map parse(InputStream is, FileResolver fileResolver) { - var map = controlParser.parseToMap(is); + Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { + var map = controlParser.parse(is); return map; } From 1aa2dd10d78648c349d018471ea21f0d99f6fd99 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 11 May 2023 18:52:42 -0700 Subject: [PATCH 09/98] FIP Control parsing --- .../nrs/vdyp/io/parse/ControlFileParser.java | 68 +-- .../vdyp/io/parse/ControlFileParserTest.java | 19 +- .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 72 +-- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 414 +++++++++++++++++- .../nrs/vdyp/fip/FipControlParserTest.java | 22 + 5 files changed, 498 insertions(+), 97 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index 7909dcb0e..ba3a0b9a2 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -50,25 +50,14 @@ public boolean isIgnoredEntry(Map segments) { .string("restOfLine"); /** - * - * @param identifiers a map from control file sequence index to meaningful names - * @param parsers a map of parsers for control values based on the sequence index - * @param defaultParser a default value parser to use when one can't be found in the value parser map - */ - public ControlFileParser( - Map identifiers, Map> parsers, ValueParser defaultParser - ) { - this.identifiers = identifiers; - this.valueParsers = parsers; - this.defaultValueParser = defaultParser; - } - - /** - * Create a control file parser which does not remap control sequence indexes and which strips leading and trailing whitepsace from values. + * Create a control file parser. */ public ControlFileParser() { - this(Collections.emptyMap(), Collections.emptyMap(), String::strip); + this.identifiers = new HashMap<>(); + this.valueParsers = new HashMap<>(); + this.defaultValueParser = String::strip; } + @Override public Map parse(InputStream input) throws IOException, ResourceParseException { @@ -103,27 +92,48 @@ public Map parse(InputStream input) throws IOException, Resource return result; }); } - + /** - * Set a map from control file sequence index to meaningful names + * Set a default value parser to use when one can't be found in the parser map */ - public void setIdentifiers(Map identifiers) { - this.identifiers = identifiers; + public void setDefaultValueParser(ValueParser defaultParser) { + this.defaultValueParser = defaultParser; } - + /** - * Set a map of parsers for control values based on the sequence index + * Remap a record index with a meaningful name and parse its value + * @param index + * @param name + * @param parser + * @return */ - public void setValueParsers(Map> parsers) { - this.valueParsers = parsers; + public ControlFileParser record(int index, String name, ValueParser parser) { + record(index, name); + record(index, parser); + return this; } - + /** - * Set a default value parser to use when one can't be found in the parser map + * Remap a record index with a meaningful name + * @param index + * @param name + * @param parser + * @return */ - public void setDefaultValueParser(ValueParser defaultParser) { - this.defaultValueParser = defaultParser; + public ControlFileParser record(int index, String name) { + this.identifiers.put(index, name); + return this; } - + /** + * Parse the value of records with the given index + * @param index + * @param name + * @param parser + * @return + */ + public ControlFileParser record(int index, ValueParser parser) { + this.valueParsers.put(index, parser); + return this; + } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index 3a9a23ae3..1f31a8389 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -234,7 +234,7 @@ void testException() throws Exception { @Test void testExceptionInControlValueParser() throws Exception { var parser = makeParser(); - parser.setValueParsers(Collections.singletonMap(2, s->{throw new ValueParseException(s,"Test Exception");})); + parser.record(2, s->{throw new ValueParseException(s,"Test Exception");}); String file = "001 Control 1\n002 Control 2"; try (InputStream is = new ByteArrayInputStream(file.getBytes())) { @@ -333,19 +333,10 @@ private ControlFileParser makeParser() { private ControlFileParser makeConfiguredParser() { var parser = makeParser(); - var identifiers = new HashMap(); - var parsers = new HashMap>(); - - identifiers.put(197, "minimums"); - parsers.put(197, ValueParser.list(ValueParser.FLOAT)); - - identifiers.put(198, "modifier_file"); - - identifiers.put(199, "debugSwitches"); - parsers.put(199, ValueParser.list(ValueParser.INTEGER)); - - parser.setIdentifiers(identifiers); - parser.setValueParsers(parsers); + parser + .record(197, "minimums", ValueParser.list(ValueParser.FLOAT)) + .record(198, "modifier_file") + .record(199, "debugSwitches", ValueParser.list(ValueParser.INTEGER)); return parser; } diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 478b0e018..7bbd11c08 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -7,8 +7,8 @@ 001 00999999 Max # of Polygons to process (I8) (poly's with MODE = -1 NOT counted) -009 coe\becdef.dat BEC Zone Definitions RD_BECD -010 coe\SP0DEF_V0.dat Standard SP0 Codes (with order) RD_SP0 +009 coe/Becdef.dat BEC Zone Definitions RD_BECD +010 coe/SP0DEF_V0.dat Standard SP0 Codes (with order) RD_SP0 011 fip_p01.dat FIP YIELD INPUT (poly) GET_FIPP 012 fip_l01.dat FIP YIELD INPUT (layer) GET_FIPL @@ -18,53 +18,53 @@ 016 vs_01.dat VDYP7 Layer by Species 018 vu_01.dat VDYP7 Layer by SP0 by Util -020 coe\vgrpdef1.dat Defines Volume Eqn groups RD_VGRP -021 coe\dgrp.dat Defines Decay Groups RD_DGRP -022 coe\bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 +020 coe/vgrpdef1.dat Defines Volume Eqn groups RD_VGRP +021 coe/dgrp.dat Defines Decay Groups RD_DGRP +022 coe/bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 -025 coe\SIEQN.prm Site Curve Numbers (SCN) assigned RD_E025 +025 coe/SIEQN.prm Site Curve Numbers (SCN) assigned RD_E025 025 Nullifies above siteCurve # -026 coe\SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 +026 coe/SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 -030 coe\grpba1.dat Default Eq # BA=f(CC) RD_GRBA1 -031 coe\gmodba1.dat Eqn modifiers for above RD_GMBA1 -033 coe\fipstkr.prm Stocking class factors RD_STK33 +030 coe/grpba1.dat Default Eq # BA=f(CC) RD_GRBA1 +031 coe/gmodba1.dat Eqn modifiers for above RD_GMBA1 +033 coe/fipstkr.prm Stocking class factors RD_STK33 -040 coe\regba25.coe Coe BA=f(CC) RD_E040 IPSJF128 -041 coe\regdq26.coe Coe DQ=f(CC) RD_E041 IPSJF129 -043 coe\upperb02.coe Upper BA by C/I SP0_P RD_E043 IPSJF128 +040 coe/regba25.coe Coe BA=f(CC) RD_E040 IPSJF128 +041 coe/regdq26.coe Coe DQ=f(CC) RD_E041 IPSJF129 +043 coe/upperb02.coe Upper BA by C/I SP0_P RD_E043 IPSJF128 -050 coe\regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 -051 coe\regyhlpa.coe HL, Primary SP, Eqn P2 RD_YHL2 -052 coe\regyhlpb.dat HL, Primary SP, Eqn P3 RD_YHL3 -053 coe\reghl.coe HL, Non-primary Species RD_YHL4 +050 coe/regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 +051 coe/regyhlpa.coe HL, Primary SP, Eqn P2 RD_YHL2 +052 coe/regyhlpb.dat HL, Primary SP, Eqn P3 RD_YHL3 +053 coe/reghl.coe HL, Non-primary Species RD_YHL4 -060 coe\REGDQI04.coe By-species DQ RD_E060 IPFJF125 -061 coe\complim.coe Species component size limits RD_E061 IPSJF158 +060 coe/REGDQI04.coe By-species DQ RD_E060 IPFJF125 +061 coe/complim.coe Species component size limits RD_E061 IPSJF158 -070 coe\regbac.dat Util. Comp, BA RD_UBA1 -071 coe\regdqc.dat Util. Comp, DQ RD_UDQ1 +070 coe/regbac.dat Util. Comp, BA RD_UBA1 +071 coe/regdqc.dat Util. Comp, DQ RD_UDQ1 -080 coe\regpr1c.dat Small Comp., Probability RD_SBA1 -081 coe\regba2c.dat Small Comp., BA RD_SBA2 -082 coe\regdq4c.dat Small Comp., DQ RD_SDQ1 -085 coe\reghl1c.dat Small Comp., HL RD_SHL1 -086 coe\regv1c.dat Small Comp., WS Volume RD_SVT1 +080 coe/regpr1c.dat Small Comp., Probability RD_SBA1 +081 coe/regba2c.dat Small Comp., BA RD_SBA2 +082 coe/regdq4c.dat Small Comp., DQ RD_SDQ1 +085 coe/reghl1c.dat Small Comp., HL RD_SHL1 +086 coe/regv1c.dat Small Comp., WS Volume RD_SVT1 -090 coe\VTOTREG4.coe Total stand WholeStem Vol RD_YVT1 IPSJF117 -091 coe\REGVU.coe Util Comp, WS volume RD_YVT2 IPSJF121 -092 coe\regvcu.coe Close Utilization Vol RD_YVC1 IPSJF122 -093 coe\regvdu.coe Vol net of Decay RD_YVD1 IPSJF123 -094 coe\regvwu.coe Vol net of (Decay+Waste) RD_YVW1 IPSJF123 -095 coe\regbreak.coe Breakage RD_EMP95 IPSJF157 +090 coe/VTOTREG4.coe Total stand WholeStem Vol RD_YVT1 IPSJF117 +091 coe/REGVU.coe Util Comp, WS volume RD_YVT2 IPSJF121 +092 coe/regvcu.coe Close Utilization Vol RD_YVC1 IPSJF122 +093 coe/regvdu.coe Vol net of Decay RD_YVD1 IPSJF123 +094 coe/regvwu.coe Vol net of (Decay+Waste) RD_YVW1 IPSJF123 +095 coe/regbreak.coe Breakage RD_EMP95 IPSJF157 -096 coe\vetvol1.dat Vet-layer volume adjust RD_YVET -097 coe\vetdq2.dat DQ for Vet layer RD_YDQV -098 coe\REGBAV01.coe VET BA, IPSJF168.doc RD_E098 +096 coe/vetvol1.dat Vet-layer volume adjust RD_YVET +097 coe/vetdq2.dat DQ for Vet layer RD_YDQV +098 coe/REGBAV01.coe VET BA, IPSJF168.doc RD_E098 197 5.0 0.0 2.0 Minimum Height, Minimum BA, Min BA fully stocked. -198 coe\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198 +198 coe/MOD19813.prm Modifier file (IPSJF155, XII) RD_E198 199 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155, App IX 1st: 1: Do NOT apply BA limits from SEQ043 2nd: 1: Do NOT apply DQ limits from SEQ043 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index d0680c86b..196ce0b41 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -5,10 +5,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; -import java.util.function.Function; +import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.model.BecDefinition; /** * Parser for FIP control files @@ -18,37 +21,412 @@ */ public class FipControlParser { - ControlFileParser controlParser = new ControlFileParser(); + public static final String FIP_YIELD_POLY_INPUT = "FIP_YIELD_POLY_INPUT"; + public static final String FIP_YIELD_LAYER_INPUT = "FIP_YIELD_LAYER_INPUT"; + public static final String FIP_YIELD_LX_SP0_INPUT = "FIP_YIELD_LxSP0_INPUT"; + public static final String VDYP_POLYGON = "VDYP_POLYGON"; + public static final String VDYP_LAYER_BY_SPECIES = "VDYP_LAYER_BY_SPECIES"; + public static final String VDYP_LAYER_BY_SP0_BY_UTIL = "VDYP_LAYER_BY_SP0_BY_UTIL"; + public static final String VOLUME_EQN_GROUPS = "VOLUME_EQN_GROUPS"; + public static final String DECAY_GROUPS = "DECAY_GROUPS"; + public static final String BREAKAGE_GROUPS = "BREAKAGE_GROUPS"; + public static final String SITE_CURVE_NUMBERS = "SITE_CURVE_NUMBERS"; + public static final String SITE_CURVE_AGE_MAX = "SITE_CURVE_AGE_MAX"; + public static final String DEFAULT_EQ_NUM = "DEFAULT_EQ_NUM"; + public static final String EQN_MODIFIERS = "EQN_MODIFIERS"; + public static final String STOCKING_CLASS_FACTORS = "STOCKING_CLASS_FACTORS"; + public static final String COE_BA = "COE_BA"; + public static final String COE_DQ = "COE_DQ"; + public static final String UPPER_BA_BY_CI_S0_P = "UPPER_BA_BY_CI_S0_P"; + public static final String HL_PRIMARY_SP_EQN_P1 = "HL_PRIMARY_SP_EQN_P1"; + public static final String HL_PRIMARY_SP_EQN_P2 = "HL_PRIMARY_SP_EQN_P2"; + public static final String HL_PRIMARY_SP_EQN_P3 = "HL_PRIMARY_SP_EQN_P3"; + public static final String HL_NONPRIMARY = "HL_NONPRIMARY"; + public static final String BY_SPECIES_DQ = "BY_SPECIES_DQ"; + public static final String SPECIES_COMPONENT_SIZE_LIMIT = "SPECIES_COMPONENT_SIZE_LIMIT"; + public static final String UTIL_COMP_BA = "UTIL_COMP_BA"; + public static final String UTIL_COMP_DQ = "UTIL_COMP_DQ"; + public static final String SMALL_COMP_PROBABILITY = "SMALL_COMP_PROBABILITY"; + public static final String SMALL_COMP_BA = "SMALL_COMP_BA"; + public static final String SMALL_COMP_DQ = "SMALL_COMP_DQ"; + public static final String SMALL_COMP_HL = "SMALL_COMP_HL"; + public static final String SMALL_COMP_WS_VOLUME = "SMALL_COMP_WS_VOLUME"; + public static final String TOTAL_STAND_WHOLE_STEM_VOL = "TOTAL_STAND_WHOLE_STEM_VOL"; + public static final String UTIL_COMP_WS_VOLUME = "UTIL_COMP_WS_VOLUME"; + public static final String CLOSE_UTIL_VOLUME = "CLOSE_UTIL_VOLUME"; + public static final String VOLUME_NET_DECAY = "VOLUME_NET_DECAY"; + public static final String VOLUME_NET_DECAY_WASTE = "VOLUME_NET_DECAY_WASTE"; + public static final String BREAKAGE = "BREAKAGE"; + public static final String VETERAN_LAYER_VOLUME_ADJUST = "VETERAN_LAYER_VOLUME_ADJUST"; + public static final String VETERAN_LAYER_DQ = "VETERAN_LAYER_DQ"; + public static final String VETERAN_BQ = "VETERAN_BQ"; + public static final String MINIMA = "MINIMA"; + public static final String MODIFIER_FILE = "MODIFIER_FILE"; + public static final String DEBUG_SWITCHES = "DEBUG_SWITCHES"; + public static final String MAX_NUM_POLY = "MAX_NUM_POLY"; + public static final String BEC_DEF = "BEC_DEF"; + public static final String SP0_DEF = "SP0_DEF"; + + static final ValueParser FILENAME = String::strip; - Map parse (Path inputFile) throws IOException { - try(var is = Files.newInputStream(inputFile)) { - return parse(is, fileName->Files.newInputStream(inputFile.resolveSibling(fileName))); + ControlFileParser controlParser = new ControlFileParser() + .record( 1, MAX_NUM_POLY, ValueParser.INTEGER) + + .record( 9, BEC_DEF, FILENAME) // RD_BECD + .record( 10, SP0_DEF, FILENAME) // RD_SP0 + + .record( 11, FIP_YIELD_POLY_INPUT, FILENAME) // GET_FIPP + .record( 12, FIP_YIELD_LAYER_INPUT, FILENAME) // GET_FIPL + .record( 13, FIP_YIELD_LX_SP0_INPUT, FILENAME) // GET_FIPS + + .record( 15, VDYP_POLYGON, FILENAME) // + .record( 16, VDYP_LAYER_BY_SPECIES, FILENAME) // + .record( 18, VDYP_LAYER_BY_SP0_BY_UTIL, FILENAME) // + + .record( 20, VOLUME_EQN_GROUPS, FILENAME) // RD_VGRP + .record( 21, DECAY_GROUPS, FILENAME) // RD_DGRP + .record( 22, BREAKAGE_GROUPS, FILENAME) // RD_BGRP IPSJF157 + + .record( 25, SITE_CURVE_NUMBERS, FILENAME) // RD_E025 + .record( 26, SITE_CURVE_AGE_MAX, FILENAME) // RD_E026 + + .record( 30, DEFAULT_EQ_NUM, FILENAME) // RD_GRBA1 + .record( 31, EQN_MODIFIERS, FILENAME) // RD_GMBA1 + .record( 33, STOCKING_CLASS_FACTORS, FILENAME) // RD_STK33 + + .record( 40, COE_BA, FILENAME) // RD_E040 IPSJF128 + .record( 41, COE_DQ, FILENAME) // RD_E041 IPSJF129 + .record( 43, UPPER_BA_BY_CI_S0_P, FILENAME) // RD_E043 IPSJF128 + + .record( 50, HL_PRIMARY_SP_EQN_P1, FILENAME) // RD_YHL1 + .record( 51, HL_PRIMARY_SP_EQN_P2, FILENAME) // RD_YHL2 + .record( 52, HL_PRIMARY_SP_EQN_P3, FILENAME) // RD_YHL3 + .record( 53, HL_NONPRIMARY, FILENAME) // RD_YHL4 + + .record( 60, BY_SPECIES_DQ, FILENAME) // RD_E060 IPFJF125 + .record( 61, SPECIES_COMPONENT_SIZE_LIMIT, FILENAME) // RD_E061 IPSJF158 + + .record( 70, UTIL_COMP_BA, FILENAME) // RD_UBA1 + .record( 71, UTIL_COMP_DQ, FILENAME) // RD_UDQ1 + + .record( 80, SMALL_COMP_PROBABILITY, FILENAME) // RD_SBA1 + .record( 81, SMALL_COMP_BA, FILENAME) // RD_SBA2 + .record( 82, SMALL_COMP_DQ, FILENAME) // RD_SDQ1 + .record( 85, SMALL_COMP_HL, FILENAME) // RD_SHL1 + .record( 86, SMALL_COMP_WS_VOLUME, FILENAME) // RD_SVT1 + + .record( 90, TOTAL_STAND_WHOLE_STEM_VOL, FILENAME) // RD_YVT1 IPSJF117 + .record( 91, UTIL_COMP_WS_VOLUME, FILENAME) // RD_YVT2 IPSJF121 + .record( 92, CLOSE_UTIL_VOLUME, FILENAME) // RD_YVC1 IPSJF122 + .record( 93, VOLUME_NET_DECAY, FILENAME) // RD_YVD1 IPSJF123 + .record( 94, VOLUME_NET_DECAY_WASTE, FILENAME) // RD_YVW1 IPSJF123 + .record( 95, BREAKAGE, FILENAME) // RD_EMP95 IPSJF157 + + .record( 96, VETERAN_LAYER_VOLUME_ADJUST, FILENAME) // RD_YVET + .record( 97, VETERAN_LAYER_DQ, FILENAME) // RD_YDQV + .record( 98, VETERAN_BQ, FILENAME) // RD_E098 + + .record(197, MINIMA, ValueParser.list(ValueParser.FLOAT)) // Minimum Height, Minimum BA, Min BA fully stocked. + + .record(198, MODIFIER_FILE, FILENAME) // RD_E198 IPSJF155, XII + + .record(199, DEBUG_SWITCHES, ValueParser.list(ValueParser.INTEGER)) // IPSJF155 + /* + Debug switches (25) 0=default See IPSJF155, App IX + 1st: 1: Do NOT apply BA limits from SEQ043 + 2nd: 1: Do NOT apply DQ limits from SEQ043 + 4th: Future Development. Choice of upper limits + 9th: 0: Normal - Suppress MATH77 error messages. + 1: show some MATH77 errors; 2: show all. + 22nd 1: extra preference for preferred sp (SEQ 010). + */ + + ; + + public FipControlParser() { + + } + + Map parse (Path inputFile) throws IOException, ResourceParseException { + try (var is = Files.newInputStream(inputFile)) { + + return parse(is, new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + return Files.newInputStream(inputFile.resolveSibling(filename)); + } + + @Override + public String toString(String filename) throws IOException { + return inputFile.resolveSibling(filename).toString(); + } + }); } } - Map parse (Class klazz, String resourceName) throws IOException { - try(var is = klazz.getResourceAsStream(resourceName)) { - return parse(is, ioExceptionOnNull(klazz::getResourceAsStream)); + Map parse (Class klazz, String resourceName) throws IOException, ResourceParseException { + try (var is = klazz.getResourceAsStream(resourceName)) { + + return parse(is, new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + InputStream resourceAsStream = klazz.getResourceAsStream(filename); + if(resourceAsStream==null) throw new IOException("Could not load "+filename); + return resourceAsStream; + } + + @Override + public String toString(String filename) throws IOException { + return klazz.getResource(filename).toString(); + } + }); } } Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { var map = controlParser.parse(is); + + // RD_BEC + loadData(map, BEC_DEF, fileResolver, this::RD_BEC); + + // DEF_BEC + // TODO + + // Read Definitions + + // RD_SP0 + // TODO + + // Read Groups + + // RD_VGRP + // TODO + + // RD_VGRP + // TODO + + // RD_DGRP + // TODO + + // RD_BGRP + // TODO + + // RD_GRBA1 + // TODO + + // RD_GMBA1 + // TODO + + int jprogram = 1; // FIPSTART only TODO Track this down + if(jprogram==1) { + // RD_STK33 + // TODO + + // TODO minima? + /* + * READ(CNTRV(197), 197, ERR= 912 ) FMINH, FMINBA, FMINBAF,FMINVetH + * IF (FMINVetH .le. 0.0) FMINVetH=10.0 + */ + } + + + // User-assigned SC's (Site Curve Numbers) + // + // RD_E025 + // TODO + + // Max tot ages to apply site curves (by SC) + // + // RD_E026 + // TODO + + // Coeff for Empirical relationships + + // RD_E040 + // TODO + + // RD_E041 + // TODO + + // RD_E043 + // TODO + + // RD_YHL1 + // TODO + + // RD_YHL2 + // TODO + + // RD_YHL3 + // TODO + + // RD_YHL4 + // TODO + + // RD_E060 + // TODO + + // Min and max DQ by species + + // RD_E061 + // TODO + + // RD_UBA1 + // TODO + + // RD_UDQ1 + // TODO + + // Small Component (4.5 to 7.5 cm) + + // RD_SBA1 + // TODO + + // RD_SBA2 + // TODO + + // RD_SDQ1 + // TODO + + // RD_SHL1 + // TODO + + // RD_SVT1 + // TODO + + // Standard Volume Relationships + + // RD_YVT1 + // TODO + + // RD_YVT2 + // TODO + + // RD_YVC1 + // TODO + + // RD_YVD1 + // TODO + + // RD_YVW1 + // TODO + + // RD_E095 + // TODO + + // Veterans + + // RD_YVVET + // TODO + + // RD_YDQV + // TODO + + // RD_E098 + // TODO + + // Initiation items NOT for FIPSTART + if(jprogram==1) { + + // RD_E106 + // TODO + + // RD_E107 + // TODO + + // RD_E108 + // TODO + + // Minima again, differently? + // TODO + /* + READ(CNTRV(197), 197, ERR= 912 ) VMINH, VMINBA, VMINBAeqn,VMINvetH + IF (VMINVetH .le. 0.0) VMINVetH=10.0 + */ + + // RD_E112 + // Was commented out in Fortran + + // RD_E116 + // Was commented out in Fortran + } + + // Modifiers, IPSJF155-Appendix XII + + // RD_E198 + // TODO + + // Debug switches (normally zero) + // TODO + /* +141 FORMAT(25I2) + DO 140 I=1,25 + if ((NDEBUG(I) .ne.0) .and. (IU_WRITE .gt. 0)) + & WRITE(IU_WRITE,142) I, NDEBUG(I) +142 FORMAT(' CTR Line 199 has NDEBUG(',i2,') =',I3) +140 CONTINUE + + if (isDBG) then + call dbgMsg( logr, 0 ) "Debug Switches (Ctl Line 199)" ) + call dbgI4( logr, 6 ) " 1: Applying BA Limits ", NDEBUG( 1) ) + call dbgMsg( logr, 6 ) " 0 - Apply BA limits from SEQ043." ) + call dbgMsg( logr, 6 ) " 1 - Do not apply BA limits from SEQ043." ) + call dbgI4( logr, 6 ) " 2: Applying BA Limits ", NDEBUG( 2) ) + call dbgMsg( logr, 6 ) " 0 - Apply DQ limits from SEQ043." ) + call dbgMsg( logr, 6 ) " 1 - Do not apply DQ limits from SEQ043." ) + call dbgI4( logr, 6 ) " 3: Not used ", NDEBUG( 3) ) + call dbgI4( logr, 6 ) " 4: Not implemented. Upper bounds ", NDEBUG( 4) ) + call dbgMsg( logr, 6 ) " 0 - Will default to (2)." ) + call dbgMsg( logr, 6 ) " 1 - Limits from Ctl Line 108 (GRPBA1)." ) + call dbgMsg( logr, 6 ) " 2 - Limits from Ctl Line 043 (Coast/Interior)" ) + call dbgI4( logr, 6 ) " 5: Not used ", NDEBUG( 5) ) + call dbgI4( logr, 6 ) " 6: Not used ", NDEBUG( 6) ) + call dbgI4( logr, 6 ) " 7: Not used ", NDEBUG( 7) ) + call dbgI4( logr, 6 ) " 8: Not used ", NDEBUG( 8) ) + call dbgI4( logr, 6 ) " 9: Error handling ", NDEBUG( 9) ) + call dbgMsg( logr, 6 ) " 0 - Stop on all errors." ) + call dbgMsg( logr, 6 ) " 1 - Continue to next poly (non-I/O errs)." ) + call dbgI4( logr, 6 ) "10: Not used ", NDEBUG(10) ) + call dbgI4( logr, 6 ) "11: Not used ", NDEBUG(11) ) + call dbgI4( logr, 6 ) "12: Not used ", NDEBUG(12) ) + call dbgI4( logr, 6 ) "13: Not used ", NDEBUG(13) ) + call dbgI4( logr, 6 ) "14: Not used ", NDEBUG(14) ) + call dbgI4( logr, 6 ) "15: Not used ", NDEBUG(15) ) + call dbgI4( logr, 6 ) "16: Not used ", NDEBUG(16) ) + call dbgI4( logr, 6 ) "17: Not used ", NDEBUG(17) ) + call dbgI4( logr, 6 ) "18: Not used ", NDEBUG(18) ) + call dbgI4( logr, 6 ) "19: Not used ", NDEBUG(19) ) + call dbgI4( logr, 6 ) "20: Not used ", NDEBUG(20) ) + call dbgI4( logr, 6 ) "21: Not used ", NDEBUG(21) ) + call dbgI4( logr, 6 ) "22: Determining primary species ", NDEBUG(22) ) + call dbgMsg( logr, 6 ) " 0 - Normal " ) + call dbgMsg( logr, 6 ) " 1 - Extra preference for preferred sp. as primary" ) + call dbgI4( logr, 6 ) "23: Not used ", NDEBUG(23) ) + call dbgI4( logr, 6 ) "24: Not used ", NDEBUG(24) ) + call dbgI4( logr, 6 ) "25: Not used ", NDEBUG(25) ) + end if + */ + return map; } - @FunctionalInterface + void loadData(Map map, String key, FileResolver fileResolver, ResourceParser parser) throws IOException, ResourceParseException { + try(var is = fileResolver.resolve((String) map.get(key))) { + map.put(key, RD_BEC(is)); + } + } + + private Map RD_BEC(InputStream data) throws IOException, ResourceParseException { + var parser = new BecDefinitionParser(); + return parser.parse(data); + } + static interface FileResolver { InputStream resolve(String filename) throws IOException; + + String toString(String filename) throws IOException; } - static FileResolver ioExceptionOnNull(Function baseResolver) { - return fileName->{ - var result = baseResolver.apply(fileName); - if(result==null) { - throw new IOException("Could not find "+fileName); - } - return result; - }; - } } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index b7de5fcb8..a6eeaf918 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -1,8 +1,18 @@ package ca.bc.gov.nrs.vdyp.fip; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +import java.util.Map; + +import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; +import ca.bc.gov.nrs.vdyp.model.BecDefinition; public class FipControlParserTest { @@ -12,4 +22,16 @@ public void testParse() throws Exception { var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); } + + @Test + public void testParseBec() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) hasEntry(is(FipControlParser.BEC_DEF), + allOf( + instanceOf(Map.class), + hasEntry( + is("AT"), + instanceOf(BecDefinition.class))))); + } } From 93c65549ae1f6ed25f976d955a67e61095f81404 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 12 May 2023 14:42:13 -0700 Subject: [PATCH 10/98] Read SP0 definitions --- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 4 +- .../vdyp/io/parse/SP0DefinitionParser.java | 72 ++++++ .../vdyp/model/AbstractSpeciesDefinition.java | 26 ++ .../bc/gov/nrs/vdyp/model/BecDefinition.java | 14 +- .../bc/gov/nrs/vdyp/model/SP0Definition.java | 17 ++ .../gov/nrs/vdyp/io/parse/LineParserTest.java | 6 +- .../io/parse/SP0DefinitionParserTest.java | 236 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 18 +- .../nrs/vdyp/fip/FipControlParserTest.java | 18 ++ 10 files changed, 395 insertions(+), 18 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 8574ca619..28a00b809 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -21,6 +21,7 @@ public class LineParser { private List segments = new ArrayList<>(); public static final Charset charset = StandardCharsets.US_ASCII; + public static final String LINE_NUMBER_KEY = "_PARSER_LINE_NUMBER"; static private abstract class LineParserSegment { int length; @@ -193,7 +194,7 @@ public Map parseLine(String line) throws ValueParseException { private Map parse(List segmentStrings) throws ValueParseException { if(segmentStrings.size() != segments.size()) { - throw new IllegalStateException("segment strings and segment halders must have the same size"); + throw new IllegalStateException("segment strings and segment handlers must have the same size"); } var result = new HashMap(); @@ -240,6 +241,7 @@ public T parse(InputStream is, T result, ParseEntryHandler>{ + + private int num_sp0; + + LineParser lineParser = new LineParser() + .strippedString(2, "alias") + .space(1) + .strippedString(32, "name") + .space(1) + .value(2, "preference", s-> + ValueParser.optional(ValueParser.INTEGER).parse(s) + .flatMap(v->v==0 ? Optional.empty() : Optional.of(v))); + ; + + public SP0DefinitionParser() { + super(); + this.num_sp0 = 16; + } + + public SP0DefinitionParser(int num_sp0) { + super(); + this.num_sp0 = num_sp0; + } + + @SuppressWarnings("unchecked") + @Override + public List parse(InputStream is) throws IOException, ResourceParseException { + SP0Definition[] result = new SP0Definition[num_sp0]; + result = lineParser.parse(is, result, (v, r)->{ + String alias = (String) v.get("alias"); + Optional preference = (Optional) v.get("preference"); + String name = (String) v.get("name"); + Integer lineNumber = (Integer) v.get(LineParser.LINE_NUMBER_KEY); + + var defn = new SP0Definition(alias, preference, name); + int p = preference.orElse(lineNumber); + + if(p>num_sp0) { + throw new ValueParseException(Integer.toString(p),String.format("Preference %d is larger than %d", p, num_sp0)); + } + if(p<1) { + throw new ValueParseException(Integer.toString(p),String.format("Preference %d is less than %d", p, 0)); + } + if(r[p-1]!=null) { + throw new ValueParseException(Integer.toString(p),String.format("Preference %d has already been set to %s", p, r[p-1].getAlias())); + } + + r[p-1] = defn; + return r; + }); + + return Collections.unmodifiableList(Arrays.asList(result)); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java new file mode 100644 index 000000000..e48210c9f --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java @@ -0,0 +1,26 @@ +package ca.bc.gov.nrs.vdyp.model; + +public class AbstractSpeciesDefinition { + + final String alias; + final String name; + + protected AbstractSpeciesDefinition(String alias, String name) { + this.alias = alias; + this.name = name; + } + + /** + * @return The short alias for the species + */ + public String getAlias() { + return alias; + } + + /** + * @return The full, human readable name for the species + */ + public String getName() { + return name; + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java index 7f0b37f0a..c84be27a0 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java @@ -1,25 +1,15 @@ package ca.bc.gov.nrs.vdyp.model; -public class BecDefinition { +public class BecDefinition extends AbstractSpeciesDefinition { - final String alias; final Region region; - final String name; public BecDefinition(String alias, Region region, String name) { - super(); - this.alias = alias; + super(alias, name); this.region = region; - this.name = name; } - public String getAlias() { - return alias; - } public Region getRegion() { return region; } - public String getName() { - return name; - } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java new file mode 100644 index 000000000..0d0c00698 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java @@ -0,0 +1,17 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Optional; + +public class SP0Definition extends AbstractSpeciesDefinition { + + final Optional preference; + + public SP0Definition(String alias, Optional preference, String name) { + super(alias, name); + this.preference = preference; + } + + public Optional getPreference() { + return preference; + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index db9170f2b..3738dc13b 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -178,11 +178,13 @@ public void testMultiLine() throws Exception { assertThat(result, contains( allOf( (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1") + (Matcher)hasEntry("part2", "Value1"), + (Matcher)hasEntry(LineParser.LINE_NUMBER_KEY, 1) ), allOf( (Matcher)hasEntry("part1", 43), - (Matcher)hasEntry("part2", "Value2") + (Matcher)hasEntry("part2", "Value2"), + (Matcher)hasEntry(LineParser.LINE_NUMBER_KEY, 2) ) )); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java new file mode 100644 index 000000000..903e2378c --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -0,0 +1,236 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.stringContainsInOrder; + +import java.io.ByteArrayInputStream; +import java.util.List; + +import org.easymock.internal.matchers.InstanceOf; +import org.hamcrest.Matchers; + +import static org.hamcrest.Matchers.equalTo; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; + +public class SP0DefinitionParserTest { + + @Test + public void testParse() throws Exception { + var parser = new SP0DefinitionParser(); + + var result = parser.parse(ControlFileParserTest.class, "coe/SP0DEF_v0.dat"); + + assertThat(result, contains( + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("B")), + Matchers.hasProperty("name", equalTo("Balsam")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("C")), + Matchers.hasProperty("name", equalTo("Cedar (X yellow)")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("D")), + Matchers.hasProperty("name", equalTo("Alder")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("E")), + Matchers.hasProperty("name", equalTo("Birch")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("F")), + Matchers.hasProperty("name", equalTo("Douglas Fir")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("H")), + Matchers.hasProperty("name", equalTo("Hemlock")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("L")), + Matchers.hasProperty("name", equalTo("Larch")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("MB")), + Matchers.hasProperty("name", equalTo("Maple")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("PA")), + Matchers.hasProperty("name", equalTo("White-bark pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("PL")), + Matchers.hasProperty("name", equalTo("Lodgepole Pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("PW")), + Matchers.hasProperty("name", equalTo("White pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("PY")), + Matchers.hasProperty("name", equalTo("Yellow pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("S")), + Matchers.hasProperty("name", equalTo("Spruce")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("Y")), + Matchers.hasProperty("name", equalTo("Yellow cedar")) + ) + + )); + } + + @Test + public void testOrderByPreference() throws Exception { + var parser = new SP0DefinitionParser(2); + + List result; + try( + var is = new ByteArrayInputStream("AT Aspen 02\r\nAC Cottonwood 01".getBytes()); + ) { + result = parser.parse(is); + } + assertThat(result, contains( + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) + ) + )); + } + + @Test + public void testOrderByLinesBlank() throws Exception { + var parser = new SP0DefinitionParser(2); + + List result; + try( + var is = new ByteArrayInputStream("AT Aspen \r\nAC Cottonwood ".getBytes()); + ) { + result = parser.parse(is); + } + assertThat(result, contains( + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) + ) + )); + } + + @Test + public void testOrderByLinesZero() throws Exception { + var parser = new SP0DefinitionParser(2); + + List result; + try( + var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood 00".getBytes()); + ) { + result = parser.parse(is); + } + assertThat(result, contains( + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), + Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) + ) + )); + } + + @Test + public void testErrorPreferenceOutOfBoundsHigh() throws Exception { + var parser = new SP0DefinitionParser(2); + + Exception ex1; + try( + var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood 03".getBytes()); + ) { + + ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + } + assertThat(ex1, hasProperty("line", is(2))); + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 3", "larger than 2"))); + } + + @Test + public void testErrorPreferenceOutOfBoundsLow() throws Exception { + var parser = new SP0DefinitionParser(2); + + Exception ex1; + try( + var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood -1".getBytes()); + ) { + + ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + } + assertThat(ex1, hasProperty("line", is(2))); + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference -1", "less than 0"))); + } + + @Test + public void testErrorPreferenceDuplicate() throws Exception { + var parser = new SP0DefinitionParser(2); + + Exception ex1; + try( + var is = new ByteArrayInputStream("AT Aspen 01\r\nAC Cottonwood 01".getBytes()); + ) { + + ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + } + assertThat(ex1, hasProperty("line", is(2))); + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 1", "set to AT"))); + } + +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 7bbd11c08..7b2b9459a 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -8,7 +8,7 @@ 001 00999999 Max # of Polygons to process (I8) (poly's with MODE = -1 NOT counted) 009 coe/Becdef.dat BEC Zone Definitions RD_BECD -010 coe/SP0DEF_V0.dat Standard SP0 Codes (with order) RD_SP0 +010 coe/SP0DEF_v0.dat Standard SP0 Codes (with order) RD_SP0 011 fip_p01.dat FIP YIELD INPUT (poly) GET_FIPP 012 fip_l01.dat FIP YIELD INPUT (layer) GET_FIPL diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 196ce0b41..1d70a1039 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -4,14 +4,17 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import java.util.Map; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; +import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; /** * Parser for FIP control files @@ -197,7 +200,7 @@ public String toString(String filename) throws IOException { // Read Definitions // RD_SP0 - // TODO + loadData(map, SP0_DEF, fileResolver, this::RD_SP0); // Read Groups @@ -414,14 +417,25 @@ call dbgI4( logr, 6 ) "25: Not used ", NDEBUG(25) ) void loadData(Map map, String key, FileResolver fileResolver, ResourceParser parser) throws IOException, ResourceParseException { try(var is = fileResolver.resolve((String) map.get(key))) { - map.put(key, RD_BEC(is)); + map.put(key, parser.parse(is)); } } + /** + * Loads the information that was in the global arrays BECV, BECNM, and BECCOASTAL in Fortran + */ private Map RD_BEC(InputStream data) throws IOException, ResourceParseException { var parser = new BecDefinitionParser(); return parser.parse(data); } + + /** + * Loads the information that was in the global arrays SP0V, SP0NAMEV in Fortran + */ + private List RD_SP0(InputStream data) throws IOException, ResourceParseException { + var parser = new SP0DefinitionParser(); + return parser.parse(data); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index a6eeaf918..a541114b5 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -3,17 +3,22 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import java.util.List; import java.util.Map; import org.hamcrest.Matcher; +import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; +@SuppressWarnings("unused") public class FipControlParserTest { @Test @@ -23,6 +28,7 @@ public void testParse() throws Exception { } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseBec() throws Exception { var parser = new FipControlParser(); @@ -34,4 +40,16 @@ public void testParseBec() throws Exception { is("AT"), instanceOf(BecDefinition.class))))); } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSP0() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) hasEntry(is(FipControlParser.SP0_DEF), + allOf( + instanceOf(List.class), + hasItem( + instanceOf(SP0Definition.class))))); + } } From 4b017f711b24204a89ef974f0986b0472f71fd4a Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 12 May 2023 15:28:49 -0700 Subject: [PATCH 11/98] Volume Equation Group Parsing --- .../io/parse/VolumeEquationGroupParser.java | 42 +++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 13 +++++- .../nrs/vdyp/fip/FipControlParserTest.java | 21 ++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java new file mode 100644 index 000000000..eb322e8bd --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java @@ -0,0 +1,42 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Parser for a Volume Equation Group data file + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class VolumeEquationGroupParser implements ResourceParser>>{ + + LineParser lineParser = new LineParser() + .strippedString(2, "sp0Alias") + .space(1) + .strippedString(4, "becAlias") + .space(1) + .integer(3,"vgrpId"); + + @Override + public Map> parse(InputStream is) throws IOException, ResourceParseException { + Map> result = new HashMap<>(); + result = lineParser.parse(is, result, (v, r)->{ + String sp0Alias = (String) v.get("sp0Alias"); + String becAlias = (String) v.get("becAlias"); + int vgrpId = (Integer) v.get("vgrpId"); + + r.computeIfAbsent(sp0Alias, k->new HashMap<>()).put(becAlias, vgrpId); + return r; + }); + + for (var e : result.entrySet()) { + result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); + } + return Collections.unmodifiableMap(result); + } + +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 7b2b9459a..e01207ab7 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -18,7 +18,7 @@ 016 vs_01.dat VDYP7 Layer by Species 018 vu_01.dat VDYP7 Layer by SP0 by Util -020 coe/vgrpdef1.dat Defines Volume Eqn groups RD_VGRP +020 coe/VGRPDEF1.DAT Defines Volume Eqn groups RD_VGRP 021 coe/dgrp.dat Defines Decay Groups RD_DGRP 022 coe/bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 1d70a1039..f1923cec5 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -13,6 +13,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.io.parse.VolumeEquationGroupParser; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -205,8 +206,8 @@ public String toString(String filename) throws IOException { // Read Groups // RD_VGRP - // TODO - + loadData(map, VOLUME_EQN_GROUPS, fileResolver, this::RD_VGRP); + // RD_VGRP // TODO @@ -436,6 +437,14 @@ private List RD_SP0(InputStream data) throws IOException, Resourc var parser = new SP0DefinitionParser(); return parser.parse(data); } + + /** + * Loads the information that was in the global array VGRPV in Fortran + */ + private Object RD_VGRP(InputStream data) throws IOException, ResourceParseException { + var parser = new VolumeEquationGroupParser(); + return parser.parse(data); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index a541114b5..8cf0a4298 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -6,6 +6,7 @@ import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isA; import java.util.List; import java.util.Map; @@ -52,4 +53,24 @@ public void testParseSP0() throws Exception { hasItem( instanceOf(SP0Definition.class))))); } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseVGRP() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.VOLUME_EQN_GROUPS), + allOf( // Map of SP0 Aliases + isA(Map.class), + hasEntry( + isA(String.class), + allOf( // Map of BEC aliases + isA(Map.class), + hasEntry( + isA(String.class), + isA(Integer.class) // Equation Identifier + )))))); + } } From 876e13e0826b68a33fccc1b403c2fb5e00cce98a Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 12 May 2023 17:41:50 -0700 Subject: [PATCH 12/98] VolumeEquationGroupParser --- .../vdyp/io/parse/BecDefinitionParser.java | 4 +- .../nrs/vdyp/io/parse/ControlFileParser.java | 7 +- .../gov/nrs/vdyp/io/parse/ResourceParser.java | 28 +++- .../vdyp/io/parse/SP0DefinitionParser.java | 5 +- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 19 +++ .../io/parse/VolumeEquationGroupParser.java | 24 +++- .../io/parse/BecDefinitionParserTest.java | 3 +- .../vdyp/io/parse/ControlFileParserTest.java | 2 +- .../io/parse/SP0DefinitionParserTest.java | 16 +-- .../parse/VolumeEquationGroupParserTest.java | 127 ++++++++++++++++++ .../{VydpMatchers.java => VdypMatchers.java} | 26 +++- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 25 ++-- .../nrs/vdyp/fip/FipControlParserTest.java | 6 +- 13 files changed, 256 insertions(+), 36 deletions(-) create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParserTest.java rename vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/{VydpMatchers.java => VdypMatchers.java} (61%) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index cc3cacf05..d7d6aecd9 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -18,6 +18,8 @@ */ public class BecDefinitionParser implements ResourceParser>{ + public static final String CONTROL_KEY = "BEC_DEF"; + LineParser lineParser = new LineParser() { @Override @@ -36,7 +38,7 @@ public boolean isStopSegment(List segments) { .strippedString("name"); @Override - public Map parse(InputStream is) throws IOException, ResourceParseException { + public Map parse(InputStream is, Map control) throws IOException, ResourceParseException { Map result = new HashMap<>(); result = lineParser.parse(is, result, (v, r)->{ String alias = (String) v.get("alias"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index ba3a0b9a2..44557d5d1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -60,7 +60,7 @@ public ControlFileParser() { @Override - public Map parse(InputStream input) throws IOException, ResourceParseException { + public Map parse(InputStream input, Map control) throws IOException, ResourceParseException { Map result = new HashMap<>(); return lineParser.parse(input, result, (map,r)->{ Integer index = (Integer) map.get("index"); @@ -136,4 +136,9 @@ public ControlFileParser record(int index, ValueParser parser) { this.valueParsers.put(index, parser); return this; } + + + public Map parse(InputStream is) throws IOException, ResourceParseException { + return this.parse(is, Collections.emptyMap()); + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java index 26ae89e81..126ef42f7 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Map; /** * A parser for a multi-line recource @@ -17,36 +18,53 @@ public interface ResourceParser { /** * Parse an InputStream * @param is + * @param control Control parameter map * @return The parsed resource * @throws IOException if there is an error communicating with the input stream * @throws ResourceParseException if there is a problem with the content of the resource */ - T parse(InputStream is) throws IOException, ResourceParseException; + T parse(InputStream is, Map control) throws IOException, ResourceParseException; /** * Parse a resource from the classpath * @param klazz * @param resourcePath + * @param control Control parameter map * @return The parsed resource * @throws IOException if there is an error communicating with the input stream * @throws ResourceParseException if there is a problem with the content of the resource */ - default T parse (Class klazz, String resourcePath) throws IOException, ResourceParseException { + default T parse (Class klazz, String resourcePath, Map control) throws IOException, ResourceParseException { try (var is = klazz.getResourceAsStream(resourcePath)) { - return parse(is); + return parse(is, control); } } /** * Parse a resource from a file * @param resourcePath + * @param control Control parameter map * @return The parsed resource * @throws IOException if there is an error communicating with the input stream * @throws ResourceParseException if there is a problem with the content of the resource */ - default T parse (Path resourcePath) throws IOException, ResourceParseException { + default T parse (Path resourcePath, Map control) throws IOException, ResourceParseException { try (InputStream is = Files.newInputStream(resourcePath)) { - return parse(is); + return parse(is, control); } } + + static U expectParsedControl(Map control, String key, Class clazz) { + var value = control.get(key); + if (value == null) { + throw new IllegalStateException("Expected control map to have "+key); + } + if (clazz!= String.class && value instanceof String) { + throw new IllegalStateException("Expected control map entry "+key+" to be parsed but was still a String "+value); + } + if(!clazz.isInstance(value)) { + throw new IllegalStateException("Expected control map entry "+key+" to be a "+clazz.getSimpleName()+" but was a "+value.getClass()); + } + return clazz.cast(value); + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index 48a079a51..fc379d4d3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -5,6 +5,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -17,6 +18,8 @@ */ public class SP0DefinitionParser implements ResourceParser>{ + public static final String CONTROL_KEY = "SP0_DEF"; + private int num_sp0; LineParser lineParser = new LineParser() @@ -41,7 +44,7 @@ public SP0DefinitionParser(int num_sp0) { @SuppressWarnings("unchecked") @Override - public List parse(InputStream is) throws IOException, ResourceParseException { + public List parse(InputStream is, Map control) throws IOException, ResourceParseException { SP0Definition[] result = new SP0Definition[num_sp0]; result = lineParser.parse(is, result, (v, r)->{ String alias = (String) v.get("alias"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 3f7c86e65..0d0603554 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.Function; /** * Parses a string to a value @@ -77,6 +78,24 @@ public static ValueParser> list(ValueParser delegate) { }; } + /** + * Wrap a parser with an additional validation step + * @param + * @param delegate + * @param validator Function that returns an error string if the parsed value is invalid + * @return + */ + public static ValueParser validate(ValueParser delegate, Function> validator) { + return s-> { + var value = delegate.parse(s); + var error = validator.apply(value); + if(error.isPresent()) { + throw new ValueParseException(s, error.get()); + } + return value; + }; + } + /** * Makes a parser that parses if the string is not blank, and returns an empty Optional otherwise. * @param delegate Parser to use if the string is not blank diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java index eb322e8bd..d750ab885 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java @@ -4,8 +4,12 @@ import java.io.InputStream; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; +import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; + /** * Parser for a Volume Equation Group data file * @@ -22,11 +26,25 @@ public class VolumeEquationGroupParser implements ResourceParser> parse(InputStream is) throws IOException, ResourceParseException { + public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { + + @SuppressWarnings("unchecked") + List sp0List = ResourceParser.expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class); + @SuppressWarnings("unchecked") + Map becMap = ResourceParser.expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class); + Map> result = new HashMap<>(); result = lineParser.parse(is, result, (v, r)->{ - String sp0Alias = (String) v.get("sp0Alias"); - String becAlias = (String) v.get("becAlias"); + final String sp0Alias = (String) v.get("sp0Alias"); + final String becAlias = (String) v.get("becAlias"); + + if(!sp0List.stream().anyMatch(def->def.getAlias().equalsIgnoreCase(sp0Alias))) { + throw new ValueParseException(sp0Alias, sp0Alias+" is not an SP0 identifier"); + } + if(!becMap.containsKey(becAlias)) { + throw new ValueParseException(becAlias, becAlias+" is not a BEC identifier"); + } + int vgrpId = (Integer) v.get("vgrpId"); r.computeIfAbsent(sp0Alias, k->new HashMap<>()).put(becAlias, vgrpId); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index 639f90026..3f02d65f7 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -5,6 +5,7 @@ import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasProperty; +import java.util.Collections; import static org.hamcrest.Matchers.equalTo; @@ -18,7 +19,7 @@ public class BecDefinitionParserTest { public void testParse() throws Exception { var parser = new BecDefinitionParser(); - var result = parser.parse(ControlFileParserTest.class, "coe/Becdef.dat"); + var result = parser.parse(ControlFileParserTest.class, "coe/Becdef.dat", Collections.emptyMap()); assertThat(result, hasEntry(equalTo("AT"), allOf( hasProperty("alias", equalTo("AT")), diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index 1f31a8389..e701047e3 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -1,6 +1,6 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import static ca.bc.gov.nrs.vdyp.test.VydpMatchers.parseAs; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.parseAs; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index 903e2378c..0533427c1 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -10,6 +10,7 @@ import static org.hamcrest.Matchers.stringContainsInOrder; import java.io.ByteArrayInputStream; +import java.util.Collections; import java.util.List; import org.easymock.internal.matchers.InstanceOf; @@ -20,7 +21,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; public class SP0DefinitionParserTest { @@ -29,7 +29,7 @@ public class SP0DefinitionParserTest { public void testParse() throws Exception { var parser = new SP0DefinitionParser(); - var result = parser.parse(ControlFileParserTest.class, "coe/SP0DEF_v0.dat"); + var result = parser.parse(ControlFileParserTest.class, "coe/SP0DEF_v0.dat", Collections.emptyMap()); assertThat(result, contains( allOf( @@ -124,7 +124,7 @@ public void testOrderByPreference() throws Exception { try( var is = new ByteArrayInputStream("AT Aspen 02\r\nAC Cottonwood 01".getBytes()); ) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat(result, contains( allOf( @@ -148,7 +148,7 @@ public void testOrderByLinesBlank() throws Exception { try( var is = new ByteArrayInputStream("AT Aspen \r\nAC Cottonwood ".getBytes()); ) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat(result, contains( allOf( @@ -172,7 +172,7 @@ public void testOrderByLinesZero() throws Exception { try( var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood 00".getBytes()); ) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat(result, contains( allOf( @@ -197,7 +197,7 @@ public void testErrorPreferenceOutOfBoundsHigh() throws Exception { var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood 03".getBytes()); ) { - ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 3", "larger than 2"))); @@ -212,7 +212,7 @@ public void testErrorPreferenceOutOfBoundsLow() throws Exception { var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood -1".getBytes()); ) { - ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference -1", "less than 0"))); @@ -227,7 +227,7 @@ public void testErrorPreferenceDuplicate() throws Exception { var is = new ByteArrayInputStream("AT Aspen 01\r\nAC Cottonwood 01".getBytes()); ) { - ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 1", "set to AT"))); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParserTest.java new file mode 100644 index 000000000..e96715c93 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParserTest.java @@ -0,0 +1,127 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.causedBy; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.stringContainsInOrder; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Optional; + + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.test.VdypMatchers; + +@SuppressWarnings("unused") +public class VolumeEquationGroupParserTest { + + @Test + public void testParse() throws Exception { + var parser = new VolumeEquationGroupParser(); + + var controlMap = makeControlMap(); + + var is = makeStream("S1 B1 001"); + var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); + + assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(1)))); + } + + @Test + public void testSP0MustExist() throws Exception { + var parser = new VolumeEquationGroupParser(); + + var controlMap = makeControlMap(); + + var is = makeStream("SX B1 001"); + + ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); + + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "SX", "SP0"))); + assertThat(ex1, hasProperty("line", is(1))); + assertThat(ex1, causedBy(hasProperty("value", is("SX")))); + } + + @Test + public void testBecMustExist() throws Exception { + var parser = new VolumeEquationGroupParser(); + + var controlMap = makeControlMap(); + + var is = makeStream("S1 BX 001"); + + ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); + + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "BX", "BEC"))); + assertThat(ex1, hasProperty("line", is(1))); + assertThat(ex1, causedBy(hasProperty("value", is("BX")))); + } + + @Test + public void testParseOvewrite() throws Exception { + // Original Fortran allows subsequent entries to overwrite old ones so don't validate against that + + var parser = new VolumeEquationGroupParser(); + + var controlMap = makeControlMap(); + + var is = makeStream("S1 B1 001", "S1 B1 002"); + var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); + + assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(2)))); + } + + @Test + public void testParseMultiple() throws Exception { + // Original Fortran allows subsequent entries to overwrite old ones so don't validate against that + + var parser = new VolumeEquationGroupParser(); + + var controlMap = makeControlMap(); + + var is = makeStream("S1 B1 001", "S1 B2 002", "S2 B1 001", "S2 B3 002", "S2 B4 003"); + var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); + + assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(1)))); + assertThat(result, hasEntry(is("S1"), hasEntry(is("B2"), is(2)))); + assertThat(result, hasEntry(is("S2"), hasEntry(is("B1"), is(1)))); + assertThat(result, hasEntry(is("S2"), hasEntry(is("B3"), is(2)))); + assertThat(result, hasEntry(is("S2"), hasEntry(is("B4"), is(3)))); + } + + private HashMap makeControlMap() { + var controlMap = new HashMap(); + + var becMap = new HashMap(); + var sp0List = new ArrayList(); + + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); + becMap.put("B2", new BecDefinition("B2", Region.INTERIOR, "Test BEC 2")); + becMap.put("B3", new BecDefinition("B3", Region.COASTAL, "Test BEC 3")); + becMap.put("B4", new BecDefinition("B4", Region.INTERIOR, "Test BEC 4")); + + sp0List.add(new SP0Definition("S1", Optional.empty(), "Test SP0 1")); + sp0List.add(new SP0Definition("S2", Optional.empty(), "Test SP0 2")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, Collections.unmodifiableMap(becMap)); + controlMap.put(SP0DefinitionParser.CONTROL_KEY, Collections.unmodifiableList(sp0List)); + return controlMap; + } + + private InputStream makeStream(String...lines) { + return new ByteArrayInputStream(String.join("\r\n", lines).getBytes()); + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java similarity index 61% rename from vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java rename to vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index 2b2f7fd46..44193c7e5 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VydpMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -1,8 +1,11 @@ package ca.bc.gov.nrs.vdyp.test; +import static org.hamcrest.Matchers.hasProperty; + import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.Matchers; import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; @@ -13,7 +16,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class VydpMatchers { +public class VdypMatchers { /** * Matches a string if when parsed by the parser method it matches the given matcher @@ -42,4 +45,25 @@ public void describeTo(Description description) { }; } + /** + * Matcher for the cause of an exception + * @param causeMatcher + * @return + */ + public static Matcher causedBy(Matcher causeMatcher) { + + return new BaseMatcher() { + + @Override + public boolean matches(Object actual) { + return causeMatcher.matches(((Throwable) actual).getCause()); + } + + @Override + public void describeTo(Description description) { + description.appendText("was caused by exception that ").appendDescriptionOf(causeMatcher); + } + + }; + } } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index f1923cec5..fd9edcc77 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -68,8 +69,8 @@ public class FipControlParser { public static final String MODIFIER_FILE = "MODIFIER_FILE"; public static final String DEBUG_SWITCHES = "DEBUG_SWITCHES"; public static final String MAX_NUM_POLY = "MAX_NUM_POLY"; - public static final String BEC_DEF = "BEC_DEF"; - public static final String SP0_DEF = "SP0_DEF"; + public static final String BEC_DEF = BecDefinitionParser.CONTROL_KEY; + public static final String SP0_DEF = SP0DefinitionParser.CONTROL_KEY; static final ValueParser FILENAME = String::strip; @@ -81,7 +82,7 @@ public class FipControlParser { .record( 11, FIP_YIELD_POLY_INPUT, FILENAME) // GET_FIPP .record( 12, FIP_YIELD_LAYER_INPUT, FILENAME) // GET_FIPL - .record( 13, FIP_YIELD_LX_SP0_INPUT, FILENAME) // GET_FIPS + .record( 13, FIP_YIELD_LX_SP0_INPUT, FILENAME) // GET_FIPS .record( 15, VDYP_POLYGON, FILENAME) // .record( 16, VDYP_LAYER_BY_SPECIES, FILENAME) // @@ -190,10 +191,10 @@ public String toString(String filename) throws IOException { } Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { - var map = controlParser.parse(is); + var map = controlParser.parse(is, Collections.emptyMap()); // RD_BEC - loadData(map, BEC_DEF, fileResolver, this::RD_BEC); + loadData(map, BecDefinitionParser.CONTROL_KEY, fileResolver, this::RD_BEC); // DEF_BEC // TODO @@ -418,32 +419,32 @@ call dbgI4( logr, 6 ) "25: Not used ", NDEBUG(25) ) void loadData(Map map, String key, FileResolver fileResolver, ResourceParser parser) throws IOException, ResourceParseException { try(var is = fileResolver.resolve((String) map.get(key))) { - map.put(key, parser.parse(is)); + map.put(key, parser.parse(is, map)); } } /** * Loads the information that was in the global arrays BECV, BECNM, and BECCOASTAL in Fortran */ - private Map RD_BEC(InputStream data) throws IOException, ResourceParseException { + private Map RD_BEC(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new BecDefinitionParser(); - return parser.parse(data); + return parser.parse(data, control); } /** * Loads the information that was in the global arrays SP0V, SP0NAMEV in Fortran */ - private List RD_SP0(InputStream data) throws IOException, ResourceParseException { + private List RD_SP0(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new SP0DefinitionParser(); - return parser.parse(data); + return parser.parse(data, control); } /** * Loads the information that was in the global array VGRPV in Fortran */ - private Object RD_VGRP(InputStream data) throws IOException, ResourceParseException { + private Object RD_VGRP(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new VolumeEquationGroupParser(); - return parser.parse(data); + return parser.parse(data, control); } static interface FileResolver { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 8cf0a4298..fc5342d95 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -15,7 +15,9 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; +import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -34,7 +36,7 @@ public void testParse() throws Exception { public void testParseBec() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) hasEntry(is(FipControlParser.BEC_DEF), + assertThat(result, (Matcher) hasEntry(is(BecDefinitionParser.CONTROL_KEY), allOf( instanceOf(Map.class), hasEntry( @@ -47,7 +49,7 @@ public void testParseBec() throws Exception { public void testParseSP0() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) hasEntry(is(FipControlParser.SP0_DEF), + assertThat(result, (Matcher) hasEntry(is(SP0DefinitionParser.CONTROL_KEY), allOf( instanceOf(List.class), hasItem( From c7636000f07571113262be1de1cd82dc74adf2a0 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 15 May 2023 11:01:02 -0700 Subject: [PATCH 13/98] Move control key for volume eqn group to parser --- .../ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java | 2 ++ .../src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java index d750ab885..ebda8d2ef 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java @@ -18,6 +18,8 @@ */ public class VolumeEquationGroupParser implements ResourceParser>>{ + public static final String CONTROL_KEY = "VOLUME_EQN_GROUPS"; + LineParser lineParser = new LineParser() .strippedString(2, "sp0Alias") .space(1) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index fd9edcc77..8345faec1 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -32,7 +32,7 @@ public class FipControlParser { public static final String VDYP_POLYGON = "VDYP_POLYGON"; public static final String VDYP_LAYER_BY_SPECIES = "VDYP_LAYER_BY_SPECIES"; public static final String VDYP_LAYER_BY_SP0_BY_UTIL = "VDYP_LAYER_BY_SP0_BY_UTIL"; - public static final String VOLUME_EQN_GROUPS = "VOLUME_EQN_GROUPS"; + public static final String VOLUME_EQN_GROUPS = VolumeEquationGroupParser.CONTROL_KEY; public static final String DECAY_GROUPS = "DECAY_GROUPS"; public static final String BREAKAGE_GROUPS = "BREAKAGE_GROUPS"; public static final String SITE_CURVE_NUMBERS = "SITE_CURVE_NUMBERS"; From 2a5763c8e355f762dcb57fca9ee06b268ef71c90 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 15 May 2023 11:38:39 -0700 Subject: [PATCH 14/98] Decay and breakage groups --- ...upParser.java => EquationGroupParser.java} | 8 +++- ...Test.java => EquationGroupParserTest.java} | 12 +++--- .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 4 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 33 ++++++++++----- .../nrs/vdyp/fip/FipControlParserTest.java | 40 +++++++++++++++++++ 5 files changed, 77 insertions(+), 20 deletions(-) rename vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/{VolumeEquationGroupParser.java => EquationGroupParser.java} (86%) rename vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/{VolumeEquationGroupParserTest.java => EquationGroupParserTest.java} (93%) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java similarity index 86% rename from vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java rename to vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index ebda8d2ef..a410e5627 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -16,9 +16,13 @@ * @author Kevin Smith, Vivid Solutions * */ -public class VolumeEquationGroupParser implements ResourceParser>>{ +public class EquationGroupParser implements ResourceParser>>{ - public static final String CONTROL_KEY = "VOLUME_EQN_GROUPS"; + public static final String VOLUME_CONTROL_KEY = "VOLUME_EQN_GROUPS"; + + public static final String DECAY_CONTROL_KEY = "DECAY_GROUPS"; + + public static final String BREAKAGE_CONTROL_KEY = "BREAKAGE_GROUPS"; LineParser lineParser = new LineParser() .strippedString(2, "sp0Alias") diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java similarity index 93% rename from vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParserTest.java rename to vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index e96715c93..f445d308b 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -26,11 +26,11 @@ import ca.bc.gov.nrs.vdyp.test.VdypMatchers; @SuppressWarnings("unused") -public class VolumeEquationGroupParserTest { +public class EquationGroupParserTest { @Test public void testParse() throws Exception { - var parser = new VolumeEquationGroupParser(); + var parser = new EquationGroupParser(); var controlMap = makeControlMap(); @@ -42,7 +42,7 @@ public void testParse() throws Exception { @Test public void testSP0MustExist() throws Exception { - var parser = new VolumeEquationGroupParser(); + var parser = new EquationGroupParser(); var controlMap = makeControlMap(); @@ -57,7 +57,7 @@ public void testSP0MustExist() throws Exception { @Test public void testBecMustExist() throws Exception { - var parser = new VolumeEquationGroupParser(); + var parser = new EquationGroupParser(); var controlMap = makeControlMap(); @@ -74,7 +74,7 @@ public void testBecMustExist() throws Exception { public void testParseOvewrite() throws Exception { // Original Fortran allows subsequent entries to overwrite old ones so don't validate against that - var parser = new VolumeEquationGroupParser(); + var parser = new EquationGroupParser(); var controlMap = makeControlMap(); @@ -88,7 +88,7 @@ public void testParseOvewrite() throws Exception { public void testParseMultiple() throws Exception { // Original Fortran allows subsequent entries to overwrite old ones so don't validate against that - var parser = new VolumeEquationGroupParser(); + var parser = new EquationGroupParser(); var controlMap = makeControlMap(); diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index e01207ab7..8fa852ec3 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -19,8 +19,8 @@ 018 vu_01.dat VDYP7 Layer by SP0 by Util 020 coe/VGRPDEF1.DAT Defines Volume Eqn groups RD_VGRP -021 coe/dgrp.dat Defines Decay Groups RD_DGRP -022 coe/bgrp.dat Defines Breakage Groups RD_BGRP IPSJF157 +021 coe/DGRP.DAT Defines Decay Groups RD_DGRP +022 coe/BGRP.DAT Defines Breakage Groups RD_BGRP IPSJF157 025 coe/SIEQN.prm Site Curve Numbers (SCN) assigned RD_E025 025 Nullifies above siteCurve # diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 8345faec1..5c5cc0f6c 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -14,7 +14,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; -import ca.bc.gov.nrs.vdyp.io.parse.VolumeEquationGroupParser; +import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -32,9 +32,9 @@ public class FipControlParser { public static final String VDYP_POLYGON = "VDYP_POLYGON"; public static final String VDYP_LAYER_BY_SPECIES = "VDYP_LAYER_BY_SPECIES"; public static final String VDYP_LAYER_BY_SP0_BY_UTIL = "VDYP_LAYER_BY_SP0_BY_UTIL"; - public static final String VOLUME_EQN_GROUPS = VolumeEquationGroupParser.CONTROL_KEY; - public static final String DECAY_GROUPS = "DECAY_GROUPS"; - public static final String BREAKAGE_GROUPS = "BREAKAGE_GROUPS"; + public static final String VOLUME_EQN_GROUPS = EquationGroupParser.VOLUME_CONTROL_KEY; + public static final String DECAY_GROUPS = EquationGroupParser.DECAY_CONTROL_KEY; + public static final String BREAKAGE_GROUPS = EquationGroupParser.BREAKAGE_CONTROL_KEY; public static final String SITE_CURVE_NUMBERS = "SITE_CURVE_NUMBERS"; public static final String SITE_CURVE_AGE_MAX = "SITE_CURVE_AGE_MAX"; public static final String DEFAULT_EQ_NUM = "DEFAULT_EQ_NUM"; @@ -209,14 +209,11 @@ public String toString(String filename) throws IOException { // RD_VGRP loadData(map, VOLUME_EQN_GROUPS, fileResolver, this::RD_VGRP); - // RD_VGRP - // TODO - // RD_DGRP - // TODO + loadData(map, DECAY_GROUPS, fileResolver, this::RD_DGRP); // RD_BGRP - // TODO + loadData(map, BREAKAGE_GROUPS, fileResolver, this::RD_BGRP); // RD_GRBA1 // TODO @@ -443,7 +440,23 @@ private List RD_SP0(InputStream data, Map control * Loads the information that was in the global array VGRPV in Fortran */ private Object RD_VGRP(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new VolumeEquationGroupParser(); + var parser = new EquationGroupParser(); + return parser.parse(data, control); + } + + /** + * Loads the information that was in the global array DGRPV in Fortran + */ + private Object RD_DGRP(InputStream data, Map control) throws IOException, ResourceParseException { + var parser = new EquationGroupParser(); + return parser.parse(data, control); + } + + /** + * Loads the information that was in the global array BG1DEFV in Fortran + */ + private Object RD_BGRP(InputStream data, Map control) throws IOException, ResourceParseException { + var parser = new EquationGroupParser(); return parser.parse(data, control); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index fc5342d95..930980c65 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -75,4 +75,44 @@ public void testParseVGRP() throws Exception { isA(Integer.class) // Equation Identifier )))))); } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseDGRP() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.DECAY_GROUPS), + allOf( // Map of SP0 Aliases + isA(Map.class), + hasEntry( + isA(String.class), + allOf( // Map of BEC aliases + isA(Map.class), + hasEntry( + isA(String.class), + isA(Integer.class) // Equation Identifier + )))))); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseBGRP() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.BREAKAGE_GROUPS), + allOf( // Map of SP0 Aliases + isA(Map.class), + hasEntry( + isA(String.class), + allOf( // Map of BEC aliases + isA(Map.class), + hasEntry( + isA(String.class), + isA(Integer.class) // Equation Identifier + )))))); + } } From f2ae92809cdf35dfdfc4ef74adaf07eab445e92c Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 15 May 2023 15:06:48 -0700 Subject: [PATCH 15/98] Validate that SP0-BEC->Group ID mappings are complete --- .../vdyp/common/ExpectationDifference.java | 63 +++++++++ .../vdyp/io/parse/EquationGroupParser.java | 60 +++++++- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 10 +- .../vdyp/io/parse/ResourceParseException.java | 37 ++--- .../io/parse/ResourceParseLineException.java | 44 ++++++ .../io/parse/ResourceParseValidException.java | 36 +++++ .../gov/nrs/vdyp/io/parse/ResourceParser.java | 6 +- .../vdyp/io/parse/ControlFileParserTest.java | 4 +- .../io/parse/EquationGroupParserTest.java | 131 ++++++++++++++++-- .../gov/nrs/vdyp/io/parse/LineParserTest.java | 2 +- .../io/parse/SP0DefinitionParserTest.java | 6 +- .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 19 ++- .../nrs/vdyp/fip/FipControlParserTest.java | 19 +++ 14 files changed, 373 insertions(+), 66 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java new file mode 100644 index 000000000..b09a371ba --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java @@ -0,0 +1,63 @@ +package ca.bc.gov.nrs.vdyp.common; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * The difference between a set of values and what they are expaected to be + * + * @author Kevin Smith, Vivid Solutions + * + * @param + */ +public class ExpectationDifference { + final Set missing; + final Set unexpected; + + public ExpectationDifference(Set missing, Set unexpected) { + super(); + this.missing = missing; + this.unexpected = unexpected; + } + + /** + * Find the missing and expected values in a collections of values. + * @param + * @param values + * @param expected + * @return + */ + public static ExpectationDifference difference(Collection values, Collection expected) { + var missing = new HashSet(expected); + missing.removeAll(values); + var unexpected = new HashSet(values); + unexpected.removeAll(expected); + return new ExpectationDifference(missing, unexpected); + } + + /** + * Which values are missing + * @return + */ + public Set getMissing() { + return missing; + } + + /** + * Which values were unexpected + * @return + */ + public Set getUnexpected() { + return unexpected; + } + + /** + * Were the values as expected + * @return + */ + public boolean isSame() { + return getMissing().isEmpty() && getUnexpected().isEmpty(); + } +} + diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index a410e5627..8c4025256 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -2,13 +2,17 @@ import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.common.ExpectationDifference; /** * Parser for a Volume Equation Group data file @@ -23,14 +27,26 @@ public class EquationGroupParser implements ResourceParser hiddenBecs = Collections.emptyList(); + public EquationGroupParser() { + this(3); + } + + public EquationGroupParser(int identifierLength) { + lineParser = new LineParser() + .strippedString(2, "sp0Alias") + .space(1) + .strippedString(4, "becAlias") + .space(1) + .integer(identifierLength,"grpId"); + } + @Override public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { @@ -51,7 +67,7 @@ public Map> parse(InputStream is, Mapnew HashMap<>()).put(becAlias, vgrpId); return r; @@ -60,7 +76,37 @@ public Map> parse(InputStream is, Map errors = new ArrayList<>(); + + var sp0Keys = sp0List.stream().map(def->def.getAlias()).collect(Collectors.toSet()); + var becKeys = becMap.keySet().stream().filter(k->!hiddenBecs.contains(k)).collect(Collectors.toSet()); + + var sp0Diff = ExpectationDifference.difference(result.keySet(), sp0Keys); + + sp0Diff.getMissing().stream().map(sp0Key->String.format("Expected mappings for SP0 %s but it was missing", sp0Key)).collect(Collectors.toCollection(()->errors)); + sp0Diff.getUnexpected().stream().map(sp0Key->String.format("Unexpected mapping for SP0 %s", sp0Key)).collect(Collectors.toCollection(()->errors)); + + for(var entry : result.entrySet()) { + var becDiff = ExpectationDifference.difference(entry.getValue().keySet(), becKeys); + var sp0Key = entry.getKey(); + becDiff.getMissing().stream().map(becKey->String.format("Expected mappings for BEC %s but it was missing for SP0 %s", becKey, sp0Key)).collect(Collectors.toCollection(()->errors)); + becDiff.getUnexpected().stream().map(becKey->String.format("Unexpected mapping for BEC %s under SP0 %s", becKey, sp0Key)).collect(Collectors.toCollection(()->errors)); + } + + if(!errors.isEmpty()) { + throw new ResourceParseValidException (String.join(System.lineSeparator(), errors)); + } + return Collections.unmodifiableMap(result); } + + public void setHiddenBecs(Collection hiddenBecs) { + this.hiddenBecs = hiddenBecs; + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 28a00b809..fa744b140 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -218,9 +218,9 @@ private Map parse(List segmentStrings) throws ValueParseE * @param addToResult Add a record from the file to the result object and return it * @return The result object after parsing * @throws IOException if an error occurs while reading from the stream - * @throws ResourceParseException if the content of the stream could not be parsed + * @throws ResourceParseLineException if the content of the stream could not be parsed */ - public T parse(InputStream is, T result, ParseEntryHandler, T> addToResult) throws IOException, ResourceParseException { + public T parse(InputStream is, T result, ParseEntryHandler, T> addToResult) throws IOException, ResourceParseLineException { var reader = new BufferedReader(new InputStreamReader(is, charset)); String line; int lineNumber = 0; @@ -250,7 +250,7 @@ public T parse(InputStream is, T result, ParseEntryHandler T parse(InputStream is, T result, ParseEntryHandler> parse (InputStream is) throws IOException, ResourceParseException { + public List> parse (InputStream is) throws IOException, ResourceParseLineException { var result = new ArrayList> (); result = this.parse(is, result, (v, r)->{r.add(v); return r;}); return result; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java index 2d6e6f356..5c1b10990 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseException.java @@ -1,44 +1,29 @@ package ca.bc.gov.nrs.vdyp.io.parse; -/** - * An error parsing a particular line of a multi-line resource - * - * @author Kevin Smith, Vivid Solutions - * - */ public class ResourceParseException extends Exception { - private static final long serialVersionUID = 5188546056230073563L; - - int line; + private static final long serialVersionUID = -5647186835165496893L; - public int getLine() { - return line; + public ResourceParseException() { + super(); } - public ResourceParseException(int line, + public ResourceParseException( String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace ) { - super(message(line, message), cause, enableSuppression, writableStackTrace); - this.line = line; + super(message, cause, enableSuppression, writableStackTrace); } - public ResourceParseException(int line, String message, Throwable cause) { + public ResourceParseException(String message, Throwable cause) { super(message, cause); - this.line = line; } - public ResourceParseException(int line, String message) { - super(message(line, message)); - this.line = line; + public ResourceParseException(String message) { + super(message); } - public ResourceParseException(int line, Throwable cause) { - super(message(line, cause.getMessage()), cause); - this.line = line; - } - - private static String message(int line, String message) { - return String.format("Error at line %d: %s",line,message); + public ResourceParseException(Throwable cause) { + super(cause); } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java new file mode 100644 index 000000000..84f710f52 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java @@ -0,0 +1,44 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +/** + * An error parsing a particular line of a multi-line resource + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class ResourceParseLineException extends ResourceParseException { + + private static final long serialVersionUID = 5188546056230073563L; + + int line; + + public int getLine() { + return line; + } + + public ResourceParseLineException(int line, + String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace + ) { + super(message(line, message), cause, enableSuppression, writableStackTrace); + this.line = line; + } + + public ResourceParseLineException(int line, String message, Throwable cause) { + super(message, cause); + this.line = line; + } + + public ResourceParseLineException(int line, String message) { + super(message(line, message)); + this.line = line; + } + + public ResourceParseLineException(int line, Throwable cause) { + super(message(line, cause.getMessage()), cause); + this.line = line; + } + + private static String message(int line, String message) { + return String.format("Error at line %d: %s",line,message); + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java new file mode 100644 index 000000000..671898573 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java @@ -0,0 +1,36 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +/** + * An error parsing resource that is not associated with a particular line + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class ResourceParseValidException extends ResourceParseException { + + private static final long serialVersionUID = 5188546056230073563L; + + public ResourceParseValidException() { + super(); + } + + public ResourceParseValidException( + String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace + ) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public ResourceParseValidException(String message, Throwable cause) { + super(message, cause); + } + + public ResourceParseValidException(String message) { + super(message); + } + + public ResourceParseValidException(Throwable cause) { + super(cause); + } + + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java index 126ef42f7..be7ffd6e1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java @@ -21,7 +21,7 @@ public interface ResourceParser { * @param control Control parameter map * @return The parsed resource * @throws IOException if there is an error communicating with the input stream - * @throws ResourceParseException if there is a problem with the content of the resource + * @throws ResourceParseLineException if there is a problem with the content of the resource */ T parse(InputStream is, Map control) throws IOException, ResourceParseException; @@ -32,7 +32,7 @@ public interface ResourceParser { * @param control Control parameter map * @return The parsed resource * @throws IOException if there is an error communicating with the input stream - * @throws ResourceParseException if there is a problem with the content of the resource + * @throws ResourceParseLineException if there is a problem with the content of the resource */ default T parse (Class klazz, String resourcePath, Map control) throws IOException, ResourceParseException { try (var is = klazz.getResourceAsStream(resourcePath)) { @@ -46,7 +46,7 @@ default T parse (Class klazz, String resourcePath, Map contro * @param control Control parameter map * @return The parsed resource * @throws IOException if there is an error communicating with the input stream - * @throws ResourceParseException if there is a problem with the content of the resource + * @throws ResourceParseLineException if there is a problem with the content of the resource */ default T parse (Path resourcePath, Map control) throws IOException, ResourceParseException { try (InputStream is = Files.newInputStream(resourcePath)) { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index e701047e3..fcba4053d 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -221,7 +221,7 @@ void testException() throws Exception { String file = "00X Control 1\n002 Control 2"; try (InputStream is = new ByteArrayInputStream(file.getBytes())) { - ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is)); assertThat(ex1, hasProperty("line", is(1))); assertThat(ex1, hasProperty("cause", instanceOf(ValueParseException.class))); @@ -238,7 +238,7 @@ void testExceptionInControlValueParser() throws Exception { String file = "001 Control 1\n002 Control 2"; try (InputStream is = new ByteArrayInputStream(file.getBytes())) { - ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is)); + ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is)); assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("cause", instanceOf(ValueParseException.class))); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index f445d308b..99233228f 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -7,12 +7,15 @@ import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.stringContainsInOrder; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Optional; @@ -32,7 +35,7 @@ public class EquationGroupParserTest { public void testParse() throws Exception { var parser = new EquationGroupParser(); - var controlMap = makeControlMap(); + var controlMap = makeControlMapSingle(); var is = makeStream("S1 B1 001"); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); @@ -44,11 +47,11 @@ public void testParse() throws Exception { public void testSP0MustExist() throws Exception { var parser = new EquationGroupParser(); - var controlMap = makeControlMap(); + var controlMap = makeControlMapSingle(); var is = makeStream("SX B1 001"); - ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); + ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "SX", "SP0"))); assertThat(ex1, hasProperty("line", is(1))); @@ -59,11 +62,11 @@ public void testSP0MustExist() throws Exception { public void testBecMustExist() throws Exception { var parser = new EquationGroupParser(); - var controlMap = makeControlMap(); + var controlMap = makeControlMapSingle(); var is = makeStream("S1 BX 001"); - ResourceParseException ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); + ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "BX", "BEC"))); assertThat(ex1, hasProperty("line", is(1))); @@ -76,7 +79,7 @@ public void testParseOvewrite() throws Exception { var parser = new EquationGroupParser(); - var controlMap = makeControlMap(); + var controlMap = makeControlMapSingle(); var is = makeStream("S1 B1 001", "S1 B1 002"); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); @@ -86,22 +89,122 @@ public void testParseOvewrite() throws Exception { @Test public void testParseMultiple() throws Exception { - // Original Fortran allows subsequent entries to overwrite old ones so don't validate against that - var parser = new EquationGroupParser(); var controlMap = makeControlMap(); - var is = makeStream("S1 B1 001", "S1 B2 002", "S2 B1 001", "S2 B3 002", "S2 B4 003"); + var is = makeStream( + "S1 B1 011", + "S1 B2 012", + "S1 B3 013", + "S1 B4 014", + "S2 B1 021", + "S2 B2 022", + "S2 B3 023", + "S2 B4 024"); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); - assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(1)))); - assertThat(result, hasEntry(is("S1"), hasEntry(is("B2"), is(2)))); - assertThat(result, hasEntry(is("S2"), hasEntry(is("B1"), is(1)))); - assertThat(result, hasEntry(is("S2"), hasEntry(is("B3"), is(2)))); - assertThat(result, hasEntry(is("S2"), hasEntry(is("B4"), is(3)))); + assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(11)))); + assertThat(result, hasEntry(is("S1"), hasEntry(is("B2"), is(12)))); + assertThat(result, hasEntry(is("S1"), hasEntry(is("B3"), is(13)))); + assertThat(result, hasEntry(is("S1"), hasEntry(is("B4"), is(14)))); + assertThat(result, hasEntry(is("S2"), hasEntry(is("B1"), is(21)))); + assertThat(result, hasEntry(is("S2"), hasEntry(is("B2"), is(22)))); + assertThat(result, hasEntry(is("S2"), hasEntry(is("B3"), is(23)))); + assertThat(result, hasEntry(is("S2"), hasEntry(is("B4"), is(24)))); } + + @Test + public void testRequireNoMissingSp0() throws Exception { + var parser = new EquationGroupParser(); + + var controlMap = makeControlMap(); + + List unusedBecs= Arrays.asList("B2", "B4"); + + var is = makeStream( + "S1 B1 011", + "S1 B2 012", + "S1 B3 013", + "S1 B4 014" + //"S2 B1 021", // Missing + //"S2 B2 022", + //"S2 B3 023", + //"S2 B4 024" + ); + + ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); + + assertThat(ex1, hasProperty("message", is("Expected mappings for SP0 S2 but it was missing"))); + + } + + @Test + public void testRequireNoMissingBec() throws Exception { + + var parser = new EquationGroupParser(); + + var controlMap = makeControlMap(); + + List unusedBecs= Arrays.asList("B2", "B4"); + + var is = makeStream( + "S1 B1 011", + "S1 B2 012", + // "S1 B3 013", // Missing + "S1 B4 014", + "S2 B1 021", + "S2 B2 022", + "S2 B3 023", + "S2 B4 024"); + + ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); + + assertThat(ex1, hasProperty("message", is("Expected mappings for BEC B3 but it was missing for SP0 S1"))); + + } + + @Test + public void testRequireNoUnexpectedBec() throws Exception { + + var parser = new EquationGroupParser(); + + var controlMap = makeControlMap(); + + List hiddenBecs= Arrays.asList("B3"); + parser.setHiddenBecs(hiddenBecs); + + var is = makeStream( + "S1 B1 011", + "S1 B2 012", + "S1 B4 014", + "S2 B1 021", + "S2 B2 022", + "S2 B3 023", // Unexpected + "S2 B4 024"); + + ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); + + assertThat(ex1, hasProperty("message", is("Unexpected mapping for BEC B3 under SP0 S2"))); + + } + + private HashMap makeControlMapSingle() { + var controlMap = new HashMap(); + + var becMap = new HashMap(); + var sp0List = new ArrayList(); + + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); + + sp0List.add(new SP0Definition("S1", Optional.empty(), "Test SP0 1")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, Collections.unmodifiableMap(becMap)); + controlMap.put(SP0DefinitionParser.CONTROL_KEY, Collections.unmodifiableList(sp0List)); + return controlMap; + } + private HashMap makeControlMap() { var controlMap = new HashMap(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 3738dc13b..c6280d5e9 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -201,7 +201,7 @@ public void testMultiLineException() throws Exception { var is = new ByteArrayInputStream("0042 Value1\r\n004x Value2".getBytes()); ) { - var ex1 = assertThrows(ResourceParseException.class, ()-> parser.parse(is)); + var ex1 = assertThrows(ResourceParseLineException.class, ()-> parser.parse(is)); assertThat(ex1, hasProperty("line", is(2))); // Line numbers indexed from 1 so the error is line 2 assertThat(ex1, hasProperty("cause", isA(ValueParseException.class))); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index 0533427c1..cf2bc9397 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -197,7 +197,7 @@ public void testErrorPreferenceOutOfBoundsHigh() throws Exception { var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood 03".getBytes()); ) { - ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.emptyMap())); + ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 3", "larger than 2"))); @@ -212,7 +212,7 @@ public void testErrorPreferenceOutOfBoundsLow() throws Exception { var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood -1".getBytes()); ) { - ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.emptyMap())); + ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference -1", "less than 0"))); @@ -227,7 +227,7 @@ public void testErrorPreferenceDuplicate() throws Exception { var is = new ByteArrayInputStream("AT Aspen 01\r\nAC Cottonwood 01".getBytes()); ) { - ex1 = Assertions.assertThrows(ResourceParseException.class, ()->parser.parse(is, Collections.emptyMap())); + ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 1", "set to AT"))); diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 8fa852ec3..daf1bdf36 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -26,7 +26,7 @@ 025 Nullifies above siteCurve # 026 coe/SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 -030 coe/grpba1.dat Default Eq # BA=f(CC) RD_GRBA1 +030 coe/GRPBA1.DAT Default Eq # BA=f(CC) RD_GRBA1 031 coe/gmodba1.dat Eqn modifiers for above RD_GMBA1 033 coe/fipstkr.prm Stocking class factors RD_STK33 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 5c5cc0f6c..4da5f66e3 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -4,17 +4,18 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; -import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -37,7 +38,7 @@ public class FipControlParser { public static final String BREAKAGE_GROUPS = EquationGroupParser.BREAKAGE_CONTROL_KEY; public static final String SITE_CURVE_NUMBERS = "SITE_CURVE_NUMBERS"; public static final String SITE_CURVE_AGE_MAX = "SITE_CURVE_AGE_MAX"; - public static final String DEFAULT_EQ_NUM = "DEFAULT_EQ_NUM"; + public static final String DEFAULT_EQ_NUM = EquationGroupParser.DEFAULT_CONTROL_KEY; public static final String EQN_MODIFIERS = "EQN_MODIFIERS"; public static final String STOCKING_CLASS_FACTORS = "STOCKING_CLASS_FACTORS"; public static final String COE_BA = "COE_BA"; @@ -216,7 +217,7 @@ public String toString(String filename) throws IOException { loadData(map, BREAKAGE_GROUPS, fileResolver, this::RD_BGRP); // RD_GRBA1 - // TODO + loadData(map, DEFAULT_EQ_NUM, fileResolver, this::RD_GRBA1); // RD_GMBA1 // TODO @@ -441,6 +442,7 @@ private List RD_SP0(InputStream data, Map control */ private Object RD_VGRP(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new EquationGroupParser(); + parser.setHiddenBecs(Arrays.asList("BG")); return parser.parse(data, control); } @@ -453,12 +455,21 @@ private Object RD_DGRP(InputStream data, Map control) throws IOE } /** - * Loads the information that was in the global array BG1DEFV in Fortran + * Loads the information that was in the global array BGRPV in Fortran */ private Object RD_BGRP(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new EquationGroupParser(); return parser.parse(data, control); } + + /** + * Loads the information that was in the global array BG1DEFV in Fortran + */ + private Object RD_GRBA1(InputStream data, Map control) throws IOException, ResourceParseException { + var parser = new EquationGroupParser(5); + parser.setHiddenBecs(Arrays.asList("BG", "AT")); + return parser.parse(data, control); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 930980c65..a392d3a09 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -115,4 +115,23 @@ public void testParseBGRP() throws Exception { isA(Integer.class) // Equation Identifier )))))); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseGRBA1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.DEFAULT_EQ_NUM), + allOf( // Map of SP0 Aliases + isA(Map.class), + hasEntry( + isA(String.class), + allOf( // Map of BEC aliases + isA(Map.class), + hasEntry( + isA(String.class), + isA(Integer.class) // Equation Identifier + )))))); + } } From dad77bebdec051c00beaa6c5ef1bfabb5a1204c5 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 15 May 2023 15:59:30 -0700 Subject: [PATCH 16/98] Parse equation modifier data file --- .../vdyp/io/parse/EquationModifierParser.java | 53 +++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 12 ++++- .../nrs/vdyp/fip/FipControlParserTest.java | 19 +++++++ 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java new file mode 100644 index 000000000..579a7ee68 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java @@ -0,0 +1,53 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Parser for an equation modifier mapping data file + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class EquationModifierParser implements ResourceParser>>{ + + public static final String CONTROL_KEY = "EQN_MODIFIERS"; + + private static final String DEFAULT_KEY = "default"; + private static final String ITG_KEY = "itg"; + private static final String REASSIGNED_KEY = "reassigned"; + + LineParser lineParser = new LineParser() + .integer(3, DEFAULT_KEY) + .integer(4, ITG_KEY) + .integer(4, REASSIGNED_KEY); + + public EquationModifierParser() { + } + + @Override + public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { + + Map> result = new HashMap<>(); + result = lineParser.parse(is, result, (v, r)->{ + final int defaultId = (int) v.get(DEFAULT_KEY); + final int itg = (int) v.get(ITG_KEY); + final int reassignedId = (int) v.get(REASSIGNED_KEY); + + + r.computeIfAbsent(defaultId, k->new HashMap<>()).put(itg, reassignedId); + return r; + }); + + for (var e : result.entrySet()) { + result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); + } + + return Collections.unmodifiableMap(result); + } + + +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index daf1bdf36..ad1fd88ad 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -27,7 +27,7 @@ 026 coe/SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 030 coe/GRPBA1.DAT Default Eq # BA=f(CC) RD_GRBA1 -031 coe/gmodba1.dat Eqn modifiers for above RD_GMBA1 +031 coe/GMODBA1.DAT Eqn modifiers for above RD_GMBA1 033 coe/fipstkr.prm Stocking class factors RD_STK33 040 coe/regba25.coe Coe BA=f(CC) RD_E040 IPSJF128 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 4da5f66e3..2af9ee3b4 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -15,6 +15,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; +import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -39,7 +40,7 @@ public class FipControlParser { public static final String SITE_CURVE_NUMBERS = "SITE_CURVE_NUMBERS"; public static final String SITE_CURVE_AGE_MAX = "SITE_CURVE_AGE_MAX"; public static final String DEFAULT_EQ_NUM = EquationGroupParser.DEFAULT_CONTROL_KEY; - public static final String EQN_MODIFIERS = "EQN_MODIFIERS"; + public static final String EQN_MODIFIERS = EquationModifierParser.CONTROL_KEY; public static final String STOCKING_CLASS_FACTORS = "STOCKING_CLASS_FACTORS"; public static final String COE_BA = "COE_BA"; public static final String COE_DQ = "COE_DQ"; @@ -220,6 +221,7 @@ public String toString(String filename) throws IOException { loadData(map, DEFAULT_EQ_NUM, fileResolver, this::RD_GRBA1); // RD_GMBA1 + loadData(map, EQN_MODIFIERS, fileResolver, this::RD_GMBA1); // TODO int jprogram = 1; // FIPSTART only TODO Track this down @@ -470,6 +472,14 @@ private Object RD_GRBA1(InputStream data, Map control) throws IO parser.setHiddenBecs(Arrays.asList("BG", "AT")); return parser.parse(data, control); } + + /** + * Loads the information that was in the global array BG1MODV in Fortran + */ + private Object RD_GMBA1(InputStream data, Map control) throws IOException, ResourceParseException { + var parser = new EquationModifierParser(); + return parser.parse(data, control); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index a392d3a09..3614e9359 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -134,4 +134,23 @@ public void testParseGRBA1() throws Exception { isA(Integer.class) // Equation Identifier )))))); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseGMBA1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.EQN_MODIFIERS), + allOf( // Default Equation + isA(Map.class), + hasEntry( + isA(Integer.class), + allOf( // ITG + isA(Map.class), + hasEntry( + isA(Integer.class), + isA(Integer.class) // Reassigned Equation + )))))); + } } From dae7cd95caa07ebb12fda497d761958e10780244 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 15 May 2023 18:04:55 -0700 Subject: [PATCH 17/98] Parse stocking factor --- .../vdyp/io/parse/BecDefinitionParser.java | 5 +- .../io/parse/StockingClassFactorParser.java | 86 +++++++++++++++++++ .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 20 +++++ .../nrs/vdyp/model/StockingClassFactor.java | 30 +++++++ .../io/parse/EquationGroupParserTest.java | 61 ++++--------- .../parse/StockingClassFactorParserTest.java | 68 +++++++++++++++ .../ca/bc/gov/nrs/vdyp/test/TestUtils.java | 11 +++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 14 ++- 8 files changed, 244 insertions(+), 51 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index d7d6aecd9..182ed0a35 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -30,10 +30,7 @@ public boolean isStopSegment(List segments) { } .strippedString(4, "alias") .space(1) - .value(1, "region", (s)->{ - return Region.fromAlias(Character.toUpperCase(s.charAt(0))) - .orElseThrow(()->new ValueParseException(s, s+" is not a valid region identifier")); - }) + .value(1, "region", ValueParser.REGION) .space(1) .strippedString("name"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java new file mode 100644 index 000000000..467b6b9d9 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java @@ -0,0 +1,86 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.StockingClassFactor; + +/** + * Parser for an stcking class factor data file + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class StockingClassFactorParser implements ResourceParser>>{ + + public static final String CONTROL_KEY = "STOCKING_CLASS_FACTORS"; + + private static final String STK_KEY = "stk"; + private static final String REGION_KEY = "region"; + private static final String LAYER_KEY = "layer"; + private static final String ITG_KEY = "itg"; + private static final String FACTOR_KEY = "factor"; + private static final String NPCT_KEY = "npct"; + + LineParser lineParser = new LineParser(){ + + @Override + public boolean isIgnoredLine(String line) { + return line.isBlank(); + } + + @Override + public boolean isIgnoredSegment(List segments) { + return segments.get(0).isBlank(); + } + + @Override + public boolean isStopSegment(List segments) { + return "Z".equalsIgnoreCase(segments.get(0)); + } + } + .value(1, STK_KEY, ValueParser.CHARACTER) + .space(1) + .value(1, REGION_KEY, ValueParser.REGION) + .space(1) + .value(1, LAYER_KEY, ValueParser.CHARACTER) + .integer(3, ITG_KEY) + .floating(6, FACTOR_KEY) + .integer(5, NPCT_KEY); + + public StockingClassFactorParser() { + } + + @Override + public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { + + Map> result = new HashMap<>(); + result = lineParser.parse(is, result, (v, r)->{ + char stk = (char) v.get(STK_KEY); + Region region = (Region) v.get(REGION_KEY); + float factor = (float) v.get(FACTOR_KEY); + int npctArea = (int) v.get(NPCT_KEY); + + // Fortran was ignoring Layer and ITG + + var factorEntry = new StockingClassFactor(stk, region, factor, npctArea); + + r.computeIfAbsent(stk, (c)->new HashMap()).put(region, factorEntry); + + return r; + }); + + for (var e : result.entrySet()) { + result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); + } + + return Collections.unmodifiableMap(result); + } + + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 0d0603554..e21ee29f6 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -6,6 +6,8 @@ import java.util.Optional; import java.util.function.Function; +import ca.bc.gov.nrs.vdyp.model.Region; + /** * Parses a string to a value * @author Kevin Smith, Vivid Solutions @@ -67,6 +69,24 @@ public static ValueParser numberParser(JavaNumberParser */ public static final ValueParser FLOAT = numberParser(Float::parseFloat, Float.class); + /** + * Parser for Characters + */ + public static final ValueParser CHARACTER = s->{ + if(s.isBlank()) { + throw new ValueParseException("Character is blank"); + } + return s.charAt(0); + }; + + + /** + * Parser for a region identifier + */ + public static final ValueParser REGION = (s)-> + Region.fromAlias(Character.toUpperCase(s.charAt(0))) + .orElseThrow(()->new ValueParseException(s, s+" is not a valid region identifier")); + public static ValueParser> list(ValueParser delegate) { return s-> { var elementStrings = s.strip().split("\s+"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java new file mode 100644 index 000000000..d16645ce7 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java @@ -0,0 +1,30 @@ +package ca.bc.gov.nrs.vdyp.model; + +public class StockingClassFactor { + + private final Character stk; + private final Region region; + private final float factor; + private final int npctArea; + + public StockingClassFactor(Character stk, Region region, float factor, int npctArea) { + super(); + this.stk = stk; + this.region = region; + this.factor = factor; + this.npctArea = npctArea; + } + public Character getStk() { + return stk; + } + public Region getRegion() { + return region; + } + public float getFactor() { + return factor; + } + public int getNpctArea() { + return npctArea; + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index 99233228f..197534093 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -26,6 +26,7 @@ import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.test.TestUtils; import ca.bc.gov.nrs.vdyp.test.VdypMatchers; @SuppressWarnings("unused") @@ -36,8 +37,9 @@ public void testParse() throws Exception { var parser = new EquationGroupParser(); var controlMap = makeControlMapSingle(); + String[] lines = { "S1 B1 001" }; - var is = makeStream("S1 B1 001"); + var is = TestUtils.makeStream(lines); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(1)))); @@ -48,8 +50,9 @@ public void testSP0MustExist() throws Exception { var parser = new EquationGroupParser(); var controlMap = makeControlMapSingle(); + String[] lines = { "SX B1 001" }; - var is = makeStream("SX B1 001"); + var is = TestUtils.makeStream(lines); ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); @@ -63,8 +66,9 @@ public void testBecMustExist() throws Exception { var parser = new EquationGroupParser(); var controlMap = makeControlMapSingle(); + String[] lines = { "S1 BX 001" }; - var is = makeStream("S1 BX 001"); + var is = TestUtils.makeStream(lines); ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); @@ -80,8 +84,9 @@ public void testParseOvewrite() throws Exception { var parser = new EquationGroupParser(); var controlMap = makeControlMapSingle(); + String[] lines = { "S1 B1 001", "S1 B1 002" }; - var is = makeStream("S1 B1 001", "S1 B1 002"); + var is = TestUtils.makeStream(lines); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(2)))); @@ -92,16 +97,9 @@ public void testParseMultiple() throws Exception { var parser = new EquationGroupParser(); var controlMap = makeControlMap(); + String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B3 013", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", "S2 B4 024" }; - var is = makeStream( - "S1 B1 011", - "S1 B2 012", - "S1 B3 013", - "S1 B4 014", - "S2 B1 021", - "S2 B2 022", - "S2 B3 023", - "S2 B4 024"); + var is = TestUtils.makeStream(lines); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(11)))); @@ -122,17 +120,9 @@ public void testRequireNoMissingSp0() throws Exception { var controlMap = makeControlMap(); List unusedBecs= Arrays.asList("B2", "B4"); + String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B3 013", "S1 B4 014" }; - var is = makeStream( - "S1 B1 011", - "S1 B2 012", - "S1 B3 013", - "S1 B4 014" - //"S2 B1 021", // Missing - //"S2 B2 022", - //"S2 B3 023", - //"S2 B4 024" - ); + var is = TestUtils.makeStream(lines); ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); @@ -148,16 +138,9 @@ public void testRequireNoMissingBec() throws Exception { var controlMap = makeControlMap(); List unusedBecs= Arrays.asList("B2", "B4"); + String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", "S2 B4 024" }; - var is = makeStream( - "S1 B1 011", - "S1 B2 012", - // "S1 B3 013", // Missing - "S1 B4 014", - "S2 B1 021", - "S2 B2 022", - "S2 B3 023", - "S2 B4 024"); + var is = TestUtils.makeStream(lines); ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); @@ -174,15 +157,9 @@ public void testRequireNoUnexpectedBec() throws Exception { List hiddenBecs= Arrays.asList("B3"); parser.setHiddenBecs(hiddenBecs); + String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", "S2 B4 024" }; - var is = makeStream( - "S1 B1 011", - "S1 B2 012", - "S1 B4 014", - "S2 B1 021", - "S2 B2 022", - "S2 B3 023", // Unexpected - "S2 B4 024"); + var is = TestUtils.makeStream(lines); ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); @@ -223,8 +200,4 @@ private HashMap makeControlMap() { controlMap.put(SP0DefinitionParser.CONTROL_KEY, Collections.unmodifiableList(sp0List)); return controlMap; } - - private InputStream makeStream(String...lines) { - return new ByteArrayInputStream(String.join("\r\n", lines).getBytes()); - } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java new file mode 100644 index 000000000..62db9ebfd --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java @@ -0,0 +1,68 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.anEmptyMap; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; + +import java.util.Collections; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class StockingClassFactorParserTest { + + @Test + public void testEmpty() throws Exception { + var parser = new StockingClassFactorParser(); + var is = TestUtils.makeStream(""); + + var result = parser.parse(is, Collections.emptyMap()); + + assertThat(result, anEmptyMap()); + } + + @Test + public void testSimple() throws Exception { + var parser = new StockingClassFactorParser(); + var is = TestUtils.makeStream("R I P 0 1.00 100", "Z Z P 0 1.00 100"); + + var result = parser.parse(is, Collections.emptyMap()); + + assertThat(result, + hasEntry(is('R') + , hasEntry(is(Region.INTERIOR), + allOf(hasProperty("factor", is(1.0f)), + allOf(hasProperty("npctArea", is(100))))))); + } + + @Test + public void testMultiple() throws Exception { + var parser = new StockingClassFactorParser(); + try(var is = StockingClassFactorParserTest.class.getResourceAsStream("coe/FIPSTKR.PRM")) { + + var result = parser.parse(is, Collections.emptyMap()); + + assertThat(result, + hasEntry(is('R') + , hasEntry(is(Region.INTERIOR), + allOf(hasProperty("factor", is(1.0f)), + allOf(hasProperty("npctArea", is(100))))))); + assertThat(result, + hasEntry(is('R') + , hasEntry(is(Region.COASTAL), + allOf(hasProperty("factor", is(1.0f)), + allOf(hasProperty("npctArea", is(100))))))); + assertThat(result, + hasEntry(is('4') + , hasEntry(is(Region.COASTAL), + allOf(hasProperty("factor", is(1.0f)), + allOf(hasProperty("npctArea", is(100))))))); + } + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java new file mode 100644 index 000000000..ea7785a58 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java @@ -0,0 +1,11 @@ +package ca.bc.gov.nrs.vdyp.test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +public class TestUtils { + + public static InputStream makeStream(String...lines) { + return new ByteArrayInputStream(String.join("\r\n", lines).getBytes()); + } +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 2af9ee3b4..d2a11f286 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -13,6 +13,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.StockingClassFactorParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; @@ -41,7 +42,7 @@ public class FipControlParser { public static final String SITE_CURVE_AGE_MAX = "SITE_CURVE_AGE_MAX"; public static final String DEFAULT_EQ_NUM = EquationGroupParser.DEFAULT_CONTROL_KEY; public static final String EQN_MODIFIERS = EquationModifierParser.CONTROL_KEY; - public static final String STOCKING_CLASS_FACTORS = "STOCKING_CLASS_FACTORS"; + public static final String STOCKING_CLASS_FACTORS = StockingClassFactorParser.CONTROL_KEY; public static final String COE_BA = "COE_BA"; public static final String COE_DQ = "COE_DQ"; public static final String UPPER_BA_BY_CI_S0_P = "UPPER_BA_BY_CI_S0_P"; @@ -222,12 +223,11 @@ public String toString(String filename) throws IOException { // RD_GMBA1 loadData(map, EQN_MODIFIERS, fileResolver, this::RD_GMBA1); - // TODO int jprogram = 1; // FIPSTART only TODO Track this down if(jprogram==1) { // RD_STK33 - // TODO + loadData(map, STOCKING_CLASS_FACTORS, fileResolver, this::RD_STK33); // TODO minima? /* @@ -480,6 +480,14 @@ private Object RD_GMBA1(InputStream data, Map control) throws IO var parser = new EquationModifierParser(); return parser.parse(data, control); } + + /** + * Loads the information that was in the global arrays STKV, FACTV, and NPCTAREA in Fortran + */ + private Object RD_STK33(InputStream data, Map control) throws IOException, ResourceParseException { + var parser = new StockingClassFactorParser(); + return parser.parse(data, control); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; From 34f165fdb5eca6b99575ad193260c4605874633a Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 16 May 2023 16:26:45 -0700 Subject: [PATCH 18/98] Site Curve parsing and ran formatter --- .../vdyp/common/ExpectationDifference.java | 11 +- .../vdyp/io/parse/BecDefinitionParser.java | 26 +- .../nrs/vdyp/io/parse/ControlFileParser.java | 104 +++-- .../nrs/vdyp/io/parse/ControlFileWriter.java | 57 +-- .../vdyp/io/parse/EquationGroupParser.java | 102 ++--- .../vdyp/io/parse/EquationModifierParser.java | 32 +- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 189 +++++---- .../nrs/vdyp/io/parse/ParseEntryHandler.java | 5 +- .../io/parse/ResourceParseLineException.java | 14 +- .../io/parse/ResourceParseValidException.java | 5 +- .../gov/nrs/vdyp/io/parse/ResourceParser.java | 53 ++- .../vdyp/io/parse/SP0DefinitionParser.java | 65 +-- .../nrs/vdyp/io/parse/SiteCurveParser.java | 59 +++ .../io/parse/StockingClassFactorParser.java | 48 +-- .../vdyp/io/parse/ValueParseException.java | 12 +- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 72 ++-- .../vdyp/model/AbstractSpeciesDefinition.java | 8 +- .../bc/gov/nrs/vdyp/model/BecDefinition.java | 6 +- .../java/ca/bc/gov/nrs/vdyp/model/Region.java | 11 +- .../bc/gov/nrs/vdyp/model/SP0Definition.java | 8 +- .../ca/bc/gov/nrs/vdyp/model/SiteCurve.java | 21 + .../nrs/vdyp/model/StockingClassFactor.java | 10 +- .../io/parse/BecDefinitionParserTest.java | 218 ++++++---- .../vdyp/io/parse/ControlFileParserTest.java | 137 +++---- .../vdyp/io/parse/ControlFileWriterTest.java | 206 +++++----- .../io/parse/EquationGroupParserTest.java | 143 ++++--- .../gov/nrs/vdyp/io/parse/LineParserTest.java | 383 +++++++----------- .../io/parse/SP0DefinitionParserTest.java | 301 +++++++------- .../vdyp/io/parse/SiteCurveParserTest.java | 129 ++++++ .../parse/StockingClassFactorParserTest.java | 78 ++-- .../ca/bc/gov/nrs/vdyp/test/TestUtils.java | 4 +- .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 105 ++++- .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 4 +- .../ca/bc/gov/nrs/vdyp/io/parse/coe/SIEQN.PRM | 24 ++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 38 +- .../nrs/vdyp/fip/FipControlParserTest.java | 52 +++ 36 files changed, 1646 insertions(+), 1094 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurve.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java index b09a371ba..2dc7a31ae 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ExpectationDifference.java @@ -6,7 +6,7 @@ /** * The difference between a set of values and what they are expaected to be - * + * * @author Kevin Smith, Vivid Solutions * * @param @@ -14,7 +14,7 @@ public class ExpectationDifference { final Set missing; final Set unexpected; - + public ExpectationDifference(Set missing, Set unexpected) { super(); this.missing = missing; @@ -23,6 +23,7 @@ public ExpectationDifference(Set missing, Set unexpected) { /** * Find the missing and expected values in a collections of values. + * * @param * @param values * @param expected @@ -38,6 +39,7 @@ public static ExpectationDifference difference(Collection values, Coll /** * Which values are missing + * * @return */ public Set getMissing() { @@ -46,18 +48,19 @@ public Set getMissing() { /** * Which values were unexpected + * * @return */ public Set getUnexpected() { return unexpected; } - + /** * Were the values as expected + * * @return */ public boolean isSame() { return getMissing().isEmpty() && getUnexpected().isEmpty(); } } - diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index 182ed0a35..d5dbc08d0 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -12,12 +12,12 @@ /** * Parser for a BEC Definition data file - * + * * @author Kevin Smith, Vivid Solutions * */ -public class BecDefinitionParser implements ResourceParser>{ - +public class BecDefinitionParser implements ResourceParser> { + public static final String CONTROL_KEY = "BEC_DEF"; LineParser lineParser = new LineParser() { @@ -26,18 +26,14 @@ public class BecDefinitionParser implements ResourceParser segments) { return "Z".equalsIgnoreCase(segments.get(2)); } - - } - .strippedString(4, "alias") - .space(1) - .value(1, "region", ValueParser.REGION) - .space(1) - .strippedString("name"); - + + }.strippedString(4, "alias").space(1).value(1, "region", ValueParser.REGION).space(1).strippedString("name"); + @Override - public Map parse(InputStream is, Map control) throws IOException, ResourceParseException { + public Map parse(InputStream is, Map control) + throws IOException, ResourceParseException { Map result = new HashMap<>(); - result = lineParser.parse(is, result, (v, r)->{ + result = lineParser.parse(is, result, (v, r) -> { String alias = (String) v.get("alias"); Region region = (Region) v.get("region"); String name = (String) v.get("name"); @@ -45,8 +41,8 @@ public Map parse(InputStream is, Map cont r.put(alias, defn); return r; }); - + return Collections.unmodifiableMap(result); } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index 44557d5d1..0b89c484e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -5,12 +5,15 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; /** * Parser for control files - * + * * @author Kevin Smith, Vivid Solutions * */ @@ -20,7 +23,7 @@ public class ControlFileParser implements ResourceParser> { public static final int EXTEND_LENGTH = 1; public static final int CONTROL_LENGTH_EXTENDED = 120; public static final int CONTROL_LENGTH = 50; - + public static final List EXTEND_FLAGS = Arrays.asList("X", ">"); public static final List COMMENT_FLAGS = Arrays.asList("C"); public static final String COMMENT_MARKER = "!"; @@ -28,26 +31,26 @@ public class ControlFileParser implements ResourceParser> { private Map identifiers; private Map> valueParsers; private ValueParser defaultValueParser; - + private Map> defaultValueGenerators; + LineParser lineParser = new LineParser() { @Override public boolean isIgnoredLine(String line) { return line.isBlank(); } + @Override public boolean isIgnoredSegment(List segments) { return segments.get(0).isBlank(); } + @Override public boolean isIgnoredEntry(Map segments) { - return 0==(Integer)segments.get("index") || COMMENT_FLAGS.contains(segments.get("extend")); + return 0 == (Integer) segments.get("index") || COMMENT_FLAGS.contains(segments.get("extend")); } - - } - .integer(3, "index") - .string(1, "extend") - .string("restOfLine"); + + }.integer(3, "index").string(1, "extend").string("restOfLine"); /** * Create a control file parser. @@ -56,41 +59,46 @@ public ControlFileParser() { this.identifiers = new HashMap<>(); this.valueParsers = new HashMap<>(); this.defaultValueParser = String::strip; + this.defaultValueGenerators = new LinkedHashMap<>(); } - @Override - public Map parse(InputStream input, Map control) throws IOException, ResourceParseException { + public Map parse(InputStream input, Map control) + throws IOException, ResourceParseException { Map result = new HashMap<>(); - return lineParser.parse(input, result, (map,r)->{ + result = lineParser.parse(input, result, (map, r) -> { Integer index = (Integer) map.get("index"); String extend = (String) map.get("extend"); String restOfLine = (String) map.get("restOfLine"); - + // How long is the control value - int controlLength = Math.min( - EXTEND_FLAGS.contains(extend) ? - CONTROL_LENGTH_EXTENDED : - CONTROL_LENGTH, - restOfLine.length( )); - + int controlLength = Math + .min(EXTEND_FLAGS.contains(extend) ? CONTROL_LENGTH_EXTENDED : CONTROL_LENGTH, restOfLine.length()); + // Trim inline comments int commentMarkerPosition = restOfLine.indexOf(COMMENT_MARKER); - if(commentMarkerPosition>=0) { + if (commentMarkerPosition >= 0) { controlLength = Math.min(controlLength, commentMarkerPosition); } - + // Find the string representation of the value of the control - String controlString = restOfLine - .substring(0, controlLength); - - String key = identifiers.getOrDefault(index, String.format("%03d", index)); + String controlString = restOfLine.substring(0, controlLength); + + String key = getKeyForIndex(index); Object value = valueParsers.getOrDefault(index, defaultValueParser).parse(controlString); - - result.put(key, value); - - return result; + + r.put(key, value); + + return r; }); + for (var e : defaultValueGenerators.entrySet()) { + result.putIfAbsent(e.getKey(), e.getValue().get()); + } + return result; + } + + private String getKeyForIndex(Integer index) { + return identifiers.getOrDefault(index, String.format("%03d", index)); } /** @@ -99,9 +107,10 @@ public Map parse(InputStream input, Map control) public void setDefaultValueParser(ValueParser defaultParser) { this.defaultValueParser = defaultParser; } - + /** * Remap a record index with a meaningful name and parse its value + * * @param index * @param name * @param parser @@ -112,9 +121,25 @@ public ControlFileParser record(int index, String name, ValueParser parser) { record(index, parser); return this; } - + + /** + * Remap a record index with a meaningful name and parse its value as an + * optional + * + * @param index + * @param name + * @param parser + * @return + */ + public ControlFileParser optional(int index, String name, ValueParser parser) { + record(index, name); + optional(index, parser); + return this; + } + /** * Remap a record index with a meaningful name + * * @param index * @param name * @param parser @@ -124,9 +149,10 @@ public ControlFileParser record(int index, String name) { this.identifiers.put(index, name); return this; } - + /** * Parse the value of records with the given index + * * @param index * @param name * @param parser @@ -137,8 +163,22 @@ public ControlFileParser record(int index, ValueParser parser) { return this; } + /** + * Parse the value of records with the given index as an optional + * + * @param index + * @param name + * @param parser + * @return + */ + public ControlFileParser optional(int index, ValueParser parser) { + record(index, ValueParser.optional(parser)); + this.defaultValueGenerators.put(getKeyForIndex(index), Optional::empty); + return this; + } public Map parse(InputStream is) throws IOException, ResourceParseException { return this.parse(is, Collections.emptyMap()); } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java index f6b59b0a6..82979cff6 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java @@ -9,19 +9,19 @@ /** * Writer for control files - * + * * @author Kevin Smith, Vivid Solutions * */ public class ControlFileWriter implements Closeable { private final OutputStream os; - + static final Charset CHARSET = StandardCharsets.US_ASCII; public static final String NEW_LINE = "\r\n"; // Always use Window line separator to write public static final Pattern NEW_LINE_PATTERN = Pattern.compile("[\r\n]"); - public static final String NORMAL_FORMAT = "%03d %-50s%s"+NEW_LINE; - public static final String EXTENDED_FORMAT = "%03dX%-120s%s"+NEW_LINE; - public static final String COMMENT_FORMAT = " %s"+NEW_LINE; + public static final String NORMAL_FORMAT = "%03d %-50s%s" + NEW_LINE; + public static final String EXTENDED_FORMAT = "%03dX%-120s%s" + NEW_LINE; + public static final String COMMENT_FORMAT = " %s" + NEW_LINE; public ControlFileWriter(OutputStream os) { super(); @@ -30,27 +30,32 @@ public ControlFileWriter(OutputStream os) { /** * Write an entry for a control file - * - * @param index Control file index (1 to 200 inclusive) - * @param control Value of the control (Max 120 characters, May not contain '!' or newlines) + * + * @param index Control file index (1 to 200 inclusive) + * @param control Value of the control (Max 120 characters, May not contain '!' + * or newlines) * @param comment A human readable comment (May not contain newlines) * @throws IOException * @throws IllegalArgumentException */ public void writeEntry(int index, String control, String comment) throws IOException { - if (index<1) { - throw new IllegalArgumentException("Control file index "+index+" is less than 1"); + if (index < 1) { + throw new IllegalArgumentException("Control file index " + index + " is less than 1"); } - if (index>200) { - throw new IllegalArgumentException("Control file index "+index+" is greater than 200"); + if (index > 200) { + throw new IllegalArgumentException("Control file index " + index + " is greater than 200"); } // There's no mechanism for extending past 120 so simply disallow this - if (control.length()>ControlFileParser.CONTROL_LENGTH_EXTENDED) { - throw new IllegalArgumentException("Control file value is longer than "+ControlFileParser.CONTROL_LENGTH_EXTENDED); + if (control.length() > ControlFileParser.CONTROL_LENGTH_EXTENDED) { + throw new IllegalArgumentException( + "Control file value is longer than " + ControlFileParser.CONTROL_LENGTH_EXTENDED + ); } // There's no mechanism for escaping so simply disallow this. if (control.contains(ControlFileParser.COMMENT_MARKER)) { - throw new IllegalArgumentException("Control file value contains a comment marker ("+ControlFileParser.COMMENT_MARKER+")"); + throw new IllegalArgumentException( + "Control file value contains a comment marker (" + ControlFileParser.COMMENT_MARKER + ")" + ); } // There's no mechanism for escaping so simply disallow this. if (NEW_LINE_PATTERN.matcher(control).find()) { @@ -60,26 +65,28 @@ public void writeEntry(int index, String control, String comment) throws IOExcep if (NEW_LINE_PATTERN.matcher(comment).find()) { throw new IllegalArgumentException("Control file comment contains a line break"); } - - String format = control.length()>ControlFileParser.CONTROL_LENGTH ? EXTENDED_FORMAT : NORMAL_FORMAT; - + + String format = control.length() > ControlFileParser.CONTROL_LENGTH ? EXTENDED_FORMAT : NORMAL_FORMAT; + os.write(String.format(format, index, control, comment).getBytes(CHARSET)); } - + /** * Write an entry for a control file - * - * @param index Control file index (1 to 200 inclusive) - * @param control Value of the control (Max 120 characters, May not contain '!' or newlines) + * + * @param index Control file index (1 to 200 inclusive) + * @param control Value of the control (Max 120 characters, May not contain '!' + * or newlines) * @throws IOException * @throws IllegalArgumentException */ public void writeEntry(int index, String control) throws IOException { writeEntry(index, control, ""); } - + /** * Write a comment line for a control file + * * @param comment A human readable comment (May not contain newlines) * @throws IOException * @throws IllegalArgumentException @@ -89,10 +96,10 @@ public void writeComment(String comment) throws IOException { if (NEW_LINE_PATTERN.matcher(comment).find()) { throw new IllegalArgumentException("Control file comment contains a line break"); } - + os.write(String.format(COMMENT_FORMAT, comment).getBytes(CHARSET)); } - + @Override public void close() throws IOException { os.close(); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index 8c4025256..47f950943 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -16,12 +16,12 @@ /** * Parser for a Volume Equation Group data file - * + * * @author Kevin Smith, Vivid Solutions * */ -public class EquationGroupParser implements ResourceParser>>{ - +public class EquationGroupParser implements ResourceParser>> { + public static final String VOLUME_CONTROL_KEY = "VOLUME_EQN_GROUPS"; public static final String DECAY_CONTROL_KEY = "DECAY_GROUPS"; @@ -29,76 +29,85 @@ public class EquationGroupParser implements ResourceParser hiddenBecs = Collections.emptyList(); - + public EquationGroupParser() { this(3); } - + public EquationGroupParser(int identifierLength) { - lineParser = new LineParser() - .strippedString(2, "sp0Alias") - .space(1) - .strippedString(4, "becAlias") - .space(1) - .integer(identifierLength,"grpId"); + lineParser = new LineParser().strippedString(2, "sp0Alias").space(1).strippedString(4, "becAlias").space(1) + .integer(identifierLength, "grpId"); } @Override - public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { - + public Map> parse(InputStream is, Map control) + throws IOException, ResourceParseException { + @SuppressWarnings("unchecked") - List sp0List = ResourceParser.expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class); + List sp0List = ResourceParser + .expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class); @SuppressWarnings("unchecked") - Map becMap = ResourceParser.expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class); - + Map becMap = ResourceParser + .expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class); + Map> result = new HashMap<>(); - result = lineParser.parse(is, result, (v, r)->{ + result = lineParser.parse(is, result, (v, r) -> { final String sp0Alias = (String) v.get("sp0Alias"); final String becAlias = (String) v.get("becAlias"); - - if(!sp0List.stream().anyMatch(def->def.getAlias().equalsIgnoreCase(sp0Alias))) { - throw new ValueParseException(sp0Alias, sp0Alias+" is not an SP0 identifier"); + + if (!sp0List.stream().anyMatch(def -> def.getAlias().equalsIgnoreCase(sp0Alias))) { + throw new ValueParseException(sp0Alias, sp0Alias + " is not an SP0 identifier"); } - if(!becMap.containsKey(becAlias)) { - throw new ValueParseException(becAlias, becAlias+" is not a BEC identifier"); + if (!becMap.containsKey(becAlias)) { + throw new ValueParseException(becAlias, becAlias + " is not a BEC identifier"); } - + int vgrpId = (Integer) v.get("grpId"); - - r.computeIfAbsent(sp0Alias, k->new HashMap<>()).put(becAlias, vgrpId); + + r.computeIfAbsent(sp0Alias, k -> new HashMap<>()).put(becAlias, vgrpId); return r; }); - + for (var e : result.entrySet()) { result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); } - - // Validate that the cartesian product of SP0 and BEC values has been provided, excluding unused BECs. - // The original fortran did a check that the number of values read matched a hard coded number. - + + // Validate that the cartesian product of SP0 and BEC values has been provided, + // excluding unused BECs. + // The original fortran did a check that the number of values read matched a + // hard coded number. + List errors = new ArrayList<>(); - - var sp0Keys = sp0List.stream().map(def->def.getAlias()).collect(Collectors.toSet()); - var becKeys = becMap.keySet().stream().filter(k->!hiddenBecs.contains(k)).collect(Collectors.toSet()); - + + var sp0Keys = sp0List.stream().map(def -> def.getAlias()).collect(Collectors.toSet()); + var becKeys = becMap.keySet().stream().filter(k -> !hiddenBecs.contains(k)).collect(Collectors.toSet()); + var sp0Diff = ExpectationDifference.difference(result.keySet(), sp0Keys); - - sp0Diff.getMissing().stream().map(sp0Key->String.format("Expected mappings for SP0 %s but it was missing", sp0Key)).collect(Collectors.toCollection(()->errors)); - sp0Diff.getUnexpected().stream().map(sp0Key->String.format("Unexpected mapping for SP0 %s", sp0Key)).collect(Collectors.toCollection(()->errors)); - - for(var entry : result.entrySet()) { + + sp0Diff.getMissing().stream() + .map(sp0Key -> String.format("Expected mappings for SP0 %s but it was missing", sp0Key)) + .collect(Collectors.toCollection(() -> errors)); + sp0Diff.getUnexpected().stream().map(sp0Key -> String.format("Unexpected mapping for SP0 %s", sp0Key)) + .collect(Collectors.toCollection(() -> errors)); + + for (var entry : result.entrySet()) { var becDiff = ExpectationDifference.difference(entry.getValue().keySet(), becKeys); - var sp0Key = entry.getKey(); - becDiff.getMissing().stream().map(becKey->String.format("Expected mappings for BEC %s but it was missing for SP0 %s", becKey, sp0Key)).collect(Collectors.toCollection(()->errors)); - becDiff.getUnexpected().stream().map(becKey->String.format("Unexpected mapping for BEC %s under SP0 %s", becKey, sp0Key)).collect(Collectors.toCollection(()->errors)); + var sp0Key = entry.getKey(); + becDiff.getMissing().stream().map( + becKey -> String + .format("Expected mappings for BEC %s but it was missing for SP0 %s", becKey, sp0Key) + ).collect(Collectors.toCollection(() -> errors)); + becDiff.getUnexpected().stream() + .map(becKey -> String.format("Unexpected mapping for BEC %s under SP0 %s", becKey, sp0Key)) + .collect(Collectors.toCollection(() -> errors)); } - - if(!errors.isEmpty()) { - throw new ResourceParseValidException (String.join(System.lineSeparator(), errors)); + + if (!errors.isEmpty()) { + throw new ResourceParseValidException(String.join(System.lineSeparator(), errors)); } return Collections.unmodifiableMap(result); @@ -107,6 +116,5 @@ public Map> parse(InputStream is, Map hiddenBecs) { this.hiddenBecs = hiddenBecs; } - } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java index 579a7ee68..003ceb4be 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java @@ -8,46 +8,42 @@ /** * Parser for an equation modifier mapping data file - * + * * @author Kevin Smith, Vivid Solutions * */ -public class EquationModifierParser implements ResourceParser>>{ - +public class EquationModifierParser implements ResourceParser>> { + public static final String CONTROL_KEY = "EQN_MODIFIERS"; - + private static final String DEFAULT_KEY = "default"; private static final String ITG_KEY = "itg"; private static final String REASSIGNED_KEY = "reassigned"; - LineParser lineParser = new LineParser() - .integer(3, DEFAULT_KEY) - .integer(4, ITG_KEY) - .integer(4, REASSIGNED_KEY); - + LineParser lineParser = new LineParser().integer(3, DEFAULT_KEY).integer(4, ITG_KEY).integer(4, REASSIGNED_KEY); + public EquationModifierParser() { } @Override - public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { - + public Map> parse(InputStream is, Map control) + throws IOException, ResourceParseException { + Map> result = new HashMap<>(); - result = lineParser.parse(is, result, (v, r)->{ + result = lineParser.parse(is, result, (v, r) -> { final int defaultId = (int) v.get(DEFAULT_KEY); final int itg = (int) v.get(ITG_KEY); final int reassignedId = (int) v.get(REASSIGNED_KEY); - - - r.computeIfAbsent(defaultId, k->new HashMap<>()).put(itg, reassignedId); + + r.computeIfAbsent(defaultId, k -> new HashMap<>()).put(itg, reassignedId); return r; }); - + for (var e : result.entrySet()) { result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); } - + return Collections.unmodifiableMap(result); } - } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index fa744b140..f8a69f6ac 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -13,23 +13,23 @@ /** * Parse a file with records consisting of lines with fixed width fields. - * + * * @author Kevin Smith, Vivid Solutions * */ public class LineParser { - + private List segments = new ArrayList<>(); public static final Charset charset = StandardCharsets.US_ASCII; public static final String LINE_NUMBER_KEY = "_PARSER_LINE_NUMBER"; - + static private abstract class LineParserSegment { int length; - + public int getLength() { return length; } - + public LineParserSegment(int length) { super(); this.length = length; @@ -37,9 +37,9 @@ public LineParserSegment(int length) { public abstract void parseIntoMap(String toParse, Map map) throws ValueParseException; } - + static private class LineParserNullSegment extends LineParserSegment { - + public LineParserNullSegment(int length) { super(length); } @@ -49,16 +49,17 @@ public void parseIntoMap(String toParse, Map map) { // do nothing } } - - static abstract class LineParserValueSegment extends LineParserSegment { + + static abstract class LineParserValueSegment extends LineParserSegment { String name; + abstract T parse(String value) throws ValueParseException; - + public String getName() { return name; } - - @Override + + @Override public void parseIntoMap(String toParse, Map map) throws ValueParseException { var value = this.parse(toParse); map.put(this.getName(), value); @@ -69,9 +70,10 @@ public LineParserValueSegment(int length, String name) { this.name = name; } } - + /** * ignore a segment of characters + * * @param length * @return */ @@ -79,44 +81,45 @@ public LineParser space(int length) { segments.add(new LineParserNullSegment(length)); return this; } - + /** * A decimal integer segment */ public LineParser integer(int length, String name) { return this.value(length, name, ValueParser.INTEGER); } - + /** * A floating point segment */ public LineParser floating(int length, String name) { return this.value(length, name, ValueParser.FLOAT); } - + /** * A string segment */ public LineParser string(int length, String name) { - return this.value(length, name, s->s); + return this.value(length, name, s -> s); } - + /** - * A string segment with no bounds. No further segments may be added. + * A string segment with no bounds. No further segments may be added. */ public LineParser string(String name) { - return this.value(name, s->s); + return this.value(name, s -> s); } - + /** * A string segment stripped of leading and trailing whitespace. */ public LineParser strippedString(int length, String name) { return this.value(length, name, String::strip); } - + /** - * A string segment stripped of leading and trailing whitespace with no bounds. No further segments may be added. + * A string segment stripped of leading and trailing whitespace with no bounds. + * No further segments may be added. */ public LineParser strippedString(String name) { return this.value(name, String::strip); @@ -124,128 +127,138 @@ public LineParser strippedString(String name) { /** * Add a segment - * @param type the segment will be parsed too + * + * @param type the segment will be parsed too * @param length length of the segment - * @param name name of the segment + * @param name name of the segment * @param parser parser to convert the string */ public LineParser value(int length, String name, ValueParser parser) { - if (length<0) throw new IllegalArgumentException("length can not be negative"); + if (length < 0) + throw new IllegalArgumentException("length can not be negative"); return doValue(length, name, parser); } - + /** * Add an unbounded segment. No further segments may be added. - * @param type the segment will be parsed too + * + * @param type the segment will be parsed too * @param length length of the segment - * @param name name of the segment + * @param name name of the segment * @param parser parser to convert the string */ public LineParser value(String name, ValueParser parser) { - return doValue(-1, name, parser); + return doValue(-1, name, parser); } - + private LineParser doValue(int length, String name, ValueParser parser) { - if (segments.size()>0 && segments.get(segments.size()-1).length<0) + if (segments.size() > 0 && segments.get(segments.size() - 1).length < 0) throw new IllegalStateException("Can not add a segment after an unbounded segment"); segments.add(new LineParserValueSegment(length, name) { - + @Override T parse(String value) throws ValueParseException { return parser.parse(value); } - + }); return this; } private List segmentize(String line) { List result = new ArrayList<>(segments.size()); - + int i = 0; - for(var segment: segments) { - if(i>=line.length()) { + for (var segment : segments) { + if (i >= line.length()) { result.add(null); continue; - }; + } + ; String segmentString; - if(segment.getLength()>=0 && i+segment.getLength()= 0 && i + segment.getLength() < line.length()) { + segmentString = line.substring(i, i + segment.length); } else { segmentString = line.substring(i); } - i+=segmentString.length(); + i += segmentString.length(); result.add(segmentString); } - + return result; } - + /** * Parse an individual line + * * @param line * @return * @throws ValueParseException */ - public Map parseLine(String line) throws ValueParseException { + public Map parseLine(String line) throws ValueParseException { var segments = segmentize(line); return parse(segments); } - private Map parse(List segmentStrings) throws ValueParseException { - if(segmentStrings.size() != segments.size()) { + private Map parse(List segmentStrings) throws ValueParseException { + if (segmentStrings.size() != segments.size()) { throw new IllegalStateException("segment strings and segment handlers must have the same size"); } - + var result = new HashMap(); - - for(int i=0; i Type of the resulting object - * @param is Input stream to parse - * @param result Starting state for the resulting object - * @param addToResult Add a record from the file to the result object and return it + * + * @param Type of the resulting object + * @param is Input stream to parse + * @param result Starting state for the resulting object + * @param addToResult Add a record from the file to the result object and return + * it * @return The result object after parsing - * @throws IOException if an error occurs while reading from the stream - * @throws ResourceParseLineException if the content of the stream could not be parsed + * @throws IOException if an error occurs while reading from the + * stream + * @throws ResourceParseLineException if the content of the stream could not be + * parsed */ - public T parse(InputStream is, T result, ParseEntryHandler, T> addToResult) throws IOException, ResourceParseLineException { + public T parse(InputStream is, T result, ParseEntryHandler, T> addToResult) + throws IOException, ResourceParseLineException { var reader = new BufferedReader(new InputStreamReader(is, charset)); String line; int lineNumber = 0; - while((line = reader.readLine())!=null) { + while ( (line = reader.readLine()) != null) { lineNumber++; try { - if(isStopLine(line)) { + if (isStopLine(line)) { break; } - if(isIgnoredLine(line)) { + if (isIgnoredLine(line)) { continue; } var segments = segmentize(line); - if(isStopSegment(segments)) { + if (isStopSegment(segments)) { break; } - if(isIgnoredSegment(segments)) { + if (isIgnoredSegment(segments)) { continue; } var entry = parse(segments); entry.put(LINE_NUMBER_KEY, lineNumber); - if(isStopEntry(entry)) { + if (isStopEntry(entry)) { break; } - if(isIgnoredEntry(entry)) { + if (isIgnoredEntry(entry)) { continue; } result = addToResult.addTo(entry, result); @@ -255,57 +268,69 @@ public T parse(InputStream is, T result, ParseEntryHandler> parse (InputStream is) throws IOException, ResourceParseLineException { - var result = new ArrayList> (); - result = this.parse(is, result, (v, r)->{r.add(v); return r;}); + public List> parse(InputStream is) throws IOException, ResourceParseLineException { + var result = new ArrayList>(); + result = this.parse(is, result, (v, r) -> { + r.add(v); + return r; + }); return result; } - + /** - * If this returns true for a parsed line, parsing will stop and that line will not be included in the result. + * If this returns true for a parsed line, parsing will stop and that line will + * not be included in the result. */ protected boolean isStopEntry(Map entry) { return false; } - + /** - * If this returns true for a segmented line, parsing will stop and that line will not be included in the result. + * If this returns true for a segmented line, parsing will stop and that line + * will not be included in the result. */ public boolean isStopSegment(List entry) { return false; } /** - * If this returns true for an unparsed line, parsing will stop and that line will not be included in the result. + * If this returns true for an unparsed line, parsing will stop and that line + * will not be included in the result. */ public boolean isStopLine(String line) { return false; } - + /** - * If this returns true for a parsed line, that line will not be included in the result. + * If this returns true for a parsed line, that line will not be included in the + * result. */ public boolean isIgnoredEntry(Map entry) { return false; } - + /** - * If this returns true for a segmented line, that line will not be included in the result. + * If this returns true for a segmented line, that line will not be included in + * the result. */ public boolean isIgnoredSegment(List entry) { return false; } /** - * If this returns true for an unparsed line, that line will not be included in the result. + * If this returns true for an unparsed line, that line will not be included in + * the result. */ public boolean isIgnoredLine(String line) { return false; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java index 0bec76ec1..4d6933435 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ParseEntryHandler.java @@ -2,7 +2,7 @@ /** * Handler to apply the result of parsing to an under construction object - * + * * @author Kevin Smith, Vivid Solutions * * @param @@ -12,7 +12,8 @@ public interface ParseEntryHandler { /** * Apply the result of parsing to an under construction object - * @param entry parsed record + * + * @param entry parsed record * @param result object under construction * @return the object under construction * @throws ValueParseException if there was a problem with the parsed value diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java index 84f710f52..9d69dd524 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseLineException.java @@ -2,22 +2,22 @@ /** * An error parsing a particular line of a multi-line resource - * + * * @author Kevin Smith, Vivid Solutions * */ public class ResourceParseLineException extends ResourceParseException { private static final long serialVersionUID = 5188546056230073563L; - + int line; public int getLine() { return line; } - public ResourceParseLineException(int line, - String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace + public ResourceParseLineException( + int line, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace ) { super(message(line, message), cause, enableSuppression, writableStackTrace); this.line = line; @@ -36,9 +36,9 @@ public ResourceParseLineException(int line, String message) { public ResourceParseLineException(int line, Throwable cause) { super(message(line, cause.getMessage()), cause); this.line = line; - } - + } + private static String message(int line, String message) { - return String.format("Error at line %d: %s",line,message); + return String.format("Error at line %d: %s", line, message); } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java index 671898573..d0af92480 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParseValidException.java @@ -2,7 +2,7 @@ /** * An error parsing resource that is not associated with a particular line - * + * * @author Kevin Smith, Vivid Solutions * */ @@ -31,6 +31,5 @@ public ResourceParseValidException(String message) { public ResourceParseValidException(Throwable cause) { super(cause); } - - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java index be7ffd6e1..bd7ca4f48 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java @@ -8,7 +8,7 @@ /** * A parser for a multi-line recource - * + * * @author Kevin Smith, Vivid Solutions * * @param @@ -17,53 +17,68 @@ public interface ResourceParser { /** * Parse an InputStream + * * @param is * @param control Control parameter map * @return The parsed resource - * @throws IOException if there is an error communicating with the input stream - * @throws ResourceParseLineException if there is a problem with the content of the resource + * @throws IOException if there is an error communicating with + * the input stream + * @throws ResourceParseLineException if there is a problem with the content of + * the resource */ T parse(InputStream is, Map control) throws IOException, ResourceParseException; - + /** * Parse a resource from the classpath + * * @param klazz * @param resourcePath - * @param control Control parameter map + * @param control Control parameter map * @return The parsed resource - * @throws IOException if there is an error communicating with the input stream - * @throws ResourceParseLineException if there is a problem with the content of the resource + * @throws IOException if there is an error communicating with + * the input stream + * @throws ResourceParseLineException if there is a problem with the content of + * the resource */ - default T parse (Class klazz, String resourcePath, Map control) throws IOException, ResourceParseException { + default T parse(Class klazz, String resourcePath, Map control) + throws IOException, ResourceParseException { try (var is = klazz.getResourceAsStream(resourcePath)) { return parse(is, control); } } - + /** * Parse a resource from a file + * * @param resourcePath - * @param control Control parameter map + * @param control Control parameter map * @return The parsed resource - * @throws IOException if there is an error communicating with the input stream - * @throws ResourceParseLineException if there is a problem with the content of the resource + * @throws IOException if there is an error communicating with + * the input stream + * @throws ResourceParseLineException if there is a problem with the content of + * the resource */ - default T parse (Path resourcePath, Map control) throws IOException, ResourceParseException { + default T parse(Path resourcePath, Map control) throws IOException, ResourceParseException { try (InputStream is = Files.newInputStream(resourcePath)) { return parse(is, control); } } - + static U expectParsedControl(Map control, String key, Class clazz) { var value = control.get(key); if (value == null) { - throw new IllegalStateException("Expected control map to have "+key); + throw new IllegalStateException("Expected control map to have " + key); } - if (clazz!= String.class && value instanceof String) { - throw new IllegalStateException("Expected control map entry "+key+" to be parsed but was still a String "+value); + if (clazz != String.class && value instanceof String) { + throw new IllegalStateException( + "Expected control map entry " + key + " to be parsed but was still a String " + value + ); } - if(!clazz.isInstance(value)) { - throw new IllegalStateException("Expected control map entry "+key+" to be a "+clazz.getSimpleName()+" but was a "+value.getClass()); + if (!clazz.isInstance(value)) { + throw new IllegalStateException( + "Expected control map entry " + key + " to be a " + clazz.getSimpleName() + " but was a " + + value.getClass() + ); } return clazz.cast(value); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index fc379d4d3..31e6326c9 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -12,64 +12,69 @@ /** * Parser for a SP0 Definition data file - * + * * @author Kevin Smith, Vivid Solutions * */ -public class SP0DefinitionParser implements ResourceParser>{ - +public class SP0DefinitionParser implements ResourceParser> { + public static final String CONTROL_KEY = "SP0_DEF"; private int num_sp0; - - LineParser lineParser = new LineParser() - .strippedString(2, "alias") - .space(1) - .strippedString(32, "name") - .space(1) - .value(2, "preference", s-> - ValueParser.optional(ValueParser.INTEGER).parse(s) - .flatMap(v->v==0 ? Optional.empty() : Optional.of(v))); - ; - + + LineParser lineParser = new LineParser().strippedString(2, "alias").space(1).strippedString(32, "name").space(1) + .value( + 2, "preference", + s -> ValueParser.optional(ValueParser.INTEGER).parse(s) + .flatMap(v -> v == 0 ? Optional.empty() : Optional.of(v)) + );; + public SP0DefinitionParser() { super(); this.num_sp0 = 16; } - + public SP0DefinitionParser(int num_sp0) { super(); this.num_sp0 = num_sp0; } - + @SuppressWarnings("unchecked") @Override - public List parse(InputStream is, Map control) throws IOException, ResourceParseException { + public List parse(InputStream is, Map control) + throws IOException, ResourceParseException { SP0Definition[] result = new SP0Definition[num_sp0]; - result = lineParser.parse(is, result, (v, r)->{ + result = lineParser.parse(is, result, (v, r) -> { String alias = (String) v.get("alias"); Optional preference = (Optional) v.get("preference"); String name = (String) v.get("name"); Integer lineNumber = (Integer) v.get(LineParser.LINE_NUMBER_KEY); - + var defn = new SP0Definition(alias, preference, name); int p = preference.orElse(lineNumber); - - if(p>num_sp0) { - throw new ValueParseException(Integer.toString(p),String.format("Preference %d is larger than %d", p, num_sp0)); + + if (p > num_sp0) { + throw new ValueParseException( + Integer.toString(p), String.format("Preference %d is larger than %d", p, num_sp0) + ); } - if(p<1) { - throw new ValueParseException(Integer.toString(p),String.format("Preference %d is less than %d", p, 0)); + if (p < 1) { + throw new ValueParseException( + Integer.toString(p), String.format("Preference %d is less than %d", p, 0) + ); } - if(r[p-1]!=null) { - throw new ValueParseException(Integer.toString(p),String.format("Preference %d has already been set to %s", p, r[p-1].getAlias())); + if (r[p - 1] != null) { + throw new ValueParseException( + Integer.toString(p), + String.format("Preference %d has already been set to %s", p, r[p - 1].getAlias()) + ); } - - r[p-1] = defn; + + r[p - 1] = defn; return r; }); - + return Collections.unmodifiableList(Arrays.asList(result)); } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java new file mode 100644 index 000000000..409134e3c --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java @@ -0,0 +1,59 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import ca.bc.gov.nrs.vdyp.common.ExpectationDifference; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.SiteCurve; + +public class SiteCurveParser implements ResourceParser> { + public static final String CONTROL_KEY = "SITE_CURVE_NUMBERS"; + + public static final String SPECIES_KEY = "species"; + public static final String VALUE_1_KEY = "value1"; + public static final String VALUE_2_KEY = "value2"; + + LineParser lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith("##"); + } + + @Override + public boolean isIgnoredLine(String line) { + return line.isBlank() || line.startsWith("# ") || line.startsWith(" "); + } + + }.strippedString(3, SPECIES_KEY).integer(3, VALUE_1_KEY).integer(3, VALUE_2_KEY); + + @Override + public Map parse(InputStream is, Map control) + throws IOException, ResourceParseException { + Map result = new HashMap<>(); + lineParser.parse(is, result, (v, r) -> { + var species = (String) v.get(SPECIES_KEY); + var value1 = (int) v.get(VALUE_1_KEY); + var value2 = (int) v.get(VALUE_2_KEY); + r.put(species, new SiteCurve(value1, value2)); + + return r; + }); + @SuppressWarnings("unchecked") + List sp0List = ((List) ResourceParser + .expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class)).stream() + .map(s -> s.getAlias()).collect(Collectors.toList()); + var missing = ExpectationDifference.difference(result.keySet(), sp0List).getMissing(); + if (!missing.isEmpty()) { + throw new ResourceParseValidException("Missing expected entries for " + String.join(", ", missing)); + } + return result; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java index 467b6b9d9..b735437b8 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java @@ -12,14 +12,14 @@ /** * Parser for an stcking class factor data file - * + * * @author Kevin Smith, Vivid Solutions * */ -public class StockingClassFactorParser implements ResourceParser>>{ - +public class StockingClassFactorParser implements ResourceParser>> { + public static final String CONTROL_KEY = "STOCKING_CLASS_FACTORS"; - + private static final String STK_KEY = "stk"; private static final String REGION_KEY = "region"; private static final String LAYER_KEY = "layer"; @@ -27,60 +27,54 @@ public class StockingClassFactorParser implements ResourceParser segments) { return segments.get(0).isBlank(); } - + @Override public boolean isStopSegment(List segments) { return "Z".equalsIgnoreCase(segments.get(0)); } - } - .value(1, STK_KEY, ValueParser.CHARACTER) - .space(1) - .value(1, REGION_KEY, ValueParser.REGION) - .space(1) - .value(1, LAYER_KEY, ValueParser.CHARACTER) - .integer(3, ITG_KEY) - .floating(6, FACTOR_KEY) + }.value(1, STK_KEY, ValueParser.CHARACTER).space(1).value(1, REGION_KEY, ValueParser.REGION).space(1) + .value(1, LAYER_KEY, ValueParser.CHARACTER).integer(3, ITG_KEY).floating(6, FACTOR_KEY) .integer(5, NPCT_KEY); - + public StockingClassFactorParser() { } @Override - public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { - + public Map> parse(InputStream is, Map control) + throws IOException, ResourceParseException { + Map> result = new HashMap<>(); - result = lineParser.parse(is, result, (v, r)->{ + result = lineParser.parse(is, result, (v, r) -> { char stk = (char) v.get(STK_KEY); Region region = (Region) v.get(REGION_KEY); float factor = (float) v.get(FACTOR_KEY); int npctArea = (int) v.get(NPCT_KEY); - + // Fortran was ignoring Layer and ITG - + var factorEntry = new StockingClassFactor(stk, region, factor, npctArea); - - r.computeIfAbsent(stk, (c)->new HashMap()).put(region, factorEntry); - + + r.computeIfAbsent(stk, (c) -> new HashMap()).put(region, factorEntry); + return r; }); - + for (var e : result.entrySet()) { result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); } - + return Collections.unmodifiableMap(result); } - } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java index af80c0499..d5b05f91f 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParseException.java @@ -2,12 +2,12 @@ /** * An error while parsing a simple value from a string. - * + * * @author Kevin Smith, Vivid Solutions * */ public class ValueParseException extends Exception { - + private static final long serialVersionUID = 4181384333196602044L; String value; @@ -20,8 +20,8 @@ public ValueParseException(String value) { this.value = value; } - public ValueParseException(String value, - String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace + public ValueParseException( + String value, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace ) { super(message, cause, enableSuppression, writableStackTrace); this.value = value; @@ -40,6 +40,6 @@ public ValueParseException(String value, String message) { public ValueParseException(String value, Throwable cause) { super(cause); this.value = value; - } - + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index e21ee29f6..8bae131dd 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -10,6 +10,7 @@ /** * Parses a string to a value + * * @author Kevin Smith, Vivid Solutions * * @param @@ -18,111 +19,118 @@ public interface ValueParser { /** * Parse a string to a value + * * @param string * @return The parsed value * @throws ValueParseException if the string could not be parsed */ T parse(String string) throws ValueParseException; - - public static interface JavaNumberParser { + + public static interface JavaNumberParser { U parse(String s) throws NumberFormatException; } - + /** * Adapts a parse method that throws NumerFormatException - * @param parser method that parses a string into the required type and throws NumerFormatException - * @param klazz the type to parse into + * + * @param parser method that parses a string into the required type and throws + * NumerFormatException + * @param klazz the type to parse into */ public static ValueParser numberParser(JavaNumberParser parser, Class klazz) { - return s->{ + return s -> { String stripped = s.strip(); try { return parser.parse(stripped); - } catch(NumberFormatException ex) { - throw new ValueParseException(stripped, String.format("\"%s\" is not a valid %s", stripped, klazz.getSimpleName()), ex); + } catch (NumberFormatException ex) { + throw new ValueParseException( + stripped, String.format("\"%s\" is not a valid %s", stripped, klazz.getSimpleName()), ex + ); } }; } - + /** * Parser for long integers */ public static final ValueParser LONG = numberParser(Long::parseLong, Long.class); - + /** * Parser for integers */ public static final ValueParser INTEGER = numberParser(Integer::parseInt, Integer.class); - + /** * Parser for short integers */ public static final ValueParser SHORT = numberParser(Short::parseShort, Short.class); - + /** * Parser for double precision floats */ public static final ValueParser DOUBLE = numberParser(Double::parseDouble, Double.class); - + /** * Parser for single precision floats */ public static final ValueParser FLOAT = numberParser(Float::parseFloat, Float.class); - + /** * Parser for Characters */ - public static final ValueParser CHARACTER = s->{ - if(s.isBlank()) { + public static final ValueParser CHARACTER = s -> { + if (s.isBlank()) { throw new ValueParseException("Character is blank"); } return s.charAt(0); }; - - + /** * Parser for a region identifier */ - public static final ValueParser REGION = (s)-> - Region.fromAlias(Character.toUpperCase(s.charAt(0))) - .orElseThrow(()->new ValueParseException(s, s+" is not a valid region identifier")); - + public static final ValueParser REGION = (s) -> Region.fromAlias(Character.toUpperCase(s.charAt(0))) + .orElseThrow(() -> new ValueParseException(s, s + " is not a valid region identifier")); + public static ValueParser> list(ValueParser delegate) { - return s-> { + return s -> { var elementStrings = s.strip().split("\s+"); List result = new ArrayList<>(); - for(String elementString : elementStrings) { + for (String elementString : elementStrings) { result.add(delegate.parse(elementString)); } return Collections.unmodifiableList(result); }; } - + /** * Wrap a parser with an additional validation step + * * @param * @param delegate - * @param validator Function that returns an error string if the parsed value is invalid + * @param validator Function that returns an error string if the parsed value is + * invalid * @return */ public static ValueParser validate(ValueParser delegate, Function> validator) { - return s-> { + return s -> { var value = delegate.parse(s); var error = validator.apply(value); - if(error.isPresent()) { + if (error.isPresent()) { throw new ValueParseException(s, error.get()); } return value; }; } - + /** - * Makes a parser that parses if the string is not blank, and returns an empty Optional otherwise. + * Makes a parser that parses if the string is not blank, and returns an empty + * Optional otherwise. + * * @param delegate Parser to use if the string is not blank */ public static ValueParser> optional(ValueParser delegate) { - return (s)->{ - if(!s.isBlank()) { + return (s) -> { + if (!s.isBlank()) { return Optional.of(delegate.parse(s)); } return Optional.empty(); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java index e48210c9f..1367e6d85 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/AbstractSpeciesDefinition.java @@ -1,22 +1,22 @@ package ca.bc.gov.nrs.vdyp.model; public class AbstractSpeciesDefinition { - + final String alias; final String name; - + protected AbstractSpeciesDefinition(String alias, String name) { this.alias = alias; this.name = name; } - + /** * @return The short alias for the species */ public String getAlias() { return alias; } - + /** * @return The full, human readable name for the species */ diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java index c84be27a0..338de4364 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java @@ -1,14 +1,14 @@ package ca.bc.gov.nrs.vdyp.model; public class BecDefinition extends AbstractSpeciesDefinition { - + final Region region; - + public BecDefinition(String alias, Region region, String name) { super(alias, name); this.region = region; } - + public Region getRegion() { return region; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java index 2ff4aa408..99cf9529f 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java @@ -4,21 +4,20 @@ import java.util.Optional; public enum Region { - COASTAL('C'), - INTERIOR('I'); - + COASTAL('C'), INTERIOR('I'); + final char characterAlias; private Region(char characterAlias) { this.characterAlias = characterAlias; } - + public static Optional fromAlias(char alias) { - return Arrays.stream(Region.values()).filter(x->x.getCharacterAlias()==alias).findFirst(); + return Arrays.stream(Region.values()).filter(x -> x.getCharacterAlias() == alias).findFirst(); } public char getCharacterAlias() { return characterAlias; } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java index 0d0c00698..25f9fad14 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java @@ -2,15 +2,15 @@ import java.util.Optional; -public class SP0Definition extends AbstractSpeciesDefinition { - +public class SP0Definition extends AbstractSpeciesDefinition { + final Optional preference; - + public SP0Definition(String alias, Optional preference, String name) { super(alias, name); this.preference = preference; } - + public Optional getPreference() { return preference; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurve.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurve.java new file mode 100644 index 000000000..fc3dd0f5f --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurve.java @@ -0,0 +1,21 @@ +package ca.bc.gov.nrs.vdyp.model; + +public class SiteCurve { + private final int value1; + private final int value2; + + public SiteCurve(int value1, int value2) { + super(); + this.value1 = value1; + this.value2 = value2; + } + + public int getValue1() { + return value1; + } + + public int getValue2() { + return value2; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java index d16645ce7..ca863b322 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/StockingClassFactor.java @@ -1,12 +1,12 @@ package ca.bc.gov.nrs.vdyp.model; public class StockingClassFactor { - + private final Character stk; private final Region region; private final float factor; private final int npctArea; - + public StockingClassFactor(Character stk, Region region, float factor, int npctArea) { super(); this.stk = stk; @@ -14,17 +14,21 @@ public StockingClassFactor(Character stk, Region region, float factor, int npctA this.factor = factor; this.npctArea = npctArea; } + public Character getStk() { return stk; } + public Region getRegion() { return region; } + public float getFactor() { return factor; } + public int getNpctArea() { return npctArea; } - + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index 3f02d65f7..7ac53044c 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -14,83 +14,153 @@ import ca.bc.gov.nrs.vdyp.model.Region; public class BecDefinitionParserTest { - + @Test public void testParse() throws Exception { var parser = new BecDefinitionParser(); - + var result = parser.parse(ControlFileParserTest.class, "coe/Becdef.dat", Collections.emptyMap()); - - assertThat(result, hasEntry(equalTo("AT"), allOf( - hasProperty("alias", equalTo("AT")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Alpine Tundra")) - ))); - assertThat(result, hasEntry(equalTo("BG"), allOf( - hasProperty("alias", equalTo("BG")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Bunchgrass")) - ))); - assertThat(result, hasEntry(equalTo("BWBS"), allOf( - hasProperty("alias", equalTo("BWBS")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Boreal White and Black Spruce")) - ))); - assertThat(result, hasEntry(equalTo("CDF"), allOf( - hasProperty("alias", equalTo("CDF")), - hasProperty("region", equalTo(Region.COASTAL)), - hasProperty("name", equalTo("Coastal Dougfir")) - ))); - assertThat(result, hasEntry(equalTo("CWH"), allOf( - hasProperty("alias", equalTo("CWH")), - hasProperty("region", equalTo(Region.COASTAL)), - hasProperty("name", equalTo("Coastal Western Hemlock")) - ))); - assertThat(result, hasEntry(equalTo("ESSF"), allOf( - hasProperty("alias", equalTo("ESSF")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Englemann Sruce -SubAlpine Fir")) - ))); - assertThat(result, hasEntry(equalTo("ICH"), allOf( - hasProperty("alias", equalTo("ICH")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Interior Cedar-Hemlock")) - ))); - assertThat(result, hasEntry(equalTo("IDF"), allOf( - hasProperty("alias", equalTo("IDF")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Interior DougFir")) - ))); - assertThat(result, hasEntry(equalTo("MH"), allOf( - hasProperty("alias", equalTo("MH")), - hasProperty("region", equalTo(Region.COASTAL)), - hasProperty("name", equalTo("Mountain Hemlock")) - ))); - assertThat(result, hasEntry(equalTo("MS"), allOf( - hasProperty("alias", equalTo("MS")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Montane Spruce")) - ))); - assertThat(result, hasEntry(equalTo("PP"), allOf( - hasProperty("alias", equalTo("PP")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Ponderosa Pine")) - ))); - assertThat(result, hasEntry(equalTo("SBPS"), allOf( - hasProperty("alias", equalTo("SBPS")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("SubBoreal Pine-Spruce")) - ))); - assertThat(result, hasEntry(equalTo("SBS"), allOf( - hasProperty("alias", equalTo("SBS")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("SubBoreal Spruce")) - ))); - assertThat(result, hasEntry(equalTo("SWB"), allOf( - hasProperty("alias", equalTo("SWB")), - hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Spruce-Willow-Birch")) - ))); + + assertThat( + result, + hasEntry( + equalTo("AT"), + allOf( + hasProperty("alias", equalTo("AT")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Alpine Tundra")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("BG"), + allOf( + hasProperty("alias", equalTo("BG")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Bunchgrass")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("BWBS"), + allOf( + hasProperty("alias", equalTo("BWBS")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Boreal White and Black Spruce")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("CDF"), + allOf( + hasProperty("alias", equalTo("CDF")), hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Coastal Dougfir")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("CWH"), + allOf( + hasProperty("alias", equalTo("CWH")), hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Coastal Western Hemlock")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("ESSF"), + allOf( + hasProperty("alias", equalTo("ESSF")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Englemann Sruce -SubAlpine Fir")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("ICH"), + allOf( + hasProperty("alias", equalTo("ICH")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Interior Cedar-Hemlock")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("IDF"), + allOf( + hasProperty("alias", equalTo("IDF")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Interior DougFir")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("MH"), + allOf( + hasProperty("alias", equalTo("MH")), hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Mountain Hemlock")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("MS"), + allOf( + hasProperty("alias", equalTo("MS")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Montane Spruce")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("PP"), + allOf( + hasProperty("alias", equalTo("PP")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Ponderosa Pine")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("SBPS"), + allOf( + hasProperty("alias", equalTo("SBPS")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("SubBoreal Pine-Spruce")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("SBS"), + allOf( + hasProperty("alias", equalTo("SBS")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("SubBoreal Spruce")) + ) + ) + ); + assertThat( + result, + hasEntry( + equalTo("SWB"), + allOf( + hasProperty("alias", equalTo("SWB")), hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Spruce-Willow-Birch")) + ) + ) + ); } - + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index fcba4053d..e0284db27 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -1,6 +1,7 @@ package ca.bc.gov.nrs.vdyp.io.parse; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.parseAs; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; @@ -17,17 +18,20 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import org.hamcrest.Matcher; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import ca.bc.gov.nrs.vdyp.test.VdypMatchers; + public class ControlFileParserTest { @Test void testParsesEntriesSimple() throws Exception { var parser = makeParser(); - + String file = "001 Control"; try (InputStream is = new ByteArrayInputStream(file.getBytes())) { var result = parser.parse(is); @@ -35,7 +39,7 @@ void testParsesEntriesSimple() throws Exception { assertThat(result.entrySet(), contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); } } - + @Test void testParsesEntriesSpacePadding() throws Exception { var parser = makeParser(); @@ -60,7 +64,8 @@ void testParsesEntriesExtended() throws Exception { result.entrySet(), contains( controlEntry( - equalTo(1), equalTo("X"), equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") + equalTo(1), equalTo("X"), + equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") ) ) ); @@ -79,7 +84,8 @@ void testParsesEntriesExtendedAlternate() throws Exception { result.entrySet(), contains( controlEntry( - equalTo(1), equalTo(">"), equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") + equalTo(1), equalTo(">"), + equalTo("Control that is longer than 50 characters. Blah Blah Blah Blah.") ) ) ); @@ -94,12 +100,7 @@ void testParsesEntriesWithDistantComment() throws Exception { try (InputStream is = new ByteArrayInputStream(file.getBytes())) { var result = parser.parse(is); - assertThat( - result.entrySet(), - contains( - controlEntry(equalTo(1), equalTo(" "), equalTo("Control")) - ) - ); + assertThat(result.entrySet(), contains(controlEntry(equalTo(1), equalTo(" "), equalTo("Control")))); } } @@ -111,17 +112,7 @@ void testParsesEntriesExtendedWithDistantComment() throws Exception { try (InputStream is = new ByteArrayInputStream(file.getBytes())) { var result = parser.parse(is); - assertThat( - result.entrySet(), - contains( - controlEntry( - equalTo(1), equalTo("X"), - equalTo( - "Control" - ) - ) - ) - ); + assertThat(result.entrySet(), contains(controlEntry(equalTo(1), equalTo("X"), equalTo("Control")))); } } @@ -214,15 +205,16 @@ void testParsesMultipleEntries() throws Exception { ); } } - + @Test void testException() throws Exception { var parser = makeParser(); String file = "00X Control 1\n002 Control 2"; try (InputStream is = new ByteArrayInputStream(file.getBytes())) { - ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is)); - + ResourceParseLineException ex1 = Assertions + .assertThrows(ResourceParseLineException.class, () -> parser.parse(is)); + assertThat(ex1, hasProperty("line", is(1))); assertThat(ex1, hasProperty("cause", instanceOf(ValueParseException.class))); assertThat(ex1, hasProperty("cause", hasProperty("cause", instanceOf(NumberFormatException.class)))); @@ -230,16 +222,19 @@ void testException() throws Exception { assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "00X"))); } } - + @Test void testExceptionInControlValueParser() throws Exception { var parser = makeParser(); - parser.record(2, s->{throw new ValueParseException(s,"Test Exception");}); - + parser.record(2, s -> { + throw new ValueParseException(s, "Test Exception"); + }); + String file = "001 Control 1\n002 Control 2"; try (InputStream is = new ByteArrayInputStream(file.getBytes())) { - ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is)); - + ResourceParseLineException ex1 = Assertions + .assertThrows(ResourceParseLineException.class, () -> parser.parse(is)); + assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("cause", instanceOf(ValueParseException.class))); assertThat(ex1, hasProperty("cause", hasProperty("value", is("Control 2")))); @@ -250,94 +245,100 @@ void testExceptionInControlValueParser() throws Exception { @Test void testParseToMap() throws Exception { var parser = makeParser(); - String file = - "097 coe\\vetdq2.dat DQ for Vet layer RD_YDQV\n" - + "098 coe\\REGBAV01.coe VET BA, IPSJF168.doc RD_E098\n" - + "\n" + String file = "097 coe\\vetdq2.dat DQ for Vet layer RD_YDQV\n" + + "098 coe\\REGBAV01.coe VET BA, IPSJF168.doc RD_E098\n" + "\n" + "197 5.0 0.0 2.0 Minimum Height, Minimum BA, Min BA fully stocked.\n" + "\n" + "198 coe\\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198\n" + "199 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155, App IX\n" + " 1st: 1: Do NOT apply BA limits from SEQ043\n" + " 2nd: 1: Do NOT apply DQ limits from SEQ043\n"; - try( - var is = new ByteArrayInputStream(file.getBytes()); - ) { + try (var is = new ByteArrayInputStream(file.getBytes());) { var result = parser.parse(is); - assertThat(result, hasEntry(equalTo("097"), equalTo("coe\\vetdq2.dat"))); - + assertThat(result, hasEntry(equalTo("098"), equalTo("coe\\REGBAV01.coe"))); assertThat(result, hasEntry(equalTo("197"), equalTo("5.0 0.0 2.0"))); assertThat(result, hasEntry(equalTo("198"), equalTo("coe\\MOD19813.prm"))); assertThat(result, hasEntry(equalTo("199"), equalTo("0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0"))); } } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test void testParseToMapWithConfiguration() throws Exception { var parser = makeConfiguredParser(); - String file = - "097 coe\\vetdq2.dat DQ for Vet layer RD_YDQV\n" - + "098 coe\\REGBAV01.coe VET BA, IPSJF168.doc RD_E098\n" - + "\n" + String file = "097 coe\\vetdq2.dat DQ for Vet layer RD_YDQV\n" + + "098 coe\\REGBAV01.coe VET BA, IPSJF168.doc RD_E098\n" + "\n" + "197 5.0 0.0 2.0 Minimum Height, Minimum BA, Min BA fully stocked.\n" + "\n" + "198 coe\\MOD19813.prm Modifier file (IPSJF155, XII) RD_E198\n" + "199 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155, App IX\n" + " 1st: 1: Do NOT apply BA limits from SEQ043\n" + " 2nd: 1: Do NOT apply DQ limits from SEQ043\n"; - try( - var is = new ByteArrayInputStream(file.getBytes()); - ) { + try (var is = new ByteArrayInputStream(file.getBytes());) { var result = parser.parse(is); - assertThat(result, hasEntry(equalTo("097"), equalTo("coe\\vetdq2.dat"))); - + assertThat(result, hasEntry(equalTo("098"), equalTo("coe\\REGBAV01.coe"))); - assertThat(result, hasEntry(equalTo("minimums"), (Matcher)contains(5.0f, 0.0f, 2.0f))); + assertThat(result, hasEntry(equalTo("minimums"), (Matcher) contains(5.0f, 0.0f, 2.0f))); assertThat(result, hasEntry(equalTo("modifier_file"), equalTo("coe\\MOD19813.prm"))); - assertThat(result, hasEntry(equalTo("debugSwitches"), (Matcher)contains(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0))); + assertThat( + result, + hasEntry( + equalTo("debugSwitches"), + (Matcher) contains( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 + ) + ) + ); } } - + @Test void testParseToMapLastOfDuplicates() throws Exception { var parser = makeParser(); - String file = - "097 value1\n" - + "097 value2\n"; - try( - var is = new ByteArrayInputStream(file.getBytes()); - ) { + String file = "097 value1\n" + "097 value2\n"; + try (var is = new ByteArrayInputStream(file.getBytes());) { var result = parser.parse(is); - assertThat(result, hasEntry(equalTo("097"), equalTo("value2"))); } } - - private static Matcher> controlEntry(Matcher index, Matcher extend, Matcher control) { - + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + void testParsesOptional() throws Exception { + var parser = makeParser(); + + parser.optional(1, "x", String::strip); + + String file = "001 Control"; + try (InputStream is = new ByteArrayInputStream(file.getBytes())) { + var result = parser.parse(is); + + assertThat(result, hasEntry(equalTo("x"), (Matcher) present(equalTo("Control")))); + } + } + + private static Matcher> + controlEntry(Matcher index, Matcher extend, Matcher control) { + return allOf(hasProperty("key", parseAs(index, Integer::valueOf)), hasProperty("value", control)); } private ControlFileParser makeParser() { return new ControlFileParser(); } - + private ControlFileParser makeConfiguredParser() { var parser = makeParser(); - - parser - .record(197, "minimums", ValueParser.list(ValueParser.FLOAT)) - .record(198, "modifier_file") - .record(199, "debugSwitches", ValueParser.list(ValueParser.INTEGER)); - + + parser.record(197, "minimums", ValueParser.list(ValueParser.FLOAT)).record(198, "modifier_file") + .record(199, "debugSwitches", ValueParser.list(ValueParser.INTEGER)); + return parser; } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java index f2bc9af83..f463e77ec 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java @@ -9,171 +9,181 @@ import org.junit.jupiter.api.Test; public class ControlFileWriterTest { - + @Test public void testWriteEntry() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + writer.writeEntry(1, "Value"); - - assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 Value \r\n")); - + + assertThat( + output.toString(ControlFileWriter.CHARSET), + equalTo("001 Value \r\n") + ); + } } - + @Test public void testWriteEntryWithComment() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + writer.writeEntry(1, "Value", "Comment"); - - assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 Value Comment\r\n")); - + + assertThat( + output.toString(ControlFileWriter.CHARSET), + equalTo("001 Value Comment\r\n") + ); + } } - + @Test public void testWriteExtendedEntry() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + writer.writeEntry(1, "Long Value........................................."); - - assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001XLong Value......................................... \r\n")); - + + assertThat( + output.toString(ControlFileWriter.CHARSET), + equalTo( + "001XLong Value......................................... \r\n" + ) + ); + } } - + @Test public void testWriteExtendedEntryWithComment() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - - writer.writeEntry(1, "Long Value.........................................","Comment"); - - assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001XLong Value......................................... Comment\r\n")); - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + + writer.writeEntry(1, "Long Value.........................................", "Comment"); + + assertThat( + output.toString(ControlFileWriter.CHARSET), + equalTo( + "001XLong Value......................................... Comment\r\n" + ) + ); + } } - + @Test public void testWriteComment() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + writer.writeComment("Comment"); - + assertThat(output.toString(ControlFileWriter.CHARSET), equalTo(" Comment\r\n")); - + } } @Test public void testValidateIndex() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + writer.writeEntry(1, "Low"); writer.writeEntry(200, "High"); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(0, "Anything"); }); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(-1, "Anything"); }); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(201, "Anything"); }); - - assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 Low \r\n200 High \r\n")); - + + assertThat( + output.toString(ControlFileWriter.CHARSET), + equalTo( + "001 Low \r\n200 High \r\n" + ) + ); + } } - + @Test public void testValidateValue() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + writer.writeEntry(1, ""); - writer.writeEntry(2, "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"); - assertThrows(IllegalArgumentException.class, ()->{ - writer.writeEntry(3, "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789X"); + writer.writeEntry( + 2, + "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + ); + assertThrows(IllegalArgumentException.class, () -> { + writer.writeEntry( + 3, + "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789X" + ); }); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(4, "No ! Bang"); }); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(5, "No \r\n windows newline"); }); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(6, "No \n POSIX newline"); }); - - assertThat(output.toString(ControlFileWriter.CHARSET), equalTo("001 \r\n002X012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n")); - + + assertThat( + output.toString(ControlFileWriter.CHARSET), + equalTo( + "001 \r\n002X012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n" + ) + ); + } } - + @Test public void testValidateComment() throws Exception { - - try ( - var output = new ByteArrayOutputStream(); - var writer = new ControlFileWriter(output); - ) { - + + try (var output = new ByteArrayOutputStream(); var writer = new ControlFileWriter(output);) { + writer.writeEntry(1, "Value", ""); writer.writeEntry(2, "Value", "Comment"); writer.writeEntry(3, "Value", "! Comment"); writer.writeComment(""); writer.writeComment("Comment"); writer.writeComment("! Comment"); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(4, "Value", "Comment with \r\n Windows newline"); }); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeEntry(5, "Value", "Comment with \n POSIX newline"); }); // Could write comments with line breaks as multiple comment lines - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeComment("Comment with \r\n Windows newline"); }); - assertThrows(IllegalArgumentException.class, ()->{ + assertThrows(IllegalArgumentException.class, () -> { writer.writeComment("Comment with \n POSIX newline"); }); - - assertThat(output.toString(ControlFileWriter.CHARSET), equalTo( - "001 Value \r\n"+ - "002 Value Comment\r\n"+ - "003 Value ! Comment\r\n"+ - " \r\n"+ - " Comment\r\n"+ - " ! Comment\r\n")); - + + assertThat( + output.toString(ControlFileWriter.CHARSET), + equalTo( + "001 Value \r\n" + + "002 Value Comment\r\n" + + "003 Value ! Comment\r\n" + " \r\n" + + " Comment\r\n" + " ! Comment\r\n" + ) + ); + } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index 197534093..87d70e7ac 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -18,7 +18,6 @@ import java.util.List; import java.util.Optional; - import org.hamcrest.Matchers; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -31,77 +30,83 @@ @SuppressWarnings("unused") public class EquationGroupParserTest { - + @Test public void testParse() throws Exception { var parser = new EquationGroupParser(); - + var controlMap = makeControlMapSingle(); String[] lines = { "S1 B1 001" }; - + var is = TestUtils.makeStream(lines); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); - + assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(1)))); } - + @Test public void testSP0MustExist() throws Exception { var parser = new EquationGroupParser(); - + var controlMap = makeControlMapSingle(); String[] lines = { "SX B1 001" }; - + var is = TestUtils.makeStream(lines); - - ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); - + + ResourceParseLineException ex1 = Assertions.assertThrows( + ResourceParseLineException.class, () -> parser.parse(is, Collections.unmodifiableMap(controlMap)) + ); + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "SX", "SP0"))); assertThat(ex1, hasProperty("line", is(1))); assertThat(ex1, causedBy(hasProperty("value", is("SX")))); } - + @Test public void testBecMustExist() throws Exception { var parser = new EquationGroupParser(); - + var controlMap = makeControlMapSingle(); String[] lines = { "S1 BX 001" }; - + var is = TestUtils.makeStream(lines); - - ResourceParseLineException ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); - + + ResourceParseLineException ex1 = Assertions.assertThrows( + ResourceParseLineException.class, () -> parser.parse(is, Collections.unmodifiableMap(controlMap)) + ); + assertThat(ex1, hasProperty("message", stringContainsInOrder("line 1", "BX", "BEC"))); assertThat(ex1, hasProperty("line", is(1))); assertThat(ex1, causedBy(hasProperty("value", is("BX")))); } - + @Test public void testParseOvewrite() throws Exception { - // Original Fortran allows subsequent entries to overwrite old ones so don't validate against that + // Original Fortran allows subsequent entries to overwrite old ones so don't + // validate against that var parser = new EquationGroupParser(); - + var controlMap = makeControlMapSingle(); String[] lines = { "S1 B1 001", "S1 B1 002" }; - + var is = TestUtils.makeStream(lines); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); - + assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(2)))); } - + @Test public void testParseMultiple() throws Exception { var parser = new EquationGroupParser(); - + var controlMap = makeControlMap(); - String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B3 013", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", "S2 B4 024" }; - + String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B3 013", "S1 B4 014", "S2 B1 021", "S2 B2 022", + "S2 B3 023", "S2 B4 024" }; + var is = TestUtils.makeStream(lines); var result = parser.parse(is, Collections.unmodifiableMap(controlMap)); - + assertThat(result, hasEntry(is("S1"), hasEntry(is("B1"), is(11)))); assertThat(result, hasEntry(is("S1"), hasEntry(is("B2"), is(12)))); assertThat(result, hasEntry(is("S1"), hasEntry(is("B3"), is(13)))); @@ -111,91 +116,99 @@ public void testParseMultiple() throws Exception { assertThat(result, hasEntry(is("S2"), hasEntry(is("B3"), is(23)))); assertThat(result, hasEntry(is("S2"), hasEntry(is("B4"), is(24)))); } - + @Test public void testRequireNoMissingSp0() throws Exception { var parser = new EquationGroupParser(); - + var controlMap = makeControlMap(); - - List unusedBecs= Arrays.asList("B2", "B4"); + + List unusedBecs = Arrays.asList("B2", "B4"); String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B3 013", "S1 B4 014" }; - + var is = TestUtils.makeStream(lines); - - ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); - + + ResourceParseValidException ex1 = assertThrows( + ResourceParseValidException.class, () -> parser.parse(is, Collections.unmodifiableMap(controlMap)) + ); + assertThat(ex1, hasProperty("message", is("Expected mappings for SP0 S2 but it was missing"))); - + } - + @Test public void testRequireNoMissingBec() throws Exception { var parser = new EquationGroupParser(); - + var controlMap = makeControlMap(); - - List unusedBecs= Arrays.asList("B2", "B4"); - String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", "S2 B4 024" }; - + + List unusedBecs = Arrays.asList("B2", "B4"); + String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", + "S2 B4 024" }; + var is = TestUtils.makeStream(lines); - - ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); - + + ResourceParseValidException ex1 = assertThrows( + ResourceParseValidException.class, () -> parser.parse(is, Collections.unmodifiableMap(controlMap)) + ); + assertThat(ex1, hasProperty("message", is("Expected mappings for BEC B3 but it was missing for SP0 S1"))); - + } - + @Test public void testRequireNoUnexpectedBec() throws Exception { var parser = new EquationGroupParser(); - + var controlMap = makeControlMap(); - - List hiddenBecs= Arrays.asList("B3"); + + List hiddenBecs = Arrays.asList("B3"); parser.setHiddenBecs(hiddenBecs); - String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", "S2 B4 024" }; - + String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B4 014", "S2 B1 021", "S2 B2 022", "S2 B3 023", + "S2 B4 024" }; + var is = TestUtils.makeStream(lines); - - ResourceParseValidException ex1 = assertThrows(ResourceParseValidException.class, ()->parser.parse(is, Collections.unmodifiableMap(controlMap))); - + + ResourceParseValidException ex1 = assertThrows( + ResourceParseValidException.class, () -> parser.parse(is, Collections.unmodifiableMap(controlMap)) + ); + assertThat(ex1, hasProperty("message", is("Unexpected mapping for BEC B3 under SP0 S2"))); - + } private HashMap makeControlMapSingle() { var controlMap = new HashMap(); - + var becMap = new HashMap(); var sp0List = new ArrayList(); - + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - + sp0List.add(new SP0Definition("S1", Optional.empty(), "Test SP0 1")); - + controlMap.put(BecDefinitionParser.CONTROL_KEY, Collections.unmodifiableMap(becMap)); controlMap.put(SP0DefinitionParser.CONTROL_KEY, Collections.unmodifiableList(sp0List)); return controlMap; } - + private HashMap makeControlMap() { var controlMap = new HashMap(); - + var becMap = new HashMap(); var sp0List = new ArrayList(); - + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); becMap.put("B2", new BecDefinition("B2", Region.INTERIOR, "Test BEC 2")); becMap.put("B3", new BecDefinition("B3", Region.COASTAL, "Test BEC 3")); becMap.put("B4", new BecDefinition("B4", Region.INTERIOR, "Test BEC 4")); - + sp0List.add(new SP0Definition("S1", Optional.empty(), "Test SP0 1")); sp0List.add(new SP0Definition("S2", Optional.empty(), "Test SP0 2")); - + controlMap.put(BecDefinitionParser.CONTROL_KEY, Collections.unmodifiableMap(becMap)); controlMap.put(SP0DefinitionParser.CONTROL_KEY, Collections.unmodifiableList(sp0List)); return controlMap; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index c6280d5e9..0a181c21c 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -20,189 +20,173 @@ import org.junit.jupiter.api.Test; public class LineParserTest { - + @Test public void testBasic() throws Exception { var parser = new LineParser(); - parser - .string(3, "part1") - .space(1) - .string(4, "part2"); - + parser.string(3, "part1").space(1).string(4, "part2"); + var result1 = parser.parseLine("042 Blah"); - + assertThat(result1, hasEntry("part1", "042")); assertThat(result1, hasEntry("part2", "Blah")); - + } - + @Test public void testNumbers() throws Exception { var parser = new LineParser(); - parser - .integer(4, "part1") - .space(1) - .floating(5, "part2"); - + parser.integer(4, "part1").space(1).floating(5, "part2"); + var result1 = parser.parseLine(" 4 0.5 "); - + assertThat(result1, hasEntry("part1", 4)); assertThat(result1, hasEntry("part2", 0.5f)); - + } - + @Test public void testIncomplete() throws Exception { var parser = new LineParser(); - parser - .integer(4, "part1") - .space(1) - .floating(5, "part2"); - + parser.integer(4, "part1").space(1).floating(5, "part2"); + var result1 = parser.parseLine(" 4 "); - + assertThat(result1, hasEntry("part1", 4)); assertThat(result1, not(hasKey("part2"))); - + } - + @Test public void testIncompleteSegment() throws Exception { var parser = new LineParser(); - parser - .integer(4, "part1") - .space(1) - .floating(5, "part2"); - + parser.integer(4, "part1").space(1).floating(5, "part2"); + var result1 = parser.parseLine(" 4 5.0"); - + assertThat(result1, hasEntry("part1", 4)); assertThat(result1, hasEntry("part2", 5.0f)); - + } - + @Test public void testNumberParseErrors() throws Exception { var parser = new LineParser(); - parser - .integer(4, "part1") - .space(1) - .floating(5, "part2"); - - var ex1 = assertThrows(ValueParseException.class, ()->parser.parseLine(" X 0.5 ")); - + parser.integer(4, "part1").space(1).floating(5, "part2"); + + var ex1 = assertThrows(ValueParseException.class, () -> parser.parseLine(" X 0.5 ")); + assertThat(ex1, hasProperty("value", is("X"))); assertThat(ex1, hasProperty("cause", isA(NumberFormatException.class))); - - var ex2 = assertThrows(ValueParseException.class, ()->parser.parseLine(" 4 0.x ")); - + + var ex2 = assertThrows(ValueParseException.class, () -> parser.parseLine(" 4 0.x ")); + assertThat(ex2, hasProperty("value", is("0.x"))); assertThat(ex2, hasProperty("cause", isA(NumberFormatException.class))); - } - + @Test public void testValueParser() throws Exception { var parser = new LineParser(); - parser - .value(4, "part1", (s)->Integer.valueOf(s.strip())+1) - .space(1) - .value("part2", (s)->Float.valueOf(s.strip())+1); - + parser.value(4, "part1", (s) -> Integer.valueOf(s.strip()) + 1).space(1) + .value("part2", (s) -> Float.valueOf(s.strip()) + 1); + var result1 = parser.parseLine(" 4 0.5 "); - + assertThat(result1, hasEntry("part1", 5)); assertThat(result1, hasEntry("part2", 1.5f)); - + } - + @Test public void testValueParserError() throws Exception { var parser = new LineParser(); - parser - .value(4, "part1", (s)->{throw new ValueParseException(s, "Testing");}) - .space(1) - .value(4, "part2", (s)->Float.valueOf(s.strip())+1); - - var ex1 = assertThrows(ValueParseException.class, ()->parser.parseLine(" X 0.5 ")); + parser.value(4, "part1", (s) -> { + throw new ValueParseException(s, "Testing"); + }).space(1).value(4, "part2", (s) -> Float.valueOf(s.strip()) + 1); + + var ex1 = assertThrows(ValueParseException.class, () -> parser.parseLine(" X 0.5 ")); assertThat(ex1, hasProperty("value", is(" X "))); assertThat(ex1, hasProperty("message", is("Testing"))); - + } @Test public void testUnbounded() throws Exception { var parser = new LineParser(); - parser - .string(4, "part1") - .string("part2"); - - var result1 = parser.parseLine("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); - + parser.string(4, "part1").string("part2"); + + var result1 = parser.parseLine( + "123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 " + ); + assertThat(result1, hasEntry("part1", "123 ")); - assertThat(result1, hasEntry("part2", " 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ")); - + assertThat( + result1, + hasEntry( + "part2", + " 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 " + ) + ); + } - + @Test public void testStripped() throws Exception { var parser = new LineParser(); - parser - .strippedString(4, "part1") - .strippedString("part2"); - - var result1 = parser.parseLine("123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "); - + parser.strippedString(4, "part1").strippedString("part2"); + + var result1 = parser.parseLine( + "123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 " + ); + assertThat(result1, hasEntry("part1", "123")); - assertThat(result1, hasEntry("part2", "67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")); - + assertThat( + result1, + hasEntry( + "part2", + "67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" + ) + ); + } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLine() throws Exception { var parser = new LineParser(); - parser - .integer(4, "part1") - .space(1) - .string("part2"); - + parser.integer(4, "part1").space(1).string("part2"); + List> result = new ArrayList<>(); - try( - var is = new ByteArrayInputStream("0042 Value1\r\n0043 Value2".getBytes()); - ) { + try (var is = new ByteArrayInputStream("0042 Value1\r\n0043 Value2".getBytes());) { result = parser.parse(is); } - - assertThat(result, contains( - allOf( - (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1"), - (Matcher)hasEntry(LineParser.LINE_NUMBER_KEY, 1) - ), - allOf( - (Matcher)hasEntry("part1", 43), - (Matcher)hasEntry("part2", "Value2"), - (Matcher)hasEntry(LineParser.LINE_NUMBER_KEY, 2) + + assertThat( + result, + contains( + allOf( + (Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1"), + (Matcher) hasEntry(LineParser.LINE_NUMBER_KEY, 1) + ), + allOf( + (Matcher) hasEntry("part1", 43), (Matcher) hasEntry("part2", "Value2"), + (Matcher) hasEntry(LineParser.LINE_NUMBER_KEY, 2) + ) ) - )); + ); } - + @Test public void testMultiLineException() throws Exception { var parser = new LineParser(); - parser - .integer(4, "part1") - .space(1) - .string("part2"); - - try( - var is = new ByteArrayInputStream("0042 Value1\r\n004x Value2".getBytes()); - ) { - - var ex1 = assertThrows(ResourceParseLineException.class, ()-> parser.parse(is)); - + parser.integer(4, "part1").space(1).string("part2"); + + try (var is = new ByteArrayInputStream("0042 Value1\r\n004x Value2".getBytes());) { + + var ex1 = assertThrows(ResourceParseLineException.class, () -> parser.parse(is)); + assertThat(ex1, hasProperty("line", is(2))); // Line numbers indexed from 1 so the error is line 2 assertThat(ex1, hasProperty("cause", isA(ValueParseException.class))); assertThat(ex1, hasProperty("cause", hasProperty("value", is("004x")))); @@ -215,197 +199,144 @@ public void testMultiLineException() throws Exception { @Test public void testMultiLineWithStopEntry() throws Exception { var parser = new LineParser() { - + @Override public boolean isStopEntry(Map entry) { return 0 == (int) entry.get("part1"); } - + }; - parser - .integer(4, "part1") - .space(1) - .string("part2"); - + parser.integer(4, "part1").space(1).string("part2"); + List> result = new ArrayList<>(); - try( - var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes()); - ) { + try (var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes());) { result = parser.parse(is); } - - assertThat(result, contains( - allOf( - (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1") - ) - )); + + assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLineWithStopLine() throws Exception { var parser = new LineParser() { - + @Override public boolean isStopLine(String line) { - return line.length()>4 && 'X' == Character.toUpperCase(line.charAt(4)); + return line.length() > 4 && 'X' == Character.toUpperCase(line.charAt(4)); } - + }; - parser - .integer(4, "part1") - .space(1) - .string("part2"); - + parser.integer(4, "part1").space(1).string("part2"); + List> result = new ArrayList<>(); - try( - var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); - ) { + try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { result = parser.parse(is); } - - assertThat(result, contains( - allOf( - (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1") - ) - )); + + assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLineWithStopSegment() throws Exception { var parser = new LineParser() { - + @Override public boolean isStopSegment(List segments) { return 'X' == Character.toUpperCase(segments.get(1).charAt(0)); } - + }; - parser - .integer(4, "part1") - .space(1) - .string("part2"); - + parser.integer(4, "part1").space(1).string("part2"); + List> result = new ArrayList<>(); - try( - var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); - ) { + try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { result = parser.parse(is); } - - assertThat(result, contains( - allOf( - (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1") - ) - )); + + assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLineWithIgnoredEntry() throws Exception { var parser = new LineParser() { - + @Override public boolean isIgnoredEntry(Map entry) { return 0 == (int) entry.get("part1"); } - + }; - parser - .integer(4, "part1") - .space(1) - .string("part2"); - + parser.integer(4, "part1").space(1).string("part2"); + List> result = new ArrayList<>(); - try( - var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes()); - ) { + try (var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes());) { result = parser.parse(is); } - - assertThat(result, contains( - allOf( - (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1") - ), - allOf( - (Matcher)hasEntry("part1", 43), - (Matcher)hasEntry("part2", "Value2") + + assertThat( + result, + contains( + allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")), + allOf((Matcher) hasEntry("part1", 43), (Matcher) hasEntry("part2", "Value2")) ) - )); + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLineWithIgnoredLine() throws Exception { var parser = new LineParser() { - + @Override public boolean isIgnoredLine(String line) { - return line.length()>4 && 'X' == Character.toUpperCase(line.charAt(4)); + return line.length() > 4 && 'X' == Character.toUpperCase(line.charAt(4)); } - + }; - parser - .integer(4, "part1") - .space(1) - .string("part2"); - + parser.integer(4, "part1").space(1).string("part2"); + List> result = new ArrayList<>(); - try( - var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); - ) { + try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { result = parser.parse(is); } - - assertThat(result, contains( - allOf( - (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1") - ), - allOf( - (Matcher)hasEntry("part1", 43), - (Matcher)hasEntry("part2", "Value2") + + assertThat( + result, + contains( + allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")), + allOf((Matcher) hasEntry("part1", 43), (Matcher) hasEntry("part2", "Value2")) ) - )); + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLineWithIgnoredSegment() throws Exception { var parser = new LineParser() { - + @Override public boolean isIgnoredSegment(List segments) { return 'X' == Character.toUpperCase(segments.get(1).charAt(0)); } - + }; - parser - .integer(4, "part1") - .space(1) - .string("part2"); - + parser.integer(4, "part1").space(1).string("part2"); + List> result = new ArrayList<>(); - try( - var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes()); - ) { + try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { result = parser.parse(is); } - - assertThat(result, contains( - allOf( - (Matcher)hasEntry("part1", 42), - (Matcher)hasEntry("part2", "Value1") - ), - allOf( - (Matcher)hasEntry("part1", 43), - (Matcher)hasEntry("part2", "Value2") + + assertThat( + result, + contains( + allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")), + allOf((Matcher) hasEntry("part1", 43), (Matcher) hasEntry("part2", "Value2")) ) - )); + ); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index cf2bc9397..0d18da827 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -24,210 +24,215 @@ import ca.bc.gov.nrs.vdyp.model.SP0Definition; public class SP0DefinitionParserTest { - + @Test public void testParse() throws Exception { var parser = new SP0DefinitionParser(); - + var result = parser.parse(ControlFileParserTest.class, "coe/SP0DEF_v0.dat", Collections.emptyMap()); - - assertThat(result, contains( - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AC")), - Matchers.hasProperty("name", equalTo("Cottonwood")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AT")), - Matchers.hasProperty("name", equalTo("Aspen")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("B")), - Matchers.hasProperty("name", equalTo("Balsam")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("C")), - Matchers.hasProperty("name", equalTo("Cedar (X yellow)")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("D")), - Matchers.hasProperty("name", equalTo("Alder")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("E")), - Matchers.hasProperty("name", equalTo("Birch")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("F")), - Matchers.hasProperty("name", equalTo("Douglas Fir")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("H")), - Matchers.hasProperty("name", equalTo("Hemlock")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("L")), - Matchers.hasProperty("name", equalTo("Larch")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("MB")), - Matchers.hasProperty("name", equalTo("Maple")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("PA")), - Matchers.hasProperty("name", equalTo("White-bark pine")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("PL")), - Matchers.hasProperty("name", equalTo("Lodgepole Pine")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("PW")), - Matchers.hasProperty("name", equalTo("White pine")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("PY")), - Matchers.hasProperty("name", equalTo("Yellow pine")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("S")), - Matchers.hasProperty("name", equalTo("Spruce")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("Y")), - Matchers.hasProperty("name", equalTo("Yellow cedar")) + + assertThat( + result, + contains( + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("B")), + Matchers.hasProperty("name", equalTo("Balsam")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("C")), + Matchers.hasProperty("name", equalTo("Cedar (X yellow)")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("D")), + Matchers.hasProperty("name", equalTo("Alder")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("E")), + Matchers.hasProperty("name", equalTo("Birch")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("F")), + Matchers.hasProperty("name", equalTo("Douglas Fir")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("H")), + Matchers.hasProperty("name", equalTo("Hemlock")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("L")), + Matchers.hasProperty("name", equalTo("Larch")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("MB")), + Matchers.hasProperty("name", equalTo("Maple")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PA")), + Matchers.hasProperty("name", equalTo("White-bark pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PL")), + Matchers.hasProperty("name", equalTo("Lodgepole Pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PW")), + Matchers.hasProperty("name", equalTo("White pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PY")), + Matchers.hasProperty("name", equalTo("Yellow pine")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("S")), + Matchers.hasProperty("name", equalTo("Spruce")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("Y")), + Matchers.hasProperty("name", equalTo("Yellow cedar")) ) - - )); + + ) + ); } - + @Test public void testOrderByPreference() throws Exception { var parser = new SP0DefinitionParser(2); - + List result; - try( - var is = new ByteArrayInputStream("AT Aspen 02\r\nAC Cottonwood 01".getBytes()); + try ( + var is = new ByteArrayInputStream( + "AT Aspen 02\r\nAC Cottonwood 01".getBytes() + ); ) { result = parser.parse(is, Collections.emptyMap()); } - assertThat(result, contains( - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AC")), - Matchers.hasProperty("name", equalTo("Cottonwood")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AT")), - Matchers.hasProperty("name", equalTo("Aspen")) + assertThat( + result, + contains( + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) ) - )); + ) + ); } - + @Test public void testOrderByLinesBlank() throws Exception { var parser = new SP0DefinitionParser(2); - + List result; - try( - var is = new ByteArrayInputStream("AT Aspen \r\nAC Cottonwood ".getBytes()); + try ( + var is = new ByteArrayInputStream( + "AT Aspen \r\nAC Cottonwood ".getBytes() + ); ) { result = parser.parse(is, Collections.emptyMap()); } - assertThat(result, contains( - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AT")), - Matchers.hasProperty("name", equalTo("Aspen")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AC")), - Matchers.hasProperty("name", equalTo("Cottonwood")) + assertThat( + result, + contains( + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) ) - )); + ) + ); } - + @Test public void testOrderByLinesZero() throws Exception { var parser = new SP0DefinitionParser(2); - + List result; - try( - var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood 00".getBytes()); + try ( + var is = new ByteArrayInputStream( + "AT Aspen 00\r\nAC Cottonwood 00".getBytes() + ); ) { result = parser.parse(is, Collections.emptyMap()); } - assertThat(result, contains( - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AT")), - Matchers.hasProperty("name", equalTo("Aspen")) - ), - allOf( - Matchers.instanceOf(SP0Definition.class), - Matchers.hasProperty("alias", equalTo("AC")), - Matchers.hasProperty("name", equalTo("Cottonwood")) + assertThat( + result, + contains( + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.hasProperty("name", equalTo("Aspen")) + ), + allOf( + Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.hasProperty("name", equalTo("Cottonwood")) ) - )); + ) + ); } - + @Test public void testErrorPreferenceOutOfBoundsHigh() throws Exception { var parser = new SP0DefinitionParser(2); - + Exception ex1; - try( - var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood 03".getBytes()); + try ( + var is = new ByteArrayInputStream( + "AT Aspen 00\r\nAC Cottonwood 03".getBytes() + ); ) { - - ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.emptyMap())); + + ex1 = Assertions + .assertThrows(ResourceParseLineException.class, () -> parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 3", "larger than 2"))); } - + @Test public void testErrorPreferenceOutOfBoundsLow() throws Exception { var parser = new SP0DefinitionParser(2); - + Exception ex1; - try( - var is = new ByteArrayInputStream("AT Aspen 00\r\nAC Cottonwood -1".getBytes()); + try ( + var is = new ByteArrayInputStream( + "AT Aspen 00\r\nAC Cottonwood -1".getBytes() + ); ) { - - ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.emptyMap())); + + ex1 = Assertions + .assertThrows(ResourceParseLineException.class, () -> parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference -1", "less than 0"))); } - + @Test public void testErrorPreferenceDuplicate() throws Exception { var parser = new SP0DefinitionParser(2); - + Exception ex1; - try( - var is = new ByteArrayInputStream("AT Aspen 01\r\nAC Cottonwood 01".getBytes()); + try ( + var is = new ByteArrayInputStream( + "AT Aspen 01\r\nAC Cottonwood 01".getBytes() + ); ) { - - ex1 = Assertions.assertThrows(ResourceParseLineException.class, ()->parser.parse(is, Collections.emptyMap())); + + ex1 = Assertions + .assertThrows(ResourceParseLineException.class, () -> parser.parse(is, Collections.emptyMap())); } assertThat(ex1, hasProperty("line", is(2))); assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 1", "set to AT"))); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java new file mode 100644 index 000000000..5ce249134 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java @@ -0,0 +1,129 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.anEmptyMap; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class SiteCurveParserTest { + + @Test + public void testSimple() throws Exception { + var parser = new SiteCurveParser(); + var is = TestUtils.makeStream("S1 001002"); + + Map controlMap = new HashMap<>(); + List sp0List = new ArrayList<>(); + + sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var result = parser.parse(is, controlMap); + + assertThat(result, hasEntry(is("S1"), allOf(hasProperty("value1", is(1)), hasProperty("value2", is(2))))); + } + + @Test + public void testExtraSpecies() throws Exception { + var parser = new SiteCurveParser(); + var is = TestUtils.makeStream("S1 001002", "X2 003004"); + + Map controlMap = new HashMap<>(); + List sp0List = new ArrayList<>(); + + sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var result = parser.parse(is, controlMap); + + assertThat(result, hasEntry(is("S1"), allOf(hasProperty("value1", is(1)), hasProperty("value2", is(2))))); + assertThat(result, hasEntry(is("X2"), allOf(hasProperty("value1", is(3)), hasProperty("value2", is(4))))); + } + + @Test + public void testMissingSpecies() throws Exception { + var parser = new SiteCurveParser(); + var is = TestUtils.makeStream("S1 001002"); + + Map controlMap = new HashMap<>(); + List sp0List = new ArrayList<>(); + + sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + sp0List.add(new SP0Definition("S2", java.util.Optional.empty(), "Test Species 2")); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var ex = assertThrows(ResourceParseValidException.class, () -> parser.parse(is, controlMap)); + + assertThat(ex, hasProperty("message", is("Missing expected entries for S2"))); + } + + @Test + public void testHashComment() throws Exception { + var parser = new SiteCurveParser(); + var is = TestUtils.makeStream("# Foo", "S1 001002"); + + Map controlMap = new HashMap<>(); + List sp0List = new ArrayList<>(); + + sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var result = parser.parse(is, controlMap); + + assertThat(result, hasEntry(is("S1"), allOf(hasProperty("value1", is(1)), hasProperty("value2", is(2))))); + } + + @Test + public void testSpaceComment() throws Exception { + var parser = new SiteCurveParser(); + var is = TestUtils.makeStream(" Foo", "S1 001002"); + + Map controlMap = new HashMap<>(); + List sp0List = new ArrayList<>(); + + sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var result = parser.parse(is, controlMap); + + assertThat(result, hasEntry(is("S1"), allOf(hasProperty("value1", is(1)), hasProperty("value2", is(2))))); + } + + @Test + public void testEndFileLine() throws Exception { + var parser = new SiteCurveParser(); + var is = TestUtils.makeStream("S1 001002", "##", "S2 003004"); + + Map controlMap = new HashMap<>(); + List sp0List = new ArrayList<>(); + + sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var result = parser.parse(is, controlMap); + + assertThat(result, hasEntry(is("S1"), allOf(hasProperty("value1", is(1)), hasProperty("value2", is(2))))); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java index 62db9ebfd..254db4994 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java @@ -21,48 +21,68 @@ public class StockingClassFactorParserTest { public void testEmpty() throws Exception { var parser = new StockingClassFactorParser(); var is = TestUtils.makeStream(""); - + var result = parser.parse(is, Collections.emptyMap()); - + assertThat(result, anEmptyMap()); } - + @Test public void testSimple() throws Exception { var parser = new StockingClassFactorParser(); var is = TestUtils.makeStream("R I P 0 1.00 100", "Z Z P 0 1.00 100"); - + var result = parser.parse(is, Collections.emptyMap()); - - assertThat(result, - hasEntry(is('R') - , hasEntry(is(Region.INTERIOR), - allOf(hasProperty("factor", is(1.0f)), - allOf(hasProperty("npctArea", is(100))))))); + + assertThat( + result, + hasEntry( + is('R'), + hasEntry( + is(Region.INTERIOR), + allOf(hasProperty("factor", is(1.0f)), allOf(hasProperty("npctArea", is(100)))) + ) + ) + ); } - + @Test public void testMultiple() throws Exception { var parser = new StockingClassFactorParser(); - try(var is = StockingClassFactorParserTest.class.getResourceAsStream("coe/FIPSTKR.PRM")) { - + try (var is = StockingClassFactorParserTest.class.getResourceAsStream("coe/FIPSTKR.PRM")) { + var result = parser.parse(is, Collections.emptyMap()); - - assertThat(result, - hasEntry(is('R') - , hasEntry(is(Region.INTERIOR), - allOf(hasProperty("factor", is(1.0f)), - allOf(hasProperty("npctArea", is(100))))))); - assertThat(result, - hasEntry(is('R') - , hasEntry(is(Region.COASTAL), - allOf(hasProperty("factor", is(1.0f)), - allOf(hasProperty("npctArea", is(100))))))); - assertThat(result, - hasEntry(is('4') - , hasEntry(is(Region.COASTAL), - allOf(hasProperty("factor", is(1.0f)), - allOf(hasProperty("npctArea", is(100))))))); + + assertThat( + result, + hasEntry( + is('R'), + hasEntry( + is(Region.INTERIOR), + allOf(hasProperty("factor", is(1.0f)), allOf(hasProperty("npctArea", is(100)))) + ) + ) + ); + assertThat( + result, + hasEntry( + is('R'), + hasEntry( + is(Region.COASTAL), + allOf(hasProperty("factor", is(1.0f)), allOf(hasProperty("npctArea", is(100)))) + ) + ) + ); + assertThat( + result, + hasEntry( + is('4'), + hasEntry( + is(Region.COASTAL), + allOf(hasProperty("factor", is(1.0f)), allOf(hasProperty("npctArea", is(100)))) + ) + ) + ); } } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java index ea7785a58..314b1cdb4 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java @@ -4,8 +4,8 @@ import java.io.InputStream; public class TestUtils { - - public static InputStream makeStream(String...lines) { + + public static InputStream makeStream(String... lines) { return new ByteArrayInputStream(String.join("\r\n", lines).getBytes()); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index 44193c7e5..f5cc3c216 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -1,6 +1,10 @@ package ca.bc.gov.nrs.vdyp.test; +import static org.hamcrest.Matchers.anything; import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.not; + +import java.util.Optional; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; @@ -12,16 +16,18 @@ /** * Custom Hamcrest Matchers - * + * * @author Kevin Smith, Vivid Solutions * */ public class VdypMatchers { - + /** - * Matches a string if when parsed by the parser method it matches the given matcher + * Matches a string if when parsed by the parser method it matches the given + * matcher + * * @param parsedMatcher matcher for the parsed value - * @param parser parser + * @param parser parser * @return */ public static Matcher parseAs(Matcher parsedMatcher, ValueParser parser) { @@ -41,29 +47,110 @@ public void describeTo(Description description) { description.appendText("parses as "); parsedMatcher.describeTo(description); } - + }; } - + /** * Matcher for the cause of an exception + * * @param causeMatcher * @return */ public static Matcher causedBy(Matcher causeMatcher) { - + return new BaseMatcher() { @Override public boolean matches(Object actual) { - return causeMatcher.matches(((Throwable) actual).getCause()); + return causeMatcher.matches( ((Throwable) actual).getCause()); } @Override public void describeTo(Description description) { description.appendText("was caused by exception that ").appendDescriptionOf(causeMatcher); } - + + }; + } + + /** + * Matches an Optional if it is present and its value matches the given matcher + * + * @param delegate matcher for the optional's value + * @return + */ + public static Matcher> present(Matcher delegate) { + return new BaseMatcher>() { + + @SuppressWarnings("unchecked") + @Override + public boolean matches(Object actual) { + if (! (actual instanceof Optional)) { + return false; + } + if (! ((Optional) actual).isPresent()) { + return false; + } + return delegate.matches( ((Optional) actual).get()); + } + + @Override + public void describeTo(Description description) { + description.appendText("Optional that "); + delegate.describeTo(description); + } + + @Override + public void describeMismatch(Object item, Description description) { + if (! (item instanceof Optional)) { + description.appendText("Not an Optional"); + return; + } + if (! ((Optional) item).isPresent()) { + description.appendText("Not present"); + return; + } + delegate.describeMismatch(item, description); + } + }; } + + /** + * Matches an Optional if it is not present + * + * @return + */ + public static Matcher> notPresent() { + return new BaseMatcher>() { + + @Override + public boolean matches(Object actual) { + if (! (actual instanceof Optional)) { + return false; + } + return ! ((Optional) actual).isPresent(); + } + + @Override + public void describeTo(Description description) { + description.appendText("Optional that is empty"); + } + + @Override + public void describeMismatch(Object item, Description description) { + if (! (item instanceof Optional)) { + description.appendText("was not an Optional"); + return; + } + if (! ((Optional) item).isPresent()) { + description.appendText("was not present"); + return; + } + } + + }; + } + } diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index ad1fd88ad..acb2be689 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -22,13 +22,13 @@ 021 coe/DGRP.DAT Defines Decay Groups RD_DGRP 022 coe/BGRP.DAT Defines Breakage Groups RD_BGRP IPSJF157 -025 coe/SIEQN.prm Site Curve Numbers (SCN) assigned RD_E025 +025 coe/SIEQN.PRM Site Curve Numbers (SCN) assigned RD_E025 025 Nullifies above siteCurve # 026 coe/SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 030 coe/GRPBA1.DAT Default Eq # BA=f(CC) RD_GRBA1 031 coe/GMODBA1.DAT Eqn modifiers for above RD_GMBA1 -033 coe/fipstkr.prm Stocking class factors RD_STK33 +033 coe/FIPSTKR.PRM Stocking class factors RD_STK33 040 coe/regba25.coe Coe BA=f(CC) RD_E040 IPSJF128 041 coe/regdq26.coe Coe DQ=f(CC) RD_E041 IPSJF129 diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIEQN.PRM b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIEQN.PRM index 0aa0b037c..df22d8837 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIEQN.PRM +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/coe/SIEQN.PRM @@ -1,4 +1,28 @@ +# These are arbitrary values to test parsing +# SP0 mappings +AC 10 42 +AT 10 42 +B 12 42 +C 2 42 +D 42 10 +E 10 10 +F 10 10 +H 10 10 +L 10 10 +MB 10 10 +PA 10 10 +PL 10 10 +PW 10 10 +PY 10 10 +S 10 10 +Y 10 10 + +# additional non-SP0 values +XXX 10 30 +YYY 42 06 ## Start of unrestricted comments +This should be ignored +ZZZ 42 06 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index d2a11f286..b691f0a3b 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -8,11 +8,13 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveParser; import ca.bc.gov.nrs.vdyp.io.parse.StockingClassFactorParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; @@ -38,7 +40,7 @@ public class FipControlParser { public static final String VOLUME_EQN_GROUPS = EquationGroupParser.VOLUME_CONTROL_KEY; public static final String DECAY_GROUPS = EquationGroupParser.DECAY_CONTROL_KEY; public static final String BREAKAGE_GROUPS = EquationGroupParser.BREAKAGE_CONTROL_KEY; - public static final String SITE_CURVE_NUMBERS = "SITE_CURVE_NUMBERS"; + public static final String SITE_CURVE_NUMBERS = SiteCurveParser.CONTROL_KEY; public static final String SITE_CURVE_AGE_MAX = "SITE_CURVE_AGE_MAX"; public static final String DEFAULT_EQ_NUM = EquationGroupParser.DEFAULT_CONTROL_KEY; public static final String EQN_MODIFIERS = EquationModifierParser.CONTROL_KEY; @@ -95,8 +97,8 @@ public class FipControlParser { .record( 21, DECAY_GROUPS, FILENAME) // RD_DGRP .record( 22, BREAKAGE_GROUPS, FILENAME) // RD_BGRP IPSJF157 - .record( 25, SITE_CURVE_NUMBERS, FILENAME) // RD_E025 - .record( 26, SITE_CURVE_AGE_MAX, FILENAME) // RD_E026 + .record( 25, SITE_CURVE_NUMBERS, ValueParser.optional(FILENAME)) // RD_E025 + .record( 26, SITE_CURVE_AGE_MAX, FILENAME) // RD_E026 .record( 30, DEFAULT_EQ_NUM, FILENAME) // RD_GRBA1 .record( 31, EQN_MODIFIERS, FILENAME) // RD_GMBA1 @@ -240,12 +242,13 @@ public String toString(String filename) throws IOException { // User-assigned SC's (Site Curve Numbers) // // RD_E025 - // TODO + loadDataOptional(map, SITE_CURVE_NUMBERS, fileResolver, this::RD_E025); // Max tot ages to apply site curves (by SC) // // RD_E026 // TODO + // loadDataOptional(map, SITE_CURVE_AGE_MAX, fileResolver, this::RD_E026); // Coeff for Empirical relationships @@ -422,6 +425,18 @@ void loadData(Map map, String key, FileResolver fileResolver, Re map.put(key, parser.parse(is, map)); } } + void loadDataOptional(Map map, String key, FileResolver fileResolver, ResourceParser parser) throws IOException, ResourceParseException { + @SuppressWarnings("unchecked") + Optional path = (Optional) map.get(key); + if(!path.isPresent()) { + // TODO Log + map.put(key, Collections.emptyMap()); + return; + } + try(var is = fileResolver.resolve(path.get())) { + map.put(key, parser.parse(is, map)); + } + } /** * Loads the information that was in the global arrays BECV, BECNM, and BECCOASTAL in Fortran @@ -489,6 +504,21 @@ private Object RD_STK33(InputStream data, Map control) throws IO return parser.parse(data, control); } + /** + * Loads the information that was in the global arrays ISCURVE and SP_SCV in Fortran + */ + private Object RD_E025(InputStream data, Map control) throws IOException, ResourceParseException { + var parser = new SiteCurveParser(); + return parser.parse(data, control); + } + + /** + * Loads the information that was in the global V7COE026 arrays ASITELIM, T1SITELIM, T2SITELIM in Fortran + */ + private Object RD_E026(InputStream data, Map control) throws IOException, ResourceParseException { + return null; + } + static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 3614e9359..17f14a239 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -13,13 +13,17 @@ import org.hamcrest.Matcher; import org.hamcrest.Matchers; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.SiteCurve; +import ca.bc.gov.nrs.vdyp.model.StockingClassFactor; @SuppressWarnings("unused") public class FipControlParserTest { @@ -153,4 +157,52 @@ public void testParseGMBA1() throws Exception { isA(Integer.class) // Reassigned Equation )))))); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSTK33() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.STOCKING_CLASS_FACTORS), + allOf( // STK + isA(Map.class), + hasEntry( + isA(Character.class), + allOf( // Region + isA(Map.class), + hasEntry( + isA(Region.class), + isA(StockingClassFactor.class) // Factors + )))))); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + @Disabled + public void testParseE025() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.SITE_CURVE_NUMBERS), + allOf( // Species + isA(Map.class), + hasEntry( + isA(String.class), + isA(SiteCurve.class) + )))); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE025Empty() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat(result, (Matcher) + hasEntry( + is(FipControlParser.SITE_CURVE_NUMBERS), + Matchers.anEmptyMap() + )); + } } From 4b1a0fbe77666b21f86335c7a4d01e9f7d58f2c7 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 18 May 2023 15:31:05 -0700 Subject: [PATCH 19/98] Site curve age max loading --- vdyp-core/pom.xml | 11 + .../io/parse/SiteCurveAgeMaximumParser.java | 89 ++++ .../nrs/vdyp/model/SiteCurveAgeMaximum.java | 41 ++ .../parse/SiteCurveAgeMaximumParserTest.java | 129 +++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 495 +++++++++--------- .../nrs/vdyp/fip/FipControlParserTest.java | 293 +++++++---- 7 files changed, 711 insertions(+), 349 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurveAgeMaximum.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java diff --git a/vdyp-core/pom.xml b/vdyp-core/pom.xml index 7df41334a..44e340738 100644 --- a/vdyp-core/pom.xml +++ b/vdyp-core/pom.xml @@ -48,6 +48,17 @@ + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java new file mode 100644 index 000000000..311bc9441 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java @@ -0,0 +1,89 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; + +/** + * Parses a Site curve maximum age data file. + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class SiteCurveAgeMaximumParser implements ResourceParser> { + public static final String CONTROL_KEY = "SITE_CURVE_AGE_MAX"; + + public static final String SC_KEY = "siteCurve"; + public static final String COASTAL_KEY = "coastalAgeMax"; + public static final String INTERIOR_KEY = "interiorAgeMax"; + public static final String T1_KEY = "t1"; + public static final String T2_KEY = "t2"; + + private static final float MAX_AGE = 1999.0f; + private static final int MAX_SC = 40; + + private static final float DEFAULT_AGE = 140.0f; + private static final float DEFAULT_T1 = 0.0f; + private static final float DEFAULT_T2 = 0.0f; + + public static final int DEFAULT_SC = 140; + + LineParser lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith("999"); + } + + }.value(3, SC_KEY, PARSE_SC).value(7, COASTAL_KEY, PARSE_AGE).value(7, INTERIOR_KEY, PARSE_AGE) + .value(7, T1_KEY, PARSE_AGE).value(7, T2_KEY, PARSE_AGE); + + static ValueParser PARSE_SC = ValueParser.validate(ValueParser.INTEGER, v -> { + if (v < -1 || v > MAX_SC) { + return Optional.of("Site curve number must be in the range -1 to " + MAX_SC + " inclusive"); + } + return Optional.empty(); + }); + + static ValueParser PARSE_AGE = s -> { + var value = ValueParser.FLOAT.parse(s); + return value <= 0.0 ? MAX_AGE : value; + }; + + @SuppressWarnings("serial") + public static Map defaultMap() { + return new HashMap<>() { + @Override + public SiteCurveAgeMaximum get(Object key) { + return containsKey(key) ? super.get(key) + : new SiteCurveAgeMaximum(DEFAULT_AGE, DEFAULT_AGE, DEFAULT_T1, DEFAULT_T2); + } + }; + } + + @Override + public Map parse(InputStream is, Map control) + throws IOException, ResourceParseException { + Map result = defaultMap(); + lineParser.parse(is, result, (v, r) -> { + var sc = (int) v.get(SC_KEY); + var ageCoast = (float) v.get(COASTAL_KEY); + var ageInt = (float) v.get(INTERIOR_KEY); + var t1 = (float) v.get(T1_KEY); + var t2 = (float) v.get(T2_KEY); + + if (sc <= -1) + sc = DEFAULT_SC; + + r.put(sc, new SiteCurveAgeMaximum(ageCoast, ageInt, t1, t2)); + + return r; + }); + return result; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurveAgeMaximum.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurveAgeMaximum.java new file mode 100644 index 000000000..2fb8a0932 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SiteCurveAgeMaximum.java @@ -0,0 +1,41 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.HashMap; +import java.util.Map; + +public class SiteCurveAgeMaximum { + final Map ageMaximums; + final float t1; + final float t2; + + public SiteCurveAgeMaximum(float ageCoast, float ageInt, float t1, float t2) { + this(maximums(ageCoast, ageInt), t1, t2); + } + + private static Map maximums(float ageCoast, float ageInt) { + var result = new HashMap(); + result.put(Region.COASTAL, ageCoast); + result.put(Region.INTERIOR, ageInt); + return result; + } + + public SiteCurveAgeMaximum(Map ageMaximums, float t1, float t2) { + super(); + this.ageMaximums = new HashMap<>(ageMaximums); + this.t1 = t1; + this.t2 = t2; + } + + public float getAgeMaximum(Region region) { + return ageMaximums.get(region); + } + + public float getT1() { + return t1; + } + + public float getT2() { + return t2; + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java new file mode 100644 index 000000000..d283b3946 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java @@ -0,0 +1,129 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; + +import java.util.HashMap; +import java.util.Map; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class SiteCurveAgeMaximumParserTest { + + @Test + public void testSimple() throws Exception { + var parser = new SiteCurveAgeMaximumParser(); + var is = TestUtils.makeStream(" 16 150.0 150.0 20.0 60.0"); + + Map controlMap = new HashMap<>(); + + var result = parser.parse(is, controlMap); + + assertThat( + result, + hasEntry( + is(16), + allOf( + hasAge(Region.COASTAL, is(150.0f)), hasAge(Region.INTERIOR, is(150.0f)), + hasProperty("t1", is(20.0f)), hasProperty("t2", is(60.0f)) + ) + ) + ); + } + + @Test + public void testDefault() throws Exception { + var parser = new SiteCurveAgeMaximumParser(); + var is = TestUtils.makeStream(" -1 150.0 150.0 20.0 60.0"); + + Map controlMap = new HashMap<>(); + + var result = parser.parse(is, controlMap); + + assertThat( + result, + hasEntry( + is(SiteCurveAgeMaximumParser.DEFAULT_SC), + allOf( + hasAge(Region.COASTAL, is(150.0f)), hasAge(Region.INTERIOR, is(150.0f)), + hasProperty("t1", is(20.0f)), hasProperty("t2", is(60.0f)) + ) + ) + ); + } + + @Test + public void testEndLine() throws Exception { + var parser = new SiteCurveAgeMaximumParser(); + var is = TestUtils.makeStream( + " -1 150.0 150.0 20.0 60.0", "999 End of usuable info", + " 42 160.0 145.0 25.0 65.0" + ); + + Map controlMap = new HashMap<>(); + + var result = parser.parse(is, controlMap); + + assertThat( + result, + hasEntry( + is(SiteCurveAgeMaximumParser.DEFAULT_SC), + allOf( + hasAge(Region.COASTAL, is(150.0f)), hasAge(Region.INTERIOR, is(150.0f)), + hasProperty("t1", is(20.0f)), hasProperty("t2", is(60.0f)) + ) + ) + ); + assertThat(result, Matchers.aMapWithSize(1)); + + } + + @Test + public void testDefaultValue() throws Exception { + var parser = new SiteCurveAgeMaximumParser(); + var is = TestUtils.makeStream(" 16 150.0 150.0 20.0 60.0"); + + Map controlMap = new HashMap<>(); + + var map = parser.parse(is, controlMap); + + var result = map.get(27); + + assertThat( + result, + allOf( + hasAge(Region.COASTAL, is(140.0f)), hasAge(Region.INTERIOR, is(140.0f)), + hasProperty("t1", is(0.0f)), hasProperty("t2", is(0.0f)) + ) + ); + } + + public static Matcher hasAge(Region region, Matcher delegate) { + return new BaseMatcher() { + + @Override + public boolean matches(Object actual) { + var max = (SiteCurveAgeMaximum) actual; + return delegate.matches(max.getAgeMaximum(region)); + } + + @Override + public void describeTo(Description description) { + description.appendText("has age for ").appendValue(region).appendText(" that "); + delegate.describeTo(description); + } + + }; + } +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index acb2be689..e0bb1944a 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -24,7 +24,7 @@ 025 coe/SIEQN.PRM Site Curve Numbers (SCN) assigned RD_E025 025 Nullifies above siteCurve # -026 coe/SIAGEMAX.prm Max ages for ht incr, by SCN RD_E026 +026 coe/SIAGEMAX.PRM Max ages for ht incr, by SCN RD_E026 030 coe/GRPBA1.DAT Default Eq # BA=f(CC) RD_GRBA1 031 coe/GMODBA1.DAT Eqn modifiers for above RD_GMBA1 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index b691f0a3b..71a150503 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -9,11 +9,13 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Supplier; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveParser; import ca.bc.gov.nrs.vdyp.io.parse.StockingClassFactorParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; @@ -21,16 +23,18 @@ import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; /** * Parser for FIP control files - * + * * @author Kevin Smith, Vivid Solutions * */ public class FipControlParser { - + public static final String FIP_YIELD_POLY_INPUT = "FIP_YIELD_POLY_INPUT"; public static final String FIP_YIELD_LAYER_INPUT = "FIP_YIELD_LAYER_INPUT"; public static final String FIP_YIELD_LX_SP0_INPUT = "FIP_YIELD_LxSP0_INPUT"; @@ -41,7 +45,7 @@ public class FipControlParser { public static final String DECAY_GROUPS = EquationGroupParser.DECAY_CONTROL_KEY; public static final String BREAKAGE_GROUPS = EquationGroupParser.BREAKAGE_CONTROL_KEY; public static final String SITE_CURVE_NUMBERS = SiteCurveParser.CONTROL_KEY; - public static final String SITE_CURVE_AGE_MAX = "SITE_CURVE_AGE_MAX"; + public static final String SITE_CURVE_AGE_MAX = SiteCurveAgeMaximumParser.CONTROL_KEY; public static final String DEFAULT_EQ_NUM = EquationGroupParser.DEFAULT_CONTROL_KEY; public static final String EQN_MODIFIERS = EquationModifierParser.CONTROL_KEY; public static final String STOCKING_CLASS_FACTORS = StockingClassFactorParser.CONTROL_KEY; @@ -78,86 +82,84 @@ public class FipControlParser { public static final String SP0_DEF = SP0DefinitionParser.CONTROL_KEY; static final ValueParser FILENAME = String::strip; - - ControlFileParser controlParser = new ControlFileParser() - .record( 1, MAX_NUM_POLY, ValueParser.INTEGER) - - .record( 9, BEC_DEF, FILENAME) // RD_BECD - .record( 10, SP0_DEF, FILENAME) // RD_SP0 - - .record( 11, FIP_YIELD_POLY_INPUT, FILENAME) // GET_FIPP - .record( 12, FIP_YIELD_LAYER_INPUT, FILENAME) // GET_FIPL - .record( 13, FIP_YIELD_LX_SP0_INPUT, FILENAME) // GET_FIPS - - .record( 15, VDYP_POLYGON, FILENAME) // - .record( 16, VDYP_LAYER_BY_SPECIES, FILENAME) // - .record( 18, VDYP_LAYER_BY_SP0_BY_UTIL, FILENAME) // - - .record( 20, VOLUME_EQN_GROUPS, FILENAME) // RD_VGRP - .record( 21, DECAY_GROUPS, FILENAME) // RD_DGRP - .record( 22, BREAKAGE_GROUPS, FILENAME) // RD_BGRP IPSJF157 - - .record( 25, SITE_CURVE_NUMBERS, ValueParser.optional(FILENAME)) // RD_E025 - .record( 26, SITE_CURVE_AGE_MAX, FILENAME) // RD_E026 - - .record( 30, DEFAULT_EQ_NUM, FILENAME) // RD_GRBA1 - .record( 31, EQN_MODIFIERS, FILENAME) // RD_GMBA1 - .record( 33, STOCKING_CLASS_FACTORS, FILENAME) // RD_STK33 - - .record( 40, COE_BA, FILENAME) // RD_E040 IPSJF128 - .record( 41, COE_DQ, FILENAME) // RD_E041 IPSJF129 - .record( 43, UPPER_BA_BY_CI_S0_P, FILENAME) // RD_E043 IPSJF128 - - .record( 50, HL_PRIMARY_SP_EQN_P1, FILENAME) // RD_YHL1 - .record( 51, HL_PRIMARY_SP_EQN_P2, FILENAME) // RD_YHL2 - .record( 52, HL_PRIMARY_SP_EQN_P3, FILENAME) // RD_YHL3 - .record( 53, HL_NONPRIMARY, FILENAME) // RD_YHL4 - - .record( 60, BY_SPECIES_DQ, FILENAME) // RD_E060 IPFJF125 - .record( 61, SPECIES_COMPONENT_SIZE_LIMIT, FILENAME) // RD_E061 IPSJF158 - - .record( 70, UTIL_COMP_BA, FILENAME) // RD_UBA1 - .record( 71, UTIL_COMP_DQ, FILENAME) // RD_UDQ1 - - .record( 80, SMALL_COMP_PROBABILITY, FILENAME) // RD_SBA1 - .record( 81, SMALL_COMP_BA, FILENAME) // RD_SBA2 - .record( 82, SMALL_COMP_DQ, FILENAME) // RD_SDQ1 - .record( 85, SMALL_COMP_HL, FILENAME) // RD_SHL1 - .record( 86, SMALL_COMP_WS_VOLUME, FILENAME) // RD_SVT1 - - .record( 90, TOTAL_STAND_WHOLE_STEM_VOL, FILENAME) // RD_YVT1 IPSJF117 - .record( 91, UTIL_COMP_WS_VOLUME, FILENAME) // RD_YVT2 IPSJF121 - .record( 92, CLOSE_UTIL_VOLUME, FILENAME) // RD_YVC1 IPSJF122 - .record( 93, VOLUME_NET_DECAY, FILENAME) // RD_YVD1 IPSJF123 - .record( 94, VOLUME_NET_DECAY_WASTE, FILENAME) // RD_YVW1 IPSJF123 - .record( 95, BREAKAGE, FILENAME) // RD_EMP95 IPSJF157 - - .record( 96, VETERAN_LAYER_VOLUME_ADJUST, FILENAME) // RD_YVET - .record( 97, VETERAN_LAYER_DQ, FILENAME) // RD_YDQV - .record( 98, VETERAN_BQ, FILENAME) // RD_E098 - - .record(197, MINIMA, ValueParser.list(ValueParser.FLOAT)) // Minimum Height, Minimum BA, Min BA fully stocked. - - .record(198, MODIFIER_FILE, FILENAME) // RD_E198 IPSJF155, XII - - .record(199, DEBUG_SWITCHES, ValueParser.list(ValueParser.INTEGER)) // IPSJF155 - /* - Debug switches (25) 0=default See IPSJF155, App IX - 1st: 1: Do NOT apply BA limits from SEQ043 - 2nd: 1: Do NOT apply DQ limits from SEQ043 - 4th: Future Development. Choice of upper limits - 9th: 0: Normal - Suppress MATH77 error messages. - 1: show some MATH77 errors; 2: show all. - 22nd 1: extra preference for preferred sp (SEQ 010). - */ - - ; - + + ControlFileParser controlParser = new ControlFileParser().record(1, MAX_NUM_POLY, ValueParser.INTEGER) + + .record(9, BEC_DEF, FILENAME) // RD_BECD + .record(10, SP0_DEF, FILENAME) // RD_SP0 + + .record(11, FIP_YIELD_POLY_INPUT, FILENAME) // GET_FIPP + .record(12, FIP_YIELD_LAYER_INPUT, FILENAME) // GET_FIPL + .record(13, FIP_YIELD_LX_SP0_INPUT, FILENAME) // GET_FIPS + + .record(15, VDYP_POLYGON, FILENAME) // + .record(16, VDYP_LAYER_BY_SPECIES, FILENAME) // + .record(18, VDYP_LAYER_BY_SP0_BY_UTIL, FILENAME) // + + .record(20, VOLUME_EQN_GROUPS, FILENAME) // RD_VGRP + .record(21, DECAY_GROUPS, FILENAME) // RD_DGRP + .record(22, BREAKAGE_GROUPS, FILENAME) // RD_BGRP IPSJF157 + + .record(25, SITE_CURVE_NUMBERS, ValueParser.optional(FILENAME)) // RD_E025 + .record(26, SITE_CURVE_AGE_MAX, ValueParser.optional(FILENAME)) // RD_E026 + + .record(30, DEFAULT_EQ_NUM, FILENAME) // RD_GRBA1 + .record(31, EQN_MODIFIERS, FILENAME) // RD_GMBA1 + .record(33, STOCKING_CLASS_FACTORS, FILENAME) // RD_STK33 + + .record(40, COE_BA, FILENAME) // RD_E040 IPSJF128 + .record(41, COE_DQ, FILENAME) // RD_E041 IPSJF129 + .record(43, UPPER_BA_BY_CI_S0_P, FILENAME) // RD_E043 IPSJF128 + + .record(50, HL_PRIMARY_SP_EQN_P1, FILENAME) // RD_YHL1 + .record(51, HL_PRIMARY_SP_EQN_P2, FILENAME) // RD_YHL2 + .record(52, HL_PRIMARY_SP_EQN_P3, FILENAME) // RD_YHL3 + .record(53, HL_NONPRIMARY, FILENAME) // RD_YHL4 + + .record(60, BY_SPECIES_DQ, FILENAME) // RD_E060 IPFJF125 + .record(61, SPECIES_COMPONENT_SIZE_LIMIT, FILENAME) // RD_E061 IPSJF158 + + .record(70, UTIL_COMP_BA, FILENAME) // RD_UBA1 + .record(71, UTIL_COMP_DQ, FILENAME) // RD_UDQ1 + + .record(80, SMALL_COMP_PROBABILITY, FILENAME) // RD_SBA1 + .record(81, SMALL_COMP_BA, FILENAME) // RD_SBA2 + .record(82, SMALL_COMP_DQ, FILENAME) // RD_SDQ1 + .record(85, SMALL_COMP_HL, FILENAME) // RD_SHL1 + .record(86, SMALL_COMP_WS_VOLUME, FILENAME) // RD_SVT1 + + .record(90, TOTAL_STAND_WHOLE_STEM_VOL, FILENAME) // RD_YVT1 IPSJF117 + .record(91, UTIL_COMP_WS_VOLUME, FILENAME) // RD_YVT2 IPSJF121 + .record(92, CLOSE_UTIL_VOLUME, FILENAME) // RD_YVC1 IPSJF122 + .record(93, VOLUME_NET_DECAY, FILENAME) // RD_YVD1 IPSJF123 + .record(94, VOLUME_NET_DECAY_WASTE, FILENAME) // RD_YVW1 IPSJF123 + .record(95, BREAKAGE, FILENAME) // RD_EMP95 IPSJF157 + + .record(96, VETERAN_LAYER_VOLUME_ADJUST, FILENAME) // RD_YVET + .record(97, VETERAN_LAYER_DQ, FILENAME) // RD_YDQV + .record(98, VETERAN_BQ, FILENAME) // RD_E098 + + .record(197, MINIMA, ValueParser.list(ValueParser.FLOAT)) // Minimum Height, Minimum BA, Min BA fully + // stocked. + + .record(198, MODIFIER_FILE, FILENAME) // RD_E198 IPSJF155, XII + + .record(199, DEBUG_SWITCHES, ValueParser.list(ValueParser.INTEGER)) // IPSJF155 + /* + * Debug switches (25) 0=default See IPSJF155, App IX 1st: 1: Do NOT apply BA + * limits from SEQ043 2nd: 1: Do NOT apply DQ limits from SEQ043 4th: Future + * Development. Choice of upper limits 9th: 0: Normal - Suppress MATH77 error + * messages. 1: show some MATH77 errors; 2: show all. 22nd 1: extra preference + * for preferred sp (SEQ 010). + */ + + ; + public FipControlParser() { - + } - Map parse (Path inputFile) throws IOException, ResourceParseException { + Map parse(Path inputFile) throws IOException, ResourceParseException { try (var is = Files.newInputStream(inputFile)) { return parse(is, new FileResolver() { @@ -174,46 +176,51 @@ public String toString(String filename) throws IOException { }); } } - - Map parse (Class klazz, String resourceName) throws IOException, ResourceParseException { + + Map parse(Class klazz, String resourceName) throws IOException, ResourceParseException { try (var is = klazz.getResourceAsStream(resourceName)) { - return parse(is, new FileResolver() { + return parse(is, fileResolver(klazz)); + } + } - @Override - public InputStream resolve(String filename) throws IOException { - InputStream resourceAsStream = klazz.getResourceAsStream(filename); - if(resourceAsStream==null) throw new IOException("Could not load "+filename); - return resourceAsStream; - } + static FileResolver fileResolver(Class klazz) { + return new FileResolver() { - @Override - public String toString(String filename) throws IOException { - return klazz.getResource(filename).toString(); - } - }); - } + @Override + public InputStream resolve(String filename) throws IOException { + InputStream resourceAsStream = klazz.getResourceAsStream(filename); + if (resourceAsStream == null) + throw new IOException("Could not load " + filename); + return resourceAsStream; + } + + @Override + public String toString(String filename) throws IOException { + return klazz.getResource(filename).toString(); + } + }; } - + Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { var map = controlParser.parse(is, Collections.emptyMap()); - + // RD_BEC loadData(map, BecDefinitionParser.CONTROL_KEY, fileResolver, this::RD_BEC); - + // DEF_BEC // TODO - + // Read Definitions - + // RD_SP0 loadData(map, SP0_DEF, fileResolver, this::RD_SP0); - + // Read Groups - + // RD_VGRP loadData(map, VOLUME_EQN_GROUPS, fileResolver, this::RD_VGRP); - + // RD_DGRP loadData(map, DECAY_GROUPS, fileResolver, this::RD_DGRP); @@ -225,31 +232,29 @@ public String toString(String filename) throws IOException { // RD_GMBA1 loadData(map, EQN_MODIFIERS, fileResolver, this::RD_GMBA1); - + int jprogram = 1; // FIPSTART only TODO Track this down - if(jprogram==1) { + if (jprogram == 1) { // RD_STK33 loadData(map, STOCKING_CLASS_FACTORS, fileResolver, this::RD_STK33); // TODO minima? /* - * READ(CNTRV(197), 197, ERR= 912 ) FMINH, FMINBA, FMINBAF,FMINVetH - * IF (FMINVetH .le. 0.0) FMINVetH=10.0 + * READ(CNTRV(197), 197, ERR= 912 ) FMINH, FMINBA, FMINBAF,FMINVetH IF (FMINVetH + * .le. 0.0) FMINVetH=10.0 */ } - - + // User-assigned SC's (Site Curve Numbers) - // + // // RD_E025 - loadDataOptional(map, SITE_CURVE_NUMBERS, fileResolver, this::RD_E025); - - // Max tot ages to apply site curves (by SC) - // + loadDataOptional(map, SITE_CURVE_NUMBERS, fileResolver, this::RD_E025, Collections::emptyMap); + + // Max tot ages to apply site curves (by SC) + // // RD_E026 - // TODO - // loadDataOptional(map, SITE_CURVE_AGE_MAX, fileResolver, this::RD_E026); - + loadDataOptional(map, SITE_CURVE_AGE_MAX, fileResolver, this::RD_E026, SiteCurveAgeMaximumParser::defaultMap); + // Coeff for Empirical relationships // RD_E040 @@ -275,186 +280,189 @@ public String toString(String filename) throws IOException { // RD_E060 // TODO - + // Min and max DQ by species - + // RD_E061 // TODO - + // RD_UBA1 // TODO - + // RD_UDQ1 // TODO - + // Small Component (4.5 to 7.5 cm) - + // RD_SBA1 // TODO - + // RD_SBA2 // TODO - + // RD_SDQ1 // TODO - + // RD_SHL1 // TODO - + // RD_SVT1 // TODO - + // Standard Volume Relationships - + // RD_YVT1 // TODO - + // RD_YVT2 // TODO - + // RD_YVC1 // TODO - + // RD_YVD1 // TODO - + // RD_YVW1 // TODO - + // RD_E095 // TODO - + // Veterans - + // RD_YVVET // TODO - + // RD_YDQV // TODO - + // RD_E098 // TODO - + // Initiation items NOT for FIPSTART - if(jprogram==1) { + if (jprogram == 1) { // RD_E106 // TODO - + // RD_E107 // TODO - + // RD_E108 // TODO - + // Minima again, differently? // TODO /* - READ(CNTRV(197), 197, ERR= 912 ) VMINH, VMINBA, VMINBAeqn,VMINvetH - IF (VMINVetH .le. 0.0) VMINVetH=10.0 - */ - + * READ(CNTRV(197), 197, ERR= 912 ) VMINH, VMINBA, VMINBAeqn,VMINvetH IF + * (VMINVetH .le. 0.0) VMINVetH=10.0 + */ + // RD_E112 // Was commented out in Fortran - + // RD_E116 // Was commented out in Fortran } - + // Modifiers, IPSJF155-Appendix XII - + // RD_E198 // TODO - + // Debug switches (normally zero) // TODO /* -141 FORMAT(25I2) - DO 140 I=1,25 - if ((NDEBUG(I) .ne.0) .and. (IU_WRITE .gt. 0)) - & WRITE(IU_WRITE,142) I, NDEBUG(I) -142 FORMAT(' CTR Line 199 has NDEBUG(',i2,') =',I3) -140 CONTINUE - - if (isDBG) then - call dbgMsg( logr, 0 ) "Debug Switches (Ctl Line 199)" ) - call dbgI4( logr, 6 ) " 1: Applying BA Limits ", NDEBUG( 1) ) - call dbgMsg( logr, 6 ) " 0 - Apply BA limits from SEQ043." ) - call dbgMsg( logr, 6 ) " 1 - Do not apply BA limits from SEQ043." ) - call dbgI4( logr, 6 ) " 2: Applying BA Limits ", NDEBUG( 2) ) - call dbgMsg( logr, 6 ) " 0 - Apply DQ limits from SEQ043." ) - call dbgMsg( logr, 6 ) " 1 - Do not apply DQ limits from SEQ043." ) - call dbgI4( logr, 6 ) " 3: Not used ", NDEBUG( 3) ) - call dbgI4( logr, 6 ) " 4: Not implemented. Upper bounds ", NDEBUG( 4) ) - call dbgMsg( logr, 6 ) " 0 - Will default to (2)." ) - call dbgMsg( logr, 6 ) " 1 - Limits from Ctl Line 108 (GRPBA1)." ) - call dbgMsg( logr, 6 ) " 2 - Limits from Ctl Line 043 (Coast/Interior)" ) - call dbgI4( logr, 6 ) " 5: Not used ", NDEBUG( 5) ) - call dbgI4( logr, 6 ) " 6: Not used ", NDEBUG( 6) ) - call dbgI4( logr, 6 ) " 7: Not used ", NDEBUG( 7) ) - call dbgI4( logr, 6 ) " 8: Not used ", NDEBUG( 8) ) - call dbgI4( logr, 6 ) " 9: Error handling ", NDEBUG( 9) ) - call dbgMsg( logr, 6 ) " 0 - Stop on all errors." ) - call dbgMsg( logr, 6 ) " 1 - Continue to next poly (non-I/O errs)." ) - call dbgI4( logr, 6 ) "10: Not used ", NDEBUG(10) ) - call dbgI4( logr, 6 ) "11: Not used ", NDEBUG(11) ) - call dbgI4( logr, 6 ) "12: Not used ", NDEBUG(12) ) - call dbgI4( logr, 6 ) "13: Not used ", NDEBUG(13) ) - call dbgI4( logr, 6 ) "14: Not used ", NDEBUG(14) ) - call dbgI4( logr, 6 ) "15: Not used ", NDEBUG(15) ) - call dbgI4( logr, 6 ) "16: Not used ", NDEBUG(16) ) - call dbgI4( logr, 6 ) "17: Not used ", NDEBUG(17) ) - call dbgI4( logr, 6 ) "18: Not used ", NDEBUG(18) ) - call dbgI4( logr, 6 ) "19: Not used ", NDEBUG(19) ) - call dbgI4( logr, 6 ) "20: Not used ", NDEBUG(20) ) - call dbgI4( logr, 6 ) "21: Not used ", NDEBUG(21) ) - call dbgI4( logr, 6 ) "22: Determining primary species ", NDEBUG(22) ) - call dbgMsg( logr, 6 ) " 0 - Normal " ) - call dbgMsg( logr, 6 ) " 1 - Extra preference for preferred sp. as primary" ) - call dbgI4( logr, 6 ) "23: Not used ", NDEBUG(23) ) - call dbgI4( logr, 6 ) "24: Not used ", NDEBUG(24) ) - call dbgI4( logr, 6 ) "25: Not used ", NDEBUG(25) ) - end if + * 141 FORMAT(25I2) DO 140 I=1,25 if ((NDEBUG(I) .ne.0) .and. (IU_WRITE .gt. 0)) + * & WRITE(IU_WRITE,142) I, NDEBUG(I) 142 FORMAT(' CTR Line 199 has + * NDEBUG(',i2,') =',I3) 140 CONTINUE + * + * if (isDBG) then call dbgMsg( logr, 0 ) "Debug Switches (Ctl Line 199)" ) call + * dbgI4( logr, 6 ) " 1: Applying BA Limits ", NDEBUG( 1) ) call + * dbgMsg( logr, 6 ) " 0 - Apply BA limits from SEQ043." ) call dbgMsg( + * logr, 6 ) " 1 - Do not apply BA limits from SEQ043." ) call dbgI4( + * logr, 6 ) " 2: Applying BA Limits ", NDEBUG( 2) ) call dbgMsg( + * logr, 6 ) " 0 - Apply DQ limits from SEQ043." ) call dbgMsg( logr, 6 ) + * " 1 - Do not apply DQ limits from SEQ043." ) call dbgI4( logr, 6 ) + * " 3: Not used ", NDEBUG( 3) ) call dbgI4( logr, 6 ) + * " 4: Not implemented. Upper bounds ", NDEBUG( 4) ) call dbgMsg( logr, 6 ) + * " 0 - Will default to (2)." ) call dbgMsg( logr, 6 ) + * " 1 - Limits from Ctl Line 108 (GRPBA1)." ) call dbgMsg( logr, 6 ) + * " 2 - Limits from Ctl Line 043 (Coast/Interior)" ) call dbgI4( logr, 6 + * ) " 5: Not used ", NDEBUG( 5) ) call dbgI4( logr, 6 ) + * " 6: Not used ", NDEBUG( 6) ) call dbgI4( logr, 6 ) + * " 7: Not used ", NDEBUG( 7) ) call dbgI4( logr, 6 ) + * " 8: Not used ", NDEBUG( 8) ) call dbgI4( logr, 6 ) + * " 9: Error handling ", NDEBUG( 9) ) call dbgMsg( logr, 6 ) + * " 0 - Stop on all errors." ) call dbgMsg( logr, 6 ) + * " 1 - Continue to next poly (non-I/O errs)." ) call dbgI4( logr, 6 ) + * "10: Not used ", NDEBUG(10) ) call dbgI4( logr, 6 ) + * "11: Not used ", NDEBUG(11) ) call dbgI4( logr, 6 ) + * "12: Not used ", NDEBUG(12) ) call dbgI4( logr, 6 ) + * "13: Not used ", NDEBUG(13) ) call dbgI4( logr, 6 ) + * "14: Not used ", NDEBUG(14) ) call dbgI4( logr, 6 ) + * "15: Not used ", NDEBUG(15) ) call dbgI4( logr, 6 ) + * "16: Not used ", NDEBUG(16) ) call dbgI4( logr, 6 ) + * "17: Not used ", NDEBUG(17) ) call dbgI4( logr, 6 ) + * "18: Not used ", NDEBUG(18) ) call dbgI4( logr, 6 ) + * "19: Not used ", NDEBUG(19) ) call dbgI4( logr, 6 ) + * "20: Not used ", NDEBUG(20) ) call dbgI4( logr, 6 ) + * "21: Not used ", NDEBUG(21) ) call dbgI4( logr, 6 ) + * "22: Determining primary species ", NDEBUG(22) ) call dbgMsg( logr, 6 ) + * " 0 - Normal " ) call dbgMsg( logr, 6 ) + * " 1 - Extra preference for preferred sp. as primary" ) call dbgI4( + * logr, 6 ) "23: Not used ", NDEBUG(23) ) call dbgI4( + * logr, 6 ) "24: Not used ", NDEBUG(24) ) call dbgI4( + * logr, 6 ) "25: Not used ", NDEBUG(25) ) end if */ - + return map; } - - void loadData(Map map, String key, FileResolver fileResolver, ResourceParser parser) throws IOException, ResourceParseException { - try(var is = fileResolver.resolve((String) map.get(key))) { + + void loadData(Map map, String key, FileResolver fileResolver, ResourceParser parser) + throws IOException, ResourceParseException { + try (var is = fileResolver.resolve((String) map.get(key))) { map.put(key, parser.parse(is, map)); } } - void loadDataOptional(Map map, String key, FileResolver fileResolver, ResourceParser parser) throws IOException, ResourceParseException { + + void loadDataOptional( + Map map, String key, FileResolver fileResolver, ResourceParser parser, + Supplier defaultSupplier + ) throws IOException, ResourceParseException { @SuppressWarnings("unchecked") Optional path = (Optional) map.get(key); - if(!path.isPresent()) { + if (!path.isPresent()) { // TODO Log - map.put(key, Collections.emptyMap()); + map.put(key, defaultSupplier.get()); return; } - try(var is = fileResolver.resolve(path.get())) { + try (var is = fileResolver.resolve(path.get())) { map.put(key, parser.parse(is, map)); } } - - /** - * Loads the information that was in the global arrays BECV, BECNM, and BECCOASTAL in Fortran + + /** + * Loads the information that was in the global arrays BECV, BECNM, and + * BECCOASTAL in Fortran */ - private Map RD_BEC(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_BEC(InputStream data, Map control) + throws IOException, ResourceParseException { var parser = new BecDefinitionParser(); return parser.parse(data, control); } - - /** + + /** * Loads the information that was in the global arrays SP0V, SP0NAMEV in Fortran */ - private List RD_SP0(InputStream data, Map control) throws IOException, ResourceParseException { + private List RD_SP0(InputStream data, Map control) + throws IOException, ResourceParseException { var parser = new SP0DefinitionParser(); return parser.parse(data, control); } - - /** + + /** * Loads the information that was in the global array VGRPV in Fortran */ private Object RD_VGRP(InputStream data, Map control) throws IOException, ResourceParseException { @@ -462,24 +470,24 @@ private Object RD_VGRP(InputStream data, Map control) throws IOE parser.setHiddenBecs(Arrays.asList("BG")); return parser.parse(data, control); } - - /** + + /** * Loads the information that was in the global array DGRPV in Fortran */ private Object RD_DGRP(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new EquationGroupParser(); return parser.parse(data, control); } - - /** + + /** * Loads the information that was in the global array BGRPV in Fortran */ private Object RD_BGRP(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new EquationGroupParser(); return parser.parse(data, control); } - - /** + + /** * Loads the information that was in the global array BG1DEFV in Fortran */ private Object RD_GRBA1(InputStream data, Map control) throws IOException, ResourceParseException { @@ -487,42 +495,59 @@ private Object RD_GRBA1(InputStream data, Map control) throws IO parser.setHiddenBecs(Arrays.asList("BG", "AT")); return parser.parse(data, control); } - - /** + + /** * Loads the information that was in the global array BG1MODV in Fortran */ private Object RD_GMBA1(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new EquationModifierParser(); return parser.parse(data, control); } - - /** - * Loads the information that was in the global arrays STKV, FACTV, and NPCTAREA in Fortran + + /** + * Loads the information that was in the global arrays STKV, FACTV, and NPCTAREA + * in Fortran */ private Object RD_STK33(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new StockingClassFactorParser(); return parser.parse(data, control); } - /** - * Loads the information that was in the global arrays ISCURVE and SP_SCV in Fortran + /** + * Loads the information that was in the global arrays ISCURVE and SP_SCV in + * Fortran */ private Object RD_E025(InputStream data, Map control) throws IOException, ResourceParseException { var parser = new SiteCurveParser(); return parser.parse(data, control); } - - /** - * Loads the information that was in the global V7COE026 arrays ASITELIM, T1SITELIM, T2SITELIM in Fortran + + /** + * Loads the information that was in the global V7COE026 arrays ASITELIM, + * T1SITELIM, T2SITELIM in Fortran */ - private Object RD_E026(InputStream data, Map control) throws IOException, ResourceParseException { - return null; + private Map RD_E026(InputStream data, Map control) + throws IOException, ResourceParseException { + // ASITELIM for each site curve number and region, the maximum total age that + // site curve will increment to. + // Defaults to 140.0 + // Default to all 140.0 if file not specified + // integer(3, 'siteCurve').float(7, 'ageCoast').float(7,'ageInt').float(7, + // 't1').float(7,'t2') + // ages of <=0.0 should be mapped to 1999.0 + // site curve number 999 is end of data + // site curve number <-1 or >40 invalid. + // site curve number -1 is special. map to max position in array + // Structure: store the age for each region plus t1 and t2 for each site curve. + + var parser = new SiteCurveAgeMaximumParser(); + return parser.parse(data, control); } - + static interface FileResolver { InputStream resolve(String filename) throws IOException; - + String toString(String filename) throws IOException; } - + } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 17f14a239..59c67fe14 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -8,6 +8,11 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isA; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.SequenceInputStream; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; @@ -18,11 +23,14 @@ import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParserTest; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.model.SiteCurve; +import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; import ca.bc.gov.nrs.vdyp.model.StockingClassFactor; @SuppressWarnings("unused") @@ -32,177 +40,236 @@ public class FipControlParserTest { public void testParse() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - + } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseBec() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) hasEntry(is(BecDefinitionParser.CONTROL_KEY), - allOf( - instanceOf(Map.class), - hasEntry( - is("AT"), - instanceOf(BecDefinition.class))))); + assertThat( + result, + (Matcher) hasEntry( + is(BecDefinitionParser.CONTROL_KEY), + allOf(instanceOf(Map.class), hasEntry(is("AT"), instanceOf(BecDefinition.class))) + ) + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSP0() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) hasEntry(is(SP0DefinitionParser.CONTROL_KEY), - allOf( - instanceOf(List.class), - hasItem( - instanceOf(SP0Definition.class))))); + assertThat( + result, + (Matcher) hasEntry( + is(SP0DefinitionParser.CONTROL_KEY), + allOf(instanceOf(List.class), hasItem(instanceOf(SP0Definition.class))) + ) + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseVGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.VOLUME_EQN_GROUPS), - allOf( // Map of SP0 Aliases - isA(Map.class), - hasEntry( - isA(String.class), - allOf( // Map of BEC aliases - isA(Map.class), - hasEntry( - isA(String.class), - isA(Integer.class) // Equation Identifier - )))))); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.VOLUME_EQN_GROUPS), allOf( + // Map of SP0 Aliases + isA(Map.class), hasEntry( + isA(String.class), allOf( + // Map of BEC aliases + isA(Map.class), hasEntry( + isA(String.class), isA(Integer.class) // Equation Identifier + ) + ) + ) + ) + ) + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseDGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.DECAY_GROUPS), - allOf( // Map of SP0 Aliases - isA(Map.class), - hasEntry( - isA(String.class), - allOf( // Map of BEC aliases - isA(Map.class), - hasEntry( - isA(String.class), - isA(Integer.class) // Equation Identifier - )))))); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.DECAY_GROUPS), allOf( + // Map of SP0 Aliases + isA(Map.class), hasEntry( + isA(String.class), allOf( + // Map of BEC aliases + isA(Map.class), hasEntry( + isA(String.class), isA(Integer.class) // Equation Identifier + ) + ) + ) + ) + ) + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseBGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.BREAKAGE_GROUPS), - allOf( // Map of SP0 Aliases - isA(Map.class), - hasEntry( - isA(String.class), - allOf( // Map of BEC aliases - isA(Map.class), - hasEntry( - isA(String.class), - isA(Integer.class) // Equation Identifier - )))))); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.BREAKAGE_GROUPS), allOf( + // Map of SP0 Aliases + isA(Map.class), hasEntry( + isA(String.class), allOf( + // Map of BEC aliases + isA(Map.class), hasEntry( + isA(String.class), isA(Integer.class) // Equation Identifier + ) + ) + ) + ) + ) + ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseGRBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.DEFAULT_EQ_NUM), - allOf( // Map of SP0 Aliases - isA(Map.class), - hasEntry( - isA(String.class), - allOf( // Map of BEC aliases - isA(Map.class), - hasEntry( - isA(String.class), - isA(Integer.class) // Equation Identifier - )))))); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.DEFAULT_EQ_NUM), allOf( + // Map of SP0 Aliases + isA(Map.class), hasEntry( + isA(String.class), allOf( + // Map of BEC aliases + isA(Map.class), hasEntry( + isA(String.class), isA(Integer.class) // Equation Identifier + ) + ) + ) + ) + ) + ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseGMBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.EQN_MODIFIERS), - allOf( // Default Equation - isA(Map.class), - hasEntry( - isA(Integer.class), - allOf( // ITG - isA(Map.class), - hasEntry( - isA(Integer.class), - isA(Integer.class) // Reassigned Equation - )))))); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.EQN_MODIFIERS), allOf( + // Default Equation + isA(Map.class), hasEntry( + isA(Integer.class), allOf( + // ITG + isA(Map.class), hasEntry( + isA(Integer.class), isA(Integer.class) // Reassigned Equation + ) + ) + ) + ) + ) + ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSTK33() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.STOCKING_CLASS_FACTORS), - allOf( // STK - isA(Map.class), - hasEntry( - isA(Character.class), - allOf( // Region - isA(Map.class), - hasEntry( - isA(Region.class), - isA(StockingClassFactor.class) // Factors - )))))); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.STOCKING_CLASS_FACTORS), allOf( + // STK + isA(Map.class), hasEntry( + isA(Character.class), allOf( + // Region + isA(Map.class), + hasEntry( + isA(Region.class), isA(StockingClassFactor.class) // Factors + ) + ) + ) + ) + ) + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - @Disabled public void testParseE025() throws Exception { var parser = new FipControlParser(); - var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.SITE_CURVE_NUMBERS), - allOf( // Species - isA(Map.class), - hasEntry( - isA(String.class), - isA(SiteCurve.class) - )))); + var result = parseWithAppendix(parser, "025 coe/SIEQN.PRM"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.SITE_CURVE_NUMBERS), allOf( + // Species + isA(Map.class), hasEntry(isA(String.class), isA(SiteCurve.class)) + ) + ) + ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE025Empty() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) - hasEntry( - is(FipControlParser.SITE_CURVE_NUMBERS), - Matchers.anEmptyMap() - )); + assertThat(result, (Matcher) hasEntry(is(FipControlParser.SITE_CURVE_NUMBERS), Matchers.anEmptyMap())); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE026() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.SITE_CURVE_AGE_MAX), allOf( + // Species + isA(Map.class), hasEntry(isA(Integer.class), isA(SiteCurveAgeMaximum.class)) + ) + ) + ); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + // @Disabled + public void testParseE026Empty() throws Exception { + var parser = new FipControlParser(); + var result = parseWithAppendix(parser, "026 "); + // Map is empty but gives appropriate default values + assertThat(result, (Matcher) hasEntry(is(FipControlParser.SITE_CURVE_AGE_MAX), Matchers.anEmptyMap())); + assertThat( + ((Map) result.get(FipControlParser.SITE_CURVE_AGE_MAX)).get(1), + (Matcher) allOf(SiteCurveAgeMaximumParserTest.hasAge(Region.COASTAL, is(140.f))) + ); + } + + static InputStream addToEnd(InputStream is, String... lines) { + var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); + var result = new SequenceInputStream(is, appendix); + return result; + } + + static Map parseWithAppendix(FipControlParser parser, String... lines) + throws IOException, ResourceParseException { + var resolver = FipControlParser.fileResolver(ControlFileParserTest.class); + try ( + InputStream baseIs = ControlFileParserTest.class.getResourceAsStream("FIPSTART.CTR"); + InputStream is = addToEnd(baseIs, lines); + ) { + return parser.parse(is, resolver); + } } } From e326fb89bfa3736d2bf8dacbc12f88598bea5a01 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 19 May 2023 16:49:43 -0700 Subject: [PATCH 20/98] CoefficientParser --- .../nrs/vdyp/io/parse/CoefficientParser.java | 82 ++++++++++++ .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 17 +++ .../gov/nrs/vdyp/io/parse/ResourceParser.java | 5 +- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 18 +++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 28 ++++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap2.java | 14 ++ .../bc/gov/nrs/vdyp/model/MatrixMap2Impl.java | 12 ++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap3.java | 14 ++ .../bc/gov/nrs/vdyp/model/MatrixMap3Impl.java | 12 ++ .../bc/gov/nrs/vdyp/model/MatrixMapImpl.java | 90 +++++++++++++ .../vdyp/io/parse/CoefficientParserTest.java | 33 +++++ .../gov/nrs/vdyp/io/parse/LineParserTest.java | 15 +++ .../bc/gov/nrs/vdyp/model/MatrixMapTest.java | 120 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 4 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 35 ++++- 15 files changed, 490 insertions(+), 9 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java new file mode 100644 index 000000000..bfe7827f7 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -0,0 +1,82 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; + +/** + * Parses a Coefficient data file. + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class CoefficientParser implements ResourceParser> { + public static final String BA_CONTROL_KEY = "COE_BA"; + public static final String DQ_CONTROL_KEY = "COE_DQ"; + + public static final String BEC_KEY = "bec"; + public static final String COEFFICIENT_INDEX_KEY = "index"; + public static final String INDICATOR_KEY = "indicator"; + public static final String COEFFICIENT_KEY = "coefficient"; + + public static final int NUM_COEFFICIENTS = 10; + public static final int NUM_SPECIES = 16; + + + LineParser lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + } + .value(4, BEC_KEY, String::strip) + .space(2) + .value(1, INDICATOR_KEY, ValueParser.INTEGER) + .value(2, COEFFICIENT_INDEX_KEY, ValueParser.INTEGER) + .multiValue(NUM_SPECIES, 8, COEFFICIENT_KEY, ValueParser.FLOAT); + + @Override + public MatrixMap3 parse(InputStream is, Map control) + throws IOException, ResourceParseException { + var becAliases = ResourceParser.>expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class).keySet(); + var coeIndecies = Stream.iterate(0, x->x+1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); + var speciesIndecies = Stream.iterate(1, x->x+1).limit(NUM_SPECIES).collect(Collectors.toList()); + MatrixMap3 result = new MatrixMap3Impl(coeIndecies, becAliases, speciesIndecies); + lineParser.parse(is, result, (v, r) -> { + var bec = (String) v.get(BEC_KEY); + var indicator = (int) v.get(INDICATOR_KEY); + var index = (int) v.get(COEFFICIENT_INDEX_KEY); + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENT_KEY); + + for(int species = 0; species type the segment will be parsed too + * @param length length of the segment + * @param name name of the segment + * @param parser parser to convert the string + */ + public LineParser multiValue(int number, int length, String name, ValueParser parser) { + if (number < 0) + throw new IllegalArgumentException("number can not be negative"); + if (length < 0) + throw new IllegalArgumentException("length can not be negative"); + + return doValue(length*number, name, ValueParser.segmentList(length, parser)); + } + /** * Add a segment * diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java index bd7ca4f48..08869e0ed 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceParser.java @@ -64,7 +64,8 @@ default T parse(Path resourcePath, Map control) throws IOExcepti } } - static U expectParsedControl(Map control, String key, Class clazz) { + @SuppressWarnings("unchecked") + static U expectParsedControl(Map control, String key, Class clazz) { var value = control.get(key); if (value == null) { throw new IllegalStateException("Expected control map to have " + key); @@ -80,6 +81,6 @@ static U expectParsedControl(Map control, String key, Class< + value.getClass() ); } - return clazz.cast(value); + return (U) value; } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 8bae131dd..7f7cb528b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -136,4 +136,22 @@ public static ValueParser> optional(ValueParser delegate) { return Optional.empty(); }; } + + /** + * Parse a string as a set of fixed length chucks. + * @param + * @param length length of a chunk + * @param delegate parser for the individual chunks + * @return + */ + public static ValueParser> segmentList(int length, ValueParser delegate) { + return s -> { + var result = new ArrayList((s.length()+length-1)/length); + for (int i = 0; i < s.length(); i += length) { + var j = Math.min(i+length, s.length()); + result.add(delegate.parse(s.substring(i, j))); + } + return Collections.unmodifiableList(result); + }; + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java new file mode 100644 index 000000000..1eca3e317 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -0,0 +1,28 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Optional; +import java.util.function.Predicate; + +/** + * A mapping from the cartesian product of a set of arbitrary identifiers to a value. + * + * @author Kevin Smith, Vivid Solutions + * + * @param + */ +public interface MatrixMap { + + public Optional getM(Object...params); + + public void putM(T value, Object...params); + + public boolean all(Predicate pred); + + default public boolean isFull() { + return all(x->x!=null); + } + + default public boolean isEmpty() { + return all(x->x==null); + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java new file mode 100644 index 000000000..adee7a163 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java @@ -0,0 +1,14 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Optional; + +public interface MatrixMap2 extends MatrixMap { + + default public void put(K1 key1, K2 key2, V value) { + putM(value, key1, key2); + } + + default public Optional get(K1 key1, K2 key2) { + return getM(key1, key2); + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java new file mode 100644 index 000000000..6db0cc21b --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java @@ -0,0 +1,12 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Arrays; +import java.util.Collection; + +public class MatrixMap2Impl extends MatrixMapImpl implements MatrixMap2{ + + public MatrixMap2Impl(Collection dimension1, Collection dimension2) { + super(Arrays.asList(dimension1, dimension2)); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java new file mode 100644 index 000000000..c69a9ecba --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java @@ -0,0 +1,14 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Optional; + +public interface MatrixMap3 extends MatrixMap { + + default public void put(K1 key1, K2 key2, K3 key3, V value) { + putM(value, key1, key2, key3); + } + + default public Optional get(K1 key1, K2 key2, K3 key3) { + return getM(key1, key2, key3); + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java new file mode 100644 index 000000000..6ce7ff28e --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java @@ -0,0 +1,12 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Arrays; +import java.util.Collection; + +public class MatrixMap3Impl extends MatrixMapImpl implements MatrixMap3{ + + public MatrixMap3Impl(Collection dimension1, Collection dimension2, Collection dimension3) { + super(Arrays.asList(dimension1, dimension2, dimension3)); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java new file mode 100644 index 000000000..0462a52cf --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java @@ -0,0 +1,90 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * A mapping from the cartesian product of a set of arbitrary identifiers to a value. + * + * @author Kevin Smith, Vivid Solutions + * + * @param + */ +public class MatrixMapImpl implements MatrixMap { + List> maps; + Object[] matrix; + + public MatrixMapImpl(Collection> dimensions) { + if(dimensions.isEmpty()) { + throw new IllegalArgumentException("Must have at least one dimension"); + } + if(dimensions.stream().anyMatch(dim->dim.isEmpty())) { + throw new IllegalArgumentException("Each dimension must have at least one value"); + } + maps = dimensions.stream().map(dim->{ + var map = new HashMap(dim.size()); + int i=0; + for(var o : dim) { + map.put(o,i); + i++; + } + return map; + }).collect(Collectors.toList()); + var matrixSize = maps.stream().map(Map::size).reduce(1, (x,y)->x*y); + matrix = new Object[matrixSize]; + } + + public MatrixMapImpl(Collection... dimensions) { + this(Arrays.asList(dimensions)); + } + + @SuppressWarnings("unchecked") + public Optional getM(Object...params) { + return (Optional) getIndex(params).flatMap(i->Optional.ofNullable(matrix[i])); + } + + public void putM(T value, Object...params) { + matrix[getIndex(params).orElseThrow(()->new IllegalArgumentException())] = value; + } + + protected Optional getIndex(Object...params) { + if(params.length!=maps.size()) { + throw new IllegalArgumentException("MatrixMap requires parameters to equal the number of dimensions"); + } + int i = 0; + int index=0; + int step = 1; + for(var o: params) { + var dim = maps.get(i); + Integer dimIndex = dim.get(o); + if(dimIndex==null) { + return Optional.empty(); + } + index+=step*dimIndex; + + step*=dim.size(); + i++; + } + return Optional.of(index); + } + + @SuppressWarnings("unchecked") + public boolean all(Predicate pred) { + return Arrays.stream(matrix).allMatch((Predicate) pred); + } + + public boolean isFull() { + return all(x->x!=null); + } + + public boolean isEmpty() { + return all(x->x==null); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java new file mode 100644 index 000000000..29ca4e144 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class CoefficientParserTest { + + @Test + public void testParseSimple() throws Exception { + + var parser = new CoefficientParser(); + + var is = TestUtils.makeStream("B1 A0 1 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + Map controlMap = new HashMap<>(); + + Map becMap = new HashMap<>(); + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); + becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + + var result = parser.parse(is, controlMap); + + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 0a181c21c..1459b4c96 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -2,6 +2,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.array; +import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasKey; @@ -17,6 +19,7 @@ import java.util.Map; import org.hamcrest.Matcher; +import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; public class LineParserTest { @@ -151,6 +154,18 @@ public void testStripped() throws Exception { ); } + @SuppressWarnings("unchecked") + @Test + public void testMultiValue() throws Exception { + var parser = new LineParser(); + parser.multiValue(4, 3, "test", ValueParser.INTEGER); + + var result1 = parser.parseLine( + " 02 04 06 08" + ); + + assertThat(result1, hasEntry(is("test"), (Matcher) contains(2,4,6,8))); + } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java new file mode 100644 index 000000000..7cfc4eef4 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -0,0 +1,120 @@ +package ca.bc.gov.nrs.vdyp.model; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class MatrixMapTest { + + @Test + public void testContruct() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1,2); + var dims = Arrays.asList(dim1, dim2); + var result = new MatrixMapImpl(dims); + } + @Test + public void testContructNoDimensionsFails() { + List> dims = Collections.emptyList(); + Assertions.assertThrows(IllegalArgumentException.class,()-> new MatrixMapImpl(dims)); + } + @Test + public void testContructEmptyDimensionsFails() { + var dim1 = Collections.emptyList(); + var dims = Arrays.asList(dim1); + Assertions.assertThrows(IllegalArgumentException.class,()-> new MatrixMapImpl(dims)); + } + + @Test + public void testNewMapIsEmpty() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1,2); + var dims = Arrays.asList(dim1, dim2); + var result = new MatrixMapImpl(dims); + assertThat(result, hasProperty("empty", is(true))); + assertThat(result, hasProperty("full", is(false))); + } + + @Test + public void testDefaultIsEmpty() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1,2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + var result = map.getM("a",2); + + assertThat(result, notPresent()); + } + + @Test + public void testCanRetrieveAValue() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1,2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + map.putM('Z', "a", 2); + var result = map.getM("a",2); + + assertThat(result, present(is('Z'))); + } + + @Test + public void testWithOneValueIsNeitherFullNorEmpty() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1,2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + map.putM('Z', "a", 2); + + assertThat(map, hasProperty("full", is(false))); + assertThat(map, hasProperty("empty", is(false))); + } + + @Test + public void testGetIndex() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1,2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + assertThat(map.getIndex("a", 1), present(is(0))); + assertThat(map.getIndex("b", 1), present(is(1))); + assertThat(map.getIndex("a", 2), present(is(2))); + assertThat(map.getIndex("b", 2), present(is(3))); + } + + @Test + public void testFullMap() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1,2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + map.putM('W', "a", 1); + map.putM('X', "a", 2); + map.putM('Y', "b", 1); + map.putM('Z', "b", 2); + + assertThat(map, hasProperty("full", is(true))); + assertThat(map, hasProperty("empty", is(false))); + + assertThat(map.getM("a", 1), present(is('W'))); + assertThat(map.getM("a", 2), present(is('X'))); + assertThat(map.getM("b", 1), present(is('Y'))); + assertThat(map.getM("b", 2), present(is('Z'))); + } + + +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index e0bb1944a..b112537c2 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -30,8 +30,8 @@ 031 coe/GMODBA1.DAT Eqn modifiers for above RD_GMBA1 033 coe/FIPSTKR.PRM Stocking class factors RD_STK33 -040 coe/regba25.coe Coe BA=f(CC) RD_E040 IPSJF128 -041 coe/regdq26.coe Coe DQ=f(CC) RD_E041 IPSJF129 +040 coe/REGBA25.coe Coe BA=f(CC) RD_E040 IPSJF128 +041 coe/REGDQ26.coe Coe DQ=f(CC) RD_E041 IPSJF129 043 coe/upperb02.coe Upper BA by C/I SP0_P RD_E043 IPSJF128 050 coe/regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 71a150503..d9121265f 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -12,6 +12,7 @@ import java.util.function.Supplier; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.CoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; @@ -23,7 +24,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; -import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; @@ -49,8 +50,8 @@ public class FipControlParser { public static final String DEFAULT_EQ_NUM = EquationGroupParser.DEFAULT_CONTROL_KEY; public static final String EQN_MODIFIERS = EquationModifierParser.CONTROL_KEY; public static final String STOCKING_CLASS_FACTORS = StockingClassFactorParser.CONTROL_KEY; - public static final String COE_BA = "COE_BA"; - public static final String COE_DQ = "COE_DQ"; + public static final String COE_BA = CoefficientParser.BA_CONTROL_KEY; + public static final String COE_DQ = CoefficientParser.DQ_CONTROL_KEY; public static final String UPPER_BA_BY_CI_S0_P = "UPPER_BA_BY_CI_S0_P"; public static final String HL_PRIMARY_SP_EQN_P1 = "HL_PRIMARY_SP_EQN_P1"; public static final String HL_PRIMARY_SP_EQN_P2 = "HL_PRIMARY_SP_EQN_P2"; @@ -258,10 +259,10 @@ public String toString(String filename) throws IOException { // Coeff for Empirical relationships // RD_E040 - // TODO + loadData(map, COE_BA, fileResolver, this::RD_E040); // RD_E041 - // TODO + loadData(map, COE_DQ, fileResolver, this::RD_E041); // RD_E043 // TODO @@ -543,6 +544,30 @@ private Map RD_E026(InputStream data, Map RD_E040(InputStream data, Map control) throws IOException, ResourceParseException { + // 10 coefficients by species (SP0) by becs + // 4 String BEC Alias, 2 gap, 1 int coefficient index, 2 int "Indicate", 16x8 Float coefficient for species + // Blank bec is ignore line + + // if indicate is 2, map the coefficients in directly + // if indicate is 0 write the first coeffecient from the file to all in the array + // if the indicate is 1, add the first from the file to each subsequent one. + + var parser = new CoefficientParser(); + return parser.parse(data, control); + } + + /** + * Loads the information that was in the global array COE041 in Fortran + */ + private MatrixMap3 RD_E041(InputStream data, Map control) throws IOException, ResourceParseException { + var parser = new CoefficientParser(); + return parser.parse(data, control); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; From 7d1f30e07df9244685164976204009f507690e08 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 23 May 2023 10:51:01 -0700 Subject: [PATCH 21/98] Upper Coeficcient parser, and fixes for regular coefficient parser --- .../nrs/vdyp/io/parse/CoefficientParser.java | 22 +++-- .../vdyp/io/parse/UpperCoefficientParser.java | 73 +++++++++++++++ .../vdyp/io/parse/CoefficientParserTest.java | 92 +++++++++++++++++++ .../io/parse/UpperCoefficientParserTest.java | 82 +++++++++++++++++ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 38 ++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 16 +++- .../nrs/vdyp/fip/FipControlParserTest.java | 43 +++++++++ 8 files changed, 360 insertions(+), 8 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java index bfe7827f7..66f842c74 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -40,8 +40,8 @@ public boolean isStopLine(String line) { } .value(4, BEC_KEY, String::strip) .space(2) - .value(1, INDICATOR_KEY, ValueParser.INTEGER) - .value(2, COEFFICIENT_INDEX_KEY, ValueParser.INTEGER) + .value(1, COEFFICIENT_INDEX_KEY, ValueParser.INTEGER) + .value(2, INDICATOR_KEY, ValueParser.INTEGER) .multiValue(NUM_SPECIES, 8, COEFFICIENT_KEY, ValueParser.FLOAT); @Override @@ -58,18 +58,28 @@ public MatrixMap3 parse(InputStream is, Map) v.get(COEFFICIENT_KEY); + if( !becAliases.contains(bec)) { + throw new ValueParseException(bec, bec+" is not a valid BEC alias"); + } + if( !coeIndecies.contains(index)) { + throw new ValueParseException(Integer.toString(index), index+" is not a valid coefficient index"); + } + for(int species = 0; species> { + public static final int BA = 1; + public static final int DQ = 2; + + public static final String CONTROL_KEY = "UPPER_BA_BY_CI_S0_P"; + + public static final String SP0_KEY = "sp0"; + public static final String REGION_KEY = "region"; + public static final String COEFFICIENT_KEY = "coefficient"; + + public static final int NUM_COEFFICIENTS = 2; + + + LineParser lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + } + .value(2, SP0_KEY, String::strip) + .space(1) + .value(1, REGION_KEY, ValueParser.REGION) + .multiValue(NUM_COEFFICIENTS, 7, COEFFICIENT_KEY, ValueParser.FLOAT); + + @Override + public MatrixMap3 parse(InputStream is, Map control) + throws IOException, ResourceParseException { + var regionIndicies = Arrays.asList(Region.values()); + List coeIndicies = Stream.iterate(1, x->x+1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); + var speciesIndicies = ResourceParser.> expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); + + MatrixMap3 result = new MatrixMap3Impl(regionIndicies, speciesIndicies, coeIndicies); + lineParser.parse(is, result, (v, r) -> { + var sp0 = (String) v.get(SP0_KEY); + var region = (Region) v.get(REGION_KEY); + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENT_KEY); + if(!speciesIndicies.contains(sp0)) { + throw new ValueParseException(sp0, sp0+" is not a valid species"); + } + + for(int coeIndex = 0; coeIndex controlMap = new HashMap<>(); + + Map becMap = new HashMap<>(); + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); + becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + + var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + + } + + @Test + public void testBadIndex() throws Exception { + + var parser = new CoefficientParser(); + + var is = TestUtils.makeStream("B1 AX 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + Map controlMap = new HashMap<>(); + + Map becMap = new HashMap<>(); + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); + becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + + var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + + } + + @Test + public void testParseDelta() throws Exception { + + var parser = new CoefficientParser(); + + var is = TestUtils.makeStream("B1 A0 2 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + Map controlMap = new HashMap<>(); + + Map becMap = new HashMap<>(); + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); + becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer)1)); + assertThat(result, mmHasEntry(present(is(2.0028f-0.5343f)), 0, "B1", (Integer)2)); } + @Test + public void testParseFixed() throws Exception { + + var parser = new CoefficientParser(); + + var is = TestUtils.makeStream("B1 A0 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + Map controlMap = new HashMap<>(); + + Map becMap = new HashMap<>(); + becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); + becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer)1)); + assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer)2)); + + } + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java new file mode 100644 index 000000000..468c9fe31 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java @@ -0,0 +1,82 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class UpperCoefficientParserTest { + + @Test + public void testParseSimple() throws Exception { + + var parser = new UpperCoefficientParser(); + + var is = TestUtils.makeStream("S1 I 2.0028 -0.5343"); + + Map controlMap = new HashMap<>(); + + List sp0List = Arrays.asList( + new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), + new SP0Definition("S2", java.util.Optional.empty(), "Test S2") + ); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(2.0028f)), Region.INTERIOR, "S1", (Integer)1)); + } + + @Test + public void testParseBadSpecies() throws Exception { + + var parser = new UpperCoefficientParser(); + + var is = TestUtils.makeStream("SX I 2.0028 -0.5343"); + + Map controlMap = new HashMap<>(); + + List sp0List = Arrays.asList( + new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), + new SP0Definition("S2", java.util.Optional.empty(), "Test S2") + ); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + + } + @Test + public void testParseBadRegion() throws Exception { + + var parser = new UpperCoefficientParser(); + + var is = TestUtils.makeStream("S1 X 2.0028 -0.5343"); + + Map controlMap = new HashMap<>(); + + List sp0List = Arrays.asList( + new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), + new SP0Definition("S2", java.util.Optional.empty(), "Test S2") + ); + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + + var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index f5cc3c216..c16a38ef9 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -13,6 +13,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.model.MatrixMap; /** * Custom Hamcrest Matchers @@ -153,4 +154,41 @@ public void describeMismatch(Object item, Description description) { }; } + public static Matcher> mmHasEntry(Matcher> valueMatcher, Object...keys) { + return new BaseMatcher>() { + + @Override + public boolean matches(Object actual) { + if (! (actual instanceof MatrixMap)) { + return false; + } + return valueMatcher.matches(((MatrixMap)actual).getM(keys)); + } + + @Override + public void describeTo(Description description) { + description + .appendText("Matrix map with entry ") + .appendValueList("[", ", ", "]", keys) + .appendText(" that "); + valueMatcher.describeTo(description); + + } + + @Override + public void describeMismatch(Object item, Description description) { + if (! (item instanceof MatrixMap)) { + description.appendText("was not a MatrixMap"); + return; + } + // TODO give better feedback if keys don't match the map + var value = ((MatrixMap)item).getM(keys); + + description.appendText("entry ").appendValueList("[", ", ", "]", keys).appendText(" "); + valueMatcher.describeMismatch(value, description); + } + + }; + + } } diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index b112537c2..09da54463 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -32,7 +32,7 @@ 040 coe/REGBA25.coe Coe BA=f(CC) RD_E040 IPSJF128 041 coe/REGDQ26.coe Coe DQ=f(CC) RD_E041 IPSJF129 -043 coe/upperb02.coe Upper BA by C/I SP0_P RD_E043 IPSJF128 +043 coe/UPPERB02.COE Upper BA by C/I SP0_P RD_E043 IPSJF128 050 coe/regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 051 coe/regyhlpa.coe HL, Primary SP, Eqn P2 RD_YHL2 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index d9121265f..0d0b0083b 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -19,12 +19,14 @@ import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveParser; import ca.bc.gov.nrs.vdyp.io.parse.StockingClassFactorParser; +import ca.bc.gov.nrs.vdyp.io.parse.UpperCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; @@ -52,7 +54,7 @@ public class FipControlParser { public static final String STOCKING_CLASS_FACTORS = StockingClassFactorParser.CONTROL_KEY; public static final String COE_BA = CoefficientParser.BA_CONTROL_KEY; public static final String COE_DQ = CoefficientParser.DQ_CONTROL_KEY; - public static final String UPPER_BA_BY_CI_S0_P = "UPPER_BA_BY_CI_S0_P"; + public static final String UPPER_BA_BY_CI_S0_P = UpperCoefficientParser.CONTROL_KEY; public static final String HL_PRIMARY_SP_EQN_P1 = "HL_PRIMARY_SP_EQN_P1"; public static final String HL_PRIMARY_SP_EQN_P2 = "HL_PRIMARY_SP_EQN_P2"; public static final String HL_PRIMARY_SP_EQN_P3 = "HL_PRIMARY_SP_EQN_P3"; @@ -265,6 +267,7 @@ public String toString(String filename) throws IOException { loadData(map, COE_DQ, fileResolver, this::RD_E041); // RD_E043 + loadData(map, UPPER_BA_BY_CI_S0_P, fileResolver, this::RD_E043); // TODO // RD_YHL1 @@ -568,6 +571,17 @@ private MatrixMap3 RD_E041(InputStream data, Ma var parser = new CoefficientParser(); return parser.parse(data, control); } + + + /** + * Loads the information that was in the global array COE043 in Fortran + */ + private MatrixMap3 RD_E043(InputStream data, Map control) throws IOException, ResourceParseException { + // Species and Region mapped to two coefficients + var parser = new UpperCoefficientParser(); + + return parser.parse(data, control); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 59c67fe14..bc0d6ad83 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -1,5 +1,7 @@ package ca.bc.gov.nrs.vdyp.fip; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasEntry; @@ -241,6 +243,47 @@ public void testParseE026() throws Exception { ) ); } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE040() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.COE_BA), allOf( + mmHasEntry(present(is(2.0028f)), 0, "AT", 1) + ) + ) + ); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE041() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.COE_DQ), allOf( + mmHasEntry(present(is(6.6190f)), 0, "AT", 1) + ) + ) + ); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE043() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.UPPER_BA_BY_CI_S0_P), allOf( + mmHasEntry(present(is(109.27f)), Region.COASTAL, "AC", 1) + ) + ) + ); + } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test From 6e4741ab01e28f14c9c1bf11c09622ea041336aa Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 24 May 2023 12:16:09 -0700 Subject: [PATCH 22/98] HL coefficient parser --- .../vdyp/io/parse/HLCoefficientParser.java | 83 +++++++++++++ .../io/parse/HLCoefficientParserTest.java | 113 ++++++++++++++++++ .../io/parse/SP0DefinitionParserTest.java | 23 ++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 6 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 41 ++++++- .../nrs/vdyp/fip/FipControlParserTest.java | 57 +++++++-- 6 files changed, 307 insertions(+), 16 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java new file mode 100644 index 000000000..d00df1333 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java @@ -0,0 +1,83 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; + +/** + * Parses an HL Coefficient data file. + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class HLCoefficientParser implements ResourceParser> { + + public static final String CONTROL_KEY_P1 = "HL_PRIMARY_SP_EQN_P1"; + public static final String CONTROL_KEY_P2 = "HL_PRIMARY_SP_EQN_P2"; + public static final String CONTROL_KEY_P3 = "HL_PRIMARY_SP_EQN_P3"; + + public static final int NUM_COEFFICIENTS_P1 = 3; + public static final int NUM_COEFFICIENTS_P2 = 2; + public static final int NUM_COEFFICIENTS_P3 = 4; + + public static final String SP0_KEY = "sp0"; + public static final String REGION_KEY = "region"; + public static final String COEFFICIENT_KEY = "coefficient"; + + int numCoefficients; + + public HLCoefficientParser(int numCoefficients) { + super(); + this.numCoefficients = numCoefficients; + this.lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + } + .value(2, SP0_KEY, String::strip) + .space(1) + .value(1, REGION_KEY, ValueParser.REGION) + .multiValue(numCoefficients, 10, COEFFICIENT_KEY, ValueParser.FLOAT); + } + + LineParser lineParser; + + + @Override + public MatrixMap3 parse(InputStream is, Map control) + throws IOException, ResourceParseException { + final var regionIndicies = Arrays.asList(Region.values()); + final List coeIndicies = Stream.iterate(1, x->x+1).limit(numCoefficients).collect(Collectors.toList()); + final var speciesIndicies = ResourceParser.> expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); + + MatrixMap3 result = new MatrixMap3Impl(coeIndicies, speciesIndicies, regionIndicies); + lineParser.parse(is, result, (v, r) -> { + var sp0 = (String) v.get(SP0_KEY); + var region = (Region) v.get(REGION_KEY); + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENT_KEY); + if(!speciesIndicies.contains(sp0)) { + throw new ValueParseException(sp0, sp0+" is not a valid species"); + } + + for(int coeIndex = 0; coeIndex controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(1.00160f)), 1, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(0.20508f)), 2, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(-0.0013743f)), 3, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher)notPresent(), 4, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher)notPresent(), 0, "S1", Region.INTERIOR)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSimpleP2() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); + + var is = TestUtils.makeStream("S1 C 0.49722 1.18403"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(0.49722f)), 1, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry(present(is(1.18403f)), 2, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry((Matcher)notPresent(), 3, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry((Matcher)notPresent(), 0, "S1", Region.COASTAL)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSimpleP3() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); + + var is = TestUtils.makeStream("S1 I 1.04422 0.93010 -0.05745 -2.50000"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(1.04422f)), 1, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(0.93010f)), 2, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(-0.05745f)), 3, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(-2.50000f)), 4, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher)notPresent(), 5, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher)notPresent(), 0, "S1", Region.INTERIOR)); + } + + @Test + public void testParseBadSpecies() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + + var is = TestUtils.makeStream("SX I 1.00160 0.20508-0.0013743"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + + } + @Test + public void testParseBadRegion() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + + var is = TestUtils.makeStream("S1 X 1.00160 0.20508-0.0013743"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index 0d18da827..3b7fba056 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -10,8 +10,11 @@ import static org.hamcrest.Matchers.stringContainsInOrder; import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import org.easymock.internal.matchers.InstanceOf; import org.hamcrest.Matchers; @@ -238,4 +241,24 @@ public void testErrorPreferenceDuplicate() throws Exception { assertThat(ex1, hasProperty("message", stringContainsInOrder("line 2", "Preference 1", "set to AT"))); } + /** + * Add a mock control map entry for SP0 parse results with species "S1" and "S2" + */ + public static void populateControlMap(Map controlMap) { + populateControlMap(controlMap, "S1", "S2"); + } + + /** + * Add a mock control map entry for SP0 parse results + */ + public static void populateControlMap(Map controlMap, String...aliases) { + + List sp0List = new ArrayList<>(); + + for (var alias: aliases) { + sp0List.add(new SP0Definition(alias, java.util.Optional.empty(), "Test "+alias)); + } + + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + } } diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 09da54463..363cbd262 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -34,9 +34,9 @@ 041 coe/REGDQ26.coe Coe DQ=f(CC) RD_E041 IPSJF129 043 coe/UPPERB02.COE Upper BA by C/I SP0_P RD_E043 IPSJF128 -050 coe/regyhlp.coe HL, Primary SP, Eqn P1 RD_YHL1 -051 coe/regyhlpa.coe HL, Primary SP, Eqn P2 RD_YHL2 -052 coe/regyhlpb.dat HL, Primary SP, Eqn P3 RD_YHL3 +050 coe/REGYHLP.COE HL, Primary SP, Eqn P1 RD_YHL1 +051 coe/REGYHLPA.COE HL, Primary SP, Eqn P2 RD_YHL2 +052 coe/REGYHLPB.DAT HL, Primary SP, Eqn P3 RD_YHL3 053 coe/reghl.coe HL, Non-primary Species RD_YHL4 060 coe/REGDQI04.coe By-species DQ RD_E060 IPFJF125 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 0d0b0083b..0733e4f7e 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -23,6 +23,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; +import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.MatrixMap3; @@ -268,16 +269,15 @@ public String toString(String filename) throws IOException { // RD_E043 loadData(map, UPPER_BA_BY_CI_S0_P, fileResolver, this::RD_E043); - // TODO // RD_YHL1 - // TODO + loadData(map, HL_PRIMARY_SP_EQN_P1, fileResolver, this::RD_YHL1); // RD_YHL2 - // TODO + loadData(map, HL_PRIMARY_SP_EQN_P2, fileResolver, this::RD_YHL2); // RD_YHL3 - // TODO + loadData(map, HL_PRIMARY_SP_EQN_P3, fileResolver, this::RD_YHL3); // RD_YHL4 // TODO @@ -582,6 +582,39 @@ private MatrixMap3 RD_E043(InputStream data, Map return parser.parse(data, control); } + + /** + * Loads the information that was in the global array COE050 in Fortran + */ + private MatrixMap3 RD_YHL1(InputStream data, Map control) throws IOException, ResourceParseException { + // Species and Region mapped to three coefficients + // coeIndex from 1 + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 + // 11 FORMAT( A2 , 1x, A1, 3f10.0) + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + + return parser.parse(data, control); + } + /** + * Loads the information that was in the global array COE051 in Fortran + */ + private MatrixMap3 RD_YHL2(InputStream data, Map control) throws IOException, ResourceParseException { + // Species and Region mapped to two coefficients + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); + + return parser.parse(data, control); + } + /** + * Loads the information that was in the global array COE052 in Fortran + */ + private MatrixMap3 RD_YHL3(InputStream data, Map control) throws IOException, ResourceParseException { + // Species and Region mapped to four coefficients + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); + + return parser.parse(data, control); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index bc0d6ad83..282e95ca3 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -243,7 +243,20 @@ public void testParseE026() throws Exception { ) ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + // @Disabled + public void testParseE026Empty() throws Exception { + var parser = new FipControlParser(); + var result = parseWithAppendix(parser, "026 "); + // Map is empty but gives appropriate default values + assertThat(result, (Matcher) hasEntry(is(FipControlParser.SITE_CURVE_AGE_MAX), Matchers.anEmptyMap())); + assertThat( + ((Map) result.get(FipControlParser.SITE_CURVE_AGE_MAX)).get(1), + (Matcher) allOf(SiteCurveAgeMaximumParserTest.hasAge(Region.COASTAL, is(140.f))) + ); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE040() throws Exception { @@ -284,21 +297,47 @@ public void testParseE043() throws Exception { ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - // @Disabled - public void testParseE026Empty() throws Exception { + public void testParseE050() throws Exception { var parser = new FipControlParser(); - var result = parseWithAppendix(parser, "026 "); - // Map is empty but gives appropriate default values - assertThat(result, (Matcher) hasEntry(is(FipControlParser.SITE_CURVE_AGE_MAX), Matchers.anEmptyMap())); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - ((Map) result.get(FipControlParser.SITE_CURVE_AGE_MAX)).get(1), - (Matcher) allOf(SiteCurveAgeMaximumParserTest.hasAge(Region.COASTAL, is(140.f))) + result, (Matcher) hasEntry( + is(FipControlParser.HL_PRIMARY_SP_EQN_P1), allOf( + mmHasEntry(present(is(1.00160f)), 1, "AC", Region.COASTAL) + ) + ) + ); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE051() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.HL_PRIMARY_SP_EQN_P2), allOf( + mmHasEntry(present(is(0.49722f)), 1, "AC", Region.COASTAL) + ) + ) + ); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE052() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.HL_PRIMARY_SP_EQN_P3), allOf( + mmHasEntry(present(is(1.04422f)), 1, "AC", Region.COASTAL) + ) + ) ); } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From 45f7be226dbcce3f51d7ac2eada6a4c337d508c8 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 24 May 2023 13:44:02 -0700 Subject: [PATCH 23/98] Nonprimary coefficient parser --- .../vdyp/io/parse/EquationGroupParser.java | 5 +- .../vdyp/io/parse/HLCoefficientParser.java | 3 +- .../parse/HLNonprimaryCoefficientParser.java | 78 +++++++++++++ .../vdyp/io/parse/SP0DefinitionParser.java | 20 ++++ .../nrs/vdyp/io/parse/SiteCurveParser.java | 6 +- .../vdyp/io/parse/UpperCoefficientParser.java | 2 +- .../bc/gov/nrs/vdyp/model/Coefficients.java | 48 ++++++++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap4.java | 14 +++ .../bc/gov/nrs/vdyp/model/MatrixMap4Impl.java | 14 +++ .../vdyp/model/NonprimaryHLCoefficients.java | 23 ++++ .../HLNonprimaryCoefficientParserTest.java | 103 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 23 +++- .../nrs/vdyp/fip/FipControlParserTest.java | 14 +++ 14 files changed, 339 insertions(+), 16 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4Impl.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/NonprimaryHLCoefficients.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index 47f950943..0c22fa3ea 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -47,9 +47,8 @@ public EquationGroupParser(int identifierLength) { public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { - @SuppressWarnings("unchecked") - List sp0List = ResourceParser - .expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class); + final var sp0List = SP0DefinitionParser.getSpecies(control); + @SuppressWarnings("unchecked") Map becMap = ResourceParser .expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java index d00df1333..0f1a2b091 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java @@ -11,7 +11,6 @@ import ca.bc.gov.nrs.vdyp.model.MatrixMap3; import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; /** * Parses an HL Coefficient data file. @@ -60,7 +59,7 @@ public MatrixMap3 parse(InputStream is, Map coeIndicies = Stream.iterate(1, x->x+1).limit(numCoefficients).collect(Collectors.toList()); - final var speciesIndicies = ResourceParser.> expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); + final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); MatrixMap3 result = new MatrixMap3Impl(coeIndicies, speciesIndicies, regionIndicies); lineParser.parse(is, result, (v, r) -> { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java new file mode 100644 index 000000000..61bd1baa5 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java @@ -0,0 +1,78 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; +import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; +import ca.bc.gov.nrs.vdyp.model.Region; + +/** + * Parses an HL Nonprimary Coefficient data file. + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class HLNonprimaryCoefficientParser + implements ResourceParser> { + + public static final String CONTROL_KEY = "HL_NONPRIMARY"; + + public static final int NUM_COEFFICIENTS = 2; + + public static final String SPECIES_1_KEY = "species1"; + public static final String SPECIES_2_KEY = "species2"; + public static final String REGION_KEY = "region"; + public static final String EQUATION_KEY = "ieqn"; + public static final String COEFFICIENT_KEY = "coefficient"; + + public HLNonprimaryCoefficientParser() { + super(); + this.lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + }.value(2, SPECIES_1_KEY, String::strip).space(1).value(2, SPECIES_2_KEY, String::strip).space(1) + .value(1, REGION_KEY, ValueParser.REGION).space(1).integer(1, EQUATION_KEY) + .multiValue(NUM_COEFFICIENTS, 10, COEFFICIENT_KEY, ValueParser.FLOAT); + } + + LineParser lineParser; + + @Override + public MatrixMap3 + parse(InputStream is, Map control) throws IOException, ResourceParseException { + final var regionIndicies = Arrays.asList(Region.values()); + final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + + MatrixMap3 result = new MatrixMap3Impl( + speciesIndicies, speciesIndicies, regionIndicies + ); + lineParser.parse(is, result, (v, r) -> { + var sp0_1 = (String) v.get(SPECIES_1_KEY); + var sp0_2 = (String) v.get(SPECIES_2_KEY); + var ieqn = (Integer) v.get(EQUATION_KEY); + var region = (Region) v.get(REGION_KEY); + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENT_KEY); + SP0DefinitionParser.checkSpecies(speciesIndicies, sp0_1); + SP0DefinitionParser.checkSpecies(speciesIndicies, sp0_2); + + if (coefficients.size() < NUM_COEFFICIENTS) { + throw new ValueParseException(null, "Expected 2 coefficients"); // TODO handle this better + } + r.put(sp0_1, sp0_2, region, new NonprimaryHLCoefficients(coefficients, ieqn)); + + return r; + }); + return result; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index 31e6326c9..c474cde36 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -77,4 +78,23 @@ public List parse(InputStream is, Map control) return Collections.unmodifiableList(Arrays.asList(result)); } + public static void checkSpecies(final List speciesIndicies, final String sp0) throws ValueParseException { + if(!speciesIndicies.contains(sp0)) { + throw new ValueParseException(sp0, sp0+" is not a valid species"); + } + } + + public static void checkSpecies(final Map controlMap, final String sp0) throws ValueParseException { + final var speciesIndicies = getSpeciesAliases(controlMap); + checkSpecies(speciesIndicies, sp0); + } + + public static List getSpecies(final Map controlMap) { + return ResourceParser.> expectParsedControl(controlMap, SP0DefinitionParser.CONTROL_KEY, List.class); + } + + public static List getSpeciesAliases(final Map controlMap) { + return getSpecies(controlMap).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java index 409134e3c..81a21b1fe 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java @@ -45,10 +45,8 @@ public Map parse(InputStream is, Map control) return r; }); - @SuppressWarnings("unchecked") - List sp0List = ((List) ResourceParser - .expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class)).stream() - .map(s -> s.getAlias()).collect(Collectors.toList()); + final var sp0List = SP0DefinitionParser.getSpeciesAliases(control); + var missing = ExpectationDifference.difference(result.keySet(), sp0List).getMissing(); if (!missing.isEmpty()) { throw new ResourceParseValidException("Missing expected entries for " + String.join(", ", missing)); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java index 4538decc7..825b52fcf 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java @@ -50,7 +50,7 @@ public MatrixMap3 parse(InputStream is, Map coeIndicies = Stream.iterate(1, x->x+1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); - var speciesIndicies = ResourceParser.> expectParsedControl(control, SP0DefinitionParser.CONTROL_KEY, List.class).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); + final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); MatrixMap3 result = new MatrixMap3Impl(regionIndicies, speciesIndicies, coeIndicies); lineParser.parse(is, result, (v, r) -> { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java new file mode 100644 index 000000000..deaf56f55 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java @@ -0,0 +1,48 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.AbstractList; +import java.util.Collection; +import java.util.List; + +public class Coefficients extends AbstractList implements List { + float[] coe; + int indexFrom; + + public Coefficients(float[] coe, int indexFrom) { + this.coe = coe; + this.indexFrom = indexFrom; + } + + public Coefficients(List coe, int indexFrom) { + + this(listToArray(coe), indexFrom); + } + + private static float[] listToArray(List coe) { + float[] floatArray = new float[coe.size()]; + int i = 0; + + for (Float f : coe) { + floatArray[i++] = (f != null ? f : Float.NaN); + } + return floatArray; + } + + public Float get(int i) { + return coe[i]; + } + + public Float getCoe(int i) { + return coe[i - indexFrom]; + } + + @Override + public int size() { + return coe.length; + } + + @Override + public boolean addAll(Collection c) { + return false; + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4.java new file mode 100644 index 000000000..563dee11c --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4.java @@ -0,0 +1,14 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Optional; + +public interface MatrixMap4 extends MatrixMap { + + default public void put(K1 key1, K2 key2, K3 key3, K4 key4, V value) { + putM(value, key1, key2, key3, key4); + } + + default public Optional get(K1 key1, K2 key2, K3 key3, K4 key4) { + return getM(key1, key2, key3, key4); + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4Impl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4Impl.java new file mode 100644 index 000000000..fc5c9c0c3 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap4Impl.java @@ -0,0 +1,14 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Arrays; +import java.util.Collection; + +public class MatrixMap4Impl extends MatrixMapImpl implements MatrixMap4 { + + public MatrixMap4Impl( + Collection dimension1, Collection dimension2, Collection dimension3, Collection dimension4 + ) { + super(Arrays.asList(dimension1, dimension2, dimension3, dimension4)); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/NonprimaryHLCoefficients.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/NonprimaryHLCoefficients.java new file mode 100644 index 000000000..bab758b1b --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/NonprimaryHLCoefficients.java @@ -0,0 +1,23 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.List; + +public class NonprimaryHLCoefficients extends Coefficients { + + private int equationIndex; + + public NonprimaryHLCoefficients(float[] coe, int equationIndex) { + super(coe, 1); + this.equationIndex = equationIndex; + } + + public NonprimaryHLCoefficients(List coe, int equationIndex) { + super(coe, 1); + this.equationIndex = equationIndex; + } + + public int getEquationIndex() { + return equationIndex; + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java new file mode 100644 index 000000000..4d902e8a4 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java @@ -0,0 +1,103 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class HLNonprimaryCoefficientParserTest { + + @Test + public void testParseSimple() throws Exception { + + var parser = new HLNonprimaryCoefficientParser(); + + var is = TestUtils.makeStream("S1 S2 C 1 0.86323 1.00505"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(coe(0.86323f, 1.00505f, 1)), "S1", "S2", Region.COASTAL)); + } + + @Test + public void testParseBadSpecies1() throws Exception { + + var parser = new HLNonprimaryCoefficientParser(); + + var is = TestUtils.makeStream("SX S2 C 1 0.86323 1.00505"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + + } + + @Test + public void testParseBadSpecies2() throws Exception { + + var parser = new HLNonprimaryCoefficientParser(); + + var is = TestUtils.makeStream("S1 SX C 1 0.86323 1.00505"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + + } + + @Test + public void testParseBadRegion() throws Exception { + + var parser = new HLNonprimaryCoefficientParser(); + + var is = TestUtils.makeStream("S1 S2 X 1 0.86323 1.00505"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + + } + + @Test + public void testParseMissingCoefficient() throws Exception { + + var parser = new HLNonprimaryCoefficientParser(); + + var is = TestUtils.makeStream("S1 S2 C 1 0.86323"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + } + + public static Matcher coe(float c1, float c2, int ieqn) { + return allOf(hasProperty("equationIndex", is(ieqn)), contains(c1, c2)); + } +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 363cbd262..e171ad931 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -37,7 +37,7 @@ 050 coe/REGYHLP.COE HL, Primary SP, Eqn P1 RD_YHL1 051 coe/REGYHLPA.COE HL, Primary SP, Eqn P2 RD_YHL2 052 coe/REGYHLPB.DAT HL, Primary SP, Eqn P3 RD_YHL3 -053 coe/reghl.coe HL, Non-primary Species RD_YHL4 +053 coe/REGHL.COE HL, Non-primary Species RD_YHL4 060 coe/REGDQI04.coe By-species DQ RD_E060 IPFJF125 061 coe/complim.coe Species component size limits RD_E061 IPSJF158 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 0733e4f7e..2cc5f1f2b 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -24,9 +24,12 @@ import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.MatrixMap4; +import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; @@ -56,10 +59,10 @@ public class FipControlParser { public static final String COE_BA = CoefficientParser.BA_CONTROL_KEY; public static final String COE_DQ = CoefficientParser.DQ_CONTROL_KEY; public static final String UPPER_BA_BY_CI_S0_P = UpperCoefficientParser.CONTROL_KEY; - public static final String HL_PRIMARY_SP_EQN_P1 = "HL_PRIMARY_SP_EQN_P1"; - public static final String HL_PRIMARY_SP_EQN_P2 = "HL_PRIMARY_SP_EQN_P2"; - public static final String HL_PRIMARY_SP_EQN_P3 = "HL_PRIMARY_SP_EQN_P3"; - public static final String HL_NONPRIMARY = "HL_NONPRIMARY"; + public static final String HL_PRIMARY_SP_EQN_P1 = HLCoefficientParser.CONTROL_KEY_P1; + public static final String HL_PRIMARY_SP_EQN_P2 = HLCoefficientParser.CONTROL_KEY_P2; + public static final String HL_PRIMARY_SP_EQN_P3 = HLCoefficientParser.CONTROL_KEY_P3; + public static final String HL_NONPRIMARY = HLNonprimaryCoefficientParser.CONTROL_KEY; public static final String BY_SPECIES_DQ = "BY_SPECIES_DQ"; public static final String SPECIES_COMPONENT_SIZE_LIMIT = "SPECIES_COMPONENT_SIZE_LIMIT"; public static final String UTIL_COMP_BA = "UTIL_COMP_BA"; @@ -280,7 +283,7 @@ public String toString(String filename) throws IOException { loadData(map, HL_PRIMARY_SP_EQN_P3, fileResolver, this::RD_YHL3); // RD_YHL4 - // TODO + loadData(map, HL_NONPRIMARY, fileResolver, this::RD_YHL4); // RD_E060 // TODO @@ -615,6 +618,16 @@ private MatrixMap3 RD_YHL3(InputStream data, Map return parser.parse(data, control); } + + /** + * Loads the information that was in the global array COE053 in Fortran + */ + private MatrixMap3 RD_YHL4(InputStream data, Map control) throws IOException, ResourceParseException { + // Two Species and a Region mapped to 2 coefficients and an equation index + var parser = new HLNonprimaryCoefficientParser(); + + return parser.parse(data, control); + } static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 282e95ca3..53a2f3dfd 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -25,6 +25,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParserTest; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParserTest; @@ -336,6 +337,19 @@ public void testParseE052() throws Exception { ) ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE053() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasEntry( + is(FipControlParser.HL_NONPRIMARY), allOf( + mmHasEntry(present(HLNonprimaryCoefficientParserTest.coe(0.86323f, 1.00505f, 1)), "AC", "AT", Region.COASTAL) + ) + ) + ); + } static InputStream addToEnd(InputStream is, String... lines) { From a591af70793268ff7bebd611cd57368678f756dd Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 24 May 2023 13:44:47 -0700 Subject: [PATCH 24/98] Run formattter --- .../nrs/vdyp/io/parse/CoefficientParser.java | 54 +++++------ .../vdyp/io/parse/HLCoefficientParser.java | 37 ++++---- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 6 +- .../vdyp/io/parse/SP0DefinitionParser.java | 13 +-- .../vdyp/io/parse/UpperCoefficientParser.java | 30 +++--- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 9 +- .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 23 ++--- .../ca/bc/gov/nrs/vdyp/model/MatrixMap2.java | 2 +- .../bc/gov/nrs/vdyp/model/MatrixMap2Impl.java | 4 +- .../ca/bc/gov/nrs/vdyp/model/MatrixMap3.java | 4 +- .../bc/gov/nrs/vdyp/model/MatrixMap3Impl.java | 4 +- .../bc/gov/nrs/vdyp/model/MatrixMapImpl.java | 63 ++++++------- .../vdyp/io/parse/CoefficientParserTest.java | 93 +++++++++++-------- .../io/parse/HLCoefficientParserTest.java | 55 +++++------ .../gov/nrs/vdyp/io/parse/LineParserTest.java | 7 +- .../io/parse/SP0DefinitionParserTest.java | 16 ++-- .../io/parse/UpperCoefficientParserTest.java | 41 ++++---- .../bc/gov/nrs/vdyp/model/MatrixMapTest.java | 57 ++++++------ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 16 ++-- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 58 +++++++----- .../nrs/vdyp/fip/FipControlParserTest.java | 66 ++++++------- 21 files changed, 342 insertions(+), 316 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java index 66f842c74..4d6835aae 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -28,8 +28,7 @@ public class CoefficientParser implements ResourceParser parse(InputStream is, Map control) throws IOException, ResourceParseException { - var becAliases = ResourceParser.>expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class).keySet(); - var coeIndecies = Stream.iterate(0, x->x+1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); - var speciesIndecies = Stream.iterate(1, x->x+1).limit(NUM_SPECIES).collect(Collectors.toList()); - MatrixMap3 result = new MatrixMap3Impl(coeIndecies, becAliases, speciesIndecies); + var becAliases = ResourceParser + .>expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class) + .keySet(); + var coeIndecies = Stream.iterate(0, x -> x + 1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); + var speciesIndecies = Stream.iterate(1, x -> x + 1).limit(NUM_SPECIES).collect(Collectors.toList()); + MatrixMap3 result = new MatrixMap3Impl( + coeIndecies, becAliases, speciesIndecies + ); lineParser.parse(is, result, (v, r) -> { var bec = (String) v.get(BEC_KEY); var indicator = (int) v.get(INDICATOR_KEY); var index = (int) v.get(COEFFICIENT_INDEX_KEY); @SuppressWarnings("unchecked") var coefficients = (List) v.get(COEFFICIENT_KEY); - - if( !becAliases.contains(bec)) { - throw new ValueParseException(bec, bec+" is not a valid BEC alias"); + + if (!becAliases.contains(bec)) { + throw new ValueParseException(bec, bec + " is not a valid BEC alias"); } - if( !coeIndecies.contains(index)) { - throw new ValueParseException(Integer.toString(index), index+" is not a valid coefficient index"); + if (!coeIndecies.contains(index)) { + throw new ValueParseException(Integer.toString(index), index + " is not a valid coefficient index"); } - - for(int species = 0; species> { - + public static final String CONTROL_KEY_P1 = "HL_PRIMARY_SP_EQN_P1"; public static final String CONTROL_KEY_P2 = "HL_PRIMARY_SP_EQN_P2"; public static final String CONTROL_KEY_P3 = "HL_PRIMARY_SP_EQN_P3"; @@ -27,13 +27,13 @@ public class HLCoefficientParser implements ResourceParser parse(InputStream is, Map control) throws IOException, ResourceParseException { final var regionIndicies = Arrays.asList(Region.values()); - final List coeIndicies = Stream.iterate(1, x->x+1).limit(numCoefficients).collect(Collectors.toList()); + final List coeIndicies = Stream.iterate(1, x -> x + 1).limit(numCoefficients) + .collect(Collectors.toList()); final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); - - MatrixMap3 result = new MatrixMap3Impl(coeIndicies, speciesIndicies, regionIndicies); + + MatrixMap3 result = new MatrixMap3Impl( + coeIndicies, speciesIndicies, regionIndicies + ); lineParser.parse(is, result, (v, r) -> { var sp0 = (String) v.get(SP0_KEY); var region = (Region) v.get(REGION_KEY); @SuppressWarnings("unchecked") var coefficients = (List) v.get(COEFFICIENT_KEY); - if(!speciesIndicies.contains(sp0)) { - throw new ValueParseException(sp0, sp0+" is not a valid species"); + if (!speciesIndicies.contains(sp0)) { + throw new ValueParseException(sp0, sp0 + " is not a valid species"); } - - for(int coeIndex = 0; coeIndex LineParser multiValue(int number, int length, String name, ValueParse throw new IllegalArgumentException("number can not be negative"); if (length < 0) throw new IllegalArgumentException("length can not be negative"); - - return doValue(length*number, name, ValueParser.segmentList(length, parser)); + + return doValue(length * number, name, ValueParser.segmentList(length, parser)); } - + /** * Add a segment * diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index c474cde36..716ee315a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -79,20 +79,21 @@ public List parse(InputStream is, Map control) } public static void checkSpecies(final List speciesIndicies, final String sp0) throws ValueParseException { - if(!speciesIndicies.contains(sp0)) { - throw new ValueParseException(sp0, sp0+" is not a valid species"); + if (!speciesIndicies.contains(sp0)) { + throw new ValueParseException(sp0, sp0 + " is not a valid species"); } } - - public static void checkSpecies(final Map controlMap, final String sp0) throws ValueParseException { + + public static void checkSpecies(final Map controlMap, final String sp0) throws ValueParseException { final var speciesIndicies = getSpeciesAliases(controlMap); checkSpecies(speciesIndicies, sp0); } public static List getSpecies(final Map controlMap) { - return ResourceParser.> expectParsedControl(controlMap, SP0DefinitionParser.CONTROL_KEY, List.class); + return ResourceParser + .>expectParsedControl(controlMap, SP0DefinitionParser.CONTROL_KEY, List.class); } - + public static List getSpeciesAliases(final Map controlMap) { return getSpecies(controlMap).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java index 825b52fcf..afe63767e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java @@ -22,7 +22,7 @@ public class UpperCoefficientParser implements ResourceParser> { public static final int BA = 1; public static final int DQ = 2; - + public static final String CONTROL_KEY = "UPPER_BA_BY_CI_S0_P"; public static final String SP0_KEY = "sp0"; @@ -30,8 +30,7 @@ public class UpperCoefficientParser implements ResourceParser parse(InputStream is, Map control) throws IOException, ResourceParseException { var regionIndicies = Arrays.asList(Region.values()); - List coeIndicies = Stream.iterate(1, x->x+1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); + List coeIndicies = Stream.iterate(1, x -> x + 1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); - - MatrixMap3 result = new MatrixMap3Impl(regionIndicies, speciesIndicies, coeIndicies); + + MatrixMap3 result = new MatrixMap3Impl( + regionIndicies, speciesIndicies, coeIndicies + ); lineParser.parse(is, result, (v, r) -> { var sp0 = (String) v.get(SP0_KEY); var region = (Region) v.get(REGION_KEY); @SuppressWarnings("unchecked") var coefficients = (List) v.get(COEFFICIENT_KEY); - if(!speciesIndicies.contains(sp0)) { - throw new ValueParseException(sp0, sp0+" is not a valid species"); + if (!speciesIndicies.contains(sp0)) { + throw new ValueParseException(sp0, sp0 + " is not a valid species"); } - - for(int coeIndex = 0; coeIndex ValueParser> optional(ValueParser delegate) { return Optional.empty(); }; } - + /** * Parse a string as a set of fixed length chucks. + * * @param - * @param length length of a chunk + * @param length length of a chunk * @param delegate parser for the individual chunks * @return */ public static ValueParser> segmentList(int length, ValueParser delegate) { return s -> { - var result = new ArrayList((s.length()+length-1)/length); + var result = new ArrayList( (s.length() + length - 1) / length); for (int i = 0; i < s.length(); i += length) { - var j = Math.min(i+length, s.length()); + var j = Math.min(i + length, s.length()); result.add(delegate.parse(s.substring(i, j))); } return Collections.unmodifiableList(result); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java index 1eca3e317..910289a36 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -4,25 +4,26 @@ import java.util.function.Predicate; /** - * A mapping from the cartesian product of a set of arbitrary identifiers to a value. - * + * A mapping from the cartesian product of a set of arbitrary identifiers to a + * value. + * * @author Kevin Smith, Vivid Solutions * * @param */ public interface MatrixMap { - - public Optional getM(Object...params); - - public void putM(T value, Object...params); - + + public Optional getM(Object... params); + + public void putM(T value, Object... params); + public boolean all(Predicate pred); - + default public boolean isFull() { - return all(x->x!=null); + return all(x -> x != null); } - + default public boolean isEmpty() { - return all(x->x==null); + return all(x -> x == null); } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java index adee7a163..10e52206e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java @@ -7,7 +7,7 @@ public interface MatrixMap2 extends MatrixMap { default public void put(K1 key1, K2 key2, V value) { putM(value, key1, key2); } - + default public Optional get(K1 key1, K2 key2) { return getM(key1, key2); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java index 6db0cc21b..09dd9be91 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2Impl.java @@ -3,10 +3,10 @@ import java.util.Arrays; import java.util.Collection; -public class MatrixMap2Impl extends MatrixMapImpl implements MatrixMap2{ +public class MatrixMap2Impl extends MatrixMapImpl implements MatrixMap2 { public MatrixMap2Impl(Collection dimension1, Collection dimension2) { super(Arrays.asList(dimension1, dimension2)); } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java index c69a9ecba..90d15bd49 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java @@ -3,11 +3,11 @@ import java.util.Optional; public interface MatrixMap3 extends MatrixMap { - + default public void put(K1 key1, K2 key2, K3 key3, V value) { putM(value, key1, key2, key3); } - + default public Optional get(K1 key1, K2 key2, K3 key3) { return getM(key1, key2, key3); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java index 6ce7ff28e..9e83de909 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3Impl.java @@ -3,10 +3,10 @@ import java.util.Arrays; import java.util.Collection; -public class MatrixMap3Impl extends MatrixMapImpl implements MatrixMap3{ +public class MatrixMap3Impl extends MatrixMapImpl implements MatrixMap3 { public MatrixMap3Impl(Collection dimension1, Collection dimension2, Collection dimension3) { super(Arrays.asList(dimension1, dimension2, dimension3)); } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java index 0462a52cf..85cb91cf0 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java @@ -10,8 +10,9 @@ import java.util.stream.Collectors; /** - * A mapping from the cartesian product of a set of arbitrary identifiers to a value. - * + * A mapping from the cartesian product of a set of arbitrary identifiers to a + * value. + * * @author Kevin Smith, Vivid Solutions * * @param @@ -19,72 +20,72 @@ public class MatrixMapImpl implements MatrixMap { List> maps; Object[] matrix; - + public MatrixMapImpl(Collection> dimensions) { - if(dimensions.isEmpty()) { + if (dimensions.isEmpty()) { throw new IllegalArgumentException("Must have at least one dimension"); } - if(dimensions.stream().anyMatch(dim->dim.isEmpty())) { + if (dimensions.stream().anyMatch(dim -> dim.isEmpty())) { throw new IllegalArgumentException("Each dimension must have at least one value"); } - maps = dimensions.stream().map(dim->{ + maps = dimensions.stream().map(dim -> { var map = new HashMap(dim.size()); - int i=0; - for(var o : dim) { - map.put(o,i); + int i = 0; + for (var o : dim) { + map.put(o, i); i++; } return map; }).collect(Collectors.toList()); - var matrixSize = maps.stream().map(Map::size).reduce(1, (x,y)->x*y); + var matrixSize = maps.stream().map(Map::size).reduce(1, (x, y) -> x * y); matrix = new Object[matrixSize]; } - + public MatrixMapImpl(Collection... dimensions) { this(Arrays.asList(dimensions)); } - + @SuppressWarnings("unchecked") - public Optional getM(Object...params) { - return (Optional) getIndex(params).flatMap(i->Optional.ofNullable(matrix[i])); + public Optional getM(Object... params) { + return (Optional) getIndex(params).flatMap(i -> Optional.ofNullable(matrix[i])); } - - public void putM(T value, Object...params) { - matrix[getIndex(params).orElseThrow(()->new IllegalArgumentException())] = value; + + public void putM(T value, Object... params) { + matrix[getIndex(params).orElseThrow(() -> new IllegalArgumentException())] = value; } - - protected Optional getIndex(Object...params) { - if(params.length!=maps.size()) { + + protected Optional getIndex(Object... params) { + if (params.length != maps.size()) { throw new IllegalArgumentException("MatrixMap requires parameters to equal the number of dimensions"); } int i = 0; - int index=0; + int index = 0; int step = 1; - for(var o: params) { + for (var o : params) { var dim = maps.get(i); Integer dimIndex = dim.get(o); - if(dimIndex==null) { + if (dimIndex == null) { return Optional.empty(); } - index+=step*dimIndex; - - step*=dim.size(); + index += step * dimIndex; + + step *= dim.size(); i++; } return Optional.of(index); } - + @SuppressWarnings("unchecked") public boolean all(Predicate pred) { return Arrays.stream(matrix).allMatch((Predicate) pred); } - + public boolean isFull() { - return all(x->x!=null); + return all(x -> x != null); } - + public boolean isEmpty() { - return all(x->x==null); + return all(x -> x == null); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java index 7ae53d4b5..4fbd4a5f7 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java @@ -17,108 +17,119 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; public class CoefficientParserTest { - + @Test public void testParseSimple() throws Exception { - + var parser = new CoefficientParser(); - - var is = TestUtils.makeStream("B1 A0 1 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + var is = TestUtils.makeStream( + "B1 A0 1 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" + ); Map controlMap = new HashMap<>(); - + Map becMap = new HashMap<>(); becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); var result = parser.parse(is, controlMap); - - assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer)1)); // COEs are 0 indexed, species are 1 indexed - assertThat(result, mmHasEntry(present(is(-0.5343f)), 0, "B1", (Integer)2)); + + assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer) 1)); // COEs are 0 indexed, species are 1 + // indexed + assertThat(result, mmHasEntry(present(is(-0.5343f)), 0, "B1", (Integer) 2)); } - + @Test public void testBadBec() throws Exception { - + var parser = new CoefficientParser(); - - var is = TestUtils.makeStream("BX A0 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + var is = TestUtils.makeStream( + "BX A0 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" + ); Map controlMap = new HashMap<>(); - + Map becMap = new HashMap<>(); becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); - var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } - + @Test public void testBadIndex() throws Exception { - + var parser = new CoefficientParser(); - - var is = TestUtils.makeStream("B1 AX 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + var is = TestUtils.makeStream( + "B1 AX 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" + ); Map controlMap = new HashMap<>(); - + Map becMap = new HashMap<>(); becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); - var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } - + @Test public void testParseDelta() throws Exception { - + var parser = new CoefficientParser(); - - var is = TestUtils.makeStream("B1 A0 2 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + var is = TestUtils.makeStream( + "B1 A0 2 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" + ); Map controlMap = new HashMap<>(); - + Map becMap = new HashMap<>(); becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); var result = parser.parse(is, controlMap); - - assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer)1)); - assertThat(result, mmHasEntry(present(is(2.0028f-0.5343f)), 0, "B1", (Integer)2)); + + assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer) 1)); + assertThat(result, mmHasEntry(present(is(2.0028f - 0.5343f)), 0, "B1", (Integer) 2)); } - + @Test public void testParseFixed() throws Exception { - + var parser = new CoefficientParser(); - - var is = TestUtils.makeStream("B1 A0 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507"); + + var is = TestUtils.makeStream( + "B1 A0 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" + ); Map controlMap = new HashMap<>(); - + Map becMap = new HashMap<>(); becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - + controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); var result = parser.parse(is, controlMap); - - assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer)1)); - assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer)2)); + + assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer) 1)); + assertThat(result, mmHasEntry(present(is(2.0028f)), 0, "B1", (Integer) 2)); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java index a2e4cb3dc..71ab7edce 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java @@ -17,17 +17,17 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; public class HLCoefficientParserTest { - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSimpleP1() throws Exception { - + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - + var is = TestUtils.makeStream("S1 I 1.00160 0.20508-0.0013743"); Map controlMap = new HashMap<>(); - + SP0DefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -35,40 +35,40 @@ public void testParseSimpleP1() throws Exception { assertThat(result, mmHasEntry(present(is(1.00160f)), 1, "S1", Region.INTERIOR)); assertThat(result, mmHasEntry(present(is(0.20508f)), 2, "S1", Region.INTERIOR)); assertThat(result, mmHasEntry(present(is(-0.0013743f)), 3, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher)notPresent(), 4, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher)notPresent(), 0, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 4, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.INTERIOR)); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSimpleP2() throws Exception { - + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); - + var is = TestUtils.makeStream("S1 C 0.49722 1.18403"); Map controlMap = new HashMap<>(); - + SP0DefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); assertThat(result, mmHasEntry(present(is(0.49722f)), 1, "S1", Region.COASTAL)); assertThat(result, mmHasEntry(present(is(1.18403f)), 2, "S1", Region.COASTAL)); - assertThat(result, mmHasEntry((Matcher)notPresent(), 3, "S1", Region.COASTAL)); - assertThat(result, mmHasEntry((Matcher)notPresent(), 0, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 3, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.COASTAL)); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSimpleP3() throws Exception { - + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); - + var is = TestUtils.makeStream("S1 I 1.04422 0.93010 -0.05745 -2.50000"); Map controlMap = new HashMap<>(); - + SP0DefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -77,36 +77,37 @@ public void testParseSimpleP3() throws Exception { assertThat(result, mmHasEntry(present(is(0.93010f)), 2, "S1", Region.INTERIOR)); assertThat(result, mmHasEntry(present(is(-0.05745f)), 3, "S1", Region.INTERIOR)); assertThat(result, mmHasEntry(present(is(-2.50000f)), 4, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher)notPresent(), 5, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher)notPresent(), 0, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 5, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.INTERIOR)); } - + @Test public void testParseBadSpecies() throws Exception { - + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - + var is = TestUtils.makeStream("SX I 1.00160 0.20508-0.0013743"); Map controlMap = new HashMap<>(); - + SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } + @Test public void testParseBadRegion() throws Exception { - + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - + var is = TestUtils.makeStream("S1 X 1.00160 0.20508-0.0013743"); Map controlMap = new HashMap<>(); - + SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 1459b4c96..bc41dac78 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -154,17 +154,16 @@ public void testStripped() throws Exception { ); } + @SuppressWarnings("unchecked") @Test public void testMultiValue() throws Exception { var parser = new LineParser(); parser.multiValue(4, 3, "test", ValueParser.INTEGER); - var result1 = parser.parseLine( - " 02 04 06 08" - ); + var result1 = parser.parseLine(" 02 04 06 08"); - assertThat(result1, hasEntry(is("test"), (Matcher) contains(2,4,6,8))); + assertThat(result1, hasEntry(is("test"), (Matcher) contains(2, 4, 6, 8))); } @SuppressWarnings({ "unchecked", "rawtypes" }) diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index 3b7fba056..edc03b449 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -247,18 +247,18 @@ public void testErrorPreferenceDuplicate() throws Exception { public static void populateControlMap(Map controlMap) { populateControlMap(controlMap, "S1", "S2"); } - + /** * Add a mock control map entry for SP0 parse results */ - public static void populateControlMap(Map controlMap, String...aliases) { - - List sp0List = new ArrayList<>(); - - for (var alias: aliases) { - sp0List.add(new SP0Definition(alias, java.util.Optional.empty(), "Test "+alias)); + public static void populateControlMap(Map controlMap, String... aliases) { + + List sp0List = new ArrayList<>(); + + for (var alias : aliases) { + sp0List.add(new SP0Definition(alias, java.util.Optional.empty(), "Test " + alias)); } - + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java index 468c9fe31..6d428f8a3 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java @@ -18,64 +18,65 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; public class UpperCoefficientParserTest { - + @Test public void testParseSimple() throws Exception { - + var parser = new UpperCoefficientParser(); - + var is = TestUtils.makeStream("S1 I 2.0028 -0.5343"); Map controlMap = new HashMap<>(); - + List sp0List = Arrays.asList( new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), new SP0Definition("S2", java.util.Optional.empty(), "Test S2") - ); - + ); + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); var result = parser.parse(is, controlMap); - assertThat(result, mmHasEntry(present(is(2.0028f)), Region.INTERIOR, "S1", (Integer)1)); + assertThat(result, mmHasEntry(present(is(2.0028f)), Region.INTERIOR, "S1", (Integer) 1)); } - + @Test public void testParseBadSpecies() throws Exception { - + var parser = new UpperCoefficientParser(); - + var is = TestUtils.makeStream("SX I 2.0028 -0.5343"); Map controlMap = new HashMap<>(); - + List sp0List = Arrays.asList( new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), new SP0Definition("S2", java.util.Optional.empty(), "Test S2") - ); - + ); + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); - var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } + @Test public void testParseBadRegion() throws Exception { - + var parser = new UpperCoefficientParser(); - + var is = TestUtils.makeStream("S1 X 2.0028 -0.5343"); Map controlMap = new HashMap<>(); - + List sp0List = Arrays.asList( new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), new SP0Definition("S2", java.util.Optional.empty(), "Test S2") - ); - + ); + controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); - var ex = assertThrows(ResourceParseLineException.class, ()->parser.parse(is, controlMap)); + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index 7cfc4eef4..260cb49ee 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -18,103 +18,104 @@ public class MatrixMapTest { @Test public void testContruct() { var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1,2); + var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var result = new MatrixMapImpl(dims); } + @Test public void testContructNoDimensionsFails() { List> dims = Collections.emptyList(); - Assertions.assertThrows(IllegalArgumentException.class,()-> new MatrixMapImpl(dims)); + Assertions.assertThrows(IllegalArgumentException.class, () -> new MatrixMapImpl(dims)); } + @Test public void testContructEmptyDimensionsFails() { var dim1 = Collections.emptyList(); var dims = Arrays.asList(dim1); - Assertions.assertThrows(IllegalArgumentException.class,()-> new MatrixMapImpl(dims)); + Assertions.assertThrows(IllegalArgumentException.class, () -> new MatrixMapImpl(dims)); } - + @Test public void testNewMapIsEmpty() { var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1,2); + var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var result = new MatrixMapImpl(dims); assertThat(result, hasProperty("empty", is(true))); assertThat(result, hasProperty("full", is(false))); } - + @Test public void testDefaultIsEmpty() { var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1,2); + var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var map = new MatrixMapImpl(dims); - - var result = map.getM("a",2); - + + var result = map.getM("a", 2); + assertThat(result, notPresent()); } - + @Test public void testCanRetrieveAValue() { var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1,2); + var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var map = new MatrixMapImpl(dims); - + map.putM('Z', "a", 2); - var result = map.getM("a",2); - + var result = map.getM("a", 2); + assertThat(result, present(is('Z'))); } - + @Test public void testWithOneValueIsNeitherFullNorEmpty() { var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1,2); + var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var map = new MatrixMapImpl(dims); - + map.putM('Z', "a", 2); - + assertThat(map, hasProperty("full", is(false))); assertThat(map, hasProperty("empty", is(false))); } - + @Test public void testGetIndex() { var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1,2); + var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var map = new MatrixMapImpl(dims); - + assertThat(map.getIndex("a", 1), present(is(0))); assertThat(map.getIndex("b", 1), present(is(1))); assertThat(map.getIndex("a", 2), present(is(2))); assertThat(map.getIndex("b", 2), present(is(3))); } - + @Test public void testFullMap() { var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1,2); + var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var map = new MatrixMapImpl(dims); - + map.putM('W', "a", 1); map.putM('X', "a", 2); map.putM('Y', "b", 1); map.putM('Z', "b", 2); - + assertThat(map, hasProperty("full", is(true))); assertThat(map, hasProperty("empty", is(false))); - + assertThat(map.getM("a", 1), present(is('W'))); assertThat(map.getM("a", 2), present(is('X'))); assertThat(map.getM("b", 1), present(is('Y'))); assertThat(map.getM("b", 2), present(is('Z'))); } - } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index c16a38ef9..28a512e90 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -154,7 +154,7 @@ public void describeMismatch(Object item, Description description) { }; } - public static Matcher> mmHasEntry(Matcher> valueMatcher, Object...keys) { + public static Matcher> mmHasEntry(Matcher> valueMatcher, Object... keys) { return new BaseMatcher>() { @Override @@ -162,17 +162,15 @@ public boolean matches(Object actual) { if (! (actual instanceof MatrixMap)) { return false; } - return valueMatcher.matches(((MatrixMap)actual).getM(keys)); + return valueMatcher.matches( ((MatrixMap) actual).getM(keys)); } @Override public void describeTo(Description description) { - description - .appendText("Matrix map with entry ") - .appendValueList("[", ", ", "]", keys) - .appendText(" that "); + description.appendText("Matrix map with entry ").appendValueList("[", ", ", "]", keys) + .appendText(" that "); valueMatcher.describeTo(description); - + } @Override @@ -182,8 +180,8 @@ public void describeMismatch(Object item, Description description) { return; } // TODO give better feedback if keys don't match the map - var value = ((MatrixMap)item).getM(keys); - + var value = ((MatrixMap) item).getM(keys); + description.appendText("entry ").appendValueList("[", ", ", "]", keys).appendText(" "); valueMatcher.describeMismatch(value, description); } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 2cc5f1f2b..bea00dfa5 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -550,82 +550,92 @@ private Map RD_E026(InputStream data, Map RD_E040(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 RD_E040(InputStream data, Map control) + throws IOException, ResourceParseException { // 10 coefficients by species (SP0) by becs - // 4 String BEC Alias, 2 gap, 1 int coefficient index, 2 int "Indicate", 16x8 Float coefficient for species + // 4 String BEC Alias, 2 gap, 1 int coefficient index, 2 int "Indicate", 16x8 + // Float coefficient for species // Blank bec is ignore line - + // if indicate is 2, map the coefficients in directly - // if indicate is 0 write the first coeffecient from the file to all in the array + // if indicate is 0 write the first coeffecient from the file to all in the + // array // if the indicate is 1, add the first from the file to each subsequent one. - + var parser = new CoefficientParser(); return parser.parse(data, control); } - + /** * Loads the information that was in the global array COE041 in Fortran */ - private MatrixMap3 RD_E041(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 RD_E041(InputStream data, Map control) + throws IOException, ResourceParseException { var parser = new CoefficientParser(); return parser.parse(data, control); } - /** * Loads the information that was in the global array COE043 in Fortran */ - private MatrixMap3 RD_E043(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 RD_E043(InputStream data, Map control) + throws IOException, ResourceParseException { // Species and Region mapped to two coefficients var parser = new UpperCoefficientParser(); - + return parser.parse(data, control); } - + /** * Loads the information that was in the global array COE050 in Fortran */ - private MatrixMap3 RD_YHL1(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 RD_YHL1(InputStream data, Map control) + throws IOException, ResourceParseException { // Species and Region mapped to three coefficients // coeIndex from 1 - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 - // 11 FORMAT( A2 , 1x, A1, 3f10.0) + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 + // 11 FORMAT( A2 , 1x, A1, 3f10.0) var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - + return parser.parse(data, control); } + /** * Loads the information that was in the global array COE051 in Fortran */ - private MatrixMap3 RD_YHL2(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 RD_YHL2(InputStream data, Map control) + throws IOException, ResourceParseException { // Species and Region mapped to two coefficients - + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); - + return parser.parse(data, control); } + /** * Loads the information that was in the global array COE052 in Fortran */ - private MatrixMap3 RD_YHL3(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 RD_YHL3(InputStream data, Map control) + throws IOException, ResourceParseException { // Species and Region mapped to four coefficients var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); - + return parser.parse(data, control); } - + /** * Loads the information that was in the global array COE053 in Fortran */ - private MatrixMap3 RD_YHL4(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 + RD_YHL4(InputStream data, Map control) throws IOException, ResourceParseException { // Two Species and a Region mapped to 2 coefficients and an equation index var parser = new HLNonprimaryCoefficientParser(); - + return parser.parse(data, control); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 53a2f3dfd..2fafbbe9b 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -244,6 +244,7 @@ public void testParseE026() throws Exception { ) ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test // @Disabled @@ -264,94 +265,97 @@ public void testParseE040() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.COE_BA), allOf( - mmHasEntry(present(is(2.0028f)), 0, "AT", 1) - ) - ) + result, + (Matcher) hasEntry(is(FipControlParser.COE_BA), allOf(mmHasEntry(present(is(2.0028f)), 0, "AT", 1))) ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE041() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.COE_DQ), allOf( - mmHasEntry(present(is(6.6190f)), 0, "AT", 1) - ) - ) + result, + (Matcher) hasEntry(is(FipControlParser.COE_DQ), allOf(mmHasEntry(present(is(6.6190f)), 0, "AT", 1))) ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE043() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.UPPER_BA_BY_CI_S0_P), allOf( - mmHasEntry(present(is(109.27f)), Region.COASTAL, "AC", 1) - ) + result, + (Matcher) hasEntry( + is(FipControlParser.UPPER_BA_BY_CI_S0_P), + allOf(mmHasEntry(present(is(109.27f)), Region.COASTAL, "AC", 1)) ) ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE050() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.HL_PRIMARY_SP_EQN_P1), allOf( - mmHasEntry(present(is(1.00160f)), 1, "AC", Region.COASTAL) - ) + result, + (Matcher) hasEntry( + is(FipControlParser.HL_PRIMARY_SP_EQN_P1), + allOf(mmHasEntry(present(is(1.00160f)), 1, "AC", Region.COASTAL)) ) ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE051() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.HL_PRIMARY_SP_EQN_P2), allOf( - mmHasEntry(present(is(0.49722f)), 1, "AC", Region.COASTAL) - ) + result, + (Matcher) hasEntry( + is(FipControlParser.HL_PRIMARY_SP_EQN_P2), + allOf(mmHasEntry(present(is(0.49722f)), 1, "AC", Region.COASTAL)) ) ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE052() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.HL_PRIMARY_SP_EQN_P3), allOf( - mmHasEntry(present(is(1.04422f)), 1, "AC", Region.COASTAL) - ) + result, + (Matcher) hasEntry( + is(FipControlParser.HL_PRIMARY_SP_EQN_P3), + allOf(mmHasEntry(present(is(1.04422f)), 1, "AC", Region.COASTAL)) ) ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE053() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.HL_NONPRIMARY), allOf( - mmHasEntry(present(HLNonprimaryCoefficientParserTest.coe(0.86323f, 1.00505f, 1)), "AC", "AT", Region.COASTAL) + result, + (Matcher) hasEntry( + is(FipControlParser.HL_NONPRIMARY), + allOf( + mmHasEntry( + present(HLNonprimaryCoefficientParserTest.coe(0.86323f, 1.00505f, 1)), "AC", + "AT", Region.COASTAL + ) ) ) ); } - static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From faf23cab742b7a873f881868e06da621cb200ebe Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 24 May 2023 17:58:43 -0700 Subject: [PATCH 25/98] BySpeciesDqCoefficientParser --- .../vdyp/io/parse/BaseCoefficientParser.java | 106 ++++++++++++++++ .../parse/BySpeciesDqCoefficientParser.java | 76 ++++++++++++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 81 +++++++++++++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap2.java | 57 +++++++++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap3.java | 57 +++++++++ .../bc/gov/nrs/vdyp/model/MatrixMapImpl.java | 22 ++++ .../BySpeciesDqCoefficientParserTest.java | 50 ++++++++ .../SimpleSpeciesCoefficientParserTest.java | 114 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 29 ++++- .../nrs/vdyp/fip/FipControlParserTest.java | 30 +++++ 11 files changed, 620 insertions(+), 4 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java new file mode 100644 index 000000000..cf3cb60fe --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -0,0 +1,106 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap; +import ca.bc.gov.nrs.vdyp.model.Region; + +/** + * Parses a Coefficient data file. + * + * @author Kevin Smith, Vivid Solutions + * + */ +public abstract class BaseCoefficientParser> + implements ResourceParser { + + public static final String SP0_KEY = "sp0"; + public static final String REGION_KEY = "region"; + public static final String COEFFICIENTS_KEY = "coefficients"; + + int numCoefficients; + + List metaKeys = new ArrayList<>(); + List> keyRanges = new ArrayList<>(); + + public BaseCoefficientParser() { + super(); + this.lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + }; + } + + public BaseCoefficientParser + key(int length, String name, ValueParser parser, Collection range, String errorTemplate) { + var validParser = ValueParser.validate( + parser, (v) -> range.contains(v) ? Optional.empty() : Optional.of(String.format(errorTemplate, v)) + ); + lineParser.value(length, name, validParser); + metaKeys.add(name); + keyRanges.add(range); + return this; + } + + public BaseCoefficientParser regionKey() { + var regions = Arrays.asList(Region.values()); + return key(1, REGION_KEY, ValueParser.REGION, regions, "% is not a valid region"); + } + + public BaseCoefficientParser speciesKey(String name, Map controlMap) { + var range = SP0DefinitionParser.getSpeciesAliases(controlMap); + return key(2, name, String::strip, range, "% is not a valid species"); + } + + public BaseCoefficientParser speciesKey(Map controlMap) { + return speciesKey(SP0_KEY, controlMap); + } + + public BaseCoefficientParser space(int length) { + lineParser.space(length); + return this; + } + + public BaseCoefficientParser coefficients(int number, int length) { + lineParser.multiValue(number, length, COEFFICIENTS_KEY, ValueParser.FLOAT); + numCoefficients = number; + return this; + } + + protected LineParser lineParser; + + @Override + public M parse(InputStream is, Map control) throws IOException, ResourceParseException { + + M result = createMap(keyRanges); + + lineParser.parse(is, result, (v, r) -> { + var key = metaKeys.stream().map(v::get).collect(Collectors.toList()).toArray(Object[]::new); + + @SuppressWarnings("unchecked") + var coe = getCoefficients((List) v.get(COEFFICIENTS_KEY)); + + r.putM(coe, key); + return r; + }); + return result; + } + + protected abstract M createMap(List> keyRanges); + + protected abstract T getCoefficients(List coefficients); + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java new file mode 100644 index 000000000..51994af23 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java @@ -0,0 +1,76 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import ca.bc.gov.nrs.vdyp.model.Coefficients; + +/** + * Parses an mapping from a species to a set of coefficients. + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class BySpeciesDqCoefficientParser implements ResourceParser> { + + public static final String CONTROL_KEY = "BY_SPECIES_DQ"; + + public static final String COEFFICIENT_INDEX_KEY = "coefficientIndex"; + public static final String COEFFICIENTS_KEY = "coefficients"; + public static final String INDICATOR_KEY = "indicator"; + + private int NUM_COEFFICIENTS = 3; + private int NUM_SPECIES = 16; + + public BySpeciesDqCoefficientParser() { + super(); + this.lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + }.space(1).value(1, COEFFICIENT_INDEX_KEY, ValueParser.INTEGER).value(2, INDICATOR_KEY, ValueParser.INTEGER) + .multiValue(NUM_SPECIES, 9, COEFFICIENTS_KEY, ValueParser.FLOAT); + } + + LineParser lineParser; + + @Override + public List parse(InputStream is, Map control) + throws IOException, ResourceParseException { + + List result = new ArrayList<>(NUM_COEFFICIENTS); + + result.add(null); + result.add(null); + result.add(null); + + lineParser.parse(is, result, (v, r) -> { + var index = (int) v.get(COEFFICIENT_INDEX_KEY); + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENTS_KEY); + + if (! (index == 0 || index == 1)) { + final var first = coefficients.get(0); + coefficients = Stream.generate(() -> first).limit(NUM_SPECIES).collect(Collectors.toList()); + } + + if (coefficients.size() < NUM_SPECIES) { + throw new ValueParseException(null, "Expected " + NUM_SPECIES + " coefficients"); // TODO handle this + // better + } + r.set(index, new Coefficients(coefficients, 1)); + + return r; + }); + return result; + } + +} \ No newline at end of file diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java index 910289a36..35c7afd5e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -1,7 +1,12 @@ package ca.bc.gov.nrs.vdyp.model; +import java.util.AbstractMap; +import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * A mapping from the cartesian product of a set of arbitrary identifiers to a @@ -19,6 +24,14 @@ public interface MatrixMap { public boolean all(Predicate pred); + public boolean any(Predicate pred); + + public List> getDimensions(); + + default public int getNumDimensions() { + return getDimensions().size(); + } + default public boolean isFull() { return all(x -> x != null); } @@ -26,4 +39,72 @@ default public boolean isFull() { default public boolean isEmpty() { return all(x -> x == null); } + + /** + * Wraps a 1 dimensional MatrixMap as a regular Java Map. + */ + public static Map cast(MatrixMap o, Class keyClass1) { + // TODO check compatibility of range types + + // Wrap it if it's not a MatrixMap3 but has 1 dimension + if (o.getNumDimensions() == 1) { + return new AbstractMap() { + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Set> entrySet() { + return (Set) o.getDimensions().get(0).stream().filter(k -> o.getM(k).isPresent()) + .collect(Collectors.toMap(k -> k, k -> o.getM(k).get())).entrySet(); + } + + @Override + public int size() { + return o.getDimensions().get(0).size(); + } + + @Override + public boolean isEmpty() { + return o.isEmpty(); + } + + @Override + public boolean containsValue(Object value) { + return o.any(v -> value.equals(v)); + } + + @Override + public boolean containsKey(Object key) { + return o.getDimensions().get(0).contains(key); + } + + @Override + public CV get(Object key) { + return o.getM(key).orElseGet(() -> null); + } + + @Override + public CV put(CK1 key, CV value) { + var old = get(key); + o.putM(value, key); + return old; + } + + @SuppressWarnings("unchecked") + @Override + public CV remove(Object key) { + return put((CK1) key, null); + } + + @SuppressWarnings("unchecked") + @Override + public Set keySet() { + return (Set) o.getDimensions().get(0); + } + + }; + } + + // Can't cast it if it doesn't have 1 dimensions + throw new ClassCastException("MatrixMap did not have 1 dimension"); + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java index 10e52206e..5c980d597 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java @@ -1,6 +1,9 @@ package ca.bc.gov.nrs.vdyp.model; +import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; public interface MatrixMap2 extends MatrixMap { @@ -11,4 +14,58 @@ default public void put(K1 key1, K2 key2, V value) { default public Optional get(K1 key1, K2 key2) { return getM(key1, key2); } + + /** + * Cast a 2 dimension MatrixMap to MatrixMap2, wrapping it if it has 2 + * dimensions but does not implement the interface. + */ + @SuppressWarnings("unchecked") + public static MatrixMap2 + cast(MatrixMap o, Class keyClass1, Class keyClass2) { + // TODO check compatibility of range types + + // Pass through if it's already a MatrixMap2 + if (o instanceof MatrixMap2) { + return (MatrixMap2) o; + } + // Wrap it if it's not a MatrixMap2 but has 2 dimensions + if (o.getNumDimensions() == 3) { + return new MatrixMap2() { + + @Override + public Optional getM(Object... params) { + return o.getM(params); + } + + @Override + public void putM(CV value, Object... params) { + o.putM(value, params); + } + + @Override + public boolean all(Predicate pred) { + return o.all(pred); + } + + @Override + public List> getDimensions() { + return o.getDimensions(); + } + + @Override + public int getNumDimensions() { + return o.getNumDimensions(); + } + + @Override + public boolean any(Predicate pred) { + return o.any(pred); + } + + }; + } + + // Can't cast it if it doesn't have 3 dimensions + throw new ClassCastException("MatrixMap did not have 2 dimensions"); + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java index 90d15bd49..fa9c51a37 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java @@ -1,6 +1,9 @@ package ca.bc.gov.nrs.vdyp.model; +import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; public interface MatrixMap3 extends MatrixMap { @@ -11,4 +14,58 @@ default public void put(K1 key1, K2 key2, K3 key3, V value) { default public Optional get(K1 key1, K2 key2, K3 key3) { return getM(key1, key2, key3); } + + /** + * Cast a 3 dimension MatrixMap to MatrixMap3, wrapping it if it has 3 + * dimensions but does not implement the interface. + */ + @SuppressWarnings("unchecked") + public static MatrixMap3 + cast(MatrixMap o, Class keyClass1, Class keyClass2, Class keyClass3) { + // TODO check compatibility of range types + + // Pass through if it's already a MatrixMap3 + if (o instanceof MatrixMap3) { + return (MatrixMap3) o; + } + // Wrap it if it's not a MatrixMap3 but has 3 dimensions + if (o.getNumDimensions() == 3) { + return new MatrixMap3() { + + @Override + public Optional getM(Object... params) { + return o.getM(params); + } + + @Override + public void putM(CV value, Object... params) { + o.putM(value, params); + } + + @Override + public boolean all(Predicate pred) { + return o.all(pred); + } + + @Override + public List> getDimensions() { + return o.getDimensions(); + } + + @Override + public int getNumDimensions() { + return o.getNumDimensions(); + } + + @Override + public boolean any(Predicate pred) { + return o.any(pred); + } + + }; + } + + // Can't cast it if it doesn't have 3 dimensions + throw new ClassCastException("MatrixMap did not have 3 dimensions"); + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java index 85cb91cf0..15f67ce89 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -46,10 +47,12 @@ public MatrixMapImpl(Collection... dimensions) { } @SuppressWarnings("unchecked") + @Override public Optional getM(Object... params) { return (Optional) getIndex(params).flatMap(i -> Optional.ofNullable(matrix[i])); } + @Override public void putM(T value, Object... params) { matrix[getIndex(params).orElseThrow(() -> new IllegalArgumentException())] = value; } @@ -76,16 +79,35 @@ protected Optional getIndex(Object... params) { } @SuppressWarnings("unchecked") + @Override public boolean all(Predicate pred) { return Arrays.stream(matrix).allMatch((Predicate) pred); } + @SuppressWarnings("unchecked") + @Override + public boolean any(Predicate pred) { + return Arrays.stream(matrix).anyMatch((Predicate) pred); + } + + @Override public boolean isFull() { return all(x -> x != null); } + @Override public boolean isEmpty() { return all(x -> x == null); } + @Override + public List> getDimensions() { + return maps.stream().map(m -> m.keySet()).collect(Collectors.toList()); + } + + @Override + public int getNumDimensions() { + return maps.size(); + } + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java new file mode 100644 index 000000000..c42d34ab7 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java @@ -0,0 +1,50 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class BySpeciesDqCoefficientParserTest { + + @Test + public void testParseSimple() throws Exception { + + var parser = new BySpeciesDqCoefficientParser(); + + var is = TestUtils.makeStream( + "A0 1 -0.65484 -0.48275 -0.75134 0.04482 -0.31195 -0.53012 -0.12645 -0.64668 -0.43538 -0.31134 -0.03435 -0.27833 -0.32476 0.10819 -0.38103 -0.12273", + "A1 2 2.26389 0.19886 -0.25704 0.18579 -0.38547 -0.14115 -0.10146 0.09067 0.54304 -0.02947 0.08473 -0.39934 0.02206 -0.18235 0.01411 -0.21683", + "A2 0 0.23162" + ); + + Map controlMap = new HashMap<>(); + + var result = parser.parse(is, controlMap); + + assertThat( + result, + contains( + contains( + -0.65484f, -0.48275f, -0.75134f, 0.04482f, -0.31195f, -0.53012f, -0.12645f, -0.64668f, + -0.43538f, -0.31134f, -0.03435f, -0.27833f, -0.32476f, 0.10819f, -0.38103f, -0.12273f + ), + contains( + 2.26389f, 0.19886f, -0.25704f, 0.18579f, -0.38547f, -0.14115f, -0.10146f, 0.09067f, + 0.54304f, -0.02947f, 0.08473f, -0.39934f, 0.02206f, -0.18235f, 0.01411f, -0.21683f + ), + contains( + 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, + 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f + ) + ) + ); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java new file mode 100644 index 000000000..5d909d1e3 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java @@ -0,0 +1,114 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; + +import org.hamcrest.Matcher; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class SimpleSpeciesCoefficientParserTest { + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSimpleP1() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + + var is = TestUtils.makeStream("S1 I 1.00160 0.20508-0.0013743"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(1.00160f)), 1, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(0.20508f)), 2, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(-0.0013743f)), 3, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 4, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.INTERIOR)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSimpleP2() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); + + var is = TestUtils.makeStream("S1 C 0.49722 1.18403"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(0.49722f)), 1, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry(present(is(1.18403f)), 2, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 3, "S1", Region.COASTAL)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.COASTAL)); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSimpleP3() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); + + var is = TestUtils.makeStream("S1 I 1.04422 0.93010 -0.05745 -2.50000"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(is(1.04422f)), 1, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(0.93010f)), 2, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(-0.05745f)), 3, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(present(is(-2.50000f)), 4, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 5, "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.INTERIOR)); + } + + @Test + public void testParseBadSpecies() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + + var is = TestUtils.makeStream("SX I 1.00160 0.20508-0.0013743"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + + } + + @Test + public void testParseBadRegion() throws Exception { + + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + + var is = TestUtils.makeStream("S1 X 1.00160 0.20508-0.0013743"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + + } + +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index e171ad931..2425102e7 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -39,7 +39,7 @@ 052 coe/REGYHLPB.DAT HL, Primary SP, Eqn P3 RD_YHL3 053 coe/REGHL.COE HL, Non-primary Species RD_YHL4 -060 coe/REGDQI04.coe By-species DQ RD_E060 IPFJF125 +060 coe/REGDQI04.COE By-species DQ RD_E060 IPFJF125 061 coe/complim.coe Species component size limits RD_E061 IPSJF158 070 coe/regbac.dat Util. Comp, BA RD_UBA1 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index bea00dfa5..9b4d41821 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -12,6 +12,7 @@ import java.util.function.Supplier; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.CoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; @@ -27,8 +28,8 @@ import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap3; -import ca.bc.gov.nrs.vdyp.model.MatrixMap4; import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -63,7 +64,7 @@ public class FipControlParser { public static final String HL_PRIMARY_SP_EQN_P2 = HLCoefficientParser.CONTROL_KEY_P2; public static final String HL_PRIMARY_SP_EQN_P3 = HLCoefficientParser.CONTROL_KEY_P3; public static final String HL_NONPRIMARY = HLNonprimaryCoefficientParser.CONTROL_KEY; - public static final String BY_SPECIES_DQ = "BY_SPECIES_DQ"; + public static final String BY_SPECIES_DQ = BySpeciesDqCoefficientParser.CONTROL_KEY; public static final String SPECIES_COMPONENT_SIZE_LIMIT = "SPECIES_COMPONENT_SIZE_LIMIT"; public static final String UTIL_COMP_BA = "UTIL_COMP_BA"; public static final String UTIL_COMP_DQ = "UTIL_COMP_DQ"; @@ -286,7 +287,7 @@ public String toString(String filename) throws IOException { loadData(map, HL_NONPRIMARY, fileResolver, this::RD_YHL4); // RD_E060 - // TODO + loadData(map, BY_SPECIES_DQ, fileResolver, this::RD_E060); // Min and max DQ by species @@ -639,6 +640,28 @@ private MatrixMap3 RD_YHL3(InputStream data, Map return parser.parse(data, control); } + /** + * Loads the information that was in the global array COE060 in Fortran + */ + private List RD_E060(InputStream data, Map control) + throws IOException, ResourceParseException { + // Map from coefficient index to per-species coefficient + var parser = new BySpeciesDqCoefficientParser(); + + return parser.parse(data, control); + } + + /** + * Loads the information that was in the global array COE061 in Fortran + */ + private MatrixMap3 + RD_E061(InputStream data, Map control) throws IOException, ResourceParseException { + // Two Species and a Region mapped to 2 coefficients and an equation index + var parser = new HLNonprimaryCoefficientParser(); + + return parser.parse(data, control); + } + static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 2fafbbe9b..f889d005d 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -4,6 +4,7 @@ import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; @@ -356,6 +357,35 @@ public void testParseE053() throws Exception { ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE060() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.BY_SPECIES_DQ), + contains( + contains( + -0.65484f, -0.48275f, -0.75134f, 0.04482f, -0.31195f, -0.53012f, -0.12645f, + -0.64668f, -0.43538f, -0.31134f, -0.03435f, -0.27833f, -0.32476f, 0.10819f, + -0.38103f, -0.12273f + ), + contains( + 2.26389f, 0.19886f, -0.25704f, 0.18579f, -0.38547f, -0.14115f, -0.10146f, + 0.09067f, 0.54304f, -0.02947f, 0.08473f, -0.39934f, 0.02206f, -0.18235f, + 0.01411f, -0.21683f + ), + contains( + 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, + 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f, 0.23162f + ) + ) + ) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From 3e10ac38a4d7d8635af3fe6bc7f6d8a11700a622 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 25 May 2023 01:55:10 -0700 Subject: [PATCH 26/98] Componetn size limit --- .../vdyp/io/parse/BaseCoefficientParser.java | 4 +- .../vdyp/io/parse/ComponentSizeParser.java | 40 +++++++++++ .../io/parse/ComponentSizeParserTest.java | 67 +++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 2 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 17 +++-- .../nrs/vdyp/fip/FipControlParserTest.java | 14 ++++ 6 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index cf3cb60fe..43559a068 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -57,12 +57,12 @@ public boolean isStopLine(String line) { public BaseCoefficientParser regionKey() { var regions = Arrays.asList(Region.values()); - return key(1, REGION_KEY, ValueParser.REGION, regions, "% is not a valid region"); + return key(1, REGION_KEY, ValueParser.REGION, regions, "%s is not a valid region"); } public BaseCoefficientParser speciesKey(String name, Map controlMap) { var range = SP0DefinitionParser.getSpeciesAliases(controlMap); - return key(2, name, String::strip, range, "% is not a valid species"); + return key(2, name, String::strip, range, "%s is not a valid species"); } public BaseCoefficientParser speciesKey(Map controlMap) { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java new file mode 100644 index 000000000..13031eed9 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java @@ -0,0 +1,40 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; +import ca.bc.gov.nrs.vdyp.model.Region; + +/** + * Parse a datafile with species component size limits + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class ComponentSizeParser extends BaseCoefficientParser> { + + public static final String CONTROL_KEY = "SPECIES_COMPONENT_SIZE_LIMIT"; + + public ComponentSizeParser(Map control) { + super(); + this.speciesKey(control).space(1).regionKey().coefficients(4, 6); + } + + @SuppressWarnings("unchecked") + @Override + protected MatrixMap2 createMap(List> keyRanges) { + return new MatrixMap2Impl( + (Collection) keyRanges.get(0), (Collection) keyRanges.get(1) + ); + } + + @Override + protected Coefficients getCoefficients(List coefficients) { + return new Coefficients(coefficients, 1); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java new file mode 100644 index 000000000..3a4c295f7 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java @@ -0,0 +1,67 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class ComponentSizeParserTest { + + @Test + public void testParseSimpleP1() throws Exception { + + var is = TestUtils.makeStream("S1 C 49.4 153.3 0.726 3.647"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var parser = new ComponentSizeParser(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(contains(49.4f, 153.3f, 0.726f, 3.647f)), "S1", Region.COASTAL)); + } + + @Test + public void testParseBadSpecies() throws Exception { + + var is = TestUtils.makeStream("SX C 49.4 153.3 0.726 3.647"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var parser = new ComponentSizeParser(controlMap); + + @SuppressWarnings("unused") + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + + } + + @Test + public void testParseBadRegion() throws Exception { + + var is = TestUtils.makeStream("S1 X 49.4 153.3 0.726 3.647"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var parser = new ComponentSizeParser(controlMap); + + @SuppressWarnings("unused") + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + + } + +} diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 2425102e7..61398db2c 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -40,7 +40,7 @@ 053 coe/REGHL.COE HL, Non-primary Species RD_YHL4 060 coe/REGDQI04.COE By-species DQ RD_E060 IPFJF125 -061 coe/complim.coe Species component size limits RD_E061 IPSJF158 +061 coe/COMPLIM.COE Species component size limits RD_E061 IPSJF158 070 coe/regbac.dat Util. Comp, BA RD_UBA1 071 coe/regdqc.dat Util. Comp, DQ RD_UDQ1 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 9b4d41821..5ab070779 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -5,15 +5,18 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Supplier; +import ca.bc.gov.nrs.vdyp.io.parse.BaseCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.CoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.ComponentSizeParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; @@ -29,6 +32,8 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.MatrixMap3; import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; import ca.bc.gov.nrs.vdyp.model.Region; @@ -65,7 +70,7 @@ public class FipControlParser { public static final String HL_PRIMARY_SP_EQN_P3 = HLCoefficientParser.CONTROL_KEY_P3; public static final String HL_NONPRIMARY = HLNonprimaryCoefficientParser.CONTROL_KEY; public static final String BY_SPECIES_DQ = BySpeciesDqCoefficientParser.CONTROL_KEY; - public static final String SPECIES_COMPONENT_SIZE_LIMIT = "SPECIES_COMPONENT_SIZE_LIMIT"; + public static final String SPECIES_COMPONENT_SIZE_LIMIT = ComponentSizeParser.CONTROL_KEY; public static final String UTIL_COMP_BA = "UTIL_COMP_BA"; public static final String UTIL_COMP_DQ = "UTIL_COMP_DQ"; public static final String SMALL_COMP_PROBABILITY = "SMALL_COMP_PROBABILITY"; @@ -292,7 +297,7 @@ public String toString(String filename) throws IOException { // Min and max DQ by species // RD_E061 - // TODO + loadData(map, SPECIES_COMPONENT_SIZE_LIMIT, fileResolver, this::RD_E061); // RD_UBA1 // TODO @@ -654,10 +659,10 @@ private List RD_E060(InputStream data, Map control /** * Loads the information that was in the global array COE061 in Fortran */ - private MatrixMap3 - RD_E061(InputStream data, Map control) throws IOException, ResourceParseException { - // Two Species and a Region mapped to 2 coefficients and an equation index - var parser = new HLNonprimaryCoefficientParser(); + private MatrixMap2 RD_E061(InputStream data, Map control) + throws IOException, ResourceParseException { + // Species and Region to 4 floats + var parser = new ComponentSizeParser(control); return parser.parse(data, control); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index f889d005d..cf36782b0 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -386,6 +386,20 @@ public void testParseE060() throws Exception { ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE061() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.SPECIES_COMPONENT_SIZE_LIMIT), + allOf(mmHasEntry(present(contains(49.4f, 153.3f, 0.726f, 3.647f)), "AC", Region.COASTAL)) + ) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From 40f3a5deb6e082b003d14e61cbb789d5f320159c Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 26 May 2023 09:59:32 -0700 Subject: [PATCH 27/98] UtilComponentBaseAreaParser --- pom.xml | 13 +- vdyp-core/pom.xml | 5 + .../java/ca/bc/gov/nrs/vdyp/common/Utils.java | 26 +++ .../vdyp/io/parse/BecDefinitionParser.java | 48 +++++ .../io/parse/UtilComponentBaseAreaParser.java | 78 ++++++++ .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 19 ++ .../bc/gov/nrs/vdyp/model/BaseAreaCode.java | 8 + .../java/ca/bc/gov/nrs/vdyp/model/Region.java | 7 + .../io/parse/BecDefinitionParserTest.java | 31 ++++ .../UtilComponentBaseAreaParserTest.java | 170 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 6 +- .../ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR | 34 ++-- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 32 +++- .../nrs/vdyp/fip/FipControlParserTest.java | 15 ++ 14 files changed, 467 insertions(+), 25 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/Utils.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java diff --git a/pom.xml b/pom.xml index 99cf07be3..b01aec260 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ 17 - + UTF-8 5.9.2 @@ -29,6 +29,11 @@ + + com.google.code.findbugs + jsr305 + 3.0.2 + org.junit.jupiter @@ -36,7 +41,7 @@ ${junit.version} test - + org.junit.jupiter junit-jupiter-api @@ -120,7 +125,7 @@ - + - + diff --git a/vdyp-core/pom.xml b/vdyp-core/pom.xml index 44e340738..148b0a3f6 100644 --- a/vdyp-core/pom.xml +++ b/vdyp-core/pom.xml @@ -15,6 +15,11 @@ + + com.google.code.findbugs + jsr305 + + org.junit.jupiter junit-jupiter-api diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/Utils.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/Utils.java new file mode 100644 index 000000000..8cba410eb --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/Utils.java @@ -0,0 +1,26 @@ +package ca.bc.gov.nrs.vdyp.common; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import javax.annotation.Nullable; + +public class Utils { + + /** + * Returns a singleton set containing the value if it's not null, otherwise an + * empty set + * + * @param + * @param value + * @return + */ + public static Set singletonOrEmpty(@Nullable T value) { + if (Objects.isNull(value)) { + return Collections.emptySet(); + } + return Collections.singleton(value); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index d5dbc08d0..d2da81d60 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -2,11 +2,13 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import ca.bc.gov.nrs.vdyp.common.Utils; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; @@ -45,4 +47,50 @@ public Map parse(InputStream is, Map cont return Collections.unmodifiableMap(result); } + /** + * Get all the BECs mapped by their aliases + * + * @param control Control map containing the parsed BEC definitions. + * @return + */ + public static Map getBecs(Map control) { + return ResourceParser.expectParsedControl(control, CONTROL_KEY, Map.class); + } + + /** + * Get all the BECs in the specified region + * + * @param control Control map containing the parsed BEC definitions. + * @return + */ + public static Collection getBecsByRegion(Map control, Region region) { + return getBecs(control).values().stream().filter(bec -> bec.getRegion() == region).toList(); + } + + /** + * Get all the aliases for defined BECs + * + * @param control Control map containing the parsed BEC definitions. + * @return + */ + public static Collection getBecAliases(Map control) { + return getBecs(control).keySet(); + } + + /** + * Find a set of BECs for the given scope. If the scope is blank, that's all + * BECs, if it's a Region alias, it's all BECs for that region, otherwise its + * treated as a BEC alias and the BEC matching it is returned. + * + * @param control Control map containing the parsed BEC definitions. + * @param scope The scope to match + * @return A collection of matching BECs, or the empty set if none match. + */ + public static Collection getBecsByScope(Map control, String scope) { + if (scope.isBlank()) { + return getBecs(control).values(); + } + return Region.fromAlias(scope).map(region -> getBecsByRegion(control, region)) + .orElseGet(() -> Utils.singletonOrEmpty(getBecs(control).get(scope))); + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java new file mode 100644 index 000000000..62ae1ce3c --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java @@ -0,0 +1,78 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; + +public class UtilComponentBaseAreaParser + implements ResourceParser> { + public static final String CONTROL_KEY = "UTIL_COMP_BA"; + + public static final int NUM_COEFFICIENTS = 2; + + public static final String BA_UTIL_CODE_KEY = "baUtilCode"; + public static final String SPECIES_KEY = "species"; + public static final String REGION_KEY = "region"; + public static final String BEC_SCOPE_KEY = "becScope"; + public static final String COEFFICIENT_KEY = "coefficient"; + + public UtilComponentBaseAreaParser() { + super(); + this.lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + }.value(4, BA_UTIL_CODE_KEY, ValueParser.enumParser(BaseAreaCode.class)).space(1) + .value(2, SPECIES_KEY, String::strip).space(1).value(4, BEC_SCOPE_KEY, String::strip) + .multiValue(NUM_COEFFICIENTS, 10, COEFFICIENT_KEY, ValueParser.FLOAT); + } + + LineParser lineParser; + + @Override + public MatrixMap3 parse(InputStream is, Map control) + throws IOException, ResourceParseException { + final var becIndices = BecDefinitionParser.getBecAliases(control); + final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var bauIndices = Set.of(BaseAreaCode.values()); + + MatrixMap3 result = new MatrixMap3Impl( + bauIndices, speciesIndicies, becIndices + ); + lineParser.parse(is, result, (v, r) -> { + var bau = (BaseAreaCode) v.get(BA_UTIL_CODE_KEY); + var sp0 = (String) v.get(SPECIES_KEY); + var scope = (String) v.get(BEC_SCOPE_KEY); + + var becs = BecDefinitionParser.getBecsByScope(control, scope); + if (becs.isEmpty()) { + throw new ValueParseException(scope, "Could not find any BECs for scope " + scope); + } + + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENT_KEY); + SP0DefinitionParser.checkSpecies(speciesIndicies, sp0); + + if (coefficients.size() < NUM_COEFFICIENTS) { + throw new ValueParseException(null, "Expected " + NUM_COEFFICIENTS + " coefficients"); + } + for (var bec : becs) { + r.put(bau, sp0, bec.getAlias(), new Coefficients(coefficients, 1)); + } + + return r; + }); + return result; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 7e1bdd670..cff8940aa 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.Enumeration; import java.util.List; import java.util.Optional; import java.util.function.Function; @@ -50,6 +51,24 @@ public static ValueParser numberParser(JavaNumberParser }; } + /** + * Adapts an parsing an Enum + * + * @param klazz the type to parse into + */ + public static > ValueParser enumParser(Class klazz) { + return s -> { + String stripped = s.strip(); + try { + return Enum.valueOf(klazz, s); + } catch (IllegalArgumentException ex) { + throw new ValueParseException( + stripped, String.format("\"%s\" is not a valid %s", stripped, klazz.getSimpleName()), ex + ); + } + }; + } + /** * Parser for long integers */ diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java new file mode 100644 index 000000000..b379033f9 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java @@ -0,0 +1,8 @@ +package ca.bc.gov.nrs.vdyp.model; + +public enum BaseAreaCode { + // Also known as "UC" or "IU" + // TODO possibly rename something clearer + + BA12, BA17, BA22; +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java index 99cf9529f..66a759456 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Region.java @@ -16,6 +16,13 @@ public static Optional fromAlias(char alias) { return Arrays.stream(Region.values()).filter(x -> x.getCharacterAlias() == alias).findFirst(); } + public static Optional fromAlias(String alias) { + if (alias.length() == 1) { + return fromAlias(alias.charAt(0)); + } + return Optional.empty(); + } + public char getCharacterAlias() { return characterAlias; } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index 7ac53044c..78a30c369 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -5,13 +5,19 @@ import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasProperty; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.hamcrest.Matchers.equalTo; import org.junit.jupiter.api.Test; +import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.SP0Definition; public class BecDefinitionParserTest { @@ -163,4 +169,29 @@ public void testParse() throws Exception { ); } + /** + * Add a mock control map entry for BEC parse results with species "B1" and "B2" + * for Coastal and Interior Regions respectively + */ + public static void populateControlMap(Map controlMap) { + populateControlMap(controlMap, "B1", "B2"); + } + + /** + * Add a mock control map entry for SP0 parse results. Alternates assigning to + * Coastal and Interior regions, starting with Coastal. + */ + public static void populateControlMap(Map controlMap, String... aliases) { + + Map map = new HashMap<>(); + + int i = 0; + for (var alias : aliases) { + map.put(alias, new BecDefinition(alias, Region.values()[i % 2], "Test " + alias)); + i++; + } + + controlMap.put(BecDefinitionParser.CONTROL_KEY, map); + } + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java new file mode 100644 index 000000000..1c5b24a0b --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java @@ -0,0 +1,170 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.causedBy; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class UtilComponentBaseAreaParserTest { + + @Test + public void testParseSingleBec() throws Exception { + + var parser = new UtilComponentBaseAreaParser(); + + var is = TestUtils.makeStream("BA12 S1 B1 -23.22790 12.60472"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B1")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B2")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B3")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B4")); + + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B1")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B2")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B3")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B4")); + + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA17, "S1", "B1")); + } + + @Test + public void testParseSingleRegion() throws Exception { + + var parser = new UtilComponentBaseAreaParser(); + + var is = TestUtils.makeStream("BA12 S1 C -23.22790 12.60472"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B1")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B3")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B2")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B4")); + + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B1")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B2")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B3")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B4")); + + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA17, "S1", "B1")); + } + + @Test + public void testParseAllBecs() throws Exception { + + var parser = new UtilComponentBaseAreaParser(); + + var is = TestUtils.makeStream("BA12 S1 -23.22790 12.60472"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B1")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B2")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B3")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B4")); + + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B1")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B2")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B3")); + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B4")); + + assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA17, "S1", "B1")); + + } + + @Test + public void testParseBadSpecies() throws Exception { + + var parser = new UtilComponentBaseAreaParser(); + + var is = TestUtils.makeStream("BA12 SX B1 -23.22790 12.60472"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThat(ex, causedBy(hasProperty("value", is("SX")))); + } + + @Test + public void testParseBadBec() throws Exception { + + var parser = new UtilComponentBaseAreaParser(); + + var is = TestUtils.makeStream("BA12 S1 BX -23.22790 12.60472"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThat(ex, causedBy(hasProperty("value", is("BX")))); + } + + @Test + public void testParseBadBau() throws Exception { + + var parser = new UtilComponentBaseAreaParser(); + + var is = TestUtils.makeStream("BAXX S1 B1 -23.22790 12.60472"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThat(ex, causedBy(hasProperty("value", is("BAXX")))); + } + + @Test + public void testParseMissingCoefficient() throws Exception { + + var parser = new UtilComponentBaseAreaParser(); + + var is = TestUtils.makeStream("BA12 S1 B1 -23.22790"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThat(ex, causedBy(hasProperty("value", nullValue()))); // TODO Do this better + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index 28a512e90..31ab33d8f 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -121,10 +121,12 @@ public void describeMismatch(Object item, Description description) { /** * Matches an Optional if it is not present * + * @param + * * @return */ - public static Matcher> notPresent() { - return new BaseMatcher>() { + public static Matcher> notPresent() { + return new BaseMatcher>() { @Override public boolean matches(Object actual) { diff --git a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR index 61398db2c..d35094be1 100755 --- a/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR +++ b/vdyp-core/src/test/resources/ca/bc/gov/nrs/vdyp/io/parse/FIPSTART.CTR @@ -42,29 +42,29 @@ 060 coe/REGDQI04.COE By-species DQ RD_E060 IPFJF125 061 coe/COMPLIM.COE Species component size limits RD_E061 IPSJF158 -070 coe/regbac.dat Util. Comp, BA RD_UBA1 -071 coe/regdqc.dat Util. Comp, DQ RD_UDQ1 +070 coe/REGBAC.DAT Util. Comp, BA RD_UBA1 +071 coe/REGDQC.DAT Util. Comp, DQ RD_UDQ1 -080 coe/regpr1c.dat Small Comp., Probability RD_SBA1 -081 coe/regba2c.dat Small Comp., BA RD_SBA2 -082 coe/regdq4c.dat Small Comp., DQ RD_SDQ1 -085 coe/reghl1c.dat Small Comp., HL RD_SHL1 -086 coe/regv1c.dat Small Comp., WS Volume RD_SVT1 +080 coe/REGPR1C.DAT Small Comp., Probability RD_SBA1 +081 coe/REGBA2C.DAT Small Comp., BA RD_SBA2 +082 coe/REGDQ4C.DAT Small Comp., DQ RD_SDQ1 +085 coe/REGHL1C.DAT Small Comp., HL RD_SHL1 +086 coe/REGV1C.DAT Small Comp., WS Volume RD_SVT1 -090 coe/VTOTREG4.coe Total stand WholeStem Vol RD_YVT1 IPSJF117 -091 coe/REGVU.coe Util Comp, WS volume RD_YVT2 IPSJF121 -092 coe/regvcu.coe Close Utilization Vol RD_YVC1 IPSJF122 -093 coe/regvdu.coe Vol net of Decay RD_YVD1 IPSJF123 -094 coe/regvwu.coe Vol net of (Decay+Waste) RD_YVW1 IPSJF123 -095 coe/regbreak.coe Breakage RD_EMP95 IPSJF157 +090 coe/VTOTREG4.COE Total stand WholeStem Vol RD_YVT1 IPSJF117 +091 coe/REGVU.COE Util Comp, WS volume RD_YVT2 IPSJF121 +092 coe/REGVCU.COE Close Utilization Vol RD_YVC1 IPSJF122 +093 coe/REGVDU.COE Vol net of Decay RD_YVD1 IPSJF123 +094 coe/REGVWU.COE Vol net of (Decay+Waste) RD_YVW1 IPSJF123 +095 coe/REGBREAK.COE Breakage RD_EMP95 IPSJF157 -096 coe/vetvol1.dat Vet-layer volume adjust RD_YVET -097 coe/vetdq2.dat DQ for Vet layer RD_YDQV -098 coe/REGBAV01.coe VET BA, IPSJF168.doc RD_E098 +096 coe/VETVOL1.DAT Vet-layer volume adjust RD_YVET +097 coe/VETDQ2.DAT DQ for Vet layer RD_YDQV +098 coe/REGBAV01.COE VET BA, IPSJF168.doc RD_E098 197 5.0 0.0 2.0 Minimum Height, Minimum BA, Min BA fully stocked. -198 coe/MOD19813.prm Modifier file (IPSJF155, XII) RD_E198 +198 coe/mod19813.prm Modifier file (IPSJF155, XII) RD_E198 199 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 Debug switches (0 by default) See IPSJF155 App IX Debug switches (25) 0=default See IPSJF155, App IX 1st: 1: Do NOT apply BA limits from SEQ043 2nd: 1: Do NOT apply DQ limits from SEQ043 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 5ab070779..d0efcfa9c 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -24,12 +24,14 @@ import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveParser; import ca.bc.gov.nrs.vdyp.io.parse.StockingClassFactorParser; import ca.bc.gov.nrs.vdyp.io.parse.UpperCoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap2; @@ -71,7 +73,7 @@ public class FipControlParser { public static final String HL_NONPRIMARY = HLNonprimaryCoefficientParser.CONTROL_KEY; public static final String BY_SPECIES_DQ = BySpeciesDqCoefficientParser.CONTROL_KEY; public static final String SPECIES_COMPONENT_SIZE_LIMIT = ComponentSizeParser.CONTROL_KEY; - public static final String UTIL_COMP_BA = "UTIL_COMP_BA"; + public static final String UTIL_COMP_BA = UtilComponentBaseAreaParser.CONTROL_KEY; public static final String UTIL_COMP_DQ = "UTIL_COMP_DQ"; public static final String SMALL_COMP_PROBABILITY = "SMALL_COMP_PROBABILITY"; public static final String SMALL_COMP_BA = "SMALL_COMP_BA"; @@ -300,7 +302,7 @@ public String toString(String filename) throws IOException { loadData(map, SPECIES_COMPONENT_SIZE_LIMIT, fileResolver, this::RD_E061); // RD_UBA1 - // TODO + loadData(map, UTIL_COMP_BA, fileResolver, this::RD_UBA1); // RD_UDQ1 // TODO @@ -667,6 +669,32 @@ private MatrixMap2 RD_E061(InputStream data, Map + RD_UBA1(InputStream data, Map control) throws IOException, ResourceParseException { + + // Uses + // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) + + // Sets + // C 2 coef BY 3 UC by (16 SP0) by (12 BEC) + // COMMON /V7COE070/ COE070( 2 , 3, 16, 12) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) CODE, SP0, BECSCOPE, + // 1 (C(I),I=1,2) + // 11 FORMAT( A4,1x, A2, 1x, A4, 2F10.0) + + // If BECSCOPE is empty, apply to all BECs, if it's I or C, apply to BECs in + // that region, otherwise only the one BEC. + + var parser = new UtilComponentBaseAreaParser(); + + return parser.parse(data, control); + } + static interface FileResolver { InputStream resolve(String filename) throws IOException; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index cf36782b0..b6f8c3ec4 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -30,6 +30,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParserTest; +import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -400,6 +401,20 @@ public void testParseE061() throws Exception { ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseUBA1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.UTIL_COMP_BA), + allOf(mmHasEntry(present(contains(-26.68771f, 14.38811f)), BaseAreaCode.BA12, "AT", "ICH")) + ) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From 14faf655fca2843474ff026e7d019af3390e39b0 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 26 May 2023 10:00:34 -0700 Subject: [PATCH 28/98] Stubbing FIP parser methods --- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 200 ++++++++++++++++-- 1 file changed, 178 insertions(+), 22 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index d0efcfa9c..920b28e1a 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -95,6 +95,9 @@ public class FipControlParser { public static final String MAX_NUM_POLY = "MAX_NUM_POLY"; public static final String BEC_DEF = BecDefinitionParser.CONTROL_KEY; public static final String SP0_DEF = SP0DefinitionParser.CONTROL_KEY; + + // TODO + public static final String TODO = "TODO"; static final ValueParser FILENAME = String::strip; @@ -305,70 +308,71 @@ public String toString(String filename) throws IOException { loadData(map, UTIL_COMP_BA, fileResolver, this::RD_UBA1); // RD_UDQ1 - // TODO + loadData(map, UTIL_COMP_DQ, fileResolver, this::RD_UDQ1); // Small Component (4.5 to 7.5 cm) // RD_SBA1 - // TODO + loadData(map, SMALL_COMP_PROBABILITY, fileResolver, this::RD_SBA1); // RD_SBA2 - // TODO - - // RD_SDQ1 - // TODO + loadData(map, SMALL_COMP_BA, fileResolver, this::RD_SBA2); + + // RD_SDQ1 + loadData(map, SMALL_COMP_DQ, fileResolver, this::RD_SDQ1); // RD_SHL1 - // TODO + loadData(map, SMALL_COMP_HL, fileResolver, this::RD_SHL1); // RD_SVT1 - // TODO + loadData(map, SMALL_COMP_WS_VOLUME, fileResolver, this::RD_SVT1); // Standard Volume Relationships // RD_YVT1 - // TODO + loadData(map, TOTAL_STAND_WHOLE_STEM_VOL, fileResolver, this::RD_YVT1); // RD_YVT2 - // TODO + loadData(map, UTIL_COMP_WS_VOLUME, fileResolver, this::RD_YVT2); // RD_YVC1 - // TODO + loadData(map, CLOSE_UTIL_VOLUME, fileResolver, this::RD_YVC1); // RD_YVD1 - // TODO + loadData(map, VOLUME_NET_DECAY, fileResolver, this::RD_YVD1); // RD_YVW1 - // TODO + loadData(map, VOLUME_NET_DECAY_WASTE, fileResolver, this::RD_YVW1); // RD_E095 - // TODO + loadData(map, BREAKAGE, fileResolver, this::RD_E095); // Veterans // RD_YVVET - // TODO + loadData(map, VETERAN_LAYER_VOLUME_ADJUST, fileResolver, this::RD_YVVET); // RD_YDQV - // TODO + loadData(map, VETERAN_LAYER_DQ, fileResolver, this::RD_YDQV); // RD_E098 - // TODO + loadData(map, VETERAN_BQ, fileResolver, this::RD_E098); // Initiation items NOT for FIPSTART - if (jprogram == 1) { + if (jprogram > 1) { // RD_E106 - // TODO + loadData(map, TODO, fileResolver, this::RD_E106); // RD_E107 - // TODO + loadData(map, TODO, fileResolver, this::RD_E107); // RD_E108 - // TODO + loadData(map, TODO, fileResolver, this::RD_E108); // Minima again, differently? // TODO + /* * READ(CNTRV(197), 197, ERR= 912 ) VMINH, VMINBA, VMINBAeqn,VMINvetH IF * (VMINVetH .le. 0.0) VMINVetH=10.0 @@ -384,7 +388,7 @@ public String toString(String filename) throws IOException { // Modifiers, IPSJF155-Appendix XII // RD_E198 - // TODO + loadData(map, MODIFIER_FILE, fileResolver, this::RD_E198); // Debug switches (normally zero) // TODO @@ -695,6 +699,158 @@ private MatrixMap2 RD_E061(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO SMALL_COMP_PROBABILITY + */ + private Object RD_SBA1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO SMALL_COMP_BA + */ + private Object RD_SBA2(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO SMALL_COMP_DQ + */ + private Object RD_SDQ1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO SMALL_COMP_HL + */ + private Object RD_SHL1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO SMALL_COMP_WS_VOLUME + */ + private Object RD_SVT1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO TOTAL_STAND_WHOLE_STEM_VOL + */ + private Object RD_YVT1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO UTIL_COMP_WS_VOLUME + */ + private Object RD_YVT2(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO CLOSE_UTIL_VOLUME + */ + private Object RD_YVC1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO VOLUME_NET_DECAY + */ + private Object RD_YVD1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO VOLUME_NET_DECAY_WASTE + */ + private Object RD_YVW1(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO BREAKAGE + */ + // Example FIPSTART.CTR calls this RD_EMP95 + private Object RD_E095(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO VETERAN_LAYER_VOLUME_ADJUST + */ + // Example FIPSTART.CTR calls this RD_YVET + private Object RD_YVVET(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO VETERAN_LAYER_DQ + */ + private Object RD_YDQV(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO VETERAN_BQ + */ + private Object RD_E098(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO MODIFIER_FILE + */ + private Object RD_E198(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + + /** + * TODO + */ + private Object RD_E106(InputStream data, Map control) + throws IOException, ResourceParseException { + return null; + } + /** + * TODO + */ + private Object RD_E107(InputStream data, Map control) + throws IOException, ResourceParseException { + throw new UnsupportedOperationException(); + } + /** + * TODO + */ + private Object RD_E108(InputStream data, Map control) + throws IOException, ResourceParseException { + throw new UnsupportedOperationException(); + } + static interface FileResolver { InputStream resolve(String filename) throws IOException; From 72ca5aa5a2396f91e197de8211872c8596a49073 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 26 May 2023 10:01:32 -0700 Subject: [PATCH 29/98] Formatter --- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 101 ++++++++---------- 1 file changed, 42 insertions(+), 59 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 920b28e1a..ed273ec1d 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -95,7 +95,7 @@ public class FipControlParser { public static final String MAX_NUM_POLY = "MAX_NUM_POLY"; public static final String BEC_DEF = BecDefinitionParser.CONTROL_KEY; public static final String SP0_DEF = SP0DefinitionParser.CONTROL_KEY; - + // TODO public static final String TODO = "TODO"; @@ -317,8 +317,8 @@ public String toString(String filename) throws IOException { // RD_SBA2 loadData(map, SMALL_COMP_BA, fileResolver, this::RD_SBA2); - - // RD_SDQ1 + + // RD_SDQ1 loadData(map, SMALL_COMP_DQ, fileResolver, this::RD_SDQ1); // RD_SHL1 @@ -372,7 +372,7 @@ public String toString(String filename) throws IOException { // Minima again, differently? // TODO - + /* * READ(CNTRV(197), 197, ERR= 912 ) VMINH, VMINBA, VMINBAeqn,VMINvetH IF * (VMINVetH .le. 0.0) VMINVetH=10.0 @@ -698,156 +698,139 @@ private MatrixMap2 RD_E061(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_UDQ1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO SMALL_COMP_PROBABILITY */ - private Object RD_SBA1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_SBA1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO SMALL_COMP_BA */ - private Object RD_SBA2(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_SBA2(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO SMALL_COMP_DQ */ - private Object RD_SDQ1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_SDQ1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO SMALL_COMP_HL */ - private Object RD_SHL1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_SHL1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO SMALL_COMP_WS_VOLUME */ - private Object RD_SVT1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_SVT1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO TOTAL_STAND_WHOLE_STEM_VOL */ - private Object RD_YVT1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_YVT1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO UTIL_COMP_WS_VOLUME */ - private Object RD_YVT2(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_YVT2(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO CLOSE_UTIL_VOLUME */ - private Object RD_YVC1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_YVC1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO VOLUME_NET_DECAY */ - private Object RD_YVD1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_YVD1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO VOLUME_NET_DECAY_WASTE */ - private Object RD_YVW1(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_YVW1(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO BREAKAGE */ // Example FIPSTART.CTR calls this RD_EMP95 - private Object RD_E095(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_E095(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO VETERAN_LAYER_VOLUME_ADJUST */ // Example FIPSTART.CTR calls this RD_YVET - private Object RD_YVVET(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_YVVET(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO VETERAN_LAYER_DQ */ - private Object RD_YDQV(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_YDQV(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO VETERAN_BQ */ - private Object RD_E098(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_E098(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO MODIFIER_FILE */ - private Object RD_E198(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_E198(InputStream data, Map control) throws IOException, ResourceParseException { return null; } - + /** * TODO */ - private Object RD_E106(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_E106(InputStream data, Map control) throws IOException, ResourceParseException { return null; } + /** * TODO */ - private Object RD_E107(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_E107(InputStream data, Map control) throws IOException, ResourceParseException { throw new UnsupportedOperationException(); } + /** * TODO */ - private Object RD_E108(InputStream data, Map control) - throws IOException, ResourceParseException { + private Object RD_E108(InputStream data, Map control) throws IOException, ResourceParseException { throw new UnsupportedOperationException(); } From c3fbe42f3bff921e1019a4f8ced2312b58a910a7 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 26 May 2023 15:36:10 -0700 Subject: [PATCH 30/98] Document behaviour of Fortran parsers --- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 301 +++++++++++++++++- 1 file changed, 285 insertions(+), 16 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index ed273ec1d..53cf7dc81 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -678,6 +678,7 @@ private MatrixMap2 RD_E061(InputStream data, Map RD_UBA1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO // Uses // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) @@ -691,6 +692,8 @@ private MatrixMap2 RD_E061(InputStream data, Map RD_E061(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Uses + // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) + + // Sets + // C 4 coef BY 4 UC by (16 SP0) by (12 BEC) + // COMMON /V7COE071/ COE071( 4 , 4, 16, 12) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) CODE, SP0, BECSCOPE, + // 1 (C(I),I=1,4) + // 11 FORMAT( A4,9x, A2, 1x, A4, 4F10.0) + + // Ignore if first segment is blank + + // If BECSCOPE is empty, apply to all BECs, if it's I or C, apply to BECs in + // that region, otherwise only the one BEC. + return null; } /** - * TODO SMALL_COMP_PROBABILITY + * Loads the information that was in the global array COE080 in Fortran + * + * @see SMALL_COMP_PROBABILITY */ private Object RD_SBA1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // C 4 coe for each of 16 SP0's + // COMMON /V7COE080/ COE080(4, 16) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,4) + // 11 FORMAT( A2, 4f10.0) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO SMALL_COMP_BA + * Loads the information that was in the global array COE081 in Fortran + * + * @see SMALL_COMP_BA */ private Object RD_SBA2(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // C 4 coe for each of 16 SP0's + // COMMON /V7COE081/ COE081(4, 16) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,4) + // 11 FORMAT( A2, 4f10.0) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO SMALL_COMP_DQ + * Loads the information that was in the global array COE082 in Fortran + * + * @see SMALL_COMP_DQ */ private Object RD_SDQ1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // C 2 coe for each of 16 SP0's + // COMMON /V7COE082/ COE082(2, 16) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,2) + // 11 FORMAT( A2, 4f10.0) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO SMALL_COMP_HL + * Loads the information that was in the global array COE085 in Fortran + * + * @see SMALL_COMP_HL */ private Object RD_SHL1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // C 2 coe for each of 16 SP0's + // COMMON /V7COE085/ COE085(2, 16) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,2) + // 11 FORMAT( A2, 4f10.0) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO SMALL_COMP_WS_VOLUME + * Loads the information that was in the global array COE086 in Fortran + * + * @see SMALL_COMP_WS_VOLUME */ private Object RD_SVT1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // C 4 coe for each of 16 SP0's + // COMMON /V7COE086/ COE086(4, 16) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,4) + // 11 FORMAT( A2, 4f10.0) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO TOTAL_STAND_WHOLE_STEM_VOL + * Loads the information that was in the global array V7COE090 in Fortran + * + * @see TOTAL_STAND_WHOLE_STEM_VOL */ private Object RD_YVT1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Uses + // PARAMETER (MAXGROUP = 80) + + // Sets + // C 9 coe for each of (Up to 80 groups) + // COMMON /V7COE090/ COE090(0:8, MAXGROUP) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) VGRP, (C(I),I=0,8) + // 11 FORMAT( I3, 9f10.0) + + // Ignore if first segment is 0 + + // Coefficient is 0 indexed + return null; } /** - * TODO UTIL_COMP_WS_VOLUME + * Loads the information that was in the global array COE091 in Fortran + * + * @see UTIL_COMP_WS_VOLUME */ private Object RD_YVT2(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Uses + // PARAMETER (MAXGROUP = 80) + + // Sets + // C 9 coe for each of (Up to 80 groups) + // COMMON /V7COE090/ COE090(0:8, MAXGROUP) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) VGRP, (C(I),I=0,8) + // 11 FORMAT( I3, 9f10.0) + + // Ignore if first segment is 0 + + // Coefficient is 0 indexed + return null; } /** - * TODO CLOSE_UTIL_VOLUME + * Loads the information that was in the global array COE092 in Fortran + * + * @see CLOSE_UTIL_VOLUME */ private Object RD_YVC1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Uses + // PARAMETER (MAXGROUP = 80) + + // Sets + // C 3 coe for (4 UC's) for (Up to 80 groups) + // COMMON /V7COE092/ COE092(3, 4, MAXGROUP) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) UC, VGRP, (C(I),I=1,3) + // 11 FORMAT( I2, I4, 4f10.0) + + // Ignore if first segment is 0 + + // UC is 1 indexed + // Coefficient is 1 indexed + return null; } /** - * TODO VOLUME_NET_DECAY + * Loads the information that was in the global array COE093 in Fortran + * + * @see VOLUME_NET_DECAY */ private Object RD_YVD1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Uses + // PARAMETER (MAXGROUP = 80) + + // Sets + // C 3 coe for (4 UC's) for (Up to 80 groups) + // COMMON /V7COE093/ COE093(3, 4, MAXGROUP) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) UC, DGRP, (C(I),I=1,3) + // 11 FORMAT( I2, I4, 4f10.0) + + // Ignore if first segment is 0 + + // UC is 1 indexed + // Coefficient is 1 indexed + return null; } /** - * TODO VOLUME_NET_DECAY_WASTE + * Loads the information that was in the global array COE094 in Fortran + * + * @see VOLUME_NET_DECAY_WASTE */ private Object RD_YVW1(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Uses + // + + // Sets + // Species to 6 coefficients + // COMMON /V7COE094/ COE094(0:5,16) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, A + // 11 FORMAT( A2, 6F9.0) + + // Ignore if first segment is blank + + // Coefficient is 0 indexed + return null; } /** - * TODO BREAKAGE + * Loads the information that was in the global array COE095 in Fortran + * + * @see BREAKAGE */ // Example FIPSTART.CTR calls this RD_EMP95 private Object RD_E095(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Uses + // PARAMETER (MAXBGRP = 40) + + // Sets + // C 4 for (Up to 40 groups) + // COMMON /V7COE095/ COE095(4, MAXBGRP) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) BGRP, A(1), A(2), A(3), A(4) + // 11 FORMAT( I2, 4f9.0) + + // Ignore if first segment is 0 + + // Coefficient is 1 indexed + return null; } /** - * TODO VETERAN_LAYER_VOLUME_ADJUST + * Loads the information that was in the global array COE096 in Fortran + * + * @see VETERAN_LAYER_VOLUME_ADJUST */ // Example FIPSTART.CTR calls this RD_YVET private Object RD_YVVET(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // COMMON /V7COE096/ COE096( 4, 16) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, C + // 11 FORMAT( A2 , 4f9.5) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO VETERAN_LAYER_DQ + * Loads the information that was in the global array COE097 in Fortran + * + * @see VETERAN_LAYER_DQ */ private Object RD_YDQV(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // C 3 coef BY 16 SP0 BY C/I (2) + // COMMON /V7COE097/ COE097( 3, 16, 2) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 + // 11 FORMAT( A2 , 1x, A1, 3f9.0) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO VETERAN_BQ + * Loads the information that was in the global array COE098 in Fortran + * + * @see VETERAN_BQ */ private Object RD_E098(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + + // Sets + // C 3 coef BY 16 SP0 BY C/I (2) + // COMMON /V7COE098/ COE098( 3, 16, 2) + + // Parses + // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 + // 11 FORMAT( A2 , 1x, A1, 3f9.0) + + // Ignore if first segment is blank + + // Coefficient is 1 indexed + return null; } /** - * TODO MODIFIER_FILE + * Modifies loaded data based on modifier file + * + * @see MODIFIER_FILE */ private Object RD_E198(InputStream data, Map control) throws IOException, ResourceParseException { + // TODO + return null; } From 101d68c64e781700109a98746f46d73cf9350ed0 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 26 May 2023 16:30:39 -0700 Subject: [PATCH 31/98] CloseUtilVolumeParser --- .../vdyp/io/parse/BaseCoefficientParser.java | 22 +++++++++++-- .../vdyp/io/parse/CloseUtilVolumeParser.java | 18 ++++++++++ .../vdyp/io/parse/ComponentSizeParser.java | 22 ++----------- .../io/parse/SimpleCoefficientParser2.java | 33 +++++++++++++++++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 10 +++--- .../nrs/vdyp/fip/FipControlParserTest.java | 14 ++++++++ 6 files changed, 93 insertions(+), 26 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index 43559a068..e2774816a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap; @@ -26,6 +27,8 @@ public abstract class BaseCoefficientParser segments) { + return segments.get(0).isBlank(); } }; @@ -60,6 +63,21 @@ public BaseCoefficientParser regionKey() { return key(1, REGION_KEY, ValueParser.REGION, regions, "%s is not a valid region"); } + public BaseCoefficientParser ucIndexKey() { + var indicies = Arrays.asList(1, 2, 3, 4); + return key( + 2, UC_INDEX, ValueParser.INTEGER, indicies, "%s is not a valid UC Index, should be 1 to 4 inclusive" + ); + } + + public BaseCoefficientParser groupIndexKey(int maxGroups) { + var indicies = Stream.iterate(1, x -> x + 1).limit(maxGroups).toList(); + return key( + 4, GROUP_INDEX, ValueParser.INTEGER, indicies, + "%s is not a valid Group Index, should be 1 to " + maxGroups + " inclusive" + ); + } + public BaseCoefficientParser speciesKey(String name, Map controlMap) { var range = SP0DefinitionParser.getSpeciesAliases(controlMap); return key(2, name, String::strip, range, "%s is not a valid species"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java new file mode 100644 index 000000000..4ef974f0a --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java @@ -0,0 +1,18 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +/** + * Parse a datafile with close util volumen coefficients + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class CloseUtilVolumeParser extends SimpleCoefficientParser2 { + + public static final String CONTROL_KEY = "CLOSE_UTIL_VOLUME"; + + public CloseUtilVolumeParser() { + super(1); + this.ucIndexKey().groupIndexKey(80).coefficients(4, 10); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java index 13031eed9..323a0cf60 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java @@ -1,12 +1,7 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.Collection; -import java.util.List; import java.util.Map; -import ca.bc.gov.nrs.vdyp.model.Coefficients; -import ca.bc.gov.nrs.vdyp.model.MatrixMap2; -import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.Region; /** @@ -15,26 +10,13 @@ * @author Kevin Smith, Vivid Solutions * */ -public class ComponentSizeParser extends BaseCoefficientParser> { +public class ComponentSizeParser extends SimpleCoefficientParser2 { public static final String CONTROL_KEY = "SPECIES_COMPONENT_SIZE_LIMIT"; public ComponentSizeParser(Map control) { - super(); + super(1); this.speciesKey(control).space(1).regionKey().coefficients(4, 6); } - @SuppressWarnings("unchecked") - @Override - protected MatrixMap2 createMap(List> keyRanges) { - return new MatrixMap2Impl( - (Collection) keyRanges.get(0), (Collection) keyRanges.get(1) - ); - } - - @Override - protected Coefficients getCoefficients(List coefficients) { - return new Coefficients(coefficients, 1); - } - } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java new file mode 100644 index 000000000..b63eef431 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Collection; +import java.util.List; + +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; + +public class SimpleCoefficientParser2 + extends BaseCoefficientParser> { + + private int indexFrom; + + public SimpleCoefficientParser2(int indexFrom) { + super(); + this.indexFrom = indexFrom; + } + + @SuppressWarnings("unchecked") + @Override + protected MatrixMap2 createMap(List> keyRanges) { + return new MatrixMap2Impl( + (Collection) keyRanges.get(0), (Collection) keyRanges.get(1) + ); + } + + @Override + protected Coefficients getCoefficients(List coefficients) { + return new Coefficients(coefficients, indexFrom); + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 53cf7dc81..adeab2ef4 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -15,6 +15,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.BaseCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.CloseUtilVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.CoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ComponentSizeParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; @@ -82,7 +83,7 @@ public class FipControlParser { public static final String SMALL_COMP_WS_VOLUME = "SMALL_COMP_WS_VOLUME"; public static final String TOTAL_STAND_WHOLE_STEM_VOL = "TOTAL_STAND_WHOLE_STEM_VOL"; public static final String UTIL_COMP_WS_VOLUME = "UTIL_COMP_WS_VOLUME"; - public static final String CLOSE_UTIL_VOLUME = "CLOSE_UTIL_VOLUME"; + public static final String CLOSE_UTIL_VOLUME = CloseUtilVolumeParser.CONTROL_KEY; public static final String VOLUME_NET_DECAY = "VOLUME_NET_DECAY"; public static final String VOLUME_NET_DECAY_WASTE = "VOLUME_NET_DECAY_WASTE"; public static final String BREAKAGE = "BREAKAGE"; @@ -900,8 +901,8 @@ private Object RD_YVT2(InputStream data, Map control) throws IOE * * @see CLOSE_UTIL_VOLUME */ - private Object RD_YVC1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO + private MatrixMap2 RD_YVC1(InputStream data, Map control) + throws IOException, ResourceParseException { // Uses // PARAMETER (MAXGROUP = 80) @@ -919,7 +920,8 @@ private Object RD_YVC1(InputStream data, Map control) throws IOE // UC is 1 indexed // Coefficient is 1 indexed - return null; + var parser = new CloseUtilVolumeParser(); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index b6f8c3ec4..4bdf501b4 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -415,6 +415,20 @@ public void testParseUBA1() throws Exception { ); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseYVC1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.CLOSE_UTIL_VOLUME), + allOf(mmHasEntry(present(contains(-3.249f, 0.2426f, 0.04621f)), 2, 53)) + ) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From 7adc378108b3b7901626eb14d4bb9a3cc8f3a403 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 11:14:34 -0700 Subject: [PATCH 32/98] VolumeNetDecayParser --- .../vdyp/io/parse/VolumeNetDecayParser.java | 18 ++++++++++++++++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 9 +++++---- .../gov/nrs/vdyp/fip/FipControlParserTest.java | 14 ++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java new file mode 100644 index 000000000..a5e1e1350 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java @@ -0,0 +1,18 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +/** + * Parse a datafile with volume net decay coefficients + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class VolumeNetDecayParser extends SimpleCoefficientParser2 { + + public static final String CONTROL_KEY = "VOLUME_NET_DECAY"; + + public VolumeNetDecayParser() { + super(1); + this.ucIndexKey().groupIndexKey(80).coefficients(4, 10); + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index adeab2ef4..025ed5eca 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -27,6 +27,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.UpperCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; @@ -929,8 +930,7 @@ private MatrixMap2 RD_YVC1(InputStream data, Map * * @see VOLUME_NET_DECAY */ - private Object RD_YVD1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO + private MatrixMap2 RD_YVD1(InputStream data, Map control) throws IOException, ResourceParseException { // Uses // PARAMETER (MAXGROUP = 80) @@ -947,8 +947,9 @@ private Object RD_YVD1(InputStream data, Map control) throws IOE // UC is 1 indexed // Coefficient is 1 indexed - - return null; + + var parser = new VolumeNetDecayParser(); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 4bdf501b4..515127100 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -428,6 +428,20 @@ public void testParseYVC1() throws Exception { ) ); } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseYVD1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.VOLUME_NET_DECAY), + allOf(mmHasEntry(present(contains(12.7054f, 0.14984f, -1.73471f)), 2, 53)) + ) + ); + } static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); From 1a45dc6497a59fafd4a9baf7cab0b02b84d4a08e Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 13:00:05 -0700 Subject: [PATCH 33/98] Small component parsers --- .../vdyp/io/parse/BaseCoefficientParser.java | 17 ++- .../io/parse/SimpleCoefficientParser1.java | 79 ++++++++++++ .../io/parse/SimpleCoefficientParser2.java | 2 +- .../parse/SmallComponentBaseAreaParser.java | 15 +++ .../vdyp/io/parse/SmallComponentDQParser.java | 15 +++ .../vdyp/io/parse/SmallComponentHLParser.java | 15 +++ .../SmallComponentProbabilityParser.java | 15 +++ .../parse/SmallComponentWSVolumeParser.java | 15 +++ .../SimpleSpeciesCoefficientParserTest.java | 114 ------------------ .../SmallComponentProbabilityParserTest.java | 50 ++++++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 41 ++++--- .../nrs/vdyp/fip/FipControlParserTest.java | 72 ++++++++++- 12 files changed, 313 insertions(+), 137 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java delete mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index e2774816a..45d68b4b5 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -34,9 +34,11 @@ public abstract class BaseCoefficientParser metaKeys = new ArrayList<>(); List> keyRanges = new ArrayList<>(); + private int expectedKeys; - public BaseCoefficientParser() { + public BaseCoefficientParser(int expectedKeys) { super(); + this.expectedKeys = expectedKeys; this.lineParser = new LineParser() { @Override @@ -47,8 +49,17 @@ public boolean isStopSegment(List segments) { }; } + public BaseCoefficientParser() { + this(0); + } + public BaseCoefficientParser key(int length, String name, ValueParser parser, Collection range, String errorTemplate) { + if (expectedKeys > 0 && metaKeys.size() == expectedKeys) { + throw new IllegalStateException( + "Expected " + expectedKeys + " keys but " + name + " was key " + expectedKeys + 1 + ); + } var validParser = ValueParser.validate( parser, (v) -> range.contains(v) ? Optional.empty() : Optional.of(String.format(errorTemplate, v)) ); @@ -102,7 +113,9 @@ public BaseCoefficientParser coefficients(int number, int length) { @Override public M parse(InputStream is, Map control) throws IOException, ResourceParseException { - + if (expectedKeys > 0 && metaKeys.size() != expectedKeys) { + throw new IllegalStateException("Expected " + expectedKeys + " keys but there were " + metaKeys.size()); + } M result = createMap(keyRanges); lineParser.parse(is, result, (v, r) -> { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java new file mode 100644 index 000000000..3d2f64a43 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java @@ -0,0 +1,79 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap; +import ca.bc.gov.nrs.vdyp.model.MatrixMapImpl; + +public class SimpleCoefficientParser1 implements ResourceParser> { + + private int indexFrom; + + Class keyClass; + + private BaseCoefficientParser> delegate = new BaseCoefficientParser>( + 1 + ) { + + @SuppressWarnings("unchecked") + @Override + protected MatrixMap createMap(List> keyRanges) { + return new MatrixMapImpl((Collection) keyRanges.get(0)); + } + + @Override + protected Coefficients getCoefficients(List coefficients) { + return new Coefficients(coefficients, indexFrom); + } + }; + + public SimpleCoefficientParser1(Class keyClass, int indexFrom) { + super(); + this.keyClass = keyClass; + this.indexFrom = indexFrom; + } + + @Override + public Map parse(InputStream is, Map control) + throws IOException, ResourceParseException { + var matrixMapResult = delegate.parse(is, control); + var result = MatrixMap.cast(matrixMapResult, keyClass); + return result; + } + + public BaseCoefficientParser> + key(int length, String name, ValueParser parser, Collection range, String errorTemplate) { + return delegate.key(length, name, parser, range, errorTemplate); + } + + public BaseCoefficientParser> regionKey() { + return delegate.regionKey(); + } + + public BaseCoefficientParser> ucIndexKey() { + return delegate.ucIndexKey(); + } + + public BaseCoefficientParser> groupIndexKey(int maxGroups) { + return delegate.groupIndexKey(maxGroups); + } + + public BaseCoefficientParser> + speciesKey(String name, Map controlMap) { + return delegate.speciesKey(name, controlMap); + } + + public BaseCoefficientParser> space(int length) { + return delegate.space(length); + } + + public BaseCoefficientParser> coefficients(int number, int length) { + return delegate.coefficients(number, length); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java index b63eef431..67285cc8c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java @@ -13,7 +13,7 @@ public class SimpleCoefficientParser2 private int indexFrom; public SimpleCoefficientParser2(int indexFrom) { - super(); + super(2); this.indexFrom = indexFrom; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java new file mode 100644 index 000000000..4a5372452 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java @@ -0,0 +1,15 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class SmallComponentBaseAreaParser extends SimpleCoefficientParser1 { + + public static final String CONTROL_KEY = "SMALL_COMP_BA"; + + public SmallComponentBaseAreaParser(Map control) { + super(String.class, 1); + this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.coefficients(4, 10); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java new file mode 100644 index 000000000..b37b78649 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java @@ -0,0 +1,15 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class SmallComponentDQParser extends SimpleCoefficientParser1 { + + public static final String CONTROL_KEY = "SMALL_COMP_DQ"; + + public SmallComponentDQParser(Map control) { + super(String.class, 1); + this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.coefficients(2, 10); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java new file mode 100644 index 000000000..0ed603f8b --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java @@ -0,0 +1,15 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class SmallComponentHLParser extends SimpleCoefficientParser1 { + + public static final String CONTROL_KEY = "SMALL_COMP_HL"; + + public SmallComponentHLParser(Map control) { + super(String.class, 1); + this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.coefficients(2, 10); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java new file mode 100644 index 000000000..410f0635f --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java @@ -0,0 +1,15 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class SmallComponentProbabilityParser extends SimpleCoefficientParser1 { + + public static final String CONTROL_KEY = "SMALL_COMP_PROBABILITY"; + + public SmallComponentProbabilityParser(Map control) { + super(String.class, 1); + this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.coefficients(4, 10); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java new file mode 100644 index 000000000..728266f9d --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java @@ -0,0 +1,15 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class SmallComponentWSVolumeParser extends SimpleCoefficientParser1 { + + public static final String CONTROL_KEY = "SMALL_COMP_WS_VOLUME"; + + public SmallComponentWSVolumeParser(Map control) { + super(String.class, 1); + this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.coefficients(4, 10); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java deleted file mode 100644 index 5d909d1e3..000000000 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleSpeciesCoefficientParserTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package ca.bc.gov.nrs.vdyp.io.parse; - -import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; -import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; -import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.HashMap; -import java.util.Map; - -import org.hamcrest.Matcher; -import org.junit.jupiter.api.Test; - -import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.test.TestUtils; - -public class SimpleSpeciesCoefficientParserTest { - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Test - public void testParseSimpleP1() throws Exception { - - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - - var is = TestUtils.makeStream("S1 I 1.00160 0.20508-0.0013743"); - - Map controlMap = new HashMap<>(); - - SP0DefinitionParserTest.populateControlMap(controlMap); - - var result = parser.parse(is, controlMap); - - assertThat(result, mmHasEntry(present(is(1.00160f)), 1, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry(present(is(0.20508f)), 2, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry(present(is(-0.0013743f)), 3, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher) notPresent(), 4, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.INTERIOR)); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Test - public void testParseSimpleP2() throws Exception { - - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); - - var is = TestUtils.makeStream("S1 C 0.49722 1.18403"); - - Map controlMap = new HashMap<>(); - - SP0DefinitionParserTest.populateControlMap(controlMap); - - var result = parser.parse(is, controlMap); - - assertThat(result, mmHasEntry(present(is(0.49722f)), 1, "S1", Region.COASTAL)); - assertThat(result, mmHasEntry(present(is(1.18403f)), 2, "S1", Region.COASTAL)); - assertThat(result, mmHasEntry((Matcher) notPresent(), 3, "S1", Region.COASTAL)); - assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.COASTAL)); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Test - public void testParseSimpleP3() throws Exception { - - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); - - var is = TestUtils.makeStream("S1 I 1.04422 0.93010 -0.05745 -2.50000"); - - Map controlMap = new HashMap<>(); - - SP0DefinitionParserTest.populateControlMap(controlMap); - - var result = parser.parse(is, controlMap); - - assertThat(result, mmHasEntry(present(is(1.04422f)), 1, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry(present(is(0.93010f)), 2, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry(present(is(-0.05745f)), 3, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry(present(is(-2.50000f)), 4, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher) notPresent(), 5, "S1", Region.INTERIOR)); - assertThat(result, mmHasEntry((Matcher) notPresent(), 0, "S1", Region.INTERIOR)); - } - - @Test - public void testParseBadSpecies() throws Exception { - - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - - var is = TestUtils.makeStream("SX I 1.00160 0.20508-0.0013743"); - - Map controlMap = new HashMap<>(); - - SP0DefinitionParserTest.populateControlMap(controlMap); - - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); - - } - - @Test - public void testParseBadRegion() throws Exception { - - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - - var is = TestUtils.makeStream("S1 X 1.00160 0.20508-0.0013743"); - - Map controlMap = new HashMap<>(); - - SP0DefinitionParserTest.populateControlMap(controlMap); - - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); - - } - -} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java new file mode 100644 index 000000000..56e46668a --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java @@ -0,0 +1,50 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.causedBy; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class SmallComponentProbabilityParserTest { + + @Test + public void testParseSimpleP1() throws Exception { + + var is = TestUtils.makeStream("S1 0.48205 0.00000 -0.011862 -0.10014"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var parser = new SmallComponentProbabilityParser(controlMap); + var result = parser.parse(is, controlMap); + + assertThat(result, hasEntry(is("S1"), contains(0.48205f, 0.00000f, -0.011862f, -0.10014f))); + } + + @Test + public void testParseBadSpecies() throws Exception { + + var is = TestUtils.makeStream("SX 0.48205 0.00000 -0.011862 -0.10014"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var parser = new SmallComponentProbabilityParser(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThat(ex, causedBy(hasProperty("value", is("SX")))); + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 025ed5eca..fb283bec9 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -23,6 +23,11 @@ import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveParser; +import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentBaseAreaParser; +import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentDQParser; +import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentHLParser; +import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentProbabilityParser; +import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.StockingClassFactorParser; import ca.bc.gov.nrs.vdyp.io.parse.UpperCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; @@ -77,11 +82,11 @@ public class FipControlParser { public static final String SPECIES_COMPONENT_SIZE_LIMIT = ComponentSizeParser.CONTROL_KEY; public static final String UTIL_COMP_BA = UtilComponentBaseAreaParser.CONTROL_KEY; public static final String UTIL_COMP_DQ = "UTIL_COMP_DQ"; - public static final String SMALL_COMP_PROBABILITY = "SMALL_COMP_PROBABILITY"; - public static final String SMALL_COMP_BA = "SMALL_COMP_BA"; - public static final String SMALL_COMP_DQ = "SMALL_COMP_DQ"; - public static final String SMALL_COMP_HL = "SMALL_COMP_HL"; - public static final String SMALL_COMP_WS_VOLUME = "SMALL_COMP_WS_VOLUME"; + public static final String SMALL_COMP_PROBABILITY = SmallComponentProbabilityParser.CONTROL_KEY; + public static final String SMALL_COMP_BA = SmallComponentBaseAreaParser.CONTROL_KEY; + public static final String SMALL_COMP_DQ = SmallComponentDQParser.CONTROL_KEY; + public static final String SMALL_COMP_HL = SmallComponentHLParser.CONTROL_KEY; + public static final String SMALL_COMP_WS_VOLUME = SmallComponentWSVolumeParser.CONTROL_KEY; public static final String TOTAL_STAND_WHOLE_STEM_VOL = "TOTAL_STAND_WHOLE_STEM_VOL"; public static final String UTIL_COMP_WS_VOLUME = "UTIL_COMP_WS_VOLUME"; public static final String CLOSE_UTIL_VOLUME = CloseUtilVolumeParser.CONTROL_KEY; @@ -736,8 +741,6 @@ private Object RD_UDQ1(InputStream data, Map control) throws IOE * @see SMALL_COMP_PROBABILITY */ private Object RD_SBA1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO - // Sets // C 4 coe for each of 16 SP0's // COMMON /V7COE080/ COE080(4, 16) @@ -750,7 +753,8 @@ private Object RD_SBA1(InputStream data, Map control) throws IOE // Coefficient is 1 indexed - return null; + var parser = new SmallComponentProbabilityParser(control); + return parser.parse(data, control); } /** @@ -759,7 +763,6 @@ private Object RD_SBA1(InputStream data, Map control) throws IOE * @see SMALL_COMP_BA */ private Object RD_SBA2(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Sets // C 4 coe for each of 16 SP0's @@ -773,7 +776,8 @@ private Object RD_SBA2(InputStream data, Map control) throws IOE // Coefficient is 1 indexed - return null; + var parser = new SmallComponentBaseAreaParser(control); + return parser.parse(data, control); } /** @@ -782,7 +786,6 @@ private Object RD_SBA2(InputStream data, Map control) throws IOE * @see SMALL_COMP_DQ */ private Object RD_SDQ1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Sets // C 2 coe for each of 16 SP0's @@ -796,7 +799,8 @@ private Object RD_SDQ1(InputStream data, Map control) throws IOE // Coefficient is 1 indexed - return null; + var parser = new SmallComponentDQParser(control); + return parser.parse(data, control); } /** @@ -805,7 +809,6 @@ private Object RD_SDQ1(InputStream data, Map control) throws IOE * @see SMALL_COMP_HL */ private Object RD_SHL1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Sets // C 2 coe for each of 16 SP0's @@ -819,7 +822,8 @@ private Object RD_SHL1(InputStream data, Map control) throws IOE // Coefficient is 1 indexed - return null; + var parser = new SmallComponentHLParser(control); + return parser.parse(data, control); } /** @@ -828,7 +832,6 @@ private Object RD_SHL1(InputStream data, Map control) throws IOE * @see SMALL_COMP_WS_VOLUME */ private Object RD_SVT1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Sets // C 4 coe for each of 16 SP0's @@ -842,7 +845,8 @@ private Object RD_SVT1(InputStream data, Map control) throws IOE // Coefficient is 1 indexed - return null; + var parser = new SmallComponentWSVolumeParser(control); + return parser.parse(data, control); } /** @@ -930,7 +934,8 @@ private MatrixMap2 RD_YVC1(InputStream data, Map * * @see VOLUME_NET_DECAY */ - private MatrixMap2 RD_YVD1(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap2 RD_YVD1(InputStream data, Map control) + throws IOException, ResourceParseException { // Uses // PARAMETER (MAXGROUP = 80) @@ -947,7 +952,7 @@ private MatrixMap2 RD_YVD1(InputStream data, Map // UC is 1 indexed // Coefficient is 1 indexed - + var parser = new VolumeNetDecayParser(); return parser.parse(data, control); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 515127100..a08a87acc 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -428,7 +428,7 @@ public void testParseYVC1() throws Exception { ) ); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseYVD1() throws Exception { @@ -438,7 +438,75 @@ public void testParseYVD1() throws Exception { result, (Matcher) hasEntry( is(FipControlParser.VOLUME_NET_DECAY), - allOf(mmHasEntry(present(contains(12.7054f, 0.14984f, -1.73471f)), 2, 53)) + allOf(mmHasEntry(present(contains(12.7054f, 0.14984f, -1.73471f)), 2, 53)) + ) + ); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSBA1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.SMALL_COMP_PROBABILITY), + allOf(hasEntry(is("AT"), contains(-1.76158f, 2.50045f, -0.030447f, -0.11746f))) + ) + ); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSBA2() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.SMALL_COMP_BA), + allOf(hasEntry(is("B"), contains(-1.3504f, 9.5806f, 3.35173f, -0.27311f))) + ) + ); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSDQ1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.SMALL_COMP_DQ), allOf(hasEntry(is("B"), contains(-0.33485f, 0.02029f))) + ) + ); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSHL1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.SMALL_COMP_HL), allOf(hasEntry(is("B"), contains(-8.5269f, -0.20000f))) + ) + ); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseSVT1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.SMALL_COMP_WS_VOLUME), + allOf(hasEntry(is("B"), contains(-9.6020f, 1.09191f, 1.26171f, 0.10841f))) ) ); } From e4a96363889f439c815e8964b802c9233a5c9067 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 16:45:42 -0700 Subject: [PATCH 34/98] Add tests for FIP control file parser methods --- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 54 +++++--- .../nrs/vdyp/fip/FipControlParserTest.java | 123 ++++++++++++++++++ 2 files changed, 160 insertions(+), 17 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index fb283bec9..824d3ca85 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -740,7 +740,8 @@ private Object RD_UDQ1(InputStream data, Map control) throws IOE * * @see SMALL_COMP_PROBABILITY */ - private Object RD_SBA1(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_SBA1(InputStream data, Map control) + throws IOException, ResourceParseException { // Sets // C 4 coe for each of 16 SP0's // COMMON /V7COE080/ COE080(4, 16) @@ -762,7 +763,8 @@ private Object RD_SBA1(InputStream data, Map control) throws IOE * * @see SMALL_COMP_BA */ - private Object RD_SBA2(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_SBA2(InputStream data, Map control) + throws IOException, ResourceParseException { // Sets // C 4 coe for each of 16 SP0's @@ -785,7 +787,8 @@ private Object RD_SBA2(InputStream data, Map control) throws IOE * * @see SMALL_COMP_DQ */ - private Object RD_SDQ1(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_SDQ1(InputStream data, Map control) + throws IOException, ResourceParseException { // Sets // C 2 coe for each of 16 SP0's @@ -808,7 +811,8 @@ private Object RD_SDQ1(InputStream data, Map control) throws IOE * * @see SMALL_COMP_HL */ - private Object RD_SHL1(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_SHL1(InputStream data, Map control) + throws IOException, ResourceParseException { // Sets // C 2 coe for each of 16 SP0's @@ -831,7 +835,8 @@ private Object RD_SHL1(InputStream data, Map control) throws IOE * * @see SMALL_COMP_WS_VOLUME */ - private Object RD_SVT1(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_SVT1(InputStream data, Map control) + throws IOException, ResourceParseException { // Sets // C 4 coe for each of 16 SP0's @@ -850,11 +855,12 @@ private Object RD_SVT1(InputStream data, Map control) throws IOE } /** - * Loads the information that was in the global array V7COE090 in Fortran + * Loads the information that was in the global array COE090 in Fortran * * @see TOTAL_STAND_WHOLE_STEM_VOL */ - private Object RD_YVT1(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_YVT1(InputStream data, Map control) + throws IOException, ResourceParseException { // TODO // Uses @@ -871,6 +877,7 @@ private Object RD_YVT1(InputStream data, Map control) throws IOE // Ignore if first segment is 0 // Coefficient is 0 indexed + // Group is 1 indexed return null; } @@ -880,23 +887,26 @@ private Object RD_YVT1(InputStream data, Map control) throws IOE * * @see UTIL_COMP_WS_VOLUME */ - private Object RD_YVT2(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap2 RD_YVT2(InputStream data, Map control) + throws IOException, ResourceParseException { // TODO // Uses // PARAMETER (MAXGROUP = 80) // Sets - // C 9 coe for each of (Up to 80 groups) - // COMMON /V7COE090/ COE090(0:8, MAXGROUP) + // C 4 coe for (4 UC's) for (Up to 80 groups) + // COMMON /V7COE091/ COE091(4, 4, MAXGROUP) // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) VGRP, (C(I),I=0,8) - // 11 FORMAT( I3, 9f10.0) + // 10 READ(IU_TEMP, 11, ERR=90, END=70) UC, VGRP, (C(I),I=1,4) + // 11 FORMAT( I2, I4, 4f10.0) // Ignore if first segment is 0 // Coefficient is 0 indexed + // UC is 1 indexed + // Group is 1 indexed return null; } @@ -922,6 +932,7 @@ private MatrixMap2 RD_YVC1(InputStream data, Map // Ignore if first segment is 0 + // Group is 1 indexed // UC is 1 indexed // Coefficient is 1 indexed @@ -950,6 +961,7 @@ private MatrixMap2 RD_YVD1(InputStream data, Map // Ignore if first segment is 0 + // Group is 1 indexed // UC is 1 indexed // Coefficient is 1 indexed @@ -962,7 +974,8 @@ private MatrixMap2 RD_YVD1(InputStream data, Map * * @see VOLUME_NET_DECAY_WASTE */ - private Object RD_YVW1(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_YVW1(InputStream data, Map control) + throws IOException, ResourceParseException { // TODO // Uses @@ -989,7 +1002,8 @@ private Object RD_YVW1(InputStream data, Map control) throws IOE * @see BREAKAGE */ // Example FIPSTART.CTR calls this RD_EMP95 - private Object RD_E095(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_E095(InputStream data, Map control) + throws IOException, ResourceParseException { // TODO // Uses @@ -1005,6 +1019,7 @@ private Object RD_E095(InputStream data, Map control) throws IOE // Ignore if first segment is 0 + // Group is 1 indexed // Coefficient is 1 indexed return null; @@ -1016,7 +1031,8 @@ private Object RD_E095(InputStream data, Map control) throws IOE * @see VETERAN_LAYER_VOLUME_ADJUST */ // Example FIPSTART.CTR calls this RD_YVET - private Object RD_YVVET(InputStream data, Map control) throws IOException, ResourceParseException { + private Map RD_YVVET(InputStream data, Map control) + throws IOException, ResourceParseException { // TODO // Sets @@ -1038,7 +1054,8 @@ private Object RD_YVVET(InputStream data, Map control) throws IO * * @see VETERAN_LAYER_DQ */ - private Object RD_YDQV(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap2 RD_YDQV(InputStream data, Map control) + throws IOException, ResourceParseException { // TODO // Sets @@ -1053,6 +1070,8 @@ private Object RD_YDQV(InputStream data, Map control) throws IOE // Coefficient is 1 indexed + // Apply to both Regions if blank + return null; } @@ -1061,7 +1080,8 @@ private Object RD_YDQV(InputStream data, Map control) throws IOE * * @see VETERAN_BQ */ - private Object RD_E098(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap2 RD_E098(InputStream data, Map control) + throws IOException, ResourceParseException { // TODO // Sets diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index a08a87acc..74c94331f 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -511,6 +511,129 @@ public void testParseSVT1() throws Exception { ); } + @Disabled + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseYVT1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.TOTAL_STAND_WHOLE_STEM_VOL), + allOf( + hasEntry( + is(2), + contains( + -10.41832f, 1.94182f, 0.99414f, 0.000000f, 1.11329f, 0.000000f, + 0.0000000f, 0.0000000f, 0.19884f + ) + ) + ) + ) + ); + } + + @Disabled + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseYVT2() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.UTIL_COMP_WS_VOLUME), + allOf(mmHasEntry(present(contains(-1.44375f, 1.20115f, 1.14639f, -1.17521f)), 2, 11)) + ) + ); + } + + @Disabled + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseYVW1() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.VOLUME_NET_DECAY_WASTE), + allOf(hasEntry(is("B"), contains(-4.2025f, 11.2235f, -33.0270f, 0.1246f, -0.2318f, -0.1259f))) + ) + ); + } + + @Disabled + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE095() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.BREAKAGE), + allOf(hasEntry(is(10), contains(-0.7153f, 2.0108f, 4.00f, 8.00f))) + ) + ); + } + + @Disabled + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseYVVET() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.BREAKAGE), + allOf(hasEntry(is("B"), contains(0.10881f, -0.09818f, 0.00048f, -0.00295f))) + ) + ); + } + + @Disabled + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseYDQV() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.UTIL_COMP_WS_VOLUME), + allOf( + mmHasEntry(present(contains(22.500f, 0.24855f, 1.46089f)), "B", Region.COASTAL), + mmHasEntry(present(contains(19.417f, 0.04354f, 1.96395f)), "B", Region.INTERIOR), + mmHasEntry(present(contains(22.500f, 0.80260f, 1.00000f)), "D", Region.COASTAL), + mmHasEntry(present(contains(22.500f, 0.80260f, 1.00000f)), "D", Region.INTERIOR) + ) + ) + ); + } + + @Disabled + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testParseE098() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasEntry( + is(FipControlParser.UTIL_COMP_WS_VOLUME), + allOf( + mmHasEntry(present(contains(0.12874f, 8.00000f, 1.26982f)), "B", Region.COASTAL), + mmHasEntry(present(contains(0.70932f, 7.63269f, 0.62545f)), "B", Region.INTERIOR), + mmHasEntry(present(contains(0.07962f, 6.60231f, 1.37998f)), "D", Region.COASTAL), + mmHasEntry(present(contains(0.07962f, 6.60231f, 1.37998f)), "D", Region.INTERIOR) + ) + ) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From ca636be66cb853c91319b6114ff189a2d42a844e Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 17:39:52 -0700 Subject: [PATCH 35/98] TotalStandWholeStemParser --- .../vdyp/io/parse/BaseCoefficientParser.java | 2 +- .../vdyp/io/parse/CloseUtilVolumeParser.java | 2 +- .../io/parse/TotalStandWholeStemParser.java | 14 ++++++++ .../vdyp/io/parse/VolumeNetDecayParser.java | 2 +- .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 34 +++++++++++++++++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 11 +++--- .../nrs/vdyp/fip/FipControlParserTest.java | 9 +++-- 7 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index 45d68b4b5..bf076451c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -84,7 +84,7 @@ public BaseCoefficientParser ucIndexKey() { public BaseCoefficientParser groupIndexKey(int maxGroups) { var indicies = Stream.iterate(1, x -> x + 1).limit(maxGroups).toList(); return key( - 4, GROUP_INDEX, ValueParser.INTEGER, indicies, + 3, GROUP_INDEX, ValueParser.INTEGER, indicies, "%s is not a valid Group Index, should be 1 to " + maxGroups + " inclusive" ); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java index 4ef974f0a..2645cb0e7 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java @@ -12,7 +12,7 @@ public class CloseUtilVolumeParser extends SimpleCoefficientParser2 { + + public static final String CONTROL_KEY = "TOTAL_STAND_WHOLE_STEM_VOL"; + + public TotalStandWholeStemParser() { + super(Integer.class, 1); + this.groupIndexKey(80); + this.coefficients(9, 10); + } + +} + diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java index a5e1e1350..1ea9fee3e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java @@ -12,7 +12,7 @@ public class VolumeNetDecayParser extends SimpleCoefficientParser2 Matcher> hasSpecificEntry(K key, Matcher valueMatcher) { + return new TypeSafeDiagnosingMatcher>() { + + @Override + protected boolean matchesSafely(Map map, Description mismatchDescription) { + V result = map.get(key); + if(Objects.isNull(result)) { + mismatchDescription.appendText("entry for ").appendValue(key).appendText(" was not present"); + return false; + } + if(! valueMatcher.matches(result)) { + mismatchDescription.appendText("entry for ").appendValue(key).appendText(" was present but "); + valueMatcher.describeMismatch(result, mismatchDescription); + return false; + } + + return true; + } + + @Override + public void describeTo(Description description) { + description.appendText("A map with an entry for ").appendValue(key).appendText(" that ").appendDescriptionOf(valueMatcher); + } + + }; + + } } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 824d3ca85..7673d222a 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -29,6 +29,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentProbabilityParser; import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.StockingClassFactorParser; +import ca.bc.gov.nrs.vdyp.io.parse.TotalStandWholeStemParser; import ca.bc.gov.nrs.vdyp.io.parse.UpperCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; @@ -87,7 +88,7 @@ public class FipControlParser { public static final String SMALL_COMP_DQ = SmallComponentDQParser.CONTROL_KEY; public static final String SMALL_COMP_HL = SmallComponentHLParser.CONTROL_KEY; public static final String SMALL_COMP_WS_VOLUME = SmallComponentWSVolumeParser.CONTROL_KEY; - public static final String TOTAL_STAND_WHOLE_STEM_VOL = "TOTAL_STAND_WHOLE_STEM_VOL"; + public static final String TOTAL_STAND_WHOLE_STEM_VOL = TotalStandWholeStemParser.CONTROL_KEY; public static final String UTIL_COMP_WS_VOLUME = "UTIL_COMP_WS_VOLUME"; public static final String CLOSE_UTIL_VOLUME = CloseUtilVolumeParser.CONTROL_KEY; public static final String VOLUME_NET_DECAY = "VOLUME_NET_DECAY"; @@ -861,8 +862,7 @@ private Map RD_SVT1(InputStream data, Map */ private Map RD_YVT1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO - + // Uses // PARAMETER (MAXGROUP = 80) @@ -878,8 +878,9 @@ private Map RD_YVT1(InputStream data, Map // Coefficient is 0 indexed // Group is 1 indexed - - return null; + + var parser = new TotalStandWholeStemParser(); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 74c94331f..775f508a2 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -1,5 +1,6 @@ package ca.bc.gov.nrs.vdyp.fip; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.hasSpecificEntry; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; @@ -511,7 +512,6 @@ public void testParseSVT1() throws Exception { ); } - @Disabled @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseYVT1() throws Exception { @@ -519,14 +519,13 @@ public void testParseYVT1() throws Exception { var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.TOTAL_STAND_WHOLE_STEM_VOL), + (Matcher) hasSpecificEntry( + FipControlParser.TOTAL_STAND_WHOLE_STEM_VOL, allOf( hasEntry( is(2), contains( - -10.41832f, 1.94182f, 0.99414f, 0.000000f, 1.11329f, 0.000000f, - 0.0000000f, 0.0000000f, 0.19884f + -10.41832f, 1.94182f, 0.99414f, 0.000000f, 1.11329f, 0.000000f, 0.0000000f, 0.0000000f, 0.19884f ) ) ) From 98c60d8ac2ebd35b1cdead7a50e6e552cc3c1954 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 17:40:47 -0700 Subject: [PATCH 36/98] Add nohup log to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index cafaf7df6..e7f9facec 100644 --- a/.gitignore +++ b/.gitignore @@ -237,3 +237,6 @@ $RECYCLE.BIN/ *.lnk # End of https://www.toptal.com/developers/gitignore/api/java,emacs,linux,maven,eclipse,windows,macos + +# nohup logs +nohup.out From b5e972392299c39e910b7181cc461b17e8a7c1e6 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 17:56:48 -0700 Subject: [PATCH 37/98] Use new hasSpecificEtry matcher for FIP parser unit tests to make errors more readable --- .../io/parse/TotalStandWholeStemParser.java | 1 - .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 13 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 4 +- .../nrs/vdyp/fip/FipControlParserTest.java | 186 +++++++----------- 4 files changed, 85 insertions(+), 119 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java index 31a263922..5aa5da60d 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java @@ -11,4 +11,3 @@ public TotalStandWholeStemParser() { } } - diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index 512e33b2c..97b715a69 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -194,9 +194,11 @@ public void describeMismatch(Object item, Description description) { }; } - + /** - * Equivalent to {@link Matchers.hasEntry} with a simple equality check on the key. Does not show the full map contents on a mismatch, just the requested entry if it's present. + * Equivalent to {@link Matchers.hasEntry} with a simple equality check on the + * key. Does not show the full map contents on a mismatch, just the requested + * entry if it's present. */ public static Matcher> hasSpecificEntry(K key, Matcher valueMatcher) { return new TypeSafeDiagnosingMatcher>() { @@ -204,11 +206,11 @@ public static Matcher> hasSpecificEntry(K key, Matcher value @Override protected boolean matchesSafely(Map map, Description mismatchDescription) { V result = map.get(key); - if(Objects.isNull(result)) { + if (Objects.isNull(result)) { mismatchDescription.appendText("entry for ").appendValue(key).appendText(" was not present"); return false; } - if(! valueMatcher.matches(result)) { + if (!valueMatcher.matches(result)) { mismatchDescription.appendText("entry for ").appendValue(key).appendText(" was present but "); valueMatcher.describeMismatch(result, mismatchDescription); return false; @@ -219,7 +221,8 @@ protected boolean matchesSafely(Map map, Description mismatchDescription) @Override public void describeTo(Description description) { - description.appendText("A map with an entry for ").appendValue(key).appendText(" that ").appendDescriptionOf(valueMatcher); + description.appendText("A map with an entry for ").appendValue(key).appendText(" that ") + .appendDescriptionOf(valueMatcher); } }; diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 7673d222a..eac129ce7 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -862,7 +862,7 @@ private Map RD_SVT1(InputStream data, Map */ private Map RD_YVT1(InputStream data, Map control) throws IOException, ResourceParseException { - + // Uses // PARAMETER (MAXGROUP = 80) @@ -878,7 +878,7 @@ private Map RD_YVT1(InputStream data, Map // Coefficient is 0 indexed // Group is 1 indexed - + var parser = new TotalStandWholeStemParser(); return parser.parse(data, control); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 775f508a2..037f1ebb8 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -39,7 +39,7 @@ import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; import ca.bc.gov.nrs.vdyp.model.StockingClassFactor; -@SuppressWarnings("unused") +@SuppressWarnings({ "unused", "unchecked", "rawtypes" }) public class FipControlParserTest { @Test @@ -49,42 +49,39 @@ public void testParse() throws Exception { } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseBec() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(BecDefinitionParser.CONTROL_KEY), + (Matcher) hasSpecificEntry( + BecDefinitionParser.CONTROL_KEY, allOf(instanceOf(Map.class), hasEntry(is("AT"), instanceOf(BecDefinition.class))) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSP0() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(SP0DefinitionParser.CONTROL_KEY), + (Matcher) hasSpecificEntry( + SP0DefinitionParser.CONTROL_KEY, allOf(instanceOf(List.class), hasItem(instanceOf(SP0Definition.class))) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseVGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.VOLUME_EQN_GROUPS), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.VOLUME_EQN_GROUPS, allOf( // Map of SP0 Aliases isA(Map.class), hasEntry( isA(String.class), allOf( @@ -99,14 +96,13 @@ public void testParseVGRP() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseDGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.DECAY_GROUPS), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.DECAY_GROUPS, allOf( // Map of SP0 Aliases isA(Map.class), hasEntry( isA(String.class), allOf( @@ -121,14 +117,13 @@ public void testParseDGRP() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseBGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.BREAKAGE_GROUPS), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.BREAKAGE_GROUPS, allOf( // Map of SP0 Aliases isA(Map.class), hasEntry( isA(String.class), allOf( @@ -143,14 +138,13 @@ public void testParseBGRP() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseGRBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.DEFAULT_EQ_NUM), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.DEFAULT_EQ_NUM, allOf( // Map of SP0 Aliases isA(Map.class), hasEntry( isA(String.class), allOf( @@ -165,14 +159,13 @@ public void testParseGRBA1() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseGMBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.EQN_MODIFIERS), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.EQN_MODIFIERS, allOf( // Default Equation isA(Map.class), hasEntry( isA(Integer.class), allOf( @@ -187,14 +180,13 @@ public void testParseGMBA1() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSTK33() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.STOCKING_CLASS_FACTORS), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.STOCKING_CLASS_FACTORS, allOf( // STK isA(Map.class), hasEntry( isA(Character.class), allOf( @@ -210,14 +202,13 @@ public void testParseSTK33() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE025() throws Exception { var parser = new FipControlParser(); var result = parseWithAppendix(parser, "025 coe/SIEQN.PRM"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.SITE_CURVE_NUMBERS), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.SITE_CURVE_NUMBERS, allOf( // Species isA(Map.class), hasEntry(isA(String.class), isA(SiteCurve.class)) ) @@ -225,22 +216,20 @@ public void testParseE025() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE025Empty() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - assertThat(result, (Matcher) hasEntry(is(FipControlParser.SITE_CURVE_NUMBERS), Matchers.anEmptyMap())); + assertThat(result, (Matcher) hasSpecificEntry(FipControlParser.SITE_CURVE_NUMBERS, Matchers.anEmptyMap())); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE026() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, (Matcher) hasEntry( - is(FipControlParser.SITE_CURVE_AGE_MAX), allOf( + result, (Matcher) hasSpecificEntry( + FipControlParser.SITE_CURVE_AGE_MAX, allOf( // Species isA(Map.class), hasEntry(isA(Integer.class), isA(SiteCurveAgeMaximum.class)) ) @@ -248,107 +237,99 @@ public void testParseE026() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test // @Disabled public void testParseE026Empty() throws Exception { var parser = new FipControlParser(); var result = parseWithAppendix(parser, "026 "); // Map is empty but gives appropriate default values - assertThat(result, (Matcher) hasEntry(is(FipControlParser.SITE_CURVE_AGE_MAX), Matchers.anEmptyMap())); + assertThat(result, (Matcher) hasSpecificEntry(FipControlParser.SITE_CURVE_AGE_MAX, Matchers.anEmptyMap())); assertThat( ((Map) result.get(FipControlParser.SITE_CURVE_AGE_MAX)).get(1), (Matcher) allOf(SiteCurveAgeMaximumParserTest.hasAge(Region.COASTAL, is(140.f))) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE040() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry(is(FipControlParser.COE_BA), allOf(mmHasEntry(present(is(2.0028f)), 0, "AT", 1))) + (Matcher) hasSpecificEntry(FipControlParser.COE_BA, allOf(mmHasEntry(present(is(2.0028f)), 0, "AT", 1))) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE041() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry(is(FipControlParser.COE_DQ), allOf(mmHasEntry(present(is(6.6190f)), 0, "AT", 1))) + (Matcher) hasSpecificEntry(FipControlParser.COE_DQ, allOf(mmHasEntry(present(is(6.6190f)), 0, "AT", 1))) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE043() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.UPPER_BA_BY_CI_S0_P), + (Matcher) hasSpecificEntry( + FipControlParser.UPPER_BA_BY_CI_S0_P, allOf(mmHasEntry(present(is(109.27f)), Region.COASTAL, "AC", 1)) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE050() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.HL_PRIMARY_SP_EQN_P1), + (Matcher) hasSpecificEntry( + FipControlParser.HL_PRIMARY_SP_EQN_P1, allOf(mmHasEntry(present(is(1.00160f)), 1, "AC", Region.COASTAL)) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE051() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.HL_PRIMARY_SP_EQN_P2), + (Matcher) hasSpecificEntry( + FipControlParser.HL_PRIMARY_SP_EQN_P2, allOf(mmHasEntry(present(is(0.49722f)), 1, "AC", Region.COASTAL)) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE052() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.HL_PRIMARY_SP_EQN_P3), + (Matcher) hasSpecificEntry( + FipControlParser.HL_PRIMARY_SP_EQN_P3, allOf(mmHasEntry(present(is(1.04422f)), 1, "AC", Region.COASTAL)) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE053() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.HL_NONPRIMARY), + (Matcher) hasSpecificEntry( + FipControlParser.HL_NONPRIMARY, allOf( mmHasEntry( present(HLNonprimaryCoefficientParserTest.coe(0.86323f, 1.00505f, 1)), "AC", @@ -359,15 +340,14 @@ public void testParseE053() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE060() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.BY_SPECIES_DQ), + (Matcher) hasSpecificEntry( + FipControlParser.BY_SPECIES_DQ, contains( contains( -0.65484f, -0.48275f, -0.75134f, 0.04482f, -0.31195f, -0.53012f, -0.12645f, @@ -388,131 +368,121 @@ public void testParseE060() throws Exception { ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseE061() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.SPECIES_COMPONENT_SIZE_LIMIT), + (Matcher) hasSpecificEntry( + FipControlParser.SPECIES_COMPONENT_SIZE_LIMIT, allOf(mmHasEntry(present(contains(49.4f, 153.3f, 0.726f, 3.647f)), "AC", Region.COASTAL)) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseUBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.UTIL_COMP_BA), + (Matcher) hasSpecificEntry( + FipControlParser.UTIL_COMP_BA, allOf(mmHasEntry(present(contains(-26.68771f, 14.38811f)), BaseAreaCode.BA12, "AT", "ICH")) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseYVC1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.CLOSE_UTIL_VOLUME), + (Matcher) hasSpecificEntry( + FipControlParser.CLOSE_UTIL_VOLUME, allOf(mmHasEntry(present(contains(-3.249f, 0.2426f, 0.04621f)), 2, 53)) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseYVD1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.VOLUME_NET_DECAY), + (Matcher) hasSpecificEntry( + FipControlParser.VOLUME_NET_DECAY, allOf(mmHasEntry(present(contains(12.7054f, 0.14984f, -1.73471f)), 2, 53)) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.SMALL_COMP_PROBABILITY), + (Matcher) hasSpecificEntry( + FipControlParser.SMALL_COMP_PROBABILITY, allOf(hasEntry(is("AT"), contains(-1.76158f, 2.50045f, -0.030447f, -0.11746f))) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSBA2() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.SMALL_COMP_BA), + (Matcher) hasSpecificEntry( + FipControlParser.SMALL_COMP_BA, allOf(hasEntry(is("B"), contains(-1.3504f, 9.5806f, 3.35173f, -0.27311f))) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSDQ1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.SMALL_COMP_DQ), allOf(hasEntry(is("B"), contains(-0.33485f, 0.02029f))) + (Matcher) hasSpecificEntry( + FipControlParser.SMALL_COMP_DQ, allOf(hasEntry(is("B"), contains(-0.33485f, 0.02029f))) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSHL1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.SMALL_COMP_HL), allOf(hasEntry(is("B"), contains(-8.5269f, -0.20000f))) + (Matcher) hasSpecificEntry( + FipControlParser.SMALL_COMP_HL, allOf(hasEntry(is("B"), contains(-8.5269f, -0.20000f))) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseSVT1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.SMALL_COMP_WS_VOLUME), + (Matcher) hasSpecificEntry( + FipControlParser.SMALL_COMP_WS_VOLUME, allOf(hasEntry(is("B"), contains(-9.6020f, 1.09191f, 1.26171f, 0.10841f))) ) ); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testParseYVT1() throws Exception { var parser = new FipControlParser(); @@ -525,7 +495,8 @@ public void testParseYVT1() throws Exception { hasEntry( is(2), contains( - -10.41832f, 1.94182f, 0.99414f, 0.000000f, 1.11329f, 0.000000f, 0.0000000f, 0.0000000f, 0.19884f + -10.41832f, 1.94182f, 0.99414f, 0.000000f, 1.11329f, 0.000000f, + 0.0000000f, 0.0000000f, 0.19884f ) ) ) @@ -533,76 +504,70 @@ public void testParseYVT1() throws Exception { ); } - @Disabled - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Disabled // TODO @Test public void testParseYVT2() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.UTIL_COMP_WS_VOLUME), + (Matcher) hasSpecificEntry( + FipControlParser.UTIL_COMP_WS_VOLUME, allOf(mmHasEntry(present(contains(-1.44375f, 1.20115f, 1.14639f, -1.17521f)), 2, 11)) ) ); } - @Disabled - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Disabled // TODO @Test public void testParseYVW1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.VOLUME_NET_DECAY_WASTE), + (Matcher) hasSpecificEntry( + FipControlParser.VOLUME_NET_DECAY_WASTE, allOf(hasEntry(is("B"), contains(-4.2025f, 11.2235f, -33.0270f, 0.1246f, -0.2318f, -0.1259f))) ) ); } - @Disabled - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Disabled // TODO @Test public void testParseE095() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.BREAKAGE), - allOf(hasEntry(is(10), contains(-0.7153f, 2.0108f, 4.00f, 8.00f))) + (Matcher) hasSpecificEntry( + FipControlParser.BREAKAGE, allOf(hasEntry(is(10), contains(-0.7153f, 2.0108f, 4.00f, 8.00f))) ) ); } - @Disabled - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Disabled // TODO @Test public void testParseYVVET() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.BREAKAGE), + (Matcher) hasSpecificEntry( + FipControlParser.BREAKAGE, allOf(hasEntry(is("B"), contains(0.10881f, -0.09818f, 0.00048f, -0.00295f))) ) ); } - @Disabled - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Disabled // TODO @Test public void testParseYDQV() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.UTIL_COMP_WS_VOLUME), + (Matcher) hasSpecificEntry( + FipControlParser.UTIL_COMP_WS_VOLUME, allOf( mmHasEntry(present(contains(22.500f, 0.24855f, 1.46089f)), "B", Region.COASTAL), mmHasEntry(present(contains(19.417f, 0.04354f, 1.96395f)), "B", Region.INTERIOR), @@ -613,16 +578,15 @@ public void testParseYDQV() throws Exception { ); } - @Disabled - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Disabled // TODO @Test public void testParseE098() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( result, - (Matcher) hasEntry( - is(FipControlParser.UTIL_COMP_WS_VOLUME), + (Matcher) hasSpecificEntry( + FipControlParser.UTIL_COMP_WS_VOLUME, allOf( mmHasEntry(present(contains(0.12874f, 8.00000f, 1.26982f)), "B", Region.COASTAL), mmHasEntry(present(contains(0.70932f, 7.63269f, 0.62545f)), "B", Region.INTERIOR), From 1575300a360619dca9a900abcefa9d26a1ac33d3 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 18:43:44 -0700 Subject: [PATCH 38/98] UtilComponentWSVolumeParser --- .../vdyp/io/parse/UtilComponentWSVolumeParser.java | 12 ++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 8 ++++---- .../ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java | 1 - 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java new file mode 100644 index 000000000..7de1c5961 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java @@ -0,0 +1,12 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +public class UtilComponentWSVolumeParser extends SimpleCoefficientParser2 { + + public static final String CONTROL_KEY = "UTIL_COMP_WS_VOLUME"; + + public UtilComponentWSVolumeParser() { + super(1); + this.ucIndexKey().space(1).groupIndexKey(80).coefficients(4, 10); + } + +} \ No newline at end of file diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index eac129ce7..8c350a5d8 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -32,6 +32,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.TotalStandWholeStemParser; import ca.bc.gov.nrs.vdyp.io.parse.UpperCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; +import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; @@ -89,7 +90,7 @@ public class FipControlParser { public static final String SMALL_COMP_HL = SmallComponentHLParser.CONTROL_KEY; public static final String SMALL_COMP_WS_VOLUME = SmallComponentWSVolumeParser.CONTROL_KEY; public static final String TOTAL_STAND_WHOLE_STEM_VOL = TotalStandWholeStemParser.CONTROL_KEY; - public static final String UTIL_COMP_WS_VOLUME = "UTIL_COMP_WS_VOLUME"; + public static final String UTIL_COMP_WS_VOLUME = UtilComponentWSVolumeParser.CONTROL_KEY; public static final String CLOSE_UTIL_VOLUME = CloseUtilVolumeParser.CONTROL_KEY; public static final String VOLUME_NET_DECAY = "VOLUME_NET_DECAY"; public static final String VOLUME_NET_DECAY_WASTE = "VOLUME_NET_DECAY_WASTE"; @@ -686,7 +687,6 @@ private MatrixMap2 RD_E061(InputStream data, Map RD_UBA1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Uses // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) @@ -890,7 +890,6 @@ private Map RD_YVT1(InputStream data, Map */ private MatrixMap2 RD_YVT2(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Uses // PARAMETER (MAXGROUP = 80) @@ -909,7 +908,8 @@ private MatrixMap2 RD_YVT2(InputStream data, Map // UC is 1 indexed // Group is 1 indexed - return null; + var parser = new UtilComponentWSVolumeParser(); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 037f1ebb8..c47bc2a1a 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -504,7 +504,6 @@ public void testParseYVT1() throws Exception { ); } - @Disabled // TODO @Test public void testParseYVT2() throws Exception { var parser = new FipControlParser(); From 1d7a178bbd59085b90fab9492c13ebc8267d78df Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 19:13:28 -0700 Subject: [PATCH 39/98] VolumeNetDecayWasteParser --- .../vdyp/io/parse/VolumeNetDecayWasteParser.java | 14 ++++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 11 ++++++----- .../bc/gov/nrs/vdyp/fip/FipControlParserTest.java | 1 - 3 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java new file mode 100644 index 000000000..3ba7b5b87 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java @@ -0,0 +1,14 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class VolumeNetDecayWasteParser extends SimpleCoefficientParser1{ + + public static final String CONTROL_KEY = "VOLUME_NET_DECAY_WASTE"; + + public VolumeNetDecayWasteParser(Map control) { + super(String.class, 1); + this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.coefficients(6, 9); + } +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 8c350a5d8..1fbe86f2a 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -35,6 +35,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; +import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayWasteParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; @@ -93,7 +94,7 @@ public class FipControlParser { public static final String UTIL_COMP_WS_VOLUME = UtilComponentWSVolumeParser.CONTROL_KEY; public static final String CLOSE_UTIL_VOLUME = CloseUtilVolumeParser.CONTROL_KEY; public static final String VOLUME_NET_DECAY = "VOLUME_NET_DECAY"; - public static final String VOLUME_NET_DECAY_WASTE = "VOLUME_NET_DECAY_WASTE"; + public static final String VOLUME_NET_DECAY_WASTE = VolumeNetDecayWasteParser.CONTROL_KEY; public static final String BREAKAGE = "BREAKAGE"; public static final String VETERAN_LAYER_VOLUME_ADJUST = "VETERAN_LAYER_VOLUME_ADJUST"; public static final String VETERAN_LAYER_DQ = "VETERAN_LAYER_DQ"; @@ -977,8 +978,7 @@ private MatrixMap2 RD_YVD1(InputStream data, Map */ private Map RD_YVW1(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO - + // Uses // @@ -993,8 +993,9 @@ private Map RD_YVW1(InputStream data, Map // Ignore if first segment is blank // Coefficient is 0 indexed - - return null; + + var parser = new VolumeNetDecayWasteParser(control); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index c47bc2a1a..14222893d 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -517,7 +517,6 @@ public void testParseYVT2() throws Exception { ); } - @Disabled // TODO @Test public void testParseYVW1() throws Exception { var parser = new FipControlParser(); From e9fa782eb3a832d659b1d281245d84384fd7ef47 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 19:21:56 -0700 Subject: [PATCH 40/98] BreakageParser --- .../bc/gov/nrs/vdyp/io/parse/BreakageParser.java | 14 ++++++++++++++ .../vdyp/io/parse/TotalStandWholeStemParser.java | 2 +- .../vdyp/io/parse/UtilComponentWSVolumeParser.java | 2 +- .../vdyp/io/parse/VolumeNetDecayWasteParser.java | 6 +++--- .../ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 9 +++++---- .../bc/gov/nrs/vdyp/fip/FipControlParserTest.java | 1 - 6 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java new file mode 100644 index 000000000..e8a4f0bd6 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java @@ -0,0 +1,14 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class BreakageParser extends SimpleCoefficientParser1 { + + public static final String CONTROL_KEY = "BREAKAGE"; + + public BreakageParser(Map control) { + super(Integer.class, 1); + this.groupIndexKey(40); + this.coefficients(6, 9); + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java index 5aa5da60d..213a77299 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java @@ -5,7 +5,7 @@ public class TotalStandWholeStemParser extends SimpleCoefficientParser1 public static final String CONTROL_KEY = "TOTAL_STAND_WHOLE_STEM_VOL"; public TotalStandWholeStemParser() { - super(Integer.class, 1); + super(Integer.class, 0); this.groupIndexKey(80); this.coefficients(9, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java index 7de1c5961..0c4401060 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java @@ -5,7 +5,7 @@ public class UtilComponentWSVolumeParser extends SimpleCoefficientParser2{ +public class VolumeNetDecayWasteParser extends SimpleCoefficientParser1 { public static final String CONTROL_KEY = "VOLUME_NET_DECAY_WASTE"; - + public VolumeNetDecayWasteParser(Map control) { - super(String.class, 1); + super(String.class, 0); this.speciesKey(BaseCoefficientParser.SP0_KEY, control); this.coefficients(6, 9); } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 1fbe86f2a..2df5798f4 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -14,6 +14,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.BaseCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.BreakageParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.CloseUtilVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.CoefficientParser; @@ -978,7 +979,7 @@ private MatrixMap2 RD_YVD1(InputStream data, Map */ private Map RD_YVW1(InputStream data, Map control) throws IOException, ResourceParseException { - + // Uses // @@ -993,7 +994,7 @@ private Map RD_YVW1(InputStream data, Map // Ignore if first segment is blank // Coefficient is 0 indexed - + var parser = new VolumeNetDecayWasteParser(control); return parser.parse(data, control); } @@ -1006,7 +1007,6 @@ private Map RD_YVW1(InputStream data, Map // Example FIPSTART.CTR calls this RD_EMP95 private Map RD_E095(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Uses // PARAMETER (MAXBGRP = 40) @@ -1024,7 +1024,8 @@ private Map RD_E095(InputStream data, Map // Group is 1 indexed // Coefficient is 1 indexed - return null; + var parser = new BreakageParser(control); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 14222893d..b6b15f3fd 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -530,7 +530,6 @@ public void testParseYVW1() throws Exception { ); } - @Disabled // TODO @Test public void testParseE095() throws Exception { var parser = new FipControlParser(); From 6793922f1893f49aa6ca387b9d0bd56e6fde8cd9 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 29 May 2023 22:59:25 -0700 Subject: [PATCH 41/98] VeteranLayerVolumeAdjustParser --- .../io/parse/VeteranLayerVolumeAdjustParser.java | 15 +++++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 14 ++++++-------- .../bc/gov/nrs/vdyp/fip/FipControlParserTest.java | 3 +-- 3 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java new file mode 100644 index 000000000..d99cab7e8 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java @@ -0,0 +1,15 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +public class VeteranLayerVolumeAdjustParser extends SimpleCoefficientParser1 { + + public static final String CONTROL_KEY = "VETERAN_LAYER_VOLUME_ADJUST"; + + public VeteranLayerVolumeAdjustParser(Map control) { + super(String.class, 0); + this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.coefficients(4, 9); + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 2df5798f4..1c6c7e63d 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -5,14 +5,12 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Supplier; -import ca.bc.gov.nrs.vdyp.io.parse.BaseCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.BreakageParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; @@ -35,6 +33,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.io.parse.VeteranLayerVolumeAdjustParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayWasteParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; @@ -46,7 +45,6 @@ import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap2; -import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.MatrixMap3; import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; import ca.bc.gov.nrs.vdyp.model.Region; @@ -94,10 +92,10 @@ public class FipControlParser { public static final String TOTAL_STAND_WHOLE_STEM_VOL = TotalStandWholeStemParser.CONTROL_KEY; public static final String UTIL_COMP_WS_VOLUME = UtilComponentWSVolumeParser.CONTROL_KEY; public static final String CLOSE_UTIL_VOLUME = CloseUtilVolumeParser.CONTROL_KEY; - public static final String VOLUME_NET_DECAY = "VOLUME_NET_DECAY"; + public static final String VOLUME_NET_DECAY = VolumeNetDecayParser.CONTROL_KEY; public static final String VOLUME_NET_DECAY_WASTE = VolumeNetDecayWasteParser.CONTROL_KEY; - public static final String BREAKAGE = "BREAKAGE"; - public static final String VETERAN_LAYER_VOLUME_ADJUST = "VETERAN_LAYER_VOLUME_ADJUST"; + public static final String BREAKAGE = BreakageParser.CONTROL_KEY; + public static final String VETERAN_LAYER_VOLUME_ADJUST = VeteranLayerVolumeAdjustParser.CONTROL_KEY; public static final String VETERAN_LAYER_DQ = "VETERAN_LAYER_DQ"; public static final String VETERAN_BQ = "VETERAN_BQ"; public static final String MINIMA = "MINIMA"; @@ -1036,7 +1034,6 @@ private Map RD_E095(InputStream data, Map // Example FIPSTART.CTR calls this RD_YVET private Map RD_YVVET(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Sets // COMMON /V7COE096/ COE096( 4, 16) @@ -1049,7 +1046,8 @@ private Map RD_YVVET(InputStream data, Map // Coefficient is 1 indexed - return null; + var parser = new VeteranLayerVolumeAdjustParser(control); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index b6b15f3fd..c6461979b 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -542,7 +542,6 @@ FipControlParser.BREAKAGE, allOf(hasEntry(is(10), contains(-0.7153f, 2.0108f, 4. ); } - @Disabled // TODO @Test public void testParseYVVET() throws Exception { var parser = new FipControlParser(); @@ -550,7 +549,7 @@ public void testParseYVVET() throws Exception { assertThat( result, (Matcher) hasSpecificEntry( - FipControlParser.BREAKAGE, + FipControlParser.VETERAN_LAYER_VOLUME_ADJUST, allOf(hasEntry(is("B"), contains(0.10881f, -0.09818f, 0.00048f, -0.00295f))) ) ); From 0418341b37eb912b103d4b6a38a5d78aacc6ab58 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 30 May 2023 00:08:20 -0700 Subject: [PATCH 42/98] VeteranBQParser --- .../gov/nrs/vdyp/io/parse/VeteranBQParser.java | 16 ++++++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 8 ++++---- .../gov/nrs/vdyp/fip/FipControlParserTest.java | 5 ++--- 3 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java new file mode 100644 index 000000000..a863e9bda --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java @@ -0,0 +1,16 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.Region; + +public class VeteranBQParser extends SimpleCoefficientParser2 { + + public static final String CONTROL_KEY = "VETERAN_BQ"; + + public VeteranBQParser(Map control) { + super(1); + this.speciesKey(control).space(1).regionKey().coefficients(3, 9); + } + +} \ No newline at end of file diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 1c6c7e63d..da060b490 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -33,6 +33,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranLayerVolumeAdjustParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayWasteParser; @@ -97,7 +98,7 @@ public class FipControlParser { public static final String BREAKAGE = BreakageParser.CONTROL_KEY; public static final String VETERAN_LAYER_VOLUME_ADJUST = VeteranLayerVolumeAdjustParser.CONTROL_KEY; public static final String VETERAN_LAYER_DQ = "VETERAN_LAYER_DQ"; - public static final String VETERAN_BQ = "VETERAN_BQ"; + public static final String VETERAN_BQ = VeteranBQParser.CONTROL_KEY; public static final String MINIMA = "MINIMA"; public static final String MODIFIER_FILE = "MODIFIER_FILE"; public static final String DEBUG_SWITCHES = "DEBUG_SWITCHES"; @@ -1083,7 +1084,6 @@ private MatrixMap2 RD_YDQV(InputStream data, Map RD_E098(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Sets // C 3 coef BY 16 SP0 BY C/I (2) @@ -1096,8 +1096,8 @@ private MatrixMap2 RD_E098(InputStream data, Map Date: Tue, 30 May 2023 00:52:18 -0700 Subject: [PATCH 43/98] UtilComponentDQParser --- .../io/parse/UtilComponentBaseAreaParser.java | 70 +---------------- .../vdyp/io/parse/UtilComponentDQParser.java | 12 +++ .../vdyp/io/parse/UtilComponentParser.java | 78 +++++++++++++++++++ .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 19 +++++ .../bc/gov/nrs/vdyp/model/BaseAreaCode.java | 8 -- .../UtilComponentBaseAreaParserTest.java | 55 +++++++------ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 12 +-- .../nrs/vdyp/fip/FipControlParserTest.java | 3 +- 8 files changed, 145 insertions(+), 112 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentDQParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java delete mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java index 62ae1ce3c..4e7143d25 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParser.java @@ -1,78 +1,12 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; -import ca.bc.gov.nrs.vdyp.model.Coefficients; -import ca.bc.gov.nrs.vdyp.model.MatrixMap3; -import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; - -public class UtilComponentBaseAreaParser - implements ResourceParser> { +public class UtilComponentBaseAreaParser extends UtilComponentParser { public static final String CONTROL_KEY = "UTIL_COMP_BA"; public static final int NUM_COEFFICIENTS = 2; - public static final String BA_UTIL_CODE_KEY = "baUtilCode"; - public static final String SPECIES_KEY = "species"; - public static final String REGION_KEY = "region"; - public static final String BEC_SCOPE_KEY = "becScope"; - public static final String COEFFICIENT_KEY = "coefficient"; - public UtilComponentBaseAreaParser() { - super(); - this.lineParser = new LineParser() { - - @Override - public boolean isStopLine(String line) { - return line.startsWith(" "); - } - - }.value(4, BA_UTIL_CODE_KEY, ValueParser.enumParser(BaseAreaCode.class)).space(1) - .value(2, SPECIES_KEY, String::strip).space(1).value(4, BEC_SCOPE_KEY, String::strip) - .multiValue(NUM_COEFFICIENTS, 10, COEFFICIENT_KEY, ValueParser.FLOAT); - } - - LineParser lineParser; - - @Override - public MatrixMap3 parse(InputStream is, Map control) - throws IOException, ResourceParseException { - final var becIndices = BecDefinitionParser.getBecAliases(control); - final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); - final var bauIndices = Set.of(BaseAreaCode.values()); - - MatrixMap3 result = new MatrixMap3Impl( - bauIndices, speciesIndicies, becIndices - ); - lineParser.parse(is, result, (v, r) -> { - var bau = (BaseAreaCode) v.get(BA_UTIL_CODE_KEY); - var sp0 = (String) v.get(SPECIES_KEY); - var scope = (String) v.get(BEC_SCOPE_KEY); - - var becs = BecDefinitionParser.getBecsByScope(control, scope); - if (becs.isEmpty()) { - throw new ValueParseException(scope, "Could not find any BECs for scope " + scope); - } - - @SuppressWarnings("unchecked") - var coefficients = (List) v.get(COEFFICIENT_KEY); - SP0DefinitionParser.checkSpecies(speciesIndicies, sp0); - - if (coefficients.size() < NUM_COEFFICIENTS) { - throw new ValueParseException(null, "Expected " + NUM_COEFFICIENTS + " coefficients"); - } - for (var bec : becs) { - r.put(bau, sp0, bec.getAlias(), new Coefficients(coefficients, 1)); - } - - return r; - }); - return result; + super(NUM_COEFFICIENTS, 1, "BA07", "BA12", "BA17", "BA22"); } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentDQParser.java new file mode 100644 index 000000000..dffc1ab55 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentDQParser.java @@ -0,0 +1,12 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +public class UtilComponentDQParser extends UtilComponentParser { + public static final String CONTROL_KEY = "UTIL_COMP_DQ"; + + public static final int NUM_COEFFICIENTS = 4; + + public UtilComponentDQParser() { + super(NUM_COEFFICIENTS, 9, "07.5", "12.5", "17.5", "22.5"); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java new file mode 100644 index 000000000..44057d1c9 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java @@ -0,0 +1,78 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; + +public class UtilComponentParser implements ResourceParser> { + public static final String CONTROL_KEY_BA = "UTIL_COMP_BA"; + public static final String CONTROL_KEY_DQ = "UTIL_COMP_DQ"; + // "07.5", "12.5", "17.5", "22.5" + public final int numCoefficients; + + public static final String UC_KEY = "uc"; + public static final String SPECIES_KEY = "species"; + public static final String REGION_KEY = "region"; + public static final String BEC_SCOPE_KEY = "becScope"; + public static final String COEFFICIENT_KEY = "coefficient"; + + public UtilComponentParser(int numCoefficients, int gap, String... ucCodes) { + super(); + this.numCoefficients = numCoefficients; + this.lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + }.value(4, UC_KEY, ValueParser.indexParser("UC", 1, ucCodes)).space(gap).value(2, SPECIES_KEY, String::strip) + .space(1).value(4, BEC_SCOPE_KEY, String::strip) + .multiValue(numCoefficients, 10, COEFFICIENT_KEY, ValueParser.FLOAT); + } + + LineParser lineParser; + + @Override + public MatrixMap3 parse(InputStream is, Map control) + throws IOException, ResourceParseException { + final var becIndices = BecDefinitionParser.getBecAliases(control); + final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var ucIndices = Arrays.asList(1, 2, 3, 4); + + MatrixMap3 result = new MatrixMap3Impl( + ucIndices, speciesIndicies, becIndices + ); + lineParser.parse(is, result, (v, r) -> { + var uc = (Integer) v.get(UC_KEY); + var sp0 = (String) v.get(SPECIES_KEY); + var scope = (String) v.get(BEC_SCOPE_KEY); + + var becs = BecDefinitionParser.getBecsByScope(control, scope); + if (becs.isEmpty()) { + throw new ValueParseException(scope, "Could not find any BECs for scope " + scope); + } + + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENT_KEY); + SP0DefinitionParser.checkSpecies(speciesIndicies, sp0); + + if (coefficients.size() < numCoefficients) { + throw new ValueParseException(null, "Expected " + numCoefficients + " coefficients"); + } + for (var bec : becs) { + r.put(uc, sp0, bec.getAlias(), new Coefficients(coefficients, 1)); + } + + return r; + }); + return result; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index cff8940aa..7317a498b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -1,6 +1,8 @@ package ca.bc.gov.nrs.vdyp.io.parse; +import java.lang.reflect.Array; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.List; @@ -69,6 +71,23 @@ public static > ValueParser enumParser(Class klazz) { }; } + /** + * Parse as index into a sequence of values + */ + // If an Enum is overkill + public static ValueParser indexParser(String sequenceName, int indexFrom, String... values) { + return s -> { + String stripped = s.strip(); + int index = Arrays.asList(values).indexOf(stripped); + if (index < 0) { + throw new ValueParseException( + stripped, String.format("\"%s\" is not a valid %s", stripped, sequenceName) + ); + } + return indexFrom + index; + }; + } + /** * Parser for long integers */ diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java deleted file mode 100644 index b379033f9..000000000 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BaseAreaCode.java +++ /dev/null @@ -1,8 +0,0 @@ -package ca.bc.gov.nrs.vdyp.model; - -public enum BaseAreaCode { - // Also known as "UC" or "IU" - // TODO possibly rename something clearer - - BA12, BA17, BA22; -} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java index 1c5b24a0b..1c55b7c6f 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java @@ -16,7 +16,6 @@ import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; import ca.bc.gov.nrs.vdyp.test.TestUtils; public class UtilComponentBaseAreaParserTest { @@ -35,17 +34,17 @@ public void testParseSingleBec() throws Exception { var result = parser.parse(is, controlMap); - assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B1")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B2")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B3")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B4")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), 2, "S1", "B1")); + assertThat(result, mmHasEntry(notPresent(), 2, "S1", "B2")); + assertThat(result, mmHasEntry(notPresent(), 2, "S1", "B3")); + assertThat(result, mmHasEntry(notPresent(), 2, "S1", "B4")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B1")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B2")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B3")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B4")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B1")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B2")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B3")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B4")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA17, "S1", "B1")); + assertThat(result, mmHasEntry(notPresent(), 3, "S1", "B1")); } @Test @@ -62,17 +61,17 @@ public void testParseSingleRegion() throws Exception { var result = parser.parse(is, controlMap); - assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B1")); - assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B3")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B2")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S1", "B4")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), 2, "S1", "B1")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), 2, "S1", "B3")); + assertThat(result, mmHasEntry(notPresent(), 2, "S1", "B2")); + assertThat(result, mmHasEntry(notPresent(), 2, "S1", "B4")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B1")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B2")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B3")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B4")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B1")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B2")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B3")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B4")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA17, "S1", "B1")); + assertThat(result, mmHasEntry(notPresent(), 3, "S1", "B1")); } @Test @@ -89,17 +88,17 @@ public void testParseAllBecs() throws Exception { var result = parser.parse(is, controlMap); - assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B1")); - assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B2")); - assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B3")); - assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), BaseAreaCode.BA12, "S1", "B4")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), 2, "S1", "B1")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), 2, "S1", "B2")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), 2, "S1", "B3")); + assertThat(result, mmHasEntry(present(contains(-23.22790f, 12.60472f)), 2, "S1", "B4")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B1")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B2")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B3")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA12, "S2", "B4")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B1")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B2")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B3")); + assertThat(result, mmHasEntry(notPresent(), 2, "S2", "B4")); - assertThat(result, mmHasEntry(notPresent(), BaseAreaCode.BA17, "S1", "B1")); + assertThat(result, mmHasEntry(notPresent(), 3, "S1", "B1")); } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index da060b490..5bab0a16f 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -31,6 +31,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.TotalStandWholeStemParser; import ca.bc.gov.nrs.vdyp.io.parse.UpperCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentBaseAreaParser; +import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentDQParser; import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; @@ -42,7 +43,6 @@ import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; -import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap2; @@ -84,7 +84,7 @@ public class FipControlParser { public static final String BY_SPECIES_DQ = BySpeciesDqCoefficientParser.CONTROL_KEY; public static final String SPECIES_COMPONENT_SIZE_LIMIT = ComponentSizeParser.CONTROL_KEY; public static final String UTIL_COMP_BA = UtilComponentBaseAreaParser.CONTROL_KEY; - public static final String UTIL_COMP_DQ = "UTIL_COMP_DQ"; + public static final String UTIL_COMP_DQ = UtilComponentDQParser.CONTROL_KEY; public static final String SMALL_COMP_PROBABILITY = SmallComponentProbabilityParser.CONTROL_KEY; public static final String SMALL_COMP_BA = SmallComponentBaseAreaParser.CONTROL_KEY; public static final String SMALL_COMP_DQ = SmallComponentDQParser.CONTROL_KEY; @@ -686,8 +686,8 @@ private MatrixMap2 RD_E061(InputStream data, Map - RD_UBA1(InputStream data, Map control) throws IOException, ResourceParseException { + private MatrixMap3 RD_UBA1(InputStream data, Map control) + throws IOException, ResourceParseException { // Uses // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) @@ -715,7 +715,6 @@ private MatrixMap2 RD_E061(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Uses // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) @@ -734,7 +733,8 @@ private Object RD_UDQ1(InputStream data, Map control) throws IOE // If BECSCOPE is empty, apply to all BECs, if it's I or C, apply to BECs in // that region, otherwise only the one BEC. - return null; + var parser = new UtilComponentDQParser(); + return parser.parse(data, control); } /** diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 283928a73..2574e2a61 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -31,7 +31,6 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParserTest; -import ca.bc.gov.nrs.vdyp.model.BaseAreaCode; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; @@ -389,7 +388,7 @@ public void testParseUBA1() throws Exception { result, (Matcher) hasSpecificEntry( FipControlParser.UTIL_COMP_BA, - allOf(mmHasEntry(present(contains(-26.68771f, 14.38811f)), BaseAreaCode.BA12, "AT", "ICH")) + allOf(mmHasEntry(present(contains(-26.68771f, 14.38811f)), 2, "AT", "ICH")) ) ); } From e0e03334aa2d19d4782790c91d6a6399abca2e71 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 30 May 2023 10:06:52 -0700 Subject: [PATCH 44/98] VeteranDQParser --- .../nrs/vdyp/io/parse/VeteranDQParser.java | 71 ++++++++++++++ .../vdyp/io/parse/VeteranDQParserTest.java | 92 +++++++++++++++++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 5 +- .../nrs/vdyp/fip/FipControlParserTest.java | 1 - 4 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java new file mode 100644 index 000000000..9fa5d9ae7 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java @@ -0,0 +1,71 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; +import ca.bc.gov.nrs.vdyp.model.Region; + +public class VeteranDQParser implements ResourceParser> { + public static final String CONTROL_KEY = "VETERAN_LAYER_DQ"; + + public final static int numCoefficients = 3; + + public static final String SPECIES_KEY = "species"; + public static final String REGION_KEY = "region"; + public static final String COEFFICIENT_KEY = "coefficient"; + + public VeteranDQParser() { + super(); + this.lineParser = new LineParser() { + + @Override + public boolean isStopLine(String line) { + return line.startsWith(" "); + } + + }.value(2, SPECIES_KEY, String::strip).space(1).value(1, REGION_KEY, ValueParser.optional(ValueParser.REGION)) + .multiValue(numCoefficients, 10, COEFFICIENT_KEY, ValueParser.FLOAT); + } + + LineParser lineParser; + + @Override + public MatrixMap2 parse(InputStream is, Map control) + throws IOException, ResourceParseException { + final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var regionIndicies = Arrays.asList(Region.values()); + + MatrixMap2 result = new MatrixMap2Impl( + speciesIndicies, regionIndicies + ); + lineParser.parse(is, result, (v, r) -> { + var sp0 = (String) v.get(SPECIES_KEY); + @SuppressWarnings("unchecked") + var regions = ((Optional) v.get(REGION_KEY)).map(Collections::singletonList).orElse(regionIndicies); + + @SuppressWarnings("unchecked") + var coefficients = (List) v.get(COEFFICIENT_KEY); + SP0DefinitionParser.checkSpecies(speciesIndicies, sp0); + + if (coefficients.size() < numCoefficients) { + throw new ValueParseException(null, "Expected " + numCoefficients + " coefficients"); + } + + for (var region : regions) { + r.put(sp0, region, new Coefficients(coefficients, 1)); + } + + return r; + }); + return result; + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java new file mode 100644 index 000000000..78565cbb6 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java @@ -0,0 +1,92 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.causedBy; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class VeteranDQParserTest { + + @Test + public void testParseSingleRegion() throws Exception { + + var parser = new VeteranDQParser(); + + var is = TestUtils.makeStream("S1 C 22.500 0.24855 1.46089"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(contains(22.500f, 0.24855f, 1.46089f)), "S1", Region.COASTAL)); + assertThat(result, mmHasEntry(notPresent(), "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(notPresent(), "S2", Region.COASTAL)); + } + + @Test + public void testParseAllRegions() throws Exception { + + var parser = new VeteranDQParser(); + + var is = TestUtils.makeStream("S1 22.500 0.24855 1.46089"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + + var result = parser.parse(is, controlMap); + + assertThat(result, mmHasEntry(present(contains(22.500f, 0.24855f, 1.46089f)), "S1", Region.COASTAL)); + assertThat(result, mmHasEntry(present(contains(22.500f, 0.24855f, 1.46089f)), "S1", Region.INTERIOR)); + assertThat(result, mmHasEntry(notPresent(), "S2", Region.COASTAL)); + } + + @Test + public void testParseBadSpecies() throws Exception { + + var parser = new VeteranDQParser(); + + var is = TestUtils.makeStream("SX C 22.500 0.24855 1.46089"); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThat(ex, causedBy(hasProperty("value", is("SX")))); + } + + @Test + public void testParseMissingCoefficient() throws Exception { + + var parser = new VeteranDQParser(); + + var is = TestUtils.makeStream("S1 C 22.500 0.24855 "); + + Map controlMap = new HashMap<>(); + + SP0DefinitionParserTest.populateControlMap(controlMap); + BecDefinitionParserTest.populateControlMap(controlMap); + + var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThat(ex, causedBy(hasProperty("value", nullValue()))); // TODO Do this better + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 5bab0a16f..bd01aa678 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -35,6 +35,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.UtilComponentWSVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; +import ca.bc.gov.nrs.vdyp.io.parse.VeteranDQParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranLayerVolumeAdjustParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayWasteParser; @@ -1058,7 +1059,6 @@ private Map RD_YVVET(InputStream data, Map */ private MatrixMap2 RD_YDQV(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO // Sets // C 3 coef BY 16 SP0 BY C/I (2) @@ -1074,7 +1074,8 @@ private MatrixMap2 RD_YDQV(InputStream data, Map Date: Tue, 30 May 2023 13:08:27 -0700 Subject: [PATCH 45/98] Refactor to allow for control map access in Line/Value parsers --- .../vdyp/io/parse/BaseCoefficientParser.java | 2 +- .../vdyp/io/parse/BecDefinitionParser.java | 2 +- .../parse/BySpeciesDqCoefficientParser.java | 2 +- .../nrs/vdyp/io/parse/CoefficientParser.java | 2 +- .../nrs/vdyp/io/parse/ControlFileParser.java | 2 +- .../vdyp/io/parse/EquationGroupParser.java | 2 +- .../vdyp/io/parse/EquationModifierParser.java | 2 +- .../vdyp/io/parse/HLCoefficientParser.java | 2 +- .../parse/HLNonprimaryCoefficientParser.java | 2 +- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 37 +++++++++-------- .../vdyp/io/parse/SP0DefinitionParser.java | 2 +- .../io/parse/SiteCurveAgeMaximumParser.java | 2 +- .../nrs/vdyp/io/parse/SiteCurveParser.java | 2 +- .../io/parse/StockingClassFactorParser.java | 2 +- .../vdyp/io/parse/UpperCoefficientParser.java | 2 +- .../vdyp/io/parse/UtilComponentParser.java | 2 +- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 11 +++-- .../nrs/vdyp/io/parse/VeteranDQParser.java | 2 +- .../gov/nrs/vdyp/io/parse/LineParserTest.java | 41 ++++++++++--------- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 7 +--- 20 files changed, 68 insertions(+), 60 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index bf076451c..3704e1821 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -126,7 +126,7 @@ public M parse(InputStream is, Map control) throws IOException, r.putM(coe, key); return r; - }); + }, control); return result; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index d2da81d60..39708f321 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -42,7 +42,7 @@ public Map parse(InputStream is, Map cont var defn = new BecDefinition(alias, region, name); r.put(alias, defn); return r; - }); + }, control); return Collections.unmodifiableMap(result); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java index 51994af23..19a385b8c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java @@ -69,7 +69,7 @@ public List parse(InputStream is, Map control) r.set(index, new Coefficients(coefficients, 1)); return r; - }); + }, control); return result; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java index 4d6835aae..d313860d3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -85,7 +85,7 @@ public MatrixMap3 parse(InputStream is, Map parse(InputStream input, Map control) r.put(key, value); return r; - }); + }, Collections.emptyMap()); for (var e : defaultValueGenerators.entrySet()) { result.putIfAbsent(e.getKey(), e.getValue().get()); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index 0c22fa3ea..c27fa631a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -69,7 +69,7 @@ public Map> parse(InputStream is, Map new HashMap<>()).put(becAlias, vgrpId); return r; - }); + }, control); for (var e : result.entrySet()) { result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java index 003ceb4be..c394fec61 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java @@ -37,7 +37,7 @@ public Map> parse(InputStream is, Map new HashMap<>()).put(itg, reassignedId); return r; - }); + }, control); for (var e : result.entrySet()) { result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java index ba8998c0f..8657be734 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java @@ -74,7 +74,7 @@ public MatrixMap3 parse(InputStream is, Map map) throws ValueParseException; + public abstract void parseIntoMap(String toParse, Map control, Map map) + throws ValueParseException; } static private class LineParserNullSegment extends LineParserSegment { @@ -45,7 +46,7 @@ public LineParserNullSegment(int length) { } @Override - public void parseIntoMap(String toParse, Map map) { + public void parseIntoMap(String toParse, Map control, Map map) { // do nothing } } @@ -53,15 +54,16 @@ public void parseIntoMap(String toParse, Map map) { static abstract class LineParserValueSegment extends LineParserSegment { String name; - abstract T parse(String value) throws ValueParseException; + abstract T parse(String value, Map control) throws ValueParseException; public String getName() { return name; } @Override - public void parseIntoMap(String toParse, Map map) throws ValueParseException { - var value = this.parse(toParse); + public void parseIntoMap(String toParse, Map control, Map map) + throws ValueParseException { + var value = this.parse(toParse, control); map.put(this.getName(), value); } @@ -174,8 +176,8 @@ private LineParser doValue(int length, String name, ValueParser parser) { segments.add(new LineParserValueSegment(length, name) { @Override - T parse(String value) throws ValueParseException { - return parser.parse(value); + T parse(String value, Map control) throws ValueParseException { + return parser.parse(value, control); } }); @@ -212,12 +214,13 @@ private List segmentize(String line) { * @return * @throws ValueParseException */ - public Map parseLine(String line) throws ValueParseException { + public Map parseLine(String line, Map control) throws ValueParseException { var segments = segmentize(line); - return parse(segments); + return parse(segments, control); } - private Map parse(List segmentStrings) throws ValueParseException { + private Map parse(List segmentStrings, Map control) + throws ValueParseException { if (segmentStrings.size() != segments.size()) { throw new IllegalStateException("segment strings and segment handlers must have the same size"); } @@ -228,7 +231,7 @@ private Map parse(List segmentStrings) throws ValueParse var segmentHandler = segments.get(i); var segmentString = segmentStrings.get(i); if (segmentString != null) { - segmentHandler.parseIntoMap(segmentString, result); + segmentHandler.parseIntoMap(segmentString, control, result); } } @@ -249,8 +252,9 @@ private Map parse(List segmentStrings) throws ValueParse * @throws ResourceParseLineException if the content of the stream could not be * parsed */ - public T parse(InputStream is, T result, ParseEntryHandler, T> addToResult) - throws IOException, ResourceParseLineException { + public T parse( + InputStream is, T result, ParseEntryHandler, T> addToResult, Map control + ) throws IOException, ResourceParseLineException { var reader = new BufferedReader(new InputStreamReader(is, charset)); String line; int lineNumber = 0; @@ -270,7 +274,7 @@ public T parse(InputStream is, T result, ParseEntryHandler T parse(InputStream is, T result, ParseEntryHandler> parse(InputStream is) throws IOException, ResourceParseLineException { + public List> parse(InputStream is, Map control) + throws IOException, ResourceParseLineException { var result = new ArrayList>(); result = this.parse(is, result, (v, r) -> { r.add(v); return r; - }); + }, control); return result; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index 716ee315a..381bac681 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -73,7 +73,7 @@ public List parse(InputStream is, Map control) r[p - 1] = defn; return r; - }); + }, control); return Collections.unmodifiableList(Arrays.asList(result)); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java index 311bc9441..9068df43c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java @@ -82,7 +82,7 @@ public Map parse(InputStream is, Map parse(InputStream is, Map control) r.put(species, new SiteCurve(value1, value2)); return r; - }); + }, control); final var sp0List = SP0DefinitionParser.getSpeciesAliases(control); var missing = ExpectationDifference.difference(result.keySet(), sp0List).getMissing(); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java index b735437b8..17eca1fcb 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java @@ -68,7 +68,7 @@ public Map> parse(InputStream is, Ma r.computeIfAbsent(stk, (c) -> new HashMap()).put(region, factorEntry); return r; - }); + }, control); for (var e : result.entrySet()) { result.put(e.getKey(), Collections.unmodifiableMap(e.getValue())); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java index afe63767e..0f2af6ea3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java @@ -64,7 +64,7 @@ public MatrixMap3 parse(InputStream is, Map parse(InputStream is, M } return r; - }); + }, control); return result; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 7317a498b..7ffb2e010 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -1,11 +1,10 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Enumeration; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.function.Function; @@ -19,7 +18,7 @@ * @param */ @FunctionalInterface -public interface ValueParser { +public interface ValueParser extends ControlledValueParser { /** * Parse a string to a value * @@ -29,6 +28,12 @@ public interface ValueParser { */ T parse(String string) throws ValueParseException; + @Override + default T parse(String string, Map control) throws ValueParseException { + // Ignore the control map + return this.parse(string); + } + public static interface JavaNumberParser { U parse(String s) throws NumberFormatException; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java index 9fa5d9ae7..9db0ed16b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java @@ -64,7 +64,7 @@ public MatrixMap2 parse(InputStream is, Map parser.parseLine(" X 0.5 ")); + var ex1 = assertThrows(ValueParseException.class, () -> parser.parseLine(" X 0.5 ", Collections.emptyMap())); assertThat(ex1, hasProperty("value", is("X"))); assertThat(ex1, hasProperty("cause", isA(NumberFormatException.class))); - var ex2 = assertThrows(ValueParseException.class, () -> parser.parseLine(" 4 0.x ")); + var ex2 = assertThrows(ValueParseException.class, () -> parser.parseLine(" 4 0.x ", Collections.emptyMap())); assertThat(ex2, hasProperty("value", is("0.x"))); assertThat(ex2, hasProperty("cause", isA(NumberFormatException.class))); @@ -95,7 +96,7 @@ public void testValueParser() throws Exception { parser.value(4, "part1", (s) -> Integer.valueOf(s.strip()) + 1).space(1) .value("part2", (s) -> Float.valueOf(s.strip()) + 1); - var result1 = parser.parseLine(" 4 0.5 "); + var result1 = parser.parseLine(" 4 0.5 ", Collections.emptyMap()); assertThat(result1, hasEntry("part1", 5)); assertThat(result1, hasEntry("part2", 1.5f)); @@ -109,7 +110,7 @@ public void testValueParserError() throws Exception { throw new ValueParseException(s, "Testing"); }).space(1).value(4, "part2", (s) -> Float.valueOf(s.strip()) + 1); - var ex1 = assertThrows(ValueParseException.class, () -> parser.parseLine(" X 0.5 ")); + var ex1 = assertThrows(ValueParseException.class, () -> parser.parseLine(" X 0.5 ", Collections.emptyMap())); assertThat(ex1, hasProperty("value", is(" X "))); assertThat(ex1, hasProperty("message", is("Testing"))); @@ -121,7 +122,8 @@ public void testUnbounded() throws Exception { parser.string(4, "part1").string("part2"); var result1 = parser.parseLine( - "123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 " + "123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ", + Collections.emptyMap() ); assertThat(result1, hasEntry("part1", "123 ")); @@ -141,7 +143,8 @@ public void testStripped() throws Exception { parser.strippedString(4, "part1").strippedString("part2"); var result1 = parser.parseLine( - "123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 " + "123 67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ", + Collections.emptyMap() ); assertThat(result1, hasEntry("part1", "123")); @@ -161,7 +164,7 @@ public void testMultiValue() throws Exception { var parser = new LineParser(); parser.multiValue(4, 3, "test", ValueParser.INTEGER); - var result1 = parser.parseLine(" 02 04 06 08"); + var result1 = parser.parseLine(" 02 04 06 08", Collections.emptyMap()); assertThat(result1, hasEntry(is("test"), (Matcher) contains(2, 4, 6, 8))); } @@ -174,7 +177,7 @@ public void testMultiLine() throws Exception { List> result = new ArrayList<>(); try (var is = new ByteArrayInputStream("0042 Value1\r\n0043 Value2".getBytes());) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat( @@ -199,7 +202,7 @@ public void testMultiLineException() throws Exception { try (var is = new ByteArrayInputStream("0042 Value1\r\n004x Value2".getBytes());) { - var ex1 = assertThrows(ResourceParseLineException.class, () -> parser.parse(is)); + var ex1 = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, Collections.emptyMap())); assertThat(ex1, hasProperty("line", is(2))); // Line numbers indexed from 1 so the error is line 2 assertThat(ex1, hasProperty("cause", isA(ValueParseException.class))); @@ -224,7 +227,7 @@ public boolean isStopEntry(Map entry) { List> result = new ArrayList<>(); try (var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes());) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); @@ -245,7 +248,7 @@ public boolean isStopLine(String line) { List> result = new ArrayList<>(); try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); @@ -266,7 +269,7 @@ public boolean isStopSegment(List segments) { List> result = new ArrayList<>(); try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); @@ -287,7 +290,7 @@ public boolean isIgnoredEntry(Map entry) { List> result = new ArrayList<>(); try (var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes());) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat( @@ -314,7 +317,7 @@ public boolean isIgnoredLine(String line) { List> result = new ArrayList<>(); try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat( @@ -341,7 +344,7 @@ public boolean isIgnoredSegment(List segments) { List> result = new ArrayList<>(); try (var is = new ByteArrayInputStream("0042 Value1\r\n0000X\r\n0043 Value2".getBytes());) { - result = parser.parse(is); + result = parser.parse(is, Collections.emptyMap()); } assertThat( diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index bd01aa678..6de761e53 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -11,6 +11,7 @@ import java.util.Optional; import java.util.function.Supplier; +import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.BreakageParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; @@ -1133,10 +1134,4 @@ private Object RD_E108(InputStream data, Map control) throws IOE throw new UnsupportedOperationException(); } - static interface FileResolver { - InputStream resolve(String filename) throws IOException; - - String toString(String filename) throws IOException; - } - } From 931f9fb0fe5757efc499a621dbef7db3e103152f Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 30 May 2023 16:07:51 -0700 Subject: [PATCH 46/98] Working --- .../ca/bc/gov/nrs/vdyp/io/FileResolver.java | 10 ++++ .../vdyp/io/parse/BaseCoefficientParser.java | 2 +- .../vdyp/io/parse/ControlMapSubResource.java | 47 +++++++++++++++++++ .../vdyp/io/parse/ControlledValueParser.java | 19 ++++++++ .../io/parse/ResourceControlMapModifier.java | 17 +++++++ .../{parse => write}/ControlFileWriter.java | 4 +- .../ControlFileWriterTest.java | 4 +- 7 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileResolver.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResource.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java rename vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/{parse => write}/ControlFileWriter.java (97%) rename vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/{parse => write}/ControlFileWriterTest.java (98%) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileResolver.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileResolver.java new file mode 100644 index 000000000..7ba6a629d --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileResolver.java @@ -0,0 +1,10 @@ +package ca.bc.gov.nrs.vdyp.io; + +import java.io.IOException; +import java.io.InputStream; + +public interface FileResolver { + InputStream resolve(String filename) throws IOException; + + String toString(String filename) throws IOException; +} \ No newline at end of file diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index 3704e1821..17901edb2 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -89,7 +89,7 @@ public BaseCoefficientParser groupIndexKey(int maxGroups) { ); } - public BaseCoefficientParser speciesKey(String name, Map controlMap) { + public BaseCoefficientParser speciesKey(String name) { var range = SP0DefinitionParser.getSpeciesAliases(controlMap); return key(2, name, String::strip, range, "%s is not a valid species"); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResource.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResource.java new file mode 100644 index 000000000..59fad8d5a --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResource.java @@ -0,0 +1,47 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import ca.bc.gov.nrs.vdyp.io.FileResolver; + +/** + * A resource that can be loaded as a sub-resource of a control file. + * + * @author Kevin Smith, Vivid Solutions + * + * @param + */ +public interface ControlMapSubResource extends ResourceControlMapModifier, ResourceParser { + + /** + * The key for this resource's entry in the control map + * + * @return + */ + String getControlKey(); + + @Override + default void modify(Map control, InputStream data) throws IOException, ResourceParseException { + var result = this.parse(data, control); + + control.put(getControlKey(), result); + } + + /** + * Replace the entry in the control map containing the filename for a resource + * with the parsed resource + * + * @param control + * @param fileResolver + * @throws IOException + * @throws ResourceParseException + */ + default void modify(Map control, FileResolver fileResolver) + throws IOException, ResourceParseException { + var filename = (String) control.get(getControlKey()); + try (InputStream data = fileResolver.resolve(filename)) { + modify(control, data); + } + } +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java new file mode 100644 index 000000000..411b5080b --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java @@ -0,0 +1,19 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Map; + +@FunctionalInterface +public interface ControlledValueParser { + + /** + * Parse a string to a value usinga control map for context. Should not attempt + * to modify the map. + * + * @param s + * @param control + * @return + * @throws ValueParseException + */ + T parse(String s, Map control) throws ValueParseException; + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java new file mode 100644 index 000000000..21ad6ff44 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java @@ -0,0 +1,17 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +/** + * Modifies the control map based on a resource + * + * @author Kevin Smith, Vivid Solutions + * + */ +public interface ResourceControlMapModifier { + + void modify(Map control, InputStream data) throws ResourceParseException, IOException; + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriter.java similarity index 97% rename from vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java rename to vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriter.java index 82979cff6..f5b874fd2 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriter.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriter.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.vdyp.io.parse; +package ca.bc.gov.nrs.vdyp.io.write; import java.io.Closeable; import java.io.IOException; @@ -7,6 +7,8 @@ import java.nio.charset.StandardCharsets; import java.util.regex.Pattern; +import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; + /** * Writer for control files * diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriterTest.java similarity index 98% rename from vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java rename to vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriterTest.java index f463e77ec..236d0106e 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileWriterTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriterTest.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.vdyp.io.parse; +package ca.bc.gov.nrs.vdyp.io.write; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @@ -8,6 +8,8 @@ import org.junit.jupiter.api.Test; +import ca.bc.gov.nrs.vdyp.io.write.ControlFileWriter; + public class ControlFileWriterTest { @Test From bf359ef30b6d9b15e812bbc43ee3d0342d90c782 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 31 May 2023 18:29:05 -0700 Subject: [PATCH 47/98] Refactor to allow parsers access to the control map --- .../vdyp/io/parse/BaseCoefficientParser.java | 48 +++++++++++---- .../vdyp/io/parse/BecDefinitionParser.java | 6 ++ .../nrs/vdyp/io/parse/CoefficientParser.java | 2 +- .../vdyp/io/parse/ComponentSizeParser.java | 2 +- .../nrs/vdyp/io/parse/ControlFileParser.java | 12 ++-- .../vdyp/io/parse/ControlledValueParser.java | 59 ++++++++++++++++++- .../vdyp/io/parse/HLCoefficientParser.java | 2 +- .../parse/HLNonprimaryCoefficientParser.java | 2 +- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 14 ++--- .../vdyp/io/parse/SP0DefinitionParser.java | 4 +- .../io/parse/SimpleCoefficientParser1.java | 9 ++- .../io/parse/SiteCurveAgeMaximumParser.java | 2 +- .../parse/SmallComponentBaseAreaParser.java | 2 +- .../vdyp/io/parse/SmallComponentDQParser.java | 2 +- .../vdyp/io/parse/SmallComponentHLParser.java | 2 +- .../SmallComponentProbabilityParser.java | 2 +- .../parse/SmallComponentWSVolumeParser.java | 2 +- .../vdyp/io/parse/UpperCoefficientParser.java | 2 +- .../vdyp/io/parse/UtilComponentParser.java | 4 +- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 30 +++++----- .../nrs/vdyp/io/parse/VeteranBQParser.java | 2 +- .../nrs/vdyp/io/parse/VeteranDQParser.java | 3 +- .../parse/VeteranLayerVolumeAdjustParser.java | 2 +- .../io/parse/VolumeNetDecayWasteParser.java | 2 +- .../vdyp/io/parse/ControlFileParserTest.java | 4 +- .../gov/nrs/vdyp/io/parse/LineParserTest.java | 8 +-- .../vdyp/io/parse/SiteCurveParserTest.java | 3 - 27 files changed, 163 insertions(+), 69 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index 17901edb2..9f842bce0 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -33,7 +34,7 @@ public abstract class BaseCoefficientParser metaKeys = new ArrayList<>(); - List> keyRanges = new ArrayList<>(); + List, Collection>> keyRanges = new ArrayList<>(); private int expectedKeys; public BaseCoefficientParser(int expectedKeys) { @@ -53,15 +54,33 @@ public BaseCoefficientParser() { this(0); } - public BaseCoefficientParser - key(int length, String name, ValueParser parser, Collection range, String errorTemplate) { + /** + * Add a key for the multimap + * + * @param type of the key + * @param length length of the key in the file + * @param name name of the key + * @param parser Parser for the + * @param range Function that returns the set of values based on the + * control map + * @param errorTemplate Error message if the parsed value is not in the given + * range, it will be formatted (see {@link String.format}) + * with the erroneous value as a parameter. + * @return + */ + public BaseCoefficientParser key( + int length, String name, ControlledValueParser parser, + Function, Collection> range, String errorTemplate + ) { if (expectedKeys > 0 && metaKeys.size() == expectedKeys) { throw new IllegalStateException( "Expected " + expectedKeys + " keys but " + name + " was key " + expectedKeys + 1 ); } - var validParser = ValueParser.validate( - parser, (v) -> range.contains(v) ? Optional.empty() : Optional.of(String.format(errorTemplate, v)) + var validParser = ControlledValueParser.validate( + parser, + (v, control) -> range.apply(control).contains(v) ? Optional.empty() + : Optional.of(String.format(errorTemplate, v)) ); lineParser.value(length, name, validParser); metaKeys.add(name); @@ -69,6 +88,11 @@ public BaseCoefficientParser() { return this; } + public BaseCoefficientParser + key(int length, String name, ControlledValueParser parser, Collection range, String errorTemplate) { + return key(length, name, parser, (c) -> range, errorTemplate); + } + public BaseCoefficientParser regionKey() { var regions = Arrays.asList(Region.values()); return key(1, REGION_KEY, ValueParser.REGION, regions, "%s is not a valid region"); @@ -90,12 +114,14 @@ public BaseCoefficientParser groupIndexKey(int maxGroups) { } public BaseCoefficientParser speciesKey(String name) { - var range = SP0DefinitionParser.getSpeciesAliases(controlMap); - return key(2, name, String::strip, range, "%s is not a valid species"); + return key( + 2, name, ControlledValueParser.SPECIES, SP0DefinitionParser::getSpeciesAliases, + "%s is not a valid species" + ); } - public BaseCoefficientParser speciesKey(Map controlMap) { - return speciesKey(SP0_KEY, controlMap); + public BaseCoefficientParser speciesKey() { + return speciesKey(SP0_KEY); } public BaseCoefficientParser space(int length) { @@ -116,7 +142,9 @@ public M parse(InputStream is, Map control) throws IOException, if (expectedKeys > 0 && metaKeys.size() != expectedKeys) { throw new IllegalStateException("Expected " + expectedKeys + " keys but there were " + metaKeys.size()); } - M result = createMap(keyRanges); + keyRanges.stream().map(x -> x.apply(control)).toList(); + @SuppressWarnings({ "unchecked", "rawtypes" }) + M result = (M) createMap((List) (keyRanges.stream().map(x -> x.apply(control)).toList())); lineParser.parse(is, result, (v, r) -> { var key = metaKeys.stream().map(v::get).collect(Collectors.toList()).toArray(Object[]::new); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index 39708f321..1f2410427 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -93,4 +93,10 @@ public static Collection getBecsByScope(Map contr return Region.fromAlias(scope).map(region -> getBecsByRegion(control, region)) .orElseGet(() -> Utils.singletonOrEmpty(getBecs(control).get(scope))); } + + public static void checkBec(Map control, String bec) throws ValueParseException { + if (!getBecAliases(control).contains(bec)) { + throw new ValueParseException(bec, bec + " is not a valid BEC"); + } + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java index d313860d3..6409fbc5e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -36,7 +36,7 @@ public boolean isStopLine(String line) { return line.startsWith(" "); } - }.value(4, BEC_KEY, String::strip).space(2).value(1, COEFFICIENT_INDEX_KEY, ValueParser.INTEGER) + }.value(4, BEC_KEY, ValueParser.STRING).space(2).value(1, COEFFICIENT_INDEX_KEY, ValueParser.INTEGER) .value(2, INDICATOR_KEY, ValueParser.INTEGER) .multiValue(NUM_SPECIES, 8, COEFFICIENT_KEY, ValueParser.FLOAT); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java index 323a0cf60..78325e5d2 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParser.java @@ -16,7 +16,7 @@ public class ComponentSizeParser extends SimpleCoefficientParser2 control) { super(1); - this.speciesKey(control).space(1).regionKey().coefficients(4, 6); + this.speciesKey().space(1).regionKey().coefficients(4, 6); } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index 0e63f71cd..b5ccb14f8 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -29,7 +29,7 @@ public class ControlFileParser implements ResourceParser> { public static final String COMMENT_MARKER = "!"; private Map identifiers; - private Map> valueParsers; + private Map> valueParsers; private ValueParser defaultValueParser; private Map> defaultValueGenerators; @@ -85,7 +85,7 @@ public Map parse(InputStream input, Map control) String controlString = restOfLine.substring(0, controlLength); String key = getKeyForIndex(index); - Object value = valueParsers.getOrDefault(index, defaultValueParser).parse(controlString); + Object value = valueParsers.getOrDefault(index, defaultValueParser).parse(controlString, control); r.put(key, value); @@ -131,7 +131,7 @@ public ControlFileParser record(int index, String name, ValueParser parser) { * @param parser * @return */ - public ControlFileParser optional(int index, String name, ValueParser parser) { + public ControlFileParser optional(int index, String name, ControlledValueParser parser) { record(index, name); optional(index, parser); return this; @@ -158,7 +158,7 @@ public ControlFileParser record(int index, String name) { * @param parser * @return */ - public ControlFileParser record(int index, ValueParser parser) { + public ControlFileParser record(int index, ControlledValueParser parser) { this.valueParsers.put(index, parser); return this; } @@ -171,8 +171,8 @@ public ControlFileParser record(int index, ValueParser parser) { * @param parser * @return */ - public ControlFileParser optional(int index, ValueParser parser) { - record(index, ValueParser.optional(parser)); + public ControlFileParser optional(int index, ControlledValueParser parser) { + record(index, ControlledValueParser.optional(parser)); this.defaultValueGenerators.put(getKeyForIndex(index), Optional::empty); return this; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java index 411b5080b..1f31f7f0d 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java @@ -1,12 +1,14 @@ package ca.bc.gov.nrs.vdyp.io.parse; import java.util.Map; +import java.util.Optional; +import java.util.function.BiFunction; @FunctionalInterface public interface ControlledValueParser { /** - * Parse a string to a value usinga control map for context. Should not attempt + * Parse a string to a value using a control map for context. Should not attempt * to modify the map. * * @param s @@ -16,4 +18,59 @@ public interface ControlledValueParser { */ T parse(String s, Map control) throws ValueParseException; + /** + * Wrap a parser with an additional validation step + * + * @param + * @param delegate + * @param validator Function that returns an error string if the parsed value is + * invalid + * @return + */ + public static ControlledValueParser validate( + ControlledValueParser delegate, BiFunction, Optional> validator + ) { + return (s, c) -> { + var value = delegate.parse(s, c); + var error = validator.apply(value, c); + if (error.isPresent()) { + throw new ValueParseException(s, error.get()); + } + return value; + }; + } + + /** + * Makes a parser that parses if the string is not blank, and returns an empty + * Optional otherwise. + * + * @param delegate Parser to use if the string is not blank + */ + public static ControlledValueParser> optional(ControlledValueParser delegate) { + return (s, c) -> { + if (!s.isBlank()) { + return Optional.of(delegate.parse(s, c)); + } + return Optional.empty(); + }; + } + + /** + * Parser that strips whitespace and validates that the string is a Species ID + */ + static final ControlledValueParser SPECIES = (string, control) -> { + var result = string.strip(); + SP0DefinitionParser.checkSpecies(control, result); + return result; + }; + + /** + * Parser that strips whitespace and validates that the string is a BEC ID + */ + static final ControlledValueParser BEC = (string, control) -> { + var result = string.strip(); + BecDefinitionParser.checkBec(control, result); + return result; + }; + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java index 8657be734..326e2b5dd 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java @@ -44,7 +44,7 @@ public boolean isStopLine(String line) { return line.startsWith(" "); } - }.value(2, SP0_KEY, String::strip).space(1).value(1, REGION_KEY, ValueParser.REGION) + }.value(2, SP0_KEY, ValueParser.STRING).space(1).value(1, REGION_KEY, ValueParser.REGION) .multiValue(numCoefficients, 10, COEFFICIENT_KEY, ValueParser.FLOAT); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java index e1d7cc343..f4b36080a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java @@ -39,7 +39,7 @@ public boolean isStopLine(String line) { return line.startsWith(" "); } - }.value(2, SPECIES_1_KEY, String::strip).space(1).value(2, SPECIES_2_KEY, String::strip).space(1) + }.value(2, SPECIES_1_KEY, ValueParser.STRING).space(1).value(2, SPECIES_2_KEY, ValueParser.STRING).space(1) .value(1, REGION_KEY, ValueParser.REGION).space(1).integer(1, EQUATION_KEY) .multiValue(NUM_COEFFICIENTS, 10, COEFFICIENT_KEY, ValueParser.FLOAT); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 5e7e4affa..927cf4dfe 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -102,21 +102,21 @@ public LineParser floating(int length, String name) { * A string segment */ public LineParser string(int length, String name) { - return this.value(length, name, s -> s); + return this.value(length, name, ValueParser.STRING_UNSTRIPPED); } /** * A string segment with no bounds. No further segments may be added. */ public LineParser string(String name) { - return this.value(name, s -> s); + return this.value(name, ValueParser.STRING_UNSTRIPPED); } /** * A string segment stripped of leading and trailing whitespace. */ public LineParser strippedString(int length, String name) { - return this.value(length, name, String::strip); + return this.value(length, name, ValueParser.STRING); } /** @@ -124,7 +124,7 @@ public LineParser strippedString(int length, String name) { * No further segments may be added. */ public LineParser strippedString(String name) { - return this.value(name, String::strip); + return this.value(name, ValueParser.STRING); } /** @@ -152,7 +152,7 @@ public LineParser multiValue(int number, int length, String name, ValueParse * @param name name of the segment * @param parser parser to convert the string */ - public LineParser value(int length, String name, ValueParser parser) { + public LineParser value(int length, String name, ControlledValueParser parser) { if (length < 0) throw new IllegalArgumentException("length can not be negative"); return doValue(length, name, parser); @@ -166,11 +166,11 @@ public LineParser value(int length, String name, ValueParser parser) { * @param name name of the segment * @param parser parser to convert the string */ - public LineParser value(String name, ValueParser parser) { + public LineParser value(String name, ControlledValueParser parser) { return doValue(-1, name, parser); } - private LineParser doValue(int length, String name, ValueParser parser) { + private LineParser doValue(int length, String name, ControlledValueParser parser) { if (segments.size() > 0 && segments.get(segments.size() - 1).length < 0) throw new IllegalStateException("Can not add a segment after an unbounded segment"); segments.add(new LineParserValueSegment(length, name) { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index 381bac681..cf5a4d4c3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -26,9 +26,9 @@ public class SP0DefinitionParser implements ResourceParser> LineParser lineParser = new LineParser().strippedString(2, "alias").space(1).strippedString(32, "name").space(1) .value( 2, "preference", - s -> ValueParser.optional(ValueParser.INTEGER).parse(s) + (s, c) -> ValueParser.optional(ValueParser.INTEGER).parse(s) .flatMap(v -> v == 0 ? Optional.empty() : Optional.of(v)) - );; + ); public SP0DefinitionParser() { super(); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java index 3d2f64a43..d07082f1e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java @@ -63,9 +63,12 @@ public BaseCoefficientParser> groupIndexKe return delegate.groupIndexKey(maxGroups); } - public BaseCoefficientParser> - speciesKey(String name, Map controlMap) { - return delegate.speciesKey(name, controlMap); + public BaseCoefficientParser> speciesKey(String name) { + return delegate.speciesKey(name); + } + + public BaseCoefficientParser> speciesKey() { + return delegate.speciesKey(); } public BaseCoefficientParser> space(int length) { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java index 9068df43c..00db897e6 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java @@ -42,7 +42,7 @@ public boolean isStopLine(String line) { }.value(3, SC_KEY, PARSE_SC).value(7, COASTAL_KEY, PARSE_AGE).value(7, INTERIOR_KEY, PARSE_AGE) .value(7, T1_KEY, PARSE_AGE).value(7, T2_KEY, PARSE_AGE); - static ValueParser PARSE_SC = ValueParser.validate(ValueParser.INTEGER, v -> { + static ControlledValueParser PARSE_SC = ControlledValueParser.validate(ValueParser.INTEGER, (v, c) -> { if (v < -1 || v > MAX_SC) { return Optional.of("Site curve number must be in the range -1 to " + MAX_SC + " inclusive"); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java index 4a5372452..5ad91e945 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java @@ -8,7 +8,7 @@ public class SmallComponentBaseAreaParser extends SimpleCoefficientParser1 control) { super(String.class, 1); - this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.speciesKey(); this.coefficients(4, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java index b37b78649..3bd896dff 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java @@ -8,7 +8,7 @@ public class SmallComponentDQParser extends SimpleCoefficientParser1 { public SmallComponentDQParser(Map control) { super(String.class, 1); - this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.speciesKey(); this.coefficients(2, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java index 0ed603f8b..e0c867986 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java @@ -8,7 +8,7 @@ public class SmallComponentHLParser extends SimpleCoefficientParser1 { public SmallComponentHLParser(Map control) { super(String.class, 1); - this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.speciesKey(); this.coefficients(2, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java index 410f0635f..35f36d20c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java @@ -8,7 +8,7 @@ public class SmallComponentProbabilityParser extends SimpleCoefficientParser1 control) { super(String.class, 1); - this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.speciesKey(); this.coefficients(4, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java index 728266f9d..6210f8639 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java @@ -8,7 +8,7 @@ public class SmallComponentWSVolumeParser extends SimpleCoefficientParser1 control) { super(String.class, 1); - this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.speciesKey(); this.coefficients(4, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java index 0f2af6ea3..bf265cd2a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java @@ -38,7 +38,7 @@ public boolean isStopLine(String line) { return line.startsWith(" "); } - }.value(2, SP0_KEY, String::strip).space(1).value(1, REGION_KEY, ValueParser.REGION) + }.value(2, SP0_KEY, ValueParser.STRING).space(1).value(1, REGION_KEY, ValueParser.REGION) .multiValue(NUM_COEFFICIENTS, 7, COEFFICIENT_KEY, ValueParser.FLOAT); @Override diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java index 67070a23f..45e64cb36 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java @@ -32,8 +32,8 @@ public boolean isStopLine(String line) { return line.startsWith(" "); } - }.value(4, UC_KEY, ValueParser.indexParser("UC", 1, ucCodes)).space(gap).value(2, SPECIES_KEY, String::strip) - .space(1).value(4, BEC_SCOPE_KEY, String::strip) + }.value(4, UC_KEY, ValueParser.indexParser("UC", 1, ucCodes)).space(gap) + .value(2, SPECIES_KEY, ValueParser.STRING).space(1).value(4, BEC_SCOPE_KEY, ValueParser.STRING) .multiValue(numCoefficients, 10, COEFFICIENT_KEY, ValueParser.FLOAT); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 7ffb2e010..67352507b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -128,6 +128,16 @@ public static ValueParser indexParser(String sequenceName, int indexFro return s.charAt(0); }; + /** + * Parser for strings that does not strip whitespace + */ + public static final ValueParser STRING_UNSTRIPPED = s -> s; + + /** + * Parser for strings + */ + public static final ValueParser STRING = String::strip; + /** * Parser for a region identifier */ @@ -155,14 +165,7 @@ public static ValueParser> list(ValueParser delegate) { * @return */ public static ValueParser validate(ValueParser delegate, Function> validator) { - return s -> { - var value = delegate.parse(s); - var error = validator.apply(value); - if (error.isPresent()) { - throw new ValueParseException(s, error.get()); - } - return value; - }; + return uncontrolled(ControlledValueParser.validate(delegate, (v, c) -> validator.apply(v))); } /** @@ -172,12 +175,7 @@ public static ValueParser validate(ValueParser delegate, Function ValueParser> optional(ValueParser delegate) { - return (s) -> { - if (!s.isBlank()) { - return Optional.of(delegate.parse(s)); - } - return Optional.empty(); - }; + return uncontrolled(ControlledValueParser.optional(delegate)); } /** @@ -198,4 +196,8 @@ public static ValueParser> segmentList(int length, ValueParser de return Collections.unmodifiableList(result); }; } + + static ValueParser uncontrolled(ControlledValueParser delegate) { + return s -> delegate.parse(s, Collections.emptyMap()); + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java index a863e9bda..eb2b067be 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranBQParser.java @@ -10,7 +10,7 @@ public class VeteranBQParser extends SimpleCoefficientParser2 { public VeteranBQParser(Map control) { super(1); - this.speciesKey(control).space(1).regionKey().coefficients(3, 9); + this.speciesKey().space(1).regionKey().coefficients(3, 9); } } \ No newline at end of file diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java index 9db0ed16b..3c89fadde 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java @@ -31,7 +31,8 @@ public boolean isStopLine(String line) { return line.startsWith(" "); } - }.value(2, SPECIES_KEY, String::strip).space(1).value(1, REGION_KEY, ValueParser.optional(ValueParser.REGION)) + }.value(2, SPECIES_KEY, ValueParser.STRING).space(1) + .value(1, REGION_KEY, ControlledValueParser.optional(ValueParser.REGION)) .multiValue(numCoefficients, 10, COEFFICIENT_KEY, ValueParser.FLOAT); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java index d99cab7e8..fca7c5035 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranLayerVolumeAdjustParser.java @@ -8,7 +8,7 @@ public class VeteranLayerVolumeAdjustParser extends SimpleCoefficientParser1 control) { super(String.class, 0); - this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.speciesKey(); this.coefficients(4, 9); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java index afc7dcb66..509000edd 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayWasteParser.java @@ -8,7 +8,7 @@ public class VolumeNetDecayWasteParser extends SimpleCoefficientParser1 public VolumeNetDecayWasteParser(Map control) { super(String.class, 0); - this.speciesKey(BaseCoefficientParser.SP0_KEY, control); + this.speciesKey(); this.coefficients(6, 9); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index e0284db27..618290fcd 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -226,7 +226,7 @@ void testException() throws Exception { @Test void testExceptionInControlValueParser() throws Exception { var parser = makeParser(); - parser.record(2, s -> { + parser.record(2, (s, c) -> { throw new ValueParseException(s, "Test Exception"); }); @@ -313,7 +313,7 @@ void testParseToMapLastOfDuplicates() throws Exception { void testParsesOptional() throws Exception { var parser = makeParser(); - parser.optional(1, "x", String::strip); + parser.optional(1, "x", ValueParser.STRING); String file = "001 Control"; try (InputStream is = new ByteArrayInputStream(file.getBytes())) { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 508027071..4bb302100 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -93,8 +93,8 @@ public void testNumberParseErrors() throws Exception { @Test public void testValueParser() throws Exception { var parser = new LineParser(); - parser.value(4, "part1", (s) -> Integer.valueOf(s.strip()) + 1).space(1) - .value("part2", (s) -> Float.valueOf(s.strip()) + 1); + parser.value(4, "part1", (s, c) -> Integer.valueOf(s.strip()) + 1).space(1) + .value("part2", (s, c) -> Float.valueOf(s.strip()) + 1); var result1 = parser.parseLine(" 4 0.5 ", Collections.emptyMap()); @@ -106,9 +106,9 @@ public void testValueParser() throws Exception { @Test public void testValueParserError() throws Exception { var parser = new LineParser(); - parser.value(4, "part1", (s) -> { + parser.value(4, "part1", (s, c) -> { throw new ValueParseException(s, "Testing"); - }).space(1).value(4, "part2", (s) -> Float.valueOf(s.strip()) + 1); + }).space(1).value(4, "part2", (s, c) -> Float.valueOf(s.strip()) + 1); var ex1 = assertThrows(ValueParseException.class, () -> parser.parseLine(" X 0.5 ", Collections.emptyMap())); assertThat(ex1, hasProperty("value", is(" X "))); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java index 5ce249134..3f199caef 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java @@ -2,19 +2,16 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.anEmptyMap; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.model.SP0Definition; From 2f25e4fcb965ec7dd48760f18f771e21b7cca36c Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 1 Jun 2023 13:56:07 -0700 Subject: [PATCH 48/98] Have all parsers for resources loaded by FIP control file implement ControlMapSubResourceParser --- .../vdyp/io/parse/BaseCoefficientParser.java | 14 +- .../vdyp/io/parse/BecDefinitionParser.java | 7 +- .../io/parse/BreakageEquationGroupParser.java | 16 + .../gov/nrs/vdyp/io/parse/BreakageParser.java | 6 +- .../parse/BySpeciesDqCoefficientParser.java | 7 +- .../vdyp/io/parse/CloseUtilVolumeParser.java | 2 +- .../nrs/vdyp/io/parse/CoefficientParser.java | 13 +- .../vdyp/io/parse/ComponentSizeParser.java | 6 +- .../nrs/vdyp/io/parse/ControlMapModifier.java | 16 + ....java => ControlMapSubResourceParser.java} | 3 +- .../io/parse/DecayEquationGroupParser.java | 16 + .../io/parse/DefaultEquationNumberParser.java | 19 + .../vdyp/io/parse/EquationGroupParser.java | 15 +- .../vdyp/io/parse/EquationModifierParser.java | 7 +- .../vdyp/io/parse/HLCoefficientParser.java | 11 +- .../parse/HLNonprimaryCoefficientParser.java | 7 +- .../OptionalControlMapSubResourceParser.java | 33 + .../io/parse/ResourceControlMapModifier.java | 2 +- .../vdyp/io/parse/SP0DefinitionParser.java | 7 +- .../io/parse/SimpleCoefficientParser1.java | 14 +- .../io/parse/SimpleCoefficientParser2.java | 4 +- .../io/parse/SiteCurveAgeMaximumParser.java | 11 +- .../nrs/vdyp/io/parse/SiteCurveParser.java | 17 +- .../parse/SmallComponentBaseAreaParser.java | 6 +- .../vdyp/io/parse/SmallComponentDQParser.java | 6 +- .../vdyp/io/parse/SmallComponentHLParser.java | 6 +- .../SmallComponentProbabilityParser.java | 6 +- .../parse/SmallComponentWSVolumeParser.java | 4 +- .../io/parse/StockingClassFactorParser.java | 7 +- .../io/parse/TotalStandWholeStemParser.java | 2 +- .../vdyp/io/parse/UpperCoefficientParser.java | 7 +- .../io/parse/UtilComponentBaseAreaParser.java | 5 + .../vdyp/io/parse/UtilComponentDQParser.java | 5 + .../vdyp/io/parse/UtilComponentParser.java | 5 +- .../io/parse/UtilComponentWSVolumeParser.java | 2 +- .../nrs/vdyp/io/parse/VeteranBQParser.java | 6 +- .../nrs/vdyp/io/parse/VeteranDQParser.java | 7 +- .../parse/VeteranLayerVolumeAdjustParser.java | 6 +- .../io/parse/VolumeEquationGroupParser.java | 19 + .../vdyp/io/parse/VolumeNetDecayParser.java | 2 +- .../io/parse/VolumeNetDecayWasteParser.java | 6 +- .../vdyp/io/parse/CoefficientParserTest.java | 10 +- .../io/parse/ComponentSizeParserTest.java | 6 +- .../io/parse/EquationGroupParserTest.java | 16 +- .../io/parse/HLCoefficientParserTest.java | 10 +- .../SmallComponentProbabilityParserTest.java | 4 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 923 +++--------------- 47 files changed, 432 insertions(+), 897 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageEquationGroupParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapModifier.java rename vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/{ControlMapSubResource.java => ControlMapSubResourceParser.java} (90%) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DecayEquationGroupParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DefaultEquationNumberParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index 9f842bce0..4bb49e5a7 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -23,7 +23,7 @@ * */ public abstract class BaseCoefficientParser> - implements ResourceParser { + implements ControlMapSubResourceParser { public static final String SP0_KEY = "sp0"; public static final String REGION_KEY = "region"; @@ -36,8 +36,9 @@ public abstract class BaseCoefficientParser metaKeys = new ArrayList<>(); List, Collection>> keyRanges = new ArrayList<>(); private int expectedKeys; + private final String controlKey; - public BaseCoefficientParser(int expectedKeys) { + public BaseCoefficientParser(int expectedKeys, String controlKey) { super(); this.expectedKeys = expectedKeys; this.lineParser = new LineParser() { @@ -48,10 +49,11 @@ public boolean isStopSegment(List segments) { } }; + this.controlKey = controlKey; } - public BaseCoefficientParser() { - this(0); + public BaseCoefficientParser(String controlKey) { + this(0, controlKey); } /** @@ -162,4 +164,8 @@ public M parse(InputStream is, Map control) throws IOException, protected abstract T getCoefficients(List coefficients); + @Override + public String getControlKey() { + return controlKey; + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index 1f2410427..2a7b7442d 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -18,7 +18,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class BecDefinitionParser implements ResourceParser> { +public class BecDefinitionParser implements ControlMapSubResourceParser> { public static final String CONTROL_KEY = "BEC_DEF"; @@ -99,4 +99,9 @@ public static void checkBec(Map control, String bec) throws Valu throw new ValueParseException(bec, bec + " is not a valid BEC"); } } + + @Override + public String getControlKey() { + return CONTROL_KEY; + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageEquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageEquationGroupParser.java new file mode 100644 index 000000000..edbb7c383 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageEquationGroupParser.java @@ -0,0 +1,16 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +public class BreakageEquationGroupParser extends EquationGroupParser { + + public static final String CONTROL_KEY = "BREAKAGE_GROUPS"; + + public BreakageEquationGroupParser() { + super(3); + } + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java index e8a4f0bd6..30917bde4 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BreakageParser.java @@ -1,13 +1,11 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.Map; - public class BreakageParser extends SimpleCoefficientParser1 { public static final String CONTROL_KEY = "BREAKAGE"; - public BreakageParser(Map control) { - super(Integer.class, 1); + public BreakageParser() { + super(Integer.class, 1, CONTROL_KEY); this.groupIndexKey(40); this.coefficients(6, 9); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java index 19a385b8c..9214d213b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java @@ -16,7 +16,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class BySpeciesDqCoefficientParser implements ResourceParser> { +public class BySpeciesDqCoefficientParser implements ControlMapSubResourceParser> { public static final String CONTROL_KEY = "BY_SPECIES_DQ"; @@ -73,4 +73,9 @@ public List parse(InputStream is, Map control) return result; } + @Override + public String getControlKey() { + return CONTROL_KEY; + } + } \ No newline at end of file diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java index 2645cb0e7..f0f729fe9 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CloseUtilVolumeParser.java @@ -11,7 +11,7 @@ public class CloseUtilVolumeParser extends SimpleCoefficientParser2> { +public class CoefficientParser implements ControlMapSubResourceParser> { public static final String BA_CONTROL_KEY = "COE_BA"; public static final String DQ_CONTROL_KEY = "COE_DQ"; @@ -29,6 +29,12 @@ public class CoefficientParser implements ResourceParser parse(InputStream is, Map control) { - super(1); + public ComponentSizeParser() { + super(1, CONTROL_KEY); this.speciesKey().space(1).regionKey().coefficients(4, 6); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapModifier.java new file mode 100644 index 000000000..47a5de643 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapModifier.java @@ -0,0 +1,16 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.io.FileResolver; + +/** + * Modifies a control map + * + * @author Kevin Smith, Vivid Solutions + * + */ +public interface ControlMapModifier { + void modify(Map control, FileResolver fileResolver) throws ResourceParseException, IOException; +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResource.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResourceParser.java similarity index 90% rename from vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResource.java rename to vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResourceParser.java index 59fad8d5a..3b047b47d 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResource.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResourceParser.java @@ -12,7 +12,7 @@ * * @param */ -public interface ControlMapSubResource extends ResourceControlMapModifier, ResourceParser { +public interface ControlMapSubResourceParser extends ResourceControlMapModifier, ResourceParser { /** * The key for this resource's entry in the control map @@ -37,6 +37,7 @@ default void modify(Map control, InputStream data) throws IOExce * @throws IOException * @throws ResourceParseException */ + @Override default void modify(Map control, FileResolver fileResolver) throws IOException, ResourceParseException { var filename = (String) control.get(getControlKey()); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DecayEquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DecayEquationGroupParser.java new file mode 100644 index 000000000..dd6bf4fe9 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DecayEquationGroupParser.java @@ -0,0 +1,16 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +public class DecayEquationGroupParser extends EquationGroupParser { + + public static final String CONTROL_KEY = "DECAY_GROUPS"; + + public DecayEquationGroupParser() { + super(3); + } + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DefaultEquationNumberParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DefaultEquationNumberParser.java new file mode 100644 index 000000000..5581a7f8e --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/DefaultEquationNumberParser.java @@ -0,0 +1,19 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Arrays; + +public class DefaultEquationNumberParser extends EquationGroupParser { + + public static final String CONTROL_KEY = "DEFAULT_EQ_NUM"; + + public DefaultEquationNumberParser() { + super(5); + this.setHiddenBecs(Arrays.asList("BG", "AT")); + } + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index c27fa631a..ce55066dd 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -11,7 +11,6 @@ import java.util.stream.Collectors; import ca.bc.gov.nrs.vdyp.model.BecDefinition; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.common.ExpectationDifference; /** @@ -20,20 +19,12 @@ * @author Kevin Smith, Vivid Solutions * */ -public class EquationGroupParser implements ResourceParser>> { - - public static final String VOLUME_CONTROL_KEY = "VOLUME_EQN_GROUPS"; - - public static final String DECAY_CONTROL_KEY = "DECAY_GROUPS"; - - public static final String BREAKAGE_CONTROL_KEY = "BREAKAGE_GROUPS"; - - public static final String DEFAULT_CONTROL_KEY = "DEFAULT_EQ_NUM"; +public abstract class EquationGroupParser implements ControlMapSubResourceParser>> { LineParser lineParser; private Collection hiddenBecs = Collections.emptyList(); - + public EquationGroupParser() { this(3); } @@ -115,5 +106,5 @@ public Map> parse(InputStream is, Map hiddenBecs) { this.hiddenBecs = hiddenBecs; } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java index c394fec61..265f0888e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParser.java @@ -12,7 +12,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class EquationModifierParser implements ResourceParser>> { +public class EquationModifierParser implements ControlMapSubResourceParser>> { public static final String CONTROL_KEY = "EQN_MODIFIERS"; @@ -46,4 +46,9 @@ public Map> parse(InputStream is, Map> { +public class HLCoefficientParser implements ControlMapSubResourceParser> { public static final String CONTROL_KEY_P1 = "HL_PRIMARY_SP_EQN_P1"; public static final String CONTROL_KEY_P2 = "HL_PRIMARY_SP_EQN_P2"; @@ -33,8 +33,9 @@ public class HLCoefficientParser implements ResourceParser parse(InputStream is, Map> { + implements ControlMapSubResourceParser> { public static final String CONTROL_KEY = "HL_NONPRIMARY"; @@ -75,4 +75,9 @@ public boolean isStopLine(String line) { return result; } + @Override + public String getControlKey() { + return CONTROL_KEY; + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java new file mode 100644 index 000000000..c86f6fdae --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Optional; + +import ca.bc.gov.nrs.vdyp.io.FileResolver; + +public interface OptionalControlMapSubResourceParser extends ControlMapSubResourceParser { + + @Override + default void modify(Map control, FileResolver fileResolver) + throws IOException, ResourceParseException { + @SuppressWarnings("unchecked") + var filename = (Optional) control.get(getControlKey()); + if(filename.isPresent()) { + try (InputStream data = fileResolver.resolve(filename.get())) { + modify(control, data); + } + } else { + defaultModify(control); + } + + } + + default void defaultModify(Map control) { + control.put(getControlKey(), defaultResult()); + } + + T defaultResult(); + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java index 21ad6ff44..612c568d1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java @@ -10,7 +10,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public interface ResourceControlMapModifier { +public interface ResourceControlMapModifier extends ControlMapModifier { void modify(Map control, InputStream data) throws ResourceParseException, IOException; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index cf5a4d4c3..0f35ccd8a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -17,7 +17,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class SP0DefinitionParser implements ResourceParser> { +public class SP0DefinitionParser implements ControlMapSubResourceParser> { public static final String CONTROL_KEY = "SP0_DEF"; @@ -98,4 +98,9 @@ public static List getSpeciesAliases(final Map controlMa return getSpecies(controlMap).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); } + @Override + public String getControlKey() { + return CONTROL_KEY; + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java index d07082f1e..c80c9c1d9 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser1.java @@ -10,14 +10,14 @@ import ca.bc.gov.nrs.vdyp.model.MatrixMap; import ca.bc.gov.nrs.vdyp.model.MatrixMapImpl; -public class SimpleCoefficientParser1 implements ResourceParser> { +public class SimpleCoefficientParser1 implements ControlMapSubResourceParser> { private int indexFrom; Class keyClass; private BaseCoefficientParser> delegate = new BaseCoefficientParser>( - 1 + 1, "DUMMY" ) { @SuppressWarnings("unchecked") @@ -32,10 +32,13 @@ protected Coefficients getCoefficients(List coefficients) { } }; - public SimpleCoefficientParser1(Class keyClass, int indexFrom) { + private String controlKey; + + public SimpleCoefficientParser1(Class keyClass, int indexFrom, String controlKey) { super(); this.keyClass = keyClass; this.indexFrom = indexFrom; + this.controlKey = controlKey; } @Override @@ -79,4 +82,9 @@ public BaseCoefficientParser> coeffici return delegate.coefficients(number, length); } + @Override + public String getControlKey() { + return this.controlKey; + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java index 67285cc8c..b1ca0aa00 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SimpleCoefficientParser2.java @@ -12,8 +12,8 @@ public class SimpleCoefficientParser2 private int indexFrom; - public SimpleCoefficientParser2(int indexFrom) { - super(2); + public SimpleCoefficientParser2(int indexFrom, String controlKey) { + super(2, controlKey); this.indexFrom = indexFrom; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java index 00db897e6..89bc18b61 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java @@ -14,7 +14,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class SiteCurveAgeMaximumParser implements ResourceParser> { +public class SiteCurveAgeMaximumParser implements OptionalControlMapSubResourceParser> { public static final String CONTROL_KEY = "SITE_CURVE_AGE_MAX"; public static final String SC_KEY = "siteCurve"; @@ -55,7 +55,7 @@ public boolean isStopLine(String line) { }; @SuppressWarnings("serial") - public static Map defaultMap() { + public Map defaultResult() { return new HashMap<>() { @Override public SiteCurveAgeMaximum get(Object key) { @@ -68,7 +68,7 @@ public SiteCurveAgeMaximum get(Object key) { @Override public Map parse(InputStream is, Map control) throws IOException, ResourceParseException { - Map result = defaultMap(); + Map result = defaultResult(); lineParser.parse(is, result, (v, r) -> { var sc = (int) v.get(SC_KEY); var ageCoast = (float) v.get(COASTAL_KEY); @@ -86,4 +86,9 @@ public Map parse(InputStream is, Map> { +public class SiteCurveParser implements OptionalControlMapSubResourceParser> { public static final String CONTROL_KEY = "SITE_CURVE_NUMBERS"; public static final String SPECIES_KEY = "species"; @@ -54,4 +51,14 @@ public Map parse(InputStream is, Map control) return result; } + @Override + public String getControlKey() { + return CONTROL_KEY; + } + + @Override + public Map defaultResult() { + return Collections.emptyMap(); + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java index 5ad91e945..2ebdf7005 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentBaseAreaParser.java @@ -1,13 +1,11 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.Map; - public class SmallComponentBaseAreaParser extends SimpleCoefficientParser1 { public static final String CONTROL_KEY = "SMALL_COMP_BA"; - public SmallComponentBaseAreaParser(Map control) { - super(String.class, 1); + public SmallComponentBaseAreaParser() { + super(String.class, 1, CONTROL_KEY); this.speciesKey(); this.coefficients(4, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java index 3bd896dff..35bbd7775 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentDQParser.java @@ -1,13 +1,11 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.Map; - public class SmallComponentDQParser extends SimpleCoefficientParser1 { public static final String CONTROL_KEY = "SMALL_COMP_DQ"; - public SmallComponentDQParser(Map control) { - super(String.class, 1); + public SmallComponentDQParser() { + super(String.class, 1, CONTROL_KEY); this.speciesKey(); this.coefficients(2, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java index e0c867986..f2d998b86 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentHLParser.java @@ -1,13 +1,11 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.Map; - public class SmallComponentHLParser extends SimpleCoefficientParser1 { public static final String CONTROL_KEY = "SMALL_COMP_HL"; - public SmallComponentHLParser(Map control) { - super(String.class, 1); + public SmallComponentHLParser() { + super(String.class, 1, CONTROL_KEY); this.speciesKey(); this.coefficients(2, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java index 35f36d20c..662416f2a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParser.java @@ -1,13 +1,11 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.Map; - public class SmallComponentProbabilityParser extends SimpleCoefficientParser1 { public static final String CONTROL_KEY = "SMALL_COMP_PROBABILITY"; - public SmallComponentProbabilityParser(Map control) { - super(String.class, 1); + public SmallComponentProbabilityParser() { + super(String.class, 1, CONTROL_KEY); this.speciesKey(); this.coefficients(4, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java index 6210f8639..bb24f032d 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java @@ -6,8 +6,8 @@ public class SmallComponentWSVolumeParser extends SimpleCoefficientParser1 control) { - super(String.class, 1); + public SmallComponentWSVolumeParser() { + super(String.class, 1, CONTROL_KEY); this.speciesKey(); this.coefficients(4, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java index 17eca1fcb..b4e670f7c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java @@ -16,7 +16,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class StockingClassFactorParser implements ResourceParser>> { +public class StockingClassFactorParser implements ControlMapSubResourceParser>> { public static final String CONTROL_KEY = "STOCKING_CLASS_FACTORS"; @@ -77,4 +77,9 @@ public Map> parse(InputStream is, Ma return Collections.unmodifiableMap(result); } + @Override + public String getControlKey() { + return CONTROL_KEY; + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java index 213a77299..4209c506b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/TotalStandWholeStemParser.java @@ -5,7 +5,7 @@ public class TotalStandWholeStemParser extends SimpleCoefficientParser1 public static final String CONTROL_KEY = "TOTAL_STAND_WHOLE_STEM_VOL"; public TotalStandWholeStemParser() { - super(Integer.class, 0); + super(Integer.class, 0, CONTROL_KEY); this.groupIndexKey(80); this.coefficients(9, 10); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java index bf265cd2a..e290a0ce0 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java @@ -19,7 +19,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class UpperCoefficientParser implements ResourceParser> { +public class UpperCoefficientParser implements ControlMapSubResourceParser> { public static final int BA = 1; public static final int DQ = 2; @@ -68,4 +68,9 @@ public MatrixMap3 parse(InputStream is, Map> { - public static final String CONTROL_KEY_BA = "UTIL_COMP_BA"; - public static final String CONTROL_KEY_DQ = "UTIL_COMP_DQ"; +public abstract class UtilComponentParser implements ControlMapSubResourceParser> { + // "07.5", "12.5", "17.5", "22.5" public final int numCoefficients; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java index 0c4401060..8d8b637c7 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentWSVolumeParser.java @@ -5,7 +5,7 @@ public class UtilComponentWSVolumeParser extends SimpleCoefficientParser2 { public static final String CONTROL_KEY = "VETERAN_BQ"; - public VeteranBQParser(Map control) { - super(1); + public VeteranBQParser() { + super(1, CONTROL_KEY); this.speciesKey().space(1).regionKey().coefficients(3, 9); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java index 3c89fadde..af4284e57 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java @@ -13,7 +13,7 @@ import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.Region; -public class VeteranDQParser implements ResourceParser> { +public class VeteranDQParser implements ControlMapSubResourceParser> { public static final String CONTROL_KEY = "VETERAN_LAYER_DQ"; public final static int numCoefficients = 3; @@ -69,4 +69,9 @@ public MatrixMap2 parse(InputStream is, Map { public static final String CONTROL_KEY = "VETERAN_LAYER_VOLUME_ADJUST"; - public VeteranLayerVolumeAdjustParser(Map control) { - super(String.class, 0); + public VeteranLayerVolumeAdjustParser() { + super(String.class, 0, CONTROL_KEY); this.speciesKey(); this.coefficients(4, 9); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java new file mode 100644 index 000000000..b27354129 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeEquationGroupParser.java @@ -0,0 +1,19 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.Arrays; + +public class VolumeEquationGroupParser extends EquationGroupParser { + + public static final String CONTROL_KEY = "VOLUME_EQN_GROUPS"; + + public VolumeEquationGroupParser() { + super(3); + this.setHiddenBecs(Arrays.asList("BG")); + } + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java index 1ea9fee3e..9c7532166 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VolumeNetDecayParser.java @@ -11,7 +11,7 @@ public class VolumeNetDecayParser extends SimpleCoefficientParser2 { public static final String CONTROL_KEY = "VOLUME_NET_DECAY_WASTE"; - public VolumeNetDecayWasteParser(Map control) { - super(String.class, 0); + public VolumeNetDecayWasteParser() { + super(String.class, 0, CONTROL_KEY); this.speciesKey(); this.coefficients(6, 9); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java index 4fbd4a5f7..cfef7cc15 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java @@ -21,7 +21,7 @@ public class CoefficientParserTest { @Test public void testParseSimple() throws Exception { - var parser = new CoefficientParser(); + var parser = new CoefficientParser("TEST"); var is = TestUtils.makeStream( "B1 A0 1 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" @@ -46,7 +46,7 @@ public void testParseSimple() throws Exception { @Test public void testBadBec() throws Exception { - var parser = new CoefficientParser(); + var parser = new CoefficientParser("TEST"); var is = TestUtils.makeStream( "BX A0 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" @@ -67,7 +67,7 @@ public void testBadBec() throws Exception { @Test public void testBadIndex() throws Exception { - var parser = new CoefficientParser(); + var parser = new CoefficientParser("TEST"); var is = TestUtils.makeStream( "B1 AX 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" @@ -88,7 +88,7 @@ public void testBadIndex() throws Exception { @Test public void testParseDelta() throws Exception { - var parser = new CoefficientParser(); + var parser = new CoefficientParser("TEST"); var is = TestUtils.makeStream( "B1 A0 2 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" @@ -112,7 +112,7 @@ public void testParseDelta() throws Exception { @Test public void testParseFixed() throws Exception { - var parser = new CoefficientParser(); + var parser = new CoefficientParser("TEST"); var is = TestUtils.makeStream( "B1 A0 0 2.0028 -0.5343 1.3949 -0.3683 -0.3343 0.5699 0.2314 0.0528 0.2366 -0.3343 0.5076 0.5076 0.6680 -0.1353 1.2445 -0.4507" diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java index 3a4c295f7..8e8ffbf50 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java @@ -25,7 +25,7 @@ public void testParseSimpleP1() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var parser = new ComponentSizeParser(controlMap); + var parser = new ComponentSizeParser(); var result = parser.parse(is, controlMap); @@ -41,7 +41,7 @@ public void testParseBadSpecies() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var parser = new ComponentSizeParser(controlMap); + var parser = new ComponentSizeParser(); @SuppressWarnings("unused") var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -57,7 +57,7 @@ public void testParseBadRegion() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var parser = new ComponentSizeParser(controlMap); + var parser = new ComponentSizeParser(); @SuppressWarnings("unused") var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index 87d70e7ac..d720eebfc 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -33,7 +33,7 @@ public class EquationGroupParserTest { @Test public void testParse() throws Exception { - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMapSingle(); String[] lines = { "S1 B1 001" }; @@ -46,7 +46,7 @@ public void testParse() throws Exception { @Test public void testSP0MustExist() throws Exception { - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMapSingle(); String[] lines = { "SX B1 001" }; @@ -64,7 +64,7 @@ public void testSP0MustExist() throws Exception { @Test public void testBecMustExist() throws Exception { - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMapSingle(); String[] lines = { "S1 BX 001" }; @@ -85,7 +85,7 @@ public void testParseOvewrite() throws Exception { // Original Fortran allows subsequent entries to overwrite old ones so don't // validate against that - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMapSingle(); String[] lines = { "S1 B1 001", "S1 B1 002" }; @@ -98,7 +98,7 @@ public void testParseOvewrite() throws Exception { @Test public void testParseMultiple() throws Exception { - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMap(); String[] lines = { "S1 B1 011", "S1 B2 012", "S1 B3 013", "S1 B4 014", "S2 B1 021", "S2 B2 022", @@ -120,7 +120,7 @@ public void testParseMultiple() throws Exception { @Test public void testRequireNoMissingSp0() throws Exception { - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMap(); @@ -140,7 +140,7 @@ public void testRequireNoMissingSp0() throws Exception { @Test public void testRequireNoMissingBec() throws Exception { - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMap(); @@ -161,7 +161,7 @@ public void testRequireNoMissingBec() throws Exception { @Test public void testRequireNoUnexpectedBec() throws Exception { - var parser = new EquationGroupParser(); + var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMap(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java index 71ab7edce..cad8cb019 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java @@ -22,7 +22,7 @@ public class HLCoefficientParserTest { @Test public void testParseSimpleP1() throws Exception { - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, "TEST"); var is = TestUtils.makeStream("S1 I 1.00160 0.20508-0.0013743"); @@ -43,7 +43,7 @@ public void testParseSimpleP1() throws Exception { @Test public void testParseSimpleP2() throws Exception { - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2, "TEST"); var is = TestUtils.makeStream("S1 C 0.49722 1.18403"); @@ -63,7 +63,7 @@ public void testParseSimpleP2() throws Exception { @Test public void testParseSimpleP3() throws Exception { - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3, "TEST"); var is = TestUtils.makeStream("S1 I 1.04422 0.93010 -0.05745 -2.50000"); @@ -84,7 +84,7 @@ public void testParseSimpleP3() throws Exception { @Test public void testParseBadSpecies() throws Exception { - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, "TEST"); var is = TestUtils.makeStream("SX I 1.00160 0.20508-0.0013743"); @@ -99,7 +99,7 @@ public void testParseBadSpecies() throws Exception { @Test public void testParseBadRegion() throws Exception { - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); + var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, "TEST"); var is = TestUtils.makeStream("S1 X 1.00160 0.20508-0.0013743"); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java index 56e46668a..ae47a7966 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java @@ -26,7 +26,7 @@ public void testParseSimpleP1() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var parser = new SmallComponentProbabilityParser(controlMap); + var parser = new SmallComponentProbabilityParser(); var result = parser.parse(is, controlMap); assertThat(result, hasEntry(is("S1"), contains(0.48205f, 0.00000f, -0.011862f, -0.10014f))); @@ -41,7 +41,7 @@ public void testParseBadSpecies() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var parser = new SmallComponentProbabilityParser(controlMap); + var parser = new SmallComponentProbabilityParser(); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); assertThat(ex, causedBy(hasProperty("value", is("SX")))); diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 6de761e53..a69805c1e 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -13,12 +13,16 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.BreakageEquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.BreakageParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.CloseUtilVolumeParser; import ca.bc.gov.nrs.vdyp.io.parse.CoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.ComponentSizeParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParser; +import ca.bc.gov.nrs.vdyp.io.parse.ControlMapModifier; +import ca.bc.gov.nrs.vdyp.io.parse.DecayEquationGroupParser; +import ca.bc.gov.nrs.vdyp.io.parse.DefaultEquationNumberParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParser; @@ -38,12 +42,14 @@ import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranDQParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranLayerVolumeAdjustParser; +import ca.bc.gov.nrs.vdyp.io.parse.VolumeEquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayWasteParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Coefficients; @@ -68,12 +74,12 @@ public class FipControlParser { public static final String VDYP_POLYGON = "VDYP_POLYGON"; public static final String VDYP_LAYER_BY_SPECIES = "VDYP_LAYER_BY_SPECIES"; public static final String VDYP_LAYER_BY_SP0_BY_UTIL = "VDYP_LAYER_BY_SP0_BY_UTIL"; - public static final String VOLUME_EQN_GROUPS = EquationGroupParser.VOLUME_CONTROL_KEY; - public static final String DECAY_GROUPS = EquationGroupParser.DECAY_CONTROL_KEY; - public static final String BREAKAGE_GROUPS = EquationGroupParser.BREAKAGE_CONTROL_KEY; + public static final String VOLUME_EQN_GROUPS = VolumeEquationGroupParser.CONTROL_KEY; + public static final String DECAY_GROUPS = DecayEquationGroupParser.CONTROL_KEY; + public static final String BREAKAGE_GROUPS = BreakageEquationGroupParser.CONTROL_KEY; public static final String SITE_CURVE_NUMBERS = SiteCurveParser.CONTROL_KEY; public static final String SITE_CURVE_AGE_MAX = SiteCurveAgeMaximumParser.CONTROL_KEY; - public static final String DEFAULT_EQ_NUM = EquationGroupParser.DEFAULT_CONTROL_KEY; + public static final String DEFAULT_EQ_NUM = DefaultEquationNumberParser.CONTROL_KEY; public static final String EQN_MODIFIERS = EquationModifierParser.CONTROL_KEY; public static final String STOCKING_CLASS_FACTORS = StockingClassFactorParser.CONTROL_KEY; public static final String COE_BA = CoefficientParser.BA_CONTROL_KEY; @@ -108,9 +114,6 @@ public class FipControlParser { public static final String BEC_DEF = BecDefinitionParser.CONTROL_KEY; public static final String SP0_DEF = SP0DefinitionParser.CONTROL_KEY; - // TODO - public static final String TODO = "TODO"; - static final ValueParser FILENAME = String::strip; ControlFileParser controlParser = new ControlFileParser().record(1, MAX_NUM_POLY, ValueParser.INTEGER) @@ -232,155 +235,184 @@ public String toString(String filename) throws IOException { }; } - Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { - var map = controlParser.parse(is, Collections.emptyMap()); + List BASIC_DEFINITIONS = Arrays.asList( - // RD_BEC - loadData(map, BecDefinitionParser.CONTROL_KEY, fileResolver, this::RD_BEC); - - // DEF_BEC - // TODO + // RD_BEC + new BecDefinitionParser(), - // Read Definitions - - // RD_SP0 - loadData(map, SP0_DEF, fileResolver, this::RD_SP0); + // DEF_BEC + // TODO - // Read Groups + // RD_SP0 + new SP0DefinitionParser() + ); + + List GROUP_DEFINITIONS = Arrays.asList( - // RD_VGRP - loadData(map, VOLUME_EQN_GROUPS, fileResolver, this::RD_VGRP); + // RD_VGRP + new VolumeEquationGroupParser(), - // RD_DGRP - loadData(map, DECAY_GROUPS, fileResolver, this::RD_DGRP); + // RD_DGRP + new DecayEquationGroupParser(), - // RD_BGRP - loadData(map, BREAKAGE_GROUPS, fileResolver, this::RD_BGRP); + // RD_BGRP + new BreakageEquationGroupParser(), - // RD_GRBA1 - loadData(map, DEFAULT_EQ_NUM, fileResolver, this::RD_GRBA1); + // RD_GRBA1 + new DefaultEquationNumberParser(), - // RD_GMBA1 - loadData(map, EQN_MODIFIERS, fileResolver, this::RD_GMBA1); + // RD_GMBA1 + new EquationModifierParser() + ); + + List FIPSTART_ONLY = Arrays.asList( - int jprogram = 1; // FIPSTART only TODO Track this down - if (jprogram == 1) { // RD_STK33 - loadData(map, STOCKING_CLASS_FACTORS, fileResolver, this::RD_STK33); + new StockingClassFactorParser() // TODO minima? /* * READ(CNTRV(197), 197, ERR= 912 ) FMINH, FMINBA, FMINBAF,FMINVetH IF (FMINVetH * .le. 0.0) FMINVetH=10.0 */ - } - - // User-assigned SC's (Site Curve Numbers) - // - // RD_E025 - loadDataOptional(map, SITE_CURVE_NUMBERS, fileResolver, this::RD_E025, Collections::emptyMap); - - // Max tot ages to apply site curves (by SC) - // - // RD_E026 - loadDataOptional(map, SITE_CURVE_AGE_MAX, fileResolver, this::RD_E026, SiteCurveAgeMaximumParser::defaultMap); - - // Coeff for Empirical relationships - + ); + List SITE_CURVES = Arrays.asList( + + // User-assigned SC's (Site Curve Numbers) + // + // RD_E025 + new SiteCurveParser(), + + // Max tot ages to apply site curves (by SC) + // + // RD_E026 + new SiteCurveAgeMaximumParser() + ); + + List COEFFICIENTS = Arrays.asList( // RD_E040 - loadData(map, COE_BA, fileResolver, this::RD_E040); - + new CoefficientParser(COE_BA), + // RD_E041 - loadData(map, COE_DQ, fileResolver, this::RD_E041); - + new CoefficientParser(COE_DQ), + // RD_E043 - loadData(map, UPPER_BA_BY_CI_S0_P, fileResolver, this::RD_E043); - + new UpperCoefficientParser(), + // RD_YHL1 - loadData(map, HL_PRIMARY_SP_EQN_P1, fileResolver, this::RD_YHL1); - + new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, HL_PRIMARY_SP_EQN_P1), + // RD_YHL2 - loadData(map, HL_PRIMARY_SP_EQN_P2, fileResolver, this::RD_YHL2); - + new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2, HL_PRIMARY_SP_EQN_P2), + // RD_YHL3 - loadData(map, HL_PRIMARY_SP_EQN_P3, fileResolver, this::RD_YHL3); - + new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3, HL_PRIMARY_SP_EQN_P3), + // RD_YHL4 - loadData(map, HL_NONPRIMARY, fileResolver, this::RD_YHL4); - + new HLNonprimaryCoefficientParser(), + // RD_E060 - loadData(map, BY_SPECIES_DQ, fileResolver, this::RD_E060); - + new BySpeciesDqCoefficientParser(), + // Min and max DQ by species - + // RD_E061 - loadData(map, SPECIES_COMPONENT_SIZE_LIMIT, fileResolver, this::RD_E061); - + new ComponentSizeParser(), + // RD_UBA1 - loadData(map, UTIL_COMP_BA, fileResolver, this::RD_UBA1); - + new UtilComponentBaseAreaParser(), + // RD_UDQ1 - loadData(map, UTIL_COMP_DQ, fileResolver, this::RD_UDQ1); - + new UtilComponentDQParser(), + // Small Component (4.5 to 7.5 cm) - + // RD_SBA1 - loadData(map, SMALL_COMP_PROBABILITY, fileResolver, this::RD_SBA1); - + new SmallComponentProbabilityParser(), + // RD_SBA2 - loadData(map, SMALL_COMP_BA, fileResolver, this::RD_SBA2); - + new SmallComponentBaseAreaParser(), + // RD_SDQ1 - loadData(map, SMALL_COMP_DQ, fileResolver, this::RD_SDQ1); - + new SmallComponentDQParser(), + // RD_SHL1 - loadData(map, SMALL_COMP_HL, fileResolver, this::RD_SHL1); - + new SmallComponentHLParser(), + // RD_SVT1 - loadData(map, SMALL_COMP_WS_VOLUME, fileResolver, this::RD_SVT1); - + new SmallComponentWSVolumeParser(), + // Standard Volume Relationships - + // RD_YVT1 - loadData(map, TOTAL_STAND_WHOLE_STEM_VOL, fileResolver, this::RD_YVT1); - + new TotalStandWholeStemParser(), + // RD_YVT2 - loadData(map, UTIL_COMP_WS_VOLUME, fileResolver, this::RD_YVT2); - + new UtilComponentWSVolumeParser(), + // RD_YVC1 - loadData(map, CLOSE_UTIL_VOLUME, fileResolver, this::RD_YVC1); - + new CloseUtilVolumeParser(), + // RD_YVD1 - loadData(map, VOLUME_NET_DECAY, fileResolver, this::RD_YVD1); - + new VolumeNetDecayParser(), + // RD_YVW1 - loadData(map, VOLUME_NET_DECAY_WASTE, fileResolver, this::RD_YVW1); - + new VolumeNetDecayWasteParser(), + // RD_E095 - loadData(map, BREAKAGE, fileResolver, this::RD_E095); - + new BreakageParser(), + // Veterans - + // RD_YVVET - loadData(map, VETERAN_LAYER_VOLUME_ADJUST, fileResolver, this::RD_YVVET); - + new VeteranLayerVolumeAdjustParser(), + // RD_YDQV - loadData(map, VETERAN_LAYER_DQ, fileResolver, this::RD_YDQV); - + new VeteranDQParser(), + // RD_E098 - loadData(map, VETERAN_BQ, fileResolver, this::RD_E098); + new VeteranBQParser() + ); + + private void applyModifiers(Mapcontrol, List modifiers, FileResolver fileResolver) throws ResourceParseException, IOException { + for (var modifier : modifiers) { + modifier.modify(control, fileResolver); + } + } + + Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { + var map = controlParser.parse(is, Collections.emptyMap()); + + applyModifiers(map, BASIC_DEFINITIONS, fileResolver); + + // Read Groups + + applyModifiers(map, GROUP_DEFINITIONS, fileResolver); + + int jprogram = 1; // FIPSTART only TODO Track this down + + if (jprogram == 1) { + applyModifiers(map, FIPSTART_ONLY, fileResolver); + } + + applyModifiers(map, SITE_CURVES, fileResolver); + + // Coeff for Empirical relationships + + applyModifiers(map, COEFFICIENTS, fileResolver); // Initiation items NOT for FIPSTART if (jprogram > 1) { - + + throw new UnsupportedOperationException(); // RD_E106 - loadData(map, TODO, fileResolver, this::RD_E106); + // TODO // RD_E107 - loadData(map, TODO, fileResolver, this::RD_E107); + // TODO // RD_E108 - loadData(map, TODO, fileResolver, this::RD_E108); + // TODO // Minima again, differently? // TODO @@ -400,7 +432,7 @@ public String toString(String filename) throws IOException { // Modifiers, IPSJF155-Appendix XII // RD_E198 - loadData(map, MODIFIER_FILE, fileResolver, this::RD_E198); + // TODO // Debug switches (normally zero) // TODO @@ -451,687 +483,4 @@ public String toString(String filename) throws IOException { return map; } - void loadData(Map map, String key, FileResolver fileResolver, ResourceParser parser) - throws IOException, ResourceParseException { - try (var is = fileResolver.resolve((String) map.get(key))) { - map.put(key, parser.parse(is, map)); - } - } - - void loadDataOptional( - Map map, String key, FileResolver fileResolver, ResourceParser parser, - Supplier defaultSupplier - ) throws IOException, ResourceParseException { - @SuppressWarnings("unchecked") - Optional path = (Optional) map.get(key); - if (!path.isPresent()) { - // TODO Log - map.put(key, defaultSupplier.get()); - return; - } - try (var is = fileResolver.resolve(path.get())) { - map.put(key, parser.parse(is, map)); - } - } - - /** - * Loads the information that was in the global arrays BECV, BECNM, and - * BECCOASTAL in Fortran - */ - private Map RD_BEC(InputStream data, Map control) - throws IOException, ResourceParseException { - var parser = new BecDefinitionParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global arrays SP0V, SP0NAMEV in Fortran - */ - private List RD_SP0(InputStream data, Map control) - throws IOException, ResourceParseException { - var parser = new SP0DefinitionParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array VGRPV in Fortran - */ - private Object RD_VGRP(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new EquationGroupParser(); - parser.setHiddenBecs(Arrays.asList("BG")); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array DGRPV in Fortran - */ - private Object RD_DGRP(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new EquationGroupParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array BGRPV in Fortran - */ - private Object RD_BGRP(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new EquationGroupParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array BG1DEFV in Fortran - */ - private Object RD_GRBA1(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new EquationGroupParser(5); - parser.setHiddenBecs(Arrays.asList("BG", "AT")); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array BG1MODV in Fortran - */ - private Object RD_GMBA1(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new EquationModifierParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global arrays STKV, FACTV, and NPCTAREA - * in Fortran - */ - private Object RD_STK33(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new StockingClassFactorParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global arrays ISCURVE and SP_SCV in - * Fortran - */ - private Object RD_E025(InputStream data, Map control) throws IOException, ResourceParseException { - var parser = new SiteCurveParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global V7COE026 arrays ASITELIM, - * T1SITELIM, T2SITELIM in Fortran - */ - private Map RD_E026(InputStream data, Map control) - throws IOException, ResourceParseException { - // ASITELIM for each site curve number and region, the maximum total age that - // site curve will increment to. - // Defaults to 140.0 - // Default to all 140.0 if file not specified - // integer(3, 'siteCurve').float(7, 'ageCoast').float(7,'ageInt').float(7, - // 't1').float(7,'t2') - // ages of <=0.0 should be mapped to 1999.0 - // site curve number 999 is end of data - // site curve number <-1 or >40 invalid. - // site curve number -1 is special. map to max position in array - // Structure: store the age for each region plus t1 and t2 for each site curve. - - var parser = new SiteCurveAgeMaximumParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE040 in Fortran - */ - private MatrixMap3 RD_E040(InputStream data, Map control) - throws IOException, ResourceParseException { - // 10 coefficients by species (SP0) by becs - // 4 String BEC Alias, 2 gap, 1 int coefficient index, 2 int "Indicate", 16x8 - // Float coefficient for species - // Blank bec is ignore line - - // if indicate is 2, map the coefficients in directly - // if indicate is 0 write the first coeffecient from the file to all in the - // array - // if the indicate is 1, add the first from the file to each subsequent one. - - var parser = new CoefficientParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE041 in Fortran - */ - private MatrixMap3 RD_E041(InputStream data, Map control) - throws IOException, ResourceParseException { - var parser = new CoefficientParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE043 in Fortran - */ - private MatrixMap3 RD_E043(InputStream data, Map control) - throws IOException, ResourceParseException { - // Species and Region mapped to two coefficients - var parser = new UpperCoefficientParser(); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE050 in Fortran - */ - private MatrixMap3 RD_YHL1(InputStream data, Map control) - throws IOException, ResourceParseException { - // Species and Region mapped to three coefficients - // coeIndex from 1 - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 - // 11 FORMAT( A2 , 1x, A1, 3f10.0) - - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE051 in Fortran - */ - private MatrixMap3 RD_YHL2(InputStream data, Map control) - throws IOException, ResourceParseException { - // Species and Region mapped to two coefficients - - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE052 in Fortran - */ - private MatrixMap3 RD_YHL3(InputStream data, Map control) - throws IOException, ResourceParseException { - // Species and Region mapped to four coefficients - var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE053 in Fortran - */ - private MatrixMap3 - RD_YHL4(InputStream data, Map control) throws IOException, ResourceParseException { - // Two Species and a Region mapped to 2 coefficients and an equation index - var parser = new HLNonprimaryCoefficientParser(); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE060 in Fortran - */ - private List RD_E060(InputStream data, Map control) - throws IOException, ResourceParseException { - // Map from coefficient index to per-species coefficient - var parser = new BySpeciesDqCoefficientParser(); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE061 in Fortran - */ - private MatrixMap2 RD_E061(InputStream data, Map control) - throws IOException, ResourceParseException { - // Species and Region to 4 floats - var parser = new ComponentSizeParser(control); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE070 in Fortran - */ - private MatrixMap3 RD_UBA1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Uses - // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) - - // Sets - // C 2 coef BY 3 UC by (16 SP0) by (12 BEC) - // COMMON /V7COE070/ COE070( 2 , 3, 16, 12) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) CODE, SP0, BECSCOPE, - // 1 (C(I),I=1,2) - // 11 FORMAT( A4,1x, A2, 1x, A4, 2F10.0) - - // Ignore if first segment is blank - - // If BECSCOPE is empty, apply to all BECs, if it's I or C, apply to BECs in - // that region, otherwise only the one BEC. - - var parser = new UtilComponentBaseAreaParser(); - - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE071 in Fortran - */ - private Object RD_UDQ1(InputStream data, Map control) throws IOException, ResourceParseException { - - // Uses - // COMMON /BECIgrow/ NBECGROW, IBECGV(14), IBECGIC(14) - - // Sets - // C 4 coef BY 4 UC by (16 SP0) by (12 BEC) - // COMMON /V7COE071/ COE071( 4 , 4, 16, 12) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) CODE, SP0, BECSCOPE, - // 1 (C(I),I=1,4) - // 11 FORMAT( A4,9x, A2, 1x, A4, 4F10.0) - - // Ignore if first segment is blank - - // If BECSCOPE is empty, apply to all BECs, if it's I or C, apply to BECs in - // that region, otherwise only the one BEC. - - var parser = new UtilComponentDQParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE080 in Fortran - * - * @see SMALL_COMP_PROBABILITY - */ - private Map RD_SBA1(InputStream data, Map control) - throws IOException, ResourceParseException { - // Sets - // C 4 coe for each of 16 SP0's - // COMMON /V7COE080/ COE080(4, 16) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,4) - // 11 FORMAT( A2, 4f10.0) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - - var parser = new SmallComponentProbabilityParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE081 in Fortran - * - * @see SMALL_COMP_BA - */ - private Map RD_SBA2(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Sets - // C 4 coe for each of 16 SP0's - // COMMON /V7COE081/ COE081(4, 16) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,4) - // 11 FORMAT( A2, 4f10.0) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - - var parser = new SmallComponentBaseAreaParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE082 in Fortran - * - * @see SMALL_COMP_DQ - */ - private Map RD_SDQ1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Sets - // C 2 coe for each of 16 SP0's - // COMMON /V7COE082/ COE082(2, 16) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,2) - // 11 FORMAT( A2, 4f10.0) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - - var parser = new SmallComponentDQParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE085 in Fortran - * - * @see SMALL_COMP_HL - */ - private Map RD_SHL1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Sets - // C 2 coe for each of 16 SP0's - // COMMON /V7COE085/ COE085(2, 16) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,2) - // 11 FORMAT( A2, 4f10.0) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - - var parser = new SmallComponentHLParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE086 in Fortran - * - * @see SMALL_COMP_WS_VOLUME - */ - private Map RD_SVT1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Sets - // C 4 coe for each of 16 SP0's - // COMMON /V7COE086/ COE086(4, 16) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, (C(I),I=1,4) - // 11 FORMAT( A2, 4f10.0) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - - var parser = new SmallComponentWSVolumeParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE090 in Fortran - * - * @see TOTAL_STAND_WHOLE_STEM_VOL - */ - private Map RD_YVT1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Uses - // PARAMETER (MAXGROUP = 80) - - // Sets - // C 9 coe for each of (Up to 80 groups) - // COMMON /V7COE090/ COE090(0:8, MAXGROUP) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) VGRP, (C(I),I=0,8) - // 11 FORMAT( I3, 9f10.0) - - // Ignore if first segment is 0 - - // Coefficient is 0 indexed - // Group is 1 indexed - - var parser = new TotalStandWholeStemParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE091 in Fortran - * - * @see UTIL_COMP_WS_VOLUME - */ - private MatrixMap2 RD_YVT2(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Uses - // PARAMETER (MAXGROUP = 80) - - // Sets - // C 4 coe for (4 UC's) for (Up to 80 groups) - // COMMON /V7COE091/ COE091(4, 4, MAXGROUP) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) UC, VGRP, (C(I),I=1,4) - // 11 FORMAT( I2, I4, 4f10.0) - - // Ignore if first segment is 0 - - // Coefficient is 0 indexed - // UC is 1 indexed - // Group is 1 indexed - - var parser = new UtilComponentWSVolumeParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE092 in Fortran - * - * @see CLOSE_UTIL_VOLUME - */ - private MatrixMap2 RD_YVC1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Uses - // PARAMETER (MAXGROUP = 80) - - // Sets - // C 3 coe for (4 UC's) for (Up to 80 groups) - // COMMON /V7COE092/ COE092(3, 4, MAXGROUP) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) UC, VGRP, (C(I),I=1,3) - // 11 FORMAT( I2, I4, 4f10.0) - - // Ignore if first segment is 0 - - // Group is 1 indexed - // UC is 1 indexed - // Coefficient is 1 indexed - - var parser = new CloseUtilVolumeParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE093 in Fortran - * - * @see VOLUME_NET_DECAY - */ - private MatrixMap2 RD_YVD1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Uses - // PARAMETER (MAXGROUP = 80) - - // Sets - // C 3 coe for (4 UC's) for (Up to 80 groups) - // COMMON /V7COE093/ COE093(3, 4, MAXGROUP) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) UC, DGRP, (C(I),I=1,3) - // 11 FORMAT( I2, I4, 4f10.0) - - // Ignore if first segment is 0 - - // Group is 1 indexed - // UC is 1 indexed - // Coefficient is 1 indexed - - var parser = new VolumeNetDecayParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE094 in Fortran - * - * @see VOLUME_NET_DECAY_WASTE - */ - private Map RD_YVW1(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Uses - // - - // Sets - // Species to 6 coefficients - // COMMON /V7COE094/ COE094(0:5,16) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, A - // 11 FORMAT( A2, 6F9.0) - - // Ignore if first segment is blank - - // Coefficient is 0 indexed - - var parser = new VolumeNetDecayWasteParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE095 in Fortran - * - * @see BREAKAGE - */ - // Example FIPSTART.CTR calls this RD_EMP95 - private Map RD_E095(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Uses - // PARAMETER (MAXBGRP = 40) - - // Sets - // C 4 for (Up to 40 groups) - // COMMON /V7COE095/ COE095(4, MAXBGRP) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) BGRP, A(1), A(2), A(3), A(4) - // 11 FORMAT( I2, 4f9.0) - - // Ignore if first segment is 0 - - // Group is 1 indexed - // Coefficient is 1 indexed - - var parser = new BreakageParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE096 in Fortran - * - * @see VETERAN_LAYER_VOLUME_ADJUST - */ - // Example FIPSTART.CTR calls this RD_YVET - private Map RD_YVVET(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Sets - // COMMON /V7COE096/ COE096( 4, 16) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, C - // 11 FORMAT( A2 , 4f9.5) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - - var parser = new VeteranLayerVolumeAdjustParser(control); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE097 in Fortran - * - * @see VETERAN_LAYER_DQ - */ - private MatrixMap2 RD_YDQV(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Sets - // C 3 coef BY 16 SP0 BY C/I (2) - // COMMON /V7COE097/ COE097( 3, 16, 2) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 - // 11 FORMAT( A2 , 1x, A1, 3f9.0) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - - // Apply to both Regions if blank - - var parser = new VeteranDQParser(); - return parser.parse(data, control); - } - - /** - * Loads the information that was in the global array COE098 in Fortran - * - * @see VETERAN_BQ - */ - private MatrixMap2 RD_E098(InputStream data, Map control) - throws IOException, ResourceParseException { - - // Sets - // C 3 coef BY 16 SP0 BY C/I (2) - // COMMON /V7COE098/ COE098( 3, 16, 2) - - // Parses - // 10 READ(IU_TEMP, 11, ERR=90, END=70) SP0, CI, C1, C2, C3 - // 11 FORMAT( A2 , 1x, A1, 3f9.0) - - // Ignore if first segment is blank - - // Coefficient is 1 indexed - var parser = new VeteranBQParser(control); - return parser.parse(data, control); - } - - /** - * Modifies loaded data based on modifier file - * - * @see MODIFIER_FILE - */ - private Object RD_E198(InputStream data, Map control) throws IOException, ResourceParseException { - // TODO - - return null; - } - - /** - * TODO - */ - private Object RD_E106(InputStream data, Map control) throws IOException, ResourceParseException { - return null; - } - - /** - * TODO - */ - private Object RD_E107(InputStream data, Map control) throws IOException, ResourceParseException { - throw new UnsupportedOperationException(); - } - - /** - * TODO - */ - private Object RD_E108(InputStream data, Map control) throws IOException, ResourceParseException { - throw new UnsupportedOperationException(); - } - } From 7644655e6bb98d56874834bd2e5a1f3fcc6f8f66 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 2 Jun 2023 15:10:16 -0700 Subject: [PATCH 49/98] Implement BEC index substitution on lookup --- .../vdyp/io/parse/BecDefinitionParser.java | 90 +++-- .../bc/gov/nrs/vdyp/io/parse/BecModifier.java | 17 + .../nrs/vdyp/io/parse/CoefficientParser.java | 6 +- .../io/parse/ControlMapSubResourceParser.java | 25 -- .../vdyp/io/parse/ControlledValueParser.java | 4 +- .../vdyp/io/parse/EquationGroupParser.java | 17 +- .../OptionalControlMapSubResourceParser.java | 12 +- .../io/parse/ResourceControlMapModifier.java | 26 ++ .../io/parse/SiteCurveAgeMaximumParser.java | 3 +- .../io/parse/StockingClassFactorParser.java | 3 +- .../vdyp/io/parse/UtilComponentParser.java | 3 +- .../bc/gov/nrs/vdyp/model/BecDefinition.java | 22 +- .../ca/bc/gov/nrs/vdyp/model/BecLookup.java | 171 ++++++++ .../io/parse/BecDefinitionParserTest.java | 192 +++++---- .../vdyp/io/parse/CoefficientParserTest.java | 31 +- .../io/parse/EquationGroupParserTest.java | 26 +- .../bc/gov/nrs/vdyp/model/BecLookupTest.java | 374 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 46 +++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 201 +++++----- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 27 ++ .../nrs/vdyp/fip/FipControlParserTest.java | 4 +- 21 files changed, 1005 insertions(+), 295 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecLookup.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index 2a7b7442d..e6fc07745 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -2,15 +2,16 @@ import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import ca.bc.gov.nrs.vdyp.common.Utils; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.BecLookup; import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.model.BecLookup.Substitution; /** * Parser for a BEC Definition data file @@ -18,7 +19,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class BecDefinitionParser implements ControlMapSubResourceParser> { +public class BecDefinitionParser implements ControlMapSubResourceParser { public static final String CONTROL_KEY = "BEC_DEF"; @@ -31,20 +32,71 @@ public boolean isStopSegment(List segments) { }.strippedString(4, "alias").space(1).value(1, "region", ValueParser.REGION).space(1).strippedString("name"); + private static final Map GROWTH_INDEX = new HashMap<>(); + private static final Map VOLUME_INDEX = new HashMap<>(); + private static final Map DECAY_INDEX = new HashMap<>(); + static { + GROWTH_INDEX.put("AT", 0); + GROWTH_INDEX.put("BG", 0); + GROWTH_INDEX.put("BWBS", 1); + GROWTH_INDEX.put("CDF", 2); + GROWTH_INDEX.put("CWH", 3); + GROWTH_INDEX.put("ESSF", 4); + GROWTH_INDEX.put("ICH", 5); + GROWTH_INDEX.put("IDF", 6); + GROWTH_INDEX.put("MH", 7); + GROWTH_INDEX.put("MS", 8); + GROWTH_INDEX.put("PP", 9); + GROWTH_INDEX.put("SBPS", 10); + GROWTH_INDEX.put("SBS", 11); + GROWTH_INDEX.put("SWB", 12); + + VOLUME_INDEX.put("AT", 1); + VOLUME_INDEX.put("BG", 0); + VOLUME_INDEX.put("BWBS", 2); + VOLUME_INDEX.put("CDF", 3); + VOLUME_INDEX.put("CWH", 4); + VOLUME_INDEX.put("ESSF", 5); + VOLUME_INDEX.put("ICH", 6); + VOLUME_INDEX.put("IDF", 7); + VOLUME_INDEX.put("MH", 8); + VOLUME_INDEX.put("MS", 9); + VOLUME_INDEX.put("PP", 10); + VOLUME_INDEX.put("SBPS", 11); + VOLUME_INDEX.put("SBS", 12); + VOLUME_INDEX.put("SWB", 13); + + DECAY_INDEX.put("AT", 1); + DECAY_INDEX.put("BG", 2); + DECAY_INDEX.put("BWBS", 3); + DECAY_INDEX.put("CDF", 4); + DECAY_INDEX.put("CWH", 5); + DECAY_INDEX.put("ESSF", 6); + DECAY_INDEX.put("ICH", 7); + DECAY_INDEX.put("IDF", 8); + DECAY_INDEX.put("MH", 9); + DECAY_INDEX.put("MS", 10); + DECAY_INDEX.put("PP", 11); + DECAY_INDEX.put("SBPS", 12); + DECAY_INDEX.put("SBS", 13); + DECAY_INDEX.put("SWB", 14); + } + @Override - public Map parse(InputStream is, Map control) - throws IOException, ResourceParseException { - Map result = new HashMap<>(); + public BecLookup parse(InputStream is, Map control) throws IOException, ResourceParseException { + List result = new ArrayList<>(16); result = lineParser.parse(is, result, (v, r) -> { String alias = (String) v.get("alias"); Region region = (Region) v.get("region"); String name = (String) v.get("name"); - var defn = new BecDefinition(alias, region, name); - r.put(alias, defn); + var defn = new BecDefinition( + alias, region, name, GROWTH_INDEX.get(alias), VOLUME_INDEX.get(alias), DECAY_INDEX.get(alias) + ); + r.add(defn); return r; }, control); - return Collections.unmodifiableMap(result); + return new BecLookup(result); } /** @@ -53,8 +105,8 @@ public Map parse(InputStream is, Map cont * @param control Control map containing the parsed BEC definitions. * @return */ - public static Map getBecs(Map control) { - return ResourceParser.expectParsedControl(control, CONTROL_KEY, Map.class); + public static BecLookup getBecs(Map control) { + return ResourceParser.expectParsedControl(control, CONTROL_KEY, BecLookup.class); } /** @@ -64,7 +116,7 @@ public static Map getBecs(Map control) { * @return */ public static Collection getBecsByRegion(Map control, Region region) { - return getBecs(control).values().stream().filter(bec -> bec.getRegion() == region).toList(); + return getBecs(control).getBecsForRegion(region, Substitution.PARTIAL_FILL_OK); } /** @@ -74,7 +126,7 @@ public static Collection getBecsByRegion(Map cont * @return */ public static Collection getBecAliases(Map control) { - return getBecs(control).keySet(); + return getBecs(control).getBecs(Substitution.PARTIAL_FILL_OK).stream().map(BecDefinition::getAlias).toList(); } /** @@ -87,17 +139,7 @@ public static Collection getBecAliases(Map control) { * @return A collection of matching BECs, or the empty set if none match. */ public static Collection getBecsByScope(Map control, String scope) { - if (scope.isBlank()) { - return getBecs(control).values(); - } - return Region.fromAlias(scope).map(region -> getBecsByRegion(control, region)) - .orElseGet(() -> Utils.singletonOrEmpty(getBecs(control).get(scope))); - } - - public static void checkBec(Map control, String bec) throws ValueParseException { - if (!getBecAliases(control).contains(bec)) { - throw new ValueParseException(bec, bec + " is not a valid BEC"); - } + return getBecs(control).getBecsForScope(scope, Substitution.PARTIAL_FILL_OK); } @Override diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java new file mode 100644 index 000000000..8d3fe9845 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java @@ -0,0 +1,17 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.io.FileResolver; + +public class BecModifier implements ControlMapModifier { + + @Override + public void modify(Map control, FileResolver fileResolver) + throws ResourceParseException, IOException { + var becMap = BecDefinitionParser.getBecs(control); + + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java index cf447099c..27e5e686f 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -30,7 +30,7 @@ public class CoefficientParser implements ControlMapSubResourceParser parse(InputStream is, Map control) throws IOException, ResourceParseException { - var becAliases = ResourceParser - .>expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class) - .keySet(); + var becAliases = BecDefinitionParser.getBecAliases(control); var coeIndecies = Stream.iterate(0, x -> x + 1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); var speciesIndecies = Stream.iterate(1, x -> x + 1).limit(NUM_SPECIES).collect(Collectors.toList()); MatrixMap3 result = new MatrixMap3Impl( diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResourceParser.java index 3b047b47d..4a6813d54 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapSubResourceParser.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; -import ca.bc.gov.nrs.vdyp.io.FileResolver; /** * A resource that can be loaded as a sub-resource of a control file. @@ -14,13 +13,6 @@ */ public interface ControlMapSubResourceParser extends ResourceControlMapModifier, ResourceParser { - /** - * The key for this resource's entry in the control map - * - * @return - */ - String getControlKey(); - @Override default void modify(Map control, InputStream data) throws IOException, ResourceParseException { var result = this.parse(data, control); @@ -28,21 +20,4 @@ default void modify(Map control, InputStream data) throws IOExce control.put(getControlKey(), result); } - /** - * Replace the entry in the control map containing the filename for a resource - * with the parsed resource - * - * @param control - * @param fileResolver - * @throws IOException - * @throws ResourceParseException - */ - @Override - default void modify(Map control, FileResolver fileResolver) - throws IOException, ResourceParseException { - var filename = (String) control.get(getControlKey()); - try (InputStream data = fileResolver.resolve(filename)) { - modify(control, data); - } - } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java index 1f31f7f0d..1f6a8388c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java @@ -69,7 +69,9 @@ public static ControlledValueParser> optional(ControlledValuePar */ static final ControlledValueParser BEC = (string, control) -> { var result = string.strip(); - BecDefinitionParser.checkBec(control, result); + if (!BecDefinitionParser.getBecAliases(control).contains(string)) { + throw new ValueParseException(string, string + " is not a valid BEC"); + } return result; }; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index ce55066dd..29743e3c2 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -24,7 +24,7 @@ public abstract class EquationGroupParser implements ControlMapSubResourceParser LineParser lineParser; private Collection hiddenBecs = Collections.emptyList(); - + public EquationGroupParser() { this(3); } @@ -40,9 +40,7 @@ public Map> parse(InputStream is, Map becMap = ResourceParser - .expectParsedControl(control, BecDefinitionParser.CONTROL_KEY, Map.class); + var becKeys = BecDefinitionParser.getBecAliases(control); Map> result = new HashMap<>(); result = lineParser.parse(is, result, (v, r) -> { @@ -52,7 +50,7 @@ public Map> parse(InputStream is, Map def.getAlias().equalsIgnoreCase(sp0Alias))) { throw new ValueParseException(sp0Alias, sp0Alias + " is not an SP0 identifier"); } - if (!becMap.containsKey(becAlias)) { + if (!becKeys.contains(becAlias)) { throw new ValueParseException(becAlias, becAlias + " is not a BEC identifier"); } @@ -73,8 +71,9 @@ public Map> parse(InputStream is, Map errors = new ArrayList<>(); - var sp0Keys = sp0List.stream().map(def -> def.getAlias()).collect(Collectors.toSet()); - var becKeys = becMap.keySet().stream().filter(k -> !hiddenBecs.contains(k)).collect(Collectors.toSet()); + var sp0Keys = SP0DefinitionParser.getSpeciesAliases(control); + + var restrictedBecKeys = becKeys.stream().filter(k -> !hiddenBecs.contains(k)).toList(); var sp0Diff = ExpectationDifference.difference(result.keySet(), sp0Keys); @@ -85,7 +84,7 @@ public Map> parse(InputStream is, Map errors)); for (var entry : result.entrySet()) { - var becDiff = ExpectationDifference.difference(entry.getValue().keySet(), becKeys); + var becDiff = ExpectationDifference.difference(entry.getValue().keySet(), restrictedBecKeys); var sp0Key = entry.getKey(); becDiff.getMissing().stream().map( becKey -> String @@ -106,5 +105,5 @@ public Map> parse(InputStream is, Map hiddenBecs) { this.hiddenBecs = hiddenBecs; } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java index c86f6fdae..0fca826c3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java @@ -8,26 +8,26 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; public interface OptionalControlMapSubResourceParser extends ControlMapSubResourceParser { - + @Override default void modify(Map control, FileResolver fileResolver) throws IOException, ResourceParseException { @SuppressWarnings("unchecked") var filename = (Optional) control.get(getControlKey()); - if(filename.isPresent()) { + if (filename.isPresent()) { try (InputStream data = fileResolver.resolve(filename.get())) { modify(control, data); } } else { defaultModify(control); } - + } - + default void defaultModify(Map control) { control.put(getControlKey(), defaultResult()); } - + T defaultResult(); - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java index 612c568d1..fd2b3ccbc 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java @@ -4,6 +4,8 @@ import java.io.InputStream; import java.util.Map; +import ca.bc.gov.nrs.vdyp.io.FileResolver; + /** * Modifies the control map based on a resource * @@ -14,4 +16,28 @@ public interface ResourceControlMapModifier extends ControlMapModifier { void modify(Map control, InputStream data) throws ResourceParseException, IOException; + /** + * The key for this resource's entry in the control map + * + * @return + */ + String getControlKey(); + + /** + * Replace the entry in the control map containing the filename for a resource + * with the parsed resource + * + * @param control + * @param fileResolver + * @throws IOException + * @throws ResourceParseException + */ + @Override + default void modify(Map control, FileResolver fileResolver) + throws IOException, ResourceParseException { + var filename = (String) control.get(getControlKey()); + try (InputStream data = fileResolver.resolve(filename)) { + modify(control, data); + } + } } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java index 89bc18b61..e7cee0f42 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParser.java @@ -14,7 +14,8 @@ * @author Kevin Smith, Vivid Solutions * */ -public class SiteCurveAgeMaximumParser implements OptionalControlMapSubResourceParser> { +public class SiteCurveAgeMaximumParser + implements OptionalControlMapSubResourceParser> { public static final String CONTROL_KEY = "SITE_CURVE_AGE_MAX"; public static final String SC_KEY = "siteCurve"; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java index b4e670f7c..7804ce1e7 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParser.java @@ -16,7 +16,8 @@ * @author Kevin Smith, Vivid Solutions * */ -public class StockingClassFactorParser implements ControlMapSubResourceParser>> { +public class StockingClassFactorParser + implements ControlMapSubResourceParser>> { public static final String CONTROL_KEY = "STOCKING_CLASS_FACTORS"; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java index a384821a5..a48dc0e06 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java @@ -10,7 +10,8 @@ import ca.bc.gov.nrs.vdyp.model.MatrixMap3; import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; -public abstract class UtilComponentParser implements ControlMapSubResourceParser> { +public abstract class UtilComponentParser + implements ControlMapSubResourceParser> { // "07.5", "12.5", "17.5", "22.5" public final int numCoefficients; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java index 338de4364..3d5df4fbd 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecDefinition.java @@ -4,12 +4,32 @@ public class BecDefinition extends AbstractSpeciesDefinition { final Region region; - public BecDefinition(String alias, Region region, String name) { + final int growthIndex; + final int volumeIndex; + final int decayIndex; + + public BecDefinition(String alias, Region region, String name, int growthIndex, int volumeIndex, int decayIndex) { super(alias, name); this.region = region; + this.growthIndex = growthIndex; + this.volumeIndex = volumeIndex; + this.decayIndex = decayIndex; } public Region getRegion() { return region; } + + public int getGrowthIndex() { + return growthIndex; + } + + public int getVolumeIndex() { + return volumeIndex; + } + + public int getDecayIndex() { + return decayIndex; + } + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecLookup.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecLookup.java new file mode 100644 index 000000000..03ff8a21a --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/BecLookup.java @@ -0,0 +1,171 @@ +package ca.bc.gov.nrs.vdyp.model; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +/** + * Lookup table for BEC definitions + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class BecLookup { + + /** + * Create a bec lookup + * + * @param becMap + */ + public BecLookup(Collection becs) { + this.becMap = new HashMap<>(); + for (var bec : becs) { + becMap.put(bec.getAlias(), bec); + } + } + + /** + * How to handle substitution of empty indices + * + * @author Kevin Smith, Vivid Solutions + * + */ + public static enum Substitution { + /** + * Raise an error if a requested BEC has an empty index. + */ + NONE, + /** + * Substitute empty values for those of the default BEC. + */ + SUBSTITUTE, + /** + * Return BECs with empty indices. + */ + PARTIAL_FILL_OK + }; + + private final Map becMap; + + /** + * Alias of the default BEC + */ + public static final String DEFAULT_BEC = "ESSF"; + + /** + * Empty index value + */ + public static final int EMPTY_INDEX = 0; + + /** + * Get a BEC definition using its alias. + * + * @param alias Alias to look up + * @param sub + * @return + */ + public Optional get(String alias, Substitution sub) { + var bec = becMap.get(alias); + if (Objects.isNull(bec)) { + return Optional.empty(); + } + return Optional.of(doSubstitute(bec, sub)); + + } + + static private int + defaultIndex(BecDefinition bec, BecDefinition defaultBec, Function accessor) { + var index = accessor.apply(bec); + var defaultIndex = accessor.apply(defaultBec); + return index == EMPTY_INDEX ? defaultIndex : index; + } + + private boolean isPartialFill(BecDefinition bec) { + return bec.getGrowthIndex() == EMPTY_INDEX || bec.getVolumeIndex() == EMPTY_INDEX + || bec.getDecayIndex() == EMPTY_INDEX; + } + + private BecDefinition doSubstitute(BecDefinition bec, Substitution sub) { + if (sub == Substitution.PARTIAL_FILL_OK) { + return bec; + } + if (isPartialFill(bec)) { + if (sub == Substitution.NONE) { + throw new IllegalArgumentException("Substitution needed but not requested for BEC " + bec.getAlias()); + } + var defaultBec = get(DEFAULT_BEC, Substitution.PARTIAL_FILL_OK) + .orElseThrow(() -> new IllegalStateException("Could not find default BEC: " + DEFAULT_BEC)); + + bec = new BecDefinition( + bec.getAlias(), bec.getRegion(), bec.getName(), + defaultIndex(bec, defaultBec, BecDefinition::getGrowthIndex), + defaultIndex(bec, defaultBec, BecDefinition::getVolumeIndex), + defaultIndex(bec, defaultBec, BecDefinition::getDecayIndex) + ); + + if (isPartialFill(bec)) { + throw new IllegalStateException( + "Could not substitute indices for BEC " + bec.getAlias() + + ". This is probably because the default BEC, " + DEFAULT_BEC + ", is incomplete." + ); + } + } + return bec; + } + + private boolean isGrowthBec(BecDefinition bec) { + return bec.getGrowthIndex() != EMPTY_INDEX; + } + + /** + * Get all BECs + * + * @param sub Substitution mode to apply. Should not be NONE. + * @return + */ + public Collection getBecs(Substitution sub) { + return this.becMap.values().stream().map(bec -> this.doSubstitute(bec, sub)).toList(); + } + + /** + * Get all growth BECs + * + * @param sub Substitution mode to apply. Should not be NONE. + * @return + */ + public Collection getGrowthBecs(Substitution sub) { + return this.becMap.values().stream().filter(this::isGrowthBec).map(bec -> this.doSubstitute(bec, sub)).toList(); + } + + /** + * Get all becs for a Region + * + * @param region Region to search for + * @param sub Substitution mode to apply. Should not be NONE. + * @return + */ + public Collection getBecsForRegion(Region region, Substitution sub) { + return this.becMap.values().stream().filter(bec -> bec.getRegion() == region) + .map(bec -> this.doSubstitute(bec, sub)).toList(); + } + + /** + * Get all becs for a scope + * + * @param scope Scope to search for + * @param sub Substitution mode to apply. Should not be NONE. + * @return + */ + public Collection getBecsForScope(String scope, Substitution sub) { + if (scope.isBlank()) { + return this.getBecs(sub); + } + return Region.fromAlias(scope).map(region -> this.getBecsForRegion(region, sub)).orElseGet( + () -> this.get(scope, sub).map(Collections::singletonList).orElseGet(Collections::emptyList) + ); + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index 78a30c369..04bc6ab9f 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -1,5 +1,7 @@ package ca.bc.gov.nrs.vdyp.io.parse; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.hasBec; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasEntry; @@ -16,8 +18,8 @@ import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.BecLookup; import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; public class BecDefinitionParserTest { @@ -29,141 +31,183 @@ public void testParse() throws Exception { assertThat( result, - hasEntry( - equalTo("AT"), - allOf( - hasProperty("alias", equalTo("AT")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Alpine Tundra")) + hasBec( + "AT", + present( + allOf( + hasProperty("alias", equalTo("AT")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Alpine Tundra")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("BG"), - allOf( - hasProperty("alias", equalTo("BG")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Bunchgrass")) + hasBec( + "BG", + present( + allOf( + hasProperty("alias", equalTo("BG")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Bunchgrass")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("BWBS"), - allOf( - hasProperty("alias", equalTo("BWBS")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Boreal White and Black Spruce")) + hasBec( + "BWBS", + present( + allOf( + hasProperty("alias", equalTo("BWBS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Boreal White and Black Spruce")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("CDF"), - allOf( - hasProperty("alias", equalTo("CDF")), hasProperty("region", equalTo(Region.COASTAL)), - hasProperty("name", equalTo("Coastal Dougfir")) + hasBec( + "CDF", + present( + allOf( + hasProperty("alias", equalTo("CDF")), + hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Coastal Dougfir")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("CWH"), - allOf( - hasProperty("alias", equalTo("CWH")), hasProperty("region", equalTo(Region.COASTAL)), - hasProperty("name", equalTo("Coastal Western Hemlock")) + hasBec( + "CWH", + present( + allOf( + hasProperty("alias", equalTo("CWH")), + hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Coastal Western Hemlock")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("ESSF"), - allOf( - hasProperty("alias", equalTo("ESSF")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Englemann Sruce -SubAlpine Fir")) + hasBec( + "ESSF", + present( + allOf( + hasProperty("alias", equalTo("ESSF")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Englemann Sruce -SubAlpine Fir")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("ICH"), - allOf( - hasProperty("alias", equalTo("ICH")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Interior Cedar-Hemlock")) + hasBec( + "ICH", + present( + allOf( + hasProperty("alias", equalTo("ICH")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Interior Cedar-Hemlock")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("IDF"), - allOf( - hasProperty("alias", equalTo("IDF")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Interior DougFir")) + hasBec( + "IDF", + present( + allOf( + hasProperty("alias", equalTo("IDF")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Interior DougFir")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("MH"), - allOf( - hasProperty("alias", equalTo("MH")), hasProperty("region", equalTo(Region.COASTAL)), - hasProperty("name", equalTo("Mountain Hemlock")) + hasBec( + "MH", + present( + allOf( + hasProperty("alias", equalTo("MH")), + hasProperty("region", equalTo(Region.COASTAL)), + hasProperty("name", equalTo("Mountain Hemlock")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("MS"), - allOf( - hasProperty("alias", equalTo("MS")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Montane Spruce")) + hasBec( + "MS", + present( + allOf( + hasProperty("alias", equalTo("MS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Montane Spruce")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("PP"), - allOf( - hasProperty("alias", equalTo("PP")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Ponderosa Pine")) + hasBec( + "PP", + present( + allOf( + hasProperty("alias", equalTo("PP")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Ponderosa Pine")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("SBPS"), - allOf( - hasProperty("alias", equalTo("SBPS")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("SubBoreal Pine-Spruce")) + hasBec( + "SBPS", + present( + allOf( + hasProperty("alias", equalTo("SBPS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("SubBoreal Pine-Spruce")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("SBS"), - allOf( - hasProperty("alias", equalTo("SBS")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("SubBoreal Spruce")) + hasBec( + "SBS", + present( + allOf( + hasProperty("alias", equalTo("SBS")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("SubBoreal Spruce")) + ) ) ) ); assertThat( result, - hasEntry( - equalTo("SWB"), - allOf( - hasProperty("alias", equalTo("SWB")), hasProperty("region", equalTo(Region.INTERIOR)), - hasProperty("name", equalTo("Spruce-Willow-Birch")) + hasBec( + "SWB", + present( + allOf( + hasProperty("alias", equalTo("SWB")), + hasProperty("region", equalTo(Region.INTERIOR)), + hasProperty("name", equalTo("Spruce-Willow-Birch")) + ) ) ) ); @@ -183,15 +227,15 @@ public static void populateControlMap(Map controlMap) { */ public static void populateControlMap(Map controlMap, String... aliases) { - Map map = new HashMap<>(); + List becs = new ArrayList<>(); int i = 0; for (var alias : aliases) { - map.put(alias, new BecDefinition(alias, Region.values()[i % 2], "Test " + alias)); + becs.add(new BecDefinition(alias, Region.values()[i % 2], "Test " + alias, 2, 2, 2)); i++; } - controlMap.put(BecDefinitionParser.CONTROL_KEY, map); + controlMap.put(BecDefinitionParser.CONTROL_KEY, new BecLookup(becs)); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java index cfef7cc15..187b54639 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java @@ -9,7 +9,6 @@ import java.util.HashMap; import java.util.Map; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.model.BecDefinition; @@ -29,11 +28,7 @@ public void testParseSimple() throws Exception { Map controlMap = new HashMap<>(); - Map becMap = new HashMap<>(); - becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - - controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + BecDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -54,11 +49,7 @@ public void testBadBec() throws Exception { Map controlMap = new HashMap<>(); - Map becMap = new HashMap<>(); - becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - - controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -75,11 +66,7 @@ public void testBadIndex() throws Exception { Map controlMap = new HashMap<>(); - Map becMap = new HashMap<>(); - becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - - controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -96,11 +83,7 @@ public void testParseDelta() throws Exception { Map controlMap = new HashMap<>(); - Map becMap = new HashMap<>(); - becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - - controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + BecDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -120,11 +103,7 @@ public void testParseFixed() throws Exception { Map controlMap = new HashMap<>(); - Map becMap = new HashMap<>(); - becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - becMap.put("B2", new BecDefinition("B2", Region.COASTAL, "Test BEC 2")); - - controlMap.put(BecDefinitionParser.CONTROL_KEY, becMap); + BecDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index d720eebfc..c2c8cf264 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -183,34 +183,16 @@ public void testRequireNoUnexpectedBec() throws Exception { private HashMap makeControlMapSingle() { var controlMap = new HashMap(); - var becMap = new HashMap(); - var sp0List = new ArrayList(); - - becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - - sp0List.add(new SP0Definition("S1", Optional.empty(), "Test SP0 1")); - - controlMap.put(BecDefinitionParser.CONTROL_KEY, Collections.unmodifiableMap(becMap)); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, Collections.unmodifiableList(sp0List)); + BecDefinitionParserTest.populateControlMap(controlMap, "B1"); + SP0DefinitionParserTest.populateControlMap(controlMap, "S1"); return controlMap; } private HashMap makeControlMap() { var controlMap = new HashMap(); - var becMap = new HashMap(); - var sp0List = new ArrayList(); - - becMap.put("B1", new BecDefinition("B1", Region.COASTAL, "Test BEC 1")); - becMap.put("B2", new BecDefinition("B2", Region.INTERIOR, "Test BEC 2")); - becMap.put("B3", new BecDefinition("B3", Region.COASTAL, "Test BEC 3")); - becMap.put("B4", new BecDefinition("B4", Region.INTERIOR, "Test BEC 4")); - - sp0List.add(new SP0Definition("S1", Optional.empty(), "Test SP0 1")); - sp0List.add(new SP0Definition("S2", Optional.empty(), "Test SP0 2")); - - controlMap.put(BecDefinitionParser.CONTROL_KEY, Collections.unmodifiableMap(becMap)); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, Collections.unmodifiableList(sp0List)); + BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); + SP0DefinitionParserTest.populateControlMap(controlMap, "S1", "S2"); return controlMap; } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java new file mode 100644 index 000000000..62b002066 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java @@ -0,0 +1,374 @@ +package ca.bc.gov.nrs.vdyp.model; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.stringContainsInOrder; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Arrays; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.model.BecLookup.Substitution; + +public class BecLookupTest { + + @Test + public void testSimpleGet() throws Exception { + var lookup = new BecLookup(Arrays.asList(new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6))); + var result = lookup.get("ESSF", Substitution.PARTIAL_FILL_OK); + + assertThat(result, present(hasProperty("alias", is("ESSF")))); + } + + @Test + public void testGetMissing() throws Exception { + var lookup = new BecLookup(Arrays.asList(new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6))); + var result = lookup.get("XX", Substitution.PARTIAL_FILL_OK); + + assertThat(result, notPresent()); + } + + @Test + public void testWithSubstitution() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + var result = lookup.get("BG", Substitution.SUBSTITUTE); + + assertThat( + result, + present( + allOf( + hasProperty("alias", is("BG")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(1)) + ) + ) + ); + } + + @Test + public void testWithSubstitutionButNoneNeeded() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("BWBS", Region.INTERIOR, "BWBS Test", 1, 2, 3), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + var result = lookup.get("BWBS", Substitution.SUBSTITUTE); + + assertThat( + result, + present( + allOf( + hasProperty("alias", is("BWBS")), hasProperty("growthIndex", is(1)), + hasProperty("volumeIndex", is(2)), hasProperty("decayIndex", is(3)) + ) + ) + ); + } + + @Test + public void testWithPartialAllowed() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + var result = lookup.get("BG", Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + present( + allOf( + hasProperty("alias", is("BG")), hasProperty("growthIndex", is(0)), + hasProperty("volumeIndex", is(0)), hasProperty("decayIndex", is(1)) + ) + ) + ); + } + + @Test + public void testWithNoSubstitution() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + var ex = assertThrows(IllegalArgumentException.class, () -> lookup.get("BG", Substitution.NONE)); + + assertThat(ex, hasProperty("message", stringContainsInOrder("Substitution needed", "BEC BG"))); + } + + @Test + public void testWithSubstitutionButDefaultIsMissing() throws Exception { + var lookup = new BecLookup(Arrays.asList(new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1))); + var ex = assertThrows(IllegalStateException.class, () -> lookup.get("BG", Substitution.SUBSTITUTE)); + + assertThat(ex, hasProperty("message", stringContainsInOrder("Could not find default BEC", "ESSF"))); + + } + + @Test + public void testWithSubstitutionButDefaultIsIncomplete() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 0, 5, 6) + ) + ); + var ex = assertThrows(IllegalStateException.class, () -> lookup.get("BG", Substitution.SUBSTITUTE)); + + assertThat(ex, hasProperty("message", stringContainsInOrder("substitute", "BG", "default", "ESSF"))); + + } + + @Test + public void testGetBecsWithSubstitution() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecs(Substitution.SUBSTITUTE); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("BG")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(1)) + ), + allOf( + hasProperty("alias", is("ESSF")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(6)) + ) + ) + ); + } + + @Test + public void testGetBecsAllowingPartial() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecs(Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("BG")), hasProperty("growthIndex", is(0)), + hasProperty("volumeIndex", is(0)), hasProperty("decayIndex", is(1)) + ), + allOf( + hasProperty("alias", is("ESSF")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(6)) + ) + ) + ); + } + + @Test + public void testGetGrowthBecs() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("AT", Region.INTERIOR, "AT Test", 0, 1, 1), + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getGrowthBecs(Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("ESSF")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(6)) + ) + ) + ); + } + + @Test + public void testGetCoastalBecs() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), + new BecDefinition("CWH", Region.COASTAL, "CWH Test", 2, 3, 4), + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecsForRegion(Region.COASTAL, Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("CDF")), hasProperty("growthIndex", is(1)), + hasProperty("volumeIndex", is(2)), hasProperty("decayIndex", is(3)) + ), + allOf( + hasProperty("alias", is("CWH")), hasProperty("growthIndex", is(2)), + hasProperty("volumeIndex", is(3)), hasProperty("decayIndex", is(4)) + ) + ) + ); + } + + @Test + public void testGetInteriorBecs() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), + new BecDefinition("CWH", Region.COASTAL, "CWH Test", 2, 3, 4), + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecsForRegion(Region.INTERIOR, Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("BG")), hasProperty("growthIndex", is(0)), + hasProperty("volumeIndex", is(0)), hasProperty("decayIndex", is(1)) + ), + allOf( + hasProperty("alias", is("ESSF")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(6)) + ) + ) + ); + } + + @Test + public void testGetByBlankScope() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), + new BecDefinition("CWH", Region.COASTAL, "CWH Test", 2, 3, 4), + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecsForScope("", Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("CDF")), hasProperty("growthIndex", is(1)), + hasProperty("volumeIndex", is(2)), hasProperty("decayIndex", is(3)) + ), + allOf( + hasProperty("alias", is("CWH")), hasProperty("growthIndex", is(2)), + hasProperty("volumeIndex", is(3)), hasProperty("decayIndex", is(4)) + ), + allOf( + hasProperty("alias", is("BG")), hasProperty("growthIndex", is(0)), + hasProperty("volumeIndex", is(0)), hasProperty("decayIndex", is(1)) + ), + allOf( + hasProperty("alias", is("ESSF")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(6)) + ) + ) + ); + } + + @Test + public void testGetByRegionScope() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), + new BecDefinition("CWH", Region.COASTAL, "CWH Test", 2, 3, 4), + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecsForScope("I", Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("BG")), hasProperty("growthIndex", is(0)), + hasProperty("volumeIndex", is(0)), hasProperty("decayIndex", is(1)) + ), + allOf( + hasProperty("alias", is("ESSF")), hasProperty("growthIndex", is(4)), + hasProperty("volumeIndex", is(5)), hasProperty("decayIndex", is(6)) + ) + ) + ); + } + + @Test + public void testGetByBecScope() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), + new BecDefinition("CWH", Region.COASTAL, "CWH Test", 2, 3, 4), + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecsForScope("CDF", Substitution.PARTIAL_FILL_OK); + + assertThat( + result, + containsInAnyOrder( + allOf( + hasProperty("alias", is("CDF")), hasProperty("growthIndex", is(1)), + hasProperty("volumeIndex", is(2)), hasProperty("decayIndex", is(3)) + ) + ) + ); + } + + @Test + public void testGetByMissingScope() throws Exception { + var lookup = new BecLookup( + Arrays.asList( + new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), + new BecDefinition("CWH", Region.COASTAL, "CWH Test", 2, 3, 4), + new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), + new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6) + ) + ); + + var result = lookup.getBecsForScope("X", Substitution.PARTIAL_FILL_OK); + + assertThat(result, empty()); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index 97b715a69..a63e16113 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -16,6 +16,9 @@ import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.BecLookup; +import ca.bc.gov.nrs.vdyp.model.BecLookup.Substitution; import ca.bc.gov.nrs.vdyp.model.MatrixMap; /** @@ -228,4 +231,47 @@ public void describeTo(Description description) { }; } + + /** + * Matches a BecLookup that contains a bec with the specified alias that matches + * the given matcher. + */ + public static Matcher + hasBec(String alias, Matcher> valueMatcher, Substitution sub) { + return new TypeSafeDiagnosingMatcher() { + + @Override + protected boolean matchesSafely(BecLookup map, Description mismatchDescription) { + var result = map.get(alias, sub); + if (Objects.isNull(result)) { + mismatchDescription.appendText("entry for ").appendValue(alias).appendText(" was not present"); + return false; + } + if (!valueMatcher.matches(result)) { + mismatchDescription.appendText("entry for ").appendValue(alias).appendText(" was present but "); + valueMatcher.describeMismatch(result, mismatchDescription); + return false; + } + + return true; + } + + @Override + public void describeTo(Description description) { + description.appendText("A BEC Lookup with an entry for ").appendValue(alias).appendText(" that ") + .appendDescriptionOf(valueMatcher); + } + + }; + + } + + /** + * Matches a BecLookup that contains a bec with the specified alias that matches + * the given matcher. + */ + public static Matcher hasBec(String alias, Matcher> valueMatcher) { + return hasBec(alias, valueMatcher, Substitution.PARTIAL_FILL_OK); + } + } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index a69805c1e..9901b27d1 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -13,6 +13,7 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.BecModifier; import ca.bc.gov.nrs.vdyp.io.parse.BreakageEquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.BreakageParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; @@ -241,12 +242,12 @@ public String toString(String filename) throws IOException { new BecDefinitionParser(), // DEF_BEC - // TODO + new BecModifier(), // RD_SP0 new SP0DefinitionParser() ); - + List GROUP_DEFINITIONS = Arrays.asList( // RD_VGRP @@ -264,17 +265,17 @@ public String toString(String filename) throws IOException { // RD_GMBA1 new EquationModifierParser() ); - + List FIPSTART_ONLY = Arrays.asList( // RD_STK33 new StockingClassFactorParser() - // TODO minima? - /* - * READ(CNTRV(197), 197, ERR= 912 ) FMINH, FMINBA, FMINBAF,FMINVetH IF (FMINVetH - * .le. 0.0) FMINVetH=10.0 - */ + // TODO minima? + /* + * READ(CNTRV(197), 197, ERR= 912 ) FMINH, FMINBA, FMINBAF,FMINVetH IF (FMINVetH + * .le. 0.0) FMINVetH=10.0 + */ ); List SITE_CURVES = Arrays.asList( @@ -288,93 +289,95 @@ public String toString(String filename) throws IOException { // RD_E026 new SiteCurveAgeMaximumParser() ); - + List COEFFICIENTS = Arrays.asList( - // RD_E040 - new CoefficientParser(COE_BA), - - // RD_E041 - new CoefficientParser(COE_DQ), - - // RD_E043 - new UpperCoefficientParser(), - - // RD_YHL1 - new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, HL_PRIMARY_SP_EQN_P1), - - // RD_YHL2 - new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2, HL_PRIMARY_SP_EQN_P2), - - // RD_YHL3 - new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3, HL_PRIMARY_SP_EQN_P3), - - // RD_YHL4 - new HLNonprimaryCoefficientParser(), - - // RD_E060 - new BySpeciesDqCoefficientParser(), - - // Min and max DQ by species - - // RD_E061 - new ComponentSizeParser(), - - // RD_UBA1 - new UtilComponentBaseAreaParser(), - - // RD_UDQ1 - new UtilComponentDQParser(), - - // Small Component (4.5 to 7.5 cm) - - // RD_SBA1 - new SmallComponentProbabilityParser(), - - // RD_SBA2 - new SmallComponentBaseAreaParser(), - - // RD_SDQ1 - new SmallComponentDQParser(), - - // RD_SHL1 - new SmallComponentHLParser(), - - // RD_SVT1 - new SmallComponentWSVolumeParser(), - - // Standard Volume Relationships - - // RD_YVT1 - new TotalStandWholeStemParser(), - - // RD_YVT2 - new UtilComponentWSVolumeParser(), - - // RD_YVC1 - new CloseUtilVolumeParser(), - - // RD_YVD1 - new VolumeNetDecayParser(), - - // RD_YVW1 - new VolumeNetDecayWasteParser(), - - // RD_E095 - new BreakageParser(), - - // Veterans - - // RD_YVVET - new VeteranLayerVolumeAdjustParser(), - - // RD_YDQV - new VeteranDQParser(), - - // RD_E098 - new VeteranBQParser() + // RD_E040 + new CoefficientParser(COE_BA), + + // RD_E041 + new CoefficientParser(COE_DQ), + + // RD_E043 + new UpperCoefficientParser(), + + // RD_YHL1 + new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, HL_PRIMARY_SP_EQN_P1), + + // RD_YHL2 + new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2, HL_PRIMARY_SP_EQN_P2), + + // RD_YHL3 + new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3, HL_PRIMARY_SP_EQN_P3), + + // RD_YHL4 + new HLNonprimaryCoefficientParser(), + + // RD_E060 + new BySpeciesDqCoefficientParser(), + + // Min and max DQ by species + + // RD_E061 + new ComponentSizeParser(), + + // RD_UBA1 + new UtilComponentBaseAreaParser(), + + // RD_UDQ1 + new UtilComponentDQParser(), + + // Small Component (4.5 to 7.5 cm) + + // RD_SBA1 + new SmallComponentProbabilityParser(), + + // RD_SBA2 + new SmallComponentBaseAreaParser(), + + // RD_SDQ1 + new SmallComponentDQParser(), + + // RD_SHL1 + new SmallComponentHLParser(), + + // RD_SVT1 + new SmallComponentWSVolumeParser(), + + // Standard Volume Relationships + + // RD_YVT1 + new TotalStandWholeStemParser(), + + // RD_YVT2 + new UtilComponentWSVolumeParser(), + + // RD_YVC1 + new CloseUtilVolumeParser(), + + // RD_YVD1 + new VolumeNetDecayParser(), + + // RD_YVW1 + new VolumeNetDecayWasteParser(), + + // RD_E095 + new BreakageParser(), + + // Veterans + + // RD_YVVET + new VeteranLayerVolumeAdjustParser(), + + // RD_YDQV + new VeteranDQParser(), + + // RD_E098 + new VeteranBQParser() ); - - private void applyModifiers(Mapcontrol, List modifiers, FileResolver fileResolver) throws ResourceParseException, IOException { + + private void + applyModifiers(Map control, List modifiers, FileResolver fileResolver) + throws ResourceParseException, IOException { for (var modifier : modifiers) { modifier.modify(control, fileResolver); } @@ -384,13 +387,13 @@ private void applyModifiers(Mapcontrol, List var map = controlParser.parse(is, Collections.emptyMap()); applyModifiers(map, BASIC_DEFINITIONS, fileResolver); - + // Read Groups - + applyModifiers(map, GROUP_DEFINITIONS, fileResolver); int jprogram = 1; // FIPSTART only TODO Track this down - + if (jprogram == 1) { applyModifiers(map, FIPSTART_ONLY, fileResolver); } @@ -398,12 +401,12 @@ private void applyModifiers(Mapcontrol, List applyModifiers(map, SITE_CURVES, fileResolver); // Coeff for Empirical relationships - + applyModifiers(map, COEFFICIENTS, fileResolver); // Initiation items NOT for FIPSTART if (jprogram > 1) { - + throw new UnsupportedOperationException(); // RD_E106 // TODO @@ -432,7 +435,7 @@ private void applyModifiers(Mapcontrol, List // Modifiers, IPSJF155-Appendix XII // RD_E198 - // TODO + // new ModifierParser().modify(map, fileResolver); // TODO // Debug switches (normally zero) // TODO diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java new file mode 100644 index 000000000..1fb2f9a79 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -0,0 +1,27 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.io.parse.ResourceControlMapModifier; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; + +public class ModifierParser implements ResourceControlMapModifier { + + public static final String CONTROL_KEY = "MODIFIERS"; + + public static final int MAX_MODS = 60; + + @Override + public void modify(Map control, InputStream data) throws ResourceParseException, IOException { + // TODO + + } + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + +} diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 88f2f2342..5bb10e971 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -1,5 +1,6 @@ package ca.bc.gov.nrs.vdyp.fip; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.hasBec; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.hasSpecificEntry; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; @@ -32,6 +33,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParserTest; import ca.bc.gov.nrs.vdyp.model.BecDefinition; +import ca.bc.gov.nrs.vdyp.model.BecLookup; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.model.SiteCurve; @@ -56,7 +58,7 @@ public void testParseBec() throws Exception { result, (Matcher) hasSpecificEntry( BecDefinitionParser.CONTROL_KEY, - allOf(instanceOf(Map.class), hasEntry(is("AT"), instanceOf(BecDefinition.class))) + allOf(instanceOf(BecLookup.class), hasBec("AT", present(instanceOf(BecDefinition.class)))) ) ); } From e065c77b060bef5295d749c6f84a36c681ee3840 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 19 Jun 2023 16:29:25 -0700 Subject: [PATCH 50/98] Stub for modifier parser --- .../OptionalControlMapSubResourceParser.java | 31 ++++------- .../OptionalResourceControlMapModifier.java | 40 ++++++++++++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 12 +++- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 13 ++++- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 55 +++++++++++++++++++ 5 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java create mode 100644 vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java index 0fca826c3..9519c39cf 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java @@ -1,33 +1,24 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.io.IOException; -import java.io.InputStream; import java.util.Map; -import java.util.Optional; -import ca.bc.gov.nrs.vdyp.io.FileResolver; -public interface OptionalControlMapSubResourceParser extends ControlMapSubResourceParser { - - @Override - default void modify(Map control, FileResolver fileResolver) - throws IOException, ResourceParseException { - @SuppressWarnings("unchecked") - var filename = (Optional) control.get(getControlKey()); - if (filename.isPresent()) { - try (InputStream data = fileResolver.resolve(filename.get())) { - modify(control, data); - } - } else { - defaultModify(control); - } - - } +/** + * Replace a control map entry referencing a file with a parsed version of that file if it was specified, otherwise initialize that entry with a default. + * @author Kevin Smith, Vivid Solutions + * + * @param + */ +public interface OptionalControlMapSubResourceParser extends ControlMapSubResourceParser, OptionalResourceControlMapModifier { default void defaultModify(Map control) { control.put(getControlKey(), defaultResult()); } + /** + * The default value + * @return + */ T defaultResult(); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java new file mode 100644 index 000000000..1e972c727 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java @@ -0,0 +1,40 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Optional; + +import ca.bc.gov.nrs.vdyp.io.FileResolver; + +/** + * Modify a control map based on a resource referenced within it if it is specified, otherwise perform a default operation. + * + * @author Kevin Smith, Vivid Solutions + * + */ +public interface OptionalResourceControlMapModifier extends ResourceControlMapModifier { + + @Override + default void modify(Map control, FileResolver fileResolver) + throws IOException, ResourceParseException { + @SuppressWarnings("unchecked") + var filename = (Optional) control.get(getControlKey()); + if (filename.isPresent()) { + try (InputStream data = fileResolver.resolve(filename.get())) { + modify(control, data); + } + } else { + defaultModify(control); + } + + } + + /** + * Perform this operation on the control map if no resource is specified. + * + * @param control + */ + void defaultModify(Map control); + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 9901b27d1..1708d2294 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -109,7 +109,7 @@ public class FipControlParser { public static final String VETERAN_LAYER_DQ = "VETERAN_LAYER_DQ"; public static final String VETERAN_BQ = VeteranBQParser.CONTROL_KEY; public static final String MINIMA = "MINIMA"; - public static final String MODIFIER_FILE = "MODIFIER_FILE"; + public static final String MODIFIER_FILE = ModifierParser.CONTROL_KEY; public static final String DEBUG_SWITCHES = "DEBUG_SWITCHES"; public static final String MAX_NUM_POLY = "MAX_NUM_POLY"; public static final String BEC_DEF = BecDefinitionParser.CONTROL_KEY; @@ -176,7 +176,7 @@ public class FipControlParser { .record(197, MINIMA, ValueParser.list(ValueParser.FLOAT)) // Minimum Height, Minimum BA, Min BA fully // stocked. - .record(198, MODIFIER_FILE, FILENAME) // RD_E198 IPSJF155, XII + .record(198, MODIFIER_FILE, ValueParser.optional(FILENAME)) // RD_E198 IPSJF155, XII .record(199, DEBUG_SWITCHES, ValueParser.list(ValueParser.INTEGER)) // IPSJF155 /* @@ -374,6 +374,12 @@ public String toString(String filename) throws IOException { // RD_E098 new VeteranBQParser() ); + + List ADDITIONAL_MODIFIERS = Arrays.asList( + + // RD_E198 + new ModifierParser() + ); private void applyModifiers(Map control, List modifiers, FileResolver fileResolver) @@ -435,7 +441,7 @@ public String toString(String filename) throws IOException { // Modifiers, IPSJF155-Appendix XII // RD_E198 - // new ModifierParser().modify(map, fileResolver); // TODO + applyModifiers(map, ADDITIONAL_MODIFIERS, fileResolver); // Debug switches (normally zero) // TODO diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 1fb2f9a79..746e609f2 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -4,10 +4,10 @@ import java.io.InputStream; import java.util.Map; -import ca.bc.gov.nrs.vdyp.io.parse.ResourceControlMapModifier; +import ca.bc.gov.nrs.vdyp.io.parse.OptionalResourceControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; -public class ModifierParser implements ResourceControlMapModifier { +public class ModifierParser implements OptionalResourceControlMapModifier { public static final String CONTROL_KEY = "MODIFIERS"; @@ -15,7 +15,9 @@ public class ModifierParser implements ResourceControlMapModifier { @Override public void modify(Map control, InputStream data) throws ResourceParseException, IOException { - // TODO + // Modifiers, IPSJF155-Appendix XII + + // RD_E198 } @@ -24,4 +26,9 @@ public String getControlKey() { return CONTROL_KEY; } + @Override + public void defaultModify(Map control) { + // Do nothing + } + } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java new file mode 100644 index 000000000..5dd5e2215 --- /dev/null +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -0,0 +1,55 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.io.FileResolver; + +public class ModifierParserTest { + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testNoFilenameForControlFile() throws Exception { + var parser = new ModifierParser(); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.empty()); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + fail("Should not call FileResolver::resolve"); + return null; + } + + @Override + public String toString(String filename) throws IOException { + fail("Should not call FileResolver::toString"); + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + assertThat(controlMap, Matchers.aMapWithSize(1)); + assertThat(controlMap, (Matcher) hasEntry(is(ModifierParser.CONTROL_KEY), notPresent())); + + } + +} From ff21e3a1146b0a51ff2fb72b3091facabadc6bc5 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 20 Jun 2023 11:08:45 -0700 Subject: [PATCH 51/98] Handle missing control file --- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 5dd5e2215..7acc1b227 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -14,14 +14,15 @@ import org.hamcrest.Matcher; import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.io.FileResolver; +@SuppressWarnings({ "unchecked", "rawtypes" }) public class ModifierParserTest { - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testNoFilenameForControlFile() throws Exception { var parser = new ModifierParser(); @@ -51,5 +52,35 @@ public String toString(String filename) throws IOException { assertThat(controlMap, (Matcher) hasEntry(is(ModifierParser.CONTROL_KEY), notPresent())); } + @Test + public void testMissingControlFile() throws Exception { + var parser = new ModifierParser(); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + throw new IOException(); + } + + @Override + public String toString(String filename) throws IOException { + fail("Should not call FileResolver::toString"); + return filename; + } + + }; + + + var ex = Assertions.assertThrows(IOException.class, ()->parser.modify(controlMap, fileResolver)); + + assertThat(ex, Matchers.notNullValue()); + + } } From 588187705239e328f9361a269fbaf0263e7c76cd Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 20 Jun 2023 17:10:31 -0700 Subject: [PATCH 52/98] Set default modifiers for BA and DQ --- .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 6 ++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap2.java | 5 ++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap3.java | 5 ++ .../bc/gov/nrs/vdyp/model/MatrixMapImpl.java | 9 ++- .../bc/gov/nrs/vdyp/model/MatrixMapTest.java | 22 ++++++ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 70 +++++++++++++++++++ .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 33 ++++++++- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 56 ++++++++++++++- 8 files changed, 200 insertions(+), 6 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java index 35c7afd5e..42146bbfe 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -107,4 +107,10 @@ public Set keySet() { // Can't cast it if it doesn't have 1 dimensions throw new ClassCastException("MatrixMap did not have 1 dimension"); } + + /** + * Set all cells to the given value + * @param value + */ + public void setAll(T value); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java index 5c980d597..608a0c450 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java @@ -62,6 +62,11 @@ public boolean any(Predicate pred) { return o.any(pred); } + @Override + public void setAll(CV value) { + o.setAll(value); + } + }; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java index fa9c51a37..3368bf4d1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java @@ -62,6 +62,11 @@ public boolean any(Predicate pred) { return o.any(pred); } + @Override + public void setAll(CV value) { + o.setAll(value); + } + }; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java index 15f67ce89..a91d85416 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java @@ -2,7 +2,7 @@ import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -30,7 +30,7 @@ public MatrixMapImpl(Collection> dimensions) { throw new IllegalArgumentException("Each dimension must have at least one value"); } maps = dimensions.stream().map(dim -> { - var map = new HashMap(dim.size()); + var map = new LinkedHashMap(dim.size()); int i = 0; for (var o : dim) { map.put(o, i); @@ -110,4 +110,9 @@ public int getNumDimensions() { return maps.size(); } + @Override + public void setAll(T value) { + Arrays.fill(matrix, value); + } + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index 260cb49ee..b98b313d4 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -117,5 +117,27 @@ public void testFullMap() { assertThat(map.getM("b", 1), present(is('Y'))); assertThat(map.getM("b", 2), present(is('Z'))); } + + @Test + public void testSetAll() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1, 2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + map.putM('W', "a", 1); + map.putM('X', "a", 2); + map.putM('Y', "b", 1); + + map.setAll('A'); + + assertThat(map, hasProperty("full", is(true))); + assertThat(map, hasProperty("empty", is(false))); + + assertThat(map.getM("a", 1), present(is('A'))); + assertThat(map.getM("a", 2), present(is('A'))); + assertThat(map.getM("b", 1), present(is('A'))); + assertThat(map.getM("b", 2), present(is('A'))); + } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index a63e16113..ab514661d 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -4,9 +4,11 @@ import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.not; +import java.util.Arrays; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; @@ -198,6 +200,74 @@ public void describeMismatch(Object item, Description description) { } + /** + * Match a MatrixMap if all of its values match the given matcher + * @param + * @param valueMatcher + * @return + */ + public static Matcher> mmAll(Matcher valueMatcher) { + return new TypeSafeDiagnosingMatcher>() { + + @Override + public void describeTo(Description description) { + description.appendText("MatrixMap with all values ").appendDescriptionOf(valueMatcher); + } + + @Override + protected boolean matchesSafely(MatrixMap item, Description mismatchDescription) { + if(item.all(valueMatcher::matches)) { + return true; + } + // TODO This could stand to be more specific + mismatchDescription.appendText("Not all values were ").appendDescriptionOf(valueMatcher); + return false; + } + + }; + } + + /** + * Match a MatrixMap if its dimensions match the given matchers + * @param + * @param + * @param valueMatcher + * @return + */ + @SafeVarargs + public static Matcher> mmDimensions(Matcher>... dimensionMatchers) { + return new TypeSafeDiagnosingMatcher>() { + + @Override + public void describeTo(Description description) { + description.appendList("MatrixMap with dimensions that ", ", ", "", Arrays.asList(dimensionMatchers)); + } + + @Override + protected boolean matchesSafely(MatrixMap item, Description mismatchDescription) { + var dimensions = item.getDimensions(); + if(dimensionMatchers.length!=dimensions.size()) { + mismatchDescription.appendText("Expected ").appendValue(dimensionMatchers.length).appendText(" dimensions but had ").appendValue(dimensions.size()); + return false; + } + var result = true; + for (int i=0; i control, InputStream data) throws Resourc // Modifiers, IPSJF155-Appendix XII // RD_E198 - + + defaultModify(control); } @Override @@ -28,7 +48,16 @@ public String getControlKey() { @Override public void defaultModify(Map control) { - // Do nothing + var spAliases = SP0DefinitionParser.getSpeciesAliases(control); + var regions = Arrays.asList(Region.values()); + + var baModifiers = new MatrixMap2Impl(spAliases, regions); + baModifiers.setAll(1.0f); + control.put(CONTROL_KEY_MOD200_BA, baModifiers); + + var dqModifiers = new MatrixMap2Impl(spAliases, regions); + dqModifiers.setAll(1.0f); + control.put(CONTROL_KEY_MOD200_DQ, dqModifiers); } } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 7acc1b227..c20d4172c 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -1,7 +1,13 @@ package ca.bc.gov.nrs.vdyp.fip; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.hasSpecificEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmAll; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmDimensions; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.arrayContaining; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.fail; @@ -18,6 +24,9 @@ import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.io.FileResolver; +import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; +import ca.bc.gov.nrs.vdyp.model.Region; +import ca.bc.gov.nrs.vdyp.test.TestUtils; @SuppressWarnings({ "unchecked", "rawtypes" }) public class ModifierParserTest { @@ -29,6 +38,7 @@ public void testNoFilenameForControlFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.empty()); + SP0DefinitionParserTest.populateControlMap(controlMap); var fileResolver = new FileResolver() { @@ -48,16 +58,21 @@ public String toString(String filename) throws IOException { parser.modify(controlMap, fileResolver); - assertThat(controlMap, Matchers.aMapWithSize(1)); - assertThat(controlMap, (Matcher) hasEntry(is(ModifierParser.CONTROL_KEY), notPresent())); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, notPresent())); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmAll(is(1.0f)))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmAll(is(1.0f)))); } + @Test public void testMissingControlFile() throws Exception { var parser = new ModifierParser(); Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMap(controlMap); var fileResolver = new FileResolver() { @@ -83,4 +98,41 @@ public String toString(String filename) throws IOException { } + @Test + public void testLoadEmptyFile() throws Exception { + var parser = new ModifierParser(); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMap(controlMap); + + var is = TestUtils.makeStream(); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + + parser.modify(controlMap, fileResolver); + + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, present(is("testFilename")))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmAll(is(1.0f)))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmAll(is(1.0f)))); + + } + } From 8274efeca71fe6d3e5977b74e97f80156ce8462d Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 20 Jun 2023 17:23:50 -0700 Subject: [PATCH 53/98] Defaults for decay and waste modifiers --- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 18 +++++++++++++++- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 21 +++++++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 9cc1262b3..da2f5f3b4 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -27,7 +27,15 @@ public class ModifierParser implements OptionalResourceControlMapModifier { * MatrixMap2 of Species ID, Region to Float */ public static final String CONTROL_KEY_MOD200_DQ = "DQ_MODIFIERS"; - public static final String CONTROL_KEY_MOD301 = "DECAY_WASTE_MODIFIERS"; + /** + * MatrixMap2 of Species ID, Region to Float + */ + public static final String CONTROL_KEY_MOD301_DECAY = "DECAY_MODIFIERS"; + /** + * MatrixMap2 of Species ID, Region to Float + */ + public static final String CONTROL_KEY_MOD301_WASTE = "WASTE_MODIFIERS"; + public static final String CONTROL_KEY_MOD400 = "HL_MODIFIERS"; public static final int MAX_MODS = 60; @@ -58,6 +66,14 @@ public void defaultModify(Map control) { var dqModifiers = new MatrixMap2Impl(spAliases, regions); dqModifiers.setAll(1.0f); control.put(CONTROL_KEY_MOD200_DQ, dqModifiers); + + var decayModifiers = new MatrixMap2Impl(spAliases, regions); + decayModifiers.setAll(0.0f); + control.put(CONTROL_KEY_MOD301_DECAY, decayModifiers); + + var wasteModifiers = new MatrixMap2Impl(spAliases, regions); + wasteModifiers.setAll(0.0f); + control.put(CONTROL_KEY_MOD301_WASTE, wasteModifiers); } } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index c20d4172c..3726ceceb 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -6,9 +6,7 @@ import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.fail; @@ -59,11 +57,17 @@ public String toString(String filename) throws IOException { parser.modify(controlMap, fileResolver); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, notPresent())); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmAll(is(1.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmAll(is(1.0f)))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmAll(is(0.0f)))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmAll(is(0.0f)))); + } @Test @@ -128,11 +132,16 @@ public String toString(String filename) throws IOException { parser.modify(controlMap, fileResolver); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, present(is("testFilename")))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmAll(is(1.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains(Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmAll(is(1.0f)))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmAll(is(0.0f)))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmAll(is(0.0f)))); } } From c0e9bb0e4a7e2316ab44d2128617b6403e9bd32e Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 20 Jun 2023 17:37:35 -0700 Subject: [PATCH 54/98] Clean up tests --- .../io/parse/SP0DefinitionParserTest.java | 14 ++++++++ .../gov/nrs/vdyp/fip/ModifierParserTest.java | 32 ++++++++----------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index edc03b449..ef95335e7 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -247,6 +247,20 @@ public void testErrorPreferenceDuplicate() throws Exception { public static void populateControlMap(Map controlMap) { populateControlMap(controlMap, "S1", "S2"); } + + /** + * Add a mock control map entry for SP0 parse results with 16 species + */ + public static void populateControlMapReal(Map controlMap) { + populateControlMap(controlMap, getSpeciesAliases()); + } + + /** + * Get the species aliases expected + */ + public static String[] getSpeciesAliases() { + return new String[]{"AC", "AT", "B", "C", "D", "E", "F", "H", "L", "MB", "PA", "PL", "PW", "PY", "S", "Y"}; + } /** * Add a mock control map entry for SP0 parse results diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 3726ceceb..55b2ef4df 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -36,7 +36,7 @@ public void testNoFilenameForControlFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.empty()); - SP0DefinitionParserTest.populateControlMap(controlMap); + SP0DefinitionParserTest.populateControlMapReal(controlMap); var fileResolver = new FileResolver() { @@ -57,17 +57,6 @@ public String toString(String filename) throws IOException { parser.modify(controlMap, fileResolver); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, notPresent())); - - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmAll(is(1.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmAll(is(1.0f)))); - - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmAll(is(0.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmAll(is(0.0f)))); - } @Test @@ -108,7 +97,7 @@ public void testLoadEmptyFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMap(controlMap); + SP0DefinitionParserTest.populateControlMapReal(controlMap); var is = TestUtils.makeStream(); @@ -131,17 +120,22 @@ public String toString(String filename) throws IOException { parser.modify(controlMap, fileResolver); + modifierDefaultAsserts(controlMap); + } + + protected void modifierDefaultAsserts(Map controlMap) { + var expectedSp0Aliases = SP0DefinitionParserTest.getSpeciesAliases(); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, present(is("testFilename")))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmAll(is(1.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmAll(is(1.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmAll(is(0.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmDimensions(contains("S1", "S2"), contains((Object[])Region.values())))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmAll(is(0.0f)))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmAll(is(0.0f)))); } - } From 86e8396f84e82b83e11af709f61eb78310997302 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 20 Jun 2023 17:39:54 -0700 Subject: [PATCH 55/98] Run formatter --- .../OptionalControlMapSubResourceParser.java | 9 ++- .../OptionalResourceControlMapModifier.java | 11 +-- .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 3 +- .../io/parse/SP0DefinitionParserTest.java | 6 +- .../bc/gov/nrs/vdyp/model/MatrixMapTest.java | 4 +- .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 23 +++--- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 2 +- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 14 ++-- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 75 ++++++++++++------- 9 files changed, 88 insertions(+), 59 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java index 9519c39cf..a0dd7224f 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalControlMapSubResourceParser.java @@ -2,14 +2,16 @@ import java.util.Map; - /** - * Replace a control map entry referencing a file with a parsed version of that file if it was specified, otherwise initialize that entry with a default. + * Replace a control map entry referencing a file with a parsed version of that + * file if it was specified, otherwise initialize that entry with a default. + * * @author Kevin Smith, Vivid Solutions * * @param */ -public interface OptionalControlMapSubResourceParser extends ControlMapSubResourceParser, OptionalResourceControlMapModifier { +public interface OptionalControlMapSubResourceParser + extends ControlMapSubResourceParser, OptionalResourceControlMapModifier { default void defaultModify(Map control) { control.put(getControlKey(), defaultResult()); @@ -17,6 +19,7 @@ default void defaultModify(Map control) { /** * The default value + * * @return */ T defaultResult(); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java index 1e972c727..9c61d125a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/OptionalResourceControlMapModifier.java @@ -8,13 +8,14 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; /** - * Modify a control map based on a resource referenced within it if it is specified, otherwise perform a default operation. - * + * Modify a control map based on a resource referenced within it if it is + * specified, otherwise perform a default operation. + * * @author Kevin Smith, Vivid Solutions * */ public interface OptionalResourceControlMapModifier extends ResourceControlMapModifier { - + @Override default void modify(Map control, FileResolver fileResolver) throws IOException, ResourceParseException { @@ -32,9 +33,9 @@ default void modify(Map control, FileResolver fileResolver) /** * Perform this operation on the control map if no resource is specified. - * + * * @param control */ void defaultModify(Map control); - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java index 42146bbfe..f92df551c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -107,9 +107,10 @@ public Set keySet() { // Can't cast it if it doesn't have 1 dimensions throw new ClassCastException("MatrixMap did not have 1 dimension"); } - + /** * Set all cells to the given value + * * @param value */ public void setAll(T value); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index ef95335e7..129d9045d 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -247,19 +247,19 @@ public void testErrorPreferenceDuplicate() throws Exception { public static void populateControlMap(Map controlMap) { populateControlMap(controlMap, "S1", "S2"); } - + /** * Add a mock control map entry for SP0 parse results with 16 species */ public static void populateControlMapReal(Map controlMap) { populateControlMap(controlMap, getSpeciesAliases()); } - + /** * Get the species aliases expected */ public static String[] getSpeciesAliases() { - return new String[]{"AC", "AT", "B", "C", "D", "E", "F", "H", "L", "MB", "PA", "PL", "PW", "PY", "S", "Y"}; + return new String[] { "AC", "AT", "B", "C", "D", "E", "F", "H", "L", "MB", "PA", "PL", "PW", "PY", "S", "Y" }; } /** diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index b98b313d4..c07f2e409 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -117,7 +117,7 @@ public void testFullMap() { assertThat(map.getM("b", 1), present(is('Y'))); assertThat(map.getM("b", 2), present(is('Z'))); } - + @Test public void testSetAll() { var dim1 = Arrays.asList("a", "b"); @@ -130,7 +130,7 @@ public void testSetAll() { map.putM('Y', "b", 1); map.setAll('A'); - + assertThat(map, hasProperty("full", is(true))); assertThat(map, hasProperty("empty", is(false))); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index ab514661d..3bb09a514 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -202,6 +202,7 @@ public void describeMismatch(Object item, Description description) { /** * Match a MatrixMap if all of its values match the given matcher + * * @param * @param valueMatcher * @return @@ -216,19 +217,20 @@ public void describeTo(Description description) { @Override protected boolean matchesSafely(MatrixMap item, Description mismatchDescription) { - if(item.all(valueMatcher::matches)) { + if (item.all(valueMatcher::matches)) { return true; } // TODO This could stand to be more specific mismatchDescription.appendText("Not all values were ").appendDescriptionOf(valueMatcher); return false; } - + }; } - + /** * Match a MatrixMap if its dimensions match the given matchers + * * @param * @param * @param valueMatcher @@ -246,14 +248,15 @@ public void describeTo(Description description) { @Override protected boolean matchesSafely(MatrixMap item, Description mismatchDescription) { var dimensions = item.getDimensions(); - if(dimensionMatchers.length!=dimensions.size()) { - mismatchDescription.appendText("Expected ").appendValue(dimensionMatchers.length).appendText(" dimensions but had ").appendValue(dimensions.size()); + if (dimensionMatchers.length != dimensions.size()) { + mismatchDescription.appendText("Expected ").appendValue(dimensionMatchers.length) + .appendText(" dimensions but had ").appendValue(dimensions.size()); return false; } var result = true; - for (int i=0; i item, Description mismatchDescripti dimensionMatchers[i].describeMismatch(dimensions.get(i), mismatchDescription); } } - + return result; } - + }; } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 1708d2294..3f651ba77 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -374,7 +374,7 @@ public String toString(String filename) throws IOException { // RD_E098 new VeteranBQParser() ); - + List ADDITIONAL_MODIFIERS = Arrays.asList( // RD_E198 diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index da2f5f3b4..8f070b43b 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -14,7 +14,7 @@ public class ModifierParser implements OptionalResourceControlMapModifier { public static final String CONTROL_KEY = "MODIFIERS"; - + /** * MatrixMap3 of COE Index 1-3, Species ID, Region to Float */ @@ -35,7 +35,7 @@ public class ModifierParser implements OptionalResourceControlMapModifier { * MatrixMap2 of Species ID, Region to Float */ public static final String CONTROL_KEY_MOD301_WASTE = "WASTE_MODIFIERS"; - + public static final String CONTROL_KEY_MOD400 = "HL_MODIFIERS"; public static final int MAX_MODS = 60; @@ -45,7 +45,7 @@ public void modify(Map control, InputStream data) throws Resourc // Modifiers, IPSJF155-Appendix XII // RD_E198 - + defaultModify(control); } @@ -58,19 +58,19 @@ public String getControlKey() { public void defaultModify(Map control) { var spAliases = SP0DefinitionParser.getSpeciesAliases(control); var regions = Arrays.asList(Region.values()); - + var baModifiers = new MatrixMap2Impl(spAliases, regions); baModifiers.setAll(1.0f); control.put(CONTROL_KEY_MOD200_BA, baModifiers); - + var dqModifiers = new MatrixMap2Impl(spAliases, regions); dqModifiers.setAll(1.0f); control.put(CONTROL_KEY_MOD200_DQ, dqModifiers); - + var decayModifiers = new MatrixMap2Impl(spAliases, regions); decayModifiers.setAll(0.0f); control.put(CONTROL_KEY_MOD301_DECAY, decayModifiers); - + var wasteModifiers = new MatrixMap2Impl(spAliases, regions); wasteModifiers.setAll(0.0f); control.put(CONTROL_KEY_MOD301_WASTE, wasteModifiers); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 55b2ef4df..06a885aff 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -29,7 +29,6 @@ @SuppressWarnings({ "unchecked", "rawtypes" }) public class ModifierParserTest { - @Test public void testNoFilenameForControlFile() throws Exception { var parser = new ModifierParser(); @@ -51,14 +50,14 @@ public String toString(String filename) throws IOException { fail("Should not call FileResolver::toString"); return filename; } - + }; - + parser.modify(controlMap, fileResolver); - + assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, notPresent())); } - + @Test public void testMissingControlFile() throws Exception { var parser = new ModifierParser(); @@ -72,7 +71,7 @@ public void testMissingControlFile() throws Exception { @Override public InputStream resolve(String filename) throws IOException { assertThat(filename, is("testFilename")); - + throw new IOException(); } @@ -81,16 +80,15 @@ public String toString(String filename) throws IOException { fail("Should not call FileResolver::toString"); return filename; } - + }; - - - var ex = Assertions.assertThrows(IOException.class, ()->parser.modify(controlMap, fileResolver)); - + + var ex = Assertions.assertThrows(IOException.class, () -> parser.modify(controlMap, fileResolver)); + assertThat(ex, Matchers.notNullValue()); - + } - + @Test public void testLoadEmptyFile() throws Exception { var parser = new ModifierParser(); @@ -98,15 +96,15 @@ public void testLoadEmptyFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); - + var is = TestUtils.makeStream(); - + var fileResolver = new FileResolver() { @Override public InputStream resolve(String filename) throws IOException { assertThat(filename, is("testFilename")); - + return is; } @@ -114,28 +112,51 @@ public InputStream resolve(String filename) throws IOException { public String toString(String filename) throws IOException { return filename; } - + }; - - + parser.modify(controlMap, fileResolver); - + modifierDefaultAsserts(controlMap); } - + protected void modifierDefaultAsserts(Map controlMap) { var expectedSp0Aliases = SP0DefinitionParserTest.getSpeciesAliases(); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, present(is("testFilename")))); - - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); + + assertThat( + controlMap, + (Matcher) hasSpecificEntry( + ModifierParser.CONTROL_KEY_MOD200_BA, + mmDimensions(contains((Object[]) expectedSp0Aliases), contains((Object[]) Region.values())) + ) + ); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_BA, mmAll(is(1.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); + assertThat( + controlMap, + (Matcher) hasSpecificEntry( + ModifierParser.CONTROL_KEY_MOD200_DQ, + mmDimensions(contains((Object[]) expectedSp0Aliases), contains((Object[]) Region.values())) + ) + ); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD200_DQ, mmAll(is(1.0f)))); - - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); + + assertThat( + controlMap, + (Matcher) hasSpecificEntry( + ModifierParser.CONTROL_KEY_MOD301_DECAY, + mmDimensions(contains((Object[]) expectedSp0Aliases), contains((Object[]) Region.values())) + ) + ); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_DECAY, mmAll(is(0.0f)))); - assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmDimensions(contains((Object[])expectedSp0Aliases), contains((Object[])Region.values())))); + assertThat( + controlMap, + (Matcher) hasSpecificEntry( + ModifierParser.CONTROL_KEY_MOD301_WASTE, + mmDimensions(contains((Object[]) expectedSp0Aliases), contains((Object[]) Region.values())) + ) + ); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmAll(is(0.0f)))); } } From c509b29498e0d6adfca86d208a646b2eb1d77ae7 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 21 Jun 2023 14:35:33 -0700 Subject: [PATCH 56/98] Apply single species modifier to BA/DQ --- .../vdyp/io/parse/SP0DefinitionParser.java | 12 ++ .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 5 + .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 3 + .../ca/bc/gov/nrs/vdyp/model/MatrixMap2.java | 5 + .../ca/bc/gov/nrs/vdyp/model/MatrixMap3.java | 6 + .../bc/gov/nrs/vdyp/model/MatrixMapImpl.java | 21 ++++ .../bc/gov/nrs/vdyp/model/MatrixMapTest.java | 21 ++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 6 +- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 114 +++++++++++++++++- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 93 +++++++++++++- 10 files changed, 277 insertions(+), 9 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java index 0f35ccd8a..07365dbdd 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java @@ -98,6 +98,18 @@ public static List getSpeciesAliases(final Map controlMa return getSpecies(controlMap).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); } + /** + * Get a species based on its index from 1 + * + * @param index + * @param controlMap + * @return + */ + public static SP0Definition getSpeciesByIndex(final int index, final Map controlMap) { + + return getSpecies(controlMap).get(index - 1); + } + @Override public String getControlKey() { return CONTROL_KEY; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index 67352507b..efa456731 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -118,6 +118,11 @@ public static ValueParser indexParser(String sequenceName, int indexFro */ public static final ValueParser FLOAT = numberParser(Float::parseFloat, Float.class); + /** + * Parser for integers as booleans + */ + public static final ValueParser LOGICAL = s -> INTEGER.parse(s) != 0; + /** * Parser for Characters */ diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java index f92df551c..63f071f31 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -5,6 +5,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -26,6 +27,8 @@ public interface MatrixMap { public boolean any(Predicate pred); + public void eachKey(Consumer body); + public List> getDimensions(); default public int getNumDimensions() { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java index 608a0c450..4626b147e 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap2.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; public interface MatrixMap2 extends MatrixMap { @@ -67,6 +68,10 @@ public void setAll(CV value) { o.setAll(value); } + @Override + public void eachKey(Consumer body) { + o.eachKey(body); + } }; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java index 3368bf4d1..bda5d4e7a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap3.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; public interface MatrixMap3 extends MatrixMap { @@ -67,6 +68,11 @@ public void setAll(CV value) { o.setAll(value); } + @Override + public void eachKey(Consumer body) { + o.eachKey(body); + } + }; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java index a91d85416..c65216cfc 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java @@ -1,12 +1,15 @@ package ca.bc.gov.nrs.vdyp.model; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -115,4 +118,22 @@ public void setAll(T value) { Arrays.fill(matrix, value); } + @Override + public void eachKey(Consumer body) { + var key = new Object[maps.size()]; + eachKey(key, 0, body); + } + + // Recursively compute the cartesian product + private void eachKey(Object[] key, int i, Consumer body) { + if (i < maps.size()) { + var dim = maps.get(i); + dim.keySet().forEach(k -> { + key[i] = k; + eachKey(key, i + 1, body); + }); + } else { + body.accept(Arrays.copyOf(key, i)); + } + } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index c07f2e409..11f625223 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -3,9 +3,12 @@ import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.arrayContaining; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -140,4 +143,22 @@ public void testSetAll() { assertThat(map.getM("b", 2), present(is('A'))); } + @Test + public void testEachKey() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1, 2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + var result = new ArrayList(); + map.eachKey(result::add); + assertThat( + result, + containsInAnyOrder( + arrayContaining("a", 1), arrayContaining("b", 1), arrayContaining("a", 2), + arrayContaining("b", 2) + ) + ); + } + } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 3f651ba77..0de161a0b 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -189,6 +189,8 @@ public class FipControlParser { ; + int jprogram = 1; // FIPSTART only TODO Track this down + public FipControlParser() { } @@ -378,7 +380,7 @@ public String toString(String filename) throws IOException { List ADDITIONAL_MODIFIERS = Arrays.asList( // RD_E198 - new ModifierParser() + new ModifierParser(jprogram) ); private void @@ -398,8 +400,6 @@ public String toString(String filename) throws IOException { applyModifiers(map, GROUP_DEFINITIONS, fileResolver); - int jprogram = 1; // FIPSTART only TODO Track this down - if (jprogram == 1) { applyModifiers(map, FIPSTART_ONLY, fileResolver); } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 8f070b43b..b1d4244d5 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -2,12 +2,23 @@ import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.Optional; +import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.LineParser; import ca.bc.gov.nrs.vdyp.io.parse.OptionalResourceControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2; import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.Region; @@ -16,9 +27,9 @@ public class ModifierParser implements OptionalResourceControlMapModifier { public static final String CONTROL_KEY = "MODIFIERS"; /** - * MatrixMap3 of COE Index 1-3, Species ID, Region to Float + * MatrixMap2 of Species ID, Region to Coefficients (1-3) */ - public static final String CONTROL_KEY_MOD098 = "VET_BA_MODIFIERS"; + public static final String CONTROL_KEY_MOD098_VETERAN_BQ = VeteranBQParser.CONTROL_KEY; /** * MatrixMap2 of Species ID, Region to Float */ @@ -36,10 +47,32 @@ public class ModifierParser implements OptionalResourceControlMapModifier { */ public static final String CONTROL_KEY_MOD301_WASTE = "WASTE_MODIFIERS"; - public static final String CONTROL_KEY_MOD400 = "HL_MODIFIERS"; + /** + * MatrixMap3 + */ + public static final String CONTROL_KEY_MOD400_NONPRIMARY = HLNonprimaryCoefficientParser.CONTROL_KEY; public static final int MAX_MODS = 60; + int jprogram; + + public ModifierParser(int jprogram) { + super(); + this.jprogram = jprogram; + } + @Override public void modify(Map control, InputStream data) throws ResourceParseException, IOException { // Modifiers, IPSJF155-Appendix XII @@ -47,6 +80,81 @@ public void modify(Map control, InputStream data) throws Resourc // RD_E198 defaultModify(control); + + var parser = new LineParser() { + + @Override + public boolean isStopSegment(List entry) { + return !entry.isEmpty() && entry.get(0).equals("999"); + } + + @Override + public boolean isIgnoredSegment(List entry) { + var sequence = entry.get(0); + try { + return sequence.isBlank() || ValueParser.INTEGER.parse(sequence) == 0; + } catch (ValueParseException e) { + return false; + } + } + + @Override + public boolean isIgnoredLine(String line) { + return line.isBlank(); + } + + }.integer(3, "sequence").multiValue(6, 2, "programs", ValueParser.LOGICAL) + .multiValue(10, 6, "mods", ValueParser.optional(ValueParser.FLOAT)); + + @SuppressWarnings("unchecked") + final var baMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_BA); + @SuppressWarnings("unchecked") + final var dqMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_DQ); + + parser.parse(data, control, (entry, result) -> { + int sequence = (int) entry.get("sequence"); + + if (!modIsForProgram(entry)) + return result; + + if (sequence > 200 && sequence <= 299) { + var sp0Index = sequence - 200; + var sp0Alias = SP0DefinitionParser.getSpeciesByIndex(sp0Index, control).getAlias(); + var mods = getMods(4, entry); + + baMap.put(sp0Alias, Region.COASTAL, mods.get(0)); + baMap.put(sp0Alias, Region.INTERIOR, mods.get(1)); + dqMap.put(sp0Alias, Region.COASTAL, mods.get(2)); + dqMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); + } + return result; + }, control); + + } + + boolean modIsForProgram(Map entry) { + @SuppressWarnings("unchecked") + var programs = (List) entry.get("programs"); + return programs.get(this.jprogram - 1); + } + + List getMods(int num, Map entry) throws ValueParseException { + @SuppressWarnings("unchecked") + var raw = (List>) entry.get("mods"); + return getMods(num, raw); + } + + List getMods(int num, List> raw) throws ValueParseException { + var it = raw.iterator(); + + var result = new ArrayList(num); + for (int i = 0; i < num; i++) { + result.add( + it.next().orElseThrow(() -> new ValueParseException("", "Expected " + num + " modifier values")) + ); + } + // Possibly log a warning if there are extra unused values + return result; } @Override diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 06a885aff..0f938f0df 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -23,6 +23,7 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; +import ca.bc.gov.nrs.vdyp.model.MatrixMap; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; @@ -31,7 +32,7 @@ public class ModifierParserTest { @Test public void testNoFilenameForControlFile() throws Exception { - var parser = new ModifierParser(); + var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.empty()); @@ -60,7 +61,7 @@ public String toString(String filename) throws IOException { @Test public void testMissingControlFile() throws Exception { - var parser = new ModifierParser(); + var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); @@ -91,7 +92,7 @@ public String toString(String filename) throws IOException { @Test public void testLoadEmptyFile() throws Exception { - var parser = new ModifierParser(); + var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); @@ -159,4 +160,90 @@ protected void modifierDefaultAsserts(Map controlMap) { ); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY_MOD301_WASTE, mmAll(is(0.0f)))); } + + @Test + public void testBaDqSpecies() throws Exception { + var parser = new ModifierParser(1); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var is = TestUtils.makeStream("201 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + var baMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD200_BA)); + baMap.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(baMap.getM(k), present(is(2.0f))); + } else { + assertThat(baMap.getM(k), present(is(3.0f))); + } + } else { + assertThat(baMap.getM(k), present(is(1.0f))); + } + }); + var dqMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD200_DQ)); + dqMap.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(dqMap.getM(k), present(is(4.0f))); + } else { + assertThat(dqMap.getM(k), present(is(5.0f))); + } + } else { + assertThat(dqMap.getM(k), present(is(1.0f))); + } + }); + } + + @Test + public void testBaDqSpeciesDifferentProgram() throws Exception { + var parser = new ModifierParser(2); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var is = TestUtils.makeStream("201 1 0 0 0 0 0 0.000 0.000 0.000 0.000"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + modifierDefaultAsserts(controlMap); + } + } From d695eb2aac9367ab40b8b3f21f1de2976082a0e0 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 21 Jun 2023 14:57:22 -0700 Subject: [PATCH 57/98] Apply BA/DQ mod to all species --- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 11 +- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 131 ++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index b1d4244d5..8fb4b0683 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -117,7 +117,16 @@ public boolean isIgnoredLine(String line) { if (!modIsForProgram(entry)) return result; - if (sequence > 200 && sequence <= 299) { + if (sequence == 200) { + var mods = getMods(4, entry); + var sp0Aliases = SP0DefinitionParser.getSpeciesAliases(control); + for (var sp0Alias : sp0Aliases) { + baMap.put(sp0Alias, Region.COASTAL, mods.get(0)); + baMap.put(sp0Alias, Region.INTERIOR, mods.get(1)); + dqMap.put(sp0Alias, Region.COASTAL, mods.get(2)); + dqMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); + } + } else if (sequence > 200 && sequence <= 299) { var sp0Index = sequence - 200; var sp0Alias = SP0DefinitionParser.getSpeciesByIndex(sp0Index, control).getAlias(); var mods = getMods(4, entry); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 0f938f0df..0c32f42fb 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -246,4 +246,135 @@ public String toString(String filename) throws IOException { modifierDefaultAsserts(controlMap); } + @Test + public void testIgnoreAfterStop() throws Exception { + var parser = new ModifierParser(1); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var is = TestUtils.makeStream("999", "201 1 0 0 0 0 0 0.000 0.000 0.000 0.000"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + modifierDefaultAsserts(controlMap); + } + + @Test + public void testIgnoreCommentsAndBlanks() throws Exception { + var parser = new ModifierParser(1); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var is = TestUtils.makeStream("", " x", "000 x", "201 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + var baMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD200_BA)); + baMap.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(baMap.getM(k), present(is(2.0f))); + } else { + assertThat(baMap.getM(k), present(is(3.0f))); + } + } else { + assertThat(baMap.getM(k), present(is(1.0f))); + } + }); + var dqMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD200_DQ)); + dqMap.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(dqMap.getM(k), present(is(4.0f))); + } else { + assertThat(dqMap.getM(k), present(is(5.0f))); + } + } else { + assertThat(dqMap.getM(k), present(is(1.0f))); + } + }); + } + + @Test + public void testBaDqAllSpecies() throws Exception { + var parser = new ModifierParser(1); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var is = TestUtils.makeStream("200 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + var baMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD200_BA)); + baMap.eachKey(k -> { + if (k[1].equals(Region.COASTAL)) { + assertThat(baMap.getM(k), present(is(2.0f))); + } else { + assertThat(baMap.getM(k), present(is(3.0f))); + } + }); + var dqMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD200_DQ)); + dqMap.eachKey(k -> { + if (k[1].equals(Region.COASTAL)) { + assertThat(dqMap.getM(k), present(is(4.0f))); + } else { + assertThat(dqMap.getM(k), present(is(5.0f))); + } + }); + } + } From 4615bc81197b99a14ab5438bfa2a9263f21e4950 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 21 Jun 2023 15:28:31 -0700 Subject: [PATCH 58/98] Remap jprogram index --- .../main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java | 6 +++++- .../java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 8fb4b0683..563df3752 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -67,6 +67,8 @@ public class ModifierParser implements OptionalResourceControlMapModifier { public static final int MAX_MODS = 60; int jprogram; + + static final int[] ipoint = {1, 0, 2, 0, 0, 3, 4, 5, 0}; public ModifierParser(int jprogram) { super(); @@ -144,7 +146,9 @@ public boolean isIgnoredLine(String line) { boolean modIsForProgram(Map entry) { @SuppressWarnings("unchecked") var programs = (List) entry.get("programs"); - return programs.get(this.jprogram - 1); + var index = ipoint[this.jprogram - 1]; + if (index<=0) throw new IllegalStateException("JProgram "+this.jprogram + " mapped to "+index); + return programs.get(index-1); } List getMods(int num, Map entry) throws ValueParseException { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 0c32f42fb..986aceeab 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -217,7 +217,7 @@ public String toString(String filename) throws IOException { @Test public void testBaDqSpeciesDifferentProgram() throws Exception { - var parser = new ModifierParser(2); + var parser = new ModifierParser(3); Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); From da08fbc7822aa3af268a6ca413b26816c17daa60 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 21 Jun 2023 16:26:08 -0700 Subject: [PATCH 59/98] Apply modifiers to veteran BQ coefficients --- .../bc/gov/nrs/vdyp/model/Coefficients.java | 9 ++++ .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 17 ++++++- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 37 +++++++++++++-- .../nrs/vdyp/fip/FipControlParserTest.java | 20 +++++--- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 47 +++++++++++++++++++ 5 files changed, 118 insertions(+), 12 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java index deaf56f55..333ff4436 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Coefficients.java @@ -3,6 +3,7 @@ import java.util.AbstractList; import java.util.Collection; import java.util.List; +import java.util.function.UnaryOperator; public class Coefficients extends AbstractList implements List { float[] coe; @@ -36,6 +37,14 @@ public Float getCoe(int i) { return coe[i - indexFrom]; } + public void modifyCoe(int i, UnaryOperator op) { + setCoe(i, op.apply(getCoe(i))); + } + + public Float setCoe(int i, float value) { + return coe[i - indexFrom] = value; + } + @Override public int size() { return coe.length; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java index 63f071f31..309f6cf69 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -6,7 +6,9 @@ import java.util.Optional; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -116,5 +118,18 @@ public Set keySet() { * * @param value */ - public void setAll(T value); + public default void setAll(T value) { + setAll(k -> value); + }; + + /** + * Set all cells to the generated value + * + * @param value + */ + public default void setAll(Function generator) { + eachKey((k) -> { + putM(generator.apply(k), k); + }); + }; } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 563df3752..2ed2a09c5 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -18,6 +18,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; +import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap2; import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.Region; @@ -67,8 +68,8 @@ public class ModifierParser implements OptionalResourceControlMapModifier { public static final int MAX_MODS = 60; int jprogram; - - static final int[] ipoint = {1, 0, 2, 0, 0, 3, 4, 5, 0}; + + static final int[] ipoint = { 1, 0, 2, 0, 0, 3, 4, 5, 0 }; public ModifierParser(int jprogram) { super(); @@ -108,6 +109,8 @@ public boolean isIgnoredLine(String line) { }.integer(3, "sequence").multiValue(6, 2, "programs", ValueParser.LOGICAL) .multiValue(10, 6, "mods", ValueParser.optional(ValueParser.FLOAT)); + @SuppressWarnings("unchecked") + final var vetBqMap = (MatrixMap2) control.get(VeteranBQParser.CONTROL_KEY); @SuppressWarnings("unchecked") final var baMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_BA); @SuppressWarnings("unchecked") @@ -119,7 +122,28 @@ public boolean isIgnoredLine(String line) { if (!modIsForProgram(entry)) return result; - if (sequence == 200) { + if (sequence == 98) { + // If modifiers are per region, for each species, multiply the first coefficient + // for veteran BQ by the region appropriate modifier. + vetBqMap.get(CONTROL_KEY, null); + var mods = getMods(2, entry); + var sp0Aliases = SP0DefinitionParser.getSpeciesAliases(control); + for (var sp0Alias : sp0Aliases) { + final float coastalMod = mods.get(0); + final float interiorMod = mods.get(1); + + if (coastalMod != 0.0) { + var coe = vetBqMap.get(sp0Alias, Region.COASTAL).get(); + coe.modifyCoe(1, x -> x * coastalMod); + } + if (interiorMod != 0.0) { + var coe = vetBqMap.get(sp0Alias, Region.INTERIOR).get(); + coe.modifyCoe(1, x -> x * interiorMod); + } + } + } else if (sequence == 200) { + // Modifiers are per region for BA and DQ, for each species, set the modifier + // map var mods = getMods(4, entry); var sp0Aliases = SP0DefinitionParser.getSpeciesAliases(control); for (var sp0Alias : sp0Aliases) { @@ -129,6 +153,8 @@ public boolean isIgnoredLine(String line) { dqMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); } } else if (sequence > 200 && sequence <= 299) { + // Modifiers are per region for BA and DQ, for the specified species, set the + // modifier map var sp0Index = sequence - 200; var sp0Alias = SP0DefinitionParser.getSpeciesByIndex(sp0Index, control).getAlias(); var mods = getMods(4, entry); @@ -147,8 +173,9 @@ boolean modIsForProgram(Map entry) { @SuppressWarnings("unchecked") var programs = (List) entry.get("programs"); var index = ipoint[this.jprogram - 1]; - if (index<=0) throw new IllegalStateException("JProgram "+this.jprogram + " mapped to "+index); - return programs.get(index-1); + if (index <= 0) + throw new IllegalStateException("JProgram " + this.jprogram + " mapped to " + index); + return programs.get(index - 1); } List getMods(int num, Map entry) throws ValueParseException { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 5bb10e971..f71c2ed3e 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -579,14 +579,22 @@ public void testParseE098() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( - result, - (Matcher) hasSpecificEntry( + result, (Matcher) hasSpecificEntry( FipControlParser.VETERAN_BQ, + // Includes modifiers from 198 allOf( - mmHasEntry(present(contains(0.12874f, 8.00000f, 1.26982f)), "B", Region.COASTAL), - mmHasEntry(present(contains(0.70932f, 7.63269f, 0.62545f)), "B", Region.INTERIOR), - mmHasEntry(present(contains(0.07962f, 6.60231f, 1.37998f)), "D", Region.COASTAL), - mmHasEntry(present(contains(0.07962f, 6.60231f, 1.37998f)), "D", Region.INTERIOR) + mmHasEntry( + present(contains(0.12874f * 0.311f, 8.00000f, 1.26982f)), "B", Region.COASTAL + ), + mmHasEntry( + present(contains(0.70932f * 0.374f, 7.63269f, 0.62545f)), "B", Region.INTERIOR + ), + mmHasEntry( + present(contains(0.07962f * 0.311f, 6.60231f, 1.37998f)), "D", Region.COASTAL + ), + mmHasEntry( + present(contains(0.07962f * 0.374f, 6.60231f, 1.37998f)), "D", Region.INTERIOR + ) ) ) ); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 986aceeab..cfd8a8a63 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -23,7 +24,11 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; +import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; @@ -377,4 +382,46 @@ public String toString(String filename) throws IOException { }); } + @Test + public void testVetBq() throws Exception { + var parser = new ModifierParser(1); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + MatrixMap2 vetBqMap = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + vetBqMap.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + controlMap.put(VeteranBQParser.CONTROL_KEY, vetBqMap); + + var is = TestUtils.makeStream("098 1 0 0 0 0 0 0.200 0.300"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + vetBqMap.eachKey(k -> { + if (k[1].equals(Region.COASTAL)) { + assertThat(vetBqMap.getM(k), present(contains(is(0.2f), is(5.0f), is(7.0f)))); + } else { + assertThat(vetBqMap.getM(k), present(contains(is(0.3f), is(5.0f), is(7.0f)))); + } + }); + } + } From e8302b56e349c76da3f14112678b5de21db661b4 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 22 Jun 2023 11:03:12 -0700 Subject: [PATCH 60/98] HL DEcay and Waste modifiers --- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 19 +++++++ .../gov/nrs/vdyp/fip/ModifierParserTest.java | 54 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 2ed2a09c5..3daa2ccd3 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -39,6 +39,10 @@ public class ModifierParser implements OptionalResourceControlMapModifier { * MatrixMap2 of Species ID, Region to Float */ public static final String CONTROL_KEY_MOD200_DQ = "DQ_MODIFIERS"; + /** + * Boolean indicates HL modifiers are present + */ + public static final String CONTROL_KEY_MOD301_HL = "HL_MODIFIERS"; /** * MatrixMap2 of Species ID, Region to Float */ @@ -115,6 +119,10 @@ public boolean isIgnoredLine(String line) { final var baMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_BA); @SuppressWarnings("unchecked") final var dqMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_DQ); + @SuppressWarnings("unchecked") + final var decayMap = (MatrixMap2) control.get(CONTROL_KEY_MOD301_DECAY); + @SuppressWarnings("unchecked") + final var wasteMap = (MatrixMap2) control.get(CONTROL_KEY_MOD301_WASTE); parser.parse(data, control, (entry, result) -> { int sequence = (int) entry.get("sequence"); @@ -163,6 +171,17 @@ public boolean isIgnoredLine(String line) { baMap.put(sp0Alias, Region.INTERIOR, mods.get(1)); dqMap.put(sp0Alias, Region.COASTAL, mods.get(2)); dqMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); + } else if (sequence > 300 && sequence <= 399) { + // Modifiers are per region for BA and DQ, for the specified species, set the + // modifier map + var sp0Index = sequence - 300; + var sp0Alias = SP0DefinitionParser.getSpeciesByIndex(sp0Index, control).getAlias(); + var mods = getMods(4, entry); + + decayMap.put(sp0Alias, Region.COASTAL, mods.get(0)); + decayMap.put(sp0Alias, Region.INTERIOR, mods.get(1)); + wasteMap.put(sp0Alias, Region.COASTAL, mods.get(2)); + wasteMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); } return result; }, control); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index cfd8a8a63..901942d34 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -424,4 +424,58 @@ public String toString(String filename) throws IOException { }); } + @Test + public void testHlDecayWaste() throws Exception { + var parser = new ModifierParser(1); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var is = TestUtils.makeStream("301 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + var decayMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD301_DECAY)); + decayMap.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(decayMap.getM(k), present(is(2.0f))); + } else { + assertThat(decayMap.getM(k), present(is(3.0f))); + } + } else { + assertThat(decayMap.getM(k), present(is(0.0f))); + } + }); + var wasteMap = ((MatrixMap) controlMap.get(ModifierParser.CONTROL_KEY_MOD301_WASTE)); + wasteMap.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(wasteMap.getM(k), present(is(4.0f))); + } else { + assertThat(wasteMap.getM(k), present(is(5.0f))); + } + } else { + assertThat(wasteMap.getM(k), present(is(0.0f))); + } + }); + } + } From 4fe31e764fc272e097e15deaad37545760814a7f Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 22 Jun 2023 12:52:39 -0700 Subject: [PATCH 61/98] Apply HL Modifiers for P1, P2, P3 --- .../vdyp/io/parse/HLCoefficientParser.java | 20 ++-- .../io/parse/HLCoefficientParserTest.java | 24 ++--- .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 91 ++++++++++++++----- .../nrs/vdyp/fip/FipControlParserTest.java | 11 ++- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 82 ++++++++++++++++- 5 files changed, 171 insertions(+), 57 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java index 9a8e64b0f..c82af4949 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java @@ -8,8 +8,9 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import ca.bc.gov.nrs.vdyp.model.MatrixMap3; -import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; +import ca.bc.gov.nrs.vdyp.model.Coefficients; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2; +import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; import ca.bc.gov.nrs.vdyp.model.Region; /** @@ -18,7 +19,7 @@ * @author Kevin Smith, Vivid Solutions * */ -public class HLCoefficientParser implements ControlMapSubResourceParser> { +public class HLCoefficientParser implements ControlMapSubResourceParser> { public static final String CONTROL_KEY_P1 = "HL_PRIMARY_SP_EQN_P1"; public static final String CONTROL_KEY_P2 = "HL_PRIMARY_SP_EQN_P2"; @@ -53,15 +54,13 @@ public boolean isStopLine(String line) { LineParser lineParser; @Override - public MatrixMap3 parse(InputStream is, Map control) + public MatrixMap2 parse(InputStream is, Map control) throws IOException, ResourceParseException { final var regionIndicies = Arrays.asList(Region.values()); - final List coeIndicies = Stream.iterate(1, x -> x + 1).limit(numCoefficients) - .collect(Collectors.toList()); final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); - MatrixMap3 result = new MatrixMap3Impl( - coeIndicies, speciesIndicies, regionIndicies + MatrixMap2 result = new MatrixMap2Impl( + speciesIndicies, regionIndicies ); lineParser.parse(is, result, (v, r) -> { var sp0 = (String) v.get(SP0_KEY); @@ -72,9 +71,8 @@ public MatrixMap3 parse(InputStream is, Map) control.get(VeteranBQParser.CONTROL_KEY); + @SuppressWarnings("unchecked") final var baMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_BA); @SuppressWarnings("unchecked") final var dqMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_DQ); + @SuppressWarnings("unchecked") final var decayMap = (MatrixMap2) control.get(CONTROL_KEY_MOD301_DECAY); @SuppressWarnings("unchecked") final var wasteMap = (MatrixMap2) control.get(CONTROL_KEY_MOD301_WASTE); + @SuppressWarnings("unchecked") + final var hlP1Map = (MatrixMap2) control.get(CONTROL_KEY_MOD400_P1); + @SuppressWarnings("unchecked") + final var hlP2Map = (MatrixMap2) control.get(CONTROL_KEY_MOD400_P2); + @SuppressWarnings("unchecked") + final var hlP3Map = (MatrixMap2) control.get(CONTROL_KEY_MOD400_P3); + parser.parse(data, control, (entry, result) -> { int sequence = (int) entry.get("sequence"); @@ -149,45 +159,71 @@ public boolean isIgnoredLine(String line) { coe.modifyCoe(1, x -> x * interiorMod); } } - } else if (sequence == 200) { + } else if (sequence >= 200 && sequence <= 299) { // Modifiers are per region for BA and DQ, for each species, set the modifier // map var mods = getMods(4, entry); - var sp0Aliases = SP0DefinitionParser.getSpeciesAliases(control); + var sp0Index = sequence - 200; + var sp0Aliases = getSpeciesByIndex(sp0Index, control); for (var sp0Alias : sp0Aliases) { - baMap.put(sp0Alias, Region.COASTAL, mods.get(0)); - baMap.put(sp0Alias, Region.INTERIOR, mods.get(1)); - dqMap.put(sp0Alias, Region.COASTAL, mods.get(2)); - dqMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); + modsByRegions(mods, 0, (m, r) -> baMap.put(sp0Alias, r, m)); + modsByRegions(mods, 2, (m, r) -> dqMap.put(sp0Alias, r, m)); } - } else if (sequence > 200 && sequence <= 299) { - // Modifiers are per region for BA and DQ, for the specified species, set the - // modifier map - var sp0Index = sequence - 200; - var sp0Alias = SP0DefinitionParser.getSpeciesByIndex(sp0Index, control).getAlias(); - var mods = getMods(4, entry); - - baMap.put(sp0Alias, Region.COASTAL, mods.get(0)); - baMap.put(sp0Alias, Region.INTERIOR, mods.get(1)); - dqMap.put(sp0Alias, Region.COASTAL, mods.get(2)); - dqMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); - } else if (sequence > 300 && sequence <= 399) { - // Modifiers are per region for BA and DQ, for the specified species, set the + } else if (sequence >= 300 && sequence <= 399) { + // Modifiers are per region for Decay and Waste, for the specified species, set + // the // modifier map var sp0Index = sequence - 300; - var sp0Alias = SP0DefinitionParser.getSpeciesByIndex(sp0Index, control).getAlias(); + var sp0Aliases = getSpeciesByIndex(sp0Index, control); var mods = getMods(4, entry); - decayMap.put(sp0Alias, Region.COASTAL, mods.get(0)); - decayMap.put(sp0Alias, Region.INTERIOR, mods.get(1)); - wasteMap.put(sp0Alias, Region.COASTAL, mods.get(2)); - wasteMap.put(sp0Alias, Region.INTERIOR, mods.get(3)); + for (var sp0Alias : sp0Aliases) { + modsByRegions(mods, 0, (m, r) -> decayMap.put(sp0Alias, r, m)); + modsByRegions(mods, 2, (m, r) -> wasteMap.put(sp0Alias, r, m)); + } + } else if (sequence >= 400 && sequence <= 499) { + // Modifiers are per region, for the specified species, multiply existing + // coefficients + var sp0Index = sequence - 400; + var sp0Aliases = getSpeciesByIndex(sp0Index, control); + var mods = getMods(2, entry); + + for (var sp0Alias : sp0Aliases) { + modsByRegions(mods, 0, (m, r) -> hlP1Map.get(sp0Alias, r).ifPresent(coe -> { + coe.modifyCoe(1, x -> x * m); + coe.modifyCoe(2, x -> x * m); + })); + modsByRegions(mods, 0, (m, r) -> hlP2Map.get(sp0Alias, r).ifPresent(coe -> { + coe.modifyCoe(1, x -> x * m); + })); + modsByRegions(mods, 0, (m, r) -> hlP3Map.get(sp0Alias, r).ifPresent(coe -> { + coe.modifyCoe(1, x -> { + if (x > 0.0f && x < 1.0e06f) { + return x * m; + } + return x; + }); + })); + + } } return result; }, control); } + void modsByRegions(List mods, int offset, BiConsumer modifier) { + assert mods.size() % 2 == 0; + assert offset % 2 == 0; + assert mods.size() - offset >= 2; + + var regions = Region.values(); + + for (int i = 0; i < regions.length; i++) { + modifier.accept(mods.get(offset + i), regions[i]); + } + } + boolean modIsForProgram(Map entry) { @SuppressWarnings("unchecked") var programs = (List) entry.get("programs"); @@ -197,6 +233,13 @@ boolean modIsForProgram(Map entry) { return programs.get(index - 1); } + List getSpeciesByIndex(int index, Map control) { + if (index == 0) { + return SP0DefinitionParser.getSpeciesAliases(control); + } + return List.of(SP0DefinitionParser.getSpeciesByIndex(index, control).getAlias()); + } + List getMods(int num, Map entry) throws ValueParseException { @SuppressWarnings("unchecked") var raw = (List>) entry.get("mods"); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index f71c2ed3e..aa8227681 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -292,7 +292,7 @@ public void testParseE050() throws Exception { result, (Matcher) hasSpecificEntry( FipControlParser.HL_PRIMARY_SP_EQN_P1, - allOf(mmHasEntry(present(is(1.00160f)), 1, "AC", Region.COASTAL)) + allOf(mmHasEntry(present(contains(1.00160f, 0.20508f, -0.0013743f)), "AC", Region.COASTAL)) ) ); } @@ -305,7 +305,7 @@ public void testParseE051() throws Exception { result, (Matcher) hasSpecificEntry( FipControlParser.HL_PRIMARY_SP_EQN_P2, - allOf(mmHasEntry(present(is(0.49722f)), 1, "AC", Region.COASTAL)) + allOf(mmHasEntry(present(contains(0.49722f, 1.18403f)), "AC", Region.COASTAL)) ) ); } @@ -318,7 +318,12 @@ public void testParseE052() throws Exception { result, (Matcher) hasSpecificEntry( FipControlParser.HL_PRIMARY_SP_EQN_P3, - allOf(mmHasEntry(present(is(1.04422f)), 1, "AC", Region.COASTAL)) + allOf( + mmHasEntry( + present(contains(1.04422f, 0.93010f, -0.05745f, -2.50000f)), "AC", + Region.COASTAL + ) + ) ) ); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 901942d34..99cb79900 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.io.FileResolver; +import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; import ca.bc.gov.nrs.vdyp.model.Coefficients; @@ -425,7 +426,7 @@ public String toString(String filename) throws IOException { } @Test - public void testHlDecayWaste() throws Exception { + public void testDecayWaste() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -478,4 +479,83 @@ public String toString(String filename) throws IOException { }); } + @Test + public void testHL() throws Exception { + var parser = new ModifierParser(1); + + Map controlMap = new HashMap<>(); + controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); + MatrixMap2 hlP1Map = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + hlP1Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); + MatrixMap2 hlP2Map = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + hlP2Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f), 1)); + MatrixMap2 hlP3Map = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + hlP3Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f, 13.0f), 1)); + + SP0DefinitionParserTest.populateControlMapReal(controlMap); + controlMap.put(HLCoefficientParser.CONTROL_KEY_P1, hlP1Map); + controlMap.put(HLCoefficientParser.CONTROL_KEY_P2, hlP2Map); + controlMap.put(HLCoefficientParser.CONTROL_KEY_P3, hlP3Map); + + var is = TestUtils.makeStream("401 1 0 0 0 0 0 0.200 0.300 0.500 0.700"); + + var fileResolver = new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + assertThat(filename, is("testFilename")); + + return is; + } + + @Override + public String toString(String filename) throws IOException { + return filename; + } + + }; + + parser.modify(controlMap, fileResolver); + + hlP1Map.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(hlP1Map.getM(k), present(contains(is(0.2f), is(0.2f * 5.0f), is(7.0f)))); + } else { + assertThat(hlP1Map.getM(k), present(contains(is(0.3f), is(0.3f * 5.0f), is(7.0f)))); + } + } else { + assertThat(hlP1Map.getM(k), present(contains(is(1.0f), is(5.0f), is(7.0f)))); + } + }); + hlP2Map.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(hlP2Map.getM(k), present(contains(is(0.2f), is(5.0f)))); + } else { + assertThat(hlP2Map.getM(k), present(contains(is(0.3f), is(5.0f)))); + } + } else { + assertThat(hlP2Map.getM(k), present(contains(is(1.0f), is(5.0f)))); + } + }); + hlP3Map.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[1].equals(Region.COASTAL)) { + assertThat(hlP3Map.getM(k), present(contains(is(0.2f), is(5.0f), is(7.0f), is(13.0f)))); + } else { + assertThat(hlP3Map.getM(k), present(contains(is(0.3f), is(5.0f), is(7.0f), is(13.0f)))); + } + } else { + assertThat(hlP3Map.getM(k), present(contains(is(1.0f), is(5.0f), is(7.0f), is(13.0f)))); + } + }); + } + } From 141b375109d26acd31388dccc26e86bf9fcab7e8 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 22 Jun 2023 15:49:45 -0700 Subject: [PATCH 62/98] Nonprimary HL modifiers --- .../ca/bc/gov/nrs/vdyp/model/MatrixMap.java | 1 - .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 47 ++++--- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 126 +++++++++++++++--- 3 files changed, 138 insertions(+), 36 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java index 309f6cf69..e06739891 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMap.java @@ -8,7 +8,6 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Collectors; /** diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index bc4418f77..7bc44bfc2 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -15,6 +15,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.LineParser; import ca.bc.gov.nrs.vdyp.io.parse.OptionalResourceControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; @@ -22,6 +23,8 @@ import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap2; import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; import ca.bc.gov.nrs.vdyp.model.Region; public class ModifierParser implements OptionalResourceControlMapModifier { @@ -114,25 +117,31 @@ public boolean isIgnoredLine(String line) { }.integer(3, "sequence").multiValue(6, 2, "programs", ValueParser.LOGICAL) .multiValue(10, 6, "mods", ValueParser.optional(ValueParser.FLOAT)); - @SuppressWarnings("unchecked") - final var vetBqMap = (MatrixMap2) control.get(VeteranBQParser.CONTROL_KEY); + final MatrixMap2 vetBqMap = ResourceParser + .expectParsedControl(control, VeteranBQParser.CONTROL_KEY, MatrixMap2.class); @SuppressWarnings("unchecked") - final var baMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_BA); + final MatrixMap2 baMap = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD200_BA, MatrixMap2.class); @SuppressWarnings("unchecked") - final var dqMap = (MatrixMap2) control.get(CONTROL_KEY_MOD200_DQ); + final MatrixMap2 dqMap = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD200_DQ, MatrixMap2.class); @SuppressWarnings("unchecked") - final var decayMap = (MatrixMap2) control.get(CONTROL_KEY_MOD301_DECAY); - @SuppressWarnings("unchecked") - final var wasteMap = (MatrixMap2) control.get(CONTROL_KEY_MOD301_WASTE); - - @SuppressWarnings("unchecked") - final var hlP1Map = (MatrixMap2) control.get(CONTROL_KEY_MOD400_P1); - @SuppressWarnings("unchecked") - final var hlP2Map = (MatrixMap2) control.get(CONTROL_KEY_MOD400_P2); + final MatrixMap2 decayMap = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD301_DECAY, MatrixMap2.class); @SuppressWarnings("unchecked") - final var hlP3Map = (MatrixMap2) control.get(CONTROL_KEY_MOD400_P3); + final MatrixMap2 wasteMap = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD301_WASTE, MatrixMap2.class); + + final MatrixMap2 hlP1Map = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD400_P1, MatrixMap2.class); + final MatrixMap2 hlP2Map = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD400_P2, MatrixMap2.class); + final MatrixMap2 hlP3Map = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD400_P3, MatrixMap2.class); + final MatrixMap3 hlNPMap = ResourceParser + .expectParsedControl(control, CONTROL_KEY_MOD400_NONPRIMARY, MatrixMap3.class); parser.parse(data, control, (entry, result) -> { int sequence = (int) entry.get("sequence"); @@ -186,7 +195,7 @@ public boolean isIgnoredLine(String line) { // coefficients var sp0Index = sequence - 400; var sp0Aliases = getSpeciesByIndex(sp0Index, control); - var mods = getMods(2, entry); + var mods = getMods(4, entry); for (var sp0Alias : sp0Aliases) { modsByRegions(mods, 0, (m, r) -> hlP1Map.get(sp0Alias, r).ifPresent(coe -> { @@ -204,8 +213,16 @@ public boolean isIgnoredLine(String line) { return x; }); })); - + for (var primarySp : SP0DefinitionParser.getSpeciesAliases(control)) { + modsByRegions(mods, 2, (m, r) -> hlNPMap.get(sp0Alias, primarySp, r).ifPresent(coe -> { + if (coe.getEquationIndex() == 1) { + coe.modifyCoe(1, x -> x * m); + } + })); + } } + } else { + // Unexpected sequence in modifier file } return result; }, control); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index 99cb79900..a2a0e0a5b 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -24,12 +24,16 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; +import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap; import ca.bc.gov.nrs.vdyp.model.MatrixMap2; import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3; +import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; +import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; @@ -103,6 +107,11 @@ public void testLoadEmptyFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); + populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream(); @@ -174,6 +183,11 @@ public void testBaDqSpecies() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); + populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream("201 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); @@ -228,6 +242,11 @@ public void testBaDqSpeciesDifferentProgram() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); + populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream("201 1 0 0 0 0 0 0.000 0.000 0.000 0.000"); @@ -259,6 +278,11 @@ public void testIgnoreAfterStop() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); + populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream("999", "201 1 0 0 0 0 0 0.000 0.000 0.000 0.000"); @@ -290,6 +314,11 @@ public void testIgnoreCommentsAndBlanks() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); + populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream("", " x", "000 x", "201 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); @@ -344,6 +373,11 @@ public void testBaDqAllSpecies() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); + populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream("200 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); @@ -389,12 +423,12 @@ public void testVetBq() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - MatrixMap2 vetBqMap = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) - ); - vetBqMap.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); SP0DefinitionParserTest.populateControlMapReal(controlMap); - controlMap.put(VeteranBQParser.CONTROL_KEY, vetBqMap); + MatrixMap2 vetBqMap = populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream("098 1 0 0 0 0 0 0.200 0.300"); @@ -425,6 +459,15 @@ public String toString(String filename) throws IOException { }); } + private MatrixMap2 populateVetBq(Map controlMap) { + MatrixMap2 vetBqMap = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + vetBqMap.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); + controlMap.put(VeteranBQParser.CONTROL_KEY, vetBqMap); + return vetBqMap; + } + @Test public void testDecayWaste() throws Exception { var parser = new ModifierParser(1); @@ -432,6 +475,11 @@ public void testDecayWaste() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); SP0DefinitionParserTest.populateControlMapReal(controlMap); + populateVetBq(controlMap); + populateHlP1(controlMap); + populateHlP2(controlMap); + populateHlP3(controlMap); + populateHlNP(controlMap); var is = TestUtils.makeStream("301 1 0 0 0 0 0 2.000 3.000 4.000 5.000"); @@ -485,23 +533,13 @@ public void testHL() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - MatrixMap2 hlP1Map = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) - ); - hlP1Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); - MatrixMap2 hlP2Map = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) - ); - hlP2Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f), 1)); - MatrixMap2 hlP3Map = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) - ); - hlP3Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f, 13.0f), 1)); SP0DefinitionParserTest.populateControlMapReal(controlMap); - controlMap.put(HLCoefficientParser.CONTROL_KEY_P1, hlP1Map); - controlMap.put(HLCoefficientParser.CONTROL_KEY_P2, hlP2Map); - controlMap.put(HLCoefficientParser.CONTROL_KEY_P3, hlP3Map); + populateVetBq(controlMap); + var hlP1Map = populateHlP1(controlMap); + var hlP2Map = populateHlP2(controlMap); + var hlP3Map = populateHlP3(controlMap); + var hlNPMap = populateHlNP(controlMap); var is = TestUtils.makeStream("401 1 0 0 0 0 0 0.200 0.300 0.500 0.700"); @@ -556,6 +594,54 @@ public String toString(String filename) throws IOException { assertThat(hlP3Map.getM(k), present(contains(is(1.0f), is(5.0f), is(7.0f), is(13.0f)))); } }); + hlNPMap.eachKey(k -> { + if (k[0].equals("AC")) { + if (k[2].equals(Region.COASTAL)) { + assertThat(hlNPMap.getM(k), present(contains(is(0.5f), is(5.0f)))); + } else { + assertThat(hlNPMap.getM(k), present(contains(is(0.7f), is(5.0f)))); + } + } else { + assertThat(hlNPMap.getM(k), present(contains(is(1.0f), is(5.0f)))); + } + }); + } + + private MatrixMap3 populateHlNP(Map controlMap) { + MatrixMap3 hlNPMap = new MatrixMap3Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + hlNPMap.setAll(k -> new NonprimaryHLCoefficients(Arrays.asList(1.0f, 5.0f), 1)); + controlMap.put(HLNonprimaryCoefficientParser.CONTROL_KEY, hlNPMap); + return hlNPMap; + } + + private MatrixMap2 populateHlP3(Map controlMap) { + MatrixMap2 hlP3Map = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + hlP3Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f, 13.0f), 1)); + controlMap.put(HLCoefficientParser.CONTROL_KEY_P3, hlP3Map); + return hlP3Map; + } + + private MatrixMap2 populateHlP2(Map controlMap) { + MatrixMap2 hlP2Map = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + hlP2Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f), 1)); + controlMap.put(HLCoefficientParser.CONTROL_KEY_P2, hlP2Map); + return hlP2Map; + } + + private MatrixMap2 populateHlP1(Map controlMap) { + MatrixMap2 hlP1Map = new MatrixMap2Impl( + Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + ); + hlP1Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); + controlMap.put(HLCoefficientParser.CONTROL_KEY_P1, hlP1Map); + return hlP1Map; } } From 7207729225e2e626343e1ea17385baa514a753a4 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 27 Jun 2023 10:24:19 -0700 Subject: [PATCH 63/98] Refactor LineParser to allow for streaming parsers to be built on top of it --- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 106 +++++++++++++----- 1 file changed, 80 insertions(+), 26 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 927cf4dfe..9b31bc53b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -10,6 +10,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; /** * Parse a file with records consisting of lines with fixed width fields. @@ -256,40 +258,92 @@ public T parse( InputStream is, T result, ParseEntryHandler, T> addToResult, Map control ) throws IOException, ResourceParseLineException { var reader = new BufferedReader(new InputStreamReader(is, charset)); - String line; - int lineNumber = 0; - while ( (line = reader.readLine()) != null) { - lineNumber++; + + var stream = new LineStream(reader, control); + while (stream.hasNext()) { + var entry = stream.next(); try { - if (isStopLine(line)) { - break; - } - if (isIgnoredLine(line)) { - continue; - } - var segments = segmentize(line); - if (isStopSegment(segments)) { - break; - } - if (isIgnoredSegment(segments)) { - continue; - } - var entry = parse(segments, control); - entry.put(LINE_NUMBER_KEY, lineNumber); - if (isStopEntry(entry)) { - break; - } - if (isIgnoredEntry(entry)) { - continue; - } result = addToResult.addTo(entry, result); } catch (ValueParseException ex) { - throw new ResourceParseLineException(lineNumber, ex); + stream.handleValueParseException(ex); } } return result; } + public class LineStream { + + int lineNumber = 0; + BufferedReader reader; + Map control; + + Optional>> next = Optional.empty(); + + public LineStream(BufferedReader reader, Map control) { + this.reader = reader; + this.control = control; + } + + public Map next() throws IOException, ResourceParseLineException { + if (next.isEmpty()) { + next = Optional.of(doGetNext()); + } + try { + return next.get() + .orElseThrow(() -> new IllegalStateException("Tried to get next entry when none exists")); + } finally { + next = Optional.empty(); + } + } + + public boolean hasNext() throws IOException, ResourceParseLineException { + if (next.isEmpty()) { + next = Optional.of(doGetNext()); + } + return next.get().isPresent(); + } + + private Optional> doGetNext() throws IOException, ResourceParseLineException { + while (true) { + lineNumber++; + var line = reader.readLine(); + if (Objects.isNull(line)) { + return Optional.empty(); + } + try { + if (isStopLine(line)) { + return Optional.empty(); + } + if (isIgnoredLine(line)) { + continue; + } + var segments = segmentize(line); + if (isStopSegment(segments)) { + return Optional.empty(); + } + if (isIgnoredSegment(segments)) { + continue; + } + var entry = parse(segments, control); + entry.put(LINE_NUMBER_KEY, lineNumber); + if (isStopEntry(entry)) { + return Optional.empty(); + } + if (isIgnoredEntry(entry)) { + continue; + } + return Optional.of(entry); + } catch (ValueParseException ex) { + handleValueParseException(ex); + } + } + } + + void handleValueParseException(ValueParseException ex) throws ResourceParseLineException { + throw new ResourceParseLineException(lineNumber, ex); + } + } + /** * Parse an input stream into a list of maps * From e86784df9b6589a01ebc8879f0029c4cee855c8c Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 28 Jun 2023 17:36:27 -0700 Subject: [PATCH 64/98] Parser for polygon data file --- .../io/parse/AbstractStreamingParser.java | 46 ++++++++++++ .../io/parse/ControlMapValueReplacer.java | 29 ++++++++ .../io/parse/KeyedControlMapModifier.java | 12 +++ .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 26 ++++++- .../io/parse/ResourceControlMapModifier.java | 9 +-- .../nrs/vdyp/io/parse/StreamingParser.java | 26 +++++++ .../vdyp/io/parse/StreamingParserFactory.java | 13 ++++ .../bc/gov/nrs/vdyp/fip/FipPolygonParser.java | 73 +++++++++++++++++++ .../bc/gov/nrs/vdyp/fip/model/FipPolygon.java | 70 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/fip_l1.dat | 23 ++++++ .../ca/bc/gov/nrs/vdyp/fip/fip_ls1.dat | 52 +++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/fip_p1.dat | 10 +++ 12 files changed, 377 insertions(+), 12 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/KeyedControlMapModifier.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_l1.dat create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_ls1.dat create mode 100755 vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_p1.dat diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java new file mode 100644 index 000000000..555ed5178 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java @@ -0,0 +1,46 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.io.parse.LineParser.LineStream; + +public abstract class AbstractStreamingParser implements StreamingParser { + + private LineStream lineStream; + + /** + * Create a new streaming parser + * @param is Input stream to read from + * @param lineParser + * @param control + */ + public AbstractStreamingParser(InputStream is, LineParser lineParser, Map control){ + + this.lineStream = lineParser.parseAsStream(is, control); + } + + + @Override + public T next() throws IOException, ResourceParseException { + return this.convert(lineStream.next()); + } + + /** + * Set up the line parser to read the resource + * @return + */ + protected abstract T convert(Map entry); + + @Override + public boolean hasNext() throws IOException, ResourceParseException { + return lineStream.hasNext(); + } + + @Override + public void close() throws IOException { + lineStream.close(); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java new file mode 100644 index 000000000..a41e60bbb --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java @@ -0,0 +1,29 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.io.FileResolver; + +public interface ControlMapValueReplacer extends KeyedControlMapModifier { + + /** + * Remap a raw control value + * @param rawValue + * @return + * @throws ResourceParseException + * @throws IOException + */ + public Result map(Raw rawValue) throws ResourceParseException, IOException; + + @SuppressWarnings("unchecked") + @Override + default void modify(Map control, FileResolver fileResolver) + throws ResourceParseException, IOException { + + control.put(getControlKey(), this.map((Raw) control.get(this.getControlKey()))); + + } + + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/KeyedControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/KeyedControlMapModifier.java new file mode 100644 index 000000000..2788f479f --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/KeyedControlMapModifier.java @@ -0,0 +1,12 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +public interface KeyedControlMapModifier extends ControlMapModifier { + + /** + * The key for this resource's entry in the control map + * + * @return + */ + String getControlKey(); + +} \ No newline at end of file diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 9b31bc53b..bc595c828 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -12,6 +12,8 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; /** * Parse a file with records consisting of lines with fixed width fields. @@ -257,9 +259,7 @@ private Map parse(List segmentStrings, Map T parse( InputStream is, T result, ParseEntryHandler, T> addToResult, Map control ) throws IOException, ResourceParseLineException { - var reader = new BufferedReader(new InputStreamReader(is, charset)); - - var stream = new LineStream(reader, control); + var stream = parseAsStream(is, control); // Assume the caller will close the stream so we don't need to close this. while (stream.hasNext()) { var entry = stream.next(); try { @@ -271,7 +271,20 @@ public T parse( return result; } - public class LineStream { + /** + * Returns a LineStream of parsed entry maps. Closing it will close the provided stream. + * @param is + * @param control + * @return + */ + LineStream parseAsStream(InputStream is, Map control) { + var reader = new BufferedReader(new InputStreamReader(is, charset)); + + var stream = new LineStream(reader, control); + return stream; + } + + public class LineStream implements AutoCloseable { int lineNumber = 0; BufferedReader reader; @@ -342,6 +355,11 @@ private Optional> doGetNext() throws IOException, ResourcePa void handleValueParseException(ValueParseException ex) throws ResourceParseLineException { throw new ResourceParseLineException(lineNumber, ex); } + + @Override + public void close() throws IOException { + this.reader.close(); + } } /** diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java index fd2b3ccbc..06bb77022 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ResourceControlMapModifier.java @@ -12,17 +12,10 @@ * @author Kevin Smith, Vivid Solutions * */ -public interface ResourceControlMapModifier extends ControlMapModifier { +public interface ResourceControlMapModifier extends ControlMapModifier, KeyedControlMapModifier { void modify(Map control, InputStream data) throws ResourceParseException, IOException; - /** - * The key for this resource's entry in the control map - * - * @return - */ - String getControlKey(); - /** * Replace the entry in the control map containing the filename for a resource * with the parsed resource diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java new file mode 100644 index 000000000..9db572c9b --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java @@ -0,0 +1,26 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; + +public interface StreamingParser extends AutoCloseable { + + /** + * Get the next entry in the resource + * @return + * @throws IOException + * @throws ResourceParseException + */ + T next() throws IOException, ResourceParseException; + + /** + * Is there a next resource + * @return + * @throws IOException + * @throws ResourceParseException + */ + boolean hasNext() throws IOException, ResourceParseException; + + @Override + void close() throws IOException; + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java new file mode 100644 index 000000000..7d4119afa --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java @@ -0,0 +1,13 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.util.function.Supplier; + +public interface StreamingParserFactory extends Supplier>{ + + /** + * Open the resource and get a streaming parser for it. This must be closed. + */ + @Override + StreamingParser get(); + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java new file mode 100644 index 000000000..14821ffc5 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java @@ -0,0 +1,73 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; +import ca.bc.gov.nrs.vdyp.io.parse.AbstractStreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.ControlMapSubResourceParser; +import ca.bc.gov.nrs.vdyp.io.parse.LineParser; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; + +public class FipPolygonParser implements ControlMapSubResourceParser> { + + public static final String CONTROL_KEY = "FIP_POLYGONS"; + + + static final String POLYGON_IDENTIFIER = "POLYGON_IDENTIFIER"; // POLYDESC + static final String FOREST_INVENTORY_ZONE = "FOREST_INVENTORY_ZONE"; // FIZ + static final String BIOGEOGRAPHIC_ZONE = "BIOGEOGRAPHIC_ZONE"; // BEC + static final String PERCENT_FOREST_LAND = "PERCENT_FOREST_LAND"; // PCTFLAND + static final String FIP_MODE = "FIP_MODE"; // MODEfip + static final String NONPRODUCTIVE_DESCRIPTION = "NONPRODUCTIVE_DESCRIPTION"; // NPDESC + static final String YIELD_FACTOR = "YIELD_FACTOR"; // YLDFACT + + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + + @Override + public StreamingParserFactory parse(InputStream is, Map control) + throws IOException, ResourceParseException { + return ()->{ + var lineParser = new LineParser() + .strippedString(25, POLYGON_IDENTIFIER) + .space(1) + .strippedString(1, FOREST_INVENTORY_ZONE) + .space(1) + .strippedString(4, BIOGEOGRAPHIC_ZONE) + .space(1) + .floating(4, PERCENT_FOREST_LAND) + .space(1) + .integer(2, FIP_MODE) + .space(1) + .string(5, NONPRODUCTIVE_DESCRIPTION) + .space(1) + .floating(5, YIELD_FACTOR); + + // TODO Default yield factor + + return new AbstractStreamingParser(is, lineParser, control) { + + @Override + protected FipPolygon convert(Map entry) { + var polygonId = (String) entry.get(POLYGON_IDENTIFIER); + var fizId = (String) entry.get(FOREST_INVENTORY_ZONE); + var becId = (String) entry.get(BIOGEOGRAPHIC_ZONE); + var percentForestLand = (float) entry.get(PERCENT_FOREST_LAND); + var fipMode = (int) entry.get(FIP_MODE); + var nonproductiveDesc = (String) entry.get(NONPRODUCTIVE_DESCRIPTION); + var yieldFactor = (float) entry.get(YIELD_FACTOR); + + return new FipPolygon(polygonId, fizId, becId, percentForestLand, fipMode, nonproductiveDesc, yieldFactor); + } + + }; + }; + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java new file mode 100644 index 000000000..9166aec0e --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java @@ -0,0 +1,70 @@ +package ca.bc.gov.nrs.vdyp.fip.model; + +public class FipPolygon { + + String polygonIdentifier; // POLYDESC + String forestInventoryZone; // FIZ + String biogeoclimaticZone; // BEC + float percentAvailable; // PCTFLAND + int modeFip; // MODEfip // Maybe make this an enum + String nonproductiveDescription; // NPDESC + float yieldFactor; // YLDFACT + + public FipPolygon( + String polygonIdentifier, String fiz, String becIdentifier, float percentAvailable, int modeFip, + String nonproductiveDescription, float yieldFactor + ) { + super(); + this.polygonIdentifier = polygonIdentifier; + this.forestInventoryZone = fiz; + this.biogeoclimaticZone = becIdentifier; + this.percentAvailable = percentAvailable; + this.modeFip = modeFip; + this.nonproductiveDescription = nonproductiveDescription; + this.yieldFactor = yieldFactor; + } + + public String getPolygonIdentifier() { + return polygonIdentifier; + } + public void setPolygonIdentifier(String polygonIdentifier) { + this.polygonIdentifier = polygonIdentifier; + } + public String getForestInventoryZone() { + return forestInventoryZone; + } + public void setForestInventoryZone(String forestInventoryZone) { + this.forestInventoryZone = forestInventoryZone; + } + public String getBiogeoclimaticZone() { + return biogeoclimaticZone; + } + public void setBiogeoclimaticZone(String biogeoclimaticZone) { + this.biogeoclimaticZone = biogeoclimaticZone; + } + public float getPercentAvailable() { + return percentAvailable; + } + public void setPercentAvailable(float percentAvailable) { + this.percentAvailable = percentAvailable; + } + public int getModeFip() { + return modeFip; + } + public void setModeFip(int modeFip) { + this.modeFip = modeFip; + } + public String getNonproductiveDescription() { + return nonproductiveDescription; + } + public void setNonproductiveDescription(String nonproductiveDescription) { + this.nonproductiveDescription = nonproductiveDescription; + } + public float getYieldFactor() { + return yieldFactor; + } + public void setYieldFactor(float yieldFactor) { + this.yieldFactor = yieldFactor; + } + +} diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_l1.dat b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_l1.dat new file mode 100755 index 000000000..d1d998376 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_l1.dat @@ -0,0 +1,23 @@ +01002 S000001 00 1970 1 55 35.3 35.0 87.4 D D 1.0 0 13 +01002 S000001 00 1970 Z 55 0.0 0.0 0.0 0.0 +01002 S000002 00 1970 1 45 24.3 28.7 82.8 H H 5.4 0 34 +01002 S000002 00 1970 V 105 26.2 16.7 4.0 H H 7.1 0 34 +01002 S000002 00 1970 Z 105 0.0 0.0 0.0 0.0 +01002 S000003 00 1970 V 125 39.0 23.9 4.0 B B 8.7 2 8 +01002 S000003 00 1970 1 85 38.3 28.6 82.8 H H 5.4 0 34 +01002 S000003 00 1970 Z 85 0.0 0.0 0.0 0.0 +01002 S000004 00 1970 V 195 45.2 22.3 4.0 B B 9.4 2 8 +01002 S000004 00 1970 1 85 42.3 31.9 82.8 H H 4.9 0 34 +01002 S000004 00 1970 Z 85 0.0 0.0 0.0 0.0 +01003AS000001 00 1953 1 215 29.5 14.8 64.4 C C 10.8 1 11 +01003AS000001 00 1953 Z 215 0.0 0.0 0.0 0.0 +01003AS000003 00 1953 1 225 34.0 16.7 64.4 C C 10.5 1 11 +01003AS000003 00 1953 Z 225 0.0 0.0 0.0 0.0 +01004 S000002 00 1953 1 245 44.8 21.4 73.6 C C 9.7 1 11 +01004 S000002 00 1953 Z 245 0.0 0.0 0.0 0.0 +01004 S000036 00 1957 1 265 41.4 19.2 78.2 C C 10.1 1 11 +01004 S000036 00 1957 Z 265 0.0 0.0 0.0 0.0 +01004 S000037 00 1957 1 265 28.9 13.4 73.6 C C 11.1 1 11 +01004 S000037 00 1957 Z 265 0.0 0.0 0.0 0.0 +01004 S000038 00 1957 1 285 24.4 11.1 64.4 C C 11.4 1 11 +01004 S000038 00 1957 Z 285 0.0 0.0 0.0 0.0 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_ls1.dat b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_ls1.dat new file mode 100755 index 000000000..e766cc8f5 --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_ls1.dat @@ -0,0 +1,52 @@ +01002 S000001 00 1970 1 B 1.0B 100.0 0.0 0.0 0.0 +01002 S000001 00 1970 1 C 7.0C 100.0 0.0 0.0 0.0 +01002 S000001 00 1970 1 D 74.0D 100.0 0.0 0.0 0.0 +01002 S000001 00 1970 1 H 9.0H 100.0 0.0 0.0 0.0 +01002 S000001 00 1970 1 S 9.0S 100.0 0.0 0.0 0.0 +01002 S000001 00 1970 Z 0.0 0.0 0.0 0.0 0.0 +01002 S000002 00 1970 1 B 15.0B 100.0 0.0 0.0 0.0 +01002 S000002 00 1970 1 D 7.0D 100.0 0.0 0.0 0.0 +01002 S000002 00 1970 1 H 77.0H 100.0 0.0 0.0 0.0 +01002 S000002 00 1970 1 S 1.0S 100.0 0.0 0.0 0.0 +01002 S000002 00 1970 V B 22.0B 100.0 0.0 0.0 0.0 +01002 S000002 00 1970 V H 60.0H 100.0 0.0 0.0 0.0 +01002 S000002 00 1970 V S 18.0S 100.0 0.0 0.0 0.0 +01002 S000002 00 1970 Z 0.0 0.0 0.0 0.0 0.0 +01002 S000003 00 1970 1 B 33.0B 100.0 0.0 0.0 0.0 +01002 S000003 00 1970 1 H 67.0H 100.0 0.0 0.0 0.0 +01002 S000003 00 1970 V B 100.0B 100.0 0.0 0.0 0.0 +01002 S000003 00 1970 Z 0.0 0.0 0.0 0.0 0.0 +01002 S000004 00 1970 1 B 24.0B 100.0 0.0 0.0 0.0 +01002 S000004 00 1970 1 H 75.0H 100.0 0.0 0.0 0.0 +01002 S000004 00 1970 1 S 1.0S 100.0 0.0 0.0 0.0 +01002 S000004 00 1970 V B 100.0B 100.0 0.0 0.0 0.0 +01002 S000004 00 1970 Z 0.0 0.0 0.0 0.0 0.0 +01003AS000001 00 1953 1 B 3.0B 100.0 0.0 0.0 0.0 +01003AS000001 00 1953 1 C 48.0C 100.0 0.0 0.0 0.0 +01003AS000001 00 1953 1 H 47.0H 100.0 0.0 0.0 0.0 +01003AS000001 00 1953 1 S 2.0S 100.0 0.0 0.0 0.0 +01003AS000001 00 1953 Z 0.0 0.0 0.0 0.0 0.0 +01003AS000003 00 1953 1 B 4.0B 100.0 0.0 0.0 0.0 +01003AS000003 00 1953 1 C 63.0C 100.0 0.0 0.0 0.0 +01003AS000003 00 1953 1 H 33.0H 100.0 0.0 0.0 0.0 +01003AS000003 00 1953 Z 0.0 0.0 0.0 0.0 0.0 +01004 S000002 00 1953 1 B 13.0B 100.0 0.0 0.0 0.0 +01004 S000002 00 1953 1 C 57.0C 100.0 0.0 0.0 0.0 +01004 S000002 00 1953 1 H 30.0H 100.0 0.0 0.0 0.0 +01004 S000002 00 1953 Z 0.0 0.0 0.0 0.0 0.0 +01004 S000036 00 1957 1 B 22.0B 100.0 0.0 0.0 0.0 +01004 S000036 00 1957 1 C 49.0C 100.0 0.0 0.0 0.0 +01004 S000036 00 1957 1 H 18.0H 100.0 0.0 0.0 0.0 +01004 S000036 00 1957 1 Y 11.0Y 100.0 0.0 0.0 0.0 +01004 S000036 00 1957 Z 0.0 0.0 0.0 0.0 0.0 +01004 S000037 00 1957 1 B 1.0B 100.0 0.0 0.0 0.0 +01004 S000037 00 1957 1 C 40.0C 100.0 0.0 0.0 0.0 +01004 S000037 00 1957 1 H 20.0H 100.0 0.0 0.0 0.0 +01004 S000037 00 1957 1 PL 6.0PL 100.0 0.0 0.0 0.0 +01004 S000037 00 1957 1 Y 33.0Y 100.0 0.0 0.0 0.0 +01004 S000037 00 1957 Z 0.0 0.0 0.0 0.0 0.0 +01004 S000038 00 1957 1 C 34.0C 100.0 0.0 0.0 0.0 +01004 S000038 00 1957 1 H 22.0H 100.0 0.0 0.0 0.0 +01004 S000038 00 1957 1 PL 11.0PL 100.0 0.0 0.0 0.0 +01004 S000038 00 1957 1 Y 33.0Y 100.0 0.0 0.0 0.0 +01004 S000038 00 1957 Z 0.0 0.0 0.0 0.0 0.0 diff --git a/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_p1.dat b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_p1.dat new file mode 100755 index 000000000..44228e2cc --- /dev/null +++ b/vdyp-fip/src/test/resources/ca/bc/gov/nrs/vdyp/fip/fip_p1.dat @@ -0,0 +1,10 @@ +01002 S000001 00 1970 A CWH 1.00 +01002 S000002 00 1970 A CWH 1.00 +01002 S000003 00 1970 A CWH 1.00 +01002 S000004 00 1970 A CWH 1.00 +01003AS000001 00 1953 B CWH 1.00 +01003AS000003 00 1953 B CWH 1.00 +01004 S000002 00 1953 B CWH 1.00 +01004 S000036 00 1957 B CWH 1.00 +01004 S000037 00 1957 B CWH 1.00 +01004 S000038 00 1957 B CWH 1.00 From cc3b86b6e9ef5c9c52435461b640ffec9550e2ba Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 29 Jun 2023 18:24:02 -0700 Subject: [PATCH 65/98] Working on parser for polygon data --- .../io/parse/AbstractStreamingParser.java | 13 +- .../vdyp/io/parse/BecDefinitionParser.java | 6 +- .../nrs/vdyp/io/parse/ControlFileParser.java | 15 +- .../io/parse/ControlMapValueReplacer.java | 15 +- .../vdyp/io/parse/ControlledValueParser.java | 2 +- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 93 +++++------ .../nrs/vdyp/io/parse/StreamingParser.java | 2 + .../vdyp/io/parse/StreamingParserFactory.java | 11 +- .../io/parse/BecDefinitionParserTest.java | 33 ++++ .../gov/nrs/vdyp/io/parse/LineParserTest.java | 53 +----- .../ca/bc/gov/nrs/vdyp/test/TestUtils.java | 26 +++ .../bc/gov/nrs/vdyp/fip/FipPolygonParser.java | 68 ++++---- .../bc/gov/nrs/vdyp/fip/model/FipPolygon.java | 23 ++- .../nrs/vdyp/fip/FipPolygonParserTest.java | 154 ++++++++++++++++++ 14 files changed, 340 insertions(+), 174 deletions(-) create mode 100644 vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java index 555ed5178..0d0315836 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java @@ -12,15 +12,15 @@ public abstract class AbstractStreamingParser implements StreamingParser { /** * Create a new streaming parser - * @param is Input stream to read from - * @param lineParser + * + * @param is Input stream to read from + * @param lineParser * @param control */ - public AbstractStreamingParser(InputStream is, LineParser lineParser, Map control){ - + public AbstractStreamingParser(InputStream is, LineParser lineParser, Map control) { + this.lineStream = lineParser.parseAsStream(is, control); } - @Override public T next() throws IOException, ResourceParseException { @@ -29,6 +29,7 @@ public T next() throws IOException, ResourceParseException { /** * Set up the line parser to read the resource + * * @return */ protected abstract T convert(Map entry); @@ -42,5 +43,5 @@ public boolean hasNext() throws IOException, ResourceParseException { public void close() throws IOException { lineStream.close(); } - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java index e6fc07745..f3587f039 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParser.java @@ -32,9 +32,9 @@ public boolean isStopSegment(List segments) { }.strippedString(4, "alias").space(1).value(1, "region", ValueParser.REGION).space(1).strippedString("name"); - private static final Map GROWTH_INDEX = new HashMap<>(); - private static final Map VOLUME_INDEX = new HashMap<>(); - private static final Map DECAY_INDEX = new HashMap<>(); + static final Map GROWTH_INDEX = new HashMap<>(); + static final Map VOLUME_INDEX = new HashMap<>(); + static final Map DECAY_INDEX = new HashMap<>(); static { GROWTH_INDEX.put("AT", 0); GROWTH_INDEX.put("BG", 0); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java index b5ccb14f8..e081db993 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParser.java @@ -42,12 +42,15 @@ public boolean isIgnoredLine(String line) { @Override public boolean isIgnoredSegment(List segments) { - return segments.get(0).isBlank(); - } - - @Override - public boolean isIgnoredEntry(Map segments) { - return 0 == (Integer) segments.get("index") || COMMENT_FLAGS.contains(segments.get("extend")); + try { + var sequenceComment = ValueParser.optional(ValueParser.INTEGER).parse(segments.get(0)) + .map(x -> x.equals(0)).orElse(true); + var extendComment = ValueParser.optional(ValueParser.STRING).parse(segments.get(1)) + .map(COMMENT_FLAGS::contains).orElse(false); + return sequenceComment || extendComment; + } catch (ValueParseException e) { + return false; // Ignore it for now, throw the exception for real when parsing instead. + } } }.integer(3, "index").string(1, "extend").string("restOfLine"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java index a41e60bbb..fd80f384f 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlMapValueReplacer.java @@ -6,24 +6,25 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; public interface ControlMapValueReplacer extends KeyedControlMapModifier { - + /** * Remap a raw control value + * * @param rawValue * @return * @throws ResourceParseException * @throws IOException */ - public Result map(Raw rawValue) throws ResourceParseException, IOException; + public Result map(Raw rawValue, FileResolver fileResolver, Map control) + throws ResourceParseException, IOException; @SuppressWarnings("unchecked") @Override default void modify(Map control, FileResolver fileResolver) throws ResourceParseException, IOException { - - control.put(getControlKey(), this.map((Raw) control.get(this.getControlKey()))); - + + control.put(getControlKey(), this.map((Raw) control.get(this.getControlKey()), fileResolver, control)); + } - - + } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java index 1f6a8388c..288f2a394 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java @@ -69,7 +69,7 @@ public static ControlledValueParser> optional(ControlledValuePar */ static final ControlledValueParser BEC = (string, control) -> { var result = string.strip(); - if (!BecDefinitionParser.getBecAliases(control).contains(string)) { + if (!BecDefinitionParser.getBecAliases(control).contains(result)) { throw new ValueParseException(string, string + " is not a valid BEC"); } return result; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index bc595c828..d872c6d8f 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -12,8 +12,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Stream; /** * Parse a file with records consisting of lines with fixed width fields. @@ -259,7 +257,8 @@ private Map parse(List segmentStrings, Map T parse( InputStream is, T result, ParseEntryHandler, T> addToResult, Map control ) throws IOException, ResourceParseLineException { - var stream = parseAsStream(is, control); // Assume the caller will close the stream so we don't need to close this. + var stream = parseAsStream(is, control); // Assume the caller will close the stream so we don't need to close + // this. while (stream.hasNext()) { var entry = stream.next(); try { @@ -272,7 +271,9 @@ public T parse( } /** - * Returns a LineStream of parsed entry maps. Closing it will close the provided stream. + * Returns a LineStream of parsed entry maps. Closing it will close the provided + * stream. + * * @param is * @param control * @return @@ -290,7 +291,7 @@ public class LineStream implements AutoCloseable { BufferedReader reader; Map control; - Optional>> next = Optional.empty(); + Optional> nextLine = Optional.empty(); public LineStream(BufferedReader reader, Map control) { this.reader = reader; @@ -298,57 +299,57 @@ public LineStream(BufferedReader reader, Map control) { } public Map next() throws IOException, ResourceParseLineException { - if (next.isEmpty()) { - next = Optional.of(doGetNext()); + if (nextLine.isEmpty()) { + nextLine = Optional.of(doGetNextLine()); } try { - return next.get() + var line = nextLine.get() .orElseThrow(() -> new IllegalStateException("Tried to get next entry when none exists")); + var segments = segmentize(line); + + var entry = parse(segments, control); + + entry.put(LINE_NUMBER_KEY, lineNumber); + + return entry; + } catch (ValueParseException ex) { + handleValueParseException(ex); + return null; } finally { - next = Optional.empty(); + nextLine = Optional.empty(); } } public boolean hasNext() throws IOException, ResourceParseLineException { - if (next.isEmpty()) { - next = Optional.of(doGetNext()); + if (nextLine.isEmpty()) { + nextLine = Optional.of(doGetNextLine()); } - return next.get().isPresent(); + return nextLine.get().isPresent(); } - private Optional> doGetNext() throws IOException, ResourceParseLineException { + private Optional doGetNextLine() throws IOException, ResourceParseLineException { while (true) { lineNumber++; var line = reader.readLine(); if (Objects.isNull(line)) { return Optional.empty(); } - try { - if (isStopLine(line)) { - return Optional.empty(); - } - if (isIgnoredLine(line)) { - continue; - } - var segments = segmentize(line); - if (isStopSegment(segments)) { - return Optional.empty(); - } - if (isIgnoredSegment(segments)) { - continue; - } - var entry = parse(segments, control); - entry.put(LINE_NUMBER_KEY, lineNumber); - if (isStopEntry(entry)) { - return Optional.empty(); - } - if (isIgnoredEntry(entry)) { - continue; - } - return Optional.of(entry); - } catch (ValueParseException ex) { - handleValueParseException(ex); + if (isStopLine(line)) { + return Optional.empty(); } + if (isIgnoredLine(line)) { + continue; + } + var segments = segmentize(line); + if (isStopSegment(segments)) { + return Optional.empty(); + } + if (isIgnoredSegment(segments)) { + continue; + } + + return Optional.of(line); + } } @@ -382,14 +383,6 @@ public List> parse(InputStream is, Map contr return result; } - /** - * If this returns true for a parsed line, parsing will stop and that line will - * not be included in the result. - */ - protected boolean isStopEntry(Map entry) { - return false; - } - /** * If this returns true for a segmented line, parsing will stop and that line * will not be included in the result. @@ -406,14 +399,6 @@ public boolean isStopLine(String line) { return false; } - /** - * If this returns true for a parsed line, that line will not be included in the - * result. - */ - public boolean isIgnoredEntry(Map entry) { - return false; - } - /** * If this returns true for a segmented line, that line will not be included in * the result. diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java index 9db572c9b..55ef49af5 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParser.java @@ -6,6 +6,7 @@ public interface StreamingParser extends AutoCloseable { /** * Get the next entry in the resource + * * @return * @throws IOException * @throws ResourceParseException @@ -14,6 +15,7 @@ public interface StreamingParser extends AutoCloseable { /** * Is there a next resource + * * @return * @throws IOException * @throws ResourceParseException diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java index 7d4119afa..4f83aa00b 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/StreamingParserFactory.java @@ -1,13 +1,12 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.function.Supplier; +import java.io.IOException; -public interface StreamingParserFactory extends Supplier>{ +public interface StreamingParserFactory { /** - * Open the resource and get a streaming parser for it. This must be closed. + * Open the resource and get a streaming parser for it. This must be closed. */ - @Override - StreamingParser get(); - + StreamingParser get() throws IOException; + } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index 04bc6ab9f..ba63bf7d3 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -12,6 +12,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; import static org.hamcrest.Matchers.equalTo; @@ -221,6 +223,37 @@ public static void populateControlMap(Map controlMap) { populateControlMap(controlMap, "B1", "B2"); } + static BecDefinition makeBec(String id, Region region, String name) { + return new BecDefinition( + id, region, name, BecDefinitionParser.GROWTH_INDEX.get("BG"), + BecDefinitionParser.VOLUME_INDEX.get("BG"), BecDefinitionParser.DECAY_INDEX.get("BG") + ); + } + + /** + * Add a mock control map entry for BEC parse results with species "B1" and "B2" + * for Coastal and Interior Regions respectively + */ + public static void populateControlMapReal(Map controlMap) { + List becs = new ArrayList<>(); + + becs.add(makeBec("BG", Region.INTERIOR, "Bunchgrass")); + becs.add(makeBec("BWBS", Region.INTERIOR, "Boreal White and Black Spruce")); + becs.add(makeBec("CDF", Region.INTERIOR, "Coastal Dougfir")); + becs.add(makeBec("CWH", Region.INTERIOR, "Coastal Western Hemlock")); + becs.add(makeBec("ESSF", Region.INTERIOR, "Englemann Sruce -SubAlpine Fir")); + becs.add(makeBec("ICH", Region.INTERIOR, "Interior Cedar-Hemlock")); + becs.add(makeBec("IDF", Region.INTERIOR, "Interior DougFir")); + becs.add(makeBec("MH", Region.INTERIOR, "Mountain Hemlock")); + becs.add(makeBec("MS", Region.INTERIOR, "Montane Spruce")); + becs.add(makeBec("PP", Region.INTERIOR, "Ponderosa Pine")); + becs.add(makeBec("SBPS", Region.INTERIOR, "SubBoreal Pine-Spruce")); + becs.add(makeBec("SBS", Region.INTERIOR, "SubBoreal Spruce")); + becs.add(makeBec("SWB", Region.INTERIOR, "Spruce-Willow-Birch")); + + controlMap.put(BecDefinitionParser.CONTROL_KEY, new BecLookup(becs)); + } + /** * Add a mock control map entry for SP0 parse results. Alternates assigning to * Coastal and Interior regions, starting with Coastal. diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 4bb302100..528cd4d95 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -2,8 +2,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.array; -import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasKey; @@ -20,7 +18,6 @@ import java.util.Map; import org.hamcrest.Matcher; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; public class LineParserTest { @@ -158,7 +155,7 @@ public void testStripped() throws Exception { } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiValue() throws Exception { var parser = new LineParser(); @@ -212,27 +209,6 @@ public void testMultiLineException() throws Exception { } } - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Test - public void testMultiLineWithStopEntry() throws Exception { - var parser = new LineParser() { - - @Override - public boolean isStopEntry(Map entry) { - return 0 == (int) entry.get("part1"); - } - - }; - parser.integer(4, "part1").space(1).string("part2"); - - List> result = new ArrayList<>(); - try (var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes());) { - result = parser.parse(is, Collections.emptyMap()); - } - - assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); - } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLineWithStopLine() throws Exception { @@ -275,33 +251,6 @@ public boolean isStopSegment(List segments) { assertThat(result, contains(allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")))); } - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Test - public void testMultiLineWithIgnoredEntry() throws Exception { - var parser = new LineParser() { - - @Override - public boolean isIgnoredEntry(Map entry) { - return 0 == (int) entry.get("part1"); - } - - }; - parser.integer(4, "part1").space(1).string("part2"); - - List> result = new ArrayList<>(); - try (var is = new ByteArrayInputStream("0042 Value1\r\n0000\r\n0043 Value2".getBytes());) { - result = parser.parse(is, Collections.emptyMap()); - } - - assertThat( - result, - contains( - allOf((Matcher) hasEntry("part1", 42), (Matcher) hasEntry("part2", "Value1")), - allOf((Matcher) hasEntry("part1", 43), (Matcher) hasEntry("part2", "Value2")) - ) - ); - } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiLineWithIgnoredLine() throws Exception { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java index 314b1cdb4..721e036d6 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/TestUtils.java @@ -1,11 +1,37 @@ package ca.bc.gov.nrs.vdyp.test; +import static org.junit.jupiter.api.Assertions.fail; + import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; +import ca.bc.gov.nrs.vdyp.io.FileResolver; + public class TestUtils { public static InputStream makeStream(String... lines) { return new ByteArrayInputStream(String.join("\r\n", lines).getBytes()); } + + public static FileResolver fileResolver(String expectedFilename, InputStream is) { + return new FileResolver() { + + @Override + public InputStream resolve(String filename) throws IOException { + if (filename.equals(expectedFilename)) { + return is; + } else { + fail("Attempted to resolve unexpected filename " + filename); + return null; + } + } + + @Override + public String toString(String filename) throws IOException { + return "TEST:" + filename; + } + + }; + } } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java index 14821ffc5..20ed35ed5 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java @@ -3,54 +3,49 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; +import java.util.Optional; import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; +import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.AbstractStreamingParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlMapSubResourceParser; +import ca.bc.gov.nrs.vdyp.io.parse.ControlMapValueReplacer; import ca.bc.gov.nrs.vdyp.io.parse.LineParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; -public class FipPolygonParser implements ControlMapSubResourceParser> { +public class FipPolygonParser implements ControlMapValueReplacer, String> { + + public static final String CONTROL_KEY = "FIP_POLYGONS"; - public static final String CONTROL_KEY = "FIP_POLYGONS"; - - static final String POLYGON_IDENTIFIER = "POLYGON_IDENTIFIER"; // POLYDESC static final String FOREST_INVENTORY_ZONE = "FOREST_INVENTORY_ZONE"; // FIZ static final String BIOGEOGRAPHIC_ZONE = "BIOGEOGRAPHIC_ZONE"; // BEC static final String PERCENT_FOREST_LAND = "PERCENT_FOREST_LAND"; // PCTFLAND - static final String FIP_MODE = "FIP_MODE"; // MODEfip + static final String FIP_MODE = "FIP_MODE"; // MODEfip static final String NONPRODUCTIVE_DESCRIPTION = "NONPRODUCTIVE_DESCRIPTION"; // NPDESC static final String YIELD_FACTOR = "YIELD_FACTOR"; // YLDFACT - - + @Override public String getControlKey() { return CONTROL_KEY; } @Override - public StreamingParserFactory parse(InputStream is, Map control) - throws IOException, ResourceParseException { - return ()->{ - var lineParser = new LineParser() - .strippedString(25, POLYGON_IDENTIFIER) - .space(1) - .strippedString(1, FOREST_INVENTORY_ZONE) - .space(1) - .strippedString(4, BIOGEOGRAPHIC_ZONE) - .space(1) - .floating(4, PERCENT_FOREST_LAND) - .space(1) - .integer(2, FIP_MODE) - .space(1) - .string(5, NONPRODUCTIVE_DESCRIPTION) - .space(1) - .floating(5, YIELD_FACTOR); - - // TODO Default yield factor - + public StreamingParserFactory + map(String fileName, FileResolver fileResolver, Map control) + throws IOException, ResourceParseException { + return () -> { + var lineParser = new LineParser().strippedString(25, POLYGON_IDENTIFIER).space(1) + .strippedString(1, FOREST_INVENTORY_ZONE).space(1).value(4, BIOGEOGRAPHIC_ZONE, ValueParser.BEC) + .space(1).value(4, PERCENT_FOREST_LAND, ValueParser.optional(ValueParser.FLOAT)).space(1) + .value(2, FIP_MODE, ValueParser.optional(ValueParser.INTEGER)).space(1) + .value(5, NONPRODUCTIVE_DESCRIPTION, ValueParser.optional(ValueParser.STRING)) + .value(5, YIELD_FACTOR, ValueParser.optional(ValueParser.FLOAT)); + + var is = fileResolver.resolve(fileName); + return new AbstractStreamingParser(is, lineParser, control) { @Override @@ -58,14 +53,19 @@ protected FipPolygon convert(Map entry) { var polygonId = (String) entry.get(POLYGON_IDENTIFIER); var fizId = (String) entry.get(FOREST_INVENTORY_ZONE); var becId = (String) entry.get(BIOGEOGRAPHIC_ZONE); - var percentForestLand = (float) entry.get(PERCENT_FOREST_LAND); - var fipMode = (int) entry.get(FIP_MODE); - var nonproductiveDesc = (String) entry.get(NONPRODUCTIVE_DESCRIPTION); - var yieldFactor = (float) entry.get(YIELD_FACTOR); - - return new FipPolygon(polygonId, fizId, becId, percentForestLand, fipMode, nonproductiveDesc, yieldFactor); + var percentForestLand = (Optional) entry.get(PERCENT_FOREST_LAND); + var fipMode = (Optional) entry.get(FIP_MODE); + var nonproductiveDesc = (Optional) entry.get(NONPRODUCTIVE_DESCRIPTION); + var yieldFactor = (Optional) entry.get(YIELD_FACTOR); + + yieldFactor = yieldFactor.filter(x -> x > 0.0f); + + return new FipPolygon( + polygonId, fizId, becId, percentForestLand.orElse(100.0f), fipMode.orElse(1), + nonproductiveDesc.orElse(""), yieldFactor.orElse(1.0f) + ); } - + }; }; } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java index 9166aec0e..8b16f5eea 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java @@ -1,15 +1,15 @@ package ca.bc.gov.nrs.vdyp.fip.model; public class FipPolygon { - + String polygonIdentifier; // POLYDESC String forestInventoryZone; // FIZ String biogeoclimaticZone; // BEC float percentAvailable; // PCTFLAND - int modeFip; // MODEfip // Maybe make this an enum + int modeFip; // MODEfip // Maybe make this an enum String nonproductiveDescription; // NPDESC float yieldFactor; // YLDFACT - + public FipPolygon( String polygonIdentifier, String fiz, String becIdentifier, float percentAvailable, int modeFip, String nonproductiveDescription, float yieldFactor @@ -23,48 +23,61 @@ public FipPolygon( this.nonproductiveDescription = nonproductiveDescription; this.yieldFactor = yieldFactor; } - + public String getPolygonIdentifier() { return polygonIdentifier; } + public void setPolygonIdentifier(String polygonIdentifier) { this.polygonIdentifier = polygonIdentifier; } + public String getForestInventoryZone() { return forestInventoryZone; } + public void setForestInventoryZone(String forestInventoryZone) { this.forestInventoryZone = forestInventoryZone; } + public String getBiogeoclimaticZone() { return biogeoclimaticZone; } + public void setBiogeoclimaticZone(String biogeoclimaticZone) { this.biogeoclimaticZone = biogeoclimaticZone; } + public float getPercentAvailable() { return percentAvailable; } + public void setPercentAvailable(float percentAvailable) { this.percentAvailable = percentAvailable; } + public int getModeFip() { return modeFip; } + public void setModeFip(int modeFip) { this.modeFip = modeFip; } + public String getNonproductiveDescription() { return nonproductiveDescription; } + public void setNonproductiveDescription(String nonproductiveDescription) { this.nonproductiveDescription = nonproductiveDescription; } + public float getYieldFactor() { return yieldFactor; } + public void setYieldFactor(float yieldFactor) { this.yieldFactor = yieldFactor; } - + } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java new file mode 100644 index 000000000..f6e8ee410 --- /dev/null +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java @@ -0,0 +1,154 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeDiagnosingMatcher; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; +import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class FipPolygonParserTest { + + @Test + public void testParseEmpty() throws Exception { + + var parser = new FipPolygonParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver("test.dat", TestUtils.makeStream(/* empty */)); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipPolygonParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + assertEmpty(stream); + } + + @Test + public void testParsePolygon() throws Exception { + + var parser = new FipPolygonParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + // Polygon ID FIZ BEC PctF mode ND Yld + // AAAAAAAAAAAAAAAAAAAAAAAAA A AAAA FFFF II AAAAAFFFFF + var fileResolver = TestUtils + .fileResolver("test.dat", TestUtils.makeStream("Test Polygon 1 CWH 90.0 1 BLAH 0.95")); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipPolygonParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var poly = assertNext(stream); + + assertEmpty(stream); + } + + @Test + public void testParsePolygonWithBlanks() throws Exception { + + var parser = new FipPolygonParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + // Polygon ID FIZ BEC PctF mode ND Yld + // AAAAAAAAAAAAAAAAAAAAAAAAA A AAAA FFFF II AAAAAFFFFF + var fileResolver = TestUtils + .fileResolver("test.dat", TestUtils.makeStream("01002 S000001 00 1970 A CWH 1.00")); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipPolygonParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var poly = assertNext(stream); + + assertEmpty(stream); + } + + static T assertNext(StreamingParser stream) throws IOException, ResourceParseException { + assertThat(stream, hasNext(true)); + var next = assertDoesNotThrow(() -> stream.next()); + assertThat(next, notNullValue()); + return next; + } + + static void assertEmpty(StreamingParser stream) throws IOException, ResourceParseException { + assertThat(stream, hasNext(false)); + assertThrows(IllegalStateException.class, () -> stream.next()); + } + + static Matcher> hasNext(boolean value) { + return new TypeSafeDiagnosingMatcher>() { + + @Override + public void describeTo(Description description) { + + description.appendText("StreamingParser with hasNext() ").appendValue(value); + + } + + @Override + protected boolean matchesSafely(StreamingParser item, Description mismatchDescription) { + try { + var hasNext = item.hasNext(); + if (hasNext == value) { + return true; + } + mismatchDescription.appendText("hasNext() returned ").appendValue(hasNext); + return false; + } catch (IOException | ResourceParseException e) { + mismatchDescription.appendText("hasNext() threw ").appendValue(e.getMessage()); + return false; + } + } + + }; + } +} From 01af9f7842709121ff1976cdc3a63521006390ca Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 30 Jun 2023 13:08:14 -0700 Subject: [PATCH 66/98] Parsing polygon data file --- .../bc/gov/nrs/vdyp/fip/FipPolygonParser.java | 7 +- .../ca/bc/gov/nrs/vdyp/fip/model/FipMode.java | 33 +++ .../bc/gov/nrs/vdyp/fip/model/FipPolygon.java | 24 +- .../nrs/vdyp/fip/FipPolygonParserTest.java | 243 +++++++++++++++++- 4 files changed, 288 insertions(+), 19 deletions(-) create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipMode.java diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java index 20ed35ed5..3e6ca08fa 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java @@ -5,6 +5,7 @@ import java.util.Map; import java.util.Optional; +import ca.bc.gov.nrs.vdyp.fip.model.FipMode; import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.AbstractStreamingParser; @@ -48,6 +49,7 @@ public String getControlKey() { return new AbstractStreamingParser(is, lineParser, control) { + @SuppressWarnings("unchecked") @Override protected FipPolygon convert(Map entry) { var polygonId = (String) entry.get(POLYGON_IDENTIFIER); @@ -58,11 +60,12 @@ protected FipPolygon convert(Map entry) { var nonproductiveDesc = (Optional) entry.get(NONPRODUCTIVE_DESCRIPTION); var yieldFactor = (Optional) entry.get(YIELD_FACTOR); + percentForestLand = percentForestLand.filter(x -> x > 0.0f); yieldFactor = yieldFactor.filter(x -> x > 0.0f); return new FipPolygon( - polygonId, fizId, becId, percentForestLand.orElse(100.0f), fipMode.orElse(1), - nonproductiveDesc.orElse(""), yieldFactor.orElse(1.0f) + polygonId, fizId, becId, percentForestLand, fipMode.flatMap(FipMode::getByCode), + nonproductiveDesc, yieldFactor.orElse(1.0f) ); } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipMode.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipMode.java new file mode 100644 index 000000000..84e51c685 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipMode.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.vdyp.fip.model; + +import java.util.Optional; + +public enum FipMode { + + DONT_PROCESS(-1), FIPSTART(1), FIPYOUNG(2); + + private final int code; + + FipMode(int i) { + code = i; + } + + public int getCode() { + return code; + } + + public static Optional getByCode(int code) { + switch (code) { + case -1: + return Optional.of(DONT_PROCESS); + case 0: + return Optional.empty(); + case 1: + return Optional.of(FIPSTART); + case 2: + return Optional.of(FIPYOUNG); + default: + return Optional.of(DONT_PROCESS); + } + } +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java index 8b16f5eea..362a89b13 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java @@ -1,18 +1,20 @@ package ca.bc.gov.nrs.vdyp.fip.model; +import java.util.Optional; + public class FipPolygon { String polygonIdentifier; // POLYDESC String forestInventoryZone; // FIZ String biogeoclimaticZone; // BEC - float percentAvailable; // PCTFLAND - int modeFip; // MODEfip // Maybe make this an enum - String nonproductiveDescription; // NPDESC + Optional percentAvailable; // PCTFLAND + Optional modeFip; // MODEfip + Optional nonproductiveDescription; // NPDESC float yieldFactor; // YLDFACT public FipPolygon( - String polygonIdentifier, String fiz, String becIdentifier, float percentAvailable, int modeFip, - String nonproductiveDescription, float yieldFactor + String polygonIdentifier, String fiz, String becIdentifier, Optional percentAvailable, + Optional modeFip, Optional nonproductiveDescription, float yieldFactor ) { super(); this.polygonIdentifier = polygonIdentifier; @@ -48,27 +50,27 @@ public void setBiogeoclimaticZone(String biogeoclimaticZone) { this.biogeoclimaticZone = biogeoclimaticZone; } - public float getPercentAvailable() { + public Optional getPercentAvailable() { return percentAvailable; } - public void setPercentAvailable(float percentAvailable) { + public void setPercentAvailable(Optional percentAvailable) { this.percentAvailable = percentAvailable; } - public int getModeFip() { + public Optional getModeFip() { return modeFip; } - public void setModeFip(int modeFip) { + public void setModeFip(Optional modeFip) { this.modeFip = modeFip; } - public String getNonproductiveDescription() { + public Optional getNonproductiveDescription() { return nonproductiveDescription; } - public void setNonproductiveDescription(String nonproductiveDescription) { + public void setNonproductiveDescription(Optional nonproductiveDescription) { this.nonproductiveDescription = nonproductiveDescription; } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java index f6e8ee410..591b6ca3b 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java @@ -1,7 +1,11 @@ package ca.bc.gov.nrs.vdyp.fip; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -15,6 +19,7 @@ import org.hamcrest.TypeSafeDiagnosingMatcher; import org.junit.jupiter.api.Test; +import ca.bc.gov.nrs.vdyp.fip.model.FipMode; import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParserTest; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; @@ -60,10 +65,8 @@ public void testParsePolygon() throws Exception { controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); BecDefinitionParserTest.populateControlMapReal(controlMap); - // Polygon ID FIZ BEC PctF mode ND Yld - // AAAAAAAAAAAAAAAAAAAAAAAAA A AAAA FFFF II AAAAAFFFFF var fileResolver = TestUtils - .fileResolver("test.dat", TestUtils.makeStream("Test Polygon 1 CWH 90.0 1 BLAH 0.95")); + .fileResolver("test.dat", TestUtils.makeStream("Test Polygon A CWH 90.0 2 BLAH 0.95")); parser.modify(controlMap, fileResolver); @@ -78,6 +81,14 @@ public void testParsePolygon() throws Exception { var poly = assertNext(stream); + assertThat(poly, hasProperty("polygonIdentifier", is("Test Polygon"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", present(is(90.0f)))); + assertThat(poly, hasProperty("modeFip", present(is(FipMode.FIPYOUNG)))); + assertThat(poly, hasProperty("nonproductiveDescription", present(is("BLAH")))); + assertThat(poly, hasProperty("yieldFactor", is(0.95f))); + assertEmpty(stream); } @@ -91,10 +102,8 @@ public void testParsePolygonWithBlanks() throws Exception { controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); BecDefinitionParserTest.populateControlMapReal(controlMap); - // Polygon ID FIZ BEC PctF mode ND Yld - // AAAAAAAAAAAAAAAAAAAAAAAAA A AAAA FFFF II AAAAAFFFFF var fileResolver = TestUtils - .fileResolver("test.dat", TestUtils.makeStream("01002 S000001 00 1970 A CWH 1.00")); + .fileResolver("test.dat", TestUtils.makeStream("01002 S000001 00 1970 A CWH ")); parser.modify(controlMap, fileResolver); @@ -109,6 +118,228 @@ public void testParsePolygonWithBlanks() throws Exception { var poly = assertNext(stream); + assertThat(poly, hasProperty("polygonIdentifier", is("01002 S000001 00 1970"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + assertEmpty(stream); + } + + @Test + public void testParseMultiple() throws Exception { + + var parser = new FipPolygonParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000001 00 1970 A CWH 1.00", + "01002 S000002 00 1970 A CWH 1.00", + "01002 S000003 00 1970 A CWH 1.00", + "01002 S000004 00 1970 A CWH 1.00", + "01003AS000001 00 1953 B CWH 1.00", + "01003AS000003 00 1953 B CWH 1.00", + "01004 S000002 00 1953 B CWH 1.00", + "01004 S000036 00 1957 B CWH 1.00", + "01004 S000037 00 1957 B CWH 1.00", + "01004 S000038 00 1957 B CWH 1.00" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipPolygonParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01002 S000001 00 1970"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01002 S000002 00 1970"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01002 S000003 00 1970"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01002 S000004 00 1970"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01003AS000001 00 1953"))); + assertThat(poly, hasProperty("forestInventoryZone", is("B"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01003AS000003 00 1953"))); + assertThat(poly, hasProperty("forestInventoryZone", is("B"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01004 S000002 00 1953"))); + assertThat(poly, hasProperty("forestInventoryZone", is("B"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01004 S000036 00 1957"))); + assertThat(poly, hasProperty("forestInventoryZone", is("B"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01004 S000037 00 1957"))); + assertThat(poly, hasProperty("forestInventoryZone", is("B"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01004 S000038 00 1957"))); + assertThat(poly, hasProperty("forestInventoryZone", is("B"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + assertEmpty(stream); + } + + @Test + public void testParsePolygonZeroAsDefault() throws Exception { + + var parser = new FipPolygonParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils + .fileResolver("test.dat", TestUtils.makeStream("01002 S000001 00 1970 A CWH 0.0 0 0.00")); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipPolygonParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01002 S000001 00 1970"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + + assertEmpty(stream); + } + + @Test + public void testParsePolygonNegativeAsDefault() throws Exception { + + var parser = new FipPolygonParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipPolygonParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils + .fileResolver("test.dat", TestUtils.makeStream("01002 S000001 00 1970 A CWH -1.0 -1.00")); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipPolygonParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var poly = assertNext(stream); + + assertThat(poly, hasProperty("polygonIdentifier", is("01002 S000001 00 1970"))); + assertThat(poly, hasProperty("forestInventoryZone", is("A"))); + assertThat(poly, hasProperty("biogeoclimaticZone", is("CWH"))); + assertThat(poly, hasProperty("percentAvailable", notPresent())); + assertThat(poly, hasProperty("modeFip", notPresent())); + assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); + assertThat(poly, hasProperty("yieldFactor", is(1.0f))); + assertEmpty(stream); } From 1d7a0f3e1ea71f76cf42389441f59fddedbe09da Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 30 Jun 2023 13:53:29 -0700 Subject: [PATCH 67/98] Load fip polygon datafile from control file --- .../ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 12 +++++++++++- .../ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 0de161a0b..c686aad37 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -69,7 +69,7 @@ */ public class FipControlParser { - public static final String FIP_YIELD_POLY_INPUT = "FIP_YIELD_POLY_INPUT"; + public static final String FIP_YIELD_POLY_INPUT = FipPolygonParser.CONTROL_KEY; public static final String FIP_YIELD_LAYER_INPUT = "FIP_YIELD_LAYER_INPUT"; public static final String FIP_YIELD_LX_SP0_INPUT = "FIP_YIELD_LxSP0_INPUT"; public static final String VDYP_POLYGON = "VDYP_POLYGON"; @@ -238,6 +238,12 @@ public String toString(String filename) throws IOException { }; } + List DATA_FILES = Arrays.asList( + + // V7O_FIP + new FipPolygonParser() + ); + List BASIC_DEFINITIONS = Arrays.asList( // RD_BEC @@ -400,6 +406,10 @@ public String toString(String filename) throws IOException { applyModifiers(map, GROUP_DEFINITIONS, fileResolver); + // Initialize data file parser factories + + applyModifiers(map, DATA_FILES, fileResolver); + if (jprogram == 1) { applyModifiers(map, FIPSTART_ONLY, fileResolver); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index aa8227681..dfe108e0e 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -32,6 +32,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.BecLookup; import ca.bc.gov.nrs.vdyp.model.Region; @@ -605,6 +606,16 @@ public void testParseE098() throws Exception { ); } + @Test + public void testParseV7O_FIP() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasSpecificEntry(FipPolygonParser.CONTROL_KEY, instanceOf(StreamingParserFactory.class)) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); From 8415f6804fd1bc6155e66add15e1f3d4d81fe605 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 30 Jun 2023 14:13:40 -0700 Subject: [PATCH 68/98] Remove unused imports --- .../gov/nrs/vdyp/io/parse/CoefficientParser.java | 1 - .../gov/nrs/vdyp/io/parse/EquationGroupParser.java | 1 - .../gov/nrs/vdyp/io/parse/HLCoefficientParser.java | 3 --- .../io/parse/SmallComponentWSVolumeParser.java | 2 -- .../nrs/vdyp/io/parse/UpperCoefficientParser.java | 1 - .../ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java | 2 -- .../nrs/vdyp/io/parse/BecDefinitionParserTest.java | 2 -- .../io/parse/BySpeciesDqCoefficientParserTest.java | 1 - .../nrs/vdyp/io/parse/CoefficientParserTest.java | 2 -- .../nrs/vdyp/io/parse/ControlFileParserTest.java | 6 ------ .../nrs/vdyp/io/parse/HLCoefficientParserTest.java | 3 --- .../parse/HLNonprimaryCoefficientParserTest.java | 1 - .../bc/gov/nrs/vdyp/io/parse/LineParserTest.java | 3 --- .../nrs/vdyp/io/parse/SP0DefinitionParserTest.java | 4 ---- .../io/parse/StockingClassFactorParserTest.java | 1 - .../nrs/vdyp/io/write/ControlFileWriterTest.java | 2 -- .../ca/bc/gov/nrs/vdyp/model/BecLookupTest.java | 2 -- .../java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 4 ---- .../ca/bc/gov/nrs/vdyp/fip/FipControlParser.java | 14 -------------- .../ca/bc/gov/nrs/vdyp/fip/ModifierParser.java | 1 - 20 files changed, 56 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java index 27e5e686f..2ffc593ca 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -7,7 +7,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.MatrixMap3; import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index 29743e3c2..23fcdbbad 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -10,7 +10,6 @@ import java.util.Map; import java.util.stream.Collectors; -import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.common.ExpectationDifference; /** diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java index c82af4949..673720a39 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java @@ -5,9 +5,6 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap2; import ca.bc.gov.nrs.vdyp.model.MatrixMap2Impl; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java index bb24f032d..949f413b1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentWSVolumeParser.java @@ -1,7 +1,5 @@ package ca.bc.gov.nrs.vdyp.io.parse; -import java.util.Map; - public class SmallComponentWSVolumeParser extends SimpleCoefficientParser1 { public static final String CONTROL_KEY = "SMALL_COMP_WS_VOLUME"; diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java index e290a0ce0..822c8aad3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java @@ -11,7 +11,6 @@ import ca.bc.gov.nrs.vdyp.model.MatrixMap3; import ca.bc.gov.nrs.vdyp.model.MatrixMap3Impl; import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; /** * Parses a Coefficient data file. diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java index c65216cfc..357ccedf3 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/MatrixMapImpl.java @@ -1,9 +1,7 @@ package ca.bc.gov.nrs.vdyp.model; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index 04bc6ab9f..bf9995cb7 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -4,12 +4,10 @@ import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasProperty; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java index c42d34ab7..7267e2fca 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java @@ -1,7 +1,6 @@ package ca.bc.gov.nrs.vdyp.io.parse; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; import java.util.HashMap; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java index 187b54639..061440864 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java @@ -11,8 +11,6 @@ import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.model.BecDefinition; -import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; public class CoefficientParserTest { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java index 618290fcd..bc5568cb0 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ControlFileParserTest.java @@ -15,17 +15,11 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; -import java.util.Optional; - import org.hamcrest.Matcher; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.test.VdypMatchers; - public class ControlFileParserTest { @Test diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java index 1fd5f4f25..1dfd2e1f6 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java @@ -1,17 +1,14 @@ package ca.bc.gov.nrs.vdyp.io.parse; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; -import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.HashMap; import java.util.Map; -import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.model.Region; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java index 4d902e8a4..afbeccc46 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java @@ -1,7 +1,6 @@ package ca.bc.gov.nrs.vdyp.io.parse; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.mmHasEntry; -import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 4bb302100..8a51c6b8c 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -2,8 +2,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.array; -import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasKey; @@ -20,7 +18,6 @@ import java.util.Map; import org.hamcrest.Matcher; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; public class LineParserTest { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index 129d9045d..26cf66012 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -3,20 +3,16 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.stringContainsInOrder; import java.io.ByteArrayInputStream; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import org.easymock.internal.matchers.InstanceOf; import org.hamcrest.Matchers; import static org.hamcrest.Matchers.equalTo; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java index 254db4994..2ffc8033e 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java @@ -9,7 +9,6 @@ import java.util.Collections; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.model.Region; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriterTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriterTest.java index 236d0106e..11ee6649b 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriterTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/write/ControlFileWriterTest.java @@ -8,8 +8,6 @@ import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.io.write.ControlFileWriter; - public class ControlFileWriterTest { @Test diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java index 62b002066..4866025e7 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java @@ -4,7 +4,6 @@ import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasProperty; @@ -14,7 +13,6 @@ import java.util.Arrays; -import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.model.BecLookup.Substitution; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index 3bb09a514..f417d06f4 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -1,9 +1,5 @@ package ca.bc.gov.nrs.vdyp.test; -import static org.hamcrest.Matchers.anything; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.not; - import java.util.Arrays; import java.util.Map; import java.util.Objects; diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 0de161a0b..f8896fa87 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -8,9 +8,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; - import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.BecModifier; @@ -24,7 +21,6 @@ import ca.bc.gov.nrs.vdyp.io.parse.ControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.DecayEquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.DefaultEquationNumberParser; -import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveParser; @@ -46,20 +42,10 @@ import ca.bc.gov.nrs.vdyp.io.parse.VolumeEquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayParser; import ca.bc.gov.nrs.vdyp.io.parse.VolumeNetDecayWasteParser; -import ca.bc.gov.nrs.vdyp.io.parse.EquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.EquationModifierParser; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; -import ca.bc.gov.nrs.vdyp.io.parse.ResourceControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; -import ca.bc.gov.nrs.vdyp.model.BecDefinition; -import ca.bc.gov.nrs.vdyp.model.Coefficients; -import ca.bc.gov.nrs.vdyp.model.MatrixMap2; -import ca.bc.gov.nrs.vdyp.model.MatrixMap3; -import ca.bc.gov.nrs.vdyp.model.NonprimaryHLCoefficients; -import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; -import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; /** * Parser for FIP control files diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 7bc44bfc2..8223da5bf 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -4,7 +4,6 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; From 3660fd2441c2060bcaae16f5054d96eb68e6fe09 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 30 Jun 2023 14:15:24 -0700 Subject: [PATCH 69/98] Fix raw type warning in test --- .../test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 8a51c6b8c..9ad1b3d6f 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -155,7 +155,7 @@ public void testStripped() throws Exception { } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testMultiValue() throws Exception { var parser = new LineParser(); From c84e10ba22efe981e85a8a5804e3dca03089c60c Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 30 Jun 2023 14:17:09 -0700 Subject: [PATCH 70/98] Fix unused variable warings in unit tests --- .../bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java | 4 ++-- .../bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java | 4 ++-- .../vdyp/io/parse/HLNonprimaryCoefficientParserTest.java | 8 ++++---- .../gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java | 4 ++-- .../test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java index 061440864..5cf4f6de9 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java @@ -49,7 +49,7 @@ public void testBadBec() throws Exception { BecDefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } @@ -66,7 +66,7 @@ public void testBadIndex() throws Exception { BecDefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java index 1dfd2e1f6..0f232a3f1 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java @@ -77,7 +77,7 @@ public void testParseBadSpecies() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } @@ -92,7 +92,7 @@ public void testParseBadRegion() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java index afbeccc46..9ee507fdf 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java @@ -48,7 +48,7 @@ public void testParseBadSpecies1() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } @@ -63,7 +63,7 @@ public void testParseBadSpecies2() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } @@ -78,7 +78,7 @@ public void testParseBadRegion() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } @@ -93,7 +93,7 @@ public void testParseMissingCoefficient() throws Exception { SP0DefinitionParserTest.populateControlMap(controlMap); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } public static Matcher coe(float c1, float c2, int ieqn) { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java index 6d428f8a3..03c59f741 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java @@ -56,7 +56,7 @@ public void testParseBadSpecies() throws Exception { controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } @@ -76,7 +76,7 @@ public void testParseBadRegion() throws Exception { controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); - var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); + assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index 11f625223..be21a5459 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -23,7 +23,7 @@ public void testContruct() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); - var result = new MatrixMapImpl(dims); + new MatrixMapImpl(dims); } @Test From 562c64103db779b0bff2891e2beb8098fb96005d Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 30 Jun 2023 14:18:50 -0700 Subject: [PATCH 71/98] Remove BecModifier as it is not needed --- .../bc/gov/nrs/vdyp/io/parse/BecModifier.java | 17 ----------------- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 3 +-- 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java deleted file mode 100644 index 8d3fe9845..000000000 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BecModifier.java +++ /dev/null @@ -1,17 +0,0 @@ -package ca.bc.gov.nrs.vdyp.io.parse; - -import java.io.IOException; -import java.util.Map; - -import ca.bc.gov.nrs.vdyp.io.FileResolver; - -public class BecModifier implements ControlMapModifier { - - @Override - public void modify(Map control, FileResolver fileResolver) - throws ResourceParseException, IOException { - var becMap = BecDefinitionParser.getBecs(control); - - } - -} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index f8896fa87..06e2aefb2 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -10,7 +10,6 @@ import java.util.Map; import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; -import ca.bc.gov.nrs.vdyp.io.parse.BecModifier; import ca.bc.gov.nrs.vdyp.io.parse.BreakageEquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.BreakageParser; import ca.bc.gov.nrs.vdyp.io.parse.BySpeciesDqCoefficientParser; @@ -230,7 +229,7 @@ public String toString(String filename) throws IOException { new BecDefinitionParser(), // DEF_BEC - new BecModifier(), + // Superseded by BecLookup.getGrowthBecs // RD_SP0 new SP0DefinitionParser() From bad1ba047180a474555bb7037fc014195d281dfa Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 30 Jun 2023 14:22:26 -0700 Subject: [PATCH 72/98] Fix unused imports --- .../ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java | 3 --- .../src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java | 2 -- 2 files changed, 5 deletions(-) diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index ee4ee93fa..ea39b8d12 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -10,9 +10,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - import static org.hamcrest.Matchers.equalTo; import org.junit.jupiter.api.Test; diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java index 3e6ca08fa..83fcc2590 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParser.java @@ -1,7 +1,6 @@ package ca.bc.gov.nrs.vdyp.fip; import java.io.IOException; -import java.io.InputStream; import java.util.Map; import java.util.Optional; @@ -9,7 +8,6 @@ import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.AbstractStreamingParser; -import ca.bc.gov.nrs.vdyp.io.parse.ControlMapSubResourceParser; import ca.bc.gov.nrs.vdyp.io.parse.ControlMapValueReplacer; import ca.bc.gov.nrs.vdyp.io.parse.LineParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; From f4a615ac82fb782f2cc7dfe3201b5e8af119b8df Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 4 Jul 2023 17:57:32 -0700 Subject: [PATCH 73/98] Class to replicate type union --- .../bc/gov/nrs/vdyp/common/ValueOrMarker.java | 123 ++++++++++++++++++ .../nrs/vdyp/io/common/ValueOrMarkerTest.java | 46 +++++++ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 88 +++++++++++++ 3 files changed, 257 insertions(+) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ValueOrMarker.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/common/ValueOrMarkerTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ValueOrMarker.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ValueOrMarker.java new file mode 100644 index 000000000..7666beac4 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/common/ValueOrMarker.java @@ -0,0 +1,123 @@ +package ca.bc.gov.nrs.vdyp.common; + +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +/** + * Type union of a value and an out of band marker. + * + * @author Kevin Smith, Vivid Solutions + * + * @param + * @param + */ +public class ValueOrMarker { + private final boolean isMarker; + private final Object obj; + + private ValueOrMarker(Object obj, boolean isMarker) { + Objects.requireNonNull(obj, "The Value or Marker of a ValueOrMarker must not be null"); + + this.isMarker = isMarker; + this.obj = obj; + } + + /** + * Is there a value + * + * @return + */ + public boolean isMarker() { + return isMarker; + } + + /** + * Is there a marker + * + * @return + */ + public boolean isValue() { + return !isMarker; + } + + /** + * Get the value if present + * + * @return + */ + @SuppressWarnings("unchecked") + public Optional getValue() { + if (isValue()) { + return (Optional) Optional.of(obj); + } + return Optional.empty(); + } + + /** + * Get the marker if present + * + * @return + */ + @SuppressWarnings("unchecked") + public Optional getMarker() { + if (isMarker()) { + return (Optional) Optional.of(obj); + } + return Optional.empty(); + } + + /** + * Apply the value handler if a value, otherwise the marker handler, and return + * the result + */ + @SuppressWarnings("unchecked") + public T handle(Function valueHandler, Function markerHandler) { + if (isValue()) { + return valueHandler.apply((Value) obj); + } + return markerHandler.apply((Marker) obj); + } + + /** + * Create a Builder to create ValueOrMarker instances for particular Value and + * Marker types + * + * @param vClazz Value class + * @param mClazz Marker class + * @return + */ + public static Builder builder(Class vClazz, Class mClazz) { + return new Builder(); + } + + /** + * Builder to create ValueOrMarker instances for particular Value and Marker + * types + * + * @author Kevin Smith, Vivid Solutions + * + * @param Value class + * @param Marker class + */ + public static class Builder { + + public Builder() { + + } + + /** + * Create a ValueOrMarker with a Marker + */ + public ValueOrMarker marker(Marker m) { + return new ValueOrMarker(m, true); + } + + /** + * Create a ValueOrMarker with a Value + */ + public ValueOrMarker value(Value v) { + return new ValueOrMarker(v, false); + } + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/common/ValueOrMarkerTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/common/ValueOrMarkerTest.java new file mode 100644 index 000000000..beae72563 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/common/ValueOrMarkerTest.java @@ -0,0 +1,46 @@ +package ca.bc.gov.nrs.vdyp.io.common; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.isMarker; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.isValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.common.ValueOrMarker; + +public class ValueOrMarkerTest { + + @Test + public void testMarker() throws Exception { + var builder = ValueOrMarker.builder(Float.class, String.class); + + var vm = builder.marker("Test"); + + assertThat(vm, isMarker(is("Test"))); + + var result = vm.handle((value) -> { + fail("Should not call value handler"); + return "Failure"; + }, (marker) -> "Success"); + + assertThat(result, is("Success")); + } + + @Test + public void testValue() throws Exception { + var builder = ValueOrMarker.builder(Float.class, String.class); + + var vm = builder.value(1.0f); + + assertThat(vm, isValue(is(1.0f))); + + var result = vm.handle((value) -> "Success", (marker) -> { + fail("Should not call marker handler"); + return "Failure"; + }); + + assertThat(result, is("Success")); + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index f417d06f4..62a54bfea 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -1,5 +1,9 @@ package ca.bc.gov.nrs.vdyp.test; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; + import java.util.Arrays; import java.util.Map; import java.util.Objects; @@ -12,6 +16,7 @@ import org.hamcrest.Matchers; import org.hamcrest.TypeSafeDiagnosingMatcher; +import ca.bc.gov.nrs.vdyp.common.ValueOrMarker; import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.model.BecDefinition; @@ -343,4 +348,87 @@ public static Matcher hasBec(String alias, Matcher Matcher> isValue(Matcher valueMatcher) { + return new TypeSafeDiagnosingMatcher>() { + + @Override + public void describeTo(Description description) { + + description.appendText("ValueOrMarker with a value ").appendDescriptionOf(valueMatcher); + + } + + @Override + protected boolean matchesSafely(ValueOrMarker item, Description mismatchDescription) { + if (item.isMarker()) { + mismatchDescription.appendText("isMarker() was true"); + return false; + } + if (!item.isValue()) { + mismatchDescription.appendText("isValue() was false"); + return false; + } + if (item.getMarker().isPresent()) { + mismatchDescription.appendText("getMarker() was present with value ") + .appendValue(item.getMarker().get()); + return false; + } + if (!item.getValue().isPresent()) { + mismatchDescription.appendText("getValue() was not present"); + return false; + } + if (valueMatcher.matches(item.getValue().get())) { + return true; + } + mismatchDescription.appendText("Value was present but "); + valueMatcher.describeMismatch(item.getValue().get(), mismatchDescription); + return false; + } + }; + } + + /** + * Matches a ValueOrMarker with a marker + */ + public static Matcher> isMarker(Matcher markerMatcher) { + return new TypeSafeDiagnosingMatcher>() { + + @Override + public void describeTo(Description description) { + + description.appendText("ValueOrMarker with a value ").appendDescriptionOf(markerMatcher); + + } + + @Override + protected boolean matchesSafely(ValueOrMarker item, Description mismatchDescription) { + if (item.isValue()) { + mismatchDescription.appendText("isValue() was true"); + return false; + } + if (!item.isMarker()) { + mismatchDescription.appendText("isMarker() was false"); + return false; + } + if (item.getValue().isPresent()) { + mismatchDescription.appendText("getValue() was present with value ") + .appendValue(item.getValue().get()); + return false; + } + if (!item.getMarker().isPresent()) { + mismatchDescription.appendText("getMarker() was not present"); + return false; + } + if (markerMatcher.matches(item.getMarker().get())) { + return true; + } + mismatchDescription.appendText("Marker was present but "); + markerMatcher.describeMismatch(item.getMarker().get(), mismatchDescription); + return false; + } + }; + } } From 98cb956b1a679010b3c956fee1636496c0e32c5a Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 5 Jul 2023 21:57:25 -0700 Subject: [PATCH 74/98] Loading FIP layer data file --- .../ca/bc/gov/nrs/vdyp/io/EndOfRecord.java | 5 + .../io/parse/GroupingStreamingParser.java | 99 ++++++++ .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 56 +++++ .../java/ca/bc/gov/nrs/vdyp/model/Layer.java | 5 + .../io/parse/GroupingStreamingParserTest.java | 215 ++++++++++++++++++ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 50 +++- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 7 +- .../bc/gov/nrs/vdyp/fip/FipLayerParser.java | 147 ++++++++++++ .../bc/gov/nrs/vdyp/fip/model/FipLayer.java | 136 +++++++++++ .../nrs/vdyp/fip/model/FipLayerPrimary.java | 45 ++++ .../nrs/vdyp/fip/FipControlParserTest.java | 9 + .../gov/nrs/vdyp/fip/FipLayerParserTest.java | 182 +++++++++++++++ .../nrs/vdyp/fip/FipPolygonParserTest.java | 61 +---- 13 files changed, 959 insertions(+), 58 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/EndOfRecord.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Layer.java create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParserTest.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java create mode 100644 vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/EndOfRecord.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/EndOfRecord.java new file mode 100644 index 000000000..ed80be125 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/EndOfRecord.java @@ -0,0 +1,5 @@ +package ca.bc.gov.nrs.vdyp.io; + +public enum EndOfRecord { + END_OF_RECORD +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java new file mode 100644 index 000000000..817edc9ee --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java @@ -0,0 +1,99 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * Wraps a StreamingParser and groups its entries. + * + * @author Kevin Smith, Vivid Solutions + * + * @param + * @param + */ +public abstract class GroupingStreamingParser implements StreamingParser { + + final StreamingParser delegate; + + Optional> next = Optional.empty(); + + public GroupingStreamingParser(StreamingParser delegate) { + super(); + this.delegate = delegate; + } + + /** + * Returns true if a child should be skipped + * + * @param nextChild + * @return + */ + protected abstract boolean skip(U nextChild); + + /** + * Returns true if a schild is an end of group marker + * + * @param nextChild + * @return + */ + protected abstract boolean stop(U nextChild); + + /** + * Convert a list of children to a result. + * + * @param children + * @return + */ + protected abstract T convert(List children); + + @Override + public T next() throws IOException, ResourceParseException { + + doGetNext(); + var children = next.orElseThrow(() -> new IllegalStateException("Requested next group when there is none")); + next = Optional.empty(); + return convert(children); + } + + protected void doGetNext() throws IOException, ResourceParseException { + + if (next.isEmpty()) { + var nextResult = new ArrayList(); + + var nextChild = safeNextChild(); + while (nextChild.map(x -> !stop(x)).orElse(false)) { + nextResult.add(nextChild.get()); + nextChild = safeNextChild(); + } + if (nextChild.isEmpty()) { + return; + } + next = Optional.of(nextResult); + + } + } + + protected Optional safeNextChild() throws IOException, ResourceParseException { + Optional result = Optional.empty(); + while (result.isEmpty() && delegate.hasNext()) { + if (delegate.hasNext()) + result = Optional.of(delegate.next()).filter(x -> !skip(x)); + } + return result; + } + + @Override + public boolean hasNext() throws IOException, ResourceParseException { + doGetNext(); + + return next.isPresent(); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + +} diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index efa456731..ee46b14a1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -7,7 +7,10 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; +import java.util.function.Predicate; +import ca.bc.gov.nrs.vdyp.common.ValueOrMarker; +import ca.bc.gov.nrs.vdyp.model.Layer; import ca.bc.gov.nrs.vdyp.model.Region; /** @@ -205,4 +208,57 @@ public static ValueParser> segmentList(int length, ValueParser de static ValueParser uncontrolled(ControlledValueParser delegate) { return s -> delegate.parse(s, Collections.emptyMap()); } + + /** + * Attempt to parse as a marker using markerParser. If it returns empty, parse + * as a value with valueParser. + * + * @param valueParser Parser from String to Value. + * @param markerParser Parser from String to Optional. This should + * return empty if the string is not a marker. + * @return a ValueOrMarker + */ + public static ValueParser> + valueOrMarker(ValueParser valueParser, ValueParser> markerParser) { + return s -> { + var builder = new ValueOrMarker.Builder(); + var marker = markerParser.parse(s).map(builder::marker); + if (marker.isPresent()) { + return marker.get(); + } + + var value = builder.value(valueParser.parse(s)); + return value; + }; + } + + /** + * Return the given value if the test passes, otherwise empty. + * + * @param + * @param test + * @param value + * @return + */ + public static ValueParser> optionalSingleton(Predicate test, T value) { + return s -> test.test(s) ? Optional.of(value) : Optional.empty(); + } + + /** + * Parser for a layer identifier + */ + public static ValueParser> LAYER = s -> { + switch (s.toUpperCase()) { + case "1": + case "P": + return Optional.of(Layer.PRIMARY); + case "2": + case "S": + return Optional.of(Layer.SECONDARY); + case "V": + return Optional.of(Layer.VETERAN); + default: + return Optional.empty(); // Unknown + } + }; } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Layer.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Layer.java new file mode 100644 index 000000000..3780c9d47 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/Layer.java @@ -0,0 +1,5 @@ +package ca.bc.gov.nrs.vdyp.model; + +public enum Layer { + PRIMARY, SECONDARY, VETERAN +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParserTest.java new file mode 100644 index 000000000..ae5550f5a --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParserTest.java @@ -0,0 +1,215 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertEmpty; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertNext; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; + +import java.util.Arrays; +import java.util.List; + +import org.easymock.EasyMock; +import org.junit.jupiter.api.Test; + +public class GroupingStreamingParserTest { + + @Test + public void testEmpty() throws Exception { + var control = EasyMock.createControl(); + + StreamingParser delegate = control.createMock("delegate", StreamingParser.class); + + EasyMock.expect(delegate.hasNext()).andStubReturn(false); + + control.replay(); + + var unit = new GroupingStreamingParser, Integer>(delegate) { + + @Override + protected boolean skip(Integer nextChild) { + return nextChild % 3 == 0; + } + + @Override + protected boolean stop(Integer nextChild) { + return nextChild % 5 == 0; + } + + @Override + protected List convert(List children) { + return children; + } + + }; + + assertEmpty(unit); + + control.verify(); + } + + @Test + public void testOneEntry() throws Exception { + var control = EasyMock.createControl(); + + var mock = Arrays.asList(1, 5).iterator(); + + StreamingParser delegate = control.createMock("delegate", StreamingParser.class); + + EasyMock.expect(delegate.hasNext()).andStubAnswer(mock::hasNext); + EasyMock.expect(delegate.next()).andStubAnswer(mock::next); + + control.replay(); + + var unit = new GroupingStreamingParser, Integer>(delegate) { + + @Override + protected boolean skip(Integer nextChild) { + return nextChild % 3 == 0; + } + + @Override + protected boolean stop(Integer nextChild) { + return nextChild % 5 == 0; + } + + @Override + protected List convert(List children) { + return children; + } + + }; + + var group = assertNext(unit); + assertThat(group, contains(1)); + + assertEmpty(unit); + + control.verify(); + } + + @Test + public void testMultipleEntries() throws Exception { + var control = EasyMock.createControl(); + + var mock = Arrays.asList(1, 2, 5).iterator(); + + StreamingParser delegate = control.createMock("delegate", StreamingParser.class); + + EasyMock.expect(delegate.hasNext()).andStubAnswer(mock::hasNext); + EasyMock.expect(delegate.next()).andStubAnswer(mock::next); + + control.replay(); + + var unit = new GroupingStreamingParser, Integer>(delegate) { + + @Override + protected boolean skip(Integer nextChild) { + return nextChild % 3 == 0; + } + + @Override + protected boolean stop(Integer nextChild) { + return nextChild % 5 == 0; + } + + @Override + protected List convert(List children) { + return children; + } + + }; + + var group = assertNext(unit); + assertThat(group, contains(1, 2)); + + assertEmpty(unit); + + control.verify(); + + } + + @Test + public void testMultipleGroups() throws Exception { + var control = EasyMock.createControl(); + + var mock = Arrays.asList(1, 5, 2, 5).iterator(); + + StreamingParser delegate = control.createMock("delegate", StreamingParser.class); + + EasyMock.expect(delegate.hasNext()).andStubAnswer(mock::hasNext); + EasyMock.expect(delegate.next()).andStubAnswer(mock::next); + + control.replay(); + + var unit = new GroupingStreamingParser, Integer>(delegate) { + + @Override + protected boolean skip(Integer nextChild) { + return nextChild % 3 == 0; + } + + @Override + protected boolean stop(Integer nextChild) { + return nextChild % 5 == 0; + } + + @Override + protected List convert(List children) { + return children; + } + + }; + + var group = assertNext(unit); + assertThat(group, contains(1)); + + group = assertNext(unit); + assertThat(group, contains(2)); + + assertEmpty(unit); + + control.verify(); + + } + + @Test + public void testSkip() throws Exception { + var control = EasyMock.createControl(); + + var mock = Arrays.asList(3, 1, 5).iterator(); + + StreamingParser delegate = control.createMock("delegate", StreamingParser.class); + + EasyMock.expect(delegate.hasNext()).andStubAnswer(mock::hasNext); + EasyMock.expect(delegate.next()).andStubAnswer(mock::next); + + control.replay(); + + var unit = new GroupingStreamingParser, Integer>(delegate) { + + @Override + protected boolean skip(Integer nextChild) { + return nextChild % 3 == 0; + } + + @Override + protected boolean stop(Integer nextChild) { + return nextChild % 5 == 0; + } + + @Override + protected List convert(List children) { + return children; + } + + }; + + var group = assertNext(unit); + assertThat(group, contains(1)); + + assertEmpty(unit); + + control.verify(); + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index 62a54bfea..e92b1e5e4 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -1,9 +1,11 @@ package ca.bc.gov.nrs.vdyp.test; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.Objects; @@ -17,6 +19,8 @@ import org.hamcrest.TypeSafeDiagnosingMatcher; import ca.bc.gov.nrs.vdyp.common.ValueOrMarker; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.model.BecDefinition; @@ -431,4 +435,44 @@ protected boolean matchesSafely(ValueOrMarker item, Description mismatchDe } }; } + + public static T assertNext(StreamingParser stream) throws IOException, ResourceParseException { + assertThat(stream, hasNext(true)); + var next = assertDoesNotThrow(() -> stream.next()); + assertThat(next, notNullValue()); + return next; + } + + public static void assertEmpty(StreamingParser stream) throws IOException, ResourceParseException { + assertThat(stream, hasNext(false)); + assertThrows(IllegalStateException.class, () -> stream.next()); + } + + public static Matcher> hasNext(boolean value) { + return new TypeSafeDiagnosingMatcher>() { + + @Override + public void describeTo(Description description) { + + description.appendText("StreamingParser with hasNext() ").appendValue(value); + + } + + @Override + protected boolean matchesSafely(StreamingParser item, Description mismatchDescription) { + try { + var hasNext = item.hasNext(); + if (hasNext == value) { + return true; + } + mismatchDescription.appendText("hasNext() returned ").appendValue(hasNext); + return false; + } catch (IOException | ResourceParseException e) { + mismatchDescription.appendText("hasNext() threw ").appendValue(e.getMessage()); + return false; + } + } + + }; + } } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index a53dcbeb7..e053cbb1c 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -55,7 +55,7 @@ public class FipControlParser { public static final String FIP_YIELD_POLY_INPUT = FipPolygonParser.CONTROL_KEY; - public static final String FIP_YIELD_LAYER_INPUT = "FIP_YIELD_LAYER_INPUT"; + public static final String FIP_YIELD_LAYER_INPUT = FipLayerParser.CONTROL_KEY; public static final String FIP_YIELD_LX_SP0_INPUT = "FIP_YIELD_LxSP0_INPUT"; public static final String VDYP_POLYGON = "VDYP_POLYGON"; public static final String VDYP_LAYER_BY_SPECIES = "VDYP_LAYER_BY_SPECIES"; @@ -226,7 +226,10 @@ public String toString(String filename) throws IOException { List DATA_FILES = Arrays.asList( // V7O_FIP - new FipPolygonParser() + new FipPolygonParser(), + + // V7O_FIL + new FipLayerParser() ); List BASIC_DEFINITIONS = Arrays.asList( diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java new file mode 100644 index 000000000..650a366cd --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java @@ -0,0 +1,147 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import ca.bc.gov.nrs.vdyp.common.ValueOrMarker; +import ca.bc.gov.nrs.vdyp.fip.model.FipLayer; +import ca.bc.gov.nrs.vdyp.fip.model.FipLayerPrimary; +import ca.bc.gov.nrs.vdyp.io.EndOfRecord; +import ca.bc.gov.nrs.vdyp.io.FileResolver; +import ca.bc.gov.nrs.vdyp.io.parse.AbstractStreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.ControlMapValueReplacer; +import ca.bc.gov.nrs.vdyp.io.parse.ControlledValueParser; +import ca.bc.gov.nrs.vdyp.io.parse.GroupingStreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.LineParser; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.model.Layer; + +public class FipLayerParser implements ControlMapValueReplacer>, String> { + + public static final String CONTROL_KEY = "FIP_LAYERS"; + + static final String POLYGON_IDENTIFIER = "POLYGON_IDENTIFIER"; // POLYDESC + static final String LAYER = "LAYER"; // LAYER + static final String AGE_TOTAL = "AGE_TOTAL"; // AGETOT + static final String HEIGHT = "HEIGHT"; // HT + static final String SITE_INDEX = "SITE_INDEX"; // SI + static final String CROWN_CLOSURE = "CROWN_CLOSURE"; // CC + static final String SITE_SP0 = "SITE_SP0"; // SITESP0 + static final String SITE_SP64 = "SITE_SP64"; // SITESP64 + static final String YEARS_TO_BREAST_HEIGHT = "YEARS_TO_BREAST_HEIGHT"; // YTBH + static final String STOCKING_CLASS = "STOCKING_CLASS"; // STK + static final String INVENTORY_TYPE_GROUP = "INVENTORY_TYPE_GROUP"; // ITGFIP + static final String BREAST_HEIGHT_AGE = "BREAST_HEIGHT_AGE"; // AGEBH + static final String SITE_CURVE_NUMBER = "SITE_CURVE_NUMBER"; // SCN + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + + @Override + public StreamingParserFactory> + map(String fileName, FileResolver fileResolver, Map control) + throws IOException, ResourceParseException { + return () -> { + var lineParser = new LineParser().strippedString(25, POLYGON_IDENTIFIER).space(1).value( + 1, LAYER, + ValueParser.valueOrMarker( + ValueParser.LAYER, ValueParser.optionalSingleton("Z"::equals, EndOfRecord.END_OF_RECORD) + ) + ).floating(4, AGE_TOTAL).floating(5, HEIGHT).floating(5, SITE_INDEX).floating(5, CROWN_CLOSURE).space(3) + .value(2, SITE_SP0, ControlledValueParser.optional(ValueParser.SPECIES)) + .value(3, SITE_SP64, ControlledValueParser.optional(ValueParser.STRING)) + .floating(5, YEARS_TO_BREAST_HEIGHT) + .value(1, STOCKING_CLASS, ValueParser.optional(ValueParser.STRING)).space(2) + .value(4, INVENTORY_TYPE_GROUP, ValueParser.optional(ValueParser.INTEGER)).space(1) + .value(6, BREAST_HEIGHT_AGE, ValueParser.optional(ValueParser.FLOAT)) + .value(3, SITE_CURVE_NUMBER, ValueParser.optional(ValueParser.INTEGER)); + + var is = fileResolver.resolve(fileName); + + var delegateStream = new AbstractStreamingParser, EndOfRecord>>( + is, lineParser, control + ) { + + @SuppressWarnings("unchecked") + @Override + protected ValueOrMarker, EndOfRecord> convert(Map entry) { + var polygonId = (String) entry.get(POLYGON_IDENTIFIER); + var layer = (ValueOrMarker, EndOfRecord>) entry.get(LAYER); + var ageTotal = (float) entry.get(AGE_TOTAL); + var height = (float) entry.get(HEIGHT); + var siteIndex = (float) entry.get(SITE_INDEX); + var crownClosure = (float) entry.get(CROWN_CLOSURE); + var siteSp0 = (Optional) entry.get(SITE_SP0); + var siteSp64 = (Optional) entry.get(SITE_SP64); + var yearsToBreastHeight = (float) entry.get(YEARS_TO_BREAST_HEIGHT); + var stockingClass = (Optional) entry.get(STOCKING_CLASS); + var inventoryTypeGroup = (Optional) entry.get(INVENTORY_TYPE_GROUP); + var breastHeightAge = (Optional) entry.get(BREAST_HEIGHT_AGE); + var siteCurveNumber = (Optional) entry.get(SITE_CURVE_NUMBER); + + var builder = new ValueOrMarker.Builder, EndOfRecord>(); + var result = layer.handle(l -> { + switch (l.orElse(null)) { + case PRIMARY: + return builder.value( + Optional.of( + new FipLayerPrimary( + polygonId, ageTotal, height, siteIndex, crownClosure, siteSp0.get(), + siteSp64.get(), yearsToBreastHeight, stockingClass, + inventoryTypeGroup, breastHeightAge, siteCurveNumber + ) + ) + ); + case VETERAN: + return builder.value( + Optional.of( + new FipLayer( + polygonId, Layer.VETERAN, ageTotal, height, siteIndex, crownClosure, + siteSp0.get(), siteSp64.get(), yearsToBreastHeight, + inventoryTypeGroup, breastHeightAge + ) + ) + ); + + default: + return builder.value(Optional.empty()); + } + }, m -> { + return builder.marker(m); + }); + return result; + } + + }; + + return new GroupingStreamingParser, ValueOrMarker, EndOfRecord>>( + delegateStream + ) { + + @Override + protected boolean skip(ValueOrMarker, EndOfRecord> nextChild) { + return nextChild.getValue().map(Optional::isEmpty).orElse(false); + } + + @Override + protected boolean stop(ValueOrMarker, EndOfRecord> nextChild) { + return nextChild.isMarker(); + } + + @Override + protected Map convert(List, EndOfRecord>> children) { + return children.stream().map(ValueOrMarker::getValue).map(Optional::get).map(Optional::get) + .collect(Collectors.toMap(FipLayer::getLayer, x -> x)); + } + + }; + }; + } +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java new file mode 100644 index 000000000..25ac77028 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java @@ -0,0 +1,136 @@ +package ca.bc.gov.nrs.vdyp.fip.model; + +import java.util.Optional; + +import ca.bc.gov.nrs.vdyp.model.Layer; + +public class FipLayer { + + static final String POLYGON_IDENTIFIER = "POLYGON_IDENTIFIER"; // POLYDESC + static final String LAYER = "LAYER"; // LAYER + static final String AGE_TOTAL = "AGE_TOTAL"; // AGETOT + static final String HEIGHT = "HEIGHT"; // HT + static final String SITE_INDEX = "SITE_INDEX"; // SI + static final String CROWN_CLOSURE = "CROWN_CLOSURE"; // CC + static final String SITE_SP0 = "SITE_SP0"; // SITESP0 + static final String SITE_SP64 = "SITE_SP64"; // SITESP64 + static final String YEARS_TO_BREAST_HEIGHT = "YEARS_TO_BREAST_HEIGHT"; // YTBH + static final String INVENTORY_TYPE_GROUP = "INVENTORY_TYPE_GROUP"; // ITGFIP + static final String BREAST_HEIGHT_AGE = "BREAST_HEIGHT_AGE"; // AGEBH + + String polygonIdentifier; // POLYDESC + final Layer layer; + float ageTotal; + float height; + float siteIndex; + float crownClosure; + String siteSp0; + String siteSp64; + float yearsToBreastHeight; + Optional inventoryTypeGroup; + Optional breastHeightAge; + + public FipLayer( + String polygonIdentifier, Layer layer, float ageTotal, float height, float siteIndex, float crownClosure, + String siteSp0, String siteSp64, float yearsToBreastHeight, Optional inventoryTypeGroup, + Optional breastHeightAge + ) { + super(); + this.polygonIdentifier = polygonIdentifier; + this.layer = layer; + this.ageTotal = ageTotal; + this.height = height; + this.siteIndex = siteIndex; + this.crownClosure = crownClosure; + this.siteSp0 = siteSp0; + this.siteSp64 = siteSp64; + this.yearsToBreastHeight = yearsToBreastHeight; + this.inventoryTypeGroup = inventoryTypeGroup; + this.breastHeightAge = breastHeightAge; + } + + public String getPolygonIdentifier() { + return polygonIdentifier; + } + + public Layer getLayer() { + return layer; + } + + public float getAgeTotal() { + return ageTotal; + } + + public float getHeight() { + return height; + } + + public float getSiteIndex() { + return siteIndex; + } + + public float getCrownClosure() { + return crownClosure; + } + + public String getSiteSp0() { + return siteSp0; + } + + public String getSiteSp64() { + return siteSp64; + } + + public float getYearsToBreastHeight() { + return yearsToBreastHeight; + } + + public Optional getInventoryTypeGroup() { + return inventoryTypeGroup; + } + + public Optional getBreastHeightAge() { + return breastHeightAge; + } + + public void setPolygonIdentifier(String polygonIdentifier) { + this.polygonIdentifier = polygonIdentifier; + } + + public void setAgeTotal(float ageTotal) { + this.ageTotal = ageTotal; + } + + public void setHeight(float height) { + this.height = height; + } + + public void setSiteIndex(float siteIndex) { + this.siteIndex = siteIndex; + } + + public void setCrownClosure(float crownClosure) { + this.crownClosure = crownClosure; + } + + public void setSireSp0(String sireSp0) { + this.siteSp0 = sireSp0; + } + + public void setSiteSp64(String siteSp64) { + this.siteSp64 = siteSp64; + } + + public void setYearsToBreastHeight(float yearsToBreastHeight) { + this.yearsToBreastHeight = yearsToBreastHeight; + } + + public void setInventoryTypeGroup(Optional inventoryTypeGroup) { + this.inventoryTypeGroup = inventoryTypeGroup; + } + + public void setBreastHeightAge(Optional breastHeightAge) { + this.breastHeightAge = breastHeightAge; + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java new file mode 100644 index 000000000..75ae1378f --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java @@ -0,0 +1,45 @@ +package ca.bc.gov.nrs.vdyp.fip.model; + +import java.util.Optional; + +import ca.bc.gov.nrs.vdyp.model.Layer; + +public class FipLayerPrimary extends FipLayer { + + static final String SITE_CURVE_NUMBER = "SITE_CURVE_NUMBER"; // SCN + static final String STOCKING_CLASS = "STOCKING_CLASS"; // STK + + Optional siteCurveNumber; // TODO Confirm if these should be required instead of optional if we know it's + // a Primary layer. + Optional stockingClass; + + public FipLayerPrimary( + String polygonIdentifier, float ageTotal, float height, float siteIndex, float crownClosure, String siteSp0, + String siteSp64, float yearsToBreastHeight, Optional stockingClass, + Optional inventoryTypeGroup, Optional breastHeightAge, Optional siteCurveNumber + ) { + super( + polygonIdentifier, Layer.PRIMARY, ageTotal, height, siteIndex, crownClosure, siteSp0, siteSp64, + yearsToBreastHeight, inventoryTypeGroup, breastHeightAge + ); + this.siteCurveNumber = siteCurveNumber; + this.stockingClass = stockingClass; + } + + public Optional getSiteCurveNumber() { + return siteCurveNumber; + } + + public void setSiteCurveNumber(Optional siteCurveNumber) { + this.siteCurveNumber = siteCurveNumber; + } + + public Optional getStockingClass() { + return stockingClass; + } + + public void setStockingClass(Optional stockingClass) { + this.stockingClass = stockingClass; + } + +} diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index dfe108e0e..cb0cfbb7e 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -616,6 +616,15 @@ public void testParseV7O_FIP() throws Exception { ); } + @Test + public void testParseV7O_FIL() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasSpecificEntry(FipLayerParser.CONTROL_KEY, instanceOf(StreamingParserFactory.class)) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java new file mode 100644 index 000000000..7317320fa --- /dev/null +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java @@ -0,0 +1,182 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertEmpty; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertNext; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.hasSpecificEntry; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.aMapWithSize; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.fip.model.FipLayer; +import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.model.Layer; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class FipLayerParserTest { + + @Test + public void testParseEmpty() throws Exception { + + var parser = new FipLayerParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipLayerParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver("test.dat", TestUtils.makeStream(/* empty */)); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipLayerParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + assertEmpty(stream); + } + + @Test + public void testParseLayer() throws Exception { + + var parser = new FipLayerParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipLayerParser.CONTROL_KEY, "test.dat"); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000001 00 1970 1 55 35.3 35.0 87.4 D D 1.0 0 13", + "01002 S000001 00 1970 Z 55 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipLayerParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var layers = assertNext(stream); + + assertThat(layers, aMapWithSize(1)); + + assertThat( + layers, + hasSpecificEntry( + Layer.PRIMARY, + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("ageTotal", is(55f)), + hasProperty("height", is(35.3f)), hasProperty("siteIndex", is(35.0f)), + hasProperty("crownClosure", is(87.4f)), hasProperty("siteSp0", is("D")), + hasProperty("siteSp64", is("D")), hasProperty("yearsToBreastHeight", is(1.0f)), + hasProperty("stockingClass", present(is("0"))), + hasProperty("inventoryTypeGroup", notPresent()), + hasProperty("breastHeightAge", notPresent()), + hasProperty("siteCurveNumber", present(is(13))) + ) + ) + ); + + assertEmpty(stream); + } + + @Test + public void testParseTwoLayers() throws Exception { + + var parser = new FipLayerParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipLayerParser.CONTROL_KEY, "test.dat"); + SP0DefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000004 00 1970 V 195 45.2 22.3 4.0 B B 9.4 2 8", + "01002 S000004 00 1970 1 85 42.3 31.9 82.8 H H 4.9 0 34", + "01002 S000004 00 1970 Z 85 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipLayerParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var layers = assertNext(stream); + + assertThat(layers, aMapWithSize(2)); + + assertThat( + layers, + hasSpecificEntry( + Layer.PRIMARY, + allOf( + hasProperty("polygonIdentifier", is("01002 S000004 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("ageTotal", is(85f)), + hasProperty("height", is(42.3f)), hasProperty("siteIndex", is(31.9f)), + hasProperty("crownClosure", is(82.8f)), hasProperty("siteSp0", is("H")), + hasProperty("siteSp64", is("H")), hasProperty("yearsToBreastHeight", is(4.9f)), + hasProperty("stockingClass", present(is("0"))), + hasProperty("inventoryTypeGroup", notPresent()), + hasProperty("breastHeightAge", notPresent()), + hasProperty("siteCurveNumber", present(is(34))) + ) + ) + ); + assertThat( + layers, + hasSpecificEntry( + Layer.VETERAN, + allOf( + hasProperty("polygonIdentifier", is("01002 S000004 00 1970")), + hasProperty("layer", is(Layer.VETERAN)), hasProperty("ageTotal", is(195f)), + hasProperty("height", is(45.2f)), hasProperty("siteIndex", is(22.3f)), + hasProperty("crownClosure", is(4.0f)), hasProperty("siteSp0", is("B")), + hasProperty("siteSp64", is("B")), hasProperty("yearsToBreastHeight", is(9.4f)), + // hasProperty("stockingClass", present(is("2"))), + hasProperty("inventoryTypeGroup", notPresent()), + hasProperty("breastHeightAge", notPresent()) + // hasProperty("siteCurveNumber", present(is(8))) + ) + ) + ); + + assertEmpty(stream); + } + +} diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java index 591b6ca3b..03f3cfb9c 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipPolygonParserTest.java @@ -1,31 +1,26 @@ package ca.bc.gov.nrs.vdyp.fip; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertEmpty; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertNext; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.notPresent; import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.present; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; -import java.io.IOException; import java.util.HashMap; import java.util.Map; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeDiagnosingMatcher; import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.fip.model.FipMode; import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParserTest; -import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; import ca.bc.gov.nrs.vdyp.test.TestUtils; +import ca.bc.gov.nrs.vdyp.test.VdypMatchers; public class FipPolygonParserTest { @@ -89,7 +84,7 @@ public void testParsePolygon() throws Exception { assertThat(poly, hasProperty("nonproductiveDescription", present(is("BLAH")))); assertThat(poly, hasProperty("yieldFactor", is(0.95f))); - assertEmpty(stream); + VdypMatchers.assertEmpty(stream); } @Test @@ -126,7 +121,7 @@ public void testParsePolygonWithBlanks() throws Exception { assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); assertThat(poly, hasProperty("yieldFactor", is(1.0f))); - assertEmpty(stream); + VdypMatchers.assertEmpty(stream); } @Test @@ -266,7 +261,7 @@ public void testParseMultiple() throws Exception { assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); assertThat(poly, hasProperty("yieldFactor", is(1.0f))); - assertEmpty(stream); + VdypMatchers.assertEmpty(stream); } @Test @@ -303,7 +298,7 @@ public void testParsePolygonZeroAsDefault() throws Exception { assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); assertThat(poly, hasProperty("yieldFactor", is(1.0f))); - assertEmpty(stream); + VdypMatchers.assertEmpty(stream); } @Test @@ -340,46 +335,6 @@ public void testParsePolygonNegativeAsDefault() throws Exception { assertThat(poly, hasProperty("nonproductiveDescription", notPresent())); assertThat(poly, hasProperty("yieldFactor", is(1.0f))); - assertEmpty(stream); - } - - static T assertNext(StreamingParser stream) throws IOException, ResourceParseException { - assertThat(stream, hasNext(true)); - var next = assertDoesNotThrow(() -> stream.next()); - assertThat(next, notNullValue()); - return next; - } - - static void assertEmpty(StreamingParser stream) throws IOException, ResourceParseException { - assertThat(stream, hasNext(false)); - assertThrows(IllegalStateException.class, () -> stream.next()); - } - - static Matcher> hasNext(boolean value) { - return new TypeSafeDiagnosingMatcher>() { - - @Override - public void describeTo(Description description) { - - description.appendText("StreamingParser with hasNext() ").appendValue(value); - - } - - @Override - protected boolean matchesSafely(StreamingParser item, Description mismatchDescription) { - try { - var hasNext = item.hasNext(); - if (hasNext == value) { - return true; - } - mismatchDescription.appendText("hasNext() returned ").appendValue(hasNext); - return false; - } catch (IOException | ResourceParseException e) { - mismatchDescription.appendText("hasNext() threw ").appendValue(e.getMessage()); - return false; - } - } - - }; + VdypMatchers.assertEmpty(stream); } } From 6abc2d2d4d4deb1c6b43ef583b3ec6f2cd2cfd91 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 6 Jul 2023 17:24:49 -0700 Subject: [PATCH 75/98] Parsing layer-species data file --- .../io/parse/AbstractStreamingParser.java | 2 +- .../vdyp/io/parse/BaseCoefficientParser.java | 2 +- .../vdyp/io/parse/ControlledValueParser.java | 52 ++- .../vdyp/io/parse/EquationGroupParser.java | 4 +- ...Parser.java => GenusDefinitionParser.java} | 26 +- .../vdyp/io/parse/HLCoefficientParser.java | 2 +- .../parse/HLNonprimaryCoefficientParser.java | 6 +- .../nrs/vdyp/io/parse/SiteCurveParser.java | 2 +- .../vdyp/io/parse/UpperCoefficientParser.java | 2 +- .../vdyp/io/parse/UtilComponentParser.java | 4 +- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 60 ++++ .../nrs/vdyp/io/parse/VeteranDQParser.java | 4 +- ...P0Definition.java => GenusDefinition.java} | 4 +- .../io/parse/ComponentSizeParserTest.java | 6 +- .../io/parse/EquationGroupParserTest.java | 6 +- ...st.java => GenusDefinitionParserTest.java} | 87 +++-- .../io/parse/HLCoefficientParserTest.java | 10 +- .../HLNonprimaryCoefficientParserTest.java | 10 +- .../vdyp/io/parse/SiteCurveParserTest.java | 40 +-- .../SmallComponentProbabilityParserTest.java | 4 +- .../io/parse/UpperCoefficientParserTest.java | 26 +- .../UtilComponentBaseAreaParserTest.java | 14 +- .../nrs/vdyp/io/parse/ValueParserTest.java | 56 +++ .../vdyp/io/parse/VeteranDQParserTest.java | 8 +- .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 35 +- .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 13 +- .../bc/gov/nrs/vdyp/fip/FipLayerParser.java | 7 +- .../bc/gov/nrs/vdyp/fip/FipSpeciesParser.java | 151 ++++++++ .../bc/gov/nrs/vdyp/fip/ModifierParser.java | 12 +- .../bc/gov/nrs/vdyp/fip/model/FipSpecies.java | 61 ++++ .../nrs/vdyp/fip/FipControlParserTest.java | 18 +- .../gov/nrs/vdyp/fip/FipLayerParserTest.java | 6 +- .../nrs/vdyp/fip/FipSpeciesParserTest.java | 328 ++++++++++++++++++ .../gov/nrs/vdyp/fip/ModifierParserTest.java | 38 +- 34 files changed, 905 insertions(+), 201 deletions(-) rename vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/{SP0DefinitionParser.java => GenusDefinitionParser.java} (72%) rename vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/{SP0Definition.java => GenusDefinition.java} (60%) rename vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/{SP0DefinitionParserTest.java => GenusDefinitionParserTest.java} (67%) create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParserTest.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java create mode 100644 vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParserTest.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java index 0d0315836..a54a3ad05 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java @@ -32,7 +32,7 @@ public T next() throws IOException, ResourceParseException { * * @return */ - protected abstract T convert(Map entry); + protected abstract T convert(Map entry) throws ResourceParseException; @Override public boolean hasNext() throws IOException, ResourceParseException { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index 4bb49e5a7..88ff769af 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -117,7 +117,7 @@ public BaseCoefficientParser groupIndexKey(int maxGroups) { public BaseCoefficientParser speciesKey(String name) { return key( - 2, name, ControlledValueParser.SPECIES, SP0DefinitionParser::getSpeciesAliases, + 2, name, ControlledValueParser.GENUS, GenusDefinitionParser::getSpeciesAliases, "%s is not a valid species" ); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java index 288f2a394..ca173df93 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ControlledValueParser.java @@ -1,8 +1,10 @@ package ca.bc.gov.nrs.vdyp.io.parse; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.function.BiFunction; +import java.util.function.Predicate; @FunctionalInterface public interface ControlledValueParser { @@ -30,6 +32,7 @@ public interface ControlledValueParser { public static ControlledValueParser validate( ControlledValueParser delegate, BiFunction, Optional> validator ) { + Objects.requireNonNull(delegate, "delegate must not be null"); return (s, c) -> { var value = delegate.parse(s, c); var error = validator.apply(value, c); @@ -47,8 +50,22 @@ public static ControlledValueParser validate( * @param delegate Parser to use if the string is not blank */ public static ControlledValueParser> optional(ControlledValueParser delegate) { + Objects.requireNonNull(delegate, "delegate must not be null"); + return pretestOptional(delegate, s -> !s.isBlank()); + } + + /** + * Makes a parser that parses if the string passes the test, and returns an + * empty Optional otherwise. + * + * @param delegate Parser to use if the string is not blank + * @param test Test to apply to the string + */ + public static ControlledValueParser> + pretestOptional(ControlledValueParser delegate, Predicate test) { + Objects.requireNonNull(delegate, "delegate must not be null"); return (s, c) -> { - if (!s.isBlank()) { + if (test.test(s)) { return Optional.of(delegate.parse(s, c)); } return Optional.empty(); @@ -56,14 +73,41 @@ public static ControlledValueParser> optional(ControlledValuePar } /** - * Parser that strips whitespace and validates that the string is a Species ID + * Makes a parser that parses the string, then tests it, and returns empty if it + * fails. + * + * @param delegate Parser to use + * @param test Test to apply to the parsed result + */ + public static ControlledValueParser> + posttestOptional(ControlledValueParser delegate, Predicate test) { + Objects.requireNonNull(delegate, "delegate must not be null"); + return (s, c) -> { + var result = delegate.parse(s, c); + if (test.test(result)) { + return Optional.of(result); + } + return Optional.empty(); + }; + } + + /** + * Parser that strips whitespace and validates that the string is a Genus (SP0) + * ID */ - static final ControlledValueParser SPECIES = (string, control) -> { + static final ControlledValueParser GENUS = (string, control) -> { var result = string.strip(); - SP0DefinitionParser.checkSpecies(control, result); + GenusDefinitionParser.checkSpecies(control, result); return result; }; + /** + * Parser that strips whitespace of a Species (SP64) id + */ + // Currently just parses as a string but marking it explicitly makes it clearer + // and could allow for validation later. + public static final ControlledValueParser SPECIES = (s, c) -> s.strip(); + /** * Parser that strips whitespace and validates that the string is a BEC ID */ diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index 23fcdbbad..224ad0142 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -37,7 +37,7 @@ public EquationGroupParser(int identifierLength) { public Map> parse(InputStream is, Map control) throws IOException, ResourceParseException { - final var sp0List = SP0DefinitionParser.getSpecies(control); + final var sp0List = GenusDefinitionParser.getSpecies(control); var becKeys = BecDefinitionParser.getBecAliases(control); @@ -70,7 +70,7 @@ public Map> parse(InputStream is, Map errors = new ArrayList<>(); - var sp0Keys = SP0DefinitionParser.getSpeciesAliases(control); + var sp0Keys = GenusDefinitionParser.getSpeciesAliases(control); var restrictedBecKeys = becKeys.stream().filter(k -> !hiddenBecs.contains(k)).toList(); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GenusDefinitionParser.java similarity index 72% rename from vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java rename to vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GenusDefinitionParser.java index 07365dbdd..833d2f4d9 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GenusDefinitionParser.java @@ -9,15 +9,15 @@ import java.util.Optional; import java.util.stream.Collectors; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.GenusDefinition; /** - * Parser for a SP0 Definition data file + * Parser for a Genus (SP0) Definition data file * * @author Kevin Smith, Vivid Solutions * */ -public class SP0DefinitionParser implements ControlMapSubResourceParser> { +public class GenusDefinitionParser implements ControlMapSubResourceParser> { public static final String CONTROL_KEY = "SP0_DEF"; @@ -30,28 +30,28 @@ public class SP0DefinitionParser implements ControlMapSubResourceParser v == 0 ? Optional.empty() : Optional.of(v)) ); - public SP0DefinitionParser() { + public GenusDefinitionParser() { super(); this.num_sp0 = 16; } - public SP0DefinitionParser(int num_sp0) { + public GenusDefinitionParser(int num_sp0) { super(); this.num_sp0 = num_sp0; } @SuppressWarnings("unchecked") @Override - public List parse(InputStream is, Map control) + public List parse(InputStream is, Map control) throws IOException, ResourceParseException { - SP0Definition[] result = new SP0Definition[num_sp0]; + GenusDefinition[] result = new GenusDefinition[num_sp0]; result = lineParser.parse(is, result, (v, r) -> { String alias = (String) v.get("alias"); Optional preference = (Optional) v.get("preference"); String name = (String) v.get("name"); Integer lineNumber = (Integer) v.get(LineParser.LINE_NUMBER_KEY); - var defn = new SP0Definition(alias, preference, name); + var defn = new GenusDefinition(alias, preference, name); int p = preference.orElse(lineNumber); if (p > num_sp0) { @@ -80,7 +80,7 @@ public List parse(InputStream is, Map control) public static void checkSpecies(final List speciesIndicies, final String sp0) throws ValueParseException { if (!speciesIndicies.contains(sp0)) { - throw new ValueParseException(sp0, sp0 + " is not a valid species"); + throw new ValueParseException(sp0, sp0 + " is not a valid genus (SP0)"); } } @@ -89,13 +89,13 @@ public static void checkSpecies(final Map controlMap, final Stri checkSpecies(speciesIndicies, sp0); } - public static List getSpecies(final Map controlMap) { + public static List getSpecies(final Map controlMap) { return ResourceParser - .>expectParsedControl(controlMap, SP0DefinitionParser.CONTROL_KEY, List.class); + .>expectParsedControl(controlMap, GenusDefinitionParser.CONTROL_KEY, List.class); } public static List getSpeciesAliases(final Map controlMap) { - return getSpecies(controlMap).stream().map(SP0Definition::getAlias).collect(Collectors.toList()); + return getSpecies(controlMap).stream().map(GenusDefinition::getAlias).collect(Collectors.toList()); } /** @@ -105,7 +105,7 @@ public static List getSpeciesAliases(final Map controlMa * @param controlMap * @return */ - public static SP0Definition getSpeciesByIndex(final int index, final Map controlMap) { + public static GenusDefinition getSpeciesByIndex(final int index, final Map controlMap) { return getSpecies(controlMap).get(index - 1); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java index 673720a39..ea07a1441 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParser.java @@ -54,7 +54,7 @@ public boolean isStopLine(String line) { public MatrixMap2 parse(InputStream is, Map control) throws IOException, ResourceParseException { final var regionIndicies = Arrays.asList(Region.values()); - final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var speciesIndicies = GenusDefinitionParser.getSpeciesAliases(control); MatrixMap2 result = new MatrixMap2Impl( speciesIndicies, regionIndicies diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java index 60b708941..f1df4b402 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParser.java @@ -50,7 +50,7 @@ public boolean isStopLine(String line) { public MatrixMap3 parse(InputStream is, Map control) throws IOException, ResourceParseException { final var regionIndicies = Arrays.asList(Region.values()); - final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var speciesIndicies = GenusDefinitionParser.getSpeciesAliases(control); MatrixMap3 result = new MatrixMap3Impl( speciesIndicies, speciesIndicies, regionIndicies @@ -62,8 +62,8 @@ public boolean isStopLine(String line) { var region = (Region) v.get(REGION_KEY); @SuppressWarnings("unchecked") var coefficients = (List) v.get(COEFFICIENT_KEY); - SP0DefinitionParser.checkSpecies(speciesIndicies, sp0_1); - SP0DefinitionParser.checkSpecies(speciesIndicies, sp0_2); + GenusDefinitionParser.checkSpecies(speciesIndicies, sp0_1); + GenusDefinitionParser.checkSpecies(speciesIndicies, sp0_2); if (coefficients.size() < NUM_COEFFICIENTS) { throw new ValueParseException(null, "Expected 2 coefficients"); // TODO handle this better diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java index 2ce166193..89bb121fb 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParser.java @@ -42,7 +42,7 @@ public Map parse(InputStream is, Map control) return r; }, control); - final var sp0List = SP0DefinitionParser.getSpeciesAliases(control); + final var sp0List = GenusDefinitionParser.getSpeciesAliases(control); var missing = ExpectationDifference.difference(result.keySet(), sp0List).getMissing(); if (!missing.isEmpty()) { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java index 822c8aad3..f90a6bd3c 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParser.java @@ -45,7 +45,7 @@ public MatrixMap3 parse(InputStream is, Map coeIndicies = Stream.iterate(1, x -> x + 1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); - final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var speciesIndicies = GenusDefinitionParser.getSpeciesAliases(control); MatrixMap3 result = new MatrixMap3Impl( regionIndicies, speciesIndicies, coeIndicies diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java index a48dc0e06..c2e9d5e47 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentParser.java @@ -43,7 +43,7 @@ public boolean isStopLine(String line) { public MatrixMap3 parse(InputStream is, Map control) throws IOException, ResourceParseException { final var becIndices = BecDefinitionParser.getBecAliases(control); - final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var speciesIndicies = GenusDefinitionParser.getSpeciesAliases(control); final var ucIndices = Arrays.asList(1, 2, 3, 4); MatrixMap3 result = new MatrixMap3Impl( @@ -61,7 +61,7 @@ public MatrixMap3 parse(InputStream is, M @SuppressWarnings("unchecked") var coefficients = (List) v.get(COEFFICIENT_KEY); - SP0DefinitionParser.checkSpecies(speciesIndicies, sp0); + GenusDefinitionParser.checkSpecies(speciesIndicies, sp0); if (coefficients.size() < numCoefficients) { throw new ValueParseException(null, "Expected " + numCoefficients + " coefficients"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index ee46b14a1..acaecb3db 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -121,6 +121,44 @@ public static ValueParser indexParser(String sequenceName, int indexFro */ public static final ValueParser FLOAT = numberParser(Float::parseFloat, Float.class); + /** + * Parser for percentages + */ + public static final ValueParser PERCENTAGE = ValueParser + .range(FLOAT, 0.0f, true, 100.0f, true, "Percentage"); + + /** + * Validate that a parsed value is within a range + * + * @param parser underlying parser + * @param min the lower bound + * @param includeMin is the lower bound inclusive + * @param max the upper bound + * @param includeMax is the upper bound inclusive + * @param name Name for the value to use in the parse error if it is out + * of the range. + */ + public static > ValueParser + range(ValueParser parser, T min, boolean includeMin, T max, boolean includeMax, String name) { + return validate(parser, x -> { + if (x.compareTo(min) < (includeMin ? 0 : 1)) { + return Optional.of( + String.format( + "%s must be %s %s.", name, includeMin ? "greater than or equal to" : "greater than", min + ) + ); + } + if (x.compareTo(max) > (includeMax ? 0 : -1)) { + return Optional.of( + String.format( + "%s must be %s %s.", name, includeMax ? "less than or equal to" : "less than", max + ) + ); + } + return Optional.empty(); + }); + } + /** * Parser for integers as booleans */ @@ -186,6 +224,28 @@ public static ValueParser> optional(ValueParser delegate) { return uncontrolled(ControlledValueParser.optional(delegate)); } + /** + * Makes a parser that parses if the string passes the test, and returns an + * empty Optional otherwise. + * + * @param delegate Parser to use if the string is not blank + * @param test Test to apply to the string + */ + public static ValueParser> pretestOptional(ValueParser delegate, Predicate test) { + return uncontrolled(ControlledValueParser.pretestOptional(delegate, test)); + } + + /** + * Makes a parser that parses the string, then tests it, and returns empty if it + * fails. + * + * @param delegate Parser to use + * @param test Test to apply to the parsed result + */ + public static ValueParser> posttestOptional(ValueParser delegate, Predicate test) { + return uncontrolled(ControlledValueParser.posttestOptional(delegate, test)); + } + /** * Parse a string as a set of fixed length chucks. * diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java index af4284e57..948945bce 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParser.java @@ -41,7 +41,7 @@ public boolean isStopLine(String line) { @Override public MatrixMap2 parse(InputStream is, Map control) throws IOException, ResourceParseException { - final var speciesIndicies = SP0DefinitionParser.getSpeciesAliases(control); + final var speciesIndicies = GenusDefinitionParser.getSpeciesAliases(control); final var regionIndicies = Arrays.asList(Region.values()); MatrixMap2 result = new MatrixMap2Impl( @@ -54,7 +54,7 @@ public MatrixMap2 parse(InputStream is, Map) v.get(COEFFICIENT_KEY); - SP0DefinitionParser.checkSpecies(speciesIndicies, sp0); + GenusDefinitionParser.checkSpecies(speciesIndicies, sp0); if (coefficients.size() < numCoefficients) { throw new ValueParseException(null, "Expected " + numCoefficients + " coefficients"); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/GenusDefinition.java similarity index 60% rename from vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java rename to vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/GenusDefinition.java index 25f9fad14..6945445a1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/SP0Definition.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/model/GenusDefinition.java @@ -2,11 +2,11 @@ import java.util.Optional; -public class SP0Definition extends AbstractSpeciesDefinition { +public class GenusDefinition extends AbstractSpeciesDefinition { final Optional preference; - public SP0Definition(String alias, Optional preference, String name) { + public GenusDefinition(String alias, Optional preference, String name) { super(alias, name); this.preference = preference; } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java index 8e8ffbf50..e2028b010 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java @@ -23,7 +23,7 @@ public void testParseSimpleP1() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var parser = new ComponentSizeParser(); @@ -39,7 +39,7 @@ public void testParseBadSpecies() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var parser = new ComponentSizeParser(); @@ -55,7 +55,7 @@ public void testParseBadRegion() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var parser = new ComponentSizeParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index c2c8cf264..1da168279 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -24,7 +24,7 @@ import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.GenusDefinition; import ca.bc.gov.nrs.vdyp.test.TestUtils; import ca.bc.gov.nrs.vdyp.test.VdypMatchers; @@ -184,7 +184,7 @@ private HashMap makeControlMapSingle() { var controlMap = new HashMap(); BecDefinitionParserTest.populateControlMap(controlMap, "B1"); - SP0DefinitionParserTest.populateControlMap(controlMap, "S1"); + GenusDefinitionParserTest.populateControlMap(controlMap, "S1"); return controlMap; } @@ -192,7 +192,7 @@ private HashMap makeControlMap() { var controlMap = new HashMap(); BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); - SP0DefinitionParserTest.populateControlMap(controlMap, "S1", "S2"); + GenusDefinitionParserTest.populateControlMap(controlMap, "S1", "S2"); return controlMap; } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/GenusDefinitionParserTest.java similarity index 67% rename from vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java rename to vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/GenusDefinitionParserTest.java index 26cf66012..040885c1d 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/GenusDefinitionParserTest.java @@ -20,13 +20,13 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.GenusDefinition; -public class SP0DefinitionParserTest { +public class GenusDefinitionParserTest { @Test public void testParse() throws Exception { - var parser = new SP0DefinitionParser(); + var parser = new GenusDefinitionParser(); var result = parser.parse(ControlFileParserTest.class, "coe/SP0DEF_v0.dat", Collections.emptyMap()); @@ -34,67 +34,74 @@ public void testParse() throws Exception { result, contains( allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AC")), Matchers.hasProperty("name", equalTo("Cottonwood")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AT")), Matchers.hasProperty("name", equalTo("Aspen")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("B")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("B")), Matchers.hasProperty("name", equalTo("Balsam")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("C")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("C")), Matchers.hasProperty("name", equalTo("Cedar (X yellow)")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("D")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("D")), Matchers.hasProperty("name", equalTo("Alder")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("E")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("E")), Matchers.hasProperty("name", equalTo("Birch")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("F")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("F")), Matchers.hasProperty("name", equalTo("Douglas Fir")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("H")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("H")), Matchers.hasProperty("name", equalTo("Hemlock")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("L")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("L")), Matchers.hasProperty("name", equalTo("Larch")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("MB")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("MB")), Matchers.hasProperty("name", equalTo("Maple")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PA")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("PA")), Matchers.hasProperty("name", equalTo("White-bark pine")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PL")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("PL")), Matchers.hasProperty("name", equalTo("Lodgepole Pine")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PW")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("PW")), Matchers.hasProperty("name", equalTo("White pine")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("PY")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("PY")), Matchers.hasProperty("name", equalTo("Yellow pine")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("S")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("S")), Matchers.hasProperty("name", equalTo("Spruce")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("Y")), + Matchers.instanceOf(GenusDefinition.class), Matchers.hasProperty("alias", equalTo("Y")), Matchers.hasProperty("name", equalTo("Yellow cedar")) ) @@ -104,9 +111,9 @@ public void testParse() throws Exception { @Test public void testOrderByPreference() throws Exception { - var parser = new SP0DefinitionParser(2); + var parser = new GenusDefinitionParser(2); - List result; + List result; try ( var is = new ByteArrayInputStream( "AT Aspen 02\r\nAC Cottonwood 01".getBytes() @@ -118,11 +125,13 @@ public void testOrderByPreference() throws Exception { result, contains( allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AC")), Matchers.hasProperty("name", equalTo("Cottonwood")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AT")), Matchers.hasProperty("name", equalTo("Aspen")) ) ) @@ -131,9 +140,9 @@ public void testOrderByPreference() throws Exception { @Test public void testOrderByLinesBlank() throws Exception { - var parser = new SP0DefinitionParser(2); + var parser = new GenusDefinitionParser(2); - List result; + List result; try ( var is = new ByteArrayInputStream( "AT Aspen \r\nAC Cottonwood ".getBytes() @@ -145,11 +154,13 @@ public void testOrderByLinesBlank() throws Exception { result, contains( allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AT")), Matchers.hasProperty("name", equalTo("Aspen")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AC")), Matchers.hasProperty("name", equalTo("Cottonwood")) ) ) @@ -158,9 +169,9 @@ public void testOrderByLinesBlank() throws Exception { @Test public void testOrderByLinesZero() throws Exception { - var parser = new SP0DefinitionParser(2); + var parser = new GenusDefinitionParser(2); - List result; + List result; try ( var is = new ByteArrayInputStream( "AT Aspen 00\r\nAC Cottonwood 00".getBytes() @@ -172,11 +183,13 @@ public void testOrderByLinesZero() throws Exception { result, contains( allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AT")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AT")), Matchers.hasProperty("name", equalTo("Aspen")) ), allOf( - Matchers.instanceOf(SP0Definition.class), Matchers.hasProperty("alias", equalTo("AC")), + Matchers.instanceOf(GenusDefinition.class), + Matchers.hasProperty("alias", equalTo("AC")), Matchers.hasProperty("name", equalTo("Cottonwood")) ) ) @@ -185,7 +198,7 @@ public void testOrderByLinesZero() throws Exception { @Test public void testErrorPreferenceOutOfBoundsHigh() throws Exception { - var parser = new SP0DefinitionParser(2); + var parser = new GenusDefinitionParser(2); Exception ex1; try ( @@ -203,7 +216,7 @@ public void testErrorPreferenceOutOfBoundsHigh() throws Exception { @Test public void testErrorPreferenceOutOfBoundsLow() throws Exception { - var parser = new SP0DefinitionParser(2); + var parser = new GenusDefinitionParser(2); Exception ex1; try ( @@ -221,7 +234,7 @@ public void testErrorPreferenceOutOfBoundsLow() throws Exception { @Test public void testErrorPreferenceDuplicate() throws Exception { - var parser = new SP0DefinitionParser(2); + var parser = new GenusDefinitionParser(2); Exception ex1; try ( @@ -263,12 +276,12 @@ public static String[] getSpeciesAliases() { */ public static void populateControlMap(Map controlMap, String... aliases) { - List sp0List = new ArrayList<>(); + List sp0List = new ArrayList<>(); for (var alias : aliases) { - sp0List.add(new SP0Definition(alias, java.util.Optional.empty(), "Test " + alias)); + sp0List.add(new GenusDefinition(alias, java.util.Optional.empty(), "Test " + alias)); } - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java index 0f232a3f1..e54aa5643 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java @@ -25,7 +25,7 @@ public void testParseSimpleP1() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -41,7 +41,7 @@ public void testParseSimpleP2() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -57,7 +57,7 @@ public void testParseSimpleP3() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -75,7 +75,7 @@ public void testParseBadSpecies() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -90,7 +90,7 @@ public void testParseBadRegion() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java index 9ee507fdf..8262efb15 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java @@ -30,7 +30,7 @@ public void testParseSimple() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -46,7 +46,7 @@ public void testParseBadSpecies1() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -61,7 +61,7 @@ public void testParseBadSpecies2() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -76,7 +76,7 @@ public void testParseBadRegion() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -91,7 +91,7 @@ public void testParseMissingCoefficient() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java index 3f199caef..a2c5ad51a 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java @@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.GenusDefinition; import ca.bc.gov.nrs.vdyp.test.TestUtils; public class SiteCurveParserTest { @@ -25,11 +25,11 @@ public void testSimple() throws Exception { var is = TestUtils.makeStream("S1 001002"); Map controlMap = new HashMap<>(); - List sp0List = new ArrayList<>(); + List sp0List = new ArrayList<>(); - sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + sp0List.add(new GenusDefinition("S1", java.util.Optional.empty(), "Test Species 1")); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); var result = parser.parse(is, controlMap); @@ -42,11 +42,11 @@ public void testExtraSpecies() throws Exception { var is = TestUtils.makeStream("S1 001002", "X2 003004"); Map controlMap = new HashMap<>(); - List sp0List = new ArrayList<>(); + List sp0List = new ArrayList<>(); - sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + sp0List.add(new GenusDefinition("S1", java.util.Optional.empty(), "Test Species 1")); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); var result = parser.parse(is, controlMap); @@ -60,12 +60,12 @@ public void testMissingSpecies() throws Exception { var is = TestUtils.makeStream("S1 001002"); Map controlMap = new HashMap<>(); - List sp0List = new ArrayList<>(); + List sp0List = new ArrayList<>(); - sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); - sp0List.add(new SP0Definition("S2", java.util.Optional.empty(), "Test Species 2")); + sp0List.add(new GenusDefinition("S1", java.util.Optional.empty(), "Test Species 1")); + sp0List.add(new GenusDefinition("S2", java.util.Optional.empty(), "Test Species 2")); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); var ex = assertThrows(ResourceParseValidException.class, () -> parser.parse(is, controlMap)); @@ -78,11 +78,11 @@ public void testHashComment() throws Exception { var is = TestUtils.makeStream("# Foo", "S1 001002"); Map controlMap = new HashMap<>(); - List sp0List = new ArrayList<>(); + List sp0List = new ArrayList<>(); - sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + sp0List.add(new GenusDefinition("S1", java.util.Optional.empty(), "Test Species 1")); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); var result = parser.parse(is, controlMap); @@ -95,11 +95,11 @@ public void testSpaceComment() throws Exception { var is = TestUtils.makeStream(" Foo", "S1 001002"); Map controlMap = new HashMap<>(); - List sp0List = new ArrayList<>(); + List sp0List = new ArrayList<>(); - sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + sp0List.add(new GenusDefinition("S1", java.util.Optional.empty(), "Test Species 1")); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); var result = parser.parse(is, controlMap); @@ -112,11 +112,11 @@ public void testEndFileLine() throws Exception { var is = TestUtils.makeStream("S1 001002", "##", "S2 003004"); Map controlMap = new HashMap<>(); - List sp0List = new ArrayList<>(); + List sp0List = new ArrayList<>(); - sp0List.add(new SP0Definition("S1", java.util.Optional.empty(), "Test Species 1")); + sp0List.add(new GenusDefinition("S1", java.util.Optional.empty(), "Test Species 1")); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); var result = parser.parse(is, controlMap); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java index ae47a7966..4e8382ba4 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java @@ -24,7 +24,7 @@ public void testParseSimpleP1() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var parser = new SmallComponentProbabilityParser(); var result = parser.parse(is, controlMap); @@ -39,7 +39,7 @@ public void testParseBadSpecies() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var parser = new SmallComponentProbabilityParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java index 03c59f741..b73dfa7d5 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java @@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.GenusDefinition; import ca.bc.gov.nrs.vdyp.test.TestUtils; public class UpperCoefficientParserTest { @@ -28,12 +28,12 @@ public void testParseSimple() throws Exception { Map controlMap = new HashMap<>(); - List sp0List = Arrays.asList( - new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), - new SP0Definition("S2", java.util.Optional.empty(), "Test S2") + List sp0List = Arrays.asList( + new GenusDefinition("S1", java.util.Optional.empty(), "Test S1"), + new GenusDefinition("S2", java.util.Optional.empty(), "Test S2") ); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); var result = parser.parse(is, controlMap); @@ -49,12 +49,12 @@ public void testParseBadSpecies() throws Exception { Map controlMap = new HashMap<>(); - List sp0List = Arrays.asList( - new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), - new SP0Definition("S2", java.util.Optional.empty(), "Test S2") + List sp0List = Arrays.asList( + new GenusDefinition("S1", java.util.Optional.empty(), "Test S1"), + new GenusDefinition("S2", java.util.Optional.empty(), "Test S2") ); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -69,12 +69,12 @@ public void testParseBadRegion() throws Exception { Map controlMap = new HashMap<>(); - List sp0List = Arrays.asList( - new SP0Definition("S1", java.util.Optional.empty(), "Test S1"), - new SP0Definition("S2", java.util.Optional.empty(), "Test S2") + List sp0List = Arrays.asList( + new GenusDefinition("S1", java.util.Optional.empty(), "Test S1"), + new GenusDefinition("S2", java.util.Optional.empty(), "Test S2") ); - controlMap.put(SP0DefinitionParser.CONTROL_KEY, sp0List); + controlMap.put(GenusDefinitionParser.CONTROL_KEY, sp0List); assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java index 1c55b7c6f..42fc22a6f 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java @@ -29,7 +29,7 @@ public void testParseSingleBec() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); var result = parser.parse(is, controlMap); @@ -56,7 +56,7 @@ public void testParseSingleRegion() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); var result = parser.parse(is, controlMap); @@ -83,7 +83,7 @@ public void testParseAllBecs() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap, "B1", "B2", "B3", "B4"); var result = parser.parse(is, controlMap); @@ -111,7 +111,7 @@ public void testParseBadSpecies() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -127,7 +127,7 @@ public void testParseBadBec() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -143,7 +143,7 @@ public void testParseBadBau() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -159,7 +159,7 @@ public void testParseMissingCoefficient() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParserTest.java new file mode 100644 index 000000000..80a56f70f --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParserTest.java @@ -0,0 +1,56 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class ValueParserTest { + + @Test + public void rangeParserTest() throws Exception { + var exclusiveParser = ValueParser.range(ValueParser.INTEGER, 10, false, 20, false, "Test"); + + var result = exclusiveParser.parse("11"); + assertThat(result, is(11)); + + result = exclusiveParser.parse("19"); + assertThat(result, is(19)); + + var ex = assertThrows(ValueParseException.class, () -> exclusiveParser.parse("10")); + assertThat(ex, hasProperty("message", is("Test must be greater than 10."))); + + ex = assertThrows(ValueParseException.class, () -> exclusiveParser.parse("9")); + assertThat(ex, hasProperty("message", is("Test must be greater than 10."))); + + ex = assertThrows(ValueParseException.class, () -> exclusiveParser.parse("20")); + assertThat(ex, hasProperty("message", is("Test must be less than 20."))); + + ex = assertThrows(ValueParseException.class, () -> exclusiveParser.parse("21")); + assertThat(ex, hasProperty("message", is("Test must be less than 20."))); + + var inclusiveParser = ValueParser.range(ValueParser.INTEGER, 10, true, 20, true, "Test"); + + result = inclusiveParser.parse("11"); + assertThat(result, is(11)); + + result = inclusiveParser.parse("19"); + assertThat(result, is(19)); + + result = inclusiveParser.parse("10"); + assertThat(result, is(10)); + + result = inclusiveParser.parse("20"); + assertThat(result, is(20)); + + ex = assertThrows(ValueParseException.class, () -> inclusiveParser.parse("9")); + assertThat(ex, hasProperty("message", is("Test must be greater than or equal to 10."))); + + ex = assertThrows(ValueParseException.class, () -> inclusiveParser.parse("21")); + assertThat(ex, hasProperty("message", is("Test must be less than or equal to 20."))); + + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java index 78565cbb6..7b1b010a9 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java @@ -30,7 +30,7 @@ public void testParseSingleRegion() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -48,7 +48,7 @@ public void testParseAllRegions() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var result = parser.parse(is, controlMap); @@ -66,7 +66,7 @@ public void testParseBadSpecies() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); @@ -82,7 +82,7 @@ public void testParseMissingCoefficient() throws Exception { Map controlMap = new HashMap<>(); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); BecDefinitionParserTest.populateControlMap(controlMap); var ex = assertThrows(ResourceParseLineException.class, () -> parser.parse(is, controlMap)); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index e92b1e5e4..aeb93895d 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -1,6 +1,7 @@ package ca.bc.gov.nrs.vdyp.test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -437,42 +438,16 @@ protected boolean matchesSafely(ValueOrMarker item, Description mismatchDe } public static T assertNext(StreamingParser stream) throws IOException, ResourceParseException { - assertThat(stream, hasNext(true)); + var hasNext = assertDoesNotThrow(() -> stream.hasNext()); + assertThat(hasNext, is(true)); var next = assertDoesNotThrow(() -> stream.next()); assertThat(next, notNullValue()); return next; } public static void assertEmpty(StreamingParser stream) throws IOException, ResourceParseException { - assertThat(stream, hasNext(false)); + var hasNext = assertDoesNotThrow(() -> stream.hasNext()); + assertThat(hasNext, is(false)); assertThrows(IllegalStateException.class, () -> stream.next()); } - - public static Matcher> hasNext(boolean value) { - return new TypeSafeDiagnosingMatcher>() { - - @Override - public void describeTo(Description description) { - - description.appendText("StreamingParser with hasNext() ").appendValue(value); - - } - - @Override - protected boolean matchesSafely(StreamingParser item, Description mismatchDescription) { - try { - var hasNext = item.hasNext(); - if (hasNext == value) { - return true; - } - mismatchDescription.appendText("hasNext() returned ").appendValue(hasNext); - return false; - } catch (IOException | ResourceParseException e) { - mismatchDescription.appendText("hasNext() threw ").appendValue(e.getMessage()); - return false; - } - } - - }; - } } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index e053cbb1c..2e4d8925b 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -20,7 +20,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.ControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.DecayEquationGroupParser; import ca.bc.gov.nrs.vdyp.io.parse.DefaultEquationNumberParser; -import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.GenusDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveParser; import ca.bc.gov.nrs.vdyp.io.parse.SmallComponentBaseAreaParser; @@ -56,7 +56,7 @@ public class FipControlParser { public static final String FIP_YIELD_POLY_INPUT = FipPolygonParser.CONTROL_KEY; public static final String FIP_YIELD_LAYER_INPUT = FipLayerParser.CONTROL_KEY; - public static final String FIP_YIELD_LX_SP0_INPUT = "FIP_YIELD_LxSP0_INPUT"; + public static final String FIP_YIELD_LX_SP0_INPUT = FipSpeciesParser.CONTROL_KEY; public static final String VDYP_POLYGON = "VDYP_POLYGON"; public static final String VDYP_LAYER_BY_SPECIES = "VDYP_LAYER_BY_SPECIES"; public static final String VDYP_LAYER_BY_SP0_BY_UTIL = "VDYP_LAYER_BY_SP0_BY_UTIL"; @@ -98,7 +98,7 @@ public class FipControlParser { public static final String DEBUG_SWITCHES = "DEBUG_SWITCHES"; public static final String MAX_NUM_POLY = "MAX_NUM_POLY"; public static final String BEC_DEF = BecDefinitionParser.CONTROL_KEY; - public static final String SP0_DEF = SP0DefinitionParser.CONTROL_KEY; + public static final String SP0_DEF = GenusDefinitionParser.CONTROL_KEY; static final ValueParser FILENAME = String::strip; @@ -229,7 +229,10 @@ public String toString(String filename) throws IOException { new FipPolygonParser(), // V7O_FIL - new FipLayerParser() + new FipLayerParser(), + + // V7O_FIS + new FipSpeciesParser() ); List BASIC_DEFINITIONS = Arrays.asList( @@ -241,7 +244,7 @@ public String toString(String filename) throws IOException { // Superseded by BecLookup.getGrowthBecs // RD_SP0 - new SP0DefinitionParser() + new GenusDefinitionParser() ); List GROUP_DEFINITIONS = Arrays.asList( diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java index 650a366cd..969fc469f 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java @@ -55,7 +55,7 @@ public String getControlKey() { ValueParser.LAYER, ValueParser.optionalSingleton("Z"::equals, EndOfRecord.END_OF_RECORD) ) ).floating(4, AGE_TOTAL).floating(5, HEIGHT).floating(5, SITE_INDEX).floating(5, CROWN_CLOSURE).space(3) - .value(2, SITE_SP0, ControlledValueParser.optional(ValueParser.SPECIES)) + .value(2, SITE_SP0, ControlledValueParser.optional(ValueParser.GENUS)) .value(3, SITE_SP64, ControlledValueParser.optional(ValueParser.STRING)) .floating(5, YEARS_TO_BREAST_HEIGHT) .value(1, STOCKING_CLASS, ValueParser.optional(ValueParser.STRING)).space(2) @@ -137,7 +137,10 @@ protected boolean stop(ValueOrMarker, EndOfRecord> nextChild) @Override protected Map convert(List, EndOfRecord>> children) { - return children.stream().map(ValueOrMarker::getValue).map(Optional::get).map(Optional::get) + return children.stream().map(ValueOrMarker::getValue).map(Optional::get) // Should never be empty as + // we've filtered out + // markers + .flatMap(Optional::stream) // Skip if empty (and unknown layer type) .collect(Collectors.toMap(FipLayer::getLayer, x -> x)); } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java new file mode 100644 index 000000000..bb3916b62 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java @@ -0,0 +1,151 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import ca.bc.gov.nrs.vdyp.common.ValueOrMarker; +import ca.bc.gov.nrs.vdyp.fip.model.FipSpecies; +import ca.bc.gov.nrs.vdyp.io.EndOfRecord; +import ca.bc.gov.nrs.vdyp.io.FileResolver; +import ca.bc.gov.nrs.vdyp.io.parse.AbstractStreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.ControlMapValueReplacer; +import ca.bc.gov.nrs.vdyp.io.parse.ControlledValueParser; +import ca.bc.gov.nrs.vdyp.io.parse.GroupingStreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.LineParser; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseValidException; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; +import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; +import ca.bc.gov.nrs.vdyp.model.Layer; + +public class FipSpeciesParser + implements ControlMapValueReplacer>, String> { + + public static final String CONTROL_KEY = "FIP_SPECIES"; + + static final String POLYGON_IDENTIFIER = "POLYGON_IDENTIFIER"; // POLYDESC + static final String LAYER = "LAYER"; // LAYER + + static final String GENUS = "GENUS"; // SP0 + static final String PERCENT_GENUS = "PERCENT_GENUS"; // PTVSP0 + + static final String SPECIES_1 = "SPECIES_1"; // SP641 + static final String PERCENT_SPECIES_1 = "PERCENT_SPECIES_1"; // PCT1 + static final String SPECIES_2 = "SPECIES_2"; // SP642 + static final String PERCENT_SPECIES_2 = "PERCENT_SPECIES_2"; // PCT2 + static final String SPECIES_3 = "SPECIES_3"; // SP643 + static final String PERCENT_SPECIES_3 = "PERCENT_SPECIES_3"; // PCT3 + static final String SPECIES_4 = "SPECIES_4"; // SP644 + static final String PERCENT_SPECIES_4 = "PERCENT_SPECIES_4"; // PCT4 + + @Override + public String getControlKey() { + return CONTROL_KEY; + } + + @Override + public StreamingParserFactory> + map(String fileName, FileResolver fileResolver, Map control) + throws IOException, ResourceParseException { + return () -> { + var lineParser = new LineParser().strippedString(25, POLYGON_IDENTIFIER).space(1).value( + 1, LAYER, + ValueParser.valueOrMarker( + ValueParser.LAYER, ValueParser.optionalSingleton("Z"::equals, EndOfRecord.END_OF_RECORD) + ) + ).space(1).value(2, GENUS, ControlledValueParser.optional(ValueParser.GENUS)) + .value(6, PERCENT_GENUS, ValueParser.PERCENTAGE) + .value(3, SPECIES_1, ControlledValueParser.optional(ValueParser.SPECIES)) + .value(5, PERCENT_SPECIES_1, ValueParser.PERCENTAGE) + .value(3, SPECIES_2, ControlledValueParser.optional(ValueParser.SPECIES)) + .value(5, PERCENT_SPECIES_2, ValueParser.PERCENTAGE) + .value(3, SPECIES_3, ControlledValueParser.optional(ValueParser.SPECIES)) + .value(5, PERCENT_SPECIES_3, ValueParser.PERCENTAGE) + .value(3, SPECIES_4, ControlledValueParser.optional(ValueParser.SPECIES)) + .value(5, PERCENT_SPECIES_4, ValueParser.PERCENTAGE); + + var is = fileResolver.resolve(fileName); + + var delegateStream = new AbstractStreamingParser, EndOfRecord>>( + is, lineParser, control + ) { + + @SuppressWarnings("unchecked") + @Override + protected ValueOrMarker, EndOfRecord> convert(Map entry) + throws ResourceParseException { + var polygonId = (String) entry.get(POLYGON_IDENTIFIER); + var layer = (ValueOrMarker, EndOfRecord>) entry.get(LAYER); + String genus; + if (layer.isValue()) { + genus = ((Optional) entry.get(GENUS)).orElseThrow( + () -> new ResourceParseValidException( + "Genus identifier can not be empty except in end of record entries" + ) + ); + } else { + genus = null; + } + var percentGenus = (Float) entry.get(PERCENT_GENUS); + var species1 = (Optional) entry.get(SPECIES_1); + var percentSpecies1 = (Float) entry.get(PERCENT_SPECIES_1); + var species2 = (Optional) entry.get(SPECIES_2); + var percentSpecies2 = (Float) entry.get(PERCENT_SPECIES_2); + var species3 = (Optional) entry.get(SPECIES_3); + var percentSpecies3 = (Float) entry.get(PERCENT_SPECIES_3); + var species4 = (Optional) entry.get(SPECIES_4); + var percentSpecies4 = (Float) entry.get(PERCENT_SPECIES_4); + + var builder = new ValueOrMarker.Builder, EndOfRecord>(); + var result = layer.handle(l -> { + return builder.value(l.map(layerType -> { + Map speciesPercent = new LinkedHashMap<>(); + species1.ifPresent((sp) -> speciesPercent.put(sp, percentSpecies1)); + species2.ifPresent((sp) -> speciesPercent.put(sp, percentSpecies2)); + species3.ifPresent((sp) -> speciesPercent.put(sp, percentSpecies3)); + species4.ifPresent((sp) -> speciesPercent.put(sp, percentSpecies4)); + var species = new FipSpecies(polygonId, layerType, genus, percentGenus, speciesPercent); + return species; + })); + }, m -> { + return builder.marker(m); + }); + return result; + } + + }; + + return new GroupingStreamingParser, ValueOrMarker, EndOfRecord>>( + delegateStream + ) { + + @Override + protected boolean skip(ValueOrMarker, EndOfRecord> nextChild) { + return nextChild.getValue().map(Optional::isEmpty).orElse(false); + } + + @Override + protected boolean stop(ValueOrMarker, EndOfRecord> nextChild) { + return nextChild.isMarker(); + } + + @Override + protected Collection + convert(List, EndOfRecord>> children) { + return children.stream().map(ValueOrMarker::getValue).map(Optional::get) // Should never be empty as + // we've filtered out + // markers + .flatMap(Optional::stream) // Skip if empty (and unknown layer type) + .collect(Collectors.toList()); + } + + }; + }; + } +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java index 8223da5bf..3120f47fc 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ModifierParser.java @@ -15,7 +15,7 @@ import ca.bc.gov.nrs.vdyp.io.parse.OptionalResourceControlMapModifier; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParser; -import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.GenusDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; @@ -153,7 +153,7 @@ public boolean isIgnoredLine(String line) { // for veteran BQ by the region appropriate modifier. vetBqMap.get(CONTROL_KEY, null); var mods = getMods(2, entry); - var sp0Aliases = SP0DefinitionParser.getSpeciesAliases(control); + var sp0Aliases = GenusDefinitionParser.getSpeciesAliases(control); for (var sp0Alias : sp0Aliases) { final float coastalMod = mods.get(0); final float interiorMod = mods.get(1); @@ -212,7 +212,7 @@ public boolean isIgnoredLine(String line) { return x; }); })); - for (var primarySp : SP0DefinitionParser.getSpeciesAliases(control)) { + for (var primarySp : GenusDefinitionParser.getSpeciesAliases(control)) { modsByRegions(mods, 2, (m, r) -> hlNPMap.get(sp0Alias, primarySp, r).ifPresent(coe -> { if (coe.getEquationIndex() == 1) { coe.modifyCoe(1, x -> x * m); @@ -251,9 +251,9 @@ boolean modIsForProgram(Map entry) { List getSpeciesByIndex(int index, Map control) { if (index == 0) { - return SP0DefinitionParser.getSpeciesAliases(control); + return GenusDefinitionParser.getSpeciesAliases(control); } - return List.of(SP0DefinitionParser.getSpeciesByIndex(index, control).getAlias()); + return List.of(GenusDefinitionParser.getSpeciesByIndex(index, control).getAlias()); } List getMods(int num, Map entry) throws ValueParseException { @@ -282,7 +282,7 @@ public String getControlKey() { @Override public void defaultModify(Map control) { - var spAliases = SP0DefinitionParser.getSpeciesAliases(control); + var spAliases = GenusDefinitionParser.getSpeciesAliases(control); var regions = Arrays.asList(Region.values()); var baModifiers = new MatrixMap2Impl(spAliases, regions); diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java new file mode 100644 index 000000000..326f15b2f --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java @@ -0,0 +1,61 @@ +package ca.bc.gov.nrs.vdyp.fip.model; + +import java.util.Map; + +import ca.bc.gov.nrs.vdyp.model.Layer; + +public class FipSpecies { + + static final String POLYGON_IDENTIFIER = "POLYGON_IDENTIFIER"; // POLYDESC + static final String LAYER = "LAYER"; // LAYER + + final String polygonIdentifier; // POLYDESC + final Layer layer; // LAYER + final String genus; // SP0 + + float percentGenus; + + Map speciesPercent; + + public FipSpecies( + String polygonIdentifier, Layer layer, String genus, Float percentGenus, Map speciesPercent + ) { + super(); + this.polygonIdentifier = polygonIdentifier; + this.layer = layer; + this.genus = genus; + + this.percentGenus = percentGenus; + + this.speciesPercent = speciesPercent; + } + + public String getPolygonIdentifier() { + return polygonIdentifier; + } + + public Layer getLayer() { + return layer; + } + + public float getPercentGenus() { + return percentGenus; + } + + public void setPercentGenus(float percentGenus) { + this.percentGenus = percentGenus; + } + + public Map getSpeciesPercent() { + return speciesPercent; + } + + public void setSpeciesPercent(Map speciesPercent) { + this.speciesPercent = speciesPercent; + } + + public String getGenus() { + return genus; + } + +} diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index cb0cfbb7e..ff4d373d4 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -30,13 +30,13 @@ import ca.bc.gov.nrs.vdyp.io.parse.ControlFileParserTest; import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParserTest; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; -import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParser; +import ca.bc.gov.nrs.vdyp.io.parse.GenusDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.SiteCurveAgeMaximumParserTest; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; import ca.bc.gov.nrs.vdyp.model.BecDefinition; import ca.bc.gov.nrs.vdyp.model.BecLookup; import ca.bc.gov.nrs.vdyp.model.Region; -import ca.bc.gov.nrs.vdyp.model.SP0Definition; +import ca.bc.gov.nrs.vdyp.model.GenusDefinition; import ca.bc.gov.nrs.vdyp.model.SiteCurve; import ca.bc.gov.nrs.vdyp.model.SiteCurveAgeMaximum; import ca.bc.gov.nrs.vdyp.model.StockingClassFactor; @@ -71,8 +71,8 @@ public void testParseSP0() throws Exception { assertThat( result, (Matcher) hasSpecificEntry( - SP0DefinitionParser.CONTROL_KEY, - allOf(instanceOf(List.class), hasItem(instanceOf(SP0Definition.class))) + GenusDefinitionParser.CONTROL_KEY, + allOf(instanceOf(List.class), hasItem(instanceOf(GenusDefinition.class))) ) ); } @@ -625,6 +625,16 @@ public void testParseV7O_FIL() throws Exception { ); } + @Test + public void testParseV7O_FIS() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, + (Matcher) hasSpecificEntry(FipSpeciesParser.CONTROL_KEY, instanceOf(StreamingParserFactory.class)) + ); + } + static InputStream addToEnd(InputStream is, String... lines) { var appendix = new ByteArrayInputStream(String.join("\r\n", lines).getBytes(StandardCharsets.US_ASCII)); var result = new SequenceInputStream(is, appendix); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java index 7317320fa..e2fcbc55d 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java @@ -19,7 +19,7 @@ import ca.bc.gov.nrs.vdyp.fip.model.FipLayer; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParserTest; -import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.GenusDefinitionParserTest; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; import ca.bc.gov.nrs.vdyp.model.Layer; @@ -61,7 +61,7 @@ public void testParseLayer() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(FipLayerParser.CONTROL_KEY, "test.dat"); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); var fileResolver = TestUtils.fileResolver( "test.dat", @@ -115,7 +115,7 @@ public void testParseTwoLayers() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(FipLayerParser.CONTROL_KEY, "test.dat"); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); var fileResolver = TestUtils.fileResolver( "test.dat", diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParserTest.java new file mode 100644 index 000000000..d9e057ed5 --- /dev/null +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParserTest.java @@ -0,0 +1,328 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertEmpty; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.assertNext; +import static ca.bc.gov.nrs.vdyp.test.VdypMatchers.hasSpecificEntry; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.aMapWithSize; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.fip.model.FipSpecies; +import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.GenusDefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.model.Layer; +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class FipSpeciesParserTest { + + @Test + public void testParseEmpty() throws Exception { + + var parser = new FipSpeciesParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipSpeciesParser.CONTROL_KEY, "test.dat"); + BecDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver("test.dat", TestUtils.makeStream(/* empty */)); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipSpeciesParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + assertEmpty(stream); + } + + @Test + public void testParseOneGenus() throws Exception { + + var parser = new FipSpeciesParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipSpeciesParser.CONTROL_KEY, "test.dat"); + GenusDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000001 00 1970 1 B 100.0B 100.0 0.0 0.0 0.0", + "01002 S000001 00 1970 Z 0.0 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipSpeciesParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var genera = assertNext(stream); + + assertThat( + genera, + containsInAnyOrder( + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("genus", is("B")), + hasProperty("percentGenus", is(100.0f)), + hasProperty("speciesPercent", allOf(aMapWithSize(1), hasSpecificEntry("B", is(100.0f)))) + ) + ) + ); + + assertEmpty(stream); + } + + @Test + public void testParseTwoGenera() throws Exception { + + var parser = new FipSpeciesParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipSpeciesParser.CONTROL_KEY, "test.dat"); + GenusDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000001 00 1970 1 B 75.0B 100.0 0.0 0.0 0.0", + "01002 S000001 00 1970 1 C 25.0C 100.0 0.0 0.0 0.0", + "01002 S000001 00 1970 Z 0.0 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipSpeciesParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var genera = assertNext(stream); + + assertThat( + genera, + containsInAnyOrder( + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("genus", is("B")), + hasProperty("percentGenus", is(75.0f)), + hasProperty("speciesPercent", allOf(aMapWithSize(1), hasSpecificEntry("B", is(100.0f)))) + ), + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("genus", is("C")), + hasProperty("percentGenus", is(25.0f)), + hasProperty("speciesPercent", allOf(aMapWithSize(1), hasSpecificEntry("C", is(100.0f)))) + ) + ) + ); + + assertEmpty(stream); + + } + + @Test + public void testParseTwoLayers() throws Exception { + + var parser = new FipSpeciesParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipSpeciesParser.CONTROL_KEY, "test.dat"); + GenusDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000001 00 1970 1 B 100.0B 100.0 0.0 0.0 0.0", + "01002 S000001 00 1970 V B 100.0B 100.0 0.0 0.0 0.0", + "01002 S000001 00 1970 Z 0.0 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipSpeciesParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var genera = assertNext(stream); + + assertThat( + genera, + containsInAnyOrder( + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("genus", is("B")), + hasProperty("percentGenus", is(100.0f)), + hasProperty("speciesPercent", allOf(aMapWithSize(1), hasSpecificEntry("B", is(100.0f)))) + ), + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.VETERAN)), hasProperty("genus", is("B")), + hasProperty("percentGenus", is(100.0f)), + hasProperty("speciesPercent", allOf(aMapWithSize(1), hasSpecificEntry("B", is(100.0f)))) + ) + ) + ); + + assertEmpty(stream); + } + + @Test + public void testParseTwoPolygons() throws Exception { + + var parser = new FipSpeciesParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipSpeciesParser.CONTROL_KEY, "test.dat"); + GenusDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000001 00 1970 1 B 100.0B 100.0 0.0 0.0 0.0", + "01002 S000001 00 1970 Z 0.0 0.0 0.0 0.0 0.0", + "01002 S000002 00 1970 1 B 100.0B 100.0 0.0 0.0 0.0", + "01002 S000002 00 1970 Z 0.0 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipSpeciesParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var genera = assertNext(stream); + + assertThat( + genera, + containsInAnyOrder( + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("genus", is("B")), + hasProperty("percentGenus", is(100.0f)), + hasProperty("speciesPercent", allOf(aMapWithSize(1), hasSpecificEntry("B", is(100.0f)))) + ) + ) + ); + + genera = assertNext(stream); + + assertThat( + genera, + containsInAnyOrder( + allOf( + hasProperty("polygonIdentifier", is("01002 S000002 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("genus", is("B")), + hasProperty("percentGenus", is(100.0f)), + hasProperty("speciesPercent", allOf(aMapWithSize(1), hasSpecificEntry("B", is(100.0f)))) + ) + ) + ); + + assertEmpty(stream); + } + + @Test + public void testParseMutipleSpecies() throws Exception { + + var parser = new FipSpeciesParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipSpeciesParser.CONTROL_KEY, "test.dat"); + GenusDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000001 00 1970 1 B 100.0B1 75.0B2 10.0B3 8.0B4 7.0", + "01002 S000001 00 1970 Z 0.0 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipSpeciesParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var genera = assertNext(stream); + + assertThat( + genera, + containsInAnyOrder( + allOf( + hasProperty("polygonIdentifier", is("01002 S000001 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("genus", is("B")), + hasProperty("percentGenus", is(100.0f)), + hasProperty( + "speciesPercent", + allOf( + aMapWithSize(4), + allOf( + hasSpecificEntry("B1", is(75.0f)), + hasSpecificEntry("B2", is(10.0f)), + hasSpecificEntry("B3", is(8.0f)), + hasSpecificEntry("B4", is(7.0f)) + ) + ) + ) + ) + ) + ); + + assertEmpty(stream); + } + +} diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index a2a0e0a5b..372beedff 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -25,7 +25,7 @@ import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.HLCoefficientParser; import ca.bc.gov.nrs.vdyp.io.parse.HLNonprimaryCoefficientParser; -import ca.bc.gov.nrs.vdyp.io.parse.SP0DefinitionParserTest; +import ca.bc.gov.nrs.vdyp.io.parse.GenusDefinitionParserTest; import ca.bc.gov.nrs.vdyp.io.parse.VeteranBQParser; import ca.bc.gov.nrs.vdyp.model.Coefficients; import ca.bc.gov.nrs.vdyp.model.MatrixMap; @@ -46,7 +46,7 @@ public void testNoFilenameForControlFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.empty()); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); var fileResolver = new FileResolver() { @@ -75,7 +75,7 @@ public void testMissingControlFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMap(controlMap); + GenusDefinitionParserTest.populateControlMap(controlMap); var fileResolver = new FileResolver() { @@ -106,7 +106,7 @@ public void testLoadEmptyFile() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -137,7 +137,7 @@ public String toString(String filename) throws IOException { } protected void modifierDefaultAsserts(Map controlMap) { - var expectedSp0Aliases = SP0DefinitionParserTest.getSpeciesAliases(); + var expectedSp0Aliases = GenusDefinitionParserTest.getSpeciesAliases(); assertThat(controlMap, (Matcher) hasSpecificEntry(ModifierParser.CONTROL_KEY, present(is("testFilename")))); @@ -182,7 +182,7 @@ public void testBaDqSpecies() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -241,7 +241,7 @@ public void testBaDqSpeciesDifferentProgram() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -277,7 +277,7 @@ public void testIgnoreAfterStop() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -313,7 +313,7 @@ public void testIgnoreCommentsAndBlanks() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -372,7 +372,7 @@ public void testBaDqAllSpecies() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -423,7 +423,7 @@ public void testVetBq() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); MatrixMap2 vetBqMap = populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -461,7 +461,7 @@ public String toString(String filename) throws IOException { private MatrixMap2 populateVetBq(Map controlMap) { MatrixMap2 vetBqMap = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + Arrays.asList(GenusDefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) ); vetBqMap.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); controlMap.put(VeteranBQParser.CONTROL_KEY, vetBqMap); @@ -474,7 +474,7 @@ public void testDecayWaste() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); populateHlP1(controlMap); populateHlP2(controlMap); @@ -534,7 +534,7 @@ public void testHL() throws Exception { Map controlMap = new HashMap<>(); controlMap.put(ModifierParser.CONTROL_KEY, Optional.of("testFilename")); - SP0DefinitionParserTest.populateControlMapReal(controlMap); + GenusDefinitionParserTest.populateControlMapReal(controlMap); populateVetBq(controlMap); var hlP1Map = populateHlP1(controlMap); var hlP2Map = populateHlP2(controlMap); @@ -609,8 +609,8 @@ public String toString(String filename) throws IOException { private MatrixMap3 populateHlNP(Map controlMap) { MatrixMap3 hlNPMap = new MatrixMap3Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + Arrays.asList(GenusDefinitionParserTest.getSpeciesAliases()), + Arrays.asList(GenusDefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) ); hlNPMap.setAll(k -> new NonprimaryHLCoefficients(Arrays.asList(1.0f, 5.0f), 1)); controlMap.put(HLNonprimaryCoefficientParser.CONTROL_KEY, hlNPMap); @@ -619,7 +619,7 @@ private MatrixMap3 populateHlN private MatrixMap2 populateHlP3(Map controlMap) { MatrixMap2 hlP3Map = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + Arrays.asList(GenusDefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) ); hlP3Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f, 13.0f), 1)); controlMap.put(HLCoefficientParser.CONTROL_KEY_P3, hlP3Map); @@ -628,7 +628,7 @@ private MatrixMap2 populateHlP3(Map populateHlP2(Map controlMap) { MatrixMap2 hlP2Map = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + Arrays.asList(GenusDefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) ); hlP2Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f), 1)); controlMap.put(HLCoefficientParser.CONTROL_KEY_P2, hlP2Map); @@ -637,7 +637,7 @@ private MatrixMap2 populateHlP2(Map populateHlP1(Map controlMap) { MatrixMap2 hlP1Map = new MatrixMap2Impl( - Arrays.asList(SP0DefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) + Arrays.asList(GenusDefinitionParserTest.getSpeciesAliases()), Arrays.asList(Region.values()) ); hlP1Map.setAll(k -> new Coefficients(Arrays.asList(1.0f, 5.0f, 7.0f), 1)); controlMap.put(HLCoefficientParser.CONTROL_KEY_P1, hlP1Map); From 804bf60f4eb2d40f985a83aca205224c7bed0062 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 11 Jul 2023 11:45:15 -0700 Subject: [PATCH 76/98] Ignore layers with height or crown closure <=0 --- .../bc/gov/nrs/vdyp/fip/FipLayerParser.java | 7 +- .../gov/nrs/vdyp/fip/FipLayerParserTest.java | 110 ++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java index 969fc469f..493050c56 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParser.java @@ -127,7 +127,12 @@ protected ValueOrMarker, EndOfRecord> convert(Map, EndOfRecord> nextChild) { - return nextChild.getValue().map(Optional::isEmpty).orElse(false); + return nextChild.getValue().map(x -> x.map(layer -> { + // TODO log this + // If the layer is present but has height or closure that's not positive, ignore + return layer.getHeight() <= 0f || layer.getCrownClosure() <= 0f; + }).orElse(true)) // If the layer is not present (Unknown layer type) ignore + .orElse(false); // If it's a marker, let it through so the stop method can see it. } @Override diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java index e2fcbc55d..15fdc42bb 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipLayerParserTest.java @@ -179,4 +179,114 @@ public void testParseTwoLayers() throws Exception { assertEmpty(stream); } + @Test + public void testIgnoreLayerIfHeightZero() throws Exception { + + var parser = new FipLayerParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipLayerParser.CONTROL_KEY, "test.dat"); + GenusDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000004 00 1970 V 195 45.2 22.3 0.0 B B 9.4 2 8", + "01002 S000004 00 1970 1 85 42.3 31.9 82.8 H H 4.9 0 34", + "01002 S000004 00 1970 Z 85 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipLayerParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var layers = assertNext(stream); + + assertThat(layers, aMapWithSize(1)); + + assertThat( + layers, + hasSpecificEntry( + Layer.PRIMARY, + allOf( + hasProperty("polygonIdentifier", is("01002 S000004 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("ageTotal", is(85f)), + hasProperty("height", is(42.3f)), hasProperty("siteIndex", is(31.9f)), + hasProperty("crownClosure", is(82.8f)), hasProperty("siteSp0", is("H")), + hasProperty("siteSp64", is("H")), hasProperty("yearsToBreastHeight", is(4.9f)), + hasProperty("stockingClass", present(is("0"))), + hasProperty("inventoryTypeGroup", notPresent()), + hasProperty("breastHeightAge", notPresent()), + hasProperty("siteCurveNumber", present(is(34))) + ) + ) + ); + + assertEmpty(stream); + } + + @Test + public void testIgnoreLayerIfCrownClosureZero() throws Exception { + + var parser = new FipLayerParser(); + + Map controlMap = new HashMap<>(); + + controlMap.put(FipLayerParser.CONTROL_KEY, "test.dat"); + GenusDefinitionParserTest.populateControlMapReal(controlMap); + + var fileResolver = TestUtils.fileResolver( + "test.dat", + TestUtils.makeStream( + "01002 S000004 00 1970 V 195 0.0 22.3 4.0 B B 9.4 2 8", + "01002 S000004 00 1970 1 85 42.3 31.9 82.8 H H 4.9 0 34", + "01002 S000004 00 1970 Z 85 0.0 0.0 0.0 0.0" + ) + ); + + parser.modify(controlMap, fileResolver); + + var parserFactory = controlMap.get(FipLayerParser.CONTROL_KEY); + + assertThat(parserFactory, instanceOf(StreamingParserFactory.class)); + + @SuppressWarnings("unchecked") + var stream = ((StreamingParserFactory>) parserFactory).get(); + + assertThat(stream, instanceOf(StreamingParser.class)); + + var layers = assertNext(stream); + + assertThat(layers, aMapWithSize(1)); + + assertThat( + layers, + hasSpecificEntry( + Layer.PRIMARY, + allOf( + hasProperty("polygonIdentifier", is("01002 S000004 00 1970")), + hasProperty("layer", is(Layer.PRIMARY)), hasProperty("ageTotal", is(85f)), + hasProperty("height", is(42.3f)), hasProperty("siteIndex", is(31.9f)), + hasProperty("crownClosure", is(82.8f)), hasProperty("siteSp0", is("H")), + hasProperty("siteSp64", is("H")), hasProperty("yearsToBreastHeight", is(4.9f)), + hasProperty("stockingClass", present(is("0"))), + hasProperty("inventoryTypeGroup", notPresent()), + hasProperty("breastHeightAge", notPresent()), + hasProperty("siteCurveNumber", present(is(34))) + ) + ) + ); + + assertEmpty(stream); + } + } From 0faa7ef3acc31311abb64bbeb058eca81871e84a Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 10 Jul 2023 17:07:39 -0700 Subject: [PATCH 77/98] Processing FIPStart data --- pom.xml | 15 +- vdyp-core/pom.xml | 9 + .../nrs/vdyp/io/FileSystemFileResolver.java | 17 ++ vdyp-fip/pom.xml | 9 + .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 2 +- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 206 +++++++++++++++++ .../gov/nrs/vdyp/fip/ProcessingException.java | 33 +++ .../bc/gov/nrs/vdyp/fip/model/FipLayer.java | 32 ++- .../bc/gov/nrs/vdyp/fip/model/FipPolygon.java | 14 ++ .../bc/gov/nrs/vdyp/fip/model/FipSpecies.java | 2 +- .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 208 ++++++++++++++++++ 11 files changed, 533 insertions(+), 14 deletions(-) create mode 100644 vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileSystemFileResolver.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java create mode 100644 vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ProcessingException.java create mode 100644 vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java diff --git a/pom.xml b/pom.xml index b01aec260..57a42124c 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ vdyp-fip vdyp-buildtools - + @@ -34,7 +34,18 @@ jsr305 3.0.2 - + + + org.slf4j + slf4j-api + 2.0.7 + + + org.slf4j + slf4j-jdk14 + 2.0.7 + + org.junit.jupiter junit-jupiter-engine diff --git a/vdyp-core/pom.xml b/vdyp-core/pom.xml index 148b0a3f6..78c4838ff 100644 --- a/vdyp-core/pom.xml +++ b/vdyp-core/pom.xml @@ -20,6 +20,15 @@ jsr305 + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-jdk14 + + org.junit.jupiter junit-jupiter-api diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileSystemFileResolver.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileSystemFileResolver.java new file mode 100644 index 000000000..0c5b99c01 --- /dev/null +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/FileSystemFileResolver.java @@ -0,0 +1,17 @@ +package ca.bc.gov.nrs.vdyp.io; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class FileSystemFileResolver implements FileResolver { + @Override + public InputStream resolve(String filename) throws IOException { + return new FileInputStream(filename); + } + + @Override + public String toString(String filename) throws IOException { + return String.format("file:%s", filename); + } +} \ No newline at end of file diff --git a/vdyp-fip/pom.xml b/vdyp-fip/pom.xml index 27b3d89dc..2fc55b2e6 100644 --- a/vdyp-fip/pom.xml +++ b/vdyp-fip/pom.xml @@ -29,6 +29,15 @@ test + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-jdk14 + + org.junit.jupiter junit-jupiter-api diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index 2e4d8925b..f55b35b74 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -388,7 +388,7 @@ public String toString(String filename) throws IOException { } } - Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { + Map parse(InputStream is, FileResolver fileResolver) throws IOException, ResourceParseException { var map = controlParser.parse(is, Collections.emptyMap()); applyModifiers(map, BASIC_DEFINITIONS, fileResolver); diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java new file mode 100644 index 000000000..119c5f495 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -0,0 +1,206 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ca.bc.gov.nrs.vdyp.fip.model.FipLayer; +import ca.bc.gov.nrs.vdyp.fip.model.FipMode; +import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; +import ca.bc.gov.nrs.vdyp.fip.model.FipSpecies; +import ca.bc.gov.nrs.vdyp.io.FileResolver; +import ca.bc.gov.nrs.vdyp.io.FileSystemFileResolver; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.model.Layer; + +public class FipStart { + + static private final Logger log = LoggerFactory.getLogger(FipStart.class); + + public static final int CONFIG_LOAD_ERROR = 1; // TODO check what Fortran FIPStart would exit with. + public static final int PROCESSING_ERROR = 2; // TODO check what Fortran FIPStart would exit with. + + private Map controlMap = Collections.emptyMap(); + + /** + * Initialize FipStart + * + * @param resolver + * @param controlFilePath + * @throws IOException + * @throws ResourceParseException + */ + void init(FileResolver resolver, String controlFilePath) throws IOException, ResourceParseException { + + // Load the control map + + var parser = new FipControlParser(); + try (var is = resolver.resolve(controlFilePath)) { + setControlMap(parser.parse(is, resolver)); + } + + } + + void setControlMap(Map controlMap) { + this.controlMap = controlMap; + } + + public static void main(final String... args) { + + var app = new FipStart(); + + var resolver = new FileSystemFileResolver(); + + var controlFileName = args[0]; + + try { + app.init(resolver, controlFileName); + } catch (Exception ex) { + log.error("Error during initialization", ex); + System.exit(CONFIG_LOAD_ERROR); + } + + try { + app.process(); + } catch (Exception ex) { + log.error("Error during processing", ex); + System.exit(PROCESSING_ERROR); + } + } + + @SuppressWarnings("unchecked") + private StreamingParser getStreamingParser(String key) throws ProcessingException { + try { + var factory = (StreamingParserFactory) controlMap.get(key); + if (factory == null) { + throw new ProcessingException(String.format("Data file %s not specified in control map.", key)); + } + return factory.get(); + } catch (IOException ex) { + throw new ProcessingException("Error while opening data file.", ex); + } + } + + void process() throws ProcessingException { + try ( + var polyStream = this.getStreamingParser(FipPolygonParser.CONTROL_KEY); + var layerStream = this.>getStreamingParser(FipLayerParser.CONTROL_KEY); + var speciesStream = this.>getStreamingParser(FipSpeciesParser.CONTROL_KEY); + ) { + + int polygonsRead = 0; + int polygonsWritten = 0; + + while (polyStream.hasNext()) { + + // FIP_GET + + log.info("Getting polygon {}", polygonsRead + 1); + var polygon = getPolygon(polyStream, layerStream, speciesStream); + + log.info("Read polygon {}, preparing to process", polygon.getPolygonIdentifier()); + + // if (MODE .eq. -1) go to 100 + + final var mode = polygon.getModeFip().orElse(FipMode.DONT_PROCESS); + + if (mode == FipMode.DONT_PROCESS) { + log.info("Skipping polygon with mode {}", mode); + continue; + } + + // IP_IN = IP_IN+1 + // if (IP_IN .gt. MAXPOLY) go to 200 + + polygonsRead++; // Don't count polygons we aren't processing. This was the behavior in VDYP7 + + // IPASS = 1 + // CALL FIP_CHK( IPASS, IER) + // if (ier .gt. 0) go to 1000 + // + // if (IPASS .le. 0) GO TO 120 + + log.info("Checking validity of polygon {}:{}", polygonsRead, polygon.getPolygonIdentifier()); + checkPolygon(polygon); + + // CALL FIPCALCV( BAV, IER) + // CALL FIPCALC1( BAV, BA_TOTL1, IER) + + } + } catch (IOException | ResourceParseException ex) { + throw new ProcessingException("Error while reading or writing data.", ex); + } + } + + private FipPolygon getPolygon( + StreamingParser polyStream, StreamingParser> layerStream, + StreamingParser> speciesStream + ) throws ProcessingException, IOException, ResourceParseException { + + log.trace("Getting polygon"); + var polygon = polyStream.next(); + + log.trace("Getting layers for polygon {}", polygon.getPolygonIdentifier()); + Map layers; + try { + layers = layerStream.next(); + } catch (IllegalStateException ex) { // TODO, make a more specific exception for this + throw new ProcessingException("Layers file has fewer records than polygon file.", ex); + } + + log.trace("Getting species for polygon {}", polygon.getPolygonIdentifier()); + Collection species; + try { + species = speciesStream.next(); + } catch (IllegalStateException ex) { // TODO, make a more specific exception for this + throw new ProcessingException("Species file has fewer records than polygon file.", ex); + } + + // Validate that layers belong to the correct polygon + for (var layer : layers.values()) { + if (!layer.getPolygonIdentifier().equals(polygon.getPolygonIdentifier())) { + throw new ProcessingException( + String.format( + "Record in layer file contains layer for polygon %s when expecting one for %s.", + layer.getPolygonIdentifier(), polygon.getPolygonIdentifier() + ) + ); + } + layer.setSpecies(new HashMap<>()); + } + + for (var spec : species) { + var layer = layers.get(spec.getLayer()); + // Validate that species belong to the correct polygon + if (!spec.getPolygonIdentifier().equals(polygon.getPolygonIdentifier())) { + throw new ProcessingException( + String.format( + "Record in species file contains species for polygon %s when expecting one for %s.", + layer.getPolygonIdentifier(), polygon.getPolygonIdentifier() + ) + ); + } + if (Objects.isNull(layer)) { + throw new ProcessingException("Species entry references layer %s of polygon %s but it is not present."); + } + layer.getSpecies().put(spec.getGenus(), spec); + } + + polygon.setLayers(layers); + + return polygon; + } + + private void checkPolygon(FipPolygon polygon) throws ProcessingException { + // TODO Auto-generated method stub + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ProcessingException.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ProcessingException.java new file mode 100644 index 000000000..98fbffc97 --- /dev/null +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/ProcessingException.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.vdyp.fip; + +/** + * A problem occurred while VDYP was processing data + * + * @author Kevin Smith, Vivid Solutions + * + */ +public class ProcessingException extends Exception { + + private static final long serialVersionUID = 1L; + + public ProcessingException() { + super(); + } + + public ProcessingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public ProcessingException(String message, Throwable cause) { + super(message, cause); + } + + public ProcessingException(String message) { + super(message); + } + + public ProcessingException(Throwable cause) { + super(cause); + } + +} diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java index 25ac77028..d828616d5 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java @@ -1,5 +1,7 @@ package ca.bc.gov.nrs.vdyp.fip.model; +import java.util.Collections; +import java.util.Map; import java.util.Optional; import ca.bc.gov.nrs.vdyp.model.Layer; @@ -24,15 +26,17 @@ public class FipLayer { float height; float siteIndex; float crownClosure; - String siteSp0; - String siteSp64; + String siteGenus; + String siteSpecies; float yearsToBreastHeight; Optional inventoryTypeGroup; Optional breastHeightAge; + Map species = Collections.emptyMap(); + public FipLayer( String polygonIdentifier, Layer layer, float ageTotal, float height, float siteIndex, float crownClosure, - String siteSp0, String siteSp64, float yearsToBreastHeight, Optional inventoryTypeGroup, + String siteGenus, String siteSpecies, float yearsToBreastHeight, Optional inventoryTypeGroup, Optional breastHeightAge ) { super(); @@ -42,8 +46,8 @@ public FipLayer( this.height = height; this.siteIndex = siteIndex; this.crownClosure = crownClosure; - this.siteSp0 = siteSp0; - this.siteSp64 = siteSp64; + this.siteGenus = siteGenus; + this.siteSpecies = siteSpecies; this.yearsToBreastHeight = yearsToBreastHeight; this.inventoryTypeGroup = inventoryTypeGroup; this.breastHeightAge = breastHeightAge; @@ -74,11 +78,11 @@ public float getCrownClosure() { } public String getSiteSp0() { - return siteSp0; + return siteGenus; } public String getSiteSp64() { - return siteSp64; + return siteSpecies; } public float getYearsToBreastHeight() { @@ -113,12 +117,12 @@ public void setCrownClosure(float crownClosure) { this.crownClosure = crownClosure; } - public void setSireSp0(String sireSp0) { - this.siteSp0 = sireSp0; + public void setSiteSp0(String sireSp0) { + this.siteGenus = sireSp0; } public void setSiteSp64(String siteSp64) { - this.siteSp64 = siteSp64; + this.siteSpecies = siteSp64; } public void setYearsToBreastHeight(float yearsToBreastHeight) { @@ -133,4 +137,12 @@ public void setBreastHeightAge(Optional breastHeightAge) { this.breastHeightAge = breastHeightAge; } + public Map getSpecies() { + return species; + } + + public void setSpecies(Map species) { + this.species = species; + } + } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java index 362a89b13..98aba335e 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java @@ -1,7 +1,11 @@ package ca.bc.gov.nrs.vdyp.fip.model; +import java.util.Collections; +import java.util.Map; import java.util.Optional; +import ca.bc.gov.nrs.vdyp.model.Layer; + public class FipPolygon { String polygonIdentifier; // POLYDESC @@ -12,6 +16,8 @@ public class FipPolygon { Optional nonproductiveDescription; // NPDESC float yieldFactor; // YLDFACT + Map layers = Collections.emptyMap(); + public FipPolygon( String polygonIdentifier, String fiz, String becIdentifier, Optional percentAvailable, Optional modeFip, Optional nonproductiveDescription, float yieldFactor @@ -82,4 +88,12 @@ public void setYieldFactor(float yieldFactor) { this.yieldFactor = yieldFactor; } + public Map getLayers() { + return layers; + } + + public void setLayers(Map layers) { + this.layers = layers; + } + } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java index 326f15b2f..0f777cd38 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java @@ -18,7 +18,7 @@ public class FipSpecies { Map speciesPercent; public FipSpecies( - String polygonIdentifier, Layer layer, String genus, Float percentGenus, Map speciesPercent + String polygonIdentifier, Layer layer, String genus, float percentGenus, Map speciesPercent ) { super(); this.polygonIdentifier = polygonIdentifier; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java new file mode 100644 index 000000000..ad81f4d01 --- /dev/null +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -0,0 +1,208 @@ +package ca.bc.gov.nrs.vdyp.fip; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.easymock.EasyMock; +import org.easymock.IMocksControl; +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.fip.model.FipLayer; +import ca.bc.gov.nrs.vdyp.fip.model.FipMode; +import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; +import ca.bc.gov.nrs.vdyp.fip.model.FipSpecies; +import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; +import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; +import ca.bc.gov.nrs.vdyp.model.Layer; + +public class FipStartTest { + + @Test + public void testProcessEmpty() throws Exception { + + var app = new FipStart(); + + var controlMap = new HashMap(); + + var control = EasyMock.createControl(); + + StreamingParser polygonStream = mockStream( + control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" + ); + StreamingParser> layerStream = mockStream( + control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" + ); + StreamingParser> speciesStream = mockStream( + control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" + ); + + expectAllEmpty(polygonStream, layerStream, speciesStream); + + expectAllClosed(polygonStream, layerStream, speciesStream); + + app.setControlMap(controlMap); + + control.replay(); + + app.process(); + + control.verify(); + } + + @Test + public void testProcessSimple() throws Exception { + + var app = new FipStart(); + + var controlMap = new HashMap(); + + var control = EasyMock.createControl(); + + StreamingParser polygonStream = mockStream( + control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" + ); + StreamingParser> layerStream = mockStream( + control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" + ); + StreamingParser> speciesStream = mockStream( + control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" + ); + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + // One polygon with one layer with one species entry + + mockWith( + polygonStream, + new FipPolygon( + polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), + java.util.Optional.empty(), 1.0f + ) + ); + mockWith( + layerStream, + Collections.singletonMap( + layer, + new FipLayer( + polygonId, layer, 0, 0, 0, 0, polygonId, polygonId, 0, java.util.Optional.empty(), + java.util.Optional.empty() + ) + ) + ); + mockWith( + speciesStream, + Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) + ); + + expectAllClosed(polygonStream, layerStream, speciesStream); + + app.setControlMap(controlMap); + + control.replay(); + + app.process(); + + control.verify(); + } + + @Test + public void testPolygonWithNoLayers() throws Exception { + + var app = new FipStart(); + + var controlMap = new HashMap(); + + var control = EasyMock.createControl(); + + StreamingParser polygonStream = mockStream( + control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" + ); + StreamingParser> layerStream = mockStream( + control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" + ); + StreamingParser> speciesStream = mockStream( + control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" + ); + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + // One polygon with one layer with one species entry + + mockWith( + polygonStream, + new FipPolygon( + polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), + java.util.Optional.empty(), 1.0f + ) + ); + EasyMock.expect(layerStream.next()).andThrow(new IllegalStateException()); + + expectAllClosed(polygonStream, layerStream, speciesStream); + + app.setControlMap(controlMap); + + control.replay(); + + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat(ex, hasProperty("message", is("Layers file has fewer records than polygon file."))); + + control.verify(); + } + + private static StreamingParser + mockStream(IMocksControl control, Map controlMap, String key, String name) + throws IOException { + StreamingParserFactory streamFactory = control.mock(name + "Factory", StreamingParserFactory.class); + StreamingParser stream = control.mock(name, StreamingParser.class); + + EasyMock.expect(streamFactory.get()).andReturn(stream); + + controlMap.put(key, streamFactory); + return stream; + } + + private static void expectAllClosed(AutoCloseable... toClose) throws Exception { + for (var x : toClose) { + x.close(); + EasyMock.expectLastCall(); + } + } + + private static void expectAllEmpty(StreamingParser... toBeEmpty) throws Exception { + for (var x : toBeEmpty) { + EasyMock.expect(x.hasNext()).andStubReturn(false); + } + } + + private static void mockWith(StreamingParser stream, List results) + throws IOException, ResourceParseException { + var it = results.iterator(); + EasyMock.expect(stream.hasNext()).andStubAnswer(it::hasNext); + EasyMock.expect(stream.next()).andAnswer(it::next).times(results.size()); + } + + @SafeVarargs + private static void mockWith(StreamingParser stream, T... results) + throws IOException, ResourceParseException { + mockWith(stream, Arrays.asList(results)); + } + + private String polygonId(String prefix, int year) { + return String.format("%-23s%4d", prefix, year); + } +} From c5e1f50a070f4f0439190acee436d9eb156cd42e Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 11 Jul 2023 12:43:12 -0700 Subject: [PATCH 78/98] Validate that polygons always have a primary layer --- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 14 +++- .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 70 ++++++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index 119c5f495..1c31ea542 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -120,7 +120,8 @@ void process() throws ProcessingException { // IP_IN = IP_IN+1 // if (IP_IN .gt. MAXPOLY) go to 200 - polygonsRead++; // Don't count polygons we aren't processing. This was the behavior in VDYP7 + polygonsRead++; // Don't count polygons we aren't processing due to mode. This was the behavior + // in VDYP7 // IPASS = 1 // CALL FIP_CHK( IPASS, IER) @@ -200,7 +201,16 @@ private FipPolygon getPolygon( } private void checkPolygon(FipPolygon polygon) throws ProcessingException { - // TODO Auto-generated method stub + + if (!polygon.getLayers().containsKey(Layer.PRIMARY)) { + throw new ProcessingException( + String.format( + "Polygon %s has no %s layer, or that layer has non-positive height or crown closure.", + polygon.getPolygonIdentifier(), Layer.PRIMARY + ) + ); + } + } } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index ad81f4d01..aaf8d0e44 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -97,7 +97,7 @@ public void testProcessSimple() throws Exception { Collections.singletonMap( layer, new FipLayer( - polygonId, layer, 0, 0, 0, 0, polygonId, polygonId, 0, java.util.Optional.empty(), + polygonId, layer, 0, 20f, 0.9f, 0, polygonId, polygonId, 0, java.util.Optional.empty(), java.util.Optional.empty() ) ) @@ -164,6 +164,74 @@ public void testPolygonWithNoLayers() throws Exception { control.verify(); } + @Test + public void testPolygonWithNoPrimaryLayer() throws Exception { + + var app = new FipStart(); + + var controlMap = new HashMap(); + + var control = EasyMock.createControl(); + + StreamingParser polygonStream = mockStream( + control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" + ); + StreamingParser> layerStream = mockStream( + control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" + ); + StreamingParser> speciesStream = mockStream( + control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" + ); + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.VETERAN; + + // One polygon with one layer with one species entry, and type is VETERAN + + mockWith( + polygonStream, + new FipPolygon( + polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), + java.util.Optional.empty(), 1.0f + ) + ); + mockWith( + layerStream, + Collections.singletonMap( + layer, + new FipLayer( + polygonId, layer, 0, 20f, 0.9f, 0, polygonId, polygonId, 0, java.util.Optional.empty(), + java.util.Optional.empty() + ) + ) + ); + mockWith( + speciesStream, + Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) + ); + + expectAllClosed(polygonStream, layerStream, speciesStream); + + app.setControlMap(controlMap); + + control.replay(); + + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + " has no " + Layer.PRIMARY + + " layer, or that layer has non-positive height or crown closure." + ) + ) + ); + + control.verify(); + } + private static StreamingParser mockStream(IMocksControl control, Map controlMap, String key, String name) throws IOException { From b08ac25ae09a0cb4cffce3a10f83d6d417165b08 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 11 Jul 2023 14:47:07 -0700 Subject: [PATCH 79/98] Reduce unit test boilerplate --- .../io/parse/GroupingStreamingParser.java | 3 +- .../bc/gov/nrs/vdyp/io/parse/LineParser.java | 3 +- .../vdyp/io/parse/MockStreamingParser.java | 101 ++++++ .../ca/bc/gov/nrs/vdyp/test/VdypMatchers.java | 3 +- .../bc/gov/nrs/vdyp/fip/FipSpeciesParser.java | 1 - .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 5 +- .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 335 +++++++++--------- 7 files changed, 268 insertions(+), 183 deletions(-) create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/MockStreamingParser.java diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java index 817edc9ee..837f1e03a 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.NoSuchElementException; import java.util.Optional; /** @@ -52,7 +53,7 @@ public GroupingStreamingParser(StreamingParser delegate) { public T next() throws IOException, ResourceParseException { doGetNext(); - var children = next.orElseThrow(() -> new IllegalStateException("Requested next group when there is none")); + var children = next.orElseThrow(() -> new NoSuchElementException("Requested next group when there is none")); next = Optional.empty(); return convert(children); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index d872c6d8f..91deef1d1 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; @@ -304,7 +305,7 @@ public Map next() throws IOException, ResourceParseLineException } try { var line = nextLine.get() - .orElseThrow(() -> new IllegalStateException("Tried to get next entry when none exists")); + .orElseThrow(() -> new NoSuchElementException("Tried to get next entry when none exists")); var segments = segmentize(line); var entry = parse(segments, control); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/MockStreamingParser.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/MockStreamingParser.java new file mode 100644 index 000000000..66e7e997a --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/MockStreamingParser.java @@ -0,0 +1,101 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class MockStreamingParser implements StreamingParser { + + boolean closed = false; + String name; + + Queue remaining = new LinkedList<>(); + State current = null; + + private class State { + + public final boolean hasNext; + public final boolean isException; + public final T next; + public final Throwable toThrow; + + public State(T next) { + this.next = next; + this.hasNext = true; + this.isException = false; + this.toThrow = null; + } + + public State(Throwable ex, boolean hasNext) { + this.next = null; + this.hasNext = hasNext; + this.isException = true; + this.toThrow = ex; + } + + public T get() throws IOException, ResourceParseException { + if (isException) { + if (toThrow instanceof IOException) { + throw (IOException) toThrow; + } else if (toThrow instanceof ResourceParseException) { + throw (ResourceParseException) toThrow; + } else if (toThrow instanceof RuntimeException) { + throw (RuntimeException) toThrow; + } else if (toThrow instanceof Error) { + throw (Error) toThrow; + } else { + fail("MockStreamingParser can not throw " + toThrow); + } + } + return next; + } + + } + + @Override + public T next() throws IOException, ResourceParseException { + var current = remaining.remove(); + return current.get(); + } + + @Override + public boolean hasNext() throws IOException, ResourceParseException { + var current = remaining.peek(); + return current != null && current.hasNext; + } + + @Override + public void close() throws IOException { + closed = true; + } + + public void expectClosed() { + assertTrue(closed, name + " was not closed"); + }; + + public void expectAllRead() { + assertTrue(remaining.isEmpty(), name + " has " + remaining.size() + " states remaining"); + }; + + public void addValue(T value) { + remaining.add(new State(value)); + } + + public void addValues(@SuppressWarnings("unchecked") T... values) { + for (var value : values) + remaining.add(new State(value)); + } + + public void addValues(List values) { + for (var value : values) + remaining.add(new State(value)); + } + + public void addThrow(Throwable ex, boolean hasNext) { + remaining.add(new State(ex, hasNext)); + } +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java index aeb93895d..d73b2ae23 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/test/VdypMatchers.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -448,6 +449,6 @@ public static T assertNext(StreamingParser stream) throws IOException, Re public static void assertEmpty(StreamingParser stream) throws IOException, ResourceParseException { var hasNext = assertDoesNotThrow(() -> stream.hasNext()); assertThat(hasNext, is(false)); - assertThrows(IllegalStateException.class, () -> stream.next()); + assertThrows(NoSuchElementException.class, () -> stream.next()); } } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java index bb3916b62..3e1d73efb 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java @@ -20,7 +20,6 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseValidException; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; -import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.model.Layer; diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index 1c31ea542..a6e7a11c4 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import org.slf4j.Logger; @@ -153,7 +154,7 @@ private FipPolygon getPolygon( Map layers; try { layers = layerStream.next(); - } catch (IllegalStateException ex) { // TODO, make a more specific exception for this + } catch (NoSuchElementException ex) { throw new ProcessingException("Layers file has fewer records than polygon file.", ex); } @@ -161,7 +162,7 @@ private FipPolygon getPolygon( Collection species; try { species = speciesStream.next(); - } catch (IllegalStateException ex) { // TODO, make a more specific exception for this + } catch (NoSuchElementException ex) { throw new ProcessingException("Species file has fewer records than polygon file.", ex); } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index aaf8d0e44..0eac3ef96 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; @@ -22,8 +23,8 @@ import ca.bc.gov.nrs.vdyp.fip.model.FipMode; import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; import ca.bc.gov.nrs.vdyp.fip.model.FipSpecies; +import ca.bc.gov.nrs.vdyp.io.parse.MockStreamingParser; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; -import ca.bc.gov.nrs.vdyp.io.parse.StreamingParser; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; import ca.bc.gov.nrs.vdyp.model.Layer; @@ -32,211 +33,157 @@ public class FipStartTest { @Test public void testProcessEmpty() throws Exception { - var app = new FipStart(); - - var controlMap = new HashMap(); - - var control = EasyMock.createControl(); - - StreamingParser polygonStream = mockStream( - control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" - ); - StreamingParser> layerStream = mockStream( - control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" - ); - StreamingParser> speciesStream = mockStream( - control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" - ); - - expectAllEmpty(polygonStream, layerStream, speciesStream); - - expectAllClosed(polygonStream, layerStream, speciesStream); - - app.setControlMap(controlMap); - - control.replay(); - - app.process(); - - control.verify(); + testWith(Arrays.asList(), Arrays.asList(), Arrays.asList(), app -> { + assertDoesNotThrow(app::process); + }); } @Test public void testProcessSimple() throws Exception { - var app = new FipStart(); - - var controlMap = new HashMap(); - - var control = EasyMock.createControl(); - - StreamingParser polygonStream = mockStream( - control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" - ); - StreamingParser> layerStream = mockStream( - control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" - ); - StreamingParser> speciesStream = mockStream( - control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" - ); - var polygonId = polygonId("Test Polygon", 2023); var layer = Layer.PRIMARY; - // One polygon with one layer with one species entry + // One polygon with one primary layer with one species entry - mockWith( - polygonStream, - new FipPolygon( - polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), - java.util.Optional.empty(), 1.0f - ) - ); - mockWith( - layerStream, - Collections.singletonMap( - layer, - new FipLayer( - polygonId, layer, 0, 20f, 0.9f, 0, polygonId, polygonId, 0, java.util.Optional.empty(), - java.util.Optional.empty() + testWith( + Arrays.asList( + new FipPolygon( + polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), + java.util.Optional.empty(), 1.0f ) - ) - ); - mockWith( - speciesStream, - Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) + ), + Arrays.asList( + Collections.singletonMap( + layer, + new FipLayer( + polygonId, layer, 0, 20f, 0.9f, 0, "B", "B", 0, java.util.Optional.empty(), + java.util.Optional.empty() + ) + ) + ), + Arrays.asList( + Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) + ), app -> { + assertDoesNotThrow(app::process); + } ); - expectAllClosed(polygonStream, layerStream, speciesStream); - - app.setControlMap(controlMap); - - control.replay(); - - app.process(); - - control.verify(); } @Test - public void testPolygonWithNoLayers() throws Exception { - - var app = new FipStart(); - - var controlMap = new HashMap(); - - var control = EasyMock.createControl(); - - StreamingParser polygonStream = mockStream( - control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" - ); - StreamingParser> layerStream = mockStream( - control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" - ); - StreamingParser> speciesStream = mockStream( - control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" - ); + public void testPolygonWithNoLayersRecord() throws Exception { var polygonId = polygonId("Test Polygon", 2023); - var layer = Layer.PRIMARY; - - // One polygon with one layer with one species entry - - mockWith( - polygonStream, - new FipPolygon( - polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), - java.util.Optional.empty(), 1.0f - ) - ); - EasyMock.expect(layerStream.next()).andThrow(new IllegalStateException()); - - expectAllClosed(polygonStream, layerStream, speciesStream); - app.setControlMap(controlMap); - - control.replay(); - - var ex = assertThrows(ProcessingException.class, () -> app.process()); + testWith( + Arrays.asList( + new FipPolygon( + polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), + java.util.Optional.empty(), 1.0f + ) + ), Collections.emptyList(), Collections.emptyList(), app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); - assertThat(ex, hasProperty("message", is("Layers file has fewer records than polygon file."))); + assertThat(ex, hasProperty("message", is("Layers file has fewer records than polygon file."))); - control.verify(); + } + ); } @Test public void testPolygonWithNoPrimaryLayer() throws Exception { - var app = new FipStart(); - - var controlMap = new HashMap(); - - var control = EasyMock.createControl(); - - StreamingParser polygonStream = mockStream( - control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" - ); - StreamingParser> layerStream = mockStream( - control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" - ); - StreamingParser> speciesStream = mockStream( - control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" - ); - var polygonId = polygonId("Test Polygon", 2023); var layer = Layer.VETERAN; // One polygon with one layer with one species entry, and type is VETERAN - - mockWith( - polygonStream, - new FipPolygon( - polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), - java.util.Optional.empty(), 1.0f - ) - ); - mockWith( - layerStream, - Collections.singletonMap( - layer, - new FipLayer( - polygonId, layer, 0, 20f, 0.9f, 0, polygonId, polygonId, 0, java.util.Optional.empty(), - java.util.Optional.empty() + testWith( + Arrays.asList( + new FipPolygon( + polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), + java.util.Optional.empty(), 1.0f ) - ) - ); - mockWith( - speciesStream, - Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) + ), + Arrays.asList( + Collections.singletonMap( + layer, + new FipLayer( + polygonId, layer, 0, 20f, 0.9f, 0, "B", "B", 0, java.util.Optional.empty(), + java.util.Optional.empty() + ) + ) + ), + Arrays.asList( + Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) + ), app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + " has no " + Layer.PRIMARY + + " layer, or that layer has non-positive height or crown closure." + ) + ) + ); + + } ); - expectAllClosed(polygonStream, layerStream, speciesStream); + } - app.setControlMap(controlMap); + @Test + public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Exception { - control.replay(); + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.VETERAN; - var ex = assertThrows(ProcessingException.class, () -> app.process()); + // One polygon with one layer with one species entry, and type is VETERAN - assertThat( - ex, - hasProperty( - "message", - is( - "Polygon " + polygonId + " has no " + Layer.PRIMARY - + " layer, or that layer has non-positive height or crown closure." + testWith( + Arrays.asList( + new FipPolygon( + polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), + java.util.Optional.empty(), 1.0f + ) + ), + Arrays.asList( + Collections.singletonMap( + layer, + new FipLayer( + polygonId, layer, 0, 20f, 0.9f, 5.0f, "B", "B", 0, java.util.Optional.empty(), + java.util.Optional.empty() + ) ) - ) + ), + Arrays.asList( + Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) + ), app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + " has no " + Layer.PRIMARY + + " layer, or that layer has non-positive height or crown closure." + ) + ) + ); + } ); - control.verify(); } - private static StreamingParser + private static MockStreamingParser mockStream(IMocksControl control, Map controlMap, String key, String name) throws IOException { StreamingParserFactory streamFactory = control.mock(name + "Factory", StreamingParserFactory.class); - StreamingParser stream = control.mock(name, StreamingParser.class); + MockStreamingParser stream = new MockStreamingParser<>(); EasyMock.expect(streamFactory.get()).andReturn(stream); @@ -244,33 +191,67 @@ public void testPolygonWithNoPrimaryLayer() throws Exception { return stream; } - private static void expectAllClosed(AutoCloseable... toClose) throws Exception { + private static void expectAllClosed(MockStreamingParser... toClose) throws Exception { for (var x : toClose) { - x.close(); - EasyMock.expectLastCall(); - } - } - - private static void expectAllEmpty(StreamingParser... toBeEmpty) throws Exception { - for (var x : toBeEmpty) { - EasyMock.expect(x.hasNext()).andStubReturn(false); + x.expectClosed(); } } - private static void mockWith(StreamingParser stream, List results) + private static void mockWith(MockStreamingParser stream, List results) throws IOException, ResourceParseException { - var it = results.iterator(); - EasyMock.expect(stream.hasNext()).andStubAnswer(it::hasNext); - EasyMock.expect(stream.next()).andAnswer(it::next).times(results.size()); + stream.addValues(results); } + @SuppressWarnings("unused") @SafeVarargs - private static void mockWith(StreamingParser stream, T... results) + private static void mockWith(MockStreamingParser stream, T... results) throws IOException, ResourceParseException { - mockWith(stream, Arrays.asList(results)); + stream.addValues(results); } private String polygonId(String prefix, int year) { return String.format("%-23s%4d", prefix, year); } + + private static final void testWith( + List polygons, List> layers, List> species, + TestConsumer test + ) throws Exception { + + var app = new FipStart(); + + var controlMap = new HashMap(); + + var control = EasyMock.createControl(); + + MockStreamingParser polygonStream = mockStream( + control, controlMap, FipPolygonParser.CONTROL_KEY, "polygonStream" + ); + MockStreamingParser> layerStream = mockStream( + control, controlMap, FipLayerParser.CONTROL_KEY, "layerStream" + ); + MockStreamingParser> speciesStream = mockStream( + control, controlMap, FipSpeciesParser.CONTROL_KEY, "speciesStream" + ); + + mockWith(polygonStream, polygons); + mockWith(layerStream, layers); + mockWith(speciesStream, species); + + app.setControlMap(controlMap); + + control.replay(); + + test.accept(app); + + control.verify(); + + expectAllClosed(polygonStream, layerStream, speciesStream); + + } + + @FunctionalInterface + private static interface TestConsumer { + public void accept(T unit) throws Exception; + } } From 5d1674c63b8019d2cfc4e5661f7278bbd0c9b2b8 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 11 Jul 2023 19:34:56 -0700 Subject: [PATCH 80/98] Validate the primary layer has YTBH less than total age --- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 15 +++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 21 ++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index a6e7a11c4..8c8a452a9 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory; import ca.bc.gov.nrs.vdyp.fip.model.FipLayer; +import ca.bc.gov.nrs.vdyp.fip.model.FipLayerPrimary; import ca.bc.gov.nrs.vdyp.fip.model.FipMode; import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; import ca.bc.gov.nrs.vdyp.fip.model.FipSpecies; @@ -212,6 +213,20 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { ); } + var primaryLayer = (FipLayerPrimary) polygon.getLayers().get(Layer.PRIMARY); + + // FIXME VDYP7 actually tests if total age - YTBH is less than 0.5 but gives an + // error that total age is "less than" YTBH. Replicating that for now but + // consider changing it. + + if (primaryLayer.getAgeTotal() - primaryLayer.getYearsToBreastHeight() < 0.5f) { + throw new ProcessingException( + String.format( + "Polygon %s has %s layer where total age is less than YTBH.", + polygon.getPolygonIdentifier(), Layer.PRIMARY + ) + ); + } } } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 0eac3ef96..c6230b681 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test; import ca.bc.gov.nrs.vdyp.fip.model.FipLayer; +import ca.bc.gov.nrs.vdyp.fip.model.FipLayerPrimary; import ca.bc.gov.nrs.vdyp.fip.model.FipMode; import ca.bc.gov.nrs.vdyp.fip.model.FipPolygon; import ca.bc.gov.nrs.vdyp.fip.model.FipSpecies; @@ -56,8 +57,9 @@ public void testProcessSimple() throws Exception { Arrays.asList( Collections.singletonMap( layer, - new FipLayer( - polygonId, layer, 0, 20f, 0.9f, 0, "B", "B", 0, java.util.Optional.empty(), + new FipLayerPrimary( + polygonId, 20f, 4.8f, 0.9f, 0, "B", "B", 5f, java.util.Optional.empty(), + java.util.Optional.empty(), java.util.Optional.empty(), java.util.Optional.empty() ) ) @@ -139,10 +141,14 @@ public void testPolygonWithNoPrimaryLayer() throws Exception { public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Exception { var polygonId = polygonId("Test Polygon", 2023); - var layer = Layer.VETERAN; + var layer = Layer.PRIMARY; // One polygon with one layer with one species entry, and type is VETERAN + // FIXME VDYP7 actually tests if total age - YTBH is less than 0.5 but gives an + // error that total age is "less than" YTBH. Replicating that for now but + // consider changing it. + testWith( Arrays.asList( new FipPolygon( @@ -153,8 +159,9 @@ public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Excepti Arrays.asList( Collections.singletonMap( layer, - new FipLayer( - polygonId, layer, 0, 20f, 0.9f, 5.0f, "B", "B", 0, java.util.Optional.empty(), + new FipLayerPrimary( + polygonId, 7f, 20f, 0.9f, 5.0f, "B", "B", 8f, java.util.Optional.empty(), + java.util.Optional.empty(), java.util.Optional.empty(), java.util.Optional.empty() ) ) @@ -169,8 +176,8 @@ public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Excepti hasProperty( "message", is( - "Polygon " + polygonId + " has no " + Layer.PRIMARY - + " layer, or that layer has non-positive height or crown closure." + "Polygon " + polygonId + " has " + Layer.PRIMARY + + " layer where total age is less than YTBH." ) ) ); From 8e36f1a935bb3f7c952d6131dbb0fe30e72f9b39 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 12 Jul 2023 17:25:33 -0700 Subject: [PATCH 81/98] Reduce test boilerplate and implement validation of minimum height --- .../bc/gov/nrs/vdyp/io/parse/ValueParser.java | 58 ++++ .../bc/gov/nrs/vdyp/fip/FipControlParser.java | 18 +- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 75 ++++-- .../nrs/vdyp/fip/model/FipLayerPrimary.java | 6 +- .../nrs/vdyp/fip/FipControlParserTest.java | 18 ++ .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 251 +++++++++++++----- 6 files changed, 334 insertions(+), 92 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java index acaecb3db..01bb88400 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/ValueParser.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -321,4 +322,61 @@ public static ValueParser> optionalSingleton(Predicate t return Optional.empty(); // Unknown } }; + + /** + * Make a list parser return a map + * + * @param parser Parser for a list of values + * @param keys Keys for each position in the list. + */ + @SafeVarargs + public static ValueParser> toMap(ValueParser> parser, K... keys) { + return toMap(parser, Collections.emptyMap(), keys); + } + + /** + * Make a list parser return a map + * + * @param parser Parser for a list of values + * @param defaultValues Map of default values. Keys with defaults must follow + * those without. + * @param keys Keys for each position in the list. + */ + @SafeVarargs + public static ValueParser> toMap(ValueParser> parser, Map defaultValues, K... keys) { + + boolean defaultSeen = false; + int required = 0; + + for (var key : keys) { + var isDefault = defaultValues.containsKey(key); + defaultSeen |= isDefault; + required += isDefault ? 0 : 1; + if (defaultSeen != isDefault) { + throw new IllegalArgumentException("Keys with defaults must follow those without"); + } + } + final int requiredFinal = required; + return s -> { + var list = parser.parse(s); + + Map result = new LinkedHashMap<>(); + var it = list.iterator(); + for (int i = 0; i < keys.length; i++) { + K key = keys[i]; + if (it.hasNext()) { + result.put(key, it.next()); + } else { + if (!defaultValues.containsKey(key)) { + throw new ValueParseException( + s, "Expected at least " + requiredFinal + " values but there were only " + list.size() + ); + } + result.put(key, defaultValues.get(key)); // should never be null due to preceding checks + } + } + return result; + }; + } + } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java index f55b35b74..ad56ec0f4 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipControlParser.java @@ -8,6 +8,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; + import ca.bc.gov.nrs.vdyp.io.FileResolver; import ca.bc.gov.nrs.vdyp.io.parse.BecDefinitionParser; import ca.bc.gov.nrs.vdyp.io.parse.BreakageEquationGroupParser; @@ -102,6 +103,13 @@ public class FipControlParser { static final ValueParser FILENAME = String::strip; + public static final String MINIMUM_HEIGHT = "MINIMUM_HEIGHT"; + public static final String MINIMUM_BASE_AREA = "MINIMUM_BASE_AREA"; + public static final String MINIMUM_PREDICTED_BASE_AREA = "MINIMUM_PREDICTED_BASE_AREA"; + public static final String MINIMUM_VETERAN_HEIGHT = "MINIMUM_VETERAN_HEIGHT"; + + public static final float DEFAULT_MINIMUM_VETERAN_HEIGHT = 10.0f; + ControlFileParser controlParser = new ControlFileParser().record(1, MAX_NUM_POLY, ValueParser.INTEGER) .record(9, BEC_DEF, FILENAME) // RD_BECD @@ -158,8 +166,14 @@ public class FipControlParser { .record(97, VETERAN_LAYER_DQ, FILENAME) // RD_YDQV .record(98, VETERAN_BQ, FILENAME) // RD_E098 - .record(197, MINIMA, ValueParser.list(ValueParser.FLOAT)) // Minimum Height, Minimum BA, Min BA fully - // stocked. + .record( + 197, MINIMA, + ValueParser.toMap( + ValueParser.list(ValueParser.FLOAT), + Collections.singletonMap(MINIMUM_VETERAN_HEIGHT, 10.0f), MINIMUM_HEIGHT, MINIMUM_BASE_AREA, + MINIMUM_PREDICTED_BASE_AREA, MINIMUM_VETERAN_HEIGHT + ) + ) .record(198, MODIFIER_FILE, ValueParser.optional(FILENAME)) // RD_E198 IPSJF155, XII diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index 8c8a452a9..5e879b92f 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -156,7 +157,7 @@ private FipPolygon getPolygon( try { layers = layerStream.next(); } catch (NoSuchElementException ex) { - throw new ProcessingException("Layers file has fewer records than polygon file.", ex); + throw validationError("Layers file has fewer records than polygon file.", ex); } log.trace("Getting species for polygon {}", polygon.getPolygonIdentifier()); @@ -164,17 +165,15 @@ private FipPolygon getPolygon( try { species = speciesStream.next(); } catch (NoSuchElementException ex) { - throw new ProcessingException("Species file has fewer records than polygon file.", ex); + throw validationError("Species file has fewer records than polygon file.", ex); } // Validate that layers belong to the correct polygon for (var layer : layers.values()) { if (!layer.getPolygonIdentifier().equals(polygon.getPolygonIdentifier())) { - throw new ProcessingException( - String.format( - "Record in layer file contains layer for polygon %s when expecting one for %s.", - layer.getPolygonIdentifier(), polygon.getPolygonIdentifier() - ) + throw validationError( + "Record in layer file contains layer for polygon %s when expecting one for %s.", + layer.getPolygonIdentifier(), polygon.getPolygonIdentifier() ); } layer.setSpecies(new HashMap<>()); @@ -184,15 +183,16 @@ private FipPolygon getPolygon( var layer = layers.get(spec.getLayer()); // Validate that species belong to the correct polygon if (!spec.getPolygonIdentifier().equals(polygon.getPolygonIdentifier())) { - throw new ProcessingException( - String.format( - "Record in species file contains species for polygon %s when expecting one for %s.", - layer.getPolygonIdentifier(), polygon.getPolygonIdentifier() - ) + throw validationError( + "Record in species file contains species for polygon %s when expecting one for %s.", + layer.getPolygonIdentifier(), polygon.getPolygonIdentifier() ); } if (Objects.isNull(layer)) { - throw new ProcessingException("Species entry references layer %s of polygon %s but it is not present."); + throw validationError( + "Species entry references layer %s of polygon %s but it is not present.", layer, + polygon.getPolygonIdentifier() + ); } layer.getSpecies().put(spec.getGenus(), spec); } @@ -202,14 +202,25 @@ private FipPolygon getPolygon( return polygon; } + private Optional heightMinimum(Layer layer, Map controlMap) { + @SuppressWarnings("unchecked") + var minima = (Map) controlMap.get(FipControlParser.MINIMA); + switch (layer) { + case PRIMARY: + return Optional.of(minima.get(FipControlParser.MINIMUM_HEIGHT)); + case VETERAN: + return Optional.of(minima.get(FipControlParser.MINIMUM_VETERAN_HEIGHT)); + default: + return Optional.empty(); + } + } + private void checkPolygon(FipPolygon polygon) throws ProcessingException { if (!polygon.getLayers().containsKey(Layer.PRIMARY)) { - throw new ProcessingException( - String.format( - "Polygon %s has no %s layer, or that layer has non-positive height or crown closure.", - polygon.getPolygonIdentifier(), Layer.PRIMARY - ) + throw validationError( + "Polygon %s has no %s layer, or that layer has non-positive height or crown closure.", + polygon.getPolygonIdentifier(), Layer.PRIMARY ); } @@ -220,13 +231,33 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { // consider changing it. if (primaryLayer.getAgeTotal() - primaryLayer.getYearsToBreastHeight() < 0.5f) { - throw new ProcessingException( - String.format( - "Polygon %s has %s layer where total age is less than YTBH.", - polygon.getPolygonIdentifier(), Layer.PRIMARY + throw validationError( + "Polygon %s has %s layer where total age is less than YTBH.", polygon.getPolygonIdentifier(), + Layer.PRIMARY + ); + } + + for (var layer : polygon.getLayers().values()) { + var height = layer.getHeight(); + + throwIfPresent( + heightMinimum(layer.getLayer(), controlMap).filter(minimum -> height < minimum).map( + minimum -> validationError( + "Polygon %s has %s layer where height %.1f is less than minimum %.1f.", + polygon.getPolygonIdentifier(), layer.getLayer(), layer.getHeight(), minimum + ) ) ); } } + private static void throwIfPresent(Optional opt) throws E { + if (opt.isPresent()) { + throw opt.get(); + } + } + + private static ProcessingException validationError(String template, Object... values) { + return new ProcessingException(String.format(template, values)); + }; } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java index 75ae1378f..83ef0c936 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java @@ -14,12 +14,12 @@ public class FipLayerPrimary extends FipLayer { Optional stockingClass; public FipLayerPrimary( - String polygonIdentifier, float ageTotal, float height, float siteIndex, float crownClosure, String siteSp0, - String siteSp64, float yearsToBreastHeight, Optional stockingClass, + String polygonIdentifier, float ageTotal, float height, float siteIndex, float crownClosure, + String siteGenus, String siteSpecies, float yearsToBreastHeight, Optional stockingClass, Optional inventoryTypeGroup, Optional breastHeightAge, Optional siteCurveNumber ) { super( - polygonIdentifier, Layer.PRIMARY, ageTotal, height, siteIndex, crownClosure, siteSp0, siteSp64, + polygonIdentifier, Layer.PRIMARY, ageTotal, height, siteIndex, crownClosure, siteGenus, siteSpecies, yearsToBreastHeight, inventoryTypeGroup, breastHeightAge ); this.siteCurveNumber = siteCurveNumber; diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index ff4d373d4..55884138d 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -606,6 +606,24 @@ public void testParseE098() throws Exception { ); } + @Test + public void testParseMinima() throws Exception { + var parser = new FipControlParser(); + var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); + assertThat( + result, (Matcher) hasSpecificEntry( + FipControlParser.MINIMA, + // Includes modifiers from 198 + allOf( + hasEntry(is(FipControlParser.MINIMUM_HEIGHT), is(5.0f)), + hasEntry(is(FipControlParser.MINIMUM_BASE_AREA), is(0.0f)), + hasEntry(is(FipControlParser.MINIMUM_PREDICTED_BASE_AREA), is(2.0f)), + hasEntry(is(FipControlParser.MINIMUM_VETERAN_HEIGHT), is(10.0f)) + ) + ) + ); + } + @Test public void testParseV7O_FIP() throws Exception { var parser = new FipControlParser(); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index c6230b681..73fabb987 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Consumer; import org.easymock.EasyMock; import org.easymock.IMocksControl; @@ -48,25 +49,10 @@ public void testProcessSimple() throws Exception { // One polygon with one primary layer with one species entry testWith( - Arrays.asList( - new FipPolygon( - polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), - java.util.Optional.empty(), 1.0f - ) - ), - Arrays.asList( - Collections.singletonMap( - layer, - new FipLayerPrimary( - polygonId, 20f, 4.8f, 0.9f, 0, "B", "B", 5f, java.util.Optional.empty(), - java.util.Optional.empty(), java.util.Optional.empty(), - java.util.Optional.empty() - ) - ) - ), - Arrays.asList( - Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) - ), app -> { + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { assertDoesNotThrow(app::process); } ); @@ -79,12 +65,10 @@ public void testPolygonWithNoLayersRecord() throws Exception { var polygonId = polygonId("Test Polygon", 2023); testWith( - Arrays.asList( - new FipPolygon( - polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), - java.util.Optional.empty(), 1.0f - ) - ), Collections.emptyList(), Collections.emptyList(), app -> { + Arrays.asList(getTestPolygon(polygonId, valid())), // + Collections.emptyList(), // + Collections.emptyList(), // + app -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat(ex, hasProperty("message", is("Layers file has fewer records than polygon file."))); @@ -101,24 +85,10 @@ public void testPolygonWithNoPrimaryLayer() throws Exception { // One polygon with one layer with one species entry, and type is VETERAN testWith( - Arrays.asList( - new FipPolygon( - polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), - java.util.Optional.empty(), 1.0f - ) - ), - Arrays.asList( - Collections.singletonMap( - layer, - new FipLayer( - polygonId, layer, 0, 20f, 0.9f, 0, "B", "B", 0, java.util.Optional.empty(), - java.util.Optional.empty() - ) - ) - ), - Arrays.asList( - Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) - ), app -> { + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestVeteranLayer(polygonId, valid()))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( @@ -138,37 +108,91 @@ public void testPolygonWithNoPrimaryLayer() throws Exception { } @Test - public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Exception { + public void testPrimaryLayerHeightLessThanMinimum() throws Exception { var polygonId = polygonId("Test Polygon", 2023); var layer = Layer.PRIMARY; - // One polygon with one layer with one species entry, and type is VETERAN + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, x -> { + x.setHeight(4f); + }))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + " has " + Layer.PRIMARY + + " layer where height 4.0 is less than minimum 5.0." + ) + ) + ); + + } + ); + + } + + @Test + public void testVeteranLayerHeightLessThanMinimum() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.VETERAN; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList( + layerMap( + getTestPrimaryLayer(polygonId, valid()), // + getTestVeteranLayer(polygonId, x -> { + x.setHeight(9f); + }) // + ) + ), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + " has " + Layer.VETERAN + + " layer where height 9.0 is less than minimum 10.0." + ) + ) + ); + + } + ); + + } + + @Test + public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; // FIXME VDYP7 actually tests if total age - YTBH is less than 0.5 but gives an // error that total age is "less than" YTBH. Replicating that for now but // consider changing it. testWith( - Arrays.asList( - new FipPolygon( - polygonId, "0", "BG", java.util.Optional.empty(), Optional.of(FipMode.FIPSTART), - java.util.Optional.empty(), 1.0f - ) - ), - Arrays.asList( - Collections.singletonMap( - layer, - new FipLayerPrimary( - polygonId, 7f, 20f, 0.9f, 5.0f, "B", "B", 8f, java.util.Optional.empty(), - java.util.Optional.empty(), java.util.Optional.empty(), - java.util.Optional.empty() - ) - ) - ), - Arrays.asList( - Collections.singletonList(new FipSpecies(polygonId, layer, "B", 100.0f, Collections.emptyMap())) - ), app -> { + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, x -> { + x.setAgeTotal(7f); + x.setYearsToBreastHeight(8f); + }))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( @@ -224,10 +248,28 @@ private static final void testWith( List polygons, List> layers, List> species, TestConsumer test ) throws Exception { + testWith(new HashMap<>(), polygons, layers, species, test); + } + + private static final void testWith( + Map myControlMap, List polygons, List> layers, + List> species, TestConsumer test + ) throws Exception { var app = new FipStart(); - var controlMap = new HashMap(); + Map controlMap = new HashMap<>(); + + Map minima = new HashMap<>(); + + minima.put(FipControlParser.MINIMUM_HEIGHT, 5f); + minima.put(FipControlParser.MINIMUM_BASE_AREA, 0f); + minima.put(FipControlParser.MINIMUM_PREDICTED_BASE_AREA, 2f); + minima.put(FipControlParser.MINIMUM_VETERAN_HEIGHT, 10f); + + controlMap.put(FipControlParser.MINIMA, minima); + + controlMap.putAll(myControlMap); var control = EasyMock.createControl(); @@ -257,6 +299,85 @@ private static final void testWith( } + /** + * Do nothing to mutate valid test data + */ + static final Consumer valid() { + return x -> { + }; + }; + + static Map layerMap(FipLayer... layers) { + Map result = new HashMap<>(); + for (var layer : layers) { + result.put(layer.getLayer(), layer); + } + return result; + } + + FipPolygon getTestPolygon(String polygonId, Consumer mutator) { + var result = new FipPolygon( + polygonId, // polygonIdentifier + "0", // fiz + "BG", // becIdentifier + Optional.empty(), // percentAvailable + Optional.of(FipMode.FIPSTART), // modeFip + Optional.empty(), // nonproductiveDescription + 1.0f // yieldFactor + ); + mutator.accept(result); + return result; + }; + + FipLayerPrimary getTestPrimaryLayer(String polygonId, Consumer mutator) { + var result = new FipLayerPrimary( + polygonId, // polygonIdentifier + 8f, // ageTotal + 6f, // height + 5.0f, // siteIndex + 0.9f, // crownClosure + "B", // siteGenus + "B", // siteSpecies + 7f, // yearsToBreastHeight + Optional.empty(), // stockingClass + Optional.empty(), // inventoryTypeGroup + Optional.empty(), // breastHeightAge + Optional.empty() // siteCurveNumber + ); + mutator.accept(result); + return result; + }; + + FipLayer getTestVeteranLayer(String polygonId, Consumer mutator) { + var result = new FipLayer( + polygonId, // polygonIdentifier + Layer.VETERAN, // layer + 8f, // ageTotal + 6f, // height + 5.0f, // siteIndex + 0.9f, // crownClosure + "B", // siteGenus + "B", // siteSpecies + 7f, // yearsToBreastHeight + Optional.empty(), // inventoryTypeGroup + Optional.empty() // breastHeightAge + ); + mutator.accept(result); + return result; + }; + + FipSpecies getTestSpecies(String polygonId, Layer layer, Consumer mutator) { + var result = new FipSpecies( + polygonId, // polygonIdentifier + layer, // layer + "B", // genus + 100.0f, // percentGenus + Collections.emptyMap() // speciesPercent + ); + mutator.accept(result); + return result; + }; + @FunctionalInterface private static interface TestConsumer { public void accept(T unit) throws Exception; From b28e67c185cb562d4f9d9e6e7feaaed6ee6ffaef Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 12 Jul 2023 17:32:32 -0700 Subject: [PATCH 82/98] Test for species file not matching polygon file --- .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 73fabb987..1f39b1c01 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -76,6 +76,24 @@ public void testPolygonWithNoLayersRecord() throws Exception { } ); } + + @Test + public void testPolygonWithNoSpeciesRecord() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Collections.emptyList(), // + app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat(ex, hasProperty("message", is("Species file has fewer records than polygon file."))); + + } + ); + } @Test public void testPolygonWithNoPrimaryLayer() throws Exception { From 930bb2fe46fad90dbca684107b1101993d6f4bf3 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 12 Jul 2023 17:47:35 -0700 Subject: [PATCH 83/98] Validate polygon mode is not FIPYOUNG --- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 7 +++++ .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 29 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index 5e879b92f..35ed0f72c 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -249,6 +249,13 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { ) ); } + + if (polygon.getModeFip().map(x -> x == FipMode.FIPYOUNG).orElse(false)) { + throw validationError( + "Polygon %s is using unsupported mode %s.", polygon.getPolygonIdentifier(), FipMode.FIPYOUNG + ); + } + } private static void throwIfPresent(Optional opt) throws E { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 1f39b1c01..59e49e8a3 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -76,7 +76,7 @@ public void testPolygonWithNoLayersRecord() throws Exception { } ); } - + @Test public void testPolygonWithNoSpeciesRecord() throws Exception { @@ -228,6 +228,33 @@ public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Excepti } + @Test + public void testPolygonWithModeFipYoung() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith(Arrays.asList(getTestPolygon(polygonId, x -> { + x.setModeFip(Optional.of(FipMode.FIPYOUNG)); + })), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { + + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is("Polygon " + polygonId + " is using unsupported mode " + FipMode.FIPYOUNG + ".") + ) + ); + } + ); + + } + private static MockStreamingParser mockStream(IMocksControl control, Map controlMap, String key, String name) throws IOException { From 638d32e3a2c82621a3fcbd18d801a3488f288a4d Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 14 Jul 2023 12:18:52 -0700 Subject: [PATCH 84/98] Validate years to breast height minimum --- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 6 ++++ .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index 35ed0f72c..fc0a70270 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -256,6 +256,12 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { ); } + if (primaryLayer.getYearsToBreastHeight() < 0.5) { + throw validationError( + "Polygon %s has %s layer where years to breast height %.1f is less than minimum %.1f years.", + polygon.getPolygonIdentifier(), Layer.PRIMARY, primaryLayer.getYearsToBreastHeight(), 0.5f + ); + } } private static void throwIfPresent(Optional opt) throws E { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 59e49e8a3..469e5b2b7 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -192,6 +192,37 @@ public void testVeteranLayerHeightLessThanMinimum() throws Exception { } + @Test + public void testPrimaryLayerYearsToBreastHeightLessThanMinimum() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, x -> { + x.setYearsToBreastHeight(0.2f); + }))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + " has " + Layer.PRIMARY + + " layer where years to breast height 0.2 is less than minimum 0.5 years." + ) + ) + ); + + } + ); + + } + @Test public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Exception { From f22209dd0a84b1f0d7e769bad8c252eaa06064f8 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 14 Jul 2023 12:22:37 -0700 Subject: [PATCH 85/98] TODO note about non-primary validation --- .../main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index fc0a70270..d16e704d7 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -124,7 +124,7 @@ void process() throws ProcessingException { // if (IP_IN .gt. MAXPOLY) go to 200 polygonsRead++; // Don't count polygons we aren't processing due to mode. This was the behavior - // in VDYP7 + // in VDYP7 // IPASS = 1 // CALL FIP_CHK( IPASS, IER) @@ -232,11 +232,16 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { if (primaryLayer.getAgeTotal() - primaryLayer.getYearsToBreastHeight() < 0.5f) { throw validationError( - "Polygon %s has %s layer where total age is less than YTBH.", polygon.getPolygonIdentifier(), - Layer.PRIMARY + "Polygon %s has %s layer where total age is less than YTBH.", polygon.getPolygonIdentifier(), Layer.PRIMARY ); } + // TODO This is the only validation step done to non-primary layers, VDYP7 had a + // less well defined idea of a layer being present or not and so it may have + // skipped validating other layers rather than validating them conditionally on + // being present. Consider extending validation of other properties to other + // layers. + for (var layer : polygon.getLayers().values()) { var height = layer.getHeight(); From 96fdf8d0327981fc5d04195c21b1255877e0675a Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 14 Jul 2023 12:45:52 -0700 Subject: [PATCH 86/98] Validate minimum site index --- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 10 +++++- .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index d16e704d7..aa0f1f54a 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -232,7 +232,8 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { if (primaryLayer.getAgeTotal() - primaryLayer.getYearsToBreastHeight() < 0.5f) { throw validationError( - "Polygon %s has %s layer where total age is less than YTBH.", polygon.getPolygonIdentifier(), Layer.PRIMARY + "Polygon %s has %s layer where total age is less than YTBH.", polygon.getPolygonIdentifier(), + Layer.PRIMARY ); } @@ -267,6 +268,13 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { polygon.getPolygonIdentifier(), Layer.PRIMARY, primaryLayer.getYearsToBreastHeight(), 0.5f ); } + + if (primaryLayer.getSiteIndex() < 0.5) { + throw validationError( + "Polygon %s has %s layer where site index %.1f is less than minimum %.1f years.", + polygon.getPolygonIdentifier(), Layer.PRIMARY, primaryLayer.getSiteIndex(), 0.5f + ); + } } private static void throwIfPresent(Optional opt) throws E { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 469e5b2b7..abdfad989 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -259,6 +259,37 @@ public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Excepti } + @Test + public void testPrimaryLayerSiteIndexLessThanMinimum() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, x -> { + x.setSiteIndex(0.2f); + }))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // + app -> { + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + " has " + Layer.PRIMARY + + " layer where site index 0.2 is less than minimum 0.5 years." + ) + ) + ); + + } + ); + + } + @Test public void testPolygonWithModeFipYoung() throws Exception { From 7f4f678cf5051ad445ef098a9b1347174b7628bc Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 14 Jul 2023 13:39:50 -0700 Subject: [PATCH 87/98] Validate species for a layer sum to 100% --- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 16 ++ .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 172 +++++++++++++++++- 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index aa0f1f54a..ad96899eb 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -275,6 +275,22 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { polygon.getPolygonIdentifier(), Layer.PRIMARY, primaryLayer.getSiteIndex(), 0.5f ); } + + // TODO fill in "FR" should be a map of species to volume proportions for the + // primary layer, see fip_chk.for:237 + + for (var layer : polygon.getLayers().values()) { + var percentTotal = layer.getSpecies().values().stream()// + .map(FipSpecies::getPercentGenus)// + .reduce(0.0f, (x, y) -> x + y); + if (Math.abs(percentTotal - 100f) > 0.01f) { + throw validationError( + "Polygon %s has %s layer where species entries have a percentage total that does not sum to 100%%.", + polygon.getPolygonIdentifier(), Layer.PRIMARY + ); + } + } + } private static void throwIfPresent(Optional opt) throws E { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index abdfad989..249ec726d 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -317,6 +317,172 @@ public void testPolygonWithModeFipYoung() throws Exception { } + @Test + public void testOneSpeciesLessThan100Percent() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, x -> { + x.setPercentGenus(99f); + }))), // + app -> { + + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + + " has PRIMARY layer where species entries have a percentage total that does not sum to 100%." + ) + ) + ); + } + ); + + } + + @Test + public void testOneSpeciesMoreThan100Percent() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, x -> { + x.setPercentGenus(101f); + }))), // + app -> { + + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + + " has PRIMARY layer where species entries have a percentage total that does not sum to 100%." + ) + ) + ); + } + ); + + } + + @Test + public void testTwoSpeciesSumTo100Percent() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList( + Arrays.asList( + // + getTestSpecies(polygonId, layer, "B", x -> { + x.setPercentGenus(75f); + }), getTestSpecies(polygonId, layer, "P", x -> { + x.setPercentGenus(25f); + }) + ) + ), // + app -> { + + assertDoesNotThrow(() -> app.process()); + + } + ); + + } + + @Test + public void testTwoSpeciesSumToLessThan100Percent() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList( + Arrays.asList( + // + getTestSpecies(polygonId, layer, "B", x -> { + x.setPercentGenus(75 - 1f); + }), getTestSpecies(polygonId, layer, "P", x -> { + x.setPercentGenus(25f); + }) + ) + ), // + app -> { + + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + + " has PRIMARY layer where species entries have a percentage total that does not sum to 100%." + ) + ) + ); + } + ); + + } + + @Test + public void testTwoSpeciesSumToMoreThan100Percent() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList( + Arrays.asList( + // + getTestSpecies(polygonId, layer, "B", x -> { + x.setPercentGenus(75 + 1f); + }), getTestSpecies(polygonId, layer, "P", x -> { + x.setPercentGenus(25f); + }) + ) + ), // + app -> { + + var ex = assertThrows(ProcessingException.class, () -> app.process()); + + assertThat( + ex, + hasProperty( + "message", + is( + "Polygon " + polygonId + + " has PRIMARY layer where species entries have a percentage total that does not sum to 100%." + ) + ) + ); + } + ); + + } + private static MockStreamingParser mockStream(IMocksControl control, Map controlMap, String key, String name) throws IOException { @@ -474,10 +640,14 @@ FipLayer getTestVeteranLayer(String polygonId, Consumer mutator) { }; FipSpecies getTestSpecies(String polygonId, Layer layer, Consumer mutator) { + return getTestSpecies(polygonId, layer, "B", mutator); + }; + + FipSpecies getTestSpecies(String polygonId, Layer layer, String genusId, Consumer mutator) { var result = new FipSpecies( polygonId, // polygonIdentifier layer, // layer - "B", // genus + genusId, // genus 100.0f, // percentGenus Collections.emptyMap() // speciesPercent ); From 829f211ba84ddea781c733c51613734589c0fa4c Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Fri, 14 Jul 2023 14:11:22 -0700 Subject: [PATCH 88/98] Species fraction computation to match VDYP7 --- .../java/ca/bc/gov/nrs/vdyp/fip/FipStart.java | 10 +- .../bc/gov/nrs/vdyp/fip/model/FipSpecies.java | 16 ++- .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 117 ++++++++++++++---- 3 files changed, 113 insertions(+), 30 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java index ad96899eb..98c59d534 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipStart.java @@ -276,9 +276,6 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { ); } - // TODO fill in "FR" should be a map of species to volume proportions for the - // primary layer, see fip_chk.for:237 - for (var layer : polygon.getLayers().values()) { var percentTotal = layer.getSpecies().values().stream()// .map(FipSpecies::getPercentGenus)// @@ -289,6 +286,13 @@ private void checkPolygon(FipPolygon polygon) throws ProcessingException { polygon.getPolygonIdentifier(), Layer.PRIMARY ); } + // VDYP7 performs this step which should be negligible but might have a small + // impact due to the 0.01 percent variation and floating point errors. + if (layer.getLayer() == Layer.PRIMARY) { + layer.getSpecies().values().forEach(species -> { + species.setFractionGenus(species.getPercentGenus() / percentTotal); + }); + } } } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java index 0f777cd38..60a2b3871 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java @@ -15,6 +15,11 @@ public class FipSpecies { float percentGenus; + // This is computed from percentGenus, but VDYP7 computes it (RFBASP0/FR) in a + // way that might lead to a slight difference so it's stored separately and can + // be modified. + float fractionGenus; + Map speciesPercent; public FipSpecies( @@ -25,7 +30,7 @@ public FipSpecies( this.layer = layer; this.genus = genus; - this.percentGenus = percentGenus; + this.setPercentGenus(percentGenus); this.speciesPercent = speciesPercent; } @@ -42,8 +47,17 @@ public float getPercentGenus() { return percentGenus; } + public float getFractionGenus() { + return fractionGenus; + } + public void setPercentGenus(float percentGenus) { this.percentGenus = percentGenus; + this.fractionGenus = percentGenus / 100f; + } + + public void setFractionGenus(float fractionGenus) { + this.fractionGenus = fractionGenus; } public Map getSpeciesPercent() { diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 249ec726d..65f4d71d1 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -1,6 +1,8 @@ package ca.bc.gov.nrs.vdyp.fip; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @@ -35,7 +37,7 @@ public class FipStartTest { @Test public void testProcessEmpty() throws Exception { - testWith(Arrays.asList(), Arrays.asList(), Arrays.asList(), app -> { + testWith(Arrays.asList(), Arrays.asList(), Arrays.asList(), (app, controlMap) -> { assertDoesNotThrow(app::process); }); } @@ -52,7 +54,7 @@ public void testProcessSimple() throws Exception { Arrays.asList(getTestPolygon(polygonId, valid())), // Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { assertDoesNotThrow(app::process); } ); @@ -68,7 +70,7 @@ public void testPolygonWithNoLayersRecord() throws Exception { Arrays.asList(getTestPolygon(polygonId, valid())), // Collections.emptyList(), // Collections.emptyList(), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat(ex, hasProperty("message", is("Layers file has fewer records than polygon file."))); @@ -86,7 +88,7 @@ public void testPolygonWithNoSpeciesRecord() throws Exception { Arrays.asList(getTestPolygon(polygonId, valid())), // Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // Collections.emptyList(), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat(ex, hasProperty("message", is("Species file has fewer records than polygon file."))); @@ -106,7 +108,7 @@ public void testPolygonWithNoPrimaryLayer() throws Exception { Arrays.asList(getTestPolygon(polygonId, valid())), // Arrays.asList(layerMap(getTestVeteranLayer(polygonId, valid()))), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( @@ -137,7 +139,7 @@ public void testPrimaryLayerHeightLessThanMinimum() throws Exception { x.setHeight(4f); }))), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( @@ -173,7 +175,7 @@ public void testVeteranLayerHeightLessThanMinimum() throws Exception { ) ), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( @@ -204,7 +206,7 @@ public void testPrimaryLayerYearsToBreastHeightLessThanMinimum() throws Exceptio x.setYearsToBreastHeight(0.2f); }))), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( @@ -240,7 +242,7 @@ public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Excepti x.setYearsToBreastHeight(8f); }))), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); @@ -248,10 +250,7 @@ public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Excepti ex, hasProperty( "message", - is( - "Polygon " + polygonId + " has " + Layer.PRIMARY - + " layer where total age is less than YTBH." - ) + is("Polygon " + polygonId + " has " + Layer.PRIMARY + " layer where total age is less than YTBH.") ) ); } @@ -271,7 +270,7 @@ public void testPrimaryLayerSiteIndexLessThanMinimum() throws Exception { x.setSiteIndex(0.2f); }))), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( @@ -301,15 +300,14 @@ public void testPolygonWithModeFipYoung() throws Exception { })), // Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, valid()))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); assertThat( ex, hasProperty( - "message", - is("Polygon " + polygonId + " is using unsupported mode " + FipMode.FIPYOUNG + ".") + "message", is("Polygon " + polygonId + " is using unsupported mode " + FipMode.FIPYOUNG + ".") ) ); } @@ -329,7 +327,7 @@ public void testOneSpeciesLessThan100Percent() throws Exception { Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, x -> { x.setPercentGenus(99f); }))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); @@ -360,7 +358,7 @@ public void testOneSpeciesMoreThan100Percent() throws Exception { Arrays.asList(Collections.singletonList(getTestSpecies(polygonId, layer, x -> { x.setPercentGenus(101f); }))), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); @@ -398,7 +396,7 @@ public void testTwoSpeciesSumTo100Percent() throws Exception { }) ) ), // - app -> { + (app, controlMap) -> { assertDoesNotThrow(() -> app.process()); @@ -426,7 +424,7 @@ public void testTwoSpeciesSumToLessThan100Percent() throws Exception { }) ) ), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); @@ -464,7 +462,7 @@ public void testTwoSpeciesSumToMoreThan100Percent() throws Exception { }) ) ), // - app -> { + (app, controlMap) -> { var ex = assertThrows(ProcessingException.class, () -> app.process()); @@ -483,9 +481,76 @@ public void testTwoSpeciesSumToMoreThan100Percent() throws Exception { } + @Test + public void testFractionGenusCalculation() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + final var speciesList = Arrays.asList( + // + getTestSpecies(polygonId, layer, "B", x -> { + x.setPercentGenus(75f); + }), getTestSpecies(polygonId, layer, "P", x -> { + x.setPercentGenus(25f); + }) + ); + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList( + speciesList + ), // + (app, controlMap) -> { + + app.process(); + + // Testing exact floating point equality is intentional + assertThat(speciesList, contains( // + allOf(hasProperty("genus",is("B")), hasProperty("fractionGenus", is(0.75f))),// + allOf(hasProperty("genus",is("P")), hasProperty("fractionGenus", is(0.25f)))// + )); + } + ); + + } + + @Test + public void testFractionGenusCalculationWithSlightError() throws Exception { + + var polygonId = polygonId("Test Polygon", 2023); + var layer = Layer.PRIMARY; + + final var speciesList = Arrays.asList( + // + getTestSpecies(polygonId, layer, "B", x -> { + x.setPercentGenus(75 + 0.009f); + }), getTestSpecies(polygonId, layer, "P", x -> { + x.setPercentGenus(25f); + }) + ); + testWith( + Arrays.asList(getTestPolygon(polygonId, valid())), // + Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // + Arrays.asList( + speciesList + ), // + (app, controlMap) -> { + + app.process(); + + // Testing exact floating point equality is intentional + assertThat(speciesList, contains( // + allOf(hasProperty("genus",is("B")), hasProperty("fractionGenus", is(0.75002253f))),// + allOf(hasProperty("genus",is("P")), hasProperty("fractionGenus", is(0.2499775f)))// + )); + } + ); + + } + private static MockStreamingParser - mockStream(IMocksControl control, Map controlMap, String key, String name) - throws IOException { + mockStream(IMocksControl control, Map controlMap, String key, String name) throws IOException { StreamingParserFactory streamFactory = control.mock(name + "Factory", StreamingParserFactory.class); MockStreamingParser stream = new MockStreamingParser<>(); @@ -564,7 +629,7 @@ private static final void testWith( control.replay(); - test.accept(app); + test.accept(app, controlMap); control.verify(); @@ -657,6 +722,6 @@ FipSpecies getTestSpecies(String polygonId, Layer layer, String genusId, Consume @FunctionalInterface private static interface TestConsumer { - public void accept(T unit) throws Exception; + public void accept(T unit, Map controlMap) throws Exception; } } From 681d7f09d7bb9b4db709f6ade9cf52ac056ee31e Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Mon, 17 Jul 2023 15:14:03 -0700 Subject: [PATCH 89/98] Document Relationship between polygon/layer/species objects and their properties and common variables in VDYP7 Fortran. --- .../bc/gov/nrs/vdyp/fip/model/FipLayer.java | 29 ++++++++---- .../nrs/vdyp/fip/model/FipLayerPrimary.java | 8 ++-- .../bc/gov/nrs/vdyp/fip/model/FipPolygon.java | 14 +++--- .../bc/gov/nrs/vdyp/fip/model/FipSpecies.java | 21 +++++---- .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 47 +++++++++++-------- 5 files changed, 71 insertions(+), 48 deletions(-) diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java index d828616d5..ee181997f 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayer.java @@ -20,16 +20,23 @@ public class FipLayer { static final String INVENTORY_TYPE_GROUP = "INVENTORY_TYPE_GROUP"; // ITGFIP static final String BREAST_HEIGHT_AGE = "BREAST_HEIGHT_AGE"; // AGEBH - String polygonIdentifier; // POLYDESC - final Layer layer; - float ageTotal; - float height; - float siteIndex; - float crownClosure; - String siteGenus; - String siteSpecies; - float yearsToBreastHeight; + String polygonIdentifier; // FIP_P/POLYDESC + final Layer layer; // This is also represents the distinction between data stored in FIPL_1(A) and + // FIP_V(A). Where VDYP7 stores both and looks at certain values to determine if + // a layer is "present". VDYP8 stores them in a map keyed by this value + float ageTotal; // FIPL_1/AGETOT_L1 or FIPL_V/AGETOT_V1 + float height; // FIPL_1/HT_L1 or FIPL_V/HT_V1 + float siteIndex; // FIPL_1/SI_L1 or FIPL_V/SI_V1 + float crownClosure; // FIPL_1/CC_L1 or FIP:_V/CC_V1 + String siteGenus; // FIPL_1A/SITESP0_L1 or FIPL_VA/SITESP0_L1 + String siteSpecies; // FIPL_1A/SITESP64_L1 or FIPL_VA/SITESP64_L1 + float yearsToBreastHeight; // FIPL_1/YTBH_L1 or FIP:_V/YTBH_V1 + + // In VDYP7 These are read but not stored in common variables. + // Marked as Deprecated for now but I think we can just remove them. + @Deprecated Optional inventoryTypeGroup; + @Deprecated Optional breastHeightAge; Map species = Collections.emptyMap(); @@ -89,10 +96,12 @@ public float getYearsToBreastHeight() { return yearsToBreastHeight; } + @Deprecated public Optional getInventoryTypeGroup() { return inventoryTypeGroup; } + @Deprecated public Optional getBreastHeightAge() { return breastHeightAge; } @@ -129,10 +138,12 @@ public void setYearsToBreastHeight(float yearsToBreastHeight) { this.yearsToBreastHeight = yearsToBreastHeight; } + @Deprecated public void setInventoryTypeGroup(Optional inventoryTypeGroup) { this.inventoryTypeGroup = inventoryTypeGroup; } + @Deprecated public void setBreastHeightAge(Optional breastHeightAge) { this.breastHeightAge = breastHeightAge; } diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java index 83ef0c936..93d44a764 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipLayerPrimary.java @@ -9,9 +9,11 @@ public class FipLayerPrimary extends FipLayer { static final String SITE_CURVE_NUMBER = "SITE_CURVE_NUMBER"; // SCN static final String STOCKING_CLASS = "STOCKING_CLASS"; // STK - Optional siteCurveNumber; // TODO Confirm if these should be required instead of optional if we know it's - // a Primary layer. - Optional stockingClass; + // TODO Confirm if these should be required instead of optional if we know it's + // a Primary layer. + Optional siteCurveNumber; // FIPL_1/SCN_L1 + + Optional stockingClass; // FIPL_1ST/STK_L1 public FipLayerPrimary( String polygonIdentifier, float ageTotal, float height, float siteIndex, float crownClosure, diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java index 98aba335e..c8a8efa08 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipPolygon.java @@ -8,13 +8,13 @@ public class FipPolygon { - String polygonIdentifier; // POLYDESC - String forestInventoryZone; // FIZ - String biogeoclimaticZone; // BEC - Optional percentAvailable; // PCTFLAND - Optional modeFip; // MODEfip - Optional nonproductiveDescription; // NPDESC - float yieldFactor; // YLDFACT + String polygonIdentifier; // FIP_P/POLYDESC + String forestInventoryZone; // FIP_P/FIZ + String biogeoclimaticZone; // FIP_P/BEC + Optional percentAvailable; // FIP_P2/PCTFLAND + Optional modeFip; // FIP_P2/MODE / MODEfip + Optional nonproductiveDescription; // FIP_P3/NPDESC + float yieldFactor; // FIP_P4/YLDFACT Map layers = Collections.emptyMap(); diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java index 60a2b3871..5933b281d 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/model/FipSpecies.java @@ -9,18 +9,21 @@ public class FipSpecies { static final String POLYGON_IDENTIFIER = "POLYGON_IDENTIFIER"; // POLYDESC static final String LAYER = "LAYER"; // LAYER - final String polygonIdentifier; // POLYDESC - final Layer layer; // LAYER - final String genus; // SP0 + final String polygonIdentifier; // FIP_P/POLYDESC + final Layer layer; // This is also represents the distinction between data stored in + // FIPL_1(A) and FIP_V(A). Where VDYP7 stores both and looks at certain values + // to determine if a layer is "present". VDYP8 stores them in a map keyed by + // this value - float percentGenus; + final String genus; // FIPSA/SP0V - // This is computed from percentGenus, but VDYP7 computes it (RFBASP0/FR) in a - // way that might lead to a slight difference so it's stored separately and can - // be modified. - float fractionGenus; + float percentGenus; // FIPS/PCTVOLV - Map speciesPercent; + // This is computed from percentGenus, but VDYP7 computes it in a way that might + // lead to a slight difference so it's stored separately and can be modified. + float fractionGenus; // RFBASP0/FR + + Map speciesPercent; // Map from public FipSpecies( String polygonIdentifier, Layer layer, String genus, float percentGenus, Map speciesPercent diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 65f4d71d1..0aece0dcc 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -250,7 +250,10 @@ public void testPrimaryLayerTotalAgeLessThanYearsToBreastHeight() throws Excepti ex, hasProperty( "message", - is("Polygon " + polygonId + " has " + Layer.PRIMARY + " layer where total age is less than YTBH.") + is( + "Polygon " + polygonId + " has " + Layer.PRIMARY + + " layer where total age is less than YTBH." + ) ) ); } @@ -307,7 +310,8 @@ public void testPolygonWithModeFipYoung() throws Exception { assertThat( ex, hasProperty( - "message", is("Polygon " + polygonId + " is using unsupported mode " + FipMode.FIPYOUNG + ".") + "message", + is("Polygon " + polygonId + " is using unsupported mode " + FipMode.FIPYOUNG + ".") ) ); } @@ -498,23 +502,24 @@ public void testFractionGenusCalculation() throws Exception { testWith( Arrays.asList(getTestPolygon(polygonId, valid())), // Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // - Arrays.asList( - speciesList - ), // + Arrays.asList(speciesList), // (app, controlMap) -> { app.process(); - + // Testing exact floating point equality is intentional - assertThat(speciesList, contains( // - allOf(hasProperty("genus",is("B")), hasProperty("fractionGenus", is(0.75f))),// - allOf(hasProperty("genus",is("P")), hasProperty("fractionGenus", is(0.25f)))// - )); + assertThat( + speciesList, contains( + // + allOf(hasProperty("genus", is("B")), hasProperty("fractionGenus", is(0.75f))), // + allOf(hasProperty("genus", is("P")), hasProperty("fractionGenus", is(0.25f)))// + ) + ); } ); } - + @Test public void testFractionGenusCalculationWithSlightError() throws Exception { @@ -532,25 +537,27 @@ public void testFractionGenusCalculationWithSlightError() throws Exception { testWith( Arrays.asList(getTestPolygon(polygonId, valid())), // Arrays.asList(layerMap(getTestPrimaryLayer(polygonId, valid()))), // - Arrays.asList( - speciesList - ), // + Arrays.asList(speciesList), // (app, controlMap) -> { app.process(); - + // Testing exact floating point equality is intentional - assertThat(speciesList, contains( // - allOf(hasProperty("genus",is("B")), hasProperty("fractionGenus", is(0.75002253f))),// - allOf(hasProperty("genus",is("P")), hasProperty("fractionGenus", is(0.2499775f)))// - )); + assertThat( + speciesList, contains( + // + allOf(hasProperty("genus", is("B")), hasProperty("fractionGenus", is(0.75002253f))), // + allOf(hasProperty("genus", is("P")), hasProperty("fractionGenus", is(0.2499775f)))// + ) + ); } ); } private static MockStreamingParser - mockStream(IMocksControl control, Map controlMap, String key, String name) throws IOException { + mockStream(IMocksControl control, Map controlMap, String key, String name) + throws IOException { StreamingParserFactory streamFactory = control.mock(name + "Factory", StreamingParserFactory.class); MockStreamingParser stream = new MockStreamingParser<>(); From e69034034c38b545c4e747c8e61a3017f5c9c0df Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 12:14:13 -0700 Subject: [PATCH 90/98] Run formatter --- .github/workflows/maven.yml | 31 ++++++++++-- pom.xml | 47 +++++++++++++++++-- report-aggregate/pom.xml | 40 ++++++++++++++++ .../ca/bc/gov/nrs/vdyp/fip/FipStartTest.java | 4 +- 4 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 report-aggregate/pom.xml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8dd438f35..6bc2993b3 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -6,9 +6,14 @@ # separate terms of service, privacy policy, and support # documentation. -name: Java CI with Maven +name: Java CI with Maven and SonarCloud -on: [pull_request] +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] jobs: build: @@ -23,5 +28,25 @@ jobs: java-version: '17' distribution: 'temurin' cache: maven + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Maven packages + uses: actions/cache@v3 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 - name: Build with Maven - run: mvn -B package + run: mvn package + - name: Run Sonar Analysis + run: mvn sonar:sonar + -Dsonar.login=${{ secrets.SONAR_TOKEN }} + -Dsonar.host.url=https://sonarcloud.io + -Dsonar.organization=bcgov-sonarcloud + -Dsonar.projectKey=bcgov_VDYP + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/pom.xml b/pom.xml index 57a42124c..6b8498eba 100644 --- a/pom.xml +++ b/pom.xml @@ -12,21 +12,26 @@ 17 - + UTF-8 5.9.2 2.2 5.1.0 - + + + ${project.basedir}/report-aggregate/target/site/ + jacoco-aggregate/jacoco.xml + vdyp-core vdyp-fip vdyp-buildtools + report-aggregate - + @@ -136,7 +141,39 @@ - + - + + + coverage + + + + org.jacoco + jacoco-maven-plugin + 0.8.9 + + + prepare-agent + + prepare-agent + + + + report + + report + + + + XML + + + + + + + + + diff --git a/report-aggregate/pom.xml b/report-aggregate/pom.xml new file mode 100644 index 000000000..ab07645eb --- /dev/null +++ b/report-aggregate/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + + ca.bc.gov.nrs.vdyp + report-aggregate + 0.0.1-SNAPSHOT + Variable Density Yield Project - Report Aggregation + Aggregate Coverage Report + + + + ${project.groupId} + vdyp-common + ${project.version} + + + ${project.groupId} + vdyp-fip + ${project.version} + + + + + + + org.jacoco + jacoco-maven-plugin + + + report-aggregate + verify + + report-aggregate + + + + + + + diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java index 0aece0dcc..b9b9721a3 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipStartTest.java @@ -510,7 +510,7 @@ public void testFractionGenusCalculation() throws Exception { // Testing exact floating point equality is intentional assertThat( speciesList, contains( - // + // allOf(hasProperty("genus", is("B")), hasProperty("fractionGenus", is(0.75f))), // allOf(hasProperty("genus", is("P")), hasProperty("fractionGenus", is(0.25f)))// ) @@ -545,7 +545,7 @@ public void testFractionGenusCalculationWithSlightError() throws Exception { // Testing exact floating point equality is intentional assertThat( speciesList, contains( - // + // allOf(hasProperty("genus", is("B")), hasProperty("fractionGenus", is(0.75002253f))), // allOf(hasProperty("genus", is("P")), hasProperty("fractionGenus", is(0.2499775f)))// ) From f94257e2711f8234175d701697b0c4efad558347 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 14:48:37 -0700 Subject: [PATCH 91/98] Prevent shallow clone so SonarCloud can work correctly. --- .github/workflows/maven.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 9223ce8d2..158b15e70 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -22,6 +22,8 @@ jobs: steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up JDK 17 uses: actions/setup-java@v3 with: From b72a0edbf7f705c3d6998313110d9d75ef76c903 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 16:44:08 -0700 Subject: [PATCH 92/98] More unit tests to improve coverage --- .../io/parse/EquationModifierParserTest.java | 33 +++++++++++++ .../bc/gov/nrs/vdyp/model/MatrixMapTest.java | 46 ++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java new file mode 100644 index 000000000..c19b7b9b2 --- /dev/null +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.vdyp.io.parse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.is; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import ca.bc.gov.nrs.vdyp.test.TestUtils; + +public class EquationModifierParserTest { + + @Test + public void testParseSimple() throws Exception { + + var parser = new EquationModifierParser(); + + var is = TestUtils.makeStream( + " 25 18 26" + ); + + Map controlMap = new HashMap<>(); + + var result = parser.parse(is, controlMap); + + assertThat(result, hasEntry(is(25), hasEntry(is(18), is(26)))); + // indexed + } + +} diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index be21a5459..4f5f04f5b 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -7,12 +7,17 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isA; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import org.hamcrest.Matcher; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -155,10 +160,47 @@ public void testEachKey() { assertThat( result, containsInAnyOrder( - arrayContaining("a", 1), arrayContaining("b", 1), arrayContaining("a", 2), - arrayContaining("b", 2) + arrayContaining("a", 1), arrayContaining("b", 1), arrayContaining("a", 2), arrayContaining("b", 2) ) ); } + @Test + public void testToMap() { + var dim1 = Arrays.asList("a", "b"); + var dims = Arrays.asList(dim1); + var map = new MatrixMapImpl(dims); + + map.putM('X', "a"); + + var result = MatrixMap.cast(map, String.class); + assertThat(result, isA(Map.class)); + assertThat(result.size(), is(2)); + assertThat(result.containsKey("a"), is(true)); + assertThat(result.containsKey("c"), is(false)); + assertThat(result.containsValue('X'), is(true)); + assertThat(result.containsValue('Y'), is(false)); + assertThat(result.get("a"), is('X')); + assertThat(result.get("c"), nullValue()); + assertThat(result.isEmpty(), is(false)); + + result.put("b", 'Y'); + assertThat(map.getM("b"), present(is('Y'))); + + result.remove("b"); + assertThat(map.getM("b"), notPresent()); + + } + @Test + public void testToMapMultipleDimensions() { + var dim1 = Arrays.asList("a", "b"); + var dim2 = Arrays.asList(1, 2); + var dims = Arrays.asList(dim1, dim2); + var map = new MatrixMapImpl(dims); + + assertThrows(ClassCastException.class, ()->MatrixMap.cast(map, String.class)); + + + } + } From 216d5cd810eca8a588a20d855c874324b2b23929 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 17:00:14 -0700 Subject: [PATCH 93/98] Change unit test scopes --- .../io/parse/BecDefinitionParserTest.java | 2 +- .../BySpeciesDqCoefficientParserTest.java | 4 +- .../vdyp/io/parse/CoefficientParserTest.java | 12 +-- .../io/parse/ComponentSizeParserTest.java | 8 +- .../io/parse/EquationGroupParserTest.java | 18 ++--- .../io/parse/EquationModifierParserTest.java | 12 ++- .../io/parse/HLCoefficientParserTest.java | 12 +-- .../HLNonprimaryCoefficientParserTest.java | 10 +-- .../gov/nrs/vdyp/io/parse/LineParserTest.java | 40 +++++----- .../io/parse/SP0DefinitionParserTest.java | 14 ++-- .../parse/SiteCurveAgeMaximumParserTest.java | 8 +- .../vdyp/io/parse/SiteCurveParserTest.java | 14 ++-- .../SmallComponentProbabilityParserTest.java | 6 +- .../parse/StockingClassFactorParserTest.java | 8 +- .../io/parse/UpperCoefficientParserTest.java | 8 +- .../UtilComponentBaseAreaParserTest.java | 16 ++-- .../vdyp/io/parse/VeteranDQParserTest.java | 10 +-- .../bc/gov/nrs/vdyp/model/BecLookupTest.java | 36 ++++----- .../bc/gov/nrs/vdyp/model/MatrixMapTest.java | 48 ++++++------ .../nrs/vdyp/fip/FipControlParserTest.java | 76 +++++++++---------- .../gov/nrs/vdyp/fip/ModifierParserTest.java | 20 ++--- 21 files changed, 190 insertions(+), 192 deletions(-) diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java index bf9995cb7..3a9266f9c 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BecDefinitionParserTest.java @@ -22,7 +22,7 @@ public class BecDefinitionParserTest { @Test - public void testParse() throws Exception { + void testParse() throws Exception { var parser = new BecDefinitionParser(); var result = parser.parse(ControlFileParserTest.class, "coe/Becdef.dat", Collections.emptyMap()); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java index 7267e2fca..18e087f0d 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParserTest.java @@ -10,10 +10,10 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class BySpeciesDqCoefficientParserTest { +class BySpeciesDqCoefficientParserTest { @Test - public void testParseSimple() throws Exception { + void testParseSimple() throws Exception { var parser = new BySpeciesDqCoefficientParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java index 5cf4f6de9..6eb3d49bf 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParserTest.java @@ -13,10 +13,10 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class CoefficientParserTest { +class CoefficientParserTest { @Test - public void testParseSimple() throws Exception { + void testParseSimple() throws Exception { var parser = new CoefficientParser("TEST"); @@ -37,7 +37,7 @@ public void testParseSimple() throws Exception { } @Test - public void testBadBec() throws Exception { + void testBadBec() throws Exception { var parser = new CoefficientParser("TEST"); @@ -54,7 +54,7 @@ public void testBadBec() throws Exception { } @Test - public void testBadIndex() throws Exception { + void testBadIndex() throws Exception { var parser = new CoefficientParser("TEST"); @@ -71,7 +71,7 @@ public void testBadIndex() throws Exception { } @Test - public void testParseDelta() throws Exception { + void testParseDelta() throws Exception { var parser = new CoefficientParser("TEST"); @@ -91,7 +91,7 @@ public void testParseDelta() throws Exception { } @Test - public void testParseFixed() throws Exception { + void testParseFixed() throws Exception { var parser = new CoefficientParser("TEST"); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java index 8e8ffbf50..1af0070d4 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/ComponentSizeParserTest.java @@ -14,10 +14,10 @@ import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class ComponentSizeParserTest { +class ComponentSizeParserTest { @Test - public void testParseSimpleP1() throws Exception { + void testParseSimpleP1() throws Exception { var is = TestUtils.makeStream("S1 C 49.4 153.3 0.726 3.647"); @@ -33,7 +33,7 @@ public void testParseSimpleP1() throws Exception { } @Test - public void testParseBadSpecies() throws Exception { + void testParseBadSpecies() throws Exception { var is = TestUtils.makeStream("SX C 49.4 153.3 0.726 3.647"); @@ -49,7 +49,7 @@ public void testParseBadSpecies() throws Exception { } @Test - public void testParseBadRegion() throws Exception { + void testParseBadRegion() throws Exception { var is = TestUtils.makeStream("S1 X 49.4 153.3 0.726 3.647"); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java index c2c8cf264..007dcdd00 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParserTest.java @@ -29,10 +29,10 @@ import ca.bc.gov.nrs.vdyp.test.VdypMatchers; @SuppressWarnings("unused") -public class EquationGroupParserTest { +class EquationGroupParserTest { @Test - public void testParse() throws Exception { + void testParse() throws Exception { var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMapSingle(); @@ -45,7 +45,7 @@ public void testParse() throws Exception { } @Test - public void testSP0MustExist() throws Exception { + void testSP0MustExist() throws Exception { var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMapSingle(); @@ -63,7 +63,7 @@ public void testSP0MustExist() throws Exception { } @Test - public void testBecMustExist() throws Exception { + void testBecMustExist() throws Exception { var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMapSingle(); @@ -81,7 +81,7 @@ public void testBecMustExist() throws Exception { } @Test - public void testParseOvewrite() throws Exception { + void testParseOvewrite() throws Exception { // Original Fortran allows subsequent entries to overwrite old ones so don't // validate against that @@ -97,7 +97,7 @@ public void testParseOvewrite() throws Exception { } @Test - public void testParseMultiple() throws Exception { + void testParseMultiple() throws Exception { var parser = new DefaultEquationNumberParser(); var controlMap = makeControlMap(); @@ -118,7 +118,7 @@ public void testParseMultiple() throws Exception { } @Test - public void testRequireNoMissingSp0() throws Exception { + void testRequireNoMissingSp0() throws Exception { var parser = new DefaultEquationNumberParser(); @@ -138,7 +138,7 @@ public void testRequireNoMissingSp0() throws Exception { } @Test - public void testRequireNoMissingBec() throws Exception { + void testRequireNoMissingBec() throws Exception { var parser = new DefaultEquationNumberParser(); @@ -159,7 +159,7 @@ public void testRequireNoMissingBec() throws Exception { } @Test - public void testRequireNoUnexpectedBec() throws Exception { + void testRequireNoUnexpectedBec() throws Exception { var parser = new DefaultEquationNumberParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java index c19b7b9b2..656faea2a 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/EquationModifierParserTest.java @@ -11,23 +11,21 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class EquationModifierParserTest { +class EquationModifierParserTest { @Test - public void testParseSimple() throws Exception { + void testParseSimple() throws Exception { var parser = new EquationModifierParser(); - var is = TestUtils.makeStream( - " 25 18 26" - ); + var is = TestUtils.makeStream(" 25 18 26"); Map controlMap = new HashMap<>(); var result = parser.parse(is, controlMap); - assertThat(result, hasEntry(is(25), hasEntry(is(18), is(26)))); - // indexed + assertThat(result, hasEntry(is(25), hasEntry(is(18), is(26)))); + // indexed } } diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java index 0f232a3f1..6ca07fed0 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLCoefficientParserTest.java @@ -14,10 +14,10 @@ import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class HLCoefficientParserTest { +class HLCoefficientParserTest { @Test - public void testParseSimpleP1() throws Exception { + void testParseSimpleP1() throws Exception { var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, "TEST"); @@ -33,7 +33,7 @@ public void testParseSimpleP1() throws Exception { } @Test - public void testParseSimpleP2() throws Exception { + void testParseSimpleP2() throws Exception { var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P2, "TEST"); @@ -49,7 +49,7 @@ public void testParseSimpleP2() throws Exception { } @Test - public void testParseSimpleP3() throws Exception { + void testParseSimpleP3() throws Exception { var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P3, "TEST"); @@ -67,7 +67,7 @@ result, mmHasEntry(present(contains(1.04422f, 0.93010f, -0.05745f, -2.50000f)), } @Test - public void testParseBadSpecies() throws Exception { + void testParseBadSpecies() throws Exception { var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, "TEST"); @@ -82,7 +82,7 @@ public void testParseBadSpecies() throws Exception { } @Test - public void testParseBadRegion() throws Exception { + void testParseBadRegion() throws Exception { var parser = new HLCoefficientParser(HLCoefficientParser.NUM_COEFFICIENTS_P1, "TEST"); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java index 9ee507fdf..52eeebdd9 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/HLNonprimaryCoefficientParserTest.java @@ -22,7 +22,7 @@ public class HLNonprimaryCoefficientParserTest { @Test - public void testParseSimple() throws Exception { + void testParseSimple() throws Exception { var parser = new HLNonprimaryCoefficientParser(); @@ -38,7 +38,7 @@ public void testParseSimple() throws Exception { } @Test - public void testParseBadSpecies1() throws Exception { + void testParseBadSpecies1() throws Exception { var parser = new HLNonprimaryCoefficientParser(); @@ -53,7 +53,7 @@ public void testParseBadSpecies1() throws Exception { } @Test - public void testParseBadSpecies2() throws Exception { + void testParseBadSpecies2() throws Exception { var parser = new HLNonprimaryCoefficientParser(); @@ -68,7 +68,7 @@ public void testParseBadSpecies2() throws Exception { } @Test - public void testParseBadRegion() throws Exception { + void testParseBadRegion() throws Exception { var parser = new HLNonprimaryCoefficientParser(); @@ -83,7 +83,7 @@ public void testParseBadRegion() throws Exception { } @Test - public void testParseMissingCoefficient() throws Exception { + void testParseMissingCoefficient() throws Exception { var parser = new HLNonprimaryCoefficientParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java index 9ad1b3d6f..7f8108538 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/LineParserTest.java @@ -20,10 +20,10 @@ import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; -public class LineParserTest { +class LineParserTest { @Test - public void testBasic() throws Exception { + void testBasic() throws Exception { var parser = new LineParser(); parser.string(3, "part1").space(1).string(4, "part2"); @@ -35,7 +35,7 @@ public void testBasic() throws Exception { } @Test - public void testNumbers() throws Exception { + void testNumbers() throws Exception { var parser = new LineParser(); parser.integer(4, "part1").space(1).floating(5, "part2"); @@ -47,7 +47,7 @@ public void testNumbers() throws Exception { } @Test - public void testIncomplete() throws Exception { + void testIncomplete() throws Exception { var parser = new LineParser(); parser.integer(4, "part1").space(1).floating(5, "part2"); @@ -59,7 +59,7 @@ public void testIncomplete() throws Exception { } @Test - public void testIncompleteSegment() throws Exception { + void testIncompleteSegment() throws Exception { var parser = new LineParser(); parser.integer(4, "part1").space(1).floating(5, "part2"); @@ -71,7 +71,7 @@ public void testIncompleteSegment() throws Exception { } @Test - public void testNumberParseErrors() throws Exception { + void testNumberParseErrors() throws Exception { var parser = new LineParser(); parser.integer(4, "part1").space(1).floating(5, "part2"); @@ -88,7 +88,7 @@ public void testNumberParseErrors() throws Exception { } @Test - public void testValueParser() throws Exception { + void testValueParser() throws Exception { var parser = new LineParser(); parser.value(4, "part1", (s, c) -> Integer.valueOf(s.strip()) + 1).space(1) .value("part2", (s, c) -> Float.valueOf(s.strip()) + 1); @@ -101,7 +101,7 @@ public void testValueParser() throws Exception { } @Test - public void testValueParserError() throws Exception { + void testValueParserError() throws Exception { var parser = new LineParser(); parser.value(4, "part1", (s, c) -> { throw new ValueParseException(s, "Testing"); @@ -114,7 +114,7 @@ public void testValueParserError() throws Exception { } @Test - public void testUnbounded() throws Exception { + void testUnbounded() throws Exception { var parser = new LineParser(); parser.string(4, "part1").string("part2"); @@ -135,7 +135,7 @@ public void testUnbounded() throws Exception { } @Test - public void testStripped() throws Exception { + void testStripped() throws Exception { var parser = new LineParser(); parser.strippedString(4, "part1").strippedString("part2"); @@ -157,7 +157,7 @@ public void testStripped() throws Exception { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiValue() throws Exception { + void testMultiValue() throws Exception { var parser = new LineParser(); parser.multiValue(4, 3, "test", ValueParser.INTEGER); @@ -168,7 +168,7 @@ public void testMultiValue() throws Exception { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiLine() throws Exception { + void testMultiLine() throws Exception { var parser = new LineParser(); parser.integer(4, "part1").space(1).string("part2"); @@ -193,7 +193,7 @@ public void testMultiLine() throws Exception { } @Test - public void testMultiLineException() throws Exception { + void testMultiLineException() throws Exception { var parser = new LineParser(); parser.integer(4, "part1").space(1).string("part2"); @@ -211,11 +211,11 @@ public void testMultiLineException() throws Exception { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiLineWithStopEntry() throws Exception { + void testMultiLineWithStopEntry() throws Exception { var parser = new LineParser() { @Override - public boolean isStopEntry(Map entry) { + protected boolean isStopEntry(Map entry) { return 0 == (int) entry.get("part1"); } @@ -232,7 +232,7 @@ public boolean isStopEntry(Map entry) { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiLineWithStopLine() throws Exception { + void testMultiLineWithStopLine() throws Exception { var parser = new LineParser() { @Override @@ -253,7 +253,7 @@ public boolean isStopLine(String line) { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiLineWithStopSegment() throws Exception { + void testMultiLineWithStopSegment() throws Exception { var parser = new LineParser() { @Override @@ -274,7 +274,7 @@ public boolean isStopSegment(List segments) { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiLineWithIgnoredEntry() throws Exception { + void testMultiLineWithIgnoredEntry() throws Exception { var parser = new LineParser() { @Override @@ -301,7 +301,7 @@ public boolean isIgnoredEntry(Map entry) { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiLineWithIgnoredLine() throws Exception { + void testMultiLineWithIgnoredLine() throws Exception { var parser = new LineParser() { @Override @@ -328,7 +328,7 @@ public boolean isIgnoredLine(String line) { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test - public void testMultiLineWithIgnoredSegment() throws Exception { + void testMultiLineWithIgnoredSegment() throws Exception { var parser = new LineParser() { @Override diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java index 26cf66012..7da4b1e3c 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SP0DefinitionParserTest.java @@ -25,7 +25,7 @@ public class SP0DefinitionParserTest { @Test - public void testParse() throws Exception { + void testParse() throws Exception { var parser = new SP0DefinitionParser(); var result = parser.parse(ControlFileParserTest.class, "coe/SP0DEF_v0.dat", Collections.emptyMap()); @@ -103,7 +103,7 @@ public void testParse() throws Exception { } @Test - public void testOrderByPreference() throws Exception { + void testOrderByPreference() throws Exception { var parser = new SP0DefinitionParser(2); List result; @@ -130,7 +130,7 @@ public void testOrderByPreference() throws Exception { } @Test - public void testOrderByLinesBlank() throws Exception { + void testOrderByLinesBlank() throws Exception { var parser = new SP0DefinitionParser(2); List result; @@ -157,7 +157,7 @@ public void testOrderByLinesBlank() throws Exception { } @Test - public void testOrderByLinesZero() throws Exception { + void testOrderByLinesZero() throws Exception { var parser = new SP0DefinitionParser(2); List result; @@ -184,7 +184,7 @@ public void testOrderByLinesZero() throws Exception { } @Test - public void testErrorPreferenceOutOfBoundsHigh() throws Exception { + void testErrorPreferenceOutOfBoundsHigh() throws Exception { var parser = new SP0DefinitionParser(2); Exception ex1; @@ -202,7 +202,7 @@ public void testErrorPreferenceOutOfBoundsHigh() throws Exception { } @Test - public void testErrorPreferenceOutOfBoundsLow() throws Exception { + void testErrorPreferenceOutOfBoundsLow() throws Exception { var parser = new SP0DefinitionParser(2); Exception ex1; @@ -220,7 +220,7 @@ public void testErrorPreferenceOutOfBoundsLow() throws Exception { } @Test - public void testErrorPreferenceDuplicate() throws Exception { + void testErrorPreferenceDuplicate() throws Exception { var parser = new SP0DefinitionParser(2); Exception ex1; diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java index d283b3946..8e9ccf8db 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveAgeMaximumParserTest.java @@ -22,7 +22,7 @@ public class SiteCurveAgeMaximumParserTest { @Test - public void testSimple() throws Exception { + void testSimple() throws Exception { var parser = new SiteCurveAgeMaximumParser(); var is = TestUtils.makeStream(" 16 150.0 150.0 20.0 60.0"); @@ -43,7 +43,7 @@ public void testSimple() throws Exception { } @Test - public void testDefault() throws Exception { + void testDefault() throws Exception { var parser = new SiteCurveAgeMaximumParser(); var is = TestUtils.makeStream(" -1 150.0 150.0 20.0 60.0"); @@ -64,7 +64,7 @@ public void testDefault() throws Exception { } @Test - public void testEndLine() throws Exception { + void testEndLine() throws Exception { var parser = new SiteCurveAgeMaximumParser(); var is = TestUtils.makeStream( " -1 150.0 150.0 20.0 60.0", "999 End of usuable info", @@ -90,7 +90,7 @@ public void testEndLine() throws Exception { } @Test - public void testDefaultValue() throws Exception { + void testDefaultValue() throws Exception { var parser = new SiteCurveAgeMaximumParser(); var is = TestUtils.makeStream(" 16 150.0 150.0 20.0 60.0"); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java index 3f199caef..9d8de3051 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SiteCurveParserTest.java @@ -17,10 +17,10 @@ import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class SiteCurveParserTest { +class SiteCurveParserTest { @Test - public void testSimple() throws Exception { + void testSimple() throws Exception { var parser = new SiteCurveParser(); var is = TestUtils.makeStream("S1 001002"); @@ -37,7 +37,7 @@ public void testSimple() throws Exception { } @Test - public void testExtraSpecies() throws Exception { + void testExtraSpecies() throws Exception { var parser = new SiteCurveParser(); var is = TestUtils.makeStream("S1 001002", "X2 003004"); @@ -55,7 +55,7 @@ public void testExtraSpecies() throws Exception { } @Test - public void testMissingSpecies() throws Exception { + void testMissingSpecies() throws Exception { var parser = new SiteCurveParser(); var is = TestUtils.makeStream("S1 001002"); @@ -73,7 +73,7 @@ public void testMissingSpecies() throws Exception { } @Test - public void testHashComment() throws Exception { + void testHashComment() throws Exception { var parser = new SiteCurveParser(); var is = TestUtils.makeStream("# Foo", "S1 001002"); @@ -90,7 +90,7 @@ public void testHashComment() throws Exception { } @Test - public void testSpaceComment() throws Exception { + void testSpaceComment() throws Exception { var parser = new SiteCurveParser(); var is = TestUtils.makeStream(" Foo", "S1 001002"); @@ -107,7 +107,7 @@ public void testSpaceComment() throws Exception { } @Test - public void testEndFileLine() throws Exception { + void testEndFileLine() throws Exception { var parser = new SiteCurveParser(); var is = TestUtils.makeStream("S1 001002", "##", "S2 003004"); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java index ae47a7966..192780f0d 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/SmallComponentProbabilityParserTest.java @@ -15,10 +15,10 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class SmallComponentProbabilityParserTest { +class SmallComponentProbabilityParserTest { @Test - public void testParseSimpleP1() throws Exception { + void testParseSimpleP1() throws Exception { var is = TestUtils.makeStream("S1 0.48205 0.00000 -0.011862 -0.10014"); @@ -33,7 +33,7 @@ public void testParseSimpleP1() throws Exception { } @Test - public void testParseBadSpecies() throws Exception { + void testParseBadSpecies() throws Exception { var is = TestUtils.makeStream("SX 0.48205 0.00000 -0.011862 -0.10014"); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java index 2ffc8033e..27ceba59c 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/StockingClassFactorParserTest.java @@ -14,10 +14,10 @@ import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class StockingClassFactorParserTest { +class StockingClassFactorParserTest { @Test - public void testEmpty() throws Exception { + void testEmpty() throws Exception { var parser = new StockingClassFactorParser(); var is = TestUtils.makeStream(""); @@ -27,7 +27,7 @@ public void testEmpty() throws Exception { } @Test - public void testSimple() throws Exception { + void testSimple() throws Exception { var parser = new StockingClassFactorParser(); var is = TestUtils.makeStream("R I P 0 1.00 100", "Z Z P 0 1.00 100"); @@ -46,7 +46,7 @@ public void testSimple() throws Exception { } @Test - public void testMultiple() throws Exception { + void testMultiple() throws Exception { var parser = new StockingClassFactorParser(); try (var is = StockingClassFactorParserTest.class.getResourceAsStream("coe/FIPSTKR.PRM")) { diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java index 03c59f741..4cb6d075b 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UpperCoefficientParserTest.java @@ -17,10 +17,10 @@ import ca.bc.gov.nrs.vdyp.model.SP0Definition; import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class UpperCoefficientParserTest { +class UpperCoefficientParserTest { @Test - public void testParseSimple() throws Exception { + void testParseSimple() throws Exception { var parser = new UpperCoefficientParser(); @@ -41,7 +41,7 @@ public void testParseSimple() throws Exception { } @Test - public void testParseBadSpecies() throws Exception { + void testParseBadSpecies() throws Exception { var parser = new UpperCoefficientParser(); @@ -61,7 +61,7 @@ public void testParseBadSpecies() throws Exception { } @Test - public void testParseBadRegion() throws Exception { + void testParseBadRegion() throws Exception { var parser = new UpperCoefficientParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java index 1c55b7c6f..882e87b43 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/UtilComponentBaseAreaParserTest.java @@ -18,10 +18,10 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class UtilComponentBaseAreaParserTest { +class UtilComponentBaseAreaParserTest { @Test - public void testParseSingleBec() throws Exception { + void testParseSingleBec() throws Exception { var parser = new UtilComponentBaseAreaParser(); @@ -48,7 +48,7 @@ public void testParseSingleBec() throws Exception { } @Test - public void testParseSingleRegion() throws Exception { + void testParseSingleRegion() throws Exception { var parser = new UtilComponentBaseAreaParser(); @@ -75,7 +75,7 @@ public void testParseSingleRegion() throws Exception { } @Test - public void testParseAllBecs() throws Exception { + void testParseAllBecs() throws Exception { var parser = new UtilComponentBaseAreaParser(); @@ -103,7 +103,7 @@ public void testParseAllBecs() throws Exception { } @Test - public void testParseBadSpecies() throws Exception { + void testParseBadSpecies() throws Exception { var parser = new UtilComponentBaseAreaParser(); @@ -119,7 +119,7 @@ public void testParseBadSpecies() throws Exception { } @Test - public void testParseBadBec() throws Exception { + void testParseBadBec() throws Exception { var parser = new UtilComponentBaseAreaParser(); @@ -135,7 +135,7 @@ public void testParseBadBec() throws Exception { } @Test - public void testParseBadBau() throws Exception { + void testParseBadBau() throws Exception { var parser = new UtilComponentBaseAreaParser(); @@ -151,7 +151,7 @@ public void testParseBadBau() throws Exception { } @Test - public void testParseMissingCoefficient() throws Exception { + void testParseMissingCoefficient() throws Exception { var parser = new UtilComponentBaseAreaParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java index 78565cbb6..f251e751c 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/io/parse/VeteranDQParserTest.java @@ -19,10 +19,10 @@ import ca.bc.gov.nrs.vdyp.model.Region; import ca.bc.gov.nrs.vdyp.test.TestUtils; -public class VeteranDQParserTest { +class VeteranDQParserTest { @Test - public void testParseSingleRegion() throws Exception { + void testParseSingleRegion() throws Exception { var parser = new VeteranDQParser(); @@ -40,7 +40,7 @@ public void testParseSingleRegion() throws Exception { } @Test - public void testParseAllRegions() throws Exception { + void testParseAllRegions() throws Exception { var parser = new VeteranDQParser(); @@ -58,7 +58,7 @@ public void testParseAllRegions() throws Exception { } @Test - public void testParseBadSpecies() throws Exception { + void testParseBadSpecies() throws Exception { var parser = new VeteranDQParser(); @@ -74,7 +74,7 @@ public void testParseBadSpecies() throws Exception { } @Test - public void testParseMissingCoefficient() throws Exception { + void testParseMissingCoefficient() throws Exception { var parser = new VeteranDQParser(); diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java index 4866025e7..653fa5461 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/BecLookupTest.java @@ -17,10 +17,10 @@ import ca.bc.gov.nrs.vdyp.model.BecLookup.Substitution; -public class BecLookupTest { +class BecLookupTest { @Test - public void testSimpleGet() throws Exception { + void testSimpleGet() throws Exception { var lookup = new BecLookup(Arrays.asList(new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6))); var result = lookup.get("ESSF", Substitution.PARTIAL_FILL_OK); @@ -28,7 +28,7 @@ public void testSimpleGet() throws Exception { } @Test - public void testGetMissing() throws Exception { + void testGetMissing() throws Exception { var lookup = new BecLookup(Arrays.asList(new BecDefinition("ESSF", Region.INTERIOR, "ESSF Test", 4, 5, 6))); var result = lookup.get("XX", Substitution.PARTIAL_FILL_OK); @@ -36,7 +36,7 @@ public void testGetMissing() throws Exception { } @Test - public void testWithSubstitution() throws Exception { + void testWithSubstitution() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), @@ -57,7 +57,7 @@ public void testWithSubstitution() throws Exception { } @Test - public void testWithSubstitutionButNoneNeeded() throws Exception { + void testWithSubstitutionButNoneNeeded() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("BWBS", Region.INTERIOR, "BWBS Test", 1, 2, 3), @@ -78,7 +78,7 @@ public void testWithSubstitutionButNoneNeeded() throws Exception { } @Test - public void testWithPartialAllowed() throws Exception { + void testWithPartialAllowed() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), @@ -99,7 +99,7 @@ public void testWithPartialAllowed() throws Exception { } @Test - public void testWithNoSubstitution() throws Exception { + void testWithNoSubstitution() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), @@ -112,7 +112,7 @@ public void testWithNoSubstitution() throws Exception { } @Test - public void testWithSubstitutionButDefaultIsMissing() throws Exception { + void testWithSubstitutionButDefaultIsMissing() throws Exception { var lookup = new BecLookup(Arrays.asList(new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1))); var ex = assertThrows(IllegalStateException.class, () -> lookup.get("BG", Substitution.SUBSTITUTE)); @@ -121,7 +121,7 @@ public void testWithSubstitutionButDefaultIsMissing() throws Exception { } @Test - public void testWithSubstitutionButDefaultIsIncomplete() throws Exception { + void testWithSubstitutionButDefaultIsIncomplete() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), @@ -135,7 +135,7 @@ public void testWithSubstitutionButDefaultIsIncomplete() throws Exception { } @Test - public void testGetBecsWithSubstitution() throws Exception { + void testGetBecsWithSubstitution() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), @@ -161,7 +161,7 @@ public void testGetBecsWithSubstitution() throws Exception { } @Test - public void testGetBecsAllowingPartial() throws Exception { + void testGetBecsAllowingPartial() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("BG", Region.INTERIOR, "BG Test", 0, 0, 1), @@ -187,7 +187,7 @@ public void testGetBecsAllowingPartial() throws Exception { } @Test - public void testGetGrowthBecs() throws Exception { + void testGetGrowthBecs() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("AT", Region.INTERIOR, "AT Test", 0, 1, 1), @@ -210,7 +210,7 @@ public void testGetGrowthBecs() throws Exception { } @Test - public void testGetCoastalBecs() throws Exception { + void testGetCoastalBecs() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), @@ -238,7 +238,7 @@ public void testGetCoastalBecs() throws Exception { } @Test - public void testGetInteriorBecs() throws Exception { + void testGetInteriorBecs() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), @@ -266,7 +266,7 @@ public void testGetInteriorBecs() throws Exception { } @Test - public void testGetByBlankScope() throws Exception { + void testGetByBlankScope() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), @@ -302,7 +302,7 @@ public void testGetByBlankScope() throws Exception { } @Test - public void testGetByRegionScope() throws Exception { + void testGetByRegionScope() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), @@ -330,7 +330,7 @@ public void testGetByRegionScope() throws Exception { } @Test - public void testGetByBecScope() throws Exception { + void testGetByBecScope() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), @@ -354,7 +354,7 @@ public void testGetByBecScope() throws Exception { } @Test - public void testGetByMissingScope() throws Exception { + void testGetByMissingScope() throws Exception { var lookup = new BecLookup( Arrays.asList( new BecDefinition("CDF", Region.COASTAL, "CDF Test", 1, 2, 3), diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index 4f5f04f5b..804a767f6 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -17,14 +17,13 @@ import java.util.List; import java.util.Map; -import org.hamcrest.Matcher; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -public class MatrixMapTest { +class MatrixMapTest { @Test - public void testContruct() { + void testContruct() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -32,20 +31,20 @@ public void testContruct() { } @Test - public void testContructNoDimensionsFails() { + void testContructNoDimensionsFails() { List> dims = Collections.emptyList(); Assertions.assertThrows(IllegalArgumentException.class, () -> new MatrixMapImpl(dims)); } @Test - public void testContructEmptyDimensionsFails() { + void testContructEmptyDimensionsFails() { var dim1 = Collections.emptyList(); var dims = Arrays.asList(dim1); Assertions.assertThrows(IllegalArgumentException.class, () -> new MatrixMapImpl(dims)); } @Test - public void testNewMapIsEmpty() { + void testNewMapIsEmpty() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -55,7 +54,7 @@ public void testNewMapIsEmpty() { } @Test - public void testDefaultIsEmpty() { + void testDefaultIsEmpty() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -67,7 +66,7 @@ public void testDefaultIsEmpty() { } @Test - public void testCanRetrieveAValue() { + void testCanRetrieveAValue() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -80,7 +79,7 @@ public void testCanRetrieveAValue() { } @Test - public void testWithOneValueIsNeitherFullNorEmpty() { + void testWithOneValueIsNeitherFullNorEmpty() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -93,7 +92,7 @@ public void testWithOneValueIsNeitherFullNorEmpty() { } @Test - public void testGetIndex() { + void testGetIndex() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -106,7 +105,7 @@ public void testGetIndex() { } @Test - public void testFullMap() { + void testFullMap() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -127,7 +126,7 @@ public void testFullMap() { } @Test - public void testSetAll() { + void testSetAll() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -149,7 +148,7 @@ public void testSetAll() { } @Test - public void testEachKey() { + void testEachKey() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); @@ -160,19 +159,20 @@ public void testEachKey() { assertThat( result, containsInAnyOrder( - arrayContaining("a", 1), arrayContaining("b", 1), arrayContaining("a", 2), arrayContaining("b", 2) + arrayContaining("a", 1), arrayContaining("b", 1), arrayContaining("a", 2), + arrayContaining("b", 2) ) ); } @Test - public void testToMap() { + void testToMap() { var dim1 = Arrays.asList("a", "b"); var dims = Arrays.asList(dim1); var map = new MatrixMapImpl(dims); - + map.putM('X', "a"); - + var result = MatrixMap.cast(map, String.class); assertThat(result, isA(Map.class)); assertThat(result.size(), is(2)); @@ -183,24 +183,24 @@ public void testToMap() { assertThat(result.get("a"), is('X')); assertThat(result.get("c"), nullValue()); assertThat(result.isEmpty(), is(false)); - + result.put("b", 'Y'); assertThat(map.getM("b"), present(is('Y'))); - + result.remove("b"); assertThat(map.getM("b"), notPresent()); - + } + @Test - public void testToMapMultipleDimensions() { + void testToMapMultipleDimensions() { var dim1 = Arrays.asList("a", "b"); var dim2 = Arrays.asList(1, 2); var dims = Arrays.asList(dim1, dim2); var map = new MatrixMapImpl(dims); - - assertThrows(ClassCastException.class, ()->MatrixMap.cast(map, String.class)); - + assertThrows(ClassCastException.class, () -> MatrixMap.cast(map, String.class)); + } } diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index aa8227681..6604025b8 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -41,17 +41,17 @@ import ca.bc.gov.nrs.vdyp.model.StockingClassFactor; @SuppressWarnings({ "unused", "unchecked", "rawtypes" }) -public class FipControlParserTest { +class FipControlParserTest { @Test - public void testParse() throws Exception { + void testParse() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); } @Test - public void testParseBec() throws Exception { + void testParseBec() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -64,7 +64,7 @@ public void testParseBec() throws Exception { } @Test - public void testParseSP0() throws Exception { + void testParseSP0() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -77,7 +77,7 @@ public void testParseSP0() throws Exception { } @Test - public void testParseVGRP() throws Exception { + void testParseVGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -98,7 +98,7 @@ FipControlParser.VOLUME_EQN_GROUPS, allOf( } @Test - public void testParseDGRP() throws Exception { + void testParseDGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -119,7 +119,7 @@ FipControlParser.DECAY_GROUPS, allOf( } @Test - public void testParseBGRP() throws Exception { + void testParseBGRP() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -140,7 +140,7 @@ FipControlParser.BREAKAGE_GROUPS, allOf( } @Test - public void testParseGRBA1() throws Exception { + void testParseGRBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -161,7 +161,7 @@ FipControlParser.DEFAULT_EQ_NUM, allOf( } @Test - public void testParseGMBA1() throws Exception { + void testParseGMBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -182,7 +182,7 @@ FipControlParser.EQN_MODIFIERS, allOf( } @Test - public void testParseSTK33() throws Exception { + void testParseSTK33() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -204,7 +204,7 @@ FipControlParser.STOCKING_CLASS_FACTORS, allOf( } @Test - public void testParseE025() throws Exception { + void testParseE025() throws Exception { var parser = new FipControlParser(); var result = parseWithAppendix(parser, "025 coe/SIEQN.PRM"); assertThat( @@ -218,14 +218,14 @@ FipControlParser.SITE_CURVE_NUMBERS, allOf( } @Test - public void testParseE025Empty() throws Exception { + void testParseE025Empty() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat(result, (Matcher) hasSpecificEntry(FipControlParser.SITE_CURVE_NUMBERS, Matchers.anEmptyMap())); } @Test - public void testParseE026() throws Exception { + void testParseE026() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -240,7 +240,7 @@ FipControlParser.SITE_CURVE_AGE_MAX, allOf( @Test // @Disabled - public void testParseE026Empty() throws Exception { + void testParseE026Empty() throws Exception { var parser = new FipControlParser(); var result = parseWithAppendix(parser, "026 "); // Map is empty but gives appropriate default values @@ -252,7 +252,7 @@ public void testParseE026Empty() throws Exception { } @Test - public void testParseE040() throws Exception { + void testParseE040() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -262,7 +262,7 @@ public void testParseE040() throws Exception { } @Test - public void testParseE041() throws Exception { + void testParseE041() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -272,7 +272,7 @@ public void testParseE041() throws Exception { } @Test - public void testParseE043() throws Exception { + void testParseE043() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -285,7 +285,7 @@ public void testParseE043() throws Exception { } @Test - public void testParseE050() throws Exception { + void testParseE050() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -298,7 +298,7 @@ public void testParseE050() throws Exception { } @Test - public void testParseE051() throws Exception { + void testParseE051() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -311,7 +311,7 @@ public void testParseE051() throws Exception { } @Test - public void testParseE052() throws Exception { + void testParseE052() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -329,7 +329,7 @@ public void testParseE052() throws Exception { } @Test - public void testParseE053() throws Exception { + void testParseE053() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -347,7 +347,7 @@ public void testParseE053() throws Exception { } @Test - public void testParseE060() throws Exception { + void testParseE060() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -375,7 +375,7 @@ public void testParseE060() throws Exception { } @Test - public void testParseE061() throws Exception { + void testParseE061() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -388,7 +388,7 @@ public void testParseE061() throws Exception { } @Test - public void testParseUBA1() throws Exception { + void testParseUBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -401,7 +401,7 @@ public void testParseUBA1() throws Exception { } @Test - public void testParseYVC1() throws Exception { + void testParseYVC1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -414,7 +414,7 @@ public void testParseYVC1() throws Exception { } @Test - public void testParseYVD1() throws Exception { + void testParseYVD1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -427,7 +427,7 @@ public void testParseYVD1() throws Exception { } @Test - public void testParseSBA1() throws Exception { + void testParseSBA1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -440,7 +440,7 @@ public void testParseSBA1() throws Exception { } @Test - public void testParseSBA2() throws Exception { + void testParseSBA2() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -453,7 +453,7 @@ public void testParseSBA2() throws Exception { } @Test - public void testParseSDQ1() throws Exception { + void testParseSDQ1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -465,7 +465,7 @@ FipControlParser.SMALL_COMP_DQ, allOf(hasEntry(is("B"), contains(-0.33485f, 0.02 } @Test - public void testParseSHL1() throws Exception { + void testParseSHL1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -477,7 +477,7 @@ FipControlParser.SMALL_COMP_HL, allOf(hasEntry(is("B"), contains(-8.5269f, -0.20 } @Test - public void testParseSVT1() throws Exception { + void testParseSVT1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -490,7 +490,7 @@ public void testParseSVT1() throws Exception { } @Test - public void testParseYVT1() throws Exception { + void testParseYVT1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -511,7 +511,7 @@ public void testParseYVT1() throws Exception { } @Test - public void testParseYVT2() throws Exception { + void testParseYVT2() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -524,7 +524,7 @@ public void testParseYVT2() throws Exception { } @Test - public void testParseYVW1() throws Exception { + void testParseYVW1() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -537,7 +537,7 @@ public void testParseYVW1() throws Exception { } @Test - public void testParseE095() throws Exception { + void testParseE095() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -549,7 +549,7 @@ FipControlParser.BREAKAGE, allOf(hasEntry(is(10), contains(-0.7153f, 2.0108f, 4. } @Test - public void testParseYVVET() throws Exception { + void testParseYVVET() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -562,7 +562,7 @@ public void testParseYVVET() throws Exception { } @Test - public void testParseYDQV() throws Exception { + void testParseYDQV() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( @@ -580,7 +580,7 @@ public void testParseYDQV() throws Exception { } @Test - public void testParseE098() throws Exception { + void testParseE098() throws Exception { var parser = new FipControlParser(); var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); assertThat( diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java index a2a0e0a5b..a2c05d93d 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/ModifierParserTest.java @@ -38,10 +38,10 @@ import ca.bc.gov.nrs.vdyp.test.TestUtils; @SuppressWarnings({ "unchecked", "rawtypes" }) -public class ModifierParserTest { +class ModifierParserTest { @Test - public void testNoFilenameForControlFile() throws Exception { + void testNoFilenameForControlFile() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -70,7 +70,7 @@ public String toString(String filename) throws IOException { } @Test - public void testMissingControlFile() throws Exception { + void testMissingControlFile() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -101,7 +101,7 @@ public String toString(String filename) throws IOException { } @Test - public void testLoadEmptyFile() throws Exception { + void testLoadEmptyFile() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -177,7 +177,7 @@ protected void modifierDefaultAsserts(Map controlMap) { } @Test - public void testBaDqSpecies() throws Exception { + void testBaDqSpecies() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -236,7 +236,7 @@ public String toString(String filename) throws IOException { } @Test - public void testBaDqSpeciesDifferentProgram() throws Exception { + void testBaDqSpeciesDifferentProgram() throws Exception { var parser = new ModifierParser(3); Map controlMap = new HashMap<>(); @@ -272,7 +272,7 @@ public String toString(String filename) throws IOException { } @Test - public void testIgnoreAfterStop() throws Exception { + void testIgnoreAfterStop() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -308,7 +308,7 @@ public String toString(String filename) throws IOException { } @Test - public void testIgnoreCommentsAndBlanks() throws Exception { + void testIgnoreCommentsAndBlanks() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -367,7 +367,7 @@ public String toString(String filename) throws IOException { } @Test - public void testBaDqAllSpecies() throws Exception { + void testBaDqAllSpecies() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); @@ -418,7 +418,7 @@ public String toString(String filename) throws IOException { } @Test - public void testVetBq() throws Exception { + void testVetBq() throws Exception { var parser = new ModifierParser(1); Map controlMap = new HashMap<>(); From abbea989e07ff58b0e069242030f35a7b5c5e312 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 17:09:05 -0700 Subject: [PATCH 94/98] Remove redundant tests --- .../test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java | 8 -------- .../java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java | 7 ------- 2 files changed, 15 deletions(-) diff --git a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java index 804a767f6..5c4444320 100644 --- a/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java +++ b/vdyp-core/src/test/java/ca/bc/gov/nrs/vdyp/model/MatrixMapTest.java @@ -22,14 +22,6 @@ class MatrixMapTest { - @Test - void testContruct() { - var dim1 = Arrays.asList("a", "b"); - var dim2 = Arrays.asList(1, 2); - var dims = Arrays.asList(dim1, dim2); - new MatrixMapImpl(dims); - } - @Test void testContructNoDimensionsFails() { List> dims = Collections.emptyList(); diff --git a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java index 6604025b8..0d338af47 100644 --- a/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java +++ b/vdyp-fip/src/test/java/ca/bc/gov/nrs/vdyp/fip/FipControlParserTest.java @@ -43,13 +43,6 @@ @SuppressWarnings({ "unused", "unchecked", "rawtypes" }) class FipControlParserTest { - @Test - void testParse() throws Exception { - var parser = new FipControlParser(); - var result = parser.parse(ControlFileParserTest.class, "FIPSTART.CTR"); - - } - @Test void testParseBec() throws Exception { var parser = new FipControlParser(); From 5792655d34fe7f90d7d77f890ff9f27a0bbd1336 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 17:27:45 -0700 Subject: [PATCH 95/98] Remove redundant traversal of key set --- .../java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java | 1 - 1 file changed, 1 deletion(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index 88ff769af..f41172cd0 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -144,7 +144,6 @@ public M parse(InputStream is, Map control) throws IOException, if (expectedKeys > 0 && metaKeys.size() != expectedKeys) { throw new IllegalStateException("Expected " + expectedKeys + " keys but there were " + metaKeys.size()); } - keyRanges.stream().map(x -> x.apply(control)).toList(); @SuppressWarnings({ "unchecked", "rawtypes" }) M result = (M) createMap((List) (keyRanges.stream().map(x -> x.apply(control)).toList())); From a5ffcd49b3013d9417ea5df737becf5f0595cacf Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 17:41:19 -0700 Subject: [PATCH 96/98] Fix warnings in species parser and grouping parser --- .../ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java | 4 ++-- .../main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java index 817edc9ee..22e99c292 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/GroupingStreamingParser.java @@ -19,7 +19,7 @@ public abstract class GroupingStreamingParser implements StreamingParser> next = Optional.empty(); - public GroupingStreamingParser(StreamingParser delegate) { + protected GroupingStreamingParser(StreamingParser delegate) { super(); this.delegate = delegate; } @@ -64,7 +64,7 @@ protected void doGetNext() throws IOException, ResourceParseException { var nextChild = safeNextChild(); while (nextChild.map(x -> !stop(x)).orElse(false)) { - nextResult.add(nextChild.get()); + nextChild.ifPresent(nextResult::add); // Should always be present due to loop condition nextChild = safeNextChild(); } if (nextChild.isEmpty()) { diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java index bb3916b62..3e1d73efb 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java @@ -20,7 +20,6 @@ import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseException; import ca.bc.gov.nrs.vdyp.io.parse.ResourceParseValidException; import ca.bc.gov.nrs.vdyp.io.parse.StreamingParserFactory; -import ca.bc.gov.nrs.vdyp.io.parse.ValueParseException; import ca.bc.gov.nrs.vdyp.io.parse.ValueParser; import ca.bc.gov.nrs.vdyp.model.Layer; From b6f5e15a7052972641e1b1d54f2a3ed8dc0afeb7 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 20 Jul 2023 19:15:49 -0700 Subject: [PATCH 97/98] Constuctors of abstract classes should be protected --- .../ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java | 2 +- .../ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java | 4 ++-- .../java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java | 4 ++-- .../src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java index a54a3ad05..391a10673 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/AbstractStreamingParser.java @@ -17,7 +17,7 @@ public abstract class AbstractStreamingParser implements StreamingParser { * @param lineParser * @param control */ - public AbstractStreamingParser(InputStream is, LineParser lineParser, Map control) { + protected AbstractStreamingParser(InputStream is, LineParser lineParser, Map control) { this.lineStream = lineParser.parseAsStream(is, control); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index f41172cd0..a0d58f308 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -38,7 +38,7 @@ public abstract class BaseCoefficientParser segments) { this.controlKey = controlKey; } - public BaseCoefficientParser(String controlKey) { + protected BaseCoefficientParser(String controlKey) { this(0, controlKey); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java index 224ad0142..6d3597892 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/EquationGroupParser.java @@ -24,11 +24,11 @@ public abstract class EquationGroupParser implements ControlMapSubResourceParser private Collection hiddenBecs = Collections.emptyList(); - public EquationGroupParser() { + protected EquationGroupParser() { this(3); } - public EquationGroupParser(int identifierLength) { + protected EquationGroupParser(int identifierLength) { lineParser = new LineParser().strippedString(2, "sp0Alias").space(1).strippedString(4, "becAlias").space(1) .integer(identifierLength, "grpId"); } diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java index 91deef1d1..a3ff7a69d 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/LineParser.java @@ -70,7 +70,7 @@ public void parseIntoMap(String toParse, Map control, Map Date: Thu, 20 Jul 2023 19:22:36 -0700 Subject: [PATCH 98/98] Replace .collect(Collectors.toList()) with .toList() --- .../ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java | 2 +- .../gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java | 2 +- .../java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java | 4 ++-- .../main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java index a0d58f308..042721ef4 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BaseCoefficientParser.java @@ -148,7 +148,7 @@ public M parse(InputStream is, Map control) throws IOException, M result = (M) createMap((List) (keyRanges.stream().map(x -> x.apply(control)).toList())); lineParser.parse(is, result, (v, r) -> { - var key = metaKeys.stream().map(v::get).collect(Collectors.toList()).toArray(Object[]::new); + var key = metaKeys.stream().map(v::get).toList().toArray(Object[]::new); @SuppressWarnings("unchecked") var coe = getCoefficients((List) v.get(COEFFICIENTS_KEY)); diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java index 9214d213b..c1012afcf 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/BySpeciesDqCoefficientParser.java @@ -59,7 +59,7 @@ public List parse(InputStream is, Map control) if (! (index == 0 || index == 1)) { final var first = coefficients.get(0); - coefficients = Stream.generate(() -> first).limit(NUM_SPECIES).collect(Collectors.toList()); + coefficients = Stream.generate(() -> first).limit(NUM_SPECIES).toList(); } if (coefficients.size() < NUM_SPECIES) { diff --git a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java index 2ffc593ca..5270bdf67 100644 --- a/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java +++ b/vdyp-core/src/main/java/ca/bc/gov/nrs/vdyp/io/parse/CoefficientParser.java @@ -49,8 +49,8 @@ public boolean isStopLine(String line) { public MatrixMap3 parse(InputStream is, Map control) throws IOException, ResourceParseException { var becAliases = BecDefinitionParser.getBecAliases(control); - var coeIndecies = Stream.iterate(0, x -> x + 1).limit(NUM_COEFFICIENTS).collect(Collectors.toList()); - var speciesIndecies = Stream.iterate(1, x -> x + 1).limit(NUM_SPECIES).collect(Collectors.toList()); + var coeIndecies = Stream.iterate(0, x -> x + 1).limit(NUM_COEFFICIENTS).toList(); + var speciesIndecies = Stream.iterate(1, x -> x + 1).limit(NUM_SPECIES).toList(); MatrixMap3 result = new MatrixMap3Impl( coeIndecies, becAliases, speciesIndecies ); diff --git a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java index 3e1d73efb..4909bc578 100644 --- a/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java +++ b/vdyp-fip/src/main/java/ca/bc/gov/nrs/vdyp/fip/FipSpeciesParser.java @@ -141,7 +141,7 @@ protected boolean stop(ValueOrMarker, EndOfRecord> nextChil // we've filtered out // markers .flatMap(Optional::stream) // Skip if empty (and unknown layer type) - .collect(Collectors.toList()); + .toList(); } };