aiqcamp commited on
Commit
10f5f24
ยท
verified ยท
1 Parent(s): 1dab7bb

Create app-backup.pyy

Browse files
Files changed (1) hide show
  1. app-backup.pyy +1625 -0
app-backup.pyy ADDED
@@ -0,0 +1,1625 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os,sys
2
+ import traceback # ์ƒ๋‹จ์— ์ถ”๊ฐ€
3
+ # install required packages
4
+ os.system('pip install plotly') # plotly ์„ค์น˜
5
+ os.system('pip install matplotlib') # matplotlib ์„ค์น˜
6
+ os.system('pip install dgl==1.0.2+cu116 -f https://data.dgl.ai/wheels/cu116/repo.html')
7
+ os.environ["DGLBACKEND"] = "pytorch"
8
+ print('Modules installed')
9
+
10
+ # ๊ธฐ๋ณธ args ์„ค์ •
11
+ if not os.path.exists('./tmp'):
12
+ os.makedirs('./tmp')
13
+
14
+ if not os.path.exists('./tmp/args.json'):
15
+ default_args = {
16
+ 'checkpoint': None,
17
+ 'dump_trb': False,
18
+ 'dump_args': True,
19
+ 'save_best_plddt': True,
20
+ 'T': 25,
21
+ 'strand_bias': 0.0,
22
+ 'loop_bias': 0.0,
23
+ 'helix_bias': 0.0,
24
+ 'd_t1d': 24,
25
+ 'potentials': None,
26
+ 'potential_scale': None,
27
+ 'aa_composition': None
28
+ }
29
+ with open('./tmp/args.json', 'w') as f:
30
+ json.dump(default_args, f)
31
+
32
+ # ์ฒดํฌํฌ์ธํŠธ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
33
+ if not os.path.exists('./SEQDIFF_230205_dssp_hotspots_25mask_EQtasks_mod30.pt'):
34
+ print('Downloading model weights 1')
35
+ os.system('wget http://files.ipd.uw.edu/pub/sequence_diffusion/checkpoints/SEQDIFF_230205_dssp_hotspots_25mask_EQtasks_mod30.pt')
36
+ print('Successfully Downloaded')
37
+
38
+ if not os.path.exists('./SEQDIFF_221219_equalTASKS_nostrSELFCOND_mod30.pt'):
39
+ print('Downloading model weights 2')
40
+ os.system('wget http://files.ipd.uw.edu/pub/sequence_diffusion/checkpoints/SEQDIFF_221219_equalTASKS_nostrSELFCOND_mod30.pt')
41
+ print('Successfully Downloaded')
42
+
43
+ from openai import OpenAI
44
+ import gradio as gr
45
+ import json # json ๋ชจ๋“ˆ ์ถ”๊ฐ€
46
+ from datasets import load_dataset
47
+ import plotly.graph_objects as go
48
+ import numpy as np
49
+ import py3Dmol
50
+ from io import StringIO
51
+ import json
52
+ import secrets
53
+ import copy
54
+ import matplotlib.pyplot as plt
55
+ from utils.sampler import HuggingFace_sampler
56
+ from utils.parsers_inference import parse_pdb
57
+ from model.util import writepdb
58
+ from utils.inpainting_util import *
59
+ import os
60
+
61
+ # args ๋กœ๋“œ
62
+ with open('./tmp/args.json', 'r') as f:
63
+ args = json.load(f)
64
+
65
+ plt.rcParams.update({'font.size': 13})
66
+
67
+ # manually set checkpoint to load
68
+ args['checkpoint'] = None
69
+ args['dump_trb'] = False
70
+ args['dump_args'] = True
71
+ args['save_best_plddt'] = True
72
+ args['T'] = 25
73
+ args['strand_bias'] = 0.0
74
+ args['loop_bias'] = 0.0
75
+ args['helix_bias'] = 0.0
76
+
77
+ # Hugging Face ํ† ํฐ ์„ค์ •
78
+ ACCESS_TOKEN = os.getenv("HF_TOKEN")
79
+ if not ACCESS_TOKEN:
80
+ raise ValueError("HF_TOKEN not found in environment variables")
81
+
82
+ # OpenAI ํด๋ผ์ด์–ธํŠธ ์„ค์ • (Hugging Face ์—”๋“œํฌ์ธํŠธ ์‚ฌ์šฉ)
83
+ client = OpenAI(
84
+ base_url="https://api-inference.huggingface.co/v1/",
85
+ api_key=ACCESS_TOKEN,
86
+ )
87
+
88
+
89
+ # ๋ฐ์ดํ„ฐ์…‹ ๋กœ๋“œ ๋ฐ ๊ตฌ์กฐ ํ™•์ธ
90
+ try:
91
+ ds = load_dataset("lamm-mit/protein_secondary_structure_from_PDB",
92
+ token=ACCESS_TOKEN)
93
+ print("Dataset structure:", ds)
94
+ print("First entry example:", next(iter(ds['train'])))
95
+ except Exception as e:
96
+ print(f"Dataset loading error: {str(e)}")
97
+ raise
98
+
99
+ def respond(
100
+ message,
101
+ history,
102
+ system_message,
103
+ max_tokens,
104
+ temperature,
105
+ top_p,
106
+ ):
107
+ messages = [{"role": "system", "content": system_message}]
108
+
109
+ for msg in history:
110
+ messages.append({"role": "user", "content": msg[0]})
111
+ if msg[1]:
112
+ messages.append({"role": "assistant", "content": msg[1]})
113
+
114
+ messages.append({"role": "user", "content": message})
115
+
116
+ try:
117
+ response = ""
118
+ for chunk in client.chat.completions.create(
119
+ model="CohereForAI/c4ai-command-r-plus-08-2024",
120
+ max_tokens=max_tokens,
121
+ stream=True,
122
+ temperature=temperature,
123
+ top_p=top_p,
124
+ messages=messages,
125
+ ):
126
+ if hasattr(chunk.choices[0].delta, 'content'):
127
+ token = chunk.choices[0].delta.content
128
+ if token is not None:
129
+ response += token
130
+ yield [{"role": "user", "content": message},
131
+ {"role": "assistant", "content": response}]
132
+
133
+ return [{"role": "user", "content": message},
134
+ {"role": "assistant", "content": response}]
135
+ except Exception as e:
136
+ print(f"Error in respond: {str(e)}")
137
+ return [{"role": "user", "content": message},
138
+ {"role": "assistant", "content": f"์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(e)}"}]
139
+
140
+ def analyze_prompt(message):
141
+ """LLM์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กฌํ”„ํŠธ ๋ถ„์„"""
142
+ try:
143
+ analysis_prompt = f"""
144
+ ๋‹ค์Œ ์š”์ฒญ์„ ๋ถ„์„ํ•˜์—ฌ ๋‹จ๋ฐฑ์งˆ ์„ค๊ณ„์— ํ•„์š”ํ•œ ์ฃผ์š” ํŠน์„ฑ์„ ์ถ”์ถœํ•˜์„ธ์š”:
145
+ ์š”์ฒญ: {message}
146
+
147
+ ๋‹ค์Œ ํ•ญ๋ชฉ๋“ค์„ ๋ถ„์„ํ•ด์ฃผ์„ธ์š”:
148
+ 1. ์ฃผ์š” ๊ธฐ๋Šฅ (์˜ˆ: ์น˜๋ฃŒ, ๊ฒฐํ•ฉ, ์ด‰๋งค ๋“ฑ)
149
+ 2. ๋ชฉํ‘œ ํ™˜๊ฒฝ (์˜ˆ: ์„ธํฌ๋ง‰, ์ˆ˜์šฉ์„ฑ, ๋“ฑ)
150
+ 3. ํ•„์š”ํ•œ ๊ตฌ์กฐ์  ํŠน์ง•
151
+ 4. ํฌ๊ธฐ ๋ฐ ๋ณต์žก๋„ ์š”๊ตฌ์‚ฌํ•ญ
152
+ """
153
+
154
+ response = client.chat.completions.create(
155
+ model="CohereForAI/c4ai-command-r-plus-08-2024",
156
+ messages=[{"role": "user", "content": analysis_prompt}],
157
+ temperature=0.7
158
+ )
159
+
160
+ return response.choices[0].message.content
161
+ except Exception as e:
162
+ print(f"ํ”„๋กฌํ”„ํŠธ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜: {str(e)}")
163
+ return None
164
+
165
+ def search_protein_data(analysis, dataset):
166
+ """๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฐ์ดํ„ฐ์…‹์—์„œ ์œ ์‚ฌํ•œ ๊ตฌ์กฐ ๊ฒ€์ƒ‰"""
167
+ try:
168
+ # ํ‚ค์›Œ๋“œ ์ถ”์ถœ
169
+ keywords = extract_keywords(analysis)
170
+ print("Extracted keywords:", keywords)
171
+
172
+ # ๋ฐ์ดํ„ฐ์…‹ ๊ตฌ์กฐ ํ™•์ธ
173
+ if not dataset or 'train' not in dataset:
174
+ print("Invalid dataset structure")
175
+ return []
176
+
177
+ # ์œ ์‚ฌ๋„ ์ ์ˆ˜ ๊ณ„์‚ฐ
178
+ scored_entries = []
179
+ for entry in dataset['train']:
180
+ try:
181
+ score = calculate_similarity(keywords, entry)
182
+ scored_entries.append((score, entry))
183
+ except Exception as e:
184
+ print(f"Error processing entry: {str(e)}")
185
+ continue
186
+
187
+ # ๊ฒฐ๊ณผ ์ •๋ ฌ ๋ฐ ๋ฐ˜ํ™˜
188
+ scored_entries.sort(reverse=True)
189
+ return scored_entries[:3]
190
+
191
+ except Exception as e:
192
+ print(f"๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ ์ค‘ ์˜ค๋ฅ˜: {str(e)}")
193
+ return []
194
+
195
+ def extract_parameters(analysis, similar_structures):
196
+ """๋ถ„์„ ๊ฒฐ๊ณผ์™€ ์œ ์‚ฌ ๊ตฌ์กฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ƒ์„ฑ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฒฐ์ •"""
197
+ try:
198
+ # ๊ธฐ๋ณธ ํŒŒ๋ผ๋ฏธํ„ฐ ํ…œํ”Œ๋ฆฟ
199
+ params = {
200
+ 'sequence_length': 100,
201
+ 'helix_bias': 0.02,
202
+ 'strand_bias': 0.02,
203
+ 'loop_bias': 0.1,
204
+ 'hydrophobic_target_score': 0
205
+ }
206
+
207
+ # ๋ถ„์„ ๊ฒฐ๊ณผ์—์„œ ๊ตฌ์กฐ์  ์š”๊ตฌ์‚ฌํ•ญ ํŒŒ์•…
208
+ if "๋ง‰ ํˆฌ๊ณผ" in analysis or "์†Œ์ˆ˜์„ฑ" in analysis:
209
+ params['hydrophobic_target_score'] = -2
210
+ params['helix_bias'] = 0.03
211
+ elif "์ˆ˜์šฉ์„ฑ" in analysis or "๊ฐ€์šฉ์„ฑ" in analysis:
212
+ params['hydrophobic_target_score'] = 2
213
+ params['loop_bias'] = 0.15
214
+
215
+ # ์œ ์‚ฌ ๊ตฌ์กฐ๋“ค์˜ ํŠน์„ฑ ๋ฐ˜์˜
216
+ if similar_structures:
217
+ avg_length = sum(len(s[1]['sequence']) for s in similar_structures) / len(similar_structures)
218
+ params['sequence_length'] = int(avg_length)
219
+
220
+ # ๊ตฌ์กฐ์  ํŠน์„ฑ ๋ถ„์„ ๋ฐ ๋ฐ˜์˜
221
+ for _, structure in similar_structures:
222
+ if 'secondary_structure' in structure:
223
+ helix_ratio = structure['secondary_structure'].count('H') / len(structure['secondary_structure'])
224
+ sheet_ratio = structure['secondary_structure'].count('E') / len(structure['secondary_structure'])
225
+ params['helix_bias'] = max(0.01, min(0.05, helix_ratio))
226
+ params['strand_bias'] = max(0.01, min(0.05, sheet_ratio))
227
+
228
+ return params
229
+ except Exception as e:
230
+ print(f"ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”์ถœ ์ค‘ ์˜ค๋ฅ˜: {str(e)}")
231
+ return None
232
+
233
+ def process_chat(message, history):
234
+ try:
235
+ if any(keyword in message.lower() for keyword in ['protein', 'generate', '๋‹จ๋ฐฑ์งˆ', '์ƒ์„ฑ', '์น˜๋ฃŒ']):
236
+ # 1. LLM์„ ์‚ฌ์šฉํ•œ ํ”„๋กฌํ”„ํŠธ ๋ถ„์„
237
+ analysis = analyze_prompt(message)
238
+ if not analysis:
239
+ return history + [
240
+ {"role": "user", "content": message},
241
+ {"role": "assistant", "content": "์š”์ฒญ ๋ถ„์„์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."}
242
+ ]
243
+
244
+ # 2. ์œ ์‚ฌ ๊ตฌ์กฐ ๊ฒ€์ƒ‰
245
+ similar_structures = search_protein_data(analysis, ds)
246
+ if not similar_structures:
247
+ return history + [
248
+ {"role": "user", "content": message},
249
+ {"role": "assistant", "content": "์ ํ•ฉํ•œ ์ฐธ์กฐ ๊ตฌ์กฐ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค."}
250
+ ]
251
+
252
+ # 3. ์ƒ์„ฑ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฒฐ์ •
253
+ params = extract_parameters(analysis, similar_structures)
254
+ if not params:
255
+ return history + [
256
+ {"role": "user", "content": message},
257
+ {"role": "assistant", "content": "ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ •์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."}
258
+ ]
259
+
260
+ # 4. ๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ
261
+ try:
262
+ protein_result = protein_diffusion_model(
263
+ sequence=None,
264
+ seq_len=params['sequence_length'],
265
+ helix_bias=params['helix_bias'],
266
+ strand_bias=params['strand_bias'],
267
+ loop_bias=params['loop_bias'],
268
+ secondary_structure=None,
269
+ aa_bias=None,
270
+ aa_bias_potential=None,
271
+ num_steps="25",
272
+ noise="normal",
273
+ hydrophobic_target_score=str(params['hydrophobic_target_score']),
274
+ hydrophobic_potential="2",
275
+ contigs=None,
276
+ pssm=None,
277
+ seq_mask=None,
278
+ str_mask=None,
279
+ rewrite_pdb=None
280
+ )
281
+
282
+ output_seq, output_pdb, structure_view, plddt_plot = next(protein_result)
283
+
284
+ # 5. ๊ฒฐ๊ณผ ์„ค๋ช… ์ƒ์„ฑ
285
+ explanation = f"""
286
+ ์š”์ฒญํ•˜์‹  ๊ธฐ๋Šฅ์— ๋งž๋Š” ๋‹จ๋ฐฑ์งˆ์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค:
287
+
288
+ ๋ถ„์„๋œ ์š”๊ตฌ์‚ฌํ•ญ:
289
+ {analysis}
290
+
291
+ ์„ค๊ณ„๋œ ๊ตฌ์กฐ์  ํŠน์ง•:
292
+ - ๊ธธ์ด: {params['sequence_length']} ์•„๋ฏธ๋…ธ์‚ฐ
293
+ - ์•ŒํŒŒ ํ—ฌ๋ฆญ์Šค ๋น„์œจ: {params['helix_bias']*100:.1f}%
294
+ - ๋ฒ ํƒ€ ์‹œํŠธ ๋น„์œจ: {params['strand_bias']*100:.1f}%
295
+ - ๋ฃจํ”„ ๊ตฌ์กฐ ๋น„์œจ: {params['loop_bias']*100:.1f}%
296
+ - ์†Œ์ˆ˜์„ฑ ์ ์ˆ˜: {params['hydrophobic_target_score']}
297
+
298
+ ์ฐธ์กฐ๋œ ์œ ์‚ฌ ๊ตฌ์กฐ: {len(similar_structures)}๊ฐœ
299
+
300
+ ์ƒ์„ฑ๋œ ๋‹จ๋ฐฑ์งˆ์˜ 3D ๊ตฌ์กฐ์™€ ์‹œํ€€์Šค๋ฅผ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
301
+ """
302
+
303
+ # 6. ๊ฒฐ๊ณผ ์ €์žฅ
304
+ global current_protein_result
305
+ current_protein_result = {
306
+ 'sequence': output_seq,
307
+ 'pdb': output_pdb,
308
+ 'structure_view': structure_view,
309
+ 'plddt_plot': plddt_plot,
310
+ 'params': params
311
+ }
312
+
313
+ return history + [
314
+ {"role": "user", "content": message},
315
+ {"role": "assistant", "content": explanation}
316
+ ]
317
+
318
+ except Exception as e:
319
+ return history + [
320
+ {"role": "user", "content": message},
321
+ {"role": "assistant", "content": f"๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(e)}"}
322
+ ]
323
+ else:
324
+ return history + [
325
+ {"role": "user", "content": message},
326
+ {"role": "assistant", "content": "๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ ๊ด€๋ จ ํ‚ค์›Œ๋“œ๋ฅผ ํฌํ•จํ•ด์ฃผ์„ธ์š”."}
327
+ ]
328
+ except Exception as e:
329
+ return history + [
330
+ {"role": "user", "content": message},
331
+ {"role": "assistant", "content": f"์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(e)}"}
332
+ ]
333
+
334
+
335
+ def generate_protein(params):
336
+ # ๊ธฐ์กด protein_diffusion_model ํ•จ์ˆ˜ ํ˜ธ์ถœ
337
+ result = protein_diffusion_model(
338
+ sequence=None,
339
+ seq_len=params['sequence_length'],
340
+ helix_bias=params['helix_bias'],
341
+ strand_bias=params['strand_bias'],
342
+ loop_bias=params['loop_bias'],
343
+ secondary_structure=None,
344
+ aa_bias=None,
345
+ aa_bias_potential=None,
346
+ num_steps="25",
347
+ noise="normal",
348
+ hydrophobic_target_score=str(params['hydrophobic_target_score']),
349
+ hydrophobic_potential="2",
350
+ contigs=None,
351
+ pssm=None,
352
+ seq_mask=None,
353
+ str_mask=None,
354
+ rewrite_pdb=None
355
+ )
356
+ return result
357
+
358
+ def generate_explanation(result, params):
359
+ explanation = f"""
360
+ ์ƒ์„ฑ๋œ ๋‹จ๋ฐฑ์งˆ ๋ถ„์„:
361
+ - ๊ธธ์ด: {params['sequence_length']} ์•„๋ฏธ๋…ธ์‚ฐ
362
+ - ๊ตฌ์กฐ์  ํŠน์ง•:
363
+ * ์•ŒํŒŒ ๋‚˜์„  ๋น„์œจ: {params['helix_bias']*100}%
364
+ * ๋ฒ ํƒ€ ์‹œํŠธ ๋น„์œจ: {params['strand_bias']*100}%
365
+ * ๋ฃจํ”„ ๊ตฌ์กฐ ๋น„์œจ: {params['loop_bias']*100}%
366
+ - ํŠน์ˆ˜ ๊ธฐ๋Šฅ: {result.get('special_features', '์—†์Œ')}
367
+ """
368
+ return explanation
369
+
370
+ # ์ฒดํฌํฌ์ธํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋กœ ์ˆ˜์ •
371
+ def protein_diffusion_model(sequence, seq_len, helix_bias, strand_bias, loop_bias,
372
+ secondary_structure, aa_bias, aa_bias_potential,
373
+ num_steps, noise, hydrophobic_target_score, hydrophobic_potential,
374
+ contigs, pssm, seq_mask, str_mask, rewrite_pdb):
375
+
376
+
377
+ dssp_checkpoint = './SEQDIFF_230205_dssp_hotspots_25mask_EQtasks_mod30.pt'
378
+ og_checkpoint = './SEQDIFF_221219_equalTASKS_nostrSELFCOND_mod30.pt'
379
+
380
+
381
+ # ์ฒดํฌํฌ์ธํŠธ ํŒŒ์ผ ์กด์žฌ ํ™•์ธ
382
+ if not os.path.exists(dssp_checkpoint):
383
+ raise FileNotFoundError(f"DSSP checkpoint file not found at: {dssp_checkpoint}")
384
+ if not os.path.exists(og_checkpoint):
385
+ raise FileNotFoundError(f"OG checkpoint file not found at: {og_checkpoint}")
386
+
387
+ model_args = copy.deepcopy(args)
388
+
389
+
390
+ # make sampler
391
+ S = HuggingFace_sampler(args=model_args)
392
+
393
+ # get random prefix
394
+ S.out_prefix = './tmp/'+secrets.token_hex(nbytes=10).upper()
395
+
396
+ # set args
397
+ S.args['checkpoint'] = None
398
+ S.args['dump_trb'] = False
399
+ S.args['dump_args'] = True
400
+ S.args['save_best_plddt'] = True
401
+ S.args['T'] = 25
402
+ S.args['strand_bias'] = 0.0
403
+ S.args['loop_bias'] = 0.0
404
+ S.args['helix_bias'] = 0.0
405
+ S.args['potentials'] = None
406
+ S.args['potential_scale'] = None
407
+ S.args['aa_composition'] = None
408
+
409
+
410
+ # get sequence if entered and make sure all chars are valid
411
+ alt_aa_dict = {'B':['D','N'],'J':['I','L'],'U':['C'],'Z':['E','Q'],'O':['K']}
412
+ if sequence not in ['',None]:
413
+ L = len(sequence)
414
+ aa_seq = []
415
+ for aa in sequence.upper():
416
+ if aa in alt_aa_dict.keys():
417
+ aa_seq.append(np.random.choice(alt_aa_dict[aa]))
418
+ else:
419
+ aa_seq.append(aa)
420
+
421
+ S.args['sequence'] = aa_seq
422
+ elif contigs not in ['',None]:
423
+ S.args['contigs'] = [contigs]
424
+ else:
425
+ S.args['contigs'] = [f'{seq_len}']
426
+ L = int(seq_len)
427
+
428
+ print('DEBUG: ',rewrite_pdb)
429
+ if rewrite_pdb not in ['',None]:
430
+ S.args['pdb'] = rewrite_pdb.name
431
+
432
+ if seq_mask not in ['',None]:
433
+ S.args['inpaint_seq'] = [seq_mask]
434
+ if str_mask not in ['',None]:
435
+ S.args['inpaint_str'] = [str_mask]
436
+
437
+ if secondary_structure in ['',None]:
438
+ secondary_structure = None
439
+ else:
440
+ secondary_structure = ''.join(['E' if x == 'S' else x for x in secondary_structure])
441
+ if L < len(secondary_structure):
442
+ secondary_structure = secondary_structure[:len(sequence)]
443
+ elif L == len(secondary_structure):
444
+ pass
445
+ else:
446
+ dseq = L - len(secondary_structure)
447
+ secondary_structure += secondary_structure[-1]*dseq
448
+
449
+
450
+ # potentials
451
+ potential_list = []
452
+ potential_bias_list = []
453
+
454
+ if aa_bias not in ['',None]:
455
+ potential_list.append('aa_bias')
456
+ S.args['aa_composition'] = aa_bias
457
+ if aa_bias_potential in ['',None]:
458
+ aa_bias_potential = 3
459
+ potential_bias_list.append(str(aa_bias_potential))
460
+ '''
461
+ if target_charge not in ['',None]:
462
+ potential_list.append('charge')
463
+ if charge_potential in ['',None]:
464
+ charge_potential = 1
465
+ potential_bias_list.append(str(charge_potential))
466
+ S.args['target_charge'] = float(target_charge)
467
+ if target_ph in ['',None]:
468
+ target_ph = 7.4
469
+ S.args['target_pH'] = float(target_ph)
470
+ '''
471
+
472
+ if hydrophobic_target_score not in ['',None]:
473
+ potential_list.append('hydrophobic')
474
+ S.args['hydrophobic_score'] = float(hydrophobic_target_score)
475
+ if hydrophobic_potential in ['',None]:
476
+ hydrophobic_potential = 3
477
+ potential_bias_list.append(str(hydrophobic_potential))
478
+
479
+ if pssm not in ['',None]:
480
+ potential_list.append('PSSM')
481
+ potential_bias_list.append('5')
482
+ S.args['PSSM'] = pssm.name
483
+
484
+
485
+ if len(potential_list) > 0:
486
+ S.args['potentials'] = ','.join(potential_list)
487
+ S.args['potential_scale'] = ','.join(potential_bias_list)
488
+
489
+
490
+ # normalise secondary_structure bias from range 0-0.3
491
+ S.args['secondary_structure'] = secondary_structure
492
+ S.args['helix_bias'] = helix_bias
493
+ S.args['strand_bias'] = strand_bias
494
+ S.args['loop_bias'] = loop_bias
495
+
496
+ # set T
497
+ if num_steps in ['',None]:
498
+ S.args['T'] = 20
499
+ else:
500
+ S.args['T'] = int(num_steps)
501
+
502
+ # noise
503
+ if 'normal' in noise:
504
+ S.args['sample_distribution'] = noise
505
+ S.args['sample_distribution_gmm_means'] = [0]
506
+ S.args['sample_distribution_gmm_variances'] = [1]
507
+ elif 'gmm2' in noise:
508
+ S.args['sample_distribution'] = noise
509
+ S.args['sample_distribution_gmm_means'] = [-1,1]
510
+ S.args['sample_distribution_gmm_variances'] = [1,1]
511
+ elif 'gmm3' in noise:
512
+ S.args['sample_distribution'] = noise
513
+ S.args['sample_distribution_gmm_means'] = [-1,0,1]
514
+ S.args['sample_distribution_gmm_variances'] = [1,1,1]
515
+
516
+
517
+
518
+ if secondary_structure not in ['',None] or helix_bias+strand_bias+loop_bias > 0:
519
+ S.args['checkpoint'] = dssp_checkpoint
520
+ S.args['d_t1d'] = 29
521
+ print('using dssp checkpoint')
522
+ else:
523
+ S.args['checkpoint'] = og_checkpoint
524
+ S.args['d_t1d'] = 24
525
+ print('using og checkpoint')
526
+
527
+
528
+ for k,v in S.args.items():
529
+ print(f"{k} --> {v}")
530
+
531
+ # init S
532
+ S.model_init()
533
+ S.diffuser_init()
534
+ S.setup()
535
+
536
+ # sampling loop
537
+ plddt_data = []
538
+ for j in range(S.max_t):
539
+ print(f'on step {j}')
540
+ output_seq, output_pdb, plddt = S.take_step_get_outputs(j)
541
+ plddt_data.append(plddt)
542
+ yield output_seq, output_pdb, display_pdb(output_pdb), get_plddt_plot(plddt_data, S.max_t)
543
+
544
+ output_seq, output_pdb, plddt = S.get_outputs()
545
+
546
+ return output_seq, output_pdb, display_pdb(output_pdb), get_plddt_plot(plddt_data, S.max_t)
547
+
548
+ def get_plddt_plot(plddt_data, max_t):
549
+ fig, ax = plt.subplots(figsize=(15,6))
550
+ x = list(range(1, len(plddt_data) + 1))
551
+ ax.plot(x, plddt_data, color='#661dbf', linewidth=3, marker='o')
552
+ ax.set_xticks(range(1, max_t + 1))
553
+ ax.set_yticks([i/10 for i in range(11)]) # 0๋ถ€ํ„ฐ 1๊นŒ์ง€
554
+ ax.set_ylim([0, 1])
555
+ ax.set_ylabel('model confidence (plddt)')
556
+ ax.set_xlabel('diffusion steps (t)')
557
+ plt.close() # ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ๋‹ซ๊ธฐ
558
+ return fig
559
+
560
+
561
+ def display_pdb(path_to_pdb):
562
+ '''
563
+ #function to display pdb in py3dmol
564
+ '''
565
+ pdb = open(path_to_pdb, "r").read()
566
+
567
+ view = py3Dmol.view(width=500, height=500)
568
+ view.addModel(pdb, "pdb")
569
+ view.setStyle({'model': -1}, {"cartoon": {'colorscheme':{'prop':'b','gradient':'roygb','min':0,'max':1}}})#'linear', 'min': 0, 'max': 1, 'colors': ["#ff9ef0","#a903fc",]}}})
570
+ view.zoomTo()
571
+ output = view._make_html().replace("'", '"')
572
+ print(view._make_html())
573
+ x = f"""<!DOCTYPE html><html></center> {output} </center></html>""" # do not use ' in this input
574
+
575
+ return f"""<iframe height="500px" width="100%" name="result" allow="midi; geolocation; microphone; camera;
576
+ display-capture; encrypted-media;" sandbox="allow-modals allow-forms
577
+ allow-scripts allow-same-origin allow-popups
578
+ allow-top-navigation-by-user-activation allow-downloads" allowfullscreen=""
579
+ allowpaymentrequest="" frameborder="0" srcdoc='{x}'></iframe>"""
580
+
581
+ '''
582
+ return f"""<iframe style="width: 100%; height:700px" name="result" allow="midi; geolocation; microphone; camera;
583
+ display-capture; encrypted-media;" sandbox="allow-modals allow-forms
584
+ allow-scripts allow-same-origin allow-popups
585
+ allow-top-navigation-by-user-activation allow-downloads" allowfullscreen=""
586
+ allowpaymentrequest="" frameborder="0" srcdoc='{x}'></iframe>"""
587
+ '''
588
+
589
+ def get_motif_preview(pdb_id, contigs):
590
+ try:
591
+ input_pdb = fetch_pdb(pdb_id=pdb_id.lower() if pdb_id else None)
592
+ if input_pdb is None:
593
+ return gr.HTML("PDB ID๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"), None
594
+
595
+ parse = parse_pdb(input_pdb)
596
+ output_name = input_pdb
597
+
598
+ pdb = open(output_name, "r").read()
599
+ view = py3Dmol.view(width=500, height=500)
600
+ view.addModel(pdb, "pdb")
601
+
602
+ if contigs in ['',0]:
603
+ contigs = ['0']
604
+ else:
605
+ contigs = [contigs]
606
+
607
+ print('DEBUG: ',contigs)
608
+
609
+ pdb_map = get_mappings(ContigMap(parse,contigs))
610
+ print('DEBUG: ',pdb_map)
611
+ print('DEBUG: ',pdb_map['con_ref_idx0'])
612
+ roi = [x[1]-1 for x in pdb_map['con_ref_pdb_idx']]
613
+
614
+ colormap = {0:'#D3D3D3', 1:'#F74CFF'}
615
+ colors = {i+1: colormap[1] if i in roi else colormap[0] for i in range(parse['xyz'].shape[0])}
616
+ view.setStyle({"cartoon": {"colorscheme": {"prop": "resi", "map": colors}}})
617
+ view.zoomTo()
618
+ output = view._make_html().replace("'", '"')
619
+ print(view._make_html())
620
+ x = f"""<!DOCTYPE html><html></center> {output} </center></html>""" # do not use ' in this input
621
+
622
+ return f"""<iframe height="500px" width="100%" name="result" allow="midi; geolocation; microphone; camera;
623
+ display-capture; encrypted-media;" sandbox="allow-modals allow-forms
624
+ allow-scripts allow-same-origin allow-popups
625
+ allow-top-navigation-by-user-activation allow-downloads" allowfullscreen=""
626
+ allowpaymentrequest="" frameborder="0" srcdoc='{x}'></iframe>""", output_name
627
+
628
+ except Exception as e:
629
+ return gr.HTML(f"์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(e)}"), None
630
+
631
+ def fetch_pdb(pdb_id=None):
632
+ if pdb_id is None or pdb_id == "":
633
+ return None
634
+ else:
635
+ os.system(f"wget -qnc https://files.rcsb.org/view/{pdb_id}.pdb")
636
+ return f"{pdb_id}.pdb"
637
+
638
+ # MSA AND PSSM GUIDANCE
639
+ def save_pssm(file_upload):
640
+ filename = file_upload.name
641
+ orig_name = file_upload.orig_name
642
+ if filename.split('.')[-1] in ['fasta', 'a3m']:
643
+ return msa_to_pssm(file_upload)
644
+ return filename
645
+
646
+ def msa_to_pssm(msa_file):
647
+ # Define the lookup table for converting amino acids to indices
648
+ aa_to_index = {'A': 0, 'R': 1, 'N': 2, 'D': 3, 'C': 4, 'Q': 5, 'E': 6, 'G': 7, 'H': 8, 'I': 9, 'L': 10,
649
+ 'K': 11, 'M': 12, 'F': 13, 'P': 14, 'S': 15, 'T': 16, 'W': 17, 'Y': 18, 'V': 19, 'X': 20, '-': 21}
650
+ # Open the FASTA file and read the sequences
651
+ records = list(SeqIO.parse(msa_file.name, "fasta"))
652
+
653
+ assert len(records) >= 1, "MSA must contain more than one protein sequecne."
654
+
655
+ first_seq = str(records[0].seq)
656
+ aligned_seqs = [first_seq]
657
+ # print(aligned_seqs)
658
+ # Perform sequence alignment using the Needleman-Wunsch algorithm
659
+ aligner = Align.PairwiseAligner()
660
+ aligner.open_gap_score = -0.7
661
+ aligner.extend_gap_score = -0.3
662
+ for record in records[1:]:
663
+ alignment = aligner.align(first_seq, str(record.seq))[0]
664
+ alignment = alignment.format().split("\n")
665
+ al1 = alignment[0]
666
+ al2 = alignment[2]
667
+ al1_fin = ""
668
+ al2_fin = ""
669
+ percent_gap = al2.count('-')/ len(al2)
670
+ if percent_gap > 0.4:
671
+ continue
672
+ for i in range(len(al1)):
673
+ if al1[i] != '-':
674
+ al1_fin += al1[i]
675
+ al2_fin += al2[i]
676
+ aligned_seqs.append(str(al2_fin))
677
+ # Get the length of the aligned sequences
678
+ aligned_seq_length = len(first_seq)
679
+ # Initialize the position scoring matrix
680
+ matrix = np.zeros((22, aligned_seq_length))
681
+ # Iterate through the aligned sequences and count the amino acids at each position
682
+ for seq in aligned_seqs:
683
+ #print(seq)
684
+ for i in range(aligned_seq_length):
685
+ if i == len(seq):
686
+ break
687
+ amino_acid = seq[i]
688
+ if amino_acid.upper() not in aa_to_index.keys():
689
+ continue
690
+ else:
691
+ aa_index = aa_to_index[amino_acid.upper()]
692
+ matrix[aa_index, i] += 1
693
+ # Normalize the counts to get the frequency of each amino acid at each position
694
+ matrix /= len(aligned_seqs)
695
+ print(len(aligned_seqs))
696
+ matrix[20:,]=0
697
+
698
+ outdir = ".".join(msa_file.name.split('.')[:-1]) + ".csv"
699
+ np.savetxt(outdir, matrix[:21,:].T, delimiter=",")
700
+ return outdir
701
+
702
+ def get_pssm(fasta_msa, input_pssm):
703
+ try:
704
+ if input_pssm is not None:
705
+ outdir = input_pssm.name
706
+ elif fasta_msa is not None:
707
+ outdir = save_pssm(fasta_msa)
708
+ else:
709
+ return gr.Plot(label="ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”"), None
710
+
711
+ pssm = np.loadtxt(outdir, delimiter=",", dtype=float)
712
+ fig, ax = plt.subplots(figsize=(15,6))
713
+ plt.imshow(torch.permute(torch.tensor(pssm),(1,0)))
714
+ return fig, outdir
715
+ except Exception as e:
716
+ return gr.Plot(label=f"์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(e)}"), None
717
+
718
+ # ํžˆ์–ด๋กœ ๋Šฅ๋ ฅ์น˜ ๊ณ„์‚ฐ ํ•จ์ˆ˜ ์ถ”๊ฐ€
719
+ def calculate_hero_stats(helix_bias, strand_bias, loop_bias, hydrophobic_score):
720
+ stats = {
721
+ 'strength': strand_bias * 20, # ๋ฒ ํƒ€์‹œํŠธ ๊ตฌ์กฐ ๊ธฐ๋ฐ˜
722
+ 'flexibility': helix_bias * 20, # ์•ŒํŒŒํ—ฌ๋ฆญ์Šค ๊ตฌ์กฐ ๊ธฐ๋ฐ˜
723
+ 'speed': loop_bias * 5, # ๋ฃจํ”„ ๊ตฌ์กฐ ๊ธฐ๋ฐ˜
724
+ 'defense': abs(hydrophobic_score) if hydrophobic_score else 0
725
+ }
726
+ return stats
727
+
728
+ def toggle_seq_input(choice):
729
+ if choice == "์ž๋™ ์„ค๊ณ„":
730
+ return gr.update(visible=True), gr.update(visible=False)
731
+ else: # "์ง์ ‘ ์ž…๋ ฅ"
732
+ return gr.update(visible=False), gr.update(visible=True)
733
+
734
+ def toggle_secondary_structure(choice):
735
+ if choice == "์Šฌ๋ผ์ด๋”๋กœ ์„ค์ •":
736
+ return (
737
+ gr.update(visible=True), # helix_bias
738
+ gr.update(visible=True), # strand_bias
739
+ gr.update(visible=True), # loop_bias
740
+ gr.update(visible=False) # secondary_structure
741
+ )
742
+ else: # "์ง์ ‘ ์ž…๋ ฅ"
743
+ return (
744
+ gr.update(visible=False), # helix_bias
745
+ gr.update(visible=False), # strand_bias
746
+ gr.update(visible=False), # loop_bias
747
+ gr.update(visible=True) # secondary_structure
748
+ )
749
+
750
+
751
+ def create_radar_chart(stats):
752
+ # ๋ ˆ์ด๋” ์ฐจํŠธ ์ƒ์„ฑ ๋กœ์ง
753
+ categories = list(stats.keys())
754
+ values = list(stats.values())
755
+
756
+ fig = go.Figure(data=go.Scatterpolar(
757
+ r=values,
758
+ theta=categories,
759
+ fill='toself'
760
+ ))
761
+
762
+ fig.update_layout(
763
+ polar=dict(
764
+ radialaxis=dict(
765
+ visible=True,
766
+ range=[0, 1]
767
+ )),
768
+ showlegend=False
769
+ )
770
+
771
+ return fig
772
+
773
+ def generate_hero_description(name, stats, abilities):
774
+ # ํžˆ์–ด๋กœ ์„ค๋ช… ์ƒ์„ฑ ๋กœ์ง
775
+ description = f"""
776
+ ํžˆ์–ด๋กœ ์ด๋ฆ„: {name}
777
+
778
+ ์ฃผ์š” ๋Šฅ๋ ฅ:
779
+ - ๊ทผ๋ ฅ: {'โ˜…' * int(stats['strength'] * 5)}
780
+ - ์œ ์—ฐ์„ฑ: {'โ˜…' * int(stats['flexibility'] * 5)}
781
+ - ์Šคํ”ผ๋“œ: {'โ˜…' * int(stats['speed'] * 5)}
782
+ - ๋ฐฉ์–ด๋ ฅ: {'โ˜…' * int(stats['defense'] * 5)}
783
+
784
+ ํŠน์ˆ˜ ๋Šฅ๋ ฅ: {', '.join(abilities)}
785
+ """
786
+ return description
787
+
788
+ def combined_generation(name, strength, flexibility, speed, defense, size, abilities,
789
+ sequence, seq_len, helix_bias, strand_bias, loop_bias,
790
+ secondary_structure, aa_bias, aa_bias_potential,
791
+ num_steps, noise, hydrophobic_target_score, hydrophobic_potential,
792
+ contigs, pssm, seq_mask, str_mask, rewrite_pdb):
793
+ try:
794
+ # protein_diffusion_model ์‹คํ–‰
795
+ generator = protein_diffusion_model(
796
+ sequence=None,
797
+ seq_len=size, # ํžˆ์–ด๋กœ ํฌ๊ธฐ๋ฅผ seq_len์œผ๋กœ ์‚ฌ์šฉ
798
+ helix_bias=flexibility, # ํžˆ์–ด๋กœ ์œ ์—ฐ์„ฑ์„ helix_bias๋กœ ์‚ฌ์šฉ
799
+ strand_bias=strength, # ํžˆ์–ด๋กœ ๊ฐ•๋„๋ฅผ strand_bias๋กœ ์‚ฌ์šฉ
800
+ loop_bias=speed, # ํžˆ์–ด๋กœ ์Šคํ”ผ๋“œ๋ฅผ loop_bias๋กœ ์‚ฌ์šฉ
801
+ secondary_structure=None,
802
+ aa_bias=None,
803
+ aa_bias_potential=None,
804
+ num_steps="25",
805
+ noise="normal",
806
+ hydrophobic_target_score=str(-defense), # ํžˆ์–ด๋กœ ๋ฐฉ์–ด๋ ฅ์„ hydrophobic score๋กœ ์‚ฌ์šฉ
807
+ hydrophobic_potential="2",
808
+ contigs=None,
809
+ pssm=None,
810
+ seq_mask=None,
811
+ str_mask=None,
812
+ rewrite_pdb=None
813
+ )
814
+
815
+ # ๋งˆ์ง€๋ง‰ ๊ฒฐ๊ณผ ๊ฐ€์ ธ์˜ค๊ธฐ
816
+ final_result = None
817
+ for result in generator:
818
+ final_result = result
819
+
820
+ if final_result is None:
821
+ raise Exception("์ƒ์„ฑ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค")
822
+
823
+ output_seq, output_pdb, structure_view, plddt_plot = final_result
824
+
825
+ # ํžˆ์–ด๋กœ ๋Šฅ๋ ฅ์น˜ ๊ณ„์‚ฐ
826
+ stats = calculate_hero_stats(flexibility, strength, speed, defense)
827
+
828
+ # ๋ชจ๋“  ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
829
+ return (
830
+ create_radar_chart(stats), # ๋Šฅ๋ ฅ์น˜ ์ฐจํŠธ
831
+ generate_hero_description(name, stats, abilities), # ํžˆ์–ด๋กœ ์„ค๋ช…
832
+ output_seq, # ๋‹จ๋ฐฑ์งˆ ์„œ์—ด
833
+ output_pdb, # PDB ํŒŒ์ผ
834
+ structure_view, # 3D ๊ตฌ์กฐ
835
+ plddt_plot # ์‹ ๋ขฐ๋„ ์ฐจํŠธ
836
+ )
837
+ except Exception as e:
838
+ print(f"Error in combined_generation: {str(e)}")
839
+ return (
840
+ None,
841
+ f"์—๋Ÿฌ: {str(e)}",
842
+ None,
843
+ None,
844
+ gr.HTML("์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค"),
845
+ None
846
+ )
847
+
848
+
849
+ def extract_parameters_from_chat(chat_response):
850
+ """์ฑ—๋ด‡ ์‘๋‹ต์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”์ถœ"""
851
+ try:
852
+ params = {
853
+ 'sequence_length': 100,
854
+ 'helix_bias': 0.02,
855
+ 'strand_bias': 0.02,
856
+ 'loop_bias': 0.1,
857
+ 'hydrophobic_target_score': 0
858
+ }
859
+
860
+ # ์‘๋‹ต ํ…์ŠคํŠธ์—์„œ ๊ฐ’ ์ถ”์ถœ
861
+ if "๊ธธ์ด:" in chat_response:
862
+ length_match = re.search(r'๊ธธ์ด: (\d+)', chat_response)
863
+ if length_match:
864
+ params['sequence_length'] = int(length_match.group(1))
865
+
866
+ if "์•ŒํŒŒ ํ—ฌ๋ฆญ์Šค ๋น„์œจ:" in chat_response:
867
+ helix_match = re.search(r'์•ŒํŒŒ ํ—ฌ๋ฆญ์Šค ๋น„์œจ: ([\d.]+)', chat_response)
868
+ if helix_match:
869
+ params['helix_bias'] = float(helix_match.group(1)) / 100
870
+
871
+ if "๋ฒ ํƒ€ ์‹œํŠธ ๋น„์œจ:" in chat_response:
872
+ strand_match = re.search(r'๋ฒ ํƒ€ ์‹œํŠธ ๋น„์œจ: ([\d.]+)', chat_response)
873
+ if strand_match:
874
+ params['strand_bias'] = float(strand_match.group(1)) / 100
875
+
876
+ if "๋ฃจํ”„ ๊ตฌ์กฐ ๋น„์œจ:" in chat_response:
877
+ loop_match = re.search(r'๋ฃจํ”„ ๊ตฌ์กฐ ๋น„์œจ: ([\d.]+)', chat_response)
878
+ if loop_match:
879
+ params['loop_bias'] = float(loop_match.group(1)) / 100
880
+
881
+ if "์†Œ์ˆ˜์„ฑ ์ ์ˆ˜:" in chat_response:
882
+ hydro_match = re.search(r'์†Œ์ˆ˜์„ฑ ์ ์ˆ˜: ([-\d.]+)', chat_response)
883
+ if hydro_match:
884
+ params['hydrophobic_target_score'] = float(hydro_match.group(1))
885
+
886
+ return params
887
+ except Exception as e:
888
+ print(f"ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”์ถœ ์ค‘ ์˜ค๋ฅ˜: {str(e)}")
889
+ return None
890
+
891
+ def update_protein_display(chat_response):
892
+ if "์ƒ์„ฑ๋œ ๋‹จ๋ฐฑ์งˆ ๋ถ„์„" in chat_response:
893
+ params = extract_parameters_from_chat(chat_response)
894
+ if params:
895
+ result = generate_protein(params)
896
+ stats = calculate_hero_stats(
897
+ helix_bias=params['helix_bias'],
898
+ strand_bias=params['strand_bias'],
899
+ loop_bias=params['loop_bias'],
900
+ hydrophobic_score=params['hydrophobic_target_score']
901
+ )
902
+ return {
903
+ hero_stats: create_radar_chart(stats),
904
+ hero_description: chat_response,
905
+ output_seq: result[0],
906
+ output_pdb: result[1],
907
+ output_viewer: display_pdb(result[1]),
908
+ plddt_plot: result[3]
909
+ }
910
+ return None
911
+
912
+ def analyze_active_sites(sequence):
913
+ """ํ™œ์„ฑ ๋ถ€์œ„ ๋ถ„์„"""
914
+ return "๋ถ„์„ ์ค‘..." # ์ž„์‹œ ๊ตฌํ˜„
915
+
916
+ def predict_interactions(params):
917
+ """์ƒํ˜ธ์ž‘์šฉ ์˜ˆ์ธก"""
918
+ return "์˜ˆ์ธก ์ค‘..." # ์ž„์‹œ ๊ตฌํ˜„
919
+
920
+ def evaluate_stability(plddt_data):
921
+ """์•ˆ์ •์„ฑ ํ‰๊ฐ€"""
922
+ if not plddt_data:
923
+ return "ํ‰๊ฐ€ ๋ถˆ๊ฐ€"
924
+ avg_score = np.mean(plddt_data)
925
+ if avg_score > 0.8:
926
+ return "๋งค์šฐ ์•ˆ์ •์ "
927
+ elif avg_score > 0.6:
928
+ return "์•ˆ์ •์ "
929
+ else:
930
+ return "๋ณดํ†ต"
931
+
932
+ def process_chat_and_generate(message, history):
933
+ try:
934
+ # 1. ์ดˆ๊ธฐ ์‘๋‹ต ์ƒ์„ฑ
935
+ initial_response = "๋‹จ๋ฐฑ์งˆ ์„ค๊ณ„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ž ์‹œ๋งŒ ๊ธฐ๋‹ค๋ ค์ฃผ์„ธ์š”..."
936
+ yield (
937
+ history + [
938
+ {"role": "user", "content": message},
939
+ {"role": "assistant", "content": initial_response}
940
+ ],
941
+ None, None, None, None, None, None
942
+ )
943
+
944
+ # 2. ํ”„๋กฌํ”„ํŠธ ๋ถ„์„
945
+ analysis = analyze_prompt(message)
946
+ similar_structures = search_protein_data(analysis, ds)
947
+ params = extract_parameters(analysis, similar_structures)
948
+
949
+ # 3. ๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ ์‹œ์ž‘ ๋ฉ”์‹œ์ง€
950
+ progress_msg = "๋‹จ๋ฐฑ์งˆ ๊ตฌ์กฐ ์ƒ์„ฑ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค..."
951
+ yield (
952
+ history + [
953
+ {"role": "user", "content": message},
954
+ {"role": "assistant", "content": progress_msg}
955
+ ],
956
+ None, None, None, None, None, None
957
+ )
958
+
959
+ # 4. ๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ
960
+ generator = protein_diffusion_model(
961
+ sequence=None,
962
+ seq_len=params['sequence_length'],
963
+ helix_bias=params['helix_bias'],
964
+ strand_bias=params['strand_bias'],
965
+ loop_bias=params['loop_bias'],
966
+ secondary_structure=None,
967
+ aa_bias=None,
968
+ aa_bias_potential=None,
969
+ num_steps="25",
970
+ noise="normal",
971
+ hydrophobic_target_score=str(params['hydrophobic_target_score']),
972
+ hydrophobic_potential="2",
973
+ contigs=None,
974
+ pssm=None,
975
+ seq_mask=None,
976
+ str_mask=None,
977
+ rewrite_pdb=None
978
+ )
979
+
980
+ # 5. ์ƒ์„ฑ ๊ณผ์ • ์ถ”์ 
981
+ final_result = None
982
+ plddt_data = []
983
+ step = 0
984
+
985
+ for result in generator:
986
+ step += 1
987
+ final_result = result
988
+ if result[3]: # plddt_plot์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ
989
+ ax = result[3].gca()
990
+ if ax.lines:
991
+ line = ax.lines[0]
992
+ plddt_data = line.get_ydata().tolist()
993
+
994
+ progress_msg = f"๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ ์ค‘... {step}/25 ๋‹จ๊ณ„ ์™„๋ฃŒ"
995
+ yield (
996
+ history + [
997
+ {"role": "user", "content": message},
998
+ {"role": "assistant", "content": progress_msg}
999
+ ],
1000
+ create_radar_chart(calculate_hero_stats(
1001
+ params['helix_bias'],
1002
+ params['strand_bias'],
1003
+ params['loop_bias'],
1004
+ float(params['hydrophobic_target_score'])
1005
+ )),
1006
+ progress_msg,
1007
+ result[0], # output_seq
1008
+ result[1], # output_pdb
1009
+ result[2], # structure_view
1010
+ result[3] # plddt_plot
1011
+ )
1012
+
1013
+ # 6. ์ตœ์ข… ๊ฒฐ๊ณผ ๋ฐ ์„ค๋ช… ์ƒ์„ฑ
1014
+ if final_result:
1015
+ output_seq, output_pdb, structure_view, plddt_plot = final_result
1016
+
1017
+ final_explanation = f"""
1018
+ ๋‹จ๋ฐฑ์งˆ ์„ค๊ณ„๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
1019
+
1020
+ [๋ถ„์„ ๊ฒฐ๊ณผ]
1021
+ {analysis}
1022
+
1023
+ [๊ตฌ์กฐ์  ํŠน์ง•]
1024
+ - ๊ธธ์ด: {params['sequence_length']} ์•„๋ฏธ๋…ธ์‚ฐ
1025
+ - ์•ŒํŒŒ ํ—ฌ๋ฆญ์Šค ๋น„์œจ: {params['helix_bias']*100:.1f}%
1026
+ - ๋ฒ ํƒ€ ์‹œํŠธ ๋น„์œจ: {params['strand_bias']*100:.1f}%
1027
+ - ๋ฃจํ”„ ๊ตฌ์กฐ ๋น„์œจ: {params['loop_bias']*100:.1f}%
1028
+ - ์†Œ์ˆ˜์„ฑ ์ ์ˆ˜: {params['hydrophobic_target_score']}
1029
+
1030
+ [์ƒ์„ฑ ๊ณผ์ •]
1031
+ - ์ด {len(plddt_data)}๋‹จ๊ณ„์˜ ์ตœ์ ํ™” ์™„๋ฃŒ
1032
+ - ์ตœ์ข… ์•ˆ์ •์„ฑ ์ ์ˆ˜: {np.mean(plddt_data) if plddt_data else 0:.2f}
1033
+ - ์ฐธ์กฐ๋œ ์œ ์‚ฌ ๊ตฌ์กฐ: {len(similar_structures)}๊ฐœ
1034
+
1035
+ 3D ๊ตฌ์กฐ์™€ ์ƒ์„ธ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1036
+ """
1037
+
1038
+ return (
1039
+ history + [
1040
+ {"role": "user", "content": message},
1041
+ {"role": "assistant", "content": final_explanation}
1042
+ ],
1043
+ create_radar_chart(calculate_hero_stats(
1044
+ params['helix_bias'],
1045
+ params['strand_bias'],
1046
+ params['loop_bias'],
1047
+ float(params['hydrophobic_target_score'])
1048
+ )),
1049
+ final_explanation,
1050
+ output_seq,
1051
+ output_pdb,
1052
+ structure_view,
1053
+ plddt_plot
1054
+ )
1055
+
1056
+ except Exception as e:
1057
+ print(f"Error in process_chat_and_generate: {str(e)}")
1058
+ traceback.print_exc()
1059
+ error_msg = f"์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(e)}"
1060
+ return (
1061
+ history + [
1062
+ {"role": "user", "content": message},
1063
+ {"role": "assistant", "content": error_msg}
1064
+ ],
1065
+ None, None, None, None, None, None
1066
+ )
1067
+
1068
+ def extract_keywords(analysis):
1069
+ """๋ถ„์„ ํ…์ŠคํŠธ์—์„œ ํ‚ค์›Œ๋“œ ์ถ”์ถœ"""
1070
+ try:
1071
+ # ๊ธฐ๋ณธ ํ‚ค์›Œ๋“œ ์ถ”์ถœ
1072
+ keywords = []
1073
+ # ์ฃผ์š” ๊ธฐ๋Šฅ ํ‚ค์›Œ๋“œ
1074
+ if "์น˜๋ฃŒ" in analysis: keywords.extend(["therapeutic", "binding"])
1075
+ if "๊ฒฐํ•ฉ" in analysis: keywords.extend(["binding", "interaction"])
1076
+ if "์ด‰๋งค" in analysis: keywords.extend(["enzyme", "catalytic"])
1077
+
1078
+ # ํ™˜๊ฒฝ ํ‚ค์›Œ๋“œ
1079
+ if "๋ง‰" in analysis: keywords.extend(["membrane", "transmembrane"])
1080
+ if "์ˆ˜์šฉ์„ฑ" in analysis: keywords.extend(["soluble", "hydrophilic"])
1081
+ if "์†Œ์ˆ˜์„ฑ" in analysis: keywords.extend(["hydrophobic"])
1082
+
1083
+ # ๊ตฌ์กฐ ํ‚ค์›Œ๋“œ
1084
+ if "์•ŒํŒŒ" in analysis or "๋‚˜์„ " in analysis: keywords.append("helix")
1085
+ if "๋ฒ ํƒ€" in analysis or "์‹œํŠธ" in analysis: keywords.append("sheet")
1086
+ if "๋ฃจํ”„" in analysis: keywords.append("loop")
1087
+
1088
+ return list(set(keywords)) # ์ค‘๋ณต ์ œ๊ฑฐ
1089
+ except Exception as e:
1090
+ print(f"ํ‚ค์›Œ๋“œ ์ถ”์ถœ ์ค‘ ์˜ค๋ฅ˜: {str(e)}")
1091
+ return []
1092
+
1093
+ def calculate_similarity(keywords, entry):
1094
+ """ํ‚ค์›Œ๋“œ์™€ ๋ฐ์ดํ„ฐ์…‹ ํ•ญ๋ชฉ ๊ฐ„์˜ ์œ ์‚ฌ๋„ ๊ณ„์‚ฐ"""
1095
+ try:
1096
+ score = 0
1097
+ # ๋ฐ์ดํ„ฐ์…‹ ๊ตฌ์กฐ ํ™•์ธ ๋ฐ ์•ˆ์ „ํ•œ ์ ‘๊ทผ
1098
+ sequence = entry.get('sequence', '').lower() if isinstance(entry, dict) else str(entry).lower()
1099
+
1100
+ # ๋ฐ์ดํ„ฐ์…‹ ๊ตฌ์กฐ ๋””๋ฒ„๊น…
1101
+ print("Entry structure:", type(entry))
1102
+ print("Entry content:", entry)
1103
+
1104
+ for keyword in keywords:
1105
+ # ์•ˆ์ „ํ•œ ์ ‘๊ทผ์„ ์œ„ํ•œ ์ˆ˜์ •
1106
+ description = entry.get('description', '') if isinstance(entry, dict) else ''
1107
+ if keyword in description.lower():
1108
+ score += 2
1109
+ if keyword in sequence:
1110
+ score += 1
1111
+ if isinstance(entry, dict) and 'secondary_structure' in entry:
1112
+ sec_structure = entry['secondary_structure']
1113
+ if keyword in ['helix'] and 'H' in sec_structure:
1114
+ score += 1
1115
+ if keyword in ['sheet'] and 'E' in sec_structure:
1116
+ score += 1
1117
+ if keyword in ['loop'] and 'L' in sec_structure:
1118
+ score += 1
1119
+ return score
1120
+ except Exception as e:
1121
+ print(f"์œ ์‚ฌ๋„ ๊ณ„์‚ฐ ์ค‘ ์ƒ์„ธ ์˜ค๋ฅ˜: {str(e)}")
1122
+ print("Entry:", entry)
1123
+ return 0
1124
+
1125
+
1126
+
1127
+ def download_checkpoint_files():
1128
+ """ํ•„์š”ํ•œ ์ฒดํฌํฌ์ธํŠธ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ"""
1129
+ try:
1130
+ import requests
1131
+
1132
+ # ์ฒดํฌํฌ์ธํŠธ ํŒŒ์ผ URL (์‹ค์ œ URL๋กœ ๊ต์ฒด ํ•„์š”)
1133
+ dssp_url = "YOUR_DSSP_CHECKPOINT_URL"
1134
+ og_url = "YOUR_OG_CHECKPOINT_URL"
1135
+
1136
+ # DSSP ์ฒดํฌํฌ์ธํŠธ ๋‹ค์šด๋กœ๋“œ
1137
+ if not os.path.exists(dssp_checkpoint):
1138
+ print("Downloading DSSP checkpoint...")
1139
+ response = requests.get(dssp_url)
1140
+ with open(dssp_checkpoint, 'wb') as f:
1141
+ f.write(response.content)
1142
+
1143
+ # OG ์ฒดํฌํฌ์ธํŠธ ๋‹ค์šด๋กœ๋“œ
1144
+ if not os.path.exists(og_checkpoint):
1145
+ print("Downloading OG checkpoint...")
1146
+ response = requests.get(og_url)
1147
+ with open(og_checkpoint, 'wb') as f:
1148
+ f.write(response.content)
1149
+
1150
+ print("Checkpoint files downloaded successfully")
1151
+ except Exception as e:
1152
+ print(f"Error downloading checkpoint files: {str(e)}")
1153
+ raise
1154
+
1155
+ # ์‹œ์ž‘ ์‹œ ์ฒดํฌํฌ์ธํŠธ ํŒŒ์ผ ํ™•์ธ ๋ฐ ๋‹ค์šด๋กœ๋“œ
1156
+ try:
1157
+ download_checkpoint_files()
1158
+ except Exception as e:
1159
+ print(f"Warning: Could not download checkpoint files: {str(e)}")
1160
+
1161
+ with gr.Blocks(theme='ParityError/Interstellar') as demo:
1162
+ with gr.Row():
1163
+ with gr.Column(scale=1):
1164
+ # ์ฑ—๋ด‡ ์ธํ„ฐํŽ˜์ด์Šค
1165
+ gr.Markdown("# ๐Ÿค– AI ๋‹จ๋ฐฑ์งˆ ์„ค๊ณ„ ๋„์šฐ๋ฏธ")
1166
+ # ์—ฌ๊ธฐ๋ฅผ ์ˆ˜์ •
1167
+ chatbot = gr.Chatbot(
1168
+ height=600,
1169
+ type='messages' # ๋ฉ”์‹œ์ง€ ํ˜•์‹ ์ง€์ •
1170
+
1171
+ )
1172
+ with gr.Row():
1173
+ msg = gr.Textbox(
1174
+ label="๋ฉ”์‹œ์ง€๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”",
1175
+ placeholder="์˜ˆ: COVID-19๋ฅผ ์น˜๋ฃŒํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ๋ฐฑ์งˆ์„ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”",
1176
+ lines=2,
1177
+ scale=4
1178
+ )
1179
+ submit_btn = gr.Button("์ „์†ก", variant="primary", scale=1)
1180
+ clear = gr.Button("๋Œ€ํ™” ๋‚ด์šฉ ์ง€์šฐ๊ธฐ")
1181
+
1182
+
1183
+
1184
+
1185
+ with gr.Accordion("์ฑ„ํŒ… ์„ค์ •", open=False):
1186
+ system_message = gr.Textbox(
1187
+ value="๋‹น์‹ ์€ ๋‹จ๋ฐฑ์งˆ ์„ค๊ณ„๋ฅผ ๋„์™€์ฃผ๋Š” ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค.",
1188
+ label="์‹œ์Šคํ…œ ๋ฉ”์‹œ์ง€"
1189
+ )
1190
+ max_tokens = gr.Slider(
1191
+ minimum=1,
1192
+ maximum=3800,
1193
+ value=3800,
1194
+ step=1,
1195
+ label="์ตœ๋Œ€ ํ† ํฐ ์ˆ˜"
1196
+ )
1197
+ temperature = gr.Slider(
1198
+ minimum=0.1,
1199
+ maximum=4.0,
1200
+ value=0.7,
1201
+ step=0.1,
1202
+ label="Temperature"
1203
+ )
1204
+ top_p = gr.Slider(
1205
+ minimum=0.1,
1206
+ maximum=1.0,
1207
+ value=0.95,
1208
+ step=0.05,
1209
+ label="Top-P"
1210
+ )
1211
+
1212
+
1213
+ # ํƒญ ์ธํ„ฐํŽ˜์ด์Šค
1214
+ with gr.Tabs():
1215
+ with gr.TabItem("๐Ÿฆธโ€โ™‚๏ธ ์ปค์Šคํ…€ ๋””์ž์ธ"):
1216
+ gr.Markdown("""
1217
+ ### โœจ ๋‹น์‹ ๋งŒ์˜ ํŠน๋ณ„ํ•œ ์ปค์Šคํ…€์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”!
1218
+ ๊ฐ ๋Šฅ๋ ฅ์น˜๋ฅผ ์กฐ์ ˆํ•˜๋ฉด ์ปค์Šคํ…€๋œ ๋‹จ๋ฐฑ์งˆ์ด ์ž๋™์œผ๋กœ ์„ค๊ณ„๋ฉ๋‹ˆ๋‹ค.
1219
+ """)
1220
+
1221
+ # ํžˆ์–ด๋กœ ๊ธฐ๋ณธ ์ •๋ณด
1222
+ hero_name = gr.Textbox(
1223
+ label="์ปค์Šคํ…€ ์ด๋ฆ„",
1224
+ placeholder="๋‹น์‹ ์˜ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์ด๋ฆ„์„ ์ง€์–ด์ฃผ์„ธ์š”!",
1225
+ info="๋‹น์‹ ๋งŒ์˜ ์ •์ฒด์„ฑ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”"
1226
+ )
1227
+
1228
+ # ๋Šฅ๋ ฅ์น˜ ์„ค์ •
1229
+ gr.Markdown("### ๐Ÿ’ช ์ปค์Šคํ…€ ๋Šฅ๋ ฅ์น˜ ์„ค์ •")
1230
+ with gr.Row():
1231
+ strength = gr.Slider(
1232
+ minimum=0.0, maximum=0.05,
1233
+ label="๐Ÿ’ช ์ดˆ๊ฐ•๋ ฅ(๊ทผ๋ ฅ)",
1234
+ value=0.02,
1235
+ info="๋‹จ๋‹จํ•œ ๋ฒ ํƒ€์‹œํŠธ ๊ตฌ์กฐ๋กœ ๊ฐ•๋ ฅํ•œ ํž˜์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค"
1236
+ )
1237
+ flexibility = gr.Slider(
1238
+ minimum=0.0, maximum=0.05,
1239
+ label="๐Ÿคธโ€โ™‚๏ธ ์œ ์—ฐ์„ฑ",
1240
+ value=0.02,
1241
+ info="๋‚˜์„ ํ˜• ์•ŒํŒŒํ—ฌ๋ฆญ์Šค ๊ตฌ์กฐ๋กœ ์œ ์—ฐํ•œ ์›€์ง์ž„์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค"
1242
+ )
1243
+
1244
+ with gr.Row():
1245
+ speed = gr.Slider(
1246
+ minimum=0.0, maximum=0.20,
1247
+ label="โšก ์Šคํ”ผ๋“œ",
1248
+ value=0.1,
1249
+ info="๋ฃจํ”„ ๊ตฌ์กฐ๋กœ ๋น ๋ฅธ ์›€์ง์ž„์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค"
1250
+ )
1251
+ defense = gr.Slider(
1252
+ minimum=-10, maximum=10,
1253
+ label="๐Ÿ›ก๏ธ ๋ฐฉ์–ด๋ ฅ",
1254
+ value=0,
1255
+ info="์Œ์ˆ˜: ์ˆ˜์ค‘ ํ™œ๋™์— ํŠนํ™”, ์–‘์ˆ˜: ์ง€์ƒ ํ™œ๋™์— ํŠนํ™”"
1256
+ )
1257
+
1258
+ # ํžˆ์–ด๋กœ ํฌ๊ธฐ ์„ค์ •
1259
+ hero_size = gr.Slider(
1260
+ minimum=50, maximum=200,
1261
+ label="๐Ÿ“ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ํฌ๊ธฐ",
1262
+ value=100,
1263
+ info="์ „์ฒด์ ์ธ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค"
1264
+ )
1265
+
1266
+ # ํŠน์ˆ˜ ๋Šฅ๋ ฅ ์„ค์ •
1267
+ with gr.Accordion("๐ŸŒŸ ํŠน์ˆ˜ ๋Šฅ๋ ฅ", open=False):
1268
+ gr.Markdown("""
1269
+ ํŠน์ˆ˜ ๋Šฅ๋ ฅ์„ ์„ ํƒํ•˜๋ฉด ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ์งˆ์— ํŠน๋ณ„ํ•œ ๊ตฌ์กฐ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
1270
+ - ์ž๊ฐ€ ํšŒ๋ณต: ๋‹จ๋ฐฑ์งˆ ๊ตฌ์กฐ ๋ณต๊ตฌ ๋Šฅ๋ ฅ ๊ฐ•ํ™”
1271
+ - ์›๊ฑฐ๋ฆฌ ๊ณต๊ฒฉ: ํŠน์ˆ˜ํ•œ ๊ตฌ์กฐ์  ๋Œ์ถœ๋ถ€ ํ˜•์„ฑ
1272
+ - ๋ฐฉ์–ด๋ง‰ ์ƒ์„ฑ: ์•ˆ์ •์ ์ธ ๋ณดํ˜ธ์ธต ๊ตฌ์กฐ ์ƒ์„ฑ
1273
+ """)
1274
+ special_ability = gr.CheckboxGroup(
1275
+ choices=["์ž๊ฐ€ ํšŒ๋ณต", "์›๊ฑฐ๋ฆฌ ๊ณต๊ฒฉ", "๋ฐฉ์–ด๋ง‰ ์ƒ์„ฑ"],
1276
+ label="ํŠน์ˆ˜ ๋Šฅ๋ ฅ ์„ ํƒ"
1277
+ )
1278
+
1279
+ # ์ƒ์„ฑ ๋ฒ„ํŠผ
1280
+ create_btn = gr.Button("๐Ÿงฌ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ!", variant="primary", scale=2)
1281
+
1282
+ with gr.TabItem("๐Ÿงฌ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์„ค๊ณ„"):
1283
+ gr.Markdown("""
1284
+ ### ๐Ÿงช ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๊ณ ๊ธ‰ ์„ค์ •
1285
+ ์œ ์ „์ž ๊ตฌ์กฐ๋ฅผ ๋” ์„ธ๋ฐ€ํ•˜๊ฒŒ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1286
+ """)
1287
+
1288
+ seq_opt = gr.Radio(
1289
+ ["์ž๋™ ์„ค๊ณ„", "์ง์ ‘ ์ž…๋ ฅ"],
1290
+ label="DNA ์„ค๊ณ„ ๋ฐฉ์‹",
1291
+ value="์ž๋™ ์„ค๊ณ„"
1292
+ )
1293
+
1294
+ sequence = gr.Textbox(
1295
+ label="๋‹จ๋ฐฑ์งˆ ์‹œํ€€์Šค",
1296
+ lines=1,
1297
+ placeholder='์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์•„๋ฏธ๋…ธ์‚ฐ: A,C,D,E,F,G,H,I,K,L,M,N,P,Q,R,S,T,V,W,Y (X๋Š” ๋ฌด์ž‘์œ„)',
1298
+ visible=False
1299
+ )
1300
+ seq_len = gr.Slider(
1301
+ minimum=5.0, maximum=250.0,
1302
+ label="DNA ๊ธธ์ด",
1303
+ value=100,
1304
+ visible=True
1305
+ )
1306
+
1307
+ with gr.Accordion(label='๐Ÿฆด ๊ณจ๊ฒฉ ๊ตฌ์กฐ ์„ค์ •', open=True):
1308
+ gr.Markdown("""
1309
+ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๊ธฐ๋ณธ ๊ณจ๊ฒฉ ๊ตฌ์กฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
1310
+ - ๋‚˜์„ ํ˜• ๊ตฌ์กฐ: ์œ ์—ฐํ•˜๊ณ  ํƒ„๋ ฅ์žˆ๋Š” ์›€์ง์ž„
1311
+ - ๋ณ‘ํ’ํ˜• ๊ตฌ์กฐ: ๋‹จ๋‹จํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ํž˜
1312
+ - ๊ณ ๋ฆฌํ˜• ๊ตฌ์กฐ: ๋น ๋ฅด๊ณ  ๋ฏผ์ฒฉํ•œ ์›€์ง์ž„
1313
+ """)
1314
+ sec_str_opt = gr.Radio(
1315
+ ["์Šฌ๋ผ์ด๋”๋กœ ์„ค์ •", "์ง์ ‘ ์ž…๋ ฅ"],
1316
+ label="๊ณจ๊ฒฉ ๊ตฌ์กฐ ์„ค์ • ๋ฐฉ์‹",
1317
+ value="์Šฌ๋ผ์ด๋”๋กœ ์„ค์ •"
1318
+ )
1319
+
1320
+ secondary_structure = gr.Textbox(
1321
+ label="๊ณจ๊ฒฉ ๊ตฌ์กฐ",
1322
+ lines=1,
1323
+ placeholder='H:๋‚˜์„ ํ˜•, S:๋ณ‘ํ’ํ˜•, L:๊ณ ๋ฆฌํ˜•, X:์ž๋™์„ค์ •',
1324
+ visible=False
1325
+ )
1326
+
1327
+ with gr.Column():
1328
+ helix_bias = gr.Slider(
1329
+ minimum=0.0, maximum=0.05,
1330
+ label="๋‚˜์„ ํ˜• ๊ตฌ์กฐ ๋น„์œจ",
1331
+ visible=True
1332
+ )
1333
+ strand_bias = gr.Slider(
1334
+ minimum=0.0, maximum=0.05,
1335
+ label="๋ณ‘ํ’ํ˜• ๊ตฌ์กฐ ๋น„์œจ",
1336
+ visible=True
1337
+ )
1338
+ loop_bias = gr.Slider(
1339
+ minimum=0.0, maximum=0.20,
1340
+ label="๊ณ ๋ฆฌํ˜• ๊ตฌ์กฐ ๋น„์œจ",
1341
+ visible=True
1342
+ )
1343
+
1344
+ with gr.Accordion(label='๐Ÿงฌ ๋‹จ๋ฐฑ์งˆ ๊ตฌ์„ฑ ์„ค์ •', open=False):
1345
+ gr.Markdown("""
1346
+ ํŠน์ • ์•„๋ฏธ๋…ธ์‚ฐ์˜ ๋น„์œจ์„ ์กฐ์ ˆํ•˜์—ฌ ํŠน์„ฑ์„ ๊ฐ•ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1347
+ ์˜ˆ์‹œ: W0.2,E0.1 (ํŠธ๋ฆฝํ† ํŒ 20%, ๊ธ€๋ฃจํƒ์‚ฐ 10%)
1348
+ """)
1349
+ with gr.Row():
1350
+ aa_bias = gr.Textbox(
1351
+ label="์•„๋ฏธ๋…ธ์‚ฐ ๋น„์œจ",
1352
+ lines=1,
1353
+ placeholder='์˜ˆ์‹œ: W0.2,E0.1'
1354
+ )
1355
+ aa_bias_potential = gr.Textbox(
1356
+ label="๊ฐ•ํ™” ์ •๋„",
1357
+ lines=1,
1358
+ placeholder='1.0-5.0 ์‚ฌ์ด ๊ฐ’ ์ž…๋ ฅ'
1359
+ )
1360
+
1361
+ with gr.Accordion(label='๐ŸŒ ํ™˜๊ฒฝ ์ ์‘๋ ฅ ์„ค์ •', open=False):
1362
+ gr.Markdown("""
1363
+ ํ™˜๊ฒฝ ์ ์‘๋ ฅ์„ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค.
1364
+ ์Œ์ˆ˜: ์ˆ˜์ค‘ ํ™œ๋™์— ํŠนํ™”, ์–‘์ˆ˜: ์ง€์ƒ ํ™œ๋™์— ํŠนํ™”
1365
+ """)
1366
+ with gr.Row():
1367
+ hydrophobic_target_score = gr.Textbox(
1368
+ label="ํ™˜๊ฒฝ ์ ์‘ ์ ์ˆ˜",
1369
+ lines=1,
1370
+ placeholder='์˜ˆ์‹œ: -5 (์ˆ˜์ค‘ ํ™œ๋™์— ํŠนํ™”)'
1371
+ )
1372
+ hydrophobic_potential = gr.Textbox(
1373
+ label="์ ์‘๋ ฅ ๊ฐ•ํ™” ์ •๋„",
1374
+ lines=1,
1375
+ placeholder='1.0-2.0 ์‚ฌ์ด ๊ฐ’ ์ž…๋ ฅ'
1376
+ )
1377
+
1378
+ with gr.Accordion(label='โš™๏ธ ๊ณ ๊ธ‰ ์„ค์ •', open=False):
1379
+ gr.Markdown("""
1380
+ DNA ์ƒ์„ฑ ๊ณผ์ •์˜ ์„ธ๋ถ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
1381
+ """)
1382
+ with gr.Row():
1383
+ num_steps = gr.Textbox(
1384
+ label="์ƒ์„ฑ ๋‹จ๊ณ„",
1385
+ lines=1,
1386
+ placeholder='25 ์ดํ•˜ ๊ถŒ์žฅ'
1387
+ )
1388
+ noise = gr.Dropdown(
1389
+ ['normal','gmm2 [-1,1]','gmm3 [-1,0,1]'],
1390
+ label='๋…ธ์ด์ฆˆ ํƒ€์ž…',
1391
+ value='normal'
1392
+ )
1393
+
1394
+ design_btn = gr.Button("๐Ÿงฌ ๋‹จ๋ฐฑ์งˆ ์„ค๊ณ„ ์ƒ์„ฑ!", variant="primary", scale=2)
1395
+
1396
+ with gr.TabItem("๐Ÿงช ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๊ฐ•ํ™”"):
1397
+ gr.Markdown("""
1398
+ ### โšก ๊ธฐ์กด ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ํ™œ์šฉ
1399
+ ๊ธฐ์กด ๋‹จ๋ฐฑ์งˆ ์ผ๋ถ€๋ฅผ ์ƒˆ๋กœ์šด ์ปค์Šคํ…€์—๊ฒŒ ์ด์‹ํ•ฉ๋‹ˆ๋‹ค.
1400
+ """)
1401
+
1402
+ gr.Markdown("๊ณต๊ฐœ๋œ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค")
1403
+ pdb_id_code = gr.Textbox(
1404
+ label="์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์ฝ”๋“œ",
1405
+ lines=1,
1406
+ placeholder='๊ธฐ์กด ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š” (์˜ˆ: 1DPX)'
1407
+ )
1408
+
1409
+ gr.Markdown("์ด์‹ํ•˜๊ณ  ์‹ถ์€ ๋‹จ๋ฐฑ์งˆ ์˜์—ญ์„ ์„ ํƒํ•˜๊ณ  ์ƒˆ๋กœ์šด ๋‹จ๋ฐฑ์งˆ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค")
1410
+ contigs = gr.Textbox(
1411
+ label="์ด์‹ํ•  ๋‹จ๋ฐฑ์งˆ ์˜๏ฟฝ๏ฟฝ",
1412
+ lines=1,
1413
+ placeholder='์˜ˆ์‹œ: 15,A3-10,20-30'
1414
+ )
1415
+
1416
+ with gr.Row():
1417
+ seq_mask = gr.Textbox(
1418
+ label='๋Šฅ๋ ฅ ์žฌ์„ค๊ณ„',
1419
+ lines=1,
1420
+ placeholder='์„ ํƒํ•œ ์˜์—ญ์˜ ๋Šฅ๋ ฅ์„ ์ƒˆ๋กญ๊ฒŒ ๋””์ž์ธ'
1421
+ )
1422
+ str_mask = gr.Textbox(
1423
+ label='๊ตฌ์กฐ ์žฌ์„ค๊ณ„',
1424
+ lines=1,
1425
+ placeholder='์„ ํƒํ•œ ์˜์—ญ์˜ ๊ตฌ์กฐ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๋””์ž์ธ'
1426
+ )
1427
+
1428
+ preview_viewer = gr.HTML()
1429
+ rewrite_pdb = gr.File(label='์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ํŒŒ์ผ')
1430
+ preview_btn = gr.Button("๐Ÿ” ๋ฏธ๋ฆฌ๋ณด๊ธฐ", variant="secondary")
1431
+ enhance_btn = gr.Button("โšก ๊ฐ•ํ™”๋œ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ!", variant="primary", scale=2)
1432
+
1433
+ with gr.TabItem("๐Ÿ‘‘ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์กฑ๋ณด"):
1434
+ gr.Markdown("""
1435
+ ### ๐Ÿฐ ์œ„๋Œ€ํ•œ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๊ฐ€๋ฌธ์˜ ์œ ์‚ฐ
1436
+ ๊ฐ•๋ ฅํ•œ ํŠน์„ฑ์„ ๊ณ„์Šนํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
1437
+ """)
1438
+
1439
+ with gr.Row():
1440
+ with gr.Column():
1441
+ gr.Markdown("์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜์„ธ์š”")
1442
+ fasta_msa = gr.File(label='๊ฐ€๋ฌธ DNA ๋ฐ์ดํ„ฐ')
1443
+ with gr.Column():
1444
+ gr.Markdown("์ด๋ฏธ ๋ถ„์„๋œ ๊ฐ€๋ฌธ ํŠน์„ฑ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด ์—…๋กœ๋“œํ•˜์„ธ์š”")
1445
+ input_pssm = gr.File(label='๊ฐ€๋ฌธ ํŠน์„ฑ ๋ฐ์ดํ„ฐ')
1446
+
1447
+ pssm = gr.File(label='๋ถ„์„๋œ ๊ฐ€๋ฌธ ํŠน์„ฑ')
1448
+ pssm_view = gr.Plot(label='๊ฐ€๋ฌธ ํŠน์„ฑ ๋ถ„์„ ๊ฒฐ๊ณผ')
1449
+ pssm_gen_btn = gr.Button("โœจ ๊ฐ€๋ฌธ ํŠน์„ฑ ๋ถ„์„", variant="secondary")
1450
+ inherit_btn = gr.Button("๐Ÿ‘‘ ๊ฐ€๋ฌธ์˜ ํž˜ ๊ณ„์Šน!", variant="primary", scale=2)
1451
+
1452
+ # ์˜ค๋ฅธ์ชฝ ์—ด: ๊ฒฐ๊ณผ ํ‘œ์‹œ
1453
+ with gr.Column(scale=1):
1454
+ gr.Markdown("## ๐Ÿฆธโ€โ™‚๏ธ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ํ”„๋กœํ•„")
1455
+ hero_stats = gr.Plot(label="๋Šฅ๋ ฅ์น˜ ๋ถ„์„")
1456
+ hero_description = gr.Textbox(label="์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ํŠน์„ฑ", lines=3)
1457
+
1458
+ gr.Markdown("## ๐Ÿงฌ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๋ถ„์„ ๊ฒฐ๊ณผ")
1459
+ gr.Markdown("#### โšก ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์•ˆ์ •์„ฑ ์ ์ˆ˜")
1460
+ plddt_plot = gr.Plot(label='์•ˆ์ •์„ฑ ๋ถ„์„')
1461
+ gr.Markdown("#### ๐Ÿ“ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์‹œํ€€์Šค")
1462
+ output_seq = gr.Textbox(label="์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ์„œ์—ด")
1463
+ gr.Markdown("#### ๐Ÿ’พ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๋ฐ์ดํ„ฐ")
1464
+ output_pdb = gr.File(label="์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ํŒŒ์ผ")
1465
+ gr.Markdown("#### ๐Ÿ”ฌ ์ปค์Šคํ…€ ๋‹จ๋ฐฑ์งˆ ๊ตฌ์กฐ")
1466
+ output_viewer = gr.HTML()
1467
+
1468
+ # ์ด๋ฒคํŠธ ์—ฐ๊ฒฐ
1469
+ # ์ฑ—๋ด‡ ์ด๋ฒคํŠธ
1470
+ msg.submit(process_chat, [msg, chatbot], [chatbot])
1471
+ clear.click(lambda: None, None, chatbot, queue=False)
1472
+
1473
+ seq_opt.change(
1474
+ fn=toggle_seq_input,
1475
+ inputs=[seq_opt],
1476
+ outputs=[seq_len, sequence],
1477
+ queue=False
1478
+ )
1479
+
1480
+
1481
+
1482
+ sec_str_opt.change(
1483
+ fn=toggle_secondary_structure,
1484
+ inputs=[sec_str_opt],
1485
+ outputs=[helix_bias, strand_bias, loop_bias, secondary_structure],
1486
+ queue=False
1487
+ )
1488
+
1489
+ preview_btn.click(
1490
+ get_motif_preview,
1491
+ inputs=[pdb_id_code, contigs],
1492
+ outputs=[preview_viewer, rewrite_pdb]
1493
+ )
1494
+
1495
+ pssm_gen_btn.click(
1496
+ get_pssm,
1497
+ inputs=[fasta_msa, input_pssm],
1498
+ outputs=[pssm_view, pssm]
1499
+ )
1500
+
1501
+ # ์ฑ—๋ด‡ ๊ธฐ๋ฐ˜ ๋‹จ๋ฐฑ์งˆ ์ƒ์„ฑ ๊ฒฐ๊ณผ ์—…๋ฐ์ดํŠธ
1502
+ def update_protein_display(chat_response):
1503
+ if "์ƒ์„ฑ๋œ ๋‹จ๋ฐฑ์งˆ ๋ถ„์„" in chat_response:
1504
+ params = extract_parameters_from_chat(chat_response)
1505
+ result = generate_protein(params)
1506
+ return {
1507
+ hero_stats: create_radar_chart(calculate_hero_stats(params)),
1508
+ hero_description: chat_response,
1509
+ output_seq: result[0],
1510
+ output_pdb: result[1],
1511
+ output_viewer: display_pdb(result[1]),
1512
+ plddt_plot: result[3]
1513
+ }
1514
+ return None
1515
+
1516
+ # ๊ฐ ์ƒ์„ฑ ๋ฒ„ํŠผ ์ด๋ฒคํŠธ ์—ฐ๊ฒฐ
1517
+ for btn in [create_btn, design_btn, enhance_btn, inherit_btn]:
1518
+ btn.click(
1519
+ combined_generation,
1520
+ inputs=[
1521
+ hero_name, strength, flexibility, speed, defense, hero_size, special_ability,
1522
+ sequence, seq_len, helix_bias, strand_bias, loop_bias,
1523
+ secondary_structure, aa_bias, aa_bias_potential,
1524
+ num_steps, noise, hydrophobic_target_score, hydrophobic_potential,
1525
+ contigs, pssm, seq_mask, str_mask, rewrite_pdb
1526
+ ],
1527
+ outputs=[
1528
+ hero_stats,
1529
+ hero_description,
1530
+ output_seq,
1531
+ output_pdb,
1532
+ output_viewer,
1533
+ plddt_plot
1534
+ ]
1535
+ )
1536
+
1537
+ # ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์—ฐ๊ฒฐ
1538
+ msg.submit(
1539
+ fn=process_chat_and_generate,
1540
+ inputs=[msg, chatbot],
1541
+ outputs=[
1542
+ chatbot,
1543
+ hero_stats,
1544
+ hero_description,
1545
+ output_seq,
1546
+ output_pdb,
1547
+ output_viewer,
1548
+ plddt_plot
1549
+ ]
1550
+ )
1551
+
1552
+ submit_btn.click(
1553
+ fn=process_chat_and_generate,
1554
+ inputs=[msg, chatbot],
1555
+ outputs=[
1556
+ chatbot,
1557
+ hero_stats,
1558
+ hero_description,
1559
+ output_seq,
1560
+ output_pdb,
1561
+ output_viewer,
1562
+ plddt_plot
1563
+ ]
1564
+ )
1565
+
1566
+ # ์ฑ„ํŒ… ๋‚ด์šฉ ์ง€์šฐ๊ธฐ
1567
+ clear.click(
1568
+ lambda: (None, None, None, None, None, None, None),
1569
+ None,
1570
+ [chatbot, hero_stats, hero_description, output_seq, output_pdb, output_viewer, plddt_plot],
1571
+ queue=False
1572
+ )
1573
+
1574
+ # ์ฑ—๋ด‡ ์‘๋‹ต์— ๋”ฐ๋ฅธ ๊ฒฐ๊ณผ ์—…๋ฐ์ดํŠธ
1575
+ msg.submit(
1576
+ update_protein_display,
1577
+ inputs=[chatbot],
1578
+ outputs=[hero_stats, hero_description, output_seq, output_pdb, output_viewer, plddt_plot]
1579
+ )
1580
+
1581
+
1582
+ submit_btn.click(respond,
1583
+ [msg, chatbot, system_message, max_tokens, temperature, top_p],
1584
+ [chatbot])
1585
+ msg.submit(respond,
1586
+ [msg, chatbot, system_message, max_tokens, temperature, top_p],
1587
+ [chatbot])
1588
+ clear.click(lambda: None, None, chatbot, queue=False)
1589
+
1590
+
1591
+ # ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์—ฐ๊ฒฐ
1592
+ msg.submit(
1593
+ fn=process_chat_and_generate,
1594
+ inputs=[msg, chatbot],
1595
+ outputs=[
1596
+ chatbot,
1597
+ hero_stats,
1598
+ hero_description,
1599
+ output_seq,
1600
+ output_pdb,
1601
+ output_viewer,
1602
+ plddt_plot
1603
+ ],
1604
+ show_progress=True
1605
+ )
1606
+
1607
+ submit_btn.click(
1608
+ fn=process_chat_and_generate,
1609
+ inputs=[msg, chatbot],
1610
+ outputs=[
1611
+ chatbot,
1612
+ hero_stats,
1613
+ hero_description,
1614
+ output_seq,
1615
+ output_pdb,
1616
+ output_viewer,
1617
+ plddt_plot
1618
+ ],
1619
+ show_progress=True
1620
+ )
1621
+
1622
+
1623
+ # ์‹คํ–‰
1624
+ demo.queue()
1625
+ demo.launch(debug=True)