chronaxis 0.1.0.dev0__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.
- chronaxis/__init__.py +72 -0
- chronaxis/__main__.py +12 -0
- chronaxis/analysis_cli.py +181 -0
- chronaxis/batch/__init__.py +14 -0
- chronaxis/batch/api.py +46 -0
- chronaxis/batch/cli.py +48 -0
- chronaxis/batch/config.py +37 -0
- chronaxis/batch/models.py +202 -0
- chronaxis/batch/process_transport.py +149 -0
- chronaxis/batch/process_tree.py +72 -0
- chronaxis/batch/publication.py +41 -0
- chronaxis/batch/runner.py +236 -0
- chronaxis/batch/templates.py +42 -0
- chronaxis/can_dependencies.py +42 -0
- chronaxis/cli.py +193 -0
- chronaxis/configuration/__init__.py +46 -0
- chronaxis/configuration/cli.py +41 -0
- chronaxis/configuration/diagnostics.py +107 -0
- chronaxis/configuration/explanation.py +233 -0
- chronaxis/configuration/file_tools.py +140 -0
- chronaxis/configuration/imports.py +144 -0
- chronaxis/configuration/initialization.py +36 -0
- chronaxis/configuration/json_parser.py +114 -0
- chronaxis/configuration/models.py +74 -0
- chronaxis/configuration/origins.py +90 -0
- chronaxis/configuration/overrides.py +55 -0
- chronaxis/configuration/resolution.py +150 -0
- chronaxis/configuration/template_catalog.py +68 -0
- chronaxis/configuration/templates/batch/analysis-annotated.yaml +18 -0
- chronaxis/configuration/templates/batch/analysis-minimal.yaml +18 -0
- chronaxis/configuration/templates/batch/annotated.yaml +6 -0
- chronaxis/configuration/templates/batch/minimal.yaml +6 -0
- chronaxis/configuration/templates/can-asc/annotated.yaml +18 -0
- chronaxis/configuration/templates/can-asc/minimal.yaml +18 -0
- chronaxis/configuration/templates/can-blf/annotated.yaml +18 -0
- chronaxis/configuration/templates/can-blf/minimal.yaml +18 -0
- chronaxis/configuration/templates/can-export/annotated.yaml +23 -0
- chronaxis/configuration/templates/can-export/minimal.yaml +23 -0
- chronaxis/configuration/templates/catalog.json +233 -0
- chronaxis/configuration/templates/charge-session/annotated.yaml +38 -0
- chronaxis/configuration/templates/charge-session/minimal.yaml +38 -0
- chronaxis/configuration/templates/command-response/annotated.yaml +32 -0
- chronaxis/configuration/templates/command-response/minimal.yaml +36 -0
- chronaxis/configuration/templates/fault-window/annotated.yaml +25 -0
- chronaxis/configuration/templates/fault-window/minimal.yaml +27 -0
- chronaxis/configuration/templates/ini-mapping/annotated.yaml +20 -0
- chronaxis/configuration/templates/ini-mapping/minimal.yaml +20 -0
- chronaxis/configuration/templates/raw-can-csv/annotated.yaml +34 -0
- chronaxis/configuration/templates/raw-can-csv/minimal.yaml +35 -0
- chronaxis/configuration/templates/shared/charge-session.asc +5 -0
- chronaxis/configuration/templates/shared/command-response.asc +8 -0
- chronaxis/configuration/templates/shared/fault-window.asc +5 -0
- chronaxis/configuration/templates/shared/power.asc +7 -0
- chronaxis/configuration/templates/shared/sample.asc +6 -0
- chronaxis/configuration/templates/shared/sample.blf +0 -0
- chronaxis/configuration/templates/shared/sample.csv +5 -0
- chronaxis/configuration/templates/shared/sample.dbc +11 -0
- chronaxis/configuration/templates/shared/signals.csv +6 -0
- chronaxis/configuration/templates/shared/source.ini +5 -0
- chronaxis/configuration/templates/shared/stability.asc +9 -0
- chronaxis/configuration/templates/shared/teaching.dbc +27 -0
- chronaxis/configuration/templates/shared/threshold.asc +7 -0
- chronaxis/configuration/templates/signal-csv/annotated.yaml +27 -0
- chronaxis/configuration/templates/signal-csv/minimal.yaml +27 -0
- chronaxis/configuration/templates/signal-export/annotated.yaml +27 -0
- chronaxis/configuration/templates/signal-export/minimal.yaml +29 -0
- chronaxis/configuration/templates/stability/annotated.yaml +35 -0
- chronaxis/configuration/templates/stability/minimal.yaml +35 -0
- chronaxis/configuration/templates/threshold/annotated.yaml +22 -0
- chronaxis/configuration/templates/threshold/minimal.yaml +22 -0
- chronaxis/configuration/yaml_parser.py +125 -0
- chronaxis/core/__init__.py +71 -0
- chronaxis/core/binding.py +449 -0
- chronaxis/core/calculation_series_join.py +106 -0
- chronaxis/core/calculations.py +435 -0
- chronaxis/core/calculations_memory_numpy.py +136 -0
- chronaxis/core/calculations_memory_reference.py +165 -0
- chronaxis/core/calculations_numpy.py +298 -0
- chronaxis/core/calculations_reference.py +294 -0
- chronaxis/core/condition_evidence.py +182 -0
- chronaxis/core/conditional_integral_result.py +43 -0
- chronaxis/core/conditional_integral_terms.py +146 -0
- chronaxis/core/conditional_integral_terms_numpy.py +148 -0
- chronaxis/core/conditional_integral_terms_reference.py +111 -0
- chronaxis/core/conditional_time_reduction.py +118 -0
- chronaxis/core/conditional_time_reduction_numpy.py +223 -0
- chronaxis/core/conditional_time_reduction_reference.py +213 -0
- chronaxis/core/declarations.py +192 -0
- chronaxis/core/decoded_binding.py +197 -0
- chronaxis/core/direct_message.py +387 -0
- chronaxis/core/export_interpolation.py +54 -0
- chronaxis/core/expression.py +642 -0
- chronaxis/core/expression_numpy.py +314 -0
- chronaxis/core/expression_reference.py +272 -0
- chronaxis/core/integral_result.py +53 -0
- chronaxis/core/integral_sum.py +77 -0
- chronaxis/core/integral_sum_numpy.py +224 -0
- chronaxis/core/integral_sum_reference.py +148 -0
- chronaxis/core/integral_terms.py +119 -0
- chronaxis/core/integral_terms_numpy.py +127 -0
- chronaxis/core/integral_terms_reference.py +91 -0
- chronaxis/core/mean_weights_numpy.py +29 -0
- chronaxis/core/mean_weights_reference.py +27 -0
- chronaxis/core/message_binding.py +305 -0
- chronaxis/core/models.py +485 -0
- chronaxis/core/normalize_numpy.py +396 -0
- chronaxis/core/numeric.py +472 -0
- chronaxis/core/numeric_numpy.py +440 -0
- chronaxis/core/record_intervals.py +115 -0
- chronaxis/core/sample_reduction.py +161 -0
- chronaxis/core/sample_reduction_numpy.py +160 -0
- chronaxis/core/sample_reduction_reference.py +154 -0
- chronaxis/core/selection.py +74 -0
- chronaxis/core/sequence.py +160 -0
- chronaxis/core/sequence_reference.py +248 -0
- chronaxis/core/stability.py +249 -0
- chronaxis/core/start_end.py +169 -0
- chronaxis/core/state.py +494 -0
- chronaxis/core/state_numpy.py +296 -0
- chronaxis/core/temporal.py +373 -0
- chronaxis/core/temporal_clock.py +25 -0
- chronaxis/core/temporal_memory_numpy.py +163 -0
- chronaxis/core/temporal_memory_reference.py +161 -0
- chronaxis/core/temporal_numpy.py +345 -0
- chronaxis/core/temporal_reference.py +304 -0
- chronaxis/core/time_reduction.py +190 -0
- chronaxis/core/time_reduction_numpy.py +205 -0
- chronaxis/core/time_reduction_reference.py +203 -0
- chronaxis/core/types.py +105 -0
- chronaxis/core/units.py +81 -0
- chronaxis/core/validation.py +94 -0
- chronaxis/core/window_delta.py +123 -0
- chronaxis/core/window_delta_numpy.py +78 -0
- chronaxis/core/window_delta_reference.py +69 -0
- chronaxis/core/windows.py +224 -0
- chronaxis/core/windows_numpy.py +78 -0
- chronaxis/core/windows_reference.py +61 -0
- chronaxis/execution/__init__.py +6 -0
- chronaxis/execution/batch_signal_groups.py +122 -0
- chronaxis/execution/bindings.py +296 -0
- chronaxis/execution/boundaries.py +568 -0
- chronaxis/execution/calculation_blocks.py +338 -0
- chronaxis/execution/calculation_values.py +55 -0
- chronaxis/execution/can_batch_reader.py +356 -0
- chronaxis/execution/can_reader.py +948 -0
- chronaxis/execution/can_reference_template.py +61 -0
- chronaxis/execution/condition_evidence.py +370 -0
- chronaxis/execution/conditional_integral_facts.py +310 -0
- chronaxis/execution/conditional_integral_reduction.py +216 -0
- chronaxis/execution/csv_observation.py +524 -0
- chronaxis/execution/csv_reader.py +662 -0
- chronaxis/execution/current_message_calculation.py +225 -0
- chronaxis/execution/driver_expression.py +274 -0
- chronaxis/execution/expressions.py +618 -0
- chronaxis/execution/frame_capture.py +245 -0
- chronaxis/execution/groups.py +236 -0
- chronaxis/execution/historical_conditional_blocks.py +264 -0
- chronaxis/execution/historical_conditional_integral.py +226 -0
- chronaxis/execution/historical_conditional_time_calculation.py +368 -0
- chronaxis/execution/historical_integral.py +219 -0
- chronaxis/execution/historical_observation.py +372 -0
- chronaxis/execution/historical_sample_calculation.py +338 -0
- chronaxis/execution/historical_selection_rows.py +300 -0
- chronaxis/execution/historical_time_calculation.py +341 -0
- chronaxis/execution/history.py +572 -0
- chronaxis/execution/history_records.py +225 -0
- chronaxis/execution/hold.py +448 -0
- chronaxis/execution/integral_facts.py +311 -0
- chronaxis/execution/integral_reduction.py +216 -0
- chronaxis/execution/legacy_frame_samples.py +94 -0
- chronaxis/execution/memory_reader.py +247 -0
- chronaxis/execution/message_bindings.py +293 -0
- chronaxis/execution/message_delivery.py +37 -0
- chronaxis/execution/observed_ingestion.py +551 -0
- chronaxis/execution/raw_signal_groups.py +192 -0
- chronaxis/execution/record_alarm_duration.py +114 -0
- chronaxis/execution/record_delta_condition.py +167 -0
- chronaxis/execution/record_diagnostics.py +87 -0
- chronaxis/execution/record_event_durations.py +143 -0
- chronaxis/execution/record_export_samples.py +94 -0
- chronaxis/execution/record_exports.py +155 -0
- chronaxis/execution/record_integral.py +196 -0
- chronaxis/execution/record_point_buffer.py +101 -0
- chronaxis/execution/record_rule_timeline.py +344 -0
- chronaxis/execution/record_sample.py +46 -0
- chronaxis/execution/record_sample_series.py +29 -0
- chronaxis/execution/record_scope_calculations.py +290 -0
- chronaxis/execution/record_selection.py +62 -0
- chronaxis/execution/record_sequences.py +199 -0
- chronaxis/execution/record_session_calculations.py +778 -0
- chronaxis/execution/record_signal_export.py +133 -0
- chronaxis/execution/record_source_cursor.py +295 -0
- chronaxis/execution/record_time_calculation.py +322 -0
- chronaxis/execution/record_time_indexes.py +143 -0
- chronaxis/execution/record_value_history.py +160 -0
- chronaxis/execution/record_windows.py +229 -0
- chronaxis/execution/required_expression.py +52 -0
- chronaxis/execution/retained_metadata.py +71 -0
- chronaxis/execution/run_session.py +402 -0
- chronaxis/execution/scanned_signal_proof.py +550 -0
- chronaxis/execution/signal_validity.py +40 -0
- chronaxis/execution/state.py +280 -0
- chronaxis/execution/temporal_buffer.py +508 -0
- chronaxis/execution/text_can_reader.py +359 -0
- chronaxis/execution/timeline.py +309 -0
- chronaxis/execution/timeline_multi.py +415 -0
- chronaxis/execution/window_delta_events.py +220 -0
- chronaxis/execution/window_replay.py +350 -0
- chronaxis/execution/windows.py +173 -0
- chronaxis/guide/README.md +70 -0
- chronaxis/guide/api/AnalysisError.md +14 -0
- chronaxis/guide/api/AnalysisPlan.md +96 -0
- chronaxis/guide/api/AnalysisResult.md +398 -0
- chronaxis/guide/api/AnalysisRunner.md +155 -0
- chronaxis/guide/api/BatchJob.md +19 -0
- chronaxis/guide/api/BatchJobResult.md +61 -0
- chronaxis/guide/api/BatchPlan.md +48 -0
- chronaxis/guide/api/BatchReport.md +108 -0
- chronaxis/guide/api/BatchRunner.md +84 -0
- chronaxis/guide/api/OutputManifest.md +23 -0
- chronaxis/guide/api/PlanFragment.md +47 -0
- chronaxis/guide/api/PlanValidationError.md +98 -0
- chronaxis/guide/api/PresetSpec.md +63 -0
- chronaxis/guide/api/ResultClosedError.md +14 -0
- chronaxis/guide/api/RunMetadata.md +100 -0
- chronaxis/guide/api/TimeConversion.md +29 -0
- chronaxis/guide/api/TimeOverflowError.md +17 -0
- chronaxis/guide/api/build_preset.md +36 -0
- chronaxis/guide/api/checked_add_ns.md +30 -0
- chronaxis/guide/api/convert_time.md +40 -0
- chronaxis/guide/api/explain_analysis_plan.md +38 -0
- chronaxis/guide/api/index.json +185 -0
- chronaxis/guide/api/load_analysis_plan.md +34 -0
- chronaxis/guide/api/load_batch_plan.md +36 -0
- chronaxis/guide/api/parse_datetime_ns.md +35 -0
- chronaxis/guide/api/parse_duration.md +30 -0
- chronaxis/guide/api/resolve_preset_roles.md +37 -0
- chronaxis/guide/api/run_batch.md +38 -0
- chronaxis/guide/api/shift_times_reference.md +33 -0
- chronaxis/guide/api/time_deltas_reference.md +37 -0
- chronaxis/guide/api/validate_analysis_plan.md +38 -0
- chronaxis/guide/en/README.md +74 -0
- chronaxis/guide/en/api/AnalysisError.md +14 -0
- chronaxis/guide/en/api/AnalysisPlan.md +93 -0
- chronaxis/guide/en/api/AnalysisResult.md +398 -0
- chronaxis/guide/en/api/AnalysisRunner.md +191 -0
- chronaxis/guide/en/api/BatchJob.md +17 -0
- chronaxis/guide/en/api/BatchJobResult.md +43 -0
- chronaxis/guide/en/api/BatchPlan.md +37 -0
- chronaxis/guide/en/api/BatchReport.md +52 -0
- chronaxis/guide/en/api/BatchRunner.md +51 -0
- chronaxis/guide/en/api/OutputManifest.md +23 -0
- chronaxis/guide/en/api/PlanFragment.md +33 -0
- chronaxis/guide/en/api/PlanValidationError.md +58 -0
- chronaxis/guide/en/api/PresetSpec.md +51 -0
- chronaxis/guide/en/api/ResultClosedError.md +14 -0
- chronaxis/guide/en/api/RunMetadata.md +100 -0
- chronaxis/guide/en/api/TimeConversion.md +23 -0
- chronaxis/guide/en/api/TimeOverflowError.md +14 -0
- chronaxis/guide/en/api/build_preset.md +23 -0
- chronaxis/guide/en/api/checked_add_ns.md +21 -0
- chronaxis/guide/en/api/convert_time.md +25 -0
- chronaxis/guide/en/api/explain_analysis_plan.md +30 -0
- chronaxis/guide/en/api/index.json +185 -0
- chronaxis/guide/en/api/load_analysis_plan.md +27 -0
- chronaxis/guide/en/api/load_batch_plan.md +28 -0
- chronaxis/guide/en/api/parse_datetime_ns.md +23 -0
- chronaxis/guide/en/api/parse_duration.md +20 -0
- chronaxis/guide/en/api/resolve_preset_roles.md +23 -0
- chronaxis/guide/en/api/run_batch.md +39 -0
- chronaxis/guide/en/api/shift_times_reference.md +21 -0
- chronaxis/guide/en/api/time_deltas_reference.md +22 -0
- chronaxis/guide/en/api/validate_analysis_plan.md +29 -0
- chronaxis/guide/en/fields/analysis/calculations-all-1.json +345 -0
- chronaxis/guide/en/fields/analysis/calculations-all-2.json +300 -0
- chronaxis/guide/en/fields/analysis/calculations-all-3.json +84 -0
- chronaxis/guide/en/fields/analysis/config_version-all-1.json +24 -0
- chronaxis/guide/en/fields/analysis/dataset-all-1.json +344 -0
- chronaxis/guide/en/fields/analysis/derived-all-1.json +147 -0
- chronaxis/guide/en/fields/analysis/diagnostics-all-1.json +69 -0
- chronaxis/guide/en/fields/analysis/execution-all-1.json +167 -0
- chronaxis/guide/en/fields/analysis/imports-all-1.json +39 -0
- chronaxis/guide/en/fields/analysis/intervals-all-1.json +173 -0
- chronaxis/guide/en/fields/analysis/message_calculations-all-1.json +345 -0
- chronaxis/guide/en/fields/analysis/message_calculations-all-2.json +270 -0
- chronaxis/guide/en/fields/analysis/metadata-all-1.json +24 -0
- chronaxis/guide/en/fields/analysis/outputs-all-1.json +332 -0
- chronaxis/guide/en/fields/analysis/outputs-all-2.json +319 -0
- chronaxis/guide/en/fields/analysis/outputs-all-3.json +321 -0
- chronaxis/guide/en/fields/analysis/outputs-all-4.json +236 -0
- chronaxis/guide/en/fields/analysis/outputs-all-5.json +246 -0
- chronaxis/guide/en/fields/analysis/outputs-all-6.json +214 -0
- chronaxis/guide/en/fields/analysis/overrides-all-1.json +104 -0
- chronaxis/guide/en/fields/analysis/presets-charge_session-1.json +398 -0
- chronaxis/guide/en/fields/analysis/presets-charge_session-2.json +114 -0
- chronaxis/guide/en/fields/analysis/presets-command_response-1.json +376 -0
- chronaxis/guide/en/fields/analysis/presets-fault_context-1.json +285 -0
- chronaxis/guide/en/fields/analysis/presets-threshold_excursion-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-condition_duration-1.json +344 -0
- chronaxis/guide/en/fields/analysis/rules-condition_duration-2.json +27 -0
- chronaxis/guide/en/fields/analysis/rules-debounce-1.json +335 -0
- chronaxis/guide/en/fields/analysis/rules-falling_edge-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-hysteresis-1.json +334 -0
- chronaxis/guide/en/fields/analysis/rules-hysteresis-2.json +27 -0
- chronaxis/guide/en/fields/analysis/rules-rising_edge-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-start_end-1.json +333 -0
- chronaxis/guide/en/fields/analysis/rules-start_end-2.json +60 -0
- chronaxis/guide/en/fields/analysis/rules-start_only-1.json +334 -0
- chronaxis/guide/en/fields/analysis/rules-window_delta-1.json +338 -0
- chronaxis/guide/en/fields/analysis/rules-window_delta-2.json +96 -0
- chronaxis/guide/en/fields/analysis/sequences-all-1.json +378 -0
- chronaxis/guide/en/fields/analysis/sequences-all-2.json +70 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-1.json +349 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-2.json +297 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-3.json +323 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-4.json +192 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-1.json +327 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-2.json +312 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-3.json +294 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-4.json +253 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-5.json +44 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-1.json +318 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-3.json +311 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-4.json +69 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-1.json +317 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-3.json +317 -0
- chronaxis/guide/en/fields/analysis/sources-memory-1.json +332 -0
- chronaxis/guide/en/fields/analysis/sources-memory-2.json +125 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-1.json +330 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-10.json +233 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-11.json +225 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-12.json +228 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-13.json +226 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-14.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-15.json +227 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-16.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-17.json +238 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-18.json +239 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-19.json +233 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-20.json +242 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-21.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-22.json +228 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-23.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-24.json +223 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-25.json +290 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-26.json +131 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-3.json +297 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-4.json +226 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-5.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-6.json +227 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-7.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-8.json +238 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-9.json +239 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-1.json +331 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-2.json +307 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-3.json +315 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-1.json +319 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-2.json +307 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-3.json +312 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-4.json +113 -0
- chronaxis/guide/en/fields/analysis/windows-all-1.json +361 -0
- chronaxis/guide/en/fields/analysis/windows-all-2.json +187 -0
- chronaxis/guide/en/fields/batch/backend-all-1.json +26 -0
- chronaxis/guide/en/fields/batch/batch_version-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/fail_fast-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/inputs-all-1.json +161 -0
- chronaxis/guide/en/fields/batch/jobs-all-1.json +58 -0
- chronaxis/guide/en/fields/batch/process_count-all-1.json +23 -0
- chronaxis/guide/en/fields/batch/source-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/template-all-1.json +22 -0
- chronaxis/guide/en/fields/definitions/derived-all-1.json +121 -0
- chronaxis/guide/en/fields/definitions/signals-all-1.json +336 -0
- chronaxis/guide/en/fields/definitions/signals-all-2.json +307 -0
- chronaxis/guide/en/fields/definitions/signals-all-3.json +290 -0
- chronaxis/guide/en/fields/definitions/signals-all-4.json +347 -0
- chronaxis/guide/en/fields/definitions/signals-all-5.json +297 -0
- chronaxis/guide/en/fields/definitions/signals-all-6.json +259 -0
- chronaxis/guide/en/fields/definitions/signals-all-7.json +117 -0
- chronaxis/guide/en/fields/definitions/sources-all-1.json +332 -0
- chronaxis/guide/en/fields/definitions/sources-all-10.json +306 -0
- chronaxis/guide/en/fields/definitions/sources-all-11.json +294 -0
- chronaxis/guide/en/fields/definitions/sources-all-12.json +212 -0
- chronaxis/guide/en/fields/definitions/sources-all-13.json +217 -0
- chronaxis/guide/en/fields/definitions/sources-all-14.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-15.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-16.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-17.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-18.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-19.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-2.json +323 -0
- chronaxis/guide/en/fields/definitions/sources-all-20.json +217 -0
- chronaxis/guide/en/fields/definitions/sources-all-21.json +210 -0
- chronaxis/guide/en/fields/definitions/sources-all-22.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-23.json +218 -0
- chronaxis/guide/en/fields/definitions/sources-all-24.json +209 -0
- chronaxis/guide/en/fields/definitions/sources-all-25.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-26.json +218 -0
- chronaxis/guide/en/fields/definitions/sources-all-27.json +224 -0
- chronaxis/guide/en/fields/definitions/sources-all-28.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-29.json +205 -0
- chronaxis/guide/en/fields/definitions/sources-all-3.json +303 -0
- chronaxis/guide/en/fields/definitions/sources-all-30.json +298 -0
- chronaxis/guide/en/fields/definitions/sources-all-31.json +315 -0
- chronaxis/guide/en/fields/definitions/sources-all-32.json +306 -0
- chronaxis/guide/en/fields/definitions/sources-all-33.json +209 -0
- chronaxis/guide/en/fields/definitions/sources-all-4.json +336 -0
- chronaxis/guide/en/fields/definitions/sources-all-5.json +299 -0
- chronaxis/guide/en/fields/definitions/sources-all-6.json +307 -0
- chronaxis/guide/en/fields/definitions/sources-all-7.json +320 -0
- chronaxis/guide/en/fields/definitions/sources-all-8.json +303 -0
- chronaxis/guide/en/fields/definitions/sources-all-9.json +315 -0
- chronaxis/guide/en/fields/index.json +3450 -0
- chronaxis/guide/en/fields/mapping/aliases-all-1.json +91 -0
- chronaxis/guide/en/fields/mapping/analysis-all-1.json +382 -0
- chronaxis/guide/en/fields/mapping/analysis-all-10.json +301 -0
- chronaxis/guide/en/fields/mapping/analysis-all-11.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-12.json +311 -0
- chronaxis/guide/en/fields/mapping/analysis-all-13.json +314 -0
- chronaxis/guide/en/fields/mapping/analysis-all-14.json +310 -0
- chronaxis/guide/en/fields/mapping/analysis-all-15.json +297 -0
- chronaxis/guide/en/fields/mapping/analysis-all-16.json +226 -0
- chronaxis/guide/en/fields/mapping/analysis-all-17.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-18.json +227 -0
- chronaxis/guide/en/fields/mapping/analysis-all-19.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-2.json +323 -0
- chronaxis/guide/en/fields/mapping/analysis-all-20.json +221 -0
- chronaxis/guide/en/fields/mapping/analysis-all-21.json +237 -0
- chronaxis/guide/en/fields/mapping/analysis-all-22.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-23.json +222 -0
- chronaxis/guide/en/fields/mapping/analysis-all-24.json +231 -0
- chronaxis/guide/en/fields/mapping/analysis-all-25.json +225 -0
- chronaxis/guide/en/fields/mapping/analysis-all-26.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-27.json +228 -0
- chronaxis/guide/en/fields/mapping/analysis-all-28.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-29.json +223 -0
- chronaxis/guide/en/fields/mapping/analysis-all-3.json +318 -0
- chronaxis/guide/en/fields/mapping/analysis-all-30.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-31.json +218 -0
- chronaxis/guide/en/fields/mapping/analysis-all-32.json +239 -0
- chronaxis/guide/en/fields/mapping/analysis-all-33.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-34.json +225 -0
- chronaxis/guide/en/fields/mapping/analysis-all-35.json +228 -0
- chronaxis/guide/en/fields/mapping/analysis-all-36.json +226 -0
- chronaxis/guide/en/fields/mapping/analysis-all-37.json +244 -0
- chronaxis/guide/en/fields/mapping/analysis-all-38.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-39.json +299 -0
- chronaxis/guide/en/fields/mapping/analysis-all-4.json +297 -0
- chronaxis/guide/en/fields/mapping/analysis-all-40.json +311 -0
- chronaxis/guide/en/fields/mapping/analysis-all-41.json +310 -0
- chronaxis/guide/en/fields/mapping/analysis-all-42.json +346 -0
- chronaxis/guide/en/fields/mapping/analysis-all-43.json +267 -0
- chronaxis/guide/en/fields/mapping/analysis-all-44.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-45.json +279 -0
- chronaxis/guide/en/fields/mapping/analysis-all-46.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-47.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-48.json +294 -0
- chronaxis/guide/en/fields/mapping/analysis-all-49.json +253 -0
- chronaxis/guide/en/fields/mapping/analysis-all-5.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-50.json +346 -0
- chronaxis/guide/en/fields/mapping/analysis-all-51.json +324 -0
- chronaxis/guide/en/fields/mapping/analysis-all-52.json +335 -0
- chronaxis/guide/en/fields/mapping/analysis-all-53.json +317 -0
- chronaxis/guide/en/fields/mapping/analysis-all-54.json +316 -0
- chronaxis/guide/en/fields/mapping/analysis-all-55.json +302 -0
- chronaxis/guide/en/fields/mapping/analysis-all-56.json +319 -0
- chronaxis/guide/en/fields/mapping/analysis-all-57.json +334 -0
- chronaxis/guide/en/fields/mapping/analysis-all-58.json +333 -0
- chronaxis/guide/en/fields/mapping/analysis-all-59.json +359 -0
- chronaxis/guide/en/fields/mapping/analysis-all-6.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-60.json +303 -0
- chronaxis/guide/en/fields/mapping/analysis-all-61.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-62.json +301 -0
- chronaxis/guide/en/fields/mapping/analysis-all-63.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-64.json +367 -0
- chronaxis/guide/en/fields/mapping/analysis-all-65.json +334 -0
- chronaxis/guide/en/fields/mapping/analysis-all-66.json +358 -0
- chronaxis/guide/en/fields/mapping/analysis-all-67.json +349 -0
- chronaxis/guide/en/fields/mapping/analysis-all-68.json +331 -0
- chronaxis/guide/en/fields/mapping/analysis-all-69.json +304 -0
- chronaxis/guide/en/fields/mapping/analysis-all-7.json +303 -0
- chronaxis/guide/en/fields/mapping/analysis-all-70.json +349 -0
- chronaxis/guide/en/fields/mapping/analysis-all-71.json +288 -0
- chronaxis/guide/en/fields/mapping/analysis-all-72.json +316 -0
- chronaxis/guide/en/fields/mapping/analysis-all-73.json +266 -0
- chronaxis/guide/en/fields/mapping/analysis-all-74.json +227 -0
- chronaxis/guide/en/fields/mapping/analysis-all-75.json +239 -0
- chronaxis/guide/en/fields/mapping/analysis-all-76.json +274 -0
- chronaxis/guide/en/fields/mapping/analysis-all-77.json +380 -0
- chronaxis/guide/en/fields/mapping/analysis-all-78.json +313 -0
- chronaxis/guide/en/fields/mapping/analysis-all-79.json +338 -0
- chronaxis/guide/en/fields/mapping/analysis-all-8.json +292 -0
- chronaxis/guide/en/fields/mapping/analysis-all-80.json +304 -0
- chronaxis/guide/en/fields/mapping/analysis-all-81.json +140 -0
- chronaxis/guide/en/fields/mapping/analysis-all-9.json +332 -0
- chronaxis/guide/en/fields/mapping/io_policy-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/mapping_version-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/path_base-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/sections-all-1.json +402 -0
- chronaxis/guide/en/fields/mapping/sections-all-2.json +232 -0
- chronaxis/guide/en/semantics.md +70 -0
- chronaxis/guide/en/tasks.json +290 -0
- chronaxis/guide/en/workflow.md +41 -0
- chronaxis/guide/examples/analysis-imports.yaml +22 -0
- chronaxis/guide/examples/analysis.yaml +23 -0
- chronaxis/guide/examples/batch-minimal.yaml +3 -0
- chronaxis/guide/examples/conditional-energy.yaml +36 -0
- chronaxis/guide/examples/data/activity.csv +6 -0
- chronaxis/guide/examples/data/can/activity.asc +11 -0
- chronaxis/guide/examples/data/can/calculation-minimal.asc +6 -0
- chronaxis/guide/examples/data/can/conditional-energy/part-1.asc +92 -0
- chronaxis/guide/examples/data/can/conditional-energy/part-2.asc +36 -0
- chronaxis/guide/examples/data/can/conditional-energy/signals.dbc +10 -0
- chronaxis/guide/examples/data/can/execution-comparison.asc +12 -0
- chronaxis/guide/examples/data/can/execution-report.asc +4 -0
- chronaxis/guide/examples/data/can/expression-extended.asc +11 -0
- chronaxis/guide/examples/data/can/interval-actual.asc +6 -0
- chronaxis/guide/examples/data/can/preset-charge-energy.asc +15 -0
- chronaxis/guide/examples/data/can/preset-charge-minimal.asc +11 -0
- chronaxis/guide/examples/data/can/preset-command-automatic.asc +11 -0
- chronaxis/guide/examples/data/can/preset-fault-context.asc +7 -0
- chronaxis/guide/examples/data/can/preset-threshold-delay.asc +7 -0
- chronaxis/guide/examples/data/can/preset-threshold-partial.asc +7 -0
- chronaxis/guide/examples/data/can/quality.asc +6 -0
- chronaxis/guide/examples/data/can/quickstart-parts/part1.asc +4 -0
- chronaxis/guide/examples/data/can/quickstart-parts/part2.asc +3 -0
- chronaxis/guide/examples/data/can/quickstart.asc +6 -0
- chronaxis/guide/examples/data/can/rule-condition_duration-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-condition_duration-minimal.asc +19 -0
- chronaxis/guide/examples/data/can/rule-debounce-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-falling_edge-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-hysteresis-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-start_end-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-start_only-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-window_delta-extended.asc +19 -0
- chronaxis/guide/examples/data/can/sequence-outcomes.asc +19 -0
- chronaxis/guide/examples/data/can/signal-types.asc +13 -0
- chronaxis/guide/examples/data/can/start-end.asc +30 -0
- chronaxis/guide/examples/data/can/teaching-base.asc +58 -0
- chronaxis/guide/examples/data/can/teaching.dbc +53 -0
- chronaxis/guide/examples/data/joint-current.csv +5 -0
- chronaxis/guide/examples/data/joint.asc +5 -0
- chronaxis/guide/examples/data/joint.dbc +7 -0
- chronaxis/guide/examples/data/message-clean.asc +6 -0
- chronaxis/guide/examples/data/message-direction.asc +7 -0
- chronaxis/guide/examples/data/message-direction.dbc +7 -0
- chronaxis/guide/examples/data/power.blf +0 -0
- chronaxis/guide/examples/data/power.dbc +6 -0
- chronaxis/guide/examples/data/quality.csv +5 -0
- chronaxis/guide/examples/data/raw-can-example.csv +5 -0
- chronaxis/guide/examples/data/signal-types.csv +5 -0
- chronaxis/guide/examples/data/signals.csv +6 -0
- chronaxis/guide/examples/data/timing.asc +6 -0
- chronaxis/guide/examples/data/timing.dbc +11 -0
- chronaxis/guide/examples/export-can-minimal.yaml +24 -0
- chronaxis/guide/examples/input-csv-minimal.yaml +23 -0
- chronaxis/guide/examples/preset-charge-energy.yaml +41 -0
- chronaxis/guide/examples/preset-charge-minimal.yaml +31 -0
- chronaxis/guide/examples/preset-fault-context.yaml +27 -0
- chronaxis/guide/examples/quality.yaml +19 -0
- chronaxis/guide/examples/sequence-outcomes.yaml +39 -0
- chronaxis/guide/examples/shared/definitions.yaml +14 -0
- chronaxis/guide/examples/signal-enum-minimal.yaml +19 -0
- chronaxis/guide/examples/signal-number-conversion.yaml +24 -0
- chronaxis/guide/examples/window-merged.yaml +28 -0
- chronaxis/guide/fields/analysis/calculations-all-1.json +360 -0
- chronaxis/guide/fields/analysis/calculations-all-2.json +299 -0
- chronaxis/guide/fields/analysis/calculations-all-3.json +70 -0
- chronaxis/guide/fields/analysis/config_version-all-1.json +24 -0
- chronaxis/guide/fields/analysis/dataset-all-1.json +344 -0
- chronaxis/guide/fields/analysis/derived-all-1.json +147 -0
- chronaxis/guide/fields/analysis/diagnostics-all-1.json +69 -0
- chronaxis/guide/fields/analysis/execution-all-1.json +167 -0
- chronaxis/guide/fields/analysis/imports-all-1.json +39 -0
- chronaxis/guide/fields/analysis/intervals-all-1.json +173 -0
- chronaxis/guide/fields/analysis/message_calculations-all-1.json +360 -0
- chronaxis/guide/fields/analysis/message_calculations-all-2.json +255 -0
- chronaxis/guide/fields/analysis/metadata-all-1.json +24 -0
- chronaxis/guide/fields/analysis/outputs-all-1.json +349 -0
- chronaxis/guide/fields/analysis/outputs-all-2.json +302 -0
- chronaxis/guide/fields/analysis/outputs-all-3.json +321 -0
- chronaxis/guide/fields/analysis/outputs-all-4.json +253 -0
- chronaxis/guide/fields/analysis/outputs-all-5.json +244 -0
- chronaxis/guide/fields/analysis/outputs-all-6.json +199 -0
- chronaxis/guide/fields/analysis/overrides-all-1.json +104 -0
- chronaxis/guide/fields/analysis/presets-charge_session-1.json +398 -0
- chronaxis/guide/fields/analysis/presets-charge_session-2.json +114 -0
- chronaxis/guide/fields/analysis/presets-command_response-1.json +376 -0
- chronaxis/guide/fields/analysis/presets-fault_context-1.json +285 -0
- chronaxis/guide/fields/analysis/presets-threshold_excursion-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-condition_duration-1.json +344 -0
- chronaxis/guide/fields/analysis/rules-condition_duration-2.json +27 -0
- chronaxis/guide/fields/analysis/rules-debounce-1.json +335 -0
- chronaxis/guide/fields/analysis/rules-falling_edge-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-hysteresis-1.json +334 -0
- chronaxis/guide/fields/analysis/rules-hysteresis-2.json +27 -0
- chronaxis/guide/fields/analysis/rules-rising_edge-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-start_end-1.json +349 -0
- chronaxis/guide/fields/analysis/rules-start_end-2.json +44 -0
- chronaxis/guide/fields/analysis/rules-start_only-1.json +334 -0
- chronaxis/guide/fields/analysis/rules-window_delta-1.json +356 -0
- chronaxis/guide/fields/analysis/rules-window_delta-2.json +78 -0
- chronaxis/guide/fields/analysis/sequences-all-1.json +394 -0
- chronaxis/guide/fields/analysis/sequences-all-2.json +54 -0
- chronaxis/guide/fields/analysis/signals-variant-1-1.json +349 -0
- chronaxis/guide/fields/analysis/signals-variant-1-2.json +297 -0
- chronaxis/guide/fields/analysis/signals-variant-1-3.json +340 -0
- chronaxis/guide/fields/analysis/signals-variant-1-4.json +175 -0
- chronaxis/guide/fields/analysis/signals-variant-2-1.json +327 -0
- chronaxis/guide/fields/analysis/signals-variant-2-2.json +335 -0
- chronaxis/guide/fields/analysis/signals-variant-2-3.json +289 -0
- chronaxis/guide/fields/analysis/signals-variant-2-4.json +270 -0
- chronaxis/guide/fields/analysis/sources-can_asc-1.json +318 -0
- chronaxis/guide/fields/analysis/sources-can_asc-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-can_asc-3.json +311 -0
- chronaxis/guide/fields/analysis/sources-can_asc-4.json +69 -0
- chronaxis/guide/fields/analysis/sources-can_blf-1.json +317 -0
- chronaxis/guide/fields/analysis/sources-can_blf-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-can_blf-3.json +317 -0
- chronaxis/guide/fields/analysis/sources-memory-1.json +347 -0
- chronaxis/guide/fields/analysis/sources-memory-2.json +110 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-1.json +330 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-10.json +233 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-11.json +225 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-12.json +228 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-13.json +226 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-14.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-15.json +227 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-16.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-17.json +238 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-18.json +239 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-19.json +233 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-20.json +242 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-21.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-22.json +228 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-23.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-24.json +223 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-25.json +290 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-26.json +131 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-3.json +297 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-4.json +226 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-5.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-6.json +227 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-7.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-8.json +238 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-9.json +239 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-1.json +331 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-2.json +327 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-3.json +295 -0
- chronaxis/guide/fields/analysis/sources-variant-6-1.json +319 -0
- chronaxis/guide/fields/analysis/sources-variant-6-2.json +327 -0
- chronaxis/guide/fields/analysis/sources-variant-6-3.json +314 -0
- chronaxis/guide/fields/analysis/sources-variant-6-4.json +91 -0
- chronaxis/guide/fields/analysis/windows-all-1.json +361 -0
- chronaxis/guide/fields/analysis/windows-all-2.json +187 -0
- chronaxis/guide/fields/batch/backend-all-1.json +26 -0
- chronaxis/guide/fields/batch/batch_version-all-1.json +22 -0
- chronaxis/guide/fields/batch/fail_fast-all-1.json +22 -0
- chronaxis/guide/fields/batch/inputs-all-1.json +161 -0
- chronaxis/guide/fields/batch/jobs-all-1.json +58 -0
- chronaxis/guide/fields/batch/process_count-all-1.json +23 -0
- chronaxis/guide/fields/batch/source-all-1.json +22 -0
- chronaxis/guide/fields/batch/template-all-1.json +22 -0
- chronaxis/guide/fields/definitions/derived-all-1.json +121 -0
- chronaxis/guide/fields/definitions/signals-all-1.json +336 -0
- chronaxis/guide/fields/definitions/signals-all-2.json +307 -0
- chronaxis/guide/fields/definitions/signals-all-3.json +305 -0
- chronaxis/guide/fields/definitions/signals-all-4.json +352 -0
- chronaxis/guide/fields/definitions/signals-all-5.json +311 -0
- chronaxis/guide/fields/definitions/signals-all-6.json +254 -0
- chronaxis/guide/fields/definitions/signals-all-7.json +88 -0
- chronaxis/guide/fields/definitions/sources-all-1.json +332 -0
- chronaxis/guide/fields/definitions/sources-all-10.json +307 -0
- chronaxis/guide/fields/definitions/sources-all-11.json +280 -0
- chronaxis/guide/fields/definitions/sources-all-12.json +209 -0
- chronaxis/guide/fields/definitions/sources-all-13.json +219 -0
- chronaxis/guide/fields/definitions/sources-all-14.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-15.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-16.json +232 -0
- chronaxis/guide/fields/definitions/sources-all-17.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-18.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-19.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-2.json +336 -0
- chronaxis/guide/fields/definitions/sources-all-20.json +228 -0
- chronaxis/guide/fields/definitions/sources-all-21.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-22.json +232 -0
- chronaxis/guide/fields/definitions/sources-all-23.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-24.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-25.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-26.json +228 -0
- chronaxis/guide/fields/definitions/sources-all-27.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-28.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-29.json +227 -0
- chronaxis/guide/fields/definitions/sources-all-3.json +306 -0
- chronaxis/guide/fields/definitions/sources-all-30.json +333 -0
- chronaxis/guide/fields/definitions/sources-all-31.json +302 -0
- chronaxis/guide/fields/definitions/sources-all-32.json +319 -0
- chronaxis/guide/fields/definitions/sources-all-33.json +89 -0
- chronaxis/guide/fields/definitions/sources-all-4.json +336 -0
- chronaxis/guide/fields/definitions/sources-all-5.json +313 -0
- chronaxis/guide/fields/definitions/sources-all-6.json +292 -0
- chronaxis/guide/fields/definitions/sources-all-7.json +319 -0
- chronaxis/guide/fields/definitions/sources-all-8.json +315 -0
- chronaxis/guide/fields/definitions/sources-all-9.json +318 -0
- chronaxis/guide/fields/index.json +3432 -0
- chronaxis/guide/fields/mapping/aliases-all-1.json +91 -0
- chronaxis/guide/fields/mapping/analysis-all-1.json +382 -0
- chronaxis/guide/fields/mapping/analysis-all-10.json +307 -0
- chronaxis/guide/fields/mapping/analysis-all-11.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-12.json +329 -0
- chronaxis/guide/fields/mapping/analysis-all-13.json +294 -0
- chronaxis/guide/fields/mapping/analysis-all-14.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-15.json +280 -0
- chronaxis/guide/fields/mapping/analysis-all-16.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-17.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-18.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-19.json +237 -0
- chronaxis/guide/fields/mapping/analysis-all-2.json +342 -0
- chronaxis/guide/fields/mapping/analysis-all-20.json +233 -0
- chronaxis/guide/fields/mapping/analysis-all-21.json +244 -0
- chronaxis/guide/fields/mapping/analysis-all-22.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-23.json +226 -0
- chronaxis/guide/fields/mapping/analysis-all-24.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-25.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-26.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-27.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-28.json +237 -0
- chronaxis/guide/fields/mapping/analysis-all-29.json +233 -0
- chronaxis/guide/fields/mapping/analysis-all-3.json +322 -0
- chronaxis/guide/fields/mapping/analysis-all-30.json +244 -0
- chronaxis/guide/fields/mapping/analysis-all-31.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-32.json +226 -0
- chronaxis/guide/fields/mapping/analysis-all-33.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-34.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-35.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-36.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-37.json +291 -0
- chronaxis/guide/fields/mapping/analysis-all-38.json +315 -0
- chronaxis/guide/fields/mapping/analysis-all-39.json +304 -0
- chronaxis/guide/fields/mapping/analysis-all-4.json +312 -0
- chronaxis/guide/fields/mapping/analysis-all-40.json +307 -0
- chronaxis/guide/fields/mapping/analysis-all-41.json +292 -0
- chronaxis/guide/fields/mapping/analysis-all-42.json +333 -0
- chronaxis/guide/fields/mapping/analysis-all-43.json +296 -0
- chronaxis/guide/fields/mapping/analysis-all-44.json +322 -0
- chronaxis/guide/fields/mapping/analysis-all-45.json +298 -0
- chronaxis/guide/fields/mapping/analysis-all-46.json +347 -0
- chronaxis/guide/fields/mapping/analysis-all-47.json +302 -0
- chronaxis/guide/fields/mapping/analysis-all-48.json +263 -0
- chronaxis/guide/fields/mapping/analysis-all-49.json +301 -0
- chronaxis/guide/fields/mapping/analysis-all-5.json +313 -0
- chronaxis/guide/fields/mapping/analysis-all-50.json +336 -0
- chronaxis/guide/fields/mapping/analysis-all-51.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-52.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-53.json +334 -0
- chronaxis/guide/fields/mapping/analysis-all-54.json +339 -0
- chronaxis/guide/fields/mapping/analysis-all-55.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-56.json +336 -0
- chronaxis/guide/fields/mapping/analysis-all-57.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-58.json +333 -0
- chronaxis/guide/fields/mapping/analysis-all-59.json +325 -0
- chronaxis/guide/fields/mapping/analysis-all-6.json +323 -0
- chronaxis/guide/fields/mapping/analysis-all-60.json +334 -0
- chronaxis/guide/fields/mapping/analysis-all-61.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-62.json +289 -0
- chronaxis/guide/fields/mapping/analysis-all-63.json +383 -0
- chronaxis/guide/fields/mapping/analysis-all-64.json +357 -0
- chronaxis/guide/fields/mapping/analysis-all-65.json +375 -0
- chronaxis/guide/fields/mapping/analysis-all-66.json +351 -0
- chronaxis/guide/fields/mapping/analysis-all-67.json +346 -0
- chronaxis/guide/fields/mapping/analysis-all-68.json +317 -0
- chronaxis/guide/fields/mapping/analysis-all-69.json +313 -0
- chronaxis/guide/fields/mapping/analysis-all-7.json +306 -0
- chronaxis/guide/fields/mapping/analysis-all-70.json +326 -0
- chronaxis/guide/fields/mapping/analysis-all-71.json +316 -0
- chronaxis/guide/fields/mapping/analysis-all-72.json +264 -0
- chronaxis/guide/fields/mapping/analysis-all-73.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-74.json +241 -0
- chronaxis/guide/fields/mapping/analysis-all-75.json +273 -0
- chronaxis/guide/fields/mapping/analysis-all-76.json +382 -0
- chronaxis/guide/fields/mapping/analysis-all-77.json +328 -0
- chronaxis/guide/fields/mapping/analysis-all-78.json +338 -0
- chronaxis/guide/fields/mapping/analysis-all-79.json +304 -0
- chronaxis/guide/fields/mapping/analysis-all-8.json +309 -0
- chronaxis/guide/fields/mapping/analysis-all-80.json +140 -0
- chronaxis/guide/fields/mapping/analysis-all-9.json +329 -0
- chronaxis/guide/fields/mapping/io_policy-all-1.json +19 -0
- chronaxis/guide/fields/mapping/mapping_version-all-1.json +19 -0
- chronaxis/guide/fields/mapping/path_base-all-1.json +19 -0
- chronaxis/guide/fields/mapping/sections-all-1.json +402 -0
- chronaxis/guide/fields/mapping/sections-all-2.json +232 -0
- chronaxis/guide/lookup.py +90 -0
- chronaxis/guide/manifest.json +614 -0
- chronaxis/guide/run_analysis.py +34 -0
- chronaxis/guide/schemas/analysis.schema.json +8451 -0
- chronaxis/guide/schemas/batch-v1.schema.json +172 -0
- chronaxis/guide/schemas/definitions.schema.json +29 -0
- chronaxis/guide/schemas/legacy-import-v1.schema.json +143 -0
- chronaxis/guide/semantics.md +62 -0
- chronaxis/guide/tasks.json +290 -0
- chronaxis/guide/workflow.md +38 -0
- chronaxis/legacy/__init__.py +46 -0
- chronaxis/legacy/batch_read.py +412 -0
- chronaxis/legacy/batch_validation.py +134 -0
- chronaxis/legacy/batch_wire.py +264 -0
- chronaxis/legacy/batch_worker.py +417 -0
- chronaxis/legacy/binding.py +154 -0
- chronaxis/legacy/dbc_cycles.py +47 -0
- chronaxis/legacy/decode_policy.py +28 -0
- chronaxis/legacy/disjunction.py +79 -0
- chronaxis/legacy/export_worker.py +147 -0
- chronaxis/legacy/export_write.py +378 -0
- chronaxis/legacy/message_store.py +562 -0
- chronaxis/legacy/process_read.py +526 -0
- chronaxis/legacy/raw_store.py +341 -0
- chronaxis/legacy/records.py +709 -0
- chronaxis/legacy/required_records.py +122 -0
- chronaxis/legacy/sum.py +403 -0
- chronaxis/legacy/sum_numpy.py +43 -0
- chronaxis/legacy/updates.py +277 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/can_processor.py +138 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/file_processor.py +218 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/utils.py +447 -0
- chronaxis/legacy/worker.py +352 -0
- chronaxis/migration/__init__.py +11 -0
- chronaxis/migration/api.py +270 -0
- chronaxis/migration/ini.py +110 -0
- chronaxis/migration/legacy_sum.py +304 -0
- chronaxis/migration/models.py +83 -0
- chronaxis/migration/publication.py +230 -0
- chronaxis/migration/sclicer.py +241 -0
- chronaxis/migration/slope.py +78 -0
- chronaxis/migration/start_end.py +48 -0
- chronaxis/planning/__init__.py +19 -0
- chronaxis/planning/channels.py +30 -0
- chronaxis/planning/checks.py +447 -0
- chronaxis/planning/config_groups.py +215 -0
- chronaxis/planning/dbc_defaults.py +88 -0
- chronaxis/planning/export_options.py +247 -0
- chronaxis/planning/input_defaults.py +62 -0
- chronaxis/planning/input_paths.py +124 -0
- chronaxis/planning/input_requirements.py +250 -0
- chronaxis/planning/inputs.py +306 -0
- chronaxis/planning/intervals.py +242 -0
- chronaxis/planning/legacy_execution.py +38 -0
- chronaxis/planning/message_calculations.py +171 -0
- chronaxis/planning/models.py +369 -0
- chronaxis/planning/nodes.py +355 -0
- chronaxis/planning/plan.py +294 -0
- chronaxis/planning/preset_models.py +211 -0
- chronaxis/planning/record_execution.py +76 -0
- chronaxis/planning/reports.py +523 -0
- chronaxis/planning/sequences.py +91 -0
- chronaxis/planning/signal_groups.py +61 -0
- chronaxis/planning/signal_validity.py +46 -0
- chronaxis/planning/text_inputs.py +110 -0
- chronaxis/presets.py +270 -0
- chronaxis/results/__init__.py +34 -0
- chronaxis/results/analysis_outcome.py +67 -0
- chronaxis/results/artifact_exports.py +212 -0
- chronaxis/results/binding_metadata.py +54 -0
- chronaxis/results/budget.py +138 -0
- chronaxis/results/can_metadata.py +247 -0
- chronaxis/results/codec.py +246 -0
- chronaxis/results/errors.py +25 -0
- chronaxis/results/export_files.py +216 -0
- chronaxis/results/frame_exports.py +299 -0
- chronaxis/results/frame_patch.py +186 -0
- chronaxis/results/frame_rebuild.py +458 -0
- chronaxis/results/frame_sort.py +223 -0
- chronaxis/results/input_diagnostics.py +51 -0
- chronaxis/results/manifest.py +343 -0
- chronaxis/results/merge_runs.py +207 -0
- chronaxis/results/owned_directory.py +32 -0
- chronaxis/results/raw_exports.py +689 -0
- chronaxis/results/readable.py +355 -0
- chronaxis/results/readable_format.py +94 -0
- chronaxis/results/result.py +734 -0
- chronaxis/results/rows.py +57 -0
- chronaxis/results/signal_exports.py +209 -0
- chronaxis/results/signal_grid.py +219 -0
- chronaxis/results/spool.py +421 -0
- chronaxis/results/summary.py +350 -0
- chronaxis/results/text_can_metadata.py +64 -0
- chronaxis/results/threshold_metadata.py +105 -0
- chronaxis/runner.py +121 -0
- chronaxis/sources/__init__.py +23 -0
- chronaxis/sources/asc.py +412 -0
- chronaxis/sources/blf.py +101 -0
- chronaxis/sources/can_spec.py +179 -0
- chronaxis/sources/can_updates.py +160 -0
- chronaxis/sources/csv_spec.py +133 -0
- chronaxis/sources/descriptions.py +65 -0
- chronaxis/sources/memory.py +299 -0
- chronaxis/sources/models.py +497 -0
- chronaxis/sources/packing.py +170 -0
- chronaxis/sources/protocol.py +221 -0
- chronaxis/sources/raw_can.py +62 -0
- chronaxis/sources/raw_csv.py +470 -0
- chronaxis/sources/raw_csv_layout.py +310 -0
- chronaxis/sources/signal_csv.py +608 -0
- chronaxis/sources/text_can_decode.py +421 -0
- chronaxis/sources/text_can_ref.py +48 -0
- chronaxis/sources/text_can_spec.py +61 -0
- chronaxis/timebase/__init__.py +19 -0
- chronaxis/timebase/conversion.py +364 -0
- chronaxis/timebase/numpy_ops.py +104 -0
- chronaxis/user_guide.py +81 -0
- chronaxis-0.1.0.dev0.dist-info/METADATA +172 -0
- chronaxis-0.1.0.dev0.dist-info/RECORD +917 -0
- chronaxis-0.1.0.dev0.dist-info/WHEEL +5 -0
- chronaxis-0.1.0.dev0.dist-info/entry_points.txt +2 -0
- chronaxis-0.1.0.dev0.dist-info/licenses/LICENSE +21 -0
- chronaxis-0.1.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""定义请求/响应配对输入与结果,不读取日志或改变原事件。
|
|
2
|
+
|
|
3
|
+
调用者先生成A、B事件,并提供响应条件的完整时间证据;SequenceTick收齐同刻
|
|
4
|
+
事实,SequenceRule规定闭区间延迟。SequenceResult保存原事件、延迟和观测质量,
|
|
5
|
+
与现有point/activity事件表分开,公共AnalysisRunner通过SequenceRow保存其原事实。
|
|
6
|
+
一个规则实例只属于一个dataset/session/group;group由上游分组后显式指定,
|
|
7
|
+
不从车辆名或报文ID猜测。这里只用标准库,不执行配对或保持全局状态。
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# 冻结输入防止跨批处理时调用者改写已确认事实。
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from .temporal import ConditionTick, Event
|
|
13
|
+
from .types import QualityFlag as Q, Truth
|
|
14
|
+
from .validation import require_identifier, require_text
|
|
15
|
+
from ..timebase.conversion import checked_add_ns, require_int64_ns
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class SequenceRule:
|
|
20
|
+
"""保存同一组内FIFO配对所需的身份和延迟范围。
|
|
21
|
+
|
|
22
|
+
延迟两端包含,最小值可为0;A/B由既有规则ID指定,以事件confirmed_ns参与配对。
|
|
23
|
+
group_id是调用者已经划分的实体/分析组,实例之间不共享候选或响应。
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
rule_id: str
|
|
27
|
+
dataset_id: str
|
|
28
|
+
session_id: str
|
|
29
|
+
start_rule_id: str
|
|
30
|
+
response_rule_id: str
|
|
31
|
+
min_delay_ns: int
|
|
32
|
+
max_delay_ns: int
|
|
33
|
+
group_id: str = 'default'
|
|
34
|
+
record_clock: bool = False # True时delay按所选记录间隔累计,事件坐标仍是实际时间。
|
|
35
|
+
|
|
36
|
+
def __post_init__(self):
|
|
37
|
+
"""验证规则身份与整数延迟,不猜测缺省等待时间。
|
|
38
|
+
|
|
39
|
+
参数: 无额外参数,读取冻结字段。
|
|
40
|
+
返回: None;纳秒规范为Python整数。
|
|
41
|
+
异常: TypeError/ValueError/OverflowError表示非法身份、范围或类型。
|
|
42
|
+
"""
|
|
43
|
+
if type(self.record_clock) is not bool:
|
|
44
|
+
raise TypeError('record_clock需要bool')
|
|
45
|
+
# 规则名称沿用简单标识符,数据集/会话/分组保留完整文本身份。
|
|
46
|
+
for field in ('rule_id', 'start_rule_id', 'response_rule_id'):
|
|
47
|
+
require_identifier(getattr(self, field), field)
|
|
48
|
+
for field in ('dataset_id', 'session_id', 'group_id'):
|
|
49
|
+
require_text(getattr(self, field), field)
|
|
50
|
+
# Python精确整数比较,拒绝负延迟、倒置范围及bool时间。
|
|
51
|
+
minimum = require_int64_ns(self.min_delay_ns, 'min_delay_ns')
|
|
52
|
+
maximum = require_int64_ns(self.max_delay_ns, 'max_delay_ns')
|
|
53
|
+
if not 0 <= minimum <= maximum:
|
|
54
|
+
raise ValueError('需要0 <= min_delay_ns <= max_delay_ns')
|
|
55
|
+
object.__setattr__(self, 'min_delay_ns', minimum)
|
|
56
|
+
object.__setattr__(self, 'max_delay_ns', maximum)
|
|
57
|
+
|
|
58
|
+
def check_event(self, event: Event, *, response: bool):
|
|
59
|
+
"""检查事件来自指定规则和当前会话,不按同名信号跨会话配对。
|
|
60
|
+
|
|
61
|
+
参数: event为既有Event;response明确表示A或B角色。
|
|
62
|
+
返回: None,保留原事件及其来源引用。
|
|
63
|
+
异常: TypeError为类型不符,ValueError为数据集/会话/规则不匹配。
|
|
64
|
+
"""
|
|
65
|
+
# Event自身已验证边界与来源归属,这里验证配对规则的范围。
|
|
66
|
+
if not isinstance(event, Event) or type(response) is not bool:
|
|
67
|
+
raise TypeError('需要Event及bool角色')
|
|
68
|
+
expected = self.response_rule_id if response else self.start_rule_id
|
|
69
|
+
if (event.rule.dataset_id, event.rule.session_id, event.rule.rule_id) != (self.dataset_id, self.session_id, expected):
|
|
70
|
+
raise ValueError('顺序事件的数据集、会话或规则不匹配')
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class SequenceTick:
|
|
75
|
+
"""保存同一时刻全部A/B及响应是否可判断的证据。
|
|
76
|
+
|
|
77
|
+
condition.state描述此刻之后的连续区间,point_state描述此刻本身;terminal的
|
|
78
|
+
人工连续UNKNOWN不污染真实末点。B出现时点证据必须已知。角色内重复ID拒绝,
|
|
79
|
+
事件顺序不参与业务配对,检测器会按稳定ID处理同刻并列事件。
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
condition: ConditionTick
|
|
83
|
+
starts: tuple[Event, ...] = ()
|
|
84
|
+
responses: tuple[Event, ...] = ()
|
|
85
|
+
|
|
86
|
+
def __post_init__(self):
|
|
87
|
+
"""验证原子时间组,避免把一半同刻事实先送入检测器。
|
|
88
|
+
|
|
89
|
+
参数: 无额外参数;condition及两个事件tuple。
|
|
90
|
+
返回: None,不排序或修改调用者对象。
|
|
91
|
+
异常: TypeError/ValueError为结构、时间、重复ID或观测矛盾。
|
|
92
|
+
"""
|
|
93
|
+
# 输入必须使用已校验的时间证据;每个事件按确认时刻参与顺序判断。
|
|
94
|
+
if not isinstance(self.condition, ConditionTick):
|
|
95
|
+
raise TypeError('condition需要ConditionTick')
|
|
96
|
+
for events in (self.starts, self.responses):
|
|
97
|
+
if not isinstance(events, tuple) or any(not isinstance(event, Event) for event in events):
|
|
98
|
+
raise TypeError('同刻事件需要Event tuple')
|
|
99
|
+
if any(event.confirmed_ns != self.condition.time_ns for event in events):
|
|
100
|
+
raise ValueError('事件确认时间与同刻组不同')
|
|
101
|
+
if len({event.event_id for event in events}) != len(events):
|
|
102
|
+
raise ValueError('同一角色内事件ID重复')
|
|
103
|
+
# 真实B不能同时被描述为响应条件无法判断,FALSE边沿则仍是已知证据。
|
|
104
|
+
if self.responses and self.condition.point_state is Truth.UNKNOWN:
|
|
105
|
+
raise ValueError('响应事件缺少已知的点观测证据')
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@dataclass(frozen=True)
|
|
109
|
+
class SequenceResult:
|
|
110
|
+
"""保存一个请求的最终处理结果,原请求和响应均可追溯。
|
|
111
|
+
|
|
112
|
+
matched表示观察到合格响应;no_response表示完整等待后可确定无响应;
|
|
113
|
+
indeterminate表示等待中缺观测或提前结束。observation_quality保留等待期间的未知原因,
|
|
114
|
+
即使最后匹配成功也不隐藏先前缺失。decided_ns为响应、deadline或提前EOF时刻。
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
result_id: str
|
|
118
|
+
rule: SequenceRule
|
|
119
|
+
request: Event
|
|
120
|
+
response: Event | None
|
|
121
|
+
status: str
|
|
122
|
+
decided_ns: int
|
|
123
|
+
delay_ns: int | None
|
|
124
|
+
observation_quality: Q
|
|
125
|
+
|
|
126
|
+
def __post_init__(self):
|
|
127
|
+
"""拒绝不可能的结果组合,防止把未知观测组装成正常超时。
|
|
128
|
+
|
|
129
|
+
参数: 无额外参数,读取结果字段。
|
|
130
|
+
返回: None;不生成事件或写结果文件。
|
|
131
|
+
异常: TypeError/ValueError/OverflowError为身份、时间或状态矛盾。
|
|
132
|
+
"""
|
|
133
|
+
# 结果保留强类型规则/原事件,范围检查与输入相同。
|
|
134
|
+
require_text(self.result_id, 'result_id')
|
|
135
|
+
if not isinstance(self.rule, SequenceRule) or not isinstance(self.observation_quality, Q):
|
|
136
|
+
raise TypeError('结果需要SequenceRule及QualityFlag')
|
|
137
|
+
self.rule.check_event(self.request, response=False)
|
|
138
|
+
decided = require_int64_ns(self.decided_ns, 'decided_ns')
|
|
139
|
+
object.__setattr__(self, 'decided_ns', decided)
|
|
140
|
+
deadline = None if self.rule.record_clock else checked_add_ns(self.request.confirmed_ns, self.rule.max_delay_ns)
|
|
141
|
+
if decided < self.request.confirmed_ns or deadline is not None and decided > deadline:
|
|
142
|
+
raise ValueError('决定时刻超出请求等待范围')
|
|
143
|
+
# 匹配必须在闭区间内;非匹配没有可用延迟值,不能用0冒充。
|
|
144
|
+
if self.status == 'matched':
|
|
145
|
+
self.rule.check_event(self.response, response=True)
|
|
146
|
+
delay = require_int64_ns(self.delay_ns, 'delay_ns')
|
|
147
|
+
object.__setattr__(self, 'delay_ns', delay)
|
|
148
|
+
if (decided != self.response.confirmed_ns
|
|
149
|
+
or not self.rule.record_clock and delay != decided-int(self.request.confirmed_ns)
|
|
150
|
+
or not self.rule.min_delay_ns <= delay <= self.rule.max_delay_ns):
|
|
151
|
+
raise ValueError('匹配时间或延迟与规则不符')
|
|
152
|
+
elif self.status in ('no_response', 'indeterminate'):
|
|
153
|
+
if self.response is not None or self.delay_ns is not None:
|
|
154
|
+
raise ValueError('未匹配结果不能包含响应或延迟')
|
|
155
|
+
if self.status == 'no_response' and (deadline is not None and decided != deadline or self.observation_quality != Q.NONE):
|
|
156
|
+
raise ValueError('no_response需要完整、已知的等待区间')
|
|
157
|
+
if self.status == 'indeterminate' and self.observation_quality == Q.NONE:
|
|
158
|
+
raise ValueError('indeterminate必须说明缺失观测原因')
|
|
159
|
+
else:
|
|
160
|
+
raise ValueError('未知顺序结果状态')
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""按时间组将请求与响应FIFO配对,区分未响应和无法确定。
|
|
2
|
+
|
|
3
|
+
输入为同一组完整有序的SequenceTick,输出为每次push新确定的SequenceResult。
|
|
4
|
+
检测器保存尚未决定的请求;返回的结果不再在内部累积。候选数有明确上限,
|
|
5
|
+
任何失败均封闭实例,调用者不能把部分结果宣告为完整任务成功。
|
|
6
|
+
响应可判断性来自既有ConditionTick的连续/点视图,TTL等边界必须由上游提供。
|
|
7
|
+
状态循环只依赖标准库,不冒称NumPy数组优化,不读取来源或写盘。
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# FIFO候选入队出队为常数时间;身份使用稳定内容,避免批次影响结果ID。
|
|
11
|
+
from collections import deque
|
|
12
|
+
from hashlib import sha256
|
|
13
|
+
from .binding import _identity
|
|
14
|
+
from .models import Interval
|
|
15
|
+
from .sequence import SequenceResult, SequenceRule, SequenceTick
|
|
16
|
+
from .temporal import ConditionTimeline, Event
|
|
17
|
+
from .temporal_reference import require_batch
|
|
18
|
+
from .types import QualityFlag as Q, Truth
|
|
19
|
+
from ..timebase.conversion import checked_add_ns
|
|
20
|
+
|
|
21
|
+
# 固定质量位前缀计数避免每次输入都遍历全部待响应请求。
|
|
22
|
+
_QUALITY_BITS = tuple(Q)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SequenceDetector:
|
|
26
|
+
"""维护一个dataset/session/group/rule的等待队列与观测状态。
|
|
27
|
+
|
|
28
|
+
候选按A时间和同刻稳定ID排序。B只消费最早的合格A;截止点先匹配再超时。
|
|
29
|
+
输入跨批连续、批尾不当EOF;每次push立即转交已决定结果。max_pending限制
|
|
30
|
+
同时存在的请求数量,不是整进程RAM保证,公共AnalysisRunner的SequenceRows另行计费。
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, rule: SequenceRule, start_ns: int, end_ns: int, *, max_pending: int = 65536):
|
|
34
|
+
"""建立独立状态,不从别的组或会话复制候选。
|
|
35
|
+
|
|
36
|
+
参数: rule;start_ns/end_ns为明确会话范围;max_pending为正原生整数。
|
|
37
|
+
返回: 新检测器,尚未消费任何时间组。
|
|
38
|
+
异常: TypeError/ValueError/OverflowError为规则、范围或容量错误。
|
|
39
|
+
"""
|
|
40
|
+
# 会话范围和容量在任何状态分配前校验。
|
|
41
|
+
if not isinstance(rule, SequenceRule) or type(max_pending) is not int or max_pending <= 0:
|
|
42
|
+
raise TypeError('需要SequenceRule及正int max_pending')
|
|
43
|
+
domain = Interval(start_ns, end_ns)
|
|
44
|
+
self.rule, self.start_ns, self.end_ns = rule, domain.start_ns, domain.end_ns
|
|
45
|
+
self.max_pending = max_pending
|
|
46
|
+
self._pending = deque()
|
|
47
|
+
self._counts = [0] * len(_QUALITY_BITS)
|
|
48
|
+
self._quality = Q.NONE
|
|
49
|
+
self._cursor = self.start_ns
|
|
50
|
+
self._last_time = None
|
|
51
|
+
self._record_elapsed = 0
|
|
52
|
+
self._ended = self._finished = self._failed = False
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def pending_count(self):
|
|
56
|
+
"""返回尚未决定的请求数量,不暴露可修改队列。
|
|
57
|
+
|
|
58
|
+
参数: 无。
|
|
59
|
+
返回: 非负整数;已结束或失败时为0。
|
|
60
|
+
异常: 无主动异常。
|
|
61
|
+
"""
|
|
62
|
+
# 不为查看数量复制全部事件。
|
|
63
|
+
return len(self._pending)
|
|
64
|
+
|
|
65
|
+
def _note(self, quality):
|
|
66
|
+
"""累计本段未知原因,供各请求按自己的起点查询。
|
|
67
|
+
|
|
68
|
+
参数: quality为已校验的质量位。
|
|
69
|
+
返回: None,更新固定长度计数器。
|
|
70
|
+
异常: 无主动异常;只由内部协议调用。
|
|
71
|
+
"""
|
|
72
|
+
# 每段最多检查固定9位,不按候选数做重复状态更新。
|
|
73
|
+
for index, bit in enumerate(_QUALITY_BITS):
|
|
74
|
+
if quality & bit:
|
|
75
|
+
self._counts[index] += 1
|
|
76
|
+
|
|
77
|
+
def _advance(self, time_ns):
|
|
78
|
+
"""结算上个时间组至指定时刻的连续观测,不推断额外响应。
|
|
79
|
+
|
|
80
|
+
参数: time_ns为不早于内部游标的时间。
|
|
81
|
+
返回: None;正长度未知区间计入质量,零长度不增加区间证据。
|
|
82
|
+
异常: 无主动异常,外层已验证时间顺序。
|
|
83
|
+
"""
|
|
84
|
+
# 同刻处理不伪造时长;此段状态由上个完整输入组确定。
|
|
85
|
+
if time_ns > self._cursor and self._quality != Q.NONE:
|
|
86
|
+
self._note(self._quality)
|
|
87
|
+
self._cursor = time_ns
|
|
88
|
+
|
|
89
|
+
def _result(self, pending, time_ns, response=None, *, early_end=False):
|
|
90
|
+
"""把一个请求的最终事实转换为稳定结果,保留原事件引用。
|
|
91
|
+
|
|
92
|
+
参数: pending含请求/质量快照/deadline;time_ns为决定时刻;response可空;early_end表示提前EOF。
|
|
93
|
+
返回: SequenceResult,匹配或有质量依据的未匹配结果。
|
|
94
|
+
异常: 模型校验或内存异常传播,不输出伪成功。
|
|
95
|
+
"""
|
|
96
|
+
# 只累积请求之后出现的未知位,之前的缺失不能污染新请求。
|
|
97
|
+
request, snapshot, _deadline = pending
|
|
98
|
+
quality = Q.NONE
|
|
99
|
+
for bit, before, after in zip(_QUALITY_BITS, snapshot, self._counts):
|
|
100
|
+
if after > before:
|
|
101
|
+
quality |= bit
|
|
102
|
+
if early_end:
|
|
103
|
+
quality |= Q.MISSING
|
|
104
|
+
status = 'matched' if response is not None else 'indeterminate' if quality != Q.NONE else 'no_response'
|
|
105
|
+
delay = None if response is None else (self._record_elapsed - _deadline + self.rule.max_delay_ns
|
|
106
|
+
if self.rule.record_clock else time_ns-int(request.confirmed_ns))
|
|
107
|
+
# 身份包括组、规则参数及原事件;批大小/候选容量不影响业务身份。
|
|
108
|
+
identity = (self.rule.dataset_id, self.rule.session_id, self.rule.group_id, self.rule.rule_id,
|
|
109
|
+
self.rule.start_rule_id, self.rule.response_rule_id, self.rule.min_delay_ns,
|
|
110
|
+
self.rule.max_delay_ns, request.event_id, int(request.confirmed_ns),
|
|
111
|
+
None if response is None else response.event_id, time_ns, status)
|
|
112
|
+
if self.rule.record_clock:
|
|
113
|
+
identity += ('record_clock', delay)
|
|
114
|
+
result_id = sha256(_identity(identity).encode('utf-8')).hexdigest()
|
|
115
|
+
return SequenceResult(result_id, self.rule, request, response, status, time_ns, delay, quality)
|
|
116
|
+
|
|
117
|
+
def _consume(self, tick, output, advance=None):
|
|
118
|
+
"""按先前截止点、同刻配对、同刻超时、EOF的顺序处理一组。
|
|
119
|
+
|
|
120
|
+
参数: tick为已检查的SequenceTick,output是本批局部输出列表。
|
|
121
|
+
返回: None;更新候选和游标,不存储已经转交的结果。
|
|
122
|
+
异常: MemoryError为候选上限;结果构造失败传播。
|
|
123
|
+
"""
|
|
124
|
+
# 上游允许NumPy整数;这里规范容器,避免后续运算/身份编码继承数组标量。
|
|
125
|
+
time = int(tick.condition.time_ns)
|
|
126
|
+
if self.rule.record_clock:
|
|
127
|
+
self._record_elapsed += advance
|
|
128
|
+
self._advance(time)
|
|
129
|
+
clock = self._record_elapsed if self.rule.record_clock else time
|
|
130
|
+
# 无新消息也在精确deadline结算;严格小于当前时间的候选已无匹配机会。
|
|
131
|
+
while self._pending and self._pending[0][2] < clock:
|
|
132
|
+
deadline = self._pending[0][2]
|
|
133
|
+
if not self.rule.record_clock:
|
|
134
|
+
self._advance(deadline)
|
|
135
|
+
output.append(self._result(self._pending.popleft(), time if self.rule.record_clock else deadline))
|
|
136
|
+
self._advance(time)
|
|
137
|
+
# 同刻A必须先收齐,B的输入顺序不能影响零延迟匹配。
|
|
138
|
+
if len(self._pending) + len(tick.starts) > self.max_pending:
|
|
139
|
+
raise MemoryError('sequence待响应请求超过max_pending')
|
|
140
|
+
for event in sorted(tick.starts, key=lambda item: item.event_id):
|
|
141
|
+
self._pending.append((event, tuple(self._counts), clock + self.rule.max_delay_ns
|
|
142
|
+
if self.rule.record_clock else checked_add_ns(time, self.rule.max_delay_ns)))
|
|
143
|
+
# 独立点UNKNOWN也不能被当作完整观察;terminal人工连续UNKNOWN不计入。
|
|
144
|
+
if tick.condition.point_state is Truth.UNKNOWN:
|
|
145
|
+
self._note(tick.condition.point_quality)
|
|
146
|
+
for response in sorted(tick.responses, key=lambda item: item.event_id):
|
|
147
|
+
# 所有请求使用同一min_delay;最老的还太新时,其余也不能匹配。
|
|
148
|
+
if self._pending and (clock - self._pending[0][2] + self.rule.max_delay_ns
|
|
149
|
+
if self.rule.record_clock else time-int(self._pending[0][0].confirmed_ns)) >= self.rule.min_delay_ns:
|
|
150
|
+
output.append(self._result(self._pending.popleft(), time, response))
|
|
151
|
+
# 只有同刻合格B都使用过后,才决定截止点仍剩余的请求。
|
|
152
|
+
while self._pending and self._pending[0][2] == clock:
|
|
153
|
+
output.append(self._result(self._pending.popleft(), time))
|
|
154
|
+
if tick.condition.terminal:
|
|
155
|
+
# 观察先结束不能证明设备未响应;不把deadline裁短成正常超时。
|
|
156
|
+
while self._pending:
|
|
157
|
+
output.append(self._result(self._pending.popleft(), time, early_end=True))
|
|
158
|
+
self._ended = True
|
|
159
|
+
self._quality = tick.condition.quality
|
|
160
|
+
self._last_time = time
|
|
161
|
+
|
|
162
|
+
def push(self, ticks: tuple[SequenceTick, ...], *, advances=None) -> tuple[SequenceResult, ...]:
|
|
163
|
+
"""消费一批完整时间组并仅返回本批确定的结果。
|
|
164
|
+
|
|
165
|
+
参数: ticks为有序tuple,可为空,首末与声明会话范围一致;advances仅规则
|
|
166
|
+
record_clock模式使用,保存一个必要累计计数而不存逐点时间对照。
|
|
167
|
+
返回: 新SequenceResult tuple;调用者负责消费,不在实例中重复保留。
|
|
168
|
+
异常: TypeError/ValueError/OverflowError为协议错误;MemoryError为容量不足。
|
|
169
|
+
副作用: 失败后释放候选并封闭实例,已转交的早先批次不能视为完整成功。
|
|
170
|
+
"""
|
|
171
|
+
# 失败或finish后的实例不允许继续使用,避免部分状态拼成另一个任务。
|
|
172
|
+
if self._failed or self._finished:
|
|
173
|
+
raise ValueError('sequence实例已失败或finish')
|
|
174
|
+
try:
|
|
175
|
+
if not isinstance(ticks, tuple) or any(not isinstance(tick, SequenceTick) for tick in ticks):
|
|
176
|
+
raise TypeError('push需要SequenceTick tuple')
|
|
177
|
+
require_batch(tuple(tick.condition for tick in ticks), self.start_ns, self.end_ns, self._last_time, self._ended)
|
|
178
|
+
from .temporal_clock import require_clock_advances
|
|
179
|
+
require_clock_advances(tuple(t.condition for t in ticks), advances, self.rule.record_clock, self._last_time)
|
|
180
|
+
# 整批先检查归属及deadline溢出,再推进;错误事件不能污染另一组。
|
|
181
|
+
for tick in ticks:
|
|
182
|
+
for event in tick.starts:
|
|
183
|
+
self.rule.check_event(event, response=False)
|
|
184
|
+
if not self.rule.record_clock:
|
|
185
|
+
checked_add_ns(event.confirmed_ns, self.rule.max_delay_ns)
|
|
186
|
+
for event in tick.responses:
|
|
187
|
+
self.rule.check_event(event, response=True)
|
|
188
|
+
output = []
|
|
189
|
+
for index, tick in enumerate(ticks):
|
|
190
|
+
self._consume(tick, output, None if advances is None else advances[index])
|
|
191
|
+
return tuple(output)
|
|
192
|
+
except Exception:
|
|
193
|
+
# 超限/坏输入均使任务失败,不能跳过该批继续生产正常结果。
|
|
194
|
+
self._failed = True
|
|
195
|
+
self._pending.clear()
|
|
196
|
+
raise
|
|
197
|
+
|
|
198
|
+
def finish(self):
|
|
199
|
+
"""确认已经收到真正EOF,不制造额外响应或超时。
|
|
200
|
+
|
|
201
|
+
参数: 无。
|
|
202
|
+
返回: None;结果已经由各次push转交。
|
|
203
|
+
异常: ValueError为缺EOF、失败或重复finish。
|
|
204
|
+
"""
|
|
205
|
+
# 与批尾区分,只有terminal之后可以声明消费完成。
|
|
206
|
+
if self._failed or self._finished or not self._ended:
|
|
207
|
+
raise ValueError('finish需要完整terminal且实例未关闭')
|
|
208
|
+
self._finished = True
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def pair_sequence(rule: SequenceRule, starts: tuple[Event, ...], responses: tuple[Event, ...],
|
|
212
|
+
timeline: ConditionTimeline, *, batch_rows: int = 65536, max_pending: int = 65536):
|
|
213
|
+
"""将既有事件与完整响应条件轴接到顺序核心,适合可控内存分析。
|
|
214
|
+
|
|
215
|
+
参数: rule;starts/responses为已确认事件tuple;timeline含全部条件变化、TTL及EOF;
|
|
216
|
+
batch_rows为每批完整时间组数,max_pending限制等待队列。
|
|
217
|
+
返回: SequenceResult tuple;只为此内存便利入口收集全部输出。
|
|
218
|
+
异常: TypeError/ValueError为类型/归属/缺失事件时刻;容量与时间溢出传播。
|
|
219
|
+
边界: 不补采样、解析文件或推断同步;大数据上层直接分批使用SequenceDetector。
|
|
220
|
+
"""
|
|
221
|
+
# 完整轴定义了可判断区间,来源范围不允许继承其他会话。
|
|
222
|
+
if not isinstance(timeline, ConditionTimeline) or type(batch_rows) is not int or batch_rows <= 0:
|
|
223
|
+
raise TypeError('需要ConditionTimeline及正int batch_rows')
|
|
224
|
+
detector = SequenceDetector(rule, timeline.start_ns, timeline.end_ns, max_pending=max_pending)
|
|
225
|
+
if any(ref.session_id != rule.session_id for ref in timeline.source_refs):
|
|
226
|
+
raise ValueError('响应观测来源不属于当前会话')
|
|
227
|
+
groups = ({}, {})
|
|
228
|
+
for events, group, response in ((starts, groups[0], False), (responses, groups[1], True)):
|
|
229
|
+
if not isinstance(events, tuple):
|
|
230
|
+
raise TypeError('完整事件输入需要tuple')
|
|
231
|
+
seen = set()
|
|
232
|
+
for event in events:
|
|
233
|
+
rule.check_event(event, response=response)
|
|
234
|
+
if event.event_id in seen:
|
|
235
|
+
raise ValueError('同一角色内事件ID重复')
|
|
236
|
+
seen.add(event.event_id)
|
|
237
|
+
group.setdefault(event.confirmed_ns, []).append(event)
|
|
238
|
+
# 事件时刻必须有明确条件点证据,不由本入口伪造TTL、点状态或EOF。
|
|
239
|
+
times = {tick.time_ns for tick in timeline.ticks}
|
|
240
|
+
if any(time not in times for group in groups for time in group):
|
|
241
|
+
raise ValueError('事件确认时刻不在响应条件时间轴中')
|
|
242
|
+
results = []
|
|
243
|
+
for offset in range(0, len(timeline.ticks), batch_rows):
|
|
244
|
+
ticks = tuple(SequenceTick(tick, tuple(groups[0].get(tick.time_ns, ())), tuple(groups[1].get(tick.time_ns, ())))
|
|
245
|
+
for tick in timeline.ticks[offset:offset+batch_rows])
|
|
246
|
+
results.extend(detector.push(ticks))
|
|
247
|
+
detector.finish()
|
|
248
|
+
return tuple(results)
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""把进入/退出条件转换为带迟滞和双向防抖的活动。
|
|
2
|
+
|
|
3
|
+
输入为同一会话、同一时刻的两组ConditionTick和非负纳秒防抖时长。
|
|
4
|
+
先结算此前已持续满足的条件,再处理当前更新;中间区间保持已确定状态,
|
|
5
|
+
UNKNOWN清除候选和此前状态。普通批次/文件边界不参与状态重置。
|
|
6
|
+
输出沿用活动Event,起点等于实际进入确认时刻;退出等待期间仍属于活动。
|
|
7
|
+
本模块仅实现有序状态转换,活动组装委托既有独立参考/NumPy检测器;
|
|
8
|
+
不声称状态循环是数值数组化,不读取文件,也不保存全量信号历史。
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass, replace
|
|
12
|
+
from .temporal import ConditionTick
|
|
13
|
+
from .temporal_reference import ReferenceTemporalDetector, require_batch, require_detector
|
|
14
|
+
from .types import QualityFlag as Q, Truth
|
|
15
|
+
from ..timebase.conversion import require_int64_ns
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class StabilitySpec:
|
|
20
|
+
"""保存进入和退出的独立等待时长;0表示条件满足即可转换。
|
|
21
|
+
|
|
22
|
+
状态属于运行实例,本声明不保存已报警标志或候选计时。
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
enter_ns: int = 0 # 进入条件连续满足多久才切换为活动。
|
|
26
|
+
exit_ns: int = 0 # 退出条件连续满足多久才切换为非活动。
|
|
27
|
+
track_duration: bool = False # 仅显式需求累计,普通规则不增加逐步统计。
|
|
28
|
+
|
|
29
|
+
def __post_init__(self):
|
|
30
|
+
"""拒绝负值、bool及超int64时长。参数: 无。返回: None。异常: 类型/范围错误。"""
|
|
31
|
+
if type(self.track_duration) is not bool:
|
|
32
|
+
raise TypeError('track_duration必须bool')
|
|
33
|
+
for name in ('enter_ns', 'exit_ns'):
|
|
34
|
+
value = require_int64_ns(getattr(self, name), name)
|
|
35
|
+
if value < 0:
|
|
36
|
+
raise ValueError('防抖时长不能为负')
|
|
37
|
+
object.__setattr__(self, name, value)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def invert_tick(tick):
|
|
41
|
+
"""取得普通防抖条件的退出证据,UNKNOWN保留原原因。
|
|
42
|
+
|
|
43
|
+
参数: tick为ConditionTick。返回: 点/连续状态分别取反的新证据。
|
|
44
|
+
异常: TypeError为非ConditionTick;不修改输入。
|
|
45
|
+
"""
|
|
46
|
+
if not isinstance(tick, ConditionTick):
|
|
47
|
+
raise TypeError('防抖条件需要ConditionTick')
|
|
48
|
+
opposite = {Truth.TRUE: Truth.FALSE, Truth.FALSE: Truth.TRUE, Truth.UNKNOWN: Truth.UNKNOWN}
|
|
49
|
+
return replace(tick, state=opposite[tick.state], point_state=opposite[tick.point_state])
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class StabilityDetector:
|
|
53
|
+
"""维护一个规则/会话的已确定状态、单个待转换候选及活动输出。
|
|
54
|
+
|
|
55
|
+
未知起点不猜未报警;两条件都假时保持前态,二者同时为真则报告配置冲突。
|
|
56
|
+
一个条件未知会中断活动;恢复时从未知开始重新确认,不能跨缺口累计防抖。
|
|
57
|
+
每次push可有多组,只有真实terminal才能finish;drain只取走输出。
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, rule, start_ns, end_ns, spec, source_refs=(), *, backend='reference', record_clock=False):
|
|
61
|
+
"""建立独立迟滞状态,复用零时长活动检测器。
|
|
62
|
+
|
|
63
|
+
参数: rule为condition_duration=0规则;start_ns/end_ns为会话域;spec为StabilitySpec;
|
|
64
|
+
source_refs为来源定位;backend为reference或numpy。
|
|
65
|
+
返回: None;初始化实例状态。异常: 规则、域、类型或后端错误。
|
|
66
|
+
"""
|
|
67
|
+
require_detector(rule, start_ns, end_ns, source_refs)
|
|
68
|
+
if not isinstance(spec, StabilitySpec) or rule.rule_type != 'condition_duration' or rule.minimum_duration_ns != 0:
|
|
69
|
+
raise ValueError('迟滞需要StabilitySpec及duration=0活动规则')
|
|
70
|
+
if backend not in ('reference', 'numpy'):
|
|
71
|
+
raise ValueError('迟滞后端需reference或numpy')
|
|
72
|
+
# 参考入口不导入NumPy;两者共用状态转换协议,活动核独立执行。
|
|
73
|
+
detector_type = ReferenceTemporalDetector
|
|
74
|
+
if backend == 'numpy':
|
|
75
|
+
from .temporal_numpy import NumpyTemporalDetector
|
|
76
|
+
detector_type = NumpyTemporalDetector
|
|
77
|
+
self.rule, self.spec = rule, spec
|
|
78
|
+
self.start_ns, self.end_ns = int(start_ns), int(end_ns)
|
|
79
|
+
self.state, self.quality = Truth.UNKNOWN, Q.MISSING
|
|
80
|
+
self.pending, self.deadline = None, None
|
|
81
|
+
self.record_clock, self.remaining = record_clock, 0
|
|
82
|
+
self.last_time, self.ended, self.finished = None, False, False
|
|
83
|
+
self._core = detector_type(rule, self.start_ns, self.end_ns, source_refs, record_clock=record_clock)
|
|
84
|
+
# 固定三个整数/一个状态,不保存逐点轨迹或额外扫描。UNKNOWN时间不会算成未报警。
|
|
85
|
+
self._duration_time, self._duration_state = self.start_ns, Truth.UNKNOWN
|
|
86
|
+
self._active_ns = self._known_ns = 0
|
|
87
|
+
|
|
88
|
+
def _push_core(self, tick, advance=None):
|
|
89
|
+
"""把已确认状态交给活动核,并按需累计左侧半开区间。
|
|
90
|
+
|
|
91
|
+
参数: tick为状态转换后的证据,advance为记录模式本组累计量。返回: 原活动核Event tuple。
|
|
92
|
+
异常: 原活动核校验错误;失败实例不能继续使用。
|
|
93
|
+
"""
|
|
94
|
+
if self.spec.track_duration:
|
|
95
|
+
duration = advance if self.record_clock else int(tick.time_ns) - self._duration_time
|
|
96
|
+
if self._duration_state is not Truth.UNKNOWN:
|
|
97
|
+
self._known_ns += duration
|
|
98
|
+
if self._duration_state is Truth.TRUE:
|
|
99
|
+
self._active_ns += duration
|
|
100
|
+
self._duration_time, self._duration_state = int(tick.time_ns), tick.state
|
|
101
|
+
return self._core.push((tick,), advances=(advance,) if self.record_clock else None)
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def duration_counts(self):
|
|
105
|
+
"""读取完成后的已知报警/已知观测整数纳秒。
|
|
106
|
+
|
|
107
|
+
参数: 无。返回: (active_ns,known_ns)或None(未请求统计)。
|
|
108
|
+
异常: ValueError表示请求统计但尚未正常finish。
|
|
109
|
+
"""
|
|
110
|
+
if not self.spec.track_duration:
|
|
111
|
+
return None
|
|
112
|
+
if not self.finished:
|
|
113
|
+
raise ValueError('迟滞累计只能在finish后读取')
|
|
114
|
+
return self._active_ns, self._known_ns
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def next_deadline_ns(self):
|
|
118
|
+
"""读取域内待转换时间。参数: 无。返回: int或None。异常: 无。
|
|
119
|
+
|
|
120
|
+
加法使用Python整数,域外结果不转换为int64或回绕。
|
|
121
|
+
"""
|
|
122
|
+
return self.deadline if not self.record_clock and self.deadline is not None and self.deadline <= self.end_ns else None
|
|
123
|
+
|
|
124
|
+
@staticmethod
|
|
125
|
+
def _target(enter, exit, quality):
|
|
126
|
+
"""区分明确方向、中间区间、未知与矛盾条件。
|
|
127
|
+
|
|
128
|
+
参数: enter/exit为Truth;quality为两个条件原因并集。
|
|
129
|
+
返回: Truth或None(中间区间)。异常: ValueError为同时满足进出条件。
|
|
130
|
+
"""
|
|
131
|
+
if enter is Truth.TRUE and exit is Truth.TRUE:
|
|
132
|
+
raise ValueError('迟滞进入和退出条件同时成立,请设置不重叠的条件')
|
|
133
|
+
if enter is Truth.UNKNOWN or exit is Truth.UNKNOWN:
|
|
134
|
+
return Truth.UNKNOWN
|
|
135
|
+
if enter is Truth.TRUE:
|
|
136
|
+
return Truth.TRUE
|
|
137
|
+
if exit is Truth.TRUE:
|
|
138
|
+
return Truth.FALSE
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
def _settle(self):
|
|
142
|
+
"""兑现已持续达到门槛的转换。参数: 无。返回: None。异常: 无。"""
|
|
143
|
+
self.state, self.quality = self.pending, Q.NONE
|
|
144
|
+
self.pending, self.deadline = None, None
|
|
145
|
+
self.remaining = 0
|
|
146
|
+
|
|
147
|
+
def _point(self, target, quality):
|
|
148
|
+
"""判断当前点状态,不把零长度点累计到等待时间。
|
|
149
|
+
|
|
150
|
+
参数: target为目标或None,quality为点原因。返回: (Truth,Q)。异常: 无。
|
|
151
|
+
"""
|
|
152
|
+
if target is Truth.UNKNOWN:
|
|
153
|
+
return Truth.UNKNOWN, quality
|
|
154
|
+
if target is not None:
|
|
155
|
+
delay = self.spec.enter_ns if target is Truth.TRUE else self.spec.exit_ns
|
|
156
|
+
if delay == 0:
|
|
157
|
+
return target, Q.NONE
|
|
158
|
+
return self.state, self.quality
|
|
159
|
+
|
|
160
|
+
def _continuous(self, target, quality, time_ns):
|
|
161
|
+
"""更新右侧持续状态和唯一候选,取消不连续的计时。
|
|
162
|
+
|
|
163
|
+
参数: target为目标/None;quality为原因;time_ns为当前纳秒。
|
|
164
|
+
返回: None,修改实例。异常: 无;超域deadline仅用于比较。
|
|
165
|
+
"""
|
|
166
|
+
if target is Truth.UNKNOWN:
|
|
167
|
+
self.state, self.quality = Truth.UNKNOWN, quality
|
|
168
|
+
self.pending, self.deadline = None, None
|
|
169
|
+
elif target is None or target is self.state:
|
|
170
|
+
# 返回中间区间仍保留已确认状态,但未满时长的进/出请求撤销。
|
|
171
|
+
self.pending, self.deadline = None, None
|
|
172
|
+
else:
|
|
173
|
+
delay = self.spec.enter_ns if target is Truth.TRUE else self.spec.exit_ns
|
|
174
|
+
if delay == 0:
|
|
175
|
+
self.state, self.quality = target, Q.NONE
|
|
176
|
+
self.pending, self.deadline = None, None
|
|
177
|
+
elif self.pending is not target:
|
|
178
|
+
self.pending = target
|
|
179
|
+
self.deadline = None if self.record_clock else time_ns + delay
|
|
180
|
+
self.remaining = delay
|
|
181
|
+
|
|
182
|
+
def push(self, ticks, exit_ticks=None, *, advances=None):
|
|
183
|
+
"""推进成对条件组,可在两次实际更新之间精确兑现防抖计时。
|
|
184
|
+
|
|
185
|
+
参数: ticks为进入条件tuple;exit_ticks为同刻退出tuple,省略时为not进入;
|
|
186
|
+
advances仅record_clock模式传入本组周期增量,无驱动边界为0。
|
|
187
|
+
返回: 本次新Event tuple;活动起点为进入转换时刻,不回填等待区间。
|
|
188
|
+
异常: 输入/顺序/同刻冲突/finish后推进错误;发生错误后调用方应丢弃实例。
|
|
189
|
+
"""
|
|
190
|
+
if self.finished:
|
|
191
|
+
raise ValueError('迟滞检测器已finish')
|
|
192
|
+
require_batch(ticks, self.start_ns, self.end_ns, self.last_time, self.ended)
|
|
193
|
+
from .temporal_clock import require_clock_advances
|
|
194
|
+
require_clock_advances(ticks, advances, self.record_clock, self.last_time)
|
|
195
|
+
if exit_ticks is None:
|
|
196
|
+
exit_ticks = tuple(invert_tick(tick) for tick in ticks)
|
|
197
|
+
require_batch(exit_ticks, self.start_ns, self.end_ns, self.last_time, self.ended)
|
|
198
|
+
if len(ticks) != len(exit_ticks) or any(a.time_ns != b.time_ns for a, b in zip(ticks, exit_ticks)):
|
|
199
|
+
raise ValueError('迟滞两个条件必须在相同的完整时间组求值')
|
|
200
|
+
output = []
|
|
201
|
+
for index, (enter, exit) in enumerate(zip(ticks, exit_ticks)):
|
|
202
|
+
time_ns = int(enter.time_ns)
|
|
203
|
+
advance = None if advances is None else advances[index]
|
|
204
|
+
# 先结算前一个半开区间,即使当前点恰好变假或失效也不抹去已得时长。
|
|
205
|
+
if self.record_clock and self.pending is not None:
|
|
206
|
+
self.remaining = max(0, self.remaining - advance)
|
|
207
|
+
settled = (self.pending is not None and self.remaining == 0 if self.record_clock
|
|
208
|
+
else self.deadline is not None and self.deadline <= time_ns)
|
|
209
|
+
if settled:
|
|
210
|
+
deadline = time_ns if self.record_clock else self.deadline
|
|
211
|
+
self._settle()
|
|
212
|
+
if deadline < time_ns:
|
|
213
|
+
output.extend(self._push_core(ConditionTick(deadline, self.state)))
|
|
214
|
+
diagnostic = enter.diagnostic_quality | exit.diagnostic_quality | enter.quality | exit.quality
|
|
215
|
+
diagnostic |= enter.point_quality | exit.point_quality
|
|
216
|
+
point_quality = enter.point_quality | exit.point_quality
|
|
217
|
+
point_target = self._target(enter.point_state, exit.point_state, point_quality)
|
|
218
|
+
point_state, point_quality = self._point(point_target, point_quality)
|
|
219
|
+
# 退出等待已在左侧完整满足;同刻EOF/失效不能把这个已知退出改成缺观测。
|
|
220
|
+
if settled and self.state is Truth.FALSE and point_state is Truth.UNKNOWN:
|
|
221
|
+
point_state, point_quality = Truth.FALSE, Q.NONE
|
|
222
|
+
if enter.terminal:
|
|
223
|
+
# 末点能解除旧活动,但不能开始新的正长度活动或假造末点后的保持。
|
|
224
|
+
state, quality = Truth.UNKNOWN, enter.quality | exit.quality | Q.MISSING
|
|
225
|
+
self.pending, self.deadline = None, None
|
|
226
|
+
else:
|
|
227
|
+
quality = enter.quality | exit.quality
|
|
228
|
+
target = self._target(enter.state, exit.state, quality)
|
|
229
|
+
self._continuous(target, quality, time_ns)
|
|
230
|
+
state, quality = self.state, self.quality
|
|
231
|
+
tick = ConditionTick(time_ns, state, quality,
|
|
232
|
+
actual_update=enter.actual_update or exit.actual_update or settled,
|
|
233
|
+
observation_end=enter.observation_end or exit.observation_end, terminal=enter.terminal,
|
|
234
|
+
point_state=point_state, point_quality=point_quality,
|
|
235
|
+
actual_unknown=(enter.actual_unknown or exit.actual_unknown) and point_state is Truth.UNKNOWN,
|
|
236
|
+
diagnostic_quality=diagnostic)
|
|
237
|
+
output.extend(self._push_core(tick, advance))
|
|
238
|
+
self.last_time, self.ended = time_ns, enter.terminal
|
|
239
|
+
return tuple(output)
|
|
240
|
+
|
|
241
|
+
def drain_events(self):
|
|
242
|
+
"""取走最终活动而不清计时。参数: 无。返回: Event tuple。异常: 分配错误。"""
|
|
243
|
+
return self._core.drain_events()
|
|
244
|
+
|
|
245
|
+
def finish(self):
|
|
246
|
+
"""只在真实会话末尾封闭。参数: 无。返回: 未取走活动。异常: 缺terminal/重复。"""
|
|
247
|
+
result = self._core.finish()
|
|
248
|
+
self.finished = True
|
|
249
|
+
return result
|