Chronaxis用户手册English
本页目录

chronaxis.legacy.disjunction

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""声明按本条原解码方向值分正负桶,并保存不经转换的选择追溯。23LegacyDisjunction给出已绑定别名、positive/negative桶及固定raw_decoded-v1策略。4运行层须核同一完整消息定位,从当前decoded字典直接取方向原值,不能施加5SignalDefinition的scale、offset、direction_factor或TTL,也不能补前一次值。6原生True按正值、False按零;缺字段、非有限值和未选桶的跳过由运行层决定,7本模块不执行分类、表达式、累计或数值转换。89LegacyDisjunctionTrace保存冻结选择器、原field定位、原生方向值和SourceRef。10None明确表示方向字段缺失;NaN/Inf保留原诊断,不改成零或字符串。模型只核11结构,不声称来自真实消息、文件EOF或旧ChrgInfo整条调用链。配置和返回追溯12由调用方拥有;本模块不创建预算、I/O、缓存或NumPy依赖。13"""1415# 两端共享冻结选择器和追溯,不在计划、结果和运行层各造一套可变字典。16from dataclasses import dataclass1718from ..core.models import SourceRef19from ..core.validation import require_identifier, require_text202122@dataclass(frozen=True)23class LegacyDisjunction:24    """选择同条消息的原数值方向桶,不修改表达式贡献的正负号。2526    signal是分析别名,原字段和完整消息定位仍由当前绑定解析;bucket只允许27    positive/negative。该声明不自行拆分指标,也不证明方向在表达式依赖中。28    """2930    signal: str  # 已绑定简单别名,可不出现在表达式中。31    bucket: str  # positive或negative,各指标独立累计。32    value_policy: str = 'raw_decoded-v1'  # 只看原decoded值,不施转换或保持。3334    def __post_init__(self) -> None:35        """校验安全别名和固定桶/取值策略,不解析来源或输入值。3637        参数: 无,读取三个冻结字段。返回: None,保原生文本原样。38        异常: TypeError为非原生文本;ValueError为别名、桶或策略不支持。39        """40        # 不按truthiness或str隐式转换选桶,避免配置拼错后悄悄进入另一种策略。41        if type(self.signal) is not str or type(self.bucket) is not str or type(self.value_policy) is not str:42            raise TypeError('disjunction别名、桶和value_policy需要原生str')43        require_identifier(self.signal, 'disjunction.signal')44        if self.bucket not in ('positive', 'negative'):45            raise ValueError('disjunction.bucket仅支持positive或negative')46        if self.value_policy != 'raw_decoded-v1':47            raise ValueError('disjunction.value_policy仅支持raw_decoded-v1')484950@dataclass(frozen=True)51class LegacyDisjunctionTrace:52    """保存本次方向的原定位和值,结构冻结但不假造真实读取证明。5354    raw_value保int/float/bool原类型,None只表示明确缺字段;非有限float不在55    模型层改写或拒绝。source_ref原对象保持,实际CAN逐序身份由运行/结果层核。56    """5758    selection: LegacyDisjunction  # 实际指标使用的同一选择器。59    field: str  # 原SignalDefinition.field,CAN路径为规范六项定位。60    raw_value: int | float | bool | None  # 未归一化方向值;None为缺失。61    source_ref: SourceRef  # 同条原消息的真实来源引用。6263    def __post_init__(self) -> None:64        """核选择器、原字段、原生值及引用一致性,不作数值强制转换。6566        参数: 无,读取冻结追溯字段。返回: None;保NaN/Inf、负零和原bool。67        异常: TypeError为非模型/原生数值;ValueError为原字段与引用不一致。68        """69        # 选择器必须已由共享模型校验,字段全文保留,不从别名反猜原字典键。70        if type(self.selection) is not LegacyDisjunction or type(self.field) is not str:71            raise TypeError('disjunction追溯需要LegacyDisjunction及原生field文本')72        require_text(self.field, 'disjunction.field')73        # None不代表零或无效浮点;数值原类型限定,拒绝str、enum和NumPy scalar。74        if self.raw_value is not None and type(self.raw_value) not in (int, float, bool):75            raise TypeError('disjunction原值需要原生int/float/bool或明确缺失None')76        if not isinstance(self.source_ref, SourceRef):77            raise TypeError('disjunction追溯需要SourceRef')78        if self.source_ref.field != self.field:79            raise ValueError('disjunction原field与来源引用不一致')80
Chronaxis 用户手册 · 离线阅读