Spaces:
Running
Running
yinuozhang
commited on
Commit
•
4f4356d
1
Parent(s):
3226415
add more functions
Browse files
app.py
CHANGED
@@ -241,16 +241,18 @@ def analyze_single_smiles(smiles):
|
|
241 |
def annotate_cyclic_structure(mol, sequence):
|
242 |
"""Create annotated 2D structure with clear, non-overlapping residue labels"""
|
243 |
# Generate 2D coordinates
|
|
|
244 |
AllChem.Compute2DCoords(mol)
|
245 |
|
246 |
# Create drawer with larger size for annotations
|
247 |
drawer = Draw.rdMolDraw2D.MolDraw2DCairo(2000, 2000) # Even larger size
|
248 |
|
249 |
-
# Get residue list
|
250 |
if sequence.startswith('cyclo('):
|
251 |
residues = sequence[6:-1].split('-')
|
252 |
else:
|
253 |
residues = sequence.split('-')
|
|
|
254 |
|
255 |
# Draw molecule first to get its bounds
|
256 |
drawer.drawOptions().addAtomIndices = False
|
@@ -260,6 +262,7 @@ def annotate_cyclic_structure(mol, sequence):
|
|
260 |
# Convert to PIL Image
|
261 |
img = Image.open(BytesIO(drawer.GetDrawingText()))
|
262 |
draw = ImageDraw.Draw(img)
|
|
|
263 |
try:
|
264 |
# Try to use DejaVuSans as it's commonly available on Linux systems
|
265 |
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 60)
|
@@ -274,7 +277,6 @@ def annotate_cyclic_structure(mol, sequence):
|
|
274 |
print("Warning: TrueType fonts not available, using default font")
|
275 |
font = ImageFont.load_default()
|
276 |
small_font = ImageFont.load_default()
|
277 |
-
|
278 |
# Get molecule bounds
|
279 |
conf = mol.GetConformer()
|
280 |
positions = []
|
@@ -296,16 +298,19 @@ def annotate_cyclic_structure(mol, sequence):
|
|
296 |
n_residues = len(residues)
|
297 |
radius = 700 # Distance of labels from center
|
298 |
|
|
|
|
|
|
|
299 |
for i, residue in enumerate(residues):
|
300 |
# Calculate position in a circle around the structure
|
301 |
-
|
|
|
302 |
|
303 |
# Calculate label position
|
304 |
label_x = center_x + radius * np.cos(angle)
|
305 |
label_y = center_y + radius * np.sin(angle)
|
306 |
|
307 |
# Draw residue label
|
308 |
-
# Add white background for better visibility
|
309 |
text = f"{i+1}. {residue}"
|
310 |
bbox = draw.textbbox((label_x, label_y), text, font=font)
|
311 |
padding = 10
|
@@ -569,8 +574,8 @@ iface = gr.Interface(
|
|
569 |
Input: Either enter a SMILES string directly or upload a text file containing SMILES strings
|
570 |
|
571 |
Example SMILES strings:
|
572 |
-
1. CC(C)C[C@@H]1NC(=O)[C@@H]
|
573 |
-
2.
|
574 |
""",
|
575 |
flagging_mode="never"
|
576 |
)
|
|
|
241 |
def annotate_cyclic_structure(mol, sequence):
|
242 |
"""Create annotated 2D structure with clear, non-overlapping residue labels"""
|
243 |
# Generate 2D coordinates
|
244 |
+
# Generate 2D coordinates
|
245 |
AllChem.Compute2DCoords(mol)
|
246 |
|
247 |
# Create drawer with larger size for annotations
|
248 |
drawer = Draw.rdMolDraw2D.MolDraw2DCairo(2000, 2000) # Even larger size
|
249 |
|
250 |
+
# Get residue list and reverse it to match structural representation
|
251 |
if sequence.startswith('cyclo('):
|
252 |
residues = sequence[6:-1].split('-')
|
253 |
else:
|
254 |
residues = sequence.split('-')
|
255 |
+
residues = list(reversed(residues)) # Reverse the sequence
|
256 |
|
257 |
# Draw molecule first to get its bounds
|
258 |
drawer.drawOptions().addAtomIndices = False
|
|
|
262 |
# Convert to PIL Image
|
263 |
img = Image.open(BytesIO(drawer.GetDrawingText()))
|
264 |
draw = ImageDraw.Draw(img)
|
265 |
+
|
266 |
try:
|
267 |
# Try to use DejaVuSans as it's commonly available on Linux systems
|
268 |
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 60)
|
|
|
277 |
print("Warning: TrueType fonts not available, using default font")
|
278 |
font = ImageFont.load_default()
|
279 |
small_font = ImageFont.load_default()
|
|
|
280 |
# Get molecule bounds
|
281 |
conf = mol.GetConformer()
|
282 |
positions = []
|
|
|
298 |
n_residues = len(residues)
|
299 |
radius = 700 # Distance of labels from center
|
300 |
|
301 |
+
# Start from the rightmost point (3 o'clock position) and go counterclockwise
|
302 |
+
# Offset by -3 positions to align with structure
|
303 |
+
offset = 0 # Adjust this value to match the structure alignment
|
304 |
for i, residue in enumerate(residues):
|
305 |
# Calculate position in a circle around the structure
|
306 |
+
# Start from 0 (3 o'clock) and go counterclockwise
|
307 |
+
angle = -(2 * np.pi * ((i + offset) % n_residues) / n_residues)
|
308 |
|
309 |
# Calculate label position
|
310 |
label_x = center_x + radius * np.cos(angle)
|
311 |
label_y = center_y + radius * np.sin(angle)
|
312 |
|
313 |
# Draw residue label
|
|
|
314 |
text = f"{i+1}. {residue}"
|
315 |
bbox = draw.textbbox((label_x, label_y), text, font=font)
|
316 |
padding = 10
|
|
|
574 |
Input: Either enter a SMILES string directly or upload a text file containing SMILES strings
|
575 |
|
576 |
Example SMILES strings:
|
577 |
+
1. CC(C)C[C@@H]1NC(=O)[C@@H](CC(C)C)N(C)C(=O)[C@@H](C)N(C)C(=O)[C@H](Cc2ccccc2)NC(=O)[C@H](CC(C)C)N(C)C(=O)[C@H]2CCCN2C1=O
|
578 |
+
2. C(C)C[C@@H]1NC(=O)[C@@H]2CCCN2C(=O)[C@@H](CC(C)C)NC(=O)[C@@H](CC(C)C)N(C)C(=O)[C@H](C)NC(=O)[C@H](Cc2ccccc2)NC1=O
|
579 |
""",
|
580 |
flagging_mode="never"
|
581 |
)
|