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
@@ -0,0 +1,61 @@
1
+ """把同一报文的集中声明展开为既有信号绑定,不增加运行时分组或重复读取。"""
2
+ from .checks import array_at, object_at, choice_at, text_at, model_at, PlanValidationError
3
+
4
+
5
+ SHARED = ('period', 'valid_for', 'same_time_policy')
6
+ LOCATOR = ('frame_id', 'channel', 'is_extended', 'is_fd')
7
+
8
+
9
+ def signal_entries(value):
10
+ """按原顺序提供信号副本和声明路径。参数: signals数组。返回: 迭代器。异常: 结构错误。
11
+
12
+ 集中项只允许声明一套报文定位;子项可覆盖周期、有效期和同刻策略,
13
+ 不能把另一个报文塞进本组。没有额外组名、引用或运行时对象。
14
+ """
15
+ for index, raw in enumerate(array_at(value, '$.signals')):
16
+ path = f'$.signals[{index}]'
17
+ if type(raw) is not dict or 'signals' not in raw:
18
+ yield raw, path
19
+ continue
20
+ group = object_at(raw, path, ('frame_id', 'signals'),
21
+ ('source', 'channel', 'is_extended', 'is_fd') + SHARED)
22
+ children = array_at(group['signals'], path + '.signals')
23
+ if not children:
24
+ raise PlanValidationError(path + '.signals', '报文组至少需要一个信号')
25
+ # 即使所有子项都覆盖共享参数,也不能把填写错误当成未提供。
26
+ from .signal_validity import declared_valid_for
27
+ declared_valid_for(group, path, dbc_available=True)
28
+ if 'same_time_policy' in group:
29
+ choice_at(group['same_time_policy'], ('error', 'last_by_sequence'), path + '.same_time_policy')
30
+ common = {key: group[key] for key in SHARED if key in group}
31
+ if 'source' in group:
32
+ common['source'] = group['source']
33
+ locator = {key: group[key] for key in LOCATOR if key in group}
34
+ from ..legacy.records import field_from_dict
35
+ # 预检使用转换后的副本;展开给子项的locator仍保留用户1基编号。
36
+ from .channels import channel_index
37
+ checked = dict(locator, signal='_group_check')
38
+ checked['channel'] = channel_index(locator['channel'], path + '.channel') if 'channel' in locator else 0
39
+ model_at(field_from_dict, path, checked)
40
+ for child_index, child in enumerate(children):
41
+ child_path = f'{path}.signals[{child_index}]'
42
+ if type(child) is not dict:
43
+ raise PlanValidationError(child_path, '信号必须为对象')
44
+ forbidden = set(child) & ({'field', 'source', 'signals'} | set(LOCATOR))
45
+ if forbidden:
46
+ raise PlanValidationError(child_path, '组内信号不能重复声明报文定位:' + ', '.join(sorted(forbidden)))
47
+ if 'signal' not in child:
48
+ raise PlanValidationError(child_path + '.signal', '需要DBC信号名称')
49
+ text_at(child['signal'], child_path + '.signal')
50
+ expanded = dict(common, **child)
51
+ expanded['field'] = dict(locator, signal=expanded.pop('signal'))
52
+ yield expanded, child_path
53
+
54
+
55
+ def declared_signals(value):
56
+ """遍历原声明的叶信号供默认展开使用。参数: 已校验数组。返回: 原字典迭代器。异常: 无。"""
57
+ for item in value:
58
+ if 'signals' in item:
59
+ yield from item['signals']
60
+ else:
61
+ yield item
@@ -0,0 +1,46 @@
1
+ """确定信号的有效期声明,不读取DBC或日志。
2
+
3
+ 显式valid_for优先;否则使用本信号period的三倍。原始报文未填period时
4
+ 保留None,执行启动再从本次已有DBC元数据取得周期。已解码数据不能借用
5
+ 别的信号或计算驱动的周期。所有数值以正int64纳秒表示,无I/O或全局缓存。
6
+ """
7
+
8
+ from .checks import PlanValidationError, duration_at
9
+ from ..timebase.conversion import require_int64_ns
10
+
11
+
12
+ def triple_period(period_ns, path):
13
+ """将周期乘三并检查溢出,避免产生无限或负有效期。
14
+
15
+ 参数: period_ns为正整数纳秒;path为配置错误位置。
16
+ 返回: 正int64纳秒有效期。异常: PlanValidationError为非法周期或乘积超界。
17
+ 副作用: 无,不读取文件。
18
+ """
19
+ try:
20
+ # bool不表示一个纳秒;先核周期,再核乘积,保持精确整数运算。
21
+ if type(period_ns) is not int or period_ns <= 0:
22
+ raise ValueError('信号周期必须是正整数纳秒')
23
+ return require_int64_ns(period_ns * 3, 'valid_for_ns')
24
+ except (TypeError, ValueError, OverflowError) as error:
25
+ raise PlanValidationError(path, '周期的3倍不能作为有效期:' + str(error)) from error
26
+
27
+
28
+ def declared_valid_for(raw, path, *, dbc_available):
29
+ """按显式有效期、信号周期、待查DBC的优先顺序解析声明。
30
+
31
+ 参数: raw为单信号配置;path为其配置位置;dbc_available说明原始来源有DBC。
32
+ 返回: 正int纳秒或None(只用于尚待DBC的声明)。
33
+ 异常: PlanValidationError为显式空值、周期/有效期错误或没有周期依据。
34
+ 副作用: 无;validate/explain不会因此打开DBC。
35
+ """
36
+ # 即使有效期已覆盖默认值,用户填写的周期也必须合法,不能静默忽略错误。
37
+ period = duration_at(raw['period'], path + '.period', positive=True) if 'period' in raw else None
38
+ if 'valid_for' in raw:
39
+ return duration_at(raw['valid_for'], path + '.valid_for', positive=True)
40
+ if period is not None:
41
+ return triple_period(period, path + '.valid_for')
42
+ # 原始报文可在运行启动借用同次DBC;静态阶段不为默认值提前读文件。
43
+ if dbc_available:
44
+ return None
45
+ raise PlanValidationError(path + '.valid_for',
46
+ '未填写valid_for且无法取得信号周期;请填写本信号period或valid_for')
@@ -0,0 +1,110 @@
1
+ """静态解释新的ASC和原始CAN表配置,不打开输入或DBC。
2
+
3
+ 来源使用既有name/time/dbc_by_channel及path或有序paths;parser明确ASC版本
4
+ 或CSV布局/时间模式。offsets可逐文件声明相对于共同time.offset的额外平移,
5
+ 不自动猜跨日、设备同步或日期。返回CANTextSpec及规范来源身份供公共AnalysisRunner。
6
+ """
7
+
8
+ from hashlib import sha256
9
+
10
+ from ..core.models import TimebaseSpec
11
+ from ..core.types import TimeType
12
+ from ..sources.asc import ASCSpec
13
+ from ..sources.blf import BLFSpec
14
+ from ..sources.raw_csv import CANCSVSpec,CSVTimeSpec
15
+ from ..sources.raw_csv_layout import CANCSVLayout
16
+ from ..sources.text_can_spec import CANTextSpec
17
+ from ..timebase.conversion import checked_add_ns
18
+ from .checks import (PlanValidationError,absolute_path,array_at,canonical,choice_at,coordinate_at,
19
+ duration_at,metadata_at,model_at,object_at,text_at,timezone_at)
20
+
21
+
22
+ def parse_text_source(raw,base,path):
23
+ """建立一个明确的新文本CAN来源。参数: raw原对象、base配置目录、path错误位置。
24
+ 返回: SourcePlan。异常: PlanValidationError定位配置问题;不发生原始输入I/O。
25
+ """
26
+ from .models import SourcePlan
27
+ raw=object_at(raw,path,('name','source_type','time','dbc_by_channel'),('path','paths','parser','offsets','metadata','input_check') + (('reader_options',)))
28
+ source_type=choice_at(raw['source_type'],('can_asc','asc_or_blf','raw_can_csv'),path+'.source_type')
29
+ name=text_at(raw['name'],path+'.name',identifier=True)
30
+ clock=object_at(raw['time'],path+'.time',('time_type','unit'),('origin','offset','timezone'))
31
+ time_type=choice_at(clock['time_type'],('relative','absolute'),path+'.time.time_type')
32
+ unit=choice_at(clock['unit'],('s','ms','us','ns','ISO8601'),path+'.time.unit')
33
+ if time_type=='relative':
34
+ if 'origin' not in clock or 'timezone' in clock or unit=='ISO8601':
35
+ raise PlanValidationError(path+'.time','relative必须声明共同origin,且不补日历时区')
36
+ origin=text_at(clock['origin'],path+'.time.origin')
37
+ clock_id='relative_'+sha256(origin.encode('utf-8')).hexdigest()[:16]
38
+ else:
39
+ if 'origin' in clock:
40
+ raise PlanValidationError(path+'.time.origin','absolute不接受relative origin')
41
+ origin=None; clock_id='utc'
42
+ timebase=model_at(TimebaseSpec,path+'.time',clock_id,TimeType(time_type),origin)
43
+ offset=coordinate_at(clock.get('offset','0s'),path+'.time.offset')
44
+ zone=None
45
+ if 'timezone' in clock:
46
+ tz=timezone_at(clock['timezone'],path+'.time.timezone')
47
+ delta=None if tz is None else tz.utcoffset(None)
48
+ if delta is None or delta.total_seconds()%60:
49
+ raise PlanValidationError(path+'.time.timezone','此原始报文读取器需要固定时区:UTC或±HH:MM')
50
+ zone=int(delta.total_seconds()//60)
51
+ if ('path' in raw)==('paths' in raw):
52
+ raise PlanValidationError(path,'path和paths必须且只能提供一种')
53
+ names=[raw['path']] if 'path' in raw else array_at(raw['paths'],path+'.paths')
54
+ if not 1<=len(names)<=4096:
55
+ raise PlanValidationError(path+'.paths','需要1至4096个有序文件')
56
+ paths=tuple(absolute_path(item,base,f'{path}.paths[{i}]') for i,item in enumerate(names))
57
+ if source_type=='asc_or_blf' and any(p.suffix.lower() not in {'.asc','.blf'} for p in paths):
58
+ raise PlanValidationError(path+'.paths','自动读取只支持ASC/BLF后缀')
59
+ offsets=array_at(raw.get('offsets',['0s']*len(paths)),path+'.offsets')
60
+ if len(offsets)!=len(paths):
61
+ raise PlanValidationError(path+'.offsets','逐文件偏移数量必须与paths相同')
62
+ shifted=tuple(model_at(checked_add_ns,f'{path}.offsets[{i}]',offset,coordinate_at(value,f'{path}.offsets[{i}]'))
63
+ for i,value in enumerate(offsets))
64
+ dbc=raw['dbc_by_channel']
65
+ if type(dbc) is not dict or len(dbc)!=1:
66
+ raise PlanValidationError(path+'.dbc_by_channel','当前文本CAN需要一个明确通道到DBC路径')
67
+ channel=next(iter(dbc))
68
+ from .channels import channel_index
69
+ channel_number=channel_index(channel,path+'.dbc_by_channel',key=True)
70
+ dbc_path=absolute_path(dbc[channel],base,path+'.dbc_by_channel.'+channel)
71
+ parser=raw.get('parser',{})
72
+ if source_type in ('can_asc','asc_or_blf'):
73
+ parser=object_at(parser,path+'.parser',(),('version','encoding'))
74
+ if unit!='s':
75
+ raise PlanValidationError(path+'.time.unit','ASC原文字以秒表示')
76
+ inputs=tuple(model_at(BLFSpec,path+'.parser',p,shift) if source_type=='asc_or_blf' and p.suffix.lower()=='.blf' else
77
+ model_at(ASCSpec,path+'.parser',p,parser.get('version','vector-asc-v1'),
78
+ parser.get('encoding','utf-8-sig'),'epoch' if time_type=='absolute' else 'relative',zone,shift)
79
+ for p,shift in zip(paths,shifted))
80
+ else:
81
+ parser=object_at(parser,path+'.parser',('layout','time_format'),
82
+ ('id_base','length_base','channel_origin','payload_style','rollover_min_drop'))
83
+ layout_raw=parser['layout']
84
+ if type(layout_raw) is dict and type(layout_raw.get('fields')) is dict:
85
+ fields=dict(layout_raw['fields'])
86
+ # 通道列缺省时继承当前来源唯一通道;先还原输入起点,reader只减一次。
87
+ origin=parser.get('channel_origin',0)
88
+ if type(origin) is not int or origin not in (0,1):
89
+ raise PlanValidationError(path+'.parser.channel_origin','通道起点须为0或1')
90
+ fields.setdefault('channel',{'fixed':channel_number+origin})
91
+ layout_raw=dict(layout_raw,fields=fields)
92
+ layout=model_at(CANCSVLayout.from_dict,path+'.parser.layout',layout_raw)
93
+ time_format=choice_at(parser['time_format'],('numeric','clock','clock-ms-us-v1','iso8601'),path+'.parser.time_format')
94
+ if ((time_format in ('clock','clock-ms-us-v1') and (time_type!='relative' or unit!='s'))
95
+ or time_format=='iso8601' and (time_type!='absolute' or unit!='ISO8601')
96
+ or time_format=='numeric' and (unit=='ISO8601' or zone is not None)):
97
+ raise PlanValidationError(path+'.time','时间种类/单位/时区与原表解析模式不符')
98
+ rollover=duration_at(parser['rollover_min_drop'],path+'.parser.rollover_min_drop',positive=True) if 'rollover_min_drop' in parser else None
99
+ inputs=tuple(model_at(CANCSVSpec,path+'.parser',p,layout,
100
+ model_at(CSVTimeSpec,path+'.parser',time_format,unit if time_format=='numeric' else 's',shift,zone,rollover),
101
+ parser.get('id_base','auto'),parser.get('length_base',10),parser.get('channel_origin',0),parser.get('payload_style','spaced'))
102
+ for p,shift in zip(paths,shifted))
103
+ options=object_at(raw.get('reader_options',{}),path+'.reader_options',(),('decode_policy',))
104
+ policy=choice_at(options.get('decode_policy','strict'),
105
+ ('strict','partial','legacy'),path+'.reader_options.decode_policy')
106
+ input_check=choice_at(raw.get('input_check','auto'),('auto','full'),path+'.input_check')
107
+ spec=model_at(CANTextSpec,path,name,inputs,dbc_path,channel_number,timebase,policy,input_check)
108
+ identity=dict(raw,paths=tuple(str(p) for p in paths),dbc_by_channel={channel:str(dbc_path)})
109
+ identity.pop('path',None)
110
+ return SourcePlan(name,source_type,spec,unit,clock.get('timezone'),canonical(identity),metadata_at(raw.get('metadata',{}),path+'.metadata'))
chronaxis/presets.py ADDED
@@ -0,0 +1,270 @@
1
+ """校验领域预设v1的角色契约,展开为可序列化的类型化公共声明。
2
+
3
+ 输入PresetSpec与当前SignalDefinition tuple,输出PlanFragment;不读取来源或执行分析。
4
+ 先严格校验参数,再显式优先解析角色/检查转换后契约,最后生成简单别名表达式和节点。
5
+ 候选语义名只属于本模块的版本化契约,不是通用核心领域目录或行业标准。
6
+ 声明会交给AnalysisPlan正常编译;不使用eval、不推断方向/位置/阈值或补造真实数据。
7
+ 输入/输出均不可变;JSON序列化返回独立副本。执行、资源预算和报文导出由执行层负责。
8
+ """
9
+
10
+ # 算法与公开声明模型分开,避免AnalysisPlan/构建器循环。
11
+ from .core.binding import SignalDefinition
12
+ from .core.expression import DerivedDefinition
13
+ from .core.types import SignalDType as D
14
+ from .core.windows import WindowSpec
15
+ from .planning.checks import (PlanValidationError, choice_at, duration_at, json_value,
16
+ array_at, number_at, object_at, text_at)
17
+ from .planning.preset_models import (RoleContract, RoleBinding, PresetSpec, PresetRule,
18
+ PresetCalculation, PlanFragment, CHARGE_ROLES, FAULT_ROLES, COMMAND_ROLES)
19
+ from .planning.sequences import SequencePlan
20
+ from .timebase.conversion import INT64_MIN, INT64_MAX
21
+
22
+
23
+ def _parameters(spec, signals=()):
24
+ """按kind检查工程参数,保持原数值并将时长转换为整数ns。
25
+
26
+ 参数: spec为PresetSpec;参数值来自独立JSON快照。
27
+ 返回: 新dict,仅内部使用已校验参数,不作为公开无类型片段。
28
+ 异常: PlanValidationError为缺项、未知参数、bool伪数值、非有限或错误范围。
29
+ """
30
+ # 将不可变快照还原为局部原生对象,严格拒绝未声明参数。
31
+ path = '$.preset.parameters'
32
+ if spec.preset_type == 'charge_session':
33
+ raw = object_at(json_value(spec.parameters), path, ('mode_value', 'current_min', 'minimum_duration'),
34
+ ('compute_energy', 'compute_charge', 'minimum_coverage', 'partial_policy'))
35
+ result = {'mode_value': number_at(raw['mode_value'], path + '.mode_value', integer=True),
36
+ 'current_min': number_at(raw['current_min'], path + '.current_min'),
37
+ 'minimum_duration': duration_at(raw['minimum_duration'], path + '.minimum_duration'),
38
+ 'compute_energy': choice_at(raw.get('compute_energy', False), (False, True), path + '.compute_energy'),
39
+ 'compute_charge': choice_at(raw.get('compute_charge', False), (False, True), path + '.compute_charge'),
40
+ 'minimum_coverage': number_at(raw.get('minimum_coverage', 0), path + '.minimum_coverage', minimum=0, maximum=1),
41
+ 'partial_policy': choice_at(raw['partial_policy'], ('report', 'strict'), path + '.partial_policy') if 'partial_policy' in raw else None}
42
+ elif spec.preset_type == 'fault_context':
43
+ raw = object_at(json_value(spec.parameters), path, (), ('pre', 'post', 'emit_initial'))
44
+ result = {'pre': duration_at(raw.get('pre', '0s'), path + '.pre'), 'post': duration_at(raw.get('post', '0s'), path + '.post'),
45
+ 'emit_initial': choice_at(raw.get('emit_initial', False), (False, True), path + '.emit_initial')}
46
+ if result['pre'] == result['post'] == 0:
47
+ raise PlanValidationError(path, 'fault_context至少一个pre/post为正')
48
+ elif spec.preset_type == 'threshold_excursion':
49
+ # v1明确高阈值进入、低阈值退出;拒绝重叠,不能在阈值相等时猜优先级。
50
+ raw = object_at(json_value(spec.parameters), path, ('enter_threshold', 'exit_threshold'),
51
+ ('unit', 'enter_delay', 'exit_delay'))
52
+ if 'unit' in raw:
53
+ unit = text_at(raw['unit'], path + '.unit')
54
+ else:
55
+ alias = spec.role_bindings.get('signal')
56
+ candidates = [item for item in signals if item.name == alias]
57
+ if len(candidates) != 1:
58
+ raise PlanValidationError('$.preset.role_bindings.signal', '请指定唯一的已绑定信号以继承单位')
59
+ unit = candidates[0].unit
60
+ result = dict(unit=unit,
61
+ enter_threshold=number_at(raw['enter_threshold'], path + '.enter_threshold'),
62
+ exit_threshold=number_at(raw['exit_threshold'], path + '.exit_threshold'),
63
+ enter_delay=duration_at(raw.get('enter_delay', '0ns'), path + '.enter_delay'),
64
+ exit_delay=duration_at(raw.get('exit_delay', '0ns'), path + '.exit_delay'))
65
+ if result['enter_threshold'] <= result['exit_threshold']:
66
+ raise PlanValidationError(path, '进入阈值必须大于退出阈值;v1高于进入、低于退出,均含等号')
67
+ else:
68
+ raw = object_at(json_value(spec.parameters), path, ('max_delay',), ('min_delay', 'emit_initial', 'max_pending'))
69
+ result = dict(min_delay=duration_at(raw.get('min_delay', '0s'), path + '.min_delay'),
70
+ max_delay=duration_at(raw['max_delay'], path + '.max_delay'),
71
+ emit_initial=choice_at(raw.get('emit_initial', False), (False, True), path + '.emit_initial'),
72
+ max_pending=number_at(raw.get('max_pending', 65536), path + '.max_pending', integer=True, minimum=1))
73
+ if result['min_delay'] > result['max_delay']:
74
+ raise PlanValidationError(path, 'min_delay不能大于max_delay')
75
+ return result
76
+
77
+
78
+ def _mismatches(definition, contract, *, generic_unit=False):
79
+ """列出转换后声明未满足的角色字段,不能用自由metadata放宽质量。
80
+
81
+ 参数: definition为SignalDefinition;contract为本v1角色;generic_unit允许明确同名无转换的自定义单位。
82
+ 返回: tuple[str, ...],空表示字段契约通过,不证明真实数据正确。
83
+ 异常: 无主动异常;输入类型由公共解析入口证明。
84
+ """
85
+ # 逐字段诊断方便缺项/歧义时列出候选不满足原因。
86
+ errors = []
87
+ if definition.dtype not in contract.dtypes:
88
+ errors.append('dtype须为' + '/'.join(item.value for item in contract.dtypes))
89
+ identity_unit = (generic_unit and definition.input_unit == definition.unit
90
+ and definition.scale == 1 and definition.offset == 0 and definition.direction_factor == 1)
91
+ if definition.unit != contract.unit or definition.unit_status != 'verified' and not identity_unit:
92
+ errors.append(f'目标unit须为{contract.unit}且关系verified')
93
+ if contract.sign_convention is not None and definition.sign_convention != contract.sign_convention:
94
+ errors.append('sign_convention须为' + contract.sign_convention)
95
+ if contract.measurement_location is not None and definition.measurement_location != contract.measurement_location:
96
+ errors.append('measurement_location须为' + contract.measurement_location)
97
+ # DBC默认有效期在运行启动时核实;声明阶段不为角色校验额外加载DBC。
98
+ if (definition.valid_for_ns is not None and definition.valid_for_ns <= 0
99
+ or definition.sample_policy != 'backward_hold' or definition.identity()[-1] != contract.forbidden_quality):
100
+ errors.append('正valid_for/backward_hold/固定基础质量策略未满足')
101
+ return tuple(errors)
102
+
103
+
104
+ def resolve_preset_roles(spec: PresetSpec, signals: tuple[SignalDefinition, ...]) -> tuple[RoleBinding, ...]:
105
+ """显式优先解析本次实际角色,否则按版本化语义契约寻找唯一合格候选。
106
+
107
+ 参数: spec为公开不可变预设;signals为当前计划SignalDefinition tuple。
108
+ 返回: RoleBinding tuple,保留原定义与explicit/semantic_unique路径。
109
+ 异常: PlanValidationError为类型、重复别名、未知角色、缺项、候选歧义或契约冲突。
110
+ 边界: 显式别名无需semantic_id,仍检查类型/单位/方向/位置/质量;不选第一个候选。
111
+ """
112
+ if not isinstance(spec, PresetSpec) or not isinstance(signals, tuple) or any(not isinstance(item, SignalDefinition) for item in signals):
113
+ raise PlanValidationError('$.preset', '需要PresetSpec与SignalDefinition tuple')
114
+ parameters = _parameters(spec, signals)
115
+ if spec.preset_type == 'threshold_excursion':
116
+ # 任意物理量显式绑定;未填单位则继承该信号,不猜温度等领域名称。
117
+ if 'signal' not in spec.role_bindings:
118
+ raise PlanValidationError('$.preset.role_bindings.signal', 'threshold_excursion必须显式指定signal角色')
119
+ from .planning.preset_models import RoleContract
120
+ contracts = (RoleContract('signal', (D.INT64, D.UINT64, D.FLOAT64), parameters['unit'], 'threshold.signal'),)
121
+ else:
122
+ contracts = {'charge_session': CHARGE_ROLES, 'fault_context': FAULT_ROLES,
123
+ 'command_response': COMMAND_ROLES}[spec.preset_type]
124
+ catalog = {item.name: item for item in signals}
125
+ if len(catalog) != len(signals):
126
+ raise PlanValidationError('$.signals', 'signal别名重复')
127
+ unknown = set(spec.role_bindings) - {item.role for item in contracts}
128
+ if unknown:
129
+ raise PlanValidationError('$.preset.role_bindings', '未知角色:' + ', '.join(sorted(unknown)))
130
+ result = []
131
+ for contract in contracts:
132
+ # voltage只在请求能量或明确提供该可选绑定时检查,不强迫无能量任务配置电压。
133
+ if contract.role == 'voltage' and not parameters['compute_energy'] and contract.role not in spec.role_bindings:
134
+ continue
135
+ path = '$.preset.role_bindings.' + contract.role
136
+ if contract.role in spec.role_bindings:
137
+ alias = spec.role_bindings[contract.role]
138
+ if alias not in catalog:
139
+ raise PlanValidationError(path, f'未知别名:{alias};可用:{", ".join(catalog)}')
140
+ definition = catalog[alias]
141
+ errors = _mismatches(definition, contract, generic_unit=spec.preset_type == 'threshold_excursion')
142
+ if errors:
143
+ raise PlanValidationError(path, f'{alias}契约不满足:{"; ".join(errors)}')
144
+ result.append(RoleBinding(contract, definition, 'explicit'))
145
+ else:
146
+ # 只取本模块公开候选标识/版本,所有合格候选统计完才决定。
147
+ candidates = [item for item in signals if item.semantic_id == contract.semantic_id]
148
+ valid = [item for item in candidates if item.semantic_contract_version == contract.version and not _mismatches(item, contract)]
149
+ if len(valid) != 1:
150
+ details = '; '.join(item.name + ': ' + ', '.join(_mismatches(item, contract) +
151
+ (() if item.semantic_contract_version == contract.version else ('semantic_contract_version须为1',))) for item in candidates)
152
+ reason = '歧义候选:' + ', '.join(item.name for item in valid) if valid else '缺少符合契约的候选'
153
+ raise PlanValidationError(path, reason + f'({contract.semantic_id} v1);' + details)
154
+ result.append(RoleBinding(contract, valid[0], 'semantic_unique'))
155
+ return tuple(result)
156
+
157
+
158
+ def build_preset(spec: PresetSpec, signals: tuple[SignalDefinition, ...]) -> PlanFragment:
159
+ """校验v1预设并展开公共声明,不执行I/O或数值分析。
160
+
161
+ 参数: spec为PresetSpec,保存id/preset_type/version/显式角色及参数;signals为当前类型化信号tuple。
162
+ 返回: PlanFragment,生成请求的功率/Wh/Ah、报警、阈值迟滞/逐段时长或响应配对。
163
+ 异常: PlanValidationError为参数/角色契约、模式编码范围及生成ID与信号冲突。
164
+ 流程: 检查角色→生成简单别名DSL→构造类型化节点→拒绝当前可见ID冲突。
165
+ 用户其他节点/多个预设的冲突由AnalysisPlan合入时继续检查。
166
+ """
167
+ resolved = resolve_preset_roles(spec, signals)
168
+ roles = {item.contract.role: item.definition for item in resolved}
169
+ parameters = _parameters(spec, signals)
170
+ if spec.preset_type == 'charge_session':
171
+ mode, current = roles['mode'], roles['current']
172
+ minimum, maximum = (INT64_MIN, INT64_MAX) if mode.dtype is D.INT64 else (0, 2**64-1)
173
+ code = parameters['mode_value']
174
+ if not minimum <= code <= maximum or mode.valid_range is not None and not mode.valid_range[0] <= code <= mode.valid_range[1]:
175
+ raise PlanValidationError('$.preset.parameters.mode_value', '模式编码超出已声明dtype/valid_range')
176
+ # 只拼接已验证别名与原生有限数值字面量,不能注入属性或任意函数。
177
+ condition = f'{mode.name} == {code!r} and {current.name} > {parameters["current_min"]!r}'
178
+ rule = PresetRule(spec.id + '_activity', 'condition_duration', condition, parameters['minimum_duration'], 'onset')
179
+ derived, calculations = [], []
180
+ for requested, suffix, signal, unit in (
181
+ (parameters['compute_energy'], 'energy', spec.id + '_power', 'Wh'),
182
+ (parameters['compute_charge'], 'charge', current.name, 'Ah')):
183
+ if requested:
184
+ calculations.append(PresetCalculation(spec.id + '_' + suffix, 'event:' + rule.id, signal, unit,
185
+ parameters['minimum_coverage'], parameters['partial_policy']))
186
+ if parameters['compute_energy']:
187
+ derived.append(DerivedDefinition(spec.id + '_power', roles['voltage'].name + ' * ' + current.name, 'W'))
188
+ fragment = PlanFragment(tuple(derived), (rule,), (), tuple(calculations))
189
+ elif spec.preset_type == 'fault_context':
190
+ rule = PresetRule(spec.id + '_alarm', 'rising_edge', roles['alarm'].name, emit_initial=parameters['emit_initial'])
191
+ window = WindowSpec(spec.id + '_context', rule.id, 'point', parameters['pre'], parameters['post'])
192
+ fragment = PlanFragment((), (rule,), (window,), ())
193
+ elif spec.preset_type == 'threshold_excursion':
194
+ # 普通迟滞规则负责全部状态,逐段时长复用原duration核;总计由同一次状态推进保存。
195
+ alias = roles['signal'].name
196
+ rule = PresetRule(spec.id + '_activity', 'hysteresis', None,
197
+ enter_condition=f'{alias} >= {parameters["enter_threshold"]!r}',
198
+ exit_condition=f'{alias} <= {parameters["exit_threshold"]!r}',
199
+ enter_delay_ns=parameters['enter_delay'], exit_delay_ns=parameters['exit_delay'])
200
+ calculation = PresetCalculation(spec.id + '_duration', 'event:' + rule.id, None, 's',
201
+ operation='duration', condition='True')
202
+ fragment = PlanFragment(rules=(rule,), calculations=(calculation,))
203
+ else:
204
+ # 布尔角色变为两条普通rising_edge规则,配对仍走公开SequencePlan,没有隐藏计算器。
205
+ request = PresetRule(spec.id + '_request', 'rising_edge', roles['request'].name, emit_initial=parameters['emit_initial'])
206
+ response = PresetRule(spec.id + '_response', 'rising_edge', roles['response'].name, emit_initial=parameters['emit_initial'])
207
+ sequence = SequencePlan(spec.id + '_pair', request.id, response.id,
208
+ parameters['min_delay'], parameters['max_delay'], parameters['max_pending'])
209
+ fragment = PlanFragment(rules=(request, response), sequences=(sequence,))
210
+ # 不自动改生成名称,当前signal碰撞在公共构建器立即拒绝。
211
+ generated = [item.name for item in fragment.derived] + [item.id for item in fragment.rules] + [item.window_id for item in fragment.windows] + [item.id for item in fragment.calculations]
212
+ generated.extend(item.sequence_id for item in fragment.sequences)
213
+ conflicts = set(generated) & {item.name for item in signals}
214
+ if conflicts:
215
+ raise PlanValidationError('$.preset.name', '生成ID冲突:' + ', '.join(sorted(conflicts)))
216
+ return fragment
217
+
218
+
219
+ def expand_presets(config, signals):
220
+ """在独立配置副本中合入预设片段,保留用户节点并拒绝全部生成ID冲突。
221
+
222
+ 参数: config为dict,是调用方复制后的配置映射;本函数原地合入生成节点。
223
+ signals为tuple[SignalDefinition, ...],提供当前信号定义和预设角色匹配依据。
224
+ 返回: (PresetSpec tuple, 各预设RoleBinding tuple),供计划保留原声明及角色追溯。
225
+ 异常: PlanValidationError为预设/用户结构或生成ID与用户/其他预设重名。
226
+ 副作用: 仅修改传入的局部derived/rules/windows/calculations/sequences;不修改raw_config快照或来源。
227
+ """
228
+ raw_derived = config.get('derived', {})
229
+ if type(raw_derived) is not dict:
230
+ raise PlanValidationError('$.derived', 'derived必须为别名对象')
231
+ # 全部当前用户名称及节点ID都保留,生成项不得隐藏覆盖。
232
+ occupied = {item.name for item in signals} | set(raw_derived)
233
+ arrays = {}
234
+ for key in ('rules', 'windows', 'calculations', 'sequences'):
235
+ arrays[key] = array_at(config.get(key, []), '$.' + key)
236
+ for index, row in enumerate(arrays[key]):
237
+ if type(row) is dict and 'id' in row:
238
+ raise PlanValidationError(f'$.{key}[{index}].id', '名称字段已统一为name,请替换id', 'unknown_field')
239
+ if type(row) is not dict or 'name' not in row:
240
+ raise PlanValidationError(f'$.{key}[{index}]', '节点必须包含name')
241
+ occupied.add(text_at(row['name'], f'$.{key}[{index}].name', identifier=True))
242
+ specs, bindings, preset_ids = [], [], set()
243
+ for index, raw in enumerate(array_at(config.get('presets', []), '$.presets')):
244
+ path = f'$.presets[{index}]'
245
+ try:
246
+ spec = PresetSpec.from_dict(raw)
247
+ if spec.id in preset_ids:
248
+ raise PlanValidationError('$.preset.name', 'preset id重复:' + spec.id)
249
+ fragment = build_preset(spec, signals)
250
+ bound = resolve_preset_roles(spec, signals)
251
+ # to_dict承诺可直接合入用户配置;内部展开再转换到同一解析器形式。
252
+ from .planning.config_groups import normalize_configuration
253
+ serialized = normalize_configuration({'sources': [], 'signals': [], **fragment.to_dict()})
254
+ generated = set(serialized['derived']) | {item['name'] for key in arrays for item in serialized.get(key, ())}
255
+ if generated & occupied:
256
+ raise PlanValidationError('$.preset.name', '生成ID冲突:' + ', '.join(sorted(generated & occupied)))
257
+ except PlanValidationError as error:
258
+ # 外层配置位置替换统一公共spec路径,不丢角色/参数诊断。
259
+ raise PlanValidationError(error.path.replace('$.preset', path, 1), error.message, error.code) from error
260
+ # 校验整个片段后再合入,失败不发布半个公开计划。
261
+ raw_derived.update(serialized['derived'])
262
+ for key in arrays:
263
+ arrays[key].extend(serialized.get(key, ()))
264
+ occupied.update(generated)
265
+ preset_ids.add(spec.id)
266
+ specs.append(spec)
267
+ bindings.append(bound)
268
+ config['derived'] = raw_derived
269
+ config.update(arrays)
270
+ return tuple(specs), tuple(bindings)
@@ -0,0 +1,34 @@
1
+ """提供typed结果行、共享预算、有限暂存、流式读取与发布协议。
2
+
3
+ 导入不启动运行或打开文件;基础行模型和预算不加载NumPy、CAN或DBC。
4
+ 实际请求ResultSpool或AnalysisResult时才导入暂存与发布模块及其依赖。
5
+ 输入读取由执行层负责;本模块预算跟踪已登记资源,不保证整个进程的RSS上限。
6
+ """
7
+
8
+ # 导出结果层异常。
9
+ from .errors import (AnalysisError, BudgetExceededError, ResultClosedError, ResultFormatError,
10
+ ContributionsUnavailableError)
11
+ from .budget import ResourceBudget
12
+ from .manifest import RunMetadata, OutputManifest
13
+
14
+ __all__ = ['AnalysisError', 'BudgetExceededError', 'ResultClosedError', 'ResultFormatError', 'ContributionsUnavailableError', 'SummaryCalculationRow', 'SummaryCoverageCalculationRow', 'SummaryEventRow', 'SummarySequenceRow', 'SummarySegmentRow', 'SummaryContributionRow', 'SummaryInputRow', 'SummarySelectionRow', 'ResultRow', 'ResourceBudget', 'ResultSpool', 'RunMetadata', 'OutputManifest', 'AnalysisResult']
15
+
16
+
17
+ def __getattr__(name):
18
+ """按需提供行模型、暂存和发布类,让纯预算与参考累计不形成依赖环。
19
+
20
+ 参数: name为请求的公开属性名称。返回: 对应原实现类,不创建实例。
21
+ 异常: AttributeError为未知名称;实际模块导入错误原样传播。
22
+ 副作用: 访问对应类才加载实现及其依赖,不读取输入或启动分析。
23
+ """
24
+ # 延迟加载结果模型,纯预算消费者导入时不建立执行层依赖。
25
+ if name in ('SummaryCalculationRow', 'SummaryCoverageCalculationRow', 'SummaryEventRow', 'SummarySequenceRow', 'SummarySegmentRow', 'SummaryContributionRow', 'SummaryInputRow', 'SummarySelectionRow', 'ResultRow'):
26
+ from . import rows
27
+ return getattr(rows, name)
28
+ if name == 'ResultSpool':
29
+ from .spool import ResultSpool
30
+ return ResultSpool
31
+ if name == 'AnalysisResult':
32
+ from .result import AnalysisResult
33
+ return AnalysisResult
34
+ raise AttributeError(f'chronaxis.results没有公开属性{name!r}')
@@ -0,0 +1,67 @@
1
+ """说明一次执行为何有或没有业务结果,不保存逐条输入或重复时间记录。
2
+
3
+ 执行层在原有规则推进、指标写出时累计少量状态;本模块只冻结并校验这些事实,
4
+ 供清单和CLI共用。事件存在与指标是否完整分别表示,不能以completed代替业务有效性。
5
+ """
6
+ from dataclasses import dataclass, asdict
7
+
8
+ from ..core.validation import require_identifier
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class RuleOutcome:
13
+ """一条规则的结果概况;未知可与已生成事件并存。"""
14
+
15
+ rule_id: str
16
+ status: str
17
+ event_count: int
18
+ has_unknown: bool
19
+ unobserved_signals: tuple[str, ...] = ()
20
+
21
+ def __post_init__(self):
22
+ """参数: 无。返回: None。异常: TypeError/ValueError,状态或计数不合法。"""
23
+ require_identifier(self.rule_id, 'rule_id')
24
+ if self.status not in ('no_observation', 'insufficient_data', 'events_found',
25
+ 'duration_not_met', 'condition_not_met', 'no_event'):
26
+ raise ValueError('规则结果状态无效')
27
+ if type(self.event_count) is not int or self.event_count < 0 or type(self.has_unknown) is not bool:
28
+ raise TypeError('规则结果需要非负事件计数和布尔未知标记')
29
+ if type(self.unobserved_signals) is not tuple or len(set(self.unobserved_signals)) != len(self.unobserved_signals):
30
+ raise TypeError('未观测信号需要无重复tuple')
31
+ for name in self.unobserved_signals:
32
+ require_identifier(name, 'unobserved_signal')
33
+ if (self.status == 'events_found') != (self.event_count > 0):
34
+ raise ValueError('规则结果状态与事件计数不一致')
35
+
36
+ def to_dict(self):
37
+ """参数: 无。返回: 小型JSON对象。异常: 无;不读取结果或输入。"""
38
+ return asdict(self)
39
+
40
+
41
+ @dataclass(frozen=True)
42
+ class AnalysisOutcome:
43
+ """规则状态与指标行计数;不根据事件数推断能量正确或数据完整。"""
44
+
45
+ rules: tuple[RuleOutcome, ...] = ()
46
+ complete: int = 0
47
+ partial: int = 0
48
+ indeterminate: int = 0
49
+ no_observation: int = 0
50
+
51
+ def __post_init__(self):
52
+ """参数: 无。返回: None。异常: TypeError/ValueError,重复规则或错误计数。"""
53
+ if type(self.rules) is not tuple or any(type(item) is not RuleOutcome for item in self.rules):
54
+ raise TypeError('分析概况需要RuleOutcome tuple')
55
+ if len({item.rule_id for item in self.rules}) != len(self.rules):
56
+ raise ValueError('分析概况规则重复')
57
+ for value in (self.complete, self.partial, self.indeterminate, self.no_observation):
58
+ if type(value) is not int or value < 0:
59
+ raise ValueError('指标概况计数需要非负整数')
60
+ if self.no_observation > self.complete + self.partial + self.indeterminate:
61
+ raise ValueError('无观测指标数不能超过指标总数')
62
+
63
+ def to_dict(self):
64
+ """参数: 无。返回: 清单/CLI同用的JSON对象。异常: 无。"""
65
+ return dict(rules=[item.to_dict() for item in self.rules], calculations=dict(
66
+ complete=self.complete, partial=self.partial, indeterminate=self.indeterminate,
67
+ no_observation=self.no_observation))