Hi. I was wondering if anyone knows how to establish x,y,z coordinates in python. I want to be able to extract this data from a text file.

Here are sample lines in my text file:

ATOM      1  N   GLN A   4      62.131  49.287  59.621  1.00 67.10           N  
ATOM      2  CA  GLN A   4      61.622  47.885  59.534  1.00 66.22           C  
ATOM      3  C   GLN A   4      60.854  47.447  60.792  1.00 64.45           C  
ATOM      4  O   GLN A   4      61.449  46.949  61.746  1.00 65.40           O  
ATOM      5  CB  GLN A   4      62.791  46.916  59.278  1.00 68.46           C  
ATOM      6  CG  GLN A   4      64.038  47.141  60.142  1.00 70.82           C  
ATOM      7  CD  GLN A   4      64.869  45.875  60.316  1.00 72.24           C  
ATOM      8  OE1 GLN A   4      64.489  44.974  61.060  1.00 72.13           O  
ATOM      9  NE2 GLN A   4      66.004  45.804  59.626  1.00 74.37           N

I need the coordinates so I can calculate the distances between different atoms. I have been putting the x,y,z values into separate lists and doing it this way. I would like to keep track of which atoms the distances are calculated from, but it's difficult with the way I was doing it before.

Any help would be greatly appreciated.

Dani AI

Generated

Building on 's suggestion to use an object and 's fixed-field idea, a practical, robust approach is to keep each atom as a small record (dataclass) and parse the coordinates with a line-oriented parser that extracts the three floats. Storing name/serial plus x,y,z together makes every distance calculation self-documenting (you always know which two atoms produced a value).

from dataclasses import dataclass
import re
from math import sqrt

@dataclass
class Atom:
    serial: int
    name: str
    resname: str
    chain: str
    resseq: int
    x: float
    y: float
    z: float

_atom_re = re.compile(
    r'^(ATOM|HETATM)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S)\s+(\d+)\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)'
)

def parse_atom_line(line):
    m = _atom_re.match(line)
    if not m:
        return None
    return Atom(
        serial=int(m.group(2)),
        name=m.group(3),
        resname=m.group(4),
        chain=m.group(5),
        resseq=int(m.group(6)),
        x=float(m.group(7)),
        y=float(m.group(8)),
        z=float(m.group(9)),
    )

atoms = []
with open('sample.pdb') as fh:
    for ln in fh:
        a = parse_atom_line(ln)
        if a:
            atoms.append(a)

Distance and example output:

def dist(a, b):
    return sqrt((a.x-b.x)**2 + (a.y-b.y)**2 + (a.z-b.z)**2)

for i, a in enumerate(atoms):
    for b in atoms[i+1:]:
        print(f"{a.serial}:{a.name} - {b.serial}:{b.name}  {dist(a,b):.3f}")

Notes and troubleshooting: use the atom serial + residue (not just name) when you need unique IDs (same atom names repeat across residues). The regex method is tolerant of varying whitespace; if your files strictly follow PDB columns, fixed-column slicing is faster. For large structures, compute distances with numpy vectorization or a KD-tree (scipy.spatial) to avoid O(n^2) loops. For production-grade parsing of PDBs (alternate locations, occupancy, etc.), consider a PDB parser such as Biopython's PDB module.

Recommended Answers

All 3 Replies

You can create an atom class and methods.

class atom:
    def __init__(self, name, x, y, z):
        self.name = name
        self.x = x
        self.y = y
        self.z = z

    def distance(self, other):
        '''Implement method to calculate distance between 2 atom'''

Maybe something like this is more appropriate for fixed length fields:

data = dict()
with open("sample.dat") as filein:
    for line in filein:
        if line.strip():
            data[line[12:16].strip()]  = tuple (float(coord) for coord in line[30:54].split())

print data

Output from sample data:

{'C': (60.854, 47.447, 60.792), 'CB': (62.791, 46.916, 59.278), 'CA': (61.622, 47.885, 59.534), 'CG': (64.038, 47.141, 60.142), 'O': (61.449, 46.949, 61.746), 'N': (62.131, 49.287, 59.621), 'CD': (64.869, 45.875, 60.316), 'NE2': (66.004, 45.804, 59.626), 'OE1': (64.489, 44.974, 61.06)}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.