Author: bugman Date: Fri Dec 19 11:23:46 2014 New Revision: 27144 URL: http://svn.gna.org/viewcvs/relax?rev=27144&view=rev Log: Implemented angular fluctuations for the structure.atomic_fluctuations user function. This adds the measure argument to the user function to allow either the default of 'distance' or the 'angle' setting to be chosen. The implementation is confirmed by the Structure.test_atomic_fluctuations_angle system test which now passes. Modified: trunk/pipe_control/structure/main.py trunk/test_suite/system_tests/structure.py trunk/user_functions/structure.py Modified: trunk/pipe_control/structure/main.py URL: http://svn.gna.org/viewcvs/relax/trunk/pipe_control/structure/main.py?rev=27144&r1=27143&r2=27144&view=diff ============================================================================== --- trunk/pipe_control/structure/main.py (original) +++ trunk/pipe_control/structure/main.py Fri Dec 19 11:23:46 2014 @@ -21,7 +21,7 @@ # Python module imports. from minfx.generic import generic_minimise -from numpy import array, float64, std, zeros +from numpy import array, average, float64, std, zeros from numpy.linalg import norm from os import F_OK, access, getcwd from re import search @@ -31,6 +31,7 @@ # relax module imports. from lib.check_types import is_float from lib.errors import RelaxError, RelaxFileError +from lib.geometry.vectors import vector_angle_atan2 from lib.io import get_file_path, open_write_file, write_data from lib.plotting.api import correlation_matrix from lib.selection import tokenise @@ -227,7 +228,7 @@ return assemble_coord_array(objects=objects, object_names=object_names, molecules=molecules, models=models, atom_id=atom_id, seq_info_flag=seq_info_flag) -def atomic_fluctuations(pipes=None, models=None, molecules=None, atom_id=None, file=None, format='text', dir=None, force=False): +def atomic_fluctuations(pipes=None, models=None, molecules=None, atom_id=None, measure='distance', file=None, format='text', dir=None, force=False): """Write out a correlation matrix of pairwise interatomic distance fluctuations between different structures. @keyword pipes: The data pipes to generate the interatomic distance fluctuation correlation matrix for. @@ -238,6 +239,8 @@ @type molecules: None or list of lists of str @keyword atom_id: The atom identification string of the coordinates of interest. This matches the spin ID string format. @type atom_id: str or None + @keyword measure: The type of fluctuation to measure. This can be either 'distance' or 'angle'. + @type measure: str @keyword file: The name of the file to write. @type file: str @keyword format: The output format. This can be set to "text" for text file output, or "gnuplot" for creating a gnuplot script. @@ -251,6 +254,9 @@ # Checks. check_pipe() check_structure() + allowed_measures = ['distance', 'angle'] + if measure not in allowed_measures: + raise RelaxError("The measure '%s' must be one of %s." % (measure, allowed_measures)) # Assemble the atomic coordinates. coord, ids, mol_names, res_names, res_nums, atom_names, elements = assemble_coordinates(pipes=pipes, molecules=molecules, models=models, atom_id=atom_id, seq_info_flag=True) @@ -267,17 +273,41 @@ for i in range(n): labels.append(generate_spin_id_unique(mol_name=mol_names[i], res_num=res_nums[i], res_name=res_names[i], spin_name=atom_names[i])) - # Generate the pairwise matrix. + # Initialise the SD matrix and other structures. matrix = zeros((n, n), float64) - for i in range(n): - for j in range(n): - # The interatomic distances between each structure. - dist = [] - for k in range(len(coord)): - dist.append(norm(coord[k, i] - coord[k, j])) - - # Calculate and store the corrected sample standard deviation. - matrix[i, j] = std(array(dist, float64), ddof=1) + vectors = zeros((len(coord), 3), float64) + angles = zeros(len(coord), float64) + + # Generate the pairwise distance SD matrix. + if measure == 'distance': + for i in range(n): + for j in range(n): + # The interatomic distances between each structure. + dist = [] + for k in range(len(coord)): + dist.append(norm(coord[k, i] - coord[k, j])) + + # Calculate and store the corrected sample standard deviation. + matrix[i, j] = std(array(dist, float64), ddof=1) + + # Generate the pairwise angle SD matrix. + elif measure == 'angle': + # Loop over the atom pairs. + for i in range(n): + for j in range(n): + # The interatomic vectors. + for k in range(len(coord)): + vectors[k] = coord[k, i] - coord[k, j] + + # The average vector. + ave_vect = average(vectors, axis=0) + + # The intervector angles. + for k in range(len(coord)): + angles[k] = vector_angle_atan2(ave_vect, vectors[k]) + + # Calculate and store the corrected sample standard deviation. + matrix[i, j] = std(angles, ddof=1) # Call the plotting API. correlation_matrix(format=format, matrix=matrix, labels=labels, file=file, dir=dir, force=force) Modified: trunk/test_suite/system_tests/structure.py URL: http://svn.gna.org/viewcvs/relax/trunk/test_suite/system_tests/structure.py?rev=27144&r1=27143&r2=27144&view=diff ============================================================================== --- trunk/test_suite/system_tests/structure.py (original) +++ trunk/test_suite/system_tests/structure.py Fri Dec 19 11:23:46 2014 @@ -353,7 +353,7 @@ # Run the structure.atomic_fluctuations user function and collect the results in a dummy file object. file = DummyFileObject() - self.interpreter.structure.atomic_fluctuations(measure='angles', atom_id='@N,CA', file=file, format='text') + self.interpreter.structure.atomic_fluctuations(measure='angle', atom_id='@N,CA', file=file, format='text') # The atom positions. n = array([[ 9.464, -9.232, 27.573], [ 9.211, -9.425, 26.970], [ 7.761, -6.392, 27.161]], float64) Modified: trunk/user_functions/structure.py URL: http://svn.gna.org/viewcvs/relax/trunk/user_functions/structure.py?rev=27144&r1=27143&r2=27144&view=diff ============================================================================== --- trunk/user_functions/structure.py (original) +++ trunk/user_functions/structure.py Fri Dec 19 11:23:46 2014 @@ -294,6 +294,16 @@ can_be_none = True ) uf.add_keyarg( + name = "measure", + py_type = "str", + default = "distance", + desc_short = "measure", + desc = "The type of fluctuation to investigate. This allows for both interatomic distance and vector angle fluctuations to be calculated.", + wiz_element_type = "combo", + wiz_combo_choices = ["Interatomic distance fluctuations", "Interatomic vector angle fluctuations"], + wiz_combo_data = ["distance", "angle"] +) +uf.add_keyarg( name = "file", py_type = "str_or_inst", arg_type = "file sel", @@ -328,7 +338,9 @@ ) # Description. uf.desc.append(Desc_container()) -uf.desc[-1].add_paragraph("This is used to visualise the interatomic distance fluctuations between different structures. The corrected sample standard deviation (SD) is calculated for the distances between all atom pairs, resulting in a pairwise matrix of SD values. The matrix will be output into a text file.") +uf.desc[-1].add_paragraph("This is used to visualise the interatomic fluctuations between different structures. By setting the measure argument, this can be set to either the fluctuations of the interatomic distances or the fluctuations of the interatomic vector angles:") +uf.desc[-1].add_item_list_element("'distance'", "This is the default. The corrected sample standard deviation (SD) is calculated for the distances between all atom pairs, resulting in a pairwise matrix of SD values.") +uf.desc[-1].add_item_list_element("'angle'", "The corrected sample standard deviation (SD) is calculated for the angles between the inter atom vectors all atom pairs to an average vector. This also produces a pairwise matrix of SD values.") uf.desc[-1].add_paragraph("In addition to creating the text file, a second file will be created if the format argument is set to anything other than the text file. It will have the same name as the text file, however the file extension will be changed to match the format. The currently supported formats are:") uf.desc[-1].add_item_list_element("'text'", "This is the default value and will result in a single text file being created.") uf.desc[-1].add_item_list_element("'gnuplot'", "This will create a script for visualising the correlation matrix using gnuplot.")