chronaxis.planning.record_execution
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""声明新记录流当前可执行范围;静态报告与实际会话共用同一检查。23这里只检查有限配置,不读取来源,不把尚未接线的能力报为已支持。4"""567from ..core.moments import MOMENTS, SAMPLE_MOMENTS8from ..core.quantiles import SAMPLE_QUANTILES9from ..core.counts_v4 import COUNT_OPERATIONS, OBJECT_COUNTS101112def is_event_duration(request):13 """识别事件总时长的静态声明,不导入执行层。参数: 指标请求。返回: bool。异常: 无。"""14 return (request.scope.startswith('event:') and request.operation=='duration' and request.signal is None15 and request.condition is not None and request.condition.root.operator=='const'16 and request.condition.root.value is True)171819def record_execution_errors(plan):20 """检查会话时间指标的已接线路径。2122 参数: 已编译计划。返回: 错误tuple,空值表示当前组合可执行。23 异常: 非法typed对象属性错误传播;不访问文件或修改计划。24 """25 from .process_execution import process_execution_errors26 errors = list(process_execution_errors(plan))27 # typed计划也不能让无DBC来源携带未确定的有效期;不靠读取数据猜周期。28 sources = {source.name: source for source in plan.sources}29 for signal in plan.signals:30 definition = signal.definition31 source = sources.get(definition.source)32 if definition.valid_for_ns is None and (source is None or33 source.source_type not in ('can_blf', 'can_asc', 'asc_or_blf', 'raw_can_csv')):34 errors.append(definition.name + '没有DBC周期依据;请填写本信号period或valid_for')35 if not (plan.calculations or plan.message_calculations or plan.rules or plan.outputs.can_frames or plan.outputs.signal_csv) or any((item.scope != 'session' and not item.scope.startswith(('event:','segment:'))) or item.operation not in36 ('integral', 'duration', 'min_time', 'max_time', 'time_weighted_mean','sample_minimum','sample_maximum','sample_mean','select', *COUNT_OPERATIONS, *MOMENTS, *SAMPLE_QUANTILES) and37 (plan.extensions is None or item.operation not in plan.extensions.reductions) for item in plan.calculations):38 errors.append('当前配置当前接入会话积分及时间统计')39 choices = dict(plan.intervals.resolved)40 if any(item.calculation_id not in choices for item in plan.calculations if item.operation not in ('sample_minimum','sample_maximum','sample_mean','select', *COUNT_OPERATIONS, *SAMPLE_MOMENTS, *SAMPLE_QUANTILES) and41 (plan.extensions is None or item.operation not in plan.extensions.reductions)):42 errors.append('当前配置指标缺少已解析间隔选择')43 names, value_names = set(), set()44 for request in plan.rules:45 names.update(request.dependencies)46 value_names.update(request.dependencies)47 choice=choices.get(request.rule_id)48 if choice is None and request.rule_type not in ('rising_edge','falling_edge'):49 errors.append('当前配置规则缺少已解析间隔选择')50 elif choice is not None and choice.driver is not None:51 names.add(choice.driver)52 for calculation in plan.calculations:53 for expression in (calculation.signal, calculation.condition):54 if expression is not None:55 names.update(expression.dependencies)56 value_names.update(expression.dependencies)57 choice = choices.get(calculation.calculation_id)58 if choice is not None and choice.driver is not None:59 names.add(choice.driver)60 for request in plan.sequences:61 choice=choices.get(request.sequence_id)62 if choice is None:63 errors.append('当前配置配对缺少已解析间隔选择')64 elif choice.driver is not None:65 names.add(choice.driver)66 for window in plan.windows:67 choice=choices.get(window.window_id)68 if choice is not None and choice.driver is not None:69 names.add(choice.driver)70 if plan.outputs.signal_csv is not None:71 names.update(plan.outputs.signal_csv.spec.signals)72 from .transforms import active_transforms, physical_dependencies73 transforms=active_transforms(plan,names)74 names.update(physical_dependencies(plan,names))75 names.update(choices[t.name].driver for t in transforms if choices[t.name].driver)76 needed = {item.definition.source for item in plan.signals if item.definition.name in names}77 if any(not t.physical for t in transforms):78 needed.update(sources)79 needed.update(item.source for item in plan.message_calculations)80 if plan.outputs.can_frames is not None:81 needed.add(plan.outputs.can_frames.source)82 if any(not rule.dependencies and (choices.get(rule.rule_id) is None or83 choices[rule.rule_id].driver is None) for rule in plan.rules) or any(84 calculation.scope=='session' and calculation.operation not in OBJECT_COUNTS and (choices.get(calculation.calculation_id) is None or choices[calculation.calculation_id].driver is None)85 and not any(e.dependencies for e in (calculation.signal,calculation.condition) if e is not None) for calculation in plan.calculations):86 needed.update(source.name for source in plan.sources)87 if not needed or any(item.source_type not in ('can_blf', 'can_asc', 'asc_or_blf', 'raw_can_csv', 'memory', 'signal_csv')88 for item in plan.sources if item.name in needed):89 errors.append('当前配置需要已声明且支持的观测来源')90 return tuple(errors)91