Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#7577 closed defect (fixed)

Atomspec /A-B sometimes orders chains B,A breaking commands where order matters

Reported by: goddard@… Owned by: Eric Pettersen
Priority: normal Milestone:
Component: Command Line Version:
Keywords: Cc:
Blocked By: Blocking:
Notify when closed: Platform: all
Project: ChimeraX

Description

The following bug report has been submitted:
Platform:        macOS-12.5.1-arm64-arm-64bit
ChimeraX Version: 1.5.dev202209022203 (2022-09-02 22:03:17 UTC)
Description
Chain specifier #2/A-B is treating the chain order as B,A while chain specifier #2/A,B treats it as A,B, causing matchmaker to pair the chains in the wrong order.

We should fix the atomspec parsing so /A-B returns chains A,B in the expected order.

Log:
UCSF ChimeraX version: 1.5.dev202209022203 (2022-09-02)  
© 2016-2022 Regents of the University of California. All rights reserved.  
How to cite UCSF ChimeraX  

> open 1a0m

1a0m title:  
1.1 angstrom crystal structure of A-conotoxin [TYR15]-epi [more info...]  
  
Chain information for 1a0m #1  
---  
Chain | Description | UniProt  
A B | α-conotoxin [TYR15]-epi | CXA1_CONEP  
  
Non-standard residues in 1a0m #1  
---  
NH2 — amino group  
  

> open 1a0m

1a0m title:  
1.1 angstrom crystal structure of A-conotoxin [TYR15]-epi [more info...]  
  
Chain information for 1a0m #2  
---  
Chain | Description | UniProt  
A B | α-conotoxin [TYR15]-epi | CXA1_CONEP  
  
Non-standard residues in 1a0m #2  
---  
NH2 — amino group  
  

> changechains #2 A,B B,A

Chain IDs of 76 residues changed  

> mmaker #2/A-B to #1/A-B pairing ss cutoff none

Parameters  
---  
Chain pairing | ss  
Alignment algorithm | Needleman-Wunsch  
Similarity matrix | BLOSUM-62  
SS fraction | 0.3  
Gap open (HH/SS/other) | 18/18/6  
Gap extend | 1  
SS matrix |  |  | H | S | O  
---|---|---|---  
H | 6 | -9 | -6  
S |  | 6 | -6  
O |  |  | 4  
No iteration  
  
Matchmaker 1a0m, chain A (#1) with 1a0m, chain B (#2), sequence alignment
score = 100  
Matchmaker 1a0m, chain B (#1) with 1a0m, chain A (#2), sequence alignment
score = 97.6  
RMSD between 32 atom pairs is 0.000 angstroms  
  

> mmaker #2/A,B to #1/A,B pairing ss cutoff none

Parameters  
---  
Chain pairing | ss  
Alignment algorithm | Needleman-Wunsch  
Similarity matrix | BLOSUM-62  
SS fraction | 0.3  
Gap open (HH/SS/other) | 18/18/6  
Gap extend | 1  
SS matrix |  |  | H | S | O  
---|---|---|---  
H | 6 | -9 | -6  
S |  | 6 | -6  
O |  |  | 4  
No iteration  
  
Matchmaker 1a0m, chain A (#1) with 1a0m, chain A (#2), sequence alignment
score = 85.6  
Matchmaker 1a0m, chain B (#1) with 1a0m, chain B (#2), sequence alignment
score = 85.6  
RMSD between 32 atom pairs is 5.161 angstroms  
  




OpenGL version: 4.1 Metal - 76.3
OpenGL renderer: Apple M1 Max
OpenGL vendor: Apple

Python: 3.9.11
Locale: UTF-8
Qt version: PyQt6 6.3.1, Qt 6.3.1
Qt runtime version: 6.3.1
Qt platform: cocoa
Hardware:

    Hardware Overview:

      Model Name: MacBook Pro
      Model Identifier: MacBookPro18,2
      Chip: Apple M1 Max
      Total Number of Cores: 10 (8 performance and 2 efficiency)
      Memory: 32 GB
      System Firmware Version: 7459.141.1
      OS Loader Version: 7459.141.1

Software:

    System Software Overview:

      System Version: macOS 12.5.1 (21G83)
      Kernel Version: Darwin 21.6.0
      Time since boot: 17 days 15:05

Graphics/Displays:

    Apple M1 Max:

      Chipset Model: Apple M1 Max
      Type: GPU
      Bus: Built-In
      Total Number of Cores: 32
      Vendor: Apple (0x106b)
      Metal Family: Supported, Metal GPUFamily Apple 7
      Displays:
        Color LCD:
          Display Type: Built-in Liquid Retina XDR Display
          Resolution: 3456 x 2234 Retina
          Main Display: Yes
          Mirror: Off
          Online: Yes
          Automatically Adjust Brightness: No
          Connection Type: Internal


Installed Packages:
    alabaster: 0.7.12
    appdirs: 1.4.4
    appnope: 0.1.3
    asttokens: 2.0.8
    Babel: 2.10.3
    backcall: 0.2.0
    blockdiag: 3.0.0
    build: 0.8.0
    certifi: 2021.10.8
    cftime: 1.6.1
    charset-normalizer: 2.1.1
    ChimeraX-AddCharge: 1.4
    ChimeraX-AddH: 2.2
    ChimeraX-AlignmentAlgorithms: 2.0
    ChimeraX-AlignmentHdrs: 3.2.1
    ChimeraX-AlignmentMatrices: 2.0
    ChimeraX-Alignments: 2.5.2
    ChimeraX-AlphaFold: 1.0
    ChimeraX-AltlocExplorer: 1.0.3
    ChimeraX-AmberInfo: 1.0
    ChimeraX-Arrays: 1.0
    ChimeraX-ArtiaX: 0.1
    ChimeraX-Atomic: 1.41.2
    ChimeraX-AtomicLibrary: 7.0.2
    ChimeraX-AtomSearch: 2.0.1
    ChimeraX-AxesPlanes: 2.3
    ChimeraX-BasicActions: 1.1.2
    ChimeraX-BILD: 1.0
    ChimeraX-BlastProtein: 2.1.2
    ChimeraX-BondRot: 2.0.1
    ChimeraX-BugReporter: 1.0.1
    ChimeraX-BuildStructure: 2.7.1
    ChimeraX-Bumps: 1.0
    ChimeraX-BundleBuilder: 1.2
    ChimeraX-ButtonPanel: 1.0.1
    ChimeraX-CageBuilder: 1.0.1
    ChimeraX-CellPack: 1.0
    ChimeraX-Centroids: 1.3.1
    ChimeraX-ChangeChains: 1.0
    ChimeraX-CheckWaters: 1.1.1
    ChimeraX-ChemGroup: 2.0
    ChimeraX-Clashes: 2.2.4
    ChimeraX-ColorActions: 1.0.1
    ChimeraX-ColorGlobe: 1.0
    ChimeraX-ColorKey: 1.5.2
    ChimeraX-CommandLine: 1.2.4
    ChimeraX-ConnectStructure: 2.0.1
    ChimeraX-Contacts: 1.0.1
    ChimeraX-Core: 1.5.dev202209022203
    ChimeraX-CoreFormats: 1.1
    ChimeraX-coulombic: 1.3.2
    ChimeraX-Crosslinks: 1.0
    ChimeraX-cryoDRGN: 1.0
    ChimeraX-Crystal: 1.0
    ChimeraX-CrystalContacts: 1.0.1
    ChimeraX-DataFormats: 1.2.2
    ChimeraX-Dicom: 1.1
    ChimeraX-DistMonitor: 1.3
    ChimeraX-DockPrep: 1.0
    ChimeraX-Dssp: 2.0
    ChimeraX-EMDB-SFF: 1.0
    ChimeraX-ExperimentalCommands: 1.0
    ChimeraX-FileHistory: 1.0.1
    ChimeraX-FunctionKey: 1.0.1
    ChimeraX-Geometry: 1.2
    ChimeraX-gltf: 1.0
    ChimeraX-Graphics: 1.1
    ChimeraX-Hbonds: 2.3.1
    ChimeraX-Help: 1.2.1
    ChimeraX-HKCage: 1.3
    ChimeraX-IHM: 1.1
    ChimeraX-ImageFormats: 1.2
    ChimeraX-IMOD: 1.0
    ChimeraX-IO: 1.0.1
    ChimeraX-ItemsInspection: 1.0.1
    ChimeraX-Label: 1.1.6
    ChimeraX-ListInfo: 1.1.1
    ChimeraX-Log: 1.1.5
    ChimeraX-LookingGlass: 1.1
    ChimeraX-Maestro: 1.8.1
    ChimeraX-Map: 1.1.1
    ChimeraX-MapData: 2.0
    ChimeraX-MapEraser: 1.0.1
    ChimeraX-MapFilter: 2.0
    ChimeraX-MapFit: 2.0
    ChimeraX-MapSeries: 2.1.1
    ChimeraX-Markers: 1.0.1
    ChimeraX-Mask: 1.0.1
    ChimeraX-MatchMaker: 2.0.6
    ChimeraX-MDcrds: 2.6
    ChimeraX-MedicalToolbar: 1.0.2
    ChimeraX-Meeting: 1.0.1
    ChimeraX-MLP: 1.1
    ChimeraX-mmCIF: 2.7
    ChimeraX-MMTF: 2.1
    ChimeraX-Modeller: 1.5.6
    ChimeraX-ModelPanel: 1.3.6
    ChimeraX-ModelSeries: 1.0.1
    ChimeraX-Mol2: 2.0
    ChimeraX-Mole: 1.0
    ChimeraX-Morph: 1.0
    ChimeraX-MouseModes: 1.1.1
    ChimeraX-Movie: 1.0
    ChimeraX-Neuron: 1.0
    ChimeraX-Nucleotides: 2.0.3
    ChimeraX-OpenCommand: 1.9.1
    ChimeraX-PDB: 2.6.7
    ChimeraX-PDBBio: 1.0
    ChimeraX-PDBLibrary: 1.0.2
    ChimeraX-PDBMatrices: 1.0
    ChimeraX-PickBlobs: 1.0.1
    ChimeraX-Positions: 1.0
    ChimeraX-PresetMgr: 1.1
    ChimeraX-PubChem: 2.1
    ChimeraX-ReadPbonds: 1.0.1
    ChimeraX-Registration: 1.1.1
    ChimeraX-RemoteControl: 1.0
    ChimeraX-RenumberResidues: 1.1
    ChimeraX-ResidueFit: 1.0.1
    ChimeraX-RestServer: 1.1
    ChimeraX-RNALayout: 1.0
    ChimeraX-RotamerLibMgr: 2.0.1
    ChimeraX-RotamerLibsDunbrack: 2.0
    ChimeraX-RotamerLibsDynameomics: 2.0
    ChimeraX-RotamerLibsRichardson: 2.0
    ChimeraX-SaveCommand: 1.5.1
    ChimeraX-SchemeMgr: 1.0
    ChimeraX-SDF: 2.0
    ChimeraX-Segger: 1.0
    ChimeraX-Segment: 1.0
    ChimeraX-SelInspector: 1.0
    ChimeraX-SeqView: 2.7.2
    ChimeraX-Shape: 1.0.1
    ChimeraX-Shell: 1.0.1
    ChimeraX-Shortcuts: 1.1.1
    ChimeraX-ShowSequences: 1.0.1
    ChimeraX-SideView: 1.0.1
    ChimeraX-Smiles: 2.1
    ChimeraX-SmoothLines: 1.0
    ChimeraX-SpaceNavigator: 1.0
    ChimeraX-StdCommands: 1.9
    ChimeraX-STL: 1.0
    ChimeraX-Storm: 1.0
    ChimeraX-StructMeasure: 1.1
    ChimeraX-Struts: 1.0.1
    ChimeraX-Surface: 1.0
    ChimeraX-SwapAA: 2.0.1
    ChimeraX-SwapRes: 2.1.3
    ChimeraX-TapeMeasure: 1.0
    ChimeraX-Test: 1.0
    ChimeraX-Toolbar: 1.1.2
    ChimeraX-ToolshedUtils: 1.2.1
    ChimeraX-Tug: 1.0.1
    ChimeraX-UI: 1.24
    ChimeraX-uniprot: 2.2.1
    ChimeraX-UnitCell: 1.0.1
    ChimeraX-ViewDockX: 1.1.3
    ChimeraX-VIPERdb: 1.0
    ChimeraX-Vive: 1.1
    ChimeraX-VolumeMenu: 1.0.1
    ChimeraX-VTK: 1.0
    ChimeraX-WavefrontOBJ: 1.0
    ChimeraX-WebCam: 1.0.1
    ChimeraX-WebServices: 1.1.0
    ChimeraX-Zone: 1.0.1
    colorama: 0.4.5
    cxservices: 1.2
    cycler: 0.11.0
    Cython: 0.29.32
    debugpy: 1.6.3
    decorator: 5.1.1
    docutils: 0.19
    entrypoints: 0.4
    executing: 1.0.0
    filelock: 3.7.1
    fonttools: 4.37.1
    funcparserlib: 1.0.0
    grako: 3.16.5
    h5py: 3.7.0
    html2text: 2020.1.16
    idna: 3.3
    ihm: 0.33
    imagecodecs: 2022.2.22
    imagesize: 1.4.1
    importlib-metadata: 4.12.0
    ipykernel: 6.15.1
    ipython: 8.4.0
    ipython-genutils: 0.2.0
    jedi: 0.18.1
    Jinja2: 3.1.2
    jupyter-client: 7.3.4
    jupyter-core: 4.11.1
    kiwisolver: 1.4.4
    line-profiler: 3.5.1
    lxml: 4.9.1
    lz4: 4.0.2
    MarkupSafe: 2.1.1
    matplotlib: 3.5.2
    matplotlib-inline: 0.1.6
    msgpack: 1.0.4
    nest-asyncio: 1.5.5
    netCDF4: 1.6.0
    networkx: 2.8.5
    numexpr: 2.8.3
    numpy: 1.23.1
    openvr: 1.23.701
    packaging: 21.3
    pandas: 1.4.3
    ParmEd: 3.4.3
    parso: 0.8.3
    pep517: 0.13.0
    pexpect: 4.8.0
    pickleshare: 0.7.5
    Pillow: 9.2.0
    pip: 22.2.1
    pkginfo: 1.8.3
    prompt-toolkit: 3.0.30
    psutil: 5.9.1
    ptyprocess: 0.7.0
    pure-eval: 0.2.2
    pycollada: 0.7.2
    pydicom: 2.3.0
    Pygments: 2.12.0
    PyOpenGL: 3.1.5
    PyOpenGL-accelerate: 3.1.5
    pyparsing: 3.0.9
    PyQt6: 6.3.1
    PyQt6-Qt6: 6.3.1
    PyQt6-sip: 13.4.0
    PyQt6-WebEngine: 6.3.1
    PyQt6-WebEngine-Qt6: 6.3.1
    python-dateutil: 2.8.2
    pytz: 2022.2.1
    pyzmq: 23.2.1
    qtconsole: 5.3.1
    QtPy: 2.2.0
    RandomWords: 0.4.0
    requests: 2.28.1
    scipy: 1.9.0
    Send2Trash: 1.8.0
    setuptools: 63.3.0
    sfftk-rw: 0.7.2
    six: 1.16.0
    snowballstemmer: 2.2.0
    sortedcontainers: 2.4.0
    Sphinx: 5.1.1
    sphinx-autodoc-typehints: 1.19.1
    sphinxcontrib-applehelp: 1.0.2
    sphinxcontrib-blockdiag: 3.0.0
    sphinxcontrib-devhelp: 1.0.2
    sphinxcontrib-htmlhelp: 2.0.0
    sphinxcontrib-jsmath: 1.0.1
    sphinxcontrib-qthelp: 1.0.3
    sphinxcontrib-serializinghtml: 1.1.5
    stack-data: 0.5.0
    starfile: 0.4.11
    superqt: 0.3.3
    tables: 3.7.0
    tifffile: 2022.7.31
    tinyarray: 1.2.4
    tomli: 2.0.1
    tornado: 6.2
    traitlets: 5.3.0
    typing-extensions: 4.3.0
    urllib3: 1.26.12
    wcwidth: 0.2.5
    webcolors: 1.12
    wheel: 0.37.1
    wheel-filename: 1.4.1
    zipp: 3.8.1

Change History (12)

comment:1 by Tom Goddard, 3 years ago

Component: UnassignedCommand Line
Owner: set to Eric Pettersen
Platform: all
Project: ChimeraX
Status: newassigned
Summary: ChimeraX bug report submissionAtomspec /A-B sometimes orders chains B,A breaking commands where order matters

Begin forwarded message:

From: Eric Pettersen <pett@…>
Subject: Re: Chain order in atom specs
Date: September 9, 2022 at 12:56:10 PM PDT
To: Tom Goddard
Cc: Elaine Meng

Knowing how specifiers work internally, I would not expect those to always be equivalent. I didn't check, but I'm pretty sure how ranges work is that it goes through the list of items (in this case chains) and checks whether the item is >= the left side of the range and <= the right side of the range. It doesn't sort the result.

Maybe it should sort the result, but sorting could be expensive depending on the size of the range and is normally superfluous. Maybe changechains should have an option to reorder the chains?

--Eric

comment:2 by Tom Goddard, 3 years ago

My actual use case was aligning and morphing 6j0b and 6g0c where two 6 member rings (chains A-F) are in opposite order so I renamed the chains then ran into 15 minutes of trouble trying to figure out why matchmaker would not align them as I expected with "mm #2/A-F to #1/A-F pairing ss cutoff none". Finally found that #2/A,B,C,D,E,F fixed the behavior.

comment:3 by Eric Pettersen, 3 years ago

Status: assignedaccepted

We may be able to mostly avoid a full-blown sort by check the items as they're added to verify they are in ascending order, possibly sorting in the latest item as needed and never doing a full sort.

comment:4 by Eric Pettersen, 3 years ago

Resolution: fixed
Status: acceptedclosed

I looked at fixing this "generically" (i.e. any /A-F atom spec comes out in the expected order) but that is impossible AFAICT. The parser in core/commands treats chain and residue ranges the same and equivalent to any other part of the atom spec -- a function that returns a boolean as to whether a given string matches that part and which has no control over the ordering of testing or results. Conversely, Structure.atomspec_filter receives an Atoms collection and returns a boolean array of whether the atoms match the spec, with no ability to adjust the ordering of the atoms based on what kind of test is being applied.

So, I changed the matchmaker command to use an OrderedAtomsArg instead of a plain AtomsArg. This means that a structure's atoms will be sorted before being delivered to Structure.atomspec_filter, which could certainly be costly in some cases, so it makes sense to restrict this to commands that actually care about the ordering of atoms/chains etc. rather than doing this for all commands.

comment:6 by Tom Goddard, 3 years ago

Not sure I understand your OrderedAtomsArg solution. Will the following match maker command behave in the expected way matching #2/B to #1/A? Or does the the ordering of the first argument mean it is going to match #2/A to #1/A?

matchmaker #2/B,A to #1/A,B pairing ss cutoff none

Another case which I have also run into a few times, the morph command. Here are examples that I would like to work

morph #1/A,B #2/B,A
morph #1/A-F #2/A-F

The command wants the specified order, not an order sorted by chain id and residue number.

comment:7 by Eric Pettersen, 3 years ago

It will work as expected. To get 'morph' to work, you would need to update it to use an OrderedAtomsArg.

comment:8 by Eric Pettersen, 3 years ago

I don't even understand your morph example. 'morph' takes structures as arguments, not chains.

in reply to:  9 ; comment:9 by goddard@…, 3 years ago

You are right, morph takes only structures not chains.  It would be very useful it it could specify chains and I forgot that it does not allow that now.  So the need to handle ordered atom specifiers for morph is only in some improved version of morph.

Could you clarify the behavior of OrderedAtomsArg?  I did not understand comment 4 where you say the atoms will be sorted.  Does OrderedAtomsArg return the atoms in the order specified?  Or does it return them in some fixed sort order?

comment:10 by Eric Pettersen, 3 years ago

Atomspec results are chimerax.core.objects.Objects instances, which only directly contain models, atoms, and bonds. As an argument Annotation that inherits from AtomSpecArg (e.g. AtomsArg) uses chimerax.core.commands.atomspec.AtomSpec.evaluate() to process its text argument, for each model that matches the spec, that model's atomspec_atoms() method will be called and the resulting atoms will either be added into the results in the entirety (if there are no chain/residue/atom tests in that part of the spec) or that model's atomspec_filter() will be called on each subpart of the spec, with the atoms from atomspec_atoms() as an argument. Each subpart will add in the parts that pass the test into the results separately. So "/B,A", which are two separate tests, will be ordered correctly despite the atoms being internally ordered in the structure with the /A atoms first. "/A-B", which is one test, will have the atoms ordered in whatever order atomspec_atoms() returned them.

An OrderedAtomsArg has atomspec_atoms() return a sorted list of atoms. As explained above, that does not affect the order of the results for "/B,A".

comment:11 by Tom Goddard, 3 years ago

Ok. I take that as a yes. But that is just a guess since I don't know what order "/A-B" uses, maybe it sorts and gives the file order or maybe it gives A then B even if file order is B then A.

comment:12 by Eric Pettersen, 3 years ago

For AtomsArg, "/A-B" gives whatever order the chains occur among the atoms in the structure ("file order", as long as no pertinent structure editing operations have happened). For OrderedAtomsArg, it gives A then B.

Note: See TracTickets for help on using tickets.