Author: bugman Date: Wed Jul 25 11:02:25 2012 New Revision: 17310 URL: http://svn.gna.org/viewcvs/relax?rev=17310&view=rev Log: Redesigned the align_tensor.init user function. This is to better handle multiple tensors per alignment (and/or per domain). The tensor ID is now optional and the alignment ID must be supplied. The order of the arguments has also changed so all the IDs (tensor, alignment, and domain) are at the start. The function generic_fns.align_tensor.get_tensor_object_from_align() has been added to handle the retrieval of alignment tensors without a tensor ID or name. Modified: branches/frame_order_testing/generic_fns/align_tensor.py branches/frame_order_testing/user_functions/align_tensor.py Modified: branches/frame_order_testing/generic_fns/align_tensor.py URL: http://svn.gna.org/viewcvs/relax/branches/frame_order_testing/generic_fns/align_tensor.py?rev=17310&r1=17309&r2=17310&view=diff ============================================================================== --- branches/frame_order_testing/generic_fns/align_tensor.py (original) +++ branches/frame_order_testing/generic_fns/align_tensor.py Wed Jul 25 11:02:25 2012 @@ -647,7 +647,7 @@ def get_tensor_object(tensor, pipe=None): - """Function for returning the AlignTensorData instance corresponding to the 'tensor' argument. + """Return the AlignTensorData instance corresponding to the tensor ID. @param tensor: The alignment tensor identification string. @type tensor: str @@ -673,11 +673,43 @@ return data -def init(tensor=None, params=None, scale=1.0, angle_units='deg', param_types=0, align_id=None, domain=None, errors=False): +def get_tensor_object_from_align(align_id, pipe=None): + """Return the unique AlignTensorData instance corresponding to the alignment ID. + + @param align_id: The alignment ID for the unique tensor. + @type align_id: str + @return: The alignment tensor object corresponding to the 'tensor' arg. + @rtype: AlignTensorData instance + """ + + # The data pipe to check. + if pipe == None: + pipe = pipes.cdp_name() + + # Init. + data = None + + # Loop over the tensors. + count = 0 + for i in xrange(len(cdp.align_tensors)): + if cdp.align_tensors[i].align_id == align_id: + data = cdp.align_tensors[i] + count += 1 + + # Multiple matches. + if count > 1: + raise RelaxError("Multiple alignment tensors match the alignment ID '%s'." % align_id) + # Return the object. + return data + + +def init(tensor=None, align_id=None, params=None, scale=1.0, angle_units='deg', param_types=0, domain=None, errors=False): """Function for initialising the alignment tensor. @keyword tensor: The alignment tensor identification string. @type tensor: str + @keyword align_id: The alignment ID string that the tensor corresponds to. + @type align_id: str or None @keyword params: The alignment tensor parameters. @type params: float @keyword scale: The alignment tensor eigenvalue scaling value. @@ -686,8 +718,6 @@ @type angle_units: str @keyword param_types: The type of parameters supplied. The flag values correspond to, 0: {Axx, Ayy, Axy, Axz, Ayz}, and 1: {Azz, Axx-yy, Axy, Axz, Ayz}. @type param_types: int - @keyword align_id: The alignment ID string that the tensor corresponds to. - @type align_id: str or None @keyword domain: The domain label. @type domain: str or None @keyword errors: A flag which determines if the alignment tensor data or its errors are being input. @@ -697,25 +727,28 @@ # Test if the current data pipe exists. pipes.test() - # Test if alignment tensor data already exists. - if errors and not align_data_exists(tensor): - raise RelaxNoTensorError('alignment') + # Parameter checks. + if align_id == None: + raise RelaxError("The alignment ID must be given.") # Check the validity of the angle_units argument. valid_types = ['deg', 'rad'] if not angle_units in valid_types: raise RelaxError("The alignment tensor 'angle_units' argument " + repr(angle_units) + " should be either 'deg' or 'rad'.") + # Test if alignment tensor data already exists. + if errors and not align_data_exists(align_id): + raise RelaxNoTensorError('alignment') + # Check that the domain is defined. if domain and (not hasattr(cdp, 'domain') or domain not in cdp.domain.keys()): raise RelaxError("The domain '%s' has not been defined. Please use the domain user function." % domain) # Add the align ID to the current data pipe if needed. - if align_id: - if not hasattr(cdp, 'align_ids'): - cdp.align_ids = [] - if align_id not in cdp.align_ids: - cdp.align_ids.append(align_id) + if not hasattr(cdp, 'align_ids'): + cdp.align_ids = [] + if align_id not in cdp.align_ids: + cdp.align_ids.append(align_id) # Add the align_tensors object to the data pipe. if not errors: @@ -724,11 +757,14 @@ cdp.align_tensors = AlignTensorList() # Add the tensor, if it doesn't already exist. - if tensor not in cdp.align_tensors.names(): + if tensor == None or tensor not in cdp.align_tensors.names(): cdp.align_tensors.add_item(tensor) # Get the tensor. - tensor_obj = get_tensor_object(tensor) + if tensor: + tensor_obj = get_tensor_object(tensor) + else: + tensor_obj = get_tensor_object_from_align(align_id) # {Sxx, Syy, Sxy, Sxz, Syz}. if param_types == 0: Modified: branches/frame_order_testing/user_functions/align_tensor.py URL: http://svn.gna.org/viewcvs/relax/branches/frame_order_testing/user_functions/align_tensor.py?rev=17310&r1=17309&r2=17310&view=diff ============================================================================== --- branches/frame_order_testing/user_functions/align_tensor.py (original) +++ branches/frame_order_testing/user_functions/align_tensor.py Wed Jul 25 11:02:25 2012 @@ -188,7 +188,21 @@ name = "tensor", py_type = "str", desc_short = "tensor ID", - desc = "The alignment tensor identification string." + desc = "The optional alignment tensor ID string, required if multiple tensors exist per alignment.", + can_be_none = True +) +uf.add_keyarg( + name = "align_id", + py_type = "str", + desc_short = "alignment ID", + desc = "The alignment ID string that the tensor corresponds to." +) +uf.add_keyarg( + name = "domain", + py_type = "str", + desc_short = "domain ID", + desc = "The optional domain ID string that the tensor corresponds to.", + can_be_none = True ) uf.add_keyarg( name = "params", @@ -242,20 +256,6 @@ wiz_read_only = True ) uf.add_keyarg( - name = "align_id", - py_type = "str", - desc_short = "alignment ID string", - desc = "The optional alignment ID string that the tensor corresponds to.", - can_be_none = True -) -uf.add_keyarg( - name = "domain", - py_type = "str", - desc_short = "domain ID string", - desc = "The optional domain ID string that the tensor corresponds to.", - can_be_none = True -) -uf.add_keyarg( name = "errors", default = False, py_type = "bool", @@ -263,7 +263,8 @@ desc = "A flag which determines if the alignment tensor data or its errors are being input." ) uf.desc.append(Desc_container()) -uf.desc[-1].add_paragraph("Using this function, the alignment tensor data can be set up. The alignment tensor parameters should be a tuple of floating point numbers (a list surrounded by round brakets). These correspond to the parameters of the tensor which can be specified by the parameter types whereby the values correspond to:") +uf.desc[-1].add_paragraph("The tensor ID is only required if there are multiple unique tensors per alignment. An example is if internal domain motions cause multiple parts of the molecule to align differently. The tensor ID is optional and in the case of only a single tensor per alignment, the tensor can be identified using the alignment ID instead.") +uf.desc[-1].add_paragraph("The alignment tensor parameters should be a tuple of floating point numbers (a list surrounded by round brakets). These correspond to the parameters of the tensor which can be specified by the parameter types whereby the values correspond to:") uf.desc[-1].add_item_list_element("0", "{Sxx, Syy, Sxy, Sxz, Syz} (unitless),") uf.desc[-1].add_item_list_element("1", "{Szz, Sxx-yy, Sxy, Sxz, Syz} (Pales default format),") uf.desc[-1].add_item_list_element("2", "{Axx, Ayy, Axy, Axz, Ayz} (unitless),") @@ -279,12 +280,12 @@ uf.desc[-1].add_paragraph("where I is the identity matrix. For the alignment tensor to be supplied in Hertz, the bond vectors must all be of equal length.") # Prompt examples. uf.desc.append(Desc_container("Prompt examples")) -uf.desc[-1].add_paragraph("To set a rhombic tensor to the run 'CaM', type one of:") -uf.desc[-1].add_prompt("relax> align_tensor.init('super media', (-8.6322e-05, -5.5786e-04, -3.1732e-05, 2.2927e-05, 2.8599e-04), param_types=1)") -uf.desc[-1].add_prompt("relax> align_tensor.init(tensor='super media', params=(-8.6322e-05, -5.5786e-04, -3.1732e-05, 2.2927e-05, 2.8599e-04), param_types=1)") +uf.desc[-1].add_paragraph("To set a rhombic tensor for the domain labelled 'domain 1' with the alignment named 'super media', type one of:") +uf.desc[-1].add_prompt("relax> align_tensor.init('domain 1', 'super media', (-8.6322e-05, -5.5786e-04, -3.1732e-05, 2.2927e-05, 2.8599e-04), param_types=1)") +uf.desc[-1].add_prompt("relax> align_tensor.init(tensor='domain 1', align_id='super media', params=(-8.6322e-05, -5.5786e-04, -3.1732e-05, 2.2927e-05, 2.8599e-04), param_types=1)") uf.backend = align_tensor.init uf.menu_text = "&init" -uf.wizard_height_desc = 420 +uf.wizard_height_desc = 370 uf.wizard_size = (1000, 750) uf.gui_icon = "relax.align_tensor" uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'