chronaxis.sources.text_can_ref
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""保存新文本CAN样本的精确原行引用,供信号历史和结果白名单编码。23输入是已有规范CAN字段键和实际读取的文件/行/原时间,输出冻结SourceRef子类。4字段键仍区分通道、消息、信号、ID及帧型;本引用另外保留文件次序与文件内序号。5不打开文件、不解码、不将float秒当作精确时间,也不冒称冻结旧profile的输出。6"""78from dataclasses import dataclass9from ..core.models import SourceRef10from ..core.validation import require_text11from .can_spec import can_field_from_key121314@dataclass(frozen=True)15class CANTextSourceRef(SourceRef):16 """定位一个实际文本记录中的信号;通用field保存完整规范CAN定位。"""1718 path: str # 实际输入路径,保持读取声明,不做隐式resolve。19 parser_version: str # ASC或原始CSV解析版本。20 line_number: int | None # 文本物理行;BLF为None,以record_sequence定位。21 input_index: int # 显式文件列表中的0基位置。22 record_sequence: int # 文件内原记录序号,同刻不同帧不去重。23 yield_sequence: int # 本次连续文件读取的全局0基原帧序号。24 raw_time: str | None # 文本原文字;BLF没有时间文字,不构造副本。25 time_quantized: bool # 源文字转纳秒时是否实际量化。2627 def __post_init__(self):28 """核对冻结定位的结构。参数: 无。返回: None。异常: 类型/规范字段/位置非法。29 """30 # 先核会话/来源归属,再核原CAN六字段;不把原信号名改成表达式别名。31 super().__post_init__()32 can_field_from_key(self.field)33 for label in ('path','parser_version'):34 require_text(getattr(self,label),'text_can_ref.'+label)35 if self.parser_version == 'blf-v1':36 if self.line_number is not None or self.raw_time is not None:37 raise ValueError('BLF引用没有物理行号或原时间文字')38 else:39 require_text(self.raw_time,'text_can_ref.raw_time')40 # 物理行从1开始,其余序号从0开始,bool不能作为整数通过。41 for label in ('line_number','input_index','record_sequence','yield_sequence'):42 value = getattr(self,label)43 if label == 'line_number' and self.parser_version == 'blf-v1':44 continue45 if type(value) is not int or value < (1 if label=='line_number' else 0):46 raise ValueError('文本CAN引用位置非法: '+label)47 if type(self.time_quantized) is not bool:48 raise TypeError('文本CAN量化标志需要bool')49