diff --git a/src/PKSim.Assets.Images/PKSim.Assets.Images.csproj b/src/PKSim.Assets.Images/PKSim.Assets.Images.csproj
index 90ff11eec..dd2e5db54 100644
--- a/src/PKSim.Assets.Images/PKSim.Assets.Images.csproj
+++ b/src/PKSim.Assets.Images/PKSim.Assets.Images.csproj
@@ -26,10 +26,8 @@
-
-
-
-
+
+
diff --git a/src/PKSim.Assets/PKSim.Assets.csproj b/src/PKSim.Assets/PKSim.Assets.csproj
index b53049c6d..96be4a81b 100644
--- a/src/PKSim.Assets/PKSim.Assets.csproj
+++ b/src/PKSim.Assets/PKSim.Assets.csproj
@@ -26,10 +26,8 @@
-
-
-
-
+
+
diff --git a/src/PKSim.Assets/PKSimConstants.cs b/src/PKSim.Assets/PKSimConstants.cs
index 3d5a1dade..2c7a7dd51 100644
--- a/src/PKSim.Assets/PKSimConstants.cs
+++ b/src/PKSim.Assets/PKSimConstants.cs
@@ -906,6 +906,9 @@ public static string MapToSnapshotNotSupportedWithoutContext(string snapshotType
public static string CannotFindSimulationInSnapshot(string simulationName, string project) => CannotFindBuildingBlockInSnapshot(ObjectTypes.Simulation, simulationName, project);
+ public static string SimulationUsedInPlotsAreNotExported(IReadOnlyList simulationNames, string project)
+ => $"{ObjectTypes.Simulation.PluralizeIf(simulationNames)} {simulationNames.ToString(", ", "'")} used in plots {"is".PluralizeIf(simulationNames)} not found in the list of exported simulations for {ObjectTypes.Project} {project}";
+
public static string CannotFindSimulationParameterInSnapshot(string parameterPath, string simulationName, string project) =>
$"Could not find {ObjectTypes.Parameter} with path '{parameterPath}' in {ObjectTypes.Simulation} '{simulationName}' defined in snapshot {project}.";
diff --git a/src/PKSim.BatchTool/PKSim.BatchTool.csproj b/src/PKSim.BatchTool/PKSim.BatchTool.csproj
index 02d124a65..c9e5a53b6 100644
--- a/src/PKSim.BatchTool/PKSim.BatchTool.csproj
+++ b/src/PKSim.BatchTool/PKSim.BatchTool.csproj
@@ -63,8 +63,7 @@
-
-
+
diff --git a/src/PKSim.CLI.Core/PKSim.CLI.Core.csproj b/src/PKSim.CLI.Core/PKSim.CLI.Core.csproj
index 2265c46fe..9b5aaaced 100644
--- a/src/PKSim.CLI.Core/PKSim.CLI.Core.csproj
+++ b/src/PKSim.CLI.Core/PKSim.CLI.Core.csproj
@@ -28,8 +28,7 @@
-
-
+
diff --git a/src/PKSim.CLI.Core/RunOptions/QualificationRunOptions.cs b/src/PKSim.CLI.Core/RunOptions/QualificationRunOptions.cs
index 483256110..84d896239 100644
--- a/src/PKSim.CLI.Core/RunOptions/QualificationRunOptions.cs
+++ b/src/PKSim.CLI.Core/RunOptions/QualificationRunOptions.cs
@@ -16,5 +16,10 @@ public class QualificationRunOptions
/// Should simulation be performed as part of the run?
///
public bool Run { get; set; }
+
+ ///
+ /// Specifies if project files (snapshot and PK-Sim project file should be exported)
+ ///
+ public bool ExportProjectFiles { get; set; }
}
}
\ No newline at end of file
diff --git a/src/PKSim.CLI.Core/Services/QualificationRunner.cs b/src/PKSim.CLI.Core/Services/QualificationRunner.cs
index 1e625dda6..872aeabdb 100644
--- a/src/PKSim.CLI.Core/Services/QualificationRunner.cs
+++ b/src/PKSim.CLI.Core/Services/QualificationRunner.cs
@@ -102,7 +102,9 @@ public async Task RunBatchAsync(QualificationRunOptions runOptions)
{
OutputFolder = projectOutputFolder,
//We run the output, this is for the old matlab implementation where we need xml. Otherwise, we only need pkml export
- ExportMode = runOptions.Run ? SimulationExportMode.Xml | SimulationExportMode.Csv : SimulationExportMode.Pkml
+ ExportMode = runOptions.Run ? SimulationExportMode.Xml | SimulationExportMode.Csv : SimulationExportMode.Pkml,
+
+ Simulations = config.Simulations
};
//Using absolute path for simulation folder. We need them to be relative
@@ -124,13 +126,16 @@ public async Task RunBatchAsync(QualificationRunOptions runOptions)
await _jsonSerializer.Serialize(mapping, config.MappingFile);
_logger.AddDebug($"Project mapping for '{project.Name}' exported to '{config.MappingFile}'", project.Name);
- var projectFile = Path.Combine(config.TempFolder, $"{project.Name}{CoreConstants.Filter.PROJECT_EXTENSION}");
- _workspacePersistor.SaveSession(_workspace, projectFile);
- _logger.AddDebug($"Project saved to '{projectFile}'", project.Name);
+ if (runOptions.ExportProjectFiles)
+ {
+ var projectFile = Path.Combine(config.TempFolder, $"{project.Name}{CoreConstants.Filter.PROJECT_EXTENSION}");
+ _workspacePersistor.SaveSession(_workspace, projectFile);
+ _logger.AddDebug($"Project saved to '{projectFile}'", project.Name);
- var snapshotFile = Path.Combine(config.TempFolder, $"{project.Name}{Constants.Filter.JSON_EXTENSION}");
- await _snapshotTask.ExportModelToSnapshotAsync(project, snapshotFile);
- _logger.AddDebug($"Project snapshot saved to '{snapshotFile}'", project.Name);
+ var snapshotFile = Path.Combine(config.TempFolder, $"{project.Name}{Constants.Filter.JSON_EXTENSION}");
+ await _snapshotTask.ExportModelToSnapshotAsync(project, snapshotFile);
+ _logger.AddDebug($"Project snapshot saved to '{snapshotFile}'", project.Name);
+ }
var end = DateTime.UtcNow;
var timeSpent = end - begin;
@@ -140,7 +145,15 @@ public async Task RunBatchAsync(QualificationRunOptions runOptions)
private PlotMapping[] retrievePlotDefinitionsFrom(Project snapshotProject, QualifcationConfiguration configuration)
{
var plotMappings = configuration.SimulationPlots?.SelectMany(x => retrievePlotDefinitionsForSimulation(x, snapshotProject));
- return plotMappings?.ToArray() ?? Array.Empty();
+ var plotMappingsArray = plotMappings?.ToArray() ?? Array.Empty();
+ var exportedSimulations = configuration.Simulations?.ToArray() ?? Array.Empty();
+ var unmappedSimulations = plotMappingsArray.Select(x => x.Simulation).Distinct().Where(x => !exportedSimulations.Contains(x)).ToList();
+
+ //All simulations referenced in the the plot mapping are also exported. We are good
+ if (!unmappedSimulations.Any())
+ return plotMappingsArray;
+
+ throw new QualificationRunException(SimulationUsedInPlotsAreNotExported(unmappedSimulations, snapshotProject.Name));
}
private void validateInputs(Project snapshotProject, QualifcationConfiguration configuration)
diff --git a/src/PKSim.CLI/Commands/QualificationRunCommand.cs b/src/PKSim.CLI/Commands/QualificationRunCommand.cs
index caf6b2905..d2b77104e 100644
--- a/src/PKSim.CLI/Commands/QualificationRunCommand.cs
+++ b/src/PKSim.CLI/Commands/QualificationRunCommand.cs
@@ -19,13 +19,17 @@ public class QualificationRunCommand : CLICommand
[Option('r', "run", Required = false, HelpText = "Should the qualification runner also run the simulation or simply export the qualification report for further processing. Default is false")]
public bool Run { get; set; } = false;
+ [Option('e', "exp", Required = false, HelpText = "Should the qualification runner also export the project files (snapshot and PK-Sim project file). Default is false")]
+ public bool ExportProjectFiles { get; set; } = false;
+
public override QualificationRunOptions ToRunOptions()
{
return new QualificationRunOptions
{
ConfigurationFile = ConfigurationFile,
Validate = Validate,
- Run = Run
+ Run = Run,
+ ExportProjectFiles = ExportProjectFiles
};
}
@@ -35,7 +39,8 @@ public override string ToString()
LogDefaultOptions(sb);
sb.AppendLine($"Validate: {Validate}");
sb.AppendLine($"Configuration file: {ConfigurationFile}");
- sb.AppendLine($"Run Simulations: {Run}");
+ sb.AppendLine($"Run simulations: {Run}");
+ sb.AppendLine($"Export project files: {ExportProjectFiles}");
return sb.ToString();
}
}
diff --git a/src/PKSim.CLI/PKSim.CLI.csproj b/src/PKSim.CLI/PKSim.CLI.csproj
index e645e56b9..77cc6de7f 100644
--- a/src/PKSim.CLI/PKSim.CLI.csproj
+++ b/src/PKSim.CLI/PKSim.CLI.csproj
@@ -61,10 +61,8 @@
-
-
-
-
+
+
diff --git a/src/PKSim.Core/PKSim.Core.csproj b/src/PKSim.Core/PKSim.Core.csproj
index 7ad2d6955..06d878d5b 100644
--- a/src/PKSim.Core/PKSim.Core.csproj
+++ b/src/PKSim.Core/PKSim.Core.csproj
@@ -30,14 +30,10 @@
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/PKSim.Infrastructure/PKSim.Infrastructure.csproj b/src/PKSim.Infrastructure/PKSim.Infrastructure.csproj
index f8d0940f3..9a559b26a 100644
--- a/src/PKSim.Infrastructure/PKSim.Infrastructure.csproj
+++ b/src/PKSim.Infrastructure/PKSim.Infrastructure.csproj
@@ -41,22 +41,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/PKSim.Infrastructure/Services/ImportObservedDataTask.cs b/src/PKSim.Infrastructure/Services/ImportObservedDataTask.cs
index 07d580b90..96fb87d0b 100644
--- a/src/PKSim.Infrastructure/Services/ImportObservedDataTask.cs
+++ b/src/PKSim.Infrastructure/Services/ImportObservedDataTask.cs
@@ -306,13 +306,13 @@ public IEnumerable PredefinedValuesFor(string name)
return Enumerable.Empty();
}
- public IReadOnlyList DefaultMetaDataCategories => CoreConstants.ObservedData.DefaultProperties;
+ public IReadOnlyList DefaultMetaDataCategories { get; } = CoreConstants.ObservedData.DefaultProperties;
- public IReadOnlyList ReadOnlyMetaDataCategories => new List { };
+ public IReadOnlyList ReadOnlyMetaDataCategories { get; } = new List { };
+
+ public bool MolWeightAlwaysEditable { get; } = false;
- public bool MolWeightEditable => false;
-
- public bool MolWeightVisible => true;
+ public bool MolWeightVisible { get; }= true;
private IEnumerable predefinedGenders => predefinedValuesFor(addPredefinedGenderValues);
diff --git a/src/PKSim.Matlab/PKSim.Matlab.csproj b/src/PKSim.Matlab/PKSim.Matlab.csproj
index ac39f4af9..db0390e73 100644
--- a/src/PKSim.Matlab/PKSim.Matlab.csproj
+++ b/src/PKSim.Matlab/PKSim.Matlab.csproj
@@ -27,8 +27,7 @@
-
-
+
diff --git a/src/PKSim.Presentation/PKSim.Presentation.csproj b/src/PKSim.Presentation/PKSim.Presentation.csproj
index e434a160d..d7726e3e4 100644
--- a/src/PKSim.Presentation/PKSim.Presentation.csproj
+++ b/src/PKSim.Presentation/PKSim.Presentation.csproj
@@ -29,10 +29,8 @@
-
-
-
-
+
+
diff --git a/src/PKSim.R/PKSim.R.csproj b/src/PKSim.R/PKSim.R.csproj
index ba55d079f..34fde684f 100644
--- a/src/PKSim.R/PKSim.R.csproj
+++ b/src/PKSim.R/PKSim.R.csproj
@@ -50,8 +50,7 @@
-
-
+
diff --git a/src/PKSim.UI/PKSim.UI.csproj b/src/PKSim.UI/PKSim.UI.csproj
index 565dbfdff..02ff3ab5b 100644
--- a/src/PKSim.UI/PKSim.UI.csproj
+++ b/src/PKSim.UI/PKSim.UI.csproj
@@ -51,12 +51,9 @@
-
-
-
-
-
-
+
+
+
diff --git a/src/PKSim/PKSim.csproj b/src/PKSim/PKSim.csproj
index 343a7574d..d8ee2c083 100644
--- a/src/PKSim/PKSim.csproj
+++ b/src/PKSim/PKSim.csproj
@@ -76,15 +76,13 @@
-
-
+
-
-
+
diff --git a/tests/PKSim.Matlab.Tests/PKSim.Matlab.Tests.csproj b/tests/PKSim.Matlab.Tests/PKSim.Matlab.Tests.csproj
index a886c0dfa..5d3be46c9 100644
--- a/tests/PKSim.Matlab.Tests/PKSim.Matlab.Tests.csproj
+++ b/tests/PKSim.Matlab.Tests/PKSim.Matlab.Tests.csproj
@@ -23,8 +23,7 @@
-
-
+
diff --git a/tests/PKSim.R.Tests/PKSim.R.Tests.csproj b/tests/PKSim.R.Tests/PKSim.R.Tests.csproj
index 1a9945a01..679927edc 100644
--- a/tests/PKSim.R.Tests/PKSim.R.Tests.csproj
+++ b/tests/PKSim.R.Tests/PKSim.R.Tests.csproj
@@ -23,8 +23,7 @@
-
-
+
diff --git a/tests/PKSim.Tests/CLI/QualificationRunnerSpecs.cs b/tests/PKSim.Tests/CLI/QualificationRunnerSpecs.cs
index f5c2d13b6..15f6e3591 100644
--- a/tests/PKSim.Tests/CLI/QualificationRunnerSpecs.cs
+++ b/tests/PKSim.Tests/CLI/QualificationRunnerSpecs.cs
@@ -18,7 +18,6 @@
using PKSim.Core.Services;
using PKSim.Core.Snapshots;
using PKSim.Core.Snapshots.Services;
-using PKSim.Presentation.Core;
using DataRepository = OSPSuite.Core.Domain.Data.DataRepository;
using Individual = PKSim.Core.Snapshots.Individual;
using Simulation = PKSim.Core.Snapshots.Simulation;
@@ -202,7 +201,7 @@ protected override async Task Context()
_input = new Input {Project = PROJECT_NAME, Name = _simulationName, SectionId = 2, Type = PKSimBuildingBlockType.Simulation, SectionLevel = 5};
_expectedSimulationPath = Path.Combine(_expectedOutputPath, _simulationName);
- _simulationExport = new SimulationMapping { Project = PROJECT_NAME, Simulation = _simulationName, Path = _expectedSimulationPath};
+ _simulationExport = new SimulationMapping {Project = PROJECT_NAME, Simulation = _simulationName, Path = _expectedSimulationPath};
_simulationExports = new[] {_simulationExport};
A.CallTo(() => _exportSimulationRunner.ExportSimulationsIn(_project, A._))
.Invokes(x => _exportOptions = x.GetArgument(1))
@@ -221,6 +220,7 @@ protected override async Task Context()
_project.AddBuildingBlock(_individualSimulation);
_qualificationConfiguration.Inputs = new[] {_input};
+ _qualificationConfiguration.Simulations = new[] {_simulationName,};
_runOptions.Run = true;
}
@@ -254,6 +254,12 @@ public void should_load_the_project_from_snapshot_and_export_its_simulations_to_
_exportOptions.ExportMode.ShouldBeEqualTo(SimulationExportMode.Csv | SimulationExportMode.Xml);
}
+ [Observation]
+ public void should_only_export_the_simulation_required_for_the_qualification()
+ {
+ _exportOptions.Simulations.ShouldBeEqualTo(_qualificationConfiguration.Simulations);
+ }
+
[Observation]
public void should_export_the_mapping_to_the_specified_mapping_file()
{
@@ -685,7 +691,7 @@ protected override async Task Context()
};
_projectSnapshot.Simulations = new[] {simulation};
_qualificationConfiguration.SimulationPlots = new[] {_simulationPlot};
-
+ _qualificationConfiguration.Simulations = new[] {simulation.Name};
A.CallTo(() => _jsonSerializer.Serialize(A._, _qualificationConfiguration.MappingFile))
.Invokes(x => _mapping = x.GetArgument(0));
}
@@ -720,6 +726,35 @@ public void should_create_an_empty_array_for_inputs_if_no_input_were_exported()
}
}
+ public class When_running_the_qualification_runner_with_a_configuration_defining_charts_for_a_simulation_that_is_not_exported : concern_for_QualificationRunnerWithValidConfiguration
+ {
+ private SimulationPlot _simulationPlot;
+ private CurveChart _curveChart;
+
+ protected override async Task Context()
+ {
+ await base.Context();
+ var simulation = new Simulation().WithName("Sim");
+
+
+ _curveChart = new CurveChart();
+ simulation.IndividualAnalyses = new[] {_curveChart};
+ _simulationPlot = new SimulationPlot
+ {
+ SectionId = 2,
+ Simulation = simulation.Name
+ };
+ _projectSnapshot.Simulations = new[] {simulation};
+ _qualificationConfiguration.SimulationPlots = new[] {_simulationPlot};
+ }
+
+ [Observation]
+ public void should_throw_an_exception()
+ {
+ The.Action(() => sut.RunBatchAsync(_runOptions)).ShouldThrowAn();
+ }
+ }
+
public class When_running_the_qualification_runner_with_a_configuration_without_any_mapping_created : concern_for_QualificationRunnerWithValidConfiguration
{
private QualificationMapping _mapping;
diff --git a/tests/PKSim.Tests/PKSim.Tests.csproj b/tests/PKSim.Tests/PKSim.Tests.csproj
index d60b963a3..536cb75b5 100644
--- a/tests/PKSim.Tests/PKSim.Tests.csproj
+++ b/tests/PKSim.Tests/PKSim.Tests.csproj
@@ -21,8 +21,7 @@
-
-
+
diff --git a/tests/PKSim.UI.Starter/PKSim.UI.Starter.csproj b/tests/PKSim.UI.Starter/PKSim.UI.Starter.csproj
index e016e03f9..b663ee8a0 100644
--- a/tests/PKSim.UI.Starter/PKSim.UI.Starter.csproj
+++ b/tests/PKSim.UI.Starter/PKSim.UI.Starter.csproj
@@ -56,15 +56,13 @@
-
-
+
-
-
+
diff --git a/tests/PKSim.UI.Tests/PKSim.UI.Tests.csproj b/tests/PKSim.UI.Tests/PKSim.UI.Tests.csproj
index 86a038139..01556d317 100644
--- a/tests/PKSim.UI.Tests/PKSim.UI.Tests.csproj
+++ b/tests/PKSim.UI.Tests/PKSim.UI.Tests.csproj
@@ -18,10 +18,8 @@
-
-
-
-
+
+