Beispiel #1
0
 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
Beispiel #2
0
 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
Beispiel #3
0
 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
Beispiel #4
0
 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
Beispiel #5
0
 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
Beispiel #6
0
 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)
     
     
     
     
Beispiel #7
0
 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
Beispiel #8
0
 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
Beispiel #9
0
 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) 
Beispiel #10
0
    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)
Beispiel #11
0
    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)
Beispiel #12
0
 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)
Beispiel #13
0
 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
Beispiel #14
0
    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
Beispiel #15
0
 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()))
Beispiel #16
0
 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
Beispiel #17
0
    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)
Beispiel #18
0
 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
Beispiel #19
0
    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)
Beispiel #20
0
 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) 
     
             
     
     
Beispiel #21
0
 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)
     
     
     
Beispiel #22
0
 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)
Beispiel #23
0
    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()  #<--