from collections import OrderedDict
from enum import Enum
from schrodinger.trajectory.trajectory_gui_dir.display_settings_data import \
DEFAULT_RADIUS
from schrodinger.trajectory.trajectory_gui_dir.display_settings_data import \
MAX_RADIUS
from schrodinger.trajectory.trajectory_gui_dir.display_settings_data import \
MIN_RADIUS
from schrodinger.trajectory.trajectory_gui_dir.display_settings_data import \
DisplayOnly
# Entry hidden properties to store 'Basic' settings
DURATION_PROP = 'r_m_hidden_frame_duration'
STEP_PROP = 'i_m_hidden_step'
SMOOTHING_PROP = 'i_m_hidden_smoothing'
DIRECTION_PROP = 'i_m_hidden_player_direction'
LOOP_PROP = 's_m_hidden_player_mode'
BEYOND_PROP = 'b_m_hidden_ha_beyond_binding_site'
SOLVENTS_PROP = 'b_m_hidden_ha_solvents_only'
NONPOLAR_PROP = 'b_m_hidden_ha_nonpolar_hydrogens'
PROTEIN_PROP = 'b_m_hidden_ha_protein_only'
# Entry hidden properties to store 'View Position' settings
POSITION_PROP = 'b_m_hidden_adjust_view_position'
ALIGN_ON_FRAME_PROP = 'b_m_hidden_superimpose'
FRAME_PROP = 'i_m_hidden_reference_frame'
CENTER_PROP = 'b_m_hidden_center'
TRANSLATE_TO_FIRST_UNIT_CELL = 'b_m_hidden_translate_to_first_unit_cell'
# avp stands for Adjust view positioning
AVP_ASL_OPTION = 'i_m_hidden_avp_asl_option'
ALIGN_ASL_PROP = 's_m_hidden_trajectory_position_asl'
# Entry hidden properties to store 'Advanced Playback' settings
BINDING_SITE_RADIUS_PROP = 'i_m_hidden_binding_site_radius'
DISPLAY_ONLY_PROP = 'b_m_hidden_show_specified_atoms'
DISPLAY_ONLY_OPTION_PROP = 'i_m_hidden_display_only_option'
DISPLAY_ASL_PROP = 's_m_hidden_trajectory_display_asl'
SECONDARY_STRUCT_PROP = 'b_m_hidden_update_secondary_structure'
SHOW_SIM_BOX_PROP = 'b_m_hidden_show_simulation_box'
INC_VEC_LENS_PROP = 'b_m_hidden_include_vector_lengths'
REPLICATE_X_PROP = 'i_m_hidden_replicate_a'
REPLICATE_Y_PROP = 'i_m_hidden_replicate_b'
REPLICATE_Z_PROP = 'i_m_hidden_replicate_c'
# Frame settings
CURRENT_FRAME = "i_chorus_frame"
START_FRAME = "i_m_hidden_start_frame"
END_FRAME = "i_m_hidden_end_frame"
[docs]class Loop(Enum):
"""
Holds enums for Playback loop
"""
NONE = 'once'
SINGLE = 'loop'
OSCILLATE = 'reverse'
[docs]class Direction(Enum):
"""
Holds enums for Playback direction
"""
FORWARD = 0
BACKWARD = 1
[docs]class AVPAslOption(Enum):
"""
Holds enums for 'Align on'/'Center on'
"""
PROTEIN = 0
LIGAND_PLUS_BINDING_SITE = 1
LIGAND = 2
MOLECULE_1 = 3
CUSTOM_SELECTION = 4
[docs]class PlaybackSettingsData():
"""
This class holds all the Playback Settings. Reads from entry id and writes
back when modified.
"""
DEFAULT_START_FRAME = 1
MIN_FRAME_DURATION = 0.01
MAX_FRAME_DURATION = 3.0
MIN_STEP = 1
MIN_REF_FRAME = 1
MIN_REPLICATE = 1
MAX_REPLICATE = 5
# Setting property name to entry hidden property data name dictionary.
# This dictionary will be used to automatically set (write to entry)
# and get (read from entry) properties.
SETTINGS_DICT = {
'frame_duration': DURATION_PROP,
'step': STEP_PROP,
'smoothing': SMOOTHING_PROP,
'direction': DIRECTION_PROP,
'loop': LOOP_PROP,
'ha_beyond_binding_site': BEYOND_PROP,
'ha_solvents_only': SOLVENTS_PROP,
'ha_nonpolar_hydrogens': NONPOLAR_PROP,
'ha_protein_only': PROTEIN_PROP,
'adjust_view_position': POSITION_PROP,
'avp_align_on_frame': ALIGN_ON_FRAME_PROP,
'avp_ref_frame': FRAME_PROP,
'avp_center_molecules': CENTER_PROP,
'avp_asl_option': AVP_ASL_OPTION,
'avp_asl': ALIGN_ASL_PROP,
'translate_to_first_unit_cell': TRANSLATE_TO_FIRST_UNIT_CELL,
'binding_site_radius': BINDING_SITE_RADIUS_PROP,
'display_only': DISPLAY_ONLY_PROP,
'display_only_option': DISPLAY_ONLY_OPTION_PROP,
'matching_asl': DISPLAY_ASL_PROP,
'update_secondary_structure': SECONDARY_STRUCT_PROP,
'show_simulation_box': SHOW_SIM_BOX_PROP,
'include_vector_lengths': INC_VEC_LENS_PROP,
'replicate_x': REPLICATE_X_PROP,
'replicate_y': REPLICATE_Y_PROP,
'replicate_z': REPLICATE_Z_PROP
}
# Frame settings dictionary with attribute, data_name, and default value
FRAME_SETTINGS_DICT = OrderedDict(
(('start_frame', (START_FRAME, 'DEFAULT_START_FRAME')),
('end_frame', (END_FRAME, 'frame_total')),
('current_frame', (CURRENT_FRAME, 'start_frame'))))
[docs] def __init__(self, proj, eid, frame_total, matsci_profile: bool):
"""
:param proj: Project from which entry's PlaybackSettingsData need to be
created.
:type proj: Project
:param eid: Entry Id for which PlaybackSettingsData has to be created.
:type eid: int or str
:param frame_total: Total number of frames in the trajectory.
:type frame_total: int
:param matsci_profile: Whether current maestro profile is MatSci.
It is used to set default state of playback settings options.
"""
self.resetSettings(show_simbox_default=matsci_profile)
self.proj = proj
self.eid = eid
self.frame_total = frame_total
self.allow_replication = True
self.readFrameSettings()
self.readSettings()
[docs] def resetSettings(self, show_simbox_default: bool):
"""
Reset settings to default values
:param show_simbox_default: Indicates the default state of show simulation box.
"""
# Basic settings
self.frame_duration = self.MIN_FRAME_DURATION
self.step = self.MIN_STEP
self.smoothing = 1
self.direction = Direction.FORWARD
self.loop = Loop.SINGLE
# ha stands for 'Hide Atoms'
self.ha_beyond_binding_site = False
self.ha_solvents_only = False
self.ha_nonpolar_hydrogens = True
self.ha_protein_only = True
# View Position settings
self.adjust_view_position = True
self.avp_align_on_frame = True
self.avp_ref_frame = self.MIN_REF_FRAME
self.avp_center_molecules = False
self.avp_asl_option = AVPAslOption.PROTEIN
self.avp_asl = ""
self.translate_to_first_unit_cell = False
# Advanced settings
self.binding_site_radius = DEFAULT_RADIUS
self.display_only = False
self.display_only_option = DisplayOnly.CURRENT
self.matching_asl = ''
self.update_secondary_structure = True
self.show_simulation_box = show_simbox_default
self.include_vector_lengths = False
self.replicate_x = self.MIN_REPLICATE
self.replicate_y = self.MIN_REPLICATE
self.replicate_z = self.MIN_REPLICATE
[docs] def readSettings(self):
"""
Reads the settings from entry and sets to the object, if appropriate.
Otherwise, sets default setting value and writes it to entry.
"""
row = self.proj.getRow(self.eid)
if row is None:
return
for setting_name, data_name in self.SETTINGS_DICT.items():
val = row[data_name]
attr = getattr(self, setting_name)
# Get the attribute type to retain its type when setting value
# This is required because we use enums for some settings.
# e.g. direction, loop, etc
attr_type = type(attr)
if val is not None:
# Got the value, set it to the setting attribute with the
# same type.
setattr(self, setting_name, attr_type(val))
# Existing hidden entry properties are used to store avp_align_on_frame
# and avp_center_molecules. With the current GUI they are mutually
# exclusive, make sure they remain same after reading.
if self.avp_align_on_frame == self.avp_center_molecules:
self.avp_align_on_frame = True
self.avp_center_molecules = False
# Validate avp_ref_frame
if not (self.MIN_REF_FRAME <= self.avp_ref_frame <= self.frame_total):
self.avp_ref_frame = self.MIN_REF_FRAME
if not self.isValidStep():
self.setToMinStep()
if not (MIN_RADIUS <= self.binding_site_radius <= MAX_RADIUS):
self.binding_site_radius = DEFAULT_RADIUS
replicates = ('replicate_x', 'replicate_y', 'replicate_z')
for replicate in replicates:
value = getattr(self, replicate)
if not (self.MIN_REPLICATE <= value <= self.MAX_REPLICATE):
setattr(self, replicate, self.MIN_REPLICATE)
def __setattr__(self, attr, value):
"""
When attributes in FRAME_SETTINGS_DICT are set, then writes them into
the entry with corresponding property.
Validate 'frame_duration' setting and set it accordingly.
"""
# Write frame settings to entry
if (attr in self.FRAME_SETTINGS_DICT):
row = self.proj.getRow(self.eid)
if row is not None:
row[self.FRAME_SETTINGS_DICT[attr][0]] = value
# Validate 'frame_duration' and correct it if required
if attr == 'frame_duration' and not (self.MIN_FRAME_DURATION <= value <=
self.MAX_FRAME_DURATION):
value = self.MIN_FRAME_DURATION
super().__setattr__(attr, value)
[docs] def getMaxStep(self):
"""
Returns maximum allowed step based on the end & start frames
"""
max_step = self.end_frame - self.start_frame
return max(max_step, self.MIN_STEP)
[docs] def isValidStep(self):
"""
Whether current step is valid.
"""
return self.MIN_STEP <= self.step <= self.getMaxStep()
[docs] def setToMinStep(self):
"""
Set step to minimum
"""
self.step = self.MIN_STEP
[docs] def writeSettings(self):
"""
Write settings to entry.
"""
row = self.proj.getRow(self.eid)
if row is None:
return
for setting_name, data_name in self.SETTINGS_DICT.items():
value = getattr(self, setting_name)
# If the value of the type Enum then store its value
val = value
if isinstance(val, Enum):
val = value.value
# Get the data name to store the setting
data_name = self.SETTINGS_DICT[setting_name]
row[data_name] = val
[docs] def readFrameSettings(self):
"""
Read frame settings according to FRAME_SETTINGS_DICT.
"""
row = self.proj.getRow(self.eid)
if row is None:
return
for attr, (data_name, def_value) in self.FRAME_SETTINGS_DICT.items():
value = row[data_name]
# If value is invalid then set to the default value
if value is None or value < self.DEFAULT_START_FRAME:
value = getattr(self, def_value)
setattr(self, attr, value)
if not (self.start_frame <= self.current_frame <= self.end_frame):
self.current_frame = self.start_frame