# roofrail_filter_static.py import numpy as np import pandas as pd # 최소 허용 R (전제) R_MIN = 1.0 # 직경별 허용범위 (직접 정의) # 구조: {직경: {각도: (상단R_max, 하단R_max)}} CONSTRAINTS = { 17: {deg: (2.0, 5.0) for deg in range(62, 90)}, # 62~89° 18: {deg: (3.0, 5.0) for deg in range(65, 91)}, # 65~90° 19: {deg: (3.5, 4.5) for deg in range(66, 91)}, # 66~90° 20: {deg: (4.0, 4.0) for deg in range(69, 91)}, # 69~90° 21: {deg: (4.5, 3.0) for deg in range(72, 88)}, # 72~87° 22: {deg: (5.0, 2.5) for deg in range(75, 88)}, # 75~87° } # 소재별 thinning 허용치 (실제 기준) THIN_LIMITS = { "SPCUD": 0.25, "SPCC": 0.21, "SPRC340": 0.20, "SPRC440": 0.17, "SPFC590": 0.16, "SPFC780": 0.10, "SPFC980": 0.08, } def filter_model_outputs( candidates: pd.DataFrame, thinning_limits: dict = THIN_LIMITS, max_failure_threshold: float = 0.97, # ✅ 수정: 0.97 이하만 통과 r_min: float = R_MIN ) -> pd.DataFrame: """ candidates DataFrame 필수 컬럼: ['material','thickness','diameter','degree','upper_r','lower_r', 'pred_max_failure','pred_thining'] 반환: 입력 + ['allowed_R','allowed_model','final_ok','reject_reason'] """ df = candidates.copy() allowed_R = [] reject_reason = [] for _, row in df.iterrows(): dia, deg, up, lo = int(row["diameter"]), int(row["degree"]), row["upper_r"], row["lower_r"] # 1) 직경/각도 허용 여부 if dia not in CONSTRAINTS or deg not in CONSTRAINTS[dia]: allowed_R.append(False) reject_reason.append("disallowed_diameter_or_degree") continue up_max, lo_max = CONSTRAINTS[dia][deg] # 2) R 범위 확인 if up < r_min or lo < r_min: allowed_R.append(False) reject_reason.append("R_below_min") continue if up > up_max: allowed_R.append(False) reject_reason.append("upper_r_above_max") continue if lo > lo_max: allowed_R.append(False) reject_reason.append("lower_r_above_max") continue # 통과 allowed_R.append(True) reject_reason.append("") df["allowed_R"] = allowed_R df["reject_reason"] = reject_reason # 3) 모델 조건 thin_limit = df["material"].map(thinning_limits) cond_model = ( (df["pred_max_failure"] <= max_failure_threshold) & # ✅ 수정: <= 0.97 thin_limit.notna() & (df["pred_thining"] <= thin_limit) ) df["allowed_model"] = cond_model # 최종 df["final_ok"] = df["allowed_R"] & df["allowed_model"] return df