Michael,

As far as I know, ChimeraX has no dedicated feature for updating bonds while animating a trajectory. I did write a Python script for updating bonds for another project, but I can't find the final version of it. Here's what I did find:

```
from chimerax.atomic import AtomicStructure
from chimerax.core.models import ADD_MODELS

from scipy.spatial import distance
import numpy as np

# tolerance so bonds don't erroneously break
tolerance = 0.4
max_dist_arrays = {}

def check_bonds(trigger_name, changes):
    mdl, diff = changes
    if not diff.structure_reasons():
        return
    # squared distance between atoms
    D = distance.squareform(
        distance.pdist(
            mdl.coordset(mdl.active_coordset_id).xyzs,
            "sqeuclidean"
        )
    )
    try:
        max_connected_dist = max_dist_arrays[mdl]
    except KeyError:
        # make an array for how far atoms can be and still be bonded
        # to each other
        max_connected_dist = np.zeros((mdl.num_atoms, mdl.num_atoms))
        for i, a1 in enumerate(mdl.atoms):
            for j, a2 in enumerate(mdl.atoms[:i]):
                max_connected_dist[i, j] = (
                    a1.element.bond_radius(a1.element.name) +
                    a1.element.bond_radius(a2.element.name) +
                    tolerance
                ) ** 2
        max_dist_arrays[mdl] = max_connected_dist
   
    # these are bonded
    connected = np.tril(D < max_connected_dist).nonzero()
    # these are not
    not_connected = np.tril(D > max_connected_dist).nonzero()
    # add new bonds
    for (ndx1, ndx2) in zip(*connected):
        try:
            b = mdl.new_bond(mdl.atoms[ndx1], mdl.atoms[ndx2])
            # set the bond radius ot 0.16 to match the BSE preset
            b.radius = 0.16
        except TypeError:
            pass

    # delete bonds that are too long
    for (ndx1, ndx2) in zip(*not_connected):
        a1 = mdl.atoms[ndx1]
        a2 = mdl.atoms[ndx2]
        for bond in a1.bonds:
            if a2 in bond.atoms:
                bond.delete()
   

def register_bond_monitor(trigger_name, models):
    for mdl in models:
        if not isinstance(mdl, AtomicStructure):
            continue
        mdl.triggers.add_handler("changes", check_bonds)


session.triggers.add_handler(ADD_MODELS, register_bond_monitor)
```

Save the script to a .py file and open it in ChimeraX, and then open your trajecories. Until you close ChimeraX, the script will update bonds any time the coordinates change. Bonds are only checked for structures opened after the script. Performance will take a noticeable hit when playing trajectories, but there's probably some room for optimization. You do have to restart ChimeraX to disable the bond checking.

I'm pretty sure the final version would show metal coordination bonds correctly, as well as TS pseudobonds once things got a bit longer than normal bonds. If you want that, let me know and I can probably add it quickly.

Best,

Tony

On Fri, Nov 3, 2023 at 4:21 PM Michael Patzschke via ChimeraX-users <chimerax-users@cgl.ucsf.edu> wrote:
Dear colleagues,

I have a trajectory from an ab initio MD run. The output is in the form of concatenated .xyz information. I can open and visualise this in ChimeraX, but the bond topology is determined from the first step. As the simulation progresses, bonds are stretched and the broken bond in my example just gets drawn, although the distance of the involved atoms gets larger then 7 Å by the end of the simulation. Is there a way to use dynamic bonds in ChimeraX? By this I mean that the bonds are only drawn when the distance of the involved atoms is below a certain threshold.

I would appreciate any help in the matter.

Kind regards,
Michael Patzschke
_______________________________________________
ChimeraX-users mailing list -- chimerax-users@cgl.ucsf.edu
To unsubscribe send an email to chimerax-users-leave@cgl.ucsf.edu
Archives: https://mail.cgl.ucsf.edu/mailman/archives/list/chimerax-users@cgl.ucsf.edu/