def calc_chi_sq(self, flag_internal: bool = True): """ Calculate chi square. Keyword Arguments ----------------- - flag_internal: a flag to calculate internal objects (default is True) Output arguments ---------------- - chi_sq_val: chi square of flip ratio (Sum_i ((y_e_i - y_m_i) / sigma_i)**2) - n: number of measured reflections """ self.apply_constraint() l_crystal = self.crystals() chi_sq_res, n_res = 0., 0. for experiment in self.experiments(): chi_sq, n = experiment.calc_chi_sq(l_crystal, flag_internal=flag_internal) experiment.chi_sq = chi_sq experiment.n = n chi_sq_res += chi_sq n_res += n if flag_internal: refine_ls = RefineLs(goodness_of_fit_all= chi_sq_res/n_res, number_reflns=n_res) self.refine_ls = refine_ls return chi_sq_res, n_res
def calc_chi_sq( self, l_crystal: List[Crystal], # or MagCrystal flag_internal=True, dict_in_out: dict = None): """ Calculate chi square. Keyword Arguments ----------------- - l_crystal: a list of Crystal objects of cryspy library - flag_internal: a flag to calculate internal objects (default is True) Output arguments ---------------- - chi_sq_val: chi square of flip ratio (Sum_i ((y_e_i - y_m_i) / sigma_i)**2) - n: number of measured reflections """ diffrn_refln = self.diffrn_refln index_h = diffrn_refln.numpy_index_h index_k = diffrn_refln.numpy_index_k index_l = diffrn_refln.numpy_index_l index_hkl = numpy.stack([index_h, index_k, index_l], axis=0) fr_exp = diffrn_refln.numpy_fr fr_sigma = diffrn_refln.numpy_fr_sigma fr_mod, dder = self.calc_iint_u_d_flip_ratio(index_hkl, l_crystal, flag_internal=flag_internal, dict_in_out=dict_in_out) if flag_internal: diffrn_refln.numpy_fr_calc = fr_mod # diffrn_refln.numpy_intensity_plus_calc = int_u_mod # diffrn_refln.numpy_intensity_minus_calc = int_d_mod diffrn_refln.numpy_to_items() flag_in = numpy.logical_not(diffrn_refln.numpy_excluded) chi_sq = ((fr_mod[flag_in]-fr_exp[flag_in])/fr_sigma[flag_in])**2 chi_sq_val = (chi_sq[numpy.logical_not(numpy.isnan(chi_sq))]).sum() n = numpy.logical_not(numpy.isnan(chi_sq)).sum() if flag_internal: refine_ls = RefineLs(number_reflns=n, goodness_of_fit_all=chi_sq_val/float(n), weighting_scheme="sigma") self.refine_ls = refine_ls return chi_sq_val, n
def maximize_entropy(crystal: Crystal, l_diffrn: List[Diffrn], mem_parameters: MEMParameters, c_lambda: float = 1e-7, n_iterations: int = 10000, disp: bool = True, d_info: dict = None) -> DensityPointL: """ Collins algroritm. Parameters ---------- crystal : Crystal DESCRIPTION. l_diffrn : TYPE DESCRIPTION. c_lambda : float, optional DESCRIPTION. The default is 1e-7. n_iterations : int, optional DESCRIPTION. The default is 10000. chi_iso_ferro : float, optional DESCRIPTION. The default is 0.. chi_iso_antiferro : float, optional DESCRIPTION. The default is 0.. n_x : int, optional DESCRIPTION. The default is 48. n_y : int, optional DESCRIPTION. The default is 48. n_z : int, optional DESCRIPTION. The default is 48. prior_density: str, optional Choose of prior density: "core" or "uniform". The default is "uniform". flag_two_channel: bool, optional DESCRIPTION. The default is False. disp : bool, optional DESCRIPTION. The default is True. Returns ------- DensityPointL Magnetization density. """ flag_info = d_info is not None if flag_info: d_info_keys = d_info.keys() if "stop" not in d_info_keys: d_info["stop"] = False if "print" not in d_info_keys: d_info["print"] = "" chi_iso_ferro = mem_parameters.chi_ferro chi_iso_antiferro = mem_parameters.chi_antiferro points_a = mem_parameters.points_a points_b = mem_parameters.points_b points_c = mem_parameters.points_c prior_density = mem_parameters.prior_density flag_two_channel = mem_parameters.method == "2channel" gof_desired = mem_parameters.gof_desired cell = crystal.cell space_group = crystal.space_group atom_site = crystal.atom_site space_group_symop = space_group.full_space_group_symop if crystal.is_attribute("atom_site_susceptibility"): atom_site_susceptibility = crystal.atom_site_susceptibility l_magnetic_labes = atom_site_susceptibility.label else: atom_site_susceptibility = None l_magnetic_labes = [] density_point = DensityPointL() if prior_density == "core": print("The prior density is core's one.", end="\r") if flag_info: d_info["print"] = "The prior density is core's one." atom_electron_configuration = crystal.atom_electron_configuration density_point.create_core_density(space_group_symop, cell, atom_site, atom_electron_configuration, points_a=points_a, points_b=points_b, points_c=points_c, flag_two_channel=flag_two_channel) else: print("The prior density is uniform.", end="\r") if flag_info: d_info["print"] = "The prior density is uniform." density_point.create_flat_density(space_group_symop, cell, atom_site, l_magnetic_labes=l_magnetic_labes, points_a=points_a, points_b=points_b, points_c=points_c, flag_two_channel=flag_two_channel) l_f_nucl, l_v_2d_i, l_fr_e, l_fr_s, l_fm_orb_perp_loc = [], [], [], [], [] total_peaks = 0 for diffrn in l_diffrn: diffrn_orient_matrix = diffrn.diffrn_orient_matrix u_matrix = diffrn_orient_matrix.u e_up = calc_e_up_loc(0., 0., 0., u_matrix) setup = diffrn.setup field = float(setup.field) h_loc = (field * e_up[0], field * e_up[1], field * e_up[2]) diffrn_refln = diffrn.diffrn_refln ind_h = numpy.array(diffrn_refln.index_h, dtype=int) ind_k = numpy.array(diffrn_refln.index_k, dtype=int) ind_l = numpy.array(diffrn_refln.index_l, dtype=int) total_peaks += ind_h.size chi_m = crystal.calc_susceptibility_moment_tensor( ind_h, ind_k, ind_l, flag_only_orbital=True) sft_ij = chi_m[:9] sftm_ij = chi_m[9:] k_loc_i = cell.calc_k_loc(ind_h, ind_k, ind_l) fm_orb_perp_loc = calc_fm_perp_loc(e_up, field, k_loc_i, sft_ij, sftm_ij) hkl = (ind_h, ind_k, ind_l) fr_e = numpy.array(diffrn_refln.fr, dtype=float) fr_s = numpy.array(diffrn_refln.fr_sigma, dtype=float) v_hkl_perp_2d_i, v_b_ferro, v_b_antiferro = \ density_point.calc_factor_in_front_of_density_for_fm_perp( hkl, space_group_symop, cell, atom_site_susceptibility, h_loc, chi_iso_ferro=chi_iso_ferro, chi_iso_antiferro=chi_iso_antiferro, flag_two_channel=flag_two_channel) f_nucl = crystal.calc_f_nucl(*hkl) l_f_nucl.append(f_nucl) l_v_2d_i.append((v_hkl_perp_2d_i, v_b_ferro, v_b_antiferro)) l_fr_e.append(fr_e) l_fr_s.append(fr_s) l_fm_orb_perp_loc.append(fm_orb_perp_loc) def temp_func(numpy_den=None): l_chi_sq, l_der_chi_sq = [], [] l_der_chi_sq_f, l_der_chi_sq_a = [], [] for diffrn, f_nucl, v_2d_i, fr_e, fr_s, fm_orb_perp_loc in \ zip(l_diffrn, l_f_nucl, l_v_2d_i, l_fr_e, l_fr_s, l_fm_orb_perp_loc): diffrn_refln = diffrn.diffrn_refln f_m_perp, delta_f_m_perp, delta_f_m_perp_f, delta_f_m_perp_a = \ density_point.calc_fm(*v_2d_i) # FIXME: put condition f_m_perp = (f_m_perp[0] + fm_orb_perp_loc[0], f_m_perp[1] + fm_orb_perp_loc[1], f_m_perp[2] + fm_orb_perp_loc[2]) fr_m, delta_fr_m = diffrn.calc_fr(cell, f_nucl, f_m_perp, delta_f_nucl=None, delta_f_m_perp=delta_f_m_perp) delta_fr_m_f = diffrn.calc_fr(cell, f_nucl, f_m_perp, delta_f_nucl=None, delta_f_m_perp=delta_f_m_perp_f)[1] delta_fr_m_a = diffrn.calc_fr(cell, f_nucl, f_m_perp, delta_f_nucl=None, delta_f_m_perp=delta_f_m_perp_a)[1] diffrn_refln.numpy_fr_calc = fr_m chi_sq, der_chi_sq = calc_chi_sq(fr_e, fr_s, fr_m, delta_fr_m) der_chi_sq_f = calc_chi_sq(fr_e, fr_s, fr_m, delta_fr_m_f)[1] der_chi_sq_a = calc_chi_sq(fr_e, fr_s, fr_m, delta_fr_m_a)[1] l_chi_sq.append(chi_sq) l_der_chi_sq.append(der_chi_sq) l_der_chi_sq_f.append(der_chi_sq_f) l_der_chi_sq_a.append(der_chi_sq_a) # print(" ".join([f" {val:10.2f}" for val in l_chi_sq])) return sum(l_chi_sq), sum(l_der_chi_sq), sum(l_der_chi_sq_f), \ sum(l_der_chi_sq_a) chi_sq_best, chi_sq_n_diff = numpy.inf, numpy.inf numpy_density_best, numpy_density_ferro_best = None, None numpy_density_antiferro_best = None delta_chi_sq_best, delta_chi_sq_f_best = None, None delta_chi_sq_a_best = None mult_i = density_point.numpy_multiplicity c_lambda_min = 1e-9 # min value i_cycle = 0 while i_cycle <= n_iterations: i_cycle += 1 numpy_density = density_point.numpy_density numpy_density_ferro = density_point.numpy_density_ferro numpy_density_antiferro = density_point.numpy_density_antiferro chi_sq, delta_chi_sq, delta_chi_sq_f, delta_chi_sq_a = temp_func() chi_sq_n = chi_sq / float(total_peaks) if disp: print(f"cycle {i_cycle:5}. chi_sq/n: {chi_sq_n:.2f} \ {c_lambda*10**5:.3f} {chi_sq_n_diff:.4f}", end="\r") if flag_info: d_info["print"] = f"""Iteration {i_cycle:5}: chi_sq/n: {chi_sq_n:.2f}; c_lambda: {c_lambda*10**5:.3f} * 10**-5; difference of chi_sq/n: {chi_sq_n_diff:.4f}.""" if chi_sq > chi_sq_best: numpy_density = numpy_density_best numpy_density_ferro = numpy_density_ferro_best numpy_density_antiferro = numpy_density_antiferro_best delta_chi_sq = delta_chi_sq_best delta_chi_sq_f = delta_chi_sq_f_best delta_chi_sq_a = delta_chi_sq_a_best c_lambda = 0.5 * c_lambda else: chi_sq_n_diff = (chi_sq_best - chi_sq) / float(total_peaks) chi_sq_best = chi_sq c_lambda = 1.03 * c_lambda if not (flag_two_channel): numpy_density_best = copy.deepcopy(numpy_density) delta_chi_sq_best = copy.deepcopy(delta_chi_sq) numpy_density_ferro_best = copy.deepcopy(numpy_density_ferro) numpy_density_antiferro_best = copy.deepcopy(numpy_density_antiferro) delta_chi_sq_f_best = copy.deepcopy(delta_chi_sq_f) delta_chi_sq_a_best = copy.deepcopy(delta_chi_sq_a) if chi_sq_n < gof_desired: print(f"OUT: cycle {i_cycle:5} chi_sq/n is less than \ {gof_desired:.2f}", end="\r") if flag_info: d_info["print"] = f"""OUT on iteration {i_cycle:5}: chi_sq/n is less than {gof_desired:.2f}.""" break elif ((c_lambda < c_lambda_min) & False): print(f"OUT: cycle {i_cycle:5} chi_sq/n is {chi_sq_n:.2f}. \ c_lambda: {c_lambda:}", end="\r") if flag_info: d_info["print"] = f"""OUT on iteration {i_cycle:5}: chi_sq/n is {chi_sq_n:.2f}. c_lambda less minimal""" if not (flag_two_channel): density_point.numpy_density = numpy_density_best density_point.numpy_density_ferro = numpy_density_ferro_best density_point.numpy_density_antiferro = \ numpy_density_antiferro_best density_point.renormalize_numpy_densities( flag_two_channel=flag_two_channel) break elif ((chi_sq_n_diff < 0.001) and (i_cycle > 10)): print(f"OUT: cycle {i_cycle:5} chi_sq/n is {chi_sq_n:.2f} as diff \ of GoF is less than 0.001.", end="\r") if flag_info: d_info["print"] = f"""OUT on iteration {i_cycle:5}: chi_sq/n is {chi_sq_n:.2f}; difference of GoF is less than 0.001.""" break elif flag_info: if d_info["stop"]: d_info["stop"] = False break delta_chi_sq_f_mult_i = delta_chi_sq_f / mult_i delta_chi_sq_a_mult_i = delta_chi_sq_a / mult_i rel_diff = 0.05 if not (flag_two_channel): delta_chi_sq_mult_i = delta_chi_sq / mult_i c_lambda = choose_max_clambda(c_lambda, numpy_density, delta_chi_sq_mult_i, rel_diff) density_point.numpy_density = numpy_density * numpy.exp( -c_lambda * delta_chi_sq_mult_i) else: c_lambda = choose_max_clambda(c_lambda, numpy_density_ferro, delta_chi_sq_f_mult_i, rel_diff) density_point.numpy_density_ferro = \ numpy_density_ferro*numpy.exp(-c_lambda*delta_chi_sq_f_mult_i) density_point.numpy_density_antiferro = \ numpy_density_antiferro*numpy.exp(-c_lambda*delta_chi_sq_a_mult_i) density_point.renormalize_numpy_densities( flag_two_channel=flag_two_channel) density_point.numpy_to_items() for diffrn in l_diffrn: diffrn.diffrn_refln.numpy_to_items() chi_sq, points = diffrn.diffrn_refln.calc_chi_sq_points() refine_ls = RefineLs(goodness_of_fit_all=chi_sq / points, number_reflns=points) diffrn.add_items([refine_ls]) return density_point
def refine_susceptibility(crystal: Crystal, l_diffrn: List[Diffrn], density_point: DensityPointL, mem_parameters: MEMParameters, disp: bool = True, d_info: dict = None) -> (float, float): """ Refinement of susceptibility. Parameters ---------- crystal : Crystal DESCRIPTION. l_diffrn : TYPE DESCRIPTION. density_point : DensityPointL DESCRIPTION. chi_iso_ferro : float, optional DESCRIPTION. The default is 0.. chi_iso_antiferro : float, optional DESCRIPTION. The default is 0.. flag_ferro : bool, optional DESCRIPTION. The default is True. flag_antiferro : bool, optional DESCRIPTION. The default is True. disp : bool, optional DESCRIPTION. The default is True. Returns ------- float Chi_iso_ferro. float Chi_iso_antiferro. """ flag_info = d_info is not None if flag_info: d_info_keys = d_info.keys() if "stop" not in d_info_keys: d_info["stop"] = False if "print" not in d_info_keys: d_info["print"] = "" crystal.apply_constraints() flag_two_channel = mem_parameters.method == "2channel" cell = crystal.cell space_group = crystal.space_group atom_site = crystal.atom_site space_group_symop = space_group.full_space_group_symop atom_site_susceptibility = crystal.atom_site_susceptibility # l_magnetic_labes = atom_site_susceptibility.label volume = density_point.volume_unit_cell np = density_point.number_unit_cell den_i = density_point.numpy_density den_ferro_i = density_point.numpy_density_ferro den_antiferro_i = density_point.numpy_density_antiferro mult_i = density_point.numpy_multiplicity l_f_nucl, l_fr_e, l_fr_s, l_e_up, l_h_loc = [], [], [], [], [] l_k_hkl, l_phase_3d = [], [] l_chi_perp_ferro, l_chi_perp_antiferro = [], [] total_peaks = 0 for diffrn in l_diffrn: diffrn_orient_matrix = diffrn.diffrn_orient_matrix u_matrix = diffrn_orient_matrix.u e_up = calc_e_up_loc(0., 0., 0., u_matrix) setup = diffrn.setup field = float(setup.field) h_loc = (field * e_up[0], field * e_up[1], field * e_up[2]) diffrn_refln = diffrn.diffrn_refln index_h = numpy.array(diffrn_refln.index_h, dtype=int) index_k = numpy.array(diffrn_refln.index_k, dtype=int) index_l = numpy.array(diffrn_refln.index_l, dtype=int) total_peaks += index_h.size hkl = (index_h, index_k, index_l) fr_e = numpy.array(diffrn_refln.fr, dtype=float) fr_s = numpy.array(diffrn_refln.fr_sigma, dtype=float) f_nucl = crystal.calc_f_nucl(*hkl) k_hkl = cell.calc_k_loc(*hkl) phase_3d = density_point.calc_phase_3d(hkl, space_group_symop) moment_2d, chi_2d_ferro, chi_2d_antiferro = \ density_point.calc_moment_2d( space_group_symop, cell, atom_site_susceptibility, h_loc, chi_iso_ferro=1., chi_iso_antiferro=1., flag_two_channel=flag_two_channel) chi_ferro = calc_fm_by_density(mult_i, den_ferro_i, np, volume, chi_2d_ferro, phase_3d) chi_perp_ferro = calc_moment_perp(k_hkl, chi_ferro) chi_aferro = calc_fm_by_density(mult_i, den_antiferro_i, np, volume, chi_2d_antiferro, phase_3d) chi_perp_aferro = calc_moment_perp(k_hkl, chi_aferro) l_f_nucl.append(f_nucl) l_fr_e.append(fr_e) l_fr_s.append(fr_s) l_e_up.append(e_up) l_h_loc.append(h_loc) l_k_hkl.append(k_hkl) l_phase_3d.append(phase_3d) l_chi_perp_ferro.append(chi_perp_ferro) l_chi_perp_antiferro.append(chi_perp_aferro) l_name_1 = atom_site_susceptibility.get_variable_names() l_par_1_0 = [ atom_site_susceptibility.get_variable_by_name(name) for name in l_name_1 ] l_name_2 = mem_parameters.get_variable_names() l_par_2_0 = [ mem_parameters.get_variable_by_name(name) for name in l_name_2 ] l_name = l_name_1 + l_name_2 l_par_0 = l_par_1_0 + l_par_2_0 def temp_func(l_par): for name, parameter in zip(l_name, l_par): if name[0][0] == "atom_site_susceptibility": atom_site_susceptibility.set_variable_by_name(name, parameter) elif name[0][0] == "mem_parameters": mem_parameters.set_variable_by_name(name, parameter) chi_iso_f = mem_parameters.chi_ferro chi_iso_af = mem_parameters.chi_antiferro atom_site_susceptibility.apply_chi_iso_constraint(cell) atom_site_susceptibility.apply_moment_iso_constraint(cell) atom_site_susceptibility.apply_space_group_constraint( atom_site, space_group) l_chi_sq = [] l_der_chi_sq, l_der_chi_sq_f, l_der_chi_sq_a = [], [], [] # FIXME: add flag for orbital magnetic moment for diffrn, f_nucl, fr_e, fr_s, e_up, h_loc, k_hkl, phase_3d, \ chi_perp_ferro, chi_perp_aferro in \ zip(l_diffrn, l_f_nucl, l_fr_e, l_fr_s, l_e_up, l_h_loc, l_k_hkl, l_phase_3d, l_chi_perp_ferro, l_chi_perp_antiferro): moment_2d, moment_ferro, moment_antiferro = \ density_point.calc_moment_2d( space_group_symop, cell, atom_site_susceptibility, h_loc, chi_iso_ferro=1., chi_iso_antiferro=1., flag_two_channel=flag_two_channel) f_m = calc_fm_by_density(mult_i, den_i, np, volume, moment_2d, phase_3d) f_m_perp = calc_moment_perp(k_hkl, f_m) # # correction on orbital moment # diffrn_refln = diffrn.diffrn_refln # setup = diffrn.setup # field = setup.field # ind_h = diffrn_refln.numpy_index_h # ind_k = diffrn_refln.numpy_index_k # ind_l = diffrn_refln.numpy_index_l # chi_m = crystal.calc_susceptibility_moment_tensor( # ind_h, ind_k, ind_l, flag_only_orbital=True) # sft_ij = chi_m[:9] # sftm_ij = chi_m[9:] # fm_orb_perp_loc = calc_fm_perp_loc(e_up, field, k_hkl, sft_ij, # sftm_ij) # add ferro and anti_ferro f_m_perp_sum = (f_m_perp[0] + chi_iso_f * chi_perp_ferro[0] + chi_iso_af * chi_perp_aferro[0], f_m_perp[1] + chi_iso_f * chi_perp_ferro[1] + chi_iso_af * chi_perp_aferro[1], f_m_perp[2] + chi_iso_f * chi_perp_ferro[2] + chi_iso_af * chi_perp_aferro[2]) fr_m, delta_fr_m = diffrn.calc_fr(cell, f_nucl, f_m_perp_sum, delta_f_m_perp=f_m_perp) delta_fr_m_f = delta_fr_m delta_fr_m_a = delta_fr_m diffrn.diffrn_refln.numpy_fr_calc = fr_m chi_sq, der_chi_sq = calc_chi_sq(fr_e, fr_s, fr_m, delta_fr_m) der_chi_sq_f = calc_chi_sq(fr_e, fr_s, fr_m, delta_fr_m_f)[1] der_chi_sq_a = calc_chi_sq(fr_e, fr_s, fr_m, delta_fr_m_a)[1] l_chi_sq.append(chi_sq) l_der_chi_sq.append(der_chi_sq) l_der_chi_sq_f.append(der_chi_sq_f) l_der_chi_sq_a.append(der_chi_sq_a) return sum(l_chi_sq) chi_sq = temp_func(l_par_0) print(f"Chi_sq before optimization {chi_sq/total_peaks:.5f}. ", end="\r") if flag_info: d_info["print"] = \ f"Chi_sq/n before optimization {chi_sq/total_peaks:.5f}." res = scipy.optimize.minimize( temp_func, l_par_0, method="BFGS", callback=lambda x: func_temp(x, param_name=l_name, d_info=d_info), options={"eps": 0.001}) l_param = res.x chi_sq_new = res.fun hess_inv = res["hess_inv"] sigma = (abs(numpy.diag(hess_inv)))**0.5 print(f"Chi_sq after optimization {chi_sq_new/total_peaks:.5f}. ", end="\r") if flag_info: d_info["print"] = \ f"Chi_sq/n after optimization {chi_sq_new/total_peaks:.5f}." for name, parameter, sig in zip(l_name, l_param, sigma): name_sig = name[:-1] + ((f"{name[-1][0]:}_sigma", name[-1][1]), ) if name[0][0] == "atom_site_susceptibility": atom_site_susceptibility.set_variable_by_name(name, parameter) atom_site_susceptibility.set_variable_by_name(name_sig, sig) elif name[0][0] == "mem_parameters": mem_parameters.set_variable_by_name(name, parameter) mem_parameters.set_variable_by_name(name_sig, sig) for diffrn in l_diffrn: diffrn.diffrn_refln.numpy_to_items() chi_sq, points = diffrn.diffrn_refln.calc_chi_sq_points() refine_ls = RefineLs(goodness_of_fit_all=chi_sq / points, number_reflns=points) diffrn.add_items([refine_ls])
def calc_chi_sq(self, l_crystal, flag_internal: bool = True): """ Calculate chi square. Arguments --------- - l_crystal: a list of Crystal objects of cryspy library - flag_internal: a flag to calculate internal objects (default is True) Output arguments ---------------- - chi_sq_val: chi square of flip ratio (Sum_i ((y_e_i - y_m_i) / sigma_i)**2) - n: number of measured reflections """ meas = self.pd2d_meas tth = meas.ttheta phi = meas.phi int_u_exp = meas.intensity_up sint_u_exp = meas.intensity_up_sigma int_d_exp = meas.intensity_down sint_d_exp = meas.intensity_down_sigma l_peak_in, l_refln_in = [], [] l_refln_susceptibility_in = [] l_dd_in = [] flag_1 = not(flag_internal) try: dd = self.dd flag_2 = True except AttributeError: flag_2 = False if (flag_1 & flag_2): for phase_item in self.phase.items: crystal = None for cryst in l_crystal: if cryst.data_name.lower() == phase_item.label.lower(): crystal = cryst break attr_peak = f"pd2d_peak_{crystal.data_name:}" attr_refln = f"refln_{crystal.data_name:}" attr_refln_s = f"refln_susceptibility_{crystal.data_name:}" l_peak_in.append(getattr(self, attr_peak)) l_refln_in.append(getattr(self, attr_refln)) l_refln_susceptibility_in.append(getattr(self, attr_refln_s)) cond_tth_in = numpy.ones(tth.size, dtype=bool) cond_phi_in = numpy.ones(phi.size, dtype=bool) try: range_ = self.range cond_tth_in = numpy.logical_and(cond_tth_in, tth >= range_.ttheta_min) cond_tth_in = numpy.logical_and(cond_tth_in, tth <= range_.ttheta_max) cond_phi_in = numpy.logical_and(cond_phi_in, phi >= range_.phi_min) cond_phi_in = numpy.logical_and(cond_phi_in, phi <= range_.phi_max) except AttributeError: pass # cond_1_in, cond_2_in = numpy.meshgrid(cond_tth_in, cond_phi_in, # indexing="ij") # cond_in = numpy.logical_and(cond_1_in, cond_2_in) tth_in = tth[cond_tth_in] phi_in = phi[cond_phi_in] int_u_exp_in = int_u_exp[cond_tth_in, :][:, cond_phi_in] sint_u_exp_in = sint_u_exp[cond_tth_in, :][:, cond_phi_in] int_d_exp_in = int_d_exp[cond_tth_in, :][:, cond_phi_in] sint_d_exp_in = sint_d_exp[cond_tth_in, :][:, cond_phi_in] proc, l_peak, l_refln, l_dd_out = self.calc_profile( tth_in, phi_in, l_crystal, l_peak_in=l_peak_in, l_refln_in=l_refln_in, l_refln_susceptibility_in=l_refln_susceptibility_in, l_dd_in=l_dd_in, flag_internal=flag_internal) proc.intensity_up = int_u_exp_in proc.intensity_up_sigma = sint_u_exp_in proc.intensity_down = int_d_exp_in proc.intensity_down_sigma = sint_d_exp_in # self.proc = proc # self.peaks = l_peak # self.reflns = l_refln self.dd = l_dd_out int_u_mod = proc.intensity_up_total int_d_mod = proc.intensity_down_total sint_sum_exp_in = (sint_u_exp_in**2 + sint_d_exp_in**2)**0.5 chi_sq_u = ((int_u_mod-int_u_exp_in)/sint_u_exp_in)**2 chi_sq_d = ((int_d_mod-int_d_exp_in)/sint_d_exp_in)**2 chi_sq_sum = ((int_u_mod+int_d_mod-int_u_exp_in-int_d_exp_in) / sint_sum_exp_in)**2 chi_sq_dif = ((int_u_mod-int_d_mod-int_u_exp_in+int_d_exp_in) / sint_sum_exp_in)**2 cond_u = numpy.logical_not(numpy.isnan(chi_sq_u)) cond_d = numpy.logical_not(numpy.isnan(chi_sq_d)) cond_sum = numpy.logical_not(numpy.isnan(chi_sq_sum)) cond_dif = numpy.logical_not(numpy.isnan(chi_sq_dif)) # exclude region try: exclude = self.exclude l_excl_tth_min = exclude.numpy_ttheta_min l_excl_tth_max = exclude.numpy_ttheta_max l_excl_phi_min = exclude.numpy_phi_min l_excl_phi_max = exclude.numpy_phi_max for excl_tth_min, excl_tth_max, excl_phi_min, excl_phi_max in \ zip(l_excl_tth_min, l_excl_tth_max, l_excl_phi_min, l_excl_phi_max): cond_1 = numpy.logical_or(tth_in < 1.*excl_tth_min, tth_in > 1.*excl_tth_max) cond_2 = numpy.logical_or(phi_in < 1.*excl_phi_min, phi_in > 1.*excl_phi_max) cond_11, cond_22 = numpy.meshgrid(cond_1, cond_2, indexing="ij") cond_12 = numpy.logical_or(cond_11, cond_22) cond_u = numpy.logical_and(cond_u, cond_12) cond_d = numpy.logical_and(cond_d, cond_12) cond_sum = numpy.logical_and(cond_sum, cond_12) except AttributeError: pass chi_sq_u_val = (chi_sq_u[cond_u]).sum() n_u = cond_u.sum() chi_sq_d_val = (chi_sq_d[cond_d]).sum() n_d = cond_d.sum() chi_sq_sum_val = (chi_sq_sum[cond_sum]).sum() n_sum = cond_sum.sum() chi_sq_dif_val = (chi_sq_dif[cond_dif]).sum() n_dif = cond_dif.sum() chi2 = self.chi2 flag_u = chi2.up flag_d = chi2.down flag_sum = chi2.sum flag_dif = chi2.diff chi_sq_val = (int(flag_u)*chi_sq_u_val + int(flag_d)*chi_sq_d_val + int(flag_sum)*chi_sq_sum_val + int(flag_dif)*chi_sq_dif_val) n = (int(flag_u)*n_u + int(flag_d)*n_d + int(flag_sum)*n_sum + int(flag_dif)*n_dif) # print(f"chi_sq_val/n: {chi_sq_val/n:.2f} \ # chi_sq_val: {chi_sq_val: .2f}") # d_exp_out = {"chi_sq_val": chi_sq_val, "n": n} # d_exp_out.update(d_exp_prof_out) if flag_internal: refine_ls = RefineLs(number_reflns=n, goodness_of_fit_all=chi_sq_val/float(n), weighting_scheme="sigma") self.refine_ls = refine_ls proc.form_ttheta_phi_intensity_bkg_calc() proc.form_ttheta_phi_intensity_up() proc.form_ttheta_phi_intensity_up_sigma() proc.form_ttheta_phi_intensity_down() proc.form_ttheta_phi_intensity_down_sigma() return chi_sq_val, n
def calc_chi_sq(self, l_crystal, flag_internal=True): """ Calculate chi square. Arguments --------- - l_crystal: a list of Crystal objects of cryspy library - flag_internal: a flag to calculate or to use internal objects. It should be True if user call the function. It's True by default. Output ------ - chi_sq_val: chi square of flip ratio (Sum_i ((y_e_i - y_m_i) / sigma_i)**2) - n: number of measured reflections """ tof_meas = self.tof_meas flag_polarized = tof_meas.is_polarized() np_time = tof_meas.numpy_time if flag_polarized: int_u_exp = tof_meas.numpy_intensity_up sint_u_exp = tof_meas.numpy_intensity_up_sigma int_d_exp = tof_meas.numpy_intensity_down sint_d_exp = tof_meas.numpy_intensity_down_sigma else: int_exp = tof_meas.numpy_intensity sint_exp = tof_meas.numpy_intensity_sigma cond_in = numpy.ones(np_time.shape, dtype=bool) try: range_ = self.range time_min = numpy.array(range_.time_min, dtype=float) time_max = numpy.array(range_.time_max, dtype=float) cond_in = numpy.logical_and(cond_in, np_time >= time_min) cond_in = numpy.logical_and(cond_in, np_time <= time_max) except AttributeError: pass np_time_in = np_time[cond_in] if flag_polarized: int_u_exp_in = int_u_exp[cond_in] sint_u_exp_in = sint_u_exp[cond_in] int_d_exp_in = int_d_exp[cond_in] sint_d_exp_in = sint_d_exp[cond_in] else: int_exp_in = int_exp[cond_in] sint_exp_in = sint_exp[cond_in] tof_proc = self.calc_profile( np_time_in, l_crystal, flag_internal=flag_internal, flag_polarized=flag_polarized) if flag_polarized: tof_proc.numpy_intensity_up = int_u_exp_in tof_proc.numpy_intensity_up_sigma = sint_u_exp_in tof_proc.numpy_intensity_down = int_d_exp_in tof_proc.numpy_intensity_down_sigma = sint_d_exp_in tof_proc.numpy_intensity = int_u_exp_in+int_d_exp_in tof_proc.numpy_intensity_sigma = numpy.sqrt( numpy.square(sint_u_exp_in) + numpy.square(sint_d_exp_in)) else: tof_proc.numpy_intensity = int_exp_in tof_proc.numpy_intensity_sigma = sint_exp_in int_u_mod = tof_proc.numpy_intensity_up_total int_d_mod = tof_proc.numpy_intensity_down_total if flag_polarized: sint_sum_exp_in = (sint_u_exp_in**2 + sint_d_exp_in**2)**0.5 chi_sq_u = ((int_u_mod-int_u_exp_in)/sint_u_exp_in)**2 chi_sq_d = ((int_d_mod-int_d_exp_in)/sint_d_exp_in)**2 chi_sq_sum = ((int_u_mod+int_d_mod-int_u_exp_in-int_d_exp_in) / sint_sum_exp_in)**2 chi_sq_dif = ((int_u_mod-int_d_mod-int_u_exp_in+int_d_exp_in) / sint_sum_exp_in)**2 cond_u = numpy.logical_not(numpy.isnan(chi_sq_u)) cond_d = numpy.logical_not(numpy.isnan(chi_sq_d)) cond_sum = numpy.logical_not(numpy.isnan(chi_sq_sum)) cond_dif = numpy.logical_not(numpy.isnan(chi_sq_dif)) else: chi_sq_sum = ((int_u_mod+int_d_mod-int_exp_in)/sint_exp_in)**2 cond_sum = numpy.logical_not(numpy.isnan(chi_sq_sum)) # exclude region try: exclude = self.exclude l_excl_time_min = exclude.time_low l_excl_time_max = exclude.time_high if flag_polarized: for excl_time_min, excl_time_max in zip(l_excl_time_min, l_excl_time_max): cond_1 = numpy.logical_or(np_time_in < 1.*excl_time_min, np_time_in > 1.*excl_time_max) cond_u = numpy.logical_and(cond_u, cond_1) cond_d = numpy.logical_and(cond_d, cond_1) cond_sum = numpy.logical_and(cond_sum, cond_1) else: for excl_time_min, excl_time_max in zip(l_excl_time_min, l_excl_time_max): cond_1 = numpy.logical_or(np_time_in < 1.*excl_time_min, np_time_in > 1.*excl_time_max) cond_sum = numpy.logical_and(cond_sum, cond_1) except AttributeError: pass tof_proc.numpy_excluded = numpy.logical_not(cond_sum) chi_sq_sum_val = (chi_sq_sum[cond_sum]).sum() n_sum = cond_sum.sum() if flag_polarized: chi_sq_u_val = (chi_sq_u[cond_u]).sum() n_u = cond_u.sum() chi_sq_d_val = (chi_sq_d[cond_d]).sum() n_d = cond_d.sum() chi_sq_dif_val = (chi_sq_dif[cond_dif]).sum() n_dif = cond_dif.sum() chi2 = self.chi2 flag_u = chi2.up flag_d = chi2.down flag_sum = chi2.sum flag_dif = chi2.diff chi_sq_val = (int(flag_u)*chi_sq_u_val + int(flag_d)*chi_sq_d_val + int(flag_sum)*chi_sq_sum_val + int(flag_dif)*chi_sq_dif_val) n = (int(flag_u)*n_u + int(flag_d)*n_d + int(flag_sum)*n_sum + int(flag_dif)*n_dif) else: chi_sq_val = chi_sq_sum_val n = n_sum if flag_internal: refine_ls = RefineLs(number_reflns=n, goodness_of_fit_all=chi_sq_val/float(n), weighting_scheme="sigma") self.refine_ls = refine_ls tof_proc.numpy_to_items() return chi_sq_val, n
def calc_fr(self): """Calculate Flip Ratios for diffraction experiments.""" crystal = self.crystals()[0] # FIXME: l_diffrn = self.experiments() # FIXME: density_point = self.density_point mem_parameters = self.mem_parameters chi_iso_ferro = mem_parameters.chi_ferro chi_iso_antiferro = mem_parameters.chi_antiferro flag_two_channel = mem_parameters.method == "2channel" cell = crystal.cell space_group = crystal.space_group space_group_symop = space_group.full_space_group_symop atom_site_susceptibility = crystal.atom_site_susceptibility # FIXME: temporary solution of calculation rbs_i if it's not defined density_point.calc_rbs_i(space_group_symop, points_a=mem_parameters.points_a, points_b=mem_parameters.points_b, points_c=mem_parameters.points_c) total_peaks = 0 den_i = numpy.array(density_point.density, dtype=float) den_ferro_i = numpy.array(density_point.density_ferro, dtype=float) den_antiferro_i = numpy.array(density_point.density_antiferro, dtype=float) mult_i = numpy.array(density_point.multiplicity, dtype=int) volume = cell.volume n_points = mult_i.sum() for diffrn in l_diffrn: diffrn_orient_matrix = diffrn.diffrn_orient_matrix e_up = diffrn_orient_matrix.calc_e_up() setup = diffrn.setup field = float(setup.field) h_loc = (field * e_up[0], field * e_up[1], field * e_up[2]) diffrn_refln = diffrn.diffrn_refln index_h = numpy.array(diffrn_refln.index_h, dtype=int) index_k = numpy.array(diffrn_refln.index_k, dtype=int) index_l = numpy.array(diffrn_refln.index_l, dtype=int) total_peaks += index_h.size hkl = (index_h, index_k, index_l) f_nucl = crystal.calc_f_nucl(*hkl) k_hkl = cell.calc_k_loc(*hkl) phase_3d = density_point.calc_phase_3d(hkl, space_group_symop) moment_2d, chi_2d_ferro, chi_2d_antiferro = \ density_point.calc_moment_2d( space_group_symop, cell, atom_site_susceptibility, h_loc, chi_iso_ferro=1., chi_iso_antiferro=1., flag_two_channel=flag_two_channel) chi_ferro = calc_fm_by_density(mult_i, den_ferro_i, n_points, volume, chi_2d_ferro, phase_3d) chi_perp_ferro = calc_moment_perp(k_hkl, chi_ferro) chi_aferro = calc_fm_by_density(mult_i, den_antiferro_i, n_points, volume, chi_2d_antiferro, phase_3d) chi_perp_aferro = calc_moment_perp(k_hkl, chi_aferro) f_m = calc_fm_by_density(mult_i, den_i, n_points, volume, moment_2d, phase_3d) f_m_perp = calc_moment_perp(k_hkl, f_m) f_m_perp_sum = (f_m_perp[0] + chi_iso_ferro * chi_perp_ferro[0] + chi_iso_antiferro * chi_perp_aferro[0], f_m_perp[1] + chi_iso_ferro * chi_perp_ferro[1] + chi_iso_antiferro * chi_perp_aferro[1], f_m_perp[2] + chi_iso_ferro * chi_perp_ferro[2] + chi_iso_antiferro * chi_perp_aferro[2]) fr_m, delta_fr_m = diffrn.calc_fr(cell, f_nucl, f_m_perp_sum, delta_f_m_perp=f_m_perp) diffrn.diffrn_refln.numpy_fr_calc = fr_m for diffrn in l_diffrn: diffrn.diffrn_refln.numpy_to_items() chi_sq, points = diffrn.diffrn_refln.calc_chi_sq_points() refine_ls = RefineLs(goodness_of_fit_all=chi_sq / points, number_reflns=points) diffrn.add_items([refine_ls])