fmdtools 2.5.2__tar.gz → 2.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fmdtools-2.5.2 → fmdtools-2.5.4}/LICENSE +1 -1
- {fmdtools-2.5.2/fmdtools.egg-info → fmdtools-2.5.4}/PKG-INFO +5 -5
- {fmdtools-2.5.2 → fmdtools-2.5.4}/README.md +3 -3
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/state.py +35 -28
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/contingency_management/model_aircraft.py +2 -2
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/contingency_management/model_environment.py +1 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/model_urban.py +4 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/test_pump_stochastic.py +2 -2
- {fmdtools-2.5.2 → fmdtools-2.5.4/fmdtools.egg-info}/PKG-INFO +5 -5
- {fmdtools-2.5.2 → fmdtools-2.5.4}/fmdtools.egg-info/SOURCES.txt +82 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/pyproject.toml +1 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/__init__.py +1 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/common.py +47 -22
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/graph/base.py +12 -2
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/history.py +59 -24
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/phases.py +20 -9
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/result.py +73 -28
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/tabulate.py +26 -17
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/architecture/action.py +1 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/architecture/geom.py +4 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/base.py +2 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/block/base.py +36 -16
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/container/base.py +2 -2
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/container/parameter.py +3 -2
- fmdtools-2.5.4/src/fmdtools/define/container/rand.py +956 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/container/state.py +15 -10
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/container/time.py +9 -3
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/object/coords.py +8 -3
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/object/timer.py +9 -6
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/sim/propagate.py +2 -1
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/sim/sample.py +83 -27
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/sim/scenario.py +33 -17
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/sim/search.py +12 -7
- fmdtools-2.5.4/tests/test_appended_history_snapshots.py +172 -0
- fmdtools-2.5.4/tests/test_approach_joint_domains.py +181 -0
- fmdtools-2.5.4/tests/test_approach_model_timestep.py +192 -0
- fmdtools-2.5.4/tests/test_approach_phase_map_ownership.py +129 -0
- fmdtools-2.5.4/tests/test_array_differences.py +153 -0
- fmdtools-2.5.4/tests/test_array_result_equality.py +167 -0
- fmdtools-2.5.4/tests/test_array_state_limits.py +126 -0
- fmdtools-2.5.4/tests/test_bootstrap_statistic_arguments.py +196 -0
- fmdtools-2.5.4/tests/test_bounded_array_increments.py +141 -0
- fmdtools-2.5.4/tests/test_callable_parameter_domains.py +142 -0
- fmdtools-2.5.4/tests/test_choice_draw_mass.py +198 -0
- fmdtools-2.5.4/tests/test_choice_probability_precision.py +173 -0
- fmdtools-2.5.4/tests/test_common.py +166 -0
- fmdtools-2.5.4/tests/test_coordinate_cell_boundaries.py +124 -0
- fmdtools-2.5.4/tests/test_default_fault_sample_timestep.py +162 -0
- fmdtools-2.5.4/tests/test_degradation_path_boundaries.py +153 -0
- fmdtools-2.5.4/tests/test_dirichlet_batches.py +195 -0
- fmdtools-2.5.4/tests/test_disconnected_graph_robustness.py +154 -0
- fmdtools-2.5.4/tests/test_discrete_sample_sizes.py +252 -0
- fmdtools-2.5.4/tests/test_exact_nominal_expectation.py +166 -0
- fmdtools-2.5.4/tests/test_explicit_result_file_formats.py +176 -0
- fmdtools-2.5.4/tests/test_exponential_rayleigh_draw_sizes.py +239 -0
- fmdtools-2.5.4/tests/test_factor_sort_priority.py +142 -0
- fmdtools-2.5.4/tests/test_fault_history_paths.py +179 -0
- fmdtools-2.5.4/tests/test_fault_weight_arrays.py +150 -0
- fmdtools-2.5.4/tests/test_faulty_scenario_selection.py +143 -0
- fmdtools-2.5.4/tests/test_fmea_input_ownership.py +126 -0
- fmdtools-2.5.4/tests/test_gamma_sampling_density.py +233 -0
- fmdtools-2.5.4/tests/test_generated_history_phase_timestep.py +92 -0
- fmdtools-2.5.4/tests/test_graph_edge_comparison.py +129 -0
- fmdtools-2.5.4/tests/test_history_phase_identifiers.py +204 -0
- fmdtools-2.5.4/tests/test_independent_single_replicate_seeds.py +201 -0
- fmdtools-2.5.4/tests/test_individual_result_paths.py +165 -0
- fmdtools-2.5.4/tests/test_integer_draw_mass.py +266 -0
- fmdtools-2.5.4/tests/test_join_phase_timestep.py +118 -0
- fmdtools-2.5.4/tests/test_joint_fault_metadata_order.py +137 -0
- fmdtools-2.5.4/tests/test_joint_fault_phase_map.py +192 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_joint_fault_weights.py +2 -1
- fmdtools-2.5.4/tests/test_json_result_arrays.py +163 -0
- fmdtools-2.5.4/tests/test_location_scale_draw_sizes.py +268 -0
- fmdtools-2.5.4/tests/test_lognormal_defaults.py +180 -0
- fmdtools-2.5.4/tests/test_metric_weight_alignment.py +140 -0
- fmdtools-2.5.4/tests/test_mixed_shape_degradation.py +180 -0
- fmdtools-2.5.4/tests/test_multidimensional_state_comparison.py +96 -0
- fmdtools-2.5.4/tests/test_multinomial_sampling_arguments.py +195 -0
- fmdtools-2.5.4/tests/test_multivariate_hypergeometric_options.py +201 -0
- fmdtools-2.5.4/tests/test_multivariate_normal_arguments.py +199 -0
- fmdtools-2.5.4/tests/test_named_default_restoration.py +143 -0
- fmdtools-2.5.4/tests/test_named_metric_rounding.py +152 -0
- fmdtools-2.5.4/tests/test_nearest_point_exclusion.py +89 -0
- fmdtools-2.5.4/tests/test_nested_history_summary.py +120 -0
- fmdtools-2.5.4/tests/test_nested_parameter_constraints.py +148 -0
- fmdtools-2.5.4/tests/test_nested_scenario_parameters.py +167 -0
- fmdtools-2.5.4/tests/test_not_equal_constraints.py +138 -0
- fmdtools-2.5.4/tests/test_object_history_copy.py +140 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_packages.py +3 -3
- fmdtools-2.5.4/tests/test_parameter_grid_bounds.py +140 -0
- fmdtools-2.5.4/tests/test_parameter_sample_defaults.py +146 -0
- fmdtools-2.5.4/tests/test_pareto_density.py +203 -0
- fmdtools-2.5.4/tests/test_permutation_axis_probabilities.py +188 -0
- fmdtools-2.5.4/tests/test_permuted_slice_probabilities.py +184 -0
- fmdtools-2.5.4/tests/test_phase_map_default_isolation.py +91 -0
- fmdtools-2.5.4/tests/test_ragged_confidence_histories.py +166 -0
- fmdtools-2.5.4/tests/test_rand.py +177 -0
- fmdtools-2.5.4/tests/test_random_combination_types.py +169 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_result.py +107 -11
- fmdtools-2.5.4/tests/test_result_constructor_input.py +121 -0
- fmdtools-2.5.4/tests/test_result_folder_selection.py +191 -0
- fmdtools-2.5.4/tests/test_sample.py +501 -0
- fmdtools-2.5.4/tests/test_scenario.py +211 -0
- fmdtools-2.5.4/tests/test_shape_distribution_sizes.py +221 -0
- fmdtools-2.5.4/tests/test_simple_problem_vector_inputs.py +164 -0
- fmdtools-2.5.4/tests/test_simulation_exposure.py +160 -0
- fmdtools-2.5.4/tests/test_standard_draw_arguments.py +205 -0
- fmdtools-2.5.4/tests/test_standard_t_density.py +192 -0
- fmdtools-2.5.4/tests/test_string_state_histories.py +96 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_time.py +4 -4
- fmdtools-2.5.4/tests/test_time_reset.py +103 -0
- fmdtools-2.5.4/tests/test_triangular_arraylike_parameters.py +181 -0
- fmdtools-2.5.4/tests/test_tuple_table_factors.py +143 -0
- fmdtools-2.5.4/tests/test_unit_random_density.py +176 -0
- fmdtools-2.5.4/tests/test_vonmises_density.py +222 -0
- fmdtools-2.5.4/tests/test_wald_density.py +188 -0
- fmdtools-2.5.4/tests/test_weighted_percent_metrics.py +106 -0
- fmdtools-2.5.4/tests/test_zero_fault_start_times.py +120 -0
- fmdtools-2.5.4/tests/test_zero_time_objectives.py +117 -0
- fmdtools-2.5.4/tests/test_zero_timer_increment.py +130 -0
- fmdtools-2.5.2/src/fmdtools/define/container/rand.py +0 -668
- fmdtools-2.5.2/tests/test_sample.py +0 -165
- fmdtools-2.5.2/tests/test_scenario.py +0 -111
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airport_taxiway/model_asset.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airport_taxiway/model_atc.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airport_taxiway/model_common.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airport_taxiway/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airport_taxiway/test_asset.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airport_taxiway/test_model.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/aircraft.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/aircraftarchitecture.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/arch/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/arch/aviate.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/arch/controlflight.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/arch/flows.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/arch/holdpayload.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/arch/perceiveenvironment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/arch/storeee.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/base/parameter.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/contingency_management/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/contingency_management/model_flightplanner.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/water_rescue/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/water_rescue/model_drone.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/water_rescue/model_environment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/water_rescue/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/water_rescue/model_responder.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/wildfire_response/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/wildfire_response/model_aircraft.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/wildfire_response/model_environment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/wildfire_response/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/cooling_tank/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/cooling_tank/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/cooling_tank/model_optimization.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/cooling_tank/test_tank.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/electric_power_system/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/electric_power_system/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/electric_power_system/test_model.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/human_hazard_mitigation/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/human_hazard_mitigation/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/model_dynamic.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/model_hierarchical.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/model_rural.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/model_static.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/script_opt_model_rural.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/multirotor_drone/test_multirotor.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/model_degradation.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/model_human.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/model_troupe.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/script_ea_analysis.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/script_mode_space.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/script_search_rover.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/navigating_rover/test_rover.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/state_communication/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/state_communication/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/state_communication/test_multiflow.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/model_indiv.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/model_stochastic.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/script_jointfaults.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/script_parallelism.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/test_pump.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/examples/water_pump/test_pump_example.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/fmdtools.egg-info/dependency_links.txt +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/fmdtools.egg-info/requires.txt +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/fmdtools.egg-info/top_level.txt +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/setup.cfg +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/graph/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/graph/label.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/graph/model.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/analyze/graph/style.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/architecture/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/architecture/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/architecture/component.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/architecture/function.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/block/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/block/action.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/block/component.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/block/function.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/container/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/container/mode.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/environment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/flow/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/flow/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/flow/commsflow.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/flow/multiflow.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/object/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/object/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/object/geom.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/define/pathplan.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/src/fmdtools/sim/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/common.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_array_random_states.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_calc_metric_ci_constant_outputs.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_comparison_groups.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_confidence_history_clipping.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_error_history_plots.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_fault_sample_without_nominal.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_fault_time_without_traces.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_geom.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_graph.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_hierarchical.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_history_standard_deviation.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_join_phasemaps.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_nested_nominal_groups.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_nesting_custom_separators.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_parameter_sample_seeds.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_parameter_subsampling_types.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_pathplan.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_phase_timestep.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_pruned_fault_times.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_scenario_defaults.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_table_factor_indices.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.4}/tests/test_uniform_density.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmdtools
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.4
|
|
4
4
|
Summary: System resilience modelling, simulation, and assessment in Python
|
|
5
5
|
Author: fmdtools Developers
|
|
6
6
|
Maintainer-email: Daniel Hulse <daniel.e.hulse@nasa.gov>
|
|
7
|
-
License: fmdtools version 2.5.
|
|
7
|
+
License: fmdtools version 2.5.4
|
|
8
8
|
---------------------------
|
|
9
9
|
Apache License
|
|
10
10
|
Version 2.0, January 2004
|
|
@@ -394,7 +394,7 @@ More guidance on development installations is provided in [How to Contribute](ht
|
|
|
394
394
|
Note that this version reflects the latest version on the ``main`` git branch along with any local changes. To use a particular version of ``fmdtools`` in the context of a development install you can checkout the tag corresponding to the version you want, e.g.:
|
|
395
395
|
|
|
396
396
|
```
|
|
397
|
-
git checkout v2.5.
|
|
397
|
+
git checkout v2.5.4
|
|
398
398
|
```
|
|
399
399
|
|
|
400
400
|
|
|
@@ -548,8 +548,8 @@ To cite a particular version of the fmdtools, you may use:
|
|
|
548
548
|
author = {{NASA}},
|
|
549
549
|
title = {fmdtools},
|
|
550
550
|
url = {https://github.com/nasa/fmdtools},
|
|
551
|
-
version = {2.5.
|
|
552
|
-
date = {2026-
|
|
551
|
+
version = {2.5.4},
|
|
552
|
+
date = {2026-10-5},
|
|
553
553
|
}
|
|
554
554
|
```
|
|
555
555
|
|
|
@@ -123,7 +123,7 @@ More guidance on development installations is provided in [How to Contribute](ht
|
|
|
123
123
|
Note that this version reflects the latest version on the ``main`` git branch along with any local changes. To use a particular version of ``fmdtools`` in the context of a development install you can checkout the tag corresponding to the version you want, e.g.:
|
|
124
124
|
|
|
125
125
|
```
|
|
126
|
-
git checkout v2.5.
|
|
126
|
+
git checkout v2.5.4
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
|
|
@@ -277,8 +277,8 @@ To cite a particular version of the fmdtools, you may use:
|
|
|
277
277
|
author = {{NASA}},
|
|
278
278
|
title = {fmdtools},
|
|
279
279
|
url = {https://github.com/nasa/fmdtools},
|
|
280
|
-
version = {2.5.
|
|
281
|
-
date = {2026-
|
|
280
|
+
version = {2.5.4},
|
|
281
|
+
date = {2026-10-5},
|
|
282
282
|
}
|
|
283
283
|
```
|
|
284
284
|
|
|
@@ -41,19 +41,26 @@ class AircraftPosition(State):
|
|
|
41
41
|
dy: float = 0.0
|
|
42
42
|
dims = ('x', 'y')
|
|
43
43
|
|
|
44
|
-
def
|
|
44
|
+
def get_dims(self, *dims):
|
|
45
|
+
"""Get the dimensions to calculate over. Default is self.dims."""
|
|
46
|
+
if not dims:
|
|
47
|
+
return self.dims
|
|
48
|
+
else:
|
|
49
|
+
return dims
|
|
50
|
+
|
|
51
|
+
def get_goal(self, *dims):
|
|
45
52
|
"""Get the goal attributes (goal_x, goal_y) of the AircraftPosition."""
|
|
46
|
-
return self.get(*['goal_'+d for d in self.dims])
|
|
53
|
+
return self.get(*['goal_'+d for d in self.get_dims(*dims)])
|
|
47
54
|
|
|
48
|
-
def get_loc(self):
|
|
55
|
+
def get_loc(self, *dims):
|
|
49
56
|
"""Get the location (x, y) attributes of the AircraftPosition."""
|
|
50
|
-
return self.get(*self.dims)
|
|
57
|
+
return self.get(*self.get_dims(*dims))
|
|
51
58
|
|
|
52
|
-
def get_vel(self):
|
|
59
|
+
def get_vel(self, *dims):
|
|
53
60
|
"""Get the velocity attributes (dx, dy) of the AircraftPosition."""
|
|
54
|
-
return self.get(*['d'+d for d in self.dims])
|
|
61
|
+
return self.get(*['d'+d for d in self.get_dims(*dims)])
|
|
55
62
|
|
|
56
|
-
def find_direction(self):
|
|
63
|
+
def find_direction(self, *dims):
|
|
57
64
|
"""
|
|
58
65
|
Find the (unit vector) direction from the x,y to goal_x, goal_y.
|
|
59
66
|
|
|
@@ -71,22 +78,22 @@ class AircraftPosition(State):
|
|
|
71
78
|
>>> ap.find_direction()
|
|
72
79
|
array([0., 1.])
|
|
73
80
|
"""
|
|
74
|
-
dist = self.calc_dist()
|
|
81
|
+
dist = self.calc_dist(*dims)
|
|
75
82
|
if dist > 0.0:
|
|
76
83
|
return self.calc_vector_dist()/self.calc_dist()
|
|
77
84
|
else:
|
|
78
85
|
return np.zeros(len(self.dims))
|
|
79
86
|
|
|
80
|
-
def calc_vector_dist(self):
|
|
87
|
+
def calc_vector_dist(self, *dims):
|
|
81
88
|
"""Calculate the vector distance from x,y to goal_x, goal_y."""
|
|
82
|
-
return self.get_goal() - self.get_loc()
|
|
89
|
+
return self.get_goal(*dims) - self.get_loc(*dims)
|
|
83
90
|
|
|
84
|
-
def calc_dist(self):
|
|
91
|
+
def calc_dist(self, *dims):
|
|
85
92
|
"""Calculate the scalar distance from x,y to goal_x, goal_y."""
|
|
86
|
-
vector_dist = self.calc_vector_dist()
|
|
93
|
+
vector_dist = self.calc_vector_dist(*dims)
|
|
87
94
|
return np.sqrt(sum(vector_dist**2))
|
|
88
95
|
|
|
89
|
-
def at_goal(self):
|
|
96
|
+
def at_goal(self, *dims):
|
|
90
97
|
"""
|
|
91
98
|
Determine if the aircraft is at its goal location.
|
|
92
99
|
|
|
@@ -99,17 +106,17 @@ class AircraftPosition(State):
|
|
|
99
106
|
>>> ap.at_goal()
|
|
100
107
|
True
|
|
101
108
|
"""
|
|
102
|
-
return all(self.get_goal() == self.get_loc())
|
|
109
|
+
return all(self.get_goal(*dims) == self.get_loc(*dims))
|
|
103
110
|
|
|
104
|
-
def in_range(self, dist_range=10.0):
|
|
111
|
+
def in_range(self, *dims, dist_range=10.0):
|
|
105
112
|
"""Determine if the aircraft is in the range of its goal location."""
|
|
106
|
-
return self.calc_dist() <= dist_range
|
|
113
|
+
return self.calc_dist(*dims) <= dist_range
|
|
107
114
|
|
|
108
|
-
def calc_dist_to_travel(self, dist_range=10.0):
|
|
115
|
+
def calc_dist_to_travel(self, *dims, dist_range=10.0):
|
|
109
116
|
"""Determine the distance to the goal location (under max dist dist_range)."""
|
|
110
|
-
return np.min([dist_range, self.calc_dist()])
|
|
117
|
+
return np.min([dist_range, self.calc_dist(*dims)])
|
|
111
118
|
|
|
112
|
-
def update_dist_to_travel(self, maxvel=10.0):
|
|
119
|
+
def update_dist_to_travel(self, *dims, maxvel=10.0):
|
|
113
120
|
"""
|
|
114
121
|
Update dx, dy to reflect goal location (travelling at max velocity).
|
|
115
122
|
|
|
@@ -128,14 +135,14 @@ class AircraftPosition(State):
|
|
|
128
135
|
>>> ap
|
|
129
136
|
AircraftPosition(x=0.0, goal_x=10.0, dx=10.0, y=0.0, goal_y=0.0, dy=0.0)
|
|
130
137
|
"""
|
|
131
|
-
if self.in_range(dist_range=maxvel):
|
|
132
|
-
vel = self.calc_dist()
|
|
138
|
+
if self.in_range(*dims, dist_range=maxvel):
|
|
139
|
+
vel = self.calc_dist(*dims)
|
|
133
140
|
else:
|
|
134
141
|
vel = maxvel
|
|
135
|
-
vels = vel * self.find_direction()
|
|
136
|
-
self.put(**{'d'+dim: vels[i] for i, dim in enumerate(self.dims)})
|
|
142
|
+
vels = vel * self.find_direction(*dims)
|
|
143
|
+
self.put(**{'d'+dim: vels[i] for i, dim in enumerate(self.get_dims(*dims))})
|
|
137
144
|
|
|
138
|
-
def update_position(self, maxvel=10.0):
|
|
145
|
+
def update_position(self, *dims, maxvel=10.0):
|
|
139
146
|
"""
|
|
140
147
|
Update x, y to reflect progress towards the goal location at maxvel.
|
|
141
148
|
|
|
@@ -157,12 +164,12 @@ class AircraftPosition(State):
|
|
|
157
164
|
>>> ap
|
|
158
165
|
AircraftPosition(x=10.0, goal_x=10.0, dx=0.0, y=10.0, goal_y=10.0, dy=0.0)
|
|
159
166
|
"""
|
|
160
|
-
self.update_dist_to_travel(maxvel=maxvel)
|
|
161
|
-
self.increment_position()
|
|
167
|
+
self.update_dist_to_travel(*dims, maxvel=maxvel)
|
|
168
|
+
self.increment_position(*dims)
|
|
162
169
|
|
|
163
|
-
def increment_position(self):
|
|
170
|
+
def increment_position(self, *dims):
|
|
164
171
|
"""Increment position (x,y) by (dx, dy)."""
|
|
165
|
-
self.inc(**{dim: getattr(self, 'd'+dim) for dim in self.dims})
|
|
172
|
+
self.inc(**{dim: getattr(self, 'd'+dim) for dim in self.get_dims(*dims)})
|
|
166
173
|
|
|
167
174
|
|
|
168
175
|
class AircraftPosition3(AircraftPosition):
|
{fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/contingency_management/model_aircraft.py
RENAMED
|
@@ -148,9 +148,9 @@ class ContingencyControlFlight(ControlFlight):
|
|
|
148
148
|
"""Set new landing location in depletion scenario."""
|
|
149
149
|
ts = self.trajectories.s.copy()
|
|
150
150
|
ts.assign(self.environment.c.start, "goal_x", "goal_y")
|
|
151
|
-
dist_to_start = ts.calc_dist_to_travel(1000)
|
|
151
|
+
dist_to_start = ts.calc_dist_to_travel(dist_range=1000)
|
|
152
152
|
ts.assign(self.environment.c.end, "goal_x", "goal_y")
|
|
153
|
-
dist_to_end = ts.calc_dist_to_travel(1000)
|
|
153
|
+
dist_to_end = ts.calc_dist_to_travel(dist_range=1000)
|
|
154
154
|
if dist_to_end < self.electricity.s.charge:
|
|
155
155
|
self.s.endpt = self.environment.c.end
|
|
156
156
|
elif dist_to_start < self.electricity.s.charge:
|
{fmdtools-2.5.2 → fmdtools-2.5.4}/examples/airspacelib/contingency_management/model_environment.py
RENAMED
|
@@ -165,7 +165,7 @@ class Threat(GeomPoint):
|
|
|
165
165
|
|
|
166
166
|
def update_position(self):
|
|
167
167
|
"""Update position given known speed."""
|
|
168
|
-
self.s.update_position(self.s.buffer_speed)
|
|
168
|
+
self.s.update_position(maxvel=self.s.buffer_speed)
|
|
169
169
|
|
|
170
170
|
def get_shapely_args(self):
|
|
171
171
|
return (self.s.x, self.s.y)
|
|
@@ -322,6 +322,7 @@ class Drone(DroneRural):
|
|
|
322
322
|
('taxi', 12, 20)),
|
|
323
323
|
end_time=30,
|
|
324
324
|
units='min',
|
|
325
|
+
use_local=False,
|
|
325
326
|
dt=0.1)
|
|
326
327
|
|
|
327
328
|
def init_architecture(self, **kwargs):
|
|
@@ -499,6 +500,9 @@ if __name__ == "__main__":
|
|
|
499
500
|
# UrbanDroneEnvironment("a")
|
|
500
501
|
# PlanPath._init_environment("a")
|
|
501
502
|
# p = PlanPath("test", {})
|
|
503
|
+
mdl = Drone(sp={'end_condition': 'scenario_finished', 'dt': 0.1}, t={'local_dt': 0.1})
|
|
504
|
+
results_fault, hist_fault = propagate.one_fault(mdl, "affect_dof.ca.comps.lr", "mechbreak", time=1.4)
|
|
505
|
+
fig, ax = plot_env_with_traj_z(hist_fault, mdl, title = "Urban Drone Trajectory")
|
|
502
506
|
|
|
503
507
|
e = UrbanDroneEnvironment("env")
|
|
504
508
|
e.c.show({"height": {}})
|
|
@@ -48,7 +48,7 @@ class StochasticPumpTests(unittest.TestCase, CommonTests):
|
|
|
48
48
|
49.32124529702974,
|
|
49
49
|
0.31327201999190035,
|
|
50
50
|
21.386958080811567,
|
|
51
|
-
3.
|
|
51
|
+
3.331196298953918,
|
|
52
52
|
9.066120598345039,
|
|
53
53
|
131.79987407014573,
|
|
54
54
|
5.81402243889764,
|
|
@@ -277,7 +277,7 @@ class StochasticPumpTests(unittest.TestCase, CommonTests):
|
|
|
277
277
|
|
|
278
278
|
if __name__ == '__main__':
|
|
279
279
|
# suite = unittest.TestSuite()
|
|
280
|
-
# suite.addTest(StochasticPumpTests("
|
|
280
|
+
# suite.addTest(StochasticPumpTests("test_stochastic_pdf"))
|
|
281
281
|
# suite.addTest(StochasticPumpTests("test_save_load_nominalapproach_indiv"))
|
|
282
282
|
# runner = unittest.TextTestRunner()
|
|
283
283
|
# runner.run(suite)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmdtools
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.4
|
|
4
4
|
Summary: System resilience modelling, simulation, and assessment in Python
|
|
5
5
|
Author: fmdtools Developers
|
|
6
6
|
Maintainer-email: Daniel Hulse <daniel.e.hulse@nasa.gov>
|
|
7
|
-
License: fmdtools version 2.5.
|
|
7
|
+
License: fmdtools version 2.5.4
|
|
8
8
|
---------------------------
|
|
9
9
|
Apache License
|
|
10
10
|
Version 2.0, January 2004
|
|
@@ -394,7 +394,7 @@ More guidance on development installations is provided in [How to Contribute](ht
|
|
|
394
394
|
Note that this version reflects the latest version on the ``main`` git branch along with any local changes. To use a particular version of ``fmdtools`` in the context of a development install you can checkout the tag corresponding to the version you want, e.g.:
|
|
395
395
|
|
|
396
396
|
```
|
|
397
|
-
git checkout v2.5.
|
|
397
|
+
git checkout v2.5.4
|
|
398
398
|
```
|
|
399
399
|
|
|
400
400
|
|
|
@@ -548,8 +548,8 @@ To cite a particular version of the fmdtools, you may use:
|
|
|
548
548
|
author = {{NASA}},
|
|
549
549
|
title = {fmdtools},
|
|
550
550
|
url = {https://github.com/nasa/fmdtools},
|
|
551
|
-
version = {2.5.
|
|
552
|
-
date = {2026-
|
|
551
|
+
version = {2.5.4},
|
|
552
|
+
date = {2026-10-5},
|
|
553
553
|
}
|
|
554
554
|
```
|
|
555
555
|
|
|
@@ -127,31 +127,112 @@ src/fmdtools/sim/scenario.py
|
|
|
127
127
|
src/fmdtools/sim/search.py
|
|
128
128
|
tests/__init__.py
|
|
129
129
|
tests/common.py
|
|
130
|
+
tests/test_appended_history_snapshots.py
|
|
131
|
+
tests/test_approach_joint_domains.py
|
|
132
|
+
tests/test_approach_model_timestep.py
|
|
133
|
+
tests/test_approach_phase_map_ownership.py
|
|
134
|
+
tests/test_array_differences.py
|
|
130
135
|
tests/test_array_random_states.py
|
|
136
|
+
tests/test_array_result_equality.py
|
|
137
|
+
tests/test_array_state_limits.py
|
|
138
|
+
tests/test_bootstrap_statistic_arguments.py
|
|
139
|
+
tests/test_bounded_array_increments.py
|
|
131
140
|
tests/test_calc_metric_ci_constant_outputs.py
|
|
141
|
+
tests/test_callable_parameter_domains.py
|
|
142
|
+
tests/test_choice_draw_mass.py
|
|
143
|
+
tests/test_choice_probability_precision.py
|
|
144
|
+
tests/test_common.py
|
|
132
145
|
tests/test_comparison_groups.py
|
|
133
146
|
tests/test_confidence_history_clipping.py
|
|
147
|
+
tests/test_coordinate_cell_boundaries.py
|
|
148
|
+
tests/test_default_fault_sample_timestep.py
|
|
149
|
+
tests/test_degradation_path_boundaries.py
|
|
150
|
+
tests/test_dirichlet_batches.py
|
|
151
|
+
tests/test_disconnected_graph_robustness.py
|
|
152
|
+
tests/test_discrete_sample_sizes.py
|
|
134
153
|
tests/test_error_history_plots.py
|
|
154
|
+
tests/test_exact_nominal_expectation.py
|
|
155
|
+
tests/test_explicit_result_file_formats.py
|
|
156
|
+
tests/test_exponential_rayleigh_draw_sizes.py
|
|
157
|
+
tests/test_factor_sort_priority.py
|
|
158
|
+
tests/test_fault_history_paths.py
|
|
135
159
|
tests/test_fault_sample_without_nominal.py
|
|
136
160
|
tests/test_fault_time_without_traces.py
|
|
161
|
+
tests/test_fault_weight_arrays.py
|
|
162
|
+
tests/test_faulty_scenario_selection.py
|
|
163
|
+
tests/test_fmea_input_ownership.py
|
|
164
|
+
tests/test_gamma_sampling_density.py
|
|
165
|
+
tests/test_generated_history_phase_timestep.py
|
|
137
166
|
tests/test_geom.py
|
|
138
167
|
tests/test_graph.py
|
|
168
|
+
tests/test_graph_edge_comparison.py
|
|
139
169
|
tests/test_hierarchical.py
|
|
170
|
+
tests/test_history_phase_identifiers.py
|
|
140
171
|
tests/test_history_standard_deviation.py
|
|
172
|
+
tests/test_independent_single_replicate_seeds.py
|
|
173
|
+
tests/test_individual_result_paths.py
|
|
174
|
+
tests/test_integer_draw_mass.py
|
|
175
|
+
tests/test_join_phase_timestep.py
|
|
141
176
|
tests/test_join_phasemaps.py
|
|
177
|
+
tests/test_joint_fault_metadata_order.py
|
|
178
|
+
tests/test_joint_fault_phase_map.py
|
|
142
179
|
tests/test_joint_fault_weights.py
|
|
180
|
+
tests/test_json_result_arrays.py
|
|
181
|
+
tests/test_location_scale_draw_sizes.py
|
|
182
|
+
tests/test_lognormal_defaults.py
|
|
183
|
+
tests/test_metric_weight_alignment.py
|
|
184
|
+
tests/test_mixed_shape_degradation.py
|
|
185
|
+
tests/test_multidimensional_state_comparison.py
|
|
186
|
+
tests/test_multinomial_sampling_arguments.py
|
|
187
|
+
tests/test_multivariate_hypergeometric_options.py
|
|
188
|
+
tests/test_multivariate_normal_arguments.py
|
|
189
|
+
tests/test_named_default_restoration.py
|
|
190
|
+
tests/test_named_metric_rounding.py
|
|
191
|
+
tests/test_nearest_point_exclusion.py
|
|
192
|
+
tests/test_nested_history_summary.py
|
|
143
193
|
tests/test_nested_nominal_groups.py
|
|
194
|
+
tests/test_nested_parameter_constraints.py
|
|
195
|
+
tests/test_nested_scenario_parameters.py
|
|
144
196
|
tests/test_nesting_custom_separators.py
|
|
197
|
+
tests/test_not_equal_constraints.py
|
|
198
|
+
tests/test_object_history_copy.py
|
|
145
199
|
tests/test_packages.py
|
|
200
|
+
tests/test_parameter_grid_bounds.py
|
|
201
|
+
tests/test_parameter_sample_defaults.py
|
|
146
202
|
tests/test_parameter_sample_seeds.py
|
|
147
203
|
tests/test_parameter_subsampling_types.py
|
|
204
|
+
tests/test_pareto_density.py
|
|
148
205
|
tests/test_pathplan.py
|
|
206
|
+
tests/test_permutation_axis_probabilities.py
|
|
207
|
+
tests/test_permuted_slice_probabilities.py
|
|
208
|
+
tests/test_phase_map_default_isolation.py
|
|
149
209
|
tests/test_phase_timestep.py
|
|
150
210
|
tests/test_pruned_fault_times.py
|
|
211
|
+
tests/test_ragged_confidence_histories.py
|
|
212
|
+
tests/test_rand.py
|
|
213
|
+
tests/test_random_combination_types.py
|
|
151
214
|
tests/test_result.py
|
|
215
|
+
tests/test_result_constructor_input.py
|
|
216
|
+
tests/test_result_folder_selection.py
|
|
152
217
|
tests/test_sample.py
|
|
153
218
|
tests/test_scenario.py
|
|
154
219
|
tests/test_scenario_defaults.py
|
|
220
|
+
tests/test_shape_distribution_sizes.py
|
|
221
|
+
tests/test_simple_problem_vector_inputs.py
|
|
222
|
+
tests/test_simulation_exposure.py
|
|
223
|
+
tests/test_standard_draw_arguments.py
|
|
224
|
+
tests/test_standard_t_density.py
|
|
225
|
+
tests/test_string_state_histories.py
|
|
155
226
|
tests/test_table_factor_indices.py
|
|
156
227
|
tests/test_time.py
|
|
157
|
-
tests/
|
|
228
|
+
tests/test_time_reset.py
|
|
229
|
+
tests/test_triangular_arraylike_parameters.py
|
|
230
|
+
tests/test_tuple_table_factors.py
|
|
231
|
+
tests/test_uniform_density.py
|
|
232
|
+
tests/test_unit_random_density.py
|
|
233
|
+
tests/test_vonmises_density.py
|
|
234
|
+
tests/test_wald_density.py
|
|
235
|
+
tests/test_weighted_percent_metrics.py
|
|
236
|
+
tests/test_zero_fault_start_times.py
|
|
237
|
+
tests/test_zero_time_objectives.py
|
|
238
|
+
tests/test_zero_timer_increment.py
|
|
@@ -35,6 +35,7 @@ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
|
35
35
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
36
36
|
specific language governing permissions and limitations under the License.
|
|
37
37
|
"""
|
|
38
|
+
import math
|
|
38
39
|
import numpy as np
|
|
39
40
|
import os
|
|
40
41
|
import matplotlib.pyplot as plt
|
|
@@ -42,6 +43,7 @@ from matplotlib import rcParams
|
|
|
42
43
|
import inspect
|
|
43
44
|
from scipy.stats import bootstrap
|
|
44
45
|
from fmdtools.define.base import filter_kwargs, round_float
|
|
46
|
+
from functools import partial
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
plt.rcParams['pdf.fonttype'] = 42
|
|
@@ -180,11 +182,11 @@ def create_indiv_filename(filename, indiv_id, splitchar='_'):
|
|
|
180
182
|
--------
|
|
181
183
|
>>> create_indiv_filename("hi.csv", "4")
|
|
182
184
|
'hi_4.csv'
|
|
185
|
+
>>> create_indiv_filename("runs.v1/results.v2.csv", "4", splitchar="/")
|
|
186
|
+
'runs.v1/results.v2/4.csv'
|
|
183
187
|
"""
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
filename_parts.insert(1, splitchar+indiv_id)
|
|
187
|
-
return "".join(filename_parts)
|
|
188
|
+
stem, extension = os.path.splitext(filename)
|
|
189
|
+
return stem + splitchar + indiv_id + extension
|
|
188
190
|
|
|
189
191
|
|
|
190
192
|
def load_folder(folder, filetype):
|
|
@@ -198,20 +200,17 @@ def load_folder(folder, filetype):
|
|
|
198
200
|
folder : str
|
|
199
201
|
Name of the folder. Must be in the current directory
|
|
200
202
|
filetype : str
|
|
201
|
-
Type of files in the folder ('
|
|
203
|
+
Type of files in the folder ('npz', 'csv', or 'json'). Other extensions
|
|
204
|
+
and subdirectories are ignored; matching files are not searched recursively.
|
|
202
205
|
|
|
203
206
|
Returns
|
|
204
207
|
-------
|
|
205
208
|
files_to_read : list
|
|
206
209
|
files to load for results/mdlhists.
|
|
207
210
|
"""
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
read_filetype = auto_filetype(file)
|
|
212
|
-
if read_filetype == filetype:
|
|
213
|
-
files_toread.append(file)
|
|
214
|
-
return files_toread
|
|
211
|
+
return [file for file in os.listdir(folder)
|
|
212
|
+
if file.endswith('.' + filetype)
|
|
213
|
+
and os.path.isfile(os.path.join(folder, file))]
|
|
215
214
|
|
|
216
215
|
|
|
217
216
|
def metric_preamble(data, dtype=None, rates=None, r_dtype=None, r_norm=False):
|
|
@@ -255,7 +254,8 @@ def calc_metric(data, method=np.average, args=(), axis=None, dtype=None,
|
|
|
255
254
|
r_norm : bool, optional
|
|
256
255
|
Whether to normalize rates. The default is False.
|
|
257
256
|
round_value : bool, optional
|
|
258
|
-
Whether to round the value
|
|
257
|
+
Whether to round the final value, including named metrics.
|
|
258
|
+
Applied once after evaluation. Default is True.
|
|
259
259
|
res : float
|
|
260
260
|
Resolution to round to. Default is 1e-6.
|
|
261
261
|
min_r : int
|
|
@@ -283,8 +283,9 @@ def calc_metric(data, method=np.average, args=(), axis=None, dtype=None,
|
|
|
283
283
|
"""
|
|
284
284
|
if isinstance(method, str):
|
|
285
285
|
method = eval("calc_"+method)
|
|
286
|
+
# Named helpers call calc_metric again; round only the final result.
|
|
286
287
|
metric = method(data, args=args, axis=axis, dtype=dtype, rates=rates,
|
|
287
|
-
r_dtype=r_dtype, r_norm=r_norm, **kwargs)
|
|
288
|
+
r_dtype=r_dtype, r_norm=r_norm, round_value=False, **kwargs)
|
|
288
289
|
else:
|
|
289
290
|
vals = metric_preamble(data, dtype, rates, r_dtype, r_norm)
|
|
290
291
|
metric = method(vals, *args, **filter_kwargs(method, **kwargs, axis=axis))
|
|
@@ -309,7 +310,8 @@ def calc_metric_ci(data, method=np.average, return_anyway=False, interval=None,
|
|
|
309
310
|
axis : int
|
|
310
311
|
Axis along which to calculate the confidence interval(s). The default is 0.
|
|
311
312
|
**kwargs : kwargs
|
|
312
|
-
Keyword arguments to
|
|
313
|
+
Keyword arguments to the statistic, preprocessing, or scipy.bootstrap.
|
|
314
|
+
Statistic arguments are used for both the point estimate and resamples.
|
|
313
315
|
|
|
314
316
|
Returns
|
|
315
317
|
-------
|
|
@@ -339,15 +341,16 @@ def calc_metric_ci(data, method=np.average, return_anyway=False, interval=None,
|
|
|
339
341
|
val = np.take(vals, [0], axis=axis)
|
|
340
342
|
if "weights" in kwargs and kwargs['weights'] is not None:
|
|
341
343
|
raise Exception("Weights not able to be used w- bootstrap--use rates instead.")
|
|
342
|
-
|
|
344
|
+
statistic = partial(method, **filter_kwargs(method, **kwargs))
|
|
345
|
+
met_val = statistic(vals, axis=axis)
|
|
343
346
|
vals_vary = vals == val
|
|
344
347
|
# Preserve the existing policy for globally identical data.
|
|
345
348
|
if not np.all(vals == vals.flat[0]):
|
|
346
349
|
if np.any(np.all(vals_vary, axis=axis)):
|
|
347
350
|
# use more robust/basic algorithm if some indices don't vary
|
|
348
|
-
bs = bootstrap([vals],
|
|
351
|
+
bs = bootstrap([vals], statistic, axis=axis, method="basic", **bs_kwar)
|
|
349
352
|
else:
|
|
350
|
-
bs = bootstrap([vals],
|
|
353
|
+
bs = bootstrap([vals], statistic, axis=axis, **bs_kwar)
|
|
351
354
|
return met_val, bs.confidence_interval.low, bs.confidence_interval.high
|
|
352
355
|
elif return_anyway:
|
|
353
356
|
return met_val, met_val, met_val
|
|
@@ -355,10 +358,26 @@ def calc_metric_ci(data, method=np.average, return_anyway=False, interval=None,
|
|
|
355
358
|
raise Exception("All data are the same!")
|
|
356
359
|
|
|
357
360
|
|
|
361
|
+
def _uniform_rate(data, axis=None):
|
|
362
|
+
"""Assign uniform mass over reduced axes, preserving unreduced dimensions."""
|
|
363
|
+
shape = np.shape(data)
|
|
364
|
+
if axis is None:
|
|
365
|
+
count = np.size(data)
|
|
366
|
+
elif not shape:
|
|
367
|
+
count = 1 # NumPy's subsequent reduction validates scalar axes.
|
|
368
|
+
else:
|
|
369
|
+
axes = axis if isinstance(axis, tuple) else (axis,)
|
|
370
|
+
count = math.prod(shape[a] for a in axes)
|
|
371
|
+
return 1 / count
|
|
372
|
+
|
|
373
|
+
|
|
358
374
|
def calc_rate(data, rates=None, weights=None, **kwargs):
|
|
359
375
|
"""
|
|
360
376
|
Calculate a rate of a non-zero value in data using calc_metric.
|
|
361
377
|
|
|
378
|
+
With no explicit rates, use equal probability over the selected axis/axes.
|
|
379
|
+
Other dimensions, such as history time, do not dilute each reduced rate.
|
|
380
|
+
|
|
362
381
|
Examples
|
|
363
382
|
--------
|
|
364
383
|
>>> calc_rate([0, 10, 0]) # defaults to equal rate
|
|
@@ -367,21 +386,24 @@ def calc_rate(data, rates=None, weights=None, **kwargs):
|
|
|
367
386
|
np.float64(0.2)
|
|
368
387
|
"""
|
|
369
388
|
if rates is None:
|
|
370
|
-
rates =
|
|
389
|
+
rates = _uniform_rate(data, kwargs.get('axis'))
|
|
371
390
|
kwar = {**kwargs, 'method': np.sum, 'dtype': bool, 'rates': rates}
|
|
372
391
|
return calc_metric(data, **kwar)
|
|
373
392
|
|
|
374
393
|
|
|
375
394
|
def calc_percent(data, weights=None, rates=None, **kwargs):
|
|
376
395
|
"""
|
|
377
|
-
Calculate a
|
|
396
|
+
Calculate a weighted fraction of non-zero values using calc_metric.
|
|
397
|
+
|
|
398
|
+
Weights are passed to the averaging method; omitted weights give each value
|
|
399
|
+
equal influence. Rates remain separate from percentage weights.
|
|
378
400
|
|
|
379
401
|
Examples
|
|
380
402
|
--------
|
|
381
403
|
>>> calc_percent([0, 10, 0])
|
|
382
404
|
np.float64(0.333333)
|
|
383
405
|
"""
|
|
384
|
-
return calc_metric(data, **{**kwargs, 'dtype': bool})
|
|
406
|
+
return calc_metric(data, **{**kwargs, 'dtype': bool, 'weights': weights})
|
|
385
407
|
|
|
386
408
|
|
|
387
409
|
def calc_total(data, weights=None, **kwargs):
|
|
@@ -402,6 +424,9 @@ def calc_expected(data, rates=None, weights=None, **kwargs):
|
|
|
402
424
|
"""
|
|
403
425
|
Calculate the expected value of given data using calc_metric.
|
|
404
426
|
|
|
427
|
+
With no explicit rates, use equal probability over the selected axis/axes.
|
|
428
|
+
Explicit rates retain their existing weighted-sum interpretation.
|
|
429
|
+
|
|
405
430
|
Examples
|
|
406
431
|
--------
|
|
407
432
|
>>> calc_expected([0, 5, 10]) # defaults to average
|
|
@@ -410,7 +435,7 @@ def calc_expected(data, rates=None, weights=None, **kwargs):
|
|
|
410
435
|
np.float64(3.5)
|
|
411
436
|
"""
|
|
412
437
|
if rates is None:
|
|
413
|
-
rates =
|
|
438
|
+
rates = _uniform_rate(data, kwargs.get('axis'))
|
|
414
439
|
return calc_metric(data, **{**kwargs, 'method': np.sum, 'rates': rates})
|
|
415
440
|
|
|
416
441
|
|
|
@@ -841,6 +841,9 @@ class Graph(object):
|
|
|
841
841
|
"""
|
|
842
842
|
Compute robustness coefficient of graph representation of model mdl.
|
|
843
843
|
|
|
844
|
+
Each trial removes nodes from the entire graph, including disconnected
|
|
845
|
+
components, to integrate the complete largest-component curve.
|
|
846
|
+
|
|
844
847
|
Parameters
|
|
845
848
|
----------
|
|
846
849
|
trials : int
|
|
@@ -865,9 +868,9 @@ class Graph(object):
|
|
|
865
868
|
N = float(len(tmp))
|
|
866
869
|
largestCC = max(nx.connected_components(tmp), key=len)
|
|
867
870
|
s = [float(len(largestCC))]
|
|
868
|
-
rs = rng.choice(range(int(
|
|
871
|
+
rs = rng.choice(range(int(N)), int(N), replace=False)
|
|
869
872
|
nodes = list(g)
|
|
870
|
-
for i in range(int(
|
|
873
|
+
for i in range(int(N)-1):
|
|
871
874
|
tmp.remove_node(nodes[rs[i]])
|
|
872
875
|
largestCC = max(nx.connected_components(tmp), key=len)
|
|
873
876
|
s.append(float(len(largestCC)))
|
|
@@ -1228,6 +1231,9 @@ class Graph(object):
|
|
|
1228
1231
|
Useful for comparing different model variants, design alternatives, or
|
|
1229
1232
|
tracking how model structure evolves across versions.
|
|
1230
1233
|
|
|
1234
|
+
When both graphs are undirected, edge endpoint order is ignored.
|
|
1235
|
+
Added and removed edges retain the endpoint tuples from their source graph.
|
|
1236
|
+
|
|
1231
1237
|
Parameters
|
|
1232
1238
|
----------
|
|
1233
1239
|
other_graph : Graph
|
|
@@ -1267,6 +1273,10 @@ class Graph(object):
|
|
|
1267
1273
|
nodes_other = set(other_graph.g.nodes())
|
|
1268
1274
|
edges_this = set(self.g.edges())
|
|
1269
1275
|
edges_other = set(other_graph.g.edges())
|
|
1276
|
+
if not (self.g.is_directed() or other_graph.g.is_directed()):
|
|
1277
|
+
# Give shared undirected edges the same orientation for comparison.
|
|
1278
|
+
edges_other = {edge[::-1] if edge[::-1] in edges_this else edge
|
|
1279
|
+
for edge in edges_other}
|
|
1270
1280
|
|
|
1271
1281
|
nodes_added = nodes_other - nodes_this
|
|
1272
1282
|
nodes_removed = nodes_this - nodes_other
|