-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.py
161 lines (135 loc) · 5.6 KB
/
app.py
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
from flask import Flask, request, jsonify, send_file, render_template
from flask import send_from_directory, abort
from werkzeug.utils import safe_join
from flask import send_file, request
import os
from Bio.PDB import PDBParser
import numpy as np
import time
app = Flask(__name__, static_folder='static', template_folder='templates')
@app.route('/')
def home():
return render_template('index.html')
return "Flask app is running. Use the /upload endpoint."
# Folder for uploaded files
UPLOAD_FOLDER = './uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
# Route for uploading files
@app.route('/upload', methods=['POST'])
def upload_pdb():
file = request.files.get('file')
if not file or not file.filename.endswith('.pdb'):
return jsonify({'error': 'Invalid file type. Please upload a PDB file.'}), 400
filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(filepath)
return jsonify({'message': 'File uploaded successfully!', 'filepath': filepath})
@app.route('/grid', methods=['POST'])
def generate_grid():
try:
# Parse incoming JSON request
data = request.json
filepath = data.get('filepath') # Path to the uploaded file
mode = data.get('mode') # Docking mode: "blind" or "targeted"
residues = data.get('residues', []) # Targeted residues as a list
# Check if file exists
if not filepath or not os.path.exists(filepath):
return jsonify({'error': 'File not found. Please upload a valid file.'}), 400
# Parse the PDB file
parser = PDBParser()
structure = parser.get_structure('protein', filepath)
coords = []
if mode == 'blind':
# Collect all atom coordinates for blind docking
for atom in structure.get_atoms():
coords.append(atom.coord)
elif mode == 'targeted':
if not residues:
return jsonify({'error': 'No residues specified for targeted docking.'}), 400
# Extract coordinates of specific residues
for residue in residues:
residue = residue.strip()
chain_id, res_id = residue.split(':')
chain_id = chain_id.strip()
res_id = res_id.strip()
for chain in structure.get_chains():
if chain.id == chain_id:
for res in chain.get_residues():
if res.id[1] == int(res_id): # Match residue number
for atom in res:
coords.append(atom.coord)
else:
return jsonify({'error': 'Invalid mode selected.'}), 400
if not coords:
return jsonify({'error': 'No atoms found for the specified residues.'}), 400
coords = np.array(coords)
min_coords = coords.min(axis=0) - 5 # Add buffer
max_coords = coords.max(axis=0) + 5 # Add buffer
center = (min_coords + max_coords) / 2
size = max_coords - min_coords
# Create configuration file for grid box
config = f"""
center_x = {center[0]}
center_y = {center[1]}
center_z = {center[2]}
size_x = {size[0]}
size_y = {size[1]}
size_z = {size[2]}
"""
# Generate a unique filename using timestamp and mode
timestamp = int(time.time())
config_filename = f'config_{mode}_{timestamp}.txt'
config_path = os.path.join(app.config['UPLOAD_FOLDER'], config_filename)
with open(config_path, 'w') as f:
f.write(config)
# Extract grid dimensions to send to the client
grid_dimensions = {
'center_x': float(center[0]),
'center_y': float(center[1]),
'center_z': float(center[2]),
'size_x': float(size[0]),
'size_y': float(size[1]),
'size_z': float(size[2]),
}
# Return the filename to the client for reference or download
return jsonify({
'message': 'Grid configuration generated!',
'config_file': config_filename,
'config_path': config_path,
'grid_dimensions': grid_dimensions
})
except Exception as e:
app.logger.error(f"Error during grid generation: {e}")
return jsonify({'error': 'An error occurred during grid generation.'}), 500
@app.route('/download/<filename>', methods=['GET'])
def download_file(filename):
try:
# Log the filename
app.logger.debug(f"Requested filename: {filename}")
# Use safe_join to construct the file path
file_path = safe_join(app.config['UPLOAD_FOLDER'], filename)
app.logger.debug(f"Constructed file path: {file_path}")
# Check if the file exists
if not os.path.isfile(file_path):
app.logger.error(f"File not found at path: {file_path}")
abort(404)
# Send the file
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
except Exception as e:
app.logger.error(f"Error during file download: {e}")
return jsonify({'error': 'An error occurred during file download.'}), 500
@app.route('/get_pdb', methods=['GET'])
def get_pdb():
filepath = request.args.get('filepath')
if not filepath or not os.path.exists(filepath):
return jsonify({'error': 'File not found.'}), 404
return send_file(filepath, mimetype='chemical/x-pdb')
if __name__ == '__main__':
app.run(debug=True)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000), debug=True))