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,778 @@
1
+ """在原AnalysisRunner会话内合并所需来源并执行会话时间指标。
2
+
3
+ 共享同刻最新状态;每项指标只保自己的驱动点和归约状态。输入只读一次,
4
+ 不创建普通历史、消息历史或完整贡献。均值仅保其算法必需的值与权重暂存。
5
+ 每来源只保有界前瞻,同刻跨来源更新收齐后求值。所有输入真正EOF并关闭
6
+ 后才交付最终结果,失败不发布已累计的前缀。
7
+ """
8
+
9
+ from dataclasses import replace
10
+ from ..core.models import Interval
11
+ from functools import partial
12
+ from ..core.calculations import CalculationDefinition
13
+ from ..legacy.records import field_to_dict
14
+ from ..results.errors import ResultClosedError, AnalysisError
15
+ from ..results.spool import _reserve_owned_ram, _release_owned_ram, _cleanup_owner
16
+ from ..results.summary import SummaryCalculationRow
17
+ from ..results.summary import SummaryCoverageCalculationRow
18
+ from ..results.summary import SummaryEventRow
19
+ from ..results.summary import SummarySequenceRow
20
+ from ..sources.can_spec import can_field_from_key
21
+ from .history import _metadata_bytes
22
+ from .state import LatestSignalState
23
+ from .driver_expression import DriverExpression
24
+ from .record_integral import RecordIntegral
25
+ from .record_time_calculation import RecordTimeCalculation
26
+ from .record_source_cursor import RecordSourceCursor
27
+ from .groups import DecodedTimeGroup
28
+ from .current_message_calculation import CurrentMessageCalculation
29
+ from ..legacy.sum import LegacySkipReason
30
+ from .record_rule_timeline import RecordRuleTimeline
31
+ from .record_sequences import RecordSequences
32
+ from ..planning.intervals import IntervalChoice
33
+ from .record_event_durations import RecordEventDurations,is_event_duration
34
+ from .record_scope_calculations import RecordScopeCalculations
35
+ from .record_time_indexes import RecordTimeIndexes
36
+ from .record_windows import RecordWindows
37
+ from .record_exports import RecordExports
38
+ from ..results.summary import SummarySegmentRow
39
+ from ..results.summary import SummaryContributionRow
40
+ from ..results.summary import SummaryInputRow
41
+ from .record_diagnostics import RecordDiagnostics
42
+ from .record_selection import RecordSelection
43
+ from ..results.summary import SummarySelectionRow
44
+
45
+
46
+ class RecordSessionCalculations:
47
+ """拥有实时计算和读取子资源;计划与最终结果仓只借用。"""
48
+
49
+ def __init__(self, plan, budget, work_dir, *, requirements=None):
50
+ """预约有限声明空间,不启动读取。
51
+
52
+ 参数: plan已校验计划、budget共享预算、work_dir已有私有运行目录。
53
+ 返回: 新owner。异常: 构造原错附record_session_cleanup_owner供父会话接管。
54
+ """
55
+ self._plan, self._budget, self._path = plan, budget, work_dir
56
+ self._full_domain = plan.dataset.domain is None
57
+ self._observed_domain = None
58
+ if requirements is None:
59
+ from ..planning.input_requirements import collect_input_requirements
60
+ requirements=collect_input_requirements(plan)
61
+ self._requirements=requirements
62
+ self._held_cost = self._fixed_cost = self._group_cost = 0
63
+ self._state = self._groups = self._adapter = self._read = self._pending = None
64
+ self._calculations = self._expressions = self._cursors = None
65
+ self._messages = None
66
+ # 汇总请求共享一份有界目标消息批;完整贡献保原逐消息输出次序。
67
+ self._message_buffer = []
68
+ self._message_cost = 0
69
+ self._message_batch_rows = (1 if plan.outputs.contributions == 'full'
70
+ else min(plan.execution.batch_rows, 4096))
71
+ self._source_ends = None
72
+ self._rules = None
73
+ self._sequences = None
74
+ self._event_durations=None
75
+ self._scope_calculations=None
76
+ self._time_indexes=self._windows=self._exports=None
77
+ self._diagnostics=None
78
+ self._rules_begun = False
79
+ self._constant_calculations=frozenset()
80
+ self._spool = None
81
+ self._next_sequence = 0
82
+ # 指标状态随原写出计数;不为了概况回读结果仓。
83
+ self._outcome_counts = dict(complete=0, partial=0, indeterminate=0, no_observation=0)
84
+ self._closed = self._closing = self._failed = self._started = False
85
+ try:
86
+ _reserve_owned_ram(self, 131584 + 64 * _metadata_bytes(
87
+ (plan.calculations, plan.intervals, plan.signals)), '_fixed_cost')
88
+ self._calculations, self._expressions, self._cursors, self._messages = [], [], [], []
89
+ self._source_ends = {}
90
+ self._rules = []
91
+ except BaseException as error:
92
+ _cleanup_owner(self, error, 'record_session_cleanup_owner', '记录流会话构造')
93
+ raise
94
+
95
+ def _new(self, factory, recovery, *args, **kwargs):
96
+ """保留尚未交付的真实子owner。参数: 工厂/恢复属性/参数。返回: owner。异常: 原错。"""
97
+ try:
98
+ return factory(*args, **kwargs)
99
+ except BaseException as error:
100
+ self._pending = getattr(error, recovery, None)
101
+ raise
102
+
103
+ def _consume_group(self, group):
104
+ """先原子提交同刻组,再分别按所选报文推进各指标。
105
+
106
+ 参数: 完整DecodedTimeGroup。返回: None。异常: 表达式/预算/累计原错。
107
+ 非驱动无效更新仅截断待算值,不新增周期;条件截止独立处理。
108
+ """
109
+ try:
110
+ if self._diagnostics is not None:
111
+ raw_sources={c.source_name for c in self._cursors if c._raw}
112
+ for sample in group.samples:
113
+ if sample.source_ref.source_name not in raw_sources:
114
+ values_needed=set(self._requirements.ordinary_sample_aliases)|set(self._requirements.message_aliases)
115
+ clock_only=sample.name not in values_needed
116
+ self._diagnostics.consume(sample.source_ref.source_name,sample.sequence,sample.time_ns,
117
+ 'signal_clock' if clock_only else 'signal_sample',sample.source_ref.field,
118
+ {} if clock_only else {sample.name:sample.value.value},sample.value.quality)
119
+ if self._time_indexes is not None:
120
+ self._time_indexes.observe_group(group)
121
+ if self._event_durations is not None:
122
+ self._event_durations.observe_group(group)
123
+ for owner in self._rules:
124
+ ends=[self._source_ends[source] for source in owner.sources if source in self._source_ends]
125
+ if len(ends)==len(owner.sources) and ends and max(ends)<group.time_ns:
126
+ owner.finish(max(ends))
127
+ owner.before_group(group.time_ns)
128
+ owner.clock_group(group)
129
+ if self._sequences is not None:
130
+ self._sequences.flush_before(group.time_ns)
131
+ if self._exports is not None and self._exports._signal is not None:
132
+ self._exports._signal.observe(group)
133
+ if self._state is not None:
134
+ selected=tuple(s for s in group.samples if s.name in self._state.definitions)
135
+ if selected:
136
+ self._state.apply(group if len(selected)==len(group.samples) else DecodedTimeGroup(group.time_ns,selected))
137
+ if self._scope_calculations is not None:
138
+ self._scope_calculations.observe_group()
139
+ if self._sequences is not None:
140
+ self._sequences.drivers(group)
141
+ for index,(calculation, expressions) in enumerate(zip(self._calculations, self._expressions)):
142
+ if index in self._constant_calculations:
143
+ continue
144
+ value, condition = expressions
145
+ row = value.evaluate()
146
+ selected = condition.evaluate() if condition is not None else None
147
+ if value.invalidated_at is not None:
148
+ calculation.expire_at(value.invalidated_at)
149
+ if condition is not None and condition.invalidated_at is not None:
150
+ calculation.expire_at(condition.invalidated_at, condition=True)
151
+ if row is not None:
152
+ updates=({'actual_value_updates':(any(s.name in value._static.dependencies for s in group.samples),)}
153
+ if getattr(calculation,'_samples',False) else {})
154
+ if condition is None:
155
+ calculation.consume((row,),**updates)
156
+ else:
157
+ if selected is None or selected[0] != row[0]:
158
+ raise AnalysisError('值和条件未按同一驱动组求值')
159
+ calculation.consume((row,), conditions=(selected[1],),
160
+ condition_valid_until_ns=(selected[2],),**updates)
161
+ for owner in self._rules:
162
+ owner.after_group(group.time_ns)
163
+ ends=[self._source_ends[source] for source in owner.sources if source in self._source_ends]
164
+ if len(ends)==len(owner.sources) and ends and max(ends)==group.time_ns:
165
+ owner.finish(max(ends))
166
+ finally:
167
+ group = calculation = expressions = value = condition = row = selected = None
168
+
169
+ def _emit_selection(self,request,parent,row):
170
+ """按请求保存一份选择值及状态。参数: 请求/父ID/旧核借入行。返回: None。异常: 暂存错误。"""
171
+ dataset=self._plan.dataset
172
+ self._spool.append(SummarySelectionRow(self._next_sequence,dataset.dataset_id,dataset.entity,
173
+ dataset.session_id,request.calculation_id,request.scope.split(':',1)[0],parent,row.time_ns,
174
+ row.value.value if row.value.valid else None,row.value.dtype.value,row.unit,row.value.valid,
175
+ row.selection.value,row.quality))
176
+ self._next_sequence+=1
177
+
178
+ def _emit_input_trace(self,source,sequence,time_ns,record_type,locator,values,quality):
179
+ """仅按trace请求写最终追溯表。参数: 本次必要输入定位。返回: None。异常: 暂存错误。"""
180
+ dataset=self._plan.dataset
181
+ self._spool.append(SummaryInputRow(self._next_sequence,dataset.dataset_id,dataset.entity,
182
+ dataset.session_id,source,sequence,time_ns,record_type,locator,values,quality))
183
+ self._next_sequence+=1
184
+
185
+ def _emit_contribution(self, request, contribution, quality):
186
+ """仅按请求写计算定位和值/跳过。参数: 请求、借入贡献及本次质量。返回: None。异常: 暂存原错。"""
187
+ update=contribution.update
188
+ dataset=self._plan.dataset
189
+ self._spool.append(SummaryContributionRow(self._next_sequence,dataset.dataset_id,dataset.entity,
190
+ dataset.session_id,request.calculation_id,update.source,update.sequence,update.evaluation_index,
191
+ contribution.value,contribution.skip_reason.value if contribution.skip_reason is not None else 'contributed',
192
+ quality))
193
+ self._next_sequence+=1
194
+
195
+ def execute_into(self, spool):
196
+ """一次读取并向原结果仓追加已完成指标;不发布文件。
197
+
198
+ 参数: 本次原ResultSpool。返回: None。异常: 任一输入/计算失败附真实恢复owner。
199
+ 只构造所需字段;独立驱动仅传帧定位,DBC周期在首帧前取得一次。
200
+ """
201
+ if self._closed or self._closing or self._failed or self._started:
202
+ raise ResultClosedError('记录流会话只能执行一次')
203
+ self._started = True
204
+ self._spool = spool
205
+ plan = self._plan
206
+ try:
207
+ choices = dict(plan.intervals.resolved)
208
+ for request in plan.calculations:
209
+ if request.operation in ('sample_minimum','sample_maximum','sample_mean','select'):
210
+ choices[request.calculation_id]=IntervalChoice('actual')
211
+ self._constant_calculations=frozenset(index for index,calculation in
212
+ enumerate(m for m in plan.calculations if m.scope=='session')
213
+ if choices[calculation.calculation_id].driver is None and not any(
214
+ expression.dependencies for expression in (calculation.signal,calculation.condition) if expression is not None))
215
+ needed=self._requirements
216
+ if plan.diagnostics.trace or plan.diagnostics.integrity:
217
+ self._diagnostics=self._new(RecordDiagnostics,'record_diagnostics_cleanup_owner',
218
+ plan,needed,self._budget,self._emit_input_trace)
219
+ observe_bounds=needed.constant_observation
220
+ values=set(needed.ordinary_sample_aliases)|set(needed.message_aliases)
221
+ clocks={name for source in needed.sources for name in source.clock_aliases}
222
+ group_names=set(needed.ordinary_sample_aliases)|clocks
223
+ state_names=set(needed.analysis_sample_aliases)|clocks
224
+ export_names=set() if plan.outputs.signal_csv is None else set(plan.outputs.signal_csv.spec.signals)
225
+ export_sources={item.definition.source for item in plan.signals if item.definition.name in export_names}
226
+ for request in plan.message_calculations:
227
+ values.update(request.expr.dependencies)
228
+ if request.disjunction is not None:
229
+ values.add(request.disjunction.signal)
230
+ owner = self._new(CurrentMessageCalculation, 'current_message_calculation_cleanup_owner',
231
+ request, plan.sources, plan.bindings, plan.dataset.session_id, self._budget,
232
+ backend=plan.execution.backend, batch_rows=self._message_batch_rows, domain=plan.dataset.domain,
233
+ contribution_consumer=(partial(self._emit_contribution,request)
234
+ if plan.outputs.contributions=='full' else None))
235
+ self._messages.append((request, owner))
236
+ definitions = tuple(item.definition for item in plan.signals
237
+ if item.definition.name in values | clocks)
238
+ state = None
239
+ source_cursors = {}
240
+ for source in plan.sources:
241
+ source_definitions = tuple(item for item in definitions if item.source == source.name)
242
+ selectors = tuple(item.update_message for item in plan.message_calculations if item.source == source.name)
243
+ keys = tuple(dict.fromkeys((item.channel, item.frame_id, item.is_extended, item.is_fd) for item in selectors))
244
+ retain_frames=plan.outputs.can_frames is not None and plan.outputs.can_frames.source==source.name
245
+ source_requirement=needed.for_source(source.name)
246
+ if source_requirement.active:
247
+ cursor = self._new(RecordSourceCursor, 'record_source_cleanup_owner',
248
+ plan, source, source_definitions, values, clocks, self._budget,
249
+ self._path / ('input-' + source.name), group_names=group_names,
250
+ message_consumer=self._consume_message if keys or self._diagnostics is not None else None, message_keys=keys,observe_bounds=observe_bounds or source.name in export_sources,retain_frames=retain_frames,requirements=source_requirement)
251
+ self._cursors.append(cursor)
252
+ source_cursors[source.name] = cursor
253
+ # 复用本次来源初始化得到的DBC周期,首帧前补齐默认有效期。
254
+ # 不提前构造带假有效期的计算状态;无关信号不进入definitions。
255
+ from .signal_validity import resolve_signal_validity
256
+ definitions = resolve_signal_validity(definitions, source_cursors)
257
+ if self._full_domain:
258
+ # 零长度只供尚未收到输入的数值owner构造,不作为观测或读取过滤条件。
259
+ # 游标已用原始None请求创建;每轮前瞻后改成真实已读范围。
260
+ plan = replace(plan, dataset=replace(plan.dataset, domain=Interval(0, 0)))
261
+ self._plan = plan
262
+ if state_names or observe_bounds:
263
+ state = self._state = self._new(LatestSignalState, 'state_cleanup_owner',
264
+ self._budget, tuple(item for item in definitions if item.name in state_names), plan.dataset.session_id)
265
+ if plan.outputs.can_frames is not None or plan.outputs.signal_csv is not None:
266
+ self._exports=self._new(RecordExports,'record_exports_cleanup_owner',
267
+ plan,self._budget,self._path/'exports',self._cursors)
268
+ derived = tuple(item.definition for item in plan.derived)
269
+ for request in plan.calculations:
270
+ if request.scope!='session':
271
+ continue
272
+ choice = choices[request.calculation_id]
273
+ step = choice.step_ns
274
+ if choice.mode == 'dbc':
275
+ locator = field_to_dict(can_field_from_key(state.definitions[choice.driver].field))
276
+ metadata = source_cursors[state.definitions[choice.driver].source].metadata
277
+ step = next(item['cycle_ns'] for item in metadata['fields'] if item['locator'] == locator)
278
+ expression = request.signal if request.signal is not None else request.condition
279
+ condition = request.condition if request.signal is not None else None
280
+ # 先登记可达槽,再构造下一个子资源,避免后续构造失败遗失前者。
281
+ self._expressions.append([None, None])
282
+ for index, static in enumerate((expression, condition)):
283
+ if static is not None:
284
+ self._expressions[-1][index] = self._new(DriverExpression,
285
+ 'driver_expression_cleanup_owner', static, state, choice.driver,
286
+ backend=plan.execution.backend, derived=derived, observation_ends=self._source_ends)
287
+ spec = CalculationDefinition(request.calculation_id, request.operation, plan.dataset.domain,
288
+ request.partial_policy, request.unit, minimum_coverage=request.minimum_coverage)
289
+ factory = RecordIntegral if request.operation == 'integral' else RecordTimeCalculation
290
+ recovery = 'record_integral_cleanup_owner' if request.operation == 'integral' else 'record_time_cleanup_owner'
291
+ extra = {'work_dir': self._path} if request.operation == 'time_weighted_mean' else {}
292
+ if request.operation=='select':
293
+ factory,recovery=RecordSelection,'record_selection_cleanup_owner'
294
+ extra={'consumer':partial(self._emit_selection,request,None)}
295
+ self._calculations.append(self._new(factory, recovery, self._budget, spec,
296
+ expression.root.unit, expression.root.dtype, step, backend=plan.execution.backend,
297
+ batch_intervals=min(plan.execution.batch_rows, 4096), conditioned=condition is not None, **extra))
298
+ metadata = None
299
+ event_requests=tuple(item for item in plan.calculations if is_event_duration(item))
300
+ index_ids={item.calculation_id for item in event_requests}|{item.window_id for item in plan.windows}
301
+ drivers=tuple(dict.fromkeys(choices[name].driver for name in index_ids if choices[name].mode!='actual'))
302
+ if drivers:
303
+ self._time_indexes=self._new(RecordTimeIndexes,'record_time_indexes_cleanup_owner',
304
+ self._budget,self._path,drivers)
305
+ if plan.windows:
306
+ steps={}
307
+ for request in plan.windows:
308
+ choice=choices[request.window_id]
309
+ step=choice.step_ns
310
+ if choice.mode=='dbc':
311
+ definition=state.definitions[choice.driver]
312
+ locator=field_to_dict(can_field_from_key(definition.field))
313
+ step=next(item['cycle_ns'] for item in source_cursors[definition.source].metadata['fields']
314
+ if item['locator']==locator)
315
+ steps[request.window_id]=step
316
+ self._windows=self._new(RecordWindows,'record_windows_cleanup_owner',
317
+ plan,self._budget,self._time_indexes,steps,self._emit_segment)
318
+ if event_requests:
319
+ steps={}
320
+ for request in event_requests:
321
+ choice=choices[request.calculation_id]
322
+ step=choice.step_ns
323
+ if choice.mode=='dbc':
324
+ definition=state.definitions[choice.driver]
325
+ locator=field_to_dict(can_field_from_key(definition.field))
326
+ step=next(item['cycle_ns'] for item in source_cursors[definition.source].metadata['fields']
327
+ if item['locator']==locator)
328
+ steps[request.calculation_id]=step
329
+ self._event_durations=self._new(RecordEventDurations,'record_event_duration_cleanup_owner',
330
+ plan,self._budget,self._path,steps,self._emit_event_duration,indexes=self._time_indexes)
331
+ scope_requests=tuple(item for item in plan.calculations if item.scope!='session' and not is_event_duration(item))
332
+ if scope_requests:
333
+ steps={}
334
+ for request in scope_requests:
335
+ choice=choices[request.calculation_id]
336
+ step=choice.step_ns
337
+ if choice.mode=='dbc':
338
+ definition=state.definitions[choice.driver]
339
+ locator=field_to_dict(can_field_from_key(definition.field))
340
+ step=next(item['cycle_ns'] for item in source_cursors[definition.source].metadata['fields']
341
+ if item['locator']==locator)
342
+ steps[request.calculation_id]=step
343
+ self._scope_calculations=self._new(RecordScopeCalculations,'record_scope_calculations_cleanup_owner',
344
+ plan,state,self._budget,self._path,steps,scope_requests,self._source_ends,self._emit_event_duration,
345
+ selection_consumer=self._emit_selection)
346
+ if plan.sequences:
347
+ steps={}
348
+ for request in plan.sequences:
349
+ choice=choices[request.sequence_id]
350
+ step=choice.step_ns
351
+ if choice.mode=='dbc':
352
+ definition=state.definitions[choice.driver]
353
+ locator=field_to_dict(can_field_from_key(definition.field))
354
+ step=next(item['cycle_ns'] for item in source_cursors[definition.source].metadata['fields']
355
+ if item['locator']==locator)
356
+ steps[request.sequence_id]=step
357
+ self._sequences=self._new(RecordSequences,'record_sequences_cleanup_owner',
358
+ plan,state,self._budget,steps,self._emit_sequence)
359
+ for request in plan.rules:
360
+ if any(p.preset_type=='threshold_excursion' and request.rule_id==p.id+'_activity' for p in plan.presets):
361
+ request=replace(request,stability=replace(request.stability,track_duration=True))
362
+ choice=choices.get(request.rule_id,IntervalChoice('actual'))
363
+ step=choice.step_ns
364
+ if choice.mode=='dbc':
365
+ definition=state.definitions[choice.driver]
366
+ locator=field_to_dict(can_field_from_key(definition.field))
367
+ step=next(item['cycle_ns'] for item in source_cursors[definition.source].metadata['fields']
368
+ if item['locator']==locator)
369
+ self._rules.append(self._new(RecordRuleTimeline,'record_rule_cleanup_owner',
370
+ plan,request,state,self._budget,step,choice.driver,self._source_ends,self._emit_event,
371
+ step_consumer=None if self._sequences is None else self._sequences.observe))
372
+ self._merge_sources()
373
+ # 真正EOF并关闭来源后,提交不足一批的尾部;失败不发布前缀。
374
+ self._flush_messages()
375
+ if self._exports is not None:
376
+ self._exports.session()
377
+ self._consume_constants()
378
+ self._finish_actual_tails()
379
+ if self._scope_calculations is not None:
380
+ self._scope_calculations.finish(self._cursors)
381
+ if self._event_durations is not None:
382
+ self._event_durations.finish()
383
+ if self._windows is not None:
384
+ self._windows.finish(self._cursors,spool)
385
+ if self._exports is not None:
386
+ self._exports.seal()
387
+ for sequence, (request, calculation) in enumerate(zip((m for m in plan.calculations if m.scope=='session'), self._calculations)):
388
+ result = calculation.finish()
389
+ if request.operation=='select':continue
390
+ if self._full_domain and self._observed_domain is None:
391
+ result = replace(result, value=None, status='indeterminate', reason='no_observation')
392
+ model=SummaryCalculationRow if result.coverage_status is None else SummaryCoverageCalculationRow
393
+ extra={} if result.coverage_status is None else {'coverage_status':result.coverage_status}
394
+ spool.append(model(self._next_sequence, plan.dataset.dataset_id, plan.dataset.entity,
395
+ plan.dataset.session_id, request.calculation_id, request.operation, 'session', None,
396
+ result.value, result.unit, result.status, result.reason, result.quality,**extra))
397
+ self._count_outcome(result.status,result.reason)
398
+ self._next_sequence+=1
399
+ for sequence, (request, owner) in enumerate(self._messages, len(plan.calculations)):
400
+ result = owner.snapshot()
401
+ incomplete = any(count for reason, count in result.skip_counts.items()
402
+ if reason is not LegacySkipReason.CONDITION_FALSE)
403
+ status = 'indeterminate' if result.value is None else 'partial' if incomplete else 'complete'
404
+ spool.append(SummaryCalculationRow(self._next_sequence, plan.dataset.dataset_id, plan.dataset.entity,
405
+ plan.dataset.session_id, request.calculation_id, 'legacy_sum', 'session', None,
406
+ None if result.value is None else round(result.value, 6), request.unit, status,
407
+ result.reason or ('partial_input' if incomplete else 'ok'), owner.quality))
408
+ self._count_outcome(status,result.reason)
409
+ self._next_sequence+=1
410
+ except BaseException as error:
411
+ self._failed = True
412
+ error.record_session_cleanup_owner = self
413
+ raise
414
+ finally:
415
+ metadata = definitions = derived = state = batch = result = source_cursors = cursor = source_definitions = None
416
+ self._spool=None
417
+
418
+ def _finish_actual_tails(self):
419
+ """以实际来源EOF结算连续计算和样本统计,固定周期不凭空加报文。
420
+
421
+ 参数: 无,读取已耗尽游标、最新状态及尚待结算的末点。
422
+ 返回: None。异常: 表达式、预算或累计错误原样传播。
423
+ 不新增样本、贡献或追溯;观察结束和TTL都来自真实输入,domain仅负责裁剪。
424
+ """
425
+ for index, (calculation, expressions) in enumerate(zip(self._calculations, self._expressions)):
426
+ samples = getattr(calculation, '_samples', False)
427
+ if (index in self._constant_calculations
428
+ or not samples and calculation._step_ns is not None or not calculation._rows):
429
+ continue
430
+ value, condition = expressions
431
+ sources = {definition.source for expression in expressions if expression is not None
432
+ for _, definition in expression._definitions}
433
+ ends = [self._source_ends[source] for source in sources if source in self._source_ends]
434
+ if not ends or max(ends) <= calculation._last_time:
435
+ continue
436
+ start, end = calculation._last_time, max(ends)
437
+ # 最后组当时可能尚未知另一来源EOF;现在按右侧保持重算,不能沿用已结束来源的点值。
438
+ current, deadline = value.evaluate_at(start)
439
+ selected, condition_deadline = (None, None) if condition is None else condition.evaluate_at(start)
440
+ if samples:
441
+ # 保留真实末点及其更新标志;EOF查询只补齐有效截止,不把保持值写成新样本。
442
+ # 某依赖来源已在末点结束时,其右侧保持无效,仍沿用既有半开EOF政策。
443
+ previous = calculation._rows[-1]
444
+ value_ends = tuple(t for t in (previous[2], deadline,
445
+ start if not current.valid else None) if t is not None)
446
+ condition_ends = tuple(t for t in (previous[4], condition_deadline,
447
+ start if selected is not None and not selected.valid else None) if t is not None)
448
+ calculation._rows[-1] = (start, previous[1], min(value_ends) if value_ends else None,
449
+ previous[3], min(condition_ends) if condition_ends else None) + previous[5:]
450
+ else:
451
+ calculation._rows[-1] = (start, current, deadline, selected, condition_deadline)
452
+ calculation.consume(((end, current, deadline),),
453
+ **({'actual_value_updates': (False,)} if samples else {}),
454
+ **({} if condition is None else
455
+ {'conditions': (selected,), 'condition_valid_until_ns': (condition_deadline,)}))
456
+
457
+ def _consume_constants(self):
458
+ """常量只需真实首末范围,EOF后复用相同统计核,不创建假信号或逐行值。
459
+
460
+ 参数: 无。返回: None。异常: 求值/预算/计算原错;无观测不喂任何点。
461
+ """
462
+ if not self._constant_calculations:
463
+ return
464
+ starts=[c.observed_start for c in self._cursors if c.observed_start is not None]
465
+ ends=[c.observed_end for c in self._cursors if c.observed_start is not None and c.observed_end is not None]
466
+ if not starts or not ends:
467
+ return
468
+ first,last=min(starts),max(ends)
469
+ for index in self._constant_calculations:
470
+ calculation=self._calculations[index]
471
+ value,condition=self._expressions[index]
472
+ result,_=value.evaluate_at(last)
473
+ selected=None if condition is None else condition.evaluate_at(last)[0]
474
+ for time in dict.fromkeys((first,last)):
475
+ calculation.consume(((time,result,None),),**({} if condition is None else
476
+ {'conditions':(selected,),'condition_valid_until_ns':(None,)}))
477
+
478
+ def _emit_event(self,event):
479
+ """将必要事件字段直接写一次最终结果仓。参数: 原核心事件。返回: None。异常: 原写入错。"""
480
+ try:
481
+ plan=self._plan
482
+ self._spool.append(SummaryEventRow(self._next_sequence,plan.dataset.dataset_id,plan.dataset.entity,
483
+ plan.dataset.session_id,event.rule.rule_id,event.event_id,event.start_ns,event.confirmed_ns,
484
+ event.end_ns,event.status,event.trigger_kind,event.quality))
485
+ self._next_sequence+=1
486
+ if self._event_durations is not None:
487
+ self._event_durations.observe_event(event)
488
+ if self._scope_calculations is not None:
489
+ self._scope_calculations.observe_event(event)
490
+ finally:
491
+ event=None
492
+
493
+ def _emit_event_duration(self,request,event_id,result):
494
+ """把每段事件指标直接写最终指标表。参数: 请求/父ID/结果。返回: None。异常: 原发布错。"""
495
+ plan=self._plan
496
+ model=SummaryCalculationRow if result.coverage_status is None else SummaryCoverageCalculationRow
497
+ extra={} if result.coverage_status is None else {'coverage_status':result.coverage_status}
498
+ self._spool.append(model(self._next_sequence,plan.dataset.dataset_id,plan.dataset.entity,
499
+ plan.dataset.session_id,request.calculation_id,request.operation,request.scope.split(':',1)[0],event_id,
500
+ result.value,result.unit,result.status,result.reason,result.quality,**extra))
501
+ self._count_outcome(result.status,result.reason)
502
+ self._next_sequence+=1
503
+
504
+ def _emit_segment(self,segment):
505
+ """只写实际片段与父关联,后续指标借用同一片段。参数: 核心片段。返回: None。异常: 原发布/计算错。"""
506
+ if self._exports is not None:
507
+ self._exports.segment(segment)
508
+ plan=self._plan
509
+ actual=segment.actual
510
+ self._spool.append(SummarySegmentRow(self._next_sequence,plan.dataset.dataset_id,plan.dataset.entity,
511
+ plan.dataset.session_id,segment.window_id,segment.segment_id,
512
+ None if actual is None else actual.start_ns,None if actual is None else actual.end_ns,
513
+ segment.status,segment.parent_event_ids,segment.quality))
514
+ self._next_sequence+=1
515
+ if self._scope_calculations is not None:
516
+ self._scope_calculations.observe_segment(segment)
517
+
518
+ def _count_outcome(self,status,reason):
519
+ """随已写出的指标计数。参数: 行状态/原因。返回: None。异常: 未支持的内部状态。"""
520
+ self._outcome_counts[status] += 1
521
+ if reason in ('no_observation','no_evaluations'):
522
+ self._outcome_counts['no_observation'] += 1
523
+
524
+ def analysis_outcome(self):
525
+ """取得同次规则和指标概况。参数: 无。返回: AnalysisOutcome。异常: 规则未完成。"""
526
+ from ..results.analysis_outcome import AnalysisOutcome
527
+ return AnalysisOutcome(tuple(owner.outcome() for owner in self._rules),**self._outcome_counts)
528
+
529
+ def threshold_summaries(self):
530
+ """生成明确预设请求的有限汇总,不复制状态轨迹。参数: 无。返回: tuple。异常: 未完成统计错误。"""
531
+ from ..results.threshold_metadata import SummaryThresholdDuration
532
+ presets={preset.id:preset for preset in self._plan.presets if preset.preset_type=='threshold_excursion'}
533
+ result=[]
534
+ for owner in self._rules:
535
+ name=owner._request.rule_id
536
+ preset_id=name.removesuffix('_activity')
537
+ if preset_id in presets:
538
+ value,status=owner.duration_result
539
+ result.append(SummaryThresholdDuration(preset_id,name,value,status))
540
+ return tuple(result)
541
+
542
+ def _emit_sequence(self,result):
543
+ """只写最终配对结论,不复制事件全文。参数: 核心结果。返回: None。异常: 原写入错。"""
544
+ try:
545
+ plan=self._plan
546
+ self._spool.append(SummarySequenceRow(self._next_sequence,plan.dataset.dataset_id,plan.dataset.entity,
547
+ plan.dataset.session_id,result.rule.rule_id,result.result_id,result.request.event_id,
548
+ None if result.response is None else result.response.event_id,result.decided_ns,
549
+ result.delay_ns,result.status,result.observation_quality))
550
+ self._next_sequence+=1
551
+ finally:
552
+ result=None
553
+
554
+ def _consume_message(self, update):
555
+ """按原序收集有限目标批,供同来源各累计器共用。
556
+
557
+ 参数: update是只借用到本回调结束的原消息;延长寿命前先付费。
558
+ 返回: None。异常: 预算、计算或取消原错;完整明细仍逐消息交付。
559
+ """
560
+ try:
561
+ if self._diagnostics is not None:
562
+ self._diagnostics.consume(update.source,update.sequence,update.time_ns,
563
+ 'decoded_message',f'can:{update.channel}:{update.frame_id}:{int(update.is_extended)}:{int(update.is_fd)}',
564
+ update.values,update.quality)
565
+ if not any(request.source == update.source for request, _ in self._messages):
566
+ return
567
+ if self._message_batch_rows == 1:
568
+ for request, owner in self._messages:
569
+ if request.source == update.source:
570
+ owner.consume((update,))
571
+ return
572
+ # 来源切换时先提交上一批,绝不将不同来源输入混入同一求和序列。
573
+ if self._message_buffer and self._message_buffer[0].source != update.source:
574
+ self._flush_messages()
575
+ cost = 16384 + 16 * _metadata_bytes(update)
576
+ # 为下一次实际计算留出空间,不能只按缓存本身是否放得下填满预算。
577
+ row_cost = max(owner._row_cost for request, owner in self._messages
578
+ if request.source == update.source)
579
+ compute_cost = 16384 + (len(self._message_buffer) + 1) * row_cost
580
+ # 读取器还可能构造本批返回列,不能把它尚未申请的费用当成空闲缓存。
581
+ # 消息延长持有最多占总预算的1/16,其余仍供读取、计算和结果共用。
582
+ buffer_limit = self._budget.memory_budget_bytes // 16
583
+ if (self._message_buffer and (self._message_cost + cost > buffer_limit
584
+ or self._budget.ram_bytes + cost + compute_cost
585
+ > self._budget.memory_budget_bytes)):
586
+ self._flush_messages()
587
+ _reserve_owned_ram(self, cost, '_message_cost')
588
+ self._message_buffer.append(update)
589
+ if (len(self._message_buffer) >= self._message_batch_rows
590
+ or self._message_cost >= buffer_limit):
591
+ self._flush_messages()
592
+ finally:
593
+ update = None
594
+
595
+ def _flush_messages(self):
596
+ """共享当前目标批完成各汇总计算,不创建历史或逐次输出。
597
+
598
+ 参数: 无,使用已付费的有限消息缓冲。返回: None。
599
+ 异常: 原计算/取消错误优先;清理失败保留费用,供close重试。
600
+ """
601
+ if not self._message_buffer:
602
+ return
603
+ updates = tuple(self._message_buffer)
604
+ primary = None
605
+ try:
606
+ for request, owner in self._messages:
607
+ if request.source == updates[0].source:
608
+ owner.consume(updates)
609
+ except BaseException as error:
610
+ primary = error
611
+ raise
612
+ finally:
613
+ # 即使计算失败也不重放可能已经累计过的批;只允许资源清理。
614
+ updates = None
615
+ self._message_buffer.clear()
616
+ try:
617
+ _release_owned_ram(self, self._message_cost, '_message_cost')
618
+ except BaseException as cleanup:
619
+ if primary is None:
620
+ raise
621
+ primary.add_note('目标消息批费用清理失败:' + type(cleanup).__name__)
622
+
623
+ def _advance_observed_domain(self):
624
+ """用已付费游标的真实首末更新在线范围,不读取更多输入或保存时间序列。
625
+
626
+ 参数: 无。返回: None。显式范围保持原裁剪规则;省略范围只保一个当前并集。
627
+ 异常: 非法时间或已封闭检测器的推进错误沿原清理路径传播。
628
+ """
629
+ if not self._full_domain:
630
+ return
631
+ starts = [c.observed_start for c in self._cursors if c.observed_start is not None]
632
+ ends = [c.observed_end for c in self._cursors if c.observed_end is not None]
633
+ if not starts or not ends:
634
+ return
635
+ domain = Interval(min(starts), max(ends))
636
+ if domain == self._observed_domain:
637
+ return
638
+ self._observed_domain = domain
639
+ self._plan = replace(self._plan, dataset=replace(self._plan.dataset, domain=domain))
640
+ for calculation in self._calculations:
641
+ calculation._spec = replace(calculation._spec, window=domain)
642
+ reduction = getattr(calculation, '_reduction', None)
643
+ if reduction is not None:
644
+ reduction._spec = calculation._spec
645
+ for owner in self._rules:
646
+ owner._plan = self._plan
647
+ owner.extend_observation(domain.end_ns)
648
+ for owner in (self._sequences, self._windows, self._scope_calculations,
649
+ self._event_durations, self._exports):
650
+ if owner is not None:
651
+ owner._plan = self._plan
652
+ if self._exports is not None and self._exports._signal is not None:
653
+ self._exports._signal.update_observation(self._plan)
654
+
655
+ def _merge_sources(self):
656
+ """每来源只取已付费前瞻,收齐同刻更新再求值。
657
+
658
+ 参数: 无。返回: None,所有实际来源EOF才返回。异常: 原读取/计算/预算错误。
659
+ 不按文件顺序拼接不同来源,不为跨源合并建磁盘历史。
660
+ """
661
+ heads = group = samples = None
662
+ primary = None
663
+ try:
664
+ while True:
665
+ heads = tuple(cursor.peek() for cursor in self._cursors)
666
+ self._advance_observed_domain()
667
+ for cursor in self._cursors:
668
+ if cursor._finished and cursor.observed_end is not None:
669
+ self._source_ends[cursor.source_name] = cursor.observed_end
670
+ if self._sequences is not None:
671
+ self._sequences.bounds(self._cursors,self._source_ends)
672
+ if not self._rules_begun:
673
+ for owner in self._rules:
674
+ starts=[cursor.observed_start for cursor in self._cursors
675
+ if cursor.source_name in owner.sources and cursor.observed_start is not None]
676
+ if starts:
677
+ owner.begin(min(starts))
678
+ self._rules_begun=True
679
+ live = tuple(head for head in heads if head is not None)
680
+ if not live:
681
+ for owner in self._rules:
682
+ ends=[self._source_ends[source] for source in owner.sources if source in self._source_ends]
683
+ if ends:
684
+ owner.finish(max(ends))
685
+ if self._sequences is not None:
686
+ self._sequences.flush_before()
687
+ return
688
+ time = min(head.time_ns for head in live)
689
+ count = sum(len(head.samples) for head in live if head.time_ns == time)
690
+ _reserve_owned_ram(self, 16384 + count*1024, '_group_cost')
691
+ samples = tuple(sample for head in live if head.time_ns == time for sample in head.samples)
692
+ group = DecodedTimeGroup(time, samples)
693
+ self._consume_group(group)
694
+ group = samples = live = None
695
+ for cursor, head in zip(self._cursors, heads):
696
+ if head is not None and head.time_ns == time:
697
+ cursor.advance()
698
+ heads = head = None
699
+ _release_owned_ram(self, self._group_cost, '_group_cost')
700
+ except BaseException as error:
701
+ primary = error
702
+ raise
703
+ finally:
704
+ heads = group = samples = live = head = None
705
+ try:
706
+ _release_owned_ram(self, self._group_cost, '_group_cost')
707
+ except BaseException as cleanup:
708
+ if primary is None:
709
+ raise
710
+ primary.add_note('跨来源同刻组清理失败:'+type(cleanup).__name__)
711
+
712
+ def _close_slot(self, slot):
713
+ """关闭成功才解除责任。参数: 槽名。返回: None。异常: 原关闭错,槽保留以便重试。"""
714
+ owner = getattr(self, slot)
715
+ if owner is not None:
716
+ owner.close()
717
+ self._require_closed(owner)
718
+ setattr(self, slot, None)
719
+
720
+ @staticmethod
721
+ def _require_closed(owner):
722
+ """核实子资源真实关闭再撤槽。参数: owner。返回: None。异常: AnalysisError保留原责任。"""
723
+ if not (getattr(owner, 'closed', False) or getattr(owner, '_closed', False)) or getattr(owner, '_held_cost', 0):
724
+ raise AnalysisError('记录流子资源仍未关闭或持有费用')
725
+
726
+ def close(self):
727
+ """反向释放自有资源,保留失败槽供父会话重试。
728
+
729
+ 参数: 无。返回: None。异常: 原关闭/预算错误;不会抵销其他owner的费用。
730
+ """
731
+ if self._closed:
732
+ return
733
+ self._closing = True
734
+ self._message_buffer.clear()
735
+ _release_owned_ram(self, self._message_cost, '_message_cost')
736
+ self._close_slot('_pending')
737
+ self._close_slot('_diagnostics')
738
+ self._close_slot('_exports')
739
+ for index, owner in enumerate(self._cursors or ()):
740
+ if owner is not None:
741
+ owner.close()
742
+ self._require_closed(owner)
743
+ self._cursors[index] = None
744
+ self._close_slot('_read')
745
+ self._close_slot('_adapter')
746
+ self._close_slot('_groups')
747
+ self._close_slot('_sequences')
748
+ self._close_slot('_event_durations')
749
+ self._close_slot('_scope_calculations')
750
+ self._close_slot('_windows')
751
+ self._close_slot('_time_indexes')
752
+ for index,owner in enumerate(self._rules or ()):
753
+ if owner is not None:
754
+ owner.close()
755
+ self._require_closed(owner)
756
+ self._rules[index]=None
757
+ for index, pair in enumerate(self._messages or ()):
758
+ if pair is not None:
759
+ pair[1].close()
760
+ self._require_closed(pair[1])
761
+ self._messages[index] = None
762
+ for index, owner in enumerate(self._calculations or ()):
763
+ if owner is not None:
764
+ owner.close()
765
+ self._require_closed(owner)
766
+ self._calculations[index] = None
767
+ for pair in self._expressions or ():
768
+ for index, owner in enumerate(pair):
769
+ if owner is not None:
770
+ owner.close()
771
+ self._require_closed(owner)
772
+ pair[index] = None
773
+ self._close_slot('_state')
774
+ self._calculations = self._expressions = self._cursors = self._messages = self._plan = self._source_ends = None
775
+ self._rules=self._spool=self._requirements=None
776
+ _release_owned_ram(self, self._group_cost, '_group_cost')
777
+ _release_owned_ram(self, self._fixed_cost, '_fixed_cost')
778
+ self._closed = True