Skip to content

Commit

Permalink
Merge pull request #60 from bcgov/feature/VDYP-400-grow-qmd+lh
Browse files Browse the repository at this point in the history
Feature/vdyp 400 grow qmd+lh
  • Loading branch information
smithkm authored Sep 10, 2024
2 parents 34c530e + ff1731d commit 0d57ac6
Show file tree
Hide file tree
Showing 209 changed files with 12,583 additions and 8,674 deletions.
48 changes: 0 additions & 48 deletions vdyp-lib/vdyp-common/GenusDefinitionMapTest.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ca.bc.gov.nrs.vdyp.application;

public class InitializationIncompleteException extends RuntimeException {

private static final long serialVersionUID = -4549468703592060502L;

public InitializationIncompleteException(String reason) {
super(reason);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@
import ca.bc.gov.nrs.vdyp.common.Utils;
import ca.bc.gov.nrs.vdyp.common.ValueOrMarker;
import ca.bc.gov.nrs.vdyp.common_calculators.BaseAreaTreeDensityDiameter;
import ca.bc.gov.nrs.vdyp.controlmap.ResolvedControlMapImpl;
import ca.bc.gov.nrs.vdyp.io.FileSystemFileResolver;
import ca.bc.gov.nrs.vdyp.io.parse.coe.UpperCoefficientParser;
import ca.bc.gov.nrs.vdyp.io.parse.common.ResourceParseException;
import ca.bc.gov.nrs.vdyp.io.parse.control.BaseControlParser;
import ca.bc.gov.nrs.vdyp.io.parse.streaming.StreamingParser;
import ca.bc.gov.nrs.vdyp.io.parse.streaming.StreamingParserFactory;
import ca.bc.gov.nrs.vdyp.io.write.VriAdjustInputWriter;
import ca.bc.gov.nrs.vdyp.io.write.VdypOutputWriter;
import ca.bc.gov.nrs.vdyp.math.FloatMath;
import ca.bc.gov.nrs.vdyp.model.BaseVdypLayer;
import ca.bc.gov.nrs.vdyp.model.BaseVdypPolygon;
Expand Down Expand Up @@ -164,7 +165,7 @@ protected static void doMain(VdypStartApplication<?, ?, ?, ?> app, final String.
.filter(x -> !x.getName().contains("Volume")).toList();
}

protected VriAdjustInputWriter vriWriter;
protected VdypOutputWriter vriWriter;

protected Map<String, Object> controlMap = new HashMap<>();

Expand Down Expand Up @@ -226,7 +227,7 @@ public void init(FileSystemFileResolver resolver, Map<String, Object> controlMap

setControlMap(controlMap);
closeVriWriter();
vriWriter = new VriAdjustInputWriter(controlMap, resolver);
vriWriter = new VdypOutputWriter(controlMap, resolver);
}

protected abstract BaseControlParser getControlFileParser();
Expand All @@ -240,7 +241,7 @@ void closeVriWriter() throws IOException {

protected void setControlMap(Map<String, Object> controlMap) {
this.controlMap = controlMap;
this.estimationMethods = new EstimationMethods(controlMap);
this.estimationMethods = new EstimationMethods(new ResolvedControlMapImpl(controlMap));
}

protected <T> StreamingParser<T> getStreamingParser(ControlKey key) throws ProcessingException {
Expand Down Expand Up @@ -271,8 +272,8 @@ protected Coefficients getCoeForSpecies(BaseVdypSpecies<?> species, ControlKey c
protected L requireLayer(P polygon, LayerType type) throws ProcessingException {
if (!polygon.getLayers().containsKey(type)) {
throw validationError(
"Polygon \"%s\" has no %s layer, or that layer has non-positive height or crown closure.", polygon
.getPolygonIdentifier(), type
"Polygon \"%s\" has no %s layer, or that layer has non-positive height or crown closure.",
polygon.getPolygonIdentifier(), type
);
}

Expand All @@ -293,8 +294,8 @@ protected float getPercentTotal(L layer) throws StandProcessingException {
.sum();
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%%.", layer
.getPolygonIdentifier(), LayerType.PRIMARY
"Polygon \"%s\" has %s layer where species entries have a percentage total that does not sum to 100%%.",
layer.getPolygonIdentifier(), LayerType.PRIMARY
);
}
return percentTotal;
Expand Down Expand Up @@ -323,7 +324,7 @@ protected List<S> findPrimarySpecies(Collection<S> allSpecies) {
continue;
}
var groupPrimary = copySpecies(
// groupSpecies.size() is at least 2 so findFirest will not be empty
// groupSpecies.size() is at least 2 so findFirst will not be empty
groupSpecies.stream().sorted(PERCENT_GENUS_DESCENDING).findFirst().orElseThrow(), builder -> {
var total = (float) groupSpecies.stream().mapToDouble(BaseVdypSpecies::getPercentGenus).sum();
builder.percentGenus(total);
Expand Down Expand Up @@ -507,7 +508,7 @@ public int findEmpiricalRelationshipParameterIndex(String specAlias, BecDefiniti
return group;
}

protected VriAdjustInputWriter getVriWriter() {
protected VdypOutputWriter getVriWriter() {
return vriWriter;
}

Expand All @@ -533,8 +534,8 @@ protected float estimatePrimaryBaseArea(

var decayBecAlias = bec.getDecayBec().getAlias();
Coefficients coe = weightedCoefficientSum(
List.of(0, 1, 2, 3, 4, 5), 9, 0, layer.getSpecies()
.values(), BaseVdypSpecies::getFractionGenus, s -> coeMap.get(decayBecAlias, s.getGenus())
List.of(0, 1, 2, 3, 4, 5), 9, 0, layer.getSpecies().values(), BaseVdypSpecies::getFractionGenus,
s -> coeMap.get(decayBecAlias, s.getGenus())
);

float ageToUse = clamp(breastHeightAge, 5f, 350f);
Expand Down Expand Up @@ -847,8 +848,8 @@ protected float estimatePrimaryQuadMeanDiameter(

var decayBecAlias = bec.getDecayBec().getAlias();
Coefficients coe = weightedCoefficientSum(
List.of(0, 1, 2, 3, 4), 8, 0, layer.getSpecies()
.values(), BaseVdypSpecies::getFractionGenus, s -> coeMap.get(decayBecAlias, s.getGenus())
List.of(0, 1, 2, 3, 4), 8, 0, layer.getSpecies().values(), BaseVdypSpecies::getFractionGenus,
s -> coeMap.get(decayBecAlias, s.getGenus())
);

var trAge = log(clamp(breastHeightAge, 5f, 350f));
Expand Down Expand Up @@ -1192,7 +1193,8 @@ public void computeUtilizationComponentsPrimary(
// Calculate tree density components
for (var uc : VdypStartApplication.UTIL_CLASSES) {
treesPerHectareUtil.set(
uc, BaseAreaTreeDensityDiameter
uc,
BaseAreaTreeDensityDiameter
.treesPerHectare(baseAreaUtil.getCoe(uc.index), quadMeanDiameterUtil.get(uc))
);
}
Expand All @@ -1210,7 +1212,8 @@ public void computeUtilizationComponentsPrimary(

for (var uc : VdypStartApplication.UTIL_CLASSES) {
treesPerHectareUtil.setCoe(
uc.index, BaseAreaTreeDensityDiameter
uc.index,
BaseAreaTreeDensityDiameter
.treesPerHectare(baseAreaUtil.getCoe(uc.index), quadMeanDiameterUtil.getCoe(uc.index))
);
}
Expand All @@ -1227,9 +1230,8 @@ public void computeUtilizationComponentsPrimary(

// EMP091
estimationMethods.estimateWholeStemVolume(
UtilizationClass.ALL, adjustCloseUtil.getCoe(
4
), spec.getVolumeGroup(), loreyHeightSpec, quadMeanDiameterUtil, baseAreaUtil, wholeStemVolumeUtil
UtilizationClass.ALL, adjustCloseUtil.getCoe(4), spec.getVolumeGroup(), loreyHeightSpec,
quadMeanDiameterUtil, baseAreaUtil, wholeStemVolumeUtil
);

if (compatibilityVariableMode == CompatibilityVariableMode.ALL) {
Expand All @@ -1244,28 +1246,28 @@ public void computeUtilizationComponentsPrimary(

// EMP092
estimationMethods.estimateCloseUtilizationVolume(
UtilizationClass.ALL, adjustCloseUtil, spec
.getVolumeGroup(), loreyHeightSpec, quadMeanDiameterUtil, wholeStemVolumeUtil, closeVolumeUtil
UtilizationClass.ALL, adjustCloseUtil, spec.getVolumeGroup(), loreyHeightSpec,
quadMeanDiameterUtil, wholeStemVolumeUtil, closeVolumeUtil
);

// EMP093
estimationMethods.estimateNetDecayVolume(
spec.getGenus(), bec.getRegion(), UtilizationClass.ALL, adjustCloseUtil, spec
.getDecayGroup(), vdypLayer.getBreastHeightAge()
.orElse(0f), quadMeanDiameterUtil, closeVolumeUtil, closeVolumeNetDecayUtil
spec.getGenus(), bec.getRegion(), UtilizationClass.ALL, adjustCloseUtil, spec.getDecayGroup(),
vdypLayer.getBreastHeightAge().orElse(0f), quadMeanDiameterUtil, closeVolumeUtil,
closeVolumeNetDecayUtil
);

// EMP094
estimationMethods.estimateNetDecayAndWasteVolume(
bec.getRegion(), UtilizationClass.ALL, adjustCloseUtil, spec
.getGenus(), loreyHeightSpec, quadMeanDiameterUtil, closeVolumeUtil, closeVolumeNetDecayUtil, closeVolumeNetDecayWasteUtil
bec.getRegion(), UtilizationClass.ALL, adjustCloseUtil, spec.getGenus(), loreyHeightSpec,
quadMeanDiameterUtil, closeVolumeUtil, closeVolumeNetDecayUtil, closeVolumeNetDecayWasteUtil
);

if (this.getId().isStart()) {
// EMP095
estimationMethods.estimateNetDecayWasteAndBreakageVolume(
UtilizationClass.ALL, spec
.getBreakageGroup(), quadMeanDiameterUtil, closeVolumeUtil, closeVolumeNetDecayWasteUtil, closeVolumeNetDecayWasteBreakUtil
UtilizationClass.ALL, spec.getBreakageGroup(), quadMeanDiameterUtil, closeVolumeUtil,
closeVolumeNetDecayWasteUtil, closeVolumeNetDecayWasteBreakUtil
);
}
}
Expand Down Expand Up @@ -1316,12 +1318,12 @@ public void computeUtilizationComponentsPrimary(
"For species {}, Species LH (7.5cm+): {}, Species BA (7.5cm+): {}, Weighted LH (7.5cm+): {}"
).log();
vdypLayer.getLoreyHeightByUtilization().scalarInPlace(
UtilizationClass.SMALL, x -> x
+ spec.getLoreyHeightByUtilization().getSmall() * spec.getBaseAreaByUtilization().getSmall()
UtilizationClass.SMALL,
x -> x + spec.getLoreyHeightByUtilization().getSmall() * spec.getBaseAreaByUtilization().getSmall()
);
vdypLayer.getLoreyHeightByUtilization().scalarInPlace(
UtilizationClass.ALL, x -> x
+ spec.getLoreyHeightByUtilization().getAll() * spec.getBaseAreaByUtilization().getAll()
UtilizationClass.ALL,
x -> x + spec.getLoreyHeightByUtilization().getAll() * spec.getBaseAreaByUtilization().getAll()
);
}
{
Expand Down Expand Up @@ -1354,14 +1356,14 @@ protected void computeLayerUtilizationComponentsFromSpecies(VdypLayer vdypLayer)
vdypLayer.getSpecies().values().stream().forEach(spec -> {
var ba = spec.getBaseAreaByUtilization();
hlVector.pairwiseInPlace(
spec.getLoreyHeightByUtilization(), (float x, float y, UtilizationClass uc) -> x
+ y * ba.get(uc)
spec.getLoreyHeightByUtilization(),
(float x, float y, UtilizationClass uc) -> x + y * ba.get(uc)
);
});
var ba = vdypLayer.getBaseAreaByUtilization();
hlVector.scalarInPlace((float x, UtilizationClass uc) -> ba.get(uc) > 0 ? x / ba.get(uc) : x);

// Update percent based on updated areas
// Update percent based on updated areas
vdypLayer.getSpecies().values().stream().forEach(spec -> {
spec.setPercentGenus(100 * spec.getBaseAreaByUtilization().getAll() / ba.getAll());
});
Expand Down Expand Up @@ -1456,44 +1458,38 @@ protected void computeUtilizationComponentsVeteran(VdypLayer vdypLayer, BecDefin
var adjust = new Coefficients(new float[] { 0f, 0f, 0f, 0f }, 1);

// EMP091
EstimationMethods.estimateWholeStemVolume(
controlMap, utilizationClass, volumeAdjustCoe.getCoe(1), vdypSpecies.getVolumeGroup(), hlSp,
estimationMethods.estimateWholeStemVolume(
utilizationClass, volumeAdjustCoe.getCoe(1), vdypSpecies.getVolumeGroup(), hlSp,
quadMeanDiameterUtil, baseAreaUtil, wholeStemVolumeUtil
);

adjust.setCoe(4, volumeAdjustCoe.getCoe(2));
// EMP092
EstimationMethods.estimateCloseUtilizationVolume(
controlMap, utilizationClass, adjust, vdypSpecies.getVolumeGroup(), hlSp, quadMeanDiameterUtil,
estimationMethods.estimateCloseUtilizationVolume(
utilizationClass, adjust, vdypSpecies.getVolumeGroup(), hlSp, quadMeanDiameterUtil,
wholeStemVolumeUtil, closeUtilizationVolumeUtil
);

adjust.setCoe(4, volumeAdjustCoe.getCoe(3));
// EMP093
EstimationMethods.estimateNetDecayVolume(
controlMap, vdypSpecies.getGenus(), bec.getRegion(), utilizationClass, adjust,
vdypSpecies.getDecayGroup(), vdypLayer.getBreastHeightAge().orElse(0f), quadMeanDiameterUtil,
closeUtilizationVolumeUtil, closeUtilizationNetOfDecayUtil
estimationMethods.estimateNetDecayVolume(
vdypSpecies.getGenus(), bec.getRegion(), utilizationClass, adjust, vdypSpecies.getDecayGroup(),
vdypLayer.getBreastHeightAge().orElse(0f), quadMeanDiameterUtil, closeUtilizationVolumeUtil,
closeUtilizationNetOfDecayUtil
);

adjust.setCoe(4, volumeAdjustCoe.getCoe(4));
// EMP094
final var netDecayCoeMap = Utils.<Map<String, Coefficients>>expectParsedControl(
controlMap, ControlKey.VOLUME_NET_DECAY_WASTE, java.util.Map.class
);
final var wasteModifierMap = Utils.<MatrixMap2<String, Region, Float>>expectParsedControl(
controlMap, ControlKey.WASTE_MODIFIERS, ca.bc.gov.nrs.vdyp.model.MatrixMap2.class
);
EstimationMethods.estimateNetDecayAndWasteVolume(
bec.getRegion(), utilizationClass, adjust, vdypSpecies.getGenus(), hlSp, netDecayCoeMap,
wasteModifierMap, quadMeanDiameterUtil, closeUtilizationVolumeUtil,
closeUtilizationNetOfDecayUtil, closeUtilizationNetOfDecayAndWasteUtil
estimationMethods.estimateNetDecayAndWasteVolume(
bec.getRegion(), utilizationClass, adjust, vdypSpecies.getGenus(), hlSp, quadMeanDiameterUtil,
closeUtilizationVolumeUtil, closeUtilizationNetOfDecayUtil,
closeUtilizationNetOfDecayAndWasteUtil
);

if (getId().isStart()) {
// EMP095
EstimationMethods.estimateNetDecayWasteAndBreakageVolume(
controlMap, utilizationClass, vdypSpecies.getBreakageGroup(), quadMeanDiameterUtil,
estimationMethods.estimateNetDecayWasteAndBreakageVolume(
utilizationClass, vdypSpecies.getBreakageGroup(), quadMeanDiameterUtil,
closeUtilizationVolumeUtil, closeUtilizationNetOfDecayAndWasteUtil,
closeUtilizationNetOfDecayWasteAndBreakageUtil
);
Expand Down
Loading

0 comments on commit 0d57ac6

Please sign in to comment.