def __init__(self, store_directory): """ Initialize YANK object with default parameters. Parameters ---------- store_directory : str The storage directory in which output NetCDF files are read or written. """ # Record that we are not yet initialized. self._initialized = False # Store output directory. self._store_directory = store_directory # Public attributes. self.restraint_type = 'flat-bottom' # default to a flat-bottom restraint between the ligand and receptor self.randomize_ligand = False self.randomize_ligand_sigma_multiplier = 2.0 self.randomize_ligand_close_cutoff = 1.5 * unit.angstrom # TODO: Allow this to be specified by user. self.mc_displacement_sigma = 10.0 * unit.angstroms # Set internal variables. self._phases = list() self._store_filenames = dict() # Default alchemical protocols. self.default_protocols = dict() self.default_protocols[ 'vacuum'] = AbsoluteAlchemicalFactory.defaultVacuumProtocol() self.default_protocols[ 'solvent-implicit'] = AbsoluteAlchemicalFactory.defaultSolventProtocolImplicit( ) self.default_protocols[ 'complex-implicit'] = AbsoluteAlchemicalFactory.defaultComplexProtocolImplicit( ) self.default_protocols[ 'solvent-explicit'] = AbsoluteAlchemicalFactory.defaultSolventProtocolExplicit( ) self.default_protocols[ 'complex-explicit'] = AbsoluteAlchemicalFactory.defaultComplexProtocolExplicit( ) # Default options for repex. self.default_options = dict() self.default_options['number_of_equilibration_iterations'] = 0 self.default_options['number_of_iterations'] = 100 self.default_options['number_of_iterations'] = 100 self.default_options['timestep'] = 2.0 * unit.femtoseconds self.default_options['collision_rate'] = 5.0 / unit.picoseconds self.default_options['minimize'] = False self.default_options[ 'show_mixing_statistics'] = True # this causes slowdown with iteration and should not be used for production self.default_options['platform'] = None self.default_options[ 'displacement_sigma'] = 1.0 * unit.nanometers # attempt to displace ligand by this stddev will be made each iteration return
def __init__(self, store_directory, verbose=False): """ Initialize YANK object with default parameters. Parameters ---------- store_directory : str The storage directory in which output NetCDF files are read or written. verbose : bool, optional, default=False If True, will turn on verbose output. """ # Record that we are not yet initialized. self._initialized = False # Store output directory. self._store_directory = store_directory # Public attributes. self.verbose = verbose self.restraint_type = 'flat-bottom' # default to a flat-bottom restraint between the ligand and receptor self.randomize_ligand = True self.randomize_ligand_sigma_multiplier = 2.0 self.randomize_ligand_close_cutoff = 1.5 * unit.angstrom # TODO: Allow this to be specified by user. self.mc_displacement_sigma = 10.0 * unit.angstroms # Set internal variables. self._phases = list() self._store_filenames = dict() # Default alchemical protocols. self.default_protocols = dict() self.default_protocols['vacuum'] = AbsoluteAlchemicalFactory.defaultVacuumProtocol() self.default_protocols['solvent-implicit'] = AbsoluteAlchemicalFactory.defaultSolventProtocolImplicit() self.default_protocols['complex-implicit'] = AbsoluteAlchemicalFactory.defaultComplexProtocolImplicit() self.default_protocols['solvent-explicit'] = AbsoluteAlchemicalFactory.defaultSolventProtocolExplicit() self.default_protocols['complex-explicit'] = AbsoluteAlchemicalFactory.defaultComplexProtocolExplicit() # Default options for repex. self.default_options = dict() self.default_options['number_of_equilibration_iterations'] = 0 self.default_options['number_of_iterations'] = 100 self.default_options['verbose'] = self.verbose self.default_options['timestep'] = 2.0 * unit.femtoseconds self.default_options['collision_rate'] = 5.0 / unit.picoseconds self.default_options['minimize'] = False self.default_options['show_mixing_statistics'] = True # this causes slowdown with iteration and should not be used for production self.default_options['platform_names'] = None self.default_options['displacement_sigma'] = 1.0 * unit.nanometers # attempt to displace ligand by this stddev will be made each iteration return
def _AutoAlchemyStates(self, phase, real_R_states=None, real_A_states=None, real_E_states=None, real_C_states=None, alchemy_source=None): #Generate the real alchemical states automatically. if alchemy_source: #Load alchemy from an external source import imp if alchemy_source[ -3:] != '.py': #Check if the file or the folder was provided alchemy_source = os.path.join(alchemy_source, 'alchemy.py') alchemy = imp.load_source('alchemy', alchemy_source) AAF = alchemy.AbsoluteAlchemicalFactory else: #Standard load from alchemy import AbsoluteAlchemicalFactory as AAF if phase is 'vacuum': protocol = AAF.defaultVacuumProtocol() elif phase is 'complex': protocol = AAF.defaultComplexProtocolExplicit() #Determine which phases need crunched if real_R_states is None: real_R_states = list() crunchR = True else: crunchR = False if real_A_states is None: real_A_states = list() crunchA = True else: crunchA = False if real_E_states is None: real_E_states = list() real_PMEFull_states = list() crunchE = True else: crunchE = False #Detect for the cap basis property if numpy.all([hasattr(state, 'ligandCapToFull') for state in protocol]) and real_C_states is None: real_C_states = list() crunchC = True else: crunchC = False #Import from the alchemy file if need be for state in protocol: #Go through each state if crunchE: real_E_states.append(state.ligandElectrostatics) try: real_PMEFull_states.append(state.ligandPMEFull) except: real_PMEFull_states.append(None) if crunchR: real_R_states.append(state.ligandRepulsion) if crunchA: real_A_states.append(state.ligandAttraction) if crunchC: real_C_states.append(state.ligandCapToFull) if numpy.all( [i is None for i in real_PMEFull_states] ): #Must put [...] around otherwise it creates the generator object which numpy.all evals to True self.PME_isolated = False else: self.PME_isolated = True #Determine cutoffs self.real_E_states = numpy.array(real_E_states) self.real_PMEFull_states = numpy.array(real_PMEFull_states) self.real_R_states = numpy.array(real_R_states) self.real_A_states = numpy.array(real_A_states) self.real_C_states = numpy.array(real_C_states) indicies = numpy.array(range(len(real_E_states))) #Determine Inversion if numpy.any(self.real_E_states < 0) or numpy.any( numpy.logical_and( self.real_PMEFull_states < 0, numpy.array( [i is not None for i in self.real_PMEFull_states]))): self.Inversion = True else: self.Inversion = False #Set the indicies, trap TypeError (logical_and false everywhere) as None (i.e. state not found in alchemy) if crunchC: #Check for the cap potential print "Not Coded Yet!" exit(1) #Create the Combinations basisVars = ["E", "A", "R", "C"] mappedStates = [ self.real_E_states, self.real_R_states, self.real_C_states, self.real_A_states ] nBasis = len(basisVars) coupled_states = {} decoupled_states = {} for iBasis in xrange(nBasis): coupled_states[basisVars[iBasis]] = numpy.where( mappedStates[iBasis] == 1.00)[ 0] #need the [0] to extract the array from the basis decoupled_states[basisVars[iBasis]] = numpy.where( mappedStates[iBasis] == 0.00)[0] self.coupled_states = coupled_states self.decoupled_states = decoupled_states self.basisVars = basisVars else: if self.PME_isolated: #Logic to solve for isolated PME case try: #Figure out the Fully coupled state self.real_EAR = int(indicies[numpy.logical_and( numpy.logical_and(self.real_E_states == 1, self.real_PMEFull_states == 1), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1))]) except TypeError: self.real_EAR = None try: self.real_AR = int(indicies[numpy.logical_and( numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 0), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1))]) except TypeError: self.real_AR = None try: self.real_R = int(indicies[numpy.logical_and( numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 0), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 0))]) except TypeError: self.real_R = None try: self.real_alloff = int(indicies[numpy.logical_and( numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 0), numpy.logical_and(self.real_R_states == 0, self.real_A_states == 0))]) except: self.real_alloff = None try: self.real_PMEAR = int(indicies[numpy.logical_and( numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 1), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1))]) except TypeError: self.real_PMEAR = None try: self.real_PMEsolve = int(indicies[numpy.logical_and( numpy.logical_and( self.real_E_states == 0, numpy.logical_and(self.real_PMEFull_states != 1, self.real_PMEFull_states != 0)), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1))]) except TypeError: self.real_PMEsolve = None if self.Inversion: self.real_inverse = int(indicies[numpy.logical_and( numpy.logical_and( numpy.logical_and(self.real_E_states == -1, self.real_PMEFull_states == -1), self.real_R_states == 1), self.real_A_states == 1)]) else: try: self.real_EAR = int(indicies[numpy.logical_and( self.real_E_states == 1, numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1))]) except TypeError: self.real_EAR = None try: self.real_AR = int(indicies[numpy.logical_and( self.real_E_states == 0, numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1))]) except TypeError: self.real_AR = None try: self.real_R = int(indicies[numpy.logical_and( self.real_E_states == 0, numpy.logical_and(self.real_R_states == 1, self.real_A_states == 0))]) except TypeError: self.real_R = None try: self.real_alloff = int(indicies[numpy.logical_and( self.real_E_states == 0, numpy.logical_and(self.real_R_states == 0, self.real_A_states == 0))]) except: self.real_alloff = None if self.Inversion: self.real_inverse = int(indicies[numpy.logical_and( numpy.logical_and(self.real_E_states == -1, self.real_R_states == 1), self.real_A_states == 1)]) #Now that all the sorting and variable assignment has been done, must set the PME states which were not defined to the electrostatic state as thats how its coded (helps sorting algorithm later) #This algorighm also ensures that real_PMEFull_states is not dtype=object nstates = len(self.real_E_states) tempPME = numpy.zeros(nstates) for i in xrange(nstates): if self.real_PMEFull_states[i] is None: #Find where they are none tempPME[i] = self.real_E_states[ i] #Assign them equal to the E state else: tempPME[i] = self.real_PMEFull_states[i] self.real_PMEFull_states = tempPME return
def _AutoAlchemyStates(self, phase, real_R_states=None, real_A_states=None, real_E_states=None, real_C_states=None, alchemy_source=None): #Generate the real alchemical states automatically. if alchemy_source: #Load alchemy from an external source import imp if alchemy_source[-3:] != '.py': #Check if the file or the folder was provided alchemy_source = os.path.join(alchemy_source, 'alchemy.py') alchemy = imp.load_source('alchemy', alchemy_source) AAF = alchemy.AbsoluteAlchemicalFactory else: #Standard load from alchemy import AbsoluteAlchemicalFactory as AAF if phase is 'vacuum': protocol = AAF.defaultVacuumProtocol() elif phase is 'complex': protocol = AAF.defaultComplexProtocolExplicit() #Determine which phases need crunched if real_R_states is None: real_R_states = list() crunchR = True else: crunchR = False if real_A_states is None: real_A_states = list() crunchA = True else: crunchA = False if real_E_states is None: real_E_states = list() real_PMEFull_states = list() crunchE = True else: crunchE = False #Detect for the cap basis property if numpy.all([hasattr(state, 'ligandCapToFull') for state in protocol]) and real_C_states is None: real_C_states = list() crunchC = True else: crunchC = False #Import from the alchemy file if need be for state in protocol: #Go through each state if crunchE: real_E_states.append(state.ligandElectrostatics) try: real_PMEFull_states.append(state.ligandPMEFull) except: real_PMEFull_states.append(None) if crunchR: real_R_states.append(state.ligandRepulsion) if crunchA: real_A_states.append(state.ligandAttraction) if crunchC: real_C_states.append(state.ligandCapToFull) if numpy.all([i is None for i in real_PMEFull_states]): #Must put [...] around otherwise it creates the generator object which numpy.all evals to True self.PME_isolated = False else: self.PME_isolated = True #Determine cutoffs self.real_E_states = numpy.array(real_E_states) self.real_PMEFull_states = numpy.array(real_PMEFull_states) self.real_R_states = numpy.array(real_R_states) self.real_A_states = numpy.array(real_A_states) self.real_C_states = numpy.array(real_C_states) indicies = numpy.array(range(len(real_E_states))) #Determine Inversion if numpy.any(self.real_E_states < 0) or numpy.any(numpy.logical_and(self.real_PMEFull_states < 0,numpy.array([i is not None for i in self.real_PMEFull_states]))): self.Inversion = True else: self.Inversion = False #Set the indicies, trap TypeError (logical_and false everywhere) as None (i.e. state not found in alchemy) if crunchC: #Check for the cap potential print "Not Coded Yet!" exit(1) #Create the Combinations basisVars = ["E", "A", "R", "C"] mappedStates = [self.real_E_states, self.real_R_states, self.real_C_states, self.real_A_states] nBasis = len(basisVars) coupled_states = {} decoupled_states = {} for iBasis in xrange(nBasis): coupled_states[basisVars[iBasis]] = numpy.where(mappedStates[iBasis] == 1.00)[0] #need the [0] to extract the array from the basis decoupled_states[basisVars[iBasis]] = numpy.where(mappedStates[iBasis] == 0.00)[0] self.coupled_states = coupled_states self.decoupled_states = decoupled_states self.basisVars = basisVars else: if self.PME_isolated: #Logic to solve for isolated PME case try: #Figure out the Fully coupled state self.real_EAR = int(indicies[ numpy.logical_and(numpy.logical_and(self.real_E_states == 1, self.real_PMEFull_states == 1), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1)) ]) except TypeError: self.real_EAR = None try: self.real_AR = int(indicies[ numpy.logical_and(numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 0), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1)) ]) except TypeError: self.real_AR = None try: self.real_R = int(indicies[ numpy.logical_and(numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 0), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 0)) ]) except TypeError: self.real_R = None try: self.real_alloff = int(indicies[ numpy.logical_and(numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 0), numpy.logical_and(self.real_R_states == 0, self.real_A_states == 0)) ]) except: self.real_alloff = None try: self.real_PMEAR = int(indicies[ numpy.logical_and(numpy.logical_and(self.real_E_states == 0, self.real_PMEFull_states == 1), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1)) ]) except TypeError: self.real_PMEAR = None try: self.real_PMEsolve = int(indicies[ numpy.logical_and(numpy.logical_and(self.real_E_states == 0, numpy.logical_and(self.real_PMEFull_states != 1, self.real_PMEFull_states != 0)), numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1)) ]) except TypeError: self.real_PMEsolve = None if self.Inversion: self.real_inverse = int(indicies[ numpy.logical_and(numpy.logical_and(numpy.logical_and(self.real_E_states == -1, self.real_PMEFull_states == -1), self.real_R_states == 1), self.real_A_states==1) ]) else: try: self.real_EAR = int(indicies[ numpy.logical_and(self.real_E_states == 1, numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1)) ]) except TypeError: self.real_EAR = None try: self.real_AR = int(indicies[ numpy.logical_and(self.real_E_states == 0, numpy.logical_and(self.real_R_states == 1, self.real_A_states == 1)) ]) except TypeError: self.real_AR = None try: self.real_R = int(indicies[ numpy.logical_and(self.real_E_states == 0, numpy.logical_and(self.real_R_states == 1, self.real_A_states == 0)) ]) except TypeError: self.real_R = None try: self.real_alloff = int(indicies[ numpy.logical_and(self.real_E_states == 0, numpy.logical_and(self.real_R_states == 0, self.real_A_states == 0)) ]) except: self.real_alloff = None if self.Inversion: self.real_inverse = int(indicies[ numpy.logical_and(numpy.logical_and(self.real_E_states == -1, self.real_R_states == 1), self.real_A_states==1) ]) #Now that all the sorting and variable assignment has been done, must set the PME states which were not defined to the electrostatic state as thats how its coded (helps sorting algorithm later) #This algorighm also ensures that real_PMEFull_states is not dtype=object nstates = len(self.real_E_states) tempPME = numpy.zeros(nstates) for i in xrange(nstates): if self.real_PMEFull_states[i] is None: #Find where they are none tempPME[i] = self.real_E_states[i] #Assign them equal to the E state else: tempPME[i] = self.real_PMEFull_states[i] self.real_PMEFull_states = tempPME return
def __init__(self, store_directory, mpicomm=None, **kwargs): """ Initialize YANK object with default parameters. Parameters ---------- store_directory : str The storage directory in which output NetCDF files are read or written. mpicomm : MPI communicator, optional If an MPI communicator is passed, an MPI simulation will be attempted. restraint_type : str, optional Restraint type to add between protein and ligand. Supported types are 'flat-bottom' and 'harmonic'. The second one is available only in implicit solvent (default: 'flat-bottom'). randomize_ligand : bool, optional Randomize ligand position when True. Not available in explicit solvent (default: False). randomize_ligand_close_cutoff : simtk.unit.Quantity (units: length), optional Cutoff for ligand position randomization (default: 1.5*unit.angstrom). randomize_ligand_sigma_multiplier : float, optional Multiplier for ligand position randomization displacement (default: 2.0). mc_displacement_sigma : simtk.unit.Quantity (units: length), optional Maximum displacement for Monte Carlo moves that augment Langevin dynamics (default: 10.0*unit.angstrom). Other Parameters ---------------- **kwargs More options to pass to the ReplicaExchange or AlchemicalFactory classes on initialization. See Also -------- ReplicaExchange.default_parameters : extra parameters accepted. """ # Copy kwargs to avoid modifications parameters = copy.deepcopy(kwargs) # Record that we are not yet initialized. self._initialized = False # Store output directory. self._store_directory = store_directory # Save MPI communicator self._mpicomm = mpicomm # Set internal variables. self._phases = list() self._store_filenames = dict() # Default alchemical protocols. self.default_protocols = dict() self.default_protocols['vacuum'] = AbsoluteAlchemicalFactory.defaultVacuumProtocol() self.default_protocols['solvent-implicit'] = AbsoluteAlchemicalFactory.defaultSolventProtocolImplicit() self.default_protocols['complex-implicit'] = AbsoluteAlchemicalFactory.defaultComplexProtocolImplicit() self.default_protocols['solvent-explicit'] = AbsoluteAlchemicalFactory.defaultSolventProtocolExplicit() self.default_protocols['complex-explicit'] = AbsoluteAlchemicalFactory.defaultComplexProtocolExplicit() # Store Yank parameters for option_name, default_value in self.default_parameters.items(): setattr(self, '_' + option_name, parameters.pop(option_name, default_value)) # Store repex parameters self._repex_parameters = {par: parameters.pop(par) for par in ModifiedHamiltonianExchange.default_parameters if par in parameters} # Store AlchemicalFactory parameters self._alchemy_parameters = {par: parameters.pop(par) for par in inspect.getargspec(AbsoluteAlchemicalFactory.__init__).args if par in parameters} # Check for unknown parameters if len(parameters) > 0: raise TypeError('got an unexpected keyword arguments {}'.format( ', '.join(parameters.keys())))