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,230 @@
|
|
|
1
|
+
"""在新目标旁发布导入原文与报告,成功转换的计划最后才安装。
|
|
2
|
+
|
|
3
|
+
输入是LegacyImportResult和.json目标,可显式附INI/mapping源路径;输出固定
|
|
4
|
+
LegacyImportFiles。三个文件先写入同父UUID临时文件,flush及实际close成功后,
|
|
5
|
+
按原文、报告、计划顺序用Windows不覆盖rename安装。转换失败只安装前两件,
|
|
6
|
+
报告status仍表示转换结果,不能据此宣称分析已运行或数据已经验证。
|
|
7
|
+
|
|
8
|
+
目标、解析后的RefProjects边界和源路径冲突在创建目录前检查;安装仍以真实
|
|
9
|
+
no-replace操作防竞态,不依赖预先exists检查或os.replace。只声明已验证的
|
|
10
|
+
Windows文件安装语义,其他平台在写入前明确拒绝。目录本身不作跨文件原子
|
|
11
|
+
事务,已安装sidecar在后续失败时保留;计划是最后的提交点。
|
|
12
|
+
|
|
13
|
+
小owner仅持本次真实FD和已独占创建的三个UUID临时文件。失败不吞原取消、
|
|
14
|
+
MemoryError或I/O异常;清理副错附note,异常上的
|
|
15
|
+
legacy_import_publication_cleanup_owner.close()可重试关闭并移除自有临时文件。
|
|
16
|
+
不递归删除,不删除已发布sidecar、用户目标或原配置,也不配置日志或运行旧链。
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
from hashlib import sha256
|
|
21
|
+
import json
|
|
22
|
+
import os
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from types import MappingProxyType
|
|
25
|
+
from uuid import uuid4
|
|
26
|
+
|
|
27
|
+
from ..planning import AnalysisPlan
|
|
28
|
+
from .models import LegacyImportReport, LegacyImportResult
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class LegacyImportFiles:
|
|
33
|
+
"""保存词法绝对发布路径;plan为None时只有原文和失败转换报告。"""
|
|
34
|
+
|
|
35
|
+
plan: Path | None
|
|
36
|
+
original: Path
|
|
37
|
+
report: Path
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _mapping_json(value):
|
|
41
|
+
"""仅展开计划固定MappingProxy,不反射任意对象或调用其序列化方法。
|
|
42
|
+
|
|
43
|
+
参数: value为JSON编码器遇到的对象。返回: 原生dict副本。
|
|
44
|
+
异常: TypeError为非MappingProxyType;MemoryError保持原生异常。
|
|
45
|
+
"""
|
|
46
|
+
if type(value) is MappingProxyType:
|
|
47
|
+
return dict(value)
|
|
48
|
+
raise TypeError('导入计划JSON仅允许固定MappingProxyType扩展')
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _require_result(result):
|
|
52
|
+
"""核公开转换结果与原bytes/计划身份一致,拒绝失败结果携带部分计划。
|
|
53
|
+
|
|
54
|
+
参数: result为LegacyImportResult。返回: None。
|
|
55
|
+
异常: TypeError为非固定模型;ValueError为状态、原SHA或计划身份不一致。
|
|
56
|
+
"""
|
|
57
|
+
if (type(result) is not LegacyImportResult or type(result.report) is not LegacyImportReport
|
|
58
|
+
or type(result.original_ini) is not bytes):
|
|
59
|
+
raise TypeError('发布需要LegacyImportResult、LegacyImportReport及原生INI bytes')
|
|
60
|
+
report = result.report
|
|
61
|
+
if report.source_sha256 != sha256(result.original_ini).hexdigest():
|
|
62
|
+
raise ValueError('发布原INI bytes与转换报告SHA不一致')
|
|
63
|
+
if result.plan is None:
|
|
64
|
+
if report.status != 'failed' or report.plan_identity is not None:
|
|
65
|
+
raise ValueError('无计划时只允许失败转换报告,plan_identity必须为None')
|
|
66
|
+
elif (type(result.plan) is not AnalysisPlan or report.status != 'success'
|
|
67
|
+
or report.plan_identity != result.plan.identity):
|
|
68
|
+
raise ValueError('成功转换报告必须关联同一完整AnalysisPlan')
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _targets(output_path, source_paths):
|
|
72
|
+
"""先核词法目标、实际保护边界及源冲突,不创建任何输出。
|
|
73
|
+
|
|
74
|
+
参数: output_path为.json文件Path/str;source_paths为INI及mapping的Path/str tuple。
|
|
75
|
+
返回: (计划、原文、报告)三个绝对Path,按计划路径派生固定后缀。
|
|
76
|
+
异常: TypeError为路径容器;ValueError为后缀/Ref/源冲突;FileExistsError为任一已有目标。
|
|
77
|
+
"""
|
|
78
|
+
if not isinstance(output_path, (Path, str)) or type(source_paths) is not tuple:
|
|
79
|
+
raise TypeError('output_path需要Path/str,source_paths需要tuple')
|
|
80
|
+
if any(not isinstance(path, (Path, str)) for path in source_paths):
|
|
81
|
+
raise TypeError('source_paths每项需要Path/str')
|
|
82
|
+
target = Path(output_path).absolute()
|
|
83
|
+
if target.suffix != '.json':
|
|
84
|
+
raise ValueError('导入计划输出必须使用.json后缀')
|
|
85
|
+
targets = (target, target.with_name(target.stem + '.original.ini'),
|
|
86
|
+
target.with_name(target.stem + '.migration-report.json'))
|
|
87
|
+
# resolve仅用于真实位置核对;安装仍使用原词法路径,已有悬空symlink也必须拒绝。
|
|
88
|
+
project = Path(__file__).absolute().parents[3]
|
|
89
|
+
protected = (project / 'RefProjects').resolve()
|
|
90
|
+
resolved = tuple(path.resolve() for path in targets)
|
|
91
|
+
sources = tuple(Path(path).resolve() for path in source_paths)
|
|
92
|
+
for path, actual in zip(targets, resolved):
|
|
93
|
+
if actual.is_relative_to(protected) or any(part.casefold() == 'refprojects' for part in actual.parts):
|
|
94
|
+
raise ValueError('导入输出禁止位于RefProjects')
|
|
95
|
+
if actual in sources:
|
|
96
|
+
raise ValueError('导入输出不能与原INI或mapping配置同路径')
|
|
97
|
+
try:
|
|
98
|
+
path.lstat()
|
|
99
|
+
except FileNotFoundError:
|
|
100
|
+
continue
|
|
101
|
+
raise FileExistsError('导入目标已存在,禁止覆盖:' + str(path))
|
|
102
|
+
return targets
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class _PublicationOwner:
|
|
106
|
+
"""仅持本次独占临时文件及一个真实FD,不接管源文件或已安装目标。"""
|
|
107
|
+
|
|
108
|
+
def __init__(self, targets):
|
|
109
|
+
"""先安装全部实际责任槽,尚不创建临时文件。
|
|
110
|
+
|
|
111
|
+
参数: targets为三个已检查的绝对Path。返回: 新owner。异常: 原内存/UUID错误传播。
|
|
112
|
+
"""
|
|
113
|
+
self._targets = targets
|
|
114
|
+
self._token = uuid4().hex
|
|
115
|
+
self._temporaries = [None, None, None]
|
|
116
|
+
self._handle = self._opening_path = self._opening_index = None
|
|
117
|
+
self.closed = False
|
|
118
|
+
|
|
119
|
+
def _close_handle(self):
|
|
120
|
+
"""关闭当前真实FD,失败时保持同一对象及临时路径可恢复。
|
|
121
|
+
|
|
122
|
+
参数: 无。返回: None。异常: 原close错误;未真实关闭则OSError。
|
|
123
|
+
"""
|
|
124
|
+
if self._handle is not None:
|
|
125
|
+
# FD已返回即证明本次独占创建,补齐open返回与临时槽安装之间的责任窗口。
|
|
126
|
+
if self._opening_path is not None:
|
|
127
|
+
self._temporaries[self._opening_index] = self._opening_path
|
|
128
|
+
self._handle.close()
|
|
129
|
+
if not self._handle.closed:
|
|
130
|
+
raise OSError('导入临时文件FD尚未关闭')
|
|
131
|
+
self._handle = None
|
|
132
|
+
self._opening_path = self._opening_index = None
|
|
133
|
+
|
|
134
|
+
def write(self, index, value, *, original=False):
|
|
135
|
+
"""独占创建一个临时文件,写完flush且真实close后才允许安装。
|
|
136
|
+
|
|
137
|
+
参数: index选择原文/报告/计划槽;value为原bytes或固定JSON树;original选择二进制原文。
|
|
138
|
+
返回: None。异常: 原open/write/flush/close/JSON/内存或取消错误,不隐式重试写入。
|
|
139
|
+
"""
|
|
140
|
+
target = self._targets[index]
|
|
141
|
+
temporary = target.parent / ('.' + target.name + '.import-' + self._token + '.tmp')
|
|
142
|
+
self._opening_path, self._opening_index = temporary, index
|
|
143
|
+
# 只在open成功返回真实FD后登记文件所有权;独占失败不能删除碰巧已有的UUID目标。
|
|
144
|
+
if original:
|
|
145
|
+
self._handle = temporary.open('xb')
|
|
146
|
+
else:
|
|
147
|
+
self._handle = temporary.open('x', encoding='utf-8', newline='\n')
|
|
148
|
+
self._temporaries[index] = temporary
|
|
149
|
+
if original:
|
|
150
|
+
if self._handle.write(value) != len(value):
|
|
151
|
+
raise OSError('原INI临时文件写入不完整')
|
|
152
|
+
else:
|
|
153
|
+
# 计划参数对象的声明顺序参与MessageDeclarations身份;不能为排版排序改写。
|
|
154
|
+
# 报告不承担该声明语义,仍沿原规范键序;公式AST和核心身份算法均不改。
|
|
155
|
+
json.dump(value, self._handle, ensure_ascii=False, allow_nan=False,
|
|
156
|
+
sort_keys=index != 0, indent=2, default=_mapping_json)
|
|
157
|
+
self._handle.write('\n')
|
|
158
|
+
self._handle.flush()
|
|
159
|
+
self._close_handle()
|
|
160
|
+
|
|
161
|
+
def install(self, index):
|
|
162
|
+
"""用Windows真实不覆盖rename安装,成功后只撤本临时槽。
|
|
163
|
+
|
|
164
|
+
参数: index为已完整关闭的临时文件槽。返回: None。
|
|
165
|
+
异常: 原rename错误;不能用exists预检查取代最终no-replace。
|
|
166
|
+
"""
|
|
167
|
+
os.rename(self._temporaries[index], self._targets[index])
|
|
168
|
+
# rename已是提交事实,之后不写状态文件、不触碰目标或执行额外文件清理。
|
|
169
|
+
self._temporaries[index] = None
|
|
170
|
+
|
|
171
|
+
def close(self):
|
|
172
|
+
"""可重试关闭FD并逐个删除自有UUID临时文件,保留全部已安装sidecar。
|
|
173
|
+
|
|
174
|
+
参数: 无。返回: None,成功后幂等。异常: 原close/unlink错误附同一最高owner。
|
|
175
|
+
"""
|
|
176
|
+
if self.closed:
|
|
177
|
+
return
|
|
178
|
+
try:
|
|
179
|
+
self._close_handle()
|
|
180
|
+
for index, temporary in enumerate(self._temporaries):
|
|
181
|
+
if temporary is not None:
|
|
182
|
+
try:
|
|
183
|
+
temporary.unlink()
|
|
184
|
+
except FileNotFoundError:
|
|
185
|
+
pass
|
|
186
|
+
self._temporaries[index] = None
|
|
187
|
+
self.closed = True
|
|
188
|
+
except BaseException as error:
|
|
189
|
+
error.legacy_import_publication_cleanup_owner = self
|
|
190
|
+
raise
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def write_legacy_import(result: LegacyImportResult, output_path, *, source_paths=()) -> LegacyImportFiles:
|
|
194
|
+
"""发布原配置及转换报告,只有完整成功转换才在最后安装计划。
|
|
195
|
+
|
|
196
|
+
参数: result为固定转换结果;output_path为新.json目标;source_paths可显式提供
|
|
197
|
+
原INI/mapping路径tuple供CLI防止同源别名冲突。
|
|
198
|
+
返回: LegacyImportFiles,均为绝对Path,转换失败时plan=None。
|
|
199
|
+
异常: 类型/配置错误、已有目标、Ref边界及系统I/O错误保持原异常;非Windows为
|
|
200
|
+
NotImplementedError。KI/MemoryError原样;清理副错仅附note,最高恢复owner留在原错上。
|
|
201
|
+
副作用: 只创建目标父目录和三个自有临时文件;失败可保已装sidecar,绝不覆盖或删用户文件。
|
|
202
|
+
"""
|
|
203
|
+
_require_result(result)
|
|
204
|
+
targets = _targets(output_path, source_paths)
|
|
205
|
+
if os.name != 'nt':
|
|
206
|
+
raise NotImplementedError('导入文件发布目前只验证Windows不覆盖安装')
|
|
207
|
+
files = LegacyImportFiles(targets[0] if result.plan is not None else None, targets[1], targets[2])
|
|
208
|
+
owner = _PublicationOwner(targets)
|
|
209
|
+
try:
|
|
210
|
+
# 所有内容先写完并关闭;有计划时也只在两个sidecar安装成功之后提交计划。
|
|
211
|
+
targets[0].parent.mkdir(parents=True, exist_ok=True)
|
|
212
|
+
owner.write(1, result.original_ini, original=True)
|
|
213
|
+
owner.write(2, result.report.to_dict())
|
|
214
|
+
if result.plan is not None:
|
|
215
|
+
owner.write(0, result.plan.raw_config)
|
|
216
|
+
owner.install(1)
|
|
217
|
+
owner.install(2)
|
|
218
|
+
if result.plan is not None:
|
|
219
|
+
owner.install(0)
|
|
220
|
+
# 所有临时槽已由rename撤销,无需在提交点后再执行可能失败的I/O。
|
|
221
|
+
owner.closed = True
|
|
222
|
+
return files
|
|
223
|
+
except BaseException as error:
|
|
224
|
+
error.legacy_import_publication_cleanup_owner = owner
|
|
225
|
+
try:
|
|
226
|
+
owner.close()
|
|
227
|
+
except BaseException as cleanup:
|
|
228
|
+
error.add_note('导入发布清理附加失败:' + type(cleanup).__name__
|
|
229
|
+
+ ';调用legacy_import_publication_cleanup_owner.close()恢复')
|
|
230
|
+
raise
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""把受支持Sclicer段转换为新活动或固定窗口,完整报告边界差异。
|
|
2
|
+
|
|
3
|
+
输入是已定位INI、显式mapping及本次独立分析字典;输出只修改该新字典的
|
|
4
|
+
rules/windows并追加字段去向和警告。不执行旧触发器、eval或来源I/O。
|
|
5
|
+
single的post只作为exit_delay,start_only的post不再次延长固定duration。
|
|
6
|
+
显式sclicer_slope使用完整window_delta和触发点周围的pre/post窗口,差异写入报告。
|
|
7
|
+
显式sclicer_start_end还要求mapping确认新开始/结束含义,旧post不附加。
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import ast
|
|
11
|
+
from decimal import Decimal, InvalidOperation
|
|
12
|
+
|
|
13
|
+
from ..timebase import parse_duration
|
|
14
|
+
from .ini import field_path, locate, mark, problem
|
|
15
|
+
from .models import LegacyImportIssue
|
|
16
|
+
from .slope import slope_rule
|
|
17
|
+
from .start_end import start_end_options
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _ini_problem(fields, section, key, code, message, *, headers=None):
|
|
21
|
+
"""附原字段行列后拒绝,缺失字段回退到原段头。
|
|
22
|
+
|
|
23
|
+
参数: fields/section/key为字段定位,code/message为原因;headers为可选原段行号。
|
|
24
|
+
返回: 无。异常: ImportProblem;不为缺失字段编造一个不存在的字段行。
|
|
25
|
+
"""
|
|
26
|
+
line, column = locate(fields, section, key)
|
|
27
|
+
if line is None and headers is not None:
|
|
28
|
+
line, column = headers[section], 1
|
|
29
|
+
problem(code, 'ini', field_path(section, key), message, line, column)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _seconds(parser, fields, section, key, default, *, positive=False):
|
|
33
|
+
"""把旧秒数转换为显式精确时长,不猜工程参数或接受NaN。
|
|
34
|
+
|
|
35
|
+
参数: parser/fields/section/key为原定位;default为已审旧默认;positive限定正值。
|
|
36
|
+
返回: 带s的时长文本。异常: ImportProblem为非法或不能精确表示的时长。
|
|
37
|
+
"""
|
|
38
|
+
value = parser.get(section, key, fallback=default, raw=True)
|
|
39
|
+
try:
|
|
40
|
+
number = Decimal(value)
|
|
41
|
+
if not number.is_finite() or number < 0 or positive and number == 0:
|
|
42
|
+
raise ValueError('时长必须有限且非负,固定窗口须大于零')
|
|
43
|
+
# 保留紧凑指数表示;由有界时间解析器检查范围,不能先展开巨量零。
|
|
44
|
+
result = str(number) + 's'
|
|
45
|
+
parse_duration(result)
|
|
46
|
+
except (InvalidOperation, ValueError, OverflowError) as error:
|
|
47
|
+
_ini_problem(fields, section, key, 'invalid_duration', str(error))
|
|
48
|
+
return result
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _boolean(parser, fields, section, key, default):
|
|
52
|
+
"""沿ConfigParser旧布尔词表读取开关;参数: 原定位和默认;返回: bool;异常: ImportProblem。"""
|
|
53
|
+
try:
|
|
54
|
+
return parser.getboolean(section, key, fallback=default)
|
|
55
|
+
except ValueError as error:
|
|
56
|
+
_ini_problem(fields, section, key, 'invalid_boolean', str(error))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class _AliasTransformer(ast.NodeTransformer):
|
|
60
|
+
"""只替换AST Name,保字符串literal、原大小写和运算结合顺序。"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, aliases, fields, section, key):
|
|
63
|
+
"""保本次显式别名表;参数: 别名及原表达式定位;返回: None;异常: 无。"""
|
|
64
|
+
self.aliases, self.fields, self.section, self.key = aliases, fields, section, key
|
|
65
|
+
|
|
66
|
+
def visit_Name(self, node):
|
|
67
|
+
"""替换一个字段引用;参数: Name节点;返回: 新Name;异常: ImportProblem为缺映射。"""
|
|
68
|
+
if node.id not in self.aliases:
|
|
69
|
+
_ini_problem(self.fields, self.section, self.key, 'missing_alias', '缺少原名称的显式alias:' + node.id)
|
|
70
|
+
return ast.copy_location(ast.Name(id=self.aliases[node.id], ctx=ast.Load()), node)
|
|
71
|
+
|
|
72
|
+
def visit_Call(self, node):
|
|
73
|
+
"""仅保现有DSL注册函数,不把函数名当字段重写。
|
|
74
|
+
|
|
75
|
+
参数: Call节点。返回: 原节点和改写后的参数。异常: ImportProblem为任意调用。
|
|
76
|
+
"""
|
|
77
|
+
if not isinstance(node.func, ast.Name) or node.func.id not in ('abs', 'isclose'):
|
|
78
|
+
_ini_problem(self.fields, self.section, self.key, 'unsafe_expression', '禁止任意调用或属性调用')
|
|
79
|
+
node.args = [self.visit(item) for item in node.args]
|
|
80
|
+
node.keywords = [self.visit(item) for item in node.keywords]
|
|
81
|
+
return node
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _expression(text, aliases, fields, section, key):
|
|
85
|
+
"""解析白名单AST并替换Name,最终类型/单位仍交公开计划检查。
|
|
86
|
+
|
|
87
|
+
参数: 原表达式、显式aliases和原位置。返回: 新DSL文本。
|
|
88
|
+
异常: ImportProblem为危险语法、旧slope或缺映射;取消和资源错误不吞。
|
|
89
|
+
"""
|
|
90
|
+
if text.lstrip().startswith(('_slope_', '_slope2_')):
|
|
91
|
+
_ini_problem(fields, section, key, 'unsupported_slope', 'M2不支持slope/slope2配置')
|
|
92
|
+
try:
|
|
93
|
+
tree = ast.parse(text, mode='eval')
|
|
94
|
+
except SyntaxError as error:
|
|
95
|
+
_ini_problem(fields, section, key, 'invalid_expression', str(error))
|
|
96
|
+
allowed = (ast.Expression, ast.Constant, ast.Name, ast.Load, ast.BinOp, ast.UnaryOp,
|
|
97
|
+
ast.BoolOp, ast.Compare, ast.Call, ast.keyword, ast.Add, ast.Sub, ast.Mult,
|
|
98
|
+
ast.Div, ast.UAdd, ast.USub, ast.Not, ast.And, ast.Or, ast.Eq, ast.NotEq,
|
|
99
|
+
ast.Lt, ast.LtE, ast.Gt, ast.GtE)
|
|
100
|
+
for node in ast.walk(tree):
|
|
101
|
+
if not isinstance(node, allowed):
|
|
102
|
+
_ini_problem(fields, section, key, 'unsafe_expression', '不支持AST节点:' + type(node).__name__)
|
|
103
|
+
# 转换只作用本次新AST;字符串和包含另一名称的标识符不会误替换。
|
|
104
|
+
tree = _AliasTransformer(aliases, fields, section, key).visit(tree)
|
|
105
|
+
return ast.unparse(ast.fix_missing_locations(tree))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def convert_sclicer(parser, headers, mapping, analysis, fields, issues, mode):
|
|
109
|
+
"""整份转换显式选择的Sclicer模式,遇一项不支持便拒绝整个计划。
|
|
110
|
+
|
|
111
|
+
参数: 已解析INI/头部定位、mapping、新analysis、局部报告列表和公开mode。
|
|
112
|
+
返回: None;新rules/windows按原段序填充。异常: ImportProblem为语义问题。
|
|
113
|
+
"""
|
|
114
|
+
triggers = [name for name in parser.sections() if name.startswith('TRIGGER_')]
|
|
115
|
+
for section in parser.sections():
|
|
116
|
+
if section not in ('INPUT', 'OUTPUT') and section not in triggers:
|
|
117
|
+
problem('unsupported_section', 'ini', '[' + section + ']', '未知或未支持的INI段', headers[section], 1)
|
|
118
|
+
if not triggers:
|
|
119
|
+
problem('missing_trigger', 'ini', '$', '至少需要一个TRIGGER_段')
|
|
120
|
+
if set(mapping['sections']) != set(triggers):
|
|
121
|
+
problem('section_mapping_mismatch', 'mapping', '$.sections', 'sections必须恰好映射全部原TRIGGER_段')
|
|
122
|
+
# I/O必须显式来自mapping;保原字段并报告ASC显示项与新输出的差异。
|
|
123
|
+
catalog = {'INPUT': ('msg_path', 'dbc_path'),
|
|
124
|
+
'OUTPUT': ('slice', 'log', 'format', 'merge', 'utc', 'msg_path')}
|
|
125
|
+
for section, keys in catalog.items():
|
|
126
|
+
if not parser.has_section(section):
|
|
127
|
+
continue
|
|
128
|
+
for key in parser.options(section):
|
|
129
|
+
if key not in keys:
|
|
130
|
+
_ini_problem(fields, section, key, 'unknown_option', '未知I/O字段')
|
|
131
|
+
mark(fields, section, key, '$.analysis.sources' if section == 'INPUT' else '$.analysis.outputs',
|
|
132
|
+
'replaced', '旧I/O由explicit_mapping完整替代;原字段仅保审计,不执行旧输出')
|
|
133
|
+
if parser.has_section('OUTPUT'):
|
|
134
|
+
if not _boolean(parser, fields, 'OUTPUT', 'slice', True):
|
|
135
|
+
_ini_problem(fields, 'OUTPUT', 'slice', 'unsupported_slice_disabled', 'slice=false不能转换为分析窗口成功')
|
|
136
|
+
if _boolean(parser, fields, 'OUTPUT', 'merge', False):
|
|
137
|
+
_ini_problem(fields, 'OUTPUT', 'merge', 'unsupported_merge', '旧merge=true未支持')
|
|
138
|
+
_boolean(parser, fields, 'OUTPUT', 'log', True)
|
|
139
|
+
if parser.get('OUTPUT', 'format', fallback='asc').lower() not in ('asc', 'blf'):
|
|
140
|
+
_ini_problem(fields, 'OUTPUT', 'format', 'unsupported_output_format', '未知旧原始输出格式')
|
|
141
|
+
try:
|
|
142
|
+
parser.getint('OUTPUT', 'utc', fallback=0)
|
|
143
|
+
except ValueError as error:
|
|
144
|
+
_ini_problem(fields, 'OUTPUT', 'utc', 'invalid_utc', str(error))
|
|
145
|
+
issues.append(LegacyImportIssue('explicit_io_mapping', 'mapping', '$.analysis',
|
|
146
|
+
'来源与输出完全采用显式mapping;OUTPUT.utc仅是旧ASC显示参数,不转换来源时钟', level='warning'))
|
|
147
|
+
issues.append(LegacyImportIssue('unknown_ttl_difference', 'plan', '$.signals',
|
|
148
|
+
'新分析使用显式有限valid_for及UNKNOWN;旧逐帧缺值/缓存行为不据此宣称等价', level='warning'))
|
|
149
|
+
issues.append(LegacyImportIssue('comparison_rounding_difference', 'plan', '$.rules',
|
|
150
|
+
'旧eval_expr先对float值round(v,10)再比较;新条件使用原值和typed数值政策,不隐式复现该舍入', level='warning'))
|
|
151
|
+
issues.append(LegacyImportIssue('raw_trigger_duplicate_difference', 'plan', '$.outputs',
|
|
152
|
+
'LC02旧触发帧可能先随pre缓冲写出后再次写入;本导入不修改旧writer,不宣称原始输出帧唯一性等价或该缺陷已修复',
|
|
153
|
+
level='warning'))
|
|
154
|
+
slope_mode = mode == 'sclicer_slope'
|
|
155
|
+
start_end_mode = mode == 'sclicer_start_end'
|
|
156
|
+
expected_mode = 'single' if slope_mode else mode.removeprefix('sclicer_')
|
|
157
|
+
analysis['rules'], analysis['windows'] = [], []
|
|
158
|
+
for section in triggers:
|
|
159
|
+
old_mode = parser.get(section, 'mode', fallback=None)
|
|
160
|
+
if old_mode is None:
|
|
161
|
+
_ini_problem(fields, section, 'mode', 'missing_option', '缺少原mode字段', headers=headers)
|
|
162
|
+
if old_mode != expected_mode:
|
|
163
|
+
_ini_problem(fields, section, 'mode', 'unsupported_mode', '原模式必须全部为' + expected_mode + ';不跳过其他模式或混合段')
|
|
164
|
+
keys = ('mode', 'pre_sec', 'post_sec', 'expr') if old_mode == 'single' else (
|
|
165
|
+
'mode', 'pre_sec', 'post_sec', 'start_expr', 'duration_sec')
|
|
166
|
+
if start_end_mode:
|
|
167
|
+
keys += ('end_expr',)
|
|
168
|
+
for key in parser.options(section):
|
|
169
|
+
if key not in keys:
|
|
170
|
+
_ini_problem(fields, section, key, 'unknown_option', '此模式不支持该字段')
|
|
171
|
+
selected = mapping['sections'][section]
|
|
172
|
+
if not slope_mode and not start_end_mode and (type(selected) is not dict or set(selected) != {'name', 'window'}):
|
|
173
|
+
problem('invalid_section_mapping', 'mapping', '$.sections.' + section, '段映射必须恰含name/window')
|
|
174
|
+
if slope_mode:
|
|
175
|
+
# 专用解析器先核段映射,之后才能安全取id;普通single仍明确拒绝旧slope串。
|
|
176
|
+
if not parser.has_option(section, 'expr'):
|
|
177
|
+
_ini_problem(fields, section, 'expr', 'missing_option', '缺少原slope表达式', headers=headers)
|
|
178
|
+
slope = slope_rule(parser.get(section, 'expr', raw=True, fallback=''),
|
|
179
|
+
mapping['aliases'], selected, fields, section, issues)
|
|
180
|
+
if start_end_mode:
|
|
181
|
+
options = start_end_options(parser, fields, section, selected, issues)
|
|
182
|
+
rule_id, window_id = selected['name'], selected['window']
|
|
183
|
+
pre = _seconds(parser, fields, section, 'pre_sec', '5')
|
|
184
|
+
post = _seconds(parser, fields, section, 'post_sec', '3')
|
|
185
|
+
missing_defaults = [key for key in ('pre_sec', 'post_sec') if not parser.has_option(section, key)]
|
|
186
|
+
if old_mode in ('start_only', 'start_end') and not parser.has_option(section, 'duration_sec'):
|
|
187
|
+
missing_defaults.append('duration_sec')
|
|
188
|
+
if missing_defaults:
|
|
189
|
+
issues.append(LegacyImportIssue('old_defaults_applied', 'ini', '[' + section + ']',
|
|
190
|
+
'沿已审旧默认:' + ', '.join(missing_defaults) + ';pre=5s/post=3s/start_only duration=10s/start_end duration=-1(不限时)',
|
|
191
|
+
headers[section], 1, 'warning'))
|
|
192
|
+
key = 'expr' if old_mode == 'single' else 'start_expr'
|
|
193
|
+
if not parser.has_option(section, key):
|
|
194
|
+
_ini_problem(fields, section, key, 'missing_option', '缺少原条件表达式', headers=headers)
|
|
195
|
+
condition = None if slope_mode else _expression(
|
|
196
|
+
parser.get(section, key, raw=True), mapping['aliases'], fields, section, key)
|
|
197
|
+
index = len(analysis['rules'])
|
|
198
|
+
rule_path, window_path = f'$.rules[{index}]', f'$.windows[{index}]'
|
|
199
|
+
if slope_mode:
|
|
200
|
+
rule = slope
|
|
201
|
+
window = {'name': window_id, 'rule': rule_id, 'anchor': 'point', 'pre': pre,
|
|
202
|
+
'post': post, 'merge': 'none'}
|
|
203
|
+
elif start_end_mode:
|
|
204
|
+
if not parser.has_option(section, 'end_expr'):
|
|
205
|
+
_ini_problem(fields, section, 'end_expr', 'missing_option', '缺少原结束条件', headers=headers)
|
|
206
|
+
end_condition = _expression(parser.get(section, 'end_expr', raw=True), mapping['aliases'], fields, section, 'end_expr')
|
|
207
|
+
rule = dict(name=rule_id, rule_type='start_end', start_condition=condition, end_condition=end_condition, **options)
|
|
208
|
+
window = dict(name=window_id, rule=rule_id, anchor='activity', pre=pre, post='0s', merge='none')
|
|
209
|
+
mark(fields, section, 'end_expr', rule_path + '.end_condition')
|
|
210
|
+
mark(fields, section, 'duration_sec', rule_path + '.timeout')
|
|
211
|
+
elif old_mode == 'single':
|
|
212
|
+
rule = {'name': rule_id, 'rule_type': 'condition_duration', 'condition': condition, 'minimum_duration': '0s', 'selection_origin': 'onset'}
|
|
213
|
+
window = {'name': window_id, 'rule': rule_id, 'anchor': 'activity', 'pre': pre,
|
|
214
|
+
'post': '0s', 'merge': 'exit_delay', 'exit_delay': post}
|
|
215
|
+
issues.append(LegacyImportIssue('single_deadline_difference', 'ini', '[' + section + ']',
|
|
216
|
+
'活动立即按FALSE/UNKNOWN结束;片段使用精确exit_delay,区别于旧等待下一帧且严格超过post关闭',
|
|
217
|
+
headers[section], 1, 'warning'))
|
|
218
|
+
else:
|
|
219
|
+
duration = _seconds(parser, fields, section, 'duration_sec', '10', positive=True)
|
|
220
|
+
rule = {'name': rule_id, 'rule_type': 'start_only', 'condition': condition,
|
|
221
|
+
'window_duration': duration, 'emit_initial': True}
|
|
222
|
+
window = {'name': window_id, 'rule': rule_id, 'anchor': 'point', 'pre': pre,
|
|
223
|
+
'post': duration, 'merge': 'none'}
|
|
224
|
+
mark(fields, section, 'duration_sec', rule_path + '.window_duration')
|
|
225
|
+
issues.append(LegacyImportIssue('start_only_edge_difference', 'ini', '[' + section + ']',
|
|
226
|
+
'采用真实边沿和固定抑制窗;emit_initial=true,旧post不叠加,不声称修复旧last_ts缺陷或重现逐帧锁存',
|
|
227
|
+
headers[section], 1, 'warning'))
|
|
228
|
+
analysis['rules'].append(rule)
|
|
229
|
+
analysis['windows'].append(window)
|
|
230
|
+
mark(fields, section, 'mode', rule_path + '.rule_type')
|
|
231
|
+
mark(fields, section, key, rule_path if slope_mode else rule_path + ('.start_condition' if start_end_mode else '.condition'))
|
|
232
|
+
mark(fields, section, 'pre_sec', window_path + '.pre')
|
|
233
|
+
if slope_mode:
|
|
234
|
+
mark(fields, section, 'post_sec', window_path + '.post', message='触发点后的固定长度,不模拟旧退出计时')
|
|
235
|
+
continue
|
|
236
|
+
if start_end_mode:
|
|
237
|
+
mark(fields, section, 'post_sec', None, 'replaced', '旧start_end未使用post,不延长新活动或片段')
|
|
238
|
+
continue
|
|
239
|
+
mark(fields, section, 'post_sec', window_path + '.exit_delay' if old_mode == 'single' else None,
|
|
240
|
+
'mapped' if old_mode == 'single' else 'replaced',
|
|
241
|
+
'single退出延迟,不再叠加post' if old_mode == 'single' else 'start_only使用duration_sec,原post不叠加')
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""把旧 slope 字符串拆为明确的完整窗口规则,不执行旧配置。
|
|
2
|
+
|
|
3
|
+
输入为一个原表达式、显式名称映射和该段的迁移选择;输出 window_delta
|
|
4
|
+
字段及可定位的差异报告。先识别固定前缀,再从右侧取阈值,剩余原信号名
|
|
5
|
+
必须完整命中 aliases,因此信号名可以包含下划线。此模块不读数据或 DBC,
|
|
6
|
+
不修复旧构造器,也不把完整窗口计算声称为旧样本口径的逐帧等价实现。
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from decimal import Decimal, InvalidOperation
|
|
10
|
+
import math
|
|
11
|
+
import re
|
|
12
|
+
|
|
13
|
+
from ..timebase import parse_duration
|
|
14
|
+
from .ini import field_path, locate, problem
|
|
15
|
+
from .models import LegacyImportIssue
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def slope_rule(text, aliases, selected, fields, section, issues):
|
|
19
|
+
"""按显式迁移选择生成一个完整窗口规则。
|
|
20
|
+
|
|
21
|
+
参数: text 为原 expr;aliases 为完整旧名称到新别名的映射;selected 为
|
|
22
|
+
段映射;fields/section 定位原字段;issues 接收兼容差异。
|
|
23
|
+
返回: 可交给 AnalysisPlan 的规则字典。异常: ImportProblem 表示有定位的
|
|
24
|
+
配置问题;内存错误及取消原样传播。阈值沿用信号单位,不除以窗口时长。
|
|
25
|
+
"""
|
|
26
|
+
path, (line, column) = field_path(section, 'expr'), locate(fields, section, 'expr')
|
|
27
|
+
mapping_path = '$.sections.' + section
|
|
28
|
+
expected = {'name', 'window', 'coverage_policy', 'emit_initial', 'retrigger'}
|
|
29
|
+
if type(selected) is not dict or set(selected) != expected:
|
|
30
|
+
problem('invalid_section_mapping', 'mapping', mapping_path,
|
|
31
|
+
'slope段映射必须包含name/window/coverage_policy/emit_initial/retrigger')
|
|
32
|
+
# 初始化和重复触发不能从旧锁存器猜测,要求调用方逐段作出明确选择。
|
|
33
|
+
if selected['coverage_policy'] != 'full':
|
|
34
|
+
problem('unsupported_slope_coverage', 'mapping', mapping_path + '.coverage_policy',
|
|
35
|
+
'当前仅支持full完整窗口;legacy_samples尚未实现,不能默默替换')
|
|
36
|
+
if type(selected['emit_initial']) is not bool:
|
|
37
|
+
problem('invalid_slope_initial', 'mapping', mapping_path + '.emit_initial', '必须明确填写布尔值')
|
|
38
|
+
if selected['retrigger'] not in ('edge', 'once'):
|
|
39
|
+
problem('invalid_slope_retrigger', 'mapping', mapping_path + '.retrigger', '必须选择edge或once')
|
|
40
|
+
match = re.fullmatch(r'_(slope2?)_(rise|fall|any)_([^_]+)_(.+)', text.strip())
|
|
41
|
+
if match is None:
|
|
42
|
+
problem('invalid_slope_syntax', 'ini', path,
|
|
43
|
+
'需要_slope或_slope2、rise/fall/any、秒窗口、完整信号名及非负阈值', line, column)
|
|
44
|
+
legacy_operator, direction, window, remainder = match.groups()
|
|
45
|
+
# 最右分隔符属于阈值;信号名本身不按下划线拆开,也不接受旧未使用的尾字段。
|
|
46
|
+
signal, separator, threshold_text = remainder.rpartition('_')
|
|
47
|
+
if not separator or not signal or signal not in aliases:
|
|
48
|
+
problem('missing_slope_alias', 'ini', path,
|
|
49
|
+
'无法把完整信号名映射到aliases:' + signal + ';请明确名称,不会丢弃额外尾字段', line, column)
|
|
50
|
+
if re.fullmatch(r'(?:\d+(?:\.\d*)?|\.\d+)s', window) is None:
|
|
51
|
+
problem('invalid_slope_window', 'ini', path, '窗口必须为正的十进制秒数并以s结束', line, column)
|
|
52
|
+
try:
|
|
53
|
+
if parse_duration(window).time_ns <= 0:
|
|
54
|
+
raise ValueError('窗口必须大于零')
|
|
55
|
+
except (ValueError, OverflowError) as error:
|
|
56
|
+
problem('invalid_slope_window', 'ini', path, str(error), line, column)
|
|
57
|
+
try:
|
|
58
|
+
if re.fullmatch(r'[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?', threshold_text) is None:
|
|
59
|
+
raise ValueError('阈值须为十进制数值')
|
|
60
|
+
threshold = Decimal(threshold_text)
|
|
61
|
+
if not threshold.is_finite() or threshold < 0:
|
|
62
|
+
raise ValueError('阈值必须有限且非负')
|
|
63
|
+
floating = float(threshold)
|
|
64
|
+
if not math.isfinite(floating) or threshold != 0 and floating == 0:
|
|
65
|
+
raise ValueError('阈值超出可表示的数值范围')
|
|
66
|
+
# 整数保留精度;小数遵循配置已有的float64数值契约。
|
|
67
|
+
number = int(threshold) if threshold == threshold.to_integral_value() else floating
|
|
68
|
+
except (InvalidOperation, ValueError, OverflowError) as error:
|
|
69
|
+
problem('invalid_slope_threshold', 'ini', path, str(error), line, column)
|
|
70
|
+
issues.append(LegacyImportIssue('slope_semantic_differences', 'ini', path,
|
|
71
|
+
'按文档字符串意图迁移,不宣称旧构造器可运行:旧代码误要求7段且忽略尾字段。'
|
|
72
|
+
'新规则要求完整窗口与有效覆盖;旧规则至少两点即可。slope要求整窗单调,'
|
|
73
|
+
'修正旧any的单调检查恒真;slope2不要求单调。初始化和重触发使用显式mapping,'
|
|
74
|
+
'不复制旧触发后返回False的锁存。pre/post生成触发点周围的固定窗口,'
|
|
75
|
+
'不复制旧single逐帧退出计时或缓冲重复写出。', line, column, 'warning'))
|
|
76
|
+
return dict(name=selected['name'], rule_type='window_delta', signal=aliases[signal], window=window,
|
|
77
|
+
direction=direction, threshold=number, monotonic=legacy_operator == 'slope',
|
|
78
|
+
coverage_policy='full', emit_initial=selected['emit_initial'], retrigger=selected['retrigger'])
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""核对旧start_end的显式业务选择及等待时限。
|
|
2
|
+
|
|
3
|
+
输入为已定位INI和用户映射,输出新开始/结束规则的初始化及时限字段。
|
|
4
|
+
旧模式先准备再确认切片,新模式从start记录到end;mapping必须声明
|
|
5
|
+
start_end_timeout-v1。本模块不执行条件、读取日志或修复旧入口。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from decimal import Decimal, InvalidOperation
|
|
9
|
+
from ..timebase import parse_duration
|
|
10
|
+
from .ini import problem, field_path, locate
|
|
11
|
+
from .models import LegacyImportIssue
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def start_end_options(parser, fields, section, selected, issues):
|
|
15
|
+
"""检查显式新语义,按已审旧字段解释正时限和不限时。
|
|
16
|
+
|
|
17
|
+
参数: parser/fields/section为原配置及定位;selected为段映射;issues接收差异。
|
|
18
|
+
返回: timeout/emit_initial字典。异常: ImportProblem为配置非法;取消和内存错误原样传播。
|
|
19
|
+
"""
|
|
20
|
+
path = '$.sections.' + section
|
|
21
|
+
if type(selected) is not dict or set(selected) != {'name', 'window', 'semantics', 'emit_initial'}:
|
|
22
|
+
problem('invalid_section_mapping', 'mapping', path,
|
|
23
|
+
'start_end段映射必须含name/window/semantics/emit_initial')
|
|
24
|
+
if selected['semantics'] != 'start_end_timeout-v1':
|
|
25
|
+
problem('unconfirmed_start_end_semantics', 'mapping', path + '.semantics',
|
|
26
|
+
'请明确选择start_end_timeout-v1:start开始、end结束、时限从start计')
|
|
27
|
+
if type(selected['emit_initial']) is not bool:
|
|
28
|
+
problem('invalid_start_end_initial', 'mapping', path + '.emit_initial', '必须明确填写布尔值')
|
|
29
|
+
raw = parser.get(section, 'duration_sec', fallback='-1', raw=True)
|
|
30
|
+
line, column = locate(fields, section, 'duration_sec')
|
|
31
|
+
try:
|
|
32
|
+
value = Decimal(raw)
|
|
33
|
+
if not value.is_finite():
|
|
34
|
+
raise ValueError('duration_sec必须有限')
|
|
35
|
+
# 非正值是旧模式的不限时,不偷偷选择工程默认时长。
|
|
36
|
+
# 正值保留紧凑指数表示,让时间解析器在分配定点字符串之前拒绝越界。
|
|
37
|
+
timeout = None if value <= 0 else str(value) + 's'
|
|
38
|
+
if timeout is not None and parse_duration(timeout).time_ns <= 0:
|
|
39
|
+
raise ValueError('正时限不能小于可表示的纳秒')
|
|
40
|
+
except (InvalidOperation, ValueError, OverflowError) as error:
|
|
41
|
+
problem('invalid_duration', 'ini', field_path(section, 'duration_sec'), str(error), line, column)
|
|
42
|
+
line, column = locate(fields, section, 'mode')
|
|
43
|
+
issues.append(LegacyImportIssue('start_end_semantic_change', 'ini', field_path(section, 'mode'),
|
|
44
|
+
'显式采用start开始/end结束/从start计时,改变旧start仅准备、end才开始切片。'
|
|
45
|
+
'新时限精确推进,同刻已知end正常结束;可判断却未结束标timeout,缺数据另标中断或截断。'
|
|
46
|
+
'开始采用新上升沿及映射的首次策略,活动中不排队;旧post不附加,非正duration为不限时。'
|
|
47
|
+
'不宣称修复旧last_ts缺陷或旧逐帧等价。', line, column, 'warning'))
|
|
48
|
+
return dict(timeout=timeout, emit_initial=selected['emit_initial'])
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""公开配置构建、静态检查和计划解释入口。
|
|
2
|
+
|
|
3
|
+
AnalysisPlan.from_dict接收版本3配置字典,load_analysis_plan读取JSON配置后构建
|
|
4
|
+
不可变计划。validate_analysis_plan报告声明检查和能力限制,explain_analysis_plan说明依赖、
|
|
5
|
+
历史需求和资源预算。只有load_analysis_plan读取指定配置文件,静态检查不打开CSV或DBC。
|
|
6
|
+
预设已按角色契约展开;实际执行和发布由根包AnalysisRunner及结果层负责,计划合法不表示已执行分析。
|
|
7
|
+
旧来源能力按静态报告保留限制,不因公共入口存在而自动放行。
|
|
8
|
+
当前配置使用同一套记录间隔与诊断声明,不提供旧版本解析或迁移入口。
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# 公开具体已实现入口,而非无类型占位类。
|
|
12
|
+
from .checks import PlanValidationError
|
|
13
|
+
from .plan import AnalysisPlan, load_analysis_plan
|
|
14
|
+
from .reports import ExplainReport, ValidationReport, explain_analysis_plan, validate_analysis_plan
|
|
15
|
+
from .sequences import SequencePlan
|
|
16
|
+
from .intervals import IntervalChoice, IntervalPlan, DiagnosticPlan
|
|
17
|
+
|
|
18
|
+
# 此包仅导出配置和静态报告;公共AnalysisRunner从chronaxis根包取得。
|
|
19
|
+
__all__ = ['AnalysisPlan', 'SequencePlan', 'PlanValidationError', 'load_analysis_plan', 'ValidationReport', 'ExplainReport', 'validate_analysis_plan', 'explain_analysis_plan', 'IntervalChoice', 'IntervalPlan', 'DiagnosticPlan']
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""把用户配置的 CAN 通道转换为内部编号,不读取报文或修改原始数据。
|
|
2
|
+
|
|
3
|
+
公共配置统一从1开始,底层模型从0开始。只在构造模型前调用;配置展开、
|
|
4
|
+
序列化与路径解析保留公共编号,避免往返时反复减1。CSV文件列的channel_origin
|
|
5
|
+
描述原始文件格式,不经过此转换。
|
|
6
|
+
"""
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from .checks import PlanValidationError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def channel_index(value, path, *, key=False):
|
|
13
|
+
"""校验公共通道并返回0基编号。
|
|
14
|
+
|
|
15
|
+
参数: value为正整数;key=True时为DBC映射的规范十进制字符串;path为配置位置。
|
|
16
|
+
返回: int,用户1对应内部0。异常: PlanValidationError,非法或旧0基声明。
|
|
17
|
+
"""
|
|
18
|
+
# 映射键不能靠int接受空格、符号、前导零或其他进制;bool也不是通道整数。
|
|
19
|
+
if key:
|
|
20
|
+
if type(value) is not str or re.fullmatch(r'[1-9][0-9]*', value) is None:
|
|
21
|
+
raise PlanValidationError(path, '配置CAN通道从1开始,DBC通道键须为无前导零的正整数文本',
|
|
22
|
+
hint='第一路填写\'1\';旧0基配置的通道编号整体加1,原始文件通道列不修改')
|
|
23
|
+
try:
|
|
24
|
+
value = int(value)
|
|
25
|
+
except ValueError as error:
|
|
26
|
+
raise PlanValidationError(path, '通道键超过当前整数能力') from error
|
|
27
|
+
elif type(value) is not int or value < 1:
|
|
28
|
+
raise PlanValidationError(path, '配置CAN通道须为从1开始的整数',
|
|
29
|
+
hint='第一路填写1;省略时继承来源唯一通道,旧0基配置整体加1')
|
|
30
|
+
return value - 1
|