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
chronaxis/__init__.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""公开时间转换、分析计划、公共AnalysisRunner和流式结果入口。
|
|
2
|
+
|
|
3
|
+
时间入口接收显式单位时间、日期或整数纳秒序列,返回转换诊断与参考结果。
|
|
4
|
+
AnalysisPlan、load_analysis_plan、validate_analysis_plan和explain_analysis_plan提供配置构建、静态
|
|
5
|
+
检查及依赖解释;访问这些名称时才加载计划模块及其数组来源依赖。
|
|
6
|
+
直接导入时间或核心入口只需标准库,不加载CAN或DBC,也不创建文件和日志。
|
|
7
|
+
预设入口校验角色并生成公共声明;结果入口提供有限暂存、流式读取和Windows原子发布。
|
|
8
|
+
AnalysisRunner接收内存信号、独立信号CSV、BLF及显式格式的ASC/原始报文CSV;访问该名称才加载运行包装。
|
|
9
|
+
BatchRunner或run_batch在外层调度独立计划,各任务使用独立状态和结果目录。
|
|
10
|
+
BLF沿用sclicer-functions-v1旧读取链;新文本CAN使用can-text-v1独立入口。
|
|
11
|
+
信号表及原帧导出可分别选择原始采样或连续量重采样,配置和边界见当前用户手册的输入与导出章节。
|
|
12
|
+
具体配置和输入限制见当前用户手册。
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# 普通根包导入仍只加载标准库时间协议;计划、运行和结果入口按需加载。
|
|
16
|
+
from .timebase import (
|
|
17
|
+
TimeConversion, TimeOverflowError, checked_add_ns, convert_time,
|
|
18
|
+
parse_datetime_ns, parse_duration, shift_times_reference, time_deltas_reference,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# 明确公开范围;没有隐式文件读取、后端回退或CAN依赖。
|
|
22
|
+
__all__ = [
|
|
23
|
+
"TimeConversion", "TimeOverflowError", "checked_add_ns", "convert_time",
|
|
24
|
+
"parse_datetime_ns", "parse_duration", "shift_times_reference", "time_deltas_reference",
|
|
25
|
+
"AnalysisPlan", "PlanValidationError", "load_analysis_plan", "validate_analysis_plan", "explain_analysis_plan",
|
|
26
|
+
"PresetSpec", "PlanFragment", "build_preset", "resolve_preset_roles",
|
|
27
|
+
"AnalysisResult", "OutputManifest", "RunMetadata", "AnalysisError", "ResultClosedError",
|
|
28
|
+
"AnalysisRunner",
|
|
29
|
+
"BatchJob", "BatchJobResult", "BatchReport", "BatchRunner", "BatchPlan", "load_batch_plan", "run_batch",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def __getattr__(name: str):
|
|
34
|
+
"""按公开名称加载计划接口,避免基础时间入口立即依赖数组模块。
|
|
35
|
+
|
|
36
|
+
参数:
|
|
37
|
+
name (str): Python请求的模块属性名,与配置表达式的属性访问无关。
|
|
38
|
+
返回:
|
|
39
|
+
公开名单中的类或函数对象。返回接口本身,不构造计划或打开分析输入。
|
|
40
|
+
异常:
|
|
41
|
+
AttributeError: 名称未在公开名单中。
|
|
42
|
+
ImportError等导入异常: 访问计划接口时所需依赖缺失或模块加载失败。
|
|
43
|
+
副作用:
|
|
44
|
+
导入planning及其依赖;不缓存任何会话输入或绑定。
|
|
45
|
+
"""
|
|
46
|
+
# Python模块只公开列出的名称;配置表达式的属性访问仍由独立语法检查拒绝。
|
|
47
|
+
if name in ('BatchJob', 'BatchJobResult', 'BatchReport', 'BatchRunner', 'BatchPlan', 'load_batch_plan', 'run_batch'):
|
|
48
|
+
# 取得批量入口时才加载模型;普通根包和CLI帮助仍不加载数组或来源。
|
|
49
|
+
from . import batch
|
|
50
|
+
return getattr(batch, name)
|
|
51
|
+
if name == 'AnalysisRunner':
|
|
52
|
+
# 取得类本身不创建session或输入;validate/explain仍只消费冻结计划声明。
|
|
53
|
+
from .runner import AnalysisRunner
|
|
54
|
+
return AnalysisRunner
|
|
55
|
+
if name in ('AnalysisResult', 'OutputManifest', 'RunMetadata', 'AnalysisError', 'ResultClosedError'):
|
|
56
|
+
# 结果层只依赖标准库和核心模型,访问入口也不启动任何读取或发布。
|
|
57
|
+
from .results import AnalysisResult, OutputManifest, RunMetadata, AnalysisError, ResultClosedError
|
|
58
|
+
return {'AnalysisResult': AnalysisResult, 'OutputManifest': OutputManifest, 'RunMetadata': RunMetadata,
|
|
59
|
+
'AnalysisError': AnalysisError, 'ResultClosedError': ResultClosedError}[name]
|
|
60
|
+
if name in ('PresetSpec', 'PlanFragment', 'build_preset', 'resolve_preset_roles'):
|
|
61
|
+
# 预设是外部领域构建层,根包普通导入仍仅加载标准库时间协议。
|
|
62
|
+
from .presets import PresetSpec, PlanFragment, build_preset, resolve_preset_roles
|
|
63
|
+
return {'PresetSpec': PresetSpec, 'PlanFragment': PlanFragment, 'build_preset': build_preset,
|
|
64
|
+
'resolve_preset_roles': resolve_preset_roles}[name]
|
|
65
|
+
if name not in ('AnalysisPlan', 'PlanValidationError', 'load_analysis_plan', 'validate_analysis_plan', 'explain_analysis_plan'):
|
|
66
|
+
# Python正常未知模块属性行为,不静默补占位。
|
|
67
|
+
raise AttributeError(f'chronaxis没有公开属性{name!r}')
|
|
68
|
+
# 只有用户实际访问计划接口时加载数组来源依赖。
|
|
69
|
+
from .planning import AnalysisPlan, PlanValidationError, load_analysis_plan, validate_analysis_plan, explain_analysis_plan
|
|
70
|
+
# 固定映射返回具体能力,不用eval/getattr任意对象或缓存输入绑定。
|
|
71
|
+
return {'AnalysisPlan': AnalysisPlan, 'PlanValidationError': PlanValidationError, 'load_analysis_plan': load_analysis_plan,
|
|
72
|
+
'validate_analysis_plan': validate_analysis_plan, 'explain_analysis_plan': explain_analysis_plan}[name]
|
chronaxis/__main__.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""将python -m chronaxis委托给同一个CLI入口。
|
|
2
|
+
|
|
3
|
+
输入为进程参数,输出及退出码由cli.main定义。作为模块导入时不运行命令;
|
|
4
|
+
实际执行只加载CLI,再由用户命令决定检查计划、运行发布或导入旧INI。
|
|
5
|
+
本文件不另写计算逻辑、加载CAN或注册额外后台动作。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .cli import main
|
|
9
|
+
|
|
10
|
+
if __name__ == '__main__':
|
|
11
|
+
# 两种入口共用解析与错误处理,SystemExit保主函数的真实退出码。
|
|
12
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""把公共AnalysisRunner的检查、解释和实际分析接到CLI,提供文本和JSON报告。
|
|
2
|
+
|
|
3
|
+
输入为解析后的命令参数,load_analysis_plan只读取指定JSON/YAML并按配置目录解释来源路径。
|
|
4
|
+
validate和explain直接调用同一AnalysisRunner接口,不读取CSV、DBC或旧日志,不建立
|
|
5
|
+
运行目录。序列化逐项选择公开报告字段,不遍历任意对象或另做一套配置校验。
|
|
6
|
+
报告中的预算和有效期是声明,execution_ready不证明实际输入已核实。
|
|
7
|
+
run先检查新输出与工作路径,再交给AnalysisRunner运行,在同一结果上write并关闭。
|
|
8
|
+
只有真实关闭成功才打印成功摘要;失败保留原原因链和现存产物,不假报回滚。
|
|
9
|
+
|
|
10
|
+
本模块仅在实际计划命令时加载;CLI帮助与参数错误仍只需要标准库。
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
# 这些接口只有计划命令实际执行时才加载;取得AnalysisRunner类不会创建运行会话。
|
|
18
|
+
from . import AnalysisRunner, load_analysis_plan
|
|
19
|
+
from .planning.checks import PlanValidationError
|
|
20
|
+
from .results.errors import AnalysisError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def validation_json(report) -> dict:
|
|
24
|
+
"""保留公共校验报告的全部固定字段和未验证警告。
|
|
25
|
+
|
|
26
|
+
参数: report为AnalysisRunner.validate返回的ValidationReport。
|
|
27
|
+
返回: 原生JSON字典;元组和只读映射转换为列表和dict,不改变字段含义。
|
|
28
|
+
异常: 接口不符的编程错误原样传播,不靠反射补缺失属性。
|
|
29
|
+
"""
|
|
30
|
+
# 显式白名单避免漏掉能力限制,也避免把内部状态或任意元数据输出到控制台。
|
|
31
|
+
return dict(valid=report.valid, errors=list(report.errors), warnings=list(report.warnings),
|
|
32
|
+
capability_status=dict(report.capability_status), execution_ready=report.execution_ready)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def explanation_json(report) -> dict:
|
|
36
|
+
"""将依赖、节点后端、历史需求和预算声明完整交给CLI使用者。
|
|
37
|
+
|
|
38
|
+
参数: report为AnalysisRunner.explain返回的ExplainReport。
|
|
39
|
+
返回: 固定JSON字典,节点保持原顺序,plan_identity保持原配置身份。
|
|
40
|
+
异常: 接口不符的编程错误原样传播;不推算实测峰值或来源观测范围。
|
|
41
|
+
"""
|
|
42
|
+
# 各节点只含原公开报告字段;state_driver与数值后端沿原报告区别显示。
|
|
43
|
+
nodes = [dict(node_id=node.node_id, node_type=node.node_type, dependencies=list(node.dependencies),
|
|
44
|
+
unit=node.unit, backend=node.backend) for node in report.nodes]
|
|
45
|
+
requirements = report.input_requirements
|
|
46
|
+
scopes = ([] if requirements is None else [dict(source=item.source, input_check=item.input_check,
|
|
47
|
+
time_scope=item.time_scope, required_aliases=list(item.required_aliases),
|
|
48
|
+
decode_frame_ids=list(item.decode_frame_ids), reasons=list(item.reasons)) for item in requirements.sources])
|
|
49
|
+
if report.intervals is not None and requirements is not None:
|
|
50
|
+
for item,scope in zip(requirements.sources,scopes):
|
|
51
|
+
scope['active']=item.active
|
|
52
|
+
output = dict(input_requirements=scopes, validation=validation_json(report.validation), plan_identity=report.plan_identity,
|
|
53
|
+
source_names=list(report.source_names), nodes=nodes,
|
|
54
|
+
history_ns=dict(report.history_ns), budget=dict(report.budget))
|
|
55
|
+
# 解释已解析的间隔声明,不推测DBC周期或输出第二时间轴。
|
|
56
|
+
if report.intervals is not None:
|
|
57
|
+
choices = {}
|
|
58
|
+
for name, choice in report.intervals.resolved:
|
|
59
|
+
choices[name] = dict(mode=choice.mode, step_ns=choice.step_ns, driver=choice.driver)
|
|
60
|
+
output['intervals'] = choices
|
|
61
|
+
if report.diagnostics is not None:
|
|
62
|
+
output['diagnostics'] = dict(trace=report.diagnostics.trace,
|
|
63
|
+
integrity=report.diagnostics.integrity, retain_work=report.diagnostics.retain_work)
|
|
64
|
+
return output
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def run_static(arguments) -> int:
|
|
68
|
+
"""只加载配置并输出共享AnalysisRunner报告,不触碰来源或创建分析产物。
|
|
69
|
+
|
|
70
|
+
参数: arguments含command=validate或explain、plan路径和可选backend覆盖。
|
|
71
|
+
返回: 0表示静态有效且当前有执行路径,2表示报告中存在能力错误。
|
|
72
|
+
异常: 配置加载、依赖、JSON输出或取消错误向主CLI传播,由统一边界处理。
|
|
73
|
+
副作用: 只读取计划JSON、写stdout;来源路径按load_analysis_plan解释,不按CLI另猜。
|
|
74
|
+
"""
|
|
75
|
+
# 只构建静态计划和无状态AnalysisRunner;这些步骤不验证来源文件是否存在或可读。
|
|
76
|
+
plan = load_analysis_plan(arguments.plan)
|
|
77
|
+
runner = AnalysisRunner(backend=arguments.backend)
|
|
78
|
+
# 两种命令使用相同有效计划,覆盖后端不会伪造新的配置或输入身份。
|
|
79
|
+
if arguments.command == 'validate':
|
|
80
|
+
validation = runner.validate(plan)
|
|
81
|
+
payload = validation_json(validation)
|
|
82
|
+
else:
|
|
83
|
+
report = runner.explain(plan)
|
|
84
|
+
validation = report.validation
|
|
85
|
+
payload = explanation_json(report)
|
|
86
|
+
# 人读输出复用同一计划及报告;机器格式保持明确字段,不重新解析输入。
|
|
87
|
+
if arguments.format=='json':
|
|
88
|
+
print(json.dumps(payload, ensure_ascii=False, allow_nan=False))
|
|
89
|
+
else:
|
|
90
|
+
from .configuration.explanation import validation_text, explanation_text
|
|
91
|
+
text=(validation_text(plan,validation) if arguments.command=='validate'
|
|
92
|
+
else explanation_text(plan,report,backend_override=arguments.backend))
|
|
93
|
+
print(text)
|
|
94
|
+
return 0 if validation.valid and validation.execution_ready and not validation.errors else 2
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _new_output(arguments) -> Path:
|
|
98
|
+
"""在扫描来源前拒绝已有输出、历史目录和必然冲突的工作路径。
|
|
99
|
+
|
|
100
|
+
参数: arguments包含output和可选work_dir,由argparse限定为路径文本。
|
|
101
|
+
返回: 绝对输出Path;不创建目录,工作目录实际分配仍归AnalysisRunner。
|
|
102
|
+
异常: FileExistsError或原lstat错误为文件失败;PlanValidationError为Ref或路径冲突。
|
|
103
|
+
"""
|
|
104
|
+
output = Path(arguments.output).absolute()
|
|
105
|
+
# 同时检查词法与物理路径,不能借符号链接把新产物写进历史快照。
|
|
106
|
+
candidates = (output,) if arguments.work_dir is None else (output, Path(arguments.work_dir).absolute())
|
|
107
|
+
for path in candidates:
|
|
108
|
+
if any(part.casefold() == 'refprojects' for part in (*path.parts, *path.resolve().parts)):
|
|
109
|
+
raise PlanValidationError('$.cli.output', '运行输出和工作目录不能位于RefProjects')
|
|
110
|
+
if arguments.work_dir is not None:
|
|
111
|
+
work = Path(arguments.work_dir).absolute().resolve()
|
|
112
|
+
destination = output.resolve()
|
|
113
|
+
# AnalysisRunner会先建立work;若它位于output内部,随后发布必因output已存在而失败。
|
|
114
|
+
if work == destination or destination in work.parents:
|
|
115
|
+
raise PlanValidationError('$.cli.work_dir', '工作目录不能等于输出目录或位于输出目录内部')
|
|
116
|
+
for path in candidates:
|
|
117
|
+
try:
|
|
118
|
+
# 两个参数自身都必须全新,不能跟随已有的悬空工作链接创建其目标。
|
|
119
|
+
# 最终输出安装的竞态仍由原write检查,运行会话也保留原工作目录检查。
|
|
120
|
+
path.lstat()
|
|
121
|
+
except FileNotFoundError:
|
|
122
|
+
continue
|
|
123
|
+
raise FileExistsError('输出或工作目标已存在,拒绝使用:' + str(path))
|
|
124
|
+
return output
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _cause_chain(error) -> tuple:
|
|
128
|
+
"""取得有限且不重复的真实cause链,供诊断和致命异常判断共用。
|
|
129
|
+
|
|
130
|
+
参数: error为实际异常。返回: 最多16个原异常对象,保持外层到根因顺序。
|
|
131
|
+
异常: 无主动异常;不访问任意业务对象,不解析日志或重建错误。
|
|
132
|
+
"""
|
|
133
|
+
chain, seen = [], set()
|
|
134
|
+
current = error
|
|
135
|
+
# 防御外部异常的cause循环;不因诊断无限遍历而阻塞清理或退出。
|
|
136
|
+
while current is not None and id(current) not in seen and len(chain) < 16:
|
|
137
|
+
seen.add(id(current))
|
|
138
|
+
chain.append(current)
|
|
139
|
+
current = current.__cause__
|
|
140
|
+
return tuple(chain)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def run_analysis(arguments) -> int:
|
|
144
|
+
"""复用真实分析和发布,成功关闭所有结果资源后才报告completed。
|
|
145
|
+
|
|
146
|
+
参数: arguments含plan、output、可选backend及work_dir;输出必须为全新目录。
|
|
147
|
+
返回: 成功0;已知分析/发布/关闭失败1,并说明输出可能已经发布。
|
|
148
|
+
异常: 配置/路径错误交主CLI分类;取消原样传播;MemoryError及已知编程错误
|
|
149
|
+
的直接或AnalysisError原因链继续抛出,不伪装成普通业务错误。
|
|
150
|
+
副作用: AnalysisRunner建立专用暂存并读来源,write按原合同安装新目录;不删除产物。
|
|
151
|
+
"""
|
|
152
|
+
plan = load_analysis_plan(arguments.plan)
|
|
153
|
+
output = _new_output(arguments)
|
|
154
|
+
runner = AnalysisRunner(backend=arguments.backend)
|
|
155
|
+
try:
|
|
156
|
+
# 结果拥有其真实仓和资源;write不重新运行来源,退出上下文完成实际close。
|
|
157
|
+
with runner.run(plan, work_dir=arguments.work_dir) as result:
|
|
158
|
+
manifest = result.write(output)
|
|
159
|
+
summary = dict(status=manifest.status, run_id=manifest.run_id,
|
|
160
|
+
plan_identity=result.metadata.plan_hash, backend=result.metadata.backend,
|
|
161
|
+
output=str(manifest.output_dir), manifest=str(manifest.manifest_path),
|
|
162
|
+
row_counts=dict(manifest.row_counts), device_label=result.metadata.device_label)
|
|
163
|
+
if result.metadata.analysis_outcome is not None:
|
|
164
|
+
summary['analysis_outcome']=result.metadata.analysis_outcome.to_dict()
|
|
165
|
+
if result.table_format == 'readable_csv':
|
|
166
|
+
from .results.readable_format import outcome_messages
|
|
167
|
+
summary['result_files'] = [path.name for path in manifest.output_files]
|
|
168
|
+
summary['result_messages'] = outcome_messages(result.metadata.analysis_outcome)
|
|
169
|
+
except (AnalysisError, OSError) as error:
|
|
170
|
+
chain = _cause_chain(error)
|
|
171
|
+
# AnalysisRunner可能包装构造内存/编程错误;保留该公开异常及原cause,不归类普通失败。
|
|
172
|
+
if any(isinstance(item, (MemoryError, TypeError, AttributeError, AssertionError, NameError)) for item in chain):
|
|
173
|
+
raise
|
|
174
|
+
causes = ' <- '.join(type(item).__name__ + ': ' + str(item).replace('\n', ' ') for item in chain)
|
|
175
|
+
# 目录可能已安装后才发生close错误,非零退出不证明输出被撤销。
|
|
176
|
+
print('分析或发布失败(输出可能已发布,请核对目标目录 ' + str(output) + '):' + causes,
|
|
177
|
+
file=sys.stderr)
|
|
178
|
+
return 1
|
|
179
|
+
# 本行在with真实退出之后,不能提前把analysis_complete当成发布和关闭成功。
|
|
180
|
+
print(json.dumps(summary, ensure_ascii=False, allow_nan=False))
|
|
181
|
+
return 0
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""公开独立批量任务模型和调度器,不自动创建进程或读取输入。
|
|
2
|
+
|
|
3
|
+
每个BatchJob调用同一公共AnalysisRunner,输出单独发布,BatchReport只汇总状态和身份。
|
|
4
|
+
调用者可设置process_count工作进程数、fail_fast和取消Event;在途任务完成关闭后才返回。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .models import BatchJob, BatchJobResult, BatchReport, BatchPlan
|
|
8
|
+
from .runner import BatchRunner
|
|
9
|
+
from .config import load_batch_plan
|
|
10
|
+
from .api import run_batch
|
|
11
|
+
from .publication import write_batch_report
|
|
12
|
+
|
|
13
|
+
__all__ = ['BatchJob', 'BatchJobResult', 'BatchReport', 'BatchRunner', 'BatchPlan',
|
|
14
|
+
'load_batch_plan', 'run_batch', 'write_batch_report']
|
chronaxis/batch/api.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""把冻结批量计划交给同一调度器并保存完整报告,不重新实现分析算法。
|
|
2
|
+
|
|
3
|
+
正常返回的BatchReport包含所有独立任务的最终状态。调度或报告写出失败时,
|
|
4
|
+
原异常保留batch_report,使调用方能访问已完成结果并重试未关闭的资源。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import replace
|
|
8
|
+
from .models import BatchPlan
|
|
9
|
+
from .runner import BatchRunner
|
|
10
|
+
from .publication import write_batch_report
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def run_batch(plan: BatchPlan, output_dir, *, process_count: int | None = None, cancel_event=None, device_label='pending'):
|
|
14
|
+
"""运行并发布批量报告。
|
|
15
|
+
|
|
16
|
+
参数: plan为load_batch_plan取得的BatchPlan,规定本次独立任务及调度设置;process_count为可选正整数覆盖,None沿用计划;output_dir全新目录;cancel_event为可选Event;device_label为实际标签。
|
|
17
|
+
返回: BatchReport;failed/cancelled保留在报告,不伪装全部成功。
|
|
18
|
+
异常: TypeError为非BatchPlan或取消对象类型不符;ValueError为无效并发、后端或
|
|
19
|
+
任务声明;目录创建、调度、报告发布错误按原类型传播。单任务失败记录在jobs中,
|
|
20
|
+
不等于本函数抛错。已产生报告后发生基础设施错误时,异常的batch_report保存
|
|
21
|
+
当次实际报告,可检查已完成任务并调用close重试清理。
|
|
22
|
+
"""
|
|
23
|
+
if not isinstance(plan, BatchPlan):
|
|
24
|
+
raise TypeError('run_batch需要BatchPlan')
|
|
25
|
+
if process_count is not None:
|
|
26
|
+
plan = replace(plan, process_count=process_count)
|
|
27
|
+
runner = BatchRunner(plan.process_count, fail_fast=plan.fail_fast, backend=plan.backend)
|
|
28
|
+
try:
|
|
29
|
+
report = runner.run(plan.jobs, output_dir, cancel_event=cancel_event, device_label=device_label)
|
|
30
|
+
except BaseException as error:
|
|
31
|
+
report = getattr(error, 'batch_report', None)
|
|
32
|
+
if report is not None:
|
|
33
|
+
report = replace(report, infrastructure_error=type(error).__name__ + ': ' + str(error))
|
|
34
|
+
error.batch_report = report
|
|
35
|
+
try:
|
|
36
|
+
write_batch_report(report)
|
|
37
|
+
except BaseException as diagnostic:
|
|
38
|
+
error.add_note('批量失败报告未发布: ' + type(diagnostic).__name__)
|
|
39
|
+
raise
|
|
40
|
+
try:
|
|
41
|
+
write_batch_report(report)
|
|
42
|
+
except BaseException as error:
|
|
43
|
+
# 已完成任务绝不因汇总文件失败而丢失,未清理资源仍可从原异常恢复。
|
|
44
|
+
error.batch_report = report
|
|
45
|
+
raise
|
|
46
|
+
return report
|
chronaxis/batch/cli.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""从严格批量配置调用公共API,打印精简计数并保留完整逐任务报告。
|
|
2
|
+
|
|
3
|
+
成功退出0、任一任务失败退出1、取消退出130;配置错误沿外层CLI退出2。
|
|
4
|
+
输出失败保已完成任务,原异常恢复报告在传播前尝试关闭,不清除诊断文件。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import replace
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
from ..planning.checks import PlanValidationError
|
|
12
|
+
from ..results.spool import _cleanup_owner
|
|
13
|
+
from .api import run_batch
|
|
14
|
+
from .config import load_batch_plan
|
|
15
|
+
from .runner import _new_root
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def run_batch_cli(arguments) -> int:
|
|
19
|
+
"""执行真实批量入口。参数: argparse参数。返回: 0/1/130。异常: 外层CLI处理的原错或配置错。"""
|
|
20
|
+
plan = load_batch_plan(arguments.plan)
|
|
21
|
+
try:
|
|
22
|
+
if arguments.process_count is not None:
|
|
23
|
+
plan = replace(plan, process_count=arguments.process_count)
|
|
24
|
+
_new_root(arguments.output)
|
|
25
|
+
except ValueError as error:
|
|
26
|
+
raise PlanValidationError('$.cli', str(error)) from error
|
|
27
|
+
label = os.environ.get('CHRONAXIS_DEVICE_LABEL', '').strip() or 'pending'
|
|
28
|
+
try:
|
|
29
|
+
report = run_batch(plan, arguments.output, device_label=label)
|
|
30
|
+
except BaseException as error:
|
|
31
|
+
report = getattr(error, 'batch_report', None)
|
|
32
|
+
if report is not None:
|
|
33
|
+
_cleanup_owner(report, error, 'batch_report', '批量异常报告')
|
|
34
|
+
raise
|
|
35
|
+
# 一般失败已经清理完;持续故障再尝试,完整报告仍保存初始失败及恢复位置。
|
|
36
|
+
cleanup_failed = False
|
|
37
|
+
try:
|
|
38
|
+
report.close()
|
|
39
|
+
except Exception as error:
|
|
40
|
+
cleanup_failed = True
|
|
41
|
+
print('批量结果清理失败:' + type(error).__name__ + ': ' + str(error), file=sys.stderr)
|
|
42
|
+
document = report.to_dict()
|
|
43
|
+
print(json.dumps(dict(status=report.status, counts=document['counts'],
|
|
44
|
+
output=str(report.output_dir), report=str(report.output_dir/'batch_report.json'),
|
|
45
|
+
cleanup_pending=cleanup_failed, device_label=label), ensure_ascii=False, allow_nan=False))
|
|
46
|
+
if cleanup_failed or report.status == 'failed':
|
|
47
|
+
return 1
|
|
48
|
+
return 130 if report.status == 'cancelled' else 0
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""加载批量清单;显式jobs保存路径,template展开为每文件独立计划。
|
|
2
|
+
|
|
3
|
+
JSON/YAML重复键、非有限值和错误定位沿用共享配置语法规则;实际独立计划到
|
|
4
|
+
jobs在worker启动时加载;template在此时读取模板和必要DBC元数据,均不预读业务日志。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from ..configuration import load_configuration, ConfigurationError
|
|
9
|
+
from ..configuration.diagnostics import locate_error
|
|
10
|
+
from ..planning.checks import PlanValidationError, configuration_error
|
|
11
|
+
from .models import BatchPlan
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def load_batch_plan(path: str | Path) -> BatchPlan:
|
|
15
|
+
"""读取批量YAML或JSON文件,建立独立任务及其调度设置。
|
|
16
|
+
|
|
17
|
+
参数:
|
|
18
|
+
path (str | Path): UTF-8批量配置路径;子计划相对路径以本文件目录为起点。
|
|
19
|
+
返回:
|
|
20
|
+
BatchPlan: 已检查批量结构的不可变计划;template已展开,jobs仍保存路径,均未读取业务输入。
|
|
21
|
+
异常:
|
|
22
|
+
PlanValidationError: 路径类型不合法、文件不可读、编码/语法错误或批量字段不合法。
|
|
23
|
+
先按错误字段路径修正批量或模板文件;jobs中的子计划错误在任务启动时记入任务报告。
|
|
24
|
+
副作用:
|
|
25
|
+
读取批量文件,template模式还读取模板与必要DBC、枚举输入集合;不创建输出目录。"""
|
|
26
|
+
if not isinstance(path, (str, Path)):
|
|
27
|
+
raise PlanValidationError('$', '批量配置路径必须为Path或文本')
|
|
28
|
+
target = Path(path).absolute()
|
|
29
|
+
try:
|
|
30
|
+
document = load_configuration(target)
|
|
31
|
+
return BatchPlan.from_dict(document.data, base_dir=target.parent)
|
|
32
|
+
except ConfigurationError as error:
|
|
33
|
+
raise configuration_error(error) from error
|
|
34
|
+
except PlanValidationError as error:
|
|
35
|
+
raise locate_error(error,document)
|
|
36
|
+
except (OSError, UnicodeError, ValueError, TypeError) as error:
|
|
37
|
+
raise PlanValidationError('$',str(error),'load_error',source=str(target)) from error
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"""保存独立批量任务及其完成、失败和取消事实。
|
|
2
|
+
|
|
3
|
+
输入是已构建计划或计划文件路径;输出保留任务、计划、会话和实际输入身份。
|
|
4
|
+
模型不读取来源、不建立进程,也不将多个任务的数值结果相加。清理失败时只保留
|
|
5
|
+
可显式重试的最高资源所有者,错误本身转成文本,避免长期保存异常栈和输入数组。
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Protocol
|
|
11
|
+
|
|
12
|
+
from ..core.validation import require_identifier
|
|
13
|
+
from ..planning.plan import AnalysisPlan
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Closable(Protocol):
|
|
17
|
+
"""表示已经存在、由调用者负责关闭的资源,不创建占位执行对象。"""
|
|
18
|
+
|
|
19
|
+
def close(self) -> None:
|
|
20
|
+
"""关闭资源。参数: 无。返回: None。异常: 原关闭错误,可恢复后重试。"""
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CleanupHandle:
|
|
25
|
+
"""只持有未关闭的最高所有者;关闭成功后撤销引用,重复关闭无副作用。"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, owner: Closable):
|
|
28
|
+
"""接管真实恢复对象。参数: owner有close方法。返回: 新句柄。异常: 无。"""
|
|
29
|
+
self._owner = owner
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def closed(self) -> bool:
|
|
33
|
+
"""读取恢复是否完成。参数: 无。返回: bool。异常: 无。"""
|
|
34
|
+
return self._owner is None
|
|
35
|
+
|
|
36
|
+
def close(self) -> None:
|
|
37
|
+
"""重试关闭,不在失败时丢所有者。参数: 无。返回: None。异常: 原关闭错误。"""
|
|
38
|
+
if self._owner is not None:
|
|
39
|
+
self._owner.close()
|
|
40
|
+
self._owner = None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True)
|
|
44
|
+
class BatchJob:
|
|
45
|
+
"""声明一个独立分析;同会话连续文件应包含在本任务的一个计划中。"""
|
|
46
|
+
|
|
47
|
+
job_id: str # 批量范围内唯一的简单标识,不用它拼接任意相对路径。
|
|
48
|
+
plan: AnalysisPlan | Path # 冻结计划或文件路径;路径到真正启动时才加载。
|
|
49
|
+
|
|
50
|
+
def __post_init__(self):
|
|
51
|
+
"""检查声明而不读文件。参数: 无。返回: None。异常: 名称或计划类型错误。"""
|
|
52
|
+
require_identifier(self.job_id, 'job_id')
|
|
53
|
+
if not isinstance(self.plan, (AnalysisPlan, Path)):
|
|
54
|
+
raise TypeError('BatchJob.plan需要AnalysisPlan或Path')
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True)
|
|
58
|
+
class BatchPlan:
|
|
59
|
+
"""保存批量配置;只关联独立计划路径,不能把一个会话拆成多个时间任务。"""
|
|
60
|
+
|
|
61
|
+
jobs: tuple[BatchJob, ...] # 声明顺序就是最终清单顺序。
|
|
62
|
+
process_count: int = 1 # 工作进程上限,默认1;各任务仍有独立预算。
|
|
63
|
+
fail_fast: bool = False # 默认继续其他独立任务。
|
|
64
|
+
backend: str | None = None # 可选统一覆盖,不修改原计划文件。
|
|
65
|
+
|
|
66
|
+
def __post_init__(self):
|
|
67
|
+
"""检查冻结声明。参数: 无。返回: None。异常: 类型、范围或重复任务错误;无I/O。"""
|
|
68
|
+
if type(self.jobs) is not tuple or any(not isinstance(j, BatchJob) for j in self.jobs):
|
|
69
|
+
raise TypeError('jobs需要BatchJob tuple')
|
|
70
|
+
if len({j.job_id.casefold() for j in self.jobs}) != len(self.jobs):
|
|
71
|
+
raise ValueError('批量job_id不能重复或仅大小写不同')
|
|
72
|
+
if type(self.process_count) is not int or self.process_count < 1:
|
|
73
|
+
raise ValueError('process_count需要正原生int')
|
|
74
|
+
if type(self.fail_fast) is not bool:
|
|
75
|
+
raise TypeError('fail_fast需要bool')
|
|
76
|
+
if self.backend is not None and (type(self.backend) is not str or self.backend not in ('reference', 'numpy')):
|
|
77
|
+
raise ValueError('backend需要reference、numpy或null')
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_dict(cls, config, *, base_dir=None):
|
|
81
|
+
"""检查批量配置;jobs只关联路径,template读取模板并展开文件集合。
|
|
82
|
+
|
|
83
|
+
参数: config原生dict;base_dir为计划路径相对基准,默认当前目录。
|
|
84
|
+
返回: 冻结BatchPlan。异常: PlanValidationError定位字段;不读取业务报文,模板可读取DBC元数据。
|
|
85
|
+
"""
|
|
86
|
+
from ..planning.checks import object_at, array_at, text_at, model_at, PlanValidationError, number_at, choice_at
|
|
87
|
+
if type(config) is dict and ('workers' in config or 'max_workers' in config):
|
|
88
|
+
raise PlanValidationError('$.process_count', '请使用process_count设置分析工作进程数;workers/max_workers不再接受')
|
|
89
|
+
raw = object_at(config, '$', ('batch_version',), ('jobs', 'template', 'inputs', 'source', 'process_count', 'fail_fast', 'backend'))
|
|
90
|
+
choice_at(raw['batch_version'],(1,),'$.batch_version')
|
|
91
|
+
base, jobs = Path.cwd() if base_dir is None else Path(base_dir).absolute(), []
|
|
92
|
+
if 'template' in raw:
|
|
93
|
+
if 'jobs' in raw or 'inputs' not in raw:
|
|
94
|
+
raise PlanValidationError('$','template需要inputs且不能同时提供jobs')
|
|
95
|
+
from .templates import template_jobs
|
|
96
|
+
jobs=template_jobs(raw,base)
|
|
97
|
+
elif 'jobs' not in raw or 'inputs' in raw or 'source' in raw:
|
|
98
|
+
raise PlanValidationError('$','需要jobs,或template与inputs')
|
|
99
|
+
names=set()
|
|
100
|
+
for index, value in enumerate(array_at(raw.get('jobs', []), '$.jobs')):
|
|
101
|
+
path = '$.jobs[' + str(index) + ']'
|
|
102
|
+
item = object_at(value, path, ('plan',), ('name',))
|
|
103
|
+
job_id = text_at(item.get('name',f'job_{index+1}'), path + '.name', identifier=True)
|
|
104
|
+
if job_id.casefold() in names:
|
|
105
|
+
raise PlanValidationError(path+'.name','任务名称不能重复或仅大小写不同','duplicate_id',
|
|
106
|
+
hint='为每个独立任务指定唯一name')
|
|
107
|
+
names.add(job_id.casefold())
|
|
108
|
+
target = Path(text_at(item['plan'], path + '.plan'))
|
|
109
|
+
if not target.is_absolute():
|
|
110
|
+
target = base / target
|
|
111
|
+
jobs.append(BatchJob(job_id, target.absolute()))
|
|
112
|
+
return model_at(cls, '$', tuple(jobs),
|
|
113
|
+
number_at(raw.get('process_count',1),'$.process_count',integer=True,minimum=1),
|
|
114
|
+
choice_at(raw.get('fail_fast',False),(False,True),'$.fail_fast'),
|
|
115
|
+
choice_at(raw.get('backend'),(None,'reference','numpy'),'$.backend'))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@dataclass(frozen=True)
|
|
119
|
+
class BatchJobResult:
|
|
120
|
+
"""保存一个任务的最终状态;发布后关闭失败仍为failed,并保留已发布路径。"""
|
|
121
|
+
|
|
122
|
+
job_id: str # 原任务身份。
|
|
123
|
+
status: str # completed、failed或cancelled。
|
|
124
|
+
plan_path: str | None = None # 路径计划的原绝对位置;内存计划无路径。
|
|
125
|
+
plan_identity: str | None = None # 配置身份,不冒充实际输入内容身份。
|
|
126
|
+
dataset_id: str | None = None # 无法加载计划时三项会话字段均为空。
|
|
127
|
+
entity_id: str | None = None
|
|
128
|
+
session_id: str | None = None
|
|
129
|
+
input_identity: str | None = None # 只有实际分析返回后才记录。
|
|
130
|
+
run_id: str | None = None # 同计划重跑仍有独立运行身份。
|
|
131
|
+
output_dir: Path | None = None # 实际发布成功的目录,不预填未生成输出。
|
|
132
|
+
error_type: str | None = None # 原异常类型或未启动取消原因。
|
|
133
|
+
error_message: str | None = None # 原错误说明,不用成功值覆盖失败。
|
|
134
|
+
error_chain: tuple[str, ...] = () # cause链和清理notes,保留错误来源。
|
|
135
|
+
elapsed_seconds: float = 0.0 # 单任务墙钟秒,含发布及关闭,不宣称CPU耗时。
|
|
136
|
+
memory_budget_bytes: int | None = None # 该任务的新分析层预算;不是整进程RSS。
|
|
137
|
+
worker_pid: int | None = None # 实际执行任务的工作进程PID;未启动项为空。
|
|
138
|
+
recovery: CleanupHandle | None = field(default=None, repr=False, compare=False)
|
|
139
|
+
|
|
140
|
+
def __post_init__(self):
|
|
141
|
+
"""拒绝伪成功状态。参数: 无。返回: None。异常: 非法状态或成功缺少事实。"""
|
|
142
|
+
if self.status not in ('completed', 'failed', 'cancelled'):
|
|
143
|
+
raise ValueError('批量任务状态无效')
|
|
144
|
+
if self.status == 'completed' and (self.output_dir is None or self.run_id is None):
|
|
145
|
+
raise ValueError('completed需要实际发布目录及运行身份')
|
|
146
|
+
|
|
147
|
+
def to_dict(self) -> dict:
|
|
148
|
+
"""生成可保存的事实。参数: 无。返回: JSON对象。异常: 无;不序列化资源对象。"""
|
|
149
|
+
names = ('job_id', 'status', 'plan_path', 'plan_identity', 'dataset_id', 'entity_id',
|
|
150
|
+
'session_id', 'input_identity', 'run_id', 'error_type', 'error_message',
|
|
151
|
+
'elapsed_seconds', 'memory_budget_bytes', 'worker_pid')
|
|
152
|
+
result = {name: getattr(self, name) for name in names}
|
|
153
|
+
result.update(output_dir=None if self.output_dir is None else str(self.output_dir),
|
|
154
|
+
error_chain=list(self.error_chain),
|
|
155
|
+
cleanup_pending=self.recovery is not None and not self.recovery.closed)
|
|
156
|
+
return result
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass(frozen=True)
|
|
160
|
+
class BatchReport:
|
|
161
|
+
"""按原任务顺序汇总结果;每个任务数值表仍在各自目录,不跨口径归约。"""
|
|
162
|
+
|
|
163
|
+
output_dir: Path # 本批新目录,已有目标不会被覆盖。
|
|
164
|
+
jobs: tuple[BatchJobResult, ...] # 最终结果顺序不受工作进程完成先后影响。
|
|
165
|
+
process_count: int # 本次配置的工作进程上限。
|
|
166
|
+
fail_fast: bool # 是否在观察到失败后停止派发。
|
|
167
|
+
cancel_requested: bool # 用户取消或KeyboardInterrupt是否曾被观察到。
|
|
168
|
+
device_label: str # 调用方明确提供;缺省pending,不猜测机器。
|
|
169
|
+
worker_process_count: int = 0 # 本次实际启动的工作进程数,空批次为0。
|
|
170
|
+
infrastructure_error: str | None = None # 调度或汇总基础设施错误,与任务业务失败分开。
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def status(self) -> str:
|
|
174
|
+
"""汇总失败优先状态。参数: 无。返回: failed/cancelled/completed。异常: 无。"""
|
|
175
|
+
if self.infrastructure_error is not None or any(job.status == 'failed' for job in self.jobs):
|
|
176
|
+
return 'failed'
|
|
177
|
+
return 'cancelled' if any(job.status == 'cancelled' for job in self.jobs) else 'completed'
|
|
178
|
+
|
|
179
|
+
def to_dict(self) -> dict:
|
|
180
|
+
"""输出身份和计数。参数: 无。返回: JSON对象。异常: 无。不合并指标值。"""
|
|
181
|
+
return dict(batch_version=1, status=self.status, output_dir=str(self.output_dir),
|
|
182
|
+
process_count=self.process_count, executor='processes', worker_process_count=self.worker_process_count, fail_fast=self.fail_fast,
|
|
183
|
+
cancel_requested=self.cancel_requested, device_label=self.device_label,
|
|
184
|
+
infrastructure_error=self.infrastructure_error,
|
|
185
|
+
budget_scope='per_task_new_analysis_layer',
|
|
186
|
+
counts={s: sum(j.status == s for j in self.jobs)
|
|
187
|
+
for s in ('completed', 'failed', 'cancelled')},
|
|
188
|
+
jobs=[job.to_dict() for job in self.jobs])
|
|
189
|
+
|
|
190
|
+
def close(self) -> None:
|
|
191
|
+
"""重试所有未完清理。参数: 无。返回: None。异常: 首个关闭错误,其他项仍尝试。"""
|
|
192
|
+
first = None
|
|
193
|
+
for job in self.jobs:
|
|
194
|
+
if job.recovery is not None:
|
|
195
|
+
try:
|
|
196
|
+
job.recovery.close()
|
|
197
|
+
except BaseException as error:
|
|
198
|
+
# 一项失败不能阻止其他独立任务释放资源;原句柄仍由本报告保留。
|
|
199
|
+
if first is None:
|
|
200
|
+
first = error
|
|
201
|
+
if first is not None:
|
|
202
|
+
raise first
|