示例#1
0
        /// <summary>
        /// Return the base R script for running morris.
        /// </summary>
        private string GetMorrisRScript()
        {
            string paramNames  = StringUtilities.Build(Parameters.Select(p => p.Name), ",", "\"", "\"");
            string lowerBounds = StringUtilities.Build(Parameters.Select(p => p.LowerBound), ",");
            string upperBounds = StringUtilities.Build(Parameters.Select(p => p.UpperBound), ",");
            string script      = string.Format
                                     ("library('sensitivity')" + Environment.NewLine +
                                     "params <- c({0})" + Environment.NewLine +
                                     "apsimMorris<-morris(model=NULL" + Environment.NewLine +
                                     " ,params #string vector of parameter names" + Environment.NewLine +
                                     " ,{1} #no of paths within the total parameter space" + Environment.NewLine +
                                     " ,design=list(type=\"oat\",levels={2},grid.jump={3})" + Environment.NewLine +
                                     " ,binf=c({4}) #min for each parameter" + Environment.NewLine +
                                     " ,bsup=c({5}) #max for each parameter" + Environment.NewLine +
                                     " ,scale=T" + Environment.NewLine +
                                     " )" + Environment.NewLine,
                                     paramNames, NumPaths, NumIntervals + 1, Jump, lowerBounds, upperBounds);

            return(script);
        }
示例#2
0
        /// <summary>
        /// Get a list of parameter values that we are to run. Call R to do this.
        /// </summary>
        private void RunRPostSimulation(DataTable predictedValues, out DataTable eeDataRaw, out DataTable statsDataRaw)
        {
            string morrisParametersFileName = GetTempFileName("parameters", ".csv");
            string apsimVariableFileName    = GetTempFileName("apsimvariable", ".csv");
            string rFileName     = GetTempFileName("morrisscript", ".r");
            string eeFileName    = GetTempFileName("ee", ".csv");
            string statsFileName = GetTempFileName("stats", ".csv");

            // write predicted values file
            using (StreamWriter writer = new StreamWriter(apsimVariableFileName))
                DataTableUtilities.DataTableToText(predictedValues, 0, ",", true, writer);

            // Write parameters
            using (StreamWriter writer = new StreamWriter(morrisParametersFileName))
                DataTableUtilities.DataTableToText(ParameterValues, 0, ",", true, writer);

            string paramNames  = StringUtilities.Build(Parameters.Select(p => p.Name), ",", "\"", "\"");
            string lowerBounds = StringUtilities.Build(Parameters.Select(p => p.LowerBound), ",");
            string upperBounds = StringUtilities.Build(Parameters.Select(p => p.UpperBound), ",");
            string script      = GetMorrisRScript();

            script += string.Format
                          ("apsimMorris$X <- read.csv(\"{0}\")" + Environment.NewLine +
                          "values = read.csv(\"{1}\", check.names = F)" + Environment.NewLine +
                          "allEE <- data.frame()" + Environment.NewLine +
                          "allStats <- data.frame()" + Environment.NewLine +
                          "for (columnName in colnames(values))" + Environment.NewLine +
                          "{{" + Environment.NewLine +
                          " apsimMorris$y <- values[[columnName]]" + Environment.NewLine +
                          " tell(apsimMorris)" + Environment.NewLine +

                          " ee <- data.frame(apsimMorris$ee)" + Environment.NewLine +
                          " ee$variable <- columnName" + Environment.NewLine +
                          " ee$path <- c(1:{2})" + Environment.NewLine +
                          " allEE <- rbind(allEE, ee)" + Environment.NewLine +

                          " mu <- apply(apsimMorris$ee, 2, mean)" + Environment.NewLine +
                          " mustar <- apply(apsimMorris$ee, 2, function(x) mean(abs(x)))" + Environment.NewLine +
                          " sigma <- apply(apsimMorris$ee, 2, sd)" + Environment.NewLine +
                          " stats <- data.frame(mu, mustar, sigma)" + Environment.NewLine +
                          " stats$param <- params" + Environment.NewLine +
                          " stats$variable <- columnName" + Environment.NewLine +
                          " allStats <- rbind(allStats, stats)" + Environment.NewLine +

                          "}}" + Environment.NewLine +
                          "write.csv(allEE,\"{3}\", row.names=FALSE)" + Environment.NewLine +
                          "write.csv(allStats, \"{4}\", row.names=FALSE)" + Environment.NewLine,
                          morrisParametersFileName.Replace("\\", "/"),
                          apsimVariableFileName.Replace("\\", "/"),
                          NumPaths,
                          eeFileName.Replace("\\", "/"),
                          statsFileName.Replace("\\", "/"));
            File.WriteAllText(rFileName, script);

            // Run R
            R r = new R();

            r.RunToTable(rFileName);

            eeDataRaw    = ApsimTextFile.ToTable(eeFileName);
            statsDataRaw = ApsimTextFile.ToTable(statsFileName);
        }
示例#3
0
        /// <summary>Main run method for performing our calculations and storing data.</summary>
        public void Run()
        {
            if (dataStore?.Writer != null && !dataStore.Writer.TablesModified.Contains("Report"))
            {
                return;
            }

            DataTable predictedData = dataStore.Reader.GetData("Report", filter: "SimulationName LIKE '" + Name + "%'", orderBy: "SimulationID");

            if (predictedData != null)
            {
                IndexedDataTable variableValues = new IndexedDataTable(null);

                // Determine how many years we have per simulation
                DataView view = new DataView(predictedData);
                view.RowFilter = "SimulationName='" + Name + "Simulation1'";
                var Years = DataTableUtilities.GetColumnAsIntegers(view, "Clock.Today.Year");

                // Create a results table.
                IndexedDataTable results;
                if (Years.Count() > 1)
                {
                    results = new IndexedDataTable(new string[] { "Year" });
                }
                else
                {
                    results = new IndexedDataTable(null);
                }


                // Loop through all years and perform analysis on each.
                List <string> errorsFromR = new List <string>();
                foreach (double year in Years)
                {
                    view.RowFilter = "Clock.Today.Year=" + year;

                    foreach (DataColumn predictedColumn in predictedData.Columns)
                    {
                        if (predictedColumn.DataType == typeof(double))
                        {
                            var values = DataTableUtilities.GetColumnAsDoubles(view, predictedColumn.ColumnName);
                            if (values.Distinct().Count() > 1)
                            {
                                variableValues.SetValues(predictedColumn.ColumnName, values);
                            }
                        }
                    }

                    string paramNames                  = StringUtilities.Build(Parameters.Select(p => p.Name), ",", "\"", "\"");
                    string sobolx1FileName             = GetTempFileName("sobolx1", ".csv");
                    string sobolx2FileName             = GetTempFileName("sobolx2", ".csv");
                    string sobolVariableValuesFileName = GetTempFileName("sobolvariableValues", ".csv");

                    // Write variables file
                    using (var writer = new StreamWriter(sobolVariableValuesFileName))
                        DataTableUtilities.DataTableToText(variableValues.ToTable(), 0, ",", true, writer, excelFriendly: false, decimalFormatString: "F6");

                    // Write X1
                    using (var writer = new StreamWriter(sobolx1FileName))
                        DataTableUtilities.DataTableToText(X1, 0, ",", true, writer, excelFriendly: false, decimalFormatString: "F6");

                    // Write X2
                    using (var writer = new StreamWriter(sobolx2FileName))
                        DataTableUtilities.DataTableToText(X2, 0, ",", true, writer, excelFriendly: false, decimalFormatString: "F6");

                    string script = string.Format(
                        $".libPaths(c('{R.PackagesDirectory}', .libPaths()))" + Environment.NewLine +
                        $"library('boot', lib.loc = '{R.PackagesDirectory}')" + Environment.NewLine +
                        $"library('sensitivity', lib.loc = '{R.PackagesDirectory}')" + Environment.NewLine +
                        "params <- c({0})" + Environment.NewLine +
                        "n <- {1}" + Environment.NewLine +
                        "nparams <- {2}" + Environment.NewLine +
                        "X1 <- read.csv(\"{3}\")" + Environment.NewLine +
                        "X2 <- read.csv(\"{4}\")" + Environment.NewLine +
                        "sa <- sobolSalt(model = NULL, X1, X2, scheme=\"A\", nboot = 100)" + Environment.NewLine +
                        "variableValues = read.csv(\"{5}\")" + Environment.NewLine +
                        "for (columnName in colnames(variableValues))" + Environment.NewLine +
                        "{{" + Environment.NewLine +
                        "  sa$y <- variableValues[[columnName]]" + Environment.NewLine +
                        "  tell(sa)" + Environment.NewLine +
                        "  sa$S$Parameter <- params" + Environment.NewLine +
                        "  sa$T$Parameter <- params" + Environment.NewLine +
                        "  sa$S$ColumnName <- columnName" + Environment.NewLine +
                        "  sa$T$ColumnName <- columnName" + Environment.NewLine +
                        "  sa$S$Indices <- \"FirstOrder\"" + Environment.NewLine +
                        "  sa$T$Indices <- \"Total\"" + Environment.NewLine +
                        "  if (!exists(\"allData\"))" + Environment.NewLine +
                        "    allData <- rbind(sa$S, sa$T)" + Environment.NewLine +
                        "  else" + Environment.NewLine +
                        "    allData <- rbind(allData, sa$S, sa$T)" + Environment.NewLine +
                        "}}" + Environment.NewLine +
                        "write.table(allData, sep=\",\", row.names=FALSE)" + Environment.NewLine
                        ,
                        paramNames, NumPaths, Parameters.Count,
                        sobolx1FileName.Replace("\\", "/"),
                        sobolx1FileName.Replace("\\", "/"),
                        sobolVariableValuesFileName.Replace("\\", "/"));

                    DataTable resultsForYear = null;
                    try
                    {
                        resultsForYear = RunR(script);

                        // Put output from R into results table.
                        if (Years.Count() > 1)
                        {
                            results.SetIndex(new object[] { year.ToString() });
                        }

                        foreach (DataColumn col in resultsForYear.Columns)
                        {
                            if (col.DataType == typeof(string))
                            {
                                results.SetValues(col.ColumnName, DataTableUtilities.GetColumnAsStrings(resultsForYear, col.ColumnName));
                            }
                            else
                            {
                                results.SetValues(col.ColumnName, DataTableUtilities.GetColumnAsDoubles(resultsForYear, col.ColumnName));
                            }
                        }
                    }
                    catch (Exception err)
                    {
                        string msg = err.Message;

                        if (Years.Count() > 1)
                        {
                            msg = "Year " + year + ": " + msg;
                        }
                        errorsFromR.Add(msg);
                    }
                }
                var resultsRawTable = results.ToTable();
                resultsRawTable.TableName = Name + "Statistics";
                dataStore.Writer.WriteTable(resultsRawTable);

                if (errorsFromR.Count > 0)
                {
                    string msg = StringUtilities.BuildString(errorsFromR.ToArray(), Environment.NewLine);
                    throw new Exception(msg);
                }
            }
        }