22#include "pism/util/error_handling.hh"
23#include "pism/util/io/io_helpers.hh"
24#include "pism/util/VariableMetadata.hh"
25#include "pism/util/io/OutputWriter.hh"
26#include "pism/util/pism_utilities.hh"
27#include "pism/util/Config.hh"
33 const std::set<VariableMetadata> &variables,
35 bool use_internal_units) {
37 std::string mapping_variable_name{};
39 mapping_variable_name = mapping.
get_name();
42 std::set<std::string> variable_names;
43 for (
const auto &v : variables) {
44 variable_names.insert(v.get_name());
47 for (
auto var : variables) {
48 if (var.get_name() ==
"PISM_GLOBAL") {
59 if (use_internal_units) {
60 var.output_units(var[
"units"]);
63 auto var_name = var.get_name();
65 if (var_name ==
"lat" and
set_member(
"lat_bnds", variable_names)) {
66 var[
"bounds"] =
"lat_bnds";
68 if (var_name ==
"lon" and
set_member(
"lon_bnds", variable_names)) {
69 var[
"bounds"] =
"lon_bnds";
80 auto dim_names = var.dimension_names();
82 if (have_lat_lon and not
set_member(var_name, {
"lat_bnds",
"lon_bnds",
"lat",
"lon" })) {
83 var[
"coordinates"] =
"lat lon";
86 if (not mapping_variable_name.empty()) {
87 var[
"grid_mapping"] = mapping_variable_name;
97 std::string data = config.
json();
102 "unable to save configuration parameters to a file: JSON string length exceeds %d",
106 std::vector<unsigned int> start = { 0 };
107 std::vector<unsigned int>
count = { (
unsigned int)data.size() + 1 };
109 if (not config.
get_string(
"output.experiment_id").empty()) {
110 start.insert(start.cbegin(), 0);
121void move_if_exists(MPI_Comm com,
const std::string &file_to_move,
int rank_to_use) {
122 int stat = 0, rank = 0;
123 MPI_Comm_rank(com, &rank);
124 std::string backup_filename = file_to_move +
"~";
126 if (rank == rank_to_use) {
130 if (FILE *f = fopen(file_to_move.c_str(),
"r")) {
138 stat = rename(file_to_move.c_str(), backup_filename.c_str());
143 MPI_Allreduce(&stat, &global_stat, 1, MPI_INT, MPI_SUM, com);
145 if (global_stat != 0) {
147 file_to_move.c_str(), backup_filename.c_str());
156 int stat = 0, rank = 0;
157 MPI_Comm_rank(com, &rank);
159 if (rank == rank_to_use) {
163 if (FILE *f = fopen(file_to_remove.c_str(),
"r")) {
171 stat = remove(file_to_remove.c_str());
176 MPI_Allreduce(&stat, &global_stat, 1, MPI_INT, MPI_SUM, com);
178 if (global_stat != 0) {
180 file_to_remove.c_str());
std::string get_string(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
static int max_length
Maximum length of the JSON string (for writing to output files)
A class for storing and accessing PISM configuration flags and parameters.
void set_global_attributes(const std::map< std::string, std::string > &strings, const std::map< std::string, std::vector< double > > &numbers) const
void append_history(const std::string &text) const
void write_text(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const std::string &input) const
void define_variable(const VariableMetadata &variable) const
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
#define PISM_ERROR_LOCATION
void write_config(const Config &config, const std::string &variable_name, const OutputFile &file)
void move_if_exists(MPI_Comm com, const std::string &file_to_move, int rank_to_use=0)
Moves the file aside (file.nc -> file.nc~).
void define_variables(const OutputFile &file, const std::set< VariableMetadata > &variables, const VariableMetadata &mapping, bool use_internal_units)
void remove_if_exists(MPI_Comm com, const std::string &file_to_remove, int rank_to_use=0)
Check if a file is present are remove it.
bool vector_member(const std::string &string, const std::vector< std::string > &vector)
bool set_member(const std::string &string, const std::set< std::string > &set)