def transform_coordinates(self, coordinates, argument=None): """ translate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ # get axis _,_,_,_,X,Y,Z =get_principal_axis(coordinates) axis = [X,Y,Z][self.axis] # generate translation axis translationAxis = generate_vectors_in_solid_angle(direction=axis, maxAngle=self.__angle, numberOfVectors=1)[0] # get translation amplitude maxAmp = self.amplitude[1]-self.amplitude[0] if self.direction is None: amplitude = (1-2*generate_random_float())*maxAmp elif self.direction: amplitude = generate_random_float()*maxAmp else: amplitude = -generate_random_float()*maxAmp # compute baseVector baseVector = FLOAT_TYPE(np.sign(amplitude)*translationAxis*self.amplitude[0]) # compute translation vector vector = baseVector + translationAxis*FLOAT_TYPE(amplitude) # translate and return return coordinates+vector
def transform_coordinates(self, coordinates, argument=None): """ translates coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ # generate translation axis translationAxis = generate_vectors_in_solid_angle( direction=self.axis, maxAngle=self.__angle, numberOfVectors=1)[0] # get translation amplitude maxAmp = self.amplitude[1] - self.amplitude[0] if self.direction is None: amplitude = (1 - 2 * generate_random_float()) * maxAmp elif self.direction: amplitude = generate_random_float() * maxAmp else: amplitude = -generate_random_float() * maxAmp # compute baseVector baseVector = FLOAT_TYPE( np.sign(amplitude) * translationAxis * self.amplitude[0]) # compute translation vector vector = baseVector + translationAxis * FLOAT_TYPE(amplitude) # translate and return return coordinates + vector
def transform_coordinates(self, coordinates, argument=None): """ translate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ if coordinates.shape[0] <= 1: # atoms where removed, fall back to random translation return coordinates + generate_random_vector( minAmp=self.__amplitude[0], maxAmp=self.__amplitude[1]) else: # get translation amplitude maxAmp = self.amplitude[1] - self.amplitude[0] if self.direction is None: amplitude = (1 - 2 * generate_random_float()) * maxAmp elif self.direction: amplitude = generate_random_float() * maxAmp else: amplitude = -generate_random_float() * maxAmp # get axis of translation _, _, _, _, X, Y, Z = get_principal_axis(coordinates) translationAxis = [X, Y, Z][self.__axis] # compute baseVector baseVector = FLOAT_TYPE( np.sign(amplitude) * translationAxis * self.amplitude[0]) # compute translation vector vector = baseVector + translationAxis * FLOAT_TYPE(amplitude) # translate and return return coordinates + vector
def transform_coordinates(self, coordinates, argument=None): """ translates coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ # get translation amplitude maxAmp = self.amplitude[1]-self.amplitude[0] if self.__direction is None: amplitude = (1-2*generate_random_float())*maxAmp elif self.__direction: amplitude = generate_random_float()*maxAmp else: amplitude = -generate_random_float()*maxAmp # compute baseVector baseVector = FLOAT_TYPE( np.sign(amplitude)*self.__axis*self.amplitude[0] ) # compute translation vector vector = baseVector + self.__axis*FLOAT_TYPE(amplitude) # translate and return return coordinates+vector
def compute_total_standard_error(self, constraints, current=True): if generate_random_float() <= self.__improveProbability: newStdErr = self.biasedStdErr-generate_random_float()*1e-3 if newStdErr<=0: raise Exception("biasedStdErr reached 0. restart using bigger initialStdErr") else: newStdErr = self.biasedStdErr+generate_random_float()*1e-3 return newStdErr
def transform_coordinates(self, coordinates, argument=None): """ Translate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ # get atoms group center center = np.sum(coordinates, 0)/coordinates.shape[0] # translate to origin rotatedCoordinates = coordinates-center # get normalized direction vectors leftVector = FLOAT_TYPE( rotatedCoordinates[1,:]-rotatedCoordinates[0,:] ) leftVector /= FLOAT_TYPE( np.linalg.norm(leftVector) ) rightVector = FLOAT_TYPE( rotatedCoordinates[2,:]-rotatedCoordinates[0,:] ) rightVector /= FLOAT_TYPE( np.linalg.norm(rightVector) ) # get rotation axis rotationAxis = np.cross(leftVector, rightVector) if rotationAxis[0]==rotationAxis[1]==rotationAxis[2]==0.: rotationAxis = np.array(1-2*np.random.random(3), dtype=FLOAT_TYPE) rotationAxis /= FLOAT_TYPE( np.linalg.norm(rotationAxis) ) # create shrink flag if self.__shrink is None: shrink = (1-2*generate_random_float())>0 else: shrink = self.__shrink # get rotation angles if self.__symmetric: angleLeft = angleRight = FLOAT_TYPE(generate_random_float()*self.__amplitude) else: angleLeft = FLOAT_TYPE(generate_random_float()*self.__amplitude) angleRight = FLOAT_TYPE(generate_random_float()*self.__amplitude) # create directions if shrink: angleLeft *= FLOAT_TYPE(-1) angleRight *= FLOAT_TYPE( 1) else: angleLeft *= FLOAT_TYPE( 1) angleRight *= FLOAT_TYPE(-1) # rotate if self.__agitate[0]: rotationMatrix = get_rotation_matrix(rotationAxis, angleLeft) rotatedCoordinates[1,:] = np.dot( rotationMatrix, rotatedCoordinates[1,:]) if self.__agitate[1]: rotationMatrix = get_rotation_matrix(rotationAxis, angleRight) rotatedCoordinates[2,:] = np.dot( rotationMatrix, rotatedCoordinates[2,:]) # translate back from center and return return np.array(rotatedCoordinates+center, dtype=FLOAT_TYPE)
def __get_amplitude(self): # get translation amplitude maxAmp = self.amplitude[1] - self.amplitude[0] if self.__direction is None: amplitude = (1 - 2 * generate_random_float()) * maxAmp elif self.__direction: amplitude = generate_random_float() * maxAmp else: amplitude = -generate_random_float() * maxAmp return amplitude
def __get_amplitude(self): # get translation amplitude maxAmp = self.amplitude[1]-self.amplitude[0] if self.__direction is None: amplitude = (1-2*generate_random_float())*maxAmp elif self.__direction: amplitude = generate_random_float()*maxAmp else: amplitude = -generate_random_float()*maxAmp return amplitude
def transform_coordinates(self, coordinates, argument=None): """ Rotate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the rotation. #. argument (object): Any python object. Not used in this generator. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the rotation. """ # get rotation angle rotationAngle = (1-2*generate_random_float())*self.amplitude # get atoms group center and rotation axis center,_,_,_,X,Y,Z =get_principal_axis(coordinates) rotationAxis = [X,Y,Z][self.__axis] # get rotation matrix rotationMatrix = get_rotation_matrix(rotationAxis, rotationAngle) # translate to origin rotatedCoordinates = coordinates-center # rotate for idx in range(rotatedCoordinates.shape[0]): rotatedCoordinates[idx,:] = np.dot( rotationMatrix, rotatedCoordinates[idx,:]) # translate back to center and return rotated coordinates return np.array(rotatedCoordinates+center, dtype=FLOAT_TYPE)
def transform_coordinates(self, coordinates, argument=None): """ Rotate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the rotation. #. argument (object): Not used here. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the rotation. """ if coordinates.shape[0] <= 1: # atoms where removed, fall back to random translation return coordinates + generate_random_vector( minAmp=self.__amplitude[0], maxAmp=self.__amplitude[1]) else: # get rotation angle rotationAngle = (1 - 2 * generate_random_float()) * self.amplitude # get atoms group center and rotation axis center, _, _, _, X, Y, Z = get_principal_axis(coordinates) rotationAxis = [X, Y, Z][self.__axis] # get rotation matrix rotationMatrix = get_rotation_matrix(rotationAxis, rotationAngle) # translate to origin rotatedCoordinates = coordinates - center # rotate for idx in range(rotatedCoordinates.shape[0]): rotatedCoordinates[idx, :] = np.dot(rotationMatrix, rotatedCoordinates[idx, :]) # translate back to center and return rotated coordinates return np.array(rotatedCoordinates + center, dtype=FLOAT_TYPE)
def transform_coordinates(self, coordinates, argument=None): """ Rotate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the rotation. #. argument (object): Not used here. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the rotation. """ # get rotation angle rotationAngle = (1 - 2 * generate_random_float()) * self.amplitude # get rotation matrix rotationMatrix = get_rotation_matrix(self.__axis, rotationAngle) # get atoms group center and rotation axis center, _, _, _, _, _, _ = get_principal_axis(coordinates) # translate to origin rotatedCoordinates = coordinates - center # rotate for idx in range(rotatedCoordinates.shape[0]): rotatedCoordinates[idx, :] = np.dot(rotationMatrix, rotatedCoordinates[idx, :]) # translate back to center and return rotated coordinates return np.array(rotatedCoordinates + center, dtype=FLOAT_TYPE)
def transform_coordinates(self, coordinates, argument=None): """ Rotate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the rotation #. argument (object): Any python object. Not used in this generator. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the rotation. """ # get rotation axis n = 0 while n<PRECISION: rotationAxis = 1-2*np.random.random(3) n = np.linalg.norm(rotationAxis) rotationAxis /= n # get rotation angle rotationAngle = (1-2*generate_random_float())*self.amplitude # get rotation matrix rotationMatrix = get_rotation_matrix(rotationAxis, rotationAngle) # get atoms group center center = np.sum(coordinates, 0)/coordinates.shape[0] # translate to origin rotatedCoordinates = coordinates-center # rotate for idx in range(rotatedCoordinates.shape[0]): rotatedCoordinates[idx,:] = np.dot( rotationMatrix, rotatedCoordinates[idx,:]) # translate back to center and return rotated coordinates return np.array(rotatedCoordinates+center, dtype=FLOAT_TYPE)
def transform_coordinates(self, coordinates, argument=None): """ Translate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ # generate random vector and ensure it is not zero vector = np.array(1-2*np.random.random(3), dtype=FLOAT_TYPE) norm = np.linalg.norm(vector) if norm == 0: while norm == 0: vector = np.array(1-2*np.random.random(3), dtype=FLOAT_TYPE) norm = np.linalg.norm(vector) # normalize vector vector /= FLOAT_TYPE( norm ) # compute baseVector baseVector = FLOAT_TYPE(vector*self.__amplitude[0]) # amplify vector maxAmp = FLOAT_TYPE(self.__amplitude[1]-self.__amplitude[0]) vector *= FLOAT_TYPE(generate_random_float()*maxAmp) vector += baseVector # translate and return return coordinates+vector
def transform_coordinates(self, coordinates, argument=None): """ Translate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ if coordinates.shape[0] != 2: # atoms where removed, fall back to random translation return coordinates + generate_random_vector( minAmp=self.__amplitude[0], maxAmp=self.__amplitude[1]) else: # get normalized direction vector vector = FLOAT_TYPE(coordinates[0, :] - coordinates[1, :]) vector /= FLOAT_TYPE(np.linalg.norm(vector)) # create amplitudes if self.__symmetric: amp0 = amp1 = FLOAT_TYPE(generate_random_float() * self.__amplitude) else: amp0 = FLOAT_TYPE(generate_random_float() * self.__amplitude) amp1 = FLOAT_TYPE(generate_random_float() * self.__amplitude) # create shrink flag if self.__shrink is None: shrink = (1 - 2 * generate_random_float()) > 0 else: shrink = self.__shrink # create directions if shrink: dir0 = FLOAT_TYPE(-1) dir1 = FLOAT_TYPE(1) else: dir0 = FLOAT_TYPE(1) dir1 = FLOAT_TYPE(-1) # create translation vectors translationVectors = np.empty((2, 3), dtype=FLOAT_TYPE) translationVectors[0, :] = self.__agitate[0] * dir0 * amp0 * vector translationVectors[1, :] = self.__agitate[1] * dir1 * amp1 * vector # translate and return return coordinates + translationVectors
def select_index(self): """ Select index. :Returns: #. index (integer): the selected group index in engine groups list """ return INT_TYPE( np.searchsorted(self._selectionScheme, generate_random_float()))
def transform_coordinates(self, coordinates, argument=None): """ Translate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ # get normalized direction vector vector = FLOAT_TYPE( coordinates[0,:]-coordinates[1,:] ) vector /= FLOAT_TYPE( np.linalg.norm(vector) ) # create amplitudes if self.__symmetric: amp0 = amp1 = FLOAT_TYPE(generate_random_float()*self.__amplitude) else: amp0 = FLOAT_TYPE(generate_random_float()*self.__amplitude) amp1 = FLOAT_TYPE(generate_random_float()*self.__amplitude) # create shrink flag if self.__shrink is None: shrink = (1-2*generate_random_float())>0 else: shrink = self.__shrink # create directions if shrink: dir0 = FLOAT_TYPE(-1) dir1 = FLOAT_TYPE( 1) else: dir0 = FLOAT_TYPE( 1) dir1 = FLOAT_TYPE(-1) # create translation vectors translationVectors = np.empty((2,3), dtype=FLOAT_TYPE) translationVectors[0,:] = self.__agitate[0]*dir0*amp0*vector translationVectors[1,:] = self.__agitate[1]*dir1*amp1*vector # translate and return return coordinates+translationVectors
def transform_coordinates(self, coordinates, argument=None): """ Rotate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the rotation. #. argument (object): Not used here. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the rotation. """ if coordinates.shape[0] <= 1: # atoms where removed, fall back to random translation return coordinates + generate_random_vector( minAmp=self.__amplitude[0], maxAmp=self.__amplitude[1]) else: # create flip flag if self.__flip is None: flip = FLOAT_TYPE(np.sign(1 - 2 * generate_random_float())) elif self.__flip: flip = FLOAT_TYPE(-1) else: flip = FLOAT_TYPE(1) # get group axis groupAxis = self.__get_group_axis__(coordinates) # get align axis within offset angle orientationAxis = flip * self.__get_orientation_axis__() orientationAxis = generate_vectors_in_solid_angle( direction=orientationAxis, maxAngle=self.__maximumOffsetAngle, numberOfVectors=1)[0] # get coordinates center center = np.array(np.sum(coordinates, 0) / coordinates.shape[0], dtype=FLOAT_TYPE) # translate to origin rotatedCoordinates = coordinates - center # align coordinates rotatedCoordinates = orient(rotatedCoordinates, groupAxis, orientationAxis) # translate back to center and return rotated coordinates return np.array(rotatedCoordinates + center, dtype=FLOAT_TYPE)
def transform_coordinates(self, coordinates, argument=None): # generate random vector and ensure it is not zero vector = np.array(1 - 2 * np.random.random(3), dtype=FLOAT_TYPE) vector[2] = 0 norm = np.linalg.norm(vector) if norm == 0: while norm == 0: vector = np.array(1 - 2 * np.random.random(3), dtype=FLOAT_TYPE) vector[2] = 0 norm = np.linalg.norm(vector) # normalize vector vector /= FLOAT_TYPE(norm) # compute baseVector baseVector = FLOAT_TYPE(vector * self.amplitude[0]) # amplify vector maxAmp = FLOAT_TYPE(self.amplitude[1] - self.amplitude[0]) vector *= FLOAT_TYPE(generate_random_float() * maxAmp) vector += baseVector # translate and return return coordinates + vector
def transform_coordinates(self, coordinates, argument=None): """ Rotate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the rotation. #. argument (object): Any python object. Not used in this generator. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the rotation. """ if coordinates.shape[0] <= 1: # atoms where removed, fall back to random translation return coordinates + generate_random_vector( minAmp=self.__amplitude[0], maxAmp=self.__amplitude[1]) else: # get rotation axis n = 0 while n < PRECISION: rotationAxis = 1 - 2 * np.random.random(3) n = np.linalg.norm(rotationAxis) rotationAxis /= n # get rotation angle rotationAngle = (1 - 2 * generate_random_float()) * self.amplitude # get rotation matrix rotationMatrix = get_rotation_matrix(rotationAxis, rotationAngle) # get atoms group center center = np.sum(coordinates, 0) / coordinates.shape[0] # translate to origin rotatedCoordinates = coordinates - center # rotate for idx in range(rotatedCoordinates.shape[0]): rotatedCoordinates[idx, :] = np.dot(rotationMatrix, rotatedCoordinates[idx, :]) # translate back to center and return rotated coordinates return np.array(rotatedCoordinates + center, dtype=FLOAT_TYPE)
def move(self, coordinates): """ Moves coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the transformation :Returns: #. coordinates (np.ndarray): The new coordinates after applying the transformation """ if self.__randomize: index = INT_TYPE( np.searchsorted(self.__selectionScheme, generate_random_float()) ) moveGenerator = self.__collection[ index ] else: moveGenerator = self.__collection[self.__step] self.__step = (self.__step+1)%len(self.__collection) # perform the move return moveGenerator.move(coordinates)
def transform_coordinates(self, coordinates, argument=None): """ Rotate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the rotation #. argument (object): Any python object. Not used in this generator. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the rotation. """ # create flip flag if self.__flip is None: flip = FLOAT_TYPE( np.sign(1-2*generate_random_float()) ) elif self.__flip: flip = FLOAT_TYPE(-1) else: flip = FLOAT_TYPE(1) # get group axis groupAxis = self.__get_group_axis__(coordinates) # get align axis within offset angle orientationAxis = flip*self.__get_orientation_axis__() orientationAxis = generate_vectors_in_solid_angle(direction=orientationAxis, maxAngle=self.__maximumOffsetAngle, numberOfVectors=1)[0] # get coordinates center center = np.array(np.sum(coordinates, 0)/coordinates.shape[0] , dtype=FLOAT_TYPE) # translate to origin rotatedCoordinates = coordinates-center # align coordinates rotatedCoordinates = orient(rotatedCoordinates, groupAxis, orientationAxis) # translate back to center and return rotated coordinates return np.array(rotatedCoordinates+center, dtype=FLOAT_TYPE)
def transform_coordinates(self, coordinates, argument=None): """ Translate coordinates. :Parameters: #. coordinates (np.ndarray): The coordinates on which to apply the translation. :Returns: #. coordinates (np.ndarray): The new coordinates after applying the translation. #. argument (object): Any python object. Not used in this generator. """ if coordinates.shape[0] != 3: # atoms where removed, fall back to random translation return coordinates + generate_random_vector( minAmp=self.__amplitude[0], maxAmp=self.__amplitude[1]) else: # get atoms group center center = np.sum(coordinates, 0) / coordinates.shape[0] # translate to origin rotatedCoordinates = coordinates - center # get normalized direction vectors leftVector = FLOAT_TYPE(rotatedCoordinates[1, :] - rotatedCoordinates[0, :]) leftVector /= FLOAT_TYPE(np.linalg.norm(leftVector)) rightVector = FLOAT_TYPE(rotatedCoordinates[2, :] - rotatedCoordinates[0, :]) rightVector /= FLOAT_TYPE(np.linalg.norm(rightVector)) # get rotation axis rotationAxis = np.cross(leftVector, rightVector) if rotationAxis[0] == rotationAxis[1] == rotationAxis[2] == 0.: rotationAxis = np.array(1 - 2 * np.random.random(3), dtype=FLOAT_TYPE) rotationAxis /= FLOAT_TYPE(np.linalg.norm(rotationAxis)) # create shrink flag if self.__shrink is None: shrink = (1 - 2 * generate_random_float()) > 0 else: shrink = self.__shrink # get rotation angles if self.__symmetric: angleLeft = angleRight = FLOAT_TYPE(generate_random_float() * self.__amplitude) else: angleLeft = FLOAT_TYPE(generate_random_float() * self.__amplitude) angleRight = FLOAT_TYPE(generate_random_float() * self.__amplitude) # create directions if shrink: angleLeft *= FLOAT_TYPE(-1) angleRight *= FLOAT_TYPE(1) else: angleLeft *= FLOAT_TYPE(1) angleRight *= FLOAT_TYPE(-1) # rotate if self.__agitate[0]: rotationMatrix = get_rotation_matrix(rotationAxis, angleLeft) rotatedCoordinates[1, :] = np.dot(rotationMatrix, rotatedCoordinates[1, :]) if self.__agitate[1]: rotationMatrix = get_rotation_matrix(rotationAxis, angleRight) rotatedCoordinates[2, :] = np.dot(rotationMatrix, rotatedCoordinates[2, :]) # translate back from center and return return np.array(rotatedCoordinates + center, dtype=FLOAT_TYPE)
def run(self, numberOfSteps=100000, saveFrequency=1000, savePath="restart", xyzFrequency=None, xyzPath="trajectory.xyz"): """ This is an exact copy of engine run method with slight changes marked with #--> to make two trajectories, one of the real system and another the explored space. new code is marked with #<-- all leading variables double scores __ removed. """ # get arguments #-->_numberOfSteps = self.__runtime_get_number_of_steps(numberOfSteps) #-->_saveFrequency, _savePath = self.__runtime_get_save_engine(saveFrequency, savePath) #-->_xyzFrequency, _xyzPath = self.__runtime_get_save_xyz(xyzFrequency, xyzPath) _numberOfSteps = numberOfSteps #<-- _saveFrequency = 2 * numberOfSteps #<-- _savePath = savePath #<-- # create xyz file #-->if _xyzFrequency is not None: #--> _xyzfd = open(_xyzPath, 'a') _xyzfd = open("trajectory.xyz", 'a') #<-- # get and initialize used constraints _usedConstraints, _constraints, _rigidConstraints = self.initialize_used_constraints( ) if not len(_usedConstraints): LOGGER.warn( "No constraints are used. Configuration will be randomize") # compute biasedStdErr self.biasedStdErr = self.compute_total_standard_error(_constraints, current=True) # initialize useful arguments _engineStartTime = time.time() _lastSavedChiSquare = self.biasedStdErr _coordsBeforeMove = None _moveTried = False # initialize group selector self.groupSelector._runtime_initialize() self.__realCoords = self.realCoordinates #<-- self.__boxCoords = self.boxCoordinates #<-- # ##################################################################################### # # #################################### RUN ENGINE ##################################### # LOGGER.info("Engine started %i steps, biasedStdErr is: %.6f" % (_numberOfSteps, self.biasedStdErr)) self.__generated = 0 #<-- self.__tried = 0 #<-- self.__accepted = 0 #<-- for step in xrange(_numberOfSteps): # increment generated self.__generated += 1 # get group self.__lastSelectedGroupIndex = self.groupSelector.select_index() group = self.groups[self.__lastSelectedGroupIndex] # get atoms indexes groupAtomsIndexes = group.indexes # get move generator groupMoveGenerator = group.moveGenerator # get group atoms coordinates before applying move if _coordsBeforeMove is None or not self.groupSelector.isRecurring: _coordsBeforeMove = np.array( self.realCoordinates[groupAtomsIndexes], dtype=self.realCoordinates.dtype) elif self.groupSelector.explore: if _moveTried: _coordsBeforeMove = movedRealCoordinates elif not self.groupSelector.refine: _coordsBeforeMove = np.array( self.realCoordinates[groupAtomsIndexes], dtype=self.realCoordinates.dtype) # compute moved coordinates movedRealCoordinates = groupMoveGenerator.move(_coordsBeforeMove) movedBoxCoordinates = transform_coordinates( transMatrix=self.reciprocalBasisVectors, coords=movedRealCoordinates) ########################### compute enhanceOnlyConstraints ############################ rejectMove = False for c in _rigidConstraints: # compute before move c.compute_before_move(realIndexes=groupAtomsIndexes, relativeIndexes=groupAtomsIndexes) # compute after move c.compute_after_move(realIndexes=groupAtomsIndexes, relativeIndexes=groupAtomsIndexes, movedBoxCoordinates=movedBoxCoordinates) # get rejectMove rejectMove = c.should_step_get_rejected( c.afterMoveStandardError) if rejectMove: break _moveTried = not rejectMove ############################## reject move before trying ############################## if rejectMove: # enhanceOnlyConstraints reject move for c in _rigidConstraints: c.reject_move(realIndexes=groupAtomsIndexes, relativeIndexes=groupAtomsIndexes) # log generated move rejected before getting tried LOGGER.log("move not tried", "Generated move %i is not tried" % self.tried) ###################################### try move ####################################### else: self.__tried += 1 for c in _constraints: # compute before move c.compute_before_move(realIndexes=groupAtomsIndexes, relativeIndexes=groupAtomsIndexes) # compute after move c.compute_after_move( realIndexes=groupAtomsIndexes, relativeIndexes=groupAtomsIndexes, movedBoxCoordinates=movedBoxCoordinates) ################################ compute new biasedStdErr ################################ newStdErr = self.compute_total_standard_error(_constraints, current=False) #if len(_constraints) and (newStdErr >= self.biasedStdErr): if newStdErr > self.biasedStdErr: if generate_random_float() > self.tolerance: rejectMove = True else: self.tolerated += 1 self.biasedStdErr = newStdErr else: self.biasedStdErr = newStdErr ################################## reject tried move ################################## if rejectMove: # set selector move rejected self.groupSelector.move_rejected(self.__lastSelectedGroupIndex) if _moveTried: # constraints reject move for c in _constraints: c.reject_move(realIndexes=groupAtomsIndexes, relativeIndexes=groupAtomsIndexes) # log tried move rejected LOGGER.log("move rejected", "Tried move %i is rejected" % self.__generated) ##################################### accept move ##################################### else: self.__accepted += 1 # set selector move accepted self.groupSelector.move_accepted(self.__lastSelectedGroupIndex) # constraints reject move for c in _usedConstraints: c.accept_move(realIndexes=groupAtomsIndexes, relativeIndexes=groupAtomsIndexes) # set new coordinates self.__realCoords[groupAtomsIndexes] = movedRealCoordinates self.__boxCoords[groupAtomsIndexes] = movedBoxCoordinates # log new successful move triedRatio = 100. * (float(self.__tried) / float(self.__generated)) acceptedRatio = 100. * (float(self.__accepted) / float(self.__generated)) LOGGER.log( "move accepted", "Generated:%i - Tried:%i(%.3f%%) - Accepted:%i(%.3f%%) - biasedStdErr:%.6f" % (self.__generated, self.__tried, triedRatio, self.__accepted, acceptedRatio, self.biasedStdErr)) ##################################### save engine ##################################### if _saveFrequency is not None: if not (step + 1) % _saveFrequency: if _lastSavedChiSquare == self.biasedStdErr: LOGGER.info( "Save engine omitted because no improvement made since last save." ) else: # update state self.state = time.time() for c in _usedConstraints: #c.increment_tried() c.set_state(self.state) # save engine _lastSavedChiSquare = self.biasedStdErr self.save(_savePath) ############################### dump coords to xyz file ############################### #-->if _xyzFrequency is not None: #--> if not(step+1)%_xyzFrequency: #--> _xyzfd.write("%s\n"%self.__pdb.numberOfAtoms) #--> triedRatio = 100.*(float(self.__tried)/float(self.__generated)) #--> acceptedRatio = 100.*(float(self.__accepted)/float(self.__generated)) #--> _xyzfd.write("Generated:%i - Tried:%i(%.3f%%) - Accepted:%i(%.3f%%) - biasedStdErr:%.6f\n" %(self.__generated , self.__tried, triedRatio, self.__accepted, acceptedRatio, self.biasedStdErr)) #--> frame = [self.allNames[idx]+ " " + "%10.5f"%self.__realCoords[idx][0] + " %10.5f"%self.__realCoords[idx][1] + " %10.5f"%self.__realCoords[idx][2] + "\n" for idx in self.__pdb.xindexes] #--> _xyzfd.write("".join(frame)) triedRatio = 100. * (float(self.__tried) / float(self.__generated) ) #<-- acceptedRatio = 100. * ( float(self.__accepted) / float(self.__generated)) #<-- _xyzfd.write("%s\n" % (len(groupAtomsIndexes) * 2)) #<-- _xyzfd.write( "Generated:%i - Tried:%i(%.3f%%) - Accepted:%i(%.3f%%) - biasedStdErr:%.6f\n" % (self.__generated, self.__tried, triedRatio, self.__accepted, acceptedRatio, self.biasedStdErr)) #<-- frame = [ self.allNames[idx] + " " + "%10.5f" % self.realCoordinates[idx][0] + " %10.5f" % self.realCoordinates[idx][1] + " %10.5f" % self.realCoordinates[idx][2] + "\n" for idx in groupAtomsIndexes ] #<-- frame.extend([ self.allNames[idx] + " " + "%10.5f" % _coordsBeforeMove[idx][0] + " %10.5f" % _coordsBeforeMove[idx][1] + " %10.5f" % _coordsBeforeMove[idx][2] + "\n" for idx in range(_coordsBeforeMove.shape[0]) ]) #<-- _xyzfd.write("".join(frame)) #<-- # ##################################################################################### # # ################################# FINISH ENGINE RUN ################################# # #-->LOGGER.info("Engine finishes executing all '%i' steps in %s" % (_numberOfSteps, get_elapsed_time(_engineStartTime, format="%d(days) %d:%d:%d"))) # close .xyz file #-->if _xyzFrequency is not None: #--> _xyzfd.close() _xyzfd.close() #<--