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.
Files changed (917) hide show
  1. chronaxis/__init__.py +72 -0
  2. chronaxis/__main__.py +12 -0
  3. chronaxis/analysis_cli.py +181 -0
  4. chronaxis/batch/__init__.py +14 -0
  5. chronaxis/batch/api.py +46 -0
  6. chronaxis/batch/cli.py +48 -0
  7. chronaxis/batch/config.py +37 -0
  8. chronaxis/batch/models.py +202 -0
  9. chronaxis/batch/process_transport.py +149 -0
  10. chronaxis/batch/process_tree.py +72 -0
  11. chronaxis/batch/publication.py +41 -0
  12. chronaxis/batch/runner.py +236 -0
  13. chronaxis/batch/templates.py +42 -0
  14. chronaxis/can_dependencies.py +42 -0
  15. chronaxis/cli.py +193 -0
  16. chronaxis/configuration/__init__.py +46 -0
  17. chronaxis/configuration/cli.py +41 -0
  18. chronaxis/configuration/diagnostics.py +107 -0
  19. chronaxis/configuration/explanation.py +233 -0
  20. chronaxis/configuration/file_tools.py +140 -0
  21. chronaxis/configuration/imports.py +144 -0
  22. chronaxis/configuration/initialization.py +36 -0
  23. chronaxis/configuration/json_parser.py +114 -0
  24. chronaxis/configuration/models.py +74 -0
  25. chronaxis/configuration/origins.py +90 -0
  26. chronaxis/configuration/overrides.py +55 -0
  27. chronaxis/configuration/resolution.py +150 -0
  28. chronaxis/configuration/template_catalog.py +68 -0
  29. chronaxis/configuration/templates/batch/analysis-annotated.yaml +18 -0
  30. chronaxis/configuration/templates/batch/analysis-minimal.yaml +18 -0
  31. chronaxis/configuration/templates/batch/annotated.yaml +6 -0
  32. chronaxis/configuration/templates/batch/minimal.yaml +6 -0
  33. chronaxis/configuration/templates/can-asc/annotated.yaml +18 -0
  34. chronaxis/configuration/templates/can-asc/minimal.yaml +18 -0
  35. chronaxis/configuration/templates/can-blf/annotated.yaml +18 -0
  36. chronaxis/configuration/templates/can-blf/minimal.yaml +18 -0
  37. chronaxis/configuration/templates/can-export/annotated.yaml +23 -0
  38. chronaxis/configuration/templates/can-export/minimal.yaml +23 -0
  39. chronaxis/configuration/templates/catalog.json +233 -0
  40. chronaxis/configuration/templates/charge-session/annotated.yaml +38 -0
  41. chronaxis/configuration/templates/charge-session/minimal.yaml +38 -0
  42. chronaxis/configuration/templates/command-response/annotated.yaml +32 -0
  43. chronaxis/configuration/templates/command-response/minimal.yaml +36 -0
  44. chronaxis/configuration/templates/fault-window/annotated.yaml +25 -0
  45. chronaxis/configuration/templates/fault-window/minimal.yaml +27 -0
  46. chronaxis/configuration/templates/ini-mapping/annotated.yaml +20 -0
  47. chronaxis/configuration/templates/ini-mapping/minimal.yaml +20 -0
  48. chronaxis/configuration/templates/raw-can-csv/annotated.yaml +34 -0
  49. chronaxis/configuration/templates/raw-can-csv/minimal.yaml +35 -0
  50. chronaxis/configuration/templates/shared/charge-session.asc +5 -0
  51. chronaxis/configuration/templates/shared/command-response.asc +8 -0
  52. chronaxis/configuration/templates/shared/fault-window.asc +5 -0
  53. chronaxis/configuration/templates/shared/power.asc +7 -0
  54. chronaxis/configuration/templates/shared/sample.asc +6 -0
  55. chronaxis/configuration/templates/shared/sample.blf +0 -0
  56. chronaxis/configuration/templates/shared/sample.csv +5 -0
  57. chronaxis/configuration/templates/shared/sample.dbc +11 -0
  58. chronaxis/configuration/templates/shared/signals.csv +6 -0
  59. chronaxis/configuration/templates/shared/source.ini +5 -0
  60. chronaxis/configuration/templates/shared/stability.asc +9 -0
  61. chronaxis/configuration/templates/shared/teaching.dbc +27 -0
  62. chronaxis/configuration/templates/shared/threshold.asc +7 -0
  63. chronaxis/configuration/templates/signal-csv/annotated.yaml +27 -0
  64. chronaxis/configuration/templates/signal-csv/minimal.yaml +27 -0
  65. chronaxis/configuration/templates/signal-export/annotated.yaml +27 -0
  66. chronaxis/configuration/templates/signal-export/minimal.yaml +29 -0
  67. chronaxis/configuration/templates/stability/annotated.yaml +35 -0
  68. chronaxis/configuration/templates/stability/minimal.yaml +35 -0
  69. chronaxis/configuration/templates/threshold/annotated.yaml +22 -0
  70. chronaxis/configuration/templates/threshold/minimal.yaml +22 -0
  71. chronaxis/configuration/yaml_parser.py +125 -0
  72. chronaxis/core/__init__.py +71 -0
  73. chronaxis/core/binding.py +449 -0
  74. chronaxis/core/calculation_series_join.py +106 -0
  75. chronaxis/core/calculations.py +435 -0
  76. chronaxis/core/calculations_memory_numpy.py +136 -0
  77. chronaxis/core/calculations_memory_reference.py +165 -0
  78. chronaxis/core/calculations_numpy.py +298 -0
  79. chronaxis/core/calculations_reference.py +294 -0
  80. chronaxis/core/condition_evidence.py +182 -0
  81. chronaxis/core/conditional_integral_result.py +43 -0
  82. chronaxis/core/conditional_integral_terms.py +146 -0
  83. chronaxis/core/conditional_integral_terms_numpy.py +148 -0
  84. chronaxis/core/conditional_integral_terms_reference.py +111 -0
  85. chronaxis/core/conditional_time_reduction.py +118 -0
  86. chronaxis/core/conditional_time_reduction_numpy.py +223 -0
  87. chronaxis/core/conditional_time_reduction_reference.py +213 -0
  88. chronaxis/core/declarations.py +192 -0
  89. chronaxis/core/decoded_binding.py +197 -0
  90. chronaxis/core/direct_message.py +387 -0
  91. chronaxis/core/export_interpolation.py +54 -0
  92. chronaxis/core/expression.py +642 -0
  93. chronaxis/core/expression_numpy.py +314 -0
  94. chronaxis/core/expression_reference.py +272 -0
  95. chronaxis/core/integral_result.py +53 -0
  96. chronaxis/core/integral_sum.py +77 -0
  97. chronaxis/core/integral_sum_numpy.py +224 -0
  98. chronaxis/core/integral_sum_reference.py +148 -0
  99. chronaxis/core/integral_terms.py +119 -0
  100. chronaxis/core/integral_terms_numpy.py +127 -0
  101. chronaxis/core/integral_terms_reference.py +91 -0
  102. chronaxis/core/mean_weights_numpy.py +29 -0
  103. chronaxis/core/mean_weights_reference.py +27 -0
  104. chronaxis/core/message_binding.py +305 -0
  105. chronaxis/core/models.py +485 -0
  106. chronaxis/core/normalize_numpy.py +396 -0
  107. chronaxis/core/numeric.py +472 -0
  108. chronaxis/core/numeric_numpy.py +440 -0
  109. chronaxis/core/record_intervals.py +115 -0
  110. chronaxis/core/sample_reduction.py +161 -0
  111. chronaxis/core/sample_reduction_numpy.py +160 -0
  112. chronaxis/core/sample_reduction_reference.py +154 -0
  113. chronaxis/core/selection.py +74 -0
  114. chronaxis/core/sequence.py +160 -0
  115. chronaxis/core/sequence_reference.py +248 -0
  116. chronaxis/core/stability.py +249 -0
  117. chronaxis/core/start_end.py +169 -0
  118. chronaxis/core/state.py +494 -0
  119. chronaxis/core/state_numpy.py +296 -0
  120. chronaxis/core/temporal.py +373 -0
  121. chronaxis/core/temporal_clock.py +25 -0
  122. chronaxis/core/temporal_memory_numpy.py +163 -0
  123. chronaxis/core/temporal_memory_reference.py +161 -0
  124. chronaxis/core/temporal_numpy.py +345 -0
  125. chronaxis/core/temporal_reference.py +304 -0
  126. chronaxis/core/time_reduction.py +190 -0
  127. chronaxis/core/time_reduction_numpy.py +205 -0
  128. chronaxis/core/time_reduction_reference.py +203 -0
  129. chronaxis/core/types.py +105 -0
  130. chronaxis/core/units.py +81 -0
  131. chronaxis/core/validation.py +94 -0
  132. chronaxis/core/window_delta.py +123 -0
  133. chronaxis/core/window_delta_numpy.py +78 -0
  134. chronaxis/core/window_delta_reference.py +69 -0
  135. chronaxis/core/windows.py +224 -0
  136. chronaxis/core/windows_numpy.py +78 -0
  137. chronaxis/core/windows_reference.py +61 -0
  138. chronaxis/execution/__init__.py +6 -0
  139. chronaxis/execution/batch_signal_groups.py +122 -0
  140. chronaxis/execution/bindings.py +296 -0
  141. chronaxis/execution/boundaries.py +568 -0
  142. chronaxis/execution/calculation_blocks.py +338 -0
  143. chronaxis/execution/calculation_values.py +55 -0
  144. chronaxis/execution/can_batch_reader.py +356 -0
  145. chronaxis/execution/can_reader.py +948 -0
  146. chronaxis/execution/can_reference_template.py +61 -0
  147. chronaxis/execution/condition_evidence.py +370 -0
  148. chronaxis/execution/conditional_integral_facts.py +310 -0
  149. chronaxis/execution/conditional_integral_reduction.py +216 -0
  150. chronaxis/execution/csv_observation.py +524 -0
  151. chronaxis/execution/csv_reader.py +662 -0
  152. chronaxis/execution/current_message_calculation.py +225 -0
  153. chronaxis/execution/driver_expression.py +274 -0
  154. chronaxis/execution/expressions.py +618 -0
  155. chronaxis/execution/frame_capture.py +245 -0
  156. chronaxis/execution/groups.py +236 -0
  157. chronaxis/execution/historical_conditional_blocks.py +264 -0
  158. chronaxis/execution/historical_conditional_integral.py +226 -0
  159. chronaxis/execution/historical_conditional_time_calculation.py +368 -0
  160. chronaxis/execution/historical_integral.py +219 -0
  161. chronaxis/execution/historical_observation.py +372 -0
  162. chronaxis/execution/historical_sample_calculation.py +338 -0
  163. chronaxis/execution/historical_selection_rows.py +300 -0
  164. chronaxis/execution/historical_time_calculation.py +341 -0
  165. chronaxis/execution/history.py +572 -0
  166. chronaxis/execution/history_records.py +225 -0
  167. chronaxis/execution/hold.py +448 -0
  168. chronaxis/execution/integral_facts.py +311 -0
  169. chronaxis/execution/integral_reduction.py +216 -0
  170. chronaxis/execution/legacy_frame_samples.py +94 -0
  171. chronaxis/execution/memory_reader.py +247 -0
  172. chronaxis/execution/message_bindings.py +293 -0
  173. chronaxis/execution/message_delivery.py +37 -0
  174. chronaxis/execution/observed_ingestion.py +551 -0
  175. chronaxis/execution/raw_signal_groups.py +192 -0
  176. chronaxis/execution/record_alarm_duration.py +114 -0
  177. chronaxis/execution/record_delta_condition.py +167 -0
  178. chronaxis/execution/record_diagnostics.py +87 -0
  179. chronaxis/execution/record_event_durations.py +143 -0
  180. chronaxis/execution/record_export_samples.py +94 -0
  181. chronaxis/execution/record_exports.py +155 -0
  182. chronaxis/execution/record_integral.py +196 -0
  183. chronaxis/execution/record_point_buffer.py +101 -0
  184. chronaxis/execution/record_rule_timeline.py +344 -0
  185. chronaxis/execution/record_sample.py +46 -0
  186. chronaxis/execution/record_sample_series.py +29 -0
  187. chronaxis/execution/record_scope_calculations.py +290 -0
  188. chronaxis/execution/record_selection.py +62 -0
  189. chronaxis/execution/record_sequences.py +199 -0
  190. chronaxis/execution/record_session_calculations.py +778 -0
  191. chronaxis/execution/record_signal_export.py +133 -0
  192. chronaxis/execution/record_source_cursor.py +295 -0
  193. chronaxis/execution/record_time_calculation.py +322 -0
  194. chronaxis/execution/record_time_indexes.py +143 -0
  195. chronaxis/execution/record_value_history.py +160 -0
  196. chronaxis/execution/record_windows.py +229 -0
  197. chronaxis/execution/required_expression.py +52 -0
  198. chronaxis/execution/retained_metadata.py +71 -0
  199. chronaxis/execution/run_session.py +402 -0
  200. chronaxis/execution/scanned_signal_proof.py +550 -0
  201. chronaxis/execution/signal_validity.py +40 -0
  202. chronaxis/execution/state.py +280 -0
  203. chronaxis/execution/temporal_buffer.py +508 -0
  204. chronaxis/execution/text_can_reader.py +359 -0
  205. chronaxis/execution/timeline.py +309 -0
  206. chronaxis/execution/timeline_multi.py +415 -0
  207. chronaxis/execution/window_delta_events.py +220 -0
  208. chronaxis/execution/window_replay.py +350 -0
  209. chronaxis/execution/windows.py +173 -0
  210. chronaxis/guide/README.md +70 -0
  211. chronaxis/guide/api/AnalysisError.md +14 -0
  212. chronaxis/guide/api/AnalysisPlan.md +96 -0
  213. chronaxis/guide/api/AnalysisResult.md +398 -0
  214. chronaxis/guide/api/AnalysisRunner.md +155 -0
  215. chronaxis/guide/api/BatchJob.md +19 -0
  216. chronaxis/guide/api/BatchJobResult.md +61 -0
  217. chronaxis/guide/api/BatchPlan.md +48 -0
  218. chronaxis/guide/api/BatchReport.md +108 -0
  219. chronaxis/guide/api/BatchRunner.md +84 -0
  220. chronaxis/guide/api/OutputManifest.md +23 -0
  221. chronaxis/guide/api/PlanFragment.md +47 -0
  222. chronaxis/guide/api/PlanValidationError.md +98 -0
  223. chronaxis/guide/api/PresetSpec.md +63 -0
  224. chronaxis/guide/api/ResultClosedError.md +14 -0
  225. chronaxis/guide/api/RunMetadata.md +100 -0
  226. chronaxis/guide/api/TimeConversion.md +29 -0
  227. chronaxis/guide/api/TimeOverflowError.md +17 -0
  228. chronaxis/guide/api/build_preset.md +36 -0
  229. chronaxis/guide/api/checked_add_ns.md +30 -0
  230. chronaxis/guide/api/convert_time.md +40 -0
  231. chronaxis/guide/api/explain_analysis_plan.md +38 -0
  232. chronaxis/guide/api/index.json +185 -0
  233. chronaxis/guide/api/load_analysis_plan.md +34 -0
  234. chronaxis/guide/api/load_batch_plan.md +36 -0
  235. chronaxis/guide/api/parse_datetime_ns.md +35 -0
  236. chronaxis/guide/api/parse_duration.md +30 -0
  237. chronaxis/guide/api/resolve_preset_roles.md +37 -0
  238. chronaxis/guide/api/run_batch.md +38 -0
  239. chronaxis/guide/api/shift_times_reference.md +33 -0
  240. chronaxis/guide/api/time_deltas_reference.md +37 -0
  241. chronaxis/guide/api/validate_analysis_plan.md +38 -0
  242. chronaxis/guide/en/README.md +74 -0
  243. chronaxis/guide/en/api/AnalysisError.md +14 -0
  244. chronaxis/guide/en/api/AnalysisPlan.md +93 -0
  245. chronaxis/guide/en/api/AnalysisResult.md +398 -0
  246. chronaxis/guide/en/api/AnalysisRunner.md +191 -0
  247. chronaxis/guide/en/api/BatchJob.md +17 -0
  248. chronaxis/guide/en/api/BatchJobResult.md +43 -0
  249. chronaxis/guide/en/api/BatchPlan.md +37 -0
  250. chronaxis/guide/en/api/BatchReport.md +52 -0
  251. chronaxis/guide/en/api/BatchRunner.md +51 -0
  252. chronaxis/guide/en/api/OutputManifest.md +23 -0
  253. chronaxis/guide/en/api/PlanFragment.md +33 -0
  254. chronaxis/guide/en/api/PlanValidationError.md +58 -0
  255. chronaxis/guide/en/api/PresetSpec.md +51 -0
  256. chronaxis/guide/en/api/ResultClosedError.md +14 -0
  257. chronaxis/guide/en/api/RunMetadata.md +100 -0
  258. chronaxis/guide/en/api/TimeConversion.md +23 -0
  259. chronaxis/guide/en/api/TimeOverflowError.md +14 -0
  260. chronaxis/guide/en/api/build_preset.md +23 -0
  261. chronaxis/guide/en/api/checked_add_ns.md +21 -0
  262. chronaxis/guide/en/api/convert_time.md +25 -0
  263. chronaxis/guide/en/api/explain_analysis_plan.md +30 -0
  264. chronaxis/guide/en/api/index.json +185 -0
  265. chronaxis/guide/en/api/load_analysis_plan.md +27 -0
  266. chronaxis/guide/en/api/load_batch_plan.md +28 -0
  267. chronaxis/guide/en/api/parse_datetime_ns.md +23 -0
  268. chronaxis/guide/en/api/parse_duration.md +20 -0
  269. chronaxis/guide/en/api/resolve_preset_roles.md +23 -0
  270. chronaxis/guide/en/api/run_batch.md +39 -0
  271. chronaxis/guide/en/api/shift_times_reference.md +21 -0
  272. chronaxis/guide/en/api/time_deltas_reference.md +22 -0
  273. chronaxis/guide/en/api/validate_analysis_plan.md +29 -0
  274. chronaxis/guide/en/fields/analysis/calculations-all-1.json +345 -0
  275. chronaxis/guide/en/fields/analysis/calculations-all-2.json +300 -0
  276. chronaxis/guide/en/fields/analysis/calculations-all-3.json +84 -0
  277. chronaxis/guide/en/fields/analysis/config_version-all-1.json +24 -0
  278. chronaxis/guide/en/fields/analysis/dataset-all-1.json +344 -0
  279. chronaxis/guide/en/fields/analysis/derived-all-1.json +147 -0
  280. chronaxis/guide/en/fields/analysis/diagnostics-all-1.json +69 -0
  281. chronaxis/guide/en/fields/analysis/execution-all-1.json +167 -0
  282. chronaxis/guide/en/fields/analysis/imports-all-1.json +39 -0
  283. chronaxis/guide/en/fields/analysis/intervals-all-1.json +173 -0
  284. chronaxis/guide/en/fields/analysis/message_calculations-all-1.json +345 -0
  285. chronaxis/guide/en/fields/analysis/message_calculations-all-2.json +270 -0
  286. chronaxis/guide/en/fields/analysis/metadata-all-1.json +24 -0
  287. chronaxis/guide/en/fields/analysis/outputs-all-1.json +332 -0
  288. chronaxis/guide/en/fields/analysis/outputs-all-2.json +319 -0
  289. chronaxis/guide/en/fields/analysis/outputs-all-3.json +321 -0
  290. chronaxis/guide/en/fields/analysis/outputs-all-4.json +236 -0
  291. chronaxis/guide/en/fields/analysis/outputs-all-5.json +246 -0
  292. chronaxis/guide/en/fields/analysis/outputs-all-6.json +214 -0
  293. chronaxis/guide/en/fields/analysis/overrides-all-1.json +104 -0
  294. chronaxis/guide/en/fields/analysis/presets-charge_session-1.json +398 -0
  295. chronaxis/guide/en/fields/analysis/presets-charge_session-2.json +114 -0
  296. chronaxis/guide/en/fields/analysis/presets-command_response-1.json +376 -0
  297. chronaxis/guide/en/fields/analysis/presets-fault_context-1.json +285 -0
  298. chronaxis/guide/en/fields/analysis/presets-threshold_excursion-1.json +317 -0
  299. chronaxis/guide/en/fields/analysis/rules-condition_duration-1.json +344 -0
  300. chronaxis/guide/en/fields/analysis/rules-condition_duration-2.json +27 -0
  301. chronaxis/guide/en/fields/analysis/rules-debounce-1.json +335 -0
  302. chronaxis/guide/en/fields/analysis/rules-falling_edge-1.json +317 -0
  303. chronaxis/guide/en/fields/analysis/rules-hysteresis-1.json +334 -0
  304. chronaxis/guide/en/fields/analysis/rules-hysteresis-2.json +27 -0
  305. chronaxis/guide/en/fields/analysis/rules-rising_edge-1.json +317 -0
  306. chronaxis/guide/en/fields/analysis/rules-start_end-1.json +333 -0
  307. chronaxis/guide/en/fields/analysis/rules-start_end-2.json +60 -0
  308. chronaxis/guide/en/fields/analysis/rules-start_only-1.json +334 -0
  309. chronaxis/guide/en/fields/analysis/rules-window_delta-1.json +338 -0
  310. chronaxis/guide/en/fields/analysis/rules-window_delta-2.json +96 -0
  311. chronaxis/guide/en/fields/analysis/sequences-all-1.json +378 -0
  312. chronaxis/guide/en/fields/analysis/sequences-all-2.json +70 -0
  313. chronaxis/guide/en/fields/analysis/signals-variant-1-1.json +349 -0
  314. chronaxis/guide/en/fields/analysis/signals-variant-1-2.json +297 -0
  315. chronaxis/guide/en/fields/analysis/signals-variant-1-3.json +323 -0
  316. chronaxis/guide/en/fields/analysis/signals-variant-1-4.json +192 -0
  317. chronaxis/guide/en/fields/analysis/signals-variant-2-1.json +327 -0
  318. chronaxis/guide/en/fields/analysis/signals-variant-2-2.json +312 -0
  319. chronaxis/guide/en/fields/analysis/signals-variant-2-3.json +294 -0
  320. chronaxis/guide/en/fields/analysis/signals-variant-2-4.json +253 -0
  321. chronaxis/guide/en/fields/analysis/signals-variant-2-5.json +44 -0
  322. chronaxis/guide/en/fields/analysis/sources-can_asc-1.json +318 -0
  323. chronaxis/guide/en/fields/analysis/sources-can_asc-2.json +310 -0
  324. chronaxis/guide/en/fields/analysis/sources-can_asc-3.json +311 -0
  325. chronaxis/guide/en/fields/analysis/sources-can_asc-4.json +69 -0
  326. chronaxis/guide/en/fields/analysis/sources-can_blf-1.json +317 -0
  327. chronaxis/guide/en/fields/analysis/sources-can_blf-2.json +310 -0
  328. chronaxis/guide/en/fields/analysis/sources-can_blf-3.json +317 -0
  329. chronaxis/guide/en/fields/analysis/sources-memory-1.json +332 -0
  330. chronaxis/guide/en/fields/analysis/sources-memory-2.json +125 -0
  331. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-1.json +330 -0
  332. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-10.json +233 -0
  333. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-11.json +225 -0
  334. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-12.json +228 -0
  335. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-13.json +226 -0
  336. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-14.json +230 -0
  337. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-15.json +227 -0
  338. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-16.json +230 -0
  339. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-17.json +238 -0
  340. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-18.json +239 -0
  341. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-19.json +233 -0
  342. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-2.json +310 -0
  343. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-20.json +242 -0
  344. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-21.json +230 -0
  345. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-22.json +228 -0
  346. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-23.json +230 -0
  347. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-24.json +223 -0
  348. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-25.json +290 -0
  349. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-26.json +131 -0
  350. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-3.json +297 -0
  351. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-4.json +226 -0
  352. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-5.json +230 -0
  353. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-6.json +227 -0
  354. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-7.json +230 -0
  355. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-8.json +238 -0
  356. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-9.json +239 -0
  357. chronaxis/guide/en/fields/analysis/sources-signal_csv-1.json +331 -0
  358. chronaxis/guide/en/fields/analysis/sources-signal_csv-2.json +307 -0
  359. chronaxis/guide/en/fields/analysis/sources-signal_csv-3.json +315 -0
  360. chronaxis/guide/en/fields/analysis/sources-variant-6-1.json +319 -0
  361. chronaxis/guide/en/fields/analysis/sources-variant-6-2.json +307 -0
  362. chronaxis/guide/en/fields/analysis/sources-variant-6-3.json +312 -0
  363. chronaxis/guide/en/fields/analysis/sources-variant-6-4.json +113 -0
  364. chronaxis/guide/en/fields/analysis/windows-all-1.json +361 -0
  365. chronaxis/guide/en/fields/analysis/windows-all-2.json +187 -0
  366. chronaxis/guide/en/fields/batch/backend-all-1.json +26 -0
  367. chronaxis/guide/en/fields/batch/batch_version-all-1.json +22 -0
  368. chronaxis/guide/en/fields/batch/fail_fast-all-1.json +22 -0
  369. chronaxis/guide/en/fields/batch/inputs-all-1.json +161 -0
  370. chronaxis/guide/en/fields/batch/jobs-all-1.json +58 -0
  371. chronaxis/guide/en/fields/batch/process_count-all-1.json +23 -0
  372. chronaxis/guide/en/fields/batch/source-all-1.json +22 -0
  373. chronaxis/guide/en/fields/batch/template-all-1.json +22 -0
  374. chronaxis/guide/en/fields/definitions/derived-all-1.json +121 -0
  375. chronaxis/guide/en/fields/definitions/signals-all-1.json +336 -0
  376. chronaxis/guide/en/fields/definitions/signals-all-2.json +307 -0
  377. chronaxis/guide/en/fields/definitions/signals-all-3.json +290 -0
  378. chronaxis/guide/en/fields/definitions/signals-all-4.json +347 -0
  379. chronaxis/guide/en/fields/definitions/signals-all-5.json +297 -0
  380. chronaxis/guide/en/fields/definitions/signals-all-6.json +259 -0
  381. chronaxis/guide/en/fields/definitions/signals-all-7.json +117 -0
  382. chronaxis/guide/en/fields/definitions/sources-all-1.json +332 -0
  383. chronaxis/guide/en/fields/definitions/sources-all-10.json +306 -0
  384. chronaxis/guide/en/fields/definitions/sources-all-11.json +294 -0
  385. chronaxis/guide/en/fields/definitions/sources-all-12.json +212 -0
  386. chronaxis/guide/en/fields/definitions/sources-all-13.json +217 -0
  387. chronaxis/guide/en/fields/definitions/sources-all-14.json +213 -0
  388. chronaxis/guide/en/fields/definitions/sources-all-15.json +214 -0
  389. chronaxis/guide/en/fields/definitions/sources-all-16.json +215 -0
  390. chronaxis/guide/en/fields/definitions/sources-all-17.json +213 -0
  391. chronaxis/guide/en/fields/definitions/sources-all-18.json +214 -0
  392. chronaxis/guide/en/fields/definitions/sources-all-19.json +213 -0
  393. chronaxis/guide/en/fields/definitions/sources-all-2.json +323 -0
  394. chronaxis/guide/en/fields/definitions/sources-all-20.json +217 -0
  395. chronaxis/guide/en/fields/definitions/sources-all-21.json +210 -0
  396. chronaxis/guide/en/fields/definitions/sources-all-22.json +214 -0
  397. chronaxis/guide/en/fields/definitions/sources-all-23.json +218 -0
  398. chronaxis/guide/en/fields/definitions/sources-all-24.json +209 -0
  399. chronaxis/guide/en/fields/definitions/sources-all-25.json +215 -0
  400. chronaxis/guide/en/fields/definitions/sources-all-26.json +218 -0
  401. chronaxis/guide/en/fields/definitions/sources-all-27.json +224 -0
  402. chronaxis/guide/en/fields/definitions/sources-all-28.json +215 -0
  403. chronaxis/guide/en/fields/definitions/sources-all-29.json +205 -0
  404. chronaxis/guide/en/fields/definitions/sources-all-3.json +303 -0
  405. chronaxis/guide/en/fields/definitions/sources-all-30.json +298 -0
  406. chronaxis/guide/en/fields/definitions/sources-all-31.json +315 -0
  407. chronaxis/guide/en/fields/definitions/sources-all-32.json +306 -0
  408. chronaxis/guide/en/fields/definitions/sources-all-33.json +209 -0
  409. chronaxis/guide/en/fields/definitions/sources-all-4.json +336 -0
  410. chronaxis/guide/en/fields/definitions/sources-all-5.json +299 -0
  411. chronaxis/guide/en/fields/definitions/sources-all-6.json +307 -0
  412. chronaxis/guide/en/fields/definitions/sources-all-7.json +320 -0
  413. chronaxis/guide/en/fields/definitions/sources-all-8.json +303 -0
  414. chronaxis/guide/en/fields/definitions/sources-all-9.json +315 -0
  415. chronaxis/guide/en/fields/index.json +3450 -0
  416. chronaxis/guide/en/fields/mapping/aliases-all-1.json +91 -0
  417. chronaxis/guide/en/fields/mapping/analysis-all-1.json +382 -0
  418. chronaxis/guide/en/fields/mapping/analysis-all-10.json +301 -0
  419. chronaxis/guide/en/fields/mapping/analysis-all-11.json +312 -0
  420. chronaxis/guide/en/fields/mapping/analysis-all-12.json +311 -0
  421. chronaxis/guide/en/fields/mapping/analysis-all-13.json +314 -0
  422. chronaxis/guide/en/fields/mapping/analysis-all-14.json +310 -0
  423. chronaxis/guide/en/fields/mapping/analysis-all-15.json +297 -0
  424. chronaxis/guide/en/fields/mapping/analysis-all-16.json +226 -0
  425. chronaxis/guide/en/fields/mapping/analysis-all-17.json +230 -0
  426. chronaxis/guide/en/fields/mapping/analysis-all-18.json +227 -0
  427. chronaxis/guide/en/fields/mapping/analysis-all-19.json +230 -0
  428. chronaxis/guide/en/fields/mapping/analysis-all-2.json +323 -0
  429. chronaxis/guide/en/fields/mapping/analysis-all-20.json +221 -0
  430. chronaxis/guide/en/fields/mapping/analysis-all-21.json +237 -0
  431. chronaxis/guide/en/fields/mapping/analysis-all-22.json +233 -0
  432. chronaxis/guide/en/fields/mapping/analysis-all-23.json +222 -0
  433. chronaxis/guide/en/fields/mapping/analysis-all-24.json +231 -0
  434. chronaxis/guide/en/fields/mapping/analysis-all-25.json +225 -0
  435. chronaxis/guide/en/fields/mapping/analysis-all-26.json +230 -0
  436. chronaxis/guide/en/fields/mapping/analysis-all-27.json +228 -0
  437. chronaxis/guide/en/fields/mapping/analysis-all-28.json +230 -0
  438. chronaxis/guide/en/fields/mapping/analysis-all-29.json +223 -0
  439. chronaxis/guide/en/fields/mapping/analysis-all-3.json +318 -0
  440. chronaxis/guide/en/fields/mapping/analysis-all-30.json +233 -0
  441. chronaxis/guide/en/fields/mapping/analysis-all-31.json +218 -0
  442. chronaxis/guide/en/fields/mapping/analysis-all-32.json +239 -0
  443. chronaxis/guide/en/fields/mapping/analysis-all-33.json +233 -0
  444. chronaxis/guide/en/fields/mapping/analysis-all-34.json +225 -0
  445. chronaxis/guide/en/fields/mapping/analysis-all-35.json +228 -0
  446. chronaxis/guide/en/fields/mapping/analysis-all-36.json +226 -0
  447. chronaxis/guide/en/fields/mapping/analysis-all-37.json +244 -0
  448. chronaxis/guide/en/fields/mapping/analysis-all-38.json +326 -0
  449. chronaxis/guide/en/fields/mapping/analysis-all-39.json +299 -0
  450. chronaxis/guide/en/fields/mapping/analysis-all-4.json +297 -0
  451. chronaxis/guide/en/fields/mapping/analysis-all-40.json +311 -0
  452. chronaxis/guide/en/fields/mapping/analysis-all-41.json +310 -0
  453. chronaxis/guide/en/fields/mapping/analysis-all-42.json +346 -0
  454. chronaxis/guide/en/fields/mapping/analysis-all-43.json +267 -0
  455. chronaxis/guide/en/fields/mapping/analysis-all-44.json +327 -0
  456. chronaxis/guide/en/fields/mapping/analysis-all-45.json +279 -0
  457. chronaxis/guide/en/fields/mapping/analysis-all-46.json +327 -0
  458. chronaxis/guide/en/fields/mapping/analysis-all-47.json +312 -0
  459. chronaxis/guide/en/fields/mapping/analysis-all-48.json +294 -0
  460. chronaxis/guide/en/fields/mapping/analysis-all-49.json +253 -0
  461. chronaxis/guide/en/fields/mapping/analysis-all-5.json +312 -0
  462. chronaxis/guide/en/fields/mapping/analysis-all-50.json +346 -0
  463. chronaxis/guide/en/fields/mapping/analysis-all-51.json +324 -0
  464. chronaxis/guide/en/fields/mapping/analysis-all-52.json +335 -0
  465. chronaxis/guide/en/fields/mapping/analysis-all-53.json +317 -0
  466. chronaxis/guide/en/fields/mapping/analysis-all-54.json +316 -0
  467. chronaxis/guide/en/fields/mapping/analysis-all-55.json +302 -0
  468. chronaxis/guide/en/fields/mapping/analysis-all-56.json +319 -0
  469. chronaxis/guide/en/fields/mapping/analysis-all-57.json +334 -0
  470. chronaxis/guide/en/fields/mapping/analysis-all-58.json +333 -0
  471. chronaxis/guide/en/fields/mapping/analysis-all-59.json +359 -0
  472. chronaxis/guide/en/fields/mapping/analysis-all-6.json +327 -0
  473. chronaxis/guide/en/fields/mapping/analysis-all-60.json +303 -0
  474. chronaxis/guide/en/fields/mapping/analysis-all-61.json +326 -0
  475. chronaxis/guide/en/fields/mapping/analysis-all-62.json +301 -0
  476. chronaxis/guide/en/fields/mapping/analysis-all-63.json +326 -0
  477. chronaxis/guide/en/fields/mapping/analysis-all-64.json +367 -0
  478. chronaxis/guide/en/fields/mapping/analysis-all-65.json +334 -0
  479. chronaxis/guide/en/fields/mapping/analysis-all-66.json +358 -0
  480. chronaxis/guide/en/fields/mapping/analysis-all-67.json +349 -0
  481. chronaxis/guide/en/fields/mapping/analysis-all-68.json +331 -0
  482. chronaxis/guide/en/fields/mapping/analysis-all-69.json +304 -0
  483. chronaxis/guide/en/fields/mapping/analysis-all-7.json +303 -0
  484. chronaxis/guide/en/fields/mapping/analysis-all-70.json +349 -0
  485. chronaxis/guide/en/fields/mapping/analysis-all-71.json +288 -0
  486. chronaxis/guide/en/fields/mapping/analysis-all-72.json +316 -0
  487. chronaxis/guide/en/fields/mapping/analysis-all-73.json +266 -0
  488. chronaxis/guide/en/fields/mapping/analysis-all-74.json +227 -0
  489. chronaxis/guide/en/fields/mapping/analysis-all-75.json +239 -0
  490. chronaxis/guide/en/fields/mapping/analysis-all-76.json +274 -0
  491. chronaxis/guide/en/fields/mapping/analysis-all-77.json +380 -0
  492. chronaxis/guide/en/fields/mapping/analysis-all-78.json +313 -0
  493. chronaxis/guide/en/fields/mapping/analysis-all-79.json +338 -0
  494. chronaxis/guide/en/fields/mapping/analysis-all-8.json +292 -0
  495. chronaxis/guide/en/fields/mapping/analysis-all-80.json +304 -0
  496. chronaxis/guide/en/fields/mapping/analysis-all-81.json +140 -0
  497. chronaxis/guide/en/fields/mapping/analysis-all-9.json +332 -0
  498. chronaxis/guide/en/fields/mapping/io_policy-all-1.json +19 -0
  499. chronaxis/guide/en/fields/mapping/mapping_version-all-1.json +19 -0
  500. chronaxis/guide/en/fields/mapping/path_base-all-1.json +19 -0
  501. chronaxis/guide/en/fields/mapping/sections-all-1.json +402 -0
  502. chronaxis/guide/en/fields/mapping/sections-all-2.json +232 -0
  503. chronaxis/guide/en/semantics.md +70 -0
  504. chronaxis/guide/en/tasks.json +290 -0
  505. chronaxis/guide/en/workflow.md +41 -0
  506. chronaxis/guide/examples/analysis-imports.yaml +22 -0
  507. chronaxis/guide/examples/analysis.yaml +23 -0
  508. chronaxis/guide/examples/batch-minimal.yaml +3 -0
  509. chronaxis/guide/examples/conditional-energy.yaml +36 -0
  510. chronaxis/guide/examples/data/activity.csv +6 -0
  511. chronaxis/guide/examples/data/can/activity.asc +11 -0
  512. chronaxis/guide/examples/data/can/calculation-minimal.asc +6 -0
  513. chronaxis/guide/examples/data/can/conditional-energy/part-1.asc +92 -0
  514. chronaxis/guide/examples/data/can/conditional-energy/part-2.asc +36 -0
  515. chronaxis/guide/examples/data/can/conditional-energy/signals.dbc +10 -0
  516. chronaxis/guide/examples/data/can/execution-comparison.asc +12 -0
  517. chronaxis/guide/examples/data/can/execution-report.asc +4 -0
  518. chronaxis/guide/examples/data/can/expression-extended.asc +11 -0
  519. chronaxis/guide/examples/data/can/interval-actual.asc +6 -0
  520. chronaxis/guide/examples/data/can/preset-charge-energy.asc +15 -0
  521. chronaxis/guide/examples/data/can/preset-charge-minimal.asc +11 -0
  522. chronaxis/guide/examples/data/can/preset-command-automatic.asc +11 -0
  523. chronaxis/guide/examples/data/can/preset-fault-context.asc +7 -0
  524. chronaxis/guide/examples/data/can/preset-threshold-delay.asc +7 -0
  525. chronaxis/guide/examples/data/can/preset-threshold-partial.asc +7 -0
  526. chronaxis/guide/examples/data/can/quality.asc +6 -0
  527. chronaxis/guide/examples/data/can/quickstart-parts/part1.asc +4 -0
  528. chronaxis/guide/examples/data/can/quickstart-parts/part2.asc +3 -0
  529. chronaxis/guide/examples/data/can/quickstart.asc +6 -0
  530. chronaxis/guide/examples/data/can/rule-condition_duration-extended.asc +35 -0
  531. chronaxis/guide/examples/data/can/rule-condition_duration-minimal.asc +19 -0
  532. chronaxis/guide/examples/data/can/rule-debounce-extended.asc +19 -0
  533. chronaxis/guide/examples/data/can/rule-falling_edge-extended.asc +35 -0
  534. chronaxis/guide/examples/data/can/rule-hysteresis-extended.asc +19 -0
  535. chronaxis/guide/examples/data/can/rule-start_end-extended.asc +35 -0
  536. chronaxis/guide/examples/data/can/rule-start_only-extended.asc +19 -0
  537. chronaxis/guide/examples/data/can/rule-window_delta-extended.asc +19 -0
  538. chronaxis/guide/examples/data/can/sequence-outcomes.asc +19 -0
  539. chronaxis/guide/examples/data/can/signal-types.asc +13 -0
  540. chronaxis/guide/examples/data/can/start-end.asc +30 -0
  541. chronaxis/guide/examples/data/can/teaching-base.asc +58 -0
  542. chronaxis/guide/examples/data/can/teaching.dbc +53 -0
  543. chronaxis/guide/examples/data/joint-current.csv +5 -0
  544. chronaxis/guide/examples/data/joint.asc +5 -0
  545. chronaxis/guide/examples/data/joint.dbc +7 -0
  546. chronaxis/guide/examples/data/message-clean.asc +6 -0
  547. chronaxis/guide/examples/data/message-direction.asc +7 -0
  548. chronaxis/guide/examples/data/message-direction.dbc +7 -0
  549. chronaxis/guide/examples/data/power.blf +0 -0
  550. chronaxis/guide/examples/data/power.dbc +6 -0
  551. chronaxis/guide/examples/data/quality.csv +5 -0
  552. chronaxis/guide/examples/data/raw-can-example.csv +5 -0
  553. chronaxis/guide/examples/data/signal-types.csv +5 -0
  554. chronaxis/guide/examples/data/signals.csv +6 -0
  555. chronaxis/guide/examples/data/timing.asc +6 -0
  556. chronaxis/guide/examples/data/timing.dbc +11 -0
  557. chronaxis/guide/examples/export-can-minimal.yaml +24 -0
  558. chronaxis/guide/examples/input-csv-minimal.yaml +23 -0
  559. chronaxis/guide/examples/preset-charge-energy.yaml +41 -0
  560. chronaxis/guide/examples/preset-charge-minimal.yaml +31 -0
  561. chronaxis/guide/examples/preset-fault-context.yaml +27 -0
  562. chronaxis/guide/examples/quality.yaml +19 -0
  563. chronaxis/guide/examples/sequence-outcomes.yaml +39 -0
  564. chronaxis/guide/examples/shared/definitions.yaml +14 -0
  565. chronaxis/guide/examples/signal-enum-minimal.yaml +19 -0
  566. chronaxis/guide/examples/signal-number-conversion.yaml +24 -0
  567. chronaxis/guide/examples/window-merged.yaml +28 -0
  568. chronaxis/guide/fields/analysis/calculations-all-1.json +360 -0
  569. chronaxis/guide/fields/analysis/calculations-all-2.json +299 -0
  570. chronaxis/guide/fields/analysis/calculations-all-3.json +70 -0
  571. chronaxis/guide/fields/analysis/config_version-all-1.json +24 -0
  572. chronaxis/guide/fields/analysis/dataset-all-1.json +344 -0
  573. chronaxis/guide/fields/analysis/derived-all-1.json +147 -0
  574. chronaxis/guide/fields/analysis/diagnostics-all-1.json +69 -0
  575. chronaxis/guide/fields/analysis/execution-all-1.json +167 -0
  576. chronaxis/guide/fields/analysis/imports-all-1.json +39 -0
  577. chronaxis/guide/fields/analysis/intervals-all-1.json +173 -0
  578. chronaxis/guide/fields/analysis/message_calculations-all-1.json +360 -0
  579. chronaxis/guide/fields/analysis/message_calculations-all-2.json +255 -0
  580. chronaxis/guide/fields/analysis/metadata-all-1.json +24 -0
  581. chronaxis/guide/fields/analysis/outputs-all-1.json +349 -0
  582. chronaxis/guide/fields/analysis/outputs-all-2.json +302 -0
  583. chronaxis/guide/fields/analysis/outputs-all-3.json +321 -0
  584. chronaxis/guide/fields/analysis/outputs-all-4.json +253 -0
  585. chronaxis/guide/fields/analysis/outputs-all-5.json +244 -0
  586. chronaxis/guide/fields/analysis/outputs-all-6.json +199 -0
  587. chronaxis/guide/fields/analysis/overrides-all-1.json +104 -0
  588. chronaxis/guide/fields/analysis/presets-charge_session-1.json +398 -0
  589. chronaxis/guide/fields/analysis/presets-charge_session-2.json +114 -0
  590. chronaxis/guide/fields/analysis/presets-command_response-1.json +376 -0
  591. chronaxis/guide/fields/analysis/presets-fault_context-1.json +285 -0
  592. chronaxis/guide/fields/analysis/presets-threshold_excursion-1.json +317 -0
  593. chronaxis/guide/fields/analysis/rules-condition_duration-1.json +344 -0
  594. chronaxis/guide/fields/analysis/rules-condition_duration-2.json +27 -0
  595. chronaxis/guide/fields/analysis/rules-debounce-1.json +335 -0
  596. chronaxis/guide/fields/analysis/rules-falling_edge-1.json +317 -0
  597. chronaxis/guide/fields/analysis/rules-hysteresis-1.json +334 -0
  598. chronaxis/guide/fields/analysis/rules-hysteresis-2.json +27 -0
  599. chronaxis/guide/fields/analysis/rules-rising_edge-1.json +317 -0
  600. chronaxis/guide/fields/analysis/rules-start_end-1.json +349 -0
  601. chronaxis/guide/fields/analysis/rules-start_end-2.json +44 -0
  602. chronaxis/guide/fields/analysis/rules-start_only-1.json +334 -0
  603. chronaxis/guide/fields/analysis/rules-window_delta-1.json +356 -0
  604. chronaxis/guide/fields/analysis/rules-window_delta-2.json +78 -0
  605. chronaxis/guide/fields/analysis/sequences-all-1.json +394 -0
  606. chronaxis/guide/fields/analysis/sequences-all-2.json +54 -0
  607. chronaxis/guide/fields/analysis/signals-variant-1-1.json +349 -0
  608. chronaxis/guide/fields/analysis/signals-variant-1-2.json +297 -0
  609. chronaxis/guide/fields/analysis/signals-variant-1-3.json +340 -0
  610. chronaxis/guide/fields/analysis/signals-variant-1-4.json +175 -0
  611. chronaxis/guide/fields/analysis/signals-variant-2-1.json +327 -0
  612. chronaxis/guide/fields/analysis/signals-variant-2-2.json +335 -0
  613. chronaxis/guide/fields/analysis/signals-variant-2-3.json +289 -0
  614. chronaxis/guide/fields/analysis/signals-variant-2-4.json +270 -0
  615. chronaxis/guide/fields/analysis/sources-can_asc-1.json +318 -0
  616. chronaxis/guide/fields/analysis/sources-can_asc-2.json +310 -0
  617. chronaxis/guide/fields/analysis/sources-can_asc-3.json +311 -0
  618. chronaxis/guide/fields/analysis/sources-can_asc-4.json +69 -0
  619. chronaxis/guide/fields/analysis/sources-can_blf-1.json +317 -0
  620. chronaxis/guide/fields/analysis/sources-can_blf-2.json +310 -0
  621. chronaxis/guide/fields/analysis/sources-can_blf-3.json +317 -0
  622. chronaxis/guide/fields/analysis/sources-memory-1.json +347 -0
  623. chronaxis/guide/fields/analysis/sources-memory-2.json +110 -0
  624. chronaxis/guide/fields/analysis/sources-raw_can_csv-1.json +330 -0
  625. chronaxis/guide/fields/analysis/sources-raw_can_csv-10.json +233 -0
  626. chronaxis/guide/fields/analysis/sources-raw_can_csv-11.json +225 -0
  627. chronaxis/guide/fields/analysis/sources-raw_can_csv-12.json +228 -0
  628. chronaxis/guide/fields/analysis/sources-raw_can_csv-13.json +226 -0
  629. chronaxis/guide/fields/analysis/sources-raw_can_csv-14.json +230 -0
  630. chronaxis/guide/fields/analysis/sources-raw_can_csv-15.json +227 -0
  631. chronaxis/guide/fields/analysis/sources-raw_can_csv-16.json +230 -0
  632. chronaxis/guide/fields/analysis/sources-raw_can_csv-17.json +238 -0
  633. chronaxis/guide/fields/analysis/sources-raw_can_csv-18.json +239 -0
  634. chronaxis/guide/fields/analysis/sources-raw_can_csv-19.json +233 -0
  635. chronaxis/guide/fields/analysis/sources-raw_can_csv-2.json +310 -0
  636. chronaxis/guide/fields/analysis/sources-raw_can_csv-20.json +242 -0
  637. chronaxis/guide/fields/analysis/sources-raw_can_csv-21.json +230 -0
  638. chronaxis/guide/fields/analysis/sources-raw_can_csv-22.json +228 -0
  639. chronaxis/guide/fields/analysis/sources-raw_can_csv-23.json +230 -0
  640. chronaxis/guide/fields/analysis/sources-raw_can_csv-24.json +223 -0
  641. chronaxis/guide/fields/analysis/sources-raw_can_csv-25.json +290 -0
  642. chronaxis/guide/fields/analysis/sources-raw_can_csv-26.json +131 -0
  643. chronaxis/guide/fields/analysis/sources-raw_can_csv-3.json +297 -0
  644. chronaxis/guide/fields/analysis/sources-raw_can_csv-4.json +226 -0
  645. chronaxis/guide/fields/analysis/sources-raw_can_csv-5.json +230 -0
  646. chronaxis/guide/fields/analysis/sources-raw_can_csv-6.json +227 -0
  647. chronaxis/guide/fields/analysis/sources-raw_can_csv-7.json +230 -0
  648. chronaxis/guide/fields/analysis/sources-raw_can_csv-8.json +238 -0
  649. chronaxis/guide/fields/analysis/sources-raw_can_csv-9.json +239 -0
  650. chronaxis/guide/fields/analysis/sources-signal_csv-1.json +331 -0
  651. chronaxis/guide/fields/analysis/sources-signal_csv-2.json +327 -0
  652. chronaxis/guide/fields/analysis/sources-signal_csv-3.json +295 -0
  653. chronaxis/guide/fields/analysis/sources-variant-6-1.json +319 -0
  654. chronaxis/guide/fields/analysis/sources-variant-6-2.json +327 -0
  655. chronaxis/guide/fields/analysis/sources-variant-6-3.json +314 -0
  656. chronaxis/guide/fields/analysis/sources-variant-6-4.json +91 -0
  657. chronaxis/guide/fields/analysis/windows-all-1.json +361 -0
  658. chronaxis/guide/fields/analysis/windows-all-2.json +187 -0
  659. chronaxis/guide/fields/batch/backend-all-1.json +26 -0
  660. chronaxis/guide/fields/batch/batch_version-all-1.json +22 -0
  661. chronaxis/guide/fields/batch/fail_fast-all-1.json +22 -0
  662. chronaxis/guide/fields/batch/inputs-all-1.json +161 -0
  663. chronaxis/guide/fields/batch/jobs-all-1.json +58 -0
  664. chronaxis/guide/fields/batch/process_count-all-1.json +23 -0
  665. chronaxis/guide/fields/batch/source-all-1.json +22 -0
  666. chronaxis/guide/fields/batch/template-all-1.json +22 -0
  667. chronaxis/guide/fields/definitions/derived-all-1.json +121 -0
  668. chronaxis/guide/fields/definitions/signals-all-1.json +336 -0
  669. chronaxis/guide/fields/definitions/signals-all-2.json +307 -0
  670. chronaxis/guide/fields/definitions/signals-all-3.json +305 -0
  671. chronaxis/guide/fields/definitions/signals-all-4.json +352 -0
  672. chronaxis/guide/fields/definitions/signals-all-5.json +311 -0
  673. chronaxis/guide/fields/definitions/signals-all-6.json +254 -0
  674. chronaxis/guide/fields/definitions/signals-all-7.json +88 -0
  675. chronaxis/guide/fields/definitions/sources-all-1.json +332 -0
  676. chronaxis/guide/fields/definitions/sources-all-10.json +307 -0
  677. chronaxis/guide/fields/definitions/sources-all-11.json +280 -0
  678. chronaxis/guide/fields/definitions/sources-all-12.json +209 -0
  679. chronaxis/guide/fields/definitions/sources-all-13.json +219 -0
  680. chronaxis/guide/fields/definitions/sources-all-14.json +213 -0
  681. chronaxis/guide/fields/definitions/sources-all-15.json +212 -0
  682. chronaxis/guide/fields/definitions/sources-all-16.json +232 -0
  683. chronaxis/guide/fields/definitions/sources-all-17.json +213 -0
  684. chronaxis/guide/fields/definitions/sources-all-18.json +212 -0
  685. chronaxis/guide/fields/definitions/sources-all-19.json +217 -0
  686. chronaxis/guide/fields/definitions/sources-all-2.json +336 -0
  687. chronaxis/guide/fields/definitions/sources-all-20.json +228 -0
  688. chronaxis/guide/fields/definitions/sources-all-21.json +212 -0
  689. chronaxis/guide/fields/definitions/sources-all-22.json +232 -0
  690. chronaxis/guide/fields/definitions/sources-all-23.json +213 -0
  691. chronaxis/guide/fields/definitions/sources-all-24.json +212 -0
  692. chronaxis/guide/fields/definitions/sources-all-25.json +217 -0
  693. chronaxis/guide/fields/definitions/sources-all-26.json +228 -0
  694. chronaxis/guide/fields/definitions/sources-all-27.json +212 -0
  695. chronaxis/guide/fields/definitions/sources-all-28.json +217 -0
  696. chronaxis/guide/fields/definitions/sources-all-29.json +227 -0
  697. chronaxis/guide/fields/definitions/sources-all-3.json +306 -0
  698. chronaxis/guide/fields/definitions/sources-all-30.json +333 -0
  699. chronaxis/guide/fields/definitions/sources-all-31.json +302 -0
  700. chronaxis/guide/fields/definitions/sources-all-32.json +319 -0
  701. chronaxis/guide/fields/definitions/sources-all-33.json +89 -0
  702. chronaxis/guide/fields/definitions/sources-all-4.json +336 -0
  703. chronaxis/guide/fields/definitions/sources-all-5.json +313 -0
  704. chronaxis/guide/fields/definitions/sources-all-6.json +292 -0
  705. chronaxis/guide/fields/definitions/sources-all-7.json +319 -0
  706. chronaxis/guide/fields/definitions/sources-all-8.json +315 -0
  707. chronaxis/guide/fields/definitions/sources-all-9.json +318 -0
  708. chronaxis/guide/fields/index.json +3432 -0
  709. chronaxis/guide/fields/mapping/aliases-all-1.json +91 -0
  710. chronaxis/guide/fields/mapping/analysis-all-1.json +382 -0
  711. chronaxis/guide/fields/mapping/analysis-all-10.json +307 -0
  712. chronaxis/guide/fields/mapping/analysis-all-11.json +311 -0
  713. chronaxis/guide/fields/mapping/analysis-all-12.json +329 -0
  714. chronaxis/guide/fields/mapping/analysis-all-13.json +294 -0
  715. chronaxis/guide/fields/mapping/analysis-all-14.json +311 -0
  716. chronaxis/guide/fields/mapping/analysis-all-15.json +280 -0
  717. chronaxis/guide/fields/mapping/analysis-all-16.json +227 -0
  718. chronaxis/guide/fields/mapping/analysis-all-17.json +230 -0
  719. chronaxis/guide/fields/mapping/analysis-all-18.json +221 -0
  720. chronaxis/guide/fields/mapping/analysis-all-19.json +237 -0
  721. chronaxis/guide/fields/mapping/analysis-all-2.json +342 -0
  722. chronaxis/guide/fields/mapping/analysis-all-20.json +233 -0
  723. chronaxis/guide/fields/mapping/analysis-all-21.json +244 -0
  724. chronaxis/guide/fields/mapping/analysis-all-22.json +228 -0
  725. chronaxis/guide/fields/mapping/analysis-all-23.json +226 -0
  726. chronaxis/guide/fields/mapping/analysis-all-24.json +230 -0
  727. chronaxis/guide/fields/mapping/analysis-all-25.json +227 -0
  728. chronaxis/guide/fields/mapping/analysis-all-26.json +230 -0
  729. chronaxis/guide/fields/mapping/analysis-all-27.json +221 -0
  730. chronaxis/guide/fields/mapping/analysis-all-28.json +237 -0
  731. chronaxis/guide/fields/mapping/analysis-all-29.json +233 -0
  732. chronaxis/guide/fields/mapping/analysis-all-3.json +322 -0
  733. chronaxis/guide/fields/mapping/analysis-all-30.json +244 -0
  734. chronaxis/guide/fields/mapping/analysis-all-31.json +228 -0
  735. chronaxis/guide/fields/mapping/analysis-all-32.json +226 -0
  736. chronaxis/guide/fields/mapping/analysis-all-33.json +230 -0
  737. chronaxis/guide/fields/mapping/analysis-all-34.json +227 -0
  738. chronaxis/guide/fields/mapping/analysis-all-35.json +230 -0
  739. chronaxis/guide/fields/mapping/analysis-all-36.json +221 -0
  740. chronaxis/guide/fields/mapping/analysis-all-37.json +291 -0
  741. chronaxis/guide/fields/mapping/analysis-all-38.json +315 -0
  742. chronaxis/guide/fields/mapping/analysis-all-39.json +304 -0
  743. chronaxis/guide/fields/mapping/analysis-all-4.json +312 -0
  744. chronaxis/guide/fields/mapping/analysis-all-40.json +307 -0
  745. chronaxis/guide/fields/mapping/analysis-all-41.json +292 -0
  746. chronaxis/guide/fields/mapping/analysis-all-42.json +333 -0
  747. chronaxis/guide/fields/mapping/analysis-all-43.json +296 -0
  748. chronaxis/guide/fields/mapping/analysis-all-44.json +322 -0
  749. chronaxis/guide/fields/mapping/analysis-all-45.json +298 -0
  750. chronaxis/guide/fields/mapping/analysis-all-46.json +347 -0
  751. chronaxis/guide/fields/mapping/analysis-all-47.json +302 -0
  752. chronaxis/guide/fields/mapping/analysis-all-48.json +263 -0
  753. chronaxis/guide/fields/mapping/analysis-all-49.json +301 -0
  754. chronaxis/guide/fields/mapping/analysis-all-5.json +313 -0
  755. chronaxis/guide/fields/mapping/analysis-all-50.json +336 -0
  756. chronaxis/guide/fields/mapping/analysis-all-51.json +335 -0
  757. chronaxis/guide/fields/mapping/analysis-all-52.json +335 -0
  758. chronaxis/guide/fields/mapping/analysis-all-53.json +334 -0
  759. chronaxis/guide/fields/mapping/analysis-all-54.json +339 -0
  760. chronaxis/guide/fields/mapping/analysis-all-55.json +335 -0
  761. chronaxis/guide/fields/mapping/analysis-all-56.json +336 -0
  762. chronaxis/guide/fields/mapping/analysis-all-57.json +335 -0
  763. chronaxis/guide/fields/mapping/analysis-all-58.json +333 -0
  764. chronaxis/guide/fields/mapping/analysis-all-59.json +325 -0
  765. chronaxis/guide/fields/mapping/analysis-all-6.json +323 -0
  766. chronaxis/guide/fields/mapping/analysis-all-60.json +334 -0
  767. chronaxis/guide/fields/mapping/analysis-all-61.json +311 -0
  768. chronaxis/guide/fields/mapping/analysis-all-62.json +289 -0
  769. chronaxis/guide/fields/mapping/analysis-all-63.json +383 -0
  770. chronaxis/guide/fields/mapping/analysis-all-64.json +357 -0
  771. chronaxis/guide/fields/mapping/analysis-all-65.json +375 -0
  772. chronaxis/guide/fields/mapping/analysis-all-66.json +351 -0
  773. chronaxis/guide/fields/mapping/analysis-all-67.json +346 -0
  774. chronaxis/guide/fields/mapping/analysis-all-68.json +317 -0
  775. chronaxis/guide/fields/mapping/analysis-all-69.json +313 -0
  776. chronaxis/guide/fields/mapping/analysis-all-7.json +306 -0
  777. chronaxis/guide/fields/mapping/analysis-all-70.json +326 -0
  778. chronaxis/guide/fields/mapping/analysis-all-71.json +316 -0
  779. chronaxis/guide/fields/mapping/analysis-all-72.json +264 -0
  780. chronaxis/guide/fields/mapping/analysis-all-73.json +228 -0
  781. chronaxis/guide/fields/mapping/analysis-all-74.json +241 -0
  782. chronaxis/guide/fields/mapping/analysis-all-75.json +273 -0
  783. chronaxis/guide/fields/mapping/analysis-all-76.json +382 -0
  784. chronaxis/guide/fields/mapping/analysis-all-77.json +328 -0
  785. chronaxis/guide/fields/mapping/analysis-all-78.json +338 -0
  786. chronaxis/guide/fields/mapping/analysis-all-79.json +304 -0
  787. chronaxis/guide/fields/mapping/analysis-all-8.json +309 -0
  788. chronaxis/guide/fields/mapping/analysis-all-80.json +140 -0
  789. chronaxis/guide/fields/mapping/analysis-all-9.json +329 -0
  790. chronaxis/guide/fields/mapping/io_policy-all-1.json +19 -0
  791. chronaxis/guide/fields/mapping/mapping_version-all-1.json +19 -0
  792. chronaxis/guide/fields/mapping/path_base-all-1.json +19 -0
  793. chronaxis/guide/fields/mapping/sections-all-1.json +402 -0
  794. chronaxis/guide/fields/mapping/sections-all-2.json +232 -0
  795. chronaxis/guide/lookup.py +90 -0
  796. chronaxis/guide/manifest.json +614 -0
  797. chronaxis/guide/run_analysis.py +34 -0
  798. chronaxis/guide/schemas/analysis.schema.json +8451 -0
  799. chronaxis/guide/schemas/batch-v1.schema.json +172 -0
  800. chronaxis/guide/schemas/definitions.schema.json +29 -0
  801. chronaxis/guide/schemas/legacy-import-v1.schema.json +143 -0
  802. chronaxis/guide/semantics.md +62 -0
  803. chronaxis/guide/tasks.json +290 -0
  804. chronaxis/guide/workflow.md +38 -0
  805. chronaxis/legacy/__init__.py +46 -0
  806. chronaxis/legacy/batch_read.py +412 -0
  807. chronaxis/legacy/batch_validation.py +134 -0
  808. chronaxis/legacy/batch_wire.py +264 -0
  809. chronaxis/legacy/batch_worker.py +417 -0
  810. chronaxis/legacy/binding.py +154 -0
  811. chronaxis/legacy/dbc_cycles.py +47 -0
  812. chronaxis/legacy/decode_policy.py +28 -0
  813. chronaxis/legacy/disjunction.py +79 -0
  814. chronaxis/legacy/export_worker.py +147 -0
  815. chronaxis/legacy/export_write.py +378 -0
  816. chronaxis/legacy/message_store.py +562 -0
  817. chronaxis/legacy/process_read.py +526 -0
  818. chronaxis/legacy/raw_store.py +341 -0
  819. chronaxis/legacy/records.py +709 -0
  820. chronaxis/legacy/required_records.py +122 -0
  821. chronaxis/legacy/sum.py +403 -0
  822. chronaxis/legacy/sum_numpy.py +43 -0
  823. chronaxis/legacy/updates.py +277 -0
  824. chronaxis/legacy/vendor/sclicer_functions_v1/can_processor.py +138 -0
  825. chronaxis/legacy/vendor/sclicer_functions_v1/file_processor.py +218 -0
  826. chronaxis/legacy/vendor/sclicer_functions_v1/utils.py +447 -0
  827. chronaxis/legacy/worker.py +352 -0
  828. chronaxis/migration/__init__.py +11 -0
  829. chronaxis/migration/api.py +270 -0
  830. chronaxis/migration/ini.py +110 -0
  831. chronaxis/migration/legacy_sum.py +304 -0
  832. chronaxis/migration/models.py +83 -0
  833. chronaxis/migration/publication.py +230 -0
  834. chronaxis/migration/sclicer.py +241 -0
  835. chronaxis/migration/slope.py +78 -0
  836. chronaxis/migration/start_end.py +48 -0
  837. chronaxis/planning/__init__.py +19 -0
  838. chronaxis/planning/channels.py +30 -0
  839. chronaxis/planning/checks.py +447 -0
  840. chronaxis/planning/config_groups.py +215 -0
  841. chronaxis/planning/dbc_defaults.py +88 -0
  842. chronaxis/planning/export_options.py +247 -0
  843. chronaxis/planning/input_defaults.py +62 -0
  844. chronaxis/planning/input_paths.py +124 -0
  845. chronaxis/planning/input_requirements.py +250 -0
  846. chronaxis/planning/inputs.py +306 -0
  847. chronaxis/planning/intervals.py +242 -0
  848. chronaxis/planning/legacy_execution.py +38 -0
  849. chronaxis/planning/message_calculations.py +171 -0
  850. chronaxis/planning/models.py +369 -0
  851. chronaxis/planning/nodes.py +355 -0
  852. chronaxis/planning/plan.py +294 -0
  853. chronaxis/planning/preset_models.py +211 -0
  854. chronaxis/planning/record_execution.py +76 -0
  855. chronaxis/planning/reports.py +523 -0
  856. chronaxis/planning/sequences.py +91 -0
  857. chronaxis/planning/signal_groups.py +61 -0
  858. chronaxis/planning/signal_validity.py +46 -0
  859. chronaxis/planning/text_inputs.py +110 -0
  860. chronaxis/presets.py +270 -0
  861. chronaxis/results/__init__.py +34 -0
  862. chronaxis/results/analysis_outcome.py +67 -0
  863. chronaxis/results/artifact_exports.py +212 -0
  864. chronaxis/results/binding_metadata.py +54 -0
  865. chronaxis/results/budget.py +138 -0
  866. chronaxis/results/can_metadata.py +247 -0
  867. chronaxis/results/codec.py +246 -0
  868. chronaxis/results/errors.py +25 -0
  869. chronaxis/results/export_files.py +216 -0
  870. chronaxis/results/frame_exports.py +299 -0
  871. chronaxis/results/frame_patch.py +186 -0
  872. chronaxis/results/frame_rebuild.py +458 -0
  873. chronaxis/results/frame_sort.py +223 -0
  874. chronaxis/results/input_diagnostics.py +51 -0
  875. chronaxis/results/manifest.py +343 -0
  876. chronaxis/results/merge_runs.py +207 -0
  877. chronaxis/results/owned_directory.py +32 -0
  878. chronaxis/results/raw_exports.py +689 -0
  879. chronaxis/results/readable.py +355 -0
  880. chronaxis/results/readable_format.py +94 -0
  881. chronaxis/results/result.py +734 -0
  882. chronaxis/results/rows.py +57 -0
  883. chronaxis/results/signal_exports.py +209 -0
  884. chronaxis/results/signal_grid.py +219 -0
  885. chronaxis/results/spool.py +421 -0
  886. chronaxis/results/summary.py +350 -0
  887. chronaxis/results/text_can_metadata.py +64 -0
  888. chronaxis/results/threshold_metadata.py +105 -0
  889. chronaxis/runner.py +121 -0
  890. chronaxis/sources/__init__.py +23 -0
  891. chronaxis/sources/asc.py +412 -0
  892. chronaxis/sources/blf.py +101 -0
  893. chronaxis/sources/can_spec.py +179 -0
  894. chronaxis/sources/can_updates.py +160 -0
  895. chronaxis/sources/csv_spec.py +133 -0
  896. chronaxis/sources/descriptions.py +65 -0
  897. chronaxis/sources/memory.py +299 -0
  898. chronaxis/sources/models.py +497 -0
  899. chronaxis/sources/packing.py +170 -0
  900. chronaxis/sources/protocol.py +221 -0
  901. chronaxis/sources/raw_can.py +62 -0
  902. chronaxis/sources/raw_csv.py +470 -0
  903. chronaxis/sources/raw_csv_layout.py +310 -0
  904. chronaxis/sources/signal_csv.py +608 -0
  905. chronaxis/sources/text_can_decode.py +421 -0
  906. chronaxis/sources/text_can_ref.py +48 -0
  907. chronaxis/sources/text_can_spec.py +61 -0
  908. chronaxis/timebase/__init__.py +19 -0
  909. chronaxis/timebase/conversion.py +364 -0
  910. chronaxis/timebase/numpy_ops.py +104 -0
  911. chronaxis/user_guide.py +81 -0
  912. chronaxis-0.1.0.dev0.dist-info/METADATA +172 -0
  913. chronaxis-0.1.0.dev0.dist-info/RECORD +917 -0
  914. chronaxis-0.1.0.dev0.dist-info/WHEEL +5 -0
  915. chronaxis-0.1.0.dev0.dist-info/entry_points.txt +2 -0
  916. chronaxis-0.1.0.dev0.dist-info/licenses/LICENSE +21 -0
  917. chronaxis-0.1.0.dev0.dist-info/top_level.txt +1 -0
chronaxis/cli.py ADDED
@@ -0,0 +1,193 @@
1
+ """提供计划检查、运行发布、独立批量与旧INI导入,复用各自公共接口。
2
+
3
+ 输入为命令行路径、模式及显式mapping;输出为新计划、原INI、迁移报告和简短
4
+ JSON摘要。转换失败仍可保存原文与失败报告,绝不返回部分可运行计划。
5
+ validate/explain只读取计划,输出共享AnalysisRunner报告,不打开数据/DBC或运行分析。
6
+ run才调用同一AnalysisRunner执行、write发布并关闭结果;完整完成后才打印成功摘要。
7
+ batch run调用同一批量API,打印状态计数,逐任务错误保存在batch_report.json。
8
+ 配置和参数错误退出2,文件/平台错误退出1,取消退出130,成功退出0。
9
+ --help及参数错误只需标准库;实际命令执行时才加载对应计划或发布模块。
10
+ """
11
+
12
+ import argparse
13
+ import json
14
+ import os
15
+ from pathlib import Path
16
+ import sys
17
+
18
+
19
+ def _parser() -> argparse.ArgumentParser:
20
+ """定义已交付命令,未知命令和缺参数由argparse定位。
21
+
22
+ 参数: 无。返回: ArgumentParser,不读取任何配置或来源。
23
+ 异常: 原参数构造错误传播;解析时的帮助/坏参数分别SystemExit(0/2)。
24
+ """
25
+ parser = argparse.ArgumentParser(prog='chronaxis', description='Chronaxis计划检查、分析与旧INI导入')
26
+ commands = parser.add_subparsers(dest='command', required=True)
27
+ guide = commands.add_parser('guide', help='显示可直接阅读的AI指南路径')
28
+ guide.add_argument('--language', choices=('zh', 'en'), default='zh', help='阅读入口语言,默认zh;不写文件')
29
+ guide.add_argument('--output', help='可选:另存完整双语ZIP;父目录须存在,目标不能已存在')
30
+ configuration = commands.add_parser('config', help='初始化及检查配置文件')
31
+ configuration_actions = configuration.add_subparsers(dest='config_command', required=True)
32
+ initialize = configuration_actions.add_parser('init', help='从合成场景生成完整新目录')
33
+ initialize.add_argument('scene', nargs='?', help='场景名;用--list查看可选场景')
34
+ initialize.add_argument('--list', action='store_true', help='列出全部场景,不写文件')
35
+ initialize.add_argument('--output', help='全新目录;父目录须已存在')
36
+ initialize.add_argument('--style', choices=('minimal','annotated'), default='annotated', help='默认完整注释版')
37
+ convert = configuration_actions.add_parser('convert', help='当前JSON/YAML互转,保持类型和值;不保留注释')
38
+ convert.add_argument('input', help='当前分析、批量或INI映射配置')
39
+ convert.add_argument('--output', required=True, help='新.json/.yaml/.yml文件;相对路径配置须写同目录')
40
+ resolve = configuration_actions.add_parser('resolve', help='展开有效配置,固定绝对路径;可选显示实际默认')
41
+ resolve.add_argument('input', help='当前分析、批量或INI映射配置')
42
+ resolve.add_argument('--output', help='可选全新JSON/YAML文件;省略时输出到终端')
43
+ resolve.add_argument('--format', choices=('json','yaml'), help='终端默认yaml;文件由扩展名确定')
44
+ resolve.add_argument('--defaults', action='store_true', help='写出适用的执行、输出、信号与规则等默认值')
45
+ # 来源报告只按请求生成,不混入可重新加载的resolve输出。
46
+ origins = configuration_actions.add_parser('origins', help='查看定义来自哪个配置文件,不读取业务输入')
47
+ origins.add_argument('input', help='当前分析、批量或INI映射配置')
48
+ origins.add_argument('--fields', action='store_true', help='列所有显式叶字段;默认列来源、信号和派生定义')
49
+ origins.add_argument('--format', choices=('text','json'), default='text', help='默认中文文本,json用于机器读取')
50
+ # 静态命令只接受配置和明确后端,不提供输出目录等会误导为已运行的选项。
51
+ for name, help_text in (('validate', '检查配置、绑定和当前执行能力'),
52
+ ('explain', '显示依赖、节点后端与预算声明')):
53
+ check = commands.add_parser(name, help=help_text)
54
+ check.add_argument('plan', help='分析计划YAML或JSON;来源相对路径按配置文件目录解释')
55
+ check.add_argument('--backend', choices=('reference', 'numpy'), default=None,
56
+ help='显式覆盖本次后端;省略则沿用计划声明')
57
+ check.add_argument('--format', choices=('text','json'), default='text',
58
+ help='默认显示易读说明;json用于程序读取')
59
+ # run只提供执行选择和新目录,数值、格式和业务声明继续来自同一个计划。
60
+ execute = commands.add_parser('run', help='分析计划并发布到全新输出目录')
61
+ execute.add_argument('plan', help='分析计划YAML或JSON')
62
+ execute.add_argument('--output', required=True, help='全新输出目录,不覆盖已有文件或目录')
63
+ execute.add_argument('--work-dir', default=None, help='可选全新工作目录;省略沿AnalysisRunner唯一专用暂存')
64
+ execute.add_argument('--backend', choices=('reference', 'numpy'), default=None,
65
+ help='显式覆盖本次后端;省略沿用计划声明')
66
+ batch = commands.add_parser('batch', help='独立分析任务批量运行')
67
+ batch_actions = batch.add_subparsers(dest='batch_command', required=True)
68
+ batch_run = batch_actions.add_parser('run', help='执行批量YAML或JSON并保存逐任务状态')
69
+ batch_run.add_argument('plan', help='批量YAML或JSON,各任务计划路径相对此文件目录')
70
+ batch_run.add_argument('--output', required=True, help='全新批量输出目录')
71
+ batch_run.add_argument('--process-count', type=int, default=None, help='可选覆盖同时运行数,须为正整数')
72
+ legacy = commands.add_parser('legacy', help='旧配置迁移')
73
+ actions = legacy.add_subparsers(dest='legacy_command', required=True)
74
+ migrate = actions.add_parser('import', help='保留原INI,生成可校验计划及迁移报告')
75
+ migrate.add_argument('ini', help='原INI文件')
76
+ migrate.add_argument('--mode', required=True,
77
+ choices=('legacy_sum', 'sclicer_single', 'sclicer_start_only', 'sclicer_slope', 'sclicer_start_end'))
78
+ migrate.add_argument('--mapping', required=True, help='显式映射YAML或JSON,来源路径相对此文件目录')
79
+ migrate.add_argument('--output', required=True, help='新计划.json;原文/报告使用同名前缀,不覆盖已有目标')
80
+ return parser
81
+
82
+
83
+ def _brief(result, files) -> dict:
84
+ """生成固定摘要,不将全部原字段或warnings输出到控制台。
85
+
86
+ 参数: result为完整导入结果;files为已实际发布的固定路径模型。
87
+ 返回: 原生JSON对象,三路径为绝对str,转换失败plan为None。
88
+ 异常: 内部typed接口不符直接传播,不以自由反射吞掉错误。
89
+ """
90
+ issues = result.report.issues
91
+ return dict(status=result.report.status, plan=None if files.plan is None else str(files.plan),
92
+ original=str(files.original), report=str(files.report), device_label=result.report.device_label,
93
+ issue_count=len(issues), error_count=sum(item.level == 'error' for item in issues),
94
+ warning_count=sum(item.level == 'warning' for item in issues))
95
+
96
+
97
+ def _issue_text(issue) -> str:
98
+ """将首个错误压缩为可跳转位置,完整事实留在迁移报告。
99
+
100
+ 参数: issue为固定导入问题。返回: 一行文本,含来源/路径及存在的行列。
101
+ 异常: 内部字段类型错误传播,不截掉报告中的原始消息。
102
+ """
103
+ location = issue.origin + ':' + issue.path
104
+ if issue.line is not None:
105
+ location += ':' + str(issue.line)
106
+ if issue.column is not None:
107
+ location += ':' + str(issue.column)
108
+ return location + ' [' + issue.code + '] ' + issue.message.replace('\n', ' ')
109
+
110
+
111
+ def _run_import(arguments) -> int:
112
+ """调用真实两配置加载与计划最后发布,静态成功不代表数据运行通过。
113
+
114
+ 参数: arguments为argparse已经校验的legacy import参数。
115
+ 返回: 0为完整转换/发布成功,2为原配置整体拒绝且原文/报告已保存。
116
+ 异常: 文件/平台/取消/资源错误原样向main传播,保发布器恢复owner。
117
+ """
118
+ from .migration import load_legacy_ini
119
+ from .migration.publication import write_legacy_import
120
+ # 环境未声明时只标pending;CLI不把当前文件位置猜成home或work。
121
+ label = os.environ.get('CHRONAXIS_DEVICE_LABEL', '').strip() or 'pending'
122
+ ini, mapping = Path(arguments.ini).absolute(), Path(arguments.mapping).absolute()
123
+ result = load_legacy_ini(ini, mapping, mode=arguments.mode, device_label=label)
124
+ files = write_legacy_import(result, arguments.output, source_paths=(ini, mapping))
125
+ print(json.dumps(_brief(result, files), ensure_ascii=False, allow_nan=False))
126
+ if result.plan is None:
127
+ issue = next((item for item in result.report.issues if item.level == 'error'), None)
128
+ print('导入失败:' + (_issue_text(issue) if issue is not None else '配置不能整体转换'), file=sys.stderr)
129
+ return 2
130
+ return 0
131
+
132
+
133
+ def main(argv=None) -> int:
134
+ """执行共享CLI并给出固定退出码,完整事实保在报告和原异常中。
135
+
136
+ 参数: argv为参数字符串序列或None(使用进程参数)。
137
+ 返回: 0成功、2配置错误、1文件/平台错误、130取消。
138
+ 异常: argparse帮助/参数错误按标准抛SystemExit;MemoryError及内部编程错误不伪装配置错误。
139
+ 副作用: 导入读取两配置并发布;静态命令只读计划;run分析后发布到新目录。
140
+ """
141
+ arguments = _parser().parse_args(argv)
142
+ operation = {'legacy': '导入', 'guide': '资料读取'}.get(arguments.command, '计划')
143
+ try:
144
+ if arguments.command == 'guide':
145
+ # 默认只定位已经存在的README;显式output才生成独立副本。
146
+ from .user_guide import export_guide, guide_path
147
+ print(export_guide(arguments.output) if arguments.output else guide_path(arguments.language))
148
+ return 0
149
+ if arguments.command == 'config':
150
+ from .configuration.cli import run_configuration_cli
151
+ return run_configuration_cli(arguments)
152
+ if arguments.command == 'legacy':
153
+ return _run_import(arguments)
154
+ if arguments.command == 'batch':
155
+ from .batch.cli import run_batch_cli
156
+ return run_batch_cli(arguments)
157
+ # 帮助和参数错误先由argparse结束;只有实际计划命令才加载计划依赖。
158
+ from .analysis_cli import run_static, run_analysis
159
+ return run_analysis(arguments) if arguments.command == 'run' else run_static(arguments)
160
+ except KeyboardInterrupt:
161
+ # 发布器已尝试最小收尾并保恢复owner;CLI退出后系统还会关闭进程持有的FD。
162
+ if arguments.command == 'legacy':
163
+ message = '导入已取消;目标目录中的原文和迁移报告可用于核对已保存内容。'
164
+ elif arguments.command == 'run':
165
+ message = '分析已取消;输出可能已发布,请核对目标目录 ' + str(Path(arguments.output).absolute())
166
+ elif arguments.command == 'batch':
167
+ message = '批量操作已取消;请核对各任务结果和批量报告目录 ' + str(Path(arguments.output).absolute())
168
+ else:
169
+ message = '计划操作已取消。'
170
+ print(message, file=sys.stderr)
171
+ return 130
172
+ except NotImplementedError as error:
173
+ print(operation + '功能不可用:' + str(error), file=sys.stderr)
174
+ return 1
175
+ except OSError as error:
176
+ print(operation + '文件操作失败:' + str(error), file=sys.stderr)
177
+ return 1
178
+ except ValueError as error:
179
+ if arguments.command in ('run', 'batch'):
180
+ # run只把明确的配置异常归为2;未包装的内部ValueError仍保原异常传播。
181
+ from .planning.checks import PlanValidationError
182
+ if not isinstance(error, PlanValidationError):
183
+ raise
184
+ # 共享语法加载增加一层配置错误,仍沿有限原异常链区分真实文件失败。
185
+ from .analysis_cli import _cause_chain
186
+ file_error = any(isinstance(cause,OSError) for cause in _cause_chain(error))
187
+ if arguments.command in ('validate','explain') and arguments.format=='json':
188
+ from .planning.checks import PlanValidationError
189
+ if isinstance(error,PlanValidationError):
190
+ print(json.dumps(dict(valid=False,error=error.to_dict()),ensure_ascii=False,allow_nan=False))
191
+ return 1 if file_error else 2
192
+ print(operation + ('文件操作失败:' if file_error else '配置错误:') + str(error), file=sys.stderr)
193
+ return 1 if file_error else 2
@@ -0,0 +1,46 @@
1
+ """共享配置语法入口;只读指定文件,返回原生值和加载期位置,不读取业务输入。"""
2
+ from pathlib import Path
3
+ from types import MappingProxyType
4
+
5
+ from .models import ConfigurationDocument, ConfigurationError, ConfigurationLocation, field_path_text
6
+ from .json_parser import parse_json
7
+
8
+ __all__=['ConfigurationDocument','ConfigurationError','ConfigurationLocation',
9
+ 'field_path_text','parse_configuration','load_configuration']
10
+
11
+
12
+ def parse_configuration(text, *, format, source='<configuration>'):
13
+ """解析显式格式文本。参数: str文本、json/yaml格式、显示来源。返回: 文档。异常: 语法或参数错误。
14
+
15
+ 不替换环境变量或执行模板。UTF-8文件开头的BOM可选;字段原始字符串保留。
16
+ """
17
+ if type(text) is not str or type(source) is not str:
18
+ raise TypeError('配置内容和来源名称需要文本')
19
+ if type(format) is not str or format not in ('json','yaml'):
20
+ raise ConfigurationError(source,(),None,'unsupported_format','配置格式只支持json或yaml')
21
+ if text.startswith('\ufeff'):text=text[1:]
22
+ if format=='json':
23
+ data,locations=parse_json(text,source)
24
+ else:
25
+ from .yaml_parser import parse_yaml
26
+ data,locations=parse_yaml(text,source)
27
+ return ConfigurationDocument(data,source,format,MappingProxyType(locations))
28
+
29
+
30
+ def load_configuration(path):
31
+ """按.json/.yaml/.yml加载UTF-8文件。返回: 文档。异常: 定位读取/语法错误;取消原样传播。
32
+
33
+ 后缀不识别时不打开文件;读取结束即关闭句柄,再解析文本,不持有调用者输入文件。
34
+ """
35
+ if not isinstance(path,(str,Path)):
36
+ raise TypeError('配置路径需要Path或文本')
37
+ target=Path(path).absolute()
38
+ format={'.json':'json','.yaml':'yaml','.yml':'yaml'}.get(target.suffix.lower())
39
+ if format is None:
40
+ raise ConfigurationError(str(target),(),None,'unsupported_format','配置后缀需要.json、.yaml或.yml')
41
+ try:
42
+ with target.open('r',encoding='utf-8-sig') as stream:
43
+ text=stream.read()
44
+ except (OSError,UnicodeError) as error:
45
+ raise ConfigurationError(str(target),(),None,'load_error',str(error)) from error
46
+ return parse_configuration(text,format=format,source=str(target))
@@ -0,0 +1,41 @@
1
+ """配置辅助命令;复用同一模板及配置入口,不执行分析。"""
2
+ from .template_catalog import available_templates
3
+ from .initialization import initialize_configuration
4
+
5
+
6
+ def run_configuration_cli(arguments):
7
+ """执行已解析的配置命令。参数: argparse结果。返回: 退出码。异常: 配置/文件/取消上交CLI。
8
+
9
+ 初始化显示实际入口与合成预期;可运行不代表适合真实设备。
10
+ """
11
+ if arguments.config_command=='origins':
12
+ from .origins import configuration_origins,render_origins
13
+ import json
14
+ report=configuration_origins(arguments.input,fields=arguments.fields)
15
+ print(json.dumps(report,ensure_ascii=False,indent=2) if arguments.format=='json' else render_origins(report),
16
+ end='\n' if arguments.format=='json' else '')
17
+ return 0
18
+ if arguments.config_command=='convert':
19
+ from .file_tools import convert_configuration
20
+ path=convert_configuration(arguments.input,arguments.output)
21
+ print('已转换:'+str(path)+';配置类型和值保持,注释不保留。')
22
+ return 0
23
+ if arguments.config_command=='resolve':
24
+ from .resolution import resolve_configuration
25
+ result=resolve_configuration(arguments.input,output=arguments.output,format=arguments.format,defaults=arguments.defaults)
26
+ if arguments.output is None:print(result,end='')
27
+ else:print('已导出有效配置:'+str(result)+';路径固定为原输入的绝对位置。')
28
+ return 0
29
+ if arguments.list:
30
+ if arguments.scene is not None or arguments.output is not None:
31
+ raise ValueError('--list不能同时指定场景或输出目录')
32
+ for template in available_templates():print(template.name+' — '+template.title)
33
+ return 0
34
+ if arguments.scene is None or arguments.output is None:
35
+ raise ValueError('初始化需要场景名和--output新目录;用--list查看场景')
36
+ path=initialize_configuration(arguments.scene,arguments.output,style=arguments.style)
37
+ template=next(t for t in available_templates() if t.name==arguments.scene)
38
+ print('已生成合成场景:'+str(path))
39
+ print('预期:'+template.expected)
40
+ print('真实使用前请核实单位、方向、有效期和阈值。')
41
+ return 0
@@ -0,0 +1,107 @@
1
+ """为配置错误附上原文位置与有限的上下文;成功计划不保存此处的文档对象。
2
+
3
+ 这里只消费已解析的原生值,不重新读取配置或来源。字段路径采用带引号键的
4
+ JSON路径;不存在字段回指最近所属对象,不能给缺少的值捏造行列。
5
+ """
6
+ import json
7
+ import re
8
+
9
+ from .models import field_path_text
10
+
11
+
12
+ def field_path_parts(text):
13
+ """读取内部字段路径。参数: $开头文本。返回: tuple或无法定位时None。异常: 无。
14
+
15
+ 引号键用标准JSON解码,不执行表达式;组合诊断如$.signals/derived不能冒充字段。
16
+ """
17
+ if not isinstance(text,str) or not text.startswith('$'):
18
+ return None
19
+ parts=[]
20
+ position=1
21
+ while position<len(text):
22
+ if text[position]=='.':
23
+ match=re.match(r'[^.\[\]/]+',text[position+1:])
24
+ if match is None:
25
+ return None
26
+ parts.append(match[0])
27
+ position+=len(match[0])+1
28
+ elif text[position:position+2]=='["':
29
+ try:
30
+ key,end=json.JSONDecoder().raw_decode(text,position+1)
31
+ except ValueError:
32
+ return None
33
+ if type(key) is not str or text[end:end+1]!=']':
34
+ return None
35
+ parts.append(key)
36
+ position=end+1
37
+ else:
38
+ match=re.match(r'\[(0|[1-9][0-9]*)\]',text[position:])
39
+ if match is None:
40
+ return None
41
+ parts.append(int(match[1]))
42
+ position+=len(match[0])
43
+ return tuple(parts)
44
+
45
+
46
+ def child_path(path,key):
47
+ """追加一层真实键。参数: 字段路径/字符串键。返回: 无歧义路径。异常: 内部路径不合法。
48
+ """
49
+ return path+field_path_text((key,))[1:]
50
+
51
+
52
+ def value_preview(value):
53
+ """只显示有限值摘要。参数: JSON原生值。返回: 最多180字符。异常: 无。
54
+
55
+ 容器仅报类型/大小,防止错误输出整份配置、内存行或自由元数据。
56
+ """
57
+ if type(value) is dict:
58
+ return f'对象({len(value)}个字段)'
59
+ if type(value) is list:
60
+ return f'数组({len(value)}项)'
61
+ text=json.dumps(value,ensure_ascii=False,allow_nan=False)
62
+ return text if len(text)<=180 else text[:177]+'…'
63
+
64
+
65
+ def locate_error(error,document):
66
+ """给计划异常补充有限诊断字段。参数: 计划异常/原文档。返回: 同一异常。异常: 无。
67
+
68
+ 不保存document、原字典或位置表;只复制源码名、单一位置、对象名和短值。
69
+ """
70
+ # 导入器可能已经把异常定位到另一个文件;外层不得用主文件覆盖真实来源。
71
+ if error.source is not None:return error
72
+ parts=field_path_parts(error.path)
73
+ error.source=document.source
74
+ if parts is None:
75
+ error.refresh_text()
76
+ return error
77
+ error.location=document.location_for(parts)
78
+ current=document.data
79
+ name=None
80
+ labels={'signals':'信号','sources':'来源','rules':'规则','windows':'窗口',
81
+ 'calculations':'计算项','sequences':'序列','jobs':'任务','presets':'预设'}
82
+ label=next((labels[part] for part in parts if part in labels),'对象')
83
+ # 从根走向出错字段,最近的命名对象比根dataset更能解释该处声明。
84
+ missing=False
85
+ for part in (*parts,None):
86
+ if type(current) is dict:
87
+ candidate=current.get('name')
88
+ if type(candidate) is str:
89
+ name=candidate[:120]
90
+ if part is None:
91
+ break
92
+ if type(current) is dict and type(part) is str and part in current:
93
+ current=current[part]
94
+ elif type(current) is list and type(part) is int and part<len(current):
95
+ current=current[part]
96
+ else:
97
+ missing=True
98
+ break
99
+ error.object_name=None if name is None else label+' '+name
100
+ error.value_preview='未提供' if missing else value_preview(current)
101
+ origin=document.origin_for(parts)
102
+ if origin is not None:
103
+ error.source=origin.source
104
+ error.path=field_path_text(origin.field_path)
105
+ error.location=origin.location
106
+ error.refresh_text()
107
+ return error
@@ -0,0 +1,233 @@
1
+ """把已验证的分析声明讲成人可阅读的步骤;不加载来源、不展开运行时数据。
2
+
3
+ 文本与JSON报告使用同一计划和能力报告。这里仅翻译已知术语、格式化精确时间,
4
+ 并从原始声明区分显式设置与默认设置,不建立另一套配置默认值或执行规则。
5
+ """
6
+ from collections.abc import Mapping
7
+
8
+
9
+ OPERATIONS={
10
+ 'integral':'积分(按前值保持累计)',
11
+ 'sample_mean':'样本均值(每个有效样本权重相同)',
12
+ 'time_weighted_mean':'时间加权均值(按有效持续时间加权)',
13
+ 'sample_minimum':'有效样本最小值','sample_maximum':'有效样本最大值',
14
+ 'min_time':'有效时间区间内最小值','max_time':'有效时间区间内最大值',
15
+ 'duration':'条件成立的累计时长','select':'选择符合条件的记录',
16
+ }
17
+ RULES={'condition_duration':'条件持续成立','rising_edge':'由假变真的上升沿',
18
+ 'falling_edge':'由真变假的下降沿','start_only':'触发后保留固定窗口',
19
+ 'window_delta':'回看窗口内变化量','debounce':'条件去抖','hysteresis':'进入与退出使用不同条件',
20
+ 'start_end':'开始条件启动、结束条件停止'}
21
+ SOURCES={'memory':'配置中的内存数据','signal_csv':'已解码信号CSV',
22
+ 'can_blf':'CAN二进制BLF','can_asc':'CAN文本ASC','asc_or_blf':'CAN连续ASC/BLF','raw_can_csv':'原始CAN帧CSV'}
23
+
24
+
25
+ def time_text(nanoseconds):
26
+ """无损显示纳秒时长。参数: 整数或None。返回: 带单位文本。异常: 无。"""
27
+ if nanoseconds is None:
28
+ return '未设置'
29
+ for divisor,unit in ((10**9,'s'),(10**6,'ms'),(1000,'us')):
30
+ if nanoseconds and nanoseconds%divisor==0:
31
+ return str(nanoseconds//divisor)+unit
32
+ return str(nanoseconds)+'ns'
33
+
34
+
35
+ def _declared(plan,*parts):
36
+ """检查原声明是否包含字段。参数: 计划/路径。返回: bool。异常: 无;不取文件默认值。"""
37
+ current=plan.raw_config
38
+ for part in parts:
39
+ if isinstance(current,Mapping) and part in current:
40
+ current=current[part]
41
+ elif type(current) is tuple and type(part) is int and 0<=part<len(current):
42
+ current=current[part]
43
+ else:
44
+ return False
45
+ return True
46
+
47
+
48
+ def _setting(plan,label,value,*parts):
49
+ """显示实际生效值及其来源。参数: 计划/标签/值/路径。返回: 文本。异常: 无。"""
50
+ if type(value) is bool:
51
+ value='开启' if value else '关闭'
52
+ source='配置指定' if _declared(plan,*parts) else '默认'
53
+ return f'{label}={value}({source})'
54
+
55
+
56
+ def _scope(value):
57
+ """解释计算/输出范围。参数: 已校验范围文本。返回: 中文及具体ID。异常: 无。"""
58
+ if value=='session':
59
+ return '整个会话'
60
+ prefix,_,identifier=value.partition(':')
61
+ return ('每个事件 ' if prefix=='event' else '每个窗口片段 ')+identifier
62
+
63
+
64
+ def _validation_lines(validation):
65
+ """保留报告中全部错误与限制。参数: ValidationReport。返回: 文本行。异常: 无。"""
66
+ lines=['静态检查通过:当前声明有可用执行路径。' if validation.valid and validation.execution_ready
67
+ else '静态检查未通过:请修正以下问题。']
68
+ lines.extend('错误:'+message for message in validation.errors)
69
+ lines.append('此检查尚未读取日志、信号表或DBC;未验证实际字段、数据覆盖和内存峰值。')
70
+ lines.extend('提示:'+message for message in validation.warnings)
71
+ return lines
72
+
73
+
74
+ def validation_text(plan,validation):
75
+ """生成简短校验说明。参数: 已加载计划/同次报告。返回: 多行文本。异常: 无。"""
76
+ return '\n'.join([f'分析 {plan.dataset.dataset_id}:{len(plan.sources)}个来源,'
77
+ f'{len(plan.signals)}个信号,{len(plan.rules)}个事件规则,'
78
+ f'{len(plan.calculations)+len(plan.message_calculations)}个计算项。',
79
+ *_validation_lines(validation)])
80
+
81
+
82
+ def _rule_lines(plan):
83
+ """说明事件、窗口和请求响应的有效声明。参数: 计划。返回: 文本行。异常: 内部模型不符。"""
84
+ lines=[]
85
+ rule_indices={item['name']:index for index,item in enumerate(plan.raw_config.get('rules',()))}
86
+ for rule in plan.rules:
87
+ index=rule_indices.get(rule.rule_id)
88
+ line=f' {rule.rule_id}:{RULES[rule.rule_type]};条件 {rule.condition.text}'
89
+ if rule.minimum_duration_ns is not None:
90
+ line+=(';持续严格超过 ' if rule.duration_comparison == '>' else ';至少持续 ')+time_text(rule.minimum_duration_ns)
91
+ line+=';统计从'+('首次成立' if rule.selection_origin=='onset' else '持续确认')+'时刻开始'
92
+ if rule.window_duration_ns is not None:
93
+ line+=';固定窗口 '+time_text(rule.window_duration_ns)
94
+ if rule.exit_condition is not None:
95
+ line+=';退出条件 '+rule.exit_condition.text
96
+ if rule.stability is not None:
97
+ line+=';进入稳定 '+time_text(rule.stability.enter_ns)+',退出稳定 '+time_text(rule.stability.exit_ns)
98
+ if rule.window_delta is not None:
99
+ spec=rule.window_delta
100
+ line+=f';回看 {time_text(spec.window_ns)},门槛 {spec.threshold},方向 {spec.direction},单调约束 {spec.monotonic}'
101
+ if rule.start_end is not None:
102
+ line+=';等待上限 '+('不限制' if rule.start_end.timeout_ns is None else time_text(rule.start_end.timeout_ns))
103
+ # 开始/结束规则的首次策略存于专用规格;活动和稳定性规则没有该配置项。
104
+ if rule.rule_type not in ('condition_duration','debounce','hysteresis'):
105
+ emit=rule.start_end.emit_initial if rule.start_end is not None else rule.emit_initial
106
+ setting=_setting(plan,'首次已知条件触发',emit,'rules',index,'emit_initial')
107
+ line+=';'+(setting if index is not None else setting.replace('(默认)','(由预设展开)'))
108
+ lines.append(line)
109
+ for window in plan.windows:
110
+ merge={'none':'分别保留','overlap':'合并重叠片段','overlap_and_adjacent':'合并重叠或相邻片段',
111
+ 'exit_delay':'按退出延迟合并'}[window.merge]
112
+ lines.append(f' 窗口 {window.window_id}:来自事件 {window.event},向前 {time_text(window.pre_ns)},'
113
+ f'向后 {time_text(window.post_ns)},{merge},退出延迟 {time_text(window.exit_delay_ns)}')
114
+ for sequence in plan.sequences:
115
+ lines.append(f' 序列 {sequence.sequence_id}:请求 {sequence.start_rule} → 响应 {sequence.response_rule};'
116
+ f'允许延迟 [{time_text(sequence.min_delay_ns)}, {time_text(sequence.max_delay_ns)}](包含两端);'
117
+ f'最多等待 {sequence.max_pending} 个请求')
118
+ return lines or [' 未声明事件、窗口或请求响应序列。']
119
+
120
+
121
+ def explanation_text(plan,report,*,backend_override=None):
122
+ """按输入→信号→事件→计算→输出说明同一有效计划。参数: 计划/报告/CLI后端。返回: 多行文本。
123
+
124
+ 异常: 内部接口不符传播,不用默认文案掩盖未实现类型;无输入I/O。
125
+ """
126
+ dataset=plan.dataset
127
+ domain=dataset.domain
128
+ declared_domain=plan.raw_config['dataset'].get('domain',{})
129
+ start=declared_domain.get('start',time_text(domain.start_ns) if domain is not None else '')
130
+ end=declared_domain.get('end',time_text(domain.end_ns) if domain is not None else '')
131
+ lines=[f'分析 {dataset.dataset_id}:对象 {dataset.entity},会话 {dataset.session_id}',
132
+ '请求范围:'+('整文件(没有时间筛选)' if domain is None else
133
+ f'[{start}, {end}),包含起点,不包含终点'),
134
+ '输入来源:']
135
+ for source in plan.sources:
136
+ config=source.config
137
+ if source.source_type=='memory':
138
+ paths='数据已在配置内声明'
139
+ elif source.source_type=='signal_csv':
140
+ paths=','.join(map(str,config.paths))
141
+ elif source.source_type=='can_blf':
142
+ paths=','.join(map(str,config.paths or (config.path,)))
143
+ else:
144
+ paths=','.join(str(item.path) for item in config.inputs)
145
+ lines.append(f' {source.name}:{SOURCES[source.source_type]};{paths};时间单位 {source.time_unit},偏移 {time_text(config.offset_ns)}')
146
+ if source.source_type in ('can_blf','can_asc','asc_or_blf','raw_can_csv'):
147
+ lines.append(f' 通道 {config.channel + 1},DBC {config.dbc_path}(缺省信号声明按需读取元数据,未读取报文)')
148
+ lines.append('输入信号:')
149
+ signal_paths={}
150
+ for index,raw in enumerate(plan.raw_config.get('signals',())):
151
+ if 'signals' in raw:
152
+ for child_index,child in enumerate(raw['signals']):
153
+ signal_paths[child['name']]=('signals',index,'signals',child_index)
154
+ else:
155
+ signal_paths[raw['name']]=('signals',index)
156
+ source_types={source.name:source.source_type for source in plan.sources}
157
+ for index,item in enumerate(plan.signals):
158
+ signal=item.definition
159
+ # 未读DBC时直说等待周期,不把None展示为没有有效期或假定无限保持。
160
+ validity = ('DBC周期的3倍(运行时确定)' if signal.valid_for_ns is None
161
+ else time_text(signal.valid_for_ns))
162
+ location=f'{signal.source}.{signal.field}'
163
+ if source_types[signal.source] in ('can_blf','can_asc','asc_or_blf','raw_can_csv'):
164
+ # 人读说明沿用配置通道;内部规范键和机器报告仍保持0基模型合同。
165
+ from ..sources.can_spec import can_field_from_key
166
+ field=can_field_from_key(signal.field)
167
+ location=(f'{signal.source} 通道 {field.channel+1},报文0x{field.frame_id:X}'
168
+ f'({field.frame_id}),信号 {field.signal}')
169
+ lines.append(f' {signal.name} ← {location};单位 {signal.unit};'
170
+ f'有效期 valid_for={validity};'
171
+ +_setting(plan,'样本策略','在有效期内沿用最近有效值(backward_hold)',
172
+ *signal_paths.get(signal.name,('signals',index)),'sample_policy'))
173
+ lines.append(' 有效期表示一个有效样本最多沿用多久;到期即未知,无效更新覆盖前值,缺口不补零。')
174
+ if plan.derived:
175
+ lines.append('派生信号:')
176
+ lines.extend(f' {item.definition.name} = {item.definition.expr};单位 {expression.root.unit}'
177
+ for item,expression in zip(plan.derived,plan.derived_expressions))
178
+ lines.append('事件与时间窗口:')
179
+ lines.extend(_rule_lines(plan))
180
+ lines.append('计算项:')
181
+ for index,calculation in enumerate(plan.calculations):
182
+ signal='无单独信号' if calculation.signal is None else calculation.signal.text
183
+ condition='' if calculation.condition is None else ';筛选 '+calculation.condition.text
184
+ lines.append(f' {calculation.calculation_id}:{OPERATIONS[calculation.operation]};'
185
+ f'{_scope(calculation.scope)};信号 {signal};结果单位 {calculation.unit}{condition};'
186
+ +_setting(plan,'有效覆盖门槛',calculation.minimum_coverage,'calculations',index,'minimum_coverage')
187
+ +f',部分结果策略 {calculation.partial_policy}')
188
+ for calculation in plan.message_calculations:
189
+ lines.append(f' {calculation.calculation_id}:逐消息累计;来源 {calculation.source};'
190
+ f'表达式 {calculation.expr.text};单位 {calculation.unit};按原消息参数求值,不额外乘时间间隔')
191
+ if not plan.calculations and not plan.message_calculations:
192
+ lines.append(' 未声明计算项。')
193
+ lines.append('计算间隔:')
194
+ choices=report.intervals.resolved if report.intervals is not None else ()
195
+ for name,choice in choices:
196
+ description={'actual':'采用实际记录时间差','fixed':'采用指定间隔 '+time_text(choice.step_ns),
197
+ 'dbc':'运行时从DBC读取周期'}[choice.mode]
198
+ lines.append(f' {name}:{description}'+(';驱动信号 '+choice.driver if choice.driver else ''))
199
+ if not choices:
200
+ lines.append(' 没有使用普通计算间隔的消费者。')
201
+ lines.append(' 固定间隔或DBC周期不延长信号有效期;导出网格独立于计算间隔。')
202
+ lines.append('输出与默认设置:')
203
+ lines.append(' '+_setting(plan,'结果表格式',plan.outputs.tables,'outputs','tables')+';清单格式 JSON')
204
+ contributions={'none':'关闭','full':'逐条保存'}[plan.outputs.contributions]
205
+ lines.append(' '+_setting(plan,'逐消息贡献明细',contributions,'outputs','contributions'))
206
+ for name,label,output in (('signal_csv','信号CSV导出',plan.outputs.signal_csv),
207
+ ('can_frames','CAN帧导出',plan.outputs.can_frames)):
208
+ if output is None:
209
+ lines.append(' '+label+':关闭(默认)')
210
+ continue
211
+ description='开启,范围 '+output.scope+(',窗口 '+output.window if output.window else '')
212
+ grid=output.spec.resampling if name=='signal_csv' else output.resampling
213
+ if name=='signal_csv':
214
+ description+=';信号 '+', '.join(output.spec.signals)
215
+ else:
216
+ description+=';来源 '+output.source+',格式 '+output.spec.format
217
+ if grid is None:
218
+ description+=';保留原始采样,不重采样'
219
+ else:
220
+ description+=';独立导出网格 '+('运行时读取DBC周期' if grid.period_ns is None else time_text(grid.period_ns))
221
+ lines.append(' '+label+':'+description)
222
+ backend=plan.execution.backend if backend_override is None else backend_override
223
+ lines.append(' 执行后端='+backend+('(命令行覆盖)' if backend_override is not None else
224
+ '(配置指定)' if _declared(plan,'execution','backend') else '(默认)'))
225
+ for field,label in (('batch_rows','每批记录上限'),('memory_budget_bytes','分析层内存预算/字节'),
226
+ ('result_buffer_rows','结果缓冲行数'),('spool_quota_bytes','暂存磁盘预算/字节')):
227
+ value=getattr(plan.execution,field)
228
+ lines.append(' '+_setting(plan,label,'未设置' if value is None else value,'execution',field))
229
+ for field,label in (('trace','详细追溯'),('integrity','完整性诊断'),('retain_work','保留现场')):
230
+ lines.append(' '+_setting(plan,label,getattr(plan.diagnostics,field),'diagnostics',field))
231
+ lines.append('检查结论:')
232
+ lines.extend(_validation_lines(report.validation))
233
+ return '\n'.join(lines)