Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -124,21 +124,21 @@ if st.session_state.get("is_genbank"):
|
|
| 124 |
st.warning("No features found. Using full sequence.")
|
| 125 |
target_sequence = record.seq
|
| 126 |
|
| 127 |
-
#
|
| 128 |
if target_sequence:
|
| 129 |
st.subheader("Sequence Preview")
|
| 130 |
st.code(str(target_sequence), language="text")
|
| 131 |
|
| 132 |
-
# Step
|
| 133 |
if target_sequence:
|
| 134 |
-
st.subheader("Step
|
| 135 |
size_range = st.slider("PCR product size (bp)", 100, len(target_sequence), (100, min(500, len(target_sequence))), step=10)
|
| 136 |
primer_count = st.number_input("Number of primer pairs", 1, 20, 5)
|
| 137 |
hp_thresh = st.number_input("Max hairpin Tm (°C)", 0.0, 100.0, 45.0)
|
| 138 |
dim_thresh = st.number_input("Max dimer Tm (°C)", 0.0, 100.0, 45.0)
|
| 139 |
|
| 140 |
if st.button("Design Primers"):
|
| 141 |
-
with st.spinner("Designing primers and checking
|
| 142 |
res = design_primers(target_sequence, f"{size_range[0]}-{size_range[1]}", primer_count)
|
| 143 |
rows = []
|
| 144 |
for i in range(primer_count):
|
|
@@ -161,8 +161,12 @@ if target_sequence:
|
|
| 161 |
})
|
| 162 |
df = pd.DataFrame(rows)
|
| 163 |
df_unique = df.drop_duplicates(subset=["Left Seq","Right Seq"]).reset_index(drop=True)
|
| 164 |
-
df_filtered = df_unique[
|
| 165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
|
| 167 |
# Display and annotate results
|
| 168 |
if 'primer_df' in st.session_state and not st.session_state['primer_df'].empty:
|
|
@@ -181,20 +185,22 @@ if target_sequence:
|
|
| 181 |
- **Left HP Tm (°C)**: Hairpin melting temp for forward primer.
|
| 182 |
- **Right HP Tm (°C)**: Hairpin melting temp for reverse primer.
|
| 183 |
- **Dimer Tm (°C)**: Heterodimer melting temp between primers.
|
| 184 |
-
"""
|
| 185 |
-
)
|
| 186 |
|
| 187 |
csv = df.to_csv(index=False).encode('utf-8')
|
| 188 |
-
st.download_button("Download Primer Table", csv, "primers.csv", "text/csv")
|
| 189 |
|
| 190 |
selected = st.selectbox("Select Primer Pair to View", df["Pair"], key="viz_pair")
|
| 191 |
-
row = df[df["Pair"]==selected].iloc[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
fig = plot_primer_binding(
|
| 193 |
len(target_sequence),
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
row["R_Pos"] if "R_Pos" in row else len(target_sequence),
|
| 197 |
-
res[f'PRIMER_RIGHT_{selected-1}'][1] if f'PRIMER_RIGHT_{selected-1}' in res else 0,
|
| 198 |
row["Product Size (bp)"]
|
| 199 |
)
|
| 200 |
st.pyplot(fig)
|
|
|
|
| 124 |
st.warning("No features found. Using full sequence.")
|
| 125 |
target_sequence = record.seq
|
| 126 |
|
| 127 |
+
# Step 3: Sequence Preview
|
| 128 |
if target_sequence:
|
| 129 |
st.subheader("Sequence Preview")
|
| 130 |
st.code(str(target_sequence), language="text")
|
| 131 |
|
| 132 |
+
# Step 4: Primer Design
|
| 133 |
if target_sequence:
|
| 134 |
+
st.subheader("Step 4: Primer Design")
|
| 135 |
size_range = st.slider("PCR product size (bp)", 100, len(target_sequence), (100, min(500, len(target_sequence))), step=10)
|
| 136 |
primer_count = st.number_input("Number of primer pairs", 1, 20, 5)
|
| 137 |
hp_thresh = st.number_input("Max hairpin Tm (°C)", 0.0, 100.0, 45.0)
|
| 138 |
dim_thresh = st.number_input("Max dimer Tm (°C)", 0.0, 100.0, 45.0)
|
| 139 |
|
| 140 |
if st.button("Design Primers"):
|
| 141 |
+
with st.spinner("Designing primers and checking structures..."):
|
| 142 |
res = design_primers(target_sequence, f"{size_range[0]}-{size_range[1]}", primer_count)
|
| 143 |
rows = []
|
| 144 |
for i in range(primer_count):
|
|
|
|
| 161 |
})
|
| 162 |
df = pd.DataFrame(rows)
|
| 163 |
df_unique = df.drop_duplicates(subset=["Left Seq","Right Seq"]).reset_index(drop=True)
|
| 164 |
+
df_filtered = df_unique[
|
| 165 |
+
(df_unique["Left HP Tm (°C)"] <= hp_thresh) &
|
| 166 |
+
(df_unique["Right HP Tm (°C)"] <= hp_thresh) &
|
| 167 |
+
(df_unique["Dimer Tm (°C)"] <= dim_thresh)
|
| 168 |
+
]
|
| 169 |
+
st.session_state['primer_df'] = df_filtered
|
| 170 |
|
| 171 |
# Display and annotate results
|
| 172 |
if 'primer_df' in st.session_state and not st.session_state['primer_df'].empty:
|
|
|
|
| 185 |
- **Left HP Tm (°C)**: Hairpin melting temp for forward primer.
|
| 186 |
- **Right HP Tm (°C)**: Hairpin melting temp for reverse primer.
|
| 187 |
- **Dimer Tm (°C)**: Heterodimer melting temp between primers.
|
| 188 |
+
""")
|
|
|
|
| 189 |
|
| 190 |
csv = df.to_csv(index=False).encode('utf-8')
|
| 191 |
+
st.download_button("Download Primer Table", csv, "primers.csv", "text/csv")
|
| 192 |
|
| 193 |
selected = st.selectbox("Select Primer Pair to View", df["Pair"], key="viz_pair")
|
| 194 |
+
row = df[df["Pair"] == selected].iloc[0]
|
| 195 |
+
# retrieve positions for visualization
|
| 196 |
+
left_pos = res.get(f'PRIMER_LEFT_{selected-1}')[0]
|
| 197 |
+
left_len = res.get(f'PRIMER_LEFT_{selected-1}')[1]
|
| 198 |
+
right_pos = res.get(f'PRIMER_RIGHT_{selected-1}')[0]
|
| 199 |
+
right_len = res.get(f'PRIMER_RIGHT_{selected-1}')[1]
|
| 200 |
fig = plot_primer_binding(
|
| 201 |
len(target_sequence),
|
| 202 |
+
left_pos, left_len,
|
| 203 |
+
right_pos, right_len,
|
|
|
|
|
|
|
| 204 |
row["Product Size (bp)"]
|
| 205 |
)
|
| 206 |
st.pyplot(fig)
|