Skip to content

Commit 841fb70

Browse files
#2614 do not create logical container neighborhoods (#2615)
* #2614 do not create logical container neighborhoods * #2614 code review * #2614 remove formula for test failure * #2614 test fix * #2614 valid with warnings * #2614 comments
1 parent 186c1f6 commit 841fb70

File tree

8 files changed

+112
-31
lines changed

8 files changed

+112
-31
lines changed

src/OSPSuite.Assets/UIConstants.cs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -616,12 +616,12 @@ public static string UpdatedMappingsMessage(IEnumerable<(string ParameterName, s
616616
{
617617
sb.AppendLine($" - Output Path: {mapping.OutputPath}");
618618
}
619+
619620
sb.AppendLine();
620621
}
621622

622623
return sb.ToString();
623624
}
624-
625625
}
626626

627627
public static class Diff
@@ -1065,12 +1065,9 @@ public static string ParameterIdentificationFinished(string parameterIdentificat
10651065
return $"Parameter identification '{parameterIdentificationName}' finished in {duration}";
10661066
}
10671067

1068-
10691068
public static string SensitivityCalculationFailed(string parameterIdentificationName, IReadOnlyList<string> errorMessages, string duration = null)
10701069
{
1071-
return string.IsNullOrEmpty(duration) ?
1072-
$"Parameter identification '{parameterIdentificationName}' finished but sensitivity calculation failed.\n\n {string.Join("\n\n", errorMessages)}" :
1073-
$"Parameter identification '{parameterIdentificationName}' finished in {duration} but sensitivity calculation failed.\n\n {string.Join("\n\n", errorMessages)}";
1070+
return string.IsNullOrEmpty(duration) ? $"Parameter identification '{parameterIdentificationName}' finished but sensitivity calculation failed.\n\n {string.Join("\n\n", errorMessages)}" : $"Parameter identification '{parameterIdentificationName}' finished in {duration} but sensitivity calculation failed.\n\n {string.Join("\n\n", errorMessages)}";
10741071
}
10751072

10761073
public static string LinkedParametersIn(string name)
@@ -1316,7 +1313,7 @@ public static string SensitivityAnalysisErrorMessage(IReadOnlyList<string> error
13161313
stringBuilder.AppendLine();
13171314
stringBuilder.AppendLine();
13181315
});
1319-
1316+
13201317
return stringBuilder.ToString();
13211318
}
13221319
}
@@ -1407,7 +1404,7 @@ public static class GroupRowFormat
14071404
public static string Time = "Time";
14081405
public static string Observation = "Observation";
14091406
public static string DeviationLine = "Deviation Lines";
1410-
public static string Undefined = "Undefined";
1407+
public static string Undefined = "Undefined";
14111408
}
14121409

14131410
public static class DeviationLines
@@ -1416,7 +1413,6 @@ public static class DeviationLines
14161413
public static string DeviationLineDescription = "Will create two deviation lines according to the given fold value which has to be greater than 1 (foldValue >1). An x-fold deviation range includes simulated values within x-fold and 1/x-fold of observed values.";
14171414
public static string DeviationLineNameUpper(float foldValue) => $"{foldValue}-fold deviation";
14181415
public static string DeviationLineNameLower(float foldValue) => $"{foldValue}-fold deviation Lower";
1419-
14201416
}
14211417
}
14221418

@@ -1425,9 +1421,9 @@ public static class DeviationLines
14251421
private static string projectNameAndVersionAsString(string versionDisplay, int version) => $"V{versionDisplay} {numberDisplay(version)}";
14261422

14271423
public static string ProjectVersionCannotBeLoaded(
1428-
int projectVersion,
1429-
string oldestSupportedDisplayVersion,
1430-
int oldestSupportedVersion,
1424+
int projectVersion,
1425+
string oldestSupportedDisplayVersion,
1426+
int oldestSupportedVersion,
14311427
string currentSupportedDisplayVersion,
14321428
int currentSupportedVersion,
14331429
string downloadUrl)
@@ -1451,12 +1447,12 @@ public static string ProjectVersionCannotBeLoaded(
14511447
public static string LoadObjectFromSnapshot(string objectType) => $"Load {objectType.ToLowerInvariant()} from snapshot";
14521448
public static string SelectSnapshotExportFile(string objectName, string objectType) => $"Export snapshot for {objectType.ToLowerInvariant()} '{objectName}'";
14531449
public static string DoYouWantToProceed(params string[] messages) => $"WARNING:\n{messages.ToString("\n")}\n\nDo you wish to continue?";
1454-
1450+
14551451
public static readonly string SnapshotOfProjectWithChangedSimulationText = "Some simulations are in a changed state (red icon) and may not be re-imported correctly.";
14561452
public static readonly string SnapshotOfProjectWithChangedSimulation = DoYouWantToProceed(SnapshotOfProjectWithChangedSimulationText);
14571453

14581454
public static string Starting(string type, string name) => $"Starting {type.ToLower()} '{name}'...";
1459-
1455+
14601456
public static string LoadingSnapshot(string snapshotFile, string type) => $"Loading {type} from {ObjectTypes.Snapshot.ToLower()} file '{snapshotFile}'";
14611457

14621458
public static string SnapshotLoaded(string typeToLoad) => $"{typeToLoad} loaded from {ObjectTypes.Snapshot.ToLower()}";
@@ -1466,7 +1462,6 @@ public static string ProjectVersionCannotBeLoaded(
14661462
public static string StartingQualificationPlan(string qualificationPlan) => Starting(ObjectTypes.QualificationPlan, qualificationPlan);
14671463

14681464
public static string StartingQualificationStep(string qualificationStep) => Starting(ObjectTypes.QualificationStep, qualificationStep);
1469-
14701465
}
14711466

14721467
public static class Error
@@ -1511,13 +1506,13 @@ public static string CannotFindSimulationParameterInSnapshot(string parameterPat
15111506

15121507
public static string SnapshotDuplicateEntryByName(string name, string type) =>
15131508
$"Another {type} named '{name}' already exists in the project. Snapshot file is corrupted.";
1514-
1509+
15151510
public static string SnapshotFileMismatch(string desiredType) => $"Snapshot file cannot be used to load a {desiredType.ToLowerInvariant()}.";
15161511

1517-
public static string CannotFindParentContainerWithPath(string parentPath, string containerName, string buildingBlockName, string moduleName) =>
1512+
public static string CannotFindParentContainerWithPath(string parentPath, string containerName, string buildingBlockName, string moduleName) =>
15181513
$"Cannot find parent container '{parentPath}' defined as target of container '{containerName}' in building block '{buildingBlockName}' in module '{moduleName}'";
15191514

1520-
public static string NoUnitColumnValues(string mappingName) => $"No values for the unit were found in the excel column mapped for '{mappingName}' \n";
1515+
public static string NoUnitColumnValues(string mappingName) => $"No values for the unit were found in the excel column mapped for '{mappingName}' \n";
15211516

15221517
public static string ParseErrorMessage(string errors) => $"There were errors while parsing your data: {errors}";
15231518

@@ -1596,7 +1591,7 @@ public static string NameAlreadyExists(string name)
15961591

15971592
public static string NameAlreadyExistsInContainerType(string name, string containerType)
15981593
{
1599-
if(string.IsNullOrEmpty(containerType))
1594+
if (string.IsNullOrEmpty(containerType))
16001595
return NameAlreadyExists(name);
16011596

16021597
return $"'{name}' already exists in {containerType}.";
@@ -1738,6 +1733,7 @@ public static string MoleculeNameExistsInAnotherList(string moleculeName)
17381733
{
17391734
return $"Cannot add molecule '{moleculeName}' into both molecules to include and molecules to exclude lists";
17401735
}
1736+
17411737
public static string BuildingBlockTypeAlreadyAddedToModule(string objectName, string type) => $"BuildingBlock '{type}' for '{objectName}' was already added to module";
17421738

17431739
public const string NotImplemented = "This feature is not implemented yet";
@@ -1888,11 +1884,11 @@ public static string TimeArrayValuesDoesNotMatchFirstIndividual(int id, int inde
18881884

18891885
public static string UnitIsNotDefinedInDimension(string unit, string dimension) => $"Unit '{unit}' is not defined in dimension '{dimension}'.";
18901886

1891-
public static string CouldNotFindNeighborhoodBetween(string container1, string container2, string formulaName, string usingFormulaPath) =>
1887+
public static string CouldNotFindNeighborhoodBetween(string container1, string container2, string formulaName, string usingFormulaPath) =>
18921888
$"Could not find neighborhood between '{container1}' and '{container2}' referenced by formula '{formulaName}' used by '{usingFormulaPath}'";
18931889

18941890
public static string FirstNeighborNotDefinedFor(string neighborhoodName) => $"First neighbor is undefined for neighborhood '{neighborhoodName}'";
1895-
1891+
18961892
public static string SecondNeighborNotDefinedFor(string neighborhoodName) => $"Second neighbor is undefined for neighborhood '{neighborhoodName}'";
18971893

18981894
public const string InParentTagCanOnlyBeUsedWithAndOperator = "IN PARENT tag can only be used with AND operator";
@@ -1920,6 +1916,7 @@ public static string CouldNotFindNeighborhoodBetween(string container1, string c
19201916
public static string SimulationUsedInPlotsAreNotExported(IReadOnlyList<string> simulationNames, string project)
19211917
=> $"{ObjectTypes.Simulation.PluralizeIf(simulationNames)} {simulationNames.ToString(", ", "'")} used in plots {"is".PluralizeIf(simulationNames)} not found in the list of exported simulations for {ObjectTypes.Project} {project}";
19221918

1919+
public static string NeighborIsLogical(string neighborName, string neighborhoodName) => $"Container {neighborName} is defined as logical for neighborhood '{neighborhoodName}'";
19231920

19241921
public static class SensitivityAnalysis
19251922
{
@@ -1997,6 +1994,7 @@ private static string listErrorMessages(IReadOnlyList<string> runResultErrorMess
19971994
{
19981995
sb.AppendLine($"- {errorMessage}");
19991996
}
1997+
20001998
return sb.ToString();
20011999
}
20022000

@@ -2223,13 +2221,12 @@ public static class Warning
22232221
public static string LargeNumberOfOutputPoints(int numberOfPoints) =>
22242222
$"The selected output resolution will generate {numberOfPoints} points and may severely impact the software performance.\nAre you sure you want to run with these setting? If not, consider changing output resolution in simulations settings";
22252223

2226-
public static string NeighborhoodWasNotFoundInModel(string neighborhoodName, string buildingBlockName) => $"The neighborhood '{neighborhoodName}' from building block '{buildingBlockName}' was not added to the simulation";
2224+
public static string NeighborhoodWasNotFoundInModel(string neighborhoodName, string buildingBlockName) => $"The neighborhood '{neighborhoodName}' from building block '{buildingBlockName}' was not added to the simulation because it is not defined or at least one of the containers is logical";
22272225

22282226
public static string UnitNotFoundInDimensionForParameter(string unit, string dimension, string parameterName)
22292227
{
22302228
return $"Unit '{unit}' not found for parameter {parameterName} with dimension '{dimension}'";
22312229
}
2232-
22332230
}
22342231

22352232
public static class RibbonCategories

src/OSPSuite.Core/Domain/Mappers/NeighborhoodBuilderToNeighborhoodMapper.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using System.Collections.Generic;
32
using System.Linq;
43
using OSPSuite.Core.Domain.Builder;
@@ -40,7 +39,7 @@ public NeighborhoodBuilderToNeighborhoodMapper(
4039
IObjectBaseFactory objectBaseFactory,
4140
IContainerBuilderToContainerMapper containerMapper,
4241
IKeywordReplacerTask keywordReplacerTask,
43-
ICloneManagerForModel cloneManagerForModel,
42+
ICloneManagerForModel cloneManagerForModel,
4443
IParameterBuilderToParameterMapper parameterMapper, IEntityTracker entityTracker)
4544
{
4645
_objectBaseFactory = objectBaseFactory;
@@ -63,8 +62,8 @@ public Neighborhood MapFrom(NeighborhoodBuilder neighborhoodBuilder, IReadOnlyLi
6362
neighborhood.FirstNeighbor = resolveReference(model, neighborhoodBuilder.FirstNeighborPath, replacementContext);
6463
neighborhood.SecondNeighbor = resolveReference(model, neighborhoodBuilder.SecondNeighborPath, replacementContext);
6564

66-
//At least one neighbor cannot be found. We are ignoring this neighborhood
67-
if (!neighborhood.IsDefined)
65+
//At least one neighbor cannot be found or is a logical container. We are ignoring this neighborhood
66+
if (!neighborhood.IsDefined || !neighborhood.HasOnlyPhysicalNeighbors)
6867
return null;
6968

7069
if (neighborhoodBuilder.MoleculeProperties != null)

src/OSPSuite.Core/Domain/Neighborhood.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,7 @@ public override void UpdatePropertiesFrom(IUpdatable source, ICloneManager clone
7676
}
7777

7878
public bool IsDefined => FirstNeighbor != null && SecondNeighbor != null;
79+
80+
public bool HasOnlyPhysicalNeighbors => IsDefined && FirstNeighbor.Mode == ContainerMode.Physical && SecondNeighbor.Mode == ContainerMode.Physical;
7981
}
8082
}

src/OSPSuite.Core/Domain/Services/SpatialStructureValidator.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@ private void validateNeighborhood(Neighborhood neighborhood, IContainer root)
3535
if (neighborhood.FirstNeighbor == null)
3636
_result.AddMessage(NotificationType.Error, neighborhood, Error.FirstNeighborNotDefinedFor(neighborhood.Name));
3737

38-
3938
if (neighborhood.SecondNeighbor == null)
4039
_result.AddMessage(NotificationType.Error, neighborhood, Error.SecondNeighborNotDefinedFor(neighborhood.Name));
40+
41+
if (neighborhood.FirstNeighbor?.Mode == ContainerMode.Logical)
42+
_result.AddMessage(NotificationType.Warning, neighborhood, Error.NeighborIsLogical(neighborhood.FirstNeighbor.Name, neighborhood.Name));
43+
44+
if (neighborhood.SecondNeighbor?.Mode == ContainerMode.Logical)
45+
_result.AddMessage(NotificationType.Warning, neighborhood, Error.NeighborIsLogical(neighborhood.SecondNeighbor.Name, neighborhood.Name));
4146
}
4247
}
4348
}

tests/OSPSuite.Core.IntegrationTests/ModelConstructorIntegrationTests.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ public void should_track_the_parameter_updated_by_a_formula_accordingly()
466466
var parameterValue = parameterValues.First(x => x.Name == parameter.Name);
467467
var entitySource = _simulationBuilder.SimulationEntitySourceFor(parameter);
468468
entitySource.SourcePath.ShouldBeEqualTo(parameterValue.Path);
469-
entitySource.SimulationEntityPath.ShouldBeEqualTo(new[] {ORGANISM, Bone, Cell, "FormulaParameterOverwritten"}.ToPathString());
469+
entitySource.SimulationEntityPath.ShouldBeEqualTo(new[] { ORGANISM, Bone, Cell, "FormulaParameterOverwritten" }.ToPathString());
470470
}
471471

472472
[Observation]
@@ -535,8 +535,15 @@ protected override void Context()
535535
var initialCondition = simulationBuilder.InitialConditions.First();
536536
var physicalContainer = simulationBuilder.SpatialStructureAndMergeBehaviors.SelectMany(x => x.spatialStructure.TopContainers)
537537
.Select(x => initialCondition.ContainerPath.TryResolve<IContainer>(x)).First(x => x != null);
538-
539538
physicalContainer.Mode = ContainerMode.Logical;
539+
540+
// "Organism|ArterialBlood|Plasma" -> is being set to Logical explicitly on the previous line,
541+
// as we now are not creating neighborhoods from logical containers, a further validation ends up on this exception:
542+
// Could not find neighborhood between 'MyModel|Organism|ArterialBlood|Plasma' and 'MyModel|Organism|Bone|Plasma'
543+
// referenced by formula 'FormulaReferencingNBH' used by 'MyModel|Organism|ArterialBlood|Plasma|RefParam'
544+
// This parameter has to be removed since the validation will make this fail before testing the initial condition.
545+
var parameterWithFormula = physicalContainer.Children.FirstOrDefault(x => x.Name == "RefParam") as Parameter;
546+
physicalContainer.RemoveChild(parameterWithFormula);
540547
}
541548

542549
[Observation]

tests/OSPSuite.Core.IntegrationTests/ModuleIntegrationTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ internal class When_running_the_case_study_for_module_integration : concern_for_
4343
public void should_return_a_successful_validation_with_warning()
4444
{
4545
_result.ValidationResult.ValidationState.ShouldBeEqualTo(ValidationState.ValidWithWarnings, _result.ValidationResult.Messages.Select(m => m.Text).ToString("\n"));
46-
_result.ValidationResult.Messages.Single().Text.ShouldBeEqualTo(Warning.NeighborhoodWasNotFoundInModel("does_not_match_existing", "Module1 - SPATIAL STRUCTURE MODULE 1"));
46+
_result.ValidationResult.Messages.FirstOrDefault(x => x.Text.Equals(Warning.NeighborhoodWasNotFoundInModel("does_not_match_existing", "Module1 - SPATIAL STRUCTURE MODULE 1"))).ShouldNotBeNull();
47+
_result.ValidationResult.Messages.FirstOrDefault(x => x.Text.Equals(Warning.NeighborhoodWasNotFoundInModel("not_physical", "Module1 - SPATIAL STRUCTURE MODULE 1"))).ShouldNotBeNull();
4748
}
4849

4950
[Observation]
@@ -103,7 +104,7 @@ public void should_track_the_parameter_accordingly()
103104
_simulationBuilder.SimulationEntitySourceFor(parameter3).SourcePath.ShouldBeEqualTo(parameter3Module2.EntityPath());
104105
}
105106

106-
protected override Func<ModuleHelperForSpecs, SimulationConfiguration> SimulationConfigurationBuilder() => x => x.CreateSimulationConfiguration();
107+
protected override Func<ModuleHelperForSpecs, SimulationConfiguration> SimulationConfigurationBuilder() => x => x.CreateSimulationConfigurationWithLogicalNeighborhood();
107108
}
108109

109110
internal class When_running_the_case_study_for_module_integration_with_merge_behavior_extend_for_neighborhood : concern_for_ModuleIntegration

tests/OSPSuite.Core.Tests/Domain/SpatialStructureValidatorSpecs.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,14 @@ protected override void Context()
5252
_neighborhood1.FirstNeighbor = _liver;
5353
_neighborhood1.SecondNeighbor = _kidney;
5454

55+
_neighborhood1.FirstNeighbor.Mode = ContainerMode.Physical;
56+
_neighborhood1.SecondNeighbor.Mode = ContainerMode.Physical;
57+
5558
_neighborhood2.FirstNeighbor = _kidney;
5659
_neighborhood2.SecondNeighbor = _heart;
60+
_neighborhood2.FirstNeighbor.Mode = ContainerMode.Physical;
61+
_neighborhood2.SecondNeighbor.Mode = ContainerMode.Physical;
62+
5763
}
5864

5965
protected override void Because()
@@ -93,4 +99,36 @@ public void should_return_an_valid_validation_result()
9399
_result.ValidationState.ShouldBeEqualTo(ValidationState.Invalid);
94100
}
95101
}
102+
103+
internal class When_validating_a_model_for_which_some_neighborhoods_are_not_physical : concern_for_SpatialStructureValidator
104+
{
105+
private ValidationResult _result;
106+
107+
protected override void Context()
108+
{
109+
base.Context();
110+
_neighborhood1.FirstNeighbor = _liver;
111+
_neighborhood1.SecondNeighbor = _kidney;
112+
113+
_neighborhood1.FirstNeighbor.Mode = ContainerMode.Logical;
114+
_neighborhood1.SecondNeighbor.Mode = ContainerMode.Physical;
115+
116+
_neighborhood2.FirstNeighbor = _kidney;
117+
_neighborhood2.SecondNeighbor = _heart;
118+
_neighborhood2.FirstNeighbor.Mode = ContainerMode.Physical;
119+
_neighborhood2.SecondNeighbor.Mode = ContainerMode.Physical;
120+
121+
}
122+
123+
protected override void Because()
124+
{
125+
_result = sut.Validate(_modelConfiguration);
126+
}
127+
128+
[Observation]
129+
public void should_return_a_valid_validation_result()
130+
{
131+
_result.ValidationState.ShouldBeEqualTo(ValidationState.ValidWithWarnings);
132+
}
133+
}
96134
}

0 commit comments

Comments
 (0)