Source code for schrodinger.application.livedesign.ld_utils
import hashlib
from requests.exceptions import HTTPError
from schrodinger import structure
from schrodinger.structutils import smiles
from . import constants
from . import login
PROPNAME_ROUND_TRIP_HASH = 's_ld_round_trip_hash'
PROPNAME_IMPORT_ENTITY_ID = constants.PROPNAME_IMPORT_ENTITY_ID
PROPNAME_CORP_ID = constants.PROPNAME_CORP_ID
[docs]def get_sha1(file_path):
"""
Return the SHA1 hash of a specified file. If no file path is provided,
return `None`.
:param file_path: the path to a file, or `None`
:type file_path: str or None
:return: the SHA1 hash of the file located at `file_path`, or `None`
:rtype: str or None
"""
if file_path is None:
return None
with open(file_path, 'rb') as fh:
file_data = fh.read()
return hashlib.sha1(file_data).hexdigest()
[docs]def get_round_trip_hash(st):
"""
Return a hash of relevant structure and host data. This will be used to
determine whether structures imported from LiveDesign can be exported back
to LiveDesign using corporate ID (vs. structure) matching.
:param st: a structure
:type st: structure.Structure
:return: a hash value related to the provided structure
:rtype: str
"""
generator = smiles.SmilesGenerator(stereo='annotation_and_geom',
unique=True)
host = login.get_host()
pattern = generator.getSmiles(st)
return str(hash((pattern, host)))
[docs]def apply_round_trip_hash(st):
"""
Store a structure-dependent hash as a property on this structure.
:param st: a structure
:type st: structure.Structure
"""
st.property[PROPNAME_ROUND_TRIP_HASH] = get_round_trip_hash(st)
[docs]def st_matches_round_trip_hash(st):
"""
Determine whether the supplied structure can be exported again using the
stored "round-trip" corporate ID value.
This can only be done if
1. The structure was originally imported from the same LD host that it
is not being exported to.
2. The SMILES/stereochemistry of the structure has not changed since
being imported.
:param st: a structure
:type st: structure.Structure
:return: whether the round trip hash value stored on this structure matches
a newly-generated hash
:rtype: bool
"""
stored_hash = st.property.get(PROPNAME_ROUND_TRIP_HASH)
if stored_hash is None:
return False
return stored_hash == get_round_trip_hash(st)
[docs]def set_corp_id_properties(sts, corp_id_match_prop=None):
"""
Set the corporate ID property for given structures.
Uses match property if passed in, or default corp ID
property if not.
:param sts: structures to set properties for
:type sts: list(structure.Structure)
:param corp_id_match_prop: Optional property to get corp ID
:type corp_id_match_prop: str | None
"""
for st in sts:
if corp_id_match_prop is not None:
corp_id = st.property.get(corp_id_match_prop)
elif st_matches_round_trip_hash(st):
corp_id = st.property.get(PROPNAME_IMPORT_ENTITY_ID)
else:
corp_id = None
corp_id = None if corp_id is None else str(corp_id)
safely_set_property(st, PROPNAME_CORP_ID, corp_id)
[docs]def safely_set_property(st, key, value):
"""
Set a specified property on a structure. If the supplied `value` is `None`,
delete the property if it is already defined on the structure if possible.
:raises ValueError: if this function is asked to delete a permanent
property, e.g. a structure title
:param st: a structure
:type st: structure.Structure
:param key: a structure property key
:type key: str
:param value: the value to store in the structure property dictionary
:type value: bool or int or float or str or None
"""
if value is not None:
st.property[key] = value
elif key in st.property:
del st.property[key]
[docs]def is_connected(ld_client):
"""
:param ld_client: a LiveDesign client instance
:type ld_client: client.LDClient
:return: whether the supplied client is connected to LiveDesign
:rtype: bool
"""
try:
return ld_client.ping()
except HTTPError:
# The user may have been logged out of LiveDesign somehow
return False
[docs]def is_sd_dataname(dataname):
"""
:param dataname: a structure property data name
:type dataname: str
:return: whether the supplied dataname belongs to the "SD" family
:rtype: bool
"""
propname = structure.PropertyName(dataname)
return propname.family.upper() == constants.FAMNAME_SD