import streamlit as st from stmol import showmol import py3Dmol import requests import biotite.structure.io as bsio import random import hashlib import urllib3 from Bio.Blast import NCBIWWW, NCBIXML from Bio.Seq import Seq from Bio.SeqRecord import SeqRecord import time import urllib.parse urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) st.set_page_config(layout='wide') st.sidebar.title('đŽ āĻā§āύāĻĒā§āϰā§ā§¨ - BD') st.sidebar.write('āĻā§āύāĻĒā§āϰā§ā§¨ - BD āĻšāϞ⧠āĻāĻāĻāĻŋ āϏāĻŽā§āĻĒā§āϰā§āĻŖ āĻĒā§āϰā§āĻāĻŋāύ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻā§āύāĻžāϰā§āĻāϰ, āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰ āĻĒā§āϰā§āĻĄāĻŋāĻā§āĻāϰ āĻāĻŦāĻ āĻ ā§āϝāĻžāύāĻžāϞāĻžāĻāϏāĻŋāϏ āĻā§āϞ āϝāĻž [ESMFold](https://esmatlas.com/explore?at=1%2C1%2C21.999999344348925) āĻāĻŦāĻ ESM-2 āϞā§āϝāĻžāĻā§āĻā§āϝāĻŧā§āĻ āĻŽāĻĄā§āϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠( Adapted from GenPro 2,5)') def generate_sequence_from_words(words, length): seed = ' '.join(words).encode('utf-8') random.seed(hashlib.md5(seed).hexdigest()) amino_acids = "ACDEFGHIKLMNPQRSTVWY" return ''.join(random.choice(amino_acids) for _ in range(length)) def render_mol(pdb): viewer = py3Dmol.view(width='100%', height='400px') viewer.addModel(pdb, 'pdb') viewer.setStyle({'cartoon': {'color': 'spectrum'}}) viewer.setBackgroundColor('white') viewer.zoomTo() viewer.zoom(0.8) # āĻāĻāĻā§ āĻā§āĻŽ āĻāĻāĻ āĻāĻŋāĻ viewer.spin(True) viewer.render() # āĻŽā§āĻŦāĻžāĻāϞā§āϰ āĻāύā§āϝ āϰā§āϏā§āĻĒāύā§āϏāĻŋāĻ āĻĄāĻŋāĻāĻžāĻāύ st.markdown(""" """, unsafe_allow_html=True) showmol(viewer, height=400, width=None) def perform_blast_analysis(sequence): st.subheader('āĻĒā§āϰā§āĻāĻŋāύ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ') with st.spinner("āĻā§āύāĻžāϰā§āĻ āĻāϰāĻž āĻĒā§āϰā§āĻāĻŋāύ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰāĻž āĻšāĻā§āĻā§... āĻāĻāĻŋ āĻāϝāĻŧā§āĻ āĻŽāĻŋāύāĻŋāĻ āϏāĻŽāϝāĻŧ āύāĻŋāϤ⧠āĻĒāĻžāϰā§āĨ¤ āĻ āύā§āĻā§āϰāĻš āĻāϰ⧠āĻ āĻĒā§āĻā§āώāĻž āĻāϰā§āύ!"): progress_bar = st.progress(0) for i in range(100): progress_bar.progress(i + 1) time.sleep(1.9) # āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āϏāĻŽāϝāĻŧ try: record = SeqRecord(Seq(sequence), id='random_protein') result_handle = NCBIWWW.qblast("blastp", "swissprot", record.seq) blast_record = NCBIXML.read(result_handle) if blast_record.alignments: alignment = blast_record.alignments[0] # āĻļā§āϰā§āώ āĻŽā§āϝāĻžāĻāĻāĻŋ āύāĻŋāύ hsp = alignment.hsps[0] # āĻĒā§āϰāĻĨāĻŽ (āϏā§āϰāĻž) HSP āύāĻŋāύ # āĻĒā§āϰā§āĻāĻŋāύ āύāĻžāĻŽ āĻāĻŦāĻ āĻ āϰā§āĻāĻžāύāĻŋāĻāĻŽ āĻāĻā§āϏāĻā§āϰāĻžāĻā§āĻ āĻāϰā§āύ title_parts = alignment.title.split('|') protein_name = title_parts[-1].strip() organism = title_parts[-2].split('OS=')[-1].split('OX=')[0].strip() # āĻāĻāĻĄā§āύā§āĻāĻŋāĻāĻŋ āĻĒāĻžāϰā§āϏā§āύā§āĻā§āĻ āĻā§āϝāĻžāϞāĻā§āϞā§āĻ āĻāϰā§āύ identity_percentage = (hsp.identities / hsp.align_length) * 100 st.write(f"**āĻļā§āϰā§āώ āĻŽā§āϝāĻžāĻ:** {protein_name}") st.write(f"**āĻāĻāύāĻŋāĻĒā§āϰā§āĻ āĻāĻāĻĄāĻŋ:** {organism}") st.write(f"**āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻāĻāĻĄā§āύā§āĻāĻŋāĻāĻŋ āĻŽā§āϝāĻžāĻ:** {identity_percentage:.2f}%") # āĻĒā§āϰā§āĻāĻŋāύ āĻĢāĻžāĻāĻļāύ āĻĢā§āĻ āĻāϰā§āύ (āϝāĻĻāĻŋ āĻĨāĻžāĻā§) if hasattr(alignment, 'description') and alignment.description: st.write(f"**āϏāĻŽā§āĻāĻžāĻŦā§āϝ āĻĢāĻžāĻāĻļāύ:** {alignment.description}") else: st.write("āĻĄāĻžāĻāĻžāĻŦā§āϏ⧠āĻā§āύ āĻāϞā§āϞā§āĻāϝā§āĻā§āϝ āĻŽā§āϝāĻžāĻ āĻĒāĻžāĻāϝāĻŧāĻž āϝāĻžāϝāĻŧāύāĻŋāĨ¤ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻ āύāύā§āϝ āĻĒā§āϰā§āĻāĻŋāύ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻšāϤ⧠āĻĒāĻžāϰā§!") except Exception as e: st.error(f"āĻĒā§āϰā§āĻāĻŋāύ āĻŦāĻŋāĻļā§āϞā§āώāĻŖ āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻāĻāĻāĻŋ āϤā§āϰā§āĻāĻŋ āĻāĻā§āĻā§: {str(e)}") st.write("āĻ āύā§āĻā§āϰāĻš āĻāϰ⧠āĻĒāϰ⧠āĻāĻŦāĻžāϰ āĻā§āώā§āĻāĻž āĻāϰā§āύ, BLAST āϏāĻžāϰā§āĻāĻžāϰ⧠āĻŦāĻŋāϞāĻŽā§āĻŦ āĻšāϤ⧠āĻĒāĻžāϰā§āĨ¤") def update(sequence, word1, word2, word3, sequence_length): headers = { 'Content-Type': 'application/x-www-form-urlencoded', } try: response = requests.post('https://api.esmatlas.com/foldSequence/v1/pdb/', headers=headers, data=sequence, verify=False, timeout=300) response.raise_for_status() pdb_string = response.content.decode('utf-8') with open('predicted.pdb', 'w') as f: f.write(pdb_string) struct = bsio.load_structure('predicted.pdb', extra_fields=["b_factor"]) b_value = round(struct.b_factor.mean(), 2) st.session_state.structure_info = { 'pdb_string': pdb_string, 'b_value': b_value, 'word1': word1, 'word2': word2, 'word3': word3, 'sequence_length': sequence_length } st.session_state.show_analyze_button = True except requests.exceptions.RequestException as e: st.error(f"API āĻāϞ āĻāϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻāĻāĻāĻŋ āϤā§āϰā§āĻāĻŋ āĻāĻā§āĻā§: {str(e)}") st.write("āĻ āύā§āĻā§āϰāĻš āĻāϰ⧠āĻĒāϰ⧠āĻāĻŦāĻžāϰ āĻā§āώā§āĻāĻž āĻāϰā§āύ āĻŦāĻž āϏāĻŽāϏā§āϝāĻž āĻĨāĻžāĻāϞ⧠āϏāĻžāĻĒā§āϰā§āĻā§ āϝā§āĻāĻžāϝā§āĻ āĻāϰā§āύāĨ¤") def share_on_twitter(word1, word2, word3, length, plddt): tweet_text = f"āĻāĻŽāĻŋ āĻļā§āϧ⧠āĻāĻāĻāĻŋ āύāϤā§āύ āĻĒā§āϰā§āĻāĻŋāύ āĻāĻŦāĻŋāώā§āĻāĻžāϰ āĻāϰā§āĻāĻŋ āϏāĻŋāĻĄ āĻļāĻŦā§āĻĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§: {word1} + {word2} + {word3} | āĻĒā§āϰā§āĻāĻŋāύ āĻā§āύāĻžāϰā§āĻ āĻāϰā§āĻā§ @PotionBio" tweet_url = f"https://twitter.com/intent/tweet?text={urllib.parse.quote(tweet_text)}" return tweet_url # āϏā§āĻļāύ āϏā§āĻā§āĻ āĻā§āϰāĻŋāϝāĻŧā§āĻŦāϞ āĻāύāĻŋāĻļāĻŋāϝāĻŧāĻžāϞāĻžāĻāĻ āĻāϰā§āύ if 'sequence' not in st.session_state: st.session_state.sequence = None if 'show_analyze_button' not in st.session_state: st.session_state.show_analyze_button = False if 'structure_info' not in st.session_state: st.session_state.structure_info = None st.title("đ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰ⧠āĻāĻžāĻāĻĄ:") st.sidebar.subheader("āĻļāĻŦā§āĻĻ āĻĨā§āĻā§ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻā§āύāĻžāϰā§āĻ āĻāϰā§āύ") word1 = st.sidebar.text_input("āĻļāĻŦā§āĻĻ ā§§") word2 = st.sidebar.text_input("āĻļāĻŦā§āĻĻ ā§¨") word3 = st.sidebar.text_input("āĻļāĻŦā§āĻĻ ā§Š") sequence_length = st.sidebar.number_input("āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻĻā§āϰā§āĻā§āϝ", min_value=50, max_value=400, value=100, step=10) # āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻžāϰā§āĻĻā§āϰ āĻāύā§āϝ āϤāĻĨā§āϝ st.info(""" āĻĒā§āϰā§āĻāĻŋāύ āĻĻā§āϰā§āĻā§āϝ āĻāĻžāĻāĻĄ: - ā§Ģā§Ļ-ā§§ā§Ļā§Ļ āĻ ā§āϝāĻžāĻŽāĻŋāύ⧠āĻ ā§āϝāĻžāϏāĻŋāĻĄ: āĻā§āĻ āĻĒā§āϰā§āĻāĻŋāύ/āĻĒā§āĻĒāĻāĻžāĻāĻĄ - ā§§ā§Ļā§Ļ-ā§Šā§Ļā§Ļ āĻ ā§āϝāĻžāĻŽāĻŋāύ⧠āĻ ā§āϝāĻžāϏāĻŋāĻĄ: āĻāĻĄāĻŧ āĻĒā§āϰā§āĻāĻŋāύ āĻĄā§āĻŽā§āĻāύ - ā§Šā§Ļā§Ļ-ā§Ģā§Ļā§Ļ āĻ ā§āϝāĻžāĻŽāĻŋāύ⧠āĻ ā§āϝāĻžāϏāĻŋāĻĄ: āĻŦāĻĄāĻŧ āϏāĻŋāĻā§āĻā§āϞ-āĻĄā§āĻŽā§āĻāύ āĻĒā§āϰā§āĻāĻŋāύ """) st.markdown(""" ā§§. āĻĒā§āϰāĻĨāĻŽā§ āϏāĻžāĻāĻĄāĻŦāĻžāϰ⧠āĻāĻĒāύāĻžāϰ āĻĒāĻāύā§āĻĻā§āϰ āϝā§āĻā§āύ⧠āϤāĻŋāύāĻāĻŋ āϏāĻŋāĻĄ āĻļāĻŦā§āĻĻ āĻāύāĻĒā§āĻ āĻāϰā§āύ āĻāĻŦāĻ āĻāĻāĻāĻŋ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻĻā§āϰā§āĻā§āϝ āϏāĻŋāϞā§āĻā§āĻ āĻāϰā§āύāĨ¤ ⧍. 'āĻā§āύāĻžāϰā§āĻ āĻāĻŦāĻ āĻĒā§āϰā§āĻĄāĻŋāĻā§āĻ' āĻŦāĻžāĻāύ⧠āĻā§āϞāĻŋāĻ āĻāϰā§āύ āĻāĻĒāύāĻžāϰ āĻāύāĻĒā§āĻā§āϰ āĻāĻŋāϤā§āϤāĻŋāϤ⧠āĻāĻāĻāĻŋ āĻ āύāύā§āϝ āĻĒā§āϰā§āĻāĻŋāύ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻā§āύāĻžāϰā§āĻ āĻāϰāϤā§āĨ¤ ā§Š. āĻā§āύāĻĒā§āϰā§ā§¨ āϤāĻāύ āĻāĻĒāύāĻžāϰ āĻĒā§āϰā§āĻāĻŋāύā§āϰ ā§ŠāĻĄāĻŋ āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰ āĻĒā§āϰā§āĻĄāĻŋāĻā§āĻ āĻāϰ⧠āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻāύāĻĢāĻŋāĻĄā§āύā§āϏ āϏā§āĻā§āϰ āĻĒā§āϰāĻĻāĻžāύ āĻāϰā§āĨ¤ āĻā§āύāĻĒā§āϰā§ā§¨ āĻāĻŦāĻ āĻĒā§āϰā§āĻāĻŋāύ āϏāĻŽā§āĻĒāϰā§āĻā§ āĻāϰāĻ: āĻāĻĒāύāĻžāϰ āĻ āύāύā§āϝ āĻĒā§āϰā§āĻāĻŋāύ āύāϤā§āύ āĻĨā§āϰāĻžāĻĒāĻŋāĻāĻāĻŋāĻ āϏāĻŽā§āĻāĻžāĻŦāύāĻž āĻāύā§āĻŽā§āĻāύ āĻŦāĻž āϰā§āĻā§āϰ āĻŽā§āĻāĻžāύāĻŋāĻāĻŽ āĻŦā§āĻāĻžāϰ āĻāĻžāĻŦāĻŋāĻāĻžāĻ āĻŋ āĻšāϤ⧠āĻĒāĻžāϰā§āĨ¤ āĻā§ āĻāĻžāύā§? āĻāĻĒāύāĻžāϰ āĻĒāϰāĻŦāϰā§āϤ⧠āĻā§āύāĻžāϰā§āĻ āĻāϰāĻž āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻāĻāĻāĻŋ āϝā§āĻāĻžāύā§āϤāĻāĻžāϰ⧠āĻāĻŦāĻŋāώā§āĻāĻžāϰā§āϰ āĻĻāĻŋāĻā§ āύāĻŋāϝāĻŧā§ āϝā§āϤ⧠āĻĒāĻžāϰā§āĨ¤ āĻāĻŽā§āĻĒāĻŋāĻāĻā§āĻļāύāĻžāϞ āĻĒā§āϰā§āĻāĻŋāύ āĻāĻā§āϏāĻĒā§āϞā§āϰā§āĻļāύ⧠āĻāĻĒāύāĻžāϰ āϝāĻžāϤā§āϰāĻž āĻļā§āϰ⧠āĻāϰā§āύ! [āĻāϰāĻ āĻāĻžāύā§āύ](https://www.youtube.com/watch?v=KpedmJdrTpY) """) if st.sidebar.button('āĻā§āύāĻžāϰā§āĻ āĻāĻŦāĻ āĻĒā§āϰā§āĻĄāĻŋāĻā§āĻ'): if word1 and word2 and word3: sequence = generate_sequence_from_words([word1, word2, word3], sequence_length) st.session_state.sequence = sequence st.sidebar.text_area("āĻā§āύāĻžāϰā§āĻ āĻāϰāĻž āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ", sequence, height=100) st.sidebar.info("āĻĻā§āϰāώā§āĻāĻŦā§āϝ: āĻāĻāĻ āĻļāĻŦā§āĻĻ āĻāĻŦāĻ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻĻā§āϰā§āĻā§āϝ āϏāĻŦāϏāĻŽāϝāĻŧ āĻāĻāĻ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻā§āĻĒāύā§āύ āĻāϰāĻŦā§āĨ¤") with st.spinner("āĻĒā§āϰā§āĻāĻŋāύ āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰ āĻĒā§āϰā§āĻĄāĻŋāĻā§āĻ āĻāϰāĻž āĻšāĻā§āĻā§... āĻāĻāĻŋ āĻāϝāĻŧā§āĻ āĻŽāĻŋāύāĻŋāĻ āϏāĻŽāϝāĻŧ āύāĻŋāϤ⧠āĻĒāĻžāϰā§āĨ¤"): update(sequence, word1, word2, word3, sequence_length) else: st.sidebar.warning("āĻāĻāĻāĻŋ āϏāĻŋāĻā§āϝāĻŧā§āύā§āϏ āĻā§āύāĻžāϰā§āĻ āĻāϰāϤ⧠āĻ āύā§āĻā§āϰāĻš āĻāϰ⧠āϤāĻŋāύāĻāĻŋ āĻļāĻŦā§āĻĻ āĻāύāĻĒā§āĻ āĻāϰā§āύāĨ¤") # āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰ āĻāύāĻĢā§ āĻĄāĻŋāϏāĻĒā§āϞ⧠āĻāϰā§āύ āϝāĻĻāĻŋ āĻĨāĻžāĻā§ if st.session_state.structure_info: info = st.session_state.structure_info st.subheader(f'āĻĒā§āϰā§āĻĄāĻŋāĻā§āĻ āĻāϰāĻž āĻĒā§āϰā§āĻāĻŋāύ āϏā§āĻā§āϰāĻžāĻāĻāĻžāϰ āϏāĻŋāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰā§: {info["word1"]}, {info["word2"]}, āĻāĻŦāĻ {info["word3"]}') render_mol(info['pdb_string']) st.subheader('plDDT āĻāύāĻĢāĻŋāĻĄā§āύā§āϏ āϏā§āĻā§āϰ') st.write('plDDT āĻšāϞ⧠āĻĒā§āϰā§āĻāĻŋāύ āĻĢā§āϞā§āĻĄāĻŋāĻ āĻĒā§āϰā§āĻĄāĻŋāĻāĻļāύā§āϰ āĻāύāĻĢāĻŋāĻĄā§āύā§āϏ āϞā§āĻā§āϞ āϏā§āĻā§āϰ āĻāϰāĻžāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āĻŦā§āĻā§āĻāĻŽāĻžāϰā§āĻ āϝāĻž ā§Ļ-ā§§ā§Ļā§Ļ% āϏā§āĻā§āϞ⧠āĻāĻžāĻ āĻāϰā§āĨ¤ ā§ā§Ļ% āĻŦāĻž āϤāĻžāϰ āĻŦā§āĻļāĻŋ āĻāĻžāϞā§!') plddt_score = int(info["b_value"] * 100) st.info(f'āĻāĻĒāύāĻžāϰ plDDT āϏā§āĻā§āϰ āĻšāϞā§: {plddt_score}%') st.subheader("āĻāĻĒāύāĻžāϰ āĻ āύāύā§āϝ āĻĒā§āϰā§āĻāĻŋāύ X(āĻā§āĻāĻāĻžāϰ) āĻ āĻļā§āϝāĻŧāĻžāϰ āĻāϰā§āύ") st.markdown("""