Esempio n. 1
0
        /// <summary>
        /// Generates the R script which performs the optimization.
        /// </summary>
        /// <param name="fileName">File path to which the R code will be saved.</param>
        /// <param name="outputPath">Directory/path to which output results will be saved. This is passed as a parameter to croptimizR.</param>
        /// <param name="apsimxFileName">Name of the .apsimx file to be run by the optimisation.</param>
        private void GenerateRScript(string fileName, string outputPath, string apsimxFileName)
        {
            // tbi: package installation. Need to test on a clean VM.
            StringBuilder contents = new StringBuilder();

            contents.AppendLine($"variable_names <- c({string.Join(", ", VariableNames.Select(x => $"'{x.Trim()}'").ToArray())})");

            // If we're reading from the PredictedObserved table, need to fix
            // Predicted./Observed. suffix for the observed variables.
            string[] sanitisedObservedVariables = GetObservedVariableName().Select(x => $"'{x.Trim()}'").ToArray();
            string   dateVariable = VariableNames.Any(v => v.StartsWith("Predicted.")) ? "Predicted.Clock.Today" : "Clock.Today";

            contents.AppendLine($"observed_variable_names <- c({string.Join(", ", sanitisedObservedVariables)}, '{dateVariable}')");
            contents.AppendLine($"apsimx_path <- '{typeof(IModel).Assembly.Location.Replace(@"\", @"\\")}'");
            contents.AppendLine($"apsimx_file <- '{apsimxFileName.Replace(@"\", @"\\")}'");
            contents.AppendLine($"simulation_names <- {GetSimulationNames()}");
            contents.AppendLine($"predicted_table_name <- '{PredictedTableName}'");
            contents.AppendLine($"observed_table_name <- '{ObservedTableName}'");
            contents.AppendLine($"param_info <- {GetParamInfo()}");
            contents.AppendLine();
            contents.AppendLine(OptimizationMethod.GenerateOptimizationOptions("optim_options"));
            contents.AppendLine($"optim_options$path_results <- '{outputPath.Replace(@"\", @"\\")}'");
            if (RandomSeed != null)
            {
                contents.AppendLine($"optim_options$ranseed <- {RandomSeed}");
            }
            contents.AppendLine();
            contents.AppendLine($"crit_function <- {OptimizationMethod.CritFunction}");
            contents.AppendLine($"optim_method <- '{OptimizationMethod.ROptimizerName}'");
            contents.AppendLine();
            contents.Append(ReflectionUtilities.GetResourceAsString("Models.Resources.RScripts.OptimizR.r"));

            File.WriteAllText(fileName, contents.ToString());
        }
Esempio n. 2
0
 private string[] GetObservedVariableName()
 {
     if (PredictedTableName == ObservedTableName)
     {
         return(VariableNames.Select(x => x.Replace("Predicted.", "Observed.")).ToArray());
     }
     return(VariableNames);
 }
Esempio n. 3
0
        /// <summary>
        /// Generates the R script which performs the optimization.
        /// </summary>
        /// <param name="fileName">File path to which the R code will be saved.</param>
        /// <param name="outputPath">Directory/path to which output results will be saved. This is passed as a parameter to croptimizR.</param>
        /// <param name="apsimxFileName">Name of the .apsimx file to be run by the optimisation.</param>
        private void GenerateRScript(string fileName, string outputPath, string apsimxFileName)
        {
            // tbi: package installation. Need to test on a clean VM.
            StringBuilder contents = new StringBuilder();

            contents.AppendLine($"variable_names <- c({string.Join(", ", VariableNames.Select(x => $"'{x.Trim()}'").ToArray())})");

            // In theory, it would be better to always use relative path to
            // the input file, by setting the working directory of the R
            // process appropriately. Unfortunately, this will require some
            // refactoring of the R wrapper which I don't really want to do
            // right now. So for now I'm going to just use relative path if
            // using docker.
            if (RDocker.UseDocker())
            {
                apsimxFileName = Path.GetFileName(apsimxFileName);
            }

            // If we're reading from the PredictedObserved table, need to fix
            // Predicted./Observed. suffix for the observed variables.
            string escapedOutputPath = outputPath.Replace(@"\", "/");

            string[] sanitisedObservedVariables = GetObservedVariableName().Select(x => $"'{x.Trim()}'").ToArray();
            string   dateVariable = VariableNames.Any(v => v.StartsWith("Predicted.")) ? "Predicted.Clock.Today" : "Clock.Today";

            contents.AppendLine($"observed_variable_names <- c({string.Join(", ", sanitisedObservedVariables)}, '{dateVariable}')");
            contents.AppendLine($"apsimx_path <- '{PathToModels().Replace(@"\", "/")}'");
            contents.AppendLine($"apsimx_file <- '{apsimxFileName.Replace(@"\", "/")}'");
            contents.AppendLine($"simulation_names <- {GetSimulationNames()}");
            contents.AppendLine($"predicted_table_name <- '{PredictedTableName}'");
            contents.AppendLine($"observed_table_name <- '{ObservedTableName}'");
            contents.AppendLine($"param_info <- {GetParamInfo()}");
            contents.AppendLine();
            contents.AppendLine(OptimizationMethod.GenerateOptimizationOptions("optim_options"));
            contents.AppendLine($"optim_options$path_results <- '{escapedOutputPath}'");
            if (RandomSeed != null)
            {
                contents.AppendLine($"optim_options$ranseed <- {RandomSeed}");
            }
            contents.AppendLine();
            contents.AppendLine($"crit_function <- {OptimizationMethod.CritFunction}");
            contents.AppendLine($"optim_method <- '{OptimizationMethod.ROptimizerName}'");
            contents.AppendLine();
            contents.AppendLine(ReflectionUtilities.GetResourceAsString("Models.Resources.RScripts.OptimizR.r"));

            // Don't use Path.Combine() - as this may be running in a (linux) docker container.
            // R will work with forward slashes for path separators on win and linux,
            // but backslashes will not work on linux.
            string rDataExpectedPath = $"{escapedOutputPath}/optim_results.Rdata";

            contents.AppendLine(CreateReadRDataScript(rDataExpectedPath));

            File.WriteAllText(fileName, contents.ToString());
        }