Spaces:
No application file
No application file
Update app.py
Browse files
app.py
CHANGED
|
@@ -223,148 +223,175 @@ def format_metrics_display(metrics: Dict) -> str:
|
|
| 223 |
|
| 224 |
def load_example_sequence():
|
| 225 |
"""Load an example DNA sequence for testing"""
|
| 226 |
-
example = """
|
| 227 |
return example
|
| 228 |
|
| 229 |
def clear_inputs():
|
| 230 |
"""Clear all input fields"""
|
| 231 |
return "", None, None, ""
|
| 232 |
|
| 233 |
-
# Create the Gradio interface
|
| 234 |
def create_interface():
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
with gr.Blocks(
|
| 244 |
-
title="Gene Prediction Tool",
|
| 245 |
-
theme=gr.themes.Soft(),
|
| 246 |
-
css="footer {visibility: hidden}"
|
| 247 |
-
) as interface:
|
| 248 |
-
|
| 249 |
-
gr.Markdown(f"""
|
| 250 |
-
# 🧬 Gene Prediction Tool
|
| 251 |
-
|
| 252 |
-
This tool predicts gene regions in DNA sequences using a boundary-aware deep learning model.
|
| 253 |
-
The model identifies start and end positions of genes, along with confidence scores and detailed analysis.
|
| 254 |
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
|
|
|
| 259 |
|
| 260 |
-
with
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
|
| 273 |
with gr.Row():
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
gt_start = gr.Number(
|
| 284 |
-
label="Start Position",
|
| 285 |
-
precision=0,
|
| 286 |
-
value=None,
|
| 287 |
-
minimum=0
|
| 288 |
-
)
|
| 289 |
-
gt_end = gr.Number(
|
| 290 |
-
label="End Position",
|
| 291 |
-
precision=0,
|
| 292 |
-
value=None,
|
| 293 |
-
minimum=0
|
| 294 |
-
)
|
| 295 |
-
|
| 296 |
-
gt_labels = gr.Textbox(
|
| 297 |
-
label="OR: Labels (comma-separated 0s and 1s)",
|
| 298 |
-
placeholder="0,0,1,1,1,0,0...",
|
| 299 |
-
lines=2,
|
| 300 |
-
info="Alternative to start/end positions"
|
| 301 |
)
|
| 302 |
-
|
| 303 |
-
with gr.Column(scale=3):
|
| 304 |
-
# Output section
|
| 305 |
-
gr.Markdown("## 🔬 Prediction Results")
|
| 306 |
|
| 307 |
-
|
| 308 |
-
|
|
|
|
|
|
|
| 309 |
)
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
)
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
|
| 323 |
-
|
| 324 |
-
example_btn.click(
|
| 325 |
-
fn=load_example_sequence,
|
| 326 |
-
outputs=sequence_input
|
| 327 |
-
)
|
| 328 |
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
)
|
| 333 |
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
|
|
|
|
|
|
|
| 338 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
|
| 340 |
-
#
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
|
|
|
|
|
|
|
|
|
| 345 |
)
|
| 346 |
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
# For Hugging Face Spaces, this will start the app
|
| 364 |
-
# For local development, you can add debug=True
|
| 365 |
-
interface.launch()
|
| 366 |
-
|
| 367 |
-
except Exception as e:
|
| 368 |
-
print(f"❌ Failed to create Gradio interface: {e}")
|
| 369 |
-
print(f"Full traceback: {traceback.format_exc()}")
|
| 370 |
-
raise
|
|
|
|
| 223 |
|
| 224 |
def load_example_sequence():
|
| 225 |
"""Load an example DNA sequence for testing"""
|
| 226 |
+
example = """ATGAAACGCATTAGCACCACCATTACCACCACCATCACCATTACCACAGGTAACGGTGCGGGCTGACGCGTACAGGAAACACAGAAAAAAGCCCGCACCTGACAGTGCGGGCTTTTTTTTTCGACCAAAGGTAACGAGGTAACAACCATGCGAGTGTTGAAGTTCGGCGGTACATCAGTGGCAAATGCAGAACGTTTTCTGCGGGTTGCCGATATTCTGGAAAGCAATGCCAGGCAGGGGCAGGTGGCCACCGTCCTCTCTGCCCCCGCCAAAATCACCAACCACCTGGTGGCGATGATTGAAAAAACCATTAGCGGCCAGGATGCTTTACCCAATATCAGCGATGCCGAACGTATTTTTGCCGAACTTTTGACGGGACTCGCCGCCGCCCAGCCGGGGTTCCCGCTGGCGCAATTGAAAACTTTCGTCGATCAGGAATTTGCCCAAATAAAACATGTCCTGCATGGCATTAGTTTGTTGGGGCAGTGCCCGGATAGCATCAACGCTGCGCTGATTTGCCGTGGCGAGAAAATGTCGATCGCCATTATGGCCGGCGTATTAGAAGCGCGCGGTCACAACGTTACTGTTATCGATCCGGTCGAAAAACTGCTGGCAGTGGGGCATTACCTCGAATCTACCGTCGATATTGCTGAGTCCACCCGCCGTATTGCGGCAAGCCGCATTCCGGCTGATCACATGGTGCTGATGGCAGGTTTCACCGCCGGTAATGAAAAAGGCGAACTGGTGGTGCTTGGACGCAACGGTTCCGACTACTCTGCTGCGGTGCTGGCTGCCTGTTTACGCGCCGATTGTTGCGAGATTTGGACGGACGTTGACGGGGTCTATACCTGCGACCCGCGTCAGGTGCCCGATGCGAGGTTGTTGAAGTCGATGTCCTACCAGGAAGCGATGGAGCTTTCCTACTTCGGCGCTAAAGTTCTTCACCCCCGCACCATTACCCCCATCGCCCAGTTCCAGATCCCTTGCCTGATTAAAAATACCGGAAATCCTCAAGCACCAGGTACGCTCATTGGTGCCAGCCGTGATGAAGACGAATTACCGGTCAAGGGCATTTCCAATCTGAATAACATGGCAATGTTCAGCGTTTCCGGCCCGGGGATGAAAGGGATGGTCGGCATGGCGGCGCGCGTCTTTGCAGCGATGTCACGCGCCCGTATTTCCGTGGTGCTGATTACGCAATCATCTTCCGAATACAGCATCAGTTTCTGCGTTCCACAAAGCGACTGTGTGCGAGCTGAACGGGCAATGCAGGAAGAGTTCTACCTGGAACTGAAAGAAGGCTTACTGGAGCCGCTGGCAGTGACGGAACGGCTGGCCATTATCTCGGTGGTAGG"""
|
| 227 |
return example
|
| 228 |
|
| 229 |
def clear_inputs():
|
| 230 |
"""Clear all input fields"""
|
| 231 |
return "", None, None, ""
|
| 232 |
|
| 233 |
+
# Create the Gradio interface with simpler structure
|
| 234 |
def create_interface():
|
| 235 |
+
try:
|
| 236 |
+
# Show setup status
|
| 237 |
+
if predictor:
|
| 238 |
+
status_message = "✅ Model loaded successfully!"
|
| 239 |
+
status_color = "green"
|
| 240 |
+
else:
|
| 241 |
+
status_message = f"��� Model failed to load: {initialization_error}"
|
| 242 |
+
status_color = "red"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
+
# Create interface with minimal configuration
|
| 245 |
+
interface = gr.Blocks(
|
| 246 |
+
title="Gene Prediction Tool",
|
| 247 |
+
theme=gr.themes.Default() # Use default theme instead of Soft
|
| 248 |
+
)
|
| 249 |
|
| 250 |
+
with interface:
|
| 251 |
+
# Header
|
| 252 |
+
gr.HTML(f"""
|
| 253 |
+
<div style="text-align: center; padding: 20px;">
|
| 254 |
+
<h1>🧬 Gene Prediction Tool</h1>
|
| 255 |
+
<p>This tool predicts gene regions in DNA sequences using a boundary-aware deep learning model.</p>
|
| 256 |
+
<div style="padding: 10px; border-left: 4px solid {status_color}; background-color: #f9f9f9; margin: 10px 0;">
|
| 257 |
+
<strong>Status:</strong> {status_message}
|
| 258 |
+
</div>
|
| 259 |
+
</div>
|
| 260 |
+
""")
|
| 261 |
+
|
| 262 |
+
# Input section
|
| 263 |
+
gr.Markdown("## 📝 Input")
|
| 264 |
+
|
| 265 |
+
sequence_input = gr.Textbox(
|
| 266 |
+
label="DNA Sequence",
|
| 267 |
+
placeholder="Enter your DNA sequence (A, C, T, G, N only)...",
|
| 268 |
+
lines=5,
|
| 269 |
+
info="Maximum length: 10,000 nucleotides"
|
| 270 |
+
)
|
| 271 |
+
|
| 272 |
+
with gr.Row():
|
| 273 |
+
example_btn = gr.Button("📋 Load Example", size="sm")
|
| 274 |
+
clear_btn = gr.Button("🗑️ Clear", size="sm")
|
| 275 |
+
predict_btn = gr.Button("🔬 Predict Genes", variant="primary")
|
| 276 |
+
|
| 277 |
+
# Ground truth section (optional)
|
| 278 |
+
with gr.Accordion("🎯 Ground Truth (Optional)", open=False):
|
| 279 |
+
gr.Markdown("*Provide ground truth data to calculate accuracy metrics*")
|
| 280 |
|
| 281 |
with gr.Row():
|
| 282 |
+
gt_start = gr.Number(
|
| 283 |
+
label="Start Position",
|
| 284 |
+
precision=0,
|
| 285 |
+
minimum=0
|
| 286 |
+
)
|
| 287 |
+
gt_end = gr.Number(
|
| 288 |
+
label="End Position",
|
| 289 |
+
precision=0,
|
| 290 |
+
minimum=0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 291 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
|
| 293 |
+
gt_labels = gr.Textbox(
|
| 294 |
+
label="OR: Labels (comma-separated 0s and 1s)",
|
| 295 |
+
placeholder="0,0,1,1,1,0,0...",
|
| 296 |
+
info="Alternative to start/end positions"
|
| 297 |
)
|
| 298 |
+
|
| 299 |
+
# Output section
|
| 300 |
+
gr.Markdown("## 🔬 Prediction Results")
|
| 301 |
+
|
| 302 |
+
regions_output = gr.Markdown(
|
| 303 |
+
value="*Results will appear here after prediction...*"
|
| 304 |
+
)
|
| 305 |
+
|
| 306 |
+
metrics_output = gr.Markdown(
|
| 307 |
+
value="*Metrics will appear here if ground truth is provided...*"
|
| 308 |
+
)
|
| 309 |
+
|
| 310 |
+
# Detailed JSON output (collapsible)
|
| 311 |
+
with gr.Accordion("📄 Detailed JSON Output", open=False):
|
| 312 |
+
json_output = gr.Code(
|
| 313 |
+
language="json",
|
| 314 |
+
value="{}",
|
| 315 |
+
lines=10
|
| 316 |
)
|
| 317 |
+
|
| 318 |
+
# Event handlers
|
| 319 |
+
example_btn.click(
|
| 320 |
+
fn=load_example_sequence,
|
| 321 |
+
outputs=sequence_input
|
| 322 |
+
)
|
| 323 |
+
|
| 324 |
+
clear_btn.click(
|
| 325 |
+
fn=clear_inputs,
|
| 326 |
+
outputs=[sequence_input, gt_start, gt_end, gt_labels]
|
| 327 |
+
)
|
| 328 |
+
|
| 329 |
+
predict_btn.click(
|
| 330 |
+
fn=predict_gene_regions,
|
| 331 |
+
inputs=[sequence_input, gt_labels, gt_start, gt_end],
|
| 332 |
+
outputs=[regions_output, metrics_output, json_output]
|
| 333 |
+
)
|
| 334 |
+
|
| 335 |
+
# Also trigger prediction on Enter in the sequence box
|
| 336 |
+
sequence_input.submit(
|
| 337 |
+
fn=predict_gene_regions,
|
| 338 |
+
inputs=[sequence_input, gt_labels, gt_start, gt_end],
|
| 339 |
+
outputs=[regions_output, metrics_output, json_output]
|
| 340 |
+
)
|
| 341 |
+
|
| 342 |
+
# Footer
|
| 343 |
+
gr.Markdown("""
|
| 344 |
+
---
|
| 345 |
+
**Model Info:** Boundary-aware gene prediction using multi-task deep learning
|
| 346 |
+
**Supported:** DNA sequences with A, C, T, G, N nucleotides
|
| 347 |
+
**Output:** Gene regions with start/end positions, codons, and confidence scores
|
| 348 |
+
""")
|
| 349 |
|
| 350 |
+
return interface
|
|
|
|
|
|
|
|
|
|
|
|
|
| 351 |
|
| 352 |
+
except Exception as e:
|
| 353 |
+
print(f"❌ Error creating interface: {e}")
|
| 354 |
+
print(f"Full traceback: {traceback.format_exc()}")
|
|
|
|
| 355 |
|
| 356 |
+
# Create a minimal fallback interface
|
| 357 |
+
fallback_interface = gr.Interface(
|
| 358 |
+
fn=lambda x: f"Error: {str(e)}",
|
| 359 |
+
inputs=gr.Textbox(label="DNA Sequence"),
|
| 360 |
+
outputs=gr.Textbox(label="Output"),
|
| 361 |
+
title="Gene Prediction Tool - Error Recovery Mode"
|
| 362 |
)
|
| 363 |
+
return fallback_interface
|
| 364 |
+
|
| 365 |
+
# Main execution
|
| 366 |
+
if __name__ == "__main__":
|
| 367 |
+
try:
|
| 368 |
+
print("Creating Gradio interface...")
|
| 369 |
+
interface = create_interface()
|
| 370 |
+
print("✅ Gradio interface created successfully")
|
| 371 |
|
| 372 |
+
# Launch the interface
|
| 373 |
+
# Remove custom CSS and use default settings for HF Spaces
|
| 374 |
+
interface.launch(
|
| 375 |
+
server_name="0.0.0.0", # Important for HF Spaces
|
| 376 |
+
server_port=7860, # Standard port for HF Spaces
|
| 377 |
+
share=False, # Don't create public link on HF Spaces
|
| 378 |
+
debug=False, # Turn off debug mode for production
|
| 379 |
+
show_error=True # Show errors in interface
|
| 380 |
)
|
| 381 |
|
| 382 |
+
except Exception as e:
|
| 383 |
+
print(f"❌ Failed to launch interface: {e}")
|
| 384 |
+
print(f"Full traceback: {traceback.format_exc()}")
|
| 385 |
+
|
| 386 |
+
# Last resort - create the simplest possible interface
|
| 387 |
+
try:
|
| 388 |
+
simple_interface = gr.Interface(
|
| 389 |
+
fn=lambda x: "Simple interface loaded - main interface failed",
|
| 390 |
+
inputs=gr.Textbox(label="Test Input"),
|
| 391 |
+
outputs=gr.Textbox(label="Test Output"),
|
| 392 |
+
title="Gene Prediction Tool - Minimal Mode"
|
| 393 |
+
)
|
| 394 |
+
simple_interface.launch()
|
| 395 |
+
except Exception as e2:
|
| 396 |
+
print(f"❌ Even simple interface failed: {e2}")
|
| 397 |
+
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|