Chronaxis用户手册English
本页目录

chronaxis.execution.record_integral

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""在有限内存内累计已求值的驱动记录对,保留实际端点直到比例裁剪完成。23输入为已归一化并按驱动同刻政策归组的(time_ns, ScalarValue[, valid_until_ns])有限批;输出仅含4积分值、单位、完成状态和质量的内部结果。复用原两后端面积及原序误差求和,5一次只持当前批和一条跨批前值,不创建历史文件、原帧副本、贡献或未知范围列表。6调用方负责绑定/表达式/有效期判定,并在输入确实结束后调用finish;本组件不7读取文件或证明来源EOF。实际间隔使用必要更新间的真实差,固定/DBC使用8所选驱动记录对;有效期都按实际截止裁剪,没有完整记录对时不虚构尾段。9"""1011from dataclasses import dataclass1213from ..core.integral_sum import require_partial_limit14from ..core.integral_sum_reference import ReferenceIntegralSum15from ..core.integral_sum_numpy import NumpyIntegralSum16from ..core.integral_terms_reference import compute_integral_terms_reference17from ..core.integral_terms_numpy import compute_integral_terms_numpy18from ..core.conditional_integral_terms_reference import compute_conditional_integral_terms_reference19from ..core.conditional_integral_terms_numpy import compute_conditional_integral_terms_numpy20from ..core.calculations import CalculationDefinition, CalculationSeries, calculation_unit, classify_calculation_value21from ..core.calculations import classify_coverage22from ..core.models import Interval23from ..core.numeric import ScalarValue24from ..core.record_intervals import require_record_step25from ..core.types import SignalDType as D, QualityFlag as Q26from ..results.budget import ResourceBudget, _reserve_owned_ram, _release_owned_ram, _cleanup_owner27from ..results.errors import ResultClosedError28from .record_point_buffer import RecordPointBuffer29from .history import _metadata_bytes303132@dataclass(frozen=True)33class RecordIntegralResult:34    """内部积分结果,不附逐条输入、时间对照或默认贡献记录;不充当公开发布清单。"""3536    value: float | None  # 已换到请求单位;未知与有效零分开。37    unit: str  # 输出单位,仅最终转换一次。38    status: str  # 沿既有complete/partial/indeterminate政策。39    reason: str  # 正常、观测不足或数值失败等必要原因。40    quality: Q  # 输入和数值计算质量,不包含逐条副本。41    coverage_status: str | None = None424344class RecordIntegral(RecordPointBuffer):45    """拥有有限驱动点缓冲和累计状态;失败后只能关闭,完成后只读结果。4647    consume借用外部有限批;留下的点只含整数时间和冻结数值,费用归本实例。48    同刻冲突须由上游既有同刻政策解决,不能在此任意覆盖或累计零跨度记录。49    """5051    def __init__(self, budget, spec, input_unit, dtype, step_ns, *, backend='numpy',52                 batch_intervals=64, partial_limit=4096, conditioned=False):53        """预付有界状态及点缓冲,数值临时数组在每次归约前另预约。5455        参数: budget共享账本,spec为integral请求;input_unit/dtype为已56            求值列单位/类型;step_ns为None(实际差)或固定/已核实DBC正周期;后端独立选择;57            batch_intervals为1—4096区间数,partial_limit为误差项容量;conditioned指定显式BOOL条件。58        返回: 新owner。异常: 配置/预算/取消错误;构造清理失败通过异常的59            record_integral_cleanup_owner提供重试入口。60        """61        if not isinstance(budget, ResourceBudget) or not isinstance(spec, CalculationDefinition):62            raise TypeError('记录流积分需要共享预算和CalculationDefinition')63        if spec.operation != 'integral':64            raise ValueError('记录流积分需要integral')65        if backend not in ('reference', 'numpy') or dtype not in (D.INT64, D.UINT64, D.FLOAT64):66            raise ValueError('记录流积分需要明确后端和数值dtype')67        if type(batch_intervals) is not int or not 1 <= batch_intervals <= 4096:68            raise ValueError('记录流区间批上限需要1到4096')69        if type(conditioned) is not bool:70            raise TypeError('条件选择需要bool')71        require_record_step(step_ns, ())72        limit = require_partial_limit(partial_limit)73        self._unit, self._factor = calculation_unit(spec, input_unit)74        self._budget, self._spec, self._input_unit, self._dtype = budget, spec, input_unit, dtype75        self._step_ns, self._limit = step_ns, batch_intervals76        self._conditioned = conditioned77        self._held_cost = self._fixed_cost = self._workspace_cost = 078        self._closed = self._closing = self._failed = self._finished = False79        self._rows = self._sum = self._result = None80        self._last_time = None81        self._covered_ns = 082        self._known_ns = self._selected_ns = self._selected_unknown_ns = self._false_ns = 083        self._quality = Q.NONE84        self._transform_partial = False85        self._coverage_value_ns=0 if spec.minimum_coverage>0 else None86        try:87            # 固定费覆盖误差求和的有限候选及点缓冲,不按总记录数扩大。88            _reserve_owned_ram(self, 65536 + limit * 256 + (batch_intervals + 1) * 102489                               + 16 * _metadata_bytes((spec, input_unit)), '_fixed_cost')90            self._rows = []91            self._sum = (ReferenceIntegralSum if backend == 'reference' else NumpyIntegralSum)(limit)92            self._compute = compute_integral_terms_reference if backend == 'reference' else compute_integral_terms_numpy93            if conditioned:94                self._compute = (compute_conditional_integral_terms_reference if backend == 'reference'95                                 else compute_conditional_integral_terms_numpy)96        except BaseException as exc:97            _cleanup_owner(self, exc, 'record_integral_cleanup_owner', '记录流积分')98            raise99100    def _flush(self):101        """消费当前完整记录对并留下一个共享端点,首条/末条不凭空增加周期。102103        参数: 无,使用当前自有缓冲。返回: None。异常: 数值结构/预算/取消;104            清理异常不覆盖原错误,临时申请保留在owner供close重试。105        """106        if len(self._rows) < 2:107            return108        series = terms = None109        primary = None110        try:111            _reserve_owned_ram(self, 65536 + len(self._rows) * 8192, '_workspace_cost')112            times = tuple(item[0] for item in self._rows)113            values = tuple(item[1] for item in self._rows)114            # 截止仅为本批计算所需;不保存来源副本或另一列累计时钟。115            deadlines = (tuple(item[2] for item in self._rows)116                         if any(item[2] is not None for item in self._rows) else None)117            conditions = tuple(item[3] for item in self._rows) if self._conditioned else None118            condition_deadlines = (tuple(item[4] for item in self._rows)119                if self._conditioned and any(item[4] is not None for item in self._rows) else None)120            series = CalculationSeries(Interval(times[0], times[-1]), times, values,121                                  (True,) * len(times), self._input_unit, conditions=conditions)122            # 窗口仍由原spec裁剪,分母保留完整记录对。按请求省去未知范围对象。123            options = {'condition_valid_until_ns': condition_deadlines} if self._conditioned else {}124            terms = self._compute(series, self._spec, step_ns=self._step_ns,125                                  retain_unknown_ranges=False, valid_until_ns=deadlines, **options)126            self._sum.push_values(terms.areas, terms.valid)127            facts = terms.facts128            from .transform_partial import partial_in_block129            if partial_in_block(self._rows,self._spec.window,samples=False):130                self._transform_partial=True131            if self._coverage_value_ns is not None:132                self._coverage_value_ns+=facts.value_valid_duration_ns133            if facts.actual_window is not None:134                span = facts.actual_window.end_ns - facts.actual_window.start_ns135                self._covered_ns += span136                self._known_ns += facts.condition_known_duration_ns if self._conditioned else span137                self._selected_ns += facts.selected_duration_ns if self._conditioned else facts.value_valid_duration_ns138                self._selected_unknown_ns += (facts.selected_value_unknown_duration_ns if self._conditioned139                                              else span - facts.value_valid_duration_ns)140                if self._conditioned:141                    self._false_ns += facts.false_duration_ns142            self._quality |= facts.quality143            self._rows[:] = self._rows[-1:]144        except BaseException as exc:145            primary = exc146            self._failed = True147            raise148        finally:149            # 断开有限临时列后再退款;释放失败不允许调用方取得成功结果。150            series = terms = times = values = facts = deadlines = conditions = condition_deadlines = options = None151            try:152                _release_owned_ram(self, self._workspace_cost, '_workspace_cost')153            except BaseException as cleanup:154                self._failed = True155                if primary is None:156                    raise157                primary.add_note('记录流积分临时费用清理失败:' + type(cleanup).__name__)158159    def finish(self):160        """输入调用方确认结束后结算最后完整记录对,返回精简内部结果。161162        参数: 无;不能代替读取器EOF/关闭成功的确认。返回: RecordIntegralResult,163            重复调用返回同一结果。异常: 预算/数值结构/取消错误,不发布前缀。164        """165        self._require_open()166        if self._finished:167            return self._result168        try:169            self._flush()170            number = self._sum.finish(self._unit, self._factor)171            value, status, reason = classify_calculation_value(self._spec, number.value, self._covered_ns,172                self._known_ns, self._selected_ns, self._selected_unknown_ns,173                calculation_failed=number.calculation_failed,174                all_false=self._conditioned and self._covered_ns > 0 and self._false_ns == self._covered_ns)175            coverage=None if self._coverage_value_ns is None else classify_coverage(176                self._spec,self._covered_ns,self._coverage_value_ns,self._known_ns)177            self._result = RecordIntegralResult(value, self._unit, status, reason, self._quality | number.quality,coverage)178            if self._transform_partial:179                from .transform_partial import partial_result180                self._result=partial_result(self._result,self._spec.partial_policy)181            self._finished = True182            return self._result183        except BaseException:184            self._failed = True185            raise186187    @property188    def closed(self):189        """读取自有费用完全释放状态。参数: 无。返回: bool。异常: 无。"""190        return self._closed191192    def close(self):193        """释放自有缓冲/数值状态及费用,不操作外部输入和目录。194195        参数: 无。返回: None;重复关闭安全。异常: 预算释放失败可重试,不假报已关闭。196        """197        if self._closed:198            return199        self._closing = True200        self._rows = self._sum = self._result = None201        _release_owned_ram(self, self._workspace_cost, '_workspace_cost')202        _release_owned_ram(self, self._fixed_cost, '_fixed_cost')203        self._closed = True204
Chronaxis 用户手册 · 离线阅读