/// <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()); }
/// <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()); }
public string?GetNameForSlot(int slot) { return(VariableNames.Any(v => v.Index == slot) ? VariableNames.First(v => v.Index == slot).Name : null); }