Skip to content

Commit

Permalink
Code review changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mjunkin committed Sep 10, 2024
1 parent 00fe5fa commit c60977f
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,6 @@ public class ComputationMethods {
.filter(x -> !x.getName().contains("Volume")).toList();
}

private final static UtilizationVector quadMeanDiameterLowerBounds = new UtilizationVector(
0f, 0f, 7.5f, 12.5f, 17.5f, 22.5f
);

private final static UtilizationVector quadMeanDiameterUpperBounds = new UtilizationVector(
0f, 0f, 12.5f, 17.5f, 22.5f, 10000f
);

private final EstimationMethods estimationMethods;

private final VdypApplicationIdentifier context;
Expand Down Expand Up @@ -172,12 +164,7 @@ public void computeUtilizationComponentsPrimary(

float newDqValue = quadMeanDiameterUtil.get(uc)
+ spec.getCvQuadraticMeanDiameter(uc, spec.getLayerType());
quadMeanDiameterUtil.set(
uc,
FloatMath.clamp(
newDqValue, quadMeanDiameterLowerBounds.get(uc), quadMeanDiameterUpperBounds.get(uc)
)
);
quadMeanDiameterUtil.set(uc, FloatMath.clamp(newDqValue, uc.lowBound, uc.highBound));
}

if (basalAreaSumForSpecies > 0.0f) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,8 @@ public void estimateBaseAreaByUtilization(
logit = a0 + a1 * dq;
}
b.set(uc, b.get(uc.previous().get()) * exponentRatio(logit));
if (uc == UtilizationClass.U75TO125 && quadMeanDiameterUtil.getAll() < 12.5f) {
if (uc == UtilizationClass.U75TO125
&& quadMeanDiameterUtil.getAll() < UtilizationClass.U125TO175.lowBound) {
float ba12Max = (1f
- pow( (quadMeanDiameterUtil.getCoe(1) - 7.4f) / (quadMeanDiameterUtil.getAll() - 7.4f), 2f))
* b.getCoe(0);
Expand All @@ -421,8 +422,9 @@ public void estimateBaseAreaByUtilization(
public void estimateQuadMeanDiameterByUtilization(
BecDefinition bec, UtilizationVector quadMeanDiameterUtil, String genus
) throws ProcessingException {
log.atTrace().setMessage("Estimate DQ by utilization class for {} in BEC {}. DQ for all >7.5 is {}")
.addArgument(genus).addArgument(bec.getName()).addArgument(quadMeanDiameterUtil.getAll());
log.atTrace().setMessage("Estimate DQ by utilization class for {} in BEC {}. DQ for all >{} is {}")
.addArgument(genus).addArgument(bec.getName()).addArgument(UtilizationClass.U75TO125.lowBound)
.addArgument(quadMeanDiameterUtil.getAll());

var coeMap = controlMap.getQuadMeanDiameterUtilizationComponentMap();

Expand All @@ -442,22 +444,29 @@ public void estimateQuadMeanDiameterByUtilization(

switch (uc) {
case U75TO125:
if (quadMeanDiameter07 < 7.5001f) {
quadMeanDiameterUtil.setAll(7.5f);
if (quadMeanDiameter07 < UtilizationClass.U75TO125.lowBound + 0.0001f) {
quadMeanDiameterUtil.setAll(UtilizationClass.U75TO125.lowBound);
} else {
log.atDebug().setMessage("DQ = 7.5 + a0 * (1 - exp(a1 / a0*(DQ07 - 7.5) ))**a2' )");

logit = a1 / a0 * (quadMeanDiameter07 - 7.5f);

quadMeanDiameterUtil
.setCoe(uc.index, min(7.5f + a0 * pow(1 - safeExponent(logit), a2), quadMeanDiameter07));
log.atDebug().setMessage("DQ = {} + a0 * (1 - exp(a1 / a0*(DQ07 - {}) ))**a2' )")
.addArgument(UtilizationClass.U75TO125.lowBound)
.addArgument(UtilizationClass.U75TO125.lowBound);

logit = a1 / a0 * (quadMeanDiameter07 - UtilizationClass.U75TO125.lowBound);

quadMeanDiameterUtil.setCoe(
uc.index,
min(
UtilizationClass.U75TO125.lowBound + a0 * pow(1 - safeExponent(logit), a2),
quadMeanDiameter07
)
);
}
break;
case U125TO175, U175TO225:
log.atDebug().setMessage(
"LOGIT = a0 + a1*(SQ07 / 7.5)**a2, DQ = (12.5 or 17.5) + 5 * exp(LOGIT) / (1 + exp(LOGIT))"
);
logit = a0 + a1 * pow(quadMeanDiameter07 / 7.5f, a2);
logit = a0 + a1 * pow(quadMeanDiameter07 / UtilizationClass.U75TO125.lowBound, a2);

quadMeanDiameterUtil.setCoe(uc.index, uc.lowBound + 5f * exponentRatio(logit));
break;
Expand All @@ -470,8 +479,10 @@ public void estimateQuadMeanDiameterByUtilization(

logit = a2 + a1 * pow(quadMeanDiameter07, a3);

quadMeanDiameterUtil
.setCoe(uc.index, max(22.5f, quadMeanDiameter07 + a0 * (1f - exponentRatio(logit))));
quadMeanDiameterUtil.setCoe(
uc.index,
max(UtilizationClass.OVER225.lowBound, quadMeanDiameter07 + a0 * (1f - exponentRatio(logit)))
);
break;
case ALL, SMALL:
throw new IllegalStateException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import static ca.bc.gov.nrs.vdyp.math.FloatMath.abs;
import static ca.bc.gov.nrs.vdyp.math.FloatMath.sqrt;

import java.text.MessageFormat;
import java.util.List;

import ca.bc.gov.nrs.vdyp.application.ProcessingException;
import ca.bc.gov.nrs.vdyp.common_calculators.BaseAreaTreeDensityDiameter;
import ca.bc.gov.nrs.vdyp.model.UtilizationVector;
import ca.bc.gov.nrs.vdyp.model.UtilizationClass;
import ca.bc.gov.nrs.vdyp.model.UtilizationVector;

public class ReconcilationMethods {

Expand Down Expand Up @@ -47,14 +48,23 @@ public static void reconcileComponents(
}

if (abs(baSum - baseAreaUtil.getAll()) > 0.00003 * baSum) {
throw new ProcessingException("Computed base areas for 7.5+ components do not sum to expected total");
throw new ProcessingException(
MessageFormat.format(
"Computed base areas for {}+ components do not sum to expected total",
UtilizationClass.U75TO125.lowBound
)
);
}

float dq0 = BaseAreaTreeDensityDiameter.quadMeanDiameter(baseAreaUtil.getAll(), treesPerHectareUtil.getAll());

if (dq0 < 7.5f) {
if (dq0 < UtilizationClass.U75TO125.lowBound) {
throw new ProcessingException(
"Quadratic mean diameter computed from total base area and trees per hectare is less than 7.5 cm"
MessageFormat.format(
"Quadratic mean diameter computed from total"
+ " base area and trees per hectare is less than {0} cm",
UtilizationClass.U75TO125.lowBound
)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

public class ZipOutputFileResolverTest {

@TempDir
Path outputLocation;

@Test
void testZipOutputFileResolver() throws IOException {

Expand All @@ -34,48 +38,44 @@ void testZipOutputFileResolver() throws IOException {
os.write(String.format("%d", i).getBytes());
}

Path zipFileFromFile = Files.createTempFile(this.getClass().getName(), ".zip");
Path zipFileFromStream = Files.createTempFile(this.getClass().getName(), "-from-stream.zip");
try {
resolver.generate(zipFileFromFile);
Path zipFileFromFile = outputLocation.resolve(this.getClass().getSimpleName() + ".zip");
Path zipFileFromStream = outputLocation.resolve(this.getClass().getSimpleName() + "-from-stream.zip");

resolver.generate(zipFileFromFile);

System.out.println("Output zip file written to " + zipFileFromFile.toString());
System.out.println("Output zip file written to " + zipFileFromFile.toString());

try (ZipFile zip = new ZipFile(zipFileFromFile.toFile())) {
var entries = zip.entries();
try (ZipFile zip = new ZipFile(zipFileFromFile.toFile())) {
var entries = zip.entries();

byte[] buffer = new byte[16];
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
byte[] buffer = new byte[16];
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();

InputStream is = zip.getInputStream(e);
int nBytesRead = is.read(buffer, 0, 10);
assertTrue(nBytesRead == 1);
String fileNumber = e.getName().substring(e.getName().length() - 1, e.getName().length());
assertTrue(new String(Arrays.copyOf(buffer, nBytesRead)).equals(fileNumber));
}
InputStream is = zip.getInputStream(e);
int nBytesRead = is.read(buffer, 0, 10);
assertTrue(nBytesRead == 1);
String fileNumber = e.getName().substring(e.getName().length() - 1, e.getName().length());
assertTrue(new String(Arrays.copyOf(buffer, nBytesRead)).equals(fileNumber));
}
}

InputStream zipByteStream = resolver.generateStream();
Files.write(zipFileFromStream, zipByteStream.readAllBytes());
InputStream zipByteStream = resolver.generateStream();
Files.write(zipFileFromStream, zipByteStream.readAllBytes());

try (ZipFile zip = new ZipFile(zipFileFromStream.toFile())) {
var entries = zip.entries();
try (ZipFile zip = new ZipFile(zipFileFromStream.toFile())) {
var entries = zip.entries();

byte[] buffer = new byte[16];
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
byte[] buffer = new byte[16];
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();

InputStream is = zip.getInputStream(e);
int nBytesRead = is.read(buffer, 0, 10);
assertTrue(nBytesRead == 1);
String fileNumber = e.getName().substring(e.getName().length() - 1, e.getName().length());
assertTrue(new String(Arrays.copyOf(buffer, nBytesRead)).equals(fileNumber));
}
InputStream is = zip.getInputStream(e);
int nBytesRead = is.read(buffer, 0, 10);
assertTrue(nBytesRead == 1);
String fileNumber = e.getName().substring(e.getName().length() - 1, e.getName().length());
assertTrue(new String(Arrays.copyOf(buffer, nBytesRead)).equals(fileNumber));
}
} finally {
Files.delete(zipFileFromFile);
Files.delete(zipFileFromStream);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,8 @@ void findRootsForDiameterAndBaseArea(VdypLayer result, FipLayerPrimary fipLayer,
int i = 0;
for (var spec : result.getSpecies().values()) {
float dqBase = (float) quadMeanDiameterBase[i++];
float dq = 7.5f + (dqBase - 7.5f) * exp((float) rootVec.getEntry(rootVec.getDimension() - 1) / 20f);
float dq = UtilizationClass.U75TO125.lowBound + (dqBase - UtilizationClass.U75TO125.lowBound)
* exp((float) rootVec.getEntry(rootVec.getDimension() - 1) / 20f);
assert dq >= 0;
float ba = baseAreaTotal * spec.getPercentGenus() / 100f;
assert ba >= 0;
Expand Down Expand Up @@ -661,7 +662,7 @@ VdypLayer processLayerAsVeteran(FipPolygon fipPolygon, FipLayer fipLayer) throws
var a1 = coe.getCoe(2);
var a2 = coe.getCoe(3);
float hl = vSpec.getLoreyHeightByUtilization().getCoe(0);
float dq = max(a0 + a1 * pow(hl, a2), 22.5f);
float dq = max(a0 + a1 * pow(hl, a2), UtilizationClass.OVER225.lowBound);
vSpec.getQuadraticMeanDiameterByUtilization().setLarge(dq);
vSpec.getTreesPerHectareByUtilization().setLarge(
BaseAreaTreeDensityDiameter.treesPerHectare(vSpec.getBaseAreaByUtilization().getLarge(), dq)
Expand Down Expand Up @@ -913,8 +914,9 @@ public float estimateMeanVolume(int volumeGroup, float loreyHeight, float quadMe

// These side effects are evil but that's how VDYP7 works.

final float quadMeanDiameter = (float) (7.5
+ (diameterBase[j] - 7.5) * FastMath.exp(point[point.length - 1] / 20d));
final float quadMeanDiameter = (float) (UtilizationClass.U75TO125.lowBound
+ (diameterBase[j] - UtilizationClass.U75TO125.lowBound)
* FastMath.exp(point[point.length - 1] / 20d));
spec.getQuadraticMeanDiameterByUtilization().setAll(quadMeanDiameter);

final float baseArea = (float) (layerBa * percentL1[j] / 100d);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.slf4j.LoggerFactory;

import ca.bc.gov.nrs.vdyp.application.ProcessingException;
import ca.bc.gov.nrs.vdyp.application.RuntimeProcessingException;
import ca.bc.gov.nrs.vdyp.application.StandProcessingException;
import ca.bc.gov.nrs.vdyp.common.ControlKey;
import ca.bc.gov.nrs.vdyp.common.EstimationMethods;
Expand Down Expand Up @@ -968,8 +969,8 @@ boolean growUsingPartialSpeciesDynamics(
}

/**
* Calculate the overall per-species basal area, trees-per-hectare and quad-mean-diameter growth during the growth
* period. The result is stored in <code>end</code>, Utilization Class ALL.
* GRSPBT - Calculate the overall per-species basal area, trees-per-hectare and quad-mean-diameter growth during the
* growth period. The result is stored in <code>end</code>, Utilization Class ALL.
*
* @param baStart per-layer basal area at start of growth period
* @param baDelta per-layer change in basal area during growth period
Expand Down Expand Up @@ -1125,7 +1126,10 @@ void growUsingFullSpeciesDynamics(
totalBasalAreaSkipped += bank.basalAreas[i][UC_ALL_INDEX];
}

float spDqMinimum = Math.max(7.6f, csl.minQuadMeanDiameterLoreyHeightRatio() * spLhAllStart);
float spDqMinimum = Math.max(
UtilizationClass.U75TO125.lowBound + 1.0f,
csl.minQuadMeanDiameterLoreyHeightRatio() * spLhAllStart
);

if (spDqStart + spDqDelta < spDqMinimum) {
spDqDelta = spDqMinimum - spDqStart;
Expand Down Expand Up @@ -1298,16 +1302,16 @@ private static float calculateQuadMeanDiameterDelta(
float a1 = mc.getCoe(2);
float a2 = mc.getCoe(3);

final float dqBase = 7.45f;
final float dqBase = UtilizationClass.U75TO125.lowBound - 0.05f;

float dqRateStart = (spDqStart - dqBase) / (dqStart - dqBase);
float logDqRateStart = FloatMath.log(dqRateStart);
float logDqRateDelta = a0 + a1 * FloatMath.log(spDqStart) + a2 * spLhStart / lhStart;
float dqRateEnd = FloatMath.exp(logDqRateStart + logDqRateDelta);

float spDqEnd = dqRateEnd * (dqStart + dqDelta - dqBase) + dqBase;
if (spDqEnd < 7.51f) {
spDqEnd = 7.51f;
if (spDqEnd < UtilizationClass.U75TO125.lowBound + 0.01f) {
spDqEnd = UtilizationClass.U75TO125.lowBound + 0.01f;
}

float spDqDelta = spDqEnd - spDqStart;
Expand Down Expand Up @@ -1503,11 +1507,8 @@ private void calculateSmallComponentYields(LayerProcessingState lps) throws Proc
spBaSmall = 0.0f;
}
spDqSmall += lps.getCVSmall(speciesIndex, UtilizationClassVariable.QUAD_MEAN_DIAMETER);
if (spDqSmall < 4.01f) {
spDqSmall = 4.01f;
} else if (spDqSmall > 7.49) {
spDqSmall = 7.49f;
}
FloatMath.clamp(spDqSmall, 4.01f, 7.49f);

spLhSmall = 1.3f * (spLhSmall - 1.3f)
* FloatMath.exp(lps.getCVSmall(speciesIndex, UtilizationClassVariable.LOREY_HEIGHT));

Expand Down Expand Up @@ -2343,7 +2344,7 @@ private void writePolygon(VdypPolygon polygon, int startYear, int currentYear, i
break;
}
default:
throw new LambdaProcessingException(
throw new RuntimeProcessingException(
new ProcessingException(
MessageFormat
.format("Invalid value for control variable 4: {0}", controlVariable4Value)
Expand All @@ -2355,10 +2356,10 @@ private void writePolygon(VdypPolygon polygon, int startYear, int currentYear, i
o.setPolygonYear(currentYear);
o.writePolygonWithSpeciesAndUtilization(polygon);
} catch (IOException e) {
throw new LambdaProcessingException(new ProcessingException(e));
throw new RuntimeProcessingException(new ProcessingException(e));
}
});
} catch (LambdaProcessingException e) {
} catch (RuntimeProcessingException e) {
throw e.getCause();
}
}
Expand Down Expand Up @@ -3289,11 +3290,7 @@ void determinePolygonRankings(Collection<List<String>> speciesToCombine) {
int defaultEquationGroup = fps.fcm.getDefaultEquationGroup().get(primarySpeciesName, becZoneAlias);
Optional<Integer> equationModifierGroup = fps.fcm.getEquationModifierGroup()
.get(defaultEquationGroup, inventoryTypeGroup);
if (equationModifierGroup.isPresent()) {
basalAreaGroup1 = equationModifierGroup.get();
} else {
basalAreaGroup1 = defaultEquationGroup;
}
basalAreaGroup1 = equationModifierGroup.orElse(defaultEquationGroup);

int primarySpeciesIndex = bank.speciesIndices[highestPercentageIndex];
int basalAreaGroup3 = defaultEquationGroups[primarySpeciesIndex];
Expand Down

This file was deleted.

Loading

0 comments on commit c60977f

Please sign in to comment.