Ym420 commited on
Commit
0f45c1c
·
verified ·
1 Parent(s): 57b2562

Upload extendedFuture_app.py

Browse files
Files changed (1) hide show
  1. extendedFuture_app.py +122 -0
extendedFuture_app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import joblib
3
+ from huggingface_hub import hf_hub_download
4
+ import pandas as pd
5
+ import numpy as np
6
+ from collections import Counter
7
+
8
+ # --- Download model from HF Hub ---
9
+ repo_id = "Ym420/Peptide-Function"
10
+ model_filename = "xgb_multilabel_model_full.pkl"
11
+
12
+ model_path = hf_hub_download(repo_id=repo_id, filename=model_filename)
13
+ model_package = joblib.load(model_path)
14
+
15
+ # --- Unwrap model dict ---
16
+ model_dict = model_package['model'] # dict: {'Gram+': XGBClassifier, ...}
17
+ feature_columns = model_package['feature_columns']
18
+
19
+ # --- Metadata (all restored) ---
20
+ aa_list = model_package.get('aa_list', [])
21
+ dipeptides = model_package.get('dipeptides', [])
22
+ hydrophobicity_scale = model_package.get('hydrophobicity_scale', {})
23
+ eisenberg_scale = model_package.get('eisenberg_scale', {})
24
+ aa_mass = model_package.get('aa_mass', {})
25
+ aa_charge = model_package.get('aa_charge', {})
26
+ aa_boman = model_package.get('aa_boman', {})
27
+ aa_flexibility = model_package.get('aa_flexibility', {})
28
+ aa_polarizability = model_package.get('aa_polarizability', {})
29
+ aa_aliphatic = model_package.get('aa_aliphatic', {})
30
+ aa_deltaG = model_package.get('aa_deltaG', {})
31
+
32
+ # --- Target cells ---
33
+ TARGET_CELLS = ["Gram+", "Fungus", "Mammalian Cell", "Cancer", "Gram-"]
34
+
35
+ # --- Feature extraction ---
36
+ def extract_features_app(seq: str) -> pd.DataFrame:
37
+ seq = seq.upper()
38
+
39
+ # Dipeptide composition
40
+ count = Counter([seq[i:i+2] for i in range(len(seq)-1)])
41
+ total = max(len(seq)-1, 1)
42
+ dipep_features = [count.get(dp, 0) / total for dp in dipeptides]
43
+
44
+ # Physicochemical features
45
+ def g(aa, table): return table.get(aa, 0)
46
+ def h(dp, table): return (g(dp[0], table) + g(dp[1], table)) / 2.0
47
+
48
+ dipeptides_seq = [seq[i:i+2] for i in range(len(seq)-1)]
49
+
50
+ if len(seq) < 2:
51
+ physchem_features = [0]*12
52
+ else:
53
+ mw = np.mean([h(dp, aa_mass) for dp in dipeptides_seq])
54
+ charge = np.mean([h(dp, aa_charge) for dp in dipeptides_seq])
55
+ hydro = np.mean([h(dp, hydrophobicity_scale) for dp in dipeptides_seq])
56
+ aromatic = np.mean([(dp[0] in 'FWY') + (dp[1] in 'FWY') for dp in dipeptides_seq]) / 2.0
57
+ pI = np.mean([h(dp, {aa: 7 + (int(aa in 'KRH') - int(aa in 'DE')) for aa in aa_list}) for dp in dipeptides_seq])
58
+ instability = np.mean([((dp[0] in 'DEKR') + (dp[1] in 'DEKR')) / 2.0 for dp in dipeptides_seq])
59
+ hydro_moment = np.sqrt(np.mean([(h(dp, eisenberg_scale))**2 for dp in dipeptides_seq]))
60
+ aliphatic = np.mean([h(dp, aa_aliphatic) for dp in dipeptides_seq])
61
+ boman = np.mean([h(dp, aa_boman) for dp in dipeptides_seq])
62
+ flexibility = np.mean([h(dp, aa_flexibility) for dp in dipeptides_seq])
63
+ polarizability = np.mean([h(dp, aa_polarizability) for dp in dipeptides_seq])
64
+ deltag = np.mean([h(dp, aa_deltaG) for dp in dipeptides_seq])
65
+
66
+ physchem_features = [mw, charge, hydro, aromatic, pI, instability,
67
+ hydro_moment, aliphatic, boman, flexibility, polarizability, deltag]
68
+
69
+ features = dipep_features + physchem_features
70
+
71
+ df = pd.DataFrame([features], columns=feature_columns)
72
+ df = df.astype('float32')
73
+ return df
74
+
75
+ # --- Prediction function ---
76
+ def predict_peptide(sequence: str):
77
+ seq = "".join(sequence.split()).upper()
78
+ if not seq:
79
+ return []
80
+
81
+ X = extract_features_app(seq)
82
+
83
+ table = []
84
+ # Iterate over each target classifier
85
+ for target in TARGET_CELLS:
86
+ clf = model_dict.get(target)
87
+ if clf is not None:
88
+ prob = clf.predict_proba(X)[0][1] # positive-class probability (0-1)
89
+ table.append([target, round(float(prob), 4)])
90
+ else:
91
+ table.append([target, None])
92
+
93
+ return table
94
+
95
+ # --- Gradio Interface ---
96
+ custom_css = """
97
+ footer, .footer {display:none !important;}
98
+ """
99
+
100
+ with gr.Blocks(css=custom_css, theme="default") as demo:
101
+ gr.Markdown("## Peptide Antimicrobial Predictor\nEnter a peptide sequence to predict efficacy/toxicity.")
102
+
103
+ seq_input = gr.Textbox(label="Enter Peptide Sequence")
104
+
105
+ with gr.Row():
106
+ predict_btn = gr.Button("Predict", variant="primary")
107
+ clear_btn = gr.Button("Clear")
108
+
109
+ table_output = gr.Dataframe(
110
+ headers=["Target Cell", "Probability of Efficacy/Toxicity"],
111
+ datatype=["str","number"],
112
+ interactive=False
113
+ )
114
+
115
+ predict_btn.click(fn=predict_peptide, inputs=seq_input, outputs=table_output)
116
+ clear_btn.click(fn=lambda: ("", []), outputs=[seq_input, table_output])
117
+
118
+ # API endpoint for iOS app
119
+ gr.api(predict_peptide, api_name="predict_peptide")
120
+
121
+ if __name__ == "__main__":
122
+ demo.launch(show_error=True)