fmdtools 2.5.2__tar.gz → 2.5.3__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.3}/LICENSE +1 -1
- {fmdtools-2.5.2/fmdtools.egg-info → fmdtools-2.5.3}/PKG-INFO +5 -5
- {fmdtools-2.5.2 → fmdtools-2.5.3}/README.md +3 -3
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/model_urban.py +4 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3/fmdtools.egg-info}/PKG-INFO +5 -5
- {fmdtools-2.5.2 → fmdtools-2.5.3}/fmdtools.egg-info/SOURCES.txt +19 -1
- {fmdtools-2.5.2 → fmdtools-2.5.3}/pyproject.toml +1 -1
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/__init__.py +1 -1
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/common.py +20 -18
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/history.py +4 -1
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/phases.py +9 -3
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/result.py +25 -16
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/base.py +2 -1
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/block/base.py +33 -15
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/container/rand.py +108 -40
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/container/time.py +7 -1
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/sim/sample.py +4 -3
- fmdtools-2.5.3/tests/test_array_differences.py +153 -0
- fmdtools-2.5.3/tests/test_array_result_equality.py +167 -0
- fmdtools-2.5.3/tests/test_bootstrap_statistic_arguments.py +196 -0
- fmdtools-2.5.3/tests/test_exact_nominal_expectation.py +166 -0
- fmdtools-2.5.3/tests/test_explicit_result_file_formats.py +176 -0
- fmdtools-2.5.3/tests/test_exponential_rayleigh_draw_sizes.py +239 -0
- fmdtools-2.5.3/tests/test_gamma_sampling_density.py +233 -0
- fmdtools-2.5.3/tests/test_history_phase_identifiers.py +204 -0
- fmdtools-2.5.3/tests/test_independent_single_replicate_seeds.py +201 -0
- fmdtools-2.5.3/tests/test_individual_result_paths.py +165 -0
- fmdtools-2.5.3/tests/test_integer_draw_mass.py +266 -0
- fmdtools-2.5.3/tests/test_json_result_arrays.py +163 -0
- fmdtools-2.5.3/tests/test_named_metric_rounding.py +152 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_packages.py +1 -1
- fmdtools-2.5.3/tests/test_pareto_density.py +203 -0
- fmdtools-2.5.3/tests/test_result_folder_selection.py +191 -0
- fmdtools-2.5.3/tests/test_standard_t_density.py +192 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_time.py +4 -4
- fmdtools-2.5.3/tests/test_unit_random_density.py +176 -0
- fmdtools-2.5.3/tests/test_vonmises_density.py +222 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airport_taxiway/model_asset.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airport_taxiway/model_atc.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airport_taxiway/model_common.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airport_taxiway/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airport_taxiway/test_asset.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airport_taxiway/test_model.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/aircraft.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/aircraftarchitecture.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/arch/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/arch/aviate.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/arch/controlflight.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/arch/flows.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/arch/holdpayload.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/arch/perceiveenvironment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/arch/storeee.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/parameter.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/base/state.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/contingency_management/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/contingency_management/model_aircraft.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/contingency_management/model_environment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/contingency_management/model_flightplanner.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/water_rescue/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/water_rescue/model_drone.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/water_rescue/model_environment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/water_rescue/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/water_rescue/model_responder.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/wildfire_response/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/wildfire_response/model_aircraft.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/wildfire_response/model_environment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/airspacelib/wildfire_response/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/cooling_tank/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/cooling_tank/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/cooling_tank/model_optimization.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/cooling_tank/test_tank.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/electric_power_system/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/electric_power_system/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/electric_power_system/test_model.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/human_hazard_mitigation/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/human_hazard_mitigation/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/model_dynamic.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/model_hierarchical.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/model_rural.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/model_static.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/script_opt_model_rural.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/multirotor_drone/test_multirotor.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/model_degradation.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/model_human.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/model_troupe.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/script_ea_analysis.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/script_mode_space.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/script_search_rover.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/navigating_rover/test_rover.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/state_communication/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/state_communication/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/state_communication/test_multiflow.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/model_indiv.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/model_main.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/model_stochastic.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/script_jointfaults.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/script_parallelism.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/test_pump.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/test_pump_example.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/examples/water_pump/test_pump_stochastic.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/fmdtools.egg-info/dependency_links.txt +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/fmdtools.egg-info/requires.txt +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/fmdtools.egg-info/top_level.txt +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/setup.cfg +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/graph/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/graph/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/graph/label.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/graph/model.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/graph/style.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/analyze/tabulate.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/architecture/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/architecture/action.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/architecture/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/architecture/component.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/architecture/function.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/architecture/geom.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/block/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/block/action.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/block/component.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/block/function.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/container/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/container/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/container/mode.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/container/parameter.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/container/state.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/environment.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/flow/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/flow/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/flow/commsflow.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/flow/multiflow.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/object/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/object/base.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/object/coords.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/object/geom.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/object/timer.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/define/pathplan.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/sim/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/sim/propagate.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/sim/scenario.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/src/fmdtools/sim/search.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/__init__.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/common.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_array_random_states.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_calc_metric_ci_constant_outputs.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_comparison_groups.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_confidence_history_clipping.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_error_history_plots.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_fault_sample_without_nominal.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_fault_time_without_traces.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_geom.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_graph.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_hierarchical.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_history_standard_deviation.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_join_phasemaps.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_joint_fault_weights.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_nested_nominal_groups.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_nesting_custom_separators.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_parameter_sample_seeds.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_parameter_subsampling_types.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_pathplan.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_phase_timestep.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_pruned_fault_times.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_result.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_sample.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_scenario.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_scenario_defaults.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/tests/test_table_factor_indices.py +0 -0
- {fmdtools-2.5.2 → fmdtools-2.5.3}/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.3
|
|
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.3
|
|
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.3
|
|
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-9-
|
|
551
|
+
version = {2.5.3},
|
|
552
|
+
date = {2026-9-30},
|
|
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.3
|
|
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-9-
|
|
280
|
+
version = {2.5.3},
|
|
281
|
+
date = {2026-9-30},
|
|
282
282
|
}
|
|
283
283
|
```
|
|
284
284
|
|
|
@@ -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": {}})
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmdtools
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.3
|
|
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.3
|
|
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.3
|
|
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-9-
|
|
551
|
+
version = {2.5.3},
|
|
552
|
+
date = {2026-9-30},
|
|
553
553
|
}
|
|
554
554
|
```
|
|
555
555
|
|
|
@@ -127,31 +127,49 @@ 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_array_differences.py
|
|
130
131
|
tests/test_array_random_states.py
|
|
132
|
+
tests/test_array_result_equality.py
|
|
133
|
+
tests/test_bootstrap_statistic_arguments.py
|
|
131
134
|
tests/test_calc_metric_ci_constant_outputs.py
|
|
132
135
|
tests/test_comparison_groups.py
|
|
133
136
|
tests/test_confidence_history_clipping.py
|
|
134
137
|
tests/test_error_history_plots.py
|
|
138
|
+
tests/test_exact_nominal_expectation.py
|
|
139
|
+
tests/test_explicit_result_file_formats.py
|
|
140
|
+
tests/test_exponential_rayleigh_draw_sizes.py
|
|
135
141
|
tests/test_fault_sample_without_nominal.py
|
|
136
142
|
tests/test_fault_time_without_traces.py
|
|
143
|
+
tests/test_gamma_sampling_density.py
|
|
137
144
|
tests/test_geom.py
|
|
138
145
|
tests/test_graph.py
|
|
139
146
|
tests/test_hierarchical.py
|
|
147
|
+
tests/test_history_phase_identifiers.py
|
|
140
148
|
tests/test_history_standard_deviation.py
|
|
149
|
+
tests/test_independent_single_replicate_seeds.py
|
|
150
|
+
tests/test_individual_result_paths.py
|
|
151
|
+
tests/test_integer_draw_mass.py
|
|
141
152
|
tests/test_join_phasemaps.py
|
|
142
153
|
tests/test_joint_fault_weights.py
|
|
154
|
+
tests/test_json_result_arrays.py
|
|
155
|
+
tests/test_named_metric_rounding.py
|
|
143
156
|
tests/test_nested_nominal_groups.py
|
|
144
157
|
tests/test_nesting_custom_separators.py
|
|
145
158
|
tests/test_packages.py
|
|
146
159
|
tests/test_parameter_sample_seeds.py
|
|
147
160
|
tests/test_parameter_subsampling_types.py
|
|
161
|
+
tests/test_pareto_density.py
|
|
148
162
|
tests/test_pathplan.py
|
|
149
163
|
tests/test_phase_timestep.py
|
|
150
164
|
tests/test_pruned_fault_times.py
|
|
151
165
|
tests/test_result.py
|
|
166
|
+
tests/test_result_folder_selection.py
|
|
152
167
|
tests/test_sample.py
|
|
153
168
|
tests/test_scenario.py
|
|
154
169
|
tests/test_scenario_defaults.py
|
|
170
|
+
tests/test_standard_t_density.py
|
|
155
171
|
tests/test_table_factor_indices.py
|
|
156
172
|
tests/test_time.py
|
|
157
|
-
tests/test_uniform_density.py
|
|
173
|
+
tests/test_uniform_density.py
|
|
174
|
+
tests/test_unit_random_density.py
|
|
175
|
+
tests/test_vonmises_density.py
|
|
@@ -42,6 +42,7 @@ from matplotlib import rcParams
|
|
|
42
42
|
import inspect
|
|
43
43
|
from scipy.stats import bootstrap
|
|
44
44
|
from fmdtools.define.base import filter_kwargs, round_float
|
|
45
|
+
from functools import partial
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
plt.rcParams['pdf.fonttype'] = 42
|
|
@@ -180,11 +181,11 @@ def create_indiv_filename(filename, indiv_id, splitchar='_'):
|
|
|
180
181
|
--------
|
|
181
182
|
>>> create_indiv_filename("hi.csv", "4")
|
|
182
183
|
'hi_4.csv'
|
|
184
|
+
>>> create_indiv_filename("runs.v1/results.v2.csv", "4", splitchar="/")
|
|
185
|
+
'runs.v1/results.v2/4.csv'
|
|
183
186
|
"""
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
filename_parts.insert(1, splitchar+indiv_id)
|
|
187
|
-
return "".join(filename_parts)
|
|
187
|
+
stem, extension = os.path.splitext(filename)
|
|
188
|
+
return stem + splitchar + indiv_id + extension
|
|
188
189
|
|
|
189
190
|
|
|
190
191
|
def load_folder(folder, filetype):
|
|
@@ -198,20 +199,17 @@ def load_folder(folder, filetype):
|
|
|
198
199
|
folder : str
|
|
199
200
|
Name of the folder. Must be in the current directory
|
|
200
201
|
filetype : str
|
|
201
|
-
Type of files in the folder ('
|
|
202
|
+
Type of files in the folder ('npz', 'csv', or 'json'). Other extensions
|
|
203
|
+
and subdirectories are ignored; matching files are not searched recursively.
|
|
202
204
|
|
|
203
205
|
Returns
|
|
204
206
|
-------
|
|
205
207
|
files_to_read : list
|
|
206
208
|
files to load for results/mdlhists.
|
|
207
209
|
"""
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
read_filetype = auto_filetype(file)
|
|
212
|
-
if read_filetype == filetype:
|
|
213
|
-
files_toread.append(file)
|
|
214
|
-
return files_toread
|
|
210
|
+
return [file for file in os.listdir(folder)
|
|
211
|
+
if file.endswith('.' + filetype)
|
|
212
|
+
and os.path.isfile(os.path.join(folder, file))]
|
|
215
213
|
|
|
216
214
|
|
|
217
215
|
def metric_preamble(data, dtype=None, rates=None, r_dtype=None, r_norm=False):
|
|
@@ -255,7 +253,8 @@ def calc_metric(data, method=np.average, args=(), axis=None, dtype=None,
|
|
|
255
253
|
r_norm : bool, optional
|
|
256
254
|
Whether to normalize rates. The default is False.
|
|
257
255
|
round_value : bool, optional
|
|
258
|
-
Whether to round the value
|
|
256
|
+
Whether to round the final value, including named metrics.
|
|
257
|
+
Applied once after evaluation. Default is True.
|
|
259
258
|
res : float
|
|
260
259
|
Resolution to round to. Default is 1e-6.
|
|
261
260
|
min_r : int
|
|
@@ -283,8 +282,9 @@ def calc_metric(data, method=np.average, args=(), axis=None, dtype=None,
|
|
|
283
282
|
"""
|
|
284
283
|
if isinstance(method, str):
|
|
285
284
|
method = eval("calc_"+method)
|
|
285
|
+
# Named helpers call calc_metric again; round only the final result.
|
|
286
286
|
metric = method(data, args=args, axis=axis, dtype=dtype, rates=rates,
|
|
287
|
-
r_dtype=r_dtype, r_norm=r_norm, **kwargs)
|
|
287
|
+
r_dtype=r_dtype, r_norm=r_norm, round_value=False, **kwargs)
|
|
288
288
|
else:
|
|
289
289
|
vals = metric_preamble(data, dtype, rates, r_dtype, r_norm)
|
|
290
290
|
metric = method(vals, *args, **filter_kwargs(method, **kwargs, axis=axis))
|
|
@@ -309,7 +309,8 @@ def calc_metric_ci(data, method=np.average, return_anyway=False, interval=None,
|
|
|
309
309
|
axis : int
|
|
310
310
|
Axis along which to calculate the confidence interval(s). The default is 0.
|
|
311
311
|
**kwargs : kwargs
|
|
312
|
-
Keyword arguments to
|
|
312
|
+
Keyword arguments to the statistic, preprocessing, or scipy.bootstrap.
|
|
313
|
+
Statistic arguments are used for both the point estimate and resamples.
|
|
313
314
|
|
|
314
315
|
Returns
|
|
315
316
|
-------
|
|
@@ -339,15 +340,16 @@ def calc_metric_ci(data, method=np.average, return_anyway=False, interval=None,
|
|
|
339
340
|
val = np.take(vals, [0], axis=axis)
|
|
340
341
|
if "weights" in kwargs and kwargs['weights'] is not None:
|
|
341
342
|
raise Exception("Weights not able to be used w- bootstrap--use rates instead.")
|
|
342
|
-
|
|
343
|
+
statistic = partial(method, **filter_kwargs(method, **kwargs))
|
|
344
|
+
met_val = statistic(vals, axis=axis)
|
|
343
345
|
vals_vary = vals == val
|
|
344
346
|
# Preserve the existing policy for globally identical data.
|
|
345
347
|
if not np.all(vals == vals.flat[0]):
|
|
346
348
|
if np.any(np.all(vals_vary, axis=axis)):
|
|
347
349
|
# use more robust/basic algorithm if some indices don't vary
|
|
348
|
-
bs = bootstrap([vals],
|
|
350
|
+
bs = bootstrap([vals], statistic, axis=axis, method="basic", **bs_kwar)
|
|
349
351
|
else:
|
|
350
|
-
bs = bootstrap([vals],
|
|
352
|
+
bs = bootstrap([vals], statistic, axis=axis, **bs_kwar)
|
|
351
353
|
return met_val, bs.confidence_interval.low, bs.confidence_interval.high
|
|
352
354
|
elif return_anyway:
|
|
353
355
|
return met_val, met_val, met_val
|
|
@@ -182,6 +182,9 @@ class History(Result):
|
|
|
182
182
|
"""
|
|
183
183
|
Find the values of two histories which are different.
|
|
184
184
|
|
|
185
|
+
Array-valued entries are retained when any element of their difference
|
|
186
|
+
is nonzero; the full difference array is returned.
|
|
187
|
+
|
|
185
188
|
Parameters
|
|
186
189
|
----------
|
|
187
190
|
other : History
|
|
@@ -195,7 +198,7 @@ class History(Result):
|
|
|
195
198
|
"""
|
|
196
199
|
diff = self-other
|
|
197
200
|
different = self.__class__()
|
|
198
|
-
different.data = {k: v for k, v in diff.items() if any(v)}
|
|
201
|
+
different.data = {k: v for k, v in diff.items() if np.any(v)}
|
|
199
202
|
return different
|
|
200
203
|
|
|
201
204
|
def copy(self):
|
|
@@ -388,9 +388,9 @@ def from_hist(hist, fxn_modephases='all', dt=1.0):
|
|
|
388
388
|
Dictionary of distict phases that the system functions pass through,
|
|
389
389
|
of the form: {'fxn': PhaseMap} where each phase is defined by its
|
|
390
390
|
corresponding mode in the modelhist.
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
391
|
+
Repeated phases are numbered mode, mode1, mode2, skipping suffixes that
|
|
392
|
+
would collide with actual mode names or previously generated phase names.
|
|
393
|
+
The modephase mapping groups each mode's intervals for future sampling.
|
|
394
394
|
|
|
395
395
|
Examples
|
|
396
396
|
--------
|
|
@@ -411,6 +411,8 @@ def from_hist(hist, fxn_modephases='all', dt=1.0):
|
|
|
411
411
|
fxn = k[k.index('m')-1]
|
|
412
412
|
if len(modehist) != 0:
|
|
413
413
|
modes = OrderedSet(modehist)
|
|
414
|
+
# Reserve actual mode names before generating repeated-phase suffixes.
|
|
415
|
+
used_phaseids = set(modes)
|
|
414
416
|
modephases = dict.fromkeys(modes)
|
|
415
417
|
phases_unsorted = dict()
|
|
416
418
|
for mode in modes:
|
|
@@ -427,6 +429,10 @@ def from_hist(hist, fxn_modephases='all', dt=1.0):
|
|
|
427
429
|
startind = modeinds[i+1]
|
|
428
430
|
phasenum += 1
|
|
429
431
|
phaseid = mode+str(phasenum)
|
|
432
|
+
while phaseid in used_phaseids:
|
|
433
|
+
phasenum += 1
|
|
434
|
+
phaseid = mode+str(phasenum)
|
|
435
|
+
used_phaseids.add(phaseid)
|
|
430
436
|
phases = dict(sorted(phases_unsorted.items(),
|
|
431
437
|
key=lambda item: item[1][0]))
|
|
432
438
|
if fxn_modephases == 'all' or fxn in fxn_modephases:
|
|
@@ -239,7 +239,8 @@ class Result(UserDict):
|
|
|
239
239
|
Check that the two values of the dictionary are equal.
|
|
240
240
|
|
|
241
241
|
Enables the syntax result1 == result2, which returns True/False depending on if
|
|
242
|
-
the keys/values are the same.
|
|
242
|
+
the keys/values are the same. Array values must have the same shape and
|
|
243
|
+
elements, without broadcasting or tolerances. NaN values remain unequal.
|
|
243
244
|
|
|
244
245
|
Parameters
|
|
245
246
|
----------
|
|
@@ -274,10 +275,11 @@ class Result(UserDict):
|
|
|
274
275
|
if self.keys() != other.keys():
|
|
275
276
|
return False
|
|
276
277
|
else:
|
|
277
|
-
return all(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
278
|
+
return all(np.array_equal(v, other.data[k])
|
|
279
|
+
if isinstance(v, np.ndarray) or
|
|
280
|
+
isinstance(other.data[k], np.ndarray)
|
|
281
|
+
else v == other.data[k]
|
|
282
|
+
for k, v in self.data.items())
|
|
281
283
|
|
|
282
284
|
def __sub__(self, other):
|
|
283
285
|
"""
|
|
@@ -324,6 +326,9 @@ class Result(UserDict):
|
|
|
324
326
|
"""
|
|
325
327
|
Find the values of two results which are different.
|
|
326
328
|
|
|
329
|
+
Array-valued entries are retained when any element of their difference
|
|
330
|
+
is nonzero; the full difference array is returned.
|
|
331
|
+
|
|
327
332
|
Parameters
|
|
328
333
|
----------
|
|
329
334
|
other : Result
|
|
@@ -337,7 +342,7 @@ class Result(UserDict):
|
|
|
337
342
|
"""
|
|
338
343
|
diff = self-other
|
|
339
344
|
different = self.__class__()
|
|
340
|
-
different.data = {k: v for k, v in diff.items() if v}
|
|
345
|
+
different.data = {k: v for k, v in diff.items() if np.any(v)}
|
|
341
346
|
return different
|
|
342
347
|
|
|
343
348
|
def keys(self):
|
|
@@ -466,7 +471,7 @@ class Result(UserDict):
|
|
|
466
471
|
|
|
467
472
|
def load(filename, filetype="", renest_dict=False, indiv=False):
|
|
468
473
|
"""Load as Result using :func:`load'."""
|
|
469
|
-
inputdict = load(filename, filetype=
|
|
474
|
+
inputdict = load(filename, filetype=filetype, renest_dict=renest_dict,
|
|
470
475
|
indiv=indiv, Rclass=Result)
|
|
471
476
|
return fromdict(Result, inputdict)
|
|
472
477
|
|
|
@@ -709,15 +714,18 @@ class Result(UserDict):
|
|
|
709
714
|
"""
|
|
710
715
|
Save a given result variable (result or history) to a file filename.
|
|
711
716
|
|
|
712
|
-
Files can be saved as npz, csv, or json.
|
|
717
|
+
Files can be saved as npz, csv, or json. JSON converts arrays to
|
|
718
|
+
nested lists of Python values (or a scalar for zero-dimensional arrays).
|
|
719
|
+
Array dtype and shape metadata are not stored in JSON.
|
|
713
720
|
|
|
714
721
|
Parameters
|
|
715
722
|
----------
|
|
716
723
|
filename : str
|
|
717
724
|
File name for the file. Can be nested in a folder if desired.
|
|
718
725
|
filetype : str, optional
|
|
719
|
-
|
|
720
|
-
The default
|
|
726
|
+
Format to write, overriding the filename extension when supplied.
|
|
727
|
+
The default "" infers the format from the extension. The exact
|
|
728
|
+
filename is used for all formats; no extension is appended.
|
|
721
729
|
overwrite : bool, optional
|
|
722
730
|
Whether to overwrite existing files with this name.
|
|
723
731
|
The default is False.
|
|
@@ -741,8 +749,8 @@ class Result(UserDict):
|
|
|
741
749
|
else:
|
|
742
750
|
res_to_save = self
|
|
743
751
|
res_to_save = res_to_save.flatten()
|
|
744
|
-
np.savez(
|
|
745
|
-
elif
|
|
752
|
+
np.savez(file_handle, **res_to_save)
|
|
753
|
+
elif filetype == 'csv':
|
|
746
754
|
# add support for nested dict mdlhist using flatten_hist?
|
|
747
755
|
variable = variable.flatten()
|
|
748
756
|
with open(filename, 'w', newline='') as file_handle:
|
|
@@ -754,13 +762,13 @@ class Result(UserDict):
|
|
|
754
762
|
writer.writerows(zip(*variable.values()))
|
|
755
763
|
else:
|
|
756
764
|
writer.writerow([*variable.values()])
|
|
757
|
-
elif
|
|
765
|
+
elif filetype == 'json':
|
|
758
766
|
with open(filename, 'w', encoding='utf8') as file_handle:
|
|
759
767
|
variable = variable.flatten()
|
|
760
768
|
new_variable = {}
|
|
761
769
|
for key in variable:
|
|
762
770
|
if isinstance(variable[key], np.ndarray):
|
|
763
|
-
new_variable[str(key)] = [
|
|
771
|
+
new_variable[str(key)] = variable[key].tolist()
|
|
764
772
|
else:
|
|
765
773
|
new_variable[str(key)] = variable[key]
|
|
766
774
|
if result_id:
|
|
@@ -798,7 +806,8 @@ class Result(UserDict):
|
|
|
798
806
|
app : SampleApproach, optional
|
|
799
807
|
Approach to use for weights (via rates). The default is [].
|
|
800
808
|
with_nominal : bool, optional
|
|
801
|
-
Whether to include the nominal
|
|
809
|
+
Whether to include the scenario named exactly 'nominal' in the
|
|
810
|
+
expectation. Other names containing 'nominal' remain included.
|
|
802
811
|
The default is False.
|
|
803
812
|
difference_from_nominal : bool, optional
|
|
804
813
|
Whether to calculated the difference of the expectation from nominal.
|
|
@@ -816,7 +825,7 @@ class Result(UserDict):
|
|
|
816
825
|
|
|
817
826
|
nomhist = {k: v for k, v in mh.nominal.items() if is_numeric(v)}
|
|
818
827
|
newhists = {k: hist for k, hist in mh.items()
|
|
819
|
-
if
|
|
828
|
+
if with_nominal or k != 'nominal'}
|
|
820
829
|
if app:
|
|
821
830
|
scenario_rates = {scen.name: scen.rate for scen in app.scenarios()}
|
|
822
831
|
if with_nominal:
|
|
@@ -442,7 +442,8 @@ def nan_to_x(metric, x=0.0):
|
|
|
442
442
|
|
|
443
443
|
def gen_timerange(start_time, end_time, dt=1.0, min_r=7):
|
|
444
444
|
"""Generate the times in a given interval given the timestep dt."""
|
|
445
|
-
return
|
|
445
|
+
return round_float(np.arange(start_time, end_time + np.power(10.0, -min_r), dt),
|
|
446
|
+
res=dt, min_r=min_r)
|
|
446
447
|
|
|
447
448
|
|
|
448
449
|
def get_code_attrs(obj):
|
|
@@ -23,7 +23,7 @@ specific language governing permissions and limitations under the License.
|
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
25
|
from fmdtools.define.base import gen_timerange, is_iter, get_var, filter_kwargs
|
|
26
|
-
from fmdtools.define.base import copy_dict_objs
|
|
26
|
+
from fmdtools.define.base import copy_dict_objs, round_float
|
|
27
27
|
from fmdtools.define.object.base import BaseObject
|
|
28
28
|
from fmdtools.define.container.parameter import Parameter
|
|
29
29
|
from fmdtools.define.container.time import Time
|
|
@@ -35,6 +35,8 @@ from fmdtools.analyze.graph.base import Graph
|
|
|
35
35
|
import itertools
|
|
36
36
|
import warnings
|
|
37
37
|
import numpy as np
|
|
38
|
+
import math
|
|
39
|
+
from decimal import Decimal
|
|
38
40
|
|
|
39
41
|
|
|
40
42
|
class SimParam(Parameter, readonly=True):
|
|
@@ -114,7 +116,7 @@ class SimParam(Parameter, readonly=True):
|
|
|
114
116
|
": " + str(self.phases) +
|
|
115
117
|
" Ensure max of each phase < min of each other phase")
|
|
116
118
|
|
|
117
|
-
def get_timerange(self, start_time=None, end_time=None, min_r=7):
|
|
119
|
+
def get_timerange(self, start_time=None, end_time=None, dt=None, min_r=7):
|
|
118
120
|
"""
|
|
119
121
|
Generate the timerange to simulate over.
|
|
120
122
|
|
|
@@ -127,7 +129,9 @@ class SimParam(Parameter, readonly=True):
|
|
|
127
129
|
start_time = self.start_time
|
|
128
130
|
if end_time is None:
|
|
129
131
|
end_time = self.end_time
|
|
130
|
-
|
|
132
|
+
if dt is None:
|
|
133
|
+
dt = self.dt
|
|
134
|
+
return gen_timerange(start_time, end_time, dt, min_r)
|
|
131
135
|
|
|
132
136
|
def get_histrange(self, start_time=0.0, end_time=None):
|
|
133
137
|
"""Get the history range associated with the SimParam."""
|
|
@@ -140,32 +144,45 @@ class SimParam(Parameter, readonly=True):
|
|
|
140
144
|
histrange = self.track_times[1]
|
|
141
145
|
return histrange
|
|
142
146
|
|
|
143
|
-
def get_hist_ind(self, t_ind, t):
|
|
147
|
+
def get_hist_ind(self, t_ind, t, local_dt=None):
|
|
144
148
|
"""
|
|
145
149
|
Get the index of the history given the simulation time/index and shift.
|
|
146
150
|
|
|
151
|
+
Returns log as true if the index of the history and simulation line up, otherwise
|
|
152
|
+
the simulation is not to be logged.
|
|
153
|
+
|
|
147
154
|
Examples
|
|
148
155
|
--------
|
|
149
156
|
>>> SimParam().get_hist_ind(2, 2.0)
|
|
150
|
-
2
|
|
157
|
+
(True, 2)
|
|
151
158
|
>>> SimParam(track_times=('interval', 2)).get_hist_ind(4, 4.0)
|
|
152
|
-
2
|
|
153
|
-
|
|
159
|
+
(True, 2)
|
|
160
|
+
>>> SimParam().get_hist_ind(2, 2.0, 0.1)
|
|
161
|
+
(False, 1)
|
|
162
|
+
>>> SimParam().get_hist_ind(10, 2.0, 0.1)
|
|
163
|
+
(True, 1)
|
|
164
|
+
"""
|
|
165
|
+
log = True
|
|
166
|
+
if local_dt is not None:
|
|
167
|
+
t_dec = Decimal(str(round_float(t_ind*local_dt, res=local_dt)))
|
|
168
|
+
dt = Decimal(str(self.dt))
|
|
169
|
+
log = t_dec % dt == 0.0
|
|
170
|
+
t_ind = math.ceil(t_dec/dt)
|
|
171
|
+
|
|
154
172
|
if self.track_times[0] == 'all':
|
|
155
173
|
t_ind_rec = t_ind
|
|
156
174
|
elif self.track_times[0] == 'interval':
|
|
175
|
+
log = t_ind % self.track_times[1] == 0
|
|
157
176
|
t_ind_rec = t_ind//self.track_times[1]
|
|
158
177
|
elif self.track_times[0] == 'times':
|
|
159
178
|
t_ind_rec = self.track_times[1].index(t)
|
|
160
179
|
else:
|
|
161
180
|
raise Exception("Invalid argument, track_times=" + str(self.track_times))
|
|
162
|
-
return t_ind_rec
|
|
181
|
+
return bool(log), t_ind_rec
|
|
163
182
|
|
|
164
183
|
def get_sub_kwargs(self):
|
|
165
184
|
"""Get keyword arguments for contained sim from larger sim."""
|
|
166
185
|
kwargs = self.asdict()
|
|
167
|
-
if not self.use_local:
|
|
168
|
-
kwargs.pop("dt")
|
|
169
186
|
kwargs['end_condition'] = ""
|
|
170
187
|
return kwargs
|
|
171
188
|
|
|
@@ -278,8 +295,8 @@ class Simulable(BaseObject):
|
|
|
278
295
|
|
|
279
296
|
Returns
|
|
280
297
|
-------
|
|
281
|
-
result :
|
|
282
|
-
|
|
298
|
+
result : Result
|
|
299
|
+
Result to return given to_return input.
|
|
283
300
|
"""
|
|
284
301
|
result = Result()
|
|
285
302
|
self.get_endclass(to_return=to_return, result=result, nomresult=nomresult,
|
|
@@ -762,7 +779,7 @@ class Simulable(BaseObject):
|
|
|
762
779
|
if time == 'end':
|
|
763
780
|
time = self.sp.end_time
|
|
764
781
|
start_time, end_time = self.t.get_sim_times(time)
|
|
765
|
-
sim_times = self.sp.get_timerange(start_time, end_time)
|
|
782
|
+
sim_times = self.sp.get_timerange(start_time, end_time, dt=self.t.dt)
|
|
766
783
|
for t in sim_times:
|
|
767
784
|
if t == end_time:
|
|
768
785
|
if copy:
|
|
@@ -778,8 +795,9 @@ class Simulable(BaseObject):
|
|
|
778
795
|
self.set_sub_faults()
|
|
779
796
|
if inc_at == "all" or (inc_at == "time" and t == time):
|
|
780
797
|
self.inc_sim_time()
|
|
781
|
-
t_ind = self.sp.get_hist_ind(self.t.t_ind, self.t.time)
|
|
782
|
-
|
|
798
|
+
log, t_ind = self.sp.get_hist_ind(self.t.t_ind, self.t.time, self.t.dt)
|
|
799
|
+
if log:
|
|
800
|
+
self.h.log(self, t_ind, self.t.time)
|
|
783
801
|
if self.sp.end_condition and not copy:
|
|
784
802
|
if get_var(self, self.sp.end_condition)():
|
|
785
803
|
break
|