tnfr 4.5.2__py3-none-any.whl → 8.5.0__py3-none-any.whl
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.
Potentially problematic release.
This version of tnfr might be problematic. Click here for more details.
- tnfr/__init__.py +334 -50
- tnfr/__init__.pyi +33 -0
- tnfr/_compat.py +10 -0
- tnfr/_generated_version.py +34 -0
- tnfr/_version.py +49 -0
- tnfr/_version.pyi +7 -0
- tnfr/alias.py +214 -37
- tnfr/alias.pyi +108 -0
- tnfr/backends/__init__.py +354 -0
- tnfr/backends/jax_backend.py +173 -0
- tnfr/backends/numpy_backend.py +238 -0
- tnfr/backends/optimized_numpy.py +420 -0
- tnfr/backends/torch_backend.py +408 -0
- tnfr/cache.py +149 -556
- tnfr/cache.pyi +13 -0
- tnfr/cli/__init__.py +51 -16
- tnfr/cli/__init__.pyi +26 -0
- tnfr/cli/arguments.py +344 -32
- tnfr/cli/arguments.pyi +29 -0
- tnfr/cli/execution.py +676 -50
- tnfr/cli/execution.pyi +70 -0
- tnfr/cli/interactive_validator.py +614 -0
- tnfr/cli/utils.py +18 -3
- tnfr/cli/utils.pyi +7 -0
- tnfr/cli/validate.py +236 -0
- tnfr/compat/__init__.py +85 -0
- tnfr/compat/dataclass.py +136 -0
- tnfr/compat/jsonschema_stub.py +61 -0
- tnfr/compat/matplotlib_stub.py +73 -0
- tnfr/compat/numpy_stub.py +155 -0
- tnfr/config/__init__.py +224 -0
- tnfr/config/__init__.pyi +10 -0
- tnfr/{constants_glyphs.py → config/constants.py} +26 -20
- tnfr/config/constants.pyi +12 -0
- tnfr/config/defaults.py +54 -0
- tnfr/{constants/core.py → config/defaults_core.py} +59 -6
- tnfr/config/defaults_init.py +33 -0
- tnfr/config/defaults_metric.py +104 -0
- tnfr/config/feature_flags.py +81 -0
- tnfr/config/feature_flags.pyi +16 -0
- tnfr/config/glyph_constants.py +31 -0
- tnfr/config/init.py +77 -0
- tnfr/config/init.pyi +8 -0
- tnfr/config/operator_names.py +254 -0
- tnfr/config/operator_names.pyi +36 -0
- tnfr/config/physics_derivation.py +354 -0
- tnfr/config/presets.py +83 -0
- tnfr/config/presets.pyi +7 -0
- tnfr/config/security.py +927 -0
- tnfr/config/thresholds.py +114 -0
- tnfr/config/tnfr_config.py +498 -0
- tnfr/constants/__init__.py +51 -133
- tnfr/constants/__init__.pyi +92 -0
- tnfr/constants/aliases.py +33 -0
- tnfr/constants/aliases.pyi +27 -0
- tnfr/constants/init.py +3 -1
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +9 -15
- tnfr/constants/metric.pyi +19 -0
- tnfr/core/__init__.py +33 -0
- tnfr/core/container.py +226 -0
- tnfr/core/default_implementations.py +329 -0
- tnfr/core/interfaces.py +279 -0
- tnfr/dynamics/__init__.py +213 -633
- tnfr/dynamics/__init__.pyi +83 -0
- tnfr/dynamics/adaptation.py +267 -0
- tnfr/dynamics/adaptation.pyi +7 -0
- tnfr/dynamics/adaptive_sequences.py +189 -0
- tnfr/dynamics/adaptive_sequences.pyi +14 -0
- tnfr/dynamics/aliases.py +23 -0
- tnfr/dynamics/aliases.pyi +19 -0
- tnfr/dynamics/bifurcation.py +232 -0
- tnfr/dynamics/canonical.py +229 -0
- tnfr/dynamics/canonical.pyi +48 -0
- tnfr/dynamics/coordination.py +385 -0
- tnfr/dynamics/coordination.pyi +25 -0
- tnfr/dynamics/dnfr.py +2699 -398
- tnfr/dynamics/dnfr.pyi +26 -0
- tnfr/dynamics/dynamic_limits.py +225 -0
- tnfr/dynamics/feedback.py +252 -0
- tnfr/dynamics/feedback.pyi +24 -0
- tnfr/dynamics/fused_dnfr.py +454 -0
- tnfr/dynamics/homeostasis.py +157 -0
- tnfr/dynamics/homeostasis.pyi +14 -0
- tnfr/dynamics/integrators.py +496 -102
- tnfr/dynamics/integrators.pyi +36 -0
- tnfr/dynamics/learning.py +310 -0
- tnfr/dynamics/learning.pyi +33 -0
- tnfr/dynamics/metabolism.py +254 -0
- tnfr/dynamics/nbody.py +796 -0
- tnfr/dynamics/nbody_tnfr.py +783 -0
- tnfr/dynamics/propagation.py +326 -0
- tnfr/dynamics/runtime.py +908 -0
- tnfr/dynamics/runtime.pyi +77 -0
- tnfr/dynamics/sampling.py +10 -5
- tnfr/dynamics/sampling.pyi +7 -0
- tnfr/dynamics/selectors.py +711 -0
- tnfr/dynamics/selectors.pyi +85 -0
- tnfr/dynamics/structural_clip.py +207 -0
- tnfr/errors/__init__.py +37 -0
- tnfr/errors/contextual.py +492 -0
- tnfr/execution.py +77 -55
- tnfr/execution.pyi +45 -0
- tnfr/extensions/__init__.py +205 -0
- tnfr/extensions/__init__.pyi +18 -0
- tnfr/extensions/base.py +173 -0
- tnfr/extensions/base.pyi +35 -0
- tnfr/extensions/business/__init__.py +71 -0
- tnfr/extensions/business/__init__.pyi +11 -0
- tnfr/extensions/business/cookbook.py +88 -0
- tnfr/extensions/business/cookbook.pyi +8 -0
- tnfr/extensions/business/health_analyzers.py +202 -0
- tnfr/extensions/business/health_analyzers.pyi +9 -0
- tnfr/extensions/business/patterns.py +183 -0
- tnfr/extensions/business/patterns.pyi +8 -0
- tnfr/extensions/medical/__init__.py +73 -0
- tnfr/extensions/medical/__init__.pyi +11 -0
- tnfr/extensions/medical/cookbook.py +88 -0
- tnfr/extensions/medical/cookbook.pyi +8 -0
- tnfr/extensions/medical/health_analyzers.py +181 -0
- tnfr/extensions/medical/health_analyzers.pyi +9 -0
- tnfr/extensions/medical/patterns.py +163 -0
- tnfr/extensions/medical/patterns.pyi +8 -0
- tnfr/flatten.py +29 -50
- tnfr/flatten.pyi +21 -0
- tnfr/gamma.py +66 -53
- tnfr/gamma.pyi +36 -0
- tnfr/glyph_history.py +144 -57
- tnfr/glyph_history.pyi +35 -0
- tnfr/glyph_runtime.py +19 -0
- tnfr/glyph_runtime.pyi +8 -0
- tnfr/immutable.py +70 -30
- tnfr/immutable.pyi +36 -0
- tnfr/initialization.py +22 -16
- tnfr/initialization.pyi +65 -0
- tnfr/io.py +5 -241
- tnfr/io.pyi +13 -0
- tnfr/locking.pyi +7 -0
- tnfr/mathematics/__init__.py +79 -0
- tnfr/mathematics/backend.py +453 -0
- tnfr/mathematics/backend.pyi +99 -0
- tnfr/mathematics/dynamics.py +408 -0
- tnfr/mathematics/dynamics.pyi +90 -0
- tnfr/mathematics/epi.py +391 -0
- tnfr/mathematics/epi.pyi +65 -0
- tnfr/mathematics/generators.py +242 -0
- tnfr/mathematics/generators.pyi +29 -0
- tnfr/mathematics/metrics.py +119 -0
- tnfr/mathematics/metrics.pyi +16 -0
- tnfr/mathematics/operators.py +239 -0
- tnfr/mathematics/operators.pyi +59 -0
- tnfr/mathematics/operators_factory.py +124 -0
- tnfr/mathematics/operators_factory.pyi +11 -0
- tnfr/mathematics/projection.py +87 -0
- tnfr/mathematics/projection.pyi +33 -0
- tnfr/mathematics/runtime.py +182 -0
- tnfr/mathematics/runtime.pyi +64 -0
- tnfr/mathematics/spaces.py +256 -0
- tnfr/mathematics/spaces.pyi +83 -0
- tnfr/mathematics/transforms.py +305 -0
- tnfr/mathematics/transforms.pyi +62 -0
- tnfr/metrics/__init__.py +47 -9
- tnfr/metrics/__init__.pyi +20 -0
- tnfr/metrics/buffer_cache.py +163 -0
- tnfr/metrics/buffer_cache.pyi +24 -0
- tnfr/metrics/cache_utils.py +214 -0
- tnfr/metrics/coherence.py +1510 -330
- tnfr/metrics/coherence.pyi +129 -0
- tnfr/metrics/common.py +23 -16
- tnfr/metrics/common.pyi +35 -0
- tnfr/metrics/core.py +251 -36
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +709 -110
- tnfr/metrics/diagnosis.pyi +86 -0
- tnfr/metrics/emergence.py +245 -0
- tnfr/metrics/export.py +60 -18
- tnfr/metrics/export.pyi +7 -0
- tnfr/metrics/glyph_timing.py +233 -43
- tnfr/metrics/glyph_timing.pyi +81 -0
- tnfr/metrics/learning_metrics.py +280 -0
- tnfr/metrics/learning_metrics.pyi +21 -0
- tnfr/metrics/phase_coherence.py +351 -0
- tnfr/metrics/phase_compatibility.py +349 -0
- tnfr/metrics/reporting.py +63 -28
- tnfr/metrics/reporting.pyi +25 -0
- tnfr/metrics/sense_index.py +1126 -43
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +215 -23
- tnfr/metrics/trig.pyi +13 -0
- tnfr/metrics/trig_cache.py +148 -24
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/multiscale/__init__.py +32 -0
- tnfr/multiscale/hierarchical.py +517 -0
- tnfr/node.py +646 -140
- tnfr/node.pyi +139 -0
- tnfr/observers.py +160 -45
- tnfr/observers.pyi +31 -0
- tnfr/ontosim.py +23 -19
- tnfr/ontosim.pyi +28 -0
- tnfr/operators/__init__.py +1358 -106
- tnfr/operators/__init__.pyi +31 -0
- tnfr/operators/algebra.py +277 -0
- tnfr/operators/canonical_patterns.py +420 -0
- tnfr/operators/cascade.py +267 -0
- tnfr/operators/cycle_detection.py +358 -0
- tnfr/operators/definitions.py +4108 -0
- tnfr/operators/definitions.pyi +78 -0
- tnfr/operators/grammar.py +1164 -0
- tnfr/operators/grammar.pyi +140 -0
- tnfr/operators/hamiltonian.py +710 -0
- tnfr/operators/health_analyzer.py +809 -0
- tnfr/operators/jitter.py +107 -38
- tnfr/operators/jitter.pyi +11 -0
- tnfr/operators/lifecycle.py +314 -0
- tnfr/operators/metabolism.py +618 -0
- tnfr/operators/metrics.py +2138 -0
- tnfr/operators/network_analysis/__init__.py +27 -0
- tnfr/operators/network_analysis/source_detection.py +186 -0
- tnfr/operators/nodal_equation.py +395 -0
- tnfr/operators/pattern_detection.py +660 -0
- tnfr/operators/patterns.py +669 -0
- tnfr/operators/postconditions/__init__.py +38 -0
- tnfr/operators/postconditions/mutation.py +236 -0
- tnfr/operators/preconditions/__init__.py +1226 -0
- tnfr/operators/preconditions/coherence.py +305 -0
- tnfr/operators/preconditions/dissonance.py +236 -0
- tnfr/operators/preconditions/emission.py +128 -0
- tnfr/operators/preconditions/mutation.py +580 -0
- tnfr/operators/preconditions/reception.py +125 -0
- tnfr/operators/preconditions/resonance.py +364 -0
- tnfr/operators/registry.py +74 -0
- tnfr/operators/registry.pyi +9 -0
- tnfr/operators/remesh.py +1415 -91
- tnfr/operators/remesh.pyi +26 -0
- tnfr/operators/structural_units.py +268 -0
- tnfr/operators/unified_grammar.py +105 -0
- tnfr/parallel/__init__.py +54 -0
- tnfr/parallel/auto_scaler.py +234 -0
- tnfr/parallel/distributed.py +384 -0
- tnfr/parallel/engine.py +238 -0
- tnfr/parallel/gpu_engine.py +420 -0
- tnfr/parallel/monitoring.py +248 -0
- tnfr/parallel/partitioner.py +459 -0
- tnfr/py.typed +0 -0
- tnfr/recipes/__init__.py +22 -0
- tnfr/recipes/cookbook.py +743 -0
- tnfr/rng.py +75 -151
- tnfr/rng.pyi +26 -0
- tnfr/schemas/__init__.py +8 -0
- tnfr/schemas/grammar.json +94 -0
- tnfr/sdk/__init__.py +107 -0
- tnfr/sdk/__init__.pyi +19 -0
- tnfr/sdk/adaptive_system.py +173 -0
- tnfr/sdk/adaptive_system.pyi +21 -0
- tnfr/sdk/builders.py +370 -0
- tnfr/sdk/builders.pyi +51 -0
- tnfr/sdk/fluent.py +1121 -0
- tnfr/sdk/fluent.pyi +74 -0
- tnfr/sdk/templates.py +342 -0
- tnfr/sdk/templates.pyi +41 -0
- tnfr/sdk/utils.py +341 -0
- tnfr/secure_config.py +46 -0
- tnfr/security/__init__.py +70 -0
- tnfr/security/database.py +514 -0
- tnfr/security/subprocess.py +503 -0
- tnfr/security/validation.py +290 -0
- tnfr/selector.py +59 -22
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +92 -67
- tnfr/sense.pyi +23 -0
- tnfr/services/__init__.py +17 -0
- tnfr/services/orchestrator.py +325 -0
- tnfr/sparse/__init__.py +39 -0
- tnfr/sparse/representations.py +492 -0
- tnfr/structural.py +639 -263
- tnfr/structural.pyi +83 -0
- tnfr/telemetry/__init__.py +35 -0
- tnfr/telemetry/cache_metrics.py +226 -0
- tnfr/telemetry/cache_metrics.pyi +64 -0
- tnfr/telemetry/nu_f.py +422 -0
- tnfr/telemetry/nu_f.pyi +108 -0
- tnfr/telemetry/verbosity.py +36 -0
- tnfr/telemetry/verbosity.pyi +15 -0
- tnfr/tokens.py +2 -4
- tnfr/tokens.pyi +36 -0
- tnfr/tools/__init__.py +20 -0
- tnfr/tools/domain_templates.py +478 -0
- tnfr/tools/sequence_generator.py +846 -0
- tnfr/topology/__init__.py +13 -0
- tnfr/topology/asymmetry.py +151 -0
- tnfr/trace.py +300 -126
- tnfr/trace.pyi +42 -0
- tnfr/tutorials/__init__.py +38 -0
- tnfr/tutorials/autonomous_evolution.py +285 -0
- tnfr/tutorials/interactive.py +1576 -0
- tnfr/tutorials/structural_metabolism.py +238 -0
- tnfr/types.py +743 -12
- tnfr/types.pyi +357 -0
- tnfr/units.py +68 -0
- tnfr/units.pyi +13 -0
- tnfr/utils/__init__.py +282 -0
- tnfr/utils/__init__.pyi +215 -0
- tnfr/utils/cache.py +4223 -0
- tnfr/utils/cache.pyi +470 -0
- tnfr/{callback_utils.py → utils/callbacks.py} +26 -39
- tnfr/utils/callbacks.pyi +49 -0
- tnfr/utils/chunks.py +108 -0
- tnfr/utils/chunks.pyi +22 -0
- tnfr/utils/data.py +428 -0
- tnfr/utils/data.pyi +74 -0
- tnfr/utils/graph.py +85 -0
- tnfr/utils/graph.pyi +10 -0
- tnfr/utils/init.py +821 -0
- tnfr/utils/init.pyi +80 -0
- tnfr/utils/io.py +559 -0
- tnfr/utils/io.pyi +66 -0
- tnfr/{helpers → utils}/numeric.py +51 -24
- tnfr/utils/numeric.pyi +21 -0
- tnfr/validation/__init__.py +257 -0
- tnfr/validation/__init__.pyi +85 -0
- tnfr/validation/compatibility.py +460 -0
- tnfr/validation/compatibility.pyi +6 -0
- tnfr/validation/config.py +73 -0
- tnfr/validation/graph.py +139 -0
- tnfr/validation/graph.pyi +18 -0
- tnfr/validation/input_validation.py +755 -0
- tnfr/validation/invariants.py +712 -0
- tnfr/validation/rules.py +253 -0
- tnfr/validation/rules.pyi +44 -0
- tnfr/validation/runtime.py +279 -0
- tnfr/validation/runtime.pyi +28 -0
- tnfr/validation/sequence_validator.py +162 -0
- tnfr/validation/soft_filters.py +170 -0
- tnfr/validation/soft_filters.pyi +32 -0
- tnfr/validation/spectral.py +164 -0
- tnfr/validation/spectral.pyi +42 -0
- tnfr/validation/validator.py +1266 -0
- tnfr/validation/window.py +39 -0
- tnfr/validation/window.pyi +1 -0
- tnfr/visualization/__init__.py +98 -0
- tnfr/visualization/cascade_viz.py +256 -0
- tnfr/visualization/hierarchy.py +284 -0
- tnfr/visualization/sequence_plotter.py +784 -0
- tnfr/viz/__init__.py +60 -0
- tnfr/viz/matplotlib.py +278 -0
- tnfr/viz/matplotlib.pyi +35 -0
- tnfr-8.5.0.dist-info/METADATA +573 -0
- tnfr-8.5.0.dist-info/RECORD +353 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/entry_points.txt +1 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/licenses/LICENSE.md +1 -1
- tnfr/collections_utils.py +0 -300
- tnfr/config.py +0 -32
- tnfr/grammar.py +0 -344
- tnfr/graph_utils.py +0 -84
- tnfr/helpers/__init__.py +0 -71
- tnfr/import_utils.py +0 -228
- tnfr/json_utils.py +0 -162
- tnfr/logging_utils.py +0 -116
- tnfr/presets.py +0 -60
- tnfr/validators.py +0 -84
- tnfr/value_utils.py +0 -59
- tnfr-4.5.2.dist-info/METADATA +0 -379
- tnfr-4.5.2.dist-info/RECORD +0 -67
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .._compat import TypeAlias as TypeAlias
|
|
4
|
+
from ..alias import (
|
|
5
|
+
collect_attr as collect_attr,
|
|
6
|
+
collect_theta_attr as collect_theta_attr,
|
|
7
|
+
get_attr as get_attr,
|
|
8
|
+
set_attr as set_attr,
|
|
9
|
+
)
|
|
10
|
+
from ..constants import get_param as get_param
|
|
11
|
+
from ..constants.aliases import (
|
|
12
|
+
ALIAS_D2VF as ALIAS_D2VF,
|
|
13
|
+
ALIAS_DEPI as ALIAS_DEPI,
|
|
14
|
+
ALIAS_DNFR as ALIAS_DNFR,
|
|
15
|
+
ALIAS_DSI as ALIAS_DSI,
|
|
16
|
+
ALIAS_DVF as ALIAS_DVF,
|
|
17
|
+
ALIAS_EPI as ALIAS_EPI,
|
|
18
|
+
ALIAS_SI as ALIAS_SI,
|
|
19
|
+
ALIAS_VF as ALIAS_VF,
|
|
20
|
+
)
|
|
21
|
+
from ..glyph_history import (
|
|
22
|
+
append_metric as append_metric,
|
|
23
|
+
ensure_history as ensure_history,
|
|
24
|
+
)
|
|
25
|
+
from ..observers import (
|
|
26
|
+
DEFAULT_GLYPH_LOAD_SPAN as DEFAULT_GLYPH_LOAD_SPAN,
|
|
27
|
+
DEFAULT_WBAR_SPAN as DEFAULT_WBAR_SPAN,
|
|
28
|
+
glyph_load as glyph_load,
|
|
29
|
+
kuramoto_order as kuramoto_order,
|
|
30
|
+
phase_sync as phase_sync,
|
|
31
|
+
)
|
|
32
|
+
from ..sense import sigma_vector as sigma_vector
|
|
33
|
+
from ..types import (
|
|
34
|
+
CoherenceMetric as CoherenceMetric,
|
|
35
|
+
FloatArray as FloatArray,
|
|
36
|
+
FloatMatrix as FloatMatrix,
|
|
37
|
+
GlyphLoadDistribution as GlyphLoadDistribution,
|
|
38
|
+
HistoryState as HistoryState,
|
|
39
|
+
NodeId as NodeId,
|
|
40
|
+
ParallelWijPayload as ParallelWijPayload,
|
|
41
|
+
SigmaVector as SigmaVector,
|
|
42
|
+
TNFRGraph as TNFRGraph,
|
|
43
|
+
)
|
|
44
|
+
from ..utils import (
|
|
45
|
+
CallbackEvent as CallbackEvent,
|
|
46
|
+
callback_manager as callback_manager,
|
|
47
|
+
clamp01 as clamp01,
|
|
48
|
+
ensure_node_index_map as ensure_node_index_map,
|
|
49
|
+
get_logger as get_logger,
|
|
50
|
+
get_numpy as get_numpy,
|
|
51
|
+
normalize_weights as normalize_weights,
|
|
52
|
+
resolve_chunk_size as resolve_chunk_size,
|
|
53
|
+
)
|
|
54
|
+
from .common import (
|
|
55
|
+
compute_coherence as compute_coherence,
|
|
56
|
+
min_max_range as min_max_range,
|
|
57
|
+
)
|
|
58
|
+
from .trig_cache import (
|
|
59
|
+
compute_theta_trig as compute_theta_trig,
|
|
60
|
+
get_trig_cache as get_trig_cache,
|
|
61
|
+
)
|
|
62
|
+
from _typeshed import Incomplete
|
|
63
|
+
from collections.abc import Callable, Mapping, Sequence
|
|
64
|
+
from dataclasses import dataclass
|
|
65
|
+
from types import ModuleType
|
|
66
|
+
from typing import Any
|
|
67
|
+
|
|
68
|
+
logger: Incomplete
|
|
69
|
+
GLYPH_LOAD_STABILIZERS_KEY: str
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class SimilarityInputs:
|
|
73
|
+
th_vals: Sequence[float]
|
|
74
|
+
epi_vals: Sequence[float]
|
|
75
|
+
vf_vals: Sequence[float]
|
|
76
|
+
si_vals: Sequence[float]
|
|
77
|
+
cos_vals: Sequence[float] | None = ...
|
|
78
|
+
sin_vals: Sequence[float] | None = ...
|
|
79
|
+
|
|
80
|
+
CoherenceMatrixDense = list[list[float]]
|
|
81
|
+
CoherenceMatrixSparse = list[tuple[int, int, float]]
|
|
82
|
+
CoherenceMatrixPayload = CoherenceMatrixDense | CoherenceMatrixSparse
|
|
83
|
+
PhaseSyncWeights: TypeAlias
|
|
84
|
+
SimilarityComponents = tuple[float, float, float, float]
|
|
85
|
+
VectorizedComponents: TypeAlias
|
|
86
|
+
ScalarOrArray: TypeAlias
|
|
87
|
+
StabilityChunkArgs = tuple[
|
|
88
|
+
Sequence[float],
|
|
89
|
+
Sequence[float],
|
|
90
|
+
Sequence[float],
|
|
91
|
+
Sequence[float | None],
|
|
92
|
+
Sequence[float],
|
|
93
|
+
Sequence[float | None],
|
|
94
|
+
Sequence[float | None],
|
|
95
|
+
float,
|
|
96
|
+
float,
|
|
97
|
+
float,
|
|
98
|
+
]
|
|
99
|
+
StabilityChunkResult = tuple[
|
|
100
|
+
int, int, float, float, list[float], list[float], list[float]
|
|
101
|
+
]
|
|
102
|
+
MetricValue: TypeAlias
|
|
103
|
+
MetricProvider = Callable[[], MetricValue]
|
|
104
|
+
MetricRecord: TypeAlias
|
|
105
|
+
|
|
106
|
+
def compute_wij_phase_epi_vf_si(
|
|
107
|
+
inputs: SimilarityInputs,
|
|
108
|
+
i: int | None = None,
|
|
109
|
+
j: int | None = None,
|
|
110
|
+
*,
|
|
111
|
+
trig: Any | None = None,
|
|
112
|
+
G: TNFRGraph | None = None,
|
|
113
|
+
nodes: Sequence[NodeId] | None = None,
|
|
114
|
+
epi_range: float = 1.0,
|
|
115
|
+
vf_range: float = 1.0,
|
|
116
|
+
np: ModuleType | None = None,
|
|
117
|
+
) -> SimilarityComponents | VectorizedComponents: ...
|
|
118
|
+
def coherence_matrix(
|
|
119
|
+
G: TNFRGraph, use_numpy: bool | None = None, *, n_jobs: int | None = None
|
|
120
|
+
) -> tuple[list[NodeId] | None, CoherenceMatrixPayload | None]: ...
|
|
121
|
+
def local_phase_sync_weighted(
|
|
122
|
+
G: TNFRGraph,
|
|
123
|
+
n: NodeId,
|
|
124
|
+
nodes_order: Sequence[NodeId] | None = None,
|
|
125
|
+
W_row: PhaseSyncWeights | None = None,
|
|
126
|
+
node_to_index: Mapping[NodeId, int] | None = None,
|
|
127
|
+
) -> float: ...
|
|
128
|
+
def local_phase_sync(G: TNFRGraph, n: NodeId) -> float: ...
|
|
129
|
+
def register_coherence_callbacks(G: TNFRGraph) -> None: ...
|
tnfr/metrics/common.py
CHANGED
|
@@ -6,17 +6,11 @@ from types import MappingProxyType
|
|
|
6
6
|
from typing import Any, Iterable, Mapping, Sequence
|
|
7
7
|
|
|
8
8
|
from ..alias import collect_attr, get_attr, multi_recompute_abs_max
|
|
9
|
-
from ..
|
|
10
|
-
from ..constants import
|
|
11
|
-
from ..
|
|
12
|
-
from ..
|
|
13
|
-
from ..
|
|
14
|
-
from ..types import GraphLike
|
|
15
|
-
|
|
16
|
-
ALIAS_DNFR = get_aliases("DNFR")
|
|
17
|
-
ALIAS_D2EPI = get_aliases("D2EPI")
|
|
18
|
-
ALIAS_DEPI = get_aliases("DEPI")
|
|
19
|
-
ALIAS_VF = get_aliases("VF")
|
|
9
|
+
from ..constants import DEFAULTS
|
|
10
|
+
from ..constants.aliases import ALIAS_D2EPI, ALIAS_DEPI, ALIAS_DNFR, ALIAS_VF
|
|
11
|
+
from ..utils import clamp01, kahan_sum_nd, normalize_optional_int
|
|
12
|
+
from ..types import GraphLike, NodeAttrMap
|
|
13
|
+
from ..utils import edge_version_cache, get_numpy, normalize_weights
|
|
20
14
|
|
|
21
15
|
__all__ = (
|
|
22
16
|
"GraphLike",
|
|
@@ -27,6 +21,7 @@ __all__ = (
|
|
|
27
21
|
"merge_graph_weights",
|
|
28
22
|
"merge_and_normalize_weights",
|
|
29
23
|
"min_max_range",
|
|
24
|
+
"_coerce_jobs",
|
|
30
25
|
"_get_vf_dnfr_max",
|
|
31
26
|
)
|
|
32
27
|
|
|
@@ -72,7 +67,10 @@ def ensure_neighbors_map(G: GraphLike) -> Mapping[Any, Sequence[Any]]:
|
|
|
72
67
|
def merge_graph_weights(G: GraphLike, key: str) -> dict[str, float]:
|
|
73
68
|
"""Merge default weights for ``key`` with any graph overrides."""
|
|
74
69
|
|
|
75
|
-
|
|
70
|
+
overrides = G.graph.get(key, {})
|
|
71
|
+
if overrides is None or not isinstance(overrides, Mapping):
|
|
72
|
+
overrides = {}
|
|
73
|
+
return {**DEFAULTS[key], **overrides}
|
|
76
74
|
|
|
77
75
|
|
|
78
76
|
def merge_and_normalize_weights(
|
|
@@ -103,7 +101,7 @@ def compute_dnfr_accel_max(G: GraphLike) -> dict[str, float]:
|
|
|
103
101
|
)
|
|
104
102
|
|
|
105
103
|
|
|
106
|
-
def normalize_dnfr(nd:
|
|
104
|
+
def normalize_dnfr(nd: NodeAttrMap, max_val: float) -> float:
|
|
107
105
|
"""Normalise ``|ΔNFR|`` using ``max_val``."""
|
|
108
106
|
|
|
109
107
|
if max_val <= 0:
|
|
@@ -137,9 +135,7 @@ def _get_vf_dnfr_max(G: GraphLike) -> tuple[float, float]:
|
|
|
137
135
|
vfmax = G.graph.get("_vfmax")
|
|
138
136
|
dnfrmax = G.graph.get("_dnfrmax")
|
|
139
137
|
if vfmax is None or dnfrmax is None:
|
|
140
|
-
maxes = multi_recompute_abs_max(
|
|
141
|
-
G, {"_vfmax": ALIAS_VF, "_dnfrmax": ALIAS_DNFR}
|
|
142
|
-
)
|
|
138
|
+
maxes = multi_recompute_abs_max(G, {"_vfmax": ALIAS_VF, "_dnfrmax": ALIAS_DNFR})
|
|
143
139
|
if vfmax is None:
|
|
144
140
|
vfmax = maxes["_vfmax"]
|
|
145
141
|
if dnfrmax is None:
|
|
@@ -149,3 +145,14 @@ def _get_vf_dnfr_max(G: GraphLike) -> tuple[float, float]:
|
|
|
149
145
|
vfmax = 1.0 if vfmax == 0 else vfmax
|
|
150
146
|
dnfrmax = 1.0 if dnfrmax == 0 else dnfrmax
|
|
151
147
|
return float(vfmax), float(dnfrmax)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _coerce_jobs(raw_jobs: Any | None) -> int | None:
|
|
151
|
+
"""Normalise parallel job hints shared by metrics modules."""
|
|
152
|
+
|
|
153
|
+
return normalize_optional_int(
|
|
154
|
+
raw_jobs,
|
|
155
|
+
allow_non_positive=False,
|
|
156
|
+
strict=False,
|
|
157
|
+
sentinels=None,
|
|
158
|
+
)
|
tnfr/metrics/common.pyi
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable, Mapping, Sequence
|
|
4
|
+
from typing import Any, Literal, overload
|
|
5
|
+
|
|
6
|
+
from ..types import GraphLike, NodeAttrMap
|
|
7
|
+
|
|
8
|
+
__all__: tuple[str, ...]
|
|
9
|
+
|
|
10
|
+
def __getattr__(name: str) -> Any: ...
|
|
11
|
+
@overload
|
|
12
|
+
def compute_coherence(G: GraphLike, *, return_means: Literal[False] = ...) -> float: ...
|
|
13
|
+
@overload
|
|
14
|
+
def compute_coherence(
|
|
15
|
+
G: GraphLike, *, return_means: Literal[True]
|
|
16
|
+
) -> tuple[float, float, float]: ...
|
|
17
|
+
def compute_coherence(
|
|
18
|
+
G: GraphLike, *, return_means: bool = ...
|
|
19
|
+
) -> float | tuple[float, float, float]: ...
|
|
20
|
+
def ensure_neighbors_map(G: GraphLike) -> Mapping[Any, Sequence[Any]]: ...
|
|
21
|
+
def merge_graph_weights(G: GraphLike, key: str) -> dict[str, float]: ...
|
|
22
|
+
def merge_and_normalize_weights(
|
|
23
|
+
G: GraphLike,
|
|
24
|
+
key: str,
|
|
25
|
+
fields: Sequence[str],
|
|
26
|
+
*,
|
|
27
|
+
default: float = ...,
|
|
28
|
+
) -> dict[str, float]: ...
|
|
29
|
+
def compute_dnfr_accel_max(G: GraphLike) -> dict[str, float]: ...
|
|
30
|
+
def normalize_dnfr(nd: NodeAttrMap, max_val: float) -> float: ...
|
|
31
|
+
def min_max_range(
|
|
32
|
+
values: Iterable[float], *, default: tuple[float, float] = ...
|
|
33
|
+
) -> tuple[float, float]: ...
|
|
34
|
+
def _get_vf_dnfr_max(G: GraphLike) -> tuple[float, float]: ...
|
|
35
|
+
def _coerce_jobs(raw_jobs: Any | None) -> int | None: ...
|
tnfr/metrics/core.py
CHANGED
|
@@ -2,13 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Mapping, MutableMapping
|
|
6
|
+
from typing import Any, NamedTuple, cast
|
|
6
7
|
|
|
7
|
-
from ..
|
|
8
|
+
from ..utils import CallbackEvent, callback_manager
|
|
8
9
|
from ..constants import get_param
|
|
9
10
|
from ..glyph_history import append_metric, ensure_history
|
|
10
|
-
from ..
|
|
11
|
+
from ..telemetry import ensure_nu_f_telemetry
|
|
12
|
+
from ..units import get_hz_bridge
|
|
13
|
+
from ..telemetry.verbosity import (
|
|
14
|
+
TELEMETRY_VERBOSITY_DEFAULT,
|
|
15
|
+
TELEMETRY_VERBOSITY_LEVELS,
|
|
16
|
+
TelemetryVerbosity,
|
|
17
|
+
)
|
|
18
|
+
from ..types import (
|
|
19
|
+
GlyphSelector,
|
|
20
|
+
NodeId,
|
|
21
|
+
SelectorPreselectionChoices,
|
|
22
|
+
SelectorPreselectionMetrics,
|
|
23
|
+
SelectorPreselectionPayload,
|
|
24
|
+
TNFRGraph,
|
|
25
|
+
TraceCallback,
|
|
26
|
+
TraceFieldFn,
|
|
27
|
+
TraceFieldMap,
|
|
28
|
+
TraceFieldRegistry,
|
|
29
|
+
)
|
|
30
|
+
from ..utils import get_logger
|
|
11
31
|
from .coherence import (
|
|
32
|
+
GLYPH_LOAD_STABILIZERS_KEY,
|
|
12
33
|
_aggregate_si,
|
|
13
34
|
_track_stability,
|
|
14
35
|
_update_coherence,
|
|
@@ -17,18 +38,28 @@ from .coherence import (
|
|
|
17
38
|
register_coherence_callbacks,
|
|
18
39
|
)
|
|
19
40
|
from .diagnosis import register_diagnosis_callbacks
|
|
20
|
-
from .glyph_timing import _compute_advanced_metrics
|
|
41
|
+
from .glyph_timing import GlyphMetricsHistory, _compute_advanced_metrics
|
|
21
42
|
from .reporting import (
|
|
22
43
|
Tg_by_node,
|
|
23
44
|
Tg_global,
|
|
24
|
-
glyphogram_series,
|
|
25
45
|
glyph_top,
|
|
46
|
+
glyphogram_series,
|
|
26
47
|
latency_series,
|
|
27
48
|
)
|
|
28
49
|
|
|
29
50
|
logger = get_logger(__name__)
|
|
30
51
|
|
|
31
52
|
__all__ = [
|
|
53
|
+
"TNFRGraph",
|
|
54
|
+
"NodeId",
|
|
55
|
+
"GlyphSelector",
|
|
56
|
+
"SelectorPreselectionMetrics",
|
|
57
|
+
"SelectorPreselectionChoices",
|
|
58
|
+
"SelectorPreselectionPayload",
|
|
59
|
+
"TraceCallback",
|
|
60
|
+
"TraceFieldFn",
|
|
61
|
+
"TraceFieldMap",
|
|
62
|
+
"TraceFieldRegistry",
|
|
32
63
|
"_metrics_step",
|
|
33
64
|
"register_metrics_callbacks",
|
|
34
65
|
"Tg_global",
|
|
@@ -39,32 +70,176 @@ __all__ = [
|
|
|
39
70
|
]
|
|
40
71
|
|
|
41
72
|
|
|
42
|
-
|
|
73
|
+
class MetricsVerbositySpec(NamedTuple):
|
|
74
|
+
"""Runtime configuration for metrics verbosity tiers."""
|
|
75
|
+
|
|
76
|
+
name: str
|
|
77
|
+
enable_phase_sync: bool
|
|
78
|
+
enable_sigma: bool
|
|
79
|
+
enable_aggregate_si: bool
|
|
80
|
+
enable_advanced: bool
|
|
81
|
+
attach_coherence_hooks: bool
|
|
82
|
+
attach_diagnosis_hooks: bool
|
|
83
|
+
enable_nu_f: bool
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
METRICS_VERBOSITY_DEFAULT = TELEMETRY_VERBOSITY_DEFAULT
|
|
87
|
+
|
|
88
|
+
_METRICS_VERBOSITY_PRESETS: dict[str, MetricsVerbositySpec] = {}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _register_metrics_preset(spec: MetricsVerbositySpec) -> None:
|
|
92
|
+
if spec.name not in TELEMETRY_VERBOSITY_LEVELS:
|
|
93
|
+
raise ValueError(
|
|
94
|
+
"Unknown metrics verbosity '%s'; use %s"
|
|
95
|
+
% (
|
|
96
|
+
spec.name,
|
|
97
|
+
", ".join(TELEMETRY_VERBOSITY_LEVELS),
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
_METRICS_VERBOSITY_PRESETS[spec.name] = spec
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
_register_metrics_preset(
|
|
104
|
+
MetricsVerbositySpec(
|
|
105
|
+
name=TelemetryVerbosity.BASIC.value,
|
|
106
|
+
enable_phase_sync=False,
|
|
107
|
+
enable_sigma=False,
|
|
108
|
+
enable_aggregate_si=False,
|
|
109
|
+
enable_advanced=False,
|
|
110
|
+
attach_coherence_hooks=False,
|
|
111
|
+
attach_diagnosis_hooks=False,
|
|
112
|
+
enable_nu_f=False,
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
_detailed_spec = MetricsVerbositySpec(
|
|
117
|
+
name=TelemetryVerbosity.DETAILED.value,
|
|
118
|
+
enable_phase_sync=True,
|
|
119
|
+
enable_sigma=True,
|
|
120
|
+
enable_aggregate_si=True,
|
|
121
|
+
enable_advanced=False,
|
|
122
|
+
attach_coherence_hooks=True,
|
|
123
|
+
attach_diagnosis_hooks=False,
|
|
124
|
+
enable_nu_f=True,
|
|
125
|
+
)
|
|
126
|
+
_register_metrics_preset(_detailed_spec)
|
|
127
|
+
_register_metrics_preset(
|
|
128
|
+
_detailed_spec._replace(
|
|
129
|
+
name=TelemetryVerbosity.DEBUG.value,
|
|
130
|
+
enable_advanced=True,
|
|
131
|
+
attach_diagnosis_hooks=True,
|
|
132
|
+
enable_nu_f=True,
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
_METRICS_BASE_HISTORY_KEYS = ("C_steps", "stable_frac", "delta_Si", "B")
|
|
137
|
+
_METRICS_PHASE_HISTORY_KEYS = ("phase_sync", "kuramoto_R")
|
|
138
|
+
_METRICS_SIGMA_HISTORY_KEYS = (
|
|
139
|
+
GLYPH_LOAD_STABILIZERS_KEY,
|
|
140
|
+
"glyph_load_disr",
|
|
141
|
+
"sense_sigma_x",
|
|
142
|
+
"sense_sigma_y",
|
|
143
|
+
"sense_sigma_mag",
|
|
144
|
+
"sense_sigma_angle",
|
|
145
|
+
)
|
|
146
|
+
_METRICS_SI_HISTORY_KEYS = ("Si_mean", "Si_hi_frac", "Si_lo_frac")
|
|
147
|
+
_METRICS_NU_F_HISTORY_KEYS = (
|
|
148
|
+
"nu_f_rate_hz_str",
|
|
149
|
+
"nu_f_rate_hz",
|
|
150
|
+
"nu_f_ci_lower_hz_str",
|
|
151
|
+
"nu_f_ci_upper_hz_str",
|
|
152
|
+
"nu_f_ci_lower_hz",
|
|
153
|
+
"nu_f_ci_upper_hz",
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _update_nu_f_snapshot(
|
|
158
|
+
G: TNFRGraph,
|
|
159
|
+
hist: MutableMapping[str, Any],
|
|
160
|
+
*,
|
|
161
|
+
record_history: bool,
|
|
162
|
+
) -> None:
|
|
163
|
+
"""Refresh νf telemetry snapshot and optionally persist it in history."""
|
|
164
|
+
|
|
165
|
+
accumulator = ensure_nu_f_telemetry(G, confidence_level=None)
|
|
166
|
+
snapshot = accumulator.snapshot(graph=G)
|
|
167
|
+
payload = snapshot.as_payload()
|
|
168
|
+
bridge: float | None
|
|
169
|
+
try:
|
|
170
|
+
bridge = float(get_hz_bridge(G))
|
|
171
|
+
except (TypeError, ValueError, KeyError):
|
|
172
|
+
bridge = None
|
|
173
|
+
else:
|
|
174
|
+
payload["hz_bridge"] = bridge
|
|
175
|
+
|
|
176
|
+
telemetry = G.graph.setdefault("telemetry", {})
|
|
177
|
+
if not isinstance(telemetry, MutableMapping):
|
|
178
|
+
telemetry = {}
|
|
179
|
+
G.graph["telemetry"] = telemetry
|
|
180
|
+
telemetry["nu_f_snapshot"] = payload
|
|
181
|
+
telemetry["nu_f_bridge"] = bridge
|
|
182
|
+
|
|
183
|
+
if record_history:
|
|
184
|
+
append_metric(hist, "nu_f_rate_hz_str", snapshot.rate_hz_str)
|
|
185
|
+
append_metric(hist, "nu_f_rate_hz", snapshot.rate_hz)
|
|
186
|
+
append_metric(hist, "nu_f_ci_lower_hz_str", snapshot.ci_lower_hz_str)
|
|
187
|
+
append_metric(hist, "nu_f_ci_upper_hz_str", snapshot.ci_upper_hz_str)
|
|
188
|
+
append_metric(hist, "nu_f_ci_lower_hz", snapshot.ci_lower_hz)
|
|
189
|
+
append_metric(hist, "nu_f_ci_upper_hz", snapshot.ci_upper_hz)
|
|
190
|
+
|
|
191
|
+
G.graph["_nu_f_snapshot_payload"] = payload
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _resolve_metrics_verbosity(cfg: Mapping[str, Any]) -> MetricsVerbositySpec:
|
|
195
|
+
"""Return the preset matching ``cfg['verbosity']``."""
|
|
196
|
+
|
|
197
|
+
raw_value = cfg.get("verbosity", METRICS_VERBOSITY_DEFAULT)
|
|
198
|
+
key = str(raw_value).lower()
|
|
199
|
+
spec = _METRICS_VERBOSITY_PRESETS.get(key)
|
|
200
|
+
if spec is not None:
|
|
201
|
+
return spec
|
|
202
|
+
logger.warning(
|
|
203
|
+
"Unknown METRICS verbosity '%s'; falling back to '%s'",
|
|
204
|
+
raw_value,
|
|
205
|
+
METRICS_VERBOSITY_DEFAULT,
|
|
206
|
+
)
|
|
207
|
+
return _METRICS_VERBOSITY_PRESETS[METRICS_VERBOSITY_DEFAULT]
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _metrics_step(G: TNFRGraph, ctx: dict[str, Any] | None = None) -> None:
|
|
43
211
|
"""Update operational TNFR metrics per step."""
|
|
44
212
|
|
|
45
213
|
del ctx
|
|
46
214
|
|
|
47
|
-
cfg = get_param(G, "METRICS")
|
|
215
|
+
cfg = cast(Mapping[str, Any], get_param(G, "METRICS"))
|
|
48
216
|
if not cfg.get("enabled", True):
|
|
49
217
|
return
|
|
50
218
|
|
|
219
|
+
spec = _resolve_metrics_verbosity(cfg)
|
|
51
220
|
hist = ensure_history(G)
|
|
221
|
+
if "glyph_load_estab" in hist:
|
|
222
|
+
raise ValueError(
|
|
223
|
+
"History payloads using 'glyph_load_estab' are no longer supported. "
|
|
224
|
+
"Rename the series to 'glyph_load_stabilizers' before loading the graph."
|
|
225
|
+
)
|
|
52
226
|
metrics_sentinel_key = "_metrics_history_id"
|
|
53
227
|
history_id = id(hist)
|
|
54
228
|
if G.graph.get(metrics_sentinel_key) != history_id:
|
|
55
|
-
for
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
229
|
+
for key in _METRICS_BASE_HISTORY_KEYS:
|
|
230
|
+
hist.setdefault(key, [])
|
|
231
|
+
if spec.enable_phase_sync:
|
|
232
|
+
for key in _METRICS_PHASE_HISTORY_KEYS:
|
|
233
|
+
hist.setdefault(key, [])
|
|
234
|
+
if spec.enable_sigma:
|
|
235
|
+
for key in _METRICS_SIGMA_HISTORY_KEYS:
|
|
236
|
+
hist.setdefault(key, [])
|
|
237
|
+
if spec.enable_aggregate_si:
|
|
238
|
+
for key in _METRICS_SI_HISTORY_KEYS:
|
|
239
|
+
hist.setdefault(key, [])
|
|
240
|
+
if spec.enable_nu_f:
|
|
241
|
+
for key in _METRICS_NU_F_HISTORY_KEYS:
|
|
242
|
+
hist.setdefault(key, [])
|
|
68
243
|
G.graph[metrics_sentinel_key] = history_id
|
|
69
244
|
|
|
70
245
|
dt = float(get_param(G, "DT"))
|
|
@@ -73,29 +248,69 @@ def _metrics_step(G, ctx: dict[str, Any] | None = None):
|
|
|
73
248
|
t = float(G.graph.get("_t", 0.0))
|
|
74
249
|
|
|
75
250
|
_update_coherence(G, hist)
|
|
76
|
-
|
|
251
|
+
|
|
252
|
+
raw_jobs = cfg.get("n_jobs")
|
|
253
|
+
metrics_jobs: int | None
|
|
77
254
|
try:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
255
|
+
metrics_jobs = None if raw_jobs is None else int(raw_jobs)
|
|
256
|
+
except (TypeError, ValueError):
|
|
257
|
+
metrics_jobs = None
|
|
258
|
+
else:
|
|
259
|
+
if metrics_jobs <= 0:
|
|
260
|
+
metrics_jobs = None
|
|
261
|
+
|
|
262
|
+
_track_stability(
|
|
263
|
+
G,
|
|
264
|
+
hist,
|
|
265
|
+
dt,
|
|
266
|
+
eps_dnfr,
|
|
267
|
+
eps_depi,
|
|
268
|
+
n_jobs=metrics_jobs,
|
|
269
|
+
)
|
|
270
|
+
if spec.enable_phase_sync or spec.enable_sigma:
|
|
271
|
+
try:
|
|
272
|
+
if spec.enable_phase_sync:
|
|
273
|
+
_update_phase_sync(G, hist)
|
|
274
|
+
if spec.enable_sigma:
|
|
275
|
+
_update_sigma(G, hist)
|
|
276
|
+
except (KeyError, AttributeError, TypeError) as exc:
|
|
277
|
+
logger.debug("observer update failed: %s", exc)
|
|
278
|
+
|
|
279
|
+
if hist.get("C_steps") and hist.get("stable_frac"):
|
|
280
|
+
append_metric(
|
|
281
|
+
hist,
|
|
282
|
+
"iota",
|
|
283
|
+
hist["C_steps"][-1] * hist["stable_frac"][-1],
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
if spec.enable_aggregate_si:
|
|
287
|
+
_aggregate_si(G, hist, n_jobs=metrics_jobs)
|
|
288
|
+
|
|
289
|
+
_update_nu_f_snapshot(G, hist, record_history=spec.enable_nu_f)
|
|
290
|
+
|
|
291
|
+
if spec.enable_advanced:
|
|
292
|
+
_compute_advanced_metrics(
|
|
293
|
+
G,
|
|
294
|
+
cast(GlyphMetricsHistory, hist),
|
|
295
|
+
t,
|
|
296
|
+
dt,
|
|
297
|
+
cfg,
|
|
298
|
+
n_jobs=metrics_jobs,
|
|
299
|
+
)
|
|
88
300
|
|
|
89
|
-
_aggregate_si(G, hist)
|
|
90
|
-
_compute_advanced_metrics(G, hist, t, dt, cfg)
|
|
91
301
|
|
|
302
|
+
def register_metrics_callbacks(G: TNFRGraph) -> None:
|
|
303
|
+
"""Attach canonical metrics callbacks according to graph configuration."""
|
|
92
304
|
|
|
93
|
-
|
|
305
|
+
cfg = cast(Mapping[str, Any], get_param(G, "METRICS"))
|
|
306
|
+
spec = _resolve_metrics_verbosity(cfg)
|
|
94
307
|
callback_manager.register_callback(
|
|
95
308
|
G,
|
|
96
309
|
event=CallbackEvent.AFTER_STEP.value,
|
|
97
310
|
func=_metrics_step,
|
|
98
311
|
name="metrics_step",
|
|
99
312
|
)
|
|
100
|
-
|
|
101
|
-
|
|
313
|
+
if spec.attach_coherence_hooks:
|
|
314
|
+
register_coherence_callbacks(G)
|
|
315
|
+
if spec.attach_diagnosis_hooks:
|
|
316
|
+
register_diagnosis_callbacks(G)
|
tnfr/metrics/core.pyi
ADDED