Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:RBVI/ChimeraX into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
elainecmeng committed Jun 12, 2024
2 parents 248e309 + ce1bce1 commit 800b2a1
Show file tree
Hide file tree
Showing 28 changed files with 1,047 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/bundles/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ REST_SUBDIRS = add_charge addh alignment_algs alignment_headers \
clashes cmd_line color_actions \
color_globe color_key connect_structure core_formats \
coulombic crosslinks crystal crystal_contacts data_formats \
dicom diffplot dist_monitor dock_prep dssp \
deep_mutational_scan dicom diffplot dist_monitor dock_prep dssp \
emdb_sff esmfold file_history function_key \
geometry gltf graphics \
hbonds help_viewer hkcage ihm image_formats imod \
Expand Down
29 changes: 19 additions & 10 deletions src/bundles/Makefile.bundle
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,24 @@ OS=Windows
endif
endif
ifeq ($(OS),Windows)
APP_PYTHON_EXE = $(CHIMERAX_APP)/bin/python.exe
APP_PYTHON_EXE = $(wildcard $(CHIMERAX_APP)/bin/python.exe)
CX_BIN = $(CHIMERAX_APP)/bin/ChimeraX-console.exe
PYMOD_EXT = pyd
endif
ifeq ($(OS),Darwin)
APP_PYTHON_EXE = $(CHIMERAX_APP)/Contents/bin/python3.11
APP_PYTHON_EXE = $(wildcard $(CHIMERAX_APP)/Contents/bin/python3.11)
CX_BIN = $(CHIMERAX_APP)/Contents/bin/ChimeraX
PYMOD_EXT = so
endif
ifeq ($(OS),Linux)
APP_PYTHON_EXE = $(CHIMERAX_APP)/bin/python3.11
APP_PYTHON_EXE = $(wildcard $(CHIMERAX_APP)/bin/python3.11)
CX_BIN = $(CHIMERAX_APP)/bin/chimerax
PYMOD_EXT = so
endif
PYTHON ?= $(APP_PYTHON_EXE) -I
RUN = PYTHONNOUSERSITE=1 $(PYTHON) -m chimerax.core --nogui --exit
RUN_SAFE = $(RUN) --safemode
RUN_CMD = $(RUN_SAFE) --cmd
ifeq (,$(wildcard $(APP_PYTHON_EXE)))
$(error missing ChimeraX application's python)
endif

ifdef INSTALL_TO_VENV
WHEEL = $(wildcard dist/*.whl)
Expand All @@ -67,14 +64,26 @@ PYSRCS = $(wildcard src/*.py)
.SECONDEXPANSION:

wheel: $$(PYSRCS)
$(RUN_CMD) "devel build . exit true $(DEBUG_ARG) $(BUILD_ARGS)"
if [ -z "$(APP_PYTHON_EXE)" ]; then \
echo "missing ChimeraX application's python"; exit 1; \
else \
$(RUN_CMD) "devel build . exit true $(DEBUG_ARG) $(BUILD_ARGS)"; \
fi

# The space means install and app-install are the same
install app-install: $$(PYSRCS)
$(RUN_CMD) "devel install . user false exit true $(DEBUG_ARG) $(INSTALL_ARGS)"
if [ -z "$(APP_PYTHON_EXE)" ]; then \
echo "missing ChimeraX application's python"; exit 1; \
else \
$(RUN_CMD) "devel install . user false exit true $(DEBUG_ARG) $(INSTALL_ARGS)"; \
fi

install-editable: clean
$(RUN_CMD) "devel install . user false editable true exit true $(DEBUG_ARG) $(INSTALL_ARGS)"
if [ -z "$(APP_PYTHON_EXE)" ]; then \
echo "missing ChimeraX application's python"; exit 1; \
else \
$(RUN_CMD) "devel install . user false editable true exit true $(DEBUG_ARG) $(INSTALL_ARGS)"; \
fi

venv-install:
ifndef VIRTUAL_ENV
Expand Down Expand Up @@ -116,7 +125,7 @@ debug:
$(CX_BIN) --debug

clean:
if [ -x $(CX_BIN) -a -e bundle_info.xml ]; then \
if [ -x "$(APP_PYTHON_EXE)" -a -e bundle_info.xml ]; then \
$(RUN_CMD) "devel clean . exit true" ; \
else \
rm -rf $(CLEAN) ; \
Expand Down
2 changes: 1 addition & 1 deletion src/bundles/atomic/bundle_info.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- Edit bundle_info.xml.in, not bundle_info.xml; then run make_selectors.py -->
<BundleInfo name="ChimeraX-Atomic" version="1.58.1"
<BundleInfo name="ChimeraX-Atomic" version="1.58.2"
package="chimerax.atomic"
purePython="false"
customInit="true"
Expand Down
2 changes: 1 addition & 1 deletion src/bundles/atomic/bundle_info.xml.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- Edit bundle_info.xml.in, not bundle_info.xml; then run make_selectors.py -->
<BundleInfo name="ChimeraX-Atomic" version="1.58.1"
<BundleInfo name="ChimeraX-Atomic" version="1.58.2"
package="chimerax.atomic"
purePython="false"
customInit="true"
Expand Down
3 changes: 2 additions & 1 deletion src/bundles/atomic/src/molobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -1212,11 +1212,12 @@ def residue_after(self, r):

@staticmethod
def restore_snapshot(session, data):
if data['structure'] is None:
return Sequence.restore_snapshot(session, data['Sequence'])
sseq = StructureSeq(chain_id=data['chain_id'], structure=data['structure'])
Sequence.set_state_from_snapshot(sseq, session, data['Sequence'])
sseq.description = data['description']
sseq.bulk_set(data['residues'], sseq.characters, fire_triggers=False)
sseq.description = data.get('description', None)
sseq.set_custom_attrs(data)
return sseq

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@ PythonInstance<C>::~PythonInstance() {
if (i == _pyinstance_object_map.end())
return;
PyObject* py_inst = (*i).second;
AcquireGIL gil; // Py_DECREF can cause code to run
PyObject_DelAttrString(py_inst, "_c_pointer");
PyObject_DelAttrString(py_inst, "_c_pointer_ref");
Py_DECREF(py_inst);
if (!PyObject_GC_IsFinalized(py_inst)) {
AcquireGIL gil; // Py_DECREF can cause code to run
PyObject_DelAttrString(py_inst, "_c_pointer");
PyObject_DelAttrString(py_inst, "_c_pointer_ref");
Py_DECREF(py_inst);
}
_pyinstance_object_map.erase(i);
}

Expand Down
2 changes: 1 addition & 1 deletion src/bundles/atomic_lib/bundle_info.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<BundleInfo name="ChimeraX-AtomicLibrary" version="14.1"
<BundleInfo name="ChimeraX-AtomicLibrary" version="14.1.1"
package="chimerax.atomic_lib"
purePython="false"
installedDataDir="data"
Expand Down
2 changes: 1 addition & 1 deletion src/bundles/bug_reporter/src/bug_reporter_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ def _linux_info():
{newline.join(displays)}
Manufacturer: {vendor}
Model: {product}
OS: {' '.join(distro.linux_distribution())}
OS: {distro.name()} {distro.version()}
Architecture: {' '.join(platform.architecture())}
Virtual Machine: {virtual_machine}
CPU: {count} {model_name}
Expand Down
1 change: 1 addition & 0 deletions src/bundles/deep_mutational_scan/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../Makefile.bundle
41 changes: 41 additions & 0 deletions src/bundles/deep_mutational_scan/bundle_info.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<BundleInfo name="ChimeraX-DeepMutationalScan" version="1.0"
package="chimerax.deep_mutational_scan"
minSessionVersion="1" maxSessionVersion="1">

<Author>UCSF RBVI</Author>
<Email>[email protected]</Email>
<URL>https://www.rbvi.ucsf.edu/chimerax/</URL>

<Synopsis>Visualize deep mutational scanning data</Synopsis>
<Description>Visualize deep mutational scanning data.</Description>

<Categories>
<Category name="Molecular structure"/>
</Categories>

<Dependencies>
<Dependency name="ChimeraX-Core" version="~=1.0"/>
<Dependency name="ChimeraX-DataFormats" version="~=1.0"/>
<Dependency name="ChimeraX-UI" version="~=1.0"/>
</Dependencies>

<Providers manager="data formats">
<Provider name="Deep mutational scan" synopsis="Deep mutational scan csv file" nicknames="dms" category="Molecular structure" suffixes=".csv" />
</Providers>

<Providers manager="open command">
<Provider name="Deep mutational scan" want_path="true" />
</Providers>

<Classifiers>
<PythonClassifier>Development Status :: 2 - Pre-Alpha</PythonClassifier>
<PythonClassifier>License :: Free for non-commercial use</PythonClassifier>
<ChimeraXClassifier>Command :: dms label :: Molecular structure :: Label residues with deep mutational scan values</ChimeraXClassifier>
<ChimeraXClassifier>Command :: dms attribute :: Molecular structure :: Assign a residue attribute computed from deep mutational scan values</ChimeraXClassifier>
<ChimeraXClassifier>Command :: dms scatterplot :: Molecular structure :: Show a scatter plot for two phenotypes from deep mutational scan data</ChimeraXClassifier>
<ChimeraXClassifier>Command :: dms statistics :: Molecular structure :: Report mean and standard deviation of deep mutational scan scores</ChimeraXClassifier>
<ChimeraXClassifier>Command :: dms histogram :: Molecular structure :: Show histogram of deep mutational scan scores</ChimeraXClassifier>
<ChimeraXClassifier>Command :: dms umap :: Molecular structure :: Show umap plot of residue deep mutational scan scores</ChimeraXClassifier>
</Classifiers>

</BundleInfo>
63 changes: 63 additions & 0 deletions src/bundles/deep_mutational_scan/src/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# vim: set expandtab ts=4 sw=4:

# === UCSF ChimeraX Copyright ===
# Copyright 2022 Regents of the University of California. All rights reserved.
# The ChimeraX application is provided pursuant to the ChimeraX license
# agreement, which covers academic and commercial uses. For more details, see
# <http://www.rbvi.ucsf.edu/chimerax/docs/licensing.html>
#
# This particular file is part of the ChimeraX library. You can also
# redistribute and/or modify it under the terms of the GNU Lesser General
# Public License version 2.1 as published by the Free Software Foundation.
# For more details, see
# <https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>
#
# THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
# EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ADDITIONAL LIABILITY
# LIMITATIONS ARE DESCRIBED IN THE GNU LESSER GENERAL PUBLIC LICENSE
# VERSION 2.1
#
# This notice must be embedded in or attached to all copies, including partial
# copies, of the software or any revisions or derivations thereof.
# === UCSF ChimeraX Copyright ===

from chimerax.core.toolshed import BundleAPI

class _DeepMutationalScanAPI(BundleAPI):

@staticmethod
def register_command(command_name, logger):
# 'register_command' is called by the toolshed on start up
from . import dms_label
dms_label.register_command(logger)
from . import dms_attribute
dms_attribute.register_command(logger)
from . import dms_scatter_plot
dms_scatter_plot.register_command(logger)
from . import dms_stats
dms_stats.register_command(logger)
from . import dms_histogram
dms_histogram.register_command(logger)
from . import dms_umap
dms_umap.register_command(logger)

@staticmethod
def run_provider(session, name, mgr):
if mgr == session.open_command:
if name == 'Deep mutational scan':
from chimerax.open_command import OpenerInfo
class DeepMutationalScanInfo(OpenerInfo):
def open(self, session, path, file_name, **kw):
from .dms_data import open_deep_mutational_scan_csv
dms_data, message = open_deep_mutational_scan_csv(session, path, **kw)
return [], message

@property
def open_args(self):
from chimerax.atomic import ChainArg
return {'Chain': ChainArg}

return DeepMutationalScanInfo()

bundle_api = _DeepMutationalScanAPI()
50 changes: 50 additions & 0 deletions src/bundles/deep_mutational_scan/src/dms_attribute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Assign a residue attribute from deep mutational scan scores.
def dms_attribute(session, chain, column_name, subtract_fit = None,
name = None, type = 'sum_absolute', above = None, below = None):
from .dms_data import dms_data
data = dms_data(chain)
if data is None:
from chimerax.core.errors import UserError
raise UserError(f'No deep mutation scan data associated with chain {chain}')
scores = data.column_values(column_name, subtract_fit = subtract_fit)

attr_name = _attribute_name(column_name, type, above, below) if name is None else name
from chimerax.atomic import Residue
Residue.register_attr(session, attr_name, "Deep Mutational Scan", attr_type=float)

residues = chain.existing_residues
count = 0
for res in residues:
value = scores.residue_value(res.number, value_type=type, above=above, below=below)
if value is not None:
setattr(res, attr_name, value)
count += 1

message = f'Set attribute {attr_name} for {count} residues of chain {chain}'
session.logger.info(message)

def _attribute_name(column_name, type, above, below):
attr_name = f'{column_name}_{type}'
if above is not None:
attr_name += f'_ge_{"%.3g"%above}'
if below is not None:
attr_name += f'_le_{"%.3g"%below}'
return attr_name

def register_command(logger):
from chimerax.core.commands import CmdDesc, register, StringArg, EnumOf, FloatArg
from chimerax.atomic import ChainArg
from .dms_data import ColumnValues
desc = CmdDesc(
required = [('chain', ChainArg)],
keyword = [('column_name', StringArg),
('subtract_fit', StringArg),
('name', StringArg),
('type', EnumOf(ColumnValues.residue_value_types)),
('above', FloatArg),
('below', FloatArg),
],
required_arguments = ['column_name'],
synopsis = 'Assign a residue attribute using deep mutation scan scores'
)
register('dms attribute', desc, dms_attribute, logger=logger)
Loading

0 comments on commit 800b2a1

Please sign in to comment.