๊ธฐ๋Šฅ ์ƒ์„ธ ๋ณด๊ณ 

๊ธฐ๋Šฅ ๋ถ„์„ ๋ณด๊ณ ์„œ โ€” ADMET Surrogate + pepADMET ๋…์„ฑ (hc50 ๊ฒŒ์ดํŠธ)

๋Œ€์ƒ ๋ชจ๋“ˆ: pyrosetta_flow/multiobjective.py, pyrosetta_flow/pepadmet_runner.py, pyrosetta_flow/pepadmet_toxicity.py, pyrosetta_flow/pepadmet_infer_script.py, backend/admet.py

์ธ์šฉ ๊ทœ์น™: ๋ชจ๋“  ๋™์ž‘ ์ฃผ์žฅ์€ file_path:line ์œผ๋กœ ๊ทผ๊ฑฐ๋ฅผ ๋‹จ๋‹ค. ์ฝ”๋“œ์—์„œ ์ง์ ‘ ํ™•์ธ๋˜์ง€ ์•Š์€ ํ•ญ๋ชฉ์€ "๋ฏธ๊ฒ€์ฆ"์œผ๋กœ ๋ช…์‹œํ•œ๋‹ค. ๋ณธ ๋ฌธ์„œ๋Š” ์ฝ๊ธฐ ์ „์šฉ ๋ถ„์„์ด๋ฉฐ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š์•˜๋‹ค.

๋‹จ์œ„ ๋ฉด์ฑ…(๊ฐ€์žฅ ์ค‘์š”): pepADMET HC50 ์ถœ๋ ฅ์˜ ์ ˆ๋Œ€ ๋‹จ์œ„(ฮผg/mL vs ฮผM)๋Š” ์›๋…ผ๋ฌธ ๋Œ€๋น„ ๋ฏธ๊ฒ€์ฆ์ด๋‹ค (pyrosetta_flow/pepadmet_toxicity.py:24-30, pyrosetta_flow/pepadmet_toxicity.py:40). ๋”ฐ๋ผ์„œ hc50 ์ ˆ๋Œ€๊ฐ’ ํ•ด์„์€ ๊ธˆ์ง€๋˜๋ฉฐ, native SST-14 ๊ธฐ์ค€์„  ๋Œ€๋น„ ์ƒ๋Œ€ ๋น„๊ต ์ „์šฉ์œผ๋กœ๋งŒ ์‚ฌ์šฉ๋œ๋‹ค.


โ‘  ๋™์ž‘ ์›๋ฆฌ

1-A. ADMET surrogate (๋ฌผ์„ฑ ๊ธฐ๋ฐ˜ ํ•ฉ๋ฆฌ์„ฑ ์ ์ˆ˜)

๋‘ ๊ฐˆ๋ž˜์˜ ADMET ๊ณ„์‚ฐ์ด ๊ณต์กดํ•œ๋‹ค.

(a) backend/admet.py โ€” ์„œ์—ด ์ „์šฉ ์ˆœ์ˆ˜ ํŒŒ์ด์ฌ ๋ฌผ์„ฑ/์•ฝ๋ฌผ์œ ์‚ฌ์„ฑ (์™ธ๋ถ€ ์˜์กด ์—†์Œ, backend/admet.py:7) - ๋ถ„์ž๋Ÿ‰(monoisotopic residue weight ํ•ฉ + H2O): backend/admet.py:74 - pH 7.4 net charge (K/R = +1, D/E = โˆ’1, H = +0.1, Nํ•ญ +1ยทCํ•ญ โˆ’1): backend/admet.py:77-89 - H-bond donor/acceptor (์‚ฌ์ด๋“œ์ฒด์ธ + backbone): backend/admet.py:91-97 - Kyte-Doolittle ํ‰๊ท  ์†Œ์ˆ˜์„ฑ + amphipathicity(๋ถ„์‚ฐ): backend/admet.py:99-107 - druglikeness_score (0~100, 25์ ร—4 ๊ทœ์น™): MW 1200~2000 / |charge|โ‰ค3 / ์†Œ์ˆ˜์„ฑ [โˆ’2,+1] / 3์—ฐ์† ๋™์ผ ์ž”๊ธฐ ์—†์Œ โ€” backend/admet.py:113-136 - ์‹ ์žฅ๋…์„ฑ(PRRT renal retention) ์œ„ํ—˜: cationic ์ž”๊ธฐ(K/R/H) ๊ธฐ๋ฐ˜ ์ ์ˆ˜, min(100, (n_lys+n_arg)*20 + max(0,net_charge)*15) โ€” backend/admet.py:188-200. ๊ทผ๊ฑฐ๋กœ DOTATATE(~25, Low)๋ฅผ ๋ ˆํผ๋Ÿฐ์Šค๋กœ ๋‘  (backend/admet.py:155-156).

(b) multiobjective.admet_reasonableness() โ€” ๋‹ค๋ชฉ์  ๋žญํ‚น์šฉ 0~1 ํ•ฉ๋ฆฌ์„ฑ ์ ์ˆ˜ (pyrosetta_flow/multiobjective.py:64-90) - ์ž…๋ ฅ: instability_index, gravy, boman_index, pi 4๊ฐœ ๋ฌผ์„ฑ (pyrosetta_flow/multiobjective.py:69-72). ์ด ๋ฌผ์„ฑ์€ AG_src.pipeline.pharma_properties.PharmaProperties ๊ฐ€ ๊ณ„์‚ฐ (pyrosetta_flow/multiobjective.py:46, pyrosetta_flow/multiobjective.py:135-147). Cys3-Cys14 SS bond ๋Š” pI ๊ณ„์‚ฐ ์‹œ ํ•ด๋‹น Cys ๋ฅผ ์ œ์™ธ (pyrosetta_flow/multiobjective.py:138-140, pyrosetta_flow/multiobjective.py:146). - ๋ถ€๋ถ„์ ์ˆ˜ ๋ณ€ํ™˜ + ๊ฐ€์ค‘ ํ‰๊ท : - Instability: <40 ๋งŒ์ , 40~80 ์„ ํ˜• ๊ฐ์ , >80 0์  (pyrosetta_flow/multiobjective.py:75) - GRAVY: โ‰คโˆ’1 ๋งŒ์ (์นœ์ˆ˜), 0โ†’0.5, โ‰ฅ1 0์  (pyrosetta_flow/multiobjective.py:77) - Boman: <1 ๊ฒฐํ•ฉ๊ฒฝํ–ฅ ์•ฝํ•จ(์ ˆ๋ฐ˜ ์Šค์ผ€์ผ), 1~4 ์„ ํ˜•, >4 ๋งŒ์  (pyrosetta_flow/multiobjective.py:79-84) - pI: 6~8 ๋งŒ์ , ๋ฉ€์–ด์งˆ์ˆ˜๋ก ์„ ํ˜• ๊ฐ์  (pyrosetta_flow/multiobjective.py:86) - ๊ฐ€์ค‘: 0.35*II + 0.30*GRAVY + 0.15*Boman + 0.20*pI โ€” ์•ˆ์ •์„ฑยท์šฉํ•ด๋ฅผ ๋” ์ค‘์‹œ (pyrosetta_flow/multiobjective.py:88-89). ์ž„๊ณ„๊ฐ’/๋ฒ”์œ„๋Š” ๋ชจ๋‘ ๋ฌธํ—Œ ํœด๋ฆฌ์Šคํ‹ฑ (pyrosetta_flow/multiobjective.py:57-62). - ์ด ์ ์ˆ˜๋Š” cheap_objectives() ์˜ admet_score ๊ฐ€ ๋˜๊ณ  (pyrosetta_flow/multiobjective.py:154), enrich_candidates() ๊ฐ€ ํ›„๋ณด์˜ druggability ํ‚ค๋กœ ๋งคํ•‘ (pyrosetta_flow/multiobjective.py:264-265).

honest disclaimer (VR-cycle-09 / H-06): half_life_h, admet_score ๋Š” ๋žญํ‚น์šฉ surrogate ์ด๋ฉฐ ์ž„์ƒ ๋ฐ˜๊ฐ๊ธฐยท์ž„์ƒ ADMET ์ˆ˜์น˜๊ฐ€ ์•„๋‹ˆ๋‹ค (pyrosetta_flow/multiobjective.py:15-18). in-vitro assay ๊ฒ€์ฆ ์—†์Œ.

1-B. pepADMET GNN ๋…์„ฑ ์ถ”๋ก 

๋ชจ๋ธ: toxicity_early_stop.pth โ€” MLR-GAT (RGCN + MLP + Attention), JCIM 2026, 66, 936-946 (pyrosetta_flow/pepadmet_toxicity.py:4-7). 4๊ฐœ ๋ฉ€ํ‹ฐํƒœ์Šคํฌ ์ถœ๋ ฅ: binary toxicity / 6-class type / 4-class neurotoxicity / HC50 (pyrosetta_flow/pepadmet_infer_script.py:110-112).

์‹คํ–‰ ๊ฒฉ๋ฆฌ(conda subprocess): bio-tools env ์˜ runner ๊ฐ€ pepadmet env(DGL 0.4.3)๋ฅผ subprocess ๋กœ ํ˜ธ์ถœ (pyrosetta_flow/pepadmet_runner.py:1-5). conda run --no-capture-output -n pepadmet python3 pepadmet_infer_script.py <json> (pyrosetta_flow/pepadmet_runner.py:77-81), timeout 120s (pyrosetta_flow/pepadmet_runner.py:80). inline -c ๋Œ€์‹  ํŒŒ์ผ ์ง์ ‘ ํ˜ธ์ถœ๋กœ ๋ฒ„ํผ๋ง hang ๋ฐฉ์ง€ (pyrosetta_flow/pepadmet_runner.py:76, pyrosetta_flow/pepadmet_runner.py:32). stdout ๋งˆ์ง€๋ง‰ JSON ๋ผ์ธ ํŒŒ์‹ฑ (pyrosetta_flow/pepadmet_runner.py:88-92).

๊ทธ๋ž˜ํ”„ ๋นŒ๋“œ: SMILES โ†’ RDKit Mol โ†’ DGL ๊ทธ๋ž˜ํ”„ (pyrosetta_flow/pepadmet_infer_script.py:74-78, 51-71). SMILES ํŒŒ์‹ฑ ์‹คํŒจ ์‹œ ์„ ํ˜• ํด๋ฐฑ Chem.MolFromSequence (pyrosetta_flow/pepadmet_infer_script.py:81-102, 131-135) โ€” ์ด ๊ฒฝ์šฐ graph_note="linear_sequence_fallback" ๊ฐ€ ๊ธฐ๋ก๋˜๊ณ  (cyclic/SS bond ๊ตฌ์กฐ ์†Œ์‹ค), descriptor ๋Š” 2133์ฐจ์› ํ…์„œ(์‹คํŒจ ์‹œ zero) (pyrosetta_flow/pepadmet_infer_script.py:23-48).

SMILES ๋ณ€ํ™˜: runner ๊ฐ€ smiles_converter.sequence_to_smiles() ๋กœ Cys3-Cys14 ์ดํ™ฉํ™” ์‚ฌ์ดํด๋ฆญ SMILES ์ƒ์„ฑ ์‹œ๋„ (pyrosetta_flow/pepadmet_runner.py:61-66, pyrosetta_flow/smiles_converter.py:1-5, pyrosetta_flow/smiles_converter.py:55-60).

์ถœ๋ ฅ ํ–‰: binary_toxicity(sigmoid), is_toxic(>0.5), toxicity_type(6-class argmax), neurotoxicity_type(4-class argmax), hc50(task_3 ํšŒ๊ท€) โ€” pyrosetta_flow/pepadmet_infer_script.py:151-168. ์ •๊ทœํ™” ๋ ˆ์ด์–ด๊ฐ€ hc50_unit, hc50_reliable ํ”Œ๋ž˜๊ทธ ๋ถ€์ฐฉ (pyrosetta_flow/pepadmet_toxicity.py:40-43).

1-C. hc50 nativeยฑ5 ๋ฐด๋“œ ๊ฒŒ์ดํŠธ (ํ•ต์‹ฌ)

apply_toxicity_to_extra() ๊ฐ€ pepADMET ๊ฒฐ๊ณผ๋ฅผ extra_scores ์— ๊ธฐ๋กํ•˜๊ณ  admet_score ์— ํŽ˜๋„ํ‹ฐ๋ฅผ ๋ฐ˜์˜ํ•œ๋‹ค (pyrosetta_flow/multiobjective.py:206-241). ๋กœ์ง:

  1. fail-closed: available ๊ฐ€ ์•„๋‹ˆ๋ฉด admet_score ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์Œ(๊ฐ€์งœ ์•ˆ์ „ํŒ์ • ๊ธˆ์ง€) (pyrosetta_flow/multiobjective.py:217-218).
  2. binary ๋Š” ๊ธฐ๋ก๋งŒ, ๊ฒŒ์ดํŠธ ๋ฏธ์‚ฌ์šฉ โ€” pepadmet_toxic/binary_toxicity ๊ธฐ๋ก๋˜์ง€๋งŒ ๊ฒŒ์ดํŠธ์— ์“ฐ์ด์ง€ ์•Š์Œ (pyrosetta_flow/multiobjective.py:219-221, ์ฃผ์„ pyrosetta_flow/multiobjective.py:211-212).
  3. ์‹ ๋ขฐ๋„ ๊ฒŒ์ดํŠธ(VR-A2, 2026-06-17): graph_note == "linear_sequence_fallback" ์ด๋ฉด cyclic ๊ตฌ์กฐ ์†Œ์‹ค๋กœ hc50 ์‹ ๋ขฐ ๋ถˆ๊ฐ€ โ†’ hc50_reliable=False ๊ธฐ๋ก ํ›„ ๊ฒŒ์ดํŠธ skip(fail-open: ๊ฐ€์งœ ๋…์„ฑํŒ์ • ๋ฐฉ์ง€) (pyrosetta_flow/multiobjective.py:225-230).
  4. native ๋Œ€๋น„ ์ƒ๋Œ€(home-advantage) ๊ฒŒ์ดํŠธ: - native hc50 ๊ธฐ์ค€์„  ๋กœ๋“œ (native_toxicity_baseline.json, hc50 = โˆ’55.6816, _native_hc50_baseline() pyrosetta_flow/multiobjective.py:171-185). - delta = hc50 โˆ’ native_hc50 (pyrosetta_flow/multiobjective.py:232), >0 ์•ˆ์ „ / <0 ๋…์„ฑโ†‘. - native ยฑ5 ๋ฐด๋“œ(_HC50_NATIVE_TOLERANCE = 5.0)๋Š” "๋™๊ธ‰"์œผ๋กœ ๋ฌดํŽ˜๋„ํ‹ฐ (pyrosetta_flow/multiobjective.py:166, pyrosetta_flow/multiobjective.py:234). - ๋ฐด๋“œ ์ดˆ๊ณผ ๋…์„ฑ์ผ ๋•Œ๋งŒ ์ดˆ๊ณผ๋ถ„์— ์„ ํ˜• ๋น„๋ก€ ํŽ˜๋„ํ‹ฐ, factor = max(0.4, 1 โˆ’ excess/200) (_TOXIC_ADMET_PENALTY=0.4, _HC50_PENALTY_SCALE=200.0) ๋กœ admet_score ๊ณฑ์…ˆ ๊ฐ์  (pyrosetta_flow/multiobjective.py:163, 167, 236-241). - hc50_vs_native, more_toxic_than_native ๊ธฐ๋ก (pyrosetta_flow/multiobjective.py:233-235).

์ด ๊ฒŒ์ดํŠธ ์‚ฐ์ถœ๋ฌผ์€ ๊ธ€๋กœ๋ฒŒ ๋ฆฌ๋”๋ณด๋“œ ํ†ต๊ณผ ํŒ์ •์— ์ง์ ‘ ์“ฐ์ธ๋‹ค โ€” count_passing() ์€ ๋…์„ฑ์„ more_toxic_than_native is False(๋ช…์‹œ์  ์ธก์ •)๋งŒ ํ†ต๊ณผ๋กœ ์ธ์ • (pyrosetta_flow/global_leaderboard.py:167-176, ํ•„๋“œ ์ ์žฌ pyrosetta_flow/global_leaderboard.py:104-106). ํŒŒ์ดํ”„๋ผ์ธ ๋ฐฐ์„ ์€ scoring_pipeline.py:98-117 (Step 0.5, ๋ฐฐ์น˜ ์ถ”๋ก  ํ›„ ํŽ˜๋„ํ‹ฐ ๋ฐ˜์˜, ์‹คํŒจ ์‹œ graceful skip).


โ‘ก ์˜ํ–ฅ โ€” binary โ†’ hc50 ๊ต์ฒด๋กœ "์˜ฅ์‹œํ† ์‹ /native ์˜คํŒ" ํ•ด๊ฒฐ

๊ฒฝ์œ„(์ •ํ™•ํžˆ):

  • ๋ฌธ์ œ: pepADMET is_toxic(binary)๊ฐ€ ๋น„๋ณ€๋ณ„์  โ€” ์ž„์ƒ ์•ˆ์ „ ํŽฉํƒ€์ด๋“œ(oxytocin), native SST-14, ๋ฒŒ๋…(melittin) ์„ ์ „๋ถ€ toxic=True ๋กœ ํŒ์ • (baseline note, data/somatostatin_receptor/curated/native_toxicity_baseline.json note; ์ฝ”๋“œ ์ฃผ์„ pyrosetta_flow/multiobjective.py:164, pyrosetta_flow/multiobjective.py:211). ์ด binary ๊ฒŒ์ดํŠธ๊ฐ€ in-loop ์„ ํƒ์„ฑ run ์—์„œ "์ธก์ • ํ›„๋ณด ์ „์› toxic โ†’ admetร—0.4 โ†’ full gate ํƒˆ๋ฝ" ์˜ ์›์ธ์ด์—ˆ๋‹ค(๋ฉ”๋ชจ๋ฆฌ sstr2-selectivity-goal ๊ธฐ๋ก).
  • ๊ด€์ฐฐ๋œ ๋ณ€๋ณ„๋ ฅ: ๋™์ผ ๋ชจ๋ธ์˜ hc50 ์—ฐ์†๊ฐ’์€ ์ƒ๋ฌผํ•™์ ์œผ๋กœ ์ •ํ™•ํ•œ ์ˆœ์„œ โ€” oxytocin(โˆ’14.5, ์•ˆ์ „) < native(โˆ’55.7) < melittin(โˆ’292.7, ๋…์„ฑ) (baseline json note ์˜ ๋Œ€์กฐ๊ตฐ ์ˆ˜์น˜).
  • ๊ต์ฒด: ๊ฒŒ์ดํŠธ๋ฅผ binary ์—์„œ hc50 โˆ’ native_hc50 ์ƒ๋Œ€(home-advantage) ๋กœ ์ „ํ™˜ (pyrosetta_flow/multiobjective.py:211-241). ฮ”margin(์„ ํƒ์„ฑ) ๊ณผ ๋™์ผ ์ฒ ํ•™ โ€” "native ๋ฅผ ๊ธฐ์ค€์„ ์œผ๋กœ ๋‘๊ณ  ๊ทธ๋ณด๋‹ค ๋‚˜์œ ํ›„๋ณด๋งŒ ๋ฒŒ์ ".
  • ํšจ๊ณผ: native ๋™๊ธ‰(ยฑ5) ํ›„๋ณด๋Š” is_toxic=True ๋ผ๋„ ๋ฌดํŽ˜๋„ํ‹ฐ๊ฐ€ ๋˜์–ด (test_apply_toxicity_native_comparable_no_penalty pyrosetta_flow/tests/test_multiobjective.py:118-126), native ๊ธ‰ ์šฐ์ˆ˜ ํ›„๋ณด๊ฐ€ admetร—0.4 ๋กœ ๋ถ€๋‹น ํƒˆ๋ฝํ•˜๋˜ ๋ฌธ์ œ๊ฐ€ ํ•ด์†Œ๋˜์—ˆ๋‹ค(์—์ด์ „ํŠธ ๋žญํ‚น ์ •์ƒํ™”). ์žฌํ‰๊ฐ€ ์‹œ ์ธก์ • 8ํ›„๋ณด ์ค‘ 7๊ฐœ๊ฐ€ "๋…์„ฑโ‰คnative"(๋ฌดํŽ˜๋„ํ‹ฐ)๋กœ ์ •์ƒํ™”๋จ(๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ก).

์ฃผ์˜(๋ฏธ๊ฒ€์ฆ): ์œ„ oxytocin/native/melittin ๋Œ€์กฐ ์ˆ˜์น˜๋Š” native_toxicity_baseline.json ์˜ note ์™€ ๋ฉ”๋ชจ๋ฆฌ์— ๊ธฐ๋ก๋œ ๊ฐ’์ด๋ฉฐ, ๋ณธ ๋ถ„์„์—์„œ ๋ชจ๋ธ์„ ์žฌ์‹คํ–‰ํ•ด ์žฌํ˜„ํ•˜์ง€๋Š” ์•Š์•˜๋‹ค(์ฝ๊ธฐ ์ „์šฉ). ๋”ฐ๋ผ์„œ "binary ๋น„๋ณ€๋ณ„์„ฑ"๊ณผ "hc50 ๋ณ€๋ณ„๋ ฅ"์€ ๊ธฐ๋ก๋œ ์ธก์ • ๊ฒฐ๊ณผ์— ๊ทผ๊ฑฐํ•œ ์ฃผ์žฅ์ด์ง€ ๋ณธ ์„ธ์…˜์—์„œ ์žฌ๊ฒ€์ฆ๋œ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.


โ‘ข ๊ด€๋ จ Action Item

ํ•ญ๋ชฉ ๋‚ด์šฉ ์ƒํƒœ/๊ทผ๊ฑฐ
B (pepADMET ํ†ตํ•ฉ) pepADMET GNN(toxicity_early_stop.pth)์„ pepadmet conda env subprocess ๋ฐฐ์น˜ ์ถ”๋ก ์œผ๋กœ ๋‹ค๋ชฉ์  ๋žญํ‚น์— ์—ฐ๊ฒฐ ๊ตฌํ˜„ ์™„๋ฃŒ. scoring_pipeline.py:98-117(Step 0.5), pyrosetta_flow/multiobjective.py:158-203, runner/infer ์ „์ฒด. ๋ฐฑ์—”๋“œ API ๋„ merge_pepadmet_into_admet_results ๋กœ ์—ฐ๊ฒฐ (backend/admet.py:242-276, backend/routers/admet.py:17-21)
hc50 ๊ฒŒ์ดํŠธ ์ˆ˜์ • (2026-06-10) binaryโ†’hc50 native ์ƒ๋Œ€ ๊ฒŒ์ดํŠธ๋กœ ๊ต์ฒด ์™„๋ฃŒ. pyrosetta_flow/multiobjective.py:206-241, baseline json, ํšŒ๊ท€ ํ…Œ์ŠคํŠธ ๊ฐฑ์‹ /์‹ ์„ค (pyrosetta_flow/tests/test_multiobjective.py:93-141)
hc50 ์‹ ๋ขฐ๋„ ๊ฒŒ์ดํŠธ (VR-A2, 2026-06-17) SMILES ์„ ํ˜• ํด๋ฐฑ(cyclic ์†Œ์‹ค) ์‹œ hc50 ์‹ ๋ขฐ๋ถˆ๊ฐ€ โ†’ ๊ฒŒ์ดํŠธ skip ์™„๋ฃŒ. pyrosetta_flow/multiobjective.py:225-230, pyrosetta_flow/pepadmet_toxicity.py:24-43, ํ…Œ์ŠคํŠธ pyrosetta_flow/tests/test_multiobjective.py:107-115
HC50 ๋‹จ์œ„ ๋ฉด์ฑ… (VR-A2) hc50 ์ ˆ๋Œ€๋‹จ์œ„ ๋ฏธ๊ฒ€์ฆ ๋ช…์‹œ, ์ƒ๋Œ€๋น„๊ต ์ „์šฉ ๊ฐ•์ œ ์™„๋ฃŒ(๋ฌธ์„œํ™”). pyrosetta_flow/pepadmet_toxicity.py:24-30, pyrosetta_flow/pepadmet_toxicity.py:40

๋‚จ์€ ๊ณผ์ œ(์ฝ”๋“œ ๊ธฐ์ค€ ๋ฏธํ•ด๊ฒฐ): - hc50 ์ ˆ๋Œ€ ๋‹จ์œ„ ๊ฒ€์ฆ(ฮผg/mL vs ฮผM, ์›๋…ผ๋ฌธ task_3 ํƒ€๊นƒ๊ณผ ๋Œ€์กฐ) โ€” ํ˜„์žฌ ๋ฏธ๊ฒ€์ฆ ๋ฉด์ฑ…์œผ๋กœ๋งŒ ํšŒํ”ผ (pyrosetta_flow/pepadmet_toxicity.py:24-30). - SMILES ๋ณ€ํ™˜ ์„ฑ๊ณต๋ฅ  โ€” ์‚ฌ์ดํด๋ฆญ SMILES ์‹คํŒจ ์‹œ ์„ ํ˜• ํด๋ฐฑ๋˜๋ฉด hc50 ๊ฒŒ์ดํŠธ๊ฐ€ ํ†ต์งธ๋กœ skip ๋˜์–ด ๋…์„ฑ ์‹ ํ˜ธ๊ฐ€ ์‚ฌ๋ผ์ง (pyrosetta_flow/multiobjective.py:225-230). ํด๋ฐฑ ๋นˆ๋„/์˜ํ–ฅ์€ ๋ฏธ์ธก์ •.


โ‘ฃ ์™„์„ฑ๋„ ํ‰๊ฐ€

์•ฝ 75%

๊ทผ๊ฑฐ(๊ฐ€์ ): - ๋ฐ์ดํ„ฐ ํ๋ฆ„ end-to-end ์—ฐ๊ฒฐ๋จ: cheap_objectives โ†’ enrich โ†’ pepADMET ์ถ”๋ก  โ†’ hc50 ๊ฒŒ์ดํŠธ โ†’ ๋ฆฌ๋”๋ณด๋“œ ํ†ต๊ณผ ํŒ์ • (pyrosetta_flow/multiobjective.py:101-266, scoring_pipeline.py:98-117, global_leaderboard.py:167-176). - ๊ฒฌ๊ณ ํ•œ ์‹คํŒจ ์ฒ˜๋ฆฌ: import/subprocess/timeout/JSON ํŒŒ์‹ฑ ๋ชจ๋‘ graceful, fail-closed(๊ฐ€์งœ ์•ˆ์ „) vs fail-open(์‹ ๋ขฐ๋ถˆ๊ฐ€ hc50) ๊ตฌ๋ถ„ ๋ช…ํ™• (pyrosetta_flow/pepadmet_runner.py:54-99, pyrosetta_flow/multiobjective.py:217-230). - ํšŒ๊ท€ ํ…Œ์ŠคํŠธ 5์ข…์ด ๊ฒŒ์ดํŠธ ๋ถ„๊ธฐ๋ฅผ ๋ชจ๋‘ ์ปค๋ฒ„(ํŽ˜๋„ํ‹ฐ/ํด๋ฐฑ skip/๋™๊ธ‰ ๋ฌดํŽ˜๋„ํ‹ฐ/๋น„๋…์„ฑ/unavailable) (pyrosetta_flow/tests/test_multiobjective.py:93-141). - ์ •์ง์„ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜: surrogate disclaimer, ๋‹จ์œ„ ๋ฉด์ฑ…, home-advantage ๋ณด์ •.

๊ฐ์ : - hc50 ์ ˆ๋Œ€ ๋‹จ์œ„ ๋ฏธ๊ฒ€์ฆ(โˆ’), ์ƒ๋Œ€๋น„๊ต๋กœ๋งŒ ์šฐํšŒ (pyrosetta_flow/pepadmet_toxicity.py:24-30). - ์„ ํ˜• ํด๋ฐฑ ์‹œ ๋…์„ฑ ๊ฒŒ์ดํŠธ ํ†ต์งธ skip โ†’ cyclic ํŽฉํƒ€์ด๋“œ์ธ๋ฐ SMILES ๋ณ€ํ™˜์ด ์ž์ฃผ ์‹คํŒจํ•˜๋ฉด ๋…์„ฑ ํ‰๊ฐ€๊ฐ€ ๋ฌด๋ ฅํ™”๋  ์ˆ˜ ์žˆ์Œ(๋นˆ๋„ ๋ฏธ์ธก์ •) (pyrosetta_flow/multiobjective.py:225-230). - binary/type/neurotoxicity ์ถœ๋ ฅ์€ ๊ธฐ๋ก๋งŒ ๋˜๊ณ  ๊ฒŒ์ดํŠธ์— ๋ฏธ๋ฐ˜์˜ โ€” 4๊ฐœ ๋ฉ€ํ‹ฐํƒœ์Šคํฌ ์ค‘ 1๊ฐœ(hc50)๋งŒ ์˜์‚ฌ๊ฒฐ์ •์— ์‚ฌ์šฉ (pyrosetta_flow/multiobjective.py:219-221). - backend/admet.py ์‹ ์žฅ๋…์„ฑ ์ ์ˆ˜์˜ ๊ณ„์ˆ˜(20/15)๋Š” ๋‹จ์ผ ๋ ˆํผ๋Ÿฐ์Šค(DOTATATE) ์™ธ ๋ณด์ • ๊ทผ๊ฑฐ ๋ถ€์žฌ (backend/admet.py:188).


โ‘ค ํ•™์ˆ ์  ๊ฐ€์น˜

  • home-advantage ์ƒ๋Œ€ ๊ฒŒ์ดํŠธ: ์ ˆ๋Œ€๊ฐ’์ด ๋น„๋ณ€๋ณ„/๋ฏธ๊ฒ€์ฆ์ธ ๋ชจ๋ธ ์ถœ๋ ฅ์„ ํ๊ธฐํ•˜์ง€ ์•Š๊ณ  "native ๊ธฐ์ค€์„  ๋Œ€๋น„ ฮ”" ๋กœ ์žฌ๊ตฌ์„ฑํ•ด ๋ณ€๋ณ„๋ ฅ์„ ํšŒ๋ณตํ•œ ์„ค๊ณ„๋Š” ์ผ๋ฐ˜ํ™” ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค โ€” ์„ ํƒ์„ฑ ฮ”margin ๊ณผ ๋™์ผ ํŒจํ„ด์œผ๋กœ ๋Œ€์นญ(pyrosetta_flow/multiobjective.py:211-214).
  • ๋‹ค์ค‘ ์‹ ๋ขฐ ๊ฒŒ์ดํŠธ: available(fail-closed) โ†’ graph_note(fail-open) โ†’ native-band ์˜ 3์ธต ๊ฒŒ์ดํŠธ๋กœ "ํ™˜๊ฐ๋œ ์•ˆ์ „/๋…์„ฑ ํŒ์ •"์„ ์–‘๋ฐฉํ–ฅ ์ฐจ๋‹จ (pyrosetta_flow/multiobjective.py:217-241).
  • ์ •์งํ•œ ํ•œ๊ณ„ ๋…ธ์ถœ: surrogate disclaimer ์™€ ๋‹จ์œ„ ๋ฉด์ฑ…์„ ์ฝ”๋“œ ์ฃผ์„์œผ๋กœ ๋ช…๋ฌธํ™” โ€” ์žฌํ˜„์„ฑยท์‹ ๋ขฐ์„ฑ ๋ณด๊ณ ์— ๋ชจ๋ฒ” (pyrosetta_flow/multiobjective.py:15-18, pyrosetta_flow/pepadmet_toxicity.py:24-30).
  • ํ•œ๊ณ„: ๋‹จ์ผ ๋ชจ๋ธ(pepADMET) ์˜์กด, ์ ˆ๋Œ€ ๋‹จ์œ„ ๋ฏธ๊ฒ€์ฆ, in-vitro/in-vivo cross-validation ๋ถ€์žฌ โ†’ ํ˜„์žฌ๋กœ์„  ๋žญํ‚น ๋ณด์กฐ ์‹ ํ˜ธ๋กœ์„œ์˜ ๊ฐ€์น˜์ด์ง€ ์ž„์ƒ ์˜ˆ์ธก ๊ฐ€์น˜๋Š” ์ฃผ์žฅ ๋ถˆ๊ฐ€.

โ‘ฅ ์‚ฌ์šฉ๋ฒ•

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(๋‹ค๋ชฉ์  ํŒŒ์ดํ”„๋ผ์ธ ๋‚ด๋ถ€) โ€” ์ž๋™ ํ˜ธ์ถœ๋จ:

from pyrosetta_flow.multiobjective import (
    cheap_objectives, enrich_candidates,
    predict_toxicity_for_sequences, apply_toxicity_to_extra,
)
enrich_candidates(candidates)                 # admet_score/druggability ์ฑ„์›€
tox = predict_toxicity_for_sequences([seq])   # pepADMET ๋ฐฐ์น˜ ์ถ”๋ก 
apply_toxicity_to_extra(cand["extra_scores"], tox[seq])  # hc50 ๊ฒŒ์ดํŠธ ์ ์šฉ

(pyrosetta_flow/multiobjective.py:188-241)

๋‹จ๊ฑด ๋…์„ฑ ์˜ˆ์ธก:

from pyrosetta_flow.pepadmet_toxicity import predict_toxicity
r = predict_toxicity("AGCKNFFWKTFTSC")        # smiles ์ƒ๋žต ์‹œ ์ž๋™ ๋ณ€ํ™˜

(pyrosetta_flow/pepadmet_toxicity.py:59-80)

๋ฐฑ์—”๋“œ REST API: - GET /admet/{sequence} โ€” ๋ฌผ์„ฑ+์‹ ์žฅ๋…์„ฑ+pepADMET ๋ณ‘ํ•ฉ (backend/routers/admet.py:24-26) - POST /admet/batch โ€” ๋ฐฐ์น˜ (backend/routers/admet.py:29-30)

ํ™˜๊ฒฝ ๋ณ€์ˆ˜: - SKIP_PEPADMET=1 โ€” pepADMET ํ˜ธ์ถœ ์ƒ๋žต(ํ…Œ์ŠคํŠธ/๋น ๋ฅธ ์‘๋‹ต) (backend/admet.py:250-251) - PEPADMET_REPO โ€” pepADMET repo ๊ฒฝ๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ (pyrosetta_flow/pepadmet_runner.py:26-30)

ํ•„์ˆ˜ ์ „์ œ: pepadmet conda env + local_models/pepadmet/repo + model/toxicity_early_stop.pth ์กด์žฌ (pyrosetta_flow/pepadmet_runner.py:19-23, pyrosetta_flow/pepadmet_infer_script.py:105). ๋ฏธ์กด์žฌ ์‹œ available=False ๋กœ graceful skip.


โ‘ฆ ํ•„์š” ์ด์œ 

  1. ์„ ํƒ์„ฑ๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑ: SSTR2 ์„ ํƒ์„ฑ์ด ์šฐ์ˆ˜ํ•ด๋„ ๋…์„ฑยท์งง์€ ๋ฐ˜๊ฐ๊ธฐยท๋‚ฎ์€ ์šฉํ•ด ํ›„๋ณด๋Š” ์•ฝ๋ฌผ์ด ๋  ์ˆ˜ ์—†๋‹ค. ADMET surrogate(admet_score)์™€ pepADMET ๋…์„ฑ์ด ๋‹ค๋ชฉ์  ๊ฒŒ์ดํŠธ์˜ ์ผ๋ถ€๋กœ ์•ˆ์ „์„ฑยท์•ฝ๋ฌผ์œ ์‚ฌ์„ฑ์„ ๋žญํ‚น์— ์ฃผ์ž…ํ•œ๋‹ค (pyrosetta_flow/multiobjective.py:1-9, ObjectiveWeights.admet=0.15 pyrosetta_flow/multiobjective.py:278).
  2. ๋ฐฉ์‚ฌ์„ฑ์˜์•ฝํ’ˆ(PRRT) ํŠน์ด ์œ„ํ—˜: ์‹ ์žฅ ์žฌํก์ˆ˜์— ์˜ํ•œ ์‹ ์žฅ๋…์„ฑ์€ PRRT ์˜ ์šฉ๋Ÿ‰ ์ œํ•œ ๋…์„ฑ โ€” cationic ํ•จ๋Ÿ‰ ๊ธฐ๋ฐ˜ ์œ„ํ—˜ ์ ์ˆ˜๊ฐ€ ์ด๋ฅผ ์กฐ๊ธฐ ๊ฒฝ๊ณ  (backend/admet.py:150-217).
  3. ํ™˜๊ฐ/์˜คํŒ ์ฐจ๋‹จ: binary ๋น„๋ณ€๋ณ„์„ฑ์œผ๋กœ ์ธํ•œ native/oxytocin ์˜คํŒ์ด ์šฐ์ˆ˜ ํ›„๋ณด๋ฅผ ๋ถ€๋‹น ํƒˆ๋ฝ์‹œํ‚ค๋˜ ๋ฌธ์ œ๋ฅผ hc50 home-advantage ๊ฒŒ์ดํŠธ๊ฐ€ ๊ต์ •ํ•ด, ์—์ด์ „ํŠธ์˜ ์ž์œจ ๋žญํ‚น์ด ์ •์ƒ ์ž‘๋™ํ•˜๋„๋ก ํ•œ๋‹ค (ยงโ‘ก ์ฐธ์กฐ, pyrosetta_flow/multiobjective.py:206-241).

๊ฒ€์ฆ ์ธ์šฉ ๋ชฉ๋ก

  • ๋™์ž‘ ํ™•์ธ(์ง์ ‘ ์ฝ”๋“œ):
  • pyrosetta_flow/multiobjective.py:64-90 โ€” admet_reasonableness ๊ฐ€์ค‘/์ž„๊ณ„๊ฐ’
  • pyrosetta_flow/multiobjective.py:101-155 โ€” cheap_objectives, PharmaProperties, SS bond pI ์ฒ˜๋ฆฌ
  • pyrosetta_flow/multiobjective.py:163-185 โ€” ํŽ˜๋„ํ‹ฐ ์ƒ์ˆ˜, native_hc50 ๊ธฐ์ค€์„  ๋กœ๋“œ
  • pyrosetta_flow/multiobjective.py:206-241 โ€” apply_toxicity_to_extra (binary ๋ฏธ์‚ฌ์šฉยทhc50 ๊ฒŒ์ดํŠธยท์‹ ๋ขฐ๋„ skip)
  • pyrosetta_flow/pepadmet_runner.py:54-99 โ€” subprocess/conda ํ˜ธ์ถœ, ์‹คํŒจ ์ฒ˜๋ฆฌ
  • pyrosetta_flow/pepadmet_infer_script.py:105-170 โ€” MGA ๋ชจ๋ธ ๋กœ๋“œ, 4ํƒœ์Šคํฌ ์ถœ๋ ฅ, ์„ ํ˜• ํด๋ฐฑ
  • pyrosetta_flow/pepadmet_toxicity.py:22-56 โ€” ์ •๊ทœํ™”, hc50_unit/hc50_reliable
  • backend/admet.py:54-228 โ€” ๋ฌผ์„ฑ/์•ฝ๋ฌผ์œ ์‚ฌ์„ฑ/์‹ ์žฅ๋…์„ฑ ๊ณ„์‚ฐ
  • backend/admet.py:242-276, backend/routers/admet.py:13-30 โ€” pepADMET ๋ณ‘ํ•ฉยทREST
  • pyrosetta_flow/global_leaderboard.py:104-106, 167-176 โ€” ๋…์„ฑ ํ†ต๊ณผ ํŒ์ • ํ•„๋“œ/๋กœ์ง
  • pyrosetta_flow/scoring_pipeline.py:98-117 โ€” ํŒŒ์ดํ”„๋ผ์ธ Step 0.5 ๋ฐฐ์„ 
  • data/somatostatin_receptor/curated/native_toxicity_baseline.json โ€” hc50=โˆ’55.6816, ๋Œ€์กฐ๊ตฐ note
  • ํ…Œ์ŠคํŠธ: pyrosetta_flow/tests/test_multiobjective.py:39-141, pyrosetta_flow/tests/test_continuous_discovery.py:28-45

  • ๋ฏธ๊ฒ€์ฆ / ์ธก์ • ๋ฏธ์žฌํ˜„(์ฝ๊ธฐ ์ „์šฉ ํ•œ๊ณ„):

  • HC50 ์ ˆ๋Œ€ ๋‹จ์œ„(ฮผg/mL vs ฮผM) โ€” ์›๋…ผ๋ฌธ ๋Œ€๋น„ ๋ฏธ๊ฒ€์ฆ, ์ƒ๋Œ€๋น„๊ต ์ „์šฉ (pyrosetta_flow/pepadmet_toxicity.py:24-30, 40)
  • oxytocin(โˆ’14.5)/native(โˆ’55.7)/melittin(โˆ’292.7) ๋Œ€์กฐ ์ˆ˜์น˜ โ€” baseline json noteยท๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ก ๊ทผ๊ฑฐ, ๋ณธ ์„ธ์…˜ ๋ชจ๋ธ ์žฌ์‹คํ–‰ ๋ฏธ์ˆ˜ํ–‰
  • "binary ์ „์› toxic" ๋น„๋ณ€๋ณ„์„ฑ โ€” ๊ธฐ๋ก๋œ ์ธก์ • ๊ฒฐ๊ณผ ๊ทผ๊ฑฐ, ๋ณธ ์„ธ์…˜ ์žฌํ˜„ ์•ˆ ํ•จ
  • SMILES ์‚ฌ์ดํด๋ฆญ ๋ณ€ํ™˜ ์„ฑ๊ณต๋ฅ  / ์„ ํ˜• ํด๋ฐฑ ๋ฐœ์ƒ ๋นˆ๋„ โ€” ๋ฏธ์ธก์ •
  • admet_reasonableness ์ž„๊ณ„๊ฐ’ยท๊ฐ€์ค‘(0.35/0.30/0.15/0.20), ์‹ ์žฅ๋…์„ฑ ๊ณ„์ˆ˜(20/15) ์˜ ๋ฌธํ—Œ ์ •๋Ÿ‰ ๋ณด์ • ๊ทผ๊ฑฐ โ€” ์ฝ”๋“œ ์ฃผ์„์˜ ํœด๋ฆฌ์Šคํ‹ฑ ํ‘œ๊ธฐ ์™ธ ์™ธ๋ถ€ ๊ฒ€์ฆ ๋ฏธํ™•์ธ