yashm commited on
Commit
8f0b24b
·
verified ·
1 Parent(s): 1f34be8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -38
app.py CHANGED
@@ -4,6 +4,7 @@ import primer3
4
  from Bio import SeqIO
5
  import os
6
  from io import StringIO
 
7
 
8
  # Ensure the 'temp' directory exists for saving temporary files
9
  temp_dir = "temp"
@@ -13,8 +14,8 @@ os.makedirs(temp_dir, exist_ok=True)
13
  st.set_page_config(page_title="PCR Primer Design", page_icon="🧬", layout="wide")
14
  uploaded_file = st.file_uploader("Upload a GenBank file", type=['gb', 'gbk'])
15
 
 
16
  def extract_features_from_genbank(genbank_content, feature_types=['CDS', 'tRNA', 'gene']):
17
- """Extracts specified features from GenBank content."""
18
  text_stream = StringIO(genbank_content.decode("utf-8")) if isinstance(genbank_content, bytes) else genbank_content
19
  record = SeqIO.read(text_stream, "genbank")
20
  features = {ftype: [] for ftype in feature_types}
@@ -23,9 +24,8 @@ def extract_features_from_genbank(genbank_content, feature_types=['CDS', 'tRNA',
23
  features[feature.type].append(feature)
24
  return features, record
25
 
 
26
  def design_primers_for_region(sequence, product_size_range, num_to_return=5):
27
- """Design primers for a specific sequence."""
28
- # Parse the product size range
29
  size_min, size_max = map(int, product_size_range.split('-'))
30
  return primer3.bindings.designPrimers(
31
  {
@@ -45,52 +45,122 @@ def design_primers_for_region(sequence, product_size_range, num_to_return=5):
45
  }
46
  )
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  if uploaded_file is not None:
49
- genbank_content = StringIO(uploaded_file.getvalue().decode("utf-8"))
50
- features, record = extract_features_from_genbank(genbank_content)
51
- feature_type = st.selectbox('Select feature type:', ['CDS', 'tRNA', 'gene'])
 
 
 
 
 
52
 
53
- feature_options = [f"{feature.qualifiers.get('gene', [''])[0]} ({feature.location})" for feature in features[feature_type]]
54
- selected_index = st.selectbox(f'Select a {feature_type}:', options=range(len(feature_options)), format_func=lambda x: feature_options[x])
55
- selected_feature = features[feature_type][selected_index]
56
 
57
- feature_sequence = selected_feature.extract(record.seq)
58
- st.write(f"Selected {feature_type} sequence (length: {len(feature_sequence)} bp):")
59
- st.text(str(feature_sequence))
60
 
61
- product_size_range = st.text_input("Enter desired PCR product size range (e.g., 150-500):", value="150-500")
62
 
63
- if st.button(f'Design Primers for selected {feature_type}'):
64
- primers = design_primers_for_region(feature_sequence, product_size_range, num_to_return=5)
65
-
66
- primer_data = []
67
- for i in range(5): # Collect data for 5 primer pairs
68
- left_sequence = primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A')
69
- right_sequence = primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A')
70
- if left_sequence != 'N/A' and right_sequence != 'N/A':
71
  primer_info = {
72
  'Primer Pair': i + 1,
73
- 'Left Sequence': left_sequence,
74
- 'Right Sequence': right_sequence,
75
  'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
76
  'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
77
  'Left Length': primers.get(f'PRIMER_LEFT_{i}_SIZE', 'N/A'),
78
  'Right Length': primers.get(f'PRIMER_RIGHT_{i}_SIZE', 'N/A'),
79
  'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
80
  }
81
- primer_data.append(primer_info)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
- if primer_data:
84
- primer_df = pd.DataFrame(primer_data)
85
- st.write('### Designed Primers')
86
- st.dataframe(primer_df)
87
- csv = primer_df.to_csv(index=False).encode('utf-8')
88
- st.download_button(
89
- "Download Primers as CSV",
90
- csv,
91
- "primers.csv",
92
- "text/csv",
93
- key='download-csv'
94
- )
95
- else:
96
- st.error('No primers were found. Please adjust your parameters and try again.')
 
4
  from Bio import SeqIO
5
  import os
6
  from io import StringIO
7
+ import matplotlib.pyplot as plt
8
 
9
  # Ensure the 'temp' directory exists for saving temporary files
10
  temp_dir = "temp"
 
14
  st.set_page_config(page_title="PCR Primer Design", page_icon="🧬", layout="wide")
15
  uploaded_file = st.file_uploader("Upload a GenBank file", type=['gb', 'gbk'])
16
 
17
+ # Function to extract features from GenBank content
18
  def extract_features_from_genbank(genbank_content, feature_types=['CDS', 'tRNA', 'gene']):
 
19
  text_stream = StringIO(genbank_content.decode("utf-8")) if isinstance(genbank_content, bytes) else genbank_content
20
  record = SeqIO.read(text_stream, "genbank")
21
  features = {ftype: [] for ftype in feature_types}
 
24
  features[feature.type].append(feature)
25
  return features, record
26
 
27
+ # Function to design primers for a specific sequence
28
  def design_primers_for_region(sequence, product_size_range, num_to_return=5):
 
 
29
  size_min, size_max = map(int, product_size_range.split('-'))
30
  return primer3.bindings.designPrimers(
31
  {
 
45
  }
46
  )
47
 
48
+ # Function to display primer design results
49
+ def display_primer_results(primer_df):
50
+ st.write('### Designed Primers')
51
+ st.dataframe(primer_df)
52
+ csv = primer_df.to_csv(index=False).encode('utf-8')
53
+ st.download_button(
54
+ "Download Primers as CSV",
55
+ csv,
56
+ "primers.csv",
57
+ "text/csv",
58
+ key='download-csv'
59
+ )
60
+
61
+ # Main application logic
62
  if uploaded_file is not None:
63
+ # Option for Batch Primer Design
64
+ batch_design = st.checkbox("Batch Primer Design")
65
+
66
+ if not batch_design:
67
+ # Design primers for a single feature
68
+ genbank_content = StringIO(uploaded_file.getvalue().decode("utf-8"))
69
+ features, record = extract_features_from_genbank(genbank_content)
70
+ feature_type = st.selectbox('Select feature type:', ['CDS', 'tRNA', 'gene'])
71
 
72
+ feature_options = [f"{feature.qualifiers.get('gene', [''])[0]} ({feature.location})" for feature in features[feature_type]]
73
+ selected_index = st.selectbox(f'Select a {feature_type}:', options=range(len(feature_options)), format_func=lambda x: feature_options[x])
74
+ selected_feature = features[feature_type][selected_index]
75
 
76
+ feature_sequence = selected_feature.extract(record.seq)
77
+ st.write(f"Selected {feature_type} sequence (length: {len(feature_sequence)} bp):")
78
+ st.text(str(feature_sequence))
79
 
80
+ product_size_range = st.text_input("Enter desired PCR product size range (e.g., 150-500):", value="150-500")
81
 
82
+ if st.button(f'Design Primers for selected {feature_type}'):
83
+ primers = design_primers_for_region(feature_sequence, product_size_range, num_to_return=5)
84
+
85
+ primer_data = []
86
+ for i in range(5): # Collect data for 5 primer pairs
 
 
 
87
  primer_info = {
88
  'Primer Pair': i + 1,
89
+ 'Left Sequence': primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A'),
90
+ 'Right Sequence': primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A'),
91
  'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
92
  'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
93
  'Left Length': primers.get(f'PRIMER_LEFT_{i}_SIZE', 'N/A'),
94
  'Right Length': primers.get(f'PRIMER_RIGHT_{i}_SIZE', 'N/A'),
95
  'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
96
  }
97
+ if primer_info['Left Sequence'] != 'N/A' and primer_info['Right Sequence'] != 'N/A':
98
+ primer_info['Primer'] = f"Left {i+1}"
99
+ primer_data.append(primer_info)
100
+ primer_info = {
101
+ 'Primer Pair': i + 1,
102
+ 'Left Sequence': primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A'),
103
+ 'Right Sequence': primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A'),
104
+ 'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
105
+ 'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
106
+ 'Left Length': primers.get(f'PRIMER_LEFT_{i}_SIZE', 'N/A'),
107
+ 'Right Length': primers.get(f'PRIMER_RIGHT_{i}_SIZE', 'N/A'),
108
+ 'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
109
+ }
110
+ if primer_info['Left Sequence'] != 'N/A' and primer_info['Right Sequence'] != 'N/A':
111
+ primer_info['Primer'] = f"Right {i+1}"
112
+ primer_data.append(primer_info)
113
+
114
+ if primer_data:
115
+ primer_df = pd.DataFrame(primer_data)
116
+ display_primer_results(primer_df)
117
+ else:
118
+ st.error('No primers were found. Please adjust your parameters and try again.')
119
+ else:
120
+ # Design primers for multiple features
121
+ uploaded_features = st.file_uploader("Upload a file containing multiple sequences (FASTA format)", type=['fasta'])
122
+ if uploaded_features is not None:
123
+ feature_records = list(SeqIO.parse(uploaded_features, "fasta"))
124
+ st.write(f"Number of sequences uploaded: {len(feature_records)}")
125
+
126
+ # Iterate over each sequence and design primers
127
+ for index, record in enumerate(feature_records):
128
+ st.write(f"### Sequence {index + 1}: {record.id} (length: {len(record.seq)})")
129
+ product_size_range = st.text_input("Enter desired PCR product size range (e.g., 150-500):", value="150-500")
130
+
131
+ if st.button(f'Design Primers for Sequence {index + 1}'):
132
+ primers = design_primers_for_region(record.seq, product_size_range, num_to_return=5)
133
+ primer_data = []
134
+ for i in range(5): # Collect data for 5 primer pairs
135
+ primer_info = {
136
+ 'Primer Pair': i + 1,
137
+ 'Left Sequence': primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A'),
138
+ 'Right Sequence': primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A'),
139
+ 'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
140
+ 'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
141
+ 'Left Length': primers.get(f'PRIMER_LEFT_{i}_SIZE', 'N/A'),
142
+ 'Right Length': primers.get(f'PRIMER_RIGHT_{i}_SIZE', 'N/A'),
143
+ 'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
144
+ }
145
+ if primer_info['Left Sequence'] != 'N/A' and primer_info['Right Sequence'] != 'N/A':
146
+ primer_info['Primer'] = f"Left {i+1}"
147
+ primer_data.append(primer_info)
148
+ primer_info = {
149
+ 'Primer Pair': i + 1,
150
+ 'Left Sequence': primers.get(f'PRIMER_LEFT_{i}_SEQUENCE', 'N/A'),
151
+ 'Right Sequence': primers.get(f'PRIMER_RIGHT_{i}_SEQUENCE', 'N/A'),
152
+ 'Left TM (°C)': primers.get(f'PRIMER_LEFT_{i}_TM', 'N/A'),
153
+ 'Right TM (°C)': primers.get(f'PRIMER_RIGHT_{i}_TM', 'N/A'),
154
+ 'Left Length': primers.get(f'PRIMER_LEFT_{i}_SIZE', 'N/A'),
155
+ 'Right Length': primers.get(f'PRIMER_RIGHT_{i}_SIZE', 'N/A'),
156
+ 'PCR Product Size (bp)': primers.get(f'PRIMER_PAIR_{i}_PRODUCT_SIZE', 'N/A')
157
+ }
158
+ if primer_info['Left Sequence'] != 'N/A' and primer_info['Right Sequence'] != 'N/A':
159
+ primer_info['Primer'] = f"Right {i+1}"
160
+ primer_data.append(primer_info)
161
 
162
+ if primer_data:
163
+ primer_df = pd.DataFrame(primer_data)
164
+ display_primer_results(primer_df)
165
+ else:
166
+ st.error(f'No primers were found for Sequence {index + 1}. Please adjust your parameters and try again.')