Spaces:
Build error
Build error
File size: 6,323 Bytes
b0f8787 784e4aa 1a77f6d 784e4aa d3184b9 b0f8787 017a644 784e4aa b0f8787 784e4aa 4cc12fd b0f8787 f36f859 626ac91 3e07321 784e4aa 23cbe89 4cc12fd 1a77f6d 4cc12fd 1a77f6d 4cc12fd 784e4aa 4cc12fd 467d1e3 4cc12fd f36f859 4cc12fd b0f8787 4cc12fd f36f859 4cc12fd bd3f684 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
import streamlit as st
import pandas as pd
import primer3
from Bio import SeqIO
import os
from io import StringIO
# Ensure the 'temp' directory exists for saving temporary files
temp_dir = "temp"
os.makedirs(temp_dir, exist_ok=True)
# Streamlit UI setup
st.set_page_config(page_title="PCR Primer Design", page_icon="🧬", layout="wide")
# User Documentation
st.sidebar.header("User Guide")
st.sidebar.info(
"""
This application allows you to design PCR primers for specific features within a GenBank file.
Follow these steps:
1. Upload a GenBank file.
2. Select a feature type and then a specific feature.
3. Enter the desired PCR product size range and the minimum number of primer pairs.
4. Click 'Design Primers' to generate your primers.
"""
)
# File uploader with additional help
uploaded_file = st.file_uploader(
"Upload a GenBank file",
type=['gb', 'gbk'],
help="Upload a GenBank (.gb or .gbk) file containing the DNA sequence from which to design primers."
)
# Custom CSS for styling
st.markdown("""
<style>
h1, h2, h3 {
color: #1f77b4;
font-weight: bold;
}
.stProgress {
margin-top: 20px;
}
</style>
""", unsafe_allow_html=True)
def extract_features_from_genbank(genbank_content, feature_types=['CDS', 'tRNA', 'gene']):
"""Extracts specified features from GenBank content."""
text_stream = StringIO(genbank_content.decode("utf-8")) if isinstance(genbank_content, bytes) else genbank_content
record = SeqIO.read(text_stream, "genbank")
features = {ftype: [] for ftype in feature_types}
for feature in record.features:
if feature.type in feature_types:
features[feature.type].append(feature)
return features, record
def design_primers_for_region(sequence, product_size_range, num_to_return=10):
"""Design primers for a specific sequence."""
size_min, size_max = map(int, product_size_range.split('-'))
return primer3.bindings.designPrimers(
{
'SEQUENCE_TEMPLATE': str(sequence),
'PRIMER_PRODUCT_SIZE_RANGE': [[size_min, size_max]]
},
{
'PRIMER_OPT_SIZE': 20,
'PRIMER_MIN_SIZE': 18,
'PRIMER_MAX_SIZE': 23,
'PRIMER_OPT_TM': 60.0,
'PRIMER_MIN_TM': 57.0,
'PRIMER_MAX_TM': 63.0,
'PRIMER_MIN_GC': 20.0,
'PRIMER_MAX_GC': 80.0,
'PRIMER_NUM_RETURN': num_to_return,
}
)
if uploaded_file is not None:
genbank_content = StringIO(uploaded_file.getvalue().decode("utf-8"))
features, record = extract_features_from_genbank(genbank_content)
st.write("## Feature Selection")
feature_type = st.selectbox(
'Select feature type:',
['CDS', 'tRNA', 'gene'],
help="Choose the type of genomic feature for which you want to design primers."
)
if features[feature_type]:
feature_options = [f"{feature.qualifiers.get('gene', [''])[0]} ({feature.location})" for feature in features[feature_type]]
selected_index = st.selectbox(
f'Select a {feature_type}:',
options=range(len(feature_options)),
format_func=lambda x: feature_options[x],
help="Select a specific feature based on its gene name and location."
)
selected_feature = features[feature_type][selected_index]
feature_sequence = selected_feature.extract(record.seq)
st.write(f"Selected {feature_type} sequence (length: {len(feature_sequence)} bp):")
st.code(str(feature_sequence), language="text") # Display sequence in code format
st.write("## Primer Design Parameters")
product_size_range = st.text_input(
"Enter desired PCR product size range (e.g., 150-500):",
value="150-500",
help="Specify the range of the desired PCR product size in base pairs (e.g., 150-500)."
)
min_num_primers = st.number_input(
"Enter minimum number of primer pairs to return:",
min_value=5, value=5, step=1,
help="Determine the minimum number of primer pairs to generate."
)
if st.button(f'Design Primers for selected {feature_type}'):
with st.spinner('Designing primers...'): # Show a spinner while primers are being designed
primers = design_primers_for_region(feature_sequence, product_size_range, num_to_return=min_num_primers)
primer_data = []
for i in range(min_num_primers):
left_sequence = primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A')
right_sequence = primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A')
if left_sequence != 'N/A' and right_sequence != 'N/A':
primer_info = {
'Primer Pair': i + 1,
'Left Sequence': left_sequence,
'Right Sequence': right_sequence,
'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
'Left Length': len(left_sequence),
'Right Length': len(right_sequence),
'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
}
primer_data.append(primer_info)
if primer_data:
st.subheader('Designed Primers')
primer_df = pd.DataFrame(primer_data)
st.table(primer_df) # Use st.table to display the primer data
csv = primer_df.to_csv(index=False).encode('utf-8')
st.download_button(
"Download Primers as CSV",
csv,
"primers.csv",
"text/csv",
key='download-csv'
)
else:
st.error('No primers were found. Please adjust your parameters and try again.')
# Add copyright information section at the end of the main page
st.markdown("""
---
**Copyright Notice**: © 2024 Yash Munnalal Gupta. All rights reserved.
For inquiries or permissions, contact: [yash.610@live.com](mailto:yash.610@live.com)
""", unsafe_allow_html=True)
|