import olex, olx
from olexex import OlexRefinementModel
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