File size: 2,834 Bytes
f0671e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 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