PypCoder commited on
Commit
21c9bd3
·
verified ·
1 Parent(s): f639baf

Added modular structure

Browse files
Files changed (6) hide show
  1. config.py +15 -0
  2. dataset.py +360 -0
  3. html_builder.py +131 -0
  4. inference.py +74 -0
  5. model.py +57 -0
  6. styles.py +259 -0
config.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Configuration constants for the SERAPH protein secondary-structure
3
+ prediction app.
4
+ """
5
+
6
+ # Hugging Face model repo / weights
7
+ HF_REPO_ID = "PypCoder/SERAPH"
8
+ WEIGHTS_FILE = "SERAPH.pth"
9
+ ESM_MODEL_ID = "facebook/esm2_t6_8M_UR50D"
10
+
11
+ # Class index -> secondary structure label
12
+ IDX_TO_LABEL = {0: 'H', 1: 'E', 2: 'C'}
13
+
14
+ # Link for the "back to portfolio" button
15
+ PORTFOLIO_URL = "https://muhammad-asad-ullah.vercel.app/"
dataset.py ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Static dataset of 50 preloaded protein structures used to populate the
3
+ preset dropdown and to compute Q3 accuracy against known ground truth.
4
+ """
5
+
6
+ PROTEIN_DATASET = [
7
+ {
8
+ "name": "01. Human Myoglobin (Oxygen Storage)",
9
+ "sequence": "GLSDGEWQLVLNVWGKVEADIPGHGQEVLIRLFKGHPETLEKFDKFKHLKSEDEMKASEDLKKHGATVLTALGGILKKKGHHEAEIKPLAQSHATKHKIPVKYLEFISECIIQVLQSKHPGDFGADAQGAMNKALELFRKDMASNYKELGFQG",
10
+ "true_ss": "CCCCCCCCCHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCCCCCCC",
11
+ "description": "Primary oxygen-carrying protein in muscle tissues, composed predominantly of dense alpha-helices.",
12
+ "fun_fact": "Deep-diving whales store massive concentrations of myoglobin in their muscles, enabling them to stay submerged for over an hour without breathing!"
13
+ },
14
+ {
15
+ "name": "02. Ubiquitin (Cellular Degradation Tag)",
16
+ "sequence": "MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTLHLVLRLRGG",
17
+ "true_ss": "CCEEEEEEECCCEEEEEECCCCCHHHHHHHHCCCCCCCEEEEEEECCCCCEEEEEECCCCCHHHHHHHHHCCCCCC",
18
+ "description": "A highly conserved regulatory protein that marks other proteins for destruction by the proteasome.",
19
+ "fun_fact": "Ubiquitin got its name because it is truly 'ubiquitous'—present in virtually every eukaryotic cell from baker's yeast to humans!"
20
+ },
21
+ {
22
+ "name": "03. Hen Egg-White Lysozyme (Antimicrobial Enzyme)",
23
+ "sequence": "KVFGRCELAAAMKRHGLDNYRGYSLGNWVCAAKFESNFNTQATNRNTDGSTDYGILQINSRWWCNDGRTPGSRNLCNIPCSALLSSDITASVNCAKKIVSDGNGMNAWVAWRNRCKGTDVQAWIRGCRL",
24
+ "true_ss": "CCCHHHHHHHHHHHCCCCCCCCHHHHHHHHHHHCCCCEEEEEECCCCCCCHHHHHHHHHHHHCCCCCCCCCCCHHHHHHHHHHHHHHHHHHHHHCCCCCCEEEEEEEECCCHHHHHHHHHHHHHHHHHCC",
25
+ "description": "An antibacterial enzyme abundant in tears, saliva, and egg whites that hydrolyzes bacterial cell walls.",
26
+ "fun_fact": "Lysozyme was discovered by Alexander Fleming in 1921 when a drop of his nasal mucus accidentally fell into a bacterial culture dish!"
27
+ },
28
+ {
29
+ "name": "04. Human Insulin A-Chain (Hormone)",
30
+ "sequence": "GIVEQCCTSICSLYQLENYCN",
31
+ "true_ss": "CCCHHHHHHHHHHHHHHHCCC",
32
+ "description": "The smaller of the two peptide chains comprising insulin, linked by disulfide bridges.",
33
+ "fun_fact": "Insulin was the very first protein ever to have its complete amino acid sequence determined, earning Frederick Sanger the Nobel Prize in 1958."
34
+ },
35
+ {
36
+ "name": "05. Human Insulin B-Chain (Hormone)",
37
+ "sequence": "FVNQHLCGSHLVEALYLVCGERGFFYTPKT",
38
+ "true_ss": "CCCCCCCCHHHHHHHHHHHHCCCCEEEECC",
39
+ "description": "The longer 30-amino-acid chain of insulin that triggers glucose uptake in fat and muscle cells.",
40
+ "fun_fact": "Synthetic human insulin created via recombinant DNA in 1978 was the first ever genetically engineered human medicine."
41
+ },
42
+ {
43
+ "name": "06. Green Fluorescent Protein (GFP Core Segment)",
44
+ "sequence": "MSKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTLVTTFSYGVQCFSRYPDHMKQHDFFKSAMPEGYVQERTIFFKDDGNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYIMADKQKNGIKVNFKIRHNIEDGSVQLADHYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLLEFVTAAGITHGMDELYK",
45
+ "true_ss": "CCCCCCEEEEEEEEEEEECCCCCCEEEEEEEECCCCCCEEEEEEEEEEEECCCCEEEEEEEEEEEEEEECCCCCHHHHHHHHHHHHHHCCCCEEEEEEEEECCCEEEEEEEEECCCCEEEEEEEEEEEEECCCCCCEEEEEEEEEECCCCCCCEEEEEEEEEEEECCCCCCEEEEEEEEECCCCCCEEEEEEEEEEECCCCCHHHHHHHHHHHCCCEEEEEEEECCCCCC",
46
+ "description": "The bioluminescent protein from the jellyfish Aequorea victoria featuring a classic 11-stranded beta-barrel.",
47
+ "fun_fact": "GFP acts as a microscopic lantern—attaching it to other proteins allows scientists to watch living cells function in real time under blue light!"
48
+ },
49
+ {
50
+ "name": "07. Human Hemoglobin Alpha Chain",
51
+ "sequence": "VLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTTKTYFPHFDLSHGSAQVKGHGKKVADALTNAVAHVDDMPNALSALSDLHAHKLRVDPVNFKLLSHCLLVTLAAHLPAEFTPAVHASLDKFLASVSTVLTSKYR",
52
+ "true_ss": "CCCCCCCHHHHHHHHHHHCCCCHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHCHHHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHCCCHHHHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHHHHHH",
53
+ "description": "Subunit of the tetrameric hemoglobin protein responsible for transporting oxygen from lungs to tissues.",
54
+ "fun_fact": "A single human red blood cell contains approximately 270 million hemoglobin molecules!"
55
+ },
56
+ {
57
+ "name": "08. Cytochrome c (Mitochondrial Electron Carrier)",
58
+ "sequence": "MGDVEKGKKIFIMKCSQCHTVEKGGKHKTGPNLHGLFGRKTGQAPGYSYTAANKNKGIIWGEDTLMEYLENPKKYIPGTKMIFVGIKKKEERADLIAYLKKATNE",
59
+ "true_ss": "CCCCCCCCHHHHHHHHCCCCCCCCCCCCCCCHHHHHHHCCCCCCCCHHHHHHHCCCCCHHHHHHHHHHHHHCCCCCEEEEEEECCCCCHHHHHHHHHHHHHHCCC",
60
+ "description": "An essential component of the mitochondrial electron transport chain that triggers apoptosis when released into the cytosol.",
61
+ "fun_fact": "Cytochrome c is so evolutionarily conserved that human cytochrome c can react with enzyme extracts from baker's yeast!"
62
+ },
63
+ {
64
+ "name": "09. Bovine Ribonuclease A (RNA Cleavage Enzyme)",
65
+ "sequence": "KETAAAKFERQHMDSSTSAASSSNYCNQMMKSRNLTKDRCKPVNTFVHESLADVQAVCSQKNVACKNGQTNCYQSYSTMSITDCRETGSSKYPNCAYKTTQANKHIIVACEGNPYVPVHFDASV",
66
+ "true_ss": "CCCCHHHHHHHHHCCCCCCCHHHHHHHHHHCCCCEEECCCCCHHHHHHHHHHHHHHHCCCCEEEECCCCCEEEEEEEECCCCCCEEEECCCCCEEEEECCCCCEEEEEEEECCCCCCEEEEEE",
67
+ "description": "A pancreatic endonuclease model enzyme widely used in protein folding and refolding research.",
68
+ "fun_fact": "Ribonuclease A can withstand boiling water for short periods without permanently losing its enzymatic activity."
69
+ },
70
+ {
71
+ "name": "10. Streptavidin Core (Biotin Binding)",
72
+ "sequence": "EAGITGTWYNQLGSTFIVTAGADGALTGTYESAVGNAESRYVLTGRYDSAPATDGSGTALGWTVAWKNNYRNAHSATTWSGQYVGGAEARINTQWLLTSGTTEANAWKSTLVGHDTFTKVKPSAAS",
73
+ "true_ss": "CCCEEEEEEEEECCEEEEEEECCCEEEEEEEEECCCCEEEEEEEEECCCCEECCCCCCEEEEEEEEECCCEEEEEEEEECCCCEEEEEEEEECCCEEEEEEEEECCCEEEEEEECCCCCCCCCC",
74
+ "description": "A tetrameric protein from Streptomyces avidinii with extraordinary affinity for vitamin B7 (biotin).",
75
+ "fun_fact": "The bond between streptavidin and biotin is one of the strongest non-covalent interactions known in biological science!"
76
+ },
77
+ {
78
+ "name": "11. Alpha-Keratin Hair Fragment",
79
+ "sequence": "MSCNQSFTVRTCAPSNCSRPVCNIPANVCNIPANVCNIP",
80
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCC",
81
+ "description": "Fibrous structural protein that makes up human hair, outer skin layers, and fingernails.",
82
+ "fun_fact": "The distinct smell of burning hair is caused by sulfur dioxide released when disulfide bonds in keratin are scorched!"
83
+ },
84
+ {
85
+ "name": "12. Human Collagen Type I Fragment",
86
+ "sequence": "PPGPPGPPGPPGPPGPPGPPGPPGPPGPPGPPGPPGPPG",
87
+ "true_ss": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
88
+ "description": "The main component of connective tissue, forming elongated triple-helical collagen fibrils.",
89
+ "fun_fact": "Gram for gram, type I collagen fibers in human tendons are stronger than structural steel!"
90
+ },
91
+ {
92
+ "name": "13. Aquaporin-1 Transmembrane Loop Segment",
93
+ "sequence": "FGLSVALAVLLALAVFGLSVALAVLLALAVFGLSVALAV",
94
+ "true_ss": "CHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHC",
95
+ "description": "Water channel membrane protein that selectively conducts water molecules in and out of cells.",
96
+ "fun_fact": "Aquaporin channels allow up to 3 billion water molecules to pass through in a single second while blocking protons!"
97
+ },
98
+ {
99
+ "name": "14. Zinc Finger Cys2His2 DNA Domain",
100
+ "sequence": "YKCPECGKSFSQKSDLVKHQRTHTGEKPYKCPECGKSFSQ",
101
+ "true_ss": "CCEEEEECCCHHHHHHHHHHHHCCCCCEEEEECCCHHHHH",
102
+ "description": "Small protein motif characterized by the coordination of one or more zinc ions to stabilize folds.",
103
+ "fun_fact": "Zinc finger proteins are the most abundant class of transcription factors found in the human genome!"
104
+ },
105
+ {
106
+ "name": "15. E. coli Thioredoxin (Redox Control Engine)",
107
+ "sequence": "SDKIIHLTDDSFDTDVLKADGAILVDFWAEWCGPCKMIAPILDEIADEYQGKLTVAKLNIDQNPGTAPKYGIRGIPTLLLFKNGEVAATKVGALSKGQLKEFLDANLA",
108
+ "true_ss": "CCEEEEEECCCCCCCHHHHCCCEEEEEEECCCCCHHHHHHHHHHHHHHHCCCCEEEEEECCCCCCCHHHHHCCCEEEEEECCCCEEEEEECCCHHHHHHHHHHHHHHC",
109
+ "description": "Essential antioxidant enzyme that facilitates the reduction of other proteins by cysteine-thiol exchange.",
110
+ "fun_fact": "Thioredoxin acts as an anti-aging cellular guardian by repairing oxidative damage to essential intracellular proteins."
111
+ },
112
+ {
113
+ "name": "16. Calmodulin (Calcium Sensor)",
114
+ "sequence": "MADQLTEEQIAEFKEAFSLFDKDGDGTITTKELGTVMRSLGQNPTEAELQDMINEVDADGNGTIDFPEFLTMMARKMKDTDSEEEIREAFRVFDKDGNGYISAAELRHVMTSLGEKLTDEEVDEMIREADIDGDGQVNYEEFVQMMTAK",
115
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHCCCCCCCHHHHHHHHHHHHCCCCCHHHHHHHHHHHHCCCCCCCHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHCCCCCCCHHHHHHHHHHHHCCCCCHHHHHHHHHHHHCCCCCCCHHHHHHHHC",
116
+ "description": "Calcium-modulated protein that transduces calcium signals upon binding to second messenger Ca2+ ions.",
117
+ "fun_fact": "Calmodulin undergoes a dramatic physical shape change upon binding calcium—wrapping around target enzymes like a flexible dumbbell!"
118
+ },
119
+ {
120
+ "name": "17. Bacteriophage T4 Lysozyme",
121
+ "sequence": "MNIFEMLRIDEGLRLKIYKDTEGYYTIGIGHLLTKSPSLNAAKSELDKAIGRNTNGVITKDEAEKLFNQDVDAAVRGILRNAKLKPVYDSLDAVRRAALINMVFQMGETGVAGFTNSLRMLQQKRWDEAAVNLAKSRWYNQTPNRAKRVITTFRTGTWDAYK",
122
+ "true_ss": "CCHHHHHHHHCCEEEEEEECCCEEEEEEECCCCHHHHHHHHHHHHHHHHHHHCCCCCCCCHHHHHHHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHCCCCCCCHHHHHHHHHHHHHHHHHHCCCCHHHHHCCCCCCCEEEEEEECCCCCC",
123
+ "description": "Lytic enzyme used by bacteriophage T4 to puncture bacterial walls during viral invasion.",
124
+ "fun_fact": "T4 lysozyme is one of the most thoroughly engineered proteins in history, with over 1,000 mutant variants created to study protein stability."
125
+ },
126
+ {
127
+ "name": "18. Triosephosphate Isomerase (TIM Barrel Prototype)",
128
+ "sequence": "APRKFFVGGNWKMNGDKKSLGELIHTLNGAKLSADTEVVCGAPSIYLDFARQKLDAKIGVAAQNCYKVPKGAFTGEISPAMIKDIGAAWVILGHSERRHVFGESDELIGQKVAHALAEGLGVIACIGEKLDEREAGITEKVVFEQTKVIADNVKDWSKVVLAYEPVWAIGTGKTATPQQAQEVHEKLRGWLKSNVSDAVAQSTRIIYGGSVTGATCKELASQPDVDGFLVGGASLKPEFVDIINAKQ",
129
+ "true_ss": "CCCEEEEECCCHHHHHHHHCCCCEEEEEECCCHHHHHHHCCCEEEEEECCCHHHHHHHHHHHCCCCCEEEEECCCCCHHHHHHHHHHHCEEEEECCCCCCCHHHHHHHHHHHHHHHCCCEEEEEECCCCCCCHHHHHHHHHHHHHCCCEEEEEEECCCCCHHHHHHHHHHHCCCEEEEEECCCCCCCHHHHHHHHHHHHHHCCCCEEEEEECCCCCHHHHHHHHHHHCCCEEEEEEECCCCCHHHH",
130
+ "description": "Enzyme in glycolysis featuring the famous (alpha/beta)8 TIM barrel fold motif.",
131
+ "fun_fact": "TIM isomerase is a 'catalytically perfect' enzyme—it accelerates reactions so fast that every single collision between enzyme and substrate results in a reaction!"
132
+ },
133
+ {
134
+ "name": "19. Concanavalin A (Lectin Beta-Sheet Sandwich)",
135
+ "sequence": "ADTIVAVELDTYPNTDIGDPSYPHIGIDIKSVRSKKTAKWNMQNGKVGTAHIIYNSVDKRLSAVVSYPNADATSVSYDVDLNDVLPEWVRVGLSASTGLYKETNTILSWSFTSKLKSNSTHETNALHFMFNQFSKDQKDLILQGDATTGTDGNLELTRVSSNGSPQGSSVGRALFYAPVHIWESSAVVASFDATFTFLIKSPDSHPADGIAFFISNIDSSIPSGSTGRLLGLFPDAN",
136
+ "true_ss": "CCEEEEEEEECCCCCCEECCCCEEEEEEEEEECCEEEEEEEECCCCCEEEEEEEEECCCEEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEEECCC",
137
+ "description": "Carbohydrate-binding lectin plant protein isolated from jack beans.",
138
+ "fun_fact": "Concanavalin A was the first plant lectin to be purified and crystallized on a large commercial scale."
139
+ },
140
+ {
141
+ "name": "20. Human Cytochrome P450 3A4 Segment",
142
+ "sequence": "MALIPDLAMETWLLLAVSLVLLYLYGTHSHGLFKKLGIPGPTPLPFLGNILSYHKGFCMFDMECHKKYGKVWGFYDGRQPVLAITDPDMVKTVLVKECYSFTNRRPFGPVGFMKSAISIAEDEEWKRLRSLLSPTFTSGKLKEMVPIIAQYGDVLVRNLRREAETGKPVTLKDVFGAYSMDVITSTSFGVNIDSLNNPQDPFVENTKKLLRFDFLDPFFLSITVFPFLIPILEVLNICVFPREVTNFLRKSVKRMKESRLEDTQKHRVDFLQLMIDNSNSKETESHKALSDLELVAQSIIFIFAGYETTSSVLSFIMYELATHPDVQQKLQEEIDAVLPNKAPPTYDTVLQMEYLDMVVNETLRLFPVAMRLERVCKKDVEINGMFIPKGVVVMIPSYALHRDPKYWTEPEKFLPERFSKKNKDNIDPYIYTPFGSGPRNCIGMRFALMNMKLALIRVLQNFSFKPCKETQIPLKLSLGGLLQPEKPVVLKVESRDGTVSGA",
143
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHC",
144
+ "description": "The primary hepatic enzyme responsible for metabolizing over 50% of all prescribed clinical drugs.",
145
+ "fun_fact": "Grapefruit juice inhibits Cytochrome P450 3A4, which can dangerously increase drug concentrations in the bloodstream!"
146
+ },
147
+ {
148
+ "name": "21. Bovine Pancreatic Trypsin Inhibitor (BPTI)",
149
+ "sequence": "RPDFCLEPPYTGPCKARIIRYFYNAKAGLCQTFVYGGCRAKRNNFKSAEDCMRTCGGA",
150
+ "true_ss": "CCCEEEECCCCCCCEEEEEEEEEEECCCCCEEEEEEEEEEECCCCCHHHHHHHHHCCC",
151
+ "description": "Small globular protein studied extensively as a canonical benchmark model for computational protein folding.",
152
+ "fun_fact": "BPTI binds to trypsin so tightly that it takes over 100 years for half of the bound molecules to spontaneously dissociate!"
153
+ },
154
+ {
155
+ "name": "22. Crambin (Plant Seed Hydrophobic Protein)",
156
+ "sequence": "TTCCPSIVARSNFNVCRLPGTPEAICATYTGCIIIPGATCPGDYAN",
157
+ "true_ss": "CCCHHHHHHHHHHCCCCEEEECCCCEEEECCCCCCCCCCCCCCCCC",
158
+ "description": "A small 46-residue plant seed protein famous for yielding ultra-high-resolution X-ray diffraction patterns.",
159
+ "fun_fact": "Crambin crystals diffract X-rays so cleanly that scientists determined the positions of individual hydrogen atoms in 1980!"
160
+ },
161
+ {
162
+ "name": "23. Alpha-Conotoxin (Cone Snail Venom Peptide)",
163
+ "sequence": "GCCSNPACMVNNPQIC",
164
+ "true_ss": "CCCCCHHHHHHCCCCC",
165
+ "description": "Neurotoxic disulfide-rich peptide produced by predatory marine cone snails to paralyze fish.",
166
+ "fun_fact": "Cone snail venom contains hundreds of unique conotoxins—some are currently used as non-opioid chronic pain killers!"
167
+ },
168
+ {
169
+ "name": "24. Bacillus amyloliquefaciens Barnase",
170
+ "sequence": "AQVINTFDGVADYLQTYHKLPDNYITKSEAQALGWVASKGNLADVAPGKSIGGDIFSNREGKLPGKSGRTWREADINYTSGFRNSDRILYSSDWLIYKTTDHYQTFTKIR",
171
+ "true_ss": "CCCEEEEECCCCCHHHHHHHHHCCCCEEEEEECCCEEEEEECCCCEEEEEECCCCEEEEEEEECCCCEEEEEEEECCCCEEEEEEECCCCCCCEEEEEEECCCEEEEEEEC",
172
+ "description": "Bacterial ribonuclease secreted by Bacillus amyloliquefaciens that is lethal to host cells without its inhibitor.",
173
+ "fun_fact": "Barnase is so lethal to bacteria that it can only be cloned inside cells that simultaneously synthesize its protective inhibitor, Barstar!"
174
+ },
175
+ {
176
+ "name": "25. Barstar (Barnase Ribonuclease Inhibitor)",
177
+ "sequence": "KKAVINGEQIRSISDLHQTLKKELALPEYYGENLDALWDCLTGWVEYPLVLEWRQFEQSKQLTENGAESVLQVFREAKAEGCDITIILS",
178
+ "true_ss": "CCEEEECCCHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHCCCCCCCEEEEEEECCCCCEEEEEEC",
179
+ "description": "Intracellular inhibitor protein produced to shield the host bacterium from internal barnase toxicity.",
180
+ "fun_fact": "The Barnase-Barstar complex is one of the tightest diffusion-controlled protein-protein interactions found in nature."
181
+ },
182
+ {
183
+ "name": "26. Chymotrypsin Inhibitor 2 (CI-2)",
184
+ "sequence": "KTEWPELVGKSVEEAKKVILQDKPEAQIIVLPVGTIVTMEYRIDRVRLFVDKLDNIAEVPRVG",
185
+ "true_ss": "CCCCCCCCCHHHHHHHHHHHHHCCCCEEEEEEECCCEEEEEEECCCCEEEEEEECCCEEEEEC",
186
+ "description": "Serine protease inhibitor from barley seeds widely utilized in biophysical nucleation-condensation folding studies.",
187
+ "fun_fact": "CI-2 folds via a simple two-state mechanism without any intermediate states, making it a favorite for folding simulations."
188
+ },
189
+ {
190
+ "name": "27. Green Tea Polyphenol Oxidase Fragment",
191
+ "sequence": "MDFLKKVAVIGAGVSGLISAYEMLKQEGHDVTVFEA",
192
+ "true_ss": "CCHHHHHCCCEEEEEEEEEEHHHHHHCCCCEEEEEE",
193
+ "description": "Copper-containing enzyme in tea leaves responsible for enzymatic browning during green-to-black tea oxidation.",
194
+ "fun_fact": "Heating green tea leaves (steaming or pan-firing) deactivates polyphenol oxidase, locking in green color and fresh taste!"
195
+ },
196
+ {
197
+ "name": "28. Spider Silk Spidroin N-Terminal Domain",
198
+ "sequence": "MSNTLALRGGFAATSQADANLASSISTASNSAASASTA",
199
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCC",
200
+ "description": "Control domain regulating the liquid-to-solid phase transition when spiders spin dragline silk threads.",
201
+ "fun_fact": "Spider dragline silk is five times stronger than steel by weight and can stretch 30% without snapping!"
202
+ },
203
+ {
204
+ "name": "29. Human Serum Albumin Domain I",
205
+ "sequence": "DAHKSEVAHRFKDLGEENFKALVLIAFAQYLQQCPFEDHVKLVNEVTEFAKTCVADESAENCDKSLHTLFGDKLCTVATLRETYGEMADCCAKQEPERNECFLQHKDDNPNLPPF",
206
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCCCCCCCCCCCCC",
207
+ "description": "The major circulating transport protein in human plasma, maintaining oncotic pressure and carrying hormones.",
208
+ "fun_fact": "Serum albumin makes up roughly half of all protein dissolved in human blood plasma!"
209
+ },
210
+ {
211
+ "name": "30. Bacteriorhodopsin Helix A",
212
+ "sequence": "PEWIWLALGTALMGLGTLYFLVKGMGVSDPDAKKFYAITTLVPAIAFTMYLSMLLGYGLTMVPFGG",
213
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCC",
214
+ "description": "Light-driven proton pump protein found in halophilic archaea that converts sunlight into cellular energy.",
215
+ "fun_fact": "Bacteriorhodopsin gives purple salt flats their intense violet-pink color!"
216
+ },
217
+ {
218
+ "name": "31. Antifreeze Protein Type I (Winter Flounder)",
219
+ "sequence": "DTASDAAAAAALTAANAKAAAELTAANAAAAAAATAR",
220
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCC",
221
+ "description": "Alanine-rich amphipathic single alpha-helix that prevents ice crystal growth in arctic fish blood.",
222
+ "fun_fact": "Antifreeze proteins bind directly to microscopic ice crystals, stopping them from growing and freezing fish blood solid!"
223
+ },
224
+ {
225
+ "name": "32. Firefly Luciferase Fragment",
226
+ "sequence": "MEDAKNIKKGPAPFYPLEDGTAGEQLHKAMKRYALVP",
227
+ "true_ss": "CCHHHHHHHHHHHCCCCCCCHHHHHHHHHHHHHHCCC",
228
+ "description": "Light-emitting enzyme that catalyzes the oxidation of luciferin in fireflies to generate bioluminescent glow.",
229
+ "fun_fact": "Firefly bioluminescence is 100% efficient—almost all energy is converted to light with virtually zero waste heat!"
230
+ },
231
+ {
232
+ "name": "33. Green Sea Turtle Myoglobin Segment",
233
+ "sequence": "GLSDGEWQLVLNVWGKVEADIPGHGQEVLIRLFKGHPETL",
234
+ "true_ss": "CCCCCCCCCHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHH",
235
+ "description": "Specialized oxygen binder enabling sea turtles to stay submerged during deep oceanic feeding dives.",
236
+ "fun_fact": "Sea turtles can rest underwater for up to 5 hours at a time by slowing their heart rates down to 1 beat every 9 minutes!"
237
+ },
238
+ {
239
+ "name": "34. SARS-CoV-2 Spike Receptor Binding Domain (RBD)",
240
+ "sequence": "RVQPTESIVRFPNITNLCPFGEVFNATRFASVYAWNRKRISNCVADYSVLYNSASFSTFKCYGVSPTKLNDLCFTNVYADSFVIRGDEVRQIAPGQTGKIADYNYKLPDDFTGCVIAWNSNNLDSKVGGNYNYLYRLFRKSNLKPFERDISTEIYQAGSTPCNGVEGFNCYFPLQSYGFQPTNGVGYQPYRVVVLSFELLHAPATVCGPKKSTNLVKNKCVNF",
241
+ "true_ss": "CCEEEEEEEECCCCCCEEEEEEEEEECCCEEEEEEECCCCCEEEEEEECCCCCEEEEEEEEEEECCCCCCCEEEEEEEEEEECCCCCEEEEEEECCCCCCCEEEEEEEEEEECCCCCCCEEEEEEEEEEECCCCCEEEEEEECCCCCCCEEEEEEEEEEEEECCCCCEEEEEEEEEEECCCCCCCEEEEEEEEEEECCCCCCCEEEEEEEEEEECCCCCEEEEEECCCCCCCCC",
242
+ "description": "The viral protein domain that docks directly onto human ACE2 receptors to initiate host cell infection.",
243
+ "fun_fact": "Neutralizing antibodies generated by mRNA vaccines specifically target this tiny RBD domain on the spike protein surface!"
244
+ },
245
+ {
246
+ "name": "35. CRISPR-Cas9 Bridge Helix Fragment",
247
+ "sequence": "RKYLIGLNIGTNSVGWAVITDEYKVPSKKFKVLGNTDRHSIKKNLIGALLLFD",
248
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCC",
249
+ "description": "Critical structural bridge helix connecting RuvC and REC domains in Cas9 gene-editing complexes.",
250
+ "fun_fact": "CRISPR was originally discovered as an adaptive bacterial immune system used to destroy invading bacteriophage DNA!"
251
+ },
252
+ {
253
+ "name": "36. Human Alpha-Synuclein (Parkinson's Domain)",
254
+ "sequence": "MDVFMKGLSKAKEGVVAAAEKTKQGVAEAAGKTKEGVLYVGSKTKEGVVHGVATVAEKTKEQVTNVGGAVVTGVTAVAQKTVEGAGSIAAATGFVKKDQLGKNEEGAPQEGILEDMPVDPDNEAYEMPSEEGYQDYEPEA",
255
+ "true_ss": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
256
+ "description": "An intrinsically disordered protein that can misfold into toxic Lewy body aggregates in Parkinson's disease.",
257
+ "fun_fact": "In its native monomeric state inside neurons, alpha-synuclein behaves like a completely unfolded, flexible noodle!"
258
+ },
259
+ {
260
+ "name": "37. Amyloid Beta 1-42 (Alzheimer's Peptide)",
261
+ "sequence": "DAEFRHDSGYEVHHQKLVFFAEDVGSNKGAIIGLMGGVVIA",
262
+ "true_ss": "CCCCCCCCCCCCCCEEEEEEEEEECCCCCEEEEEEEEEEECC",
263
+ "description": "The neurotoxic peptide segment that aggregates into beta-sheet fibrillar plaques in Alzheimer's disease.",
264
+ "fun_fact": "Cleaving just two extra amino acids off Amyloid Beta 1-40 transforms it into 1-42, dramatically speeding up toxic plaque formation!"
265
+ },
266
+ {
267
+ "name": "38. Human Growth Hormone (hGH Helix 1)",
268
+ "sequence": "FPTIPLSRLFDNAMLRAHRLHQLAFDTYQEFEEAYIPKEQKYSFLQNPQTSLCFSESIPTPSNREETQQKSNLELLRISLLLIQSWLEPVQFLRSVFANSLVYGASDSNVYDLLKDLEEGIQTLMGRLEDGSPRTGQIFKQTYSKFDTNSHNDDALLKNYGLLYCFRKDMDKVETFLRIVQCRSVEGSCGF",
269
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCCCCCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCCC",
270
+ "description": "Pituitary peptide hormone that stimulates growth, cell reproduction, and physical regeneration.",
271
+ "fun_fact": "Recombinant human growth hormone (hGH) is widely used in pediatric medicine to treat severe growth hormone deficiency."
272
+ },
273
+ {
274
+ "name": "39. Epidermal Growth Factor (EGF)",
275
+ "sequence": "NSDSECPLSHDGYCLHDGVCMYIEALDKYACNCVVGYIGERCQYRDLWWELR",
276
+ "true_ss": "CCCEEEEECCCCCCEEEEEECCCCCEEEEEECCCCCEEEEEECCCCCCCCCC",
277
+ "description": "Small peptide growth factor that stimulates cell proliferation, differentiation, and survival by binding EGF receptors.",
278
+ "fun_fact": "EGF was discovered by Stanley Cohen in 1962, who noticed it accelerated tooth eruption and eyelid opening in newborn mice!"
279
+ },
280
+ {
281
+ "name": "40. Human Parathyroid Hormone (PTH 1-34)",
282
+ "sequence": "SVSEIQLMHNLGKHLNSMERVEWLRKKLQDVHNF",
283
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCC",
284
+ "description": "The essential N-terminal domain of PTH regulating systemic serum calcium concentration.",
285
+ "fun_fact": "Intermittent daily injections of PTH actually stimulate bone formation and are used clinically to reverse severe osteoporosis!"
286
+ },
287
+ {
288
+ "name": "41. Glucagon-like Peptide 1 (GLP-1 7-36)",
289
+ "sequence": "HAEGTFTSDVSSYLEGQAAKEFIAWLVKGRG",
290
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHCC",
291
+ "description": "Incretin metabolic peptide hormone that stimulates insulin secretion, serving as the basis for GLP-1 receptor agonist drugs.",
292
+ "fun_fact": "GLP-1 receptor agonist medications (like Semaglutide/Ozempic) mimic this exact peptide sequence to regulate blood sugar!"
293
+ },
294
+ {
295
+ "name": "42. Melittin (Honeybee Venom Main Peptide)",
296
+ "sequence": "GIGAVLKVLTTGLPALISWIKRKRQQ",
297
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHCC",
298
+ "description": "Principal toxic component of European honeybee venom that forms pores in cell membranes.",
299
+ "fun_fact": "Melittin makes up 50% of the dry weight of honeybee venom and is responsible for the sharp burning sensation of a bee sting!"
300
+ },
301
+ {
302
+ "name": "43. Magainin 2 (African Clawed Frog Peptide)",
303
+ "sequence": "GIGKFLHSAKKFGKAFVGEIMNS",
304
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHCC",
305
+ "description": "Antimicrobial amphipathic alpha-helical peptide secreted from frog skin to kill bacteria and fungi.",
306
+ "fun_fact": "African clawed frogs can live in murky, bacteria-laden water with open wounds without getting infected thanks to magainins!"
307
+ },
308
+ {
309
+ "name": "44. Human Beta-Defensin 2 (HBD-2)",
310
+ "sequence": "GIGDPVTCLKSGAICHPVFCPRRYKQIGTCGLPGTKCCKKP",
311
+ "true_ss": "CCCEEEEEECCCCEEEEEECCCCCEEEEEECCCCCCCCCCC",
312
+ "description": "Epithelial host-defense antimicrobial peptide that ruptures bacterial cell membranes.",
313
+ "fun_fact": "Defensins are ancient molecular weapons found across all plants, insects, animals, and humans!"
314
+ },
315
+ {
316
+ "name": "45. Cobra Cardiotoxin V4 (Beta-Sheet Venom)",
317
+ "sequence": "LKCNKLVPLFYKTCPAGKNLCYKMFMVATPKVPVKRGCIDVCPKSSLLVKYVCCNTDRCN",
318
+ "true_ss": "CCCEEEEECCCCCEEEEECCCCCCEEEEEECCCCCCEEEEEECCCCCEEEEEECCCCCCC",
319
+ "description": "Pore-forming cardiotoxic peptide present in Naja cobra venom that causes heart muscle depolarization.",
320
+ "fun_fact": "Cobra cardiotoxins act within minutes by poking holes in cardiac muscle membranes, causing rapid heart arrest."
321
+ },
322
+ {
323
+ "name": "46. Apamin (Honeybee Neurotoxin)",
324
+ "sequence": "CNCKAPETALCARRCQQH",
325
+ "true_ss": "CCCCHHHHHHHHHHHCCC",
326
+ "description": "Small 18-amino-acid peptide neurotoxin in bee venom that selectively blocks Ca2+-activated potassium channels.",
327
+ "fun_fact": "Apamin is so small that it can cross the human blood-brain barrier!"
328
+ },
329
+ {
330
+ "name": "47. Viscotoxin A3 (Mistletoe Plant Toxin)",
331
+ "sequence": "KSCCRNTTARNCYNVCRFAGTGREICAKKCDIIKGIKMEAMLCAKTCGKRETCP",
332
+ "true_ss": "CCCHHHHHHHHHHCCCCEEEECCCCEEEECCCCCHHHHHHHHHHCCCCCCCCCC",
333
+ "description": "Cytotoxic thionin protein isolated from European mistletoe leaves.",
334
+ "fun_fact": "Mistletoe viscotoxins evolved as natural chemical weapons to prevent birds and herbivores from eating the plant's stems!"
335
+ },
336
+ {
337
+ "name": "48. Cecropin A (Silk Moth Antibacterial)",
338
+ "sequence": "KWKLFKKIEKVGQNIRDGIIKAGPAVAVVGQATQIAK",
339
+ "true_ss": "CCHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHCCC",
340
+ "description": "Linear lytic peptide expressed in silk moth pupae upon bacterial infection.",
341
+ "fun_fact": "Cecropins punch lethal holes in bacterial membranes while leaving human red blood cells unharmed!"
342
+ },
343
+ {
344
+ "name": "49. Kalata B1 (Macrocyclic Plant Cyclotide)",
345
+ "sequence": "GLPVCGETCFGGTCNTPGCTCSWPVCTRN",
346
+ "true_ss": "CCCEEEEECCCCCCEEEEEECCCCEEEEC",
347
+ "description": "Head-to-tail cyclic plant defense peptide with a rigid disulfide cystine knot framework.",
348
+ "fun_fact": "Kalata B1 is so structurally indestructible that it survives boiling water and digestive stomach acids!"
349
+ },
350
+ {
351
+ "name": "50. Crambin Variant S22/I25 (High-Res Diffraction)",
352
+ "sequence": "TTCCPSIVARSNFNVCRLPGTPEASCAYTGCIIIPGATCPGDYAN",
353
+ "true_ss": "CCCHHHHHHHHHHCCCCEEEECCCCEEEECCCCCCCCCCCCCCCCC",
354
+ "description": "Natural isoform variant of crambin used for atomic-resolution crystallographic validation.",
355
+ "fun_fact": "Studying crambin's hydrophobic core helped biochemists understand how oil-repelling forces drive all protein folding!"
356
+ }
357
+ ]
358
+
359
+ # Quick lookup dict keyed by display name
360
+ PROTEIN_MAP = {p["name"]: p for p in PROTEIN_DATASET}
html_builder.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Builds the HTML visualization block shown after a prediction — the
3
+ sequence node grid, metrics cards, alignment view, and info/fun-fact card.
4
+ """
5
+ import html
6
+
7
+
8
+ def build_result_html(sequence, pred_str, true_ss=None, q3_score=None, description="", fun_fact=""):
9
+ """Renders the custom HTML result panel matching the app's design system."""
10
+
11
+ # 1. Interactive Node Grid (first 60 residues shown as scannable nodes)
12
+ grid_nodes_html = "<div class='sequence-grid'>"
13
+ display_limit = min(len(sequence), 60)
14
+
15
+ for i in range(display_limit):
16
+ aa = sequence[i]
17
+ st = pred_str[i]
18
+ grid_nodes_html += f"""
19
+ <div class="seq-node" data-state="{st}">
20
+ <span class="seq-aa">{aa}</span>
21
+ <span class="seq-state">{st}</span>
22
+ </div>
23
+ """
24
+ grid_nodes_html += "</div>"
25
+
26
+ if len(sequence) > 60:
27
+ grid_nodes_html += f"""
28
+ <p style='text-align: center; color: #8e8e93; font-size: 0.78rem; font-family: "JetBrains Mono"; margin-top: 12px;'>
29
+ + {len(sequence) - 60} additional amino acid residues sequence mapped below
30
+ </p>
31
+ """
32
+
33
+ # 2. Structure Composition Analysis
34
+ h_cnt, e_cnt, c_cnt = pred_str.count('H'), pred_str.count('E'), pred_str.count('C')
35
+ tot = max(len(pred_str), 1)
36
+ h_pct, e_pct, c_pct = (h_cnt / tot) * 100, (e_cnt / tot) * 100, (c_cnt / tot) * 100
37
+
38
+ # 3. Alignment Rows (Monospaced Sequence Alignment)
39
+ pred_align_html = ""
40
+ truth_align_html = ""
41
+
42
+ for i in range(len(sequence)):
43
+ p_char = pred_str[i]
44
+ if true_ss and i < len(true_ss):
45
+ t_char = true_ss[i]
46
+ if p_char == t_char:
47
+ pred_align_html += f"<span class='match'>{p_char}</span>"
48
+ else:
49
+ pred_align_html += f"<span class='miss'>{p_char}</span>"
50
+ truth_align_html += t_char
51
+ else:
52
+ pred_align_html += p_char
53
+
54
+ alignment_card_html = f"""
55
+ <div class="alignment-card">
56
+ {f'''
57
+ <div class="align-row">
58
+ <div class="row-label">Ground Truth</div>
59
+ <div class="row-seq">{truth_align_html}</div>
60
+ </div>
61
+ ''' if true_ss else ''}
62
+ <div class="align-row">
63
+ <div class="row-label">SERAPH Pred</div>
64
+ <div class="row-seq">{pred_align_html}</div>
65
+ </div>
66
+ <div class="align-row">
67
+ <div class="row-label">AA Sequence</div>
68
+ <div class="row-seq" style="color: #8e8e93;">{sequence}</div>
69
+ </div>
70
+ </div>
71
+ """
72
+
73
+ # 4. Metric Header Card
74
+ if q3_score is not None:
75
+ metrics_card_html = f"""
76
+ <div class="metrics-grid">
77
+ <div class="metric-card winner">
78
+ <div class="metric-value">{q3_score:.1f}%</div>
79
+ <div class="metric-label">Q3 Accuracy Score</div>
80
+ </div>
81
+ <div class="metric-card">
82
+ <div class="metric-value">{len(sequence)}</div>
83
+ <div class="metric-label">Residue Length</div>
84
+ </div>
85
+ </div>
86
+ """
87
+ else:
88
+ metrics_card_html = f"""
89
+ <div class="metrics-grid">
90
+ <div class="metric-card winner">
91
+ <div class="metric-value">{len(sequence)}</div>
92
+ <div class="metric-label">Residues Analyzed</div>
93
+ </div>
94
+ <div class="metric-card">
95
+ <div class="metric-value">{h_pct:.0f}% / {e_pct:.0f}% / {c_pct:.0f}%</div>
96
+ <div class="metric-label">Helix / Sheet / Coil</div>
97
+ </div>
98
+ </div>
99
+ """
100
+
101
+ # 5. Protein Info & Fun Fact Card
102
+ info_card_html = ""
103
+ if description or fun_fact:
104
+ info_card_html = f"""
105
+ <div style="background: rgba(255,255,255,0.025); border: 1px solid rgba(255,255,255,0.08); border-radius: 16px; padding: 24px; margin-top: 20px;">
106
+ {f'<p style="color: #f5f5f7; font-size: 0.92rem; margin-bottom: 12px; line-height: 1.5;"><strong>Overview:</strong> {html.escape(description)}</p>' if description else ''}
107
+ {f'<p style="color: #38bdf8; font-size: 0.88rem; background: rgba(56, 189, 248, 0.08); border: 1px solid rgba(56, 189, 248, 0.2); padding: 12px 16px; border-radius: 10px; margin-top: 8px;"><strong>💡 Fun Fact:</strong> {html.escape(fun_fact)}</p>' if fun_fact else ''}
108
+ </div>
109
+ """
110
+
111
+ # Full Combined Output Block
112
+ return f"""
113
+ <div style="animation: fadeIn 0.5s ease-out;">
114
+ {metrics_card_html}
115
+
116
+ <div class="sequence-board" style="margin-bottom: 24px;">
117
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
118
+ <span class="section-label" style="margin: 0;">Predicted Secondary Structure Mapping</span>
119
+ <div class="board-legend" style="margin: 0;">
120
+ <div class="legend-item"><div class="legend-dot h"></div> Helix (H) {h_cnt} ({h_pct:.0f}%)</div>
121
+ <div class="legend-item"><div class="legend-dot e"></div> Sheet (E) {e_cnt} ({e_pct:.0f}%)</div>
122
+ <div class="legend-item"><div class="legend-dot c"></div> Coil (C) {c_cnt} ({c_pct:.0f}%)</div>
123
+ </div>
124
+ </div>
125
+ {grid_nodes_html}
126
+ </div>
127
+
128
+ {alignment_card_html}
129
+ {info_card_html}
130
+ </div>
131
+ """
inference.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Loads the SERAPH model once at import time and exposes the prediction
3
+ and preset-change handlers used by the Gradio UI.
4
+ """
5
+ import spaces
6
+ import torch
7
+
8
+ from config import IDX_TO_LABEL
9
+ from dataset import PROTEIN_MAP
10
+ from html_builder import build_result_html
11
+ from model import load_model
12
+
13
+ model, tokenizer = load_model()
14
+
15
+
16
+ @spaces.GPU
17
+ def predict_structure(sequence_input: str, selected_protein_name: str) -> tuple:
18
+ """Runs ESM-2 + BiLSTM inference and builds the HTML visualization."""
19
+ sequence = sequence_input.upper().strip()
20
+ # Sanitize inputs to amino acid alphabet
21
+ valid_aas = set("ACDEFGHIKLMNPQRSTVWY")
22
+ sequence = "".join([c for c in sequence if c in valid_aas])
23
+
24
+ if not sequence:
25
+ empty_html = """
26
+ <div style='padding: 24px; text-align: center; background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.08); border-radius: 16px;'>
27
+ <p style='color: #8e8e93; font-family: "JetBrains Mono", monospace;'>Please enter a valid amino acid sequence (e.g., M K W V T F I S L L L L F S S A)...</p>
28
+ </div>
29
+ """
30
+ return empty_html, "", ""
31
+
32
+ # Model inference
33
+ tokens = tokenizer(sequence, return_tensors="pt", truncation=True, max_length=512)
34
+ with torch.no_grad():
35
+ output = model(input_ids=tokens["input_ids"], attention_mask=tokens["attention_mask"])
36
+ preds = output.argmax(dim=-1)[0]
37
+
38
+ # Extract predicted structure labels
39
+ pred_labels = [IDX_TO_LABEL[p.item()] for p in preds[1:-1]]
40
+ # Handle truncation alignment safely
41
+ pred_str = "".join(pred_labels[:len(sequence)])
42
+ if len(pred_str) < len(sequence):
43
+ pred_str += "C" * (len(sequence) - len(pred_str))
44
+
45
+ # Match with dataset ground truth if selected
46
+ meta = PROTEIN_MAP.get(selected_protein_name, None)
47
+ has_truth = False
48
+ true_ss = ""
49
+ description = ""
50
+ fun_fact = ""
51
+
52
+ if meta and meta["sequence"].upper() == sequence:
53
+ has_truth = True
54
+ true_ss = meta["true_ss"]
55
+ description = meta["description"]
56
+ fun_fact = meta["fun_fact"]
57
+
58
+ # Calculate Q3 Metric if Ground Truth matches
59
+ q3_score = None
60
+ if has_truth and len(true_ss) == len(sequence):
61
+ matches = sum(1 for i in range(len(sequence)) if pred_str[i] == true_ss[i])
62
+ q3_score = (matches / len(sequence)) * 100.0
63
+
64
+ html_output = build_result_html(sequence, pred_str, true_ss if has_truth else None, q3_score, description, fun_fact)
65
+
66
+ return html_output, sequence, pred_str
67
+
68
+
69
+ def on_preset_change(selected_name):
70
+ """Populates the sequence textbox when a preset dropdown item is chosen."""
71
+ if selected_name in PROTEIN_MAP:
72
+ item = PROTEIN_MAP[selected_name]
73
+ return item["sequence"]
74
+ return ""
model.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ SERAPH model architecture definition and weight-loading helper.
3
+ """
4
+ import torch
5
+ import torch.nn as nn
6
+ from huggingface_hub import hf_hub_download
7
+ from transformers import EsmModel, EsmTokenizer
8
+
9
+ from config import HF_REPO_ID, WEIGHTS_FILE, ESM_MODEL_ID
10
+
11
+
12
+ class SERAPH(nn.Module):
13
+ """ESM-2 backbone + Conv1D + BiLSTM head for 3-state secondary
14
+ structure prediction (Helix / Sheet / Coil)."""
15
+
16
+ def __init__(self, esm_model, conv_channels=256, kernel_size=7,
17
+ lstm_hidden=256, num_classes=3, dropout=0.3, freeze_esm=True):
18
+ super().__init__()
19
+ self.esm = esm_model
20
+ if freeze_esm:
21
+ for param in self.esm.encoder.layer[:-2].parameters():
22
+ param.requires_grad = False
23
+ esm_embed_dim = self.esm.config.hidden_size
24
+ self.conv = nn.Conv1d(esm_embed_dim, conv_channels, kernel_size=kernel_size, padding=kernel_size // 2)
25
+ self.bn = nn.BatchNorm1d(conv_channels)
26
+ self.dropout = nn.Dropout(dropout)
27
+ self.bilstm = nn.LSTM(conv_channels, lstm_hidden, num_layers=2, batch_first=True, bidirectional=True)
28
+ self.fc = nn.Linear(lstm_hidden * 2, num_classes)
29
+
30
+ def forward(self, input_ids, attention_mask=None):
31
+ x = self.esm(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state
32
+ x = x.transpose(1, 2)
33
+ x = torch.relu(self.bn(self.conv(x)))
34
+ x = self.dropout(x)
35
+ x = x.transpose(1, 2)
36
+ x, _ = self.bilstm(x)
37
+ x = self.dropout(x)
38
+ return self.fc(x)
39
+
40
+
41
+ def load_model():
42
+ """Downloads the ESM-2 backbone + tokenizer and the fine-tuned SERAPH
43
+ checkpoint, and returns a ready-to-use (model, tokenizer) pair."""
44
+ print("Loading ESM2 backbone...")
45
+ esm = EsmModel.from_pretrained(ESM_MODEL_ID)
46
+ tokenizer = EsmTokenizer.from_pretrained(ESM_MODEL_ID)
47
+
48
+ print("Downloading SERAPH weights...")
49
+ weights_path = hf_hub_download(repo_id=HF_REPO_ID, filename=WEIGHTS_FILE)
50
+ checkpoint = torch.load(weights_path, map_location="cpu")
51
+
52
+ model = SERAPH(esm_model=esm)
53
+ model.load_state_dict(checkpoint["model_state_dict"])
54
+ model.eval()
55
+ print("SERAPH model ready.")
56
+
57
+ return model, tokenizer
styles.py ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Custom CSS injected into the Gradio Blocks app to match the SERAPH
3
+ design system (dark glass UI, monospace sequence nodes, etc.).
4
+ """
5
+
6
+ CUSTOM_CSS = """
7
+ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Plus+Jakarta+Sans:wght@300;400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap');
8
+
9
+ :root {
10
+ --bg-base: #060608;
11
+ --bg-surface: rgba(255, 255, 255, 0.025);
12
+ --bg-surface-hover: rgba(255, 255, 255, 0.05);
13
+ --bg-glass: rgba(10, 10, 14, 0.78);
14
+ --border-subtle: rgba(255, 255, 255, 0.08);
15
+ --border-accent: rgba(255, 255, 255, 0.22);
16
+
17
+ --text-main: #f5f5f7;
18
+ --text-muted: #8e8e93;
19
+ --text-dim: #55555a;
20
+ --accent-glow: rgba(255, 255, 255, 0.15);
21
+ --success-green: #10b981;
22
+
23
+ --color-h: #fb7185;
24
+ --bg-h: rgba(251, 113, 133, 0.15);
25
+ --color-e: #38bdf8;
26
+ --bg-e: rgba(56, 189, 248, 0.15);
27
+ --color-c: #94a3b8;
28
+ --bg-c: rgba(148, 163, 184, 0.15);
29
+
30
+ --font-heading: 'Space Grotesk', -apple-system, sans-serif;
31
+ --font-body: 'Plus Jakarta Sans', -apple-system, sans-serif;
32
+ --font-mono: 'JetBrains Mono', ui-monospace, monospace;
33
+ }
34
+
35
+ body, .gradio-container {
36
+ background-color: var(--bg-base) !important;
37
+ color: var(--text-main) !important;
38
+ font-family: var(--font-body) !important;
39
+ max-width: 900px !important;
40
+ margin: 0 auto !important;
41
+ padding: 20px !important;
42
+ }
43
+
44
+ /* Headers */
45
+ .hero-title {
46
+ font-family: var(--font-heading);
47
+ font-size: 2.2rem;
48
+ font-weight: 700;
49
+ letter-spacing: -0.03em;
50
+ background: linear-gradient(180deg, #ffffff 0%, rgba(255, 255, 255, 0.7) 100%);
51
+ -webkit-background-clip: text;
52
+ -webkit-text-fill-color: transparent;
53
+ margin-bottom: 8px;
54
+ text-align: center;
55
+ }
56
+
57
+ .hero-subtitle {
58
+ color: var(--text-muted);
59
+ text-align: center;
60
+ font-size: 0.95rem;
61
+ margin-bottom: 28px;
62
+ }
63
+
64
+ /* Back-to-portfolio button */
65
+ .back-to-portfolio {
66
+ display: inline-flex;
67
+ align-items: center;
68
+ gap: 6px;
69
+ font-family: var(--font-mono);
70
+ font-size: 0.78rem;
71
+ font-weight: 500;
72
+ color: var(--text-muted) !important;
73
+ text-decoration: none !important;
74
+ background: rgba(255, 255, 255, 0.04);
75
+ border: 1px solid var(--border-subtle);
76
+ border-radius: 99px;
77
+ padding: 6px 14px;
78
+ transition: all 0.2s ease;
79
+ }
80
+
81
+ .back-to-portfolio:hover {
82
+ color: var(--text-main) !important;
83
+ border-color: var(--border-accent);
84
+ background: rgba(255, 255, 255, 0.08);
85
+ }
86
+
87
+ /* Custom Gradio Textbox & Dropdown Overrides */
88
+ .gradio-container textarea, .gradio-container input, .gradio-container select {
89
+ background: rgba(255, 255, 255, 0.03) !important;
90
+ border: 1px solid var(--border-subtle) !important;
91
+ border-radius: 12px !important;
92
+ color: var(--text-main) !important;
93
+ font-family: var(--font-mono) !important;
94
+ }
95
+
96
+ .gradio-container textarea:focus, .gradio-container input:focus {
97
+ border-color: var(--border-accent) !important;
98
+ box-shadow: 0 0 12px var(--accent-glow) !important;
99
+ }
100
+
101
+ /* Action Buttons */
102
+ .btn-magnetic {
103
+ background: #ffffff !important;
104
+ color: #000000 !important;
105
+ border-radius: 99px !important;
106
+ font-weight: 600 !important;
107
+ font-size: 0.9rem !important;
108
+ border: none !important;
109
+ padding: 12px 28px !important;
110
+ cursor: pointer !important;
111
+ transition: all 0.25s ease !important;
112
+ }
113
+
114
+ .btn-magnetic:hover {
115
+ box-shadow: 0 0 24px var(--accent-glow) !important;
116
+ transform: translateY(-1px);
117
+ }
118
+
119
+ /* Sequence Node Visualizer Grid */
120
+ .sequence-board {
121
+ background: var(--bg-surface);
122
+ border: 1px solid var(--border-subtle);
123
+ border-radius: 20px;
124
+ padding: 24px;
125
+ }
126
+
127
+ .sequence-grid {
128
+ display: flex;
129
+ flex-wrap: wrap;
130
+ gap: 8px;
131
+ justify-content: center;
132
+ }
133
+
134
+ .seq-node {
135
+ background: rgba(255, 255, 255, 0.02);
136
+ border: 1px solid var(--border-subtle);
137
+ border-radius: 10px;
138
+ width: 38px;
139
+ height: 58px;
140
+ display: flex;
141
+ flex-direction: column;
142
+ align-items: center;
143
+ justify-content: space-between;
144
+ padding: 6px 0;
145
+ user-select: none;
146
+ }
147
+
148
+ .seq-aa {
149
+ font-family: var(--font-heading);
150
+ font-weight: 600;
151
+ font-size: 1rem;
152
+ color: var(--text-main);
153
+ }
154
+
155
+ .seq-state {
156
+ font-family: var(--font-mono);
157
+ font-size: 0.68rem;
158
+ font-weight: 600;
159
+ width: 22px;
160
+ height: 22px;
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ border-radius: 6px;
165
+ }
166
+
167
+ .seq-node[data-state="C"] .seq-state { background: var(--bg-c); color: var(--color-c); }
168
+ .seq-node[data-state="H"] .seq-state { background: var(--bg-h); color: var(--color-h); }
169
+ .seq-node[data-state="E"] .seq-state { background: var(--bg-e); color: var(--color-e); }
170
+
171
+ /* Board Legend */
172
+ .board-legend {
173
+ display: flex;
174
+ gap: 16px;
175
+ font-size: 0.8rem;
176
+ color: var(--text-muted);
177
+ }
178
+ .legend-item { display: flex; align-items: center; gap: 6px; }
179
+ .legend-dot { width: 8px; height: 8px; border-radius: 50%; }
180
+ .legend-dot.c { background: var(--color-c); }
181
+ .legend-dot.h { background: var(--color-h); }
182
+ .legend-dot.e { background: var(--color-e); }
183
+
184
+ /* Metrics & Alignment Cards */
185
+ .metrics-grid {
186
+ display: grid;
187
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
188
+ gap: 16px;
189
+ margin-bottom: 20px;
190
+ }
191
+
192
+ .metric-card {
193
+ background: var(--bg-surface);
194
+ border: 1px solid var(--border-subtle);
195
+ border-radius: 16px;
196
+ padding: 20px;
197
+ text-align: center;
198
+ }
199
+
200
+ .metric-card.winner {
201
+ border-color: var(--border-accent);
202
+ background: radial-gradient(circle at 50% -20%, rgba(255,255,255,0.06) 0%, var(--bg-surface) 70%);
203
+ }
204
+
205
+ .metric-value {
206
+ font-family: var(--font-heading);
207
+ font-size: 2.4rem;
208
+ font-weight: 700;
209
+ line-height: 1;
210
+ margin-bottom: 6px;
211
+ background: linear-gradient(180deg, #ffffff 0%, #a1a1aa 100%);
212
+ -webkit-background-clip: text;
213
+ -webkit-text-fill-color: transparent;
214
+ }
215
+
216
+ .metric-label {
217
+ font-size: 0.75rem;
218
+ color: var(--text-muted);
219
+ text-transform: uppercase;
220
+ letter-spacing: 0.08em;
221
+ }
222
+
223
+ .alignment-card {
224
+ background: rgba(10, 10, 14, 0.6);
225
+ border: 1px solid var(--border-subtle);
226
+ border-radius: 16px;
227
+ padding: 20px;
228
+ overflow-x: auto;
229
+ }
230
+
231
+ .align-row {
232
+ display: flex;
233
+ align-items: center;
234
+ margin-bottom: 8px;
235
+ font-family: var(--font-mono);
236
+ }
237
+
238
+ .row-label {
239
+ width: 120px;
240
+ flex-shrink: 0;
241
+ font-size: 0.78rem;
242
+ color: var(--text-muted);
243
+ }
244
+
245
+ .row-seq {
246
+ font-size: 0.92rem;
247
+ letter-spacing: 3px;
248
+ color: var(--text-main);
249
+ white-space: nowrap;
250
+ }
251
+
252
+ .row-seq .match { color: var(--success-green); }
253
+ .row-seq .miss { color: #ef4444; }
254
+
255
+ @keyframes fadeIn {
256
+ from { opacity: 0; transform: translateY(10px); }
257
+ to { opacity: 1; transform: translateY(0); }
258
+ }
259
+ """