Skip to content

Commit dce0d2d

Browse files
authored
Stage damage details bug (#1313)
This PR addresses issues in a user's study where the structure details out file did not match the calculated damages. There are two changes related to this - The structure damage details went through a different code path to get WSEs and depths than the compute, and that path did not include the "barely dry adjustment". The new one does. No data values are now 9 feet down from the ground like we'd expect. - The loading of a structure inventory used to check for a FFE, and calculate it from Found. ht. and ground elev only if it didn't exist. This missed a case where the user actually set FFE, but indicated in the UI to calculate the value anyway. This change solved the issue.
1 parent edfa195 commit dce0d2d

3 files changed

Lines changed: 57 additions & 17 deletions

File tree

HEC.FDA.Model/Spatial/StructureFactory.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ public static OperationResult LoadStructuresFromSourceFiles(string pointShapefil
8787

8888
double found_ht = row.TryGetValueAs<double>(map.FoundationHeightCol, DEFAULT_MISSING_NUMBER_VALUE);
8989
double ground_elv = updateGroundElevFromTerrain ? groundelevs[i] : row.TryGetValueAs<double>(map.GroundElevCol, DEFAULT_MISSING_NUMBER_VALUE);
90-
double ff_elev = row.TryGetValueAs<double>(map.FirstFloorElevCol, ground_elv + found_ht);
90+
double ff_elev = map.IsUsingFirstFloorElevation
91+
? row.TryGetValueAs<double>(map.FirstFloorElevCol, DEFAULT_MISSING_NUMBER_VALUE)
92+
: ground_elv + found_ht;
9193

9294
// Optional parameters:
9395
double val_cont = row.TryGetValueAs<double>(map.ContentValueCol, 0);

HEC.FDA.Model/stageDamage/ImpactAreaStageDamage.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -653,16 +653,18 @@ internal List<string> ProduceImpactAreaStructureDetails(Dictionary<int, string>
653653
//this list will be the size of the number of structures + 1 where the first string is the header
654654
List<DeterministicOccupancyType> deterministicOccupancyTypes = Inventory.SampleOccupancyTypes(iteration: 1, computeIsDeterministic: true);
655655
List<string> structureDetails = Inventory.StructureDetails(deterministicOccupancyTypes, impactAreaNames);
656-
//here I need to add to structure details: occ types, impact area,
657-
StagesToStrings(ref structureDetails);
658-
DepthsToStrings(ref structureDetails);
656+
657+
//get corrected WSE data once — same correction the compute path applies
658+
(List<double> profileProbabilities, List<float[]> correctedWSEs) = _HydraulicDataset.GetHydraulicDatasetInFloatsWithProbabilities(Inventory, _HydraulicParentDirectory);
659+
660+
StagesToStrings(correctedWSEs, ref structureDetails);
661+
DepthsToStrings(correctedWSEs, ref structureDetails);
659662

660663
List<List<ConsequenceResult>> consequencesAllHydraulicProfiles = new();
661664

662-
foreach (IHydraulicProfile hydraulicProfile in _HydraulicDataset.HydraulicProfiles)
665+
for (int p = 0; p < correctedWSEs.Count; p++)
663666
{
664-
float[] stagesAtStructures = hydraulicProfile.GetWSE(Inventory.GetPointMs(), _HydraulicDataset.DataSource, _HydraulicParentDirectory);
665-
667+
float[] stagesAtStructures = correctedWSEs[p];
666668

667669
List<ConsequenceResult> consequenceResultList = new();
668670
for (int i = 0; i < stagesAtStructures.Length; i++)
@@ -731,13 +733,12 @@ private void DamagesToStrings(string assetType, List<List<ConsequenceResult>> de
731733
}
732734
}
733735

734-
private void DepthsToStrings(ref List<string> structureDetails)
736+
private void DepthsToStrings(List<float[]> correctedWSEs, ref List<string> structureDetails)
735737
{
736-
foreach (IHydraulicProfile hydraulicProfile in _HydraulicDataset.HydraulicProfiles)
738+
for (int p = 0; p < _HydraulicDataset.HydraulicProfiles.Count; p++)
737739
{
738-
float[] stagesAtStructures = hydraulicProfile.GetWSE(Inventory.GetPointMs(), _HydraulicDataset.DataSource, _HydraulicParentDirectory);
739-
//first, create the header with the probability information on the hydraulic profile
740-
//that will go in structureDetails[0]
740+
float[] stagesAtStructures = correctedWSEs[p];
741+
IHydraulicProfile hydraulicProfile = _HydraulicDataset.HydraulicProfiles[p];
741742
structureDetails[0] += $"DepthAboveFirstFloorOf{hydraulicProfile.Probability}AEP,";
742743
for (int i = 0; i < stagesAtStructures.Length; i++)
743744
{
@@ -746,13 +747,12 @@ private void DepthsToStrings(ref List<string> structureDetails)
746747
}
747748
}
748749

749-
private void StagesToStrings(ref List<string> structureDetails)
750+
private void StagesToStrings(List<float[]> correctedWSEs, ref List<string> structureDetails)
750751
{
751-
foreach (IHydraulicProfile hydraulicProfile in _HydraulicDataset.HydraulicProfiles)
752+
for (int p = 0; p < _HydraulicDataset.HydraulicProfiles.Count; p++)
752753
{
753-
float[] stagesAtStructures = hydraulicProfile.GetWSE(Inventory.GetPointMs(), _HydraulicDataset.DataSource, _HydraulicParentDirectory);
754-
//first, create the header with the probability information on the hydraulic profile
755-
//that will go in structureDetails[0]
754+
float[] stagesAtStructures = correctedWSEs[p];
755+
IHydraulicProfile hydraulicProfile = _HydraulicDataset.HydraulicProfiles[p];
756756
structureDetails[0] += $"StageOf{hydraulicProfile.Probability}AEP,";
757757
for (int i = 0; i < stagesAtStructures.Length; i++)
758758
{

HEC.FDA.ModelTest/unittests/StageDamageShould.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,44 @@ public void StructureDetailsShould(double expectedLength)
277277

278278

279279

280+
[Fact]
281+
public void StructureDetailsShouldNotContainNoDataValues()
282+
{
283+
//Arrange - create profiles where some return -9999 (no data) to simulate dry/projection mismatch
284+
float noData = -9999f;
285+
DummyHydraulicProfile noDataProfile2 = new DummyHydraulicProfile(new float[] { noData, noData, noData, noData }, 0.5);
286+
DummyHydraulicProfile noDataProfile5 = new DummyHydraulicProfile(new float[] { noData, noData, noData, noData }, 0.2);
287+
DummyHydraulicProfile noDataProfile10 = new DummyHydraulicProfile(new float[] { noData, noData, noData, noData }, 0.1);
288+
DummyHydraulicProfile noDataProfile25 = new DummyHydraulicProfile(new float[] { noData, noData, noData, noData }, 0.04);
289+
DummyHydraulicProfile noDataProfile50 = new DummyHydraulicProfile(new float[] { 4, 4, 4, 4 }, .02);
290+
DummyHydraulicProfile noDataProfile100 = new DummyHydraulicProfile(new float[] { 5, 5, 5, 5 }, .01);
291+
DummyHydraulicProfile noDataProfile200 = new DummyHydraulicProfile(new float[] { 6, 6, 6, 6 }, .005);
292+
DummyHydraulicProfile noDataProfile500 = new DummyHydraulicProfile(new float[] { 7, 7, 7, 7 }, .002);
293+
294+
List<IHydraulicProfile> noDataProfiles = new List<IHydraulicProfile>()
295+
{
296+
noDataProfile2, noDataProfile5, noDataProfile10, noDataProfile25,
297+
noDataProfile50, noDataProfile100, noDataProfile200, noDataProfile500
298+
};
299+
HydraulicDataset noDataHydraulicDataset = new HydraulicDataset(noDataProfiles, hydraulicDataSource);
300+
301+
Inventory inventory = CreateInventory();
302+
ImpactAreaStageDamage impactAreaStageDamage = new ImpactAreaStageDamage(impactAreaID, inventory, noDataHydraulicDataset, String.Empty, graphicalFrequency: stageFrequency, usingMockData: true);
303+
List<ImpactAreaStageDamage> impactAreaStageDamageList = new List<ImpactAreaStageDamage>() { impactAreaStageDamage };
304+
ScenarioStageDamage scenarioStageDamage = new ScenarioStageDamage(impactAreaStageDamageList);
305+
Dictionary<int, string> iaNames = new();
306+
iaNames.Add(1, "Test Impact Area");
307+
308+
//Act
309+
List<string> structureDetails = scenarioStageDamage.ProduceStructureDetails(iaNames);
310+
311+
//Assert - no structure detail line should contain -9999
312+
for (int i = 1; i < structureDetails.Count; i++)
313+
{
314+
Assert.DoesNotContain("-9999", structureDetails[i]);
315+
}
316+
}
317+
280318
[Theory]
281319
[InlineData(new float[] { 5, 4, 3 }, new float[] { 10, 9, 8 })]
282320
public void ExtrapolateFromAboveShould(float[] input, float[] expectedResult)

0 commit comments

Comments
 (0)