TCL/Python correspondence

Unlike TCL, Python is much more naturally object-oriented. This means that all psfgen functionality is performed on a PsfGen object that holds the state of the system. For example:

from psfgen import PsfGen
gen = PsfGen()

Then all commands are done on the PsfGen object. The syntax in the following table refers to this generic PsfGen object I’ve chosen to name gen.

Topology and naming functions

Task TCL command Python class equivalent
Load topology definitions topology <file name> gen.read_topology(filename) psfgen.PsfGen.read_topology()
Provide alternate names for residues in topology file topology alias <desired residue name> <topology residue name> No exact match. Make a PDB alias with psfgen.PsfGen.alias_residue()
Provide alternate names for residues in pdb file pdbalias residue <PDB residue name> <desired residue name> gen.alias_residue(top_resname, pdb_resname) psfgen.PsfGen.alias_residue()
Provide translations for atom names found in PDB files to those in topology files pdbalias atom <residue name> <PDB atomname> <topology atomname> gen.alias_atom(resname, pdb_atomname, top_atomname) psfgen.PsfGen.alias_atom()
Change the name of a single residue psfset resname <segment ID> <resid> <resname> gen.set_resname(segid, resid, new_resname) psfgen.PsfGen.set_resname()
Rename a segment psfset segid <segment ID> <new name> gen.set_segid(segid, new_segid) psfgen.PsfGen.set_segid()

Query functions

Task TCL command Python class equivalent
List loaded topology files topology list gen.get_topologies() psfgen.PsfGen.get_topologies()
List current segids segment segids gen.get_segids() psfgen.PsfGen.get_segids()
List current resids in a segment segment resids gen.get_resids(segid) psfgen.PsfGen.get_resids()
Get residue name given a resid and a segment segment residue <segment ID> <resid> gen.get_resname(segid, resid) psfgen.PsfGen.get_resname()
List all currently applied patches, including default patches patch listall gen.get_patches() psfgen.PsfGen.get_patches()
List all explicitly applied patches patch list gen.get_patches(list_defaults=False) psfgen.PsfGen.get_patches()
List all available residue types topology residues gen.get_residue_types() psfgen.PsfGen.get_residue_types()
List all available patches topology patches gen.get_patches(list_all=True) psfgen.PsfGen.get_patches()
Get the name of the patch applied to the beginning of a given segment segment first <segment ID> gen.get_first(segid) psfgen.PsfGen.get_first()
Get the name of the patch applied to the end of a given segment segment last <segment ID> gen.get_last(segid) psfgen.PsfGen.get_last()
Get names for atoms in a given residue segment atoms <segment ID> <resid> gen.get_atom_names(segid, resid) psfgen.PsfGen.get_atom_names()
Get charges for atoms in a given residue segment charges <segment ID> <resid> gen.get_charges(segid, resid) psfgen.PsfGen.get_charges()
Get masses for atoms in a given residue segment masses <segment ID> <resid> gen.get_masses(segi, resid) psfgen.PsfGen.get_masses()
Get indices/atom IDs for atoms in a given residue segment atomid <segment ID> <resid> gen.get_atom_indices(segid, resid) psfgen.PsfGen.get_atom_indices()
Get x,y,z coordinates for atoms in a given residue segment coordinates <segment ID> <resid> gen.get_coordinates(segid, resid) psfgen.PsfGen.get_coordinates()
Get vx,vy,vz velocites for atoms in a given residue, if set segment velocities <segment ID> <resid> gen.get_velocities(segid, resid) psfgen.PsfGen.get_velocities()

System building functions

Task TCL command Python class equivalent
Guess coordinates of atoms that aren’t explicitly set guesscoord gen.guess_coords() psfgen.PsfGen.guess_coords()
Delete all atoms in a segment delatom <segment ID> gen.delete_atoms(segid) psfgen.PsfGen.delete_atoms()
Delete all atoms in a residue delatom <segment ID> <resid> gen.delete_atoms(segid, resid) psfgen.PsfGen.delete_atoms()
Delete a single atom delatom <segment ID> <resid> <atom name> gen.delete_atoms(segid, resid, atomname) psfgen.PsfGen.delete_atoms()
Create multiple images of a set of atoms for locally enhanced sampling multiply <factor> <segid[:resid[:atomname]]> ... Not implemented
Remove insertion codes and modify resids minimially for uniqueness regenerate resids gen.regenerate_resids() psfgen.PsfGen.regenerate_resids()
Remove angles and regenerate them, after patching regenerate angles gen.regenerate_angles() psfgen.PsfGen.regenerate_angles()
Remove dihedrals and regenerate them, after patching. regenerate dihedrals gen.regenerate_dihedrals() psfgen.PsfGen.regenerate_dihedrals()
Apply a patch to one or more residues, as determined by the patch patch <patchname> <segid:resid> [...] gen.patch(patch_name, targets) psfgen.PsfGen.patch()

Modifying atom attributes

You can modify many atom attributes.

Task TCL command Python class equivalent
Change the name of an atom psfset name <segment ID> <resid> <atomname> <new name> gen.set_atom_name(segid, resid, atomname, new_atomname) psfgen.PsfGen.set_atom_name()
Change the charge on an atom psfset charge <segment ID> <resid> <atomname> <charge> gen.set_charge(segid, resid, atomname, charge) psfgen.PsfGen.set_charge()
Change the beta factor on an atom psfset beta <segment ID> <resid> <atomname> <beta> gen.set_beta(segid, resid, atomname, beta) psfgen.PsfGen.set_beta()
Change the mass of an atom psfset mass <segment ID> <resid> <atomname> <mass> gen.set_mass(segid, resid, atomname, mass) psfgen.PsfGen.set_mass()
Set coordinates of a given atom coord <segment ID> <resid> <atomname> {x y z} or psfset coord <segment ID> <resid> <atomname> {x y z} gen.set_position(segid, resid, atomname, position=(x,y,z)) psfgen.PsfGen.set_position()
Set velocities of a given atom psfset vel <segment ID> <resid> <atomname> {x y z} gen.set_velocity(segid, resid, atomname, velocity=(x,y,z)) psfgen.PsfGen.set_velocity()

Adding a new segment

All of the following TCL code to create a new segment is equivalent to the following Python code:

segment <segment ID> {                    # Create a new segment with given ID
    first <patchname>                     # Set patch applied to first residue
    last  <patchname>                     # Set patch applied to last residue
    pdb <pdbfilename>                     # Extract sequence info from given PDB file
    auto [angles|dihedrals|none]          # Automatically generate these

    residue <resid> <resname> [<chain>]   # Add a residue to the end of segment
    mutate <resid> <resname>              # Mutate a residue in current segment to a new one
}

All of this block is equivalent to the psfgen.PsfGen.add_segment() function call in Python, with the segid argument being mandatory, and all others optional:

gen.add_segment(segid=<segment ID>,
                first=None,
                last=None,
                pdbfile=None,
                auto_angles=True,
                auto_dihedrals=True,
                residue=None,
                mutate=None,
               )

You can also create new segments based on those already defined in an existing PSF file with the psfgen.PsfGen.read_psf() function.

I/O functions

Task TCL command Python class equivalent
Write out structure to a PSF file writepsf [charmm] [x-plor] [cmap|nocmap] <filename> gen.write_psf(filename, type) psfgen.PsfGen.write_psf()
Write out structure to a PDB file writepdb <filename> gen.write_pdb(filename) psfgen.PsfGen.write_pdb()
Write out a NAMD binary input file writenamdbin <filename> gen.write_namdbin(filename, velocity_filename) psfgen.PsfGen.write_namdbin()
Read in a PSF file and add it to the current structure. Optionally read coordinates from a pdb file or a namdbin file. readpsf <filename> [pdb] <pdbfilename> ... gen.read_psf(filename, pdbfile, ...) psfgen.PsfGen.read_psf()
Read coordinates in from a PDB file, matching segment, residue, and atom names coordpdb <filename> [segid] gen.read_coords(filename, segid) psfgen.PsfGen.read_coords()

Context functions

The TCL version of psfgen has the concept of a “psf context”, that is, a given molecule or system that is being built. You can use the TCL methods in the table below to generate new contexts or switch between them to build multiple molecules at once.

However since Python is object oriented, all you need to do to have multiple systems in memory is create multiple PsfGen objects. Each one is self-contained.

Task TCL command Python class equivalent
Create a new context, with its own structure, topology definitions, and aliases, and set it to active psfcontext new gen = new PsfGen()
Create a new context, but do not switch to it. psfcontext create gen = new PsfGen()
Delete a psfcontext psfcontext delete <context> del gen
Switch to a diferent psfcontext psfcontext <id> Use multiple PsfGen objects
Make context case sensitive (by default it is not) psfcontext mixedcase gen.case_sensitive = True psfgen.PsfGen.case_sensitive
Make context case insensitive (default setting) psfcontext allcaps gen.case_sensitive = False psfgen.PsfGen.case_sensitive
Clear the structure, topology definitions, and aliases psfcontext reset Delete and make a new PsfGen object
Evaluate commands in a given context, returning to the current one when done psfcontext eval <context> { <commands> } Use multiple PsfGen objects
Get total number of contexts created and destroyed so far psfcontext stats Use multiple PsfGen objects