chronaxis.execution.calculation_values
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""读取计算列中的有效标量,并按当前消息原值决定方向桶及跳过原因。23这些纯函数不访问来源、消息历史或结果仓;参考与数组执行共用相同边界语义。4无效占位不当有效数值,方向字段不应用普通信号转换,表达式失败原因优先。5"""6from math import isfinite7from ..core.numeric import ScalarValue8from ..core.scalar import _scalar_from_validated_fields9from ..core.types import QualityFlag as Q, _QUALITY_BY_MASK10from ..legacy.sum import LegacySkipReason111213def scalar_from_column(column, index):14 """取一项实际归一化值,失效时保留原诊断而不把数组占位当正常值。1516 参数: column为本批SignalSeries;index为匹配列位置。返回: ScalarValue。17 异常: 原类型/布局错误;不做第二次数值转换。18 """19 return _extract_scalar(column, index, ScalarValue)202122def _scalar_from_validated_column(column, index):23 """借用当前适配器刚核过且未交给外部的列,不重验每个标签域。2425 参数: 本次运行拥有的已校验NumericArray/SignalSeries和位置。26 返回: ScalarValue;不复制列或保留另一份值。异常: 索引/分配原错。27 公开或来源不明的列须用scalar_from_column,不使用本内部入口。28 """29 return _extract_scalar(column, index, _scalar_from_validated_fields)303132def _extract_scalar(column, index, factory):33 """按列原有规则取值并交给内部选定的构造器。3435 参数: 数值列、位置、构造函数。返回: ScalarValue。36 异常: 索引、标签或构造错误传播;无效值不读取数组占位为真值。37 """38 mask = int(column.quality[index])39 # 内部列已验证范围;公开入口仍由枚举拒绝未知位与负值。40 quality = _QUALITY_BY_MASK[mask] if factory is _scalar_from_validated_fields else Q(mask)41 valid = bool(column.valid[index])42 # ENUM有效值还原实际逻辑标签;其他有效值取原生标量。43 if valid:44 value = column.labels[int(column.values[index])] if column.labels else column.values[index].item()45 else:46 # 纯消息NumericArray没有展示用原值列;无效性由掩码及原因表达,不读占位。47 originals=getattr(column,'original_values',None)48 value = originals[index] if originals is not None else None49 code = getattr(column, 'code', None)50 return factory(value, column.dtype, valid, quality, column.labels,51 None if code is None else _extract_scalar(code, index, factory))5253def direction_bucket_state(raw, bucket):54 """按同条原值判桶,既不转换单位也不把缺值或非有限当正常零。5556 参数: raw为原生方向数值或None,bucket为已核positive/negative。57 返回: 方向质量及是否选中。异常: TypeError为非原生数值,不接受NumPy标量。58 """59 if raw is not None and type(raw) not in (int, float, bool):60 raise TypeError('disjunction原值需要原生int/float/bool或明确缺失None')61 if raw is None:62 return Q.MISSING, False63 if type(raw) is float and not isfinite(raw):64 return Q.NONFINITE, False65 return Q.NONE, raw > 0 if bucket == 'positive' else raw < 06667def direction_skip_reason(value, reason, direction_quality, selected):68 """保表达式失败优先,只有有效表达式才用原方向决定是否跳过。6970 参数: 原数值、原因、方向质量与选择。返回: 最终LegacySkipReason或None。71 异常: 无主动异常;不修改累计器或原质量。72 """73 if value.valid:74 if direction_quality & Q.MISSING:75 return LegacySkipReason.MISSING_INPUT76 if direction_quality & Q.NONFINITE:77 return LegacySkipReason.NONFINITE_INPUT78 if not selected:79 return LegacySkipReason.CONDITION_FALSE80 return reason81