def check_type(pipe_type): """Check the validity of the given data pipe type. @keyword pipe_type: The data pipe type to check. @type pipe_type: str @raises RelaxError: If the data pipe type is invalid or the required Python modules are missing. """ # Test if pipe_type is valid. if not pipe_type in VALID_TYPES: raise RelaxError( "The data pipe type " + repr(pipe_type) + " is invalid and must be one of the strings in the list " + repr(VALID_TYPES) + ".") # Test that the C modules have been loaded. if pipe_type == 'relax_fit' and not C_module_exp_fn: raise RelaxError( "Relaxation curve fitting is not available. Try compiling the C modules on your platform." ) # Test that the scipy is installed for the frame order analysis. if pipe_type == 'frame order' and not scipy_module: raise RelaxError( "The frame order analysis is not available. Please install the scipy Python package." )
def return_interatom(spin_hash1=None, spin_hash2=None, pipe=None): """Return the list of interatomic data containers for the two spins. @keyword spin_hash1: The unique spin hash for the first atom. @type spin_hash1: str @keyword spin_hash2: The unique spin hash for the second atom. @type spin_hash2: str @keyword pipe: The data pipe holding the container. Defaults to the current data pipe. @type pipe: str or None @return: The matching interatomic data container, if it exists. @rtype: data.interatomic.InteratomContainer instance or None """ # Checks. if spin_hash1 == None: raise RelaxError("The first spin hash must be supplied.") if spin_hash2 == None: raise RelaxError("The second spin hash must be supplied.") # The data pipe. if pipe == None: pipe = pipes.cdp_name() # Get the data pipe. dp = pipes.get_pipe(pipe) # Return the matching container. for i in range(len(dp.interatomic)): if spin_hash1 != spin_hash2 and spin_hash1 in [dp.interatomic[i]._spin_hash1, dp.interatomic[i]._spin_hash2] and spin_hash2 in [dp.interatomic[i]._spin_hash1, dp.interatomic[i]._spin_hash2]: return dp.interatomic[i] # No matchs. return None
def map(params=None, map_type='Iso3D', spin_id=None, inc=20, lower=None, upper=None, axis_incs=10, file_prefix="map", dir="dx", point=None, point_file="point", chi_surface=None, create_par_file=False): """Map the space corresponding to the spin identifier and create the OpenDX files. @keyword params: The list of model parameters to map. @type params: list of str @keyword map_type: The type of map to create. The available options are: - 'Iso3D', a 3D isosurface visualisation of the space. @type map_type: str @keyword spin_id: The spin identification string. @type spin_id: str @keyword inc: The resolution of the plot. This is the number of increments per dimension. @type inc: int @keyword lower: The lower bounds of the space to map. If supplied, this should be a list of floats, its length equal to the number of parameters in the model. @type lower: None or list of float @keyword upper: The upper bounds of the space to map. If supplied, this should be a list of floats, its length equal to the number of parameters in the model. @type upper: None or list of float @keyword axis_incs: The number of tick marks to display in the OpenDX plot in each dimension. @type axis_incs: int @keyword file_prefix: The file prefix for all the created files. @type file_prefix: str @keyword dir: The directory to place the files into. @type dir: str or None @keyword point: If supplied, a red sphere will be placed at these coordinates. @type point: None or list of float @keyword point_file: The file prefix for the point output files. @type point_file: str or None @keyword create_par_file: Whether to create a file with parameters and associated chi2 value. @type create_par_file: bool """ # Check the args. if inc <= 1: raise RelaxError("The increment value needs to be greater than 1.") if axis_incs <= 1: raise RelaxError( "The axis increment value needs to be greater than 1.") # Space type. if map_type.lower() == "iso3d": if len(params) != 3: raise RelaxError( "The 3D isosurface map requires a 3 parameter model.") # Create the map. Map(params, spin_id, inc, lower, upper, axis_incs, file_prefix, dir, point, point_file, chi_surface, create_par_file) else: raise RelaxError("The map type '" + map_type + "' is not supported.")
def associate_auto(self, event): """Associate the selected data pipe with a new auto-analysis. @param event: The wx event. @type event: wx event """ # Initialise the GUI data store object if needed. if not hasattr(ds, 'relax_gui'): self.gui.init_data() # The type and data pipe bundle. type = get_type(self.selected_pipe) bundle = get_bundle(self.selected_pipe) # Error checking. if self.selected_pipe == None: raise RelaxError("No data pipe has been selected - this is not possible.") if bundle == None: raise RelaxError("The selected data pipe is not associated with a data pipe bundle.") # The name. names = { 'noe': 'Steady-state NOE', 'r1': 'R1 relaxation', 'r2': 'R2 relaxation', 'mf': 'Model-free', 'relax_disp': 'Relaxation dispersion' } # Create a new analysis with the selected data pipe. self.gui.analysis.new_analysis(analysis_type=type, analysis_name=names[type], pipe_name=self.selected_pipe, pipe_bundle=bundle)
def domain_moving(): """Return the spin ID string corresponding to the moving domain. @return: The spin ID string defining the moving domain. @rtype: str """ # Check that the domain is defined. if not hasattr(cdp, 'domain'): raise RelaxError( "No domains have been defined. Please use the domain user function." ) # Only support for 2 domains. if len(cdp.domain) > 2: raise RelaxError( "Only two domains are supported in the frame order analysis.") # Reference domain not set yet. if not hasattr(cdp, 'ref_domain'): raise RelaxError( "The reference non-moving domain has not been specified.") # Loop over the domains. for id in cdp.domain: # Reference domain. if id == cdp.ref_domain: continue # Return the ID. return cdp.domain[id]
def __errors_volume_no_repl(subset=None): """Calculate the errors for peak volumes when no spectra are replicated.""" # Loop over the spins and set the error to the RMSD of the base plane noise. for spin, spin_id in spin_loop(return_id=True): # Skip deselected spins. if not spin.select: continue # Skip spins missing intensity data. if not hasattr(spin, 'peak_intensity'): continue # Test if the RMSD has been set. if not hasattr(spin, 'baseplane_rmsd'): raise RelaxError( "The RMSD of the base plane noise for spin '%s' has not been set." % spin_id) # Test that the total number of points have been set. if not hasattr(spin, 'N'): raise RelaxError( "The total number of points used in the volume integration has not been specified for spin '%s'." % spin_id) # Set the error to the RMSD multiplied by the square root of the total number of points. for key in spin.peak_intensity: spin.peak_intensity_err[key] = spin.baseplane_rmsd[key] * sqrt( spin.N)
def __setattr__(self, name, value): """Override the class __setattr__ method. @param name: The name of the attribute to modify. @type name: str @param value: The new value of the attribute. @type value: anything """ # Test if the attribute that is trying to be set is modifiable. if not name in self.__mod_attr__: raise RelaxError("The object '%s' is not a modifiable attribute." % name) # Check for duplicative modifications (to catch typo coding errors). if name in ['title', 'title_short', 'backend', 'gui_icon']: # No object set yet. if not hasattr(self, name): obj = None # Get the current object. else: obj = getattr(self, name) # Not None! if obj != None: raise RelaxError("The variable '%s' is already set to %s." % (name, repr(obj))) # Set the attribute normally. self.__dict__[name] = value
def check_exp_type(id=None): """Check if the experiment type have been set up for one or all IDs. @param id: The experiment ID string. If not set, then all spectrum IDs will be checked. @type id: None or str @raises RelaxError: When the experiment type for the given ID is missing or, when not given, if the dispersion experiment type has not been set. """ # Test if the experiment type is set. if not hasattr(cdp, 'exp_type'): raise RelaxError("The relaxation dispersion experiment types have not been set for any spectra.") # Individual ID. if id != None: if id not in cdp.exp_type: raise RelaxError("The dispersion experiment type for the experiment ID '%s' has not been set." % id) # Check that at least one spectrum ID is set. else: found = False for id in cdp.spectrum_ids: if id in cdp.exp_type: found = True if not found: raise RelaxError("The relaxation dispersion experiment type has not been set any spectra.")
def add_uf(self, name): """Add the user function to the object. @param name: The name of the user function. @type name: str @return: The user function data object. @rtype: user_functions.objects.Uf_container instance """ # Check if the user function already exists. if name in self._uf_names: raise RelaxError("The user function %s has already been set up." % name) # First check if the user function class has been set up. if search('\.', name): # Split up the name. class_name, fn_name = name.split('.') # Check for the class name. if class_name not in self._class_names: raise RelaxError( "The user function class '%s' has not been set up yet." % class_name) # Store the name and initialise a new object. self._uf_names.append(name) self._uf[name] = Uf_container() # Alphabetically sort the names. self._uf_names.sort() # Return the object. return self._uf[name]
def aicc(chi2, k, n): """Small sample size corrected AIC. The formula is:: 2k(k + 1) AICc = chi2 + 2k + --------- n - k - 1 @param chi2: The minimised chi-squared value. @type chi2: float @param k: The number of parameters in the model. @type k: int @param n: The dimension of the relaxation data set. @type n: int @return: The AIC value. @rtype: float """ if n > (k+1): return chi2 + 2.0*k + 2.0*k*(k + 1.0) / (n - k - 1.0) elif n == (k+1): raise RelaxError("The size of the dataset, n=%s, is too small for this model of size k=%s. This situation causes a fatal division by zero as:\n AICc = chi2 + 2k + 2k*(k + 1) / (n - k - 1).\n\nPlease use AIC model selection instead." % (n, k)) elif n < (k+1): raise RelaxError("The size of the dataset, n=%s, is too small for this model of size k=%s. This situation produces a negative, and hence nonsense, AICc score as:\n AICc = chi2 + 2k + 2k*(k + 1) / (n - k - 1).\n\nPlease use AIC model selection instead." % (n, k))
def fold_spherical_angles(theta, phi, theta_lower=0, theta_upper=2 * pi, theta_window=2 * pi, phi_lower=0, phi_upper=2 * pi, phi_window=2 * pi): """Fold the spherical angles taking symmetry into account. The angles will be folded between:: 0 <= theta <= pi, 0 <= phi <= 2*pi, @param theta: The azimuthal angle. @type theta: float @param phi: The polar angle. @type phi: float @param theta_lower: The theta angle lower bound (defaults to 0). @type theta_lower: float @param theta_upper: The theta angle upper bound (defaults to 2*pi). @type theta_upper: float @param theta_window: The size of the theta angle window where symmetry exists (defaults to 2*pi). @type theta_window: float @param phi_lower: The phi angle lower bound (defaults to 0). @type phi_lower: float @param phi_upper: The phi angle upper bound (defaults to 2*pi). @type phi_upper: float @param phi_window: The size of the phi angle window where symmetry exists (defaults to 2*pi). @type phi_window: float @return: The folded angles, theta and phi. @rtype: float """ # Check the bounds and window. if theta_window - (theta_upper - theta_lower) > 1e-7: raise RelaxError( "The theta angle lower and upper bounds [%s, %s] do not match the window size of %s." % (theta_lower, theta_upper, theta_window)) if phi_window - (phi_upper - phi_lower) > 1e-7: raise RelaxError( "The phi angle lower and upper bounds [%s, %s] do not match the window size of %s." % (phi_lower, phi_upper, phi_window)) # First wrap the angles. theta = wrap_angles(theta, theta_lower, theta_upper, theta_window) phi = wrap_angles(phi, phi_lower, phi_upper, phi_window) # Then remove the symmetry to the lower half of phi. if phi >= phi_upper - phi_window / 2.0: theta = pi - theta phi = phi - pi # Wrap again if necessary. theta = wrap_angles(theta, theta_lower, theta_upper, theta_window) phi = wrap_angles(phi, phi_lower, phi_upper, phi_window) # Return the folded angles. return theta, phi
def check_parameters_func(): """Check if the frame order parameters exist. @return: The initialised RelaxError object if the model parameters have not been setup, or nothing. @rtype: None or RelaxError instance """ # The model has not been set up. if not hasattr(cdp, 'params'): return RelaxError( "The frame order model has not been set up, no parameters have been defined." ) # The model has been set up. else: # Find missing parameters. missing = [] for param in cdp.params: # Check that the parameters exists. if not hasattr(cdp, param): missing.append(param) # Check that it has a value. else: obj = getattr(cdp, param) if obj == None: missing.append(param) # Failure. if len(missing): return RelaxError( "The frame order parameters %s have not been set up." % missing)
def check_structure_func(pipe_name=None): """Test if structural data is present. @return: The initialised RelaxError object or nothing. @rtype: None or RelaxError instance """ # Defaults. if pipe_name == None: pipe_name = cdp_name() # Get the data pipe. dp = get_pipe(pipe_name) # Test if the structure exists. if not hasattr(dp, 'structure'): return RelaxError( "No structural data is present in the current data pipe.") # Check for models: if not dp.structure.num_models(): return RelaxError( "The structural object in the current data pipe contains no models." ) # Check for molecules. if not dp.structure.num_molecules(): return RelaxError( "The structural object in the current data pipe contains no molecules." )
def add_item(self, res_name=None, res_num=None): """Append an empty ResidueContainer to the ResidueList.""" # If no residue data exists, replace the empty first residue with this residue. if self.is_empty(): self[0].num = res_num self[0].name = res_name # Otherwise append a new ResidueContainer. else: # Test if the residue number (or name if unnumbered) already exists. for i in range(len(self)): # Residue number has been supplied. if res_num != None: if self[i].num == res_num: raise RelaxError("The residue number '" + repr(res_num) + "' already exists in the sequence.") # No residue numbers. else: if self[i].name == res_name: raise RelaxError("The unnumbered residue name '" + repr(res_name) + "' already exists.") # Append a new ResidueContainer. self.append(ResidueContainer(res_name, res_num))
def register(self, key, method, method_name=None): """Register a method to be called when the state changes. @param key: The key to identify the observer's method. @type key: str @param method: The observer's method to be called after a state change. @type method: method @keyword method_name: The optional method name used in debugging printouts. @type method_name: str or None """ # Already exists. if key in self._keys: raise RelaxError("The observer '%s' already exists." % key) # Blank key. if key == None: raise RelaxError("The observer key must be supplied.") # Debugging. if self._status.debug: if method_name: sys.stdout.write("debug> Observer: '%s' registering the '%s' method %s().\n" % (self._name, key, method_name)) else: sys.stdout.write("debug> Observer: '%s' registering '%s'.\n" % (self._name, key)) # Add the method to the dictionary of callbacks. self._callback[key] = method # Add the method name. self._method_names[key] = method_name # Add the key to the ordered list. self._keys.append(key)
def return_error(self, data_id): """Return the RDC or PCS error structure. @param data_id: The data set as yielded by the base_data_loop() generator method. @type data_id: list of str @return: The array of RDC or PCS error values. @rtype: list of float """ # Initialise the MC data structure. mc_errors = [] # The RDC data. if data_id[0] == 'rdc': # Unpack the set. data_type, spin_hash1, spin_hash2, align_id = data_id # Get the interatomic data container. interatom = return_interatom(spin_hash1=spin_hash1, spin_hash2=spin_hash2) # Do errors exist? if not hasattr(interatom, 'rdc_err'): raise RelaxError( "The RDC errors are missing for interatomic data container between spins '%s' and '%s'." % (spin_id1, spin_id2)) # Handle missing data. if align_id not in interatom.rdc_err: mc_errors.append(None) # Append the data. else: mc_errors.append(interatom.rdc_err[align_id]) # The PCS data. elif data_id[0] == 'pcs': # Unpack the set. data_type, spin_id, align_id = data_id # Get the spin container. spin = return_spin(spin_id=spin_id) # Do errors exist? if not hasattr(spin, 'pcs_err'): raise RelaxError("The PCS errors are missing for spin '%s'." % spin_id) # Handle missing data. if align_id not in spin.pcs_err: mc_errors.append(None) # Append the data. else: mc_errors.append(spin.pcs_err[align_id]) # Return the errors. return mc_errors
def cpmgfit_input(dir=None, binary='cpmgfit', spin_id=None, force=False): """Create the CPMGFit input files. @keyword dir: The optional directory to place the files into. If None, then the files will be placed into a directory named after the dispersion model. @type dir: str or None @keyword binary: The name of the CPMGFit binary file. This can include the path to the binary. @type binary: str @keyword spin_id: The spin ID string to restrict the file creation to. @type spin_id: str @keyword force: A flag which if True will cause all pre-existing files to be overwritten. @type force: bool """ # Test if the current pipe exists. check_pipe() # Test if sequence data is loaded. if not exists_mol_res_spin_data(): raise RelaxNoSequenceError # Test if the experiment type has been set. if not hasattr(cdp, 'exp_type'): raise RelaxError("The relaxation dispersion experiment type has not been specified.") # Test if the model has been set. if not hasattr(cdp, 'model_type'): raise RelaxError("The relaxation dispersion model has not been specified.") # Directory creation. if dir != None: mkdir_nofail(dir, verbosity=0) # The 'run.sh' script. batch = open_write_file('batch_run.sh', dir, force) batch.write("#! /bin/sh\n\n") # Generate the input files for each spin. for spin, spin_id in spin_loop(return_id=True, skip_desel=True): # Translate the model. function = translate_model(spin.model) # Create the input file. file_in = create_spin_input(function=function, spin=spin, spin_id=spin_id, dir=dir) # The output file name. file_out = spin_file_name(spin_id=spin_id, output=True) # Add the file to the batch script. batch.write("%s -grid -xmgr -f %s | tee %s\n" % (binary, file_in, file_out)) # Close the batch script, then make it executable. batch.close() if dir: chmod(dir + sep + 'batch_run.sh', S_IRWXU|S_IRGRP|S_IROTH) else: chmod('batch_run.sh', S_IRWXU|S_IRGRP|S_IROTH)
def exec_script(name, globals): """Execute the script.""" # Execution lock. status.exec_lock.acquire('script UI', mode='script') # The module path. head, tail = path.split(name) script_path = path.join(getcwd(), head) sys.path.append(script_path) # The module name. module, ext = path.splitext(tail) # Check if the script name is ok. if search('\.', module): raise RelaxError( "The relax script must not contain the '.' character (except before the extension '*.py')." ) if ext != '.py': raise RelaxError("The script must have the extension *.py.") # Read the contents of the script for finding old user function calls, prepending a newline character so that old user functions on the first line of a script can be handled. file = open(name) text = '\n' text += file.read() file.close() # Parse the code in the module for old user function calls. for old_uf in uf_translation_table: # Find an old call. if search('[ \\n]' + old_uf + '\(', text): raise RelaxError( "The user function '%s' has been renamed to '%s', please update your script." % (old_uf, uf_translation_table[old_uf])) # Execute the module. try: # Reverse the system path so that the script path is first. sys.path.reverse() # Execute the script as a module. if dep_check.runpy_module: runpy.run_module(module, globals) # Allow scripts to run under Python <= 2.4. else: exec(compile(open(name).read(), name, 'exec'), globals) finally: # Remove the script path. sys.path.reverse() sys.path.pop(sys.path.index(script_path)) # Unlock execution if needed. status.exec_lock.release()
def open_read_file(file_name=None, dir=None, verbosity=1): """Open the file 'file' and return all the data. @keyword file_name: The name of the file to extract the data from. @type file_name: str @keyword dir: The path where the file is located. If None, then the current directory is assumed. @type dir: str @keyword verbosity: The verbosity level. @type verbosity: int @return: The open file object. @rtype: file object """ # A file descriptor object. if is_filetype(file_name): # Nothing to do here! return file_name # Invalid file name. if not file_name and not isinstance(file_name, str): raise RelaxError("The file name " + repr(file_name) + " " + repr(type(file_name)) + " is invalid and cannot be opened.") # File path. file_path = get_file_path(file_name, dir) # Test if the file exists and determine the compression type. compress_type, file_path = determine_compression(file_path) # Open the file for reading. try: # Print out. if verbosity: print("Opening the file " + repr(file_path) + " for reading.") # Uncompressed text. if compress_type == 0: file_obj = open(file_path, 'r') # Bzip2 compressed text. elif compress_type == 1: file_obj = bz2_open(file=file_path, mode='r') # Gzipped compressed text. elif compress_type == 2: file_obj = gz_open(file=file_path, mode='r') # Cannot open. except IOError: message = sys.exc_info()[1] raise RelaxError("Cannot open the file " + repr(file_path) + ". " + message.args[1] + ".") # Return the opened file. return file_obj
def check_spectrometer_frq(): """Check if the spectrometer frequencies have been set up. @raises RelaxError: If the spectrometer frequencies have not been set. """ # Test if the experiment type is set. if not hasattr(cdp, 'spectrometer_frq'): raise RelaxError("The spectrometer frequencies have not been set for any spectra.") # Check each spectrum ID. for id in cdp.exp_type: if id not in cdp.spectrometer_frq: raise RelaxError("The spectrometer frequency has not been set for the '%s' spectrum." % id)
def set_dist(spin_id1=None, spin_id2=None, ave_dist=None, unit='meter'): """Set up the magnetic dipole-dipole interaction. @keyword spin_id1: The spin identifier string of the first spin of the pair. @type spin_id1: str @keyword spin_id2: The spin identifier string of the second spin of the pair. @type spin_id2: str @keyword ave_dist: The r^-3 averaged interatomic distance. @type ave_dist: float @keyword unit: The measurement unit. This can be either 'meter' or 'Angstrom'. @type unit: str """ # Check the units. if unit not in ['meter', 'Angstrom']: raise RelaxError("The measurement unit of '%s' must be one of 'meter' or 'Angstrom'." % unit) # Unit conversion. if unit == 'Angstrom': ave_dist = ave_dist * 1e-10 # Generate the selection objects. sel_obj1 = Selection(spin_id1) sel_obj2 = Selection(spin_id2) # Loop over the interatomic containers. data = [] for interatom in interatomic_loop(): # Get the spin info. mol_name1, res_num1, res_name1, spin1 = return_spin(spin_hash=interatom._spin_hash1, full_info=True) mol_name2, res_num2, res_name2, spin2 = return_spin(spin_hash=interatom._spin_hash2, full_info=True) # No match, either way. if not (sel_obj1.contains_spin(spin_num=spin1.num, spin_name=spin1.name, res_num=res_num1, res_name=res_name1, mol=mol_name1) and sel_obj2.contains_spin(spin_num=spin2.num, spin_name=spin2.name, res_num=res_num2, res_name=res_name2, mol=mol_name2)) and not (sel_obj2.contains_spin(spin_num=spin1.num, spin_name=spin1.name, res_num=res_num1, res_name=res_name1, mol=mol_name1) and sel_obj1.contains_spin(spin_num=spin2.num, spin_name=spin2.name, res_num=res_num2, res_name=res_name2, mol=mol_name2)): continue # Store the averaged distance. interatom.r = ave_dist # Store the data for the printout. data.append([repr(interatom.spin_id1), repr(interatom.spin_id2), repr(ave_dist)]) # No data, so fail! if not len(data): raise RelaxError("No data could be set.") # Print out. print("The following averaged distances have been set:\n") write_data(out=sys.stdout, headings=["Spin_ID_1", "Spin_ID_2", "Ave_distance(meters)"], data=data)
def compare_objects(object_from, object_to, pipe_from, pipe_to): """Compare the contents of the two objects and raise RelaxErrors if they are not the same. @param object_from: The first object. @type object_from: any object @param object_to: The second object. @type object_to: any object @param pipe_from: The name of the data pipe containing the first object. @type pipe_from: str @param pipe_to: The name of the data pipe containing the second object. @type pipe_to: str """ # Loop over the modifiable objects. for data_name in dir(object_from): # Skip special objects (starting with _, or in the original class and base class namespaces). if search( '^_', data_name) or data_name in object_from.__class__.__dict__ or ( hasattr(object_from.__class__, '__bases__') and len(object_from.__class__.__bases__) and data_name in object_from.__class__.__bases__[0].__dict__): continue # Skip some more special objects. if data_name in ['structural_data']: continue # Get the original object. data_from = None if hasattr(object_from, data_name): data_from = getattr(object_from, data_name) # Get the target object. if data_from and not hasattr(object_to, data_name): raise RelaxError("The structural object " + repr(data_name) + " of the " + repr(pipe_from) + " data pipe is not located in the " + repr(pipe_to) + " data pipe.") elif data_from: data_to = getattr(object_to, data_name) else: continue # The data must match! if data_from != data_to: raise RelaxError("The object " + repr(data_name) + " is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
def __call__(self, *uf_args, **uf_kargs): """Make the user function executable.""" # Check the keyword args. for name in uf_kargs: # Unknown keyword. if name not in self._karg_names: raise RelaxError("User function %s - the keyword argument '%s' is unknown." % (self._name, name)) # Convert the args to keyword args if needed. num_args = len(uf_args) new_args = [] if num_args: for i in range(num_args): # Check if the keyword is already assigned. if self._kargs[i]['name'] in uf_kargs: raise RelaxError("User function %s - the argument '%s' and the keyword argument '%s' cannot both be supplied." % (self._name, uf_args[i], self._kargs[i]['name'])) # Add the arg as a keyword arg. uf_kargs[self._kargs[i]['name']] = uf_args[i] # Set the argument defaults. for i in range(self._karg_num): # The keyword. name = self._kargs[i]['name'] # Set the default if the user has not supplied a value. if name not in uf_kargs: uf_kargs[name] = self._kargs[i]['default'] # Function intro text. if status.uf_intro: # Convert the keys and values. keys = [] values = [] for i in range(self._karg_num): keys.append(self._kargs[i]['name']) values.append(uf_kargs[self._kargs[i]['name']]) # The printout. print(self._intro_text(keys, values)) # Check the argument values. for i in range(self._karg_num): arg = self._kargs[i] lib.arg_check.validate_arg(uf_kargs[self._kargs[i]['name']], arg['desc_short'], dim=arg['dim'], basic_types=arg['basic_types'], container_types=arg['container_types'], can_be_none=arg['can_be_none'], can_be_empty=arg['can_be_empty'], none_elements=arg['none_elements']) # Execute the functional code. self._backend(*new_args, **uf_kargs)
def _set_param_values_global(self, param=None, value=None, index=None, spin_id=None, error=False, force=True): """Set the global parameter values in the top layer of the data pipe. @keyword param: The parameter name list. @type param: list of str @keyword value: The parameter value list. @type value: list @keyword index: The index for parameters which are of the list-type. This is unused. @type index: None or int @keyword spin_id: The spin identification string (unused). @type spin_id: None @keyword error: A flag which if True will allow the parameter errors to be set instead of the values. @type error: bool @keyword force: A flag which if True will cause current values to be overwritten. If False, a RelaxError will raised if the parameter value is already set. @type force: bool """ # Checks. lib.arg_check.is_str_list(param, 'parameter name') lib.arg_check.is_list(value, 'parameter value') # Loop over the parameters. for i in range(len(param)): # Is the parameter is valid? if not param[i]: raise RelaxError( "The parameter '%s' is not valid for this data pipe type." % param[i]) # Error object. if error: param[i] += '_err' # Is the parameter already set. if not force and hasattr( cdp, param[i]) and getattr(cdp, param[i]) != None: raise RelaxError( "The parameter '%s' already exists, set the force flag to True to overwrite." % param[i]) # Set the parameter. setattr(cdp, param[i], value[i])
def check_mixed_curve_types(): """Prevent both fixed time and exponential curves from being analysed simultaneously. @raises RelaxError: If mixed curve types are present. """ # No experiment types set. if not hasattr(cdp, 'exp_type') or not hasattr(cdp, 'spectrum_ids') or not hasattr(cdp, 'relax_times'): return False # Get the times. times = get_times() # Loop over all experiment types. var_flag = False fixed_flag = False for exp_type in times: if times[exp_type] == 1: fixed_flag = True else: var_flag = True # The check. if var_flag and fixed_flag: raise RelaxError("Fixed time and exponential curves cannot be analysed simultaneously.")
def set_temperature(id=None, temp=None): """Set the experimental temperature. @keyword id: The experiment ID string (allowing for multiple experiments per data pipe). @type id: str @keyword temp: The temperature in Kelvin. @type temp: float """ # Test if the current data pipe exists. check_pipe() # Set up the dictionary data structure if it doesn't exist yet. if not hasattr(cdp, 'temperature'): cdp.temperature = {} # Convert to a float. temp = float(temp) # Test the temperature has not already been set. if id in cdp.temperature and cdp.temperature[id] != temp: raise RelaxError("The temperature for the experiment '%s' has already been set to %s K." % (id, cdp.temperature[id])) # Set the temperature. cdp.temperature[id] = temp
def open_gui(self): """Open a Molmol pipe.""" # Test that the Molmol binary exists. test_binary('molmol') # Python 2.3 and earlier. if Popen == None: raise RelaxError( "The subprocess module is not available in this version of Python." ) # Open Molmol as a pipe. self.molmol = Popen(['molmol', '-f', '-'], stdin=PIPE).stdin # Execute the command history. if len(self.command_history) > 0: self.exec_cmd(self.command_history, store_command=0) return # Wait a little while for Molmol to initialise. sleep(2) # Test if the PDB file has been loaded. if hasattr(cdp, 'structure'): self.open_pdb() # Run InitAll to remove everything from Molmol. else: self.molmol.write("InitAll yes\n")
def check_vars(self): """Check that the user has set the variables correctly.""" # Printout. section(file=sys.stdout, text="Variable checking", prespace=2) # The pipe name. if not has_pipe(self.pipe_name): raise RelaxNoPipeError(self.pipe_name) # Check the model selection. allowed = ['AIC', 'AICc', 'BIC'] if self.modsel not in allowed: raise RelaxError( "The model selection technique '%s' is not in the allowed list of %s." % (self.modsel, allowed)) # Some warning for the user if the pure numeric solution is selected. if self.numeric_only: # Loop over all models. for model in self.models: # Skip the models used for nesting. if model in MODEL_LIST_NEST: continue # Warnings for all other analytic models. if model in MODEL_LIST_ANALYTIC: warn( RelaxWarning( "The analytic model '%s' will be optimised but will not be used in any way in this numeric model only auto-analysis." % model)) # Printout. print("The dispersion auto-analysis variables are OK.")
def show_apod_rmsd(file_name=None, dir=None, path_to_command='showApod'): """Extract showApod 'Noise Std Dev' for spectrum fourier transformed with NMRPipe. @keyword file: The filename of the NMRPipe fourier transformed file. @type file: str @keyword dir: The directory where the file is located. @type dir: str @keyword path_to_command: If showApod not in PATH, then specify absolute path as: /path/to/showApod @type path_to_command: str @return: The Noise Std Dev from line: 'REMARK Automated Noise Std Dev in Processed Data' @rtype: float """ # Call extract function. show_apod_lines = show_apod_extract(file_name=file_name, dir=dir, path_to_command=path_to_command) # Loop over the lines found = False for line in show_apod_lines: # Look for line with this remark. if line[:49] == 'REMARK Automated Noise Std Dev in Processed Data:': # The rest of the line is the rmsd. rmsd = float(line[49:].split()[0]) return rmsd if not found: print(show_apod_lines) raise RelaxError("Could not find the line: 'REMARK Automated Noise Std Dev in Processed Data:', from the output of showApod.")
def show_apod_extract(file_name=None, dir=None, path_to_command='showApod'): """Extract showApod information for spectrum fourier transformed with NMRPipe. @keyword file: The filename of the NMRPipe fourier transformed file. @type file: str @keyword dir: The directory where the file is located. @type dir: str @keyword path_to_command: If showApod not in PATH, then specify absolute path as: /path/to/showApod @type path_to_command: str @return: The output from showApod as list of lines. @rtype: list of lines """ # Get the file path. file_path = get_file_path(file_name=file_name, dir=dir) if not subprocess_module: raise RelaxError("Python module 'subprocess' not found, cannot call showApod.") # Call function. Temp = subprocess.Popen([path_to_command, file_path], stdout=subprocess.PIPE) # Communicate with program, and get outout and exitcode. (output, errput) = Temp.communicate() # Wait for finish and get return code. return_value = Temp.wait() # Python 3 support - convert byte arrays to text. if hasattr(output, 'decode'): output = output.decode() return output.splitlines()