fix: [FL-110] 对齐雷电流幅值统计数据过滤逻辑
修改 _fit_line_current_parameters 函数,使其数据处理逻辑与参考工程保持一致: 1. 数据过滤改为取绝对值,不再过滤0值和负值 2. 返回值增加 peak_max 和 peak_min 字段 3. API 响应模型添加最大值和最小值字段 主要变更: - api/app/services/lightning_service.py * _fit_line_current_parameters: 数据清洗逻辑从 if item > 0 改为 abs(item) * 返回值从 3 个增加到 5 个,新增 peak_max 和 peak_min * prepare_line_lightning_current: 移除查询时的 > 0 过滤 * 在 extra_profile_json 和 preparation_source 中记录 peak_max/peak_min - api/app/schemas/lightning.py * LightningCurrentPreparationResponse: 添加 peak_max 和 peak_min 字段 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -308,6 +308,8 @@ class LightningCurrentPreparationResponse(BaseModel):
|
||||
line: LineSummary
|
||||
current_a: float
|
||||
current_b: float
|
||||
peak_max: float
|
||||
peak_min: float
|
||||
sampled_event_count: int
|
||||
updated_tower_count: int
|
||||
created_profile_count: int = 0
|
||||
|
||||
@@ -1335,12 +1335,12 @@ def prepare_line_lightning_current(
|
||||
peaks = [
|
||||
float(item)
|
||||
for item in db.execute(select(LightningCurrentEvent.peak_abs_current_ka).where(*filters)).scalars().all()
|
||||
if item is not None and float(item) > 0
|
||||
if item is not None
|
||||
]
|
||||
if not peaks:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="未找到可用于线路雷电流拟合的幅值样本")
|
||||
|
||||
current_a, current_b, warnings = _fit_line_current_parameters(peaks)
|
||||
current_a, current_b, peak_max, peak_min, warnings = _fit_line_current_parameters(peaks)
|
||||
now = utcnow()
|
||||
tower_ids = [tower.id for tower in towers]
|
||||
existing_profiles = db.execute(select(TowerProfile).where(TowerProfile.tower_id.in_(tower_ids))).scalars().all()
|
||||
@@ -1369,6 +1369,8 @@ def prepare_line_lightning_current(
|
||||
"line_code": line.code,
|
||||
"current_a": current_a,
|
||||
"current_b": current_b,
|
||||
"peak_max": peak_max,
|
||||
"peak_min": peak_min,
|
||||
"sampled_event_count": len(peaks),
|
||||
"region_id": normalized_region,
|
||||
"is_synthetic": payload.is_synthetic,
|
||||
@@ -1398,6 +1400,8 @@ def prepare_line_lightning_current(
|
||||
"is_synthetic": payload.is_synthetic,
|
||||
"current_a": current_a,
|
||||
"current_b": current_b,
|
||||
"peak_max": peak_max,
|
||||
"peak_min": peak_min,
|
||||
},
|
||||
)
|
||||
db.commit()
|
||||
@@ -1411,6 +1415,8 @@ def prepare_line_lightning_current(
|
||||
line=serialize_line(line, tower_count=len(towers), preparation_json=preparation_json),
|
||||
current_a=current_a,
|
||||
current_b=current_b,
|
||||
peak_max=peak_max,
|
||||
peak_min=peak_min,
|
||||
sampled_event_count=len(peaks),
|
||||
updated_tower_count=len(towers),
|
||||
created_profile_count=created_profile_count,
|
||||
@@ -2356,15 +2362,15 @@ def _parse_float(value: Any) -> float | None:
|
||||
return None
|
||||
|
||||
|
||||
def _fit_line_current_parameters(values: list[float]) -> tuple[float, float, list[str]]:
|
||||
cleaned = sorted(float(item) for item in values if item > 0)
|
||||
def _fit_line_current_parameters(values: list[float]) -> tuple[float, float, float, float, list[str]]:
|
||||
cleaned = sorted(abs(float(item)) for item in values)
|
||||
if not cleaned:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="雷电流幅值样本为空")
|
||||
|
||||
warnings: list[str] = []
|
||||
unique_values = {round(item, 6) for item in cleaned}
|
||||
if len(unique_values) == 1:
|
||||
return round(cleaned[0], 3), 2.6, ["样本幅值单一,已使用默认 b=2.6"]
|
||||
return round(cleaned[0], 3), 2.6, round(cleaned[0], 3), round(cleaned[0], 3), ["样本幅值单一,已使用默认 b=2.6"]
|
||||
|
||||
peak_max = max(cleaned)
|
||||
peak_min = min(cleaned)
|
||||
@@ -2430,7 +2436,7 @@ def _fit_line_current_parameters(values: list[float]) -> tuple[float, float, lis
|
||||
current_b = 2.6
|
||||
warnings.append("样本分布不足以稳定拟合 b,已使用默认 b=2.6")
|
||||
|
||||
return round(current_a, 3), round(current_b, 3), warnings
|
||||
return round(current_a, 3), round(current_b, 3), round(peak_max, 3), round(peak_min, 3), warnings
|
||||
|
||||
|
||||
def _normalize_str(value: Any) -> str | None:
|
||||
|
||||
Reference in New Issue
Block a user