yashm commited on
Commit
d5326d7
·
verified ·
1 Parent(s): 0eecf0c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +101 -106
app.py CHANGED
@@ -5,7 +5,7 @@ from Bio import SeqIO
5
  import os
6
  from io import StringIO
7
 
8
- # Ensure the 'temp' directory exists
9
  temp_dir = "temp"
10
  os.makedirs(temp_dir, exist_ok=True)
11
 
@@ -16,37 +16,24 @@ st.set_page_config(page_title="PCR Primer Design", page_icon="🧬", layout="wid
16
  st.sidebar.header("User Guide")
17
  st.sidebar.info(
18
  """
19
- This application allows you to design PCR primers for specific features within a GenBank file.
20
- Follow these steps:
21
- 1. Upload a GenBank file.
22
- 2. Select a feature type and then a specific feature.
23
- 3. Adjust the desired PCR product size range and the number of primer pairs.
24
- 4. Click 'Design Primers' to generate your primers.
25
  """
26
  )
27
 
28
  # File uploader
29
  uploaded_file = st.file_uploader(
30
- "Upload a GenBank file",
31
- type=['gb', 'gbk'],
32
- help="Upload a GenBank (.gb or .gbk) file containing the DNA sequence from which to design primers."
33
  )
34
 
35
- # Custom CSS
36
- st.markdown("""
37
- <style>
38
- h1, h2, h3 {
39
- color: #1f77b4;
40
- font-weight: bold;
41
- }
42
- .stProgress {
43
- margin-top: 20px;
44
- }
45
- </style>
46
- """, unsafe_allow_html=True)
47
-
48
  def extract_features_from_genbank(genbank_content, feature_types=['CDS', 'tRNA', 'gene']):
49
- """Extracts specified features from GenBank content."""
50
  text_stream = StringIO(genbank_content.decode("utf-8")) if isinstance(genbank_content, bytes) else genbank_content
51
  record = SeqIO.read(text_stream, "genbank")
52
  features = {ftype: [] for ftype in feature_types}
@@ -55,8 +42,12 @@ def extract_features_from_genbank(genbank_content, feature_types=['CDS', 'tRNA',
55
  features[feature.type].append(feature)
56
  return features, record
57
 
 
 
 
 
 
58
  def design_primers_for_region(sequence, product_size_range, num_to_return=10):
59
- """Design primers for a specific sequence."""
60
  size_min, size_max = map(int, product_size_range.split('-'))
61
  return primer3.bindings.designPrimers(
62
  {
@@ -76,95 +67,99 @@ def design_primers_for_region(sequence, product_size_range, num_to_return=10):
76
  }
77
  )
78
 
 
79
  if uploaded_file is not None:
80
- genbank_content = StringIO(uploaded_file.getvalue().decode("utf-8"))
81
- features, record = extract_features_from_genbank(genbank_content)
82
-
83
- st.write("## Feature Selection")
84
- feature_type = st.selectbox(
85
- 'Select feature type:',
86
- ['CDS', 'tRNA', 'gene'],
87
- help="Choose the type of genomic feature for which you want to design primers."
88
- )
89
-
90
- if features[feature_type]:
91
- feature_options = [
92
- f"{feature.qualifiers.get('gene', [''])[0]} ({feature.location}) [length: {len(feature.location)} bp]"
93
- for feature in features[feature_type]
94
- ]
95
- selected_index = st.selectbox(
96
- f'Select a {feature_type}:',
97
- options=range(len(feature_options)),
98
- format_func=lambda x: feature_options[x],
99
- help="Select a specific feature based on its gene name and location."
100
- )
101
- selected_feature = features[feature_type][selected_index]
102
-
103
- feature_sequence = selected_feature.extract(record.seq)
104
- st.write(f"Selected {feature_type} sequence (length: {len(feature_sequence)} bp):")
105
- st.code(str(feature_sequence), language="text")
106
 
107
- st.write("## Primer Design Parameters")
 
 
108
 
109
- product_size_range = st.slider(
110
- "Select desired PCR product size range:",
111
- min_value=100,
112
- max_value=len(feature_sequence),
113
- value=(100, min(500, len(feature_sequence))),
114
- step=10,
115
- help="Adjust the desired PCR product size range (min 100 bp, max = feature length)."
116
  )
117
 
118
- min_num_primers = st.number_input(
119
- "Enter minimum number of primer pairs to return:",
120
- min_value=1, value=5, step=1,
121
- help="Determine the number of primer pairs to generate."
122
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
- if st.button(f'Design Primers for selected {feature_type}'):
125
- with st.spinner('Designing primers...'):
126
- primers = design_primers_for_region(
127
- feature_sequence,
128
- f"{product_size_range[0]}-{product_size_range[1]}",
129
- num_to_return=min_num_primers
130
- )
131
-
132
- primer_data = []
133
- for i in range(min_num_primers):
134
- left_sequence = primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A')
135
- right_sequence = primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A')
136
- if left_sequence != 'N/A' and right_sequence != 'N/A':
137
- primer_info = {
138
- 'Primer Pair': i + 1,
139
- 'Left Sequence': left_sequence,
140
- 'Right Sequence': right_sequence,
141
- 'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
142
- 'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
143
- 'Left Length': len(left_sequence),
144
- 'Right Length': len(right_sequence),
145
- 'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
146
- }
147
- primer_data.append(primer_info)
148
-
149
- if primer_data:
150
- st.subheader('Designed Primers')
151
- primer_df = pd.DataFrame(primer_data)
152
- st.table(primer_df)
153
-
154
- csv = primer_df.to_csv(index=False).encode('utf-8')
155
- st.download_button(
156
- "Download Primers as CSV",
157
- csv,
158
- "primers.csv",
159
- "text/csv",
160
- key='download-csv'
161
- )
162
- else:
163
- st.error('No primers were found. Please adjust your parameters and try again.')
164
 
165
  # Footer
166
  st.markdown("""
167
  ---
168
  **© 2024 Yash Munnalal Gupta**
169
- For inquiries or permissions, contact: [yash.610@live.com](mailto:yash.610@live.com)
170
- """, unsafe_allow_html=True)
 
5
  import os
6
  from io import StringIO
7
 
8
+ # Ensure temp directory exists
9
  temp_dir = "temp"
10
  os.makedirs(temp_dir, exist_ok=True)
11
 
 
16
  st.sidebar.header("User Guide")
17
  st.sidebar.info(
18
  """
19
+ This app allows you to design PCR primers from GenBank or FASTA files.
20
+
21
+ 1. Upload a GenBank or FASTA file.
22
+ 2. If GenBank: choose a feature (CDS, gene, tRNA).
23
+ 3. Adjust product size range and primer count.
24
+ 4. Click to generate primers.
25
  """
26
  )
27
 
28
  # File uploader
29
  uploaded_file = st.file_uploader(
30
+ "Upload a GenBank or FASTA file",
31
+ type=['gb', 'gbk', 'fa', 'fasta'],
32
+ help="Supported formats: .gb, .gbk (GenBank); .fa, .fasta (FASTA)"
33
  )
34
 
35
+ # Helper functions
 
 
 
 
 
 
 
 
 
 
 
 
36
  def extract_features_from_genbank(genbank_content, feature_types=['CDS', 'tRNA', 'gene']):
 
37
  text_stream = StringIO(genbank_content.decode("utf-8")) if isinstance(genbank_content, bytes) else genbank_content
38
  record = SeqIO.read(text_stream, "genbank")
39
  features = {ftype: [] for ftype in feature_types}
 
42
  features[feature.type].append(feature)
43
  return features, record
44
 
45
+ def parse_fasta(fasta_content):
46
+ text_stream = StringIO(fasta_content.decode("utf-8"))
47
+ record = SeqIO.read(text_stream, "fasta")
48
+ return record
49
+
50
  def design_primers_for_region(sequence, product_size_range, num_to_return=10):
 
51
  size_min, size_max = map(int, product_size_range.split('-'))
52
  return primer3.bindings.designPrimers(
53
  {
 
67
  }
68
  )
69
 
70
+ # File processing logic
71
  if uploaded_file is not None:
72
+ file_ext = os.path.splitext(uploaded_file.name)[-1].lower()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
+ if file_ext in ['.gb', '.gbk']:
75
+ genbank_content = StringIO(uploaded_file.getvalue().decode("utf-8"))
76
+ features, record = extract_features_from_genbank(genbank_content)
77
 
78
+ st.write("## Feature Selection")
79
+ feature_type = st.selectbox(
80
+ 'Select feature type:',
81
+ ['CDS', 'tRNA', 'gene'],
82
+ help="Choose the feature type for primer design."
 
 
83
  )
84
 
85
+ if features[feature_type]:
86
+ feature_options = [
87
+ f"{f.qualifiers.get('gene', [''])[0]} ({f.location}) [length: {len(f.location)} bp]"
88
+ for f in features[feature_type]
89
+ ]
90
+ selected_index = st.selectbox(
91
+ f"Select a {feature_type}:",
92
+ options=range(len(feature_options)),
93
+ format_func=lambda x: feature_options[x],
94
+ help="Choose a specific feature."
95
+ )
96
+ selected_feature = features[feature_type][selected_index]
97
+ sequence = selected_feature.extract(record.seq)
98
+ st.code(str(sequence), language="text")
99
+
100
+ elif file_ext in ['.fa', '.fasta']:
101
+ record = parse_fasta(uploaded_file.getvalue())
102
+ sequence = record.seq
103
+ st.write(f"FASTA sequence loaded (length: {len(sequence)} bp):")
104
+ st.code(str(sequence), language="text")
105
+ else:
106
+ st.error("Unsupported file format.")
107
+ st.stop()
108
+
109
+ st.write("## Primer Design Parameters")
110
+
111
+ product_size_range = st.slider(
112
+ "Select PCR product size range:",
113
+ min_value=100,
114
+ max_value=len(sequence),
115
+ value=(100, min(500, len(sequence))),
116
+ step=10,
117
+ help="Range of the desired PCR product size."
118
+ )
119
 
120
+ min_num_primers = st.number_input(
121
+ "Number of primer pairs to return:",
122
+ min_value=1, value=5, step=1,
123
+ help="How many primer pairs to return."
124
+ )
125
+
126
+ if st.button("Design Primers"):
127
+ with st.spinner("Designing primers..."):
128
+ primers = design_primers_for_region(
129
+ sequence,
130
+ f"{product_size_range[0]}-{product_size_range[1]}",
131
+ num_to_return=min_num_primers
132
+ )
133
+
134
+ primer_data = []
135
+ for i in range(min_num_primers):
136
+ left = primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A')
137
+ right = primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A')
138
+ if left != 'N/A' and right != 'N/A':
139
+ primer_data.append({
140
+ 'Primer Pair': i + 1,
141
+ 'Left Sequence': left,
142
+ 'Right Sequence': right,
143
+ 'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
144
+ 'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
145
+ 'Left Length': len(left),
146
+ 'Right Length': len(right),
147
+ 'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
148
+ })
149
+
150
+ if primer_data:
151
+ st.subheader('Designed Primers')
152
+ df = pd.DataFrame(primer_data)
153
+ st.table(df)
154
+
155
+ csv = df.to_csv(index=False).encode('utf-8')
156
+ st.download_button("Download Primers as CSV", csv, "primers.csv", "text/csv")
157
+ else:
158
+ st.error("No primers found. Try adjusting your parameters.")
 
159
 
160
  # Footer
161
  st.markdown("""
162
  ---
163
  **© 2024 Yash Munnalal Gupta**
164
+ Contact: [yash.610@live.com](mailto:yash.610@live.com)
165
+ """, unsafe_allow_html=True)