def run(self, processor, completed): """Set up and perform the optimisation.""" # Print out. if self.verbosity >= 1: # Individual spin block section. top = 2 if self.verbosity >= 2: top += 2 subsection(file=sys.stdout, text="Fitting to the spin block %s"%self.spin_ids, prespace=top) # Grid search printout. if search('^[Gg]rid', self.min_algor): result = 1 for x in self.inc: result = mul(result, x) print("Unconstrained grid search size: %s (constraints may decrease this size).\n" % result) # Initialise the function to minimise. model = Dispersion(model=self.spins[0].model, num_params=self.param_num, num_spins=count_spins(self.spins), num_frq=len(self.fields), exp_types=self.exp_types, values=self.values, errors=self.errors, missing=self.missing, frqs=self.frqs, frqs_H=self.frqs_H, cpmg_frqs=self.cpmg_frqs, spin_lock_nu1=self.spin_lock_nu1, chemical_shifts=self.chemical_shifts, offset=self.offsets, tilt_angles=self.tilt_angles, r1=self.r1, relax_times=self.relax_times, scaling_matrix=self.scaling_matrix, r1_fit=self.r1_fit) # Grid search. if search('^[Gg]rid', self.min_algor): results = grid(func=model.func, args=(), num_incs=self.inc, lower=self.lower, upper=self.upper, A=self.A, b=self.b, verbosity=self.verbosity) # Unpack the results. param_vector, chi2, iter_count, warning = results f_count = iter_count g_count = 0.0 h_count = 0.0 # Minimisation. else: results = generic_minimise(func=model.func, args=(), x0=self.param_vector, min_algor=self.min_algor, min_options=self.min_options, func_tol=self.func_tol, grad_tol=self.grad_tol, maxiter=self.max_iterations, A=self.A, b=self.b, full_output=True, print_flag=self.verbosity) # Unpack the results. if results == None: return param_vector, chi2, iter_count, f_count, g_count, h_count, warning = results # Optimisation printout. if self.verbosity: print("\nOptimised parameter values:") for i in range(len(param_vector)): print("%-20s %25.15f" % (self.param_names[i], param_vector[i]*self.scaling_matrix[i, i])) # Create the result command object to send back to the master. processor.return_object(Disp_result_command(processor=processor, memo_id=self.memo_id, param_vector=param_vector, chi2=chi2, iter_count=iter_count, f_count=f_count, g_count=g_count, h_count=h_count, warning=warning, missing=self.missing, back_calc=model.get_back_calc(), completed=False))
def run(self, processor, completed): """Set up and perform the optimisation.""" # Print out. if self.verbosity >= 1: # Individual spin block section. top = 2 if self.verbosity >= 2: top += 2 subsection(file=sys.stdout, text="Fitting to the spin block %s"%self.spin_ids, prespace=top) # Grid search printout. if search('^[Gg]rid', self.min_algor): result = 1 for x in self.inc: result = mul(result, x) print("Unconstrained grid search size: %s (constraints may decrease this size).\n" % result) # Initialise the function to minimise. model = Dispersion(model=self.spins[0].model, num_params=self.param_num, num_spins=count_spins(self.spins), num_frq=len(self.fields), exp_types=self.exp_types, values=self.values, errors=self.errors, missing=self.missing, frqs=self.frqs, frqs_H=self.frqs_H, cpmg_frqs=self.cpmg_frqs, spin_lock_nu1=self.spin_lock_nu1, chemical_shifts=self.chemical_shifts, offset=self.offsets, tilt_angles=self.tilt_angles, r1=self.r1, relax_times=self.relax_times, scaling_matrix=self.scaling_matrix, r1_fit=self.r1_fit) # Grid search. if search('^[Gg]rid', self.min_algor): results = grid(func=model.func, args=(), num_incs=self.inc, lower=self.lower, upper=self.upper, A=self.A, b=self.b, verbosity=self.verbosity) # Unpack the results. param_vector, chi2, iter_count, warning = results f_count = iter_count g_count = 0.0 h_count = 0.0 # Minimisation. else: results = generic_minimise(func=model.func, args=(), x0=self.param_vector, min_algor=self.min_algor, min_options=self.min_options, func_tol=self.func_tol, grad_tol=self.grad_tol, maxiter=self.max_iterations, A=self.A, b=self.b, full_output=True, print_flag=self.verbosity) # Unpack the results. if results == None: return param_vector, chi2, iter_count, f_count, g_count, h_count, warning = results # Optimisation printout. if self.verbosity: print("\nOptimised parameter values:") for i in range(len(param_vector)): print("%-20s %25.15f" % (self.param_names[i], param_vector[i]*self.scaling_matrix[i, i])) # Create the result command object to send back to the master. processor.return_object(Disp_result_command(processor=processor, memo_id=self.memo_id, param_vector=param_vector, chi2=chi2, iter_count=iter_count, f_count=f_count, g_count=g_count, h_count=h_count, warning=warning, missing=self.missing, back_calc=model.get_back_calc(), completed=False))
def back_calc_r2eff(spins=None, spin_ids=None, cpmg_frqs=None, spin_lock_offset=None, spin_lock_nu1=None, relax_times_new=None, store_chi2=False): """Back-calculation of R2eff/R1rho values for the given spin. @keyword spins: The list of specific spin data container for cluster. @type spins: List of SpinContainer instances @keyword spin_ids: The list of spin ID strings for the spin containers in cluster. @type spin_ids: list of str @keyword cpmg_frqs: The CPMG frequencies to use instead of the user loaded values - to enable interpolation. @type cpmg_frqs: list of lists of numpy rank-1 float arrays @keyword spin_lock_offset: The spin-lock offsets to use instead of the user loaded values - to enable interpolation. @type spin_lock_offset: list of lists of numpy rank-1 float arrays @keyword spin_lock_nu1: The spin-lock field strengths to use instead of the user loaded values - to enable interpolation. @type spin_lock_nu1: list of lists of numpy rank-1 float arrays @keyword relax_times_new: The interpolated experiment specific fixed time period for relaxation (in seconds). The dimensions are {Ei, Mi, Oi, Di, Ti}. @type relax_times_new: rank-4 list of floats @keyword store_chi2: A flag which if True will cause the spin specific chi-squared value to be stored in the spin container. @type store_chi2: bool @return: The back-calculated R2eff/R1rho value for the given spin. @rtype: numpy rank-1 float array """ # Create the initial parameter vector. param_vector = assemble_param_vector(spins=spins) # Number of spectrometer fields. fields = [None] field_count = 1 if hasattr(cdp, 'spectrometer_frq_count'): fields = cdp.spectrometer_frq_list field_count = cdp.spectrometer_frq_count # Initialise the data structures for the target function. values, errors, missing, frqs, frqs_H, exp_types, relax_times = return_r2eff_arrays(spins=spins, spin_ids=spin_ids, fields=fields, field_count=field_count) # The offset and R1 data. r1_setup() offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff = return_offset_data(spins=spins, spin_ids=spin_ids, field_count=field_count, spin_lock_offset=spin_lock_offset, fields=spin_lock_nu1) r1 = return_r1_data(spins=spins, spin_ids=spin_ids, field_count=field_count) r1_fit = is_r1_optimised(spins[0].model) # The relaxation times. if relax_times_new != None: relax_times = relax_times_new # The dispersion data. recalc_tau = True if cpmg_frqs == None and spin_lock_nu1 == None and spin_lock_offset == None: cpmg_frqs = return_cpmg_frqs(ref_flag=False) spin_lock_nu1 = return_spin_lock_nu1(ref_flag=False) # Reset the cpmg_frqs if interpolating R1rho models. elif cpmg_frqs == None and spin_lock_offset != None: cpmg_frqs = None spin_lock_nu1 = spin_lock_fields_inter recalc_tau = False values = [] errors = [] missing = [] for exp_type, ei in loop_exp(return_indices=True): values.append([]) errors.append([]) missing.append([]) for si in range(len(spins)): values[ei].append([]) errors[ei].append([]) missing[ei].append([]) for frq, mi in loop_frq(return_indices=True): values[ei][si].append([]) errors[ei][si].append([]) missing[ei][si].append([]) for oi, offset in enumerate(offsets[ei][si][mi]): num = len(spin_lock_nu1[ei][mi][oi]) values[ei][si][mi].append(zeros(num, float64)) errors[ei][si][mi].append(ones(num, float64)) missing[ei][si][mi].append(zeros(num, int32)) # Reconstruct the structures for interpolation. else: recalc_tau = False values = [] errors = [] missing = [] for exp_type, ei in loop_exp(return_indices=True): values.append([]) errors.append([]) missing.append([]) for si in range(len(spins)): values[ei].append([]) errors[ei].append([]) missing[ei].append([]) for frq, mi in loop_frq(return_indices=True): values[ei][si].append([]) errors[ei][si].append([]) missing[ei][si].append([]) for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): if exp_type in EXP_TYPE_LIST_CPMG: num = len(cpmg_frqs[ei][mi][oi]) else: num = len(spin_lock_nu1[ei][mi][oi]) values[ei][si][mi].append(zeros(num, float64)) errors[ei][si][mi].append(ones(num, float64)) missing[ei][si][mi].append(zeros(num, int32)) # Initialise the relaxation dispersion fit functions. model = Dispersion(model=spins[0].model, num_params=param_num(spins=spins), num_spins=len(spins), num_frq=field_count, exp_types=exp_types, values=values, errors=errors, missing=missing, frqs=frqs, frqs_H=frqs_H, cpmg_frqs=cpmg_frqs, spin_lock_nu1=spin_lock_nu1, chemical_shifts=chemical_shifts, offset=offsets, tilt_angles=tilt_angles, r1=r1, relax_times=relax_times, recalc_tau=recalc_tau, r1_fit=r1_fit) # Make a single function call. This will cause back calculation and the data will be stored in the class instance. chi2 = model.func(param_vector) # Store the chi-squared value. if store_chi2: for spin in spins: spin.chi2 = chi2 # Return the structure. return model.get_back_calc()
def back_calc_r2eff(spins=None, spin_ids=None, cpmg_frqs=None, spin_lock_offset=None, spin_lock_nu1=None, relax_times_new=None, store_chi2=False): """Back-calculation of R2eff/R1rho values for the given spin. @keyword spins: The list of specific spin data container for cluster. @type spins: List of SpinContainer instances @keyword spin_ids: The list of spin ID strings for the spin containers in cluster. @type spin_ids: list of str @keyword cpmg_frqs: The CPMG frequencies to use instead of the user loaded values - to enable interpolation. @type cpmg_frqs: list of lists of numpy rank-1 float arrays @keyword spin_lock_offset: The spin-lock offsets to use instead of the user loaded values - to enable interpolation. @type spin_lock_offset: list of lists of numpy rank-1 float arrays @keyword spin_lock_nu1: The spin-lock field strengths to use instead of the user loaded values - to enable interpolation. @type spin_lock_nu1: list of lists of numpy rank-1 float arrays @keyword relax_times_new: The interpolated experiment specific fixed time period for relaxation (in seconds). The dimensions are {Ei, Mi, Oi, Di, Ti}. @type relax_times_new: rank-4 list of floats @keyword store_chi2: A flag which if True will cause the spin specific chi-squared value to be stored in the spin container. @type store_chi2: bool @return: The back-calculated R2eff/R1rho value for the given spin. @rtype: numpy rank-1 float array """ # Create the initial parameter vector. param_vector = assemble_param_vector(spins=spins) # Number of spectrometer fields. fields = [None] field_count = 1 if hasattr(cdp, 'spectrometer_frq_count'): fields = cdp.spectrometer_frq_list field_count = cdp.spectrometer_frq_count # Initialise the data structures for the target function. values, errors, missing, frqs, frqs_H, exp_types, relax_times = return_r2eff_arrays(spins=spins, spin_ids=spin_ids, fields=fields, field_count=field_count) # The offset and R1 data. r1_setup() offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff = return_offset_data(spins=spins, spin_ids=spin_ids, field_count=field_count, spin_lock_offset=spin_lock_offset, fields=spin_lock_nu1) r1 = return_r1_data(spins=spins, spin_ids=spin_ids, field_count=field_count) r1_fit = is_r1_optimised(spins[0].model) # The relaxation times. if relax_times_new != None: relax_times = relax_times_new # The dispersion data. recalc_tau = True if cpmg_frqs == None and spin_lock_nu1 == None and spin_lock_offset == None: cpmg_frqs = return_cpmg_frqs(ref_flag=False) spin_lock_nu1 = return_spin_lock_nu1(ref_flag=False) # Reset the cpmg_frqs if interpolating R1rho models. elif cpmg_frqs == None and spin_lock_offset != None: cpmg_frqs = None spin_lock_nu1 = spin_lock_fields_inter recalc_tau = False values = [] errors = [] missing = [] for exp_type, ei in loop_exp(return_indices=True): values.append([]) errors.append([]) missing.append([]) for si in range(len(spins)): values[ei].append([]) errors[ei].append([]) missing[ei].append([]) for frq, mi in loop_frq(return_indices=True): values[ei][si].append([]) errors[ei][si].append([]) missing[ei][si].append([]) for oi, offset in enumerate(offsets[ei][si][mi]): num = len(spin_lock_nu1[ei][mi][oi]) values[ei][si][mi].append(zeros(num, float64)) errors[ei][si][mi].append(ones(num, float64)) missing[ei][si][mi].append(zeros(num, int32)) # Reconstruct the structures for interpolation. else: recalc_tau = False values = [] errors = [] missing = [] for exp_type, ei in loop_exp(return_indices=True): values.append([]) errors.append([]) missing.append([]) for si in range(len(spins)): values[ei].append([]) errors[ei].append([]) missing[ei].append([]) for frq, mi in loop_frq(return_indices=True): values[ei][si].append([]) errors[ei][si].append([]) missing[ei][si].append([]) for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): if exp_type in EXP_TYPE_LIST_CPMG: num = len(cpmg_frqs[ei][mi][oi]) else: num = len(spin_lock_nu1[ei][mi][oi]) values[ei][si][mi].append(zeros(num, float64)) errors[ei][si][mi].append(ones(num, float64)) missing[ei][si][mi].append(zeros(num, int32)) # Initialise the relaxation dispersion fit functions. model = Dispersion(model=spins[0].model, num_params=param_num(spins=spins), num_spins=len(spins), num_frq=field_count, exp_types=exp_types, values=values, errors=errors, missing=missing, frqs=frqs, frqs_H=frqs_H, cpmg_frqs=cpmg_frqs, spin_lock_nu1=spin_lock_nu1, chemical_shifts=chemical_shifts, offset=offsets, tilt_angles=tilt_angles, r1=r1, relax_times=relax_times, recalc_tau=recalc_tau, r1_fit=r1_fit) # Make a single function call. This will cause back calculation and the data will be stored in the class instance. chi2 = model.func(param_vector) # Store the chi-squared value. if store_chi2: for spin in spins: spin.chi2 = chi2 # Return the structure. return model.get_back_calc()