def oneVsFollowing(self, conformation_number): """ Calculates the RMSD between a reference conformation and all other conformations with an id greater than it. If fitting symmetry groups are used, input coordinates won't be modified (as it works with coordinate copies). @param conformation_number: The id of the reference structure. @return: A numpy array of RMSD values. @author: vgil @date: 26/11/2012 """ np_coords_fit, np_coords_calc = self.__coords_reshaping() if self.fit_symmetry_groups == []: rmsds = pyRMSD.calculators.oneVsFollowing( availableCalculators()[self.calculator_type], np_coords_fit, self.number_of_fitting_atoms, np_coords_calc, self.number_of_calculation_atoms, conformation_number, self.number_of_conformations, self.calc_symmetry_groups, self.__number_of_threads, self.__threads_per_block, self.__blocks_per_grid) else: # If we have fitting symmetry groups, we have to try with all possible combinations. # Calculation symmetry groups are applied at C level, changing the way RMSD is calculated. symm_rmsds = [] for permutation in symm_permutations(self.fit_symmetry_groups): # Copy the coordinates and convert to matrix form for ease of indexing coords_copy = numpy.array(np_coords_fit, copy=True, dtype=numpy.float64) coords_copy.shape = (self.number_of_conformations, self.number_of_fitting_atoms, 3) # Apply the changes to reference for symm_group in permutation: # Do it only if the symm. group is not permuted. Otherwise we would always permute! if not symm_group in self.fit_symmetry_groups: for symm_pair in symm_group: swap_atoms(coords_copy[conformation_number], symm_pair[0], symm_pair[1]) # Flatten again to feed the C calculator coords_copy.shape = (self.number_of_conformations * self.number_of_fitting_atoms * 3) # And calculate the RMSD of this permutation symm_rmsds.append( pyRMSD.calculators.oneVsFollowing( availableCalculators()[self.calculator_type], coords_copy, self.number_of_fitting_atoms, np_coords_calc, self.number_of_calculation_atoms, conformation_number, self.number_of_conformations, self.calc_symmetry_groups, self.__number_of_threads, self.__threads_per_block, self.__blocks_per_grid)) # Pick the minimum rmsd of all possibilities. rmsds = min_rmsd_of_rmsds_list(numpy.array(symm_rmsds)) return rmsds
def oneVsFollowing(self, conformation_number): """ Calculates the RMSD between a reference conformation and all other conformations with an id greater than it. If fitting symmetry groups are used, input coordinates won't be modified (as it works with coordinate copies). @param conformation_number: The id of the reference structure. @return: A numpy array of RMSD values. @author: vgil @date: 26/11/2012 """ np_coords_fit, np_coords_calc = self.__coords_reshaping() if self.fit_symmetry_groups == []: rmsds = pyRMSD.calculators.oneVsFollowing( availableCalculators()[self.calculator_type], np_coords_fit, self.number_of_fitting_atoms, np_coords_calc, self.number_of_calculation_atoms, conformation_number, self.number_of_conformations, self.calc_symmetry_groups, self.__number_of_threads, self.__threads_per_block, self.__blocks_per_grid, ) else: # If we have fitting symmetry groups, we have to try with all possible combinations. # Calculation symmetry groups are applied at C level, changing the way RMSD is calculated. symm_rmsds = [] for permutation in symm_permutations(self.fit_symmetry_groups): # Copy the coordinates and convert to matrix form for ease of indexing coords_copy = numpy.array(np_coords_fit, copy=True, dtype=numpy.float64) coords_copy.shape = (self.number_of_conformations, self.number_of_fitting_atoms, 3) # Apply the changes to reference for symm_group in permutation: # Do it only if the symm. group is not permuted. Otherwise we would always permute! if not symm_group in self.fit_symmetry_groups: for symm_pair in symm_group: swap_atoms(coords_copy[conformation_number], symm_pair[0], symm_pair[1]) # Flatten again to feed the C calculator coords_copy.shape = self.number_of_conformations * self.number_of_fitting_atoms * 3 # And calculate the RMSD of this permutation symm_rmsds.append( pyRMSD.calculators.oneVsFollowing( availableCalculators()[self.calculator_type], coords_copy, self.number_of_fitting_atoms, np_coords_calc, self.number_of_calculation_atoms, conformation_number, self.number_of_conformations, self.calc_symmetry_groups, self.__number_of_threads, self.__threads_per_block, self.__blocks_per_grid, ) ) # Pick the minimum rmsd of all possibilities. rmsds = min_rmsd_of_rmsds_list(numpy.array(symm_rmsds)) return rmsds
def test_swap_atoms(self): coordsets = numpy.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) swap_atoms(coordsets, 0, 2) numpy.testing.assert_array_equal([[7, 8, 9],[4, 5, 6],[1, 2, 3],[10, 11, 12]], coordsets)