2020import random as ran
2121import pickle
2222import scipy .interpolate as si
23+ from sympy import symbols , nsimplify , Rational as SRational
24+ from fractions import Fraction
2325from . import GSASIIpath
2426from . import GSASIImath as G2mth
2527from . import GSASIIpwd as G2pwd
@@ -5197,7 +5199,6 @@ def _get_opt_val(opt_name, out):
51975199
51985200 def grab_all_kvecs (out_html ):
51995201 """Extract all k-vectors from the ISODISTORT output HTML."""
5200- from fractions import Fraction
52015202 import re
52025203
52035204 kvec1_pattern = r'<SELECT NAME="kvec1">(.*?)</SELECT>'
@@ -5224,49 +5225,77 @@ def grab_all_kvecs(out_html):
52245225 else :
52255226 return None
52265227
5227- def setup_kvec_input (k_vec , k_vec_dict , symmetry = None ):
5228+ a , b , g = symbols ('a b g' )
5229+
5230+ def frac_str (value , max_den = 1000 ):
5231+ # Try to get a rational exactly; if huge, fall back to bounded approximation
5232+ try :
5233+ rat = nsimplify (value , rational = True , maxsteps = 50 )
5234+ if isinstance (rat , SRational ):
5235+ num , den = rat .as_numer_denom ()
5236+ num , den = int (num ), int (den )
5237+ if den <= max_den :
5238+ return f"{ num } /{ den } " if den != 1 else str (num )
5239+ except Exception :
5240+ pass
5241+
5242+ # Best rational with denominator <= max_den
5243+ try :
5244+ f = Fraction (value ).limit_denominator (max_den )
5245+ except TypeError :
5246+ f = Fraction (float (value )).limit_denominator (max_den )
5247+
5248+ return f"{ f .numerator } /{ f .denominator } " if f .denominator != 1 else str (f .numerator )
5249+
5250+ def to_fraction_strs (d , keys = (a , b , g ), max_den = 1000 ):
5251+ out = {}
5252+ for k in keys :
5253+ if k in d :
5254+ out [str (k )] = frac_str (d [k ], max_den )
5255+ return out
5256+
5257+ def setup_kvec_input (k_vec , k_vec_dict , isocif_cif ):
52285258 """Set up the input for isodistort post request
52295259
52305260 Args:
52315261 k_vec (str): The k-vector to use for the isodistort request.
52325262 k_vec_dict (dict): The dictionary containing the k-vector
5233- form extracted from isodistort.
5234- symmetry (str, optional ): The crystal system .
5263+ form extracted from isodistort.
5264+ isocif_cif (str): The CIF file content exported from ISOCIF .
52355265
52365266 Returns:
52375267 dict: New entries and those need to be corrected in the data
52385268 to be used in the post request.
52395269 """
52405270 k_forms = k_vec_dict .items ()
5271+ all_keys = list (k_forms )
52415272
5242- k_vec_form = match_vector_pattern (k_vec , k_vec_dict , symmetry = "cubic" )
5273+ spg_num = kvsolve .grab_spg_num (isocif_cif )
5274+ k_vec_sol = kvsolve .find_kvec_form_param (spg_num , isocif_cif , k_vec , k_forms )
5275+ k_vec_form = all_keys [k_vec_sol [0 ]]
52435276
52445277 data_update = dict ()
52455278 data_update ['kvec1' ] = k_vec_form
5246- kvec_template = k_vec_dict [k_vec_form ]
5247- if isinstance (kvec_template [0 ], str ):
5248- num = k_vec [0 ].numerator
5249- den = k_vec [0 ].denominator
5250- data_update ['kparam11' ] = f"{ num } /{ den } "
5251- if isinstance (kvec_template [1 ], str ):
5252- num = k_vec [1 ].numerator
5253- den = k_vec [1 ].denominator
5254- data_update ['kparam21' ] = f"{ num } /{ den } "
5255- if isinstance (kvec_template [2 ], str ):
5256- num = k_vec [2 ].numerator
5257- den = k_vec [2 ].denominator
5258- data_update ['kparam31' ] = f"{ num } /{ den } "
5279+ k_vec_params = to_fraction_strs (k_vec_sol [1 ], max_den = 1000 )
5280+
5281+ if "a" in k_vec_params :
5282+ data_update ['kparam11' ] = k_vec_params ["a" ]
5283+ if "b" in k_vec_params :
5284+ data_update ['kparam21' ] = k_vec_params ["b" ]
5285+ if "g" in k_vec_params :
5286+ data_update ['kparam31' ] = k_vec_params ["g" ]
52595287
52605288 return data_update
52615289
52625290 # start of OnISODISTORT_kvec computations
52635291 import tempfile
52645292 import re
52655293 import requests
5266- from fractions import Fraction
52675294 from GSASII .exports import G2export_CIF
52685295 from . import ISODISTORT as ISO
52695296 isoformsite = 'https://iso.byu.edu/isodistortform.php'
5297+ isocifformsite = 'https://iso.byu.edu/isocifform.php'
5298+ isocifuploadsite = 'https://iso.byu.edu/isocifuploadfile.php'
52705299
52715300 if not G2frame .kvecSearch ['mode' ]:
52725301 return
@@ -5354,9 +5383,37 @@ def setup_kvec_input(k_vec, k_vec_dict, symmetry=None):
53545383 data ['input' ] = 'kvector'
53555384 data ['irrepcount' ] = '1'
53565385
5386+ # We need to upload the CIF file to ISOCIF and export from there, since
5387+ # some of the routines for k vector form solving only works with the
5388+ # CIF coming out from ISOCIF.
5389+ init_cif = ISO .UploadCIF (parentcif , upload_site = isocifuploadsite )
5390+ isocif_up = {'submit' : 'OK' , 'input' : 'uploadcif' , 'filename' : init_cif }
5391+ isocif_out_1 = requests .post (isocifformsite , data = isocif_up ).text
5392+
5393+ isocif_form = re .split (
5394+ '</form' ,
5395+ next (
5396+ i for i in re .split ('<form' , isocif_out_1 , flags = re .IGNORECASE )
5397+ if 'Detect higher' in i
5398+ ),
5399+ flags = re .IGNORECASE
5400+ )[0 ]
5401+
5402+ isocif_formDict = {}
5403+ for f in isocif_form .split ('<' ):
5404+ try :
5405+ name = re .split ('name=' ,f ,flags = re .IGNORECASE )[1 ].split ('"' )[1 ]
5406+ value = re .split ('value=' ,f ,flags = re .IGNORECASE )[1 ].split ('"' )[1 ]
5407+ isocif_formDict [name ] = value
5408+ except IndexError :
5409+ pass
5410+ isocif_formDict ['input' ] = 'savecif'
5411+
5412+ isocif_out_cif = requests .post (isocifformsite , data = isocif_formDict ).text
5413+
53575414 kvec_dict = grab_all_kvecs (out2 )
53585415 lat_sym = Phase ['General' ]['SGData' ]
5359- data_update = setup_kvec_input (kpoint , kvec_dict , symmetry = lat_sym )
5416+ data_update = setup_kvec_input (kpoint , kvec_dict , isocif_out_cif , lat_sym )
53605417 for key , value in data_update .items ():
53615418 data [key ] = value
53625419
0 commit comments