Пример #1
0
        /// <summary>
        /// Called when the user passes the /Edit command line switch.
        /// Performs pattern matching and edits all specified .apsimx
        /// files (e.g. *.apsimx /Recurse).
        /// </summary>
        private static void ModifyFile(string fileName, bool recurse)
        {
            int index = Array.IndexOf(arguments, "/Edit");

            if (index < 0)
            {
                throw new Exception("Illegal state - this should never happen. /Edit paramter was not specified?");
            }
            if (index + 1 >= arguments.Length)
            {
                throw new Exception("/Edit option was provided but no config file argument was given. The config file argument must directly follow the /Edit argument. Use this syntax: Models.exe path/to/apsimXFile.apsimx /Edit path/to/configfile.txt");
            }
            string configFileName = arguments[index + 1];

            string dir = Path.GetDirectoryName(fileName);

            if (!Directory.Exists(dir))
            {
                dir = Directory.GetCurrentDirectory();
            }

            string[] files = Directory.EnumerateFiles(dir, Path.GetFileName(fileName), recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToArray();
            foreach (string file in files)
            {
                EditFile.Do(file, configFileName);
            }
        }
Пример #2
0
        public void TestEditingGenericLists()
        {
            string configFile = Path.GetTempFileName();

            File.WriteAllLines(configFile, new[]
            {
                // Set an entire (string) list.
                "[StringList].Data = 1, x, y, true, 0.5",

                // Modify a single element of a (string) list.
                "[StringList].Data[1] = 6",

                // Modify multiple elements of a (string) list.
                "[StringList].Data[3:4] = xyz",

                // Set an entire (numeric) list.
                "[DoubleList].Data = 1, 2, 3, 4, 4.5",

                // Modify a single element of a (numeric) list.
                "[DoubleList].Data[1] = -13",

                // Modify multiple elements of a (numeric) list.
                "[DoubleList].Data[3:4] = 1e9",
            });

            Simulations file = EditFile.Do(fileName, configFile);

            ListClass <string> stringList = (ListClass <string>)file.Children[1].Children[7];
            ListClass <double> doubleList = (ListClass <double>)file.Children[1].Children[8];

            List <string> expectedStrings = new List <string>(new[]
            {
                "6",
                "x",
                "xyz",
                "xyz",
                "0.5"
            });

            Assert.AreEqual(expectedStrings, stringList.Data);
            List <double> expectedNumbers = new List <double>(new[]
            {
                -13,
                2,
                1e9,
                1e9,
                4.5
            });

            Assert.AreEqual(expectedNumbers, doubleList.Data);
        }
Пример #3
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.Physical.Thickness[1] = 500",
                ".Simulations.Sim1.Field.Soil.Physical.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;
            IPhysical  physical = sims.FindByPath(".Simulations.Sim1.Field.Soil.Physical")?.Value as IPhysical;

            // 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(physical.Thickness[0], 150);
            Assert.AreEqual(physical.Thickness[1], 150);

            // Run Models.exe with /Edit command.
            sims.Write(apsimxFileName);
            sims = EditFile.Do(apsimxFileName, configFileName);

            // 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();
            physical = sims.FindByPath(".Simulations.Sim1.Field.Soil.Physical")?.Value as IPhysical;

            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(physical.Thickness[0], 500, 1e-8);
            Assert.AreEqual(physical.Thickness[1], 2500, 1e-8);
        }
Пример #4
0
        public void TestEditing()
        {
            string configFile = Path.GetTempFileName();

            File.WriteAllLines(configFile, new[]
            {
                // Modify an array
                "[Report].VariableNames = x,y,z",

                // Modify a date - try a few different formats.
                "[Clock].StartDate = 2000-01-01",
                "[Clock].EndDate = 2000-01-10T00:00:00",

                // Modify a string
                "[Weather].FileName = fdsa.met",
                @"[Weather2].FullFileName = jkl.met",

                // Replace a model with a model from another file.
                $"[Weather3] = {extFile}",
                $"[Weather4] = {extFile};[w2]",

                // Change a property of a resource model.
                "[Wheat].Leaf.Photosynthesis.RUE.FixedValue = 0.4",

                // Change a property of a manager script.
                "[Manager].Script.Amount = 1234",

                // Set an entire array.
                "[Physical].BD = 1, 2, 3, 4, 5",

                // Modify a single element of an array.
                "[Physical].AirDry[2] = 6",

                // Modify multiple elements of an array.
                "[Physical].LL15[3:4] = 7",
            });

            Simulations file = EditFile.Do(fileName, configFile);

            var report = file.FindInScope <Models.Report>();

            string[] variableNames = new[] { "x", "y", "z" };
            Assert.AreEqual(variableNames, report.VariableNames);

            IModel sim = file.FindChild <Simulation>();

            // Use an index-based lookup to locate child models.
            // When we replace an entire model, we want to ensure
            // that the replacement is inserted at the correct index.

            Clock clock = sim.Children[0] as Clock;

            Assert.AreEqual(new DateTime(2000, 1, 1), clock.StartDate);
            Assert.AreEqual(new DateTime(2000, 1, 10), clock.EndDate);

            var weather = sim.Children[3] as Models.Climate.Weather;

            Assert.NotNull(weather);
            Assert.AreEqual("Weather", weather.Name);
            Assert.AreEqual("fdsa.met", weather.FileName);

            var weather2 = sim.Children[4] as Models.Climate.Weather;

            Assert.NotNull(weather2);
            Assert.AreEqual("Weather2", weather2.Name);
            Assert.AreEqual(@"jkl.met", weather2.FileName);

            // Weather3 and Weather4 should have been
            // renamed to w1 and w2, respectively.
            var weather3 = sim.Children[5] as Models.Climate.Weather;

            Assert.NotNull(weather3);
            Assert.AreEqual("w1", weather3.Name);
            Assert.AreEqual("w1.met", weather3.FileName);

            var weather4 = sim.Children[6] as Models.Climate.Weather;

            Assert.NotNull(weather4);
            Assert.AreEqual("w2", weather4.Name);
            Assert.AreEqual("w2.met", weather4.FileName);

            // The edit file operation should have changed RUE value to 0.4.
            var wheat = sim.Children[2].Children[2] as Plant;
            var rue   = wheat.Children[6].Children[4].Children[0] as Constant;

            Assert.AreEqual(0.4, rue.FixedValue);

            double amount = (double)sim.FindByPath("[Manager].Script.Amount")?.Value;

            Assert.AreEqual(1234, amount);

            Physical physical = sim.Children[2].Children[4] as Physical;

            Assert.AreEqual(new double[5] {
                1, 2, 3, 4, 5
            }, physical.BD);
            Assert.AreEqual(new double[5] {
                0, 6, 0, 0, 0
            }, physical.AirDry);
            Assert.AreEqual(new double[5] {
                0, 0, 7, 7, 0
            }, physical.LL15);
        }
Пример #5
0
        /// <summary>
        /// Run Models with the given set of options.
        /// </summary>
        /// <param name="options"></param>
        public static void Run(Options options)
        {
            try
            {
                string[] files = options.Files.SelectMany(f => DirectoryUtilities.FindFiles(f, options.Recursive)).ToArray();
                if (files == null || files.Length < 1)
                {
                    throw new ArgumentException($"No files were specified");
                }
                if (options.NumProcessors == 0)
                {
                    throw new ArgumentException($"Number of processors cannot be 0");
                }
                if (options.Upgrade)
                {
                    foreach (string file in files)
                    {
                        UpgradeFile(file);
                        if (options.Verbose)
                        {
                            Console.WriteLine("Successfully upgraded " + file);
                        }
                    }
                }
                else if (options.ListSimulationNames)
                {
                    foreach (string file in files)
                    {
                        ListSimulationNames(file, options.SimulationNameRegex);
                    }
                }
                else if (options.MergeDBFiles)
                {
                    string[] dbFiles = files.Select(f => Path.ChangeExtension(f, ".db")).ToArray();
                    string   outFile = Path.Combine(Path.GetDirectoryName(dbFiles[0]), "merged.db");
                    DBMerger.MergeFiles(dbFiles, outFile);
                }
                else
                {
                    Runner runner;
                    if (string.IsNullOrEmpty(options.EditFilePath))
                    {
                        // Run simulations
                        runner = new Runner(files,
                                            options.RunTests,
                                            options.RunType,
                                            numberOfProcessors: options.NumProcessors,
                                            simulationNamePatternMatch: options.SimulationNameRegex);
                    }
                    else
                    {
                        runner = new Runner(files.Select(f => EditFile.Do(f, options.EditFilePath)),
                                            true,
                                            true,
                                            options.RunTests,
                                            runType: options.RunType,
                                            numberOfProcessors: options.NumProcessors,
                                            simulationNamePatternMatch: options.SimulationNameRegex);
                    }
                    runner.SimulationCompleted += OnJobCompleted;
                    if (options.Verbose)
                    {
                        runner.SimulationCompleted += WriteCompleteMessage;
                    }
                    if (options.ExportToCsv)
                    {
                        runner.SimulationGroupCompleted += OnSimulationGroupCompleted;
                    }
                    runner.AllSimulationsCompleted += OnAllJobsCompleted;
                    runner.Run();

                    // If errors occurred, write them to the console.
                    if (exitCode != 0)
                    {
                        Console.WriteLine("ERRORS FOUND!!");
                    }
                    if (options.Verbose)
                    {
                        Console.WriteLine("Elapsed time was " + runner.ElapsedTime.TotalSeconds.ToString("F1") + " seconds");
                    }
                }
            }
            catch (Exception err)
            {
                Console.WriteLine(err.ToString());
                exitCode = 1;
            }
        }