import os import re from fractions import Fraction from olexFunctions import OV import OlexVFS try: from_outside = False p_path = os.path.dirname(os.path.abspath(__file__)) except: from_outside = True p_path = os.path.dirname(os.path.abspath("__file__")) import olx import olex import iotbx.cif.model import CifInfo debug = OV.IsDebugging() global mask_info_has_updated mask_info_has_updated = False gui_green = OV.GetParam('gui.green').hexadecimal gui_orange = OV.GetParam('gui.orange').hexadecimal gui_red = OV.GetParam('gui.red').hexadecimal gui_grey = OV.GetParam('gui.grey').hexadecimal gui_light_grey = OV.GetParam('gui.light_grey').hexadecimal gui_highlight = OV.GetParam('gui.html.highlight_colour').hexadecimal gui_width = OV.GetParam('gui.htmlpanelwidth') OV.SetParam('snum.masks.special_detail_colour', gui_green) from PeriodicTable import PeriodicTable PT = PeriodicTable() pt = PT.PeriodicTable() import gui template_path = os.path.join(OV.DataDir(), 'mask_output.htm') if not os.path.exists(template_path): template_path = os.path.join(p_path, 'mask_output.htm') def get_mask_info(): if not olx.cif_model: import CifInfo CifInfo.ExtractCifInfo() global mask_info_has_updated import gui output_fn = '%s_masking_info.htm' % OV.ModelSrc() if OV.GetVar("current_mask_sqf"): if bool(OlexVFS.exists(output_fn)): return output_fn else: return return_note(note="A mask has been applied, but no masking information is available.", col=gui_red) get_template = gui.tools.TemplateProvider.get_template if olx.IsFileLoaded() != 'true': return return_note("") if (olx.IsFileType('cif') == 'true'): return return_note("") based_on = OV.GetParam('user.masks.based_on') based_on_display = "Asymmetric Unit" if based_on == "FU": based_on_display = "Formula Unit" elif based_on == "Cell": based_on_display = "Unit Cell" # print ".. %s .." %template_path global current_sNum current_sNum = OV.ModelSrc().replace(" ", "") prg = OV.GetParam('snum.refinement.recompute_mask_before_refinement_prg', "Olex2") if prg == "Platon": base = "platon_squeeze" else: base = "smtbx_masks" # change_hklsrc_according_to_mask_prg(prg) d = {} d['table_bg'] = olx.GetVar('HtmlTableBgColour') d['based_on'] = based_on d['based_on_display'] = based_on_display d['row_begin'] = get_template('row_begin', path=template_path, force=debug) % d d['row_end'] = get_template('row_end', path=template_path, force=debug) % d d['table_begin'] = get_template('table_begin', path=template_path, force=debug) % d d["note"] = "No Masking Information" d["note_bg"] = OV.GetVar('HtmlHighlightCOlour') d["masking_info_src"] = OV.GetVar("masking_info_src", "") d["masking_src"] = OV.GetVar("masking_info_src", "") d["masking_info_dte"] = OV.GetVar("masking_info_dte", "") d["masking_dte"] = OV.GetVar("masking_dte", "") _ = escape_param_names(name=OV.ModelSrc()) mask_special_details_vn = "%s_%s" % (_, "mask_special_details") is_CIF = (olx.IsFileType('cif') == 'true') sqf = None if is_CIF: volumes = olx.Cif('_%s_void_volume' % base).split(",") electrons = olx.Cif('_%s_void_count_electrons' % base).split(",") contents = olx.Cif('_%s_void_content' % base).split(",") details = olx.Cif('_%s_details' % base).split(",") mask_special_details = olx.Cif('_%s_special_details' % base).split(",") mask_special_details = mask_special_details[0].strip().lstrip("'").rstrip("'") else: try: sqf_f = get_sqf_name() rFile = open(sqf_f, 'r').read() if "platon_squeeze" in rFile: if base != "platon_squeeze": return return_note(note="SQUEEZE output found, but was looking for olex2.mask output", col=gui_green) if not rFile.startswith("data_"): rFile = "data_%s\n" % str(current_sNum) + rFile sqf = iotbx.cif.fast_reader(input_string=rFile).model() except Exception as err: return return_note(note="No masking info yet! ", col=gui_orange) if sqf: if current_sNum not in sqf: sqf_block = sqf[sqf.keys()[0]] OV.PrintMaskHKLWarning( "Warning: mask data name (%s) does not match file name (%s) - check HKL file used for the refinement!" % (sqf.keys()[0], current_sNum)) else: sqf_block = sqf[current_sNum] olx.cif_model[current_sNum].update(sqf_block) volumes = olx.cif_model[current_sNum].get('_%s_void_volume' % base) if not volumes: return return_note(note="No void has been found.", col=gui_orange) electrons = olx.cif_model[current_sNum].get('_%s_void_count_electrons' % base) contents = olx.cif_model[current_sNum].get('_%s_void_content' % base) details = olx.cif_model[current_sNum].get('_%s_details' % base) mask_special_details = olx.cif_model[current_sNum].get('_%s_special_details' % base) if mask_special_details: mask_special_details = mask_special_details.strip() numbers = olx.cif_model[current_sNum].get('_%s_void_nr' % base, None) if numbers == ['n/a']: return return_note(note="No Voids Found", col=gui_green) if not numbers: numbers = olx.cif_model[current_sNum].get('_%s_void_nr' % base) if not numbers: if is_CIF: numbers = olx.Cif('_%s_void_nr' % base).split(",") if not numbers: return return_note(note="No Voids in CIF", col=gui_green) Z = float(olx.xf.au.GetZ()) Zprime = float(olx.xf.au.GetZprime()) number_of_symm_op = round(Z / Zprime) Z = round(Z) Zprime = Z / number_of_symm_op t = get_template('mask_output_table_begin', path=template_path, force=debug) % d t += get_template('mask_output_table_header_rp', path=template_path, force=debug) % d ident_l = [] for number, volume, electron, content in zip(numbers, volumes, electrons, contents): volume = "%.0f" % round(float(volume), 0) electron = "%.0f" % round(float(electron), 0) ident_l.append((volume, electron)) accounted_for = {} sum_content = [] sum_e = 0 total_void_volume = 0 total_void_electrons = 0 total_void_accounted_for_electrons = 0 total_void_no = 0 f = get_adjust_for_base_factor() for number, volume, electron, content in zip(numbers, volumes, electrons, contents): multi_idx = [] electrons_accounted_for = 0 non_h_accounted_for = 0 volume = float(volume) electron = float(electron) volume = "%.0f" % round(volume, 0) electron = "%.0f" % round(electron, 0) _ = (volume, electron) got_it = False for accounted_for_entry in accounted_for: if volume in accounted_for_entry: got_it = True if got_it: continue multiplicity = 0 i = 1 _idx = [] for occ in ident_l: # if _ == occ: if volume == occ[0]: multiplicity += 1 _idx.append(str(i)) i += 1 for bit in _idx: multi_idx.append("%s|%s" % (bit, multiplicity)) accounted_for.setdefault(volume, []) accounted_for[volume].append(_[0]) moiety = OV.get_cif_item('_chemical_formula_moiety', None) if not moiety or "[]" in moiety or "[+ solvents]" in moiety: moiety = olx.xf.latt.GetMoiety() electron = float(electron) * multiplicity volume = float(volume) * multiplicity if float(volume) < 15: continue #f = get_adjust_for_base_factor() #volume *= f #electron *= f d['number'] = number d['electron'] = "%.0f" % float(electron) d['volume'] = "%.0f" % float(volume) d['multiplicity'] = format_number(multiplicity) d['formula'] = get_rounded_formula(as_string_sep=" ") d['moiety'] = moiety d['based_on'] = based_on d['based_on_display'] = based_on_display total_void_electrons += electron total_void_volume += volume total_void_no += 1 content = content.strip("'") _ = content.split(",") content_disp_l = [] for entry in _: if not entry or entry == "?": continue sum_content.append((multiplicity, entry)) entity, user_number = split_entity(entry) user_number = float(user_number) ent = moieties.get(entity.lower(), entity) ent = formula_cleaner(str(ent)) try: Z, N = get_sum_electrons_from_formula(ent) electrons_accounted_for += Z * user_number non_h_accounted_for += N * user_number except: electrons_accounted_for += 0 if entity and entity != "?": _ = "%s %s" % (format_number(multiplicity * user_number / f), entity) if ent: content_disp_l.append(_) else: content_disp_l.append("%s" % (gui.red, _)) else: _ = "%s" % (gui.red, entity) content_disp_l.append(_) content_disp = ", ".join(content_disp_l) electrons_accounted_for = electrons_accounted_for * multiplicity non_h_accounted_for = non_h_accounted_for * multiplicity if volume == "n/a": return total_void_accounted_for_electrons += electrons_accounted_for eaf = electrons_accounted_for eafd = "%.0f" % (electrons_accounted_for / f) electron_bg = gui_red electron_fg = "#eeeeee" if eaf - (0.1 * eaf) < float(electron) < eaf + (0.1 * eaf): electron_bg = gui_green elif eaf - (0.2 * eaf) < float(electron) < eaf + (0.2 * eaf): electron_bg = gui_orange e_accounted_for_display = eafd if float(electron) != 0: v_over_e = float(volume) / float(electron) if v_over_e < OV.GetParam('user.masks.v_over_e.lower'): v_over_e_html = "%.1f " % (gui_red, v_over_e) elif v_over_e > OV.GetParam('user.masks.v_over_e.upper'): v_over_e_html = "%.1f " % (gui_red, v_over_e) else: v_over_e_html = "%.1f " % (gui_green, v_over_e) else: v_over_e_html = "n/a" d['v_over_e'] = v_over_e_html if float(volume) != 0: v_over_n_html = "n/a" if non_h_accounted_for != 0: v_over_n = float(volume) / non_h_accounted_for if v_over_n < 20: v_over_n_html = "%.1f " % (gui_red, v_over_n) elif v_over_n > 50: v_over_n_html = "%.1f " % (gui_red, v_over_n) else: v_over_n_html = "%.1f " % (gui_green, v_over_n) try: float(content_disp) content_disp = "" except: pass d['v_over_n'] = v_over_n_html d['content_disp'] = content_disp d['multi_idx'] = ":".join(multi_idx) content = get_template('mask_content_with_edit', path=template_path, force=debug) % d details = ' (Edit)' % ":".join(multi_idx) d['content'] = content d['details'] = details d['e_accounted_for_display'] = e_accounted_for_display d['electron_bg'] = electron_bg d['electron_fg'] = electron_fg d['electrons_disp'] = electron / f d['volume_disp'] = volume / f d['e_accounted_for_raw'] = electrons_accounted_for t += get_template('mask_output_table_row_rp', path=template_path, force=debug) % d t += get_template('mask_output_based_on', path=template_path, force=debug) % d #-- FINAL BLOCK ############### total_formula = get_rounded_formula() total_electrons_accounted_for = 0 add_to_formula = "" add_to_moiety = "" for entry in sum_content: entity = entry[1] if "?" in entity: add_to_moiety = "[+ solvents]" continue multiplicity = float(entry[0]) entity, multi = split_entity(entity) multi = float(multi) ent = moieties.get(entity.lower(), entity) ent_disp = ent.replace(" ", "") ent = " ".join(re.findall(r'\d+|[A-Z][a-z]*', ent)) ent = formula_cleaner(str(ent)) try: total_electrons_accounted_for += get_sum_electrons_from_formula(ent)[0] * user_number * number_of_symm_op except: total_electrons_accounted_for += 0 f = number_of_symm_op * Zprime add_to_formula = _add_formula(add_to_formula, ent, multi / f * multiplicity) add_to_moiety += "%s[%s], " % (format_number(multi / f * multiplicity), ent_disp) total_formula = _add_formula(total_formula, add_to_formula, 1) add_to_moiety = add_to_moiety.rstrip(", ") if not add_to_moiety: add_to_moiety = OV.GetVar(get_sqf_name() + "_add_to_moiety", "") OV.SetVar(get_sqf_name() + "_add_to_moiety", add_to_moiety) suggested_moiety = "%s, %s" % (olx.xf.latt.GetMoiety(), add_to_moiety) if "[+ solvents]" in suggested_moiety: olex.m("spy.set_cif_item(_chemical_formula_moiety,'%s')" % suggested_moiety) total_void_no_plural = "" if total_void_no > 1: total_void_no_plural = "s" d['suggested_moiety'] = suggested_moiety d['add_to_moiety'] = add_to_moiety d['suggested_sum'] = total_formula.replace(".0 ", " ") d['add_to_formula'] = add_to_formula.replace(".0 ", " ") d['base'] = base d['current_sNum'] = current_sNum d['escaped_model_src'] = escape_param_names(OV.ModelSrc()) d['total_void_electrons'] = total_void_electrons d['total_void_accounted_for_electrons'] = total_void_accounted_for_electrons d['total_void_volume'] = total_void_volume d['total_void_no_plural'] = total_void_no_plural d['total_void_no'] = total_void_no # If auto-add is on, updat the formulae if bool(OV.GetParam('snum.refinement.auto_add_masked_moieties')): if olx.xf.GetFormula() != d['suggested_sum']: olx.xf.SetFormula("%(suggested_sum)s" % d) if add_to_moiety not in olx.xf.latt.GetMoiety(): olex.m("spy.set_cif_item(_chemical_formula_moiety,'%s')" % suggested_moiety) # Set the background colour of the Formula + and Moiety + buttons. if add_to_moiety not in OV.get_cif_item('_chemical_formula_moiety'): if OV.IsControl("ADD_TO_MASK_MOIETY"): olx.html.SetBG("ADD_TO_MASK_MOIETY", gui_red) OV.SetVar("ADD_TO_MASK_MOIETY_BG", gui_red) else: OV.SetVar("ADD_TO_MASK_MOIETY_BG", OV.GetParam('gui.green').hexadecimal) if gui.tools.is_masked_moiety_in_formula(olx.xf.GetFormula('', 3)): if OV.IsControl("ADD_TO_MASK_FORMULA"): olx.html.SetBG("ADD_TO_MASK_FORMULA", gui_red) OV.SetVar("ADD_TO_MASK_FORMULA_BG", gui_red) else: OV.SetVar("ADD_TO_MASK_FORMULA_BG", gui_green) #################################################################### template_value = get_template('mask_special_detail_default', path=template_path, force=debug) % d template_value = template_value.strip() if mask_special_details: if "[]" in mask_special_details: mask_special_details = template_value if mask_special_details == "?" or not mask_special_details or mask_info_has_updated: mask_special_details = template_value mask_info_has_updated = False if mask_special_details == template_value: OV.SetParam('snum.masks.special_detail_colour', gui_red) OV.SetParam('snum.masks.special_detail_button_text', 'Use & Edit') else: OV.SetParam('snum.masks.special_detail_colour', gui_green) OV.SetParam('snum.masks.special_detail_button_text', 'Edit') # if add_to_formula: #mask_special_details = get_template('mask_special_detail_default', path=template_path, force=debug)%d # else: #mask_special_details = "" if mask_special_details: mask_special_details = mask_special_details.strip().lstrip('"').rstrip('"').replace("\r", " ") if mask_info_has_updated: olx.cif_model[current_sNum]['_%s_special_details' % base] = mask_special_details update_sqf_file(current_sNum, '_%s_special_details' % base) if mask_special_details is None: mask_special_details = '' d['mask_special_details'] = mask_special_details d['mask_special_details_vn'] = mask_special_details_vn d['ADD_TO_MASK_FORMULA_BG'] = OV.GetVar('ADD_TO_MASK_FORMULA_BG') OV.SetVar(mask_special_details_vn, mask_special_details) if add_to_formula: if not OV.GetParam('snum.refinement.auto_add_masked_moieties'): t += get_template('mask_output_end_rp', path=template_path, force=debug) % d t += get_template('mask_special_details', path=template_path, force=debug) % d t += get_template('mask_output_table_end', path=template_path, force=debug) % d OlexVFS.write_to_olex(output_fn, t) return output_fn OV.registerFunction(get_mask_info, False, 'gui.tools') def get_moieties_from_list(): moieties = {} _ = os.path.join(OV.DataDir(), 'moieties.cvs') if os.path.exists(_): pass else: _ = os.path.join(p_path, 'moieties.csv') rFile = open(_, 'r').readlines() for line in rFile: if line.startswith("#") or line == '\n': continue nick, formula = line.split(";") nick = nick.strip() formula = formula.strip() if nick and formula: moieties.setdefault(nick, formula) return moieties moieties = get_moieties_from_list() import decimal import random def get_rounded_formula(rnd=2, as_string_sep=""): # get actual and not user formula formula = olx.xf.GetFormula('list', rnd, True) if as_string_sep: formula = formula.split(",") formula = as_string_sep.join(formula).replace(":", "") return formula # def format_number(num): # return round(num,3) def format_number(num): if "." in str(num): _ = str(num).split(".")[1] if _.startswith('99'): num = round(num, 0) elif _.startswith('00'): num = round(num, 0) s = str(num) if s.endswith(".0"): retVal = int(num) elif s.endswith(".5"): retVal = round(num, 1) elif s.endswith(".25") or s.endswith(".25"): retVal = round(num, 2) else: retVal = round(num, 3) return retVal def get_sum_electrons_from_formula(f): Z = 0 N = 0 if not f: return retVal f = f.split() for entry in f: element = entry.rstrip('0123456789') try: number = float(entry[len(element):]) except: number = 1 Z += int(pt[element].get('Z')) * number if element != "H": N += number return Z, N def split_entity(entry): try: entry = entry.strip() entity = entry.lstrip('0123456789./(') multi = entry[:(len(entry) - len(entity))] if not multi: multi = 1 else: if "/" in multi: #multi = float(multi.split("/")[0])/float(multi.split("/")[1]) multi = Fraction(int(multi.split("/")[0]), int(multi.split("/")[1])) entity = entity.strip().rstrip("(") except: entity = "" multi = 1 return entity, multi # !HP remove once updated in main! #from gui.tools import Templates # class TemplatesTemp(object): # def __init__(self,): #nparent = gui.tools.TemplateProvider #self.parent.get_all_templates = self.get_all_templates # def get_all_templates(self, path=None, mask="*.*", marker='{-}'): # ''' # Parses the path for template files. # ''' # if not path: #path = os.path.join(OV.BaseDir(), 'util', 'pyUtil', 'gui', 'templates') # if path[-4:-3] != ".": #i.e. a specific template file has been provided #g = glob.glob("%s%s%s" %(path,os.sep,mask)) # else: #g = [path] # for f_path in g: #fc = open(f_path, 'r').read() # if not self.parent._extract_templates_from_text(fc,marker=marker): #name = os.path.basename(os.path.normpath(f_path)) #self.templates[name] = fc # TemplatesTemp() cleaned_formulae = {} def formula_cleaner(formula): formula = formula.replace(" ", "").replace(" ", "") # formula = unicode(formula) #py3HP if formula in cleaned_formulae: return cleaned_formulae[formula] retVal = "" el = "" n = "" i = 0 for char in formula: if str.isnumeric(char) or str.isspace(char) or str.islower(char): continue while str.isalpha(char): i += 1 if not el: el += char else: if str.islower(char): el += char elif str.isupper(char): n = "1" i -= 1 break char = formula[i:(i + 1)] while str.isnumeric(char): i += 1 n += char char = formula[i:(i + 1)] if el and n == "": n = 1 retVal += "%s%s " % (el, n) n = "" el = "" if debug: print("%s --> %s" % (formula, retVal.strip())) cleaned_formulae[formula] = retVal return retVal.strip() def update_metacif(sNum, file_name): pass ciflist = OV.GetCifMergeFilesList() if file_name not in ciflist: gui.report.publication.add_cif_to_merge_list.__func__(file_name) try: olex.m("spy.gui.report.publication.add_cif_to_merge_list(%s)" % file_name) except: return # ATTEMPT 2 from CifInfo import CifTools CT = CifTools() CT.update_cif_block(olx.cif_model[sNum], force=True) # ATTEMPT 1 #metacif_path = '%s%s%s.metacif' %(OV.StrDir(), os.sep, sNum) # with open(metacif_path, 'wb') as f: #print >> f, olx.cif_model[sNum] # olex.m('cifmerge') #def get_sqf_name(full=True, base=None): #if val := OV.GetVar("current_mask_sqf"): #return val #if not base: #base = _get_mask_base() #hklsrc = OV.HKLSrc() #if "_sq" in hklsrc or "_sqd" in hklsrc: #retVal = olx.file.ChangeExt(hklsrc, ".sqf") #else: #retVal = "%s.sqf" % (current_sNum) #return retVal def get_sqf_name(base=None): import time prg = OV.GetParam('snum.refinement.recompute_mask_before_refinement_prg', "Olex2") HKLSrc_base = os.path.splitext(OV.HKLSrc())[0] if prg == "Platon": retVal = f"{HKLSrc_base}_sqd.sqf" else: retVal = f"{HKLSrc_base}.sqf" OV.SetVar('masking_info_dte', time.ctime(os.path.getmtime(retVal))) OV.SetVar('masking_info_src', os.path.basename(retVal)) return retVal def edit_mask_special_details(txt, base, sNum): OV.SetVar('current_mask_sqf', "") user_value = str(OV.GetUserInput(0, "Edit _mask_special_details", txt)) if user_value == "None": return if user_value: olx.cif_model[current_sNum]['_%s_special_details' % base] = user_value update_sqf_file(current_sNum, '_%s_special_details' % base) OV.SetParam('snum.masks.special_detail_colour', gui_green) OV.SetParam('snum.masks.special_detail_button_text', 'Edit') OV.UpdateHtml(force=True) ## After the special details text has been edited, switch off the mask updating. if OV.IsControl('SNUM_REFINEMENT_RECOMPUTE_MASK_BEFORE_REFINEMENT'): olx.html.SetState('SNUM_REFINEMENT_RECOMPUTE_MASK_BEFORE_REFINEMENT', False) OV.SetParam('snum.refinement.recompute_mask_before_refinement','false') OV.registerFunction(edit_mask_special_details) def update_sqf_file(current_sNum, scope, scope2=None): OV.SetVar('current_mask_sqf', "") sqf_file = get_sqf_name() OV.SetVar('current_mask_sqf', "") if os.path.exists(sqf_file): with open(sqf_file, 'r') as original: data = original.read() with open(sqf_file, 'w') as modified: modified.write("data_%s\n" % OV.ModelSrc() + data) with open(sqf_file, 'r') as f: cif_block = iotbx.cif.reader(file_object=f).model() if not scope2: cif_block[current_sNum][scope] = olx.cif_model[current_sNum][scope] else: cif_block[current_sNum][scope][scope2] = olx.cif_model[current_sNum][scope][scope2] with open(sqf_file, 'w') as f: print(cif_block, file=f) CifInfo.MergeCif() def _get_mask_base(): if OV.IsControl('SNUM_REFINEMENT_RECOMPUTE_MASK_BEFORE_REFINEMENT_PRG'): base = olx.html.GetValue('SNUM_REFINEMENT_RECOMPUTE_MASK_BEFORE_REFINEMENT_PRG').lower() if "platon" in base.lower(): base = "platon_squeeze" elif "olex2" in base.lower(): base = "smtbx_masks" else: if OV.HKLSrc().rstrip(".hkl").endswith("_sq"): base = "platon_squeeze" else: base = "smtbx_masks" return base def add_mask_content(i, which): global mask_info_has_updated global current_sNum current_sNum = OV.ModelSrc() base = _get_mask_base() is_CIF = (olx.IsFileType('cif') == 'true') if ":" not in i: i_l = [str(i)] else: i_l = i.split(":") current_sNum = OV.ModelSrc() contents = olx.cif_model[current_sNum].get('_%s_void_%s' % (base, which)) if not contents: if is_CIF: contents = olx.Cif('_%s_void_nr' % base).split(",") else: contents = olx.cif_model[current_sNum].get('_%s_void_%s' % (base, which)) if not contents: return return_note(note="No void has been found.", col=gui_orange) try: disp = ",".join(i_l) except: disp = "fix me!" based_on = OV.GetParam('user.masks.based_on') based_on_display = "Asymmetric unit" if based_on == "FU": based_on_display = "Formula Unit" elif based_on == "Cell": based_on_display = "Unit Cell" f = get_adjust_for_base_factor() c = contents[int(i_l[0].split("|")[0]) - 1] multiplicity = int(i_l[0].split("|")[1]) if c == "?": c = "" c = c.lstrip("'").rstrip("'") c_l = c.split(",") c_new_l = [] for c in c_l: c = c.strip() n = 1 m = c if " " in c: n, m = c.split() n = format_number(multiplicity * float(n) / f) if m != "?" and m != "": c = "%s %s" % (n, m) else: c = m c_new_l.append(c) c = ", ".join(c_new_l) user_value = str(OV.GetUserInput(0, "Edit Mask %s for Void No %s based on %s" % (which, disp, based_on_display), c)).strip() if user_value == "None": return if not user_value: user_value = "?" user_value_l = user_value.split(",") user_value_new_l = [] for string in user_value_l: string = string.lstrip().rstrip() if " " in string: val, entity = string.split() elif "(" in string: val, entity = string.split("(") val = int(val) entity = entity.rstrip().rstrip(")") else: entity = string val = "1" if "/" in val: _ = val.split("/") val = Fraction(int(_[0]), int(_[1])) _ = format_number(float(val) * f / multiplicity) user_value_new_l.append("%s %s" % (format_number(float(val) * f / multiplicity), entity)) user_value = ",".join(user_value_new_l) _ = list(contents) for idx in i_l: idx = int(idx.split("|")[0]) - 1 _[idx] = user_value #mask = OV.get_cif_item('_%s_void' %base) olx.cif_model[current_sNum]['_%s_void' % base]['_%s_void_content' % base] = _ update_sqf_file(current_sNum, '_%s_void' % base, '_%s_void_content' % base) mask_info_has_updated = True # olex.m("spy.makeFormulaForsNumInfo()") get_mask_info() OV.UpdateHtml(force=True) # change_based_on_button_states() def get_adjust_for_base_factor(): Z = float(olx.xf.au.GetZ()) Zprime = float(olx.xf.au.GetZprime()) number_of_symm_op = round(Z / Zprime) based_on = OV.GetParam('user.masks.based_on') if based_on == "ASU": f = number_of_symm_op elif based_on == "FU": f = number_of_symm_op * Zprime elif based_on == "Cell": f = 1 return round(f) def _add_formula(curr, new, multi=1): if "," in curr: curr_l = curr.split(",") else: curr_l = curr.split() new_l = new.split() updated_d = {} # if len(new_l) == 1: #retVal = "please adjust manually!" _ = [curr_l, new_l] i = 0 for item in _: if not item: i += 1 continue for tem in item: if not tem: continue if ":" in tem: head = tem.split(":")[0] tail = tem.split(":")[1] else: head = tem.rstrip('0123456789./') tail = tem[len(head):] if tail: tail = float(tail) else: tail = 1.0 if i == 1: # don't mulitply the already existing bits tail = round(tail * multi, 2) updated_d.setdefault(head, 0) updated_d[head] += tail i += 1 l = [] l_beginning = [] for item in updated_d: if item == "C" or item == "H": l_beginning.append("%s%s " % (item, format_number(updated_d[item]))) else: l.append("%s%s " % (item, format_number(updated_d[item]))) l.sort() l_beginning.sort() l = l_beginning + l retVal = "" for item in l: retVal += item return retVal def status_bg(var, val, status='on'): var = OV.GetParam(var) if var.lower() == val.lower(): return gui_highlight OV.registerFunction(status_bg) def return_note(note, note_details="", col=OV.GetVar('HtmlHighlightColour')): if "#" not in col: col = OV.GetParam(col, OV.GetVar('HtmlHighlightColour')).hexadecimal output_fn = '%s_masking_info.htm' % OV.ModelSrc() d = {"note": note, "note_details": note_details, "note_bg": col} t = gui.tools.TemplateProvider.get_template('masking_note', path=template_path, force=debug) % d OlexVFS.write_to_olex(output_fn, t) return output_fn def escape_param_names(name): l = ["[", "]", "(", ")"] for item in l: name = name.replace(item, "_") return name def change_hklsrc_according_to_mask_prg(prg): OV.SetParam('snum.refinement.recompute_mask_before_refinement_prg', prg) target = "" OV.SetVar('current_mask_sqf', "") # sort_out_masking_hkl() #import glob #files_to_delete = glob.glob("*.sqf") # for fn in files_to_delete: # os.remove(fn) if target and OV.HasGUI() and OV.IsControl("SET_REFLECTIONS_parent_name"): olx.html.SetBG('SET_REFLECTIONS_parent_name', OV.GetParam('gui.green').hexadecimal) olx.html.SetValue('SET_REFLECTIONS_parent_name', os.path.basename(target)) get_mask_info() OV.UpdateHtml(force=True) def change_based_on_button_states(): l = ["BASE_ON_CELL", "BASE_ON_FU", "BASE_ON_ASU"] based_on = OV.GetParam('user.masks.based_on') for btn in l: if not OV.IsControl(btn): return if btn == "BASE_ON_CELL" and based_on == 'Cell': state = "true" elif btn == "BASE_ON_FU" and based_on == 'FU': state = "true" elif btn == "BASE_ON_ASU" and based_on == 'ASU': state = "true" else: state = "false" if state == "true": olx.html.SetBG(btn, 'gui_green') l.remove(btn) for btn in l: olx.html.SetBG(btn, 'gui_light_grey') break def get_masking_method(): prg = OV.GetParam("snum.refinement.recompute_mask_before_refinement_prg") method = "smbtx" if prg == "Platon": method = "SQUEEZE" return method def sort_out_masking_hkl(): pass #_ = OV.GetParam("snum.refinement.recompute_mask_before_refinement_prg") # if _ == "Platon": # if "_sq" not in OV.HKLSrc(): #fn = OV.HKLSrc().replace(".", "_sq.") # if os.path.exists(fn): # OV.HKLSrc(fn) # else: # if "_sq" in OV.HKLSrc(): #fn = OV.HKLSrc().replace("_sq.", ".") # if not os.path.exists(fn): #import shutil #shutil.copy2(OV.HKLSrc(), fn) # OV.HKLSrc(fn) def get_and_check_mask_origin(fab_path=None, prg=None, check_time = False): ## Checking whether a given .fab file has actually been generated by the method that is to be used. Returns the contents of the fab file as lines if the fab file is from the correct program import shutil try: hkl_base = os.path.splitext(OV.HKLSrc())[0] except: return [], None, None if not prg: prg = OV.GetParam('snum.refinement.recompute_mask_before_refinement_prg', "Olex2") if not fab_path: if prg == "Olex2": fab_path = f"{hkl_base}.fab" else: fab_path = f"{hkl_base}_sq.fab" print(f"Getting the fab information from {fab_path}") if not os.path.exists(fab_path): print(f"-- alas, no such file exists") return [], None, None with open(fab_path) as fab: lines = [] lines = fab.readlines() ## The following is necessary to find whether the mask is from the program shown in the GUI find = "_platon_squeeze" platon_in_file = any(find in line for line in reversed(lines)) if prg == "Platon" and platon_in_file: print(f"-- This was created by PLATON, and we want a {prg} mask. Good") return lines, fab_path, prg elif prg != "Platon" and platon_in_file: print(f"-- This was created by PLATON, and we want a {prg} mask. Not Good") print(f"-- Creating backup of the original file as {fab_path}_bak") shutil.copyfile(fab_path, f"{fab_path}_bak") return [], fab_path, prg print(f"-- Returning contehts from this file, generated by {prg}") return lines, fab_path, prg OV.registerFunction(change_based_on_button_states) OV.registerFunction(change_hklsrc_according_to_mask_prg) OV.registerFunction(add_mask_content) OV.registerFunction(formula_cleaner)