示例#1
0
        public void MoveUpDown()
        {
            CommandHistory commandHistory = new CommandHistory();
            Model          modelToMove    = simulations.FindByPath("APS14.Factors.Permutation.NRate")?.Value as Model;

            MoveModelUpDownCommand moveCommand = new MoveModelUpDownCommand(modelToMove, true, null);

            moveCommand.Do(commandHistory);

            Model modelToMove2 = simulations.FindByPath("APS14.Factors.NRate")?.Value as Model;

            Assert.AreEqual(simulations.Children[2].Children[0].Children[0].Children[0].Name, "NRate");
            Assert.AreEqual(simulations.Children[2].Children[0].Children[0].Children[0].Children.Count, 4);
        }
示例#2
0
文件: EditFile.cs 项目: lie112/ApsimX
        /// <summary>
        /// Edits a single apsimx file according to the changes specified in the config file.
        /// </summary>
        /// <param name="file">An .apsimx file.</param>
        /// <param name="factors">Factors to apply to the file.</param>
        public static Simulations ApplyChanges(Simulations file, IEnumerable <CompositeFactor> factors)
        {
            foreach (CompositeFactor factor in factors)
            {
                IVariable variable = file.FindByPath(factor.Paths[0]);
                if (variable == null)
                {
                    throw new Exception($"Invalid path: {factor.Paths[0]}");
                }

                string value        = factor.Values[0].ToString();
                string absolutePath = null;
                try
                {
                    if (!value.Contains(":"))
                    {
                        absolutePath = PathUtilities.GetAbsolutePath(value, Directory.GetCurrentDirectory());
                    }
                }
                catch
                {
                }

                string[] parts = value.Split(';');
                if (parts != null && parts.Length == 2)
                {
                    string fileName         = parts[0];
                    string absoluteFileName = PathUtilities.GetAbsolutePath(fileName, Directory.GetCurrentDirectory());
                    string modelPath        = parts[1];

                    if (File.Exists(fileName))
                    {
                        ReplaceModelFromFile(file, factor.Paths[0], fileName, modelPath);
                    }
                    else if (File.Exists(absoluteFileName))
                    {
                        ReplaceModelFromFile(file, factor.Paths[0], absoluteFileName, modelPath);
                    }
                    else
                    {
                        ChangeVariableValue(variable, value);
                    }
                }
                else if (File.Exists(value) && variable.Value is IModel)
                {
                    ReplaceModelFromFile(file, factor.Paths[0], value, null);
                }
                else if (File.Exists(absolutePath) && variable.Value is IModel)
                {
                    ReplaceModelFromFile(file, factor.Paths[0], absolutePath, null);
                }
                else
                {
                    ChangeVariableValue(variable, value);
                }
            }
            return(file);
        }
示例#3
0
        /// <summary>
        /// Generate the auto-documentation at the given output path.
        /// </summary>
        /// <param name="path">Path to which the file will be generated.</param>
        public void Generate(string path)
        {
            // This document instance will be used to write all of the input files'
            // documentation to a single document.
            Document   document = PdfWriter.CreateStandardDocument();
            PdfBuilder builder  = new PdfBuilder(document, options);

            // Read the file.
            Simulations rootNode = FileFormat.ReadFromFile <Simulations>(filePath, e => throw e, false);

            // Attempt to resolve the model path inside the file.
            IVariable variable = rootNode.FindByPath(modelPath);

            // Ensure that we found a model.
            object result = variable?.Value;
            IModel model  = result as IModel;

            if (variable == null)
            {
                throw new Exception($"Failed to resolve path {modelPath} in file {filePath}");
            }
            if (result == null)
            {
                throw new Exception($"When resolving path {modelPath} in file {filePath}: {modelPath} resolved to null");
            }
            if (model == null)
            {
                throw new Exception($"Attempted to read model from path {modelPath} in file {filePath}, but the path resolves to an object of type {result.GetType()}");
            }

            // Attempt to resolve links for the given model.
            rootNode.Links.Resolve(model, true, true, false);

            // Document the model.
            IEnumerable <ITag> tags = model.Document();

            // Document the rest of the file afterwards if necessary.
            if (documentRestOfFile)
            {
                tags = tags.AppendMany(rootNode.Document());
            }

            // Write tags to document.
            foreach (ITag tag in tags)
            {
                builder.Write(tag);
            }

            // Write bibliography at end of document.
            builder.WriteBibliography();

            // Write to PDF file at the specified path.
            string outFile = Path.Combine(path, OutputFileName);

            PdfWriter.Save(document, outFile);
        }
示例#4
0
        /// <summary>
        /// Replace a model with a model from another file.
        /// </summary>
        /// <param name="topLevel">The top-level model of the file being modified.</param>
        /// <param name="modelToReplace">Path to the model which is to be replaced.</param>
        /// <param name="replacementFile">Path of the .apsimx file containing the model which will be inserted.</param>
        /// <param name="replacementPath">Path to the model in replacementFile which will be used to replace a model in topLevel.</param>
        private static void ReplaceModelFromFile(Simulations topLevel, string modelToReplace, string replacementFile, string replacementPath)
        {
            IModel toBeReplaced = topLevel.FindByPath(modelToReplace)?.Value as IModel;

            if (toBeReplaced == null)
            {
                throw new Exception($"Unable to find model which is to be replaced ({modelToReplace}) in file {topLevel.FileName}");
            }

            IModel extFile = FileFormat.ReadFromFile <IModel>(replacementFile, out List <Exception> errors);

            if (errors?.Count > 0)
            {
                throw new Exception($"Error reading replacement file {replacementFile}", errors[0]);
            }

            IModel replacement;

            if (string.IsNullOrEmpty(replacementPath))
            {
                replacement = extFile.FindAllDescendants().Where(d => toBeReplaced.GetType().IsAssignableFrom(d.GetType())).FirstOrDefault();
                if (replacement == null)
                {
                    throw new Exception($"Unable to find replacement model of type {toBeReplaced.GetType().Name} in file {replacementFile}");
                }
            }
            else
            {
                replacement = extFile.FindByPath(replacementPath)?.Value as IModel;
                if (replacement == null)
                {
                    throw new Exception($"Unable to find model at path {replacementPath} in file {replacementFile}");
                }
            }

            IModel parent = toBeReplaced.Parent;
            int    index  = parent.Children.IndexOf((Model)toBeReplaced);

            parent.Children.Remove((Model)toBeReplaced);

            // Need to call Structure.Add to add the model to the parent.
            Structure.Add(replacement, parent);

            // Move the new model to the index in the list at which the
            // old model previously resided.
            parent.Children.Remove((Model)replacement);
            parent.Children.Insert(index, (Model)replacement);
        }
示例#5
0
        public void TestEditOption()
        {
            string[] changes = new string[]
            {
                "[Clock].StartDate = 2019-1-20",
                ".Simulations.Sim1.Clock.EndDate = 3/20/2019",
                ".Simulations.Sim2.Enabled = false",
                ".Simulations.Sim1.Field.Soil.Thickness[1] = 500",
                ".Simulations.Sim1.Field.Soil.Thickness[2] = 2500",
                ".Simulations.Sim2.Name = SimulationVariant35",
            };
            string configFileName = Path.GetTempFileName();

            File.WriteAllLines(configFileName, changes);

            string apsimxFileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx");
            string text           = ReflectionUtilities.GetResourceAsString("UnitTests.BasicFile.apsimx");

            // Check property values at this point.
            Simulations sims = FileFormat.ReadFromString <Simulations>(text, out List <Exception> errors);

            if (errors != null && errors.Count > 0)
            {
                throw errors[0];
            }

            Clock      clock = sims.FindInScope <Clock>();
            Simulation sim1  = sims.FindInScope <Simulation>();
            Simulation sim2  = sims.FindInScope("Sim2") as Simulation;
            Soil       soil  = sims.FindByPath(".Simulations.Sim1.Field.Soil")?.Value as Soil;

            // Check property values - they should be unchanged at this point.
            DateTime start = new DateTime(2003, 11, 15);

            Assert.AreEqual(start.Year, clock.StartDate.Year);
            Assert.AreEqual(start.DayOfYear, clock.StartDate.DayOfYear);

            Assert.AreEqual(sim1.Name, "Sim1");
            Assert.AreEqual(sim2.Enabled, true);
            Assert.AreEqual(soil.Thickness[0], 150);
            Assert.AreEqual(soil.Thickness[1], 150);

            // Run Models.exe with /Edit command.
            sims.Write(apsimxFileName);
            Utilities.RunModels($"{apsimxFileName} /Edit {configFileName}");
            sims = FileFormat.ReadFromFile <Simulations>(apsimxFileName, out errors);
            if (errors != null && errors.Count > 0)
            {
                throw errors[0];
            }

            // Get references to the changed models.
            clock = sims.FindInScope <Clock>();
            Clock clock2 = sims.FindByPath(".Simulations.SimulationVariant35.Clock")?.Value as Clock;

            // Sims should have at least 3 children - data store and the 2 sims.
            Assert.That(sims.Children.Count > 2);
            sim1 = sims.Children.OfType <Simulation>().First();
            sim2 = sims.Children.OfType <Simulation>().Last();
            soil = sims.FindByPath(".Simulations.Sim1.Field.Soil")?.Value as Soil;

            start = new DateTime(2019, 1, 20);
            DateTime end = new DateTime(2019, 3, 20);

            // Check clock.
            Assert.AreEqual(clock.StartDate.Year, start.Year);
            Assert.AreEqual(clock.StartDate.DayOfYear, start.DayOfYear);
            Assert.AreEqual(clock.EndDate.Year, end.Year);
            Assert.AreEqual(clock.EndDate.DayOfYear, end.DayOfYear);

            // These changes should not affect the clock in simulation 2.
            start = new DateTime(2003, 11, 15);
            end   = new DateTime(2003, 11, 15);
            Assert.AreEqual(clock2.StartDate.Year, start.Year);
            Assert.AreEqual(clock2.StartDate.DayOfYear, start.DayOfYear);
            Assert.AreEqual(clock2.EndDate.Year, end.Year);
            Assert.AreEqual(clock2.EndDate.DayOfYear, end.DayOfYear);

            // Sim2 should have been renamed to SimulationVariant35
            Assert.AreEqual(sim2.Name, "SimulationVariant35");

            // Sim1's name should be unchanged.
            Assert.AreEqual(sim1.Name, "Sim1");

            // Sim2 should have been disabled. This should not affect sim1.
            Assert.That(sim1.Enabled);
            Assert.That(!sim2.Enabled);

            // First 2 soil thicknesses have been changed to 500 and 2500 respectively.
            Assert.AreEqual(soil.Thickness[0], 500, 1e-8);
            Assert.AreEqual(soil.Thickness[1], 2500, 1e-8);
        }
示例#6
0
        /// <summary>
        /// Edits a single apsimx file according to the changes specified in the config file.
        /// </summary>
        /// <param name="apsimxFileName">Path to an .apsimx file.</param>
        /// <param name="factors">Factors to apply to the file.</param>
        private static void ApplyChanges(string apsimxFileName, List <CompositeFactor> factors)
        {
            Simulations file = FileFormat.ReadFromFile <Simulations>(apsimxFileName, out List <Exception> errors);

            if (errors != null && errors.Count > 0)
            {
                throw new Exception($"Error reading file ${apsimxFileName}: {errors[0].ToString()}");
            }

            foreach (CompositeFactor factor in factors)
            {
                IVariable variable = file.FindByPath(factor.Paths[0]);
                if (variable == null)
                {
                    throw new Exception($"Invalid path: {factor.Paths[0]}");
                }

                string value        = factor.Values[0].ToString();
                string absolutePath = null;
                try
                {
                    if (!value.Contains(":"))
                    {
                        absolutePath = PathUtilities.GetAbsolutePath(value, Directory.GetCurrentDirectory());
                    }
                }
                catch
                {
                }

                string[] parts = value.Split(';');
                if (parts != null && parts.Length == 2)
                {
                    string fileName         = parts[0];
                    string absoluteFileName = PathUtilities.GetAbsolutePath(fileName, Directory.GetCurrentDirectory());
                    string modelPath        = parts[1];

                    if (File.Exists(fileName))
                    {
                        ReplaceModelFromFile(file, factor.Paths[0], fileName, modelPath);
                    }
                    else if (File.Exists(absoluteFileName))
                    {
                        ReplaceModelFromFile(file, factor.Paths[0], absoluteFileName, modelPath);
                    }
                    else
                    {
                        ChangeVariableValue(variable, value);
                    }
                }
                else if (File.Exists(value) && variable.Value is IModel)
                {
                    ReplaceModelFromFile(file, factor.Paths[0], value, null);
                }
                else if (File.Exists(absolutePath) && variable.Value is IModel)
                {
                    ReplaceModelFromFile(file, factor.Paths[0], absolutePath, null);
                }
                else
                {
                    ChangeVariableValue(variable, value);
                }
            }
            file.Write(apsimxFileName);
        }
示例#7
0
        public void TestManagerParameterChanges()
        {
            Manager m = new Manager()
            {
                Name = "Manager",
                Code = "using System; namespace Models { using Core; [Serializable] public class Script : Models.Core.Model { [Description(\"x\")] public string X { get; set; } } }"
            };
            Simulations sims = new Simulations()
            {
                Children = new List <IModel>()
                {
                    new DataStore(),
                    new Experiment()
                    {
                        Name     = "expt",
                        Children = new List <IModel>()
                        {
                            new Factors()
                            {
                                Children = new List <IModel>()
                                {
                                    new Factor()
                                    {
                                        Name          = "x",
                                        Specification = "[Manager].Script.X = 1"
                                    }
                                }
                            },
                            new Simulation()
                            {
                                Name     = "sim",
                                Children = new List <IModel>()
                                {
                                    new Clock()
                                    {
                                        StartDate = new DateTime(2020, 1, 1),
                                        EndDate   = new DateTime(2020, 1, 2),
                                        Name      = "Clock"
                                    },
                                    new Summary(),
                                    m
                                }
                            }
                        }
                    }
                }
            };

            sims.ParentAllDescendants();
            m.OnCreated();
            Runner runner = new Runner(sims);
            string temp   = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            try
            {
                IEnumerable <string> files = GenerateApsimXFiles.Generate(runner, 1, temp, _ => {});
                Assert.AreEqual(1, files.Count());
                string file = files.First();
                sims = FileFormat.ReadFromFile <Simulations>(file, e => throw e, false);
                Assert.AreEqual("1", sims.FindByPath("[Manager].Script.X").Value);
            }
            finally
            {
                if (Directory.Exists(temp))
                {
                    Directory.Delete(temp, true);
                }
            }
        }