기능 상세 보고

Silo B — SST-14 변이생성 + PyRosetta 도킹

Silo B 본 페이지는 녹색 계열(Silo B)에 해당하는 구조 기반 발굴 파이프라인을 다룹니다. 신뢰등급 배지: 실측 HIGH / surrogate-상대 MED / surrogate-절대 LOW


핵심 결론 (두괄식)

  • Silo B = SST-14 변이체를 PyRosetta FlexPepDock으로 실측 도킹하고, SSTR1/3/4/5 off-target 회피(Δmargin)를 순환 개선하는 무한 발굴 엔진이다. ddG·margin은 실측 HIGH, 반감기·ADMET은 surrogate.
  • 현재 성과: 글로벌 리더보드 50건 전원 Δmargin>0, best = AGCKNFFWKTDTSC(F11D) Δmargin +10.54 / ddG −45.11 kcal/mol, 누적 도킹 645 서열. [데이터: runs/pyrosetta_flow/global_selectivity_leaderboard.json]
  • 한계 정직 명시: ddG 절대값은 Ki/Kd 캘리브레이션 부재로 LOW, 순위 신호로만 유효. pos11 선택성 기전은 구조적으로 미검증.

1. 파이프라인 한눈에 (변이 → 도킹 → 선택성 게이트 → 반복)

flowchart TD subgraph SB["🟢 Silo B — 구조 기반 발굴 (녹색)"] direction TB A["native SST-14
AGCKNFFWKTFTSC"] --> B["변이 생성
design_positions 보존게이트
(Cys3/14 · FWKT 고정)"] B --> C["PyRosetta FlexPepDock
실측 ddG / clash"] C --> D{"in-loop 선택성
게이트 should_screen()"} D -->|"top-K & ddG 강함"| E["off-target 도킹
SSTR1/3/4/5 → Δmargin"] D -->|"비용 절감 skip"| F["다목적 스코어
반감기·ADMET surrogate"] E --> G["글로벌 리더보드
capacity=50 영속 기억"] F --> G G --> H{"무한엔진 continuous.py
DiversityPolicy"} H -->|"정체(patience)"| B H -->|"STOP 파일"| I["종료"] end style SB fill:#eafaf0,stroke:#1a8a4a

[근거: pyrosetta_flow/continuous.py:1-13 · runner.py:1-100 · selectivity_loop.py:48-56]


2. 단일 run 오케스트레이션 + 변이 엔진 (runner.py 코드 흐름)

2-0. runner.py — 에이전트 루프 한 바퀴는 어떻게 도는가

코드 흐름 서술: run_pyrosetta_agentic_mutdock_flow(config)가 한 epoch(run)의 전체 파이프라인을 오케스트레이션한다.

  • 목적: native SST-14에서 출발해 Planner 계획 → 변이 생성 → FlexPepDock 도킹 → QC 게이트 → 선택성 측정을 max_iterations 회 반복하며 선택성 우수 변이체를 발굴한다 [근거: pyrosetta_flow/runner.py:294].
  • 입력: FlowConfig(native 서열·design_positions·n_candidates·top_k·ddG/clash 임계 등) + 디스크에 누적된 사전 기록(experiment_log.jsonl)을 로드해 역대 후보·top hit·bandit guidance에 활용한다 [근거: pyrosetta_flow/runner.py:328-336]. (주: dedup용 seen_sequences는 cross-run 역대 서열로 시드하지 않고 native 1개로만 초기화 — 탐색 공간 보존을 위해 현재 run 내에서만 dedup [근거: pyrosetta_flow/runner.py:456-458].)
  • 흐름 (iteration 루프, runner.py:508~): 1. Planner 계획: PlannerAgent.execute(...)에 직전 top 후보·in-loop 선택성 리더보드(Δmargin)·역대 top hit을 previous_results로 피드백 → hypothesis + mutation_guidance(focus_positions) 산출 [근거: pyrosetta_flow/runner.py:522-541]. 2. 변이 생성: _mutable_design_positions(config)로 변이 가능 위치를 산출한 뒤, idx≤n_guided이면 generate_guided_mutant(Planner focus 사용), 아니면 generate_random_mutant로 후보를 만든다. dedup 실패가 누적되면 강제 변이 수를 단계적으로 상향(escalation)하고, scaffold 미보존 후보는 폐기·재시도(PHARMACOPHORE_RETRY_LIMIT=3) [근거: pyrosetta_flow/runner.py:596-664]. 3. 도킹: 후보별 _dock_one(job)ThreadPoolExecutor로 병렬 실행 — flexpep_dock.py를 subprocess로 호출해 ddG/total_score/clash를 받는다. 실패 시 ddg=999 fail-closed [근거: pyrosetta_flow/runner.py:716-790]. 4. QC 게이트: QCRankerAgent.execute(...)에 rosetta 게이트만 ON(plddt/docking/selectivity OFF)으로 넘겨 ddG≤rosetta_ddg_max·clash≤max로 거른 뒤 top_k 선별 → selected 마킹 [근거: pyrosetta_flow/runner.py:846-882]. 5. 선택성 측정: 이번 iteration 전체 후보를 screen_iteration_candidates(...)에 넘기면 내부 게이트(fail 아님·clash≤max·Cys 보존·ddG 게이트) 통과분만 off-target 도킹한다(§4) [근거: pyrosetta_flow/runner.py:885-901 · selectivity_loop.py:102-128]. 6. 수렴/기록: ConvergenceDetector로 ddG 수렴 판정, 후보 레코드를 run_records에 적재 [근거: pyrosetta_flow/runner.py:905-952].
  • 출력: 후보 결과·rank table·선택성 측정이 담긴 FlowArtifacts. continuous.py가 이를 글로벌 리더보드로 흡수한다(§5).

2-1. 변이 위치는 scaffold 보존 게이트로 제한된다

  • 주장: SST-14의 Cys3·Cys14(SS bond)와 FWKT(pos7–10) 파마코포어는 변이 대상에서 제외된다.
  • 근거(코드 흐름): _mutable_design_positions(config)config.design_positions를 입력받아 FWKT 위치(PHARMACOPHORE_POSITIONS_1IDX=(7,8,9,10))와 native 서열의 모든 Cys 위치를 집합 차집합으로 제거해 변이 가능 위치 리스트를 산출한다(전부 제외되면 원본 design_positions로 폴백) [근거: pyrosetta_flow/runner.py:132-139]. 생성된 후보는 다시 _preserves_scaffold()(FWKT slice 일치 AND 모든 Cys 위치 보존)로 2차 검사돼 통과해야만 seen_sequences에 등록된다 [근거: pyrosetta_flow/runner.py:126-129,642-645]. 기본 design_positions = [1,2,4,5,6,7,8,9,10,11,12](7-10은 필터로 제거), original_sequence = "AGCKNFFWKTFTSC" [근거: pyrosetta_flow/schema.py:13-17].
  • 함의: SSTR2 결합 필수 모티프를 깨는 후보가 도킹 풀에 진입하지 않아 탐색이 생물학적으로 타당한 공간에 집중된다.

2-2. SS bond(Cys3-Cys14) 보존을 구조 수준에서 검사한다

  • 주장: 도킹 단계에서 disulfide를 탐지·재형성하고, refine 후 SG-SG 거리로 INTACT/BROKEN을 판정한다.
  • 근거: 펩타이드 Cys 탐지 → conformation().detect_disulfides() 우선, 실패 시 SG-SG AtomPairConstraint(2.05 Å, sd=0.3) 폴백, refine 후 거리 <3.0 Å = INTACT [근거: AG_src/scripts/flexpep_dock.py:243-341]. 추가로 in-loop 적격 필터에 _disulfide_ok 적용 [근거: pyrosetta_flow/selectivity_loop.py:99-100].
  • 함의: SS bond는 임상 SST 유사체(octreotide/DOTATATE)에서 SSTR2 결합 필수 요소 [출처: Patel YC 1999, Front Neuroendocrinol 20(3):157-198, PMID 10433861, https://pubmed.ncbi.nlm.nih.gov/10433861/], 구조적 비타당 후보 1차 배제.
  • ⚠️ 한계: BROKEN 후보가 실제 도킹 풀에서 배제되는지(게이트화)는 코드상 미확인. [미검증] LOW [근거: BIO_biology.md §2-4 → flexpep_dock.py:339-341]

2-3. FWKT 파마코포어 보존을 서열 수준에서 판정한다

  • 주장: Phe7-Trp8-Lys9-Thr10(seq[6:10]=='FWKT') 보존 여부를 추적한다.
  • 근거: 정본 판정 "seq[6:10] == 'FWKT'" [근거: backend/pharmacophore.py:15-19]. SSTR2 pocket key residues TM3(Asp122)·TM5(Asn276)·TM6(Phe294,Trp291)·TM7(Tyr316) [출처: Robertson MJ et al. 2022, Nat Struct Mol Biol 29:210-217, PDB 7T11, https://doi.org/10.1038/s41594-022-00727-5]. best 후보 AGCKNFFWKTDTSC에서 FWKT 완전 보존 [데이터: global_selectivity_leaderboard.json:9].
  • ⚠️ 한계: 기본 모드는 substring 존재만 확인 — ≤4.5 Å 거리 기반 pocket 접촉 미검증, confidence_grade=HEURISTIC. MED [근거: backend/pharmacophore.py:101-102,130-132]

3. PyRosetta FlexPepDock — 실측 ΔG (flexpep_dock.py 코드 흐름)

3-0. flexpep_dock.py — 서열 하나가 ddG로 바뀌는 경로

코드 흐름 서술: 후보 서열 1개당 별도 subprocess(bio-tools conda Python)에서 실행되는 독립 도킹 스크립트.

  • 목적: 변이 펩타이드를 SSTR2 복합체에 refine 도킹하고 interface ΔG·clash·SS bond 무결성을 실측 산출한다 [근거: AG_src/scripts/flexpep_dock.py:5].
  • 입력: --input 복합체 PDB, --target-sequence 변이 서열, --reference-complex, --peptide-chain(runner가 넘김) [근거: pyrosetta_flow/runner.py:734-746].
  • 흐름: 1. SS bond 처리: 펩타이드(마지막 체인) Cys 잔기를 탐색해 정확히 2개면 conformation().detect_disulfides()로 자동 탐지(실패 시 SG-SG AtomPairConstraint HarmonicFunc(2.05Å, sd=0.3) 폴백) [근거: AG_src/scripts/flexpep_dock.py:243-334]. 2. refine: FlexPepDockingProtocol().apply(pose)로 펩타이드-수용체 인터페이스 최적화 [근거: AG_src/scripts/flexpep_dock.py:335-336]. 3. SS bond 판정: refine 후 SG-SG 거리 측정, <3.0Å이면 INTACT [근거: AG_src/scripts/flexpep_dock.py:275-290,338-341]. 4. ddG 산출: InterfaceAnalyzerMover(1)(jump_id=1로 수용체/펩타이드 분리)에 pack_separated=True로 get_interface_dG() 호출 → kcal/mol(음수일수록 강결합) [근거: AG_src/scripts/flexpep_dock.py:394-406]. 5. clash 산출: 펩타이드 체인 잔기 중 fa_rep>10.0 REU인 잔기 수를 셈(수용체 내부 clash 제외 — interface clash만) [근거: AG_src/scripts/flexpep_dock.py:416-446].
  • 출력: stdout 마지막 줄에 {"ddg", "total_score", "clash_score", ...} JSON [근거: AG_src/scripts/flexpep_dock.py:539-550].

3-1. 도킹은 subprocess로 분리된 실측 PyRosetta 호출이다

  • 주장: ddG는 mock 없이 실제 FlexPepDock InterfaceAnalyzer 결과다.
  • 근거(코드 흐름): runner의 _run_script()가 conda Python으로 위 도킹 스크립트를 실행(timeout 600s)하고, 반환코드 0·stdout 비어있지 않음을 검사한 뒤 마지막 줄을 json.loads로 파싱한다(실패 시 RuntimeError) [근거: pyrosetta_flow/docking_executor.py:38-75]. fail-closed: 사전게이트 탈락·subprocess 예외·validation 실패 시 ddg=999(명백한 탈락)로 기록 [근거: pyrosetta_flow/runner.py:721-732,757-767,1342-1344].
  • 함의: 리더보드 ddG가 실제 시뮬레이션 값임을 구조적으로 보장(환각성 점수 차단, H-06 가드). HIGH

3-2. ddG 절대값은 캘리브레이션 부재 — 순위로만 신뢰

  • 주장: ddG는 PyRosetta REU/kcal·mol이며 실험 Ki/Kd로 보정되지 않았다.
  • 근거: honest disclaimer "ddG·selectivity_margin은 실제 FlexPepDock 결과지만 절대 친화도(Ki/Kd)가 아니다" [근거: pyrosetta_flow/multiobjective.py:13-17].
  • 함의: best ddG=−45.11이 "DOTATATE보다 우수한 결합"을 의미하지 않음. 절대값 LOW / 상대순위 MED. 임상 이행 전 SPR/ITC Ki 측정 필수.

3-3. 실행 이력 규모

  • 실험 로그 누적 17,853+ 레코드(candidate/status/ddg/clash/selected; 무한엔진 가동중이라 단조 증가하는 스냅샷 값) [데이터: runs/pyrosetta_flow/experiment_log.jsonl]. 실패 사례는 PyRosetta segfault 등 failure_stage로 기록 — 가짜 통과 없음 [근거: EV09_silo_b_trace.md §IV-C].

4. 선택성 Δmargin — home-advantage 보정 (multiobjective.py · selectivity_loop.py 코드 흐름)

4-0. screen_selectivity() — 선택성 신호는 어떻게 계산되는가

코드 흐름 서술: multiobjective.screen_selectivity()가 후보 1개에 대한 선택성 측정의 핵심 연산이다.

  • 목적: on-target(SSTR2)과 off-target(SSTR1/3/4/5)을 동일 프로토콜로 도킹해 native 대비 선택성(Δmargin)을 산출한다 [근거: pyrosetta_flow/multiobjective.py:380].
  • 입력: 후보의 SSTR2 복합체 PDB(sstr2_complex_pdb), 루프 내 측정한 on-target ddG, off-target 수용체 PDB 5종(DEFAULT_OFFTARGET_RECEPTORS + SSTR2) [근거: pyrosetta_flow/multiobjective.py:333-337,405-410].
  • 흐름: 1. SSTR2 + off-target 4종을 ThreadPoolExecutor(max 6 worker)로 병렬 transplant+pre-relax 도킹(dock_against_offtarget) [근거: pyrosetta_flow/multiobjective.py:404-425]. 2. SSTR2를 off-target과 동일 프로토콜로 재도킹한 값(sstr2_ddg_same)을 baseline으로 삼아 프로토콜 편향 제거(실패 시 루프 ddG 폴백) [근거: pyrosetta_flow/multiobjective.py:427-433]. 3. worst = min(offtarget_ddg)(가장 강한 off-target), margin = worst − baseline(양수=SSTR2가 더 강함) [근거: pyrosetta_flow/multiobjective.py:434-435]. 4. native baseline(_native_selectivity_baseline, JSON에서 로드·캐시)을 빼서 delta_margin = margin − nat_margin [근거: pyrosetta_flow/multiobjective.py:438-439,343-358].
  • 출력: {selectivity_margin, delta_margin, offtarget_ddg, sstr2_ddg_sameprotocol, more_selective_than_native, ...} dict — selectivity_loop가 후보 extra_scores에 기록 [근거: pyrosetta_flow/multiobjective.py:440-458 · selectivity_loop.py:132-138].

4-1. Δmargin 정의와 native baseline

  • 주장: 선택성은 절대 margin이 아니라 native 대비 향상분(Δmargin)으로 평가한다.
  • 근거: Δmargin = margin − native_margin(+13.37) [근거: pyrosetta_flow/multiobjective.py:438-439]. native baseline: SSTR2 ddG=−61.35, worst off-target SSTR5=−47.98, margin=+13.37 [데이터: data/somatostatin_receptor/curated/native_selectivity_baseline.json]. SSTR2도 off-target과 동일 transplant+pre-relax로 재측정해 프로토콜 편향 제거 [근거: pyrosetta_flow/multiobjective.py:401-407].
  • 함의: Δmargin>0 = "native SST-14 초과 선택성"이라는 상대적·정직한 in-silico 신호. 절대 margin은 source 구조 편향으로 변별력 없음. MED

4-2. off-target 5종 구조 정렬

  • SSTR1(9IK8)·SSTR3(8XIR)·SSTR4(7XMT)·SSTR5(8ZBJ)를 SSTR2(7XNA) 기준 cealign, RMSD 2.77~3.13 Å [데이터: data/somatostatin_receptor/alignment_summary.json].
  • ⚠️ 보수 해석: 3 Å RMSD는 결합 포켓 주변에서 수 Å 위치 오차 유발 가능 → Δmargin ≈ 1~3은 정렬 오차와 구분 곤란, Δmargin > 5만 신뢰 신호로 해석 권고 [근거: BIO_biology.md §2-5].

4-3. 비용 제어 게이트 (selectivity_loop.py 코드 흐름)

코드 흐름 서술: SelectivityLeaderboard + screen_iteration_candidates()가 "어떤 후보를 비싼 off-target 도킹에 넘길지"를 결정하는 비용 게이트.

  • 목적: off-target 도킹(후보×5수용체, ~6분/후보)은 비싸므로 실측 ddG를 유망도 프록시로 써 가치 있는 후보만 선별 도킹한다 [근거: pyrosetta_flow/selectivity_loop.py:1-8].
  • 입력: 이번 iteration 후보 리스트, in-loop SelectivityLeaderboard(글로벌 리더보드로 warm-start됨), iter_dir의 도킹 PDB [근거: pyrosetta_flow/selectivity_loop.py:76-85,23-41].
  • 흐름 (screen_iteration_candidates): 1. 적격 필터: fail_reason 없음 + clash≤clash_max + _disulfide_ok(모든 native Cys 위치 보존) + 도킹 PDB 존재 후보만 통과 [근거: pyrosetta_flow/selectivity_loop.py:99-118]. 2. 정렬: ddG 강한 순으로 정렬 [근거: pyrosetta_flow/selectivity_loop.py:121]. 3. 게이트 should_screen(seq, ddg): 이미 도킹한 서열이면 skip → ddG>−10이면 약한 binder로 skip → 리더보드 미충원이면 도킹 → 충원 시 기존 top-K 최약체(worst_ddg=최고 ddG)보다 강해야만 도킹 [근거: pyrosetta_flow/selectivity_loop.py:48-56]. 4. 도킹·기록: 게이트 통과분에 screen_selectivity(§4-0) 호출, 결과를 후보 extra_scores와 리더보드(update, Δmargin 내림차순 top-K 유지)에 반영. iteration당 최대 max_screen_per_iter(기본 2)건 [근거: pyrosetta_flow/selectivity_loop.py:123-144,58-65].
  • 출력: 이번에 도킹한 후보들의 요약 리스트 + Δmargin이 채워진 extra_scores.
  • 함의: 실측 ddG(강신호)를 유망도 프록시로 써 도킹 비용을 통제하면서 선택성 신호를 확보.

4-4. 글로벌 리더보드 — run 간 영속 기억 (global_leaderboard.py 코드 흐름)

코드 흐름 서술: GlobalSelectivityLeaderboard가 무한 엔진의 "선택성 기억"을 디스크에 영속화한다.

  • 목적: 매 epoch의 선택성 측정을 누적해 ① 재도킹 회피 ② in-loop 리더보드 warm-start ③ 역대 best Δmargin 단조 추적에 사용한다 [근거: pyrosetta_flow/global_leaderboard.py:1-9].
  • 입력: run의 artifacts(iteration/final 후보의 extra_scores) 또는 단건 측정 [근거: pyrosetta_flow/global_leaderboard.py:123-148].
  • 흐름: 1. load: JSON에서 entries·screened_seqs·n_ingested_total 복원, 손상 시 빈 리더보드로 fail-open(발굴 계속) [근거: pyrosetta_flow/global_leaderboard.py:52-67]. 2. add_measurement: margin 없으면 무시, Δ 미계산 시 native baseline으로 backfill, 동일 서열은 더 높은 Δmargin만 유지, 신규 best 갱신 여부 반환 [근거: pyrosetta_flow/global_leaderboard.py:85-121]. 3. _resort: Δmargin 내림차순(동률 ddG)으로 정렬 후 capacity=50로 truncate [근거: pyrosetta_flow/global_leaderboard.py:152-157]. 4. save: tmp→replace atomic write [근거: pyrosetta_flow/global_leaderboard.py:69-82].
  • 출력: top-N, best_delta, count_passing(Δ>0 & ddG≤−15 & 비독성; None은 fail-closed 불통과), warm_start_payload [근거: pyrosetta_flow/global_leaderboard.py:160-183].
항목 신뢰등급 근거
best Δmargin +10.5351 MED global_selectivity_leaderboard.json:3
top-K 보관 50건 전원 Δ>0 MED …json:4 (n_unique)
누적 도킹 서열 645 HIGH …json:5 (n_screened_unique)
누적 측정 676 HIGH …json:6 (n_ingested_total)

Top-3 (실측 ddG, Δmargin) [데이터: runs/pyrosetta_flow/global_selectivity_leaderboard.json:8-]:

순위 서열 변이 ddG (kcal/mol) Δmargin 비독성
1 AGCKNFFWKTDTSC F11D −45.11 +10.54
2 AICLNWFWKTVISC 다중 −48.81 +9.32
3 ARCGKFFWKTATSC 다중 −32.12 +9.10

pos11 신호: best/4위가 F11D/F11E(음하전 도입). FWKT·SS bond 보존 채 pos11만 변이 [근거: BIO_biology.md §1-4]. ⚠️ 구조적 기전(SSTR2 특이 pocket 상호작용)은 미검증 — 순위 상관만 존재. LOW [근거: BIO_biology.md §2-3]


5. 무한 발굴 엔진 (continuous.py 코드 흐름)

5-0. run_continuous_discovery() — 단발 run을 무한 루프로 감싸기

코드 흐름 서술: run_continuous_discovery()가 §2의 단발 run 위에 epoch 루프를 씌운다.

  • 목적: STOP 파일이 생길 때까지(또는 max_epochs까지) §2 run을 반복 호출하며, run 간 학습을 글로벌 리더보드 + experiment_log로 누적한다 [근거: pyrosetta_flow/continuous.py:1-13].
  • 입력: base FlowConfig(inloop_selectivity·reuse_baseline 강제 ON), control JSON 경로, STOP 파일 경로, status 파일 경로 [근거: pyrosetta_flow/continuous.py:107-118].
  • 흐름 (while 루프): 1. STOP 파일 존재·max_epochs 도달 검사 → graceful 종료 [근거: pyrosetta_flow/continuous.py:125-132]. 2. control JSON 매 epoch 재로드 → 화이트리스트 필드만 config에 덮어씀(재시작 없이 실시간 조정) [근거: pyrosetta_flow/continuous.py:135-136,51-54]. 3. seed_base를 epoch별로 교체(+epoch*1000)하고 직전 정책이 정한 변이 수를 적용 [근거: pyrosetta_flow/continuous.py:138-142]. 4. (옵션) 목표 통과 수 도달 시 자동 정지 [근거: pyrosetta_flow/continuous.py:144-152]. 5. run_pyrosetta_agentic_mutdock_flow(cfg) 실행 — epoch 실패는 try/except로 잡아 루프를 죽이지 않음 [근거: pyrosetta_flow/continuous.py:159-166]. 6. 글로벌 리더보드 재로드 → DiversityPolicy.update로 다음 epoch 다양성 결정, status 파일에 atomic write [근거: pyrosetta_flow/continuous.py:168-200].
  • 출력: status JSON(running·epochs_done·global_best·passing_count·diversity_level·top·history) + 종료 시 final 상태 [근거: pyrosetta_flow/continuous.py:190-220].

5-1. 수렴→다양성 탈출 (DiversityPolicy)

  • 코드 흐름: DiversityPolicy.update(global_best)는 best Δmargin이 개선되면 stale=0·level=0(base 복귀, 탐색 집중), patience(기본 3) epoch 정체하면 level↑로 변이 다양성을 단계 상승시킨다. 반환 max_random_mutations = min(6, 3+level) [근거: pyrosetta_flow/continuous.py:57-85].
  • 함의: 국소최적 탈출을 위한 적응적 변이 다양성 조절.

5-2. 라이브 운영 상태 (2026-06-18 시점)

  • 근거: [데이터: runs/pyrosetta_flow/discovery_status.json]
지표 근거
running true (가동중) discovery_status.json
epochs_done 110 discovery_status.json
passing_count 48 discovery_status.json
diversity_level 4 discovery_status.json
global_best_delta_margin 10.5351 discovery_status.json
  • history 관측: epoch 97에서 Δmargin 9.10→10.54 돌파(improved=true, diversity_level 0 리셋), 이후 정체 → diversity_level 점증(탈출 시도 작동 확인) [데이터: runs/pyrosetta_flow/discovery_status.json:history].

6. 다목적 스코어링 (surrogate 계층, multiobjective.py 코드 흐름)

코드 흐름 서술: 비용 계층화(cost-tiered) — Layer 0(서열만, 모든 후보, μs) surrogate와 Layer 1(top-K, 실제 도킹) 선택성을 분리한다 [근거: pyrosetta_flow/multiobjective.py:11-13].

  • cheap_objectives(sequence) (Layer 0): 서열 1개를 입력받아 ① 반감기 앙상블(ensemble_halflife, 휴리스틱 A + RF C 결합, native SST-14 ~16h 기준; 실패 시 휴리스틱 단독 fallback) ② ADMET-reasonableness(Instability<40·GRAVY<0·Boman·pI를 각각 0~1 부분점수로 변환 후 가중평균 0.35/0.30/0.15/0.20)를 산출한다. 모두 surrogate [근거: pyrosetta_flow/multiobjective.py:101-132,64-90,98].
  • multiobjective_scalar(cand): ddG·selectivity_margin·stability·admet를 각각 0~1로 정규화해 가중합한 UI 정렬 보조 스칼라(ddG는 (ddg_ref−ddg)/50, margin은 /20 포화) [근거: pyrosetta_flow/multiobjective.py:281-305].
  • 스코어 파이프라인: cheap → GNINA rescore → ECR consensus → NSGA-II Pareto → BO suggest(graceful skip) [근거: pyrosetta_flow/scoring_pipeline.py:79-100].
지표 유형 신뢰등급 근거
ddG 실측 FlexPepDock HIGH multiobjective.py:18
selectivity_margin 실측 off-target 도킹 HIGH selectivity_loop.py:1-8
Δmargin 계산(상대) MED global_leaderboard.py:8
half_life_h surrogate 앙상블 MED multiobjective.py:15-19
admet_score surrogate 물성 휴리스틱 LOW multiobjective.py:57-62

7. 핵심 모듈 file:line 요약

구성 경로 진입점 / 핵심 라인
무한 엔진 (epoch 루프) pyrosetta_flow/continuous.py run_continuous_discovery 87-223 · DiversityPolicy 57-85
단일 run 오케스트레이션 pyrosetta_flow/runner.py run_pyrosetta_agentic_mutdock_flow 294- · iteration 루프 508- · 변이 596-664 · 도킹 716-790 · QC 846-882 · fail-closed 721-732,757-767
변이 위치 게이트 pyrosetta_flow/runner.py _mutable_design_positions 132-139 · _preserves_scaffold 126-129
in-loop 선택성 게이트 pyrosetta_flow/selectivity_loop.py screen_iteration_candidates 76-144 · should_screen 48-56
글로벌 리더보드 pyrosetta_flow/global_leaderboard.py add_measurement 85-121 · count_passing 167-179 · I/O 52-82
선택성 연산 pyrosetta_flow/multiobjective.py screen_selectivity 361-458 · cheap_objectives 101-132 · multiobjective_scalar 281-305
도킹 실행(subprocess) pyrosetta_flow/docking_executor.py _run_script 38-75
스코어 파이프라인 pyrosetta_flow/scoring_pipeline.py 79-100
설정 스키마 pyrosetta_flow/schema.py 11-127
도킹 스크립트(refine+ddG+SS) AG_src/scripts/flexpep_dock.py run_flexpep_refine_pose 297-341 · compute_interface_ddg 394-406 · compute_clash_score 416-446
파마코포어 판정 backend/pharmacophore.py 15-19, 130-132

경로 기준: AgenticAI4SCIENCE_pyrosetta_track/repos/ai4sci-kaeri/. 산출 JSON: runs/pyrosetta_flow/. (P5: 최상위 pipelines/silo_b는 의도 구조이며 실제 활성 시스템은 본 경로.)