chronaxis.execution.where_state
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""从最新完整组提取 where 的反事实输入和活动更新证据,不读历史文件。23同一组可能同时替换条件与两个分支。取状态已保存的旧规范标量,在本时刻检查4TTL 和来源范围,两种后端分别解释前后条件。所需临时空间由调用侧查询预付。5"""67from ..core.numeric import ScalarValue8from ..core.types import QualityFlag as Q9from ..core.where_updates import reference_updates, numpy_updates, reference_active, numpy_active101112def before_context(state, names, time, *, ends=None, bounds=None, continuous=False, left_limit=False):13 """构造同刻排除最近组的点、右侧或左侧保持。1415 参数: 最新状态、依赖、纳秒,ends/bounds 来源范围及视图。16 返回: 标量映射。异常: 声明或类型错误;不回退状态。17 """18 context = {}19 for name in names:20 definition = state.definitions[name]21 previous = state._before_group(name)22 start, end = bounds[definition.source] if bounds is not None else (23 None, None if ends is None else ends.get(definition.source))24 if previous is None:25 context[name] = ScalarValue(None, definition.dtype, False, Q.MISSING, state._labels.get(name, ()))26 continue27 timestamp, value = previous28 reason = Q.NONE29 elapsed = time - timestamp30 if elapsed > definition.valid_for_ns or (not left_limit and elapsed == definition.valid_for_ns):31 reason |= Q.STALE32 if ((start is not None and (time <= start if left_limit else time < start)) or33 (end is not None and (time >= end if continuous and not left_limit else time > end))):34 reason |= Q.MISSING35 from ..core.enum_codes import expire_value36 context[name] = expire_value(value, reason) if reason else value37 return context383940def scalar_columns(context):41 """单点 NumPy 调用保留原 dtype/标签。4243 参数: 规范标量映射。返回: 单行列映射,大整数不转 float。异常: 非法标签或列类型。44 """45 import numpy as np46 from ..core.numeric_numpy import NumericArray, DTYPES4748 columns = {}49 for name, value in context.items():50 physical = value.labels.index(value.value) if value.valid and value.labels else value.value if value.valid else 051 code = None if value.code is None else scalar_columns({name: value.code})[name]52 columns[name] = NumericArray(value.dtype, np.array([physical], dtype=DTYPES[value.dtype]),53 np.array([value.valid], dtype=bool), np.array([int(value.quality)], dtype=np.uint16), value.labels, code)54 return columns555657def group_updates(root, context, previous, updates, backend, *, point_program=None):58 """计算原子组是否更新输出。参数: 根、前后值、更新、后端及可选生产逐点程序。返回: bool。异常: 求值原错。"""59 if not any(updates.values()):60 return False61 if backend == 'reference':62 return reference_updates(root, context, previous, updates)63 if point_program is not None:64 return point_program.updates(root, context, previous, updates)65 import numpy as np66 return bool(numpy_updates(root, scalar_columns(context), scalar_columns(previous),67 {name: np.array([flag], dtype=bool) for name, flag in updates.items()}, 1)[0])686970def group_active(root, context, flags, backend, *, point_program=None):71 """检查标记输入是否活动。参数: 根、点值、标志、后端及可选生产逐点程序。返回: bool。异常: 求值错误。"""72 if not any(flags.values()):73 return False74 if backend == 'reference':75 return reference_active(root, context, flags)76 if point_program is not None:77 return point_program.active(root, context, flags)78 import numpy as np79 return bool(numpy_active(root, scalar_columns(context),80 {name: np.array([flag], dtype=bool) for name, flag in flags.items()}, 1)[0])81