Chronaxis用户手册English
本页目录

chronaxis.core.conditional_integral_terms_reference

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""独立标量生成有限条件积分面积,分别保存值覆盖与BOOL条件覆盖。23输入为有限CalculationSeries和原integral请求,输出原序(N-1,)面积/掩码及冻结事实。4每个值先通过标量浮点精度检查;只有TRUE且有效值才乘裁剪后的整数纳秒时长。5面积溢出或非零下溢使该位置值和真实样本失效;FALSE、UNKNOWN不做面积乘法。6不把UNKNOWN补零,不归约面积或转换最终单位,不读取来源、不修改输入。7只依赖标准库及typed模型,不调用NumPy;有限临时列须由调用方owner预约。8"""910# 标量数值与覆盖判据独立于数组核,仅复用已校验模型和结构门槛。11from math import isfinite12from .conditional_integral_terms import ConditionalIntegralFacts, ReferenceConditionalIntegralTerms, require_conditional_integral_terms13from .calculations import merge_ranges14from .models import Interval15from .numeric import ScalarValue, to_float_reference16from .types import QualityFlag as Q17from .record_intervals import clipped_record_seconds181920def compute_conditional_integral_terms_reference(series, spec, *, step_ns=None, valid_until_ns=None,21                                                condition_valid_until_ns=None, retain_unknown_ranges=True):22    """逐正区间生成未转换原序面积与独立值、条件覆盖事实。2324    参数: series为有限数值CalculationSeries及显式BOOL条件,spec为原integral请求。25        step_ns为可选所选周期;两个until列是实际有效截止;范围明细可显式关闭。26    返回: ReferenceConditionalIntegralTerms;面积为输入单位乘秒,无效槽位0配False。27    异常: 输入、单位、时间与分配错误传播;精度、面积溢出/下溢写入质量及未知。28    """29    # 结构先校验,裁剪保留精确整数ns;没有交集不凭空创建观察域。30    require_conditional_integral_terms(series, spec, step_ns=step_ns, valid_until_ns=valid_until_ns,31                                      condition_valid_until_ns=condition_valid_until_ns)32    if type(retain_unknown_ranges) is not bool:33        raise TypeError('未知范围保留选项需要bool')34    start = max(series.observation.start_ns, spec.window.start_ns)35    end = min(series.observation.end_ns, spec.window.end_ns)36    actual = Interval(start, end) if start <= end else None37    # 所有值都接受原完整积分的精度门槛,包括FALSE与UNKNOWN未选择的值。38    values = [to_float_reference(value) for value in series.values]39    conditions = series.conditions if condition_valid_until_ns is None else list(series.conditions)40    # 到期点本身已失效;未到期的部分区间在下方独立裁剪。41    for rows, deadlines in ((values, valid_until_ns), (conditions, condition_valid_until_ns)):42        if deadlines is not None:43            for index, deadline in enumerate(deadlines):44                if deadline is not None and series.times_ns[index] >= deadline:45                    old = rows[index]46                    rows[index] = ScalarValue(None, old.dtype, False, old.quality | Q.STALE, old.labels)47    areas, valid, value_unknown, condition_unknown = [], [], [], []48    value_duration, known_duration, selected_duration = 0, 0, 049    selected_unknown_duration, false_duration, sample_count, quality = 0, 0, 0, Q.NONE50    # 原N-1槽位顺序不变;数值未跨块归约,条件单独变化只改变选择覆盖。51    for index in range(len(series.times_ns) - 1):52        left, right = max(start, series.times_ns[index]), min(end, series.times_ns[index + 1])53        area, keep = 0.0, False54        if left < right:55            value, condition = values[index], conditions[index]56            quality |= series.diagnostics[index] | value.quality | condition.quality57            value_end = right if valid_until_ns is None or valid_until_ns[index] is None else max(left, min(right, valid_until_ns[index]))58            condition_end = right if condition_valid_until_ns is None or condition_valid_until_ns[index] is None else max(left, min(right, condition_valid_until_ns[index]))59            selected_end = min(value_end, condition_end)60            if value_end < right or condition_end < right:61                quality |= Q.STALE62            # 只有明确TRUE才计算面积;FALSE不因未执行的溢出丢掉值覆盖。63            if value.valid and condition.valid and condition.value and selected_end > left:64                seconds = ((selected_end - left) / 1_000_000_000 if step_ns is None else65                    clipped_record_seconds(series.times_ns[index], series.times_ns[index + 1],66                        spec.window if selected_end == right else Interval(left, selected_end), step_ns=step_ns))67                term = value.value * seconds68                failure = Q.NONFINITE if not isfinite(term) else Q.PRECISION_LOSS if term == 0 and value.value != 0 else Q.NONE69                if failure == Q.NONE:70                    area, keep = term, True71                else:72                    # 局部转换列同时更新样本有效性;原ScalarValue不被改写。73                    value = ScalarValue(value.value, value.dtype, False, value.quality | failure, value.labels)74                    values[index] = value75                    quality |= failure76            # 值和条件各自完整分区;TRUE值未知与条件UNKNOWN分别登记。77            if value.valid:78                value_duration += value_end - left79                if retain_unknown_ranges and value_end < right:80                    value_unknown.append(Interval(value_end, right))81            elif retain_unknown_ranges:82                value_unknown.append(Interval(left, right))83            if condition.valid:84                known_duration += condition_end - left85                if not condition.value:86                    false_duration += condition_end - left87                elif value.valid:88                    selected_duration += selected_end - left89                    selected_unknown_duration += condition_end - selected_end90                else:91                    selected_unknown_duration += condition_end - left92                if retain_unknown_ranges and condition_end < right:93                    condition_unknown.append(Interval(condition_end, right))94            elif retain_unknown_ranges:95                condition_unknown.append(Interval(left, right))96        # 未观察槽位也保留原位置,但不形成UNKNOWN或正常积分项。97        areas.append(area)98        valid.append(keep)99    # 只计半开范围内原值真实更新且有效/TRUE;条件更新与末点不能计样本。100    for index, time in enumerate(series.times_ns):101        if start <= time < end and series.actual_value_updates[index]:102            value, condition = values[index], conditions[index]103            quality |= series.diagnostics[index] | value.quality | condition.quality104            if value.valid and condition.valid and condition.value:105                sample_count += 1106    # 两未知元组仅合并相邻范围;完整来源子类和联合绑定身份原样保留。107    facts = ConditionalIntegralFacts(spec, actual, value_duration, known_duration, selected_duration,108        selected_unknown_duration, false_duration, sample_count, merge_ranges(value_unknown),109        merge_ranges(condition_unknown), quality, series.unit, series.binding_identity, series.source_refs,110        ranges_retained=retain_unknown_ranges)111    return ReferenceConditionalIntegralTerms(tuple(areas), tuple(valid), facts)112
Chronaxis 用户手册 · 离线阅读