Author: bugman Date: Tue Feb 25 09:13:32 2014 New Revision: 22295 URL: http://svn.gna.org/viewcvs/relax?rev=22295&view=rev Log: Complete support for deselected spins has been added to the relaxation dispersion analysis. This fixes bug #21715 (https://gna.org/bugs/?21715), the failure of the relaxation dispersion auto-analysis when running a clustered analysis due to an IndexError during minimisation. Modified: trunk/specific_analyses/relax_disp/disp_data.py trunk/specific_analyses/relax_disp/optimisation.py trunk/specific_analyses/relax_disp/parameters.py Modified: trunk/specific_analyses/relax_disp/disp_data.py URL: http://svn.gna.org/viewcvs/relax/trunk/specific_analyses/relax_disp/disp_data.py?rev=22295&r1=22294&r2=22295&view=diff ============================================================================== --- trunk/specific_analyses/relax_disp/disp_data.py (original) +++ trunk/specific_analyses/relax_disp/disp_data.py Tue Feb 25 09:13:32 2014 @@ -214,6 +214,19 @@ # Return the count. return count + + +def count_spins(spins=None): + """Count the number of selected spins in the spin cluster.""" + + # Count the selected spins. + spin_num = 0 + for spin in spins: + if spin.select: + spin_num += 1 + + # Return the count. + return spin_num def cpmg_frq(spectrum_id=None, cpmg_frq=None): @@ -2698,7 +2711,10 @@ # The counts. exp_num = num_exp_types() - spin_num = len(spins) + spin_num = 0 + for spin in spins: + if spin.select: + spin_num += 1 # Initialise the data structures for the target function. fields_orig = fields @@ -2723,10 +2739,15 @@ # Assemble the data. data_flag = False - for si in range(spin_num): + si = 0 + for spin_index in range(len(spins)): + # Skip deselected spins. + if not spins[spin_index].select: + continue + # Alias the spin. - spin = spins[si] - spin_id = spin_ids[si] + spin = spins[spin_index] + spin_id = spin_ids[spin_index] # No data. shift = 0.0 @@ -2809,6 +2830,9 @@ else: theta[ei][si][mi][oi].append(atan(omega1 / Delta_omega)) + # Increment the spin index. + si += 1 + # No shift data for the spin cluster. if not data_flag: return None, None, None @@ -2874,7 +2898,7 @@ """ # The spin count. - spin_num = len(spins) + spin_num = count_spins(spins) # Initialise the data structure. r1 = -ones((spin_num, field_count), float64) @@ -2949,7 +2973,7 @@ # The counts. exp_num = num_exp_types() - spin_num = len(spins) + spin_num = count_spins(spins) # 1H MMQ flag. proton_mmq_flag = has_proton_mmq_cpmg() @@ -2990,10 +3014,15 @@ # Pack the R2eff/R1rho data. data_flag = False - for si in range(spin_num): + si = 0 + for spin_index in range(len(spins)): + # Skip deselected spins. + if not spins[spin_index].select: + continue + # Alias the spin. - spin = spins[si] - spin_id = spin_ids[si] + spin = spins[spin_index] + spin_id = spin_ids[spin_index] # Get the attached proton. proton = None @@ -3089,6 +3118,9 @@ # Store the time. relax_times[ei][mi] = relax_time + + # Increment the spin index. + si += 1 # No R2eff/R1rho data for the spin cluster. if not data_flag: Modified: trunk/specific_analyses/relax_disp/optimisation.py URL: http://svn.gna.org/viewcvs/relax/trunk/specific_analyses/relax_disp/optimisation.py?rev=22295&r1=22294&r2=22295&view=diff ============================================================================== --- trunk/specific_analyses/relax_disp/optimisation.py (original) +++ trunk/specific_analyses/relax_disp/optimisation.py Tue Feb 25 09:13:32 2014 @@ -1,6 +1,6 @@ ############################################################################### # # -# Copyright (C) 2013 Edward d'Auvergne # +# Copyright (C) 2013-2014 Edward d'Auvergne # # # # This file is part of the program relax (http://www.nmr-relax.com). # # # @@ -35,7 +35,7 @@ from lib.errors import RelaxError from lib.text.sectioning import subsection from multi import Memo, Result_command, Slave_command -from specific_analyses.relax_disp.disp_data import has_disp_data, has_proton_mmq_cpmg, loop_exp, loop_exp_frq, loop_exp_frq_offset_point, loop_frq, loop_offset, pack_back_calc_r2eff, return_cpmg_frqs, return_index_from_disp_point, return_index_from_exp_type, return_index_from_frq, return_offset_data, return_param_key_from_data, return_r1_data, return_r2eff_arrays, return_spin_lock_nu1, return_value_from_frq_index +from specific_analyses.relax_disp.disp_data import count_spins, has_disp_data, has_proton_mmq_cpmg, loop_exp, loop_exp_frq, loop_exp_frq_offset_point, loop_frq, loop_offset, pack_back_calc_r2eff, return_cpmg_frqs, return_index_from_disp_point, return_index_from_exp_type, return_index_from_frq, return_offset_data, return_param_key_from_data, return_r1_data, return_r2eff_arrays, return_spin_lock_nu1, return_value_from_frq_index from specific_analyses.relax_disp.parameters import assemble_param_vector, assemble_scaling_matrix, disassemble_param_vector, linear_constraints, loop_parameters, param_conversion, param_num from specific_analyses.relax_disp.variables import EXP_TYPE_CPMG_PROTON_MQ, EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_LIST_CPMG, MODEL_CR72, MODEL_CR72_FULL, MODEL_DPL94, MODEL_LIST_MMQ, MODEL_LM63, MODEL_M61, MODEL_M61B, MODEL_MP05, MODEL_NS_R1RHO_2SITE, MODEL_TAP03, MODEL_TP02 from target_functions.relax_disp import Dispersion @@ -431,7 +431,7 @@ print("Unconstrained grid search size: %s (constraints may decrease this size).\n" % self.grid_size) # Initialise the function to minimise. - model = Dispersion(model=self.spins[0].model, num_params=self.param_num, num_spins=len(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) + 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) # Grid search. if search('^[Gg]rid', self.min_algor): @@ -539,6 +539,10 @@ # Monte Carlo minimisation statistics. if memo.sim_index != None: for spin in memo.spins: + # Skip deselected spins. + if not spin.select: + continue + # Chi-squared statistic. spin.chi2_sim[memo.sim_index] = self.chi2 @@ -560,6 +564,10 @@ # Normal statistics. else: for spin in memo.spins: + # Skip deselected spins. + if not spin.select: + continue + # Chi-squared statistic. spin.chi2 = self.chi2 @@ -584,5 +592,14 @@ proton_mmq_flag = has_proton_mmq_cpmg() # Loop over each spin, packing the data. - for si in range(len(memo.spins)): - pack_back_calc_r2eff(spin=memo.spins[si], spin_id=memo.spin_ids[si], si=si, back_calc=self.back_calc, proton_mmq_flag=proton_mmq_flag) + si = 0 + for spin_index in range(len(memo.spins)): + # Skip deselected spins. + if not memo.spins[spin_index].select: + continue + + # Pack the data. + pack_back_calc_r2eff(spin=memo.spins[spin_index], spin_id=memo.spin_ids[spin_index], si=si, back_calc=self.back_calc, proton_mmq_flag=proton_mmq_flag) + + # Increment the spin index. + si += 1 Modified: trunk/specific_analyses/relax_disp/parameters.py URL: http://svn.gna.org/viewcvs/relax/trunk/specific_analyses/relax_disp/parameters.py?rev=22295&r1=22294&r2=22295&view=diff ============================================================================== --- trunk/specific_analyses/relax_disp/parameters.py (original) +++ trunk/specific_analyses/relax_disp/parameters.py Tue Feb 25 09:13:32 2014 @@ -1,6 +1,6 @@ ############################################################################### # # -# Copyright (C) 2004-2013 Edward d'Auvergne # +# Copyright (C) 2004-2014 Edward d'Auvergne # # Copyright (C) 2009 Sebastien Morin # # # # This file is part of the program relax (http://www.nmr-relax.com). # @@ -33,7 +33,7 @@ from lib.text.sectioning import subsection from pipe_control import pipes from pipe_control.mol_res_spin import exists_mol_res_spin_data, return_spin -from specific_analyses.relax_disp.disp_data import generate_r20_key, has_exponential_exp_type, loop_cluster, loop_exp_frq, return_value_from_frq_index +from specific_analyses.relax_disp.disp_data import count_spins, generate_r20_key, has_exponential_exp_type, loop_cluster, loop_exp_frq, return_value_from_frq_index from specific_analyses.relax_disp.variables import MODEL_LIST_MMQ, MODEL_M61B, MODEL_NS_MMQ_3SITE, MODEL_NS_MMQ_3SITE_LINEAR, MODEL_NS_R1RHO_3SITE, MODEL_NS_R1RHO_3SITE_LINEAR @@ -342,6 +342,10 @@ # Initialise parameters if needed. for spin in spins: + # Skip deselected spins. + if not spin.select: + continue + # The R2 parameter. if 'r2' in spin.params: if sim_index != None: @@ -687,6 +691,10 @@ if cdp.model_type == 'R2eff': # Loop over the spins. for spin_index in range(len(spins)): + # Skip deselected spins. + if not spins[spin_index].select: + continue + # Yield the two parameters. params = ['r2eff', 'i0'] for i in range(2): @@ -700,6 +708,10 @@ else: # First the R2 parameters (one per spin per field strength). for spin_index in range(len(spins)): + # Skip deselected spins. + if not spins[spin_index].select: + continue + # The R2 parameter. if 'r2' in spins[0].params: for exp_type, frq in loop_exp_frq(): @@ -720,6 +732,10 @@ # Then the chemical shift difference parameters 'phi_ex', 'phi_ex_B', 'phi_ex_C', 'padw2', 'dw', 'dw_AB', 'dw_BC', 'dw_AB' (one per spin). for spin_index in range(len(spins)): + # Skip deselected spins. + if not spins[spin_index].select: + continue + # Yield the data. if 'phi_ex' in spins[spin_index].params: param_index += 1 @@ -748,6 +764,10 @@ # Then a separate block for the proton chemical shift difference parameters for the MQ models (one per spin). for spin_index in range(len(spins)): + # Skip deselected spins. + if not spins[spin_index].select: + continue + if 'dwH' in spins[spin_index].params: param_index += 1 yield 'dwH', param_index, spin_index, None @@ -857,12 +877,15 @@ # The R2eff model. if cdp.model_type == 'R2eff': + # Count the selected spins. + spin_num = count_spins(spins) + # Exponential curves (with clustering). if has_exponential_exp_type(): - return 2 * len(spins) + return 2 * spin_num # Fixed time period experiments (with clustering). - return 1 * len(spins) + return 1 * spin_num # Check the spin cluster. for spin in spins: @@ -969,6 +992,10 @@ else: # Set the same parameter value for all spins in the cluster. for spin in spins: + # Skip deselected spins. + if not spin.select: + continue + # Set the simulation value. if sim_index != None: sim_obj = getattr(spin, param_name+'_sim')