import olex, olx
from olexex import OlexRefinementModel
from scitbx.array_family import flex
import numpy as np
from olexFunctions import OV
class RefinementChecks(object):
def __init__(self, cctbx):
self.cctbx = cctbx
self.refinement_has_failed = []
def check_PDF(self, force=False):
RM = OlexRefinementModel()
any_have_anh = False
label_list = []
for i, atom in enumerate(RM._atoms):
anh_adp = atom.get('anharmonic_adp')
if anh_adp == None:
continue
any_have_anh = True
label_list.append(atom['label'])
if any_have_anh == True:
if OV.HasGUI():
olex.m("PDF")
else:
olex.m("spy.NoSpherA2.PDF_map(0.1,1,true,true,true,true,false,false)")
problem = OV.GetVar("Negative_PDF")
Kuhs = OV.GetVar("Kuhs_Rule")
err_list = []
if problem == True:
err_list.append("Negative PDF found")
if force == True:
print("Making all anharmonic atoms hamrnoic again!")
for label in label_list:
print(label)
olex.m("anis %s" % label)
if Kuhs == True:
err_list.append("Kuhs' rule not fulfilled")
if err_list:
self.refinement_has_failed.extend(err_list)
def check_occu(self):
scatterers = self.cctbx.normal_eqns.xray_structure.scatterers()
wrong_occu = []
for sc in scatterers:
if sc.flags.grad_occupancy():
if sc.occupancy < 0 or sc.occupancy > 1.0:
wrong_occu.append(sc.label)
if len(wrong_occu) != 0:
if len(wrong_occu) == 1:
self.refinement_has_failed.append(f"{wrong_occu[0]} has unreasonable Occupancy")
else:
_ = ", ".join(wrong_occu)
self.refinement_has_failed.append(f"{_} have unreasonable Occupancy")
def check_disp(self):
scatterers = self.cctbx.normal_eqns.xray_structure.scatterers()
refined_disp = []
for sc in scatterers:
if sc.flags.grad_fp() or sc.flags.grad_fdp():
fp, fdp = sc.fp, sc.fdp
refined_disp.append((sc, fp, fdp))
if refined_disp != []:
wavelength = float(olx.xf.exptl.Radiation())
from cctbx.eltbx import sasaki
from cctbx.eltbx import henke
from brennan import brennan
tables = [sasaki, henke, brennan()]
unreasonable_fp = []
unreasonable_fdp = []
for sc, fp, fdp in refined_disp:
e = str(sc.element_symbol())
table = []
for t in tables:
table.append(t.table(e))
fp_min_max = [135.0, 0.0]
fdp_min_max = [135.0, 0.0]
fp_average = 0.0
fdp_average = 0.0
for t in table:
temp = t.at_angstrom(wavelength)
fp_average += temp.fp()
fdp_average += temp.fdp()
fp_min_max = [min(fp_min_max[0], temp.fp()), max(fp_min_max[1], temp.fp())]
fdp_min_max = [min(fdp_min_max[0], temp.fdp()), max(fdp_min_max[1], temp.fdp())]
fp_average /= len(tables)
fdp_average /= len(tables)
fpdiff = (fp_min_max[1] - fp_min_max[0])
fdpdiff = (fdp_min_max[1] - fdp_min_max[0])
if fp_average + 2 * fpdiff < fp or fp_average - 2 * fpdiff > fp:
unreasonable_fp.append(sc.label)
if fdp_average + 2 * fdpdiff < fdp or fdp_average - 2 * fdpdiff > fdp:
unreasonable_fdp.append(sc.label)
if len(unreasonable_fdp) != 0:
if len(unreasonable_fdp) == 1:
self.refinement_has_failed.append("%s has strongly deviating f''" % unreasonable_fdp[0])
else:
self.refinement_has_failed.append("%s have strongly deviating f''" % ",".join(unreasonable_fdp))
if len(unreasonable_fp) != 0:
if len(unreasonable_fp) == 1:
self.refinement_has_failed.append("%s has strongly deviating f'" % unreasonable_fp[0])
else:
self.refinement_has_failed.append("%s have strongly deviating f'" % ",".join(unreasonable_fp))
def check_mu(self):
try:
mu = self.cctbx.normal_eqns.iterations_object.mu
if mu > 1E1:
self.refinement_has_failed.append("Mu of LM is very large!")
except AttributeError:
return
def check_corr(self):
try:
m_and_a = self.cctbx.normal_eqns.covariance_matrix_and_annotations()
annotations = m_and_a.annotations
n = len(annotations)
nf = m_and_a.matrix.as_numpy_array()
counter = 0
cov_array = []
arr_counter = 0
for i in range(n):
for j in range(n-counter):
cov_array.append(nf[arr_counter])
arr_counter += 1
counter +=1
for k in range(counter):
cov_array.append(0)
cov_Array2 = np.array(cov_array[:-n])
cov_array = cov_Array2.reshape((n,n))
corrMat = np.corrcoef(cov_array)
iu_nodiag = np.triu_indices(n, k=1)
strong_mask = np.abs(corrMat[iu_nodiag]) > 0.75
strong_corr_count = np.sum(strong_mask)
print(f"List of correlations > 0.75:\nThere are {strong_corr_count} strong correlations")
print("==================================")
for i,j,corr in zip(iu_nodiag[0][strong_mask], iu_nodiag[1][strong_mask], corrMat[iu_nodiag][strong_mask]):
print(f" {annotations[i]:<10} v {annotations[j]:<10}: {corr:>6.3f}")
print("==================================")
except Exception as e:
import traceback
traceback.print_exc()
print(f"Error reading vcv matrix for calculation of correlations {e}")
return