Getting your Trinity Audio player ready…
|
With openaiGPTo1-preview
Explanation:
- Amino Acid Properties: We define a dictionary amino_acids that maps each amino acid to its type based on hydrophobicity and charge.
- Initialization: The protein sequence is placed randomly within a 3D grid.
- Interaction Rules:
- Hydrophobic Interactions: Hydrophobic amino acids tend to move closer together to avoid contact with the aqueous environment.
- Electrostatic Interactions: Positively charged amino acids are attracted to negatively charged ones and vice versa.
- Charge Repulsion: Amino acids with the same charge repel each other.
- Update Function: update_positions moves amino acids according to the interaction rules, updating their positions on the grid.
- Simulation Loop: The simulation runs for a specified number of steps, updating positions at each step.
- Visualization: The final positions of the amino acids are plotted in a 3D scatter plot, color-coded based on their properties.
Customization:
- Protein Sequence: You can modify the protein_sequence variable to simulate different proteins.
- Grid Size: Adjust the grid_size variable to change the simulation space.
- Simulation Steps: Modify the steps variable to run the simulation for more or fewer iterations.
Limitations:
- This model is highly simplified and does not capture the full complexity of protein folding.
- The movement rules are basic and do not account for all physical forces involved in actual protein folding.
- For more accurate simulations, molecular dynamics software or specialized protein folding algorithms should be used.
References to ML Insights:
The rules used in this simulation are inspired by patterns identified through machine learning in protein folding studies:
- Hydrophobic Collapse: ML models have shown the significance of hydrophobic interactions in the early stages of folding.
- Electrostatic Interactions: Machine learning has helped in understanding the role of long-range electrostatic interactions.
- Secondary Structure Formation: While not explicitly modeled here, ML has contributed to predicting alpha-helices and beta-sheets formations.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random
# Define amino acid properties
amino_acids = {
‘A’: {‘type’: ‘hydrophobic’},
‘C’: {‘type’: ‘hydrophobic’},
‘D’: {‘type’: ‘negatively_charged’},
‘E’: {‘type’: ‘negatively_charged’},
‘F’: {‘type’: ‘hydrophobic’},
‘G’: {‘type’: ‘hydrophobic’},
‘H’: {‘type’: ‘positively_charged’},
‘I’: {‘type’: ‘hydrophobic’},
‘K’: {‘type’: ‘positively_charged’},
‘L’: {‘type’: ‘hydrophobic’},
‘M’: {‘type’: ‘hydrophobic’},
‘N’: {‘type’: ‘polar’},
‘P’: {‘type’: ‘hydrophobic’},
‘Q’: {‘type’: ‘polar’},
‘R’: {‘type’: ‘positively_charged’},
‘S’: {‘type’: ‘polar’},
‘T’: {‘type’: ‘polar’},
‘V’: {‘type’: ‘hydrophobic’},
‘W’: {‘type’: ‘hydrophobic’},
‘Y’: {‘type’: ‘polar’},
}
# Initial protein sequence (You can modify this)
protein_sequence = ‘ACDEFGHIKLMNPQRSTVWY’
# Grid size
grid_size = 20
# Initialize the 3D grid
grid = np.full((grid_size, grid_size, grid_size), None)
# Place amino acids randomly in the grid
positions = []
for aa in protein_sequence:
while True:
x, y, z = np.random.randint(0, grid_size, size=3)
if grid[x, y, z] is None:
grid[x, y, z] = aa
positions.append([x, y, z])
break
positions = np.array(positions)
# Interaction rules
def get_neighbors(pos):
x, y, z = pos
neighbors = []
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
for dz in [-1, 0, 1]:
if (dx == 0 and dy == 0 and dz == 0):
continue
nx, ny, nz = x + dx, y + dy, z + dz
if 0 <= nx < grid_size and 0 <= ny < grid_size and 0 <= nz < grid_size:
neighbors.append((nx, ny, nz))
return neighbors
def update_positions(positions):
new_positions = positions.copy()
for idx, pos in enumerate(positions):
aa = grid[tuple(pos)]
aa_type = amino_acids[aa][‘type’]
neighbors = get_neighbors(pos)
random.shuffle(neighbors)
for neighbor in neighbors:
npos = np.array(neighbor)
naa = grid[tuple(npos)]
if naa is None:
continue
naa_type = amino_acids[naa][‘type’]
# Hydrophobic interactions
if aa_type == ‘hydrophobic’ and naa_type == ‘hydrophobic’:
# Move closer
direction = npos – pos
new_pos = pos + np.sign(direction)
new_pos = np.clip(new_pos, 0, grid_size – 1)
if grid[tuple(new_pos)] is None:
grid[tuple(pos)] = None
grid[tuple(new_pos)] = aa
new_positions[idx] = new_pos
break
# Electrostatic interactions
elif (aa_type == ‘positively_charged’ and naa_type == ‘negatively_charged’) or \
(aa_type == ‘negatively_charged’ and naa_type == ‘positively_charged’):
# Move closer
direction = npos – pos
new_pos = pos + np.sign(direction)
new_pos = np.clip(new_pos, 0, grid_size – 1)
if grid[tuple(new_pos)] is None:
grid[tuple(pos)] = None
grid[tuple(new_pos)] = aa
new_positions[idx] = new_pos
break
# Repulsion for same charges
elif aa_type == naa_type and aa_type in [‘positively_charged’, ‘negatively_charged’]:
# Move away
direction = pos – npos
new_pos = pos + np.sign(direction)
new_pos = np.clip(new_pos, 0, grid_size – 1)
if grid[tuple(new_pos)] is None:
grid[tuple(pos)] = None
grid[tuple(new_pos)] = aa
new_positions[idx] = new_pos
break
return new_positions
# Run the simulation
steps = 50
for step in range(steps):
positions = update_positions(positions)
# Visualization
fig = plt.figure()
ax = fig.add_subplot(111, projection=’3d’)
aa_types = {‘hydrophobic’: ‘red’, ‘polar’: ‘blue’, ‘positively_charged’: ‘green’, ‘negatively_charged’: ‘yellow’}
colors = []
for pos in positions:
aa = grid[tuple(pos)]
aa_type = amino_acids[aa][‘type’]
colors.append(aa_types[aa_type])
ax.scatter(positions[:, 0], positions[:, 1], positions[:, 2], c=colors, s=100)
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_zlabel(‘Z’)
plt.title(‘3D Cellular Automaton Protein Folding Simulation’)
plt.show()
Leave a Reply