diff --git a/include/trick/mc_variable.hh b/include/trick/mc_variable.hh index 84ba2ed7..51207f2b 100644 --- a/include/trick/mc_variable.hh +++ b/include/trick/mc_variable.hh @@ -65,8 +65,10 @@ class MonteCarloVariable const std::string & get_command() const {return command;} const std::string & get_variable_name() const {return variable_name;} const std::string & get_assignment() const {return assignment;} - MonteCarloVariableType get_type() const {return type;} + virtual MonteCarloVariableType get_type() const {return type;} + virtual std::string get_type_str() const; virtual unsigned int get_seed() const {return 0;} + virtual std::string summarize_variable() const; protected: void insert_units(); diff --git a/include/trick/mc_variable_file.hh b/include/trick/mc_variable_file.hh index 7b1df70b..9931972d 100644 --- a/include/trick/mc_variable_file.hh +++ b/include/trick/mc_variable_file.hh @@ -68,6 +68,8 @@ class MonteCarloVariableFile : public MonteCarloVariable virtual ~MonteCarloVariableFile(){}; void initialize_file(); void generate_assignment(); + virtual std::string summarize_variable() const; + void register_dependent( MonteCarloVariableFile *); virtual void shutdown() {file.close();} diff --git a/include/trick/mc_variable_random.hh b/include/trick/mc_variable_random.hh index 649b4ea1..0ab003ac 100644 --- a/include/trick/mc_variable_random.hh +++ b/include/trick/mc_variable_random.hh @@ -40,7 +40,6 @@ class MonteCarloVariableRandom : public MonteCarloVariable virtual ~MonteCarloVariableRandom(){}; unsigned int get_seed() const {return seed_m;} // override but SWIG cannot process the // override keyword - private: // and undefined: MonteCarloVariableRandom( const MonteCarloVariableRandom & ); MonteCarloVariableRandom& operator = (const MonteCarloVariableRandom&); diff --git a/include/trick/mc_variable_random_normal.hh b/include/trick/mc_variable_random_normal.hh index 2353ecf4..311bd7ac 100644 --- a/include/trick/mc_variable_random_normal.hh +++ b/include/trick/mc_variable_random_normal.hh @@ -44,6 +44,7 @@ class MonteCarloVariableRandomNormal : public MonteCarloVariableRandom virtual ~MonteCarloVariableRandomNormal(){}; virtual void generate_assignment(); + virtual std::string summarize_variable() const; void truncate(double limit, TruncationType type = StandardDeviation); void truncate(double min, double max, TruncationType type = StandardDeviation); void truncate_low(double limit, TruncationType type = StandardDeviation); diff --git a/include/trick/mc_variable_random_string.hh b/include/trick/mc_variable_random_string.hh index 602e8eea..352af382 100644 --- a/include/trick/mc_variable_random_string.hh +++ b/include/trick/mc_variable_random_string.hh @@ -43,6 +43,7 @@ class MonteCarloVariableRandomStringSet : public MonteCarloVariableRandomUniform virtual ~MonteCarloVariableRandomStringSet(){}; virtual void generate_assignment(); + virtual std::string summarize_variable() const; void add_string(std::string); private: // and undefined: MonteCarloVariableRandomStringSet(const MonteCarloVariableRandomStringSet&); diff --git a/include/trick/mc_variable_random_uniform.hh b/include/trick/mc_variable_random_uniform.hh index e563ab34..34f0d35c 100644 --- a/include/trick/mc_variable_random_uniform.hh +++ b/include/trick/mc_variable_random_uniform.hh @@ -35,6 +35,7 @@ class MonteCarloVariableRandomUniform : public MonteCarloVariableRandom double upper_bound = 1.0); virtual ~MonteCarloVariableRandomUniform(){}; virtual void generate_assignment(); + virtual std::string summarize_variable() const; private: // and undefined: MonteCarloVariableRandomUniform( const MonteCarloVariableRandomUniform & ); MonteCarloVariableRandomUniform& operator = ( @@ -59,6 +60,7 @@ class MonteCarloVariableRandomUniformInt : public MonteCarloVariableRandom double upper_bound = 1); virtual ~MonteCarloVariableRandomUniformInt(){}; virtual void generate_assignment(); + virtual std::string summarize_variable() const; private: // and undefined: MonteCarloVariableRandomUniformInt(const MonteCarloVariableRandomUniformInt&); MonteCarloVariableRandomUniformInt& operator = ( diff --git a/test/SIM_mc_generation/RUN_WARN_no_string_values/input.py b/test/SIM_mc_generation/RUN_WARN_no_string_values/input.py new file mode 100644 index 00000000..d540547d --- /dev/null +++ b/test/SIM_mc_generation/RUN_WARN_no_string_values/input.py @@ -0,0 +1,19 @@ +monte_carlo.mc_master.activate("RUN_WARN_no_string_values") +monte_carlo.mc_master.set_num_runs(1) + +print('*********************************************************************************') +print('this message is expected:') +print('No values for MonteCarloVariableRandomStringSet') +print('Length of values vector is zero for variable: test.x_string, Did you forget to call add_string()?') +print('*********************************************************************************') + + +# add a string variable but forget to give it options to randomize +mc_var = trick.MonteCarloVariableRandomStringSet( "test.x_string", 3) +#mc_var.add_string("\"ABC\"") +#mc_var.add_string("\"DEF\"") +#mc_var.add_string("'GHIJKL'") +mc_var.thisown = False +monte_carlo.mc_master.add_variable(mc_var) +monte_carlo.mc_master.generate_meta_data = True + diff --git a/test/SIM_mc_generation/verif_data/MONTE_RUN_nominal/MonteCarlo_Meta_data_output b/test/SIM_mc_generation/verif_data/MONTE_RUN_nominal/MonteCarlo_Meta_data_output index c4743ab8..cf10481a 100644 --- a/test/SIM_mc_generation/verif_data/MONTE_RUN_nominal/MonteCarlo_Meta_data_output +++ b/test/SIM_mc_generation/verif_data/MONTE_RUN_nominal/MonteCarlo_Meta_data_output @@ -10,32 +10,32 @@ - 0 variables of undefined type ********************* LIST OF VARIABLES, TYPES**************** -test.x_boolean, Random -test.x_file_lookup[0], Prescribed -test.x_file_lookup[1], Prescribed -test.x_file_lookup[2], Prescribed -test.x_fixed_value_double, Constant -test.x_fixed_value_int, Constant -test.x_fixed_value_string, Constant -test.x_integer, Random -test.x_line_command, Calculated -test.x_normal, Random -test.x_normal_length, Random -test.x_normal_trunc[0], Random -test.x_normal_trunc[1], Random -test.x_normal_trunc[2], Random -test.x_normal_trunc[3], Random -test.x_normal_trunc[4], Random -test.x_semi_fixed_value, Constant -test.x_string, Random -test.x_uniform, Random +test.x_boolean: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=4, values=[False,True,] +test.x_file_lookup[0]: type=Prescribed, max_skip=0, is_dependent=0, filename=Modified_data/datafile.txt, column_number=3, first_column_number=1 +test.x_file_lookup[1]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=2, first_column_number=1 +test.x_file_lookup[2]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=1, first_column_number=1 +test.x_fixed_value_double: type=Constant +test.x_fixed_value_int: type=Constant +test.x_fixed_value_string: type=Constant +test.x_integer: type=Random dispersion=Uniform, min_value=0, max_value=2, seed=1 +test.x_line_command: type=Calculated +test.x_normal: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2 +test.x_normal_length: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2 +test.x_normal_trunc[0]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9, max_value=11, seed=2 +test.x_normal_trunc[1]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.5, max_value=10.7, seed=2 +test.x_normal_trunc[2]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=11, seed=2 +test.x_normal_trunc[3]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=0, seed=2 +test.x_normal_trunc[4]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=4, seed=2 +test.x_semi_fixed_value: type=Constant +test.x_string: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=3, values=["ABC","DEF",'GHIJKL',] +test.x_uniform: type=Random, dispersion=Uniform, min_value=10, max_value=20, seed=0 ************************************************************** *********** LIST OF EXECUTABLE FILES AND FUNCTIONS *********** -test.standalone_function( test.x_normal) +test.standalone_function( test.x_normal): type=Execute *** -Modified_data/sample.py +Modified_data/sample.py: type=Execute *** ************************************************************** diff --git a/test/SIM_mc_generation/verif_data/MonteCarlo_Meta_data_output b/test/SIM_mc_generation/verif_data/MonteCarlo_Meta_data_output index bbe69dd8..fcebca0c 100644 --- a/test/SIM_mc_generation/verif_data/MonteCarlo_Meta_data_output +++ b/test/SIM_mc_generation/verif_data/MonteCarlo_Meta_data_output @@ -14,32 +14,32 @@ Sending meta-data to top-level directory. - 0 variables of undefined type ********************* LIST OF VARIABLES, TYPES**************** -test.x_boolean, Random -test.x_file_lookup[0], Prescribed -test.x_file_lookup[1], Prescribed -test.x_file_lookup[2], Prescribed -test.x_fixed_value_double, Constant -test.x_fixed_value_int, Constant -test.x_fixed_value_string, Constant -test.x_integer, Random -test.x_line_command, Calculated -test.x_normal, Random -test.x_normal_length, Random -test.x_normal_trunc[0], Random -test.x_normal_trunc[1], Random -test.x_normal_trunc[2], Random -test.x_normal_trunc[3], Random -test.x_normal_trunc[4], Random -test.x_semi_fixed_value, Constant -test.x_string, Random -test.x_uniform, Random +test.x_boolean: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=4, values=[False,True,] +test.x_file_lookup[0]: type=Prescribed, max_skip=0, is_dependent=0, filename=Modified_data/datafile.txt, column_number=3, first_column_number=1 +test.x_file_lookup[1]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=2, first_column_number=1 +test.x_file_lookup[2]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=1, first_column_number=1 +test.x_fixed_value_double: type=Constant +test.x_fixed_value_int: type=Constant +test.x_fixed_value_string: type=Constant +test.x_integer: type=Random dispersion=Uniform, min_value=0, max_value=2, seed=1 +test.x_line_command: type=Calculated +test.x_normal: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2 +test.x_normal_length: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2 +test.x_normal_trunc[0]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9, max_value=11, seed=2 +test.x_normal_trunc[1]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.5, max_value=10.7, seed=2 +test.x_normal_trunc[2]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=11, seed=2 +test.x_normal_trunc[3]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=0, seed=2 +test.x_normal_trunc[4]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=4, seed=2 +test.x_semi_fixed_value: type=Constant +test.x_string: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=3, values=["ABC","DEF",'GHIJKL',] +test.x_uniform: type=Random, dispersion=Uniform, min_value=10, max_value=20, seed=0 ************************************************************** *********** LIST OF EXECUTABLE FILES AND FUNCTIONS *********** -test.standalone_function( test.x_normal) +test.standalone_function( test.x_normal): type=Execute *** -Modified_data/sample.py +Modified_data/sample.py: type=Execute *** ************************************************************** diff --git a/test_sims.yml b/test_sims.yml index c44ae1a6..c5dd9e59 100644 --- a/test_sims.yml +++ b/test_sims.yml @@ -447,6 +447,9 @@ SIM_mc_generation: RUN_WARN_overconstrained_config/input.py: compare: phase: -1 + RUN_WARN_no_string_values/input.py: + compare: + phase: -1 MONTE_RUN_WARN_overconstrained_config/RUN_0/monte_input.py: FAIL_config_error/input.py: returns: 1 diff --git a/trick_source/sim_services/MonteCarloGeneration/mc_master.cc b/trick_source/sim_services/MonteCarloGeneration/mc_master.cc index 7fd4ba45..488a0aeb 100644 --- a/trick_source/sim_services/MonteCarloGeneration/mc_master.cc +++ b/trick_source/sim_services/MonteCarloGeneration/mc_master.cc @@ -441,7 +441,7 @@ MonteCarloMaster::collate_meta_data() // Capture and alphabetize all variable names with their respective variable // type; count the number of each type. - std::list< std::string > variable_names; + std::list< std::string > variable_details; std::list< std::string > exec_file_names; std::list< std::pair < unsigned int, std::string> > random_variables; unsigned int count_calc = 0; @@ -456,27 +456,27 @@ MonteCarloMaster::collate_meta_data() // Unreachable case in current implementation. // All current variable classes have been given a "type" default: - variable_names.push_back (var_it->get_variable_name() + ", Undefined_type"); + variable_details.push_back(var_it->summarize_variable()); count_undef++; break; case MonteCarloVariable::Calculated: - variable_names.push_back (var_it->get_variable_name() + ", Calculated"); + variable_details.push_back (var_it->summarize_variable()); count_calc++; break; case MonteCarloVariable::Constant: - variable_names.push_back (var_it->get_variable_name() + ", Constant"); + variable_details.push_back (var_it->summarize_variable()); count_const++; break; case MonteCarloVariable::Execute: - exec_file_names.push_back (var_it->get_variable_name()); + exec_file_names.push_back (var_it->summarize_variable()); count_exec++; break; case MonteCarloVariable::Prescribed: - variable_names.push_back (var_it->get_variable_name() + ", Prescribed"); + variable_details.push_back (var_it->summarize_variable()); count_presc++; break; case MonteCarloVariable::Random: - variable_names.push_back (var_it->get_variable_name() + ", Random"); + variable_details.push_back (var_it->summarize_variable()); count_rand++; std::pair< unsigned int, std::string> var(var_it->get_seed(), var_it->get_variable_name()); @@ -484,7 +484,7 @@ MonteCarloMaster::collate_meta_data() break; } } - variable_names.sort(); + variable_details.sort(); meta_data << "\n\n*************************** SUMMARY **************************\n" << @@ -497,8 +497,8 @@ MonteCarloMaster::collate_meta_data() count_undef << " variables of undefined type" << "\n\n********************* LIST OF VARIABLES, TYPES****************\n"; - std::list< std::string >::iterator var_name_it = variable_names.begin(); - for (; var_name_it != variable_names.end(); ++var_name_it) { + std::list< std::string >::iterator var_name_it = variable_details.begin(); + for (; var_name_it != variable_details.end(); ++var_name_it) { meta_data << (*var_name_it) << "\n"; } meta_data << diff --git a/trick_source/sim_services/MonteCarloGeneration/mc_variable.cc b/trick_source/sim_services/MonteCarloGeneration/mc_variable.cc index 63af93e3..b57f3513 100644 --- a/trick_source/sim_services/MonteCarloGeneration/mc_variable.cc +++ b/trick_source/sim_services/MonteCarloGeneration/mc_variable.cc @@ -116,3 +116,48 @@ MonteCarloVariable::generate_command() { command = "\n" + variable_name + " = " + assignment; } + +/***************************************************************************** +get_type_str +Purpose:(Return the type of this variable as string. Meant to be overridden + by derived classes) +*****************************************************************************/ +std::string MonteCarloVariable::get_type_str() const +{ + switch (get_type()) { + // Unreachable case in current implementation. + // All current variable classes have been given a "type" + default: + return(std::string("Undefined_type")); + break; + case MonteCarloVariable::Calculated: + return(std::string("Calculated")); + break; + case MonteCarloVariable::Constant: + return(std::string("Constant")); + break; + case MonteCarloVariable::Execute: + return(std::string("Execute")); + break; + case MonteCarloVariable::Prescribed: + return(std::string("Prescribed")); + break; + case MonteCarloVariable::Random: + return(std::string("Random")); + break; + } +} + + +/***************************************************************************** +summarize_variable +Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable) +*****************************************************************************/ +std::string MonteCarloVariable::summarize_variable() const +{ + std::ostringstream ss; + ss << variable_name << std::string(": type=") << get_type_str(); + return (ss.str()); +} + + diff --git a/trick_source/sim_services/MonteCarloGeneration/mc_variable_file.cc b/trick_source/sim_services/MonteCarloGeneration/mc_variable_file.cc index 3122f649..e4eca0a8 100644 --- a/trick_source/sim_services/MonteCarloGeneration/mc_variable_file.cc +++ b/trick_source/sim_services/MonteCarloGeneration/mc_variable_file.cc @@ -271,3 +271,17 @@ bool MonteCarloVariableFile::sort_by_col_num( { return left->get_column_number() < right->get_column_number(); } + +/***************************************************************************** +summarize_variable +Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable) +*****************************************************************************/ +std::string MonteCarloVariableFile::summarize_variable() const +{ + std::ostringstream ss; + ss << MonteCarloVariable::summarize_variable() + << ", max_skip=" << max_skip << ", is_dependent=" << is_dependent + << ", filename=" << filename << ", column_number=" << column_number + << ", first_column_number=" << first_column_number; + return (ss.str()); +} diff --git a/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_normal.cc b/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_normal.cc index ebf7ed5e..60efe73e 100644 --- a/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_normal.cc +++ b/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_normal.cc @@ -16,6 +16,7 @@ PROGRAMMERS: #include #include #include +#include // ostringstream /***************************************************************************** Constructor @@ -105,6 +106,19 @@ MonteCarloVariableRandomNormal::generate_assignment() assign_double(assignment_d); } +/***************************************************************************** +summarize_variable +Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable) +*****************************************************************************/ +std::string MonteCarloVariableRandomNormal::summarize_variable() const +{ + std::ostringstream ss; + ss << MonteCarloVariable::summarize_variable() << std::string(", dispersion=Normal") + << ", mean=" << distribution.mean() << ", stddev=" << distribution.stddev() + << ", min_value=" << min_value << ", max_value=" << max_value + << ", seed=" << seed_m; + return (ss.str()); +} /***************************************************************************** truncate Purpose:(Truncates the normal distribution to be within +- limit.) diff --git a/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_string.cc b/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_string.cc index 6d544b57..6199e8b8 100644 --- a/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_string.cc +++ b/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_string.cc @@ -8,6 +8,10 @@ PROGRAMMERS: (((Gary Turner) (OSR) (October 2019) (Antares) (Initial))) (((Isaac Reaves) (NASA) (November 2022) (Integration into Trick Core))) **********************************************************************/ +#include // ostringstream +#include "trick/message_type.h" +#include "trick/message_proto.h" +#include "trick/exec_proto.h" #include "trick/mc_variable_random_string.hh" /***************************************************************************** @@ -32,14 +36,47 @@ Purpose:(pick one string at random) void MonteCarloVariableRandomStringSet::generate_assignment() { - // generate a random number on the interval [0,1) - double pre_ix = distribution(random_generator); - // convert to an integer between 0 and max-index of the "values" vector. - size_t ix = static_cast (pre_ix * values.size()); - // send the string at that index to the command-generation. - assignment = values[ix]; - generate_command(); + // Protect against accessing 0th index of an empty list. In this case, + // generate_command() is never called + if (values.size() > 0) { + // generate a random number on the interval [0,1) + double pre_ix = distribution(random_generator); + // convert to an integer between 0 and max-index of the "values" vector. + size_t ix = static_cast (pre_ix * values.size()); + // send the string at that index to the command-generation. + // TODO: This fales if values.size() is zero!!! + assignment = values[ix]; + generate_command(); + } else { + std::string message = + std::string("File: ") + __FILE__ + ", Line: " + + std::to_string(__LINE__) + ", No values for MonteCarloVariableRandomStringSet\n" + "Length of values vector is zero for variable: " + variable_name + ", Did " + + "you forget to call add_string()?\n"; + message_publish(MSG_WARNING, message.c_str()); + } } +/***************************************************************************** +summarize_variable +Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable) +*****************************************************************************/ +std::string MonteCarloVariableRandomStringSet::summarize_variable() const +{ + std::ostringstream ss; + // TODO: Here we create a string in [val1, val2, ... ] form, but this is + // ambigious because if there's a comma in any value, parsing the resultant + // string from the MonteCarlo_Meta_data_output file could fail. What delimter + // or approach would be better? -Jordan 10/2023 + ss << MonteCarloVariableRandomUniform::summarize_variable() << ", values=["; + if (values.size() > 0) { + for (auto val_it : values) { + ss << val_it << ","; + } + } + ss << "]"; + return (ss.str()); +} + /***************************************************************************** add_string Purpose:(Adds an option to the set of strings) @@ -64,3 +101,4 @@ MonteCarloVariableRandomStringSet::add_string( std::string new_string) { values.push_back(new_string); } + diff --git a/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_uniform.cc b/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_uniform.cc index 1287ae3d..6726deaa 100644 --- a/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_uniform.cc +++ b/trick_source/sim_services/MonteCarloGeneration/mc_variable_random_uniform.cc @@ -7,6 +7,7 @@ PROGRAMMERS: (((Gary Turner) (OSR) (October 2019) (Antares) (Initial))) (((Isaac Reaves) (NASA) (November 2022) (Integration into Trick Core))) **********************************************************************/ +#include // ostringstream #include "trick/mc_variable_random_uniform.hh" /***************************************************************************** @@ -33,6 +34,18 @@ MonteCarloVariableRandomUniform::generate_assignment() assign_double(distribution(random_generator)); } +/***************************************************************************** +summarize_variable +Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable) +*****************************************************************************/ +std::string MonteCarloVariableRandomUniform::summarize_variable() const +{ + std::ostringstream ss; + ss << MonteCarloVariable::summarize_variable() << std::string(", dispersion=Uniform") + << ", min_value=" << distribution.min() << ", max_value=" << distribution.max() + << ", seed=" << seed_m; + return (ss.str()); +} @@ -59,3 +72,15 @@ MonteCarloVariableRandomUniformInt::generate_assignment() { assign_int(distribution(random_generator)); } +/***************************************************************************** +summarize_variable +Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable) +*****************************************************************************/ +std::string MonteCarloVariableRandomUniformInt::summarize_variable() const +{ + std::ostringstream ss; + ss << MonteCarloVariable::summarize_variable() << std::string(" dispersion=Uniform,") + << " min_value=" << distribution.min() << ", max_value=" << distribution.max() + << ", seed=" << seed_m; + return (ss.str()); +}