diff --git a/src/Vts.Desktop.Test/Vts.Desktop.Test.csproj b/src/Vts.Desktop.Test/Vts.Desktop.Test.csproj index 215e244bd..fa39bf078 100644 --- a/src/Vts.Desktop.Test/Vts.Desktop.Test.csproj +++ b/src/Vts.Desktop.Test/Vts.Desktop.Test.csproj @@ -211,6 +211,9 @@ MonteCarlo\DataStructuresValidation\DetectorInputs\dMCdROfRhodMusDetectorInputValidationTests.cs + + MonteCarlo\DataStructuresValidation\PostProcessorInputs\PostProcessorInputValidationTests.cs + MonteCarlo\DataStructuresValidation\SimulationInputValidationTests.cs diff --git a/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMuaDetectorInputValidationTests.cs b/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMuaDetectorInputValidationTests.cs index 7867afc75..29adf3a83 100644 --- a/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMuaDetectorInputValidationTests.cs +++ b/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMuaDetectorInputValidationTests.cs @@ -12,7 +12,8 @@ namespace Vts.Test.MonteCarlo.DataStructuresValidation.DetectorInputs public class dMCdROfRhodMuaDetectorInputValidationTests { /// - /// Test to check that layers that overlap. + /// Can only run dMC with one tissue region at the present. + /// Check that detector input does not specify more than 1 region /// [Test] public void validate_only_one_perturbed_region_index_specified() diff --git a/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMusDetectorInputValidationTests.cs b/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMusDetectorInputValidationTests.cs index df9f924e9..075a18335 100644 --- a/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMusDetectorInputValidationTests.cs +++ b/src/Vts.Test/MonteCarlo/DataStructuresValidation/DetectorInputs/dMCdROfRhodMusDetectorInputValidationTests.cs @@ -12,7 +12,8 @@ namespace Vts.Test.MonteCarlo.DataStructuresValidation.DetectorInputs public class dMCdROfRhodMusDetectorInputValidationTests { /// - /// Test to check that layers that overlap. + /// Can only run dMC with one tissue region at the present. + /// Check that detector input does not specify more than 1 region /// [Test] public void validate_only_one_perturbed_region_index_specified() diff --git a/src/Vts.Test/MonteCarlo/DataStructuresValidation/PostProcessorInputs/PostProcessorInputValidationTests.cs b/src/Vts.Test/MonteCarlo/DataStructuresValidation/PostProcessorInputs/PostProcessorInputValidationTests.cs new file mode 100644 index 000000000..1154cd709 --- /dev/null +++ b/src/Vts.Test/MonteCarlo/DataStructuresValidation/PostProcessorInputs/PostProcessorInputValidationTests.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Vts.Common; +using Vts.MonteCarlo; +using Vts.MonteCarlo.Detectors; +using Vts.MonteCarlo.Tissues; + +namespace Vts.Test.MonteCarlo.DataStructuresValidation.PostProcessorInputs +{ + [TestFixture] + public class PostProcessorInputValidationTests + { + /// + /// Test to check that post-processor perturbed OPs are not negative + /// + [Test] + public void validate_tissue_optical_properties_are_non_negative() + { + var tissueInput = new MultiLayerTissueInput( + new ITissueRegion[] + { + new LayerTissueRegion( + new DoubleRange(double.NegativeInfinity, 0.0), + new OpticalProperties( 0.0, 1e-10, 1.0, 1.0)), + new LayerTissueRegion( + new DoubleRange(0.0, 100.0), + new OpticalProperties(-1.0, 1.0, 0.8, 1.4)), // make mua negative + new LayerTissueRegion( + new DoubleRange(100.0, double.PositiveInfinity), + new OpticalProperties(0.0, 1e-10, 1.0, 1.0)) + }); + var input = new PostProcessorInput( + new List() + { + new pMCROfRhoDetectorInput() + { + Rho=new DoubleRange(0.0, 100.0), + // set perturbed ops to reference ops + PerturbedOps = new List() + { + tissueInput.Regions[0].RegionOP, + tissueInput.Regions[1].RegionOP, + tissueInput.Regions[2].RegionOP + }, + PerturbedRegionsIndices = new List() { 1 } + } + }, + "","","" + ); + var result = PostProcessorInputValidation.ValidateInput(input,""); + Assert.IsFalse(result.IsValid); + } + } +} diff --git a/src/Vts.Test/MonteCarlo/DataStructuresValidation/SimulationInputValidationTests.cs b/src/Vts.Test/MonteCarlo/DataStructuresValidation/SimulationInputValidationTests.cs index 8b4298309..62e7b436c 100644 --- a/src/Vts.Test/MonteCarlo/DataStructuresValidation/SimulationInputValidationTests.cs +++ b/src/Vts.Test/MonteCarlo/DataStructuresValidation/SimulationInputValidationTests.cs @@ -120,5 +120,28 @@ public void validate_voxel_tissue_and_ROfFx_detectors_are_not_defined_together() var result = SimulationInputValidation.ValidateInput(input); Assert.IsFalse(result.IsValid); } + [Test] + public void validate_tissue_optical_properties_are_non_negative() + { + // generate input embedded ellipsoid tissue and cylindrical detector + var input = new SimulationInput() + { + TissueInput = new MultiLayerTissueInput( + new ITissueRegion[] + { + new LayerTissueRegion( + new DoubleRange(double.NegativeInfinity, 0.0), + new OpticalProperties( 0.0, 1e-10, 1.0, 1.0)), + new LayerTissueRegion( + new DoubleRange(0.0, 100.0), + new OpticalProperties(-1.0, 1.0, 0.8, 1.4)), // make mua negative + new LayerTissueRegion( + new DoubleRange(100.0, double.PositiveInfinity), + new OpticalProperties(0.0, 1e-10, 1.0, 1.0)) + }) + }; + var result = SimulationInputValidation.ValidateInput(input); + Assert.IsFalse(result.IsValid); + } } } diff --git a/src/Vts/MonteCarlo/DataStructuresValidation/PostProcessorInputs/PostProcessorInputValidation.cs b/src/Vts/MonteCarlo/DataStructuresValidation/PostProcessorInputs/PostProcessorInputValidation.cs index deecc794e..86db6eb55 100644 --- a/src/Vts/MonteCarlo/DataStructuresValidation/PostProcessorInputs/PostProcessorInputValidation.cs +++ b/src/Vts/MonteCarlo/DataStructuresValidation/PostProcessorInputs/PostProcessorInputValidation.cs @@ -2,7 +2,6 @@ using System.IO; using System.Linq; using Vts.MonteCarlo.DataStructuresValidation; -using Vts.MonteCarlo.Extensions; namespace Vts.MonteCarlo { @@ -21,6 +20,12 @@ public class PostProcessorInputValidation public static ValidationResult ValidateInput(PostProcessorInput input, string inpath) { ValidationResult tempResult; + tempResult = ValidateTissueOpticalProperties(input.DetectorInputs); + if (!tempResult.IsValid) + + { + return tempResult; + } tempResult = ValidateInputFolderExistence(Path.Combine(inpath, input.InputFolder)); if (!tempResult.IsValid) @@ -97,5 +102,31 @@ private static ValidationResult ValidateSimulationInputExistence( "PostProcessorInput: SimulationInput filename does not exist", "check that a SimulationInput file exists in inputFolder"); } + private static ValidationResult ValidateTissueOpticalProperties( + IList detectorInputs) + { + // for all pMC detectors, check that perturbed OPs are non-negative (g could be neg) + foreach (var detectorInput in detectorInputs) + { + if (detectorInput.TallyDetails.IspMCReflectanceTally) + { + var ops = ((dynamic)detectorInput).PerturbedOps; + foreach (var op in ops) + { + if ((op.Mua < 0.0) || (op.Musp < 0.0) || (op.N < 0.0)) + { + + return new ValidationResult( + false, + "Tissue optical properties mua, mus', n need to be non-negative", + "Please check optical properties"); + } + } + } + } + return new ValidationResult( + true, + "PostProcessorInput: perturbed optical properties are all non-negative"); + } } } diff --git a/src/Vts/MonteCarlo/DataStructuresValidation/SimulationInputValidation.cs b/src/Vts/MonteCarlo/DataStructuresValidation/SimulationInputValidation.cs index b44070c63..0727e6584 100644 --- a/src/Vts/MonteCarlo/DataStructuresValidation/SimulationInputValidation.cs +++ b/src/Vts/MonteCarlo/DataStructuresValidation/SimulationInputValidation.cs @@ -72,6 +72,16 @@ private static ValidationResult ValidateSourceInput(ISourceInput sourceInput, IT private static ValidationResult ValidateTissueInput(ITissueInput tissueInput) { + // for all types of tissues, check that OPs are non-negative (g could be neg) + if (tissueInput.Regions.Any(r => r.RegionOP.Mua < 0.0) || + tissueInput.Regions.Any(r => r.RegionOP.Musp < 0.0) || + tissueInput.Regions.Any(r => r.RegionOP.N < 0.0)) + { + return new ValidationResult( + false, + "Tissue optical properties mua, mus', n need to be non-negative", + "Please check optical properties"); + } if (tissueInput is MultiLayerTissueInput) { return MultiLayerTissueInputValidation.ValidateInput(tissueInput);