Changeset 763
 Timestamp:
 Sep 26, 2012 1:34:54 AM (9 years ago)
 Location:
 trunk
 Files:

 2 edited
Legend:
 Unmodified
 Added
 Removed

trunk/GSASIImath.py
r762 r763 1 <<<<<<< .mine 1 2 # * coding: utf8 * 2 3 #GSASIImath  major mathematics routines … … 24 25 import GSASIIlattice as G2lat 25 26 import GSASIIspc as G2spc 26 import scipy.optimize as so27 import scipy.linalg as sl28 27 import numpy.fft as fft 29 28 … … 807 806 return mapData 808 807 808 def SearchMap(data): 809 rollMap = lambda rho,roll: np.roll(np.roll(np.roll(rho,roll[0],axis=0),roll[1],axis=1),roll[2],axis=2) 810 811 norm = 1./(np.sqrt(3.)*np.sqrt(2.*np.pi)**3) 812 813 def noDuplicate(xyz,peaks,Amat): 814 XYZ = np.inner(Amat,xyz) 815 if True in [np.allclose(XYZ,np.inner(Amat,peak),atol=0.5) for peak in peaks]: 816 print ' Peak',xyz,' <0.5A from another peak' 817 return False 818 return True 819 820 def fixSpecialPos(xyz,SGData,Amat): 821 equivs = G2spc.GenAtom(xyz,SGData,Move=True) 822 X = [] 823 xyzs = [equiv[0] for equiv in equivs] 824 for x in xyzs: 825 if np.sqrt(np.sum(np.inner(Amat,xyzx)**2,axis=0))<0.5: 826 X.append(x) 827 if len(X) > 1: 828 return np.average(X,axis=0) 829 else: 830 return xyz 831 832 def rhoCalc(parms,rX,rY,rZ,res,SGLaue): 833 Mag,x0,y0,z0,sig = parms 834 return norm*Mag*np.exp(((x0rX)**2+(y0rY)**2+(z0rZ)**2)/(2.*sig**2))/(sig*res**3) 835 836 def peakFunc(parms,rX,rY,rZ,rho,res,SGLaue): 837 Mag,x0,y0,z0,sig = parms 838 M = rhorhoCalc(parms,rX,rY,rZ,res,SGLaue) 839 return M 840 841 def peakHess(parms,rX,rY,rZ,rho,res,SGLaue): 842 Mag,x0,y0,z0,sig = parms 843 dMdv = np.zeros(([5,]+list(rX.shape))) 844 delt = .01 845 for i in range(5): 846 parms[i] = delt 847 rhoCm = rhoCalc(parms,rX,rY,rZ,res,SGLaue) 848 parms[i] += 2.*delt 849 rhoCp = rhoCalc(parms,rX,rY,rZ,res,SGLaue) 850 parms[i] = delt 851 dMdv[i] = (rhoCprhoCm)/(2.*delt) 852 rhoC = rhoCalc(parms,rX,rY,rZ,res,SGLaue) 853 Vec = np.sum(np.sum(np.sum(dMdv*(rhorhoC),axis=3),axis=2),axis=1) 854 dMdv = np.reshape(dMdv,(5,rX.size)) 855 Hess = np.inner(dMdv,dMdv) 856 857 return Vec,Hess 858 859 generalData = data['General'] 860 phaseName = generalData['Name'] 861 SGData = generalData['SGData'] 862 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 863 drawingData = data['Drawing'] 864 peaks = [] 865 mags = [] 866 dzeros = [] 867 try: 868 mapData = generalData['Map'] 869 contLevel = mapData['cutOff']*mapData['rhoMax']/100. 870 rho = copy.copy(mapData['rho']) #don't mess up original 871 mapHalf = np.array(rho.shape)/2 872 res = mapData['Resolution'] 873 incre = np.array(rho.shape,dtype=np.float) 874 step = max(1.0,1./res)+1 875 steps = np.array(3*[step,]) 876 except KeyError: 877 print '**** ERROR  Fourier map not defined' 878 return peaks,mags 879 rhoMask = ma.array(rho,mask=(rho<contLevel)) 880 indices = (1,0,1) 881 rolls = np.array([[h,k,l] for h in indices for k in indices for l in indices]) 882 for roll in rolls: 883 if np.any(roll): 884 rhoMask = ma.array(rhoMask,mask=(rhoMaskrollMap(rho,roll)<=0.)) 885 indx = np.transpose(rhoMask.nonzero()) 886 peaks = indx/incre 887 mags = rhoMask[rhoMask.nonzero()] 888 for i,[ind,peak,mag] in enumerate(zip(indx,peaks,mags)): 889 rho = rollMap(rho,ind) 890 rMM = mapHalfsteps 891 rMP = mapHalf+steps+1 892 rhoPeak = rho[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]] 893 peakInt = np.sum(rhoPeak)*res**3 894 rX,rY,rZ = np.mgrid[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]] 895 x0 = [peakInt,mapHalf[0],mapHalf[1],mapHalf[2],2.0] #magnitude, position & width(sig) 896 result = HessianLSQ(peakFunc,x0,Hess=peakHess, 897 args=(rX,rY,rZ,rhoPeak,res,SGData['SGLaue']),ftol=.01,maxcyc=10) 898 x1 = result[0] 899 if not np.any(x1 < 0): 900 mag = x1[0] 901 peak = (np.array(x1[1:4])ind)/incre 902 peak = fixSpecialPos(peak,SGData,Amat) 903 rho = rollMap(rho,ind) 904 dzeros = np.sqrt(np.sum(np.inner(Amat,peaks)**2,axis=0)) 905 return np.array(peaks),np.array([mags,]).T,np.array([dzeros,]).T 906 907 def sortArray(data,pos,reverse=False): 908 #data is a list of items 909 #sort by pos in list; reverse if True 910 T = [] 911 for i,M in enumerate(data): 912 T.append((M[pos],i)) 913 D = dict(zip(T,data)) 914 T.sort() 915 if reverse: 916 T.reverse() 917 X = [] 918 for key in T: 919 X.append(D[key]) 920 return X 921 922 def PeaksUnique(data,Ind): 923 924 def noDuplicate(xyz,peaks,Amat): 925 if True in [np.allclose(np.inner(Amat,xyz),np.inner(Amat,peak),atol=0.5) for peak in peaks]: 926 return False 927 return True 928 929 generalData = data['General'] 930 cell = generalData['Cell'][1:7] 931 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 932 A = G2lat.cell2A(cell) 933 SGData = generalData['SGData'] 934 mapPeaks = data['Map Peaks'] 935 Indx = {} 936 XYZ = {} 937 for ind in Ind: 938 XYZ[ind] = np.array(mapPeaks[ind][1:4]) 939 Indx[ind] = True 940 for ind in Ind: 941 if Indx[ind]: 942 xyz = XYZ[ind] 943 for jnd in Ind: 944 if ind != jnd and Indx[jnd]: 945 Equiv = G2spc.GenAtom(XYZ[jnd],SGData,Move=True) 946 xyzs = np.array([equiv[0] for equiv in Equiv]) 947 Indx[jnd] = noDuplicate(xyz,xyzs,Amat) 948 Ind = [] 949 for ind in Indx: 950 if Indx[ind]: 951 Ind.append(ind) 952 return Ind 953 954 def prodQQ(QA,QB): 955 ''' Grassman quaternion product 956 QA,QB quaternions; q=r+ai+bj+ck 957 ''' 958 D = np.zeros(4) 959 D[0] = QA[0]*QB[0]QA[1]*QB[1]QA[2]*QB[2]QA[3]*QB[3] 960 D[1] = QA[0]*QB[1]+QA[1]*QB[0]+QA[2]*QB[3]QA[3]*QB[2] 961 D[2] = QA[0]*QB[2]QA[1]*QB[3]+QA[2]*QB[0]+QA[3]*QB[1] 962 D[3] = QA[0]*QB[3]+QA[1]*QB[2]QA[2]*QB[1]+QA[3]*QB[0] 963 return D 964 965 def normQ(QA): 966 ''' get length of quaternion & normalize it 967 q=r+ai+bj+ck 968 ''' 969 n = np.sqrt(np.sum(np.array(QA)**2)) 970 return QA/n 971 972 def invQ(Q): 973 ''' 974 get inverse of quaternion 975 q=r+ai+bj+ck; q* = raibjck 976 ''' 977 return Q*np.array([1,1,1,1]) 978 979 def prodQVQ(Q,V): 980 ''' compute the quaternion vector rotation qvq1 = v' 981 q=r+ai+bj+ck 982 ''' 983 VP = np.zeros(3) 984 T2 = Q[0]*Q[1] 985 T3 = Q[0]*Q[2] 986 T4 = Q[0]*Q[3] 987 T5 = Q[1]*Q[1] 988 T6 = Q[1]*Q[2] 989 T7 = Q[1]*Q[3] 990 T8 = Q[2]*Q[2] 991 T9 = Q[2]*Q[3] 992 T10 = Q[3]*Q[3] 993 VP[0] = 2.*((T8+T10)*V[0]+(T6T4)*V[1]+(T3+T7)*V[2])+V[0] 994 VP[1] = 2.*((T4+T6)*V[0]+(T5+T10)*V[1]+(T9T2)*V[2])+V[1] 995 VP[2] = 2.*((T7T3)*V[0]+(T2+T9)*V[1]+(T5+T8)*V[2])+V[2] 996 return VP 997 998 def Q2Mat(Q): 999 ''' make rotation matrix from quaternion 1000 q=r+ai+bj+ck 1001 ''' 1002 aa = Q[0]**2 1003 ab = Q[0]*Q[1] 1004 ac = Q[0]*Q[2] 1005 ad = Q[0]*Q[3] 1006 bb = Q[1]**2 1007 bc = Q[1]*Q[2] 1008 bd = Q[1]*Q[3] 1009 cc = Q[2]**2 1010 cd = Q[2]*Q[3] 1011 dd = Q[3]**2 1012 M = [[aa+bbccdd, 2.*(bcad), 2.*(ac+bd)], 1013 [2*(ad+bc), aabb+ccdd, 2.*(cdab)], 1014 [2*(bdac), 2.*(ab+cd), aabbcc+dd]] 1015 return np.array(M) 1016 1017 def AV2Q(A,V): 1018 ''' convert angle (radians pi to pi) & vector to quaternion 1019 q=r+ai+bj+ck 1020 ''' 1021 Q = np.zeros(4) 1022 d = np.sqrt(np.sum(np.array(V)**2)) 1023 if d: 1024 V /= d 1025 else: 1026 return [1.,0.,0.,0.] #identity 1027 p = A/2. 1028 Q[0] = np.cos(p) 1029 s = np.sin(p) 1030 Q[1:4] = V*s 1031 return Q 1032 1033 def AVdeg2Q(A,V): 1034 ''' convert angle (degrees 180 to 180) & vector to quaternion 1035 q=r+ai+bj+ck 1036 ''' 1037 Q = np.zeros(4) 1038 d = np.sqrt(np.sum(np.array(V)**2)) 1039 if d: 1040 V /= d 1041 else: 1042 return [1.,0.,0.,0.] #identity 1043 p = A/2. 1044 Q[0] = cosd(p) 1045 S = sind(p) 1046 Q[1:4] = V*S 1047 return Q 1048 1049 ======= 1050 # * coding: utf8 * 1051 #GSASIImath  major mathematics routines 1052 ########### SVN repository information ################### 1053 # $Date$ 1054 # $Author$ 1055 # $Revision$ 1056 # $URL$ 1057 # $Id$ 1058 ########### SVN repository information ################### 1059 import sys 1060 import os 1061 import os.path as ospath 1062 import random as rn 1063 import numpy as np 1064 import numpy.linalg as nl 1065 import numpy.ma as ma 1066 import cPickle 1067 import time 1068 import math 1069 import copy 1070 import GSASIIpath 1071 GSASIIpath.SetVersionNumber("$Revision$") 1072 import GSASIIElem as G2el 1073 import GSASIIlattice as G2lat 1074 import GSASIIspc as G2spc 1075 import scipy.optimize as so 1076 import scipy.linalg as sl 1077 import numpy.fft as fft 1078 1079 sind = lambda x: np.sin(x*np.pi/180.) 1080 cosd = lambda x: np.cos(x*np.pi/180.) 1081 tand = lambda x: np.tan(x*np.pi/180.) 1082 asind = lambda x: 180.*np.arcsin(x)/np.pi 1083 acosd = lambda x: 180.*np.arccos(x)/np.pi 1084 atan2d = lambda y,x: 180.*np.arctan2(y,x)/np.pi 1085 1086 def HessianLSQ(func,x0,Hess,args=(),ftol=1.49012e8,xtol=1.49012e8, maxcyc=0): 1087 1088 """ 1089 Minimize the sum of squares of a set of equations. 1090 1091 :: 1092 1093 Nobs 1094 x = arg min(sum(func(y)**2,axis=0)) 1095 y=0 1096 1097 Parameters 1098  1099 func : callable 1100 should take at least one (possibly length N vector) argument and 1101 returns M floating point numbers. 1102 x0 : ndarray 1103 The starting estimate for the minimization of length N 1104 Hess : callable 1105 A required function or method to compute the weighted vector and Hessian for func. 1106 It must be a symmetric NxN array 1107 args : tuple 1108 Any extra arguments to func are placed in this tuple. 1109 ftol : float 1110 Relative error desired in the sum of squares. 1111 xtol : float 1112 Relative error desired in the approximate solution. 1113 maxcyc : int 1114 The maximum number of cycles of refinement to execute, if 1 refine 1115 until other limits are met (ftol, xtol) 1116 1117 Returns 1118  1119 x : ndarray 1120 The solution (or the result of the last iteration for an unsuccessful 1121 call). 1122 cov_x : ndarray 1123 Uses the fjac and ipvt optional outputs to construct an 1124 estimate of the jacobian around the solution. ``None`` if a 1125 singular matrix encountered (indicates very flat curvature in 1126 some direction). This matrix must be multiplied by the 1127 residual standard deviation to get the covariance of the 1128 parameter estimates  see curve_fit. 1129 infodict : dict 1130 a dictionary of optional outputs with the key s:: 1131 1132  'fvec' : the function evaluated at the output 1133 1134 1135 Notes 1136  1137 1138 """ 1139 1140 x0 = np.array(x0, ndmin=1) #might be redundant? 1141 n = len(x0) 1142 if type(args) != type(()): 1143 args = (args,) 1144 1145 icycle = 0 1146 One = np.ones((n,n)) 1147 lam = 0.001 1148 lamMax = lam 1149 nfev = 0 1150 while icycle < maxcyc: 1151 lamMax = max(lamMax,lam) 1152 M = func(x0,*args) 1153 nfev += 1 1154 chisq0 = np.sum(M**2) 1155 Yvec,Amat = Hess(x0,*args) 1156 Adiag = np.sqrt(np.diag(Amat)) 1157 psing = np.where(np.abs(Adiag) < 1.e14,True,False) 1158 if np.any(psing): #hard singularity in matrix 1159 return [x0,None,{'num cyc':icycle,'fvec':M,'nfev':nfev,'lamMax':lamMax,'psing':psing}] 1160 Anorm = np.outer(Adiag,Adiag) 1161 Yvec /= Adiag 1162 Amat /= Anorm 1163 while True: 1164 Lam = np.eye(Amat.shape[0])*lam 1165 Amatlam = Amat*(One+Lam) 1166 try: 1167 Xvec = nl.solve(Amatlam,Yvec) 1168 except nl.LinAlgError: 1169 print 'ouch #1' 1170 psing = list(np.where(np.diag(nl.qr(Amatlam)[1]) < 1.e14)[0]) 1171 return [x0,None,{'num cyc':icycle,'fvec':M,'nfev':nfev,'lamMax':lamMax,'psing':psing}] 1172 Xvec /= Adiag 1173 M2 = func(x0+Xvec,*args) 1174 nfev += 1 1175 chisq1 = np.sum(M2**2) 1176 if chisq1 > chisq0: 1177 lam *= 10. 1178 else: 1179 x0 += Xvec 1180 lam /= 10. 1181 break 1182 if (chisq0chisq1)/chisq0 < ftol: 1183 break 1184 icycle += 1 1185 M = func(x0,*args) 1186 nfev += 1 1187 Yvec,Amat = Hess(x0,*args) 1188 try: 1189 Bmat = nl.inv(Amat) 1190 return [x0,Bmat,{'num cyc':icycle,'fvec':M,'nfev':nfev,'lamMax':lamMax,'psing':[]}] 1191 except nl.LinAlgError: 1192 print 'ouch #2 linear algebra error in LS' 1193 psing = [] 1194 if maxcyc: 1195 psing = list(np.where(np.diag(nl.qr(Amat)[1]) < 1.e14)[0]) 1196 return [x0,None,{'num cyc':icycle,'fvec':M,'nfev':nfev,'lamMax':lamMax,'psing':psing}] 1197 1198 def getVCov(varyNames,varyList,covMatrix): 1199 vcov = np.zeros((len(varyNames),len(varyNames))) 1200 for i1,name1 in enumerate(varyNames): 1201 for i2,name2 in enumerate(varyNames): 1202 try: 1203 vcov[i1][i2] = covMatrix[varyList.index(name1)][varyList.index(name2)] 1204 except ValueError: 1205 vcov[i1][i2] = 0.0 1206 return vcov 1207 1208 def getMass(generalData): 1209 mass = 0. 1210 for i,elem in enumerate(generalData['AtomTypes']): 1211 mass += generalData['NoAtoms'][elem]*generalData['AtomMass'][i] 1212 return mass 1213 1214 def getDensity(generalData): 1215 1216 mass = getMass(generalData) 1217 Volume = generalData['Cell'][7] 1218 density = mass/(0.6022137*Volume) 1219 return density,Volume/mass 1220 1221 def getRestDist(XYZ,Amat): 1222 return np.sqrt(np.sum(np.inner(Amat,(XYZ[1]XYZ[0]))**2)) 1223 1224 def getRestAngle(XYZ,Amat): 1225 1226 def calcVec(Ox,Tx,Amat): 1227 return np.inner(Amat,(TxOx)) 1228 1229 VecA = calcVec(XYZ[1],XYZ[0],Amat) 1230 VecA /= np.sqrt(np.sum(VecA**2)) 1231 VecB = calcVec(XYZ[1],XYZ[2],Amat) 1232 VecB /= np.sqrt(np.sum(VecB**2)) 1233 edge = VecBVecA 1234 edge = np.sum(edge**2) 1235 angle = (2.edge)/2. 1236 angle = max(angle,1.) 1237 return acosd(angle) 1238 1239 def getRestPlane(XYZ,Amat): 1240 sumXYZ = np.zeros(3) 1241 for xyz in XYZ: 1242 sumXYZ += xyz 1243 sumXYZ /= len(XYZ) 1244 XYZ = np.array(XYZ)sumXYZ 1245 XYZ = np.inner(Amat,XYZ).T 1246 Zmat = np.zeros((3,3)) 1247 for i,xyz in enumerate(XYZ): 1248 Zmat += np.outer(xyz.T,xyz) 1249 Evec,Emat = nl.eig(Zmat) 1250 Evec = np.sqrt(Evec)/(len(XYZ)3) 1251 Order = np.argsort(Evec) 1252 return Evec[Order[0]] 1253 1254 def getRestChiral(XYZ,Amat): 1255 1256 VecA = np.empty((3,3)) 1257 VecA[0] = np.inner(XYZ[1]XYZ[0],Amat) 1258 VecA[1] = np.inner(XYZ[2]XYZ[0],Amat) 1259 VecA[2] = np.inner(XYZ[3]XYZ[0],Amat) 1260 return nl.det(VecA) 1261 1262 def getDistDerv(Oxyz,Txyz,Amat,Tunit,Top,SGData): 1263 1264 def calcDist(Ox,Tx,U,inv,C,M,T,Amat): 1265 TxT = inv*(np.inner(M,Tx)+T)+C+U 1266 return np.sqrt(np.sum(np.inner(Amat,(TxTOx))**2)) 1267 1268 inv = Top/abs(Top) 1269 cent = abs(Top)/100 1270 op = abs(Top)%1001 1271 M,T = SGData['SGOps'][op] 1272 C = SGData['SGCen'][cent] 1273 dx = .00001 1274 deriv = np.zeros(6) 1275 for i in [0,1,2]: 1276 Oxyz[i] += dx 1277 d0 = calcDist(Oxyz,Txyz,Tunit,inv,C,M,T,Amat) 1278 Oxyz[i] = 2*dx 1279 deriv[i] = (calcDist(Oxyz,Txyz,Tunit,inv,C,M,T,Amat)d0)/(2.*dx) 1280 Oxyz[i] += dx 1281 Txyz[i] += dx 1282 d0 = calcDist(Oxyz,Txyz,Tunit,inv,C,M,T,Amat) 1283 Txyz[i] = 2*dx 1284 deriv[i+3] = (calcDist(Oxyz,Txyz,Tunit,inv,C,M,T,Amat)d0)/(2.*dx) 1285 Txyz[i] += dx 1286 return deriv 1287 1288 def getAngSig(VA,VB,Amat,SGData,covData={}): 1289 1290 def calcVec(Ox,Tx,U,inv,C,M,T,Amat): 1291 TxT = inv*(np.inner(M,Tx)+T)+C 1292 TxT = G2spc.MoveToUnitCell(TxT)+U 1293 return np.inner(Amat,(TxTOx)) 1294 1295 def calcAngle(Ox,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat): 1296 VecA = calcVec(Ox,TxA,unitA,invA,CA,MA,TA,Amat) 1297 VecA /= np.sqrt(np.sum(VecA**2)) 1298 VecB = calcVec(Ox,TxB,unitB,invB,CB,MB,TB,Amat) 1299 VecB /= np.sqrt(np.sum(VecB**2)) 1300 edge = VecBVecA 1301 edge = np.sum(edge**2) 1302 angle = (2.edge)/2. 1303 angle = max(angle,1.) 1304 return acosd(angle) 1305 1306 OxAN,OxA,TxAN,TxA,unitA,TopA = VA 1307 OxBN,OxB,TxBN,TxB,unitB,TopB = VB 1308 invA = invB = 1 1309 invA = TopA/abs(TopA) 1310 invB = TopB/abs(TopB) 1311 centA = abs(TopA)/100 1312 centB = abs(TopB)/100 1313 opA = abs(TopA)%1001 1314 opB = abs(TopB)%1001 1315 MA,TA = SGData['SGOps'][opA] 1316 MB,TB = SGData['SGOps'][opB] 1317 CA = SGData['SGCen'][centA] 1318 CB = SGData['SGCen'][centB] 1319 if 'covMatrix' in covData: 1320 covMatrix = covData['covMatrix'] 1321 varyList = covData['varyList'] 1322 AngVcov = getVCov(OxAN+TxAN+TxBN,varyList,covMatrix) 1323 dx = .00001 1324 dadx = np.zeros(9) 1325 Ang = calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat) 1326 for i in [0,1,2]: 1327 OxA[i] += dx 1328 a0 = calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat) 1329 OxA[i] = 2*dx 1330 dadx[i] = (calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat)a0)/dx 1331 OxA[i] += dx 1332 1333 TxA[i] += dx 1334 a0 = calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat) 1335 TxA[i] = 2*dx 1336 dadx[i+3] = (calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat)a0)/dx 1337 TxA[i] += dx 1338 1339 TxB[i] += dx 1340 a0 = calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat) 1341 TxB[i] = 2*dx 1342 dadx[i+6] = (calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat)a0)/dx 1343 TxB[i] += dx 1344 1345 sigAng = np.sqrt(np.inner(dadx,np.inner(AngVcov,dadx))) 1346 if sigAng < 0.01: 1347 sigAng = 0.0 1348 return Ang,sigAng 1349 else: 1350 return calcAngle(OxA,TxA,TxB,unitA,unitB,invA,CA,MA,TA,invB,CB,MB,TB,Amat),0.0 1351 1352 def GetDistSig(Oatoms,Atoms,Amat,SGData,covData={}): 1353 1354 def calcDist(Atoms,SyOps,Amat): 1355 XYZ = [] 1356 for i,atom in enumerate(Atoms): 1357 Inv,M,T,C,U = SyOps[i] 1358 XYZ.append(np.array(atom[1:4])) 1359 XYZ[1] = Inv*(np.inner(M,np.array(XYZ[1]))+T)+C+U 1360 XYZ[1] = np.inner(Amat,XYZ[1]).T 1361 V1 = XYZ[1]XYZ[0] 1362 return np.sqrt(np.sum(V1**2)) 1363 1364 Inv = [] 1365 SyOps = [] 1366 names = [] 1367 for i,atom in enumerate(Oatoms): 1368 names += atom[1] 1369 Op,unit = Atoms[i][1] 1370 inv = Op/abs(Op) 1371 m,t = SGData['SGOps'][abs(Op)%1001] 1372 c = SGData['SGCen'][abs(Op)/100] 1373 SyOps.append([inv,m,t,c,unit]) 1374 Dist = calcDist(Oatoms,SyOps,Amat) 1375 1376 sig = 0.001 1377 if 'covMatrix' in covData: 1378 parmNames = [] 1379 dx = .00001 1380 dadx = np.zeros(6) 1381 for i in range(6): 1382 ia = i/3 1383 ix = i%3 1384 Oatoms[ia][ix+1] += dx 1385 a0 = calcDist(Oatoms,SyOps,Amat) 1386 Oatoms[ia][ix+1] = 2*dx 1387 dadx[i] = (calcDist(Oatoms,SyOps,Amat)a0)/(2.*dx) 1388 covMatrix = covData['covMatrix'] 1389 varyList = covData['varyList'] 1390 DistVcov = getVCov(names,varyList,covMatrix) 1391 sig = np.sqrt(np.inner(dadx,np.inner(DistVcov,dadx))) 1392 if sig < 0.001: 1393 sig = 0.001 1394 1395 return Dist,sig 1396 1397 def GetAngleSig(Oatoms,Atoms,Amat,SGData,covData={}): 1398 1399 def calcAngle(Atoms,SyOps,Amat): 1400 XYZ = [] 1401 for i,atom in enumerate(Atoms): 1402 Inv,M,T,C,U = SyOps[i] 1403 XYZ.append(np.array(atom[1:4])) 1404 XYZ[1] = Inv*(np.inner(M,np.array(XYZ[1]))+T)+C+U 1405 XYZ[1] = np.inner(Amat,XYZ[1]).T 1406 V1 = XYZ[1]XYZ[0] 1407 V1 /= np.sqrt(np.sum(V1**2)) 1408 V2 = XYZ[1]XYZ[2] 1409 V2 /= np.sqrt(np.sum(V2**2)) 1410 V3 = V2V1 1411 cang = min(1.,max((2.np.sum(V3**2))/2.,1.)) 1412 return acosd(cang) 1413 1414 Inv = [] 1415 SyOps = [] 1416 names = [] 1417 for i,atom in enumerate(Oatoms): 1418 names += atom[1] 1419 Op,unit = Atoms[i][1] 1420 inv = Op/abs(Op) 1421 m,t = SGData['SGOps'][abs(Op)%1001] 1422 c = SGData['SGCen'][abs(Op)/100] 1423 SyOps.append([inv,m,t,c,unit]) 1424 Angle = calcAngle(Oatoms,SyOps,Amat) 1425 1426 sig = 0.01 1427 if 'covMatrix' in covData: 1428 parmNames = [] 1429 dx = .00001 1430 dadx = np.zeros(9) 1431 for i in range(9): 1432 ia = i/3 1433 ix = i%3 1434 Oatoms[ia][ix+1] += dx 1435 a0 = calcAngle(Oatoms,SyOps,Amat) 1436 Oatoms[ia][ix+1] = 2*dx 1437 dadx[i] = (calcAngle(Oatoms,SyOps,Amat)a0)/(2.*dx) 1438 covMatrix = covData['covMatrix'] 1439 varyList = covData['varyList'] 1440 AngVcov = getVCov(names,varyList,covMatrix) 1441 sig = np.sqrt(np.inner(dadx,np.inner(AngVcov,dadx))) 1442 if sig < 0.01: 1443 sig = 0.01 1444 1445 return Angle,sig 1446 1447 def GetTorsionSig(Oatoms,Atoms,Amat,SGData,covData={}): 1448 1449 def calcTorsion(Atoms,SyOps,Amat): 1450 1451 XYZ = [] 1452 for i,atom in enumerate(Atoms): 1453 Inv,M,T,C,U = SyOps[i] 1454 XYZ.append(np.array(atom[1:4])) 1455 XYZ[1] = Inv*(np.inner(M,np.array(XYZ[1]))+T)+C+U 1456 XYZ[1] = np.inner(Amat,XYZ[1]).T 1457 V1 = XYZ[1]XYZ[0] 1458 V2 = XYZ[2]XYZ[1] 1459 V3 = XYZ[3]XYZ[2] 1460 V1 /= np.sqrt(np.sum(V1**2)) 1461 V2 /= np.sqrt(np.sum(V2**2)) 1462 V3 /= np.sqrt(np.sum(V3**2)) 1463 M = np.array([V1,V2,V3]) 1464 D = nl.det(M) 1465 Ang = 1.0 1466 P12 = np.dot(V1,V2) 1467 P13 = np.dot(V1,V3) 1468 P23 = np.dot(V2,V3) 1469 Tors = acosd((P12*P23P13)/(np.sqrt(1.P12**2)*np.sqrt(1.P23**2)))*D/abs(D) 1470 return Tors 1471 1472 Inv = [] 1473 SyOps = [] 1474 names = [] 1475 for i,atom in enumerate(Oatoms): 1476 names += atom[1] 1477 Op,unit = Atoms[i][1] 1478 inv = Op/abs(Op) 1479 m,t = SGData['SGOps'][abs(Op)%1001] 1480 c = SGData['SGCen'][abs(Op)/100] 1481 SyOps.append([inv,m,t,c,unit]) 1482 Tors = calcTorsion(Oatoms,SyOps,Amat) 1483 1484 sig = 0.01 1485 if 'covMatrix' in covData: 1486 parmNames = [] 1487 dx = .00001 1488 dadx = np.zeros(12) 1489 for i in range(12): 1490 ia = i/3 1491 ix = i%3 1492 Oatoms[ia][ix+1] += dx 1493 a0 = calcTorsion(Oatoms,SyOps,Amat) 1494 Oatoms[ia][ix+1] = 2*dx 1495 dadx[i] = (calcTorsion(Oatoms,SyOps,Amat)a0)/(2.*dx) 1496 covMatrix = covData['covMatrix'] 1497 varyList = covData['varyList'] 1498 TorVcov = getVCov(names,varyList,covMatrix) 1499 sig = np.sqrt(np.inner(dadx,np.inner(TorVcov,dadx))) 1500 if sig < 0.01: 1501 sig = 0.01 1502 1503 return Tors,sig 1504 1505 def GetDATSig(Oatoms,Atoms,Amat,SGData,covData={}): 1506 1507 def calcDist(Atoms,SyOps,Amat): 1508 XYZ = [] 1509 for i,atom in enumerate(Atoms): 1510 Inv,M,T,C,U = SyOps[i] 1511 XYZ.append(np.array(atom[1:4])) 1512 XYZ[1] = Inv*(np.inner(M,np.array(XYZ[1]))+T)+C+U 1513 XYZ[1] = np.inner(Amat,XYZ[1]).T 1514 V1 = XYZ[1]XYZ[0] 1515 return np.sqrt(np.sum(V1**2)) 1516 1517 def calcAngle(Atoms,SyOps,Amat): 1518 XYZ = [] 1519 for i,atom in enumerate(Atoms): 1520 Inv,M,T,C,U = SyOps[i] 1521 XYZ.append(np.array(atom[1:4])) 1522 XYZ[1] = Inv*(np.inner(M,np.array(XYZ[1]))+T)+C+U 1523 XYZ[1] = np.inner(Amat,XYZ[1]).T 1524 V1 = XYZ[1]XYZ[0] 1525 V1 /= np.sqrt(np.sum(V1**2)) 1526 V2 = XYZ[1]XYZ[2] 1527 V2 /= np.sqrt(np.sum(V2**2)) 1528 V3 = V2V1 1529 cang = min(1.,max((2.np.sum(V3**2))/2.,1.)) 1530 return acosd(cang) 1531 1532 def calcTorsion(Atoms,SyOps,Amat): 1533 1534 XYZ = [] 1535 for i,atom in enumerate(Atoms): 1536 Inv,M,T,C,U = SyOps[i] 1537 XYZ.append(np.array(atom[1:4])) 1538 XYZ[1] = Inv*(np.inner(M,np.array(XYZ[1]))+T)+C+U 1539 XYZ[1] = np.inner(Amat,XYZ[1]).T 1540 V1 = XYZ[1]XYZ[0] 1541 V2 = XYZ[2]XYZ[1] 1542 V3 = XYZ[3]XYZ[2] 1543 V1 /= np.sqrt(np.sum(V1**2)) 1544 V2 /= np.sqrt(np.sum(V2**2)) 1545 V3 /= np.sqrt(np.sum(V3**2)) 1546 M = np.array([V1,V2,V3]) 1547 D = nl.det(M) 1548 Ang = 1.0 1549 P12 = np.dot(V1,V2) 1550 P13 = np.dot(V1,V3) 1551 P23 = np.dot(V2,V3) 1552 Tors = acosd((P12*P23P13)/(np.sqrt(1.P12**2)*np.sqrt(1.P23**2)))*D/abs(D) 1553 return Tors 1554 1555 Inv = [] 1556 SyOps = [] 1557 names = [] 1558 for i,atom in enumerate(Oatoms): 1559 names += atom[1] 1560 Op,unit = Atoms[i][1] 1561 inv = Op/abs(Op) 1562 m,t = SGData['SGOps'][abs(Op)%1001] 1563 c = SGData['SGCen'][abs(Op)/100] 1564 SyOps.append([inv,m,t,c,unit]) 1565 M = len(Oatoms) 1566 if M == 2: 1567 Val = calcDist(Oatoms,SyOps,Amat) 1568 elif M == 3: 1569 Val = calcAngle(Oatoms,SyOps,Amat) 1570 else: 1571 Val = calcTorsion(Oatoms,SyOps,Amat) 1572 1573 sigVals = [0.001,0.01,0.01] 1574 sig = sigVals[M3] 1575 if 'covMatrix' in covData: 1576 parmNames = [] 1577 dx = .00001 1578 N = M*3 1579 dadx = np.zeros(N) 1580 for i in range(N): 1581 ia = i/3 1582 ix = i%3 1583 Oatoms[ia][ix+1] += dx 1584 if M == 2: 1585 a0 = calcDist(Oatoms,SyOps,Amat) 1586 elif M == 3: 1587 a0 = calcAngle(Oatoms,SyOps,Amat) 1588 else: 1589 a0 = calcTorsion(Oatoms,SyOps,Amat) 1590 Oatoms[ia][ix+1] = 2*dx 1591 if M == 2: 1592 dadx[i] = (calcDist(Oatoms,SyOps,Amat)a0)/(2.*dx) 1593 elif M == 3: 1594 dadx[i] = (calcAngle(Oatoms,SyOps,Amat)a0)/(2.*dx) 1595 else: 1596 dadx[i] = (calcTorsion(Oatoms,SyOps,Amat)a0)/(2.*dx) 1597 covMatrix = covData['covMatrix'] 1598 varyList = covData['varyList'] 1599 Vcov = getVCov(names,varyList,covMatrix) 1600 sig = np.sqrt(np.inner(dadx,np.inner(Vcov,dadx))) 1601 if sig < sigVals[M3]: 1602 sig = sigVals[M3] 1603 1604 return Val,sig 1605 1606 1607 def ValEsd(value,esd=0,nTZ=False): #NOT complete  don't use 1608 # returns value(esd) string; nTZ=True for no trailing zeros 1609 # use esd < 0 for level of precision shown e.g. esd=0.01 gives 2 places beyond decimal 1610 #get the 2 significant digits in the esd 1611 edig = lambda esd: int(round(10**(math.log10(esd) % 1+1))) 1612 #get the number of digits to represent them 1613 epl = lambda esd: 2+int(1.545math.log10(10*edig(esd))) 1614 1615 mdec = lambda esd: int(round(math.log10(abs(esd))))+1 1616 ndec = lambda esd: int(1.545math.log10(abs(esd))) 1617 if esd > 0: 1618 fmt = '"%.'+str(ndec(esd))+'f(%d)"' 1619 return str(fmt%(value,int(round(esd*10**(mdec(esd)))))).strip('"') 1620 elif esd < 0: 1621 return str(round(value,mdec(esd)1)) 1622 else: 1623 text = str("%f"%(value)) 1624 if nTZ: 1625 return text.rstrip('0') 1626 else: 1627 return text 1628 1629 def adjHKLmax(SGData,Hmax): 1630 if SGData['SGLaue'] in ['3','3m1','31m','6/m','6/mmm']: 1631 Hmax[0] = ((Hmax[0]+3)/6)*6 1632 Hmax[1] = ((Hmax[1]+3)/6)*6 1633 Hmax[2] = ((Hmax[2]+1)/4)*4 1634 else: 1635 Hmax[0] = ((Hmax[0]+2)/4)*4 1636 Hmax[1] = ((Hmax[1]+2)/4)*4 1637 Hmax[2] = ((Hmax[2]+1)/4)*4 1638 1639 def FourierMap(data,reflData): 1640 1641 generalData = data['General'] 1642 if not generalData['Map']['MapType']: 1643 print '**** ERROR  Fourier map not defined' 1644 return 1645 mapData = generalData['Map'] 1646 dmin = mapData['Resolution'] 1647 SGData = generalData['SGData'] 1648 cell = generalData['Cell'][1:8] 1649 A = G2lat.cell2A(cell[:6]) 1650 Hmax = np.asarray(G2lat.getHKLmax(dmin,SGData,A),dtype='i')+1 1651 adjHKLmax(SGData,Hmax) 1652 Fhkl = np.zeros(shape=2*Hmax,dtype='c16') 1653 # Fhkl[0,0,0] = generalData['F000X'] 1654 time0 = time.time() 1655 for ref in reflData: 1656 if ref[4] >= dmin: 1657 Fosq,Fcsq,ph = ref[8:11] 1658 for i,hkl in enumerate(ref[11]): 1659 hkl = np.asarray(hkl,dtype='i') 1660 dp = 360.*ref[12][i] 1661 a = cosd(ph+dp) 1662 b = sind(ph+dp) 1663 phasep = complex(a,b) 1664 phasem = complex(a,b) 1665 if 'Fobs' in mapData['MapType']: 1666 F = np.sqrt(Fosq) 1667 h,k,l = hkl+Hmax 1668 Fhkl[h,k,l] = F*phasep 1669 h,k,l = hkl+Hmax 1670 Fhkl[h,k,l] = F*phasem 1671 elif 'Fcalc' in mapData['MapType']: 1672 F = np.sqrt(Fcsq) 1673 h,k,l = hkl+Hmax 1674 Fhkl[h,k,l] = F*phasep 1675 h,k,l = hkl+Hmax 1676 Fhkl[h,k,l] = F*phasem 1677 elif 'deltF' in mapData['MapType']: 1678 dF = np.sqrt(Fosq)np.sqrt(Fcsq) 1679 h,k,l = hkl+Hmax 1680 Fhkl[h,k,l] = dF*phasep 1681 h,k,l = hkl+Hmax 1682 Fhkl[h,k,l] = dF*phasem 1683 elif '2*FoFc' in mapData['MapType']: 1684 F = 2.*np.sqrt(Fosq)np.sqrt(Fcsq) 1685 h,k,l = hkl+Hmax 1686 Fhkl[h,k,l] = F*phasep 1687 h,k,l = hkl+Hmax 1688 Fhkl[h,k,l] = F*phasem 1689 elif 'Patterson' in mapData['MapType']: 1690 h,k,l = hkl+Hmax 1691 Fhkl[h,k,l] = complex(Fosq,0.) 1692 h,k,l = hkl+Hmax 1693 Fhkl[h,k,l] = complex(Fosq,0.) 1694 rho = fft.fftn(fft.fftshift(Fhkl))/cell[6] 1695 print 'Fourier map time: %.4f'%(time.time()time0),'no. elements: %d'%(Fhkl.size) 1696 mapData['rho'] = np.real(rho) 1697 mapData['rhoMax'] = max(np.max(mapData['rho']),np.min(mapData['rho'])) 1698 return mapData 1699 1700 # map printing for testing purposes 1701 def printRho(SGLaue,rho,rhoMax): 1702 dim = len(rho.shape) 1703 if dim == 2: 1704 ix,jy = rho.shape 1705 for j in range(jy): 1706 line = '' 1707 if SGLaue in ['3','3m1','31m','6/m','6/mmm']: 1708 line += (jyj)*' ' 1709 for i in range(ix): 1710 r = int(100*rho[i,j]/rhoMax) 1711 line += '%4d'%(r) 1712 print line+'\n' 1713 else: 1714 ix,jy,kz = rho.shape 1715 for k in range(kz): 1716 print 'k = ',k 1717 for j in range(jy): 1718 line = '' 1719 if SGLaue in ['3','3m1','31m','6/m','6/mmm']: 1720 line += (jyj)*' ' 1721 for i in range(ix): 1722 r = int(100*rho[i,j,k]/rhoMax) 1723 line += '%4d'%(r) 1724 print line+'\n' 1725 ## keep this 1726 1727 def findOffset(SGData,A,Fhkl): 1728 if SGData['SpGrp'] == 'P 1': 1729 return [0,0,0] 1730 hklShape = Fhkl.shape 1731 steps = np.array(hklShape) 1732 Hmax = 2*np.asarray(G2lat.getHKLmax(4.5,SGData,A),dtype='i') 1733 Fmax = np.max(np.absolute(Fhkl)) 1734 hklHalf = np.array(hklShape)/2 1735 sortHKL = np.argsort(Fhkl.flatten()) 1736 Fdict = {} 1737 for hkl in sortHKL: 1738 HKL = np.unravel_index(hkl,hklShape) 1739 F = Fhkl[HKL[0]][HKL[1]][HKL[2]] 1740 if F == 0.: 1741 break 1742 Fdict['%.6f'%(np.absolute(F))] = hkl 1743 Flist = np.flipud(np.sort(Fdict.keys())) 1744 F = str(1.e6) 1745 i = 0 1746 DH = [] 1747 Dphi = [] 1748 while i < 20 and len(DH) < 30: 1749 F = Flist[i] 1750 hkl = np.unravel_index(Fdict[F],hklShape) 1751 iabsnt,mulp,Uniq,Phi = G2spc.GenHKLf(list(hklhklHalf),SGData) 1752 Uniq = np.array(Uniq,dtype='i') 1753 Phi = np.array(Phi) 1754 Uniq = np.concatenate((Uniq,Uniq))+hklHalf # put in Friedel pairs & make as index to Farray 1755 Phi = np.concatenate((Phi,Phi)) # and their phase shifts 1756 Fh0 = Fhkl[hkl[0],hkl[1],hkl[2]] 1757 ang0 = np.angle(Fh0,deg=True)/360. 1758 for j,H in enumerate(Uniq[1:]): 1759 ang = (np.angle(Fhkl[H[0],H[1],H[2]],deg=True)/360.Phi[j+1]) 1760 dH = Hhkl 1761 dang = angang0 1762 if np.any(np.abs(dH)Hmax > 0): #keep low order DHs 1763 continue 1764 DH.append(dH) 1765 Dphi.append((dang+0.5) % 1.0) 1766 i += 1 1767 DH = np.array(DH) 1768 print ' map offset no.of terms: %d'%(len(DH)) 1769 Dphi = np.array(Dphi) 1770 X,Y,Z = np.mgrid[0:1:1./steps[0],0:1:1./steps[1],0:1:1./steps[2]] 1771 XYZ = np.array(zip(X.flatten(),Y.flatten(),Z.flatten())) 1772 Mmap = np.reshape(np.sum(((np.dot(XYZ,DH.T)+.5)%1.Dphi)**2,axis=1),newshape=steps) 1773 chisq = np.min(Mmap) 1774 DX = np.array(np.unravel_index(np.argmin(Mmap),Mmap.shape)) 1775 print ' map offset chi**2: %.3f, map offset: %d %d %d'%(chisq,DX[0],DX[1],DX[2]) 1776 return DX 1777 1778 def ChargeFlip(data,reflData,pgbar): 1779 generalData = data['General'] 1780 mapData = generalData['Map'] 1781 flipData = generalData['Flip'] 1782 FFtable = {} 1783 if 'None' not in flipData['Norm element']: 1784 normElem = flipData['Norm element'].upper() 1785 FFs = G2el.GetFormFactorCoeff(normElem.split('+')[0].split('')[0]) 1786 for ff in FFs: 1787 if ff['Symbol'] == normElem: 1788 FFtable.update(ff) 1789 dmin = flipData['Resolution'] 1790 SGData = generalData['SGData'] 1791 cell = generalData['Cell'][1:8] 1792 A = G2lat.cell2A(cell[:6]) 1793 Vol = cell[6] 1794 Hmax = np.asarray(G2lat.getHKLmax(dmin,SGData,A),dtype='i')+1 1795 adjHKLmax(SGData,Hmax) 1796 Ehkl = np.zeros(shape=2*Hmax,dtype='c16') #2X64bits per complex no. 1797 time0 = time.time() 1798 for ref in reflData: 1799 dsp = ref[4] 1800 if dsp >= dmin: 1801 ff = 0.1*Vol #est. no. atoms for ~10A**3/atom 1802 if FFtable: 1803 SQ = 0.25/dsp**2 1804 ff *= G2el.ScatFac(FFtable,SQ)[0] 1805 if ref[8] > 0.: 1806 E = np.sqrt(ref[8])/ff 1807 else: 1808 E = 0. 1809 ph = ref[10] 1810 ph = rn.uniform(0.,360.) 1811 for i,hkl in enumerate(ref[11]): 1812 hkl = np.asarray(hkl,dtype='i') 1813 dp = 360.*ref[12][i] 1814 a = cosd(ph+dp) 1815 b = sind(ph+dp) 1816 phasep = complex(a,b) 1817 phasem = complex(a,b) 1818 h,k,l = hkl+Hmax 1819 Ehkl[h,k,l] = E*phasep 1820 h,k,l = hkl+Hmax #Friedel pair refl. 1821 Ehkl[h,k,l] = E*phasem 1822 # Ehkl[Hmax] = 0.00001 #this to preserve F[0,0,0] 1823 CEhkl = copy.copy(Ehkl) 1824 MEhkl = ma.array(Ehkl,mask=(Ehkl==0.0)) 1825 Emask = ma.getmask(MEhkl) 1826 sumE = np.sum(ma.array(np.absolute(CEhkl),mask=Emask)) 1827 Ncyc = 0 1828 old = np.seterr(all='raise') 1829 while True: 1830 CErho = np.real(fft.fftn(fft.fftshift(CEhkl)))*(1.+0j) 1831 CEsig = np.std(CErho) 1832 CFrho = np.where(np.real(CErho) >= flipData['kfactor']*CEsig,CErho,CErho) 1833 CFhkl = fft.ifftshift(fft.ifftn(CFrho)) 1834 CFhkl = np.where(CFhkl,CFhkl,1.0) #avoid divide by zero 1835 phase = CFhkl/np.absolute(CFhkl) 1836 CEhkl = np.absolute(Ehkl)*phase 1837 Ncyc += 1 1838 sumCF = np.sum(ma.array(np.absolute(CFhkl),mask=Emask)) 1839 DEhkl = np.absolute(np.absolute(Ehkl)/sumEnp.absolute(CFhkl)/sumCF) 1840 Rcf = min(100.,np.sum(ma.array(DEhkl,mask=Emask)*100.)) 1841 if Rcf < 5.: 1842 break 1843 GoOn = pgbar.Update(Rcf,newmsg='%s%8.3f%s\n%s %d'%('Residual Rcf =',Rcf,'%','No.cycles = ',Ncyc))[0] 1844 if not GoOn or Ncyc > 10000: 1845 break 1846 np.seterr(**old) 1847 print ' Charge flip time: %.4f'%(time.time()time0),'no. elements: %d'%(Ehkl.size) 1848 CErho = np.real(fft.fftn(fft.fftshift(CEhkl))) 1849 print ' No.cycles = ',Ncyc,'Residual Rcf =%8.3f%s'%(Rcf,'%')+' Map size:',CErho.shape 1850 roll = findOffset(SGData,A,CEhkl) 1851 1852 mapData['Rcf'] = Rcf 1853 mapData['rho'] = np.roll(np.roll(np.roll(CErho,roll[0],axis=0),roll[1],axis=1),roll[2],axis=2) 1854 mapData['rhoMax'] = max(np.max(mapData['rho']),np.min(mapData['rho'])) 1855 mapData['rollMap'] = [0,0,0] 1856 return mapData 1857 809 1858 def SearchMap(data,keepDup=False,Pgbar=None): 810 1859 … … 1091 2140 return Q 1092 2141 2142 >>>>>>> .r762 
trunk/GSASIIphsGUI.py
r762 r763 1 <<<<<<< .mine 1 2 # * coding: utf8 * 2 3 #GSASII  phase data display routines … … 4298 4299 mapData = generalData['Map'] 4299 4300 if len(mapData['rho']): 4300 pgbar = wx.ProgressDialog('Map search','No. Peaks found =',1001.0, 4301 style = wx.PD_ELAPSED_TIMEwx.PD_AUTO_HIDEwx.PD_CAN_ABORT) 4302 screenSize = wx.ClientDisplayRect() 4303 Size = pgbar.GetSize() 4304 Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x 4305 pgbar.SetPosition(wx.Point(screenSize[2]Size[0]305,screenSize[1]+5)) 4306 pgbar.SetSize(Size) 4301 wx.BeginBusyCursor() 4307 4302 try: 4308 peaks,mags,dzeros = G2mth.SearchMap(data ,keepDup=True,Pgbar=pgbar)4303 peaks,mags,dzeros = G2mth.SearchMap(data) 4309 4304 finally: 4310 pgbar.Destroy() 4311 sortIdx = np.argsort(mags.flatten()) 4305 wx.EndBusyCursor() 4312 4306 if len(peaks): 4313 data['Map Peaks'] = np.concatenate((mags,peaks,dzeros),axis=1) 4314 print ' Map search finished, time = %.2fs'%(time.time()time0) 4307 mapPeaks = np.concatenate((mags,peaks,dzeros),axis=1) 4308 data['Map Peaks'] = G2mth.sortArray(mapPeaks,0,reverse=True) 4309 print ' Map search finished, time = %.2fs'%(time.time()time0) 4310 print ' No.peaks found:',len(peaks) 4315 4311 Page = G2frame.dataDisplay.FindPage('Map peaks') 4316 4312 G2frame.dataDisplay.ChangeSelection(Page) … … 4485 4481 G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged) 4486 4482 G2frame.dataDisplay.SetSelection(oldPage) 4483 ======= 4484 # * coding: utf8 * 4485 #GSASII  phase data display routines 4486 ########### SVN repository information ################### 4487 # $Date$ 4488 # $Author$ 4489 # $Revision$ 4490 # $URL$ 4491 # $Id$ 4492 ########### SVN repository information ################### 4493 import wx 4494 import wx.grid as wg 4495 import matplotlib as mpl 4496 import math 4497 import copy 4498 import time 4499 import sys 4500 import random as ran 4501 import cPickle 4502 import GSASIIpath 4503 GSASIIpath.SetVersionNumber("$Revision$") 4504 import GSASIIlattice as G2lat 4505 import GSASIIspc as G2spc 4506 import GSASIIElem as G2elem 4507 import GSASIIElemGUI as G2elemGUI 4508 import GSASIIplot as G2plt 4509 import GSASIIgrid as G2gd 4510 import GSASIIIO as G2IO 4511 import GSASIIstruct as G2str 4512 import GSASIImath as G2mth 4513 import GSASIIpwd as G2pwd 4514 import numpy as np 4515 import numpy.linalg as nl 4516 import numpy.ma as ma 4517 4518 VERY_LIGHT_GREY = wx.Colour(235,235,235) 4519 WHITE = wx.Colour(255,255,255) 4520 BLACK = wx.Colour(0,0,0) 4521 mapDefault = {'MapType':'','RefList':'','Resolution':0.5, 4522 'rho':[],'rhoMax':0.,'mapSize':10.0,'cutOff':50.,'Flip':False} 4523 # trig functions in degrees 4524 sind = lambda x: np.sin(x*np.pi/180.) 4525 tand = lambda x: np.tan(x*np.pi/180.) 4526 cosd = lambda x: np.cos(x*np.pi/180.) 4527 asind = lambda x: 180.*np.arcsin(x)/np.pi 4528 acosd = lambda x: 180.*np.arccos(x)/np.pi 4529 4530 class SymOpDialog(wx.Dialog): 4531 def __init__(self,parent,SGData,New=True,ForceUnit=False): 4532 wx.Dialog.__init__(self,parent,1,'Select symmetry operator', 4533 pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE) 4534 panel = wx.Panel(self) 4535 self.SGData = SGData 4536 self.New = New 4537 self.Force = ForceUnit 4538 self.OpSelected = [0,0,0,[0,0,0],False,False] 4539 mainSizer = wx.BoxSizer(wx.VERTICAL) 4540 if ForceUnit: 4541 choice = ['No','Yes'] 4542 self.force = wx.RadioBox(panel,1,'Force to unit cell?',choices=choice) 4543 self.force.Bind(wx.EVT_RADIOBOX, self.OnOpSelect) 4544 mainSizer.Add(self.force,0,wx.ALIGN_CENTER_VERTICAL) 4545 mainSizer.Add((5,5),0) 4546 if SGData['SGInv']: 4547 choice = ['No','Yes'] 4548 self.inv = wx.RadioBox(panel,1,'Choose inversion?',choices=choice) 4549 self.inv.Bind(wx.EVT_RADIOBOX, self.OnOpSelect) 4550 mainSizer.Add(self.inv,0,wx.ALIGN_CENTER_VERTICAL) 4551 mainSizer.Add((5,5),0) 4552 if SGData['SGLatt'] != 'P': 4553 LattOp = G2spc.Latt2text(SGData['SGLatt']).split(';') 4554 self.latt = wx.RadioBox(panel,1,'Choose cell centering?',choices=LattOp) 4555 self.latt.Bind(wx.EVT_RADIOBOX, self.OnOpSelect) 4556 mainSizer.Add(self.latt,0,wx.ALIGN_CENTER_VERTICAL) 4557 mainSizer.Add((5,5),0) 4558 if SGData['SGLaue'] in ['1','2/m','mmm','4/m','4/mmm']: 4559 Ncol = 2 4560 else: 4561 Ncol = 3 4562 OpList = [] 4563 for M,T in SGData['SGOps']: 4564 OpList.append(G2spc.MT2text(M,T)) 4565 self.oprs = wx.RadioBox(panel,1,'Choose space group operator?',choices=OpList, 4566 majorDimension=Ncol) 4567 self.oprs.Bind(wx.EVT_RADIOBOX, self.OnOpSelect) 4568 mainSizer.Add(self.oprs,0,wx.ALIGN_CENTER_VERTICAL) 4569 mainSizer.Add((5,5),0) 4570 mainSizer.Add(wx.StaticText(panel,1," Choose unit cell?"),0,wx.ALIGN_CENTER_VERTICAL) 4571 mainSizer.Add((5,5),0) 4572 cellSizer = wx.BoxSizer(wx.HORIZONTAL) 4573 cellSizer.Add((5,0),0) 4574 cellName = ['X','Y','Z'] 4575 self.cell = [] 4576 for i in range(3): 4577 self.cell.append(wx.SpinCtrl(panel,1,cellName[i],size=wx.Size(50,20))) 4578 self.cell[1].SetRange(3,3) 4579 self.cell[1].SetValue(0) 4580 self.cell[1].Bind(wx.EVT_SPINCTRL, self.OnOpSelect) 4581 cellSizer.Add(self.cell[1],0,wx.ALIGN_CENTER_VERTICAL) 4582 mainSizer.Add(cellSizer,0,) 4583 if self.New: 4584 choice = ['No','Yes'] 4585 self.new = wx.RadioBox(panel,1,'Generate new positions?',choices=choice) 4586 self.new.Bind(wx.EVT_RADIOBOX, self.OnOpSelect) 4587 mainSizer.Add(self.new,0,wx.ALIGN_CENTER_VERTICAL) 4588 mainSizer.Add((5,5),0) 4589 4590 OkBtn = wx.Button(panel,1,"Ok") 4591 OkBtn.Bind(wx.EVT_BUTTON, self.OnOk) 4592 cancelBtn = wx.Button(panel,1,"Cancel") 4593 cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel) 4594 btnSizer = wx.BoxSizer(wx.HORIZONTAL) 4595 btnSizer.Add((20,20),1) 4596 btnSizer.Add(OkBtn) 4597 btnSizer.Add((20,20),1) 4598 btnSizer.Add(cancelBtn) 4599 btnSizer.Add((20,20),1) 4600 4601 mainSizer.Add(btnSizer,0,wx.EXPANDwx.BOTTOMwx.TOP, 10) 4602 panel.SetSizer(mainSizer) 4603 panel.Fit() 4604 self.Fit() 4605 4606 def OnOpSelect(self,event): 4607 if self.SGData['SGInv']: 4608 self.OpSelected[0] = self.inv.GetSelection() 4609 if self.SGData['SGLatt'] != 'P': 4610 self.OpSelected[1] = self.latt.GetSelection() 4611 self.OpSelected[2] = self.oprs.GetSelection() 4612 for i in range(3): 4613 self.OpSelected[3][i] = float(self.cell[i].GetValue()) 4614 if self.New: 4615 self.OpSelected[4] = self.new.GetSelection() 4616 if self.Force: 4617 self.OpSelected[5] = self.force.GetSelection() 4618 4619 def GetSelection(self): 4620 return self.OpSelected 4621 4622 def OnOk(self,event): 4623 parent = self.GetParent() 4624 parent.Raise() 4625 self.EndModal(wx.ID_OK) 4626 4627 def OnCancel(self,event): 4628 parent = self.GetParent() 4629 parent.Raise() 4630 self.EndModal(wx.ID_CANCEL) 4631 4632 class DisAglDialog(wx.Dialog): 4633 4634 def __default__(self,data,default): 4635 if data: 4636 self.data = data 4637 else: 4638 self.data = {} 4639 self.data['Name'] = default['Name'] 4640 self.data['Factors'] = [0.85,0.85] 4641 self.data['AtomTypes'] = default['AtomTypes'] 4642 self.data['BondRadii'] = default['BondRadii'] 4643 self.data['AngleRadii'] = default['AngleRadii'] 4644 4645 def __init__(self,parent,data,default): 4646 wx.Dialog.__init__(self,parent,1,'Distance Angle Controls', 4647 pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE) 4648 self.default = default 4649 self.panel = wx.Panel(self) #just a dummy  gets destroyed in Draw! 4650 self.__default__(data,self.default) 4651 self.Draw(self.data) 4652 4653 def Draw(self,data): 4654 self.panel.Destroy() 4655 self.panel = wx.Panel(self) 4656 mainSizer = wx.BoxSizer(wx.VERTICAL) 4657 mainSizer.Add(wx.StaticText(self.panel,1,'Controls for phase '+data['Name']), 4658 0,wx.ALIGN_CENTER_VERTICALwx.LEFT,10) 4659 mainSizer.Add((10,10),1) 4660 4661 radiiSizer = wx.FlexGridSizer(2,3,5,5) 4662 radiiSizer.Add(wx.StaticText(self.panel,1,' Type'),0,wx.ALIGN_CENTER_VERTICAL) 4663 radiiSizer.Add(wx.StaticText(self.panel,1,'Bond radii'),0,wx.ALIGN_CENTER_VERTICAL) 4664 radiiSizer.Add(wx.StaticText(self.panel,1,'Angle radii'),0,wx.ALIGN_CENTER_VERTICAL) 4665 self.objList = {} 4666 for id,item in enumerate(self.data['AtomTypes']): 4667 radiiSizer.Add(wx.StaticText(self.panel,1,' '+item),0,wx.ALIGN_CENTER_VERTICAL) 4668 bRadii = wx.TextCtrl(self.panel,1,value='%.3f'%(data['BondRadii'][id]),style=wx.TE_PROCESS_ENTER) 4669 self.objList[bRadii.GetId()] = ['BondRadii',id] 4670 bRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal) 4671 bRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal) 4672 radiiSizer.Add(bRadii,0,wx.ALIGN_CENTER_VERTICAL) 4673 aRadii = wx.TextCtrl(self.panel,1,value='%.3f'%(data['AngleRadii'][id]),style=wx.TE_PROCESS_ENTER) 4674 self.objList[aRadii.GetId()] = ['AngleRadii',id] 4675 aRadii.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal) 4676 aRadii.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal) 4677 radiiSizer.Add(aRadii,0,wx.ALIGN_CENTER_VERTICAL) 4678 mainSizer.Add(radiiSizer,0,wx.EXPAND) 4679 factorSizer = wx.FlexGridSizer(2,2,5,5) 4680 Names = ['Bond','Angle'] 4681 for i,name in enumerate(Names): 4682 factorSizer.Add(wx.StaticText(self.panel,1,name+' search factor'),0,wx.ALIGN_CENTER_VERTICAL) 4683 bondFact = wx.TextCtrl(self.panel,1,value='%.3f'%(data['Factors'][i]),style=wx.TE_PROCESS_ENTER) 4684 self.objList[bondFact.GetId()] = ['Factors',i] 4685 bondFact.Bind(wx.EVT_TEXT_ENTER,self.OnRadiiVal) 4686 bondFact.Bind(wx.EVT_KILL_FOCUS,self.OnRadiiVal) 4687 factorSizer.Add(bondFact) 4688 mainSizer.Add(factorSizer,0,wx.EXPAND) 4689 4690 OkBtn = wx.Button(self.panel,1,"Ok") 4691 OkBtn.Bind(wx.EVT_BUTTON, self.OnOk) 4692 ResetBtn = wx.Button(self.panel,1,'Reset') 4693 ResetBtn.Bind(wx.EVT_BUTTON, self.OnReset) 4694 btnSizer = wx.BoxSizer(wx.HORIZONTAL) 4695 btnSizer.Add((20,20),1) 4696 btnSizer.Add(OkBtn) 4697 btnSizer.Add(ResetBtn) 4698 btnSizer.Add((20,20),1) 4699 mainSizer.Add(btnSizer,0,wx.EXPANDwx.BOTTOMwx.TOP, 10) 4700 self.panel.SetSizer(mainSizer) 4701 self.panel.Fit() 4702 self.Fit() 4703 4704 def OnRadiiVal(self,event): 4705 Obj = event.GetEventObject() 4706 item = self.objList[Obj.GetId()] 4707 try: 4708 self.data[item[0]][item[1]] = float(Obj.GetValue()) 4709 except ValueError: 4710 pass 4711 Obj.SetValue("%.3f"%(self.data[item[0]][item[1]])) #reset in case of error 4712 4713 def GetData(self): 4714 return self.data 4715 4716 def OnOk(self,event): 4717 parent = self.GetParent() 4718 parent.Raise() 4719 self.EndModal(wx.ID_OK) 4720 4721 def OnReset(self,event): 4722 data = {} 4723 self.__default__(data,self.default) 4724 self.Draw(self.data) 4725 4726 class SingleFloatDialog(wx.Dialog): 4727 4728 def __init__(self,parent,title,prompt,value,limits=[0.,1.]): 4729 wx.Dialog.__init__(self,parent,1,title, 4730 pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE) 4731 self.panel = wx.Panel(self) #just a dummy  gets destroyed in Draw! 4732 self.limits = limits 4733 self.value = value 4734 self.prompt = prompt 4735 self.Draw() 4736 4737 def Draw(self): 4738 4739 def OnValItem(event): 4740 try: 4741 val = float(valItem.GetValue()) 4742 if val < self.limits[0] or val > self.limits[1]: 4743 raise ValueError 4744 except ValueError: 4745 val = self.value 4746 self.value = val 4747 valItem.SetValue('%.5g'%(self.value)) 4748 4749 self.panel.Destroy() 4750 self.panel = wx.Panel(self) 4751 mainSizer = wx.BoxSizer(wx.VERTICAL) 4752 mainSizer.Add(wx.StaticText(self.panel,1,self.prompt),0,wx.ALIGN_CENTER) 4753 valItem = wx.TextCtrl(self.panel,1,value='%.5g'%(self.value),style=wx.TE_PROCESS_ENTER) 4754 mainSizer.Add(valItem,0,wx.ALIGN_CENTER) 4755 valItem.Bind(wx.EVT_TEXT_ENTER,OnValItem) 4756 valItem.Bind(wx.EVT_KILL_FOCUS,OnValItem) 4757 OkBtn = wx.Button(self.panel,1,"Ok") 4758 OkBtn.Bind(wx.EVT_BUTTON, self.OnOk) 4759 CancelBtn = wx.Button(self.panel,1,'Cancel') 4760 CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel) 4761 btnSizer = wx.BoxSizer(wx.HORIZONTAL) 4762 btnSizer.Add((20,20),1) 4763 btnSizer.Add(OkBtn) 4764 btnSizer.Add(CancelBtn) 4765 btnSizer.Add((20,20),1) 4766 mainSizer.Add(btnSizer,0,wx.EXPANDwx.BOTTOMwx.TOP, 10) 4767 self.panel.SetSizer(mainSizer) 4768 self.panel.Fit() 4769 self.Fit() 4770 4771 def GetValue(self): 4772 return self.value 4773 4774 def OnOk(self,event): 4775 parent = self.GetParent() 4776 parent.Raise() 4777 self.EndModal(wx.ID_OK) 4778 4779 def OnCancel(self,event): 4780 parent = self.GetParent() 4781 parent.Raise() 4782 self.EndModal(wx.ID_CANCEL) 4783 4784 class GridFractionEditor(wg.PyGridCellEditor): 4785 def __init__(self,grid): 4786 wg.PyGridCellEditor.__init__(self) 4787 4788 def Create(self, parent, id, evtHandler): 4789 self._tc = wx.TextCtrl(parent, id, "") 4790 self._tc.SetInsertionPoint(0) 4791 self.SetControl(self._tc) 4792 4793 if evtHandler: 4794 self._tc.PushEventHandler(evtHandler) 4795 4796 self._tc.Bind(wx.EVT_CHAR, self.OnChar) 4797 4798 def SetSize(self, rect): 4799 self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2, 4800 wx.SIZE_ALLOW_MINUS_ONE) 4801 4802 def BeginEdit(self, row, col, grid): 4803 self.startValue = grid.GetTable().GetValue(row, col) 4804 self._tc.SetValue(str(self.startValue)) 4805 self._tc.SetInsertionPointEnd() 4806 self._tc.SetFocus() 4807 self._tc.SetSelection(0, self._tc.GetLastPosition()) 4808 4809 def EndEdit(self, row, col, grid): 4810 changed = False 4811 4812 val = self._tc.GetValue() 4813 4814 if val != self.startValue: 4815 changed = True 4816 if '/' in val and '.' not in val: 4817 val += '.' 4818 try: 4819 val = float(eval(val)) 4820 except (SyntaxError,NameError): 4821 val = self.startValue 4822 grid.GetTable().SetValue(row, col, val) # update the table 4823 4824 self.startValue = '' 4825 self._tc.SetValue('') 4826 return changed 4827 4828 def Reset(self): 4829 self._tc.SetValue(self.startValue) 4830 self._tc.SetInsertionPointEnd() 4831 4832 def Clone(self): 4833 return GridFractionEditor(grid) 4834 4835 def StartingKey(self, evt): 4836 self.OnChar(evt) 4837 if evt.GetSkipped(): 4838 self._tc.EmulateKeyPress(evt) 4839 4840 def OnChar(self, evt): 4841 key = evt.GetKeyCode() 4842 if key > 255: 4843 evt.Skip() 4844 return 4845 char = chr(key) 4846 if char in '.+/0123456789': 4847 self._tc.WriteText(char) 4848 else: 4849 evt.Skip() 4850 4851 def FindAtomIndexByIDs(atomData,IDs,Draw=True): 4852 indx = [] 4853 for i,atom in enumerate(atomData): 4854 if Draw and atom[3] in IDs: 4855 indx.append(i) 4856 elif atom[1] in IDs: 4857 indx.append(i) 4858 return indx 4859 4860 def UpdatePhaseData(G2frame,Item,data,oldPage): 4861 4862 Atoms = [] 4863 if G2frame.dataDisplay: 4864 G2frame.dataDisplay.Destroy() 4865 PhaseName = G2frame.PatternTree.GetItemText(Item) 4866 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu) 4867 G2frame.dataFrame.SetLabel('Phase Data for '+PhaseName) 4868 G2frame.dataFrame.CreateStatusBar() 4869 G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize()) 4870 4871 def SetupGeneral(): 4872 generalData = data['General'] 4873 atomData = data['Atoms'] 4874 generalData['AtomTypes'] = [] 4875 generalData['Isotopes'] = {} 4876 # various patches 4877 if 'Isotope' not in generalData: 4878 generalData['Isotope'] = {} 4879 if 'Data plot type' not in generalData: 4880 generalData['Data plot type'] = 'Mustrain' 4881 if 'POhkl' not in generalData: 4882 generalData['POhkl'] = [0,0,1] 4883 if 'Map' not in generalData: 4884 generalData['Map'] = mapDefault 4885 if 'Flip' not in generalData: 4886 generalData['Flip'] = {'RefList':'','Resolution':0.5,'Norm element':'None', 4887 'kfactor':0.1} 4888 if 'doPawley' not in generalData: 4889 generalData['doPawley'] = False 4890 if 'Pawley dmin' not in generalData: 4891 generalData['Pawley dmin'] = 1.0 4892 if 'Pawley neg wt' not in generalData: 4893 generalData['Pawley neg wt'] = 0.0 4894 4895 # if 'SH Texture' not in generalData: 4896 # generalData['SH Texture'] = data['SH Texture'] 4897 generalData['NoAtoms'] = {} 4898 generalData['BondRadii'] = [] 4899 generalData['AngleRadii'] = [] 4900 generalData['vdWRadii'] = [] 4901 generalData['AtomMass'] = [] 4902 generalData['Color'] = [] 4903 generalData['Mydir'] = G2frame.dirname 4904 cx,ct,cs,cia = [3,1,7,9] 4905 if generalData['Type'] =='macromolecular': 4906 cx,ct,cs,cia = [6,4,10,12] 4907 generalData['AtomPtrs'] = [cx,ct,cs,cia] 4908 for atom in atomData: 4909 atom[ct] = atom[ct].lower().capitalize() #force to standard form 4910 if generalData['AtomTypes'].count(atom[ct]): 4911 generalData['NoAtoms'][atom[ct]] += atom[cs1]*float(atom[cs+1]) 4912 elif atom[ct] != 'UNK': 4913 Info = G2elem.GetAtomInfo(atom[ct]) 4914 generalData['AtomTypes'].append(atom[ct]) 4915 generalData['Z'] = Info['Z'] 4916 generalData['Isotopes'][atom[ct]] = Info['Isotopes'] 4917 generalData['BondRadii'].append(Info['Drad']) 4918 generalData['AngleRadii'].append(Info['Arad']) 4919 generalData['vdWRadii'].append(Info['Vdrad']) 4920 if atom[ct] in generalData['Isotope']: 4921 generalData['AtomMass'].append(Info['Isotopes'][generalData['Isotope'][atom[ct]]][0]) 4922 else: 4923 generalData['Isotope'][atom[ct]] = 'Nat. Abund.' 4924 generalData['AtomMass'].append(Info['Mass']) 4925 generalData['NoAtoms'][atom[ct]] = atom[cs1]*float(atom[cs+1]) 4926 generalData['Color'].append(Info['Color']) 4927 F000X = 0. 4928 F000N = 0. 4929 for i,elem in enumerate(generalData['AtomTypes']): 4930 F000X += generalData['NoAtoms'][elem]*generalData['Z'] 4931 isotope = generalData['Isotope'][elem] 4932 F000N += generalData['NoAtoms'][elem]*generalData['Isotopes'][elem][isotope][1] 4933 generalData['F000X'] = F000X 4934 generalData['F000N'] = F000N 4935 4936 4937 ################################################################################ 4938 ##### General phase routines 4939 ################################################################################ 4940 4941 def UpdateGeneral(): 4942 4943 ''' default dictionary structure for phase data: (taken from GSASII.py) 4944 'General':{ 4945 'Name':PhaseName 4946 'Type':'nuclear' 4947 'SGData':SGData 4948 'Cell':[False,10.,10.,10.,90.,90.,90,1000.] 4949 'AtomPtrs':[] 4950 'Histogram list':['',] 4951 'Pawley dmin':1.0, 4952 'Pawley neg wt':0.0} 4953 'Atoms':[] 4954 'Drawing':{} 4955 ''' 4956 4957 phaseTypes = ['nuclear','modulated','magnetic','macromolecular'] 4958 SetupGeneral() 4959 generalData = data['General'] 4960 Map = generalData['Map'] 4961 Flip = generalData['Flip'] 4962 PWDR = any(['PWDR' in item for item in data['Histograms'].keys()]) 4963 4964 def NameSizer(): 4965 4966 def OnPhaseName(event): 4967 oldName = generalData['Name'] 4968 generalData['Name'] = NameTxt.GetValue() 4969 G2frame.G2plotNB.Rename(oldName,generalData['Name']) 4970 G2frame.dataFrame.SetLabel('Phase Data for '+generalData['Name']) 4971 G2frame.PatternTree.SetItemText(Item,generalData['Name']) 4972 #Hmm, need to change phase name key in Reflection Lists for each histogram 4973 4974 def OnPhaseType(event): 4975 if not generalData['AtomTypes']: #can change only if no atoms! 4976 generalData['Type'] = TypeTxt.GetValue() 4977 dataDisplay.DestroyChildren() #needed to clear away bad cellSizer, etc. 4978 wx.CallAfter(UpdateGeneral) 4979 else: 4980 TypeTxt.SetValue(generalData['Type']) 4981 4982 def OnSpaceGroup(event): 4983 SpcGp = SGTxt.GetValue() 4984 SGErr,SGData = G2spc.SpcGroup(SpcGp) 4985 # try a lookup on the usersupplied name 4986 if SGErr: 4987 SpGrpNorm = G2spc.StandardizeSpcName(SpcGp) 4988 if SpGrpNorm: 4989 E,SGData = G2spc.SpcGroup(SpGrpNorm) 4990 if not E: SGErr = False 4991 if SGErr: 4992 text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous'] 4993 SGTxt.SetValue(generalData['SGData']['SpGrp']) 4994 msg = 'Space Group Error' 4995 Style = wx.ICON_EXCLAMATION 4996 else: 4997 text = G2spc.SGPrint(SGData) 4998 generalData['SGData'] = SGData 4999 msg = 'Space Group Information' 5000 Style = wx.ICON_INFORMATION 5001 Text = '' 5002 for line in text: 5003 Text += line+'\n' 5004 wx.MessageBox(Text,caption=msg,style=Style) 5005 dataDisplay.DestroyChildren() #needed to clear away bad cellSizer, etc. 5006 wx.CallAfter(UpdateGeneral) 5007 5008 nameSizer = wx.BoxSizer(wx.HORIZONTAL) 5009 nameSizer.Add(wx.StaticText(dataDisplay,1,' Phase name: '),0,wx.ALIGN_CENTER_VERTICAL) 5010 NameTxt = wx.TextCtrl(dataDisplay,1,value=generalData['Name'],style=wx.TE_PROCESS_ENTER) 5011 NameTxt.Bind(wx.EVT_TEXT_ENTER,OnPhaseName) 5012 NameTxt.Bind(wx.EVT_KILL_FOCUS,OnPhaseName) 5013 nameSizer.Add(NameTxt,0,wx.ALIGN_CENTER_VERTICAL) 5014 nameSizer.Add(wx.StaticText(dataDisplay,1,' Phase type: '),0,wx.ALIGN_CENTER_VERTICAL) 5015 if len(data['Atoms']): 5016 choices = phaseTypes[:1] 5017 else: 5018 choices = phaseTypes 5019 TypeTxt = wx.ComboBox(dataDisplay,1,value=generalData['Type'],choices=choices, 5020 style=wx.CB_READONLYwx.CB_DROPDOWN) 5021 TypeTxt.Bind(wx.EVT_COMBOBOX, OnPhaseType) 5022 nameSizer.Add(TypeTxt,0,wx.ALIGN_CENTER_VERTICAL) 5023 nameSizer.Add(wx.StaticText(dataDisplay,1,' Space group: '),0,wx.ALIGN_CENTER_VERTICAL) 5024 SGTxt = wx.TextCtrl(dataDisplay,1,value=generalData['SGData']['SpGrp'],style=wx.TE_PROCESS_ENTER) 5025 SGTxt.Bind(wx.EVT_TEXT_ENTER,OnSpaceGroup) 5026 nameSizer.Add(SGTxt,0,wx.ALIGN_CENTER_VERTICAL) 5027 return nameSizer 5028 5029 def CellSizer(): 5030 5031 cellGUIlist = [[['m3','m3m'],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])], 5032 [['3R','3mR'],6,zip([" a = "," alpha = "," Vol = "],["%.5f","%.3f","%.3f"],[True,True,False],[0,2,0])], 5033 [['3','3m1','31m','6/m','6/mmm','4/m','4/mmm'],6,zip([" a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])], 5034 [['mmm'],8,zip([" a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"], 5035 [True,True,True,False],[0,1,2,0])], 5036 [['2/m'+'a'],10,zip([" a = "," b = "," c = "," alpha = "," Vol = "], 5037 ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])], 5038 [['2/m'+'b'],10,zip([" a = "," b = "," c = "," beta = "," Vol = "], 5039 ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])], 5040 [['2/m'+'c'],10,zip([" a = "," b = "," c = "," gamma = "," Vol = "], 5041 ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])], 5042 [['1'],8,zip([" a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "], 5043 ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"], 5044 [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]] 5045 5046 def OnCellRef(event): 5047 generalData['Cell'][0] = cellRef.GetValue() 5048 5049 def OnCellChange(event): 5050 SGData = generalData['SGData'] 5051 laue = SGData['SGLaue'] 5052 if laue == '2/m': 5053 laue += SGData['SGUniq'] 5054 cell = generalData['Cell'] 5055 Obj = event.GetEventObject() 5056 ObjId = cellList.index(Obj.GetId()) 5057 try: 5058 value = max(1.0,float(Obj.GetValue())) 5059 except ValueError: 5060 if ObjId < 3: #bad cell edge  reset 5061 value = controls[6+ObjId] 5062 else: #bad angle 5063 value = 90. 5064 if laue in ['m3','m3m']: 5065 cell[1] = cell[2] = cell[3] = value 5066 cell[4] = cell[5] = cell[6] = 90.0 5067 Obj.SetValue("%.5f"%(cell[1])) 5068 elif laue in ['3R','3mR']: 5069 if ObjId == 0: 5070 cell[1] = cell[2] = cell[3] = value 5071 Obj.SetValue("%.5f"%(cell[1])) 5072 else: 5073 cell[4] = cell[5] = cell[6] = value 5074 Obj.SetValue("%.5f"%(cell[4])) 5075 elif laue in ['3','3m1','31m','6/m','6/mmm','4/m','4/mmm']: 5076 cell[4] = cell[5] = 90. 5077 cell[6] = 120. 5078 if laue in ['4/m','4/mmm']: 5079 cell[6] = 90. 5080 if ObjId == 0: 5081 cell[1] = cell[2] = value 5082 Obj.SetValue("%.5f"%(cell[1])) 5083 else: 5084 cell[3] = value 5085 Obj.SetValue("%.5f"%(cell[3])) 5086 elif laue in ['mmm']: 5087 cell[ObjId+1] = value 5088 cell[4] = cell[5] = cell[6] = 90. 5089 Obj.SetValue("%.5f"%(cell[ObjId+1])) 5090 elif laue in ['2/m'+'a']: 5091 cell[5] = cell[6] = 90. 5092 if ObjId != 3: 5093 cell[ObjId+1] = value 5094 Obj.SetValue("%.5f"%(cell[ObjId+1])) 5095 else: 5096 cell[4] = value 5097 Obj.SetValue("%.3f"%(cell[4])) 5098 elif laue in ['2/m'+'b']: 5099 cell[4] = cell[6] = 90. 5100 if ObjId != 3: 5101 cell[ObjId+1] = value 5102 Obj.SetValue("%.5f"%(cell[ObjId+1])) 5103 else: 5104 cell[5] = value 5105 Obj.SetValue("%.3f"%(cell[5])) 5106 elif laue in ['2/m'+'c']: 5107 cell[5] = cell[6] = 90. 5108 if ObjId != 3: 5109 cell[ObjId+1] = value 5110 Obj.SetValue("%.5f"%(cell[ObjId+1])) 5111 else: 5112 cell[6] = value 5113 Obj.SetValue("%.3f"%(cell[6])) 5114 else: 5115 cell[ObjId+1] = value 5116 if ObjId < 3: 5117 Obj.SetValue("%.5f"%(cell[1+ObjId])) 5118 else: 5119 Obj.SetValue("%.3f"%(cell[1+ObjId])) 5120 cell[7] = G2lat.calc_V(G2lat.cell2A(cell[1:7])) 5121 volVal.SetValue("%.3f"%(cell[7])) 5122 density,mattCoeff = G2mth.getDensity(generalData) 5123 if denSizer: 5124 denSizer[1].SetValue('%.3f'%(density)) 5125 if denSizer[2]: 5126 denSizer[2].SetValue('%.3f'%(mattCoeff)) 5127 generalData['Cell'] = cell 5128 5129 cell = generalData['Cell'] 5130 laue = generalData['SGData']['SGLaue'] 5131 if laue == '2/m': 5132 laue += generalData['SGData']['SGUniq'] 5133 for cellGUI in cellGUIlist: 5134 if laue in cellGUI[0]: 5135 useGUI = cellGUI 5136 cellSizer = wx.FlexGridSizer(2,useGUI[1]+1,5,5) 5137 if PWDR: 5138 cellRef = wx.CheckBox(dataDisplay,1,label='Refine unit cell:') 5139 cellSizer.Add(cellRef,0,wx.ALIGN_CENTER_VERTICAL) 5140 cellRef.Bind(wx.EVT_CHECKBOX, OnCellRef) 5141 cellRef.SetValue(cell[0]) 5142 cellList = [] 5143 for txt,fmt,ifEdit,Id in useGUI[2]: 5144 cellSizer.Add(wx.StaticText(dataDisplay,label=txt),0,wx.ALIGN_CENTER_VERTICAL) 5145 if ifEdit: #a,b,c,etc. 5146 cellVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[Id+1])), 5147 style=wx.TE_PROCESS_ENTER) 5148 cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange) 5149 cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange) 5150 cellSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL) 5151 cellList.append(cellVal.GetId()) 5152 else: #volume 5153 volVal = wx.TextCtrl(dataDisplay,value=(fmt%(cell[7])),style=wx.TE_READONLY) 5154 volVal.SetBackgroundColour(VERY_LIGHT_GREY) 5155 cellSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL) 5156 return cellSizer 5157 5158 def ElemSizer(): 5159 5160 def OnIsotope(event): 5161 Obj = event.GetEventObject() 5162 item = Indx[Obj.GetId()] 5163 isotope = Obj.GetValue() 5164 generalData['Isotope'][item] = isotope 5165 indx = generalData['AtomTypes'].index(item) 5166 data['General']['AtomMass'][indx] = generalData['Isotopes'][item][isotope][0] 5167 density,mattCoeff = G2mth.getDensity(generalData) 5168 denSizer[1].SetValue('%.3f'%(density)) 5169 if denSizer[2]: 5170 denSizer[2].SetValue('%.3f'%(mattCoeff)) 5171 5172 elemSizer = wx.FlexGridSizer(8,len(generalData['AtomTypes'])+1,1,1) 5173 elemSizer.Add(wx.StaticText(dataDisplay,label=' Elements'),0,wx.ALIGN_CENTER_VERTICAL) 5174 for elem in generalData['AtomTypes']: 5175 typTxt = wx.TextCtrl(dataDisplay,value=elem,style=wx.TE_READONLY) 5176 typTxt.SetBackgroundColour(VERY_LIGHT_GREY) 5177 elemSizer.Add(typTxt,0,wx.ALIGN_CENTER_VERTICAL) 5178 elemSizer.Add(wx.StaticText(dataDisplay,label=' Isotope'),0,wx.ALIGN_CENTER_VERTICAL) 5179 for elem in generalData['AtomTypes']: 5180 choices = generalData['Isotopes'][elem].keys() 5181 isoSel = wx.ComboBox(dataDisplay,1,value=generalData['Isotope'][elem],choices=choices, 5182 style=wx.CB_READONLYwx.CB_DROPDOWN) 5183 isoSel.Bind(wx.EVT_COMBOBOX,OnIsotope) 5184 Indx[isoSel.GetId()] = elem 5185 elemSizer.Add(isoSel,1,wx.ALIGN_CENTER_VERTICALwx.EXPAND) 5186 elemSizer.Add(wx.StaticText(dataDisplay,label=' No. per cell'),0,wx.ALIGN_CENTER_VERTICAL) 5187 for elem in generalData['AtomTypes']: 5188 numbTxt = wx.TextCtrl(dataDisplay,value='%.1f'%(generalData['NoAtoms'][elem]), 5189 style=wx.TE_READONLY) 5190 numbTxt.SetBackgroundColour(VERY_LIGHT_GREY) 5191 elemSizer.Add(numbTxt,0,wx.ALIGN_CENTER_VERTICAL) 5192 elemSizer.Add(wx.StaticText(dataDisplay,label=' Atom weight'),0,wx.ALIGN_CENTER_VERTICAL) 5193 for wt in generalData['AtomMass']: 5194 wtTxt = wx.TextCtrl(dataDisplay,value='%.3f'%(wt),style=wx.TE_READONLY) 5195 wtTxt.SetBackgroundColour(VERY_LIGHT_GREY) 5196 elemSizer.Add(wtTxt,0,wx.ALIGN_CENTER_VERTICAL) 5197 elemSizer.Add(wx.StaticText(dataDisplay,label=' Bond radii'),0,wx.ALIGN_CENTER_VERTICAL) 5198 for rad in generalData['BondRadii']: 5199 bondRadii = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY) 5200 bondRadii.SetBackgroundColour(VERY_LIGHT_GREY) 5201 elemSizer.Add(bondRadii,0,wx.ALIGN_CENTER_VERTICAL) 5202 elemSizer.Add(wx.StaticText(dataDisplay,label=' Angle radii'),0,wx.ALIGN_CENTER_VERTICAL) 5203 for rad in generalData['AngleRadii']: 5204 elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY) 5205 elemTxt.SetBackgroundColour(VERY_LIGHT_GREY) 5206 elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL) 5207 elemSizer.Add(wx.StaticText(dataDisplay,label=' van der Waals radii'),0,wx.ALIGN_CENTER_VERTICAL) 5208 for rad in generalData['vdWRadii']: 5209 elemTxt = wx.TextCtrl(dataDisplay,value='%.2f'%(rad),style=wx.TE_READONLY) 5210 elemTxt.SetBackgroundColour(VERY_LIGHT_GREY) 5211 elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL) 5212 elemSizer.Add(wx.StaticText(dataDisplay,label=' Default color'),0,wx.ALIGN_CENTER_VERTICAL) 5213 for R,G,B in generalData['Color']: 5214 colorTxt = wx.TextCtrl(dataDisplay,value='',style=wx.TE_READONLY) 5215 colorTxt.SetBackgroundColour(wx.Colour(R,G,B)) 5216 elemSizer.Add(colorTxt,0,wx.ALIGN_CENTER_VERTICAL) 5217 return elemSizer 5218 5219 def DenSizer(): 5220 5221 mass = G2mth.getMass(generalData) 5222 density,mattCoeff = G2mth.getDensity(generalData) 5223 denSizer = wx.BoxSizer(wx.HORIZONTAL) 5224 denSizer.Add(wx.StaticText(dataDisplay,1,' Density: '),0,wx.ALIGN_CENTER_VERTICAL) 5225 denTxt = wx.TextCtrl(dataDisplay,1,'%.3f'%(density),style=wx.TE_READONLY) 5226 denTxt.SetBackgroundColour(VERY_LIGHT_GREY) 5227 denSizer.Add(denTxt,0,wx.ALIGN_CENTER_VERTICAL) 5228 mattTxt = None 5229 if generalData['Type'] == 'macromolecular' and mass > 0.0: 5230 denSizer.Add(wx.StaticText(dataDisplay,1,' Matthews coeff.: '), 5231 0,wx.ALIGN_CENTER_VERTICAL) 5232 mattTxt = wx.TextCtrl(dataDisplay,1,'%.3f'%(mattCoeff),style=wx.TE_READONLY) 5233 mattTxt.SetBackgroundColour(VERY_LIGHT_GREY) 5234 denSizer.Add(mattTxt,0,wx.ALIGN_CENTER_VERTICAL) 5235 return denSizer,denTxt,mattTxt 5236 5237 def PawleySizer(): 5238 5239 def OnPawleyRef(event): 5240 generalData['doPawley'] = pawlRef.GetValue() 5241 5242 def OnPawleyVal(event): 5243 try: 5244 dmin = float(pawlVal.GetValue()) 5245 if 0.25 <= dmin <= 20.: 5246 generalData['Pawley dmin'] = dmin 5247 except ValueError: 5248 pass 5249 pawlVal.SetValue("%.3f"%(generalData['Pawley dmin'])) #reset in case of error 5250 5251 def OnPawleyNegWt(event): 5252 try: 5253 wt = float(pawlNegWt.GetValue()) 5254 if 0. <= wt <= 1.: 5255 generalData['Pawley neg wt'] = wt 5256 except ValueError: 5257 pass 5258 pawlNegWt.SetValue("%.3g"%(generalData['Pawley neg wt'])) #reset in case of error 5259 5260 pawleySizer = wx.BoxSizer(wx.HORIZONTAL) 5261 pawleySizer.Add(wx.StaticText(dataDisplay,label=' Pawley controls: '),0,wx.ALIGN_CENTER_VERTICAL) 5262 pawlRef = wx.CheckBox(dataDisplay,1,label=' Do Pawley refinement?') 5263 pawlRef.SetValue(generalData['doPawley']) 5264 pawlRef.Bind(wx.EVT_CHECKBOX,OnPawleyRef) 5265 pawleySizer.Add(pawlRef,0,wx.ALIGN_CENTER_VERTICAL) 5266 pawleySizer.Add(wx.StaticText(dataDisplay,label=' Pawley dmin: '),0,wx.ALIGN_CENTER_VERTICAL) 5267 pawlVal = wx.TextCtrl(dataDisplay,value='%.3f'%(generalData['Pawley dmin']),style=wx.TE_PROCESS_ENTER) 5268 pawlVal.Bind(wx.EVT_TEXT_ENTER,OnPawleyVal) 5269 pawlVal.Bind(wx.EVT_KILL_FOCUS,OnPawleyVal) 5270 pawleySizer.Add(pawlVal,0,wx.ALIGN_CENTER_VERTICAL) 5271 pawleySizer.Add(wx.StaticText(dataDisplay,label=' Pawley neg. wt.: '),0,wx.ALIGN_CENTER_VERTICAL) 5272 pawlNegWt = wx.TextCtrl(dataDisplay,value='%.3g'%(generalData['Pawley neg wt']),style=wx.TE_PROCESS_ENTER) 5273 pawlNegWt.Bind(wx.EVT_TEXT_ENTER,OnPawleyNegWt) 5274 pawlNegWt.Bind(wx.EVT_KILL_FOCUS,OnPawleyNegWt) 5275 pawleySizer.Add(pawlNegWt,0,wx.ALIGN_CENTER_VERTICAL) 5276 return pawleySizer 5277 5278 def MapSizer(): 5279 5280 def OnMapType(event): 5281 Map['MapType'] = mapType.GetValue() 5282 5283 def OnRefList(event): 5284 Map['RefList'] = refList.GetValue() 5285 5286 def OnResVal(event): 5287 try: 5288 res = float(mapRes.GetValue()) 5289 if 0.25 <= res <= 20.: 5290 Map['Resolution'] = res 5291 except ValueError: 5292 pass 5293 mapRes.SetValue("%.2f"%(Map['Resolution'])) #reset in case of error 5294 5295 def OnCutOff(event): 5296 try: 5297 res = float(cutOff.GetValue()) 5298 if 10.0 <= res <= 100.: 5299 Map['cutOff'] = res 5300 except ValueError: 5301 pass 5302 cutOff.SetValue("%.1f"%(Map['cutOff'])) #reset in case of error 5303 5304 #patch 5305 if 'cutOff' not in Map: 5306 Map['cutOff'] = 100.0 5307 mapTypes = ['Fobs','Fcalc','deltF','2*FoFc','Patterson'] 5308 refList = data['Histograms'].keys() 5309 if not generalData['AtomTypes']: 5310 mapTypes = ['Patterson',] 5311 Map['MapType'] = 'Patterson' 5312 mapSizer = wx.BoxSizer(wx.VERTICAL) 5313 lineSizer = wx.BoxSizer(wx.HORIZONTAL) 5314 lineSizer.Add(wx.StaticText(dataDisplay,label=' Fourier map controls: Map type: '),0,wx.ALIGN_CENTER_VERTICAL) 5315 mapType = wx.ComboBox(dataDisplay,1,value=Map['MapType'],choices=mapTypes, 5316 style=wx.CB_READONLYwx.CB_DROPDOWN) 5317 mapType.Bind(wx.EVT_COMBOBOX,OnMapType) 5318 lineSizer.Add(mapType,0,wx.ALIGN_CENTER_VERTICAL) 5319 lineSizer.Add(wx.StaticText(dataDisplay,label=' Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL) 5320 refList = wx.ComboBox(dataDisplay,1,value=Map['RefList'],choices=refList, 5321 style=wx.CB_READONLYwx.CB_DROPDOWN) 5322 refList.Bind(wx.EVT_COMBOBOX,OnRefList) 5323 lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL) 5324 mapSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL) 5325 line2Sizer = wx.BoxSizer(wx.HORIZONTAL) 5326 line2Sizer.Add(wx.StaticText(dataDisplay,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL) 5327 mapRes = wx.TextCtrl(dataDisplay,value='%.2f'%(Map['Resolution']),style=wx.TE_PROCESS_ENTER) 5328 mapRes.Bind(wx.EVT_TEXT_ENTER,OnResVal) 5329 mapRes.Bind(wx.EVT_KILL_FOCUS,OnResVal) 5330 line2Sizer.Add(mapRes,0,wx.ALIGN_CENTER_VERTICAL) 5331 line2Sizer.Add(wx.StaticText(dataDisplay,label=' Peak cutoff %: '),0,wx.ALIGN_CENTER_VERTICAL) 5332 cutOff = wx.TextCtrl(dataDisplay,value='%.1f'%(Map['cutOff']),style=wx.TE_PROCESS_ENTER) 5333 cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff) 5334 cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff) 5335 line2Sizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL) 5336 mapSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL) 5337 return mapSizer 5338 5339 def FlipSizer(): 5340 5341 def OnRefList(event): 5342 Flip['RefList'] = refList.GetValue() 5343 5344 def OnNormElem(event): 5345 PE = G2elemGUI.PickElement(G2frame,ifNone=True) 5346 if PE.ShowModal() == wx.ID_OK: 5347 Flip['Norm element'] = PE.Elem.strip() 5348 normElem.SetLabel(Flip['Norm element']) 5349 PE.Destroy() 5350 5351 def OnResVal(event): 5352 try: 5353 res = float(flipRes.GetValue()) 5354 if 0.25 <= res <= 20.: 5355 Flip['Resolution'] = res 5356 except ValueError: 5357 pass 5358 flipRes.SetValue("%.2f"%(Flip['Resolution'])) #reset in case of error 5359 5360 def OnkFactor(event): 5361 try: 5362 res = float(kFactor.GetValue()) 5363 if 0.1 <= res <= 1.2: 5364 Flip['kfactor'] = res 5365 except ValueError: 5366 pass 5367 kFactor.SetValue("%.3f"%(Flip['kfactor'])) #reset in case of error 5368 5369 refList = data['Histograms'].keys() 5370 flipSizer = wx.BoxSizer(wx.VERTICAL) 5371 lineSizer = wx.BoxSizer(wx.HORIZONTAL) 5372 lineSizer.Add(wx.StaticText(dataDisplay,label=' Charge flip controls: Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL) 5373 refList = wx.ComboBox(dataDisplay,1,value=Flip['RefList'],choices=refList, 5374 style=wx.CB_READONLYwx.CB_DROPDOWN) 5375 refList.Bind(wx.EVT_COMBOBOX,OnRefList) 5376 lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL) 5377 flipSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL) 5378 line2Sizer = wx.BoxSizer(wx.HORIZONTAL) 5379 line2Sizer.Add(wx.StaticText(dataDisplay,label=' Normalizing element: '),0,wx.ALIGN_CENTER_VERTICAL) 5380 normElem = wx.Button(dataDisplay,label=Flip['Norm element'],style=wx.TE_READONLY) 5381 normElem.Bind(wx.EVT_BUTTON,OnNormElem) 5382 line2Sizer.Add(normElem,0,wx.ALIGN_CENTER_VERTICAL) 5383 line2Sizer.Add(wx.StaticText(dataDisplay,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL) 5384 flipRes = wx.TextCtrl(dataDisplay,value='%.2f'%(Flip['Resolution']),style=wx.TE_PROCESS_ENTER) 5385 flipRes.Bind(wx.EVT_TEXT_ENTER,OnResVal) 5386 flipRes.Bind(wx.EVT_KILL_FOCUS,OnResVal) 5387 line2Sizer.Add(flipRes,0,wx.ALIGN_CENTER_VERTICAL) 5388 line2Sizer.Add(wx.StaticText(dataDisplay,label=' kFactor (0.11.2): '),0,wx.ALIGN_CENTER_VERTICAL) 5389 kFactor = wx.TextCtrl(dataDisplay,value='%.3f'%(Flip['kfactor']),style=wx.TE_PROCESS_ENTER) 5390 kFactor.Bind(wx.EVT_TEXT_ENTER,OnkFactor) 5391 kFactor.Bind(wx.EVT_KILL_FOCUS,OnkFactor) 5392 line2Sizer.Add(kFactor,0,wx.ALIGN_CENTER_VERTICAL) 5393 flipSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL) 5394 return flipSizer 5395 5396 General.DestroyChildren() 5397 dataDisplay = wx.Panel(General) 5398 mainSizer = wx.BoxSizer(wx.VERTICAL) 5399 mainSizer.Add((5,5),0) 5400 mainSizer.Add(NameSizer(),0) 5401 mainSizer.Add((5,5),0) 5402 mainSizer.Add(CellSizer(),0) 5403 mainSizer.Add((5,5),0) 5404 5405 Indx = {} 5406 denSizer = None 5407 if len(generalData['AtomTypes']): 5408 denSizer = DenSizer() 5409 mainSizer.Add(denSizer[0]) 5410 mainSizer.Add((5,5),0) 5411 mainSizer.Add(ElemSizer()) 5412 5413 mainSizer.Add((5,5),0) 5414 mainSizer.Add(PawleySizer()) 5415 5416 mainSizer.Add((5,5),0) 5417 mainSizer.Add(MapSizer()) 5418 5419 mainSizer.Add((5,5),0) 5420 mainSizer.Add(FlipSizer()) 5421 5422 dataDisplay.SetSizer(mainSizer) 5423 Size = mainSizer.Fit(G2frame.dataFrame) 5424 Size[1] += 35 #compensate for status bar 5425 dataDisplay.SetSize(Size) 5426 G2frame.dataFrame.SetStatusText('') 5427 G2frame.dataFrame.setSizePosLeft(Size) 5428 5429 ################################################################################ 5430 ##### Atom routines 5431 ################################################################################ 5432 5433 def FillAtomsGrid(): 5434 5435 G2frame.dataFrame.setSizePosLeft([700,300]) 5436 generalData = data['General'] 5437 atomData = data['Atoms'] 5438 DData = data['Drawing'] 5439 Items = [G2gd.wxID_ATOMSEDITINSERT, G2gd.wxID_ATOMSEDITDELETE, G2gd.wxID_ATOMSREFINE, 5440 G2gd.wxID_ATOMSMODIFY, G2gd.wxID_ATOMSTRANSFORM, G2gd.wxID_ATOMVIEWINSERT] 5441 if atomData: 5442 for item in Items: 5443 G2frame.dataFrame.AtomsMenu.Enable(item,True) 5444 else: 5445 for item in Items: 5446 G2frame.dataFrame.AtomsMenu.Enable(item,False) 5447 Items = [G2gd.wxID_ATOMVIEWINSERT, G2gd.wxID_ATOMSVIEWADD] 5448 if data['Drawing']['showABC']: 5449 for item in Items: 5450 G2frame.dataFrame.AtomsMenu.Enable(item,True) 5451 else: 5452 for item in Items: 5453 G2frame.dataFrame.AtomsMenu.Enable(item,False) 5454 5455 AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK" 5456 Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",]+ \ 5457 3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_FLOAT+':10,4', #x,y,z,frac 5458 wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",] 5459 Types += 7*[wg.GRID_VALUE_FLOAT+':10,5',] 5460 colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23'] 5461 if generalData['Type'] == 'magnetic': 5462 colLabels += ['Mx','My','Mz'] 5463 Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU," 5464 Types += 3*[wg.GRID_VALUE_FLOAT+':10,4',] 5465 elif generalData['Type'] == 'macromolecular': 5466 colLabels = ['res no','residue','chain'] + colLabels 5467 Types = [wg.GRID_VALUE_STRING, 5468 wg.GRID_VALUE_CHOICE+AAchoice, 5469 wg.GRID_VALUE_STRING] + Types 5470 elif generalData['Type'] == 'modulated': 5471 Types += [] 5472 colLabels += [] 5473 5474 def RefreshAtomGrid(event): 5475 5476 r,c = event.GetRow(),event.GetCol() 5477 if r < 0 and c < 0: 5478 for row in range(Atoms.GetNumberRows()): 5479 Atoms.SelectRow(row,True) 5480 if r < 0: #double click on col label! Change all atoms! 5481 sel = 1 5482 noSkip = True 5483 if Atoms.GetColLabelValue(c) == 'refine': 5484 Type = generalData['Type'] 5485 if Type in ['nuclear','macromolecular']: 5486 choice = ['F  site fraction','X  coordinates','U  thermal parameters'] 5487 elif Type in ['magnetic',]: 5488 choice = ['F  site fraction','X  coordinates','U  thermal parameters','M  magnetic moment'] 5489 dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice) 5490 if dlg.ShowModal() == wx.ID_OK: 5491 sel = dlg.GetSelections() 5492 parms = '' 5493 for x in sel: 5494 parms += choice[x][0] 5495 dlg.Destroy() 5496 elif Atoms.GetColLabelValue(c) == 'I/A': 5497 choice = ['Isotropic','Anisotropic'] 5498 dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal Motion',choice) 5499 if dlg.ShowModal() == wx.ID_OK: 5500 sel = dlg.GetSelection() 5501 parms = choice[sel][0] 5502 dlg.Destroy() 5503 elif Atoms.GetColLabelValue(c) == 'Type': 5504 choice = generalData['AtomTypes'] 5505 dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom types',choice) 5506 if dlg.ShowModal() == wx.ID_OK: 5507 sel = dlg.GetSelection() 5508 parms = choice[sel] 5509 noSkip = False 5510 Atoms.ClearSelection() 5511 for row in range(Atoms.GetNumberRows()): 5512 if parms == atomData[row][c]: 5513 Atoms.SelectRow(row,True) 5514 dlg.Destroy() 5515 SetupGeneral() 5516 elif Atoms.GetColLabelValue(c) == 'residue': 5517 choice = [] 5518 for r in range(Atoms.GetNumberRows()): 5519 if str(atomData[r][c]) not in choice: 5520 choice.append(str(atomData[r][c])) 5521 choice.sort() 5522 dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue',choice) 5523 if dlg.ShowModal() == wx.ID_OK: 5524 sel = dlg.GetSelection() 5525 parms = choice[sel] 5526 noSkip = False 5527 Atoms.ClearSelection() 5528 for row in range(Atoms.GetNumberRows()): 5529 if parms == atomData[row][c]: 5530 Atoms.SelectRow(row,True) 5531 dlg.Destroy() 5532 elif Atoms.GetColLabelValue(c) == 'res no': 5533 choice = [] 5534 for r in range(Atoms.GetNumberRows()): 5535 if str(atomData[r][c]) not in choice: 5536 choice.append(str(atomData[r][c])) 5537 dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue no.',choice) 5538 if dlg.ShowModal() == wx.ID_OK: 5539 sel = dlg.GetSelection() 5540 parms = choice[sel] 5541 noSkip = False 5542 Atoms.ClearSelection() 5543 for row in range(Atoms.GetNumberRows()): 5544 if int(parms) == atomData[row][c]: 5545 Atoms.SelectRow(row,True) 5546 dlg.Destroy() 5547 elif Atoms.GetColLabelValue(c) == 'chain': 5548 choice = [] 5549 for r in range(Atoms.GetNumberRows()): 5550 if atomData[r][c] not in choice: 5551 choice.append(atomData[r][c]) 5552 dlg = wx.SingleChoiceDialog(G2frame,'Select','Chain',choice) 5553 if dlg.ShowModal() == wx.ID_OK: 5554 sel = dlg.GetSelection() 5555 parms = choice[sel] 5556 noSkip = False 5557 Atoms.ClearSelection() 5558 for row in range(Atoms.GetNumberRows()): 5559 if parms == atomData[row][c]: 5560 Atoms.SelectRow(row,True) 5561 dlg.Destroy() 5562 elif Atoms.GetColLabelValue(c) == 'Uiso': #this needs to ask for value 5563 pass #& then change all 'I' atoms 5564 if sel >= 0 and noSkip: 5565 ui = colLabels.index('U11') 5566 us = colLabels.index('Uiso') 5567 ss = colLabels.index('site sym') 5568 for r in range(Atoms.GetNumberRows()): 5569 ID = atomData[r][1] 5570 if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A': 5571 if parms == 'A': #'I' > 'A' 5572 Uiso = float(Atoms.GetCellValue(r,us)) 5573 sytsym = atomData[r][ss] 5574 CSI = G2spc.GetCSuinel(sytsym) 5575 atomData[r][ui:ui+6] = Uiso*np.array(CSI[3]) 5576 atomData[r][us] = 0.0 5577 Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True) 5578 for i in range(6): 5579 ci = ui+i 5580 Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) 5581 if CSI[2][i]: 5582 Atoms.SetCellStyle(r,ci,WHITE,False) 5583 else: #'A' > 'I' 5584 Uij = atomData[r][ui:ui+6] 5585 Uiso = (Uij[0]+Uij[1]+Uij[2])/3.0 5586 atomData[r][us] = Uiso 5587 Atoms.SetCellStyle(r,us,WHITE,False) 5588 for i in range(6): 5589 ci = ui+i 5590 atomData[r][ci] = 0.0 5591 Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) 5592 atomData[r][c] = parms 5593 if 'Atoms' in data['Drawing']: 5594 DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) 5595 FillAtomsGrid() 5596 5597 def ChangeAtomCell(event): 5598 5599 def chkUij(Uij,CSI): #needs to do something!!! 5600 return Uij 5601 5602 r,c = event.GetRow(),event.GetCol() 5603 if r >= 0 and c >= 0: 5604 ID = atomData[r][1] 5605 if Atoms.GetColLabelValue(c) in ['x','y','z']: 5606 ci = colLabels.index('x') 5607 XYZ = atomData[r][ci:ci+3] 5608 if None in XYZ: 5609 XYZ = [0,0,0] 5610 SScol = colLabels.index('site sym') 5611 Mulcol = colLabels.index('mult') 5612 E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp']) 5613 Sytsym,Mult = G2spc.SytSym(XYZ,SGData) 5614 atomData[r][SScol] = Sytsym 5615 atomData[r][Mulcol] = Mult 5616 if atomData[r][colLabels.index('I/A')] == 'A': 5617 ui = colLabels.index('U11') 5618 CSI = G2spc.GetCSuinel(Sytsym) 5619 atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym) 5620 for i in range(6): 5621 ci = i+ui 5622 Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) 5623 if CSI[2][i]: 5624 Atoms.SetCellStyle(r,ci,WHITE,False) 5625 SetupGeneral() 5626 elif Atoms.GetColLabelValue(c) == 'I/A': #note use of text color to make it vanish! 5627 if atomData[r][c] == 'I': 5628 Uij = atomData[r][c+2:c+8] 5629 atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0 5630 Atoms.SetCellStyle(r,c+1,WHITE,False) 5631 Atoms.SetCellTextColour(r,c+1,BLACK) 5632 for i in range(6): 5633 ci = i+colLabels.index('U11') 5634 Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) 5635 Atoms.SetCellTextColour(r,ci,VERY_LIGHT_GREY) 5636 atomData[r][ci] = 0.0 5637 else: 5638 value = atomData[r][c+1] 5639 CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')]) 5640 atomData[r][c+1] = 0.0 5641 Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True) 5642 Atoms.SetCellTextColour(r,c+1,VERY_LIGHT_GREY) 5643 for i in range(6): 5644 ci = i+colLabels.index('U11') 5645 atomData[r][ci] = value*CSI[3][i] 5646 Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) 5647 Atoms.SetCellTextColour(r,ci,BLACK) 5648 if CSI[2][i]: 5649 Atoms.SetCellStyle(r,ci,WHITE,False) 5650 elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']: 5651 value = atomData[r][c] 5652 CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')]) 5653 iUij = CSI[0][ccolLabels.index('U11')] 5654 for i in range(6): 5655 if iUij == CSI[0][i]: 5656 atomData[r][i+colLabels.index('U11')] = value*CSI[1][i] 5657 if 'Atoms' in data['Drawing']: 5658 DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) 5659 FindBondsDraw() 5660 5661 def AtomTypeSelect(event): 5662 r,c = event.GetRow(),event.GetCol() 5663 if Atoms.GetColLabelValue(c) == 'Type': 5664 PE = G2elemGUI.PickElement(G2frame) 5665 if PE.ShowModal() == wx.ID_OK: 5666 if PE.Elem != 'None': 5667 atomData[r][c] = PE.Elem.strip() 5668 name = atomData[r][c] 5669 if len(name) in [2,4]: 5670 atomData[r][c1] = name[:2]+'(%d)'%(r+1) 5671 else: 5672 atomData[r][c1] = name[:1]+'(%d)'%(r+1) 5673 PE.Destroy() 5674 SetupGeneral() 5675 FillAtomsGrid() 5676 value = Atoms.GetCellValue(r,c) 5677 atomData[r][c] = value 5678 ID = atomData[r][1] 5679 if 'Atoms' in data['Drawing']: 5680 DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) 5681 SetupGeneral() 5682 else: 5683 event.Skip() 5684 5685 def RowSelect(event): 5686 r,c = event.GetRow(),event.GetCol() 5687 if r < 0 and c < 0: 5688 if Atoms.IsSelection(): 5689 Atoms.ClearSelection() 5690 elif c < 0: #only row clicks 5691 if event.ControlDown(): 5692 if r in Atoms.GetSelectedRows(): 5693 Atoms.DeselectRow(r) 5694 else: 5695 Atoms.SelectRow(r,True) 5696 elif event.ShiftDown(): 5697 for row in range(r+1): 5698 Atoms.SelectRow(row,True) 5699 else: 5700 Atoms.ClearSelection() 5701 Atoms.SelectRow(r,True) 5702 5703 def ChangeSelection(event): 5704 r,c = event.GetRow(),event.GetCol() 5705 if r < 0 and c < 0: 5706 Atoms.ClearSelection() 5707 if c < 0: 5708 if r in Atoms.GetSelectedRows(): 5709 Atoms.DeselectRow(r) 5710 else: 5711 Atoms.SelectRow(r,True) 5712 if r < 0: 5713 if c in Atoms.GetSelectedCols(): 5714 Atoms.DeselectCol(c) 5715 else: 5716 Atoms.SelectCol(c,True) 5717 5718 SGData = data['General']['SGData'] 5719 G2frame.dataFrame.SetStatusText('') 5720 if SGData['SGPolax']: 5721 G2frame.dataFrame.SetStatusText('Warning: The location of the origin is arbitrary in '+SGData['SGPolax']) 5722 table = [] 5723 rowLabels = [] 5724 for i,atom in enumerate(atomData): 5725 table.append(atom) 5726 rowLabels.append(str(i)) 5727 atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) 5728 Atoms.SetTable(atomTable, True) 5729 Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeAtomCell) 5730 Atoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, AtomTypeSelect) 5731 Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid) 5732 Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect) 5733 Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection) 5734 Atoms.SetMargins(0,0) 5735 Atoms.AutoSizeColumns(False) 5736 colType = colLabels.index('Type') 5737 colSS = colLabels.index('site sym') 5738 colX = colLabels.index('x') 5739 colIA = colLabels.index('I/A') 5740 colU11 = colLabels.index('U11') 5741 colUiso = colLabels.index('Uiso') 5742 attr = wx.grid.GridCellAttr() 5743 attr.SetEditor(GridFractionEditor(Atoms)) 5744 for c in range(colX,colX+3): 5745 Atoms.SetColAttr(c, attr) 5746 for i in range(colU111,colU11+6): 5747 Atoms.SetColSize(i,50) 5748 for row in range(Atoms.GetNumberRows()): 5749 Atoms.SetReadOnly(row,colType,True) 5750 Atoms.SetReadOnly(row,colSS,True) #site sym 5751 Atoms.SetReadOnly(row,colSS+1,True) #Mult 5752 if Atoms.GetCellValue(row,colIA) == 'A': 5753 CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')]) 5754 Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True) 5755 Atoms.SetCellTextColour(row,colUiso,VERY_LIGHT_GREY) 5756 for i in range(6): 5757 ci = colU11+i 5758 Atoms.SetCellTextColour(row,ci,BLACK) 5759 Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True) 5760 if CSI[2][i]: 5761 Atoms.SetCellStyle(row,ci,WHITE,False) 5762 else: 5763 Atoms.SetCellStyle(row,colUiso,WHITE,False) 5764 Atoms.SetCellTextColour(row,colUiso,BLACK) 5765 for i in range(6): 5766 ci = colU11+i 5767 Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True) 5768 Atoms.SetCellTextColour(row,ci,VERY_LIGHT_GREY) 5769 5770 def OnAtomAdd(event): 5771 AtomAdd(0,0,0) 5772 FillAtomsGrid() 5773 event.StopPropagation() 5774 5775 def OnAtomViewAdd(event): 5776 try: 5777 drawData = data['Drawing'] 5778 x,y,z = drawData['viewPoint'][0] 5779 AtomAdd(x,y,z) 5780 except: 5781 AtomAdd(0,0,0) 5782 FillAtomsGrid() 5783 event.StopPropagation() 5784 5785 def AtomAdd(x,y,z,El='H'): 5786 atomData = data['Atoms'] 5787 generalData = data['General'] 5788 Ncol = Atoms.GetNumberCols() 5789 atId = ran.randint(0,sys.maxint) 5790 E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp']) 5791 Sytsym,Mult = G2spc.SytSym([x,y,z],SGData) 5792 if generalData['Type'] == 'macromolecular': 5793 atomData.append([0,'UNK','','UNK',El,'',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId]) 5794 elif generalData['Type'] == 'nuclear': 5795 atomData.append(['UNK',El,'',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId]) 5796 elif generalData['Type'] == 'magnetic': 5797 atomData.append(['UNK',El,'',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId]) 5798 SetupGeneral() 5799 if 'Atoms' in data['Drawing']: 5800 DrawAtomAdd(data['Drawing'],atomData[1]) 5801 G2plt.PlotStructure(G2frame,data) 5802 5803 def OnAtomInsert(event): 5804 AtomInsert(0,0,0) 5805 FillAtomsGrid() 5806 event.StopPropagation() 5807 5808 def OnAtomViewInsert(event): 5809 if 'Drawing' in data: 5810 drawData = data['Drawing'] 5811 x,y,z = drawData['viewPoint'][0] 5812 AtomAdd(x,y,z) 5813 FillAtomsGrid() 5814 event.StopPropagation() 5815 5816 def AtomInsert(x,y,z): 5817 indx = Atoms.GetSelectedRows() 5818 if indx: 5819 indx = indx[0] 5820 atomData = data['Atoms'] 5821 generalData = data['General'] 5822 Ncol = Atoms.GetNumberCols() 5823 E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp']) 5824 Sytsym,Mult = G2spc.SytSym([0,0,0],SGData) 5825 atId = ran.randint(0,sys.maxint) 5826 if generalData['Type'] == 'macromolecular': 5827 atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId]) 5828 elif generalData['Type'] == 'nuclear': 5829 atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId]) 5830 elif generalData['Type'] == 'magnetic': 5831 atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId]) 5832 SetupGeneral() 5833 5834 def AtomDelete(event): 5835 indx = Atoms.GetSelectedRows() 5836 IDs = [] 5837 if indx: 5838 atomData = data['Atoms'] 5839 indx.reverse() 5840 for ind in indx: 5841 atom = atomData[ind] 5842 IDs.append(atom[1]) 5843 del atomData[ind] 5844 if 'Atoms' in data['Drawing']: 5845 DrawAtomsDeleteByIDs(IDs) 5846 wx.CallAfter(FillAtomsGrid) 5847 G2plt.PlotStructure(G2frame,data) 5848 SetupGeneral() 5849 event.StopPropagation() 5850 5851 def AtomRefine(event): 5852 colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] 5853 c = colLabels.index('refine') 5854 indx = Atoms.GetSelectedRows() 5855 if indx: 5856 atomData = data['Atoms'] 5857 generalData = data['General'] 5858 Type = generalData['Type'] 5859 if Type in ['nuclear','macromolecular']: 5860 choice = ['F  site fraction','X  coordinates','U  thermal parameters'] 5861 elif Type == 'magnetic': 5862 choice = ['F  site fraction','X  coordinates','U  thermal parameters','M  magnetic moment'] 5863 dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice) 5864 if dlg.ShowModal() == wx.ID_OK: 5865 sel = dlg.GetSelections() 5866 parms = '' 5867 for x in sel: 5868 parms += choice[x][0] 5869 for r in indx: 5870 atomData[r][c] = parms 5871 Atoms.ForceRefresh() 5872 dlg.Destroy() 5873 5874 def AtomModify(event): #intent to implement global modifications (+,,*,/, etc.)? 5875 indx = Atoms.GetSelectedRows() 5876 if indx: 5877 atomData = data['Atoms'] 5878 generalData = data['General'] 5879 colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] 5880 choices = ['Type','Name','x','y','z','frac','I/A','Uiso'] 5881 dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom parameter',choices) 5882 if dlg.ShowModal() == wx.ID_OK: 5883 sel = dlg.GetSelection() 5884 parm = choices[sel] 5885 cid = colLabels.index(parm) 5886 dlg.Destroy() 5887 if parm in ['Type']: 5888 dlg = G2elemGUI.PickElement(G2frame) 5889 if dlg.ShowModal() == wx.ID_OK: 5890 if dlg.Elem not in ['None']: 5891 El = dlg.Elem.strip() 5892 for r in indx: 5893 atomData[r][cid] = El 5894 if len(El) in [2,4]: 5895 atomData[r][cid1] = El[:2]+'(%d)'%(r+1) 5896 else: 5897 atomData[r][cid1] = El[:1]+'(%d)'%(r+1) 5898 SetupGeneral() 5899 if 'Atoms' in data['Drawing']: 5900 for r in indx: 5901 ID = atomData[r][1] 5902 DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) 5903 FillAtomsGrid() 5904 dlg.Destroy() 5905 elif parm in ['Name',]: 5906 dlg = wx.MessageDialog(G2frame,'Do you really want to rename the selected atoms?','Rename', 5907 wx.YES_NO  wx.ICON_QUESTION) 5908 try: 5909 result = dlg.ShowModal() 5910 if result == wx.ID_YES: 5911 for r in indx: 5912 El = atomData[r][cid+1] 5913 if len(El) in [2,4]: 5914 atomData[r][cid] = El[:2]+'(%d)'%(r+1) 5915 else: 5916 atomData[r][cid] = El[:1]+'(%d)'%(r+1) 5917 FillAtomsGrid() 5918 finally: 5919 dlg.Destroy() 5920 5921 elif parm in ['I/A']: 5922 choices = ['Isotropic','Anisotropic'] 5923 dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal parameter model',choices) 5924 if dlg.ShowModal() == wx.ID_OK: 5925 sel = dlg.GetSelection() 5926 parm = choices[sel][0] 5927 for r in indx: 5928 atomData[r][cid] = parm 5929 FillAtomsGrid() 5930 dlg.Destroy() 5931 elif parm in ['frac','Uiso']: 5932 limits = [0.,1.] 5933 val = 1.0 5934 if parm in ['Uiso']: 5935 limits = [0.,0.25] 5936 val = 0.01 5937 dlg = SingleFloatDialog(G2frame,'New value','Enter new value for '+parm,val,limits) 5938 if dlg.ShowModal() == wx.ID_OK: 5939 parm = dlg.GetValue() 5940 for r in indx: 5941 atomData[r][cid] = parm 5942 SetupGeneral() 5943 FillAtomsGrid() 5944 dlg.Destroy() 5945 elif parm in ['x','y','z']: 5946 limits = [1.,1.] 5947 val = 0. 5948 dlg = SingleFloatDialog(G2frame,'Atom shift','Enter shift for '+parm,val,limits) 5949 if dlg.ShowModal() == wx.ID_OK: 5950 parm = dlg.GetValue() 5951 for r in indx: 5952 atomData[r][cid] += parm 5953 SetupGeneral() 5954 FillAtomsGrid() 5955 dlg.Destroy() 5956 5957 def AtomTransform(event): 5958 indx = Atoms.GetSelectedRows() 5959 if indx: 5960 generalData = data['General'] 5961 colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] 5962 cx = colLabels.index('x') 5963 cuia = colLabels.index('I/A') 5964 cuij = colLabels.index('U11') 5965 css = colLabels.index('site sym') 5966 atomData = data['Atoms'] 5967 generalData = data['General'] 5968 SGData = generalData['SGData'] 5969 dlg = SymOpDialog(G2frame,SGData,True,True) 5970 try: 5971 if dlg.ShowModal() == wx.ID_OK: 5972 Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection() 5973 Cell = np.array(Cell) 5974 cent = SGData['SGCen'][Cent] 5975 M,T = SGData['SGOps'][Opr] 5976 for ind in indx: 5977 XYZ = np.array(atomData[ind][cx:cx+3]) 5978 XYZ = np.inner(M,XYZ)+T 5979 if Inv: 5980 XYZ = XYZ 5981 XYZ = XYZ+cent+Cell 5982 if Force: 5983 XYZ = G2spc.MoveToUnitCell(XYZ) 5984 if New: 5985 atom = copy.copy(atomData[ind]) 5986 else: 5987 atom = atomData[ind] 5988 atom[cx:cx+3] = XYZ 5989 atom[css:css+2] = G2spc.SytSym(XYZ,SGData) 5990 if atom[cuia] == 'A': 5991 Uij = atom[cuij:cuij+6] 5992 U = G2spc.Uij2U(Uij) 5993 U = np.inner(np.inner(M,U),M) 5994 Uij = G2spc.U2Uij(U) 5995 atom[cuij:cuij+6] = Uij 5996 if New: 5997 atomData.append(atom) 5998 finally: 5999 dlg.Destroy() 6000 Atoms.ClearSelection() 6001 if New: 6002 FillAtomsGrid() 6003 else: 6004 Atoms.ForceRefresh() 6005 6006 def OnDistAngle(event): 6007 indx = Atoms.GetSelectedRows() 6008 Oxyz = [] 6009 xyz = [] 6010 DisAglData = {} 6011 DisAglCtls = {} 6012 if indx: 6013 generalData = data['General'] 6014 DisAglData['OrigIndx'] = indx 6015 if 'DisAglCtls' in generalData: 6016 DisAglCtls = generalData['DisAglCtls'] 6017 dlg = DisAglDialog(G2frame,DisAglCtls,generalData) 6018 if dlg.ShowModal() == wx.ID_OK: 6019 DisAglCtls = dlg.GetData() 6020 dlg.Destroy() 6021 generalData['DisAglCtls'] = DisAglCtls 6022 atomData = data['Atoms'] 6023 colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] 6024 cx = colLabels.index('x') 6025 cn = colLabels.index('Name') 6026 for i,atom in enumerate(atomData): 6027 xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3]) 6028 if i in indx: 6029 Oxyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3]) 6030 DisAglData['OrigAtoms'] = Oxyz 6031 DisAglData['TargAtoms'] = xyz 6032 generalData = data['General'] 6033 DisAglData['SGData'] = generalData['SGData'] 6034 DisAglData['Cell'] = generalData['Cell'][1:] #+ volume 6035 if 'pId' in data: 6036 DisAglData['pId'] = data['pId'] 6037 DisAglData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance')) 6038 G2str.DistAngle(DisAglCtls,DisAglData) 6039 6040 ################################################################################ 6041 #Structure drawing GUI stuff 6042 ################################################################################ 6043 6044 def SetupDrawingData(): 6045 generalData = data['General'] 6046 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 6047 atomData = data['Atoms'] 6048 AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE', 6049 'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK'] 6050 AA1letter = ['A','R','N','D','C','Q','E','G','H','I', 6051 'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' '] 6052 defaultDrawing = {'Atoms':[],'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True, 6053 'backColor':[0,0,0],'depthFog':False,'Zclip':50.0,'cameraPos':50.,'Zstep':0.5, 6054 'radiusFactor':0.85,'contourLevel':1.,'bondRadius':0.1,'ballScale':0.33, 6055 'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,'unitCellBox':False, 6056 'showABC':True,'selectedAtoms':[],'Atoms':[],'oldxy':[], 6057 'bondList':{},'viewDir':[1,0,0]} 6058 V0 = np.array([0,0,1]) 6059 V = np.inner(Amat,V0) 6060 V /= np.sqrt(np.sum(V**2)) 6061 A = np.arccos(np.sum(V*V0)) 6062 defaultDrawing['Quaternion'] = G2mth.AV2Q(A,[0,1,0]) 6063 try: 6064 drawingData = data['Drawing'] 6065 except KeyError: 6066 data['Drawing'] = {} 6067 drawingData = data['Drawing'] 6068 if not drawingData: #fill with defaults if empty 6069 drawingData.update(defaultDrawing) 6070 if 'Zstep' not in drawingData: 6071 drawingData['Zstep'] = 0.5 6072 if 'contourLevel' not in drawingData: 6073 drawingData['contourLevel'] = 1. 6074 if 'viewDir' not in drawingData: 6075 drawingData['viewDir'] = [0,0,1] 6076 if 'Quaternion' not in drawingData: 6077 drawingData['Quaternion'] = G2mth.AV2Q(2*np.pi,np.inner(Amat,[0,0,1])) 6078 cx,ct,cs,ci = [0,0,0,0] 6079 if generalData['Type'] == 'nuclear': 6080 cx,ct,cs,ci = [2,1,6,17] #x, type, style & index 6081 elif generalData['Type'] == 'macromolecular': 6082 cx,ct,cs,ci = [5,4,9,20] #x, type, style & index 6083 elif generalData['Type'] == 'magnetic': 6084 cx,ct,cs,ci = [2,1,6,20] #x, type, style & index 6085 # elif generalData['Type'] == 'modulated': 6086 # ????? for future 6087 drawingData['atomPtrs'] = [cx,ct,cs,ci] 6088 if not drawingData.get('Atoms'): 6089 for atom in atomData: 6090 DrawAtomAdd(drawingData,atom) 6091 data['Drawing'] = drawingData 6092 6093 def MakeDrawAtom(atom,oldatom=None): 6094 AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE', 6095 'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK'] 6096 AA1letter = ['A','R','N','D','C','Q','E','G','H','I', 6097 'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' '] 6098 generalData = data['General'] 6099 SGData = generalData['SGData'] 6100 if generalData['Type'] == 'nuclear': 6101 if oldatom: 6102 opr = oldatom[5] 6103 if atom[9] == 'A': 6104 X,U = G2spc.ApplyStringOps(opr,SGData,atom[3:6],atom[11:17]) 6105 atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:11]+list(U)+oldatom[17:]][0] 6106 else: 6107 X = G2spc.ApplyStringOps(opr,SGData,atom[3:6]) 6108 atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:]+[oldatom[1]]][0] 6109 else: 6110 atomInfo = [atom[:2]+atom[3:6]+['1',]+['vdW balls',]+ 6111 ['',]+[[255,255,255],]+atom[9:]+[[],[]]][0] 6112 ct,cs = [1,8] #type & color 6113 elif generalData['Type'] == 'macromolecular': 6114 try: 6115 oneLetter = AA3letter.index(atom[1]) 6116 except ValueError: 6117 oneLetter = 1 6118 atomInfo = [[atom[1].strip()+atom[0],]+ 6119 [AA1letter[oneLetter]+atom[0],]+atom[2:5]+ 6120 atom[6:9]+['1',]+['sticks',]+['',]+[[255,255,255],]+atom[12:]+[[],[]]][0] 6121 ct,cs = [4,11] #type & color 6122 elif generalData['Type'] == 'magnetic': 6123 if oldatom: 6124 atomInfo = [atom[:2]+oldatom[3:]][0] 6125 else: 6126 atomInfo = [atom[:2]+atom[3:6]+['vdW balls',]+['',]+atom[9:]+[[],[]]][0] 6127 ct,cs = [1,8] #type & color 6128 # elif generalData['Type'] == 'modulated': 6129 # ????? for future 6130 atNum = generalData['AtomTypes'].index(atom[ct]) 6131 atomInfo[cs] = list(generalData['Color'][atNum]) 6132 return atomInfo 6133 6134 def DrawAtomAdd(drawingData,atom): 6135 drawingData['Atoms'].append(MakeDrawAtom(atom)) 6136 6137 def DrawAtomsReplaceByID(drawingData,atom,ID): 6138 IDs = [ID,] 6139 atomData = drawingData['Atoms'] 6140 indx = FindAtomIndexByIDs(atomData,IDs) 6141 for ind in indx: 6142 atomData[ind] = MakeDrawAtom(atom,atomData[ind]) 6143 6144 def OnRestraint(event): 6145 indx = drawAtoms.GetSelectedRows() 6146 restData = G2frame.PatternTree.GetItemPyData( 6147 G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Restraints')) 6148 drawingData = data['Drawing'] 6149 generalData = data['General'] 6150 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 6151 cx,ct,cs,ci = drawingData['atomPtrs'] 6152 atomData = drawingData['Atoms'] 6153 atNames = [] 6154 atXYZ = [] 6155 atSymOp = [] 6156 atIndx = [] 6157 for item in indx: 6158 atNames.append(atomData[item][ct1]) 6159 atXYZ.append(np.array(atomData[item][cx:cx+3])) 6160 atSymOp.append(atomData[item][cs1]) 6161 atIndx.append(atomData[item][ci]) 6162 if event.GetId() == G2gd.wxID_DRAWRESTRBOND and len(indx) == 2: 6163 try: 6164 bondData = restData[PhaseName]['Bond'] 6165 except KeyError: 6166 bondData = {'wtFactor':1.0,'Bonds':[]} 6167 restData[PhaseName] = {} 6168 restData[PhaseName]['Bond'] = bondData 6169 dist = G2mth.getRestDist(atXYZ,Amat) 6170 bondData['Bonds'].append([atNames,atSymOp,atIndx,dist,1.54,0.01]) 6171 elif event.GetId() == G2gd.wxID_DRAWRESTRANGLE and len(indx) == 3: 6172 try: 6173 angleData = restData[PhaseName]['Angle'] 6174 except KeyError: 6175 angleData = {'wtFactor':1.0,'Angles':[]} 6176 restData[PhaseName] = {} 6177 restData[PhaseName]['Angle'] = angleData 6178 angle = G2mth.getRestAngle(atXYZ,Amat) 6179 angleData['Angles'].append([atNames,atSymOp,atIndx,angle,109.5,1.0]) 6180 elif event.GetId() == G2gd.wxID_DRAWRESTRPLANE and len(indx) > 3: 6181 try: 6182 planeData = restData[PhaseName]['Plane'] 6183 except KeyError: 6184 planeData = {'wtFactor':1.0,'Planes':[]} 6185 restData[PhaseName] = {} 6186 restData[PhaseName]['Plane'] = planeData 6187 plane = G2mth.getRestPlane(atXYZ,Amat) 6188 planeData['Planes'].append([atNames,atSymOp,atIndx,plane,0.0,0.01]) 6189 elif event.GetId() == G2gd.wxID_DRAWRESTRCHIRAL and len(indx) == 4: 6190 try: 6191 chiralData = restData[PhaseName]['Chiral'] 6192 except KeyError: 6193 chiralData = {'wtFactor':1.0,'Volumes':[]} 6194 restData[PhaseName] = {} 6195 restData[PhaseName]['Chiral'] = chiralData 6196 volume = G2mth.getRestChiral(atXYZ,Amat) 6197 chiralData['Volumes'].append([atNames,atSymOp,atIndx,volume,2.5,0.1]) 6198 else: 6199 print '**** ERROR wrong number of atoms selected for this restraint' 6200 return 6201 G2frame.PatternTree.SetItemPyData( 6202 G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Restraints'),restData) 6203 6204 ################################################################################ 6205 ##### Atom draw routines 6206 ################################################################################ 6207 6208 def UpdateDrawAtoms(): 6209 G2frame.dataFrame.SetStatusText('') 6210 generalData = data['General'] 6211 SetupDrawingData() 6212 drawingData = data['Drawing'] 6213 cx,ct,cs,ci = drawingData['atomPtrs'] 6214 atomData = drawingData['Atoms'] 6215 Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]+ \ 6216 [wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra", 6217 wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,] 6218 styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra'] 6219 labelChoice = [' ','type','name','number'] 6220 colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','Color','I/A'] 6221 if generalData['Type'] == 'macromolecular': 6222 colLabels = ['Residue','1letter','Chain'] + colLabels 6223 Types = 3*[wg.GRID_VALUE_STRING,]+Types 6224 Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic" 6225 styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic'] 6226 labelChoice = [' ','type','name','number','residue','1letter','chain'] 6227 Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1letter,chain" 6228 # elif generalData['Type'] == 'modulated': 6229 # Types += [] 6230 # colLabels += [] 6231 6232 def RefreshAtomGrid(event): 6233 6234 def SetChoice(name,c,n=0): 6235 choice = [] 6236 for r in range(len(atomData)): 6237 if n: 6238 srchStr = str(atomData[r][c][:n]) 6239 else: 6240 srchStr = str(atomData[r][c]) 6241 if srchStr not in choice: 6242 if n: 6243 choice.append(str(atomData[r][c][:n])) 6244 else: 6245 choice.append(str(atomData[r][c])) 6246 choice.sort() 6247 6248 dlg = wx.MultiChoiceDialog(G2frame,'Select',name,choice) 6249 if dlg.ShowModal() == wx.ID_OK: 6250 sel = dlg.GetSelections() 6251 parms = [] 6252 for x in sel: 6253 parms.append(choice[x]) 6254 noSkip = False 6255 drawAtoms.ClearSelection() 6256 drawingData['selectedAtoms'] = [] 6257 for row in range(len(atomData)): 6258 test = atomData[row][c] 6259 if n: 6260 test = test[:n] 6261 if test in parms: 6262 drawAtoms.SelectRow(row,True) 6263 drawingData['selectedAtoms'].append(row) 6264 G2plt.PlotStructure(G2frame,data) 6265 dlg.Destroy() 6266 6267 r,c = event.GetRow(),event.GetCol() 6268 if r < 0 and c < 0: 6269 for row in range(drawAtoms.GetNumberRows()): 6270 drawingData['selectedAtoms'].append(row) 6271 drawAtoms.SelectRow(row,True) 6272 elif r < 0: #dclick on col label 6273 sel = 1 6274 Parms = False 6275 noSkip = True 6276 if drawAtoms.GetColLabelValue(c) == 'Style': 6277 dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice) 6278 if dlg.ShowModal() == wx.ID_OK: 6279 sel = dlg.GetSelection() 6280 parms = styleChoice[sel] 6281 for r in range(len(atomData)): 6282 atomData[r][c] = parms 6283 drawAtoms.SetCellValue(r,c,parms) 6284 FindBondsDraw() 6285 G2plt.PlotStructure(G2frame,data) 6286 dlg.Destroy() 6287 elif drawAtoms.GetColLabelValue(c) == 'Label': 6288 dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom labelling style',labelChoice) 6289 if dlg.ShowModal() == wx.ID_OK: 6290 sel = dlg.GetSelection() 6291 parms = labelChoice[sel] 6292 for r in range(len(atomData)): 6293 atomData[r][c] = parms 6294 drawAtoms.SetCellValue(r,c,parms) 6295 dlg.Destroy() 6296 elif drawAtoms.GetColLabelValue(c) == 'Color': 6297 dlg = wx.ColourDialog(G2frame) 6298 if dlg.ShowModal() == wx.ID_OK: 6299 color = dlg.GetColourData().GetColour() 6300 attr = wg.GridCellAttr() #needs to be here  gets lost if outside loop! 6301 attr.SetReadOnly(True) 6302 attr.SetBackgroundColour(color) 6303 for r in range(len(atomData)): 6304 atomData[r][c] = color 6305 drawingData['Atoms'][r][c] = color 6306 drawAtoms.SetAttr(r,c,attr) 6307 UpdateDrawAtoms() 6308 dlg.Destroy() 6309 elif drawAtoms.GetColLabelValue(c) == 'Residue': 6310 SetChoice('Residue',c,3) 6311 elif drawAtoms.GetColLabelValue(c) == '1letter': 6312 SetChoice('1letter',c,1) 6313 elif drawAtoms.GetColLabelValue(c) == 'Chain': 6314 SetChoice('Chain',c) 6315 elif drawAtoms.GetColLabelValue(c) == 'Name': 6316 SetChoice('Name',c) 6317 elif drawAtoms.GetColLabelValue(c) == 'Sym Op': 6318 SetChoice('Name',c) 6319 elif drawAtoms.GetColLabelValue(c) == 'Type': 6320 SetChoice('Type',c) 6321 elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']: 6322 drawAtoms.ClearSelection() 6323 else: 6324 if drawAtoms.GetColLabelValue(c) in ['Style','Label']: 6325 atomData[r][c] = drawAtoms.GetCellValue(r,c) 6326 FindBondsDraw() 6327 elif drawAtoms.GetColLabelValue(c) == 'Color': 6328 dlg = wx.ColourDialog(G2frame) 6329 if dlg.ShowModal() == wx.ID_OK: 6330 color = dlg.GetColourData().GetColour() 6331 attr = wg.GridCellAttr() #needs to be here  gets lost if outside loop! 6332 attr.SetReadOnly(True) 6333 attr.SetBackgroundColour(color) 6334 atomData[r][c] = color 6335 drawingData['Atoms'][r][c] = color 6336 drawAtoms.SetAttr(i,cs+2,attr) 6337 dlg.Destroy() 6338 UpdateDrawAtoms() 6339 G2plt.PlotStructure(G2frame,data) 6340 6341 def RowSelect(event): 6342 r,c = event.GetRow(),event.GetCol() 6343 if r < 0 and c < 0: 6344 if drawAtoms.IsSelection(): 6345 drawAtoms.ClearSelection() 6346 elif c < 0: #only row clicks 6347 if event.ControlDown(): 6348 if r in drawAtoms.GetSelectedRows(): 6349 drawAtoms.DeselectRow(r) 6350 else: 6351 drawAtoms.SelectRow(r,True) 6352 elif event.ShiftDown(): 6353 for row in range(r+1): 6354 drawAtoms.SelectRow(row,True) 6355 else: 6356 drawAtoms.ClearSelection() 6357 drawAtoms.SelectRow(r,True) 6358 drawingData['selectedAtoms'] = [] 6359 drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows() 6360 G2plt.PlotStructure(G2frame,data) 6361 6362 table = [] 6363 rowLabels = [] 6364 for i,atom in enumerate(drawingData['Atoms']): 6365 table.append(atom[:colLabels.index('I/A')+1]) 6366 rowLabels.append(str(i)) 6367 6368 atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) 6369 drawAtoms.SetTable(atomTable, True) 6370 drawAtoms.SetMargins(0,0) 6371 drawAtoms.AutoSizeColumns(True) 6372 drawAtoms.SetColSize(colLabels.index('Style'),80) 6373 drawAtoms.SetColSize(colLabels.index('Color'),50) 6374 drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid) 6375 drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid) 6376 drawAtoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, RefreshAtomGrid) 6377 drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect) 6378 for i,atom in enumerate(drawingData['Atoms']): 6379 attr = wg.GridCellAttr() #needs to be here  gets lost if outside loop! 6380 attr.SetReadOnly(True) 6381 attr.SetBackgroundColour(atom[cs+2]) 6382 drawAtoms.SetAttr(i,cs+2,attr) 6383 drawAtoms.SetCellValue(i,cs+2,'') 6384 indx = drawingData['selectedAtoms'] 6385 if indx: 6386 for r in range(len(atomData)): 6387 if r in indx: 6388 drawAtoms.SelectRow(r) 6389 for c in range(len(colLabels)): 6390 attr = wg.GridCellAttr() #needs to be here  gets lost if outside loop! 6391 attr.SetReadOnly(True) 6392 attr.SetBackgroundColour(VERY_LIGHT_GREY) 6393 if colLabels[c] not in ['Style','Label','Color']: 6394 drawAtoms.SetColAttr(c,attr) 6395 G2frame.dataFrame.setSizePosLeft([600,300]) 6396 6397 FindBondsDraw() 6398 drawAtoms.ClearSelection() 6399 G2plt.PlotStructure(G2frame,data) 6400 6401 def DrawAtomStyle(event): 6402 indx = drawAtoms.GetSelectedRows() 6403 if indx: 6404 generalData = data['General'] 6405 atomData = data['Drawing']['Atoms'] 6406 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6407 styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra'] 6408 if generalData['Type'] == 'macromolecular': 6409 styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids', 6410 'backbone','ribbons','schematic'] 6411 dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice) 6412 if dlg.ShowModal() == wx.ID_OK: 6413 sel = dlg.GetSelection() 6414 parms = styleChoice[sel] 6415 for r in indx: 6416 atomData[r][cs] = parms 6417 drawAtoms.SetCellValue(r,cs,parms) 6418 dlg.Destroy() 6419 FindBondsDraw() 6420 drawAtoms.ClearSelection() 6421 G2plt.PlotStructure(G2frame,data) 6422 6423 def DrawAtomLabel(event): 6424 indx = drawAtoms.GetSelectedRows() 6425 if indx: 6426 generalData = data['General'] 6427 atomData = data['Drawing']['Atoms'] 6428 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6429 styleChoice = [' ','type','name','number'] 6430 if generalData['Type'] == 'macromolecular': 6431 styleChoice = [' ','type','name','number','residue','1letter','chain'] 6432 dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom label style',styleChoice) 6433 if dlg.ShowModal() == wx.ID_OK: 6434 sel = dlg.GetSelection() 6435 parms = styleChoice[sel] 6436 for r in indx: 6437 atomData[r][cs+1] = parms 6438 drawAtoms.SetCellValue(r,cs+1,parms) 6439 dlg.Destroy() 6440 drawAtoms.ClearSelection() 6441 G2plt.PlotStructure(G2frame,data) 6442 6443 def DrawAtomColor(event): 6444 6445 indx = drawAtoms.GetSelectedRows() 6446 if indx: 6447 if len(indx) > 1: 6448 G2frame.dataFrame.SetStatusText('Select Custom Color, change color, Add to Custom Colors, then OK') 6449 else: 6450 G2frame.dataFrame.SetStatusText('Change color, Add to Custom Colors, then OK') 6451 generalData = data['General'] 6452 atomData = data['Drawing']['Atoms'] 6453 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6454 atmColors = [] 6455 atmTypes = [] 6456 for r in indx: 6457 if atomData[r][cs+2] not in atmColors: 6458 atmColors.append(atomData[r][cs+2]) 6459 atmTypes.append(atomData[r][ct]) 6460 if len(atmColors) > 16: 6461 break 6462 colors = wx.ColourData() 6463 colors.SetChooseFull(True) 6464 dlg = wx.ColourDialog(G2frame) 6465 if dlg.ShowModal() == wx.ID_OK: 6466 for i in range(len(atmColors)): 6467 atmColors[i] = dlg.GetColourData().GetColour() 6468 colorDict = dict(zip(atmTypes,atmColors)) 6469 for r in indx: 6470 color = colorDict[atomData[r][ct]] 6471 atomData[r][cs+2] = color 6472 attr = wg.GridCellAttr() #needs to be here  gets lost if outside loop! 6473 attr.SetBackgroundColour(color) 6474 drawAtoms.SetAttr(r,cs+2,attr) 6475 data['Drawing']['Atoms'][r][cs+2] = color 6476 drawAtoms.ClearSelection() 6477 dlg.Destroy() 6478 G2frame.dataFrame.SetStatusText('') 6479 G2plt.PlotStructure(G2frame,data) 6480 6481 def ResetAtomColors(event): 6482 generalData = data['General'] 6483 atomData = data['Drawing']['Atoms'] 6484 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6485 for atom in atomData: 6486 atNum = generalData['AtomTypes'].index(atom[ct]) 6487 atom[cs+2] = list(generalData['Color'][atNum]) 6488 UpdateDrawAtoms() 6489 drawAtoms.ClearSelection() 6490 G2plt.PlotStructure(G2frame,data) 6491 6492 def SetViewPoint(event): 6493 indx = drawAtoms.GetSelectedRows() 6494 if indx: 6495 atomData = data['Drawing']['Atoms'] 6496 cx = data['Drawing']['atomPtrs'][0] 6497 data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]] 6498 drawAtoms.ClearSelection() #do I really want to do this? 6499 G2plt.PlotStructure(G2frame,data) 6500 6501 def noDuplicate(xyz,atomData): #be careful where this is used  it's slow 6502 cx = data['Drawing']['atomPtrs'][0] 6503 if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]: 6504 return False 6505 else: 6506 return True 6507 6508 def AddSymEquiv(event): 6509 indx = drawAtoms.GetSelectedRows() 6510 indx.sort() 6511 if indx: 6512 colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] 6513 cx = colLabels.index('x') 6514 cuia = colLabels.index('I/A') 6515 cuij = cuia+2 6516 atomData = data['Drawing']['Atoms'] 6517 generalData = data['General'] 6518 SGData = generalData['SGData'] 6519 dlg = SymOpDialog(G2frame,SGData,False,True) 6520 try: 6521 if dlg.ShowModal() == wx.ID_OK: 6522 Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection() 6523 Cell = np.array(Cell) 6524 cent = SGData['SGCen'][Cent] 6525 M,T = SGData['SGOps'][Opr] 6526 for ind in indx: 6527 XYZ = np.array(atomData[ind][cx:cx+3]) 6528 XYZ = np.inner(M,XYZ)+T 6529 if Inv: 6530 XYZ = XYZ 6531 XYZ = XYZ+cent+Cell 6532 if Force: 6533 XYZ = G2spc.MoveToUnitCell(XYZ) 6534 if noDuplicate(XYZ,atomData): 6535 atom = copy.copy(atomData[ind]) 6536 atom[cx:cx+3] = XYZ 6537 atomOp = atom[cx+3] 6538 newOp = str(((Opr+1)+100*Cent)*(12*Inv))+'+'+ \ 6539 str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2])) 6540 atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData) 6541 if atom[cuia] == 'A': 6542 Uij = atom[cuij:cuij+6] 6543 U = G2spc.Uij2U(Uij) 6544 U = np.inner(np.inner(M,U),M) 6545 Uij = G2spc.U2Uij(U) 6546 atom[cuij:cuij+6] = Uij 6547 atomData.append(atom) 6548 finally: 6549 dlg.Destroy() 6550 UpdateDrawAtoms() 6551 drawAtoms.ClearSelection() 6552 G2plt.PlotStructure(G2frame,data) 6553 6554 def TransformSymEquiv(event): 6555 indx = drawAtoms.GetSelectedRows() 6556 indx.sort() 6557 if indx: 6558 atomData = data['Drawing']['Atoms'] 6559 colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] 6560 cx = colLabels.index('x') 6561 cuia = colLabels.index('I/A') 6562 cuij = cuia+2 6563 atomData = data['Drawing']['Atoms'] 6564 generalData = data['General'] 6565 SGData = generalData['SGData'] 6566 dlg = SymOpDialog(G2frame,SGData,False,True) 6567 try: 6568 if dlg.ShowModal() == wx.ID_OK: 6569 Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection() 6570 Cell = np.array(Cell) 6571 cent = SGData['SGCen'][Cent] 6572 M,T = SGData['SGOps'][Opr] 6573 for ind in indx: 6574 XYZ = np.array(atomData[ind][cx:cx+3]) 6575 XYZ = np.inner(M,XYZ)+T 6576 if Inv: 6577 XYZ = XYZ 6578 XYZ = XYZ+cent+Cell 6579 if Force: 6580 XYZ = G2spc.MoveToUnitCell(XYZ) 6581 atom = atomData[ind] 6582 atom[cx:cx+3] = XYZ 6583 atomOp = atom[cx+3] 6584 newOp = str(((Opr+1)+100*Cent)*(12*Inv))+'+'+ \ 6585 str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2])) 6586 atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData) 6587 if atom[cuia] == 'A': 6588 Uij = atom[cuij:cuij+6] 6589 U = G2spc.Uij2U(Uij) 6590 U = np.inner(np.inner(M,U),M) 6591 Uij = G2spc.U2Uij(U) 6592 atom[cuij:cuij+6] = Uij 6593 data['Drawing']['Atoms'] = atomData 6594 finally: 6595 dlg.Destroy() 6596 UpdateDrawAtoms() 6597 drawAtoms.ClearSelection() 6598 G2plt.PlotStructure(G2frame,data) 6599 6600 def FillCoordSphere(event): 6601 generalData = data['General'] 6602 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 6603 radii = generalData['BondRadii'] 6604 atomTypes = generalData['AtomTypes'] 6605 try: 6606 indH = atomTypes.index('H') 6607 radii[indH] = 0.5 6608 except: 6609 pass 6610 indx = drawAtoms.GetSelectedRows() 6611 if indx: 6612 indx.sort() 6613 atomData = data['Drawing']['Atoms'] 6614 numAtoms = len(atomData) 6615 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6616 generalData = data['General'] 6617 SGData = generalData['SGData'] 6618 cellArray = G2lat.CellBlock(1) 6619 wx.BeginBusyCursor() 6620 try: 6621 for ind in indx: 6622 atomA = atomData[ind] 6623 xyzA = np.array(atomA[cx:cx+3]) 6624 indA = atomTypes.index(atomA[ct]) 6625 for atomB in atomData[:numAtoms]: 6626 indB = atomTypes.index(atomB[ct]) 6627 sumR = radii[indA]+radii[indB] 6628 xyzB = np.array(atomB[cx:cx+3]) 6629 for xyz in cellArray+xyzB: 6630 dist = np.sqrt(np.sum(np.inner(Amat,xyzxyzA)**2)) 6631 if 0 < dist <= data['Drawing']['radiusFactor']*sumR: 6632 if noDuplicate(xyz,atomData): 6633 oprB = atomB[cx+3] 6634 C = xyzxyzB 6635 newOp = '1+'+str(int(round(C[0])))+','+str(int(round(C[1])))+','+str(int(round(C[2]))) 6636 newAtom = atomB[:] 6637 newAtom[cx:cx+3] = xyz 6638 newAtom[cx+3] = G2spc.StringOpsProd(oprB,newOp,SGData) 6639 atomData.append(newAtom) 6640 finally: 6641 wx.EndBusyCursor() 6642 data['Drawing']['Atoms'] = atomData 6643 UpdateDrawAtoms() 6644 drawAtoms.ClearSelection() 6645 G2plt.PlotStructure(G2frame,data) 6646 6647 def FillUnitCell(event): 6648 indx = drawAtoms.GetSelectedRows() 6649 indx.sort() 6650 if indx: 6651 atomData = data['Drawing']['Atoms'] 6652 colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] 6653 cx = colLabels.index('x') 6654 cuia = colLabels.index('I/A') 6655 cuij = cuia+2 6656 generalData = data['General'] 6657 SGData = generalData['SGData'] 6658 wx.BeginBusyCursor() 6659 try: 6660 for ind in indx: 6661 atom = atomData[ind] 6662 XYZ = np.array(atom[cx:cx+3]) 6663 if atom[cuia] == 'A': 6664 Uij = atom[cuij:cuij+6] 6665 result = G2spc.GenAtom(XYZ,SGData,False,Uij,False) 6666 for item in result: 6667 atom = copy.copy(atomData[ind]) 6668 atom[cx:cx+3] = item[0] 6669 atom[cx+3] = str(item[2])+'+' \ 6670 +str(item[3][0])+','+str(item[3][1])+','+str(item[3][2]) 6671 atom[cuij:cuij+6] = item[1] 6672 Opp = G2spc.Opposite(item[0]) 6673 for xyz in Opp: 6674 if noDuplicate(xyz,atomData): 6675 cell = np.asarray(np.rint(xyzatom[cx:cx+3]),dtype=np.int32) 6676 cell = '1'+'+'+ \ 6677 str(cell[0])+','+str(cell[1])+','+str(cell[2]) 6678 atom[cx:cx+3] = xyz 6679 atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData) 6680 atomData.append(atom[:]) 6681 else: 6682 result = G2spc.GenAtom(XYZ,SGData,False,Move=False) 6683 for item in result: 6684 atom = copy.copy(atomData[ind]) 6685 atom[cx:cx+3] = item[0] 6686 atom[cx+3] = str(item[1])+'+' \ 6687 +str(item[2][0])+','+str(item[2][1])+','+str(item[2][2]) 6688 Opp = G2spc.Opposite(item[0]) 6689 for xyz in Opp: 6690 if noDuplicate(xyz,atomData): 6691 cell = np.asarray(np.rint(xyzatom[cx:cx+3]),dtype=np.int32) 6692 cell = '1'+'+'+ \ 6693 str(cell[0])+','+str(cell[1])+','+str(cell[2]) 6694 atom[cx:cx+3] = xyz 6695 atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData) 6696 atomData.append(atom[:]) 6697 data['Drawing']['Atoms'] = atomData 6698 finally: 6699 wx.EndBusyCursor() 6700 UpdateDrawAtoms() 6701 drawAtoms.ClearSelection() 6702 G2plt.PlotStructure(G2frame,data) 6703 6704 def FindBondsToo(): #works but slow for large structures  keep as reference 6705 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6706 atomData = data['Drawing']['Atoms'] 6707 generalData = data['General'] 6708 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 6709 radii = generalData['BondRadii'] 6710 atomTypes = generalData['AtomTypes'] 6711 try: 6712 indH = atomTypes.index('H') 6713 radii[indH] = 0.5 6714 except: 6715 pass 6716 for atom in atomData: 6717 atom[1] = [] 6718 Atoms = [] 6719 for i,atom in enumerate(atomData): 6720 Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]]) 6721 for atomA in Atoms: 6722 if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']: 6723 for atomB in Atoms: 6724 Dx = atomB[1]atomA[1] 6725 DX = np.inner(Amat,Dx) 6726 dist = np.sqrt(np.sum(DX**2)) 6727 sumR = atomA[3]+atomB[3] 6728 if 0.5 < dist <= 0.85*sumR: 6729 i = atomA[0] 6730 if atomA[2] == 'polyhedra': 6731 atomData[i][1].append(DX) 6732 elif atomB[1] != 'polyhedra': 6733 j = atomB[0] 6734 atomData[i][1].append(Dx*atomA[3]/sumR) 6735 atomData[j][1].append(Dx*atomB[3]/sumR) 6736 6737 def FindBondsDraw(): #uses numpy & masks  very fast even for proteins! 6738 import numpy.ma as ma 6739 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6740 hydro = data['Drawing']['showHydrogen'] 6741 atomData = data['Drawing']['Atoms'] 6742 generalData = data['General'] 6743 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 6744 radii = generalData['BondRadii'] 6745 atomTypes = generalData['AtomTypes'] 6746 try: 6747 indH = atomTypes.index('H') 6748 radii[indH] = 0.5 6749 except: 6750 pass 6751 for atom in atomData: 6752 atom[2] = [] #clear out old bonds/polyhedra 6753 atom[1] = [] 6754 Indx = range(len(atomData)) 6755 Atoms = [] 6756 Styles = [] 6757 Radii = [] 6758 for atom in atomData: 6759 Atoms.append(np.array(atom[cx:cx+3])) 6760 Styles.append(atom[cs]) 6761 try: 6762 if not hydro and atom[ct] == 'H': 6763 Radii.append(0.0) 6764 else: 6765 Radii.append(radii[atomTypes.index(atom[ct])]) 6766 except ValueError: #changed atom type! 6767 Radii.append(0.20) 6768 Atoms = np.array(Atoms) 6769 Radii = np.array(Radii) 6770 IASR = zip(Indx,Atoms,Styles,Radii) 6771 for atomA in IASR: 6772 if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']: 6773 Dx = AtomsatomA[1] 6774 dist = ma.masked_less(np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)),0.5) #gets rid of G2frame & disorder "bonds" < 0.5A 6775 sumR = atomA[3]+Radii 6776 IndB = ma.nonzero(ma.masked_greater(distdata['Drawing']['radiusFactor']*sumR,0.)) #get indices of bonded atoms 6777 i = atomA[0] 6778 for j in IndB[0]: 6779 if Styles[i] == 'polyhedra': 6780 atomData[i][2].append(np.inner(Amat,Dx[j])) 6781 elif Styles[j] != 'polyhedra' and j > i: 6782 atomData[i][2].append(Dx[j]*Radii[i]/sumR[j]) 6783 atomData[j][2].append(Dx[j]*Radii[j]/sumR[j]) 6784 if Styles[i] == 'polyhedra': 6785 Bonds = atomData[i][2] 6786 Faces = [] 6787 if len(Bonds) > 2: 6788 FaceGen = G2lat.uniqueCombinations(Bonds,3) #N.B. this is a generator 6789 for face in FaceGen: 6790 vol = nl.det(face) 6791 if abs(vol) > 1. or len(Bonds) == 3: 6792 if vol < 0.: 6793 face = [face[0],face[2],face[1]] 6794 face = np.array(face) 6795 if not np.array([np.array(nl.det(facebond))+0.0001 < 0 for bond in Bonds]).any(): 6796 norm = np.cross(face[1]face[0],face[2]face[0]) 6797 norm /= np.sqrt(np.sum(norm**2)) 6798 Faces.append([face,norm]) 6799 atomData[i][1] = Faces 6800 6801 def DrawAtomsDelete(event): 6802 indx = drawAtoms.GetSelectedRows() 6803 indx.sort() 6804 if indx: 6805 atomData = data['Drawing']['Atoms'] 6806 indx.reverse() 6807 for ind in indx: 6808 del atomData[ind] 6809 UpdateDrawAtoms() 6810 drawAtoms.ClearSelection() 6811 G2plt.PlotStructure(G2frame,data) 6812 event.StopPropagation() 6813 6814 def OnReloadDrawAtoms(event): 6815 data['Drawing']['Atoms'] = [] 6816 UpdateDrawAtoms() 6817 drawAtoms.ClearSelection() 6818 G2plt.PlotStructure(G2frame,data) 6819 event.StopPropagation() 6820 6821 def FindAtomIndexByIDs(atomData,IDs,Draw=True): 6822 indx = [] 6823 for i,atom in enumerate(atomData): 6824 if Draw and atom[3] in IDs: 6825 indx.append(i) 6826 elif atom[1] in IDs: 6827 indx.append(i) 6828 return indx 6829 6830 def DrawAtomsDeleteByIDs(IDs): 6831 atomData = data['Drawing']['Atoms'] 6832 indx = FindAtomIndexByIDs(atomData,IDs) 6833 indx.reverse() 6834 for ind in indx: 6835 del atomData[ind] 6836 6837 def ChangeDrawAtomsByIDs(colName,IDs,value): 6838 atomData = data['Drawing']['Atoms'] 6839 cx,ct,cs,ci = data['Drawing']['atomPtrs'] 6840 if colName == 'Name': 6841 col = ct1 6842 elif colName == 'Type': 6843 col = ct 6844 elif colName == 'I/A': 6845 col = cs 6846 indx = FindAtomIndexByIDs(atomData,IDs) 6847 for ind in indx: 6848 atomData[ind][col] = value 6849 6850 def OnDrawPlane(event): 6851 indx = drawAtoms.GetSelectedRows() 6852 if len(indx) < 4: 6853 print '**** ERROR  need 4+ atoms for plane calculation' 6854 return 6855 PlaneData = {} 6856 drawingData = data['Drawing'] 6857 atomData = drawingData['Atoms'] 6858 colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] 6859 cx = colLabels.index('x') 6860 cn = colLabels.index('Name') 6861 xyz = [] 6862 for i,atom in enumerate(atomData): 6863 if i in indx: 6864 xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3]) 6865 generalData = data['General'] 6866 PlaneData['Name'] = generalData['Name'] 6867 PlaneData['Atoms'] = xyz 6868 PlaneData['Cell'] = generalData['Cell'][1:] #+ volume 6869 G2str.BestPlane(PlaneData) 6870 6871 def OnDrawDistVP(event): 6872 # distance to view point 6873 indx = drawAtoms.GetSelectedRows() 6874 if not indx: 6875 print '***** ERROR  no atoms selected' 6876 return 6877 generalData = data['General'] 6878 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 6879 drawingData = data['Drawing'] 6880 viewPt = np.array(drawingData['viewPoint'][0]) 6881 print ' Distance from view point at %.3f %.3f %.3f to:'%(viewPt[0],viewPt[1],viewPt[2]) 6882 atomDData = drawingData['Atoms'] 6883 colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] 6884 cx = colLabels.index('x') 6885 cn = colLabels.index('Name') 6886 for i in indx: 6887 atom = atomDData[i] 6888 Dx = np.array(atom[cx:cx+3])viewPt 6889 dist = np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)) 6890 print 'Atom: %8s (%12s) distance = %.3f'%(atom[cn],atom[cx+3],dist) 6891 6892 def OnDrawDAT(event): 6893 #distance, angle, torsion 6894 indx = drawAtoms.GetSelectedRows() 6895 if len(indx) not in [2,3,4]: 6896 print '**** ERROR  wrong number of atoms for distance, angle or torsion calculation' 6897 return 6898 DATData = {} 6899 ocx,oct,ocs,cia = data['General']['AtomPtrs'] 6900 drawingData = data['Drawing'] 6901 atomData = data['Atoms'] 6902 atomDData = drawingData['Atoms'] 6903 colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] 6904 cx = colLabels.index('x') 6905 cn = colLabels.index('Name') 6906 cid = colLabels.index('I/A')+8 6907 xyz = [] 6908 Oxyz = [] 6909 DATData['Natoms'] = len(indx) 6910 for i in indx: 6911 atom = atomDData[i] 6912 xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+4]) #also gets Sym Op 6913 id = FindAtomIndexByIDs(atomData,[atom[cid],],False)[0] 6914 Oxyz.append([id,]+atomData[id][cx+1:cx+4]) 6915 DATData['Datoms'] = xyz 6916 DATData['Oatoms'] = Oxyz 6917 generalData = data['General'] 6918 DATData['Name'] = generalData['Name'] 6919 DATData['SGData'] = generalData['SGData'] 6920 DATData['Cell'] = generalData['Cell'][1:] #+ volume 6921 if 'pId' in data: 6922 DATData['pId'] = data['pId'] 6923 DATData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance')) 6924 G2str.DisAglTor(DATData) 6925 6926 ################################################################################ 6927 #### Draw Options page 6928 ################################################################################ 6929 6930 def UpdateDrawOptions(): 6931 import copy 6932 import wx.lib.colourselect as wcs 6933 generalData = data['General'] 6934 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 6935 SetupDrawingData() 6936 drawingData = data['Drawing'] 6937 if generalData['Type'] == 'nuclear': 6938 pickChoice = ['Atoms','Bonds','Torsions','Planes'] 6939 elif generalData['Type'] == 'macromolecular': 6940 pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi'] 6941 6942 def SlopSizer(): 6943 6944 def OnCameraPos(event): 6945 drawingData['cameraPos'] = cameraPos.GetValue() 6946 cameraPosTxt.SetLabel(' Camera Distance: '+'%.2f'%(drawingData['cameraPos'])) 6947 ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.)) 6948 G2plt.PlotStructure(G2frame,data) 6949 6950 def OnZclip(event): 6951 drawingData['Zclip'] = Zclip.GetValue() 6952 ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.)) 6953 G2plt.PlotStructure(G2frame,data) 6954 6955 def OnZstep(event): 6956 try: 6957 step = float(Zstep.GetValue()) 6958 if not (0.01 <= step <= 1.0): 6959 raise ValueError 6960 except ValueError: 6961 step = drawingData['Zstep'] 6962 drawingData['Zstep'] = step 6963 Zstep.SetValue('%.2fA'%(drawingData['Zstep'])) 6964 6965 def OnMoveZ(event): 6966 move = MoveZ.GetValue()*drawingData['Zstep'] 6967 MoveZ.SetValue(0) 6968 VP = np.inner(Amat,np.array(drawingData['viewPoint'][0])) 6969 VD = np.inner(Amat,np.array(drawingData['viewDir'])) 6970 VD /= np.sqrt(np.sum(VD**2)) 6971 VP += move*VD 6972 VP = np.inner(Bmat,VP) 6973 drawingData['viewPoint'][0] = VP 6974 panel = dataDisplay.GetChildren() 6975 names = [child.GetName() for child in panel] 6976 panel[names.index('viewPoint')].SetValue('%.3f %.3f %.3f'%(VP[0],VP[1],VP[2])) 6977 G2plt.PlotStructure(G2frame,data) 6978 6979 def OnVdWScale(event): 6980 drawingData['vdwScale'] = vdwScale.GetValue()/100. 6981 vdwScaleTxt.SetLabel(' van der Waals scale: '+'%.2f'%(drawingData['vdwScale'])) 6982 G2plt.PlotStructure(G2frame,data) 6983 6984 def OnEllipseProb(event): 6985 drawingData['ellipseProb'] = ellipseProb.GetValue() 6986 ellipseProbTxt.SetLabel(' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb'])) 6987 G2plt.PlotStructure(G2frame,data) 6988 6989 def OnBallScale(event): 6990 drawingData['ballScale'] = ballScale.GetValue()/100. 6991 ballScaleTxt.SetLabel(' Ball scale: '+'%.2f'%(drawingData['ballScale'])) 6992 G2plt.PlotStructure(G2frame,data) 6993 6994 def OnBondRadius(event): 6995 drawingData['bondRadius'] = bondRadius.GetValue()/100. 6996 bondRadiusTxt.SetLabel(' Bond radius, A: '+'%.2f'%(drawingData['bondRadius'])) 6997 G2plt.PlotStructure(G2frame,data) 6998 6999 def OnContourLevel(event): 7000 drawingData['contourLevel'] = contourLevel.GetValue()/100. 7001 contourLevelTxt.SetLabel(' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax'])) 7002 G2plt.PlotStructure(G2frame,data) 7003 7004 def OnMapSize(event): 7005 drawingData['mapSize'] = mapSize.GetValue()/10. 7006 mapSizeTxt.SetLabel(' Map radius, A: '+'%.1f'%(drawingData['mapSize'])) 7007 G2plt.PlotStructure(G2frame,data) 7008 7009 7010 slopSizer = wx.BoxSizer(wx.HORIZONTAL) 7011 slideSizer = wx.FlexGridSizer(7,2) 7012 slideSizer.AddGrowableCol(1,1) 7013 7014 cameraPosTxt = wx.StaticText(dataDisplay,1, 7015 ' Camera Distance: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos') 7016 slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL) 7017 cameraPos = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider') 7018 cameraPos.SetRange(10,500) 7019 cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos) 7020 slideSizer.Add(cameraPos,1,wx.EXPANDwx.RIGHT) 7021 7022 ZclipTxt = wx.StaticText(dataDisplay,1,' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.)) 7023 slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL) 7024 Zclip = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['Zclip']) 7025 Zclip.SetRange(1,99) 7026 Zclip.Bind(wx.EVT_SLIDER, OnZclip) 7027 slideSizer.Add(Zclip,1,wx.EXPANDwx.RIGHT) 7028 7029 ZstepSizer = wx.BoxSizer(wx.HORIZONTAL) 7030 ZstepSizer.Add(wx.StaticText(dataDisplay,1,' Z step:'),0,wx.ALIGN_CENTER_VERTICAL) 7031 Zstep = wx.TextCtrl(dataDisplay,value='%.2f'%(drawingData['Zstep']), 7032 style=wx.TE_PROCESS_ENTER) 7033 Zstep.Bind(wx.EVT_TEXT_ENTER,OnZstep) 7034 Zstep.Bind(wx.EVT_KILL_FOCUS,OnZstep) 7035 ZstepSizer.Add(Zstep,0,wx.ALIGN_CENTER_VERTICAL) 7036 slideSizer.Add(ZstepSizer) 7037 MoveSizer = wx.BoxSizer(wx.HORIZONTAL) 7038 MoveSizer.Add(wx.StaticText(dataDisplay,1,' Press to step:'),0,wx.ALIGN_CENTER_VERTICAL) 7039 MoveZ = wx.SpinButton(dataDisplay,style=wx.SP_HORIZONTAL,size=wx.Size(100,20)) 7040 MoveZ.SetValue(0) 7041 MoveZ.SetRange(1,1) 7042 MoveZ.Bind(wx.EVT_SPIN, OnMoveZ) 7043 MoveSizer.Add(MoveZ) 7044 slideSizer.Add(MoveSizer,1,wx.EXPANDwx.RIGHT) 7045 7046 vdwScaleTxt = wx.StaticText(dataDisplay,1,' van der Waals scale: '+'%.2f'%(drawingData['vdwScale'])) 7047 slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL) 7048 vdwScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale'])) 7049 vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale) 7050 slideSizer.Add(vdwScale,1,wx.EXPANDwx.RIGHT) 7051 7052 ellipseProbTxt = wx.StaticText(dataDisplay,1,' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb'])) 7053 slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL) 7054 ellipseProb = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb']) 7055 ellipseProb.SetRange(1,99) 7056 ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb) 7057 slideSizer.Add(ellipseProb,1,wx.EXPANDwx.RIGHT) 7058 7059 ballScaleTxt = wx.StaticText(dataDisplay,1,' Ball scale: '+'%.2f'%(drawingData['ballScale'])) 7060 slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL) 7061 ballScale = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale'])) 7062 ballScale.Bind(wx.EVT_SLIDER, OnBallScale) 7063 slideSizer.Add(ballScale,1,wx.EXPANDwx.RIGHT) 7064 7065 bondRadiusTxt = wx.StaticText(dataDisplay,1,' Bond radius, A: '+'%.2f'%(drawingData['bondRadius'])) 7066 slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL) 7067 bondRadius = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius'])) 7068 bondRadius.SetRange(1,25) 7069 bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius) 7070 slideSizer.Add(bondRadius,1,wx.EXPANDwx.RIGHT) 7071 7072 if generalData['Map']['rhoMax']: 7073 contourLevelTxt = wx.StaticText(dataDisplay,1,' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax'])) 7074 slideSizer.Add(contourLevelTxt,0,wx.ALIGN_CENTER_VERTICAL) 7075 contourLevel = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(100*drawingData['contourLevel'])) 7076 contourLevel.SetRange(1,100) 7077 contourLevel.Bind(wx.EVT_SLIDER, OnContourLevel) 7078 slideSizer.Add(contourLevel,1,wx.EXPANDwx.RIGHT) 7079 mapSizeTxt = wx.StaticText(dataDisplay,1,' Map radius, A: '+'%.1f'%(drawingData['mapSize'])) 7080 slideSizer.Add(mapSizeTxt,0,wx.ALIGN_CENTER_VERTICAL) 7081 mapSize = wx.Slider(dataDisplay,style=wx.SL_HORIZONTAL,value=int(10*drawingData['mapSize'])) 7082 mapSize.SetRange(1,100) 7083 mapSize.Bind(wx.EVT_SLIDER, OnMapSize) 7084 slideSizer.Add(mapSize,1,wx.EXPANDwx.RIGHT) 7085 7086 slopSizer.Add(slideSizer,1,wx.EXPANDwx.RIGHT) 7087 slopSizer.Add((10,5),0) 7088 slopSizer.SetMinSize(wx.Size(350,10)) 7089 return slopSizer 7090 7091 def ShowSizer(): 7092 7093 def OnBackColor(event): 7094 drawingData['backColor'] = event.GetValue() 7095 G2plt.PlotStructure(G2frame,data) 7096 7097 def OnShowABC(event): 7098 drawingData['showABC'] = showABC.GetValue() 7099 G2plt.PlotStructure(G2frame,data) 7100 7101 def OnShowUnitCell(event): 7102 drawingData['unitCellBox'] = unitCellBox.GetValue() 7103 G2plt.PlotStructure(G2frame,data) 7104 7105 def OnShowHyd(event): 7106 drawingData['showHydrogen'] = showHydrogen.GetValue() 7107 FindBondsDraw() 7108 G2plt.PlotStructure(G2frame,data) 7109 7110 def OnViewPoint(event): 7111 Obj = event.GetEventObject() 7112 viewPt = Obj.GetValue().split() 7113 try: 7114 VP = [float(viewPt[i]) for i in range(3)] 7115 except (ValueError,IndexError): 7116 VP = drawingData['viewPoint'][0] 7117 Obj.SetValue('%.3f %.3f %.3f'%(VP[0],VP[1],VP[2])) 7118 drawingData['viewPoint'][0] = VP 7119 G2plt.PlotStructure(G2frame,data) 7120 7121 def OnViewDir(event): 7122 Obj = event.GetEventObject() 7123 viewDir = Obj.GetValue().split() 7124 try: 7125 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 7126 VD = np.array([float(viewDir[i]) for i in range(3)]) 7127 VC = np.inner(Amat,VD) 7128 VC /= np.sqrt(np.sum(VC**2)) 7129 V = np.array(drawingData['viewDir']) 7130 VB = np.inner(Amat,V) 7131 VB /= np.sqrt(np.sum(VB**2)) 7132 VX = np.cross(VC,VB) 7133 A = acosd(max((2.np.sum((VBVC)**2))/2.,1.)) 7134 QV = G2mth.AVdeg2Q(A,VX) 7135 Q = drawingData['Quaternion'] 7136 drawingData['Quaternion'] = G2mth.prodQQ(Q,QV) 7137 except (ValueError,IndexError): 7138 VD = drawingData['viewDir'] 7139 Obj.SetValue('%.3f %.3f %.3f'%(VD[0],VD[1],VD[2])) 7140 drawingData['viewDir'] = VD 7141 G2plt.PlotStructure(G2frame,data) 7142 7143 showSizer = wx.BoxSizer(wx.VERTICAL) 7144 lineSizer = wx.BoxSizer(wx.HORIZONTAL) 7145 lineSizer.Add(wx.StaticText(dataDisplay,1,' Background color:'),0,wx.ALIGN_CENTER_VERTICAL) 7146 backColor = wcs.ColourSelect(dataDisplay, 1,colour=drawingData['backColor'],size=wx.Size(25,25)) 7147 backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor) 7148 lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL) 7149 lineSizer.Add(wx.StaticText(dataDisplay,1,' View Dir.:'),0,wx.ALIGN_CENTER_VERTICAL) 7150 VD = drawingData['viewDir'] 7151 viewDir = wx.TextCtrl(dataDisplay,value='%.3f %.3f %.3f'%(VD[0],VD[1],VD[2]), 7152 style=wx.TE_PROCESS_ENTER,size=wx.Size(140,20),name='viewDir') 7153 viewDir.Bind(wx.EVT_TEXT_ENTER,OnViewDir) 7154 viewDir.Bind(wx.EVT_KILL_FOCUS,OnViewDir) 7155 lineSizer.Add(viewDir,0,wx.ALIGN_CENTER_VERTICAL) 7156 showSizer.Add(lineSizer) 7157 showSizer.Add((0,5),0) 7158 7159 lineSizer = wx.BoxSizer(wx.HORIZONTAL) 7160 showABC = wx.CheckBox(dataDisplay,1,label=' Show view point?') 7161 showABC.Bind(wx.EVT_CHECKBOX, OnShowABC) 7162 showABC.SetValue(drawingData['showABC']) 7163 lineSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL) 7164 lineSizer.Add(wx.StaticText(dataDisplay,1,' View Point:'),0,wx.ALIGN_CENTER_VERTICAL) 7165 VP = drawingData['viewPoint'][0] 7166 viewPoint = wx.TextCtrl(dataDisplay,value='%.3f %.3f %.3f'%(VP[0],VP[1],VP[2]), 7167 style=wx.TE_PROCESS_ENTER,size=wx.Size(140,20),name='viewPoint') 7168 viewPoint.Bind(wx.EVT_TEXT_ENTER,OnViewPoint) 7169 viewPoint.Bind(wx.EVT_KILL_FOCUS,OnViewPoint) 7170 lineSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL) 7171 showSizer.Add(lineSizer) 7172 showSizer.Add((0,5),0) 7173 7174 line2Sizer = wx.BoxSizer(wx.HORIZONTAL) 7175 7176 unitCellBox = wx.CheckBox(dataDisplay,1,label=' Show unit cell?') 7177 unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell) 7178 unitCellBox.SetValue(drawingData['unitCellBox']) 7179 line2Sizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL) 7180 7181 showHydrogen = wx.CheckBox(dataDisplay,1,label=' Show hydrogens?') 7182 showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd) 7183 showHydrogen.SetValue(drawingData['showHydrogen']) 7184 line2Sizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL) 7185 showSizer.Add(line2Sizer) 7186 return showSizer 7187 7188 def RadSizer(): 7189 7190 def OnSizeHatoms(event): 7191 try: 7192 value = max(0.1,min(1.2,float(sizeH.GetValue()))) 7193 except ValueError: 7194 value = 0.5 7195 drawingData['sizeH'] = value 7196 sizeH.SetValue("%.2f"%(value)) 7197 G2plt.PlotStructure(G2frame,data) 7198 7199 def OnRadFactor(event): 7200 try: 7201 value = max(0.1,min(1.2,float(radFactor.GetValue()))) 7202 except ValueError: 7203 value = 0.85 7204 drawingData['radiusFactor'] = value 7205 radFactor.SetValue("%.2f"%(value)) 7206 FindBondsDraw() 7207 G2plt.PlotStructure(G2frame,data) 7208 7209 radSizer = wx.BoxSizer(wx.HORIZONTAL) 7210 radSizer.Add(wx.StaticText(dataDisplay,1,' Hydrogen radius, A: '),0,wx.ALIGN_CENTER_VERTICAL) 7211 sizeH = wx.TextCtrl(dataDisplay,1,value='%.2f'%(drawingData['sizeH']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER) 7212 sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms) 7213 sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms) 7214 radSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL) 7215 7216 radSizer.Add(wx.StaticText(dataDisplay,1,' Bond search factor: '),0,wx.ALIGN_CENTER_VERTICAL) 7217 radFactor = wx.TextCtrl(dataDisplay,value='%.2f'%(drawingData['radiusFactor']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER) 7218 radFactor.Bind(wx.EVT_TEXT_ENTER,OnRadFactor) 7219 radFactor.Bind(wx.EVT_KILL_FOCUS,OnRadFactor) 7220 radSizer.Add(radFactor,0,wx.ALIGN_CENTER_VERTICAL) 7221 return radSizer 7222 7223 G2frame.dataFrame.SetStatusText('') 7224 drawOptions.DestroyChildren() 7225 dataDisplay = wx.Panel(drawOptions) 7226 mainSizer = wx.BoxSizer(wx.VERTICAL) 7227 mainSizer.Add((5,5),0) 7228 mainSizer.Add(wx.StaticText(dataDisplay,1,' Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL) 7229 mainSizer.Add((5,5),0) 7230 mainSizer.Add(SlopSizer(),0) 7231 mainSizer.Add((5,5),0) 7232 mainSizer.Add(ShowSizer(),0,) 7233 mainSizer.Add((5,5),0) 7234 mainSizer.Add(RadSizer(),0,) 7235 7236 dataDisplay.SetSizer(mainSizer) 7237 Size = mainSizer.Fit(G2frame.dataFrame) 7238 Size[1] += 35 #compensate for status bar 7239 dataDisplay.SetSize(Size) 7240 G2frame.dataFrame.setSizePosLeft(Size) 7241 7242 ################################################################################ 7243 #### Texture routines 7244 ################################################################################ 7245 7246 def UpdateTexture(): 7247 G2frame.dataFrame.SetStatusText('') 7248 generalData = data['General'] 7249 SGData = generalData['SGData'] 7250 try: 7251 textureData = generalData['SH Texture'] 7252 except KeyError: #fix old files! 7253 textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical', 7254 'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0], 7255 'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1], 7256 'PFxyz':[0,0,1.],'PlotType':'Pole figure'} 7257 if 'SHShow' not in textureData: #another fix 7258 textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'}) 7259 try: #another fix! 7260 x = textureData['PlotType'] 7261 except KeyError: 7262 textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'}) 7263 shModels = ['cylindrical','none','shear  2/m','rolling  mmm'] 7264 SamSym = dict(zip(shModels,['0','1','2/m','mmm'])) 7265 if generalData['doPawley'] and G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequental results'): 7266 G2frame.dataFrame.RefineTexture.Enable(True) 7267 shAngles = ['omega','chi','phi'] 7268 7269 def SetSHCoef(): 7270 cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order']) 7271 newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames)))) 7272 SHCoeff = textureData['SH Coeff'][1] 7273 for cofName in SHCoeff: 7274 if cofName in cofNames: 7275 newSHCoef[cofName] = SHCoeff[cofName] 7276 return newSHCoef 7277 7278 def OnShOrder(event): 7279 Obj = event.GetEventObject() 7280 textureData['Order'] = int(Obj.GetValue()) 7281 textureData['SH Coeff'][1] = SetSHCoef() 7282 wx.CallAfter(UpdateTexture) 7283 G2plt.PlotTexture(G2frame,data) 7284 7285 def OnShModel(event): 7286 Obj = event.GetEventObject() 7287 textureData['Model'] = Obj.GetValue() 7288 textureData['SH Coeff'][1] = SetSHCoef() 7289 wx.CallAfter(UpdateTexture) 7290 G2plt.PlotTexture(G2frame,data) 7291 7292 def OnSHRefine(event): 7293 Obj = event.GetEventObject() 7294 textureData['SH Coeff'][0] = Obj.GetValue() 7295 7296 def OnSHShow(event): 7297 Obj = event.GetEventObject() 7298 textureData['SHShow'] = Obj.GetValue() 7299 wx.CallAfter(UpdateTexture) 7300 7301 def OnProjSel(event): 7302 Obj = event.GetEventObject() 7303 G2frame.Projection = Obj.GetValue() 7304 G2plt.PlotTexture(G2frame,data) 7305 7306 def OnColorSel(event): 7307 Obj = event.GetEventObject() 7308 G2frame.ContourColor = Obj.GetValue() 7309 G2plt.PlotTexture(G2frame,data) 7310 7311 def OnAngRef(event): 7312 Obj = event.GetEventObject() 7313 textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue() 7314 7315 def OnAngValue(event): 7316 Obj = event.GetEventObject() 7317 try: 7318 value = float(Obj.GetValue()) 7319 except ValueError: 7320 value = textureData[valIndx[Obj.GetId()]][1] 7321 Obj.SetValue('%8.2f'%(value)) 7322 textureData[valIndx[Obj.GetId()]][1] = value 7323 7324 def OnODFValue(event): 7325 Obj = event.GetEventObject() 7326 try: 7327 value = float(Obj.GetValue()) 7328 except ValueError: 7329 value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] 7330 Obj.SetValue('%8.3f'%(value)) 7331 textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value 7332 G2plt.PlotTexture(G2frame,data) 7333 7334 def OnPfType(event): 7335 Obj = event.GetEventObject() 7336 textureData['PlotType'] = Obj.GetValue() 7337 wx.CallAfter(UpdateTexture) 7338 G2plt.PlotTexture(G2frame,data) 7339 7340 def OnPFValue(event): 7341 Obj = event.GetEventObject() 7342 Saxis = Obj.GetValue().split() 7343 if textureData['PlotType'] in ['Pole figure','Axial pole distribution']: 7344 try: 7345 hkl = [int(Saxis[i]) for i in range(3)] 7346 except (ValueError,IndexError): 7347 hkl = textureData['PFhkl'] 7348 if not np.any(np.array(hkl)): #can't be all zeros! 7349 hkl = textureData['PFhkl'] 7350 Obj.SetValue('%d %d %d'%(hkl[0],hkl[1],hkl[2])) 7351 textureData['PFhkl'] = hkl 7352 else: 7353 try: 7354 xyz = [float(Saxis[i]) for i in range(3)] 7355 except (ValueError,IndexError): 7356 xyz = textureData['PFxyz'] 7357 if not np.any(np.array(xyz)): #can't be all zeros! 7358 xyz = textureData['PFxyz'] 7359 Obj.SetValue('%3.1f %3.1f %3.1f'%(xyz[0],xyz[1],xyz[2])) 7360 textureData['PFxyz'] = xyz 7361 G2plt.PlotTexture(G2frame,data) 7362 7363 if Texture.GetSizer(): 7364 Texture.GetSizer().Clear(True) 7365 mainSizer = wx.BoxSizer(wx.VERTICAL) 7366 titleSizer = wx.BoxSizer(wx.HORIZONTAL) 7367 titleSizer.Add(wx.StaticText(Texture,1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL) 7368 titleSizer.Add(wx.StaticText(Texture,1, 7369 ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))), 7370 0,wx.ALIGN_CENTER_VERTICAL) 7371 mainSizer.Add(titleSizer,0) 7372 mainSizer.Add((0,5),0) 7373 shSizer = wx.FlexGridSizer(1,6,5,5) 7374 shSizer.Add(wx.StaticText(Texture,1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL) 7375 shModel = wx.ComboBox(Texture,1,value=textureData['Model'],choices=shModels, 7376 style=wx.CB_READONLYwx.CB_DROPDOWN) 7377 shModel.Bind(wx.EVT_COMBOBOX,OnShModel) 7378 shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL) 7379 shSizer.Add(wx.StaticText(Texture,1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL) 7380 shOrder = wx.ComboBox(Texture,1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)], 7381 style=wx.CB_READONLYwx.CB_DROPDOWN) 7382 shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder) 7383 shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL) 7384 shRef = wx.CheckBox(Texture,1,label=' Refine texture?') 7385 shRef.SetValue(textureData['SH Coeff'][0]) 7386 shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine) 7387 shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL) 7388 shShow = wx.CheckBox(Texture,1,label=' Show coeff.?') 7389 shShow.SetValue(textureData['SHShow']) 7390 shShow.Bind(wx.EVT_CHECKBOX, OnSHShow) 7391 shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL) 7392 mainSizer.Add(shSizer,0,0) 7393 mainSizer.Add((0,5),0) 7394 PTSizer = wx.FlexGridSizer(2,4,5,5) 7395 PTSizer.Add(wx.StaticText(Texture,1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL) 7396 choices = ['Axial pole distribution','Pole figure','Inverse pole figure'] 7397 pfType = wx.ComboBox(Texture,1,value=str(textureData['PlotType']),choices=choices, 7398 style=wx.CB_READONLYwx.CB_DROPDOWN) 7399 pfType.Bind(wx.EVT_COMBOBOX,OnPfType) 7400 PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL) 7401 if 'Axial' not in textureData['PlotType']: 7402 PTSizer.Add(wx.StaticText(Texture,1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL) 7403 projSel = wx.ComboBox(Texture,1,value=G2frame.Projection,choices=['equal area','stereographic','3D display'], 7404 style=wx.CB_READONLYwx.CB_DROPDOWN) 7405 projSel.Bind(wx.EVT_COMBOBOX,OnProjSel) 7406 PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL) 7407 if textureData['PlotType'] in ['Pole figure','Axial pole distribution']: 7408 PTSizer.Add(wx.StaticText(Texture,1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL) 7409 PH = textureData['PFhkl'] 7410 pfVal = wx.TextCtrl(Texture,1,'%d %d %d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER) 7411 else: 7412 PTSizer.Add(wx.StaticText(Texture,1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL) 7413 PX = textureData['PFxyz'] 7414 pfVal = wx.TextCtrl(Texture,1,'%3.1f %3.1f %3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER) 7415 pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue) 7416 pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue) 7417 PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL) 7418 if 'Axial' not in textureData['PlotType']: 7419 PTSizer.Add(wx.StaticText(Texture,1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL) 7420 choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] 7421 choice.sort() 7422 colorSel = wx.ComboBox(Texture,1,value=G2frame.ContourColor,choices=choice, 7423 style=wx.CB_READONLYwx.CB_DROPDOWN) 7424 colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel) 7425 PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL) 7426 mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL) 7427 mainSizer.Add((0,5),0) 7428 if textureData['SHShow']: 7429 mainSizer.Add(wx.StaticText(Texture,1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL) 7430 mainSizer.Add((0,5),0) 7431 ODFSizer = wx.FlexGridSizer(2,8,2,2) 7432 ODFIndx = {} 7433 ODFkeys = textureData['SH Coeff'][1].keys() 7434 ODFkeys.sort() 7435 for item in ODFkeys: 7436 ODFSizer.Add(wx.StaticText(Texture,1,item),0,wx.ALIGN_CENTER_VERTICAL) 7437 ODFval = wx.TextCtrl(Texture,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER) 7438 ODFIndx[ODFval.GetId()] = item 7439 ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue) 7440 ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue) 7441 ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL) 7442 mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL) 7443 mainSizer.Add((0,5),0) 7444 mainSizer.Add((0,5),0) 7445 mainSizer.Add(wx.StaticText(Texture,1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL) 7446 mainSizer.Add((0,5),0) 7447 angSizer = wx.BoxSizer(wx.HORIZONTAL) 7448 angIndx = {} 7449 valIndx = {} 7450 for item in ['Sample omega','Sample chi','Sample phi']: 7451 angRef = wx.CheckBox(Texture,1,label=item+': ') 7452 angRef.SetValue(textureData[item][0]) 7453 angIndx[angRef.GetId()] = item 7454 angRef.Bind(wx.EVT_CHECKBOX, OnAngRef) 7455 angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL) 7456 angVal = wx.TextCtrl(Texture,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER) 7457 valIndx[angVal.GetId()] = item 7458 angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue) 7459 angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue) 7460 angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL) 7461 angSizer.Add((5,0),0) 7462 mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL) 7463 Texture.SetSizer(mainSizer,True) 7464 mainSizer.Fit(G2frame.dataFrame) 7465 Size = mainSizer.GetMinSize() 7466 Size[0] += 40 7467 Size[1] = max(Size[1],250) + 35 7468 Texture.SetSize(Size) 7469 Texture.SetScrollbars(10,10,Size[0]/104,Size[1]/101) 7470 Size[1] = min(Size[1],450) 7471 G2frame.dataFrame.setSizePosLeft(Size) 7472 7473 ################################################################################ 7474 ##### DData routines 7475 ################################################################################ 7476 7477 def UpdateDData(): 7478 G2frame.dataFrame.SetStatusText('') 7479 UseList = data['Histograms'] 7480 if UseList: 7481 G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,True) 7482 G2frame.Refine.Enable(True) 7483 else: 7484 G2frame.dataFrame.DataMenu.Enable(G2gd.wxID_DATADELETE,False) 7485 G2frame.Refine.Enable(False) 7486 generalData = data['General'] 7487 SGData = generalData['SGData'] 7488 keyList = UseList.keys() 7489 keyList.sort() 7490 PWDR = any(['PWDR' in item for item in keyList]) 7491 Indx = {} 7492 7493 def PlotSizer(): 7494 7495 def OnPlotSel(event): 7496 Obj = event.GetEventObject() 7497 generalData['Data plot type'] = Obj.GetStringSelection() 7498 wx.CallAfter(UpdateDData) 7499 G2plt.PlotSizeStrainPO(G2frame,data) 7500 7501 def OnPOhkl(event): 7502 Obj = event.GetEventObject() 7503 Saxis = Obj.GetValue().split() 7504 try: 7505 hkl = [int(Saxis[i]) for i in range(3)] 7506 except (ValueError,IndexError): 7507 hkl = generalData['POhkl'] 7508 if not np.any(np.array(hkl)): 7509 hkl = generalData['POhkl'] 7510 generalData['POhkl'] = hkl 7511 h,k,l = hkl 7512 Obj.SetValue('%3d %3d %3d'%(h,k,l)) 7513 G2plt.PlotSizeStrainPO(G2frame,data) 7514 7515 plotSizer = wx.BoxSizer(wx.VERTICAL) 7516 choice = ['None','Mustrain','Size','Preferred orientation'] 7517 plotSel = wx.RadioBox(DData,1,'Select plot type:',choices=choice, 7518 majorDimension=2,style=wx.RA_SPECIFY_COLS) 7519 plotSel.SetStringSelection(generalData['Data plot type']) 7520 plotSel.Bind(wx.EVT_RADIOBOX,OnPlotSel) 7521 plotSizer.Add(plotSel) 7522 if generalData['Data plot type'] == 'Preferred orientation': 7523 POhklSizer = wx.BoxSizer(wx.HORIZONTAL) 7524 POhklSizer.Add(wx.StaticText(DData,1,' Plot preferred orientation for H K L: '),0,wx.ALIGN_CENTER_VERTICAL) 7525 h,k,l = generalData['POhkl'] 7526 poAxis = wx.TextCtrl(DData,1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER) 7527 poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOhkl) 7528 poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOhkl) 7529 POhklSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL) 7530 plotSizer.Add(POhklSizer) 7531 return plotSizer 7532 7533 def ScaleSizer(): 7534 7535 def OnScaleRef(event): 7536 Obj = event.GetEventObject() 7537 UseList[Indx[Obj.GetId()]]['Scale'][1] = Obj.GetValue() 7538 7539 def OnScaleVal(event): 7540 Obj = event.GetEventObject() 7541 try: 7542 scale = float(Obj.GetValue()) 7543 if scale > 0: 7544 UseList[Indx[Obj.GetId()]]['Scale'][0] = scale 7545 except ValueError: 7546 pass 7547 Obj.SetValue("%.4f"%(UseList[Indx[Obj.GetId()]]['Scale'][0])) #reset in case of error 7548 7549 scaleSizer = wx.BoxSizer(wx.HORIZONTAL) 7550 if 'PWDR' in item: 7551 scaleRef = wx.CheckBox(DData,1,label=' Phase fraction: ') 7552 elif 'HKLF' in item: 7553 scaleRef = wx.CheckBox(DData,1,label=' Scale factor: ') 7554 scaleRef.SetValue(UseList[item]['Scale'][1]) 7555 Indx[scaleRef.GetId()] = item 7556 scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef) 7557 scaleSizer.Add(scaleRef,0,wx.ALIGN_CENTER_VERTICAL) 7558 scaleVal = wx.TextCtrl(DData,wx.ID_ANY, 7559 '%.4f'%(UseList[item]['Scale'][0]),style=wx.TE_PROCESS_ENTER) 7560 Indx[scaleVal.GetId()] = item 7561 scaleVal.Bind(wx.EVT_TEXT_ENTER,OnScaleVal) 7562 scaleVal.Bind(wx.EVT_KILL_FOCUS,OnScaleVal) 7563 scaleSizer.Add(scaleVal,0,wx.ALIGN_CENTER_VERTICAL) 7564 return scaleSizer 7565 7566 def OnUseData(event): 7567 Obj = event.GetEventObject() 7568 hist = Indx[Obj.GetId()] 7569 UseList[hist]['Use'] = Obj.GetValue() 7570 7571 def OnShowData(event): 7572 Obj = event.GetEventObject() 7573 hist = Indx[Obj.GetId()] 7574 UseList[hist]['Show'] = Obj.GetValue() 7575 wx.CallAfter(UpdateDData) 7576 G2plt.PlotSizeStrainPO(G2frame,data) 7577 7578 def OnCopyData(event): 7579 #how about HKLF data? This is only for PWDR data 7580 Obj = event.GetEventObject() 7581 hist = Indx[Obj.GetId()] 7582 sourceDict = UseList[hist] 7583 copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction'] 7584 copyDict = {} 7585 for name in copyNames: 7586 copyDict[name] = copy.deepcopy(sourceDict[name]) #force copy 7587 keyList = ['All',]+UseList.keys() 7588 if UseList: 7589 copyList = [] 7590 dlg = wx.MultiChoiceDialog(G2frame, 7591 'Copy parameters to which histograms?', 'Copy parameters', 7592 keyList, wx.CHOICEDLG_STYLE) 7593 try: 7594 if dlg.ShowModal() == wx.ID_OK: 7595 result = dlg.GetSelections() 7596 for i in result: 7597 copyList.append(keyList[i]) 7598 if 'All' in copyList: 7599 copyList = keyList[1:] 7600 for item in copyList: 7601 UseList[item].update(copy.deepcopy(copyDict)) 7602 wx.CallAfter(UpdateDData) 7603 finally: 7604 dlg.Destroy() 7605 7606 def OnCopyFlags(event): 7607 Obj = event.GetEventObject() 7608 hist = Indx[Obj.GetId()] 7609 sourceDict = UseList[hist] 7610 copyDict = {} 7611 copyNames = ['Scale','Pref.Ori.','Size','Mustrain','HStrain','Extinction'] 7612 for name in copyNames: 7613 if name in ['Scale','Extinction','HStrain']: 7614 copyDict[name] = sourceDict[name][1] 7615 elif name in ['Size','Mustrain']: 7616 copyDict[name] = [sourceDict[name][0],sourceDict[name][2],sourceDict[name][4]] 7617 elif name == 'Pref.Ori.': 7618 copyDict[name] = [sourceDict[name][0],sourceDict[name][2]] 7619 if sourceDict[name][0] == 'SH': 7620 SHterms = sourceDict[name][5] 7621 SHflags = {} 7622 for item in SHterms: 7623 SHflags[item] = SHterms[item][1] 7624 copyDict[name].append(SHflags) 7625 keyList = ['All',]+UseList.keys() 7626 if UseList: 7627 copyList = [] 7628 dlg = wx.MultiChoiceDialog(G2frame, 7629 'Copy parameters to which histograms?', 'Copy parameters', 7630 keyList, wx.CHOICEDLG_STYLE) 7631 try: 7632 if dlg.ShowModal() == wx.ID_OK: 7633 result = dlg.GetSelections() 7634 for i in result: 7635 copyList.append(keyList[i]) 7636 if 'All' in copyList: 7637 copyList = keyList[1:] 7638 for item in copyList: 7639 UseList[item] 7640 for name in copyNames: 7641 if name in ['Scale','Extinction','HStrain']: 7642 UseList[item][name][1] = copy.copy(copyDict[name]) 7643 elif name in ['Size','Mustrain']: 7644 UseList[item][name][0] = copy.copy(copyDict[name][0]) 7645 UseList[item][name][2] = copy.copy(copyDict[name][1]) 7646 UseList[item][name][4] = copy.copy(copyDict[name][2]) 7647 elif name == 'Pref.Ori.': 7648 UseList[item][name][0] = copy.copy(copyDict[name][0]) 7649 UseList[item][name][2] = copy.copy(copyDict[name][1]) 7650 if sourceDict[name][0] == 'SH': 7651 SHflags = copy.copy(copyDict[name][2]) 7652 SHterms = copy.copy(sourceDict[name][5]) 7653 for item in SHflags: 7654 SHterms[item][1] = copy.copy(SHflags[item]) 7655 wx.CallAfter(UpdateDData) 7656 finally: 7657 dlg.Destroy() 7658 7659 7660 def OnLGmixRef(event): 7661 Obj = event.GetEventObject() 7662 hist,name = Indx[Obj.GetId()] 7663 UseList[hist][name][2][2] = Obj.GetValue() 7664 7665 def OnLGmixVal(event): 7666 Obj = event.GetEventObject() 7667 hist,name = Indx[Obj.GetId()] 7668 try: 7669 value = float(Obj.GetValue()) 7670 if 0.1 <= value <= 1: 7671 UseList[hist][name][1][2] = value 7672 else: 7673 raise ValueError 7674 except ValueError: 7675 pass 7676 Obj.SetValue("%.4f"%(UseList[hist][name][1][2])) #reset in case of error 7677 7678 def OnSizeType(event): 7679 Obj = event.GetEventObject() 7680 hist = Indx[Obj.GetId()] 7681 UseList[hist]['Size'][0] = Obj.GetValue() 7682 G2plt.PlotSizeStrainPO(G2frame,data) 7683 wx.CallAfter(UpdateDData) 7684 7685 def OnSizeRef(event): 7686 Obj = event.GetEventObject() 7687 hist,pid = Indx[Obj.GetId()] 7688 if UseList[hist]['Size'][0] == 'ellipsoidal': 7689 UseList[hist]['Size'][5][pid] = Obj.GetValue() 7690 else: 7691 UseList[hist]['Size'][2][pid] = Obj.GetValue() 7692 7693 def OnSizeVal(event): 7694 Obj = event.GetEventObject() 7695 hist,pid = Indx[Obj.GetId()] 7696 if UseList[hist]['Size'][0] == 'ellipsoidal': 7697 try: 7698 size = float(Obj.GetValue()) 7699 if pid < 3 and size <= 0.001: #10A lower limit! 7700 raise ValueError 7701 UseList[hist]['Size'][4][pid] = size 7702 except ValueError: 7703 pass 7704 Obj.SetValue("%.3f"%(UseList[hist]['Size'][4][pid])) #reset in case of error 7705 else: 7706 try: 7707 size = float(Obj.GetValue()) 7708 if size <= 0.001: #10A lower limit! 7709 raise ValueError 7710 UseList[hist]['Size'][1][pid] = size 7711 except ValueError: 7712 pass 7713 Obj.SetValue("%.3f"%(UseList[hist]['Size'][1][pid])) #reset in case of error 7714 G2plt.PlotSizeStrainPO(G2frame,data) 7715 7716 def OnSizeAxis(event): 7717 Obj = event.GetEventObject() 7718 hist = Indx[Obj.GetId()] 7719 Saxis = Obj.GetValue().split() 7720 try: 7721 hkl = [int(Saxis[i]) for i in range(3)] 7722 except (ValueError,IndexError): 7723 hkl = UseList[hist]['Size'][3] 7724 if not np.any(np.array(hkl)): 7725 hkl = UseList[hist]['Size'][3] 7726 UseList[hist]['Size'][3] = hkl 7727 h,k,l = hkl 7728 Obj.SetValue('%3d %3d %3d'%(h,k,l)) 7729 7730 def OnStrainType(event): 7731 Obj = event.GetEventObject() 7732 hist = Indx[Obj.GetId()] 7733 UseList[hist]['Mustrain'][0] = Obj.GetValue() 7734 wx.CallAfter(UpdateDData) 7735 G2plt.PlotSizeStrainPO(G2frame,data) 7736 7737 def OnStrainRef(event): 7738 Obj = event.GetEventObject() 7739 hist,pid = Indx[Obj.GetId()] 7740 if UseList[hist]['Mustrain'][0] == 'generalized': 7741 UseList[hist]['Mustrain'][5][pid] = Obj.GetValue() 7742 else: 7743 UseList[hist]['Mustrain'][2][pid] = Obj.GetValue() 7744 7745 def OnStrainVal(event): 7746 Snames = G2spc.MustrainNames(SGData) 7747 Obj = event.GetEventObject() 7748 hist,pid = Indx[Obj.GetId()] 7749 try: 7750 strain = float(Obj.GetValue()) 7751 if UseList[hist]['Mustrain'][0] == 'generalized': 7752 if '4' in Snames[pid] and strain < 0: 7753 raise ValueError 7754 UseList[hist]['Mustrain'][4][pid] = strain 7755 else: 7756 if strain <= 0: 7757 raise ValueError 7758 UseList[hist]['Mustrain'][1][pid] = strain 7759 except ValueError: 7760 pass 7761 if UseList[hist]['Mustrain'][0] == 'generalized': 7762 Obj.SetValue("%.3f"%(UseList[hist]['Mustrain'][4][pid])) #reset in case of error 7763 else: 7764 Obj.SetValue("%.1f"%(UseList[hist]['Mustrain'][1][pid])) #reset in case of error 7765 G2plt.PlotSizeStrainPO(G2frame,data) 7766 7767 def OnStrainAxis(event): 7768 Obj = event.GetEventObject() 7769 hist = Indx[Obj.GetId()] 7770 Saxis = Obj.GetValue().split() 7771 try: 7772 hkl = [int(Saxis[i]) for i in range(3)] 7773 except (ValueError,IndexError): 7774 hkl = UseList[hist]['Mustrain'][3] 7775 if not np.any(np.array(hkl)): 7776 hkl = UseList[hist]['Mustrain'][3] 7777 UseList[hist]['Mustrain'][3] = hkl 7778 h,k,l = hkl 7779 Obj.SetValue('%3d %3d %3d'%(h,k,l)) 7780 G2plt.PlotSizeStrainPO(G2frame,data) 7781 7782 def OnHstrainRef(event): 7783 Obj = event.GetEventObject() 7784 hist,pid = Indx[Obj.GetId()] 7785 UseList[hist]['HStrain'][1][pid] = Obj.GetValue() 7786 7787 def OnHstrainVal(event): 7788 Snames = G2spc.HStrainNames(SGData) 7789 Obj = event.GetEventObject() 7790 hist,pid = Indx[Obj.GetId()] 7791 try: 7792 strain = float(Obj.GetValue()) 7793 UseList[hist]['HStrain'][0][pid] = strain 7794 except ValueError: 7795 pass 7796 Obj.SetValue("%.5f"%(UseList[hist]['HStrain'][0][pid])) #reset in case of error 7797 7798 def OnPOVal(event): 7799 Obj = event.GetEventObject() 7800 hist = Indx[Obj.GetId()] 7801 try: 7802 mdVal = float(Obj.GetValue()) 7803 if mdVal > 0: 7804 UseList[hist]['Pref.Ori.'][1] = mdVal 7805 except ValueError: 7806 pass 7807 Obj.SetValue("%.3f"%(UseList[hist]['Pref.Ori.'][1])) #reset in case of error 7808 7809 def OnPOAxis(event): 7810 Obj = event.GetEventObject() 7811 hist = Indx[Obj.GetId()] 7812 Saxis = Obj.GetValue().split() 7813 try: 7814 hkl = [int(Saxis[i]) for i in range(3)] 7815 except (ValueError,IndexError): 7816 hkl = UseList[hist]['Pref.Ori.'][3] 7817 if not np.any(np.array(hkl)): 7818 hkl = UseList[hist]['Pref.Ori.'][3] 7819 UseList[hist]['Pref.Ori.'][3] = hkl 7820 h,k,l = hkl 7821 Obj.SetValue('%3d %3d %3d'%(h,k,l)) 7822 7823 def OnPOOrder(event): 7824 Obj = event.GetEventObject() 7825 hist = Indx[Obj.GetId()] 7826 Order = int(Obj.GetValue()) 7827 UseList[hist]['Pref.Ori.'][4] = Order 7828 UseList[hist]['Pref.Ori.'][5] = SetPOCoef(Order,hist) 7829 wx.CallAfter(UpdateDData) 7830 7831 def OnPOType(event): 7832 Obj = event.GetEventObject() 7833 hist = Indx[Obj.GetId()] 7834 if 'March' in Obj.GetValue(): 7835 UseList[hist]['Pref.Ori.'][0] = 'MD' 7836 else: 7837 UseList[hist]['Pref.Ori.'][0] = 'SH' 7838 wx.CallAfter(UpdateDData) 7839 7840 def OnPORef(event): 7841 Obj = event.GetEventObject() 7842 hist = Indx[Obj.GetId()] 7843 UseList[hist]['Pref.Ori.'][2] = Obj.GetValue() 7844 7845 def SetPOCoef(Order,hist): 7846 cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',Order,False) #cylindrical & no M 7847 newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames)))) 7848 POCoeff = UseList[hist]['Pref.Ori.'][5] 7849 for cofName in POCoeff: 7850 if cofName in cofNames: 7851 newPOCoef[cofName] = POCoeff[cofName] 7852 return newPOCoef 7853 7854 def OnExtRef(event): 7855 Obj = event.GetEventObject() 7856 UseList[Indx[Obj.GetId()]]['Extinction'][1] = Obj.GetValue() 7857 7858 def OnExtVal(event): 7859 Obj = event.GetEventObject() 7860 try: 7861 ext = float(Obj.GetValue()) 7862 if ext >= 0: 7863 UseList[Indx[Obj.GetId()]]['Extinction'][0] = ext 7864 except ValueError: 7865 pass 7866 Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][0])) 7867 7868 def OnTbarVal(event): 7869 Obj = event.GetEventObject() 7870 try: 7871 tbar = float(Obj.GetValue()) 7872 if tbar >= 0: 7873 UseList[Indx[Obj.GetId()]]['Extinction'][2]['Tbar'] = tbar 7874 except ValueError: 7875 pass 7876 Obj.SetValue("%.2f"%(UseList[Indx[Obj.GetId()]]['Extinction'][2]['Tbar'])) 7877 7878 def OnEval(event): 7879 Obj = event.GetEventObject() 7880 item = Indx[Obj.GetId()] 7881 try: 7882 val = float(Obj.GetValue()) 7883 if val >= 0: 7884 UseList[item[0]]['Extinction'][2][item[1]][0] = val 7885 except ValueError: 7886 pass 7887 Obj.SetValue("%9.3g"%(UseList[item[0]]['Extinction'][2][item[1]][0])) 7888 7889 def OnEref(event): 7890 Obj = event.GetEventObject() 7891 item = Indx[Obj.GetId()] 7892 UseList[item[0]]['Extinction'][2][item[1]][1] = Obj.GetValue() 7893 7894 def OnSCExtType(event): 7895 Obj = event.GetEventObject() 7896 item = Indx[Obj.GetId()] 7897 UseList[item[0]]['Extinction'][item[1]] = Obj.GetValue() 7898 wx.CallAfter(UpdateDData) 7899 7900 def checkAxis(axis): 7901 if not np.any(np.array(axis)): 7902 return False 7903 return axis 7904 7905 def TopSizer(name,choices,parm,OnType): 7906 topSizer = wx.BoxSizer(wx.HORIZONTAL) 7907 topSizer.Add(wx.StaticText(DData,1,name),0,wx.ALIGN_CENTER_VERTICAL) 7908 sizeType = wx.ComboBox(DData,wx.ID_ANY,value=UseList[item][parm][0],choices=choices, 7909 style=wx.CB_READONLYwx.CB_DROPDOWN) 7910 sizeType.Bind(wx.EVT_COMBOBOX, OnType) 7911 Indx[sizeType.GetId()] = item 7912 topSizer.Add(sizeType) 7913 topSizer.Add((5,0),0) 7914 return topSizer 7915 7916 def LGmixSizer(name,OnVal,OnRef): 7917 lgmixSizer = wx.BoxSizer(wx.HORIZONTAL) 7918 lgmixRef = wx.CheckBox(DData,1,label='LGmix') 7919 lgmixRef.thisown = False 7920 lgmixRef.SetValue(UseList[item][name][2][2]) 7921 Indx[lgmixRef.GetId()] = [item,name] 7922 lgmixRef.Bind(wx.EVT_CHECKBOX, OnRef) 7923 lgmixSizer.Add(lgmixRef,0,wx.ALIGN_CENTER_VERTICAL) 7924 lgmixVal = wx.TextCtrl(DData,wx.ID_ANY, 7925 '%.4f'%(UseList[item][name][1][2]),style=wx.TE_PROCESS_ENTER) 7926 Indx[lgmixVal.GetId()] = [item,name] 7927 lgmixVal.Bind(wx.EVT_TEXT_ENTER,OnVal) 7928 lgmixVal.Bind(wx.EVT_KILL_FOCUS,OnVal) 7929 lgmixSizer.Add(lgmixVal,0,wx.ALIGN_CENTER_VERTICAL) 7930 return lgmixSizer 7931 7932 def IsoSizer(name,parm,fmt,OnVal,OnRef): 7933 isoSizer = wx.BoxSizer(wx.HORIZONTAL) 7934 sizeRef = wx.CheckBox(DData,1,label=name) 7935 sizeRef.thisown = False 7936 sizeRef.SetValue(UseList[item][parm][2][0]) 7937 Indx[sizeRef.GetId()] = [item,0] 7938 sizeRef.Bind(wx.EVT_CHECKBOX, OnRef) 7939 isoSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL) 7940 sizeVal = wx.TextCtrl(DData,wx.ID_ANY, 7941 fmt%(UseList[item][parm][1][0]),style=wx.TE_PROCESS_ENTER) 7942 Indx[sizeVal.GetId()] = [item,0] 7943 sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal) 7944 sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal) 7945 isoSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL) 7946 return isoSizer 7947 7948 def UniSizer(parm,OnAxis): 7949 uniSizer = wx.BoxSizer(wx.HORIZONTAL) 7950 uniSizer.Add(wx.StaticText(DData,1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL) 7951 h,k,l = UseList[item][parm][3] 7952 Axis = wx.TextCtrl(DData,1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER) 7953 Indx[Axis.GetId()] = item 7954 Axis.Bind(wx.EVT_TEXT_ENTER,OnAxis) 7955 Axis.Bind(wx.EVT_KILL_FOCUS,OnAxis) 7956 uniSizer.Add(Axis,0,wx.ALIGN_CENTER_VERTICAL) 7957 return uniSizer 7958 7959 def UniDataSizer(parmName,parm,fmt,OnVal,OnRef): 7960 dataSizer = wx.BoxSizer(wx.HORIZONTAL) 7961 parms = zip([' Equatorial '+parmName,' Axial '+parmName], 7962 UseList[item][parm][1],UseList[item][parm][2],range(2)) 7963 for Pa,val,ref,id in parms: 7964 sizeRef = wx.CheckBox(DData,1,label=Pa) 7965 sizeRef.thisown = False 7966 sizeRef.SetValue(ref) 7967 Indx[sizeRef.GetId()] = [item,id] 7968 sizeRef.Bind(wx.EVT_CHECKBOX, OnRef) 7969 dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL) 7970 sizeVal = wx.TextCtrl(DData,wx.ID_ANY,fmt%(val),style=wx.TE_PROCESS_ENTER) 7971 Indx[sizeVal.GetId()] = [item,id] 7972 sizeVal.Bind(wx.EVT_TEXT_ENTER,OnVal) 7973 sizeVal.Bind(wx.EVT_KILL_FOCUS,OnVal) 7974 dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL) 7975 dataSizer.Add((5,0),0) 7976 return dataSizer 7977 7978 def EllSizeDataSizer(): 7979 parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[item]['Size'][4], 7980 UseList[item]['Size'][5],range(6)) 7981 dataSizer = wx.FlexGridSizer(1,6,5,5) 7982 for Pa,val,ref,id in parms: 7983 sizeRef = wx.CheckBox(DData,1,label=Pa) 7984 sizeRef.thisown = False 7985 sizeRef.SetValue(ref) 7986 Indx[sizeRef.GetId()] = [item,id] 7987 sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef) 7988 dataSizer.Add(sizeRef,0,wx.ALIGN_CENTER_VERTICAL) 7989 sizeVal = wx.TextCtrl(DData,wx.ID_ANY,'%.3f'%(val),style=wx.TE_PROCESS_ENTER) 7990 Indx[sizeVal.GetId()] = [item,id] 7991 sizeVal.Bind(wx.EVT_TEXT_ENTER,OnSizeVal) 7992 sizeVal.Bind(wx.EVT_KILL_FOCUS,OnSizeVal) 7993 dataSizer.Add(sizeVal,0,wx.ALIGN_CENTER_VERTICAL) 7994 return dataSizer 7995 7996 def GenStrainDataSizer(): 7997 Snames = G2spc.MustrainNames(SGData) 7998 numb = len(Snames) 7999 if len(UseList[item]['Mustrain'][4]) < numb: 8000 UseList[item]['Mustrain'][4] = numb*[0.0,] 8001 UseList[item]['Mustrain'][5] = numb*[False,] 8002 parms = zip(Snames,UseList[item]['Mustrain'][4],UseList[item]['Mustrain'][5],range(numb)) 8003 dataSizer = wx.FlexGridSizer(1,6,5,5) 8004 for Pa,val,ref,id in parms: 8005 strainRef = wx.CheckBox(DData,1,label=Pa) 8006 strainRef.thisown = False 8007 strainRef.SetValue(ref) 8008 Indx[strainRef.GetId()] = [item,id] 8009 strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef) 8010 dataSizer.Add(strainRef,0,wx.ALIGN_CENTER_VERTICAL) 8011 strainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER) 8012 Indx[strainVal.GetId()] = [item,id] 8013 strainVal.Bind(wx.EVT_TEXT_ENTER,OnStrainVal) 8014 strainVal.Bind(wx.EVT_KILL_FOCUS,OnStrainVal) 8015 dataSizer.Add(strainVal,0,wx.ALIGN_CENTER_VERTICAL) 8016 return dataSizer 8017 8018 def HstrainSizer(): 8019 hstrainSizer = wx.FlexGridSizer(1,6,5,5) 8020 Hsnames = G2spc.HStrainNames(SGData) 8021 parms = zip(Hsnames,UseList[item]['HStrain'][0],UseList[item]['HStrain'][1],range(len(Hsnames))) 8022 for Pa,val,ref,id in parms: 8023 hstrainRef = wx.CheckBox(DData,1,label=Pa) 8024 hstrainRef.thisown = False 8025 hstrainRef.SetValue(ref) 8026 Indx[hstrainRef.GetId()] = [item,id] 8027 hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef) 8028 hstrainSizer.Add(hstrainRef,0,wx.ALIGN_CENTER_VERTICAL) 8029 hstrainVal = wx.TextCtrl(DData,wx.ID_ANY,'%.5f'%(val),style=wx.TE_PROCESS_ENTER) 8030 Indx[hstrainVal.GetId()] = [item,id] 8031 hstrainVal.Bind(wx.EVT_TEXT_ENTER,OnHstrainVal) 8032 hstrainVal.Bind(wx.EVT_KILL_FOCUS,OnHstrainVal) 8033 hstrainSizer.Add(hstrainVal,0,wx.ALIGN_CENTER_VERTICAL) 8034 return hstrainSizer 8035 8036 def PoTopSizer(POData): 8037 poSizer = wx.FlexGridSizer(1,6,5,5) 8038 choice = ['MarchDollase','Spherical harmonics'] 8039 POtype = choice[['MD','SH'].index(POData[0])] 8040 poSizer.Add(wx.StaticText(DData,1,' Preferred orientation model '),0,wx.ALIGN_CENTER_VERTICAL) 8041 POType = wx.ComboBox(DData,wx.ID_ANY,value=POtype,choices=choice, 8042 style=wx.CB_READONLYwx.CB_DROPDOWN) 8043 Indx[POType.GetId()] = item 8044 POType.Bind(wx.EVT_COMBOBOX, OnPOType) 8045 poSizer.Add(POType) 8046 if POData[0] == 'SH': 8047 poSizer.Add(wx.StaticText(DData,1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL) 8048 poOrder = wx.ComboBox(DData,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)], 8049 style=wx.CB_READONLYwx.CB_DROPDOWN) 8050 Indx[poOrder.GetId()] = item 8051 poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder) 8052 poSizer.Add(poOrder,0,wx.ALIGN_CENTER_VERTICAL) 8053 poRef = wx.CheckBox(DData,1,label=' Refine? ') 8054 poRef.SetValue(POData[2]) 8055 Indx[poRef.GetId()] = item 8056 poRef.Bind(wx.EVT_CHECKBOX,OnPORef) 8057 poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL) 8058 return poSizer 8059 8060 def MDDataSizer(POData): 8061 poSizer = wx.BoxSizer(wx.HORIZONTAL) 8062 poRef = wx.CheckBox(DData,1,label=' MarchDollase ratio: ') 8063 poRef.SetValue(POData[2]) 8064 Indx[poRef.GetId()] = item 8065 poRef.Bind(wx.EVT_CHECKBOX,OnPORef) 8066 poSizer.Add(poRef,0,wx.ALIGN_CENTER_VERTICAL) 8067 poVal = wx.TextCtrl(DData,wx.ID_ANY, 8068 '%.3f'%(POData[1]),style=wx.TE_PROCESS_ENTER) 8069 Indx[poVal.GetId()] = item 8070 poVal.Bind(wx.EVT_TEXT_ENTER,OnPOVal) 8071 poVal.Bind(wx.EVT_KILL_FOCUS,OnPOVal) 8072 poSizer.Add(poVal,0,wx.ALIGN_CENTER_VERTICAL) 8073 poSizer.Add(wx.StaticText(DData,1,' Unique axis, H K L: '),0,wx.ALIGN_CENTER_VERTICAL) 8074 h,k,l =POData[3] 8075 poAxis = wx.TextCtrl(DData,1,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER) 8076 Indx[poAxis.GetId()] = item 8077 poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis) 8078 poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis) 8079 poSizer.Add(poAxis,0,wx.ALIGN_CENTER_VERTICAL) 8080 return poSizer 8081 8082 def SHDataSizer(POData): 8083 textJ = G2lat.textureIndex(POData[5]) 8084 mainSizer.Add(wx.StaticText(DData,1,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ)),0,wx.ALIGN_CENTER_VERTICAL) 8085 mainSizer.Add((0,5),0) 8086 ODFSizer = wx.FlexGridSizer(2,8,2,2) 8087 ODFIndx = {} 8088 ODFkeys = POData[5].keys() 8089 ODFkeys.sort() 8090 for odf in ODFkeys: 8091 ODFSizer.Add(wx.StaticText(DData,1,odf),0,wx.ALIGN_CENTER_VERTICAL) 8092 ODFval = wx.TextCtrl(DData,wx.ID_ANY,'%8.3f'%(POData[5][odf]),style=wx.TE_PROCESS_ENTER) 8093 ODFIndx[ODFval.GetId()] = odf 8094 # ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue) 8095 # ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue) 8096 ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL) 8097 return ODFSizer 8098 8099 def ExtSizer(): 8100 extSizer = wx.BoxSizer(wx.HORIZONTAL) 8101 extRef = wx.CheckBox(DData,1,label=' Extinction: ') 8102 extRef.SetValue(UseList[item]['Extinction'][1]) 8103 Indx[extRef.GetId()] = item 8104 extRef.Bind(wx.EVT_CHECKBOX, OnExtRef) 8105 extSizer.Add(extRef,0,wx.ALIGN_CENTER_VERTICAL) 8106 extVal = wx.TextCtrl(DData,wx.ID_ANY, 8107 '%.2f'%(UseList[item]['Extinction'][0]),style=wx.TE_PROCESS_ENTER) 8108 Indx[extVal.GetId()] = item 8109 extVal.Bind(wx.EVT_TEXT_ENTER,OnExtVal) 8110 extVal.Bind(wx.EVT_KILL_FOCUS,OnExtVal) 8111 extSizer.Add(extVal,0,wx.ALIGN_CENTER_VERTICAL) 8112 return extSizer 8113 8114 def SCExtSizer(): 8115 extSizer = wx.BoxSizer(wx.VERTICAL) 8116 typeSizer = wx.BoxSizer(wx.HORIZONTAL) 8117 typeSizer.Add(wx.StaticText(DData,1,' Extinction type: '),0,wx.ALIGN_CENTER_VERTICAL) 8118 Choices = ['Primary','Secondary Type I','Secondary Type II','Secondary Type I & II'] 8119 typeTxt = wx.ComboBox(DData,1,choices=Choices,value=UseList[item]['Extinction'][1], 8120 style=wx.CB_READONLYwx.CB_DROPDOWN) 8121 Indx[typeTxt.GetId()] = [item,1] 8122 typeTxt.Bind(wx.EVT_COMBOBOX,OnSCExtType) 8123 typeSizer.Add(typeTxt) 8124 typeSizer.Add(wx.StaticText(DData,1,' Approx: '),0,wx.ALIGN_CENTER_VERTICAL) 8125 Choices=['Lorentzian','Gaussian'] 8126 approxTxT = wx.ComboBox(DData,1,choices=Choices,value=UseList[item]['Extinction'][0], 8127 style=wx.CB_READONLYwx.CB_DROPDOWN) 8128 Indx[approxTxT.GetId()] = [item,0] 8129 approxTxT.Bind(wx.EVT_COMBOBOX,OnSCExtType) 8130 typeSizer.Add(approxTxT) 8131 extSizer.Add(typeSizer,0,wx.ALIGN_CENTER_VERTICAL) 8132 extSizer.Add((0,5),) 8133 valSizer =wx.BoxSizer(wx.HORIZONTAL) 8134 valSizer.Add(wx.StaticText(DData,1,' Tbar(mm):'),0,wx.ALIGN_CENTER_VERTICAL) 8135 tbarVal = wx.TextCtrl(DData,wx.ID_ANY, 8136 '%.3f'%(UseList[item]['Extinction'][2]['Tbar']),style=wx.TE_PROCESS_ENTER) 8137 Indx[tbarVal.GetId()] = item 8138 tbarVal.Bind(wx.EVT_TEXT_ENTER,OnTbarVal) 8139 tbarVal.Bind(wx.EVT_KILL_FOCUS,OnTbarVal) 8140 valSizer.Add(tbarVal,0,wx.ALIGN_CENTER_VERTICAL) 8141 if 'Primary' in UseList[item]['Extinction'][1]: 8142 Ekey = ['Ep',] 8143 elif 'Secondary Type II' == UseList[item]['Extinction'][1]: 8144 Ekey = ['Es',] 8145 elif 'Secondary Type I' == UseList[item]['Extinction'][1]: 8146 Ekey = ['Eg',] 8147 else: 8148 Ekey = ['Eg','Es'] 8149 for ekey in Ekey: 8150 Eref = wx.CheckBox(DData,1,label=ekey+' : ') 8151 Eref.SetValue(UseList[item]['Extinction'][2][ekey][1]) 8152 Indx[Eref.GetId()] = [item,ekey] 8153 Eref.Bind(wx.EVT_CHECKBOX, OnEref) 8154 valSizer.Add(Eref,0,wx.ALIGN_CENTER_VERTICAL) 8155 Eval = wx.TextCtrl(DData,wx.ID_ANY, 8156 '%9.3g'%(UseList[item]['Extinction'][2][ekey][0]),style=wx.TE_PROCESS_ENTER) 8157 Indx[Eval.GetId()] = [item,ekey] 8158 Eval.Bind(wx.EVT_TEXT_ENTER,OnEval) 8159 Eval.Bind(wx.EVT_KILL_FOCUS,OnEval) 8160 valSizer.Add(Eval,0,wx.ALIGN_CENTER_VERTICAL) 8161 8162 extSizer.Add(valSizer,0,wx.ALIGN_CENTER_VERTICAL) 8163 return extSizer 8164 8165 if DData.GetSizer(): 8166 DData.GetSizer().Clear(True) 8167 mainSizer = wx.BoxSizer(wx.VERTICAL) 8168 mainSizer.Add(wx.StaticText(DData,1,'Histogram data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL) 8169 if PWDR: 8170 mainSizer.Add(PlotSizer()) 8171 8172 for item in keyList: 8173 histData = UseList[item] 8174 if 'Use' not in UseList[item]: #patch 8175 UseList[item]['Use'] = True 8176 showSizer = wx.BoxSizer(wx.HORIZONTAL) 8177 showData = wx.CheckBox(DData,1,label=' Show '+item) 8178 showData.SetValue(UseList[item]['Show']) 8179 Indx[showData.GetId()] = item 8180 showData.Bind(wx.EVT_CHECKBOX, OnShowData) 8181 showSizer.Add(showData,0,wx.ALIGN_CENTER_VERTICAL) 8182 useData = wx.CheckBox(DData,1,label='Use?') 8183 Indx[useData.GetId()] = item 8184 showSizer.Add(useData,0,wx.ALIGN_CENTER_VERTICAL) 8185 useData.Bind(wx.EVT_CHECKBOX, OnUseData) 8186 useData.SetValue(UseList[item]['Use']) 8187 copyData = wx.Button(DData,1,label=' Copy?') 8188 Indx[copyData.GetId()] = item 8189 copyData.Bind(wx.EVT_BUTTON,OnCopyData) 8190 showSizer.Add(copyData,wx.ALIGN_CENTER_VERTICAL) 8191 copyFlags = wx.Button(DData,1,label=' Copy flags?') 8192 Indx[copyFlags.GetId()] = item 8193 copyFlags.Bind(wx.EVT_BUTTON,OnCopyFlags) 8194 showSizer.Add(copyFlags,wx.ALIGN_CENTER_VERTICAL) 8195 mainSizer.Add((5,5),0) 8196 mainSizer.Add(showSizer,0,wx.ALIGN_CENTER_VERTICAL) 8197 mainSizer.Add((0,5),0) 8198 8199 if UseList[item]['Show']: 8200 mainSizer.Add(ScaleSizer()) 8201 mainSizer.Add((0,5),0) 8202 8203 if item[:4] == 'PWDR' and UseList[item]['Show']: 8204 if UseList[item]['Size'][0] == 'isotropic': 8205 isoSizer = wx.BoxSizer(wx.HORIZONTAL) 8206 isoSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'], 8207 'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL) 8208 isoSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef)) 8209 mainSizer.Add(isoSizer) 8210 mainSizer.Add(IsoSizer(u' Cryst. size(\xb5m): ','Size','%.3f', 8211 OnSizeVal,OnSizeRef),0,wx.ALIGN_CENTER_VERTICAL) 8212 elif UseList[item]['Size'][0] == 'uniaxial': 8213 uniSizer = wx.BoxSizer(wx.HORIZONTAL) 8214 uniSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'], 8215 'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL) 8216 uniSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef)) 8217 uniSizer.Add(UniSizer('Size',OnSizeAxis),0,wx.ALIGN_CENTER_VERTICAL) 8218 mainSizer.Add(uniSizer) 8219 mainSizer.Add(UniDataSizer(u'size(\xb5m): ','Size','%.3f',OnSizeVal,OnSizeRef)) 8220 elif UseList[item]['Size'][0] == 'ellipsoidal': 8221 ellSizer = wx.BoxSizer(wx.HORIZONTAL) 8222 ellSizer.Add(TopSizer(' Size model: ',['isotropic','uniaxial','ellipsoidal'], 8223 'Size',OnSizeType),0,wx.ALIGN_CENTER_VERTICAL) 8224 ellSizer.Add(LGmixSizer('Size',OnLGmixVal,OnLGmixRef)) 8225 mainSizer.Add(ellSizer) 8226 mainSizer.Add(EllSizeDataSizer()) 8227 mainSizer.Add((0,5),0) 8228 8229 if UseList[item]['Mustrain'][0] == 'isotropic': 8230 isoSizer = wx.BoxSizer(wx.HORIZONTAL) 8231 isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',], 8232 'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL) 8233 isoSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef)) 8234 mainSizer.Add(isoSizer) 8235 mainSizer.Add(IsoSizer(' microstrain: ','Mustrain','%.1f', 8236 OnStrainVal,OnStrainRef),0,wx.ALIGN_CENTER_VERTICAL) 8237 mainSizer.Add((0,5),0) 8238 elif UseList[item]['Mustrain'][0] == 'uniaxial': 8239 uniSizer = wx.BoxSizer(wx.HORIZONTAL) 8240 uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',], 8241 'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL) 8242 uniSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef)) 8243 uniSizer.Add(UniSizer('Mustrain',OnStrainAxis),0,wx.ALIGN_CENTER_VERTICAL) 8244 mainSizer.Add(uniSizer) 8245 mainSizer.Add(UniDataSizer('mustrain: ','Mustrain','%.1f',OnStrainVal,OnStrainRef)) 8246 elif UseList[item]['Mustrain'][0] == 'generalized': 8247 genSizer = wx.BoxSizer(wx.HORIZONTAL) 8248 genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',], 8249 'Mustrain',OnStrainType),0,wx.ALIGN_CENTER_VERTICAL) 8250 genSizer.Add(LGmixSizer('Mustrain',OnLGmixVal,OnLGmixRef)) 8251 mainSizer.Add(genSizer) 8252 mainSizer.Add(GenStrainDataSizer()) 8253 mainSizer.Add((0,5),0) 8254 8255 mainSizer.Add(wx.StaticText(DData,1,' Hydrostatic/elastic strain:')) 8256 mainSizer.Add(HstrainSizer()) 8257 8258 #texture 'Pref. Ori.':['MD',1.0,False,[0,0,1],0,[]] last two for 'SH' are SHorder & coeff 8259 poSizer = wx.BoxSizer(wx.VERTICAL) 8260 POData = UseList[item]['Pref.Ori.'] 8261 poSizer.Add(PoTopSizer(POData)) 8262 if POData[0] == 'MD': 8263 poSizer.Add(MDDataSizer(POData)) 8264 else: #'SH' 8265 if POData[4]: #SH order > 0 8266 poSizer.Add(SHDataSizer(POData)) 8267 8268 mainSizer.Add(poSizer) 8269 mainSizer.Add((0,5),0) 8270 #Extinction 'Extinction':[0.0,False] 8271 mainSizer.Add(ExtSizer()) 8272 mainSizer.Add((0,5),0) 8273 elif item[:4] == 'HKLF' and UseList[item]['Show']: 8274 mainSizer.Add((0,5),0) 8275 mainSizer.Add(SCExtSizer()) 8276 mainSizer.Add((0,5),0) 8277 pass 8278 mainSizer.Add((5,5),0) 8279 8280 DData.SetSizer(mainSizer,True) 8281 mainSizer.FitInside(G2frame.dataFrame) 8282 Size = mainSizer.GetMinSize() 8283 Size[0] += 40 8284 Size[1] = max(Size[1],290) + 35 8285 DData.SetSize(Size) 8286 DData.SetScrollbars(10,10,Size[0]/104,Size[1]/101) 8287 Size[1] = min(Size[1],450) 8288 G2frame.dataFrame.setSizePosLeft(Size) 8289 8290 def OnHklfAdd(event): 8291 UseList = data['Histograms'] 8292 keyList = UseList.keys() 8293 TextList = [] 8294 if G2frame.PatternTree.GetCount(): 8295 item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) 8296 while item: 8297 name = G2frame.PatternTree.GetItemText(item) 8298 if name not in keyList and 'HKLF' in name: 8299 TextList.append(name) 8300 item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) 8301 dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE) 8302 try: 8303 if dlg.ShowModal() == wx.ID_OK: 8304 result = dlg.GetSelections() 8305 for i in result: 8306 histoName = TextList[i] 8307 UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True], 8308 'Extinction':['Lorentzian','Secondary Type I', 8309 {'Tbar':0.0,'Eg':[0.0,False],'Es':[0.0,False],'Ep':[0.0,False]},]} 8310 data['Histograms'] = UseList 8311 wx.BeginBusyCursor() 8312 UpdateHKLFdata(histoName) 8313 wx.EndBusyCursor() 8314 wx.CallAfter(UpdateDData) 8315 finally: 8316 dlg.Destroy() 8317 8318 def UpdateHKLFdata(histoName): 8319 generalData = data['General'] 8320 Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName) 8321 reflData = G2frame.PatternTree.GetItemPyData(Id)[1] 8322 SGData = generalData['SGData'] 8323 Cell = generalData['Cell'][1:7] 8324 G,g = G2lat.cell2Gmat(Cell) 8325 for ref in reflData: 8326 H = ref[:3] 8327 ref[4] = np.sqrt(1./G2lat.calc_rDsq2(H,G)) 8328 iabsnt,ref[3],ref[11],ref[12] = G2spc.GenHKLf(H,SGData) 8329 G2frame.PatternTree.SetItemPyData(Id,[histoName,reflData]) 8330 8331 def OnPwdrAdd(event): 8332 generalData = data['General'] 8333 SGData = generalData['SGData'] 8334 UseList = data['Histograms'] 8335 newList = [] 8336 NShkl = len(G2spc.MustrainNames(SGData)) 8337 NDij = len(G2spc.HStrainNames(SGData)) 8338 keyList = UseList.keys() 8339 TextList = ['All PWDR'] 8340 if G2frame.PatternTree.GetCount(): 8341 item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) 8342 while item: 8343 name = G2frame.PatternTree.GetItemText(item) 8344 if name not in keyList and 'PWDR' in name: 8345 TextList.append(name) 8346 item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) 8347 dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE) 8348 try: 8349 if dlg.ShowModal() == wx.ID_OK: 8350 result = dlg.GetSelections() 8351 for i in result: newList.append(TextList[i]) 8352 if 'All PWDR' in newList: 8353 newList = TextList[1:] 8354 for histoName in newList: 8355 pId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName) 8356 UseList[histoName] = {'Histogram':histoName,'Show':False, 8357 'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}], 8358 'Size':['isotropic',[4.,4.,1.0],[False,False,False],[0,0,1], 8359 [4.,4.,4.,0.,0.,0.],6*[False,]], 8360 'Mustrain':['isotropic',[1000.0,1000.0,1.0],[False,False,False],[0,0,1], 8361 NShkl*[0.01,],NShkl*[False,]], 8362 'HStrain':[NDij*[0.0,],NDij*[False,]], 8363 'Extinction':[0.0,False]} 8364 refList = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,pId,'Reflection Lists')) 8365 refList[generalData['Name']] = [] 8366 data['Histograms'] = UseList 8367 wx.CallAfter(UpdateDData) 8368 finally: 8369 dlg.Destroy() 8370 8371 def OnDataDelete(event): 8372 UseList = data['Histograms'] 8373 keyList = ['All',]+UseList.keys() 8374 keyList.sort() 8375 DelList = [] 8376 if UseList: 8377 DelList = [] 8378 dlg = wx.MultiChoiceDialog(G2frame, 8379 'Which histogram to delete from this phase?', 'Delete histogram', 8380 keyList, wx.CHOICEDLG_STYLE) 8381 try: 8382 if dlg.ShowModal() == wx.ID_OK: 8383 result = dlg.GetSelections() 8384 for i in result: 8385 DelList.append(keyList[i]) 8386 if 'All' in DelList: 8387 DelList = keyList[1:] 8388 for i in DelList: 8389 del UseList[i] 8390 wx.CallAfter(UpdateDData) 8391 finally: 8392 dlg.Destroy() 8393 8394 ################################################################################ 8395 ##### Pawley routines 8396 ################################################################################ 8397 8398 def FillPawleyReflectionsGrid(): 8399 G2frame.dataFrame.SetStatusText('') 8400 8401 def KeyEditPawleyGrid(event): 8402 colList = G2frame.PawleyRefl.GetSelectedCols() 8403 PawleyPeaks = data['Pawley ref'] 8404 if event.GetKeyCode() == wx.WXK_RETURN: 8405 event.Skip(True) 8406 elif event.GetKeyCode() == wx.WXK_CONTROL: 8407 event.Skip(True) 8408 elif event.GetKeyCode() == wx.WXK_SHIFT: 8409 event.Skip(True) 8410 elif colList: 8411 G2frame.PawleyRefl.ClearSelection() 8412 key = event.GetKeyCode() 8413 for col in colList: 8414 if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL: 8415 if key == 89: #'Y' 8416 for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True 8417 elif key == 78: #'N' 8418 for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False 8419 FillPawleyReflectionsGrid() 8420 8421 if 'Pawley ref' in data: 8422 PawleyPeaks = data['Pawley ref'] 8423 rowLabels = [] 8424 for i in range(len(PawleyPeaks)): rowLabels.append(str(i)) 8425 colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)'] 8426 Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \ 8427 2*[wg.GRID_VALUE_FLOAT+':10,2',] 8428 PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types) 8429 G2frame.PawleyRefl.SetTable(PawleyTable, True) 8430 G2frame.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid) 8431 for r in range(G2frame.PawleyRefl.GetNumberRows()): 8432 for c in range(G2frame.PawleyRefl.GetNumberCols()): 8433 if c in [5,6]: 8434 G2frame.PawleyRefl.SetReadOnly(r,c,isReadOnly=False) 8435 else: 8436 G2frame.PawleyRefl.SetCellStyle(r,c,VERY_LIGHT_GREY,True) 8437 G2frame.PawleyRefl.SetMargins(0,0) 8438 G2frame.PawleyRefl.AutoSizeColumns(False) 8439 G2frame.dataFrame.setSizePosLeft([500,300]) 8440 8441 def OnPawleyLoad(event): 8442 generalData = data['General'] 8443 dmin = generalData['Pawley dmin'] 8444 cell = generalData['Cell'][1:7] 8445 A = G2lat.cell2A(cell) 8446 SGData = generalData['SGData'] 8447 HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A)) 8448 PawleyPeaks = [] 8449 wx.BeginBusyCursor() 8450 try: 8451 for h,k,l,d in HKLd: 8452 ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2] 8453 if not ext: 8454 mul *= 2 #for powder multiplicity 8455 PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0]) 8456 finally: 8457 wx.EndBusyCursor() 8458 data['Pawley ref'] = PawleyPeaks 8459 FillPawleyReflectionsGrid() 8460 8461 def OnPawleyEstimate(event): 8462 try: 8463 Refs = data['Pawley ref'] 8464 Histograms = data['Histograms'] 8465 except KeyError: 8466 print '**** Error  no histograms defined for this phase ****' 8467 return 8468 HistoNames = Histograms.keys() 8469 PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0]) 8470 xdata = G2frame.PatternTree.GetItemPyData(PatternId)[1] 8471 Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Instrument Parameters')) 8472 Inst = dict(zip(Inst[3],Inst[1])) 8473 Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Sample Parameters')) 8474 if 'Lam' in Inst: 8475 wave = Inst['Lam'] 8476 else: 8477 wave = Inst['Lam1'] 8478 posCorr = Inst['Zero'] 8479 const = 9.e2/(np.pi*Sample['Gonio. radius']) #shifts in microns 8480 8481 wx.BeginBusyCursor() 8482 try: 8483 for ref in Refs: 8484 pos = 2.0*asind(wave/(2.0*ref[4])) 8485 if 'Bragg' in Sample['Type']: 8486 pos = const*(4.*Sample['Shift'][0]*cosd(pos/2.0)+ \ 8487 Sample['Transparency'][0]*sind(pos)*100.0) #trans(=1/mueff) in cm 8488 else: #DebyeScherrer  simple but maybe not right 8489 pos = const*(Sample['DisplaceX'][0]*cosd(pos)+Sample['DisplaceY'][0]*sind(pos)) 8490 indx = np.searchsorted(xdata[0],pos) 8491 try: 8492 FWHM = max(0.001,G2pwd.getFWHM(pos,Inst))/2. 8493 dx = xdata[0][indx+1]xdata[0][indx] 8494 ref[6] = FWHM*(xdata[1][indx]xdata[4][indx])*cosd(pos/2.)**3/dx 8495 Lorenz = 1./(2.*sind(xdata[0][indx]/2.)**2*cosd(xdata[0][indx]/2.)) #Lorentz correction 8496 pola,dIdPola = G2pwd.Polarization(Inst['Polariz.'],xdata[0][indx],Inst['Azimuth']) 8497 ref[6] /= (Lorenz*pola*ref[3]) 8498 except IndexError: 8499 pass 8500 finally: 8501 wx.EndBusyCursor() 8502 FillPawleyReflectionsGrid() 8503 8504 def OnPawleyUpdate(event): 8505 try: 8506 Refs = data['Pawley ref'] 8507 Histograms = data['Histograms'] 8508 except KeyError: 8509 print '**** Error  no histograms defined for this phase ****' 8510 return 8511 HistoNames = Histograms.keys() 8512 PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0]) 8513 refData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))[PhaseName] 8514 wx.BeginBusyCursor() 8515 try: 8516 for iref,ref in enumerate(Refs): 8517 try: 8518 ref[6] = abs(refData[iref][9]) 8519 ref[7] = 1.0 8520 except IndexError: 8521 pass 8522 finally: 8523 wx.EndBusyCursor() 8524 FillPawleyReflectionsGrid() 8525 8526 def OnPawleyDelete(event): #doesn't work 8527 dlg = wx.MessageDialog(G2frame,'Do you really want to delete selected Pawley reflections?','Delete', 8528 wx.YES_NO  wx.ICON_QUESTION) 8529 try: 8530 result = dlg.ShowModal() 8531 if result == wx.ID_YES: 8532 Refs = data['Pawley ref'] 8533 Ind = G2frame.PawleyRefl.GetSelectedRows() 8534 Ind.sort() 8535 Ind.reverse() 8536 for ind in Ind: 8537 Refs = np.delete(Refs,ind,0) 8538 data['Pawley ref'] = Refs 8539 FillPawleyReflectionsGrid() 8540 finally: 8541 dlg.Destroy() 8542 8543 ################################################################################ 8544 ##### Fourier routines 8545 ################################################################################ 8546 8547 def FillMapPeaksGrid(): 8548 8549 def RowSelect(event): 8550 r,c = event.GetRow(),event.GetCol() 8551 if r < 0 and c < 0: 8552 if MapPeaks.IsSelection(): 8553 MapPeaks.ClearSelection() 8554 else: 8555 for row in range(MapPeaks.GetNumberRows()): 8556 MapPeaks.SelectRow(row,True) 8557 8558 elif c < 0: #only row clicks 8559 if event.ControlDown(): 8560 if r in MapPeaks.GetSelectedRows(): 8561 MapPeaks.DeselectRow(r) 8562 else: 8563 MapPeaks.SelectRow(r,True) 8564 elif event.ShiftDown(): 8565 for row in range(r+1): 8566 MapPeaks.SelectRow(row,True) 8567 else: 8568 MapPeaks.ClearSelection() 8569 MapPeaks.SelectRow(r,True) 8570 elif r < 0: #a column pick 8571 mapPeaks = data['Map Peaks'] 8572 c = event.GetCol() 8573 if colLabels[c] == 'mag': 8574 mapPeaks = G2mth.sortArray(mapPeaks,0,reverse=True) 8575 elif colLabels[c] == 'dzero': 8576 mapPeaks = G2mth.sortArray(mapPeaks,4) 8577 else: 8578 return 8579 data['Map Peaks'] = mapPeaks 8580 wx.CallAfter(FillMapPeaksGrid) 8581 G2plt.PlotStructure(G2frame,data) 8582 8583 G2frame.dataFrame.setSizePosLeft([450,300]) 8584 G2frame.dataFrame.SetStatusText('') 8585 if 'Map Peaks' in data: 8586 G2frame.dataFrame.SetStatusText('Select mag or dzero columns to sort') 8587 mapPeaks = data['Map Peaks'] 8588 rowLabels = [] 8589 for i in range(len(mapPeaks)): rowLabels.append(str(i)) 8590 colLabels = ['mag','x','y','z','dzero'] 8591 Types = 5*[wg.GRID_VALUE_FLOAT+':10,4',] 8592 G2frame.MapPeaksTable = G2gd.Table(mapPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types) 8593 MapPeaks.SetTable(G2frame.MapPeaksTable, True) 8594 MapPeaks.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect) 8595 for r in range(MapPeaks.GetNumberRows()): 8596 for c in range(MapPeaks.GetNumberCols()): 8597 MapPeaks.SetCellStyle(r,c,VERY_LIGHT_GREY,True) 8598 MapPeaks.SetMargins(0,0) 8599 MapPeaks.AutoSizeColumns(False) 8600 8601 def OnPeaksMove(event): 8602 if 'Map Peaks' in data: 8603 mapPeaks = data['Map Peaks'] 8604 Ind = MapPeaks.GetSelectedRows() 8605 for ind in Ind: 8606 x,y,z,d = mapPeaks[ind][1:] 8607 AtomAdd(x,y,z,'C') 8608 8609 def OnPeaksClear(event): 8610 data['Map Peaks'] = [] 8611 FillMapPeaksGrid() 8612 G2plt.PlotStructure(G2frame,data) 8613 8614 def OnPeaksDelete(event): 8615 if 'Map Peaks' in data: 8616 mapPeaks = data['Map Peaks'] 8617 Ind = MapPeaks.GetSelectedRows() 8618 Ind.sort() 8619 Ind.reverse() 8620 for ind in Ind: 8621 mapPeaks = np.delete(mapPeaks,ind,0) 8622 data['Map Peaks'] = mapPeaks 8623 FillMapPeaksGrid() 8624 G2plt.PlotStructure(G2frame,data) 8625 8626 def OnPeaksUnique(event): 8627 if 'Map Peaks' in data: 8628 mapPeaks = data['Map Peaks'] 8629 Ind = MapPeaks.GetSelectedRows() 8630 if Ind: 8631 wx.BeginBusyCursor() 8632 try: 8633 Ind = G2mth.PeaksUnique(data,Ind) 8634 for r in range(MapPeaks.GetNumberRows()): 8635 if r in Ind: 8636 MapPeaks.SelectRow(r,addToSelected=True) 8637 else: 8638 MapPeaks.DeselectRow(r) 8639 finally: 8640 wx.EndBusyCursor() 8641 G2plt.PlotStructure(G2frame,data) 8642 8643 def OnPeaksViewPoint(event): 8644 # set view point 8645 indx = MapPeaks.GetSelectedRows() 8646 if not indx: 8647 print '***** ERROR  no peaks selected' 8648 return 8649 mapPeaks = data['Map Peaks'] 8650 drawingData = data['Drawing'] 8651 drawingData['viewPoint'][0] = mapPeaks[indx[0]][1:4] 8652 G2plt.PlotStructure(G2frame,data) 8653 8654 def OnPeaksDistVP(event): 8655 # distance to view point 8656 indx = MapPeaks.GetSelectedRows() 8657 if not indx: 8658 print '***** ERROR  no peaks selected' 8659 return 8660 generalData = data['General'] 8661 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 8662 mapPeaks = data['Map Peaks'] 8663 drawingData = data['Drawing'] 8664 viewPt = np.array(drawingData['viewPoint'][0]) 8665 print ' Distance from view point at %.3f %.3f %.3f to:'%(viewPt[0],viewPt[1],viewPt[2]) 8666 colLabels = [MapPeaks.GetColLabelValue(c) for c in range(MapPeaks.GetNumberCols())] 8667 cx = colLabels.index('x') 8668 cm = colLabels.index('mag') 8669 for i in indx: 8670 peak = mapPeaks[i] 8671 Dx = np.array(peak[cx:cx+3])viewPt 8672 dist = np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)) 8673 print 'Peak: %5d mag= %8.2f distance = %.3f'%(i,peak[cm],dist) 8674 8675 def OnPeaksDA(event): 8676 #distance, angle 8677 indx = MapPeaks.GetSelectedRows() 8678 if len(indx) not in [2,3]: 8679 print '**** ERROR  wrong number of atoms for distance or angle calculation' 8680 return 8681 generalData = data['General'] 8682 Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 8683 mapPeaks = data['Map Peaks'] 8684 xyz = [] 8685 for i in indx: 8686 xyz.append(mapPeaks[i][1:4]) 8687 if len(indx) == 2: 8688 print ' distance for atoms %s = %.3f'%(str(indx),G2mth.getRestDist(xyz,Amat)) 8689 else: 8690 print ' angle for atoms %s = %.2f'%(str(indx),G2mth.getRestAngle(xyz,Amat)) 8691 8692 def OnFourierMaps(event): 8693 generalData = data['General'] 8694 mapData = generalData['Map'] 8695 reflName = mapData['RefList'] 8696 phaseName = generalData['Name'] 8697 if 'PWDR' in reflName: 8698 PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) 8699 reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) 8700 reflData = reflSets[phaseName] 8701 elif 'HKLF' in reflName: 8702 PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) 8703 reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1] 8704 mapData.update(G2mth.FourierMap(data,reflData)) 8705 mapData['Flip'] = False 8706 mapSig = np.std(mapData['rho']) 8707 if not data['Drawing']: #if new drawing  no drawing data! 8708 SetupDrawingData() 8709 data['Drawing']['contourLevel'] = 1. 8710 data['Drawing']['mapSize'] = 10. 8711 print mapData['MapType']+' computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig) 8712 UpdateDrawAtoms() 8713 G2plt.PlotStructure(G2frame,data) 8714 8715 def OnFourClear(event): 8716 generalData = data['General'] 8717 generalData['Map'] = mapDefault 8718 G2plt.PlotStructure(G2frame,data) 8719 8720 def printRho(SGLaue,rho,rhoMax): 8721 # map printing for testing purposes 8722 dim = len(rho.shape) 8723 if dim == 2: 8724 ix,jy = rho.shape 8725 for j in range(jy): 8726 line = '' 8727 if SGLaue in ['3','3m1','31m','6/m','6/mmm']: 8728 line += (jyj)*' ' 8729 for i in range(ix): 8730 r = int(100*rho[i,j]/rhoMax) 8731 line += '%4d'%(r) 8732 print line+'\n' 8733 else: 8734 ix,jy,kz = rho.shape 8735 for k in range(kz): 8736 print 'k = ',k 8737 for j in range(jy): 8738 line = '' 8739 if SGLaue in ['3','3m1','31m','6/m','6/mmm']: 8740 line += (jyj)*' ' 8741 for i in range(ix): 8742 r = int(100*rho[i,j,k]/rhoMax) 8743 line += '%4d'%(r) 8744 print line+'\n' 8745 ## keep this 8746 8747 def OnSearchMaps(event): 8748 8749 # def FindBondsPeaks(peaks): #uses numpy & masks  very fast even for proteins! 8750 # import numpy.ma as ma 8751 # Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) 8752 # for peak in peaks: 8753 # peak[1] = [] 8754 # Indx = range(len(peaks)) 8755 # Peaks = [] 8756 # Radii = [] 8757 # for peak in peaks: 8758 # Peaks.append(np.array(peak[1:4])) 8759 # Radii.append(1.0) 8760 # Atoms = np.array(Atoms) 8761 # Radii = np.array(Radii) 8762 # IAR = zip(Indx,Atoms,Radii) 8763 # for atomA in IAR: 8764 # Dx = AtomsatomA[1] 8765 # dist = ma.masked_less(np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)),0.5) #gets rid of G2frame & disorder "bonds" < 0.5A 8766 # sumR = atomA[3]+Radii 8767 # IndB = ma.nonzero(ma.masked_greater(distdata['Drawing']['radiusFactor']*sumR,0.)) #get indices of bonded atoms 8768 # i = atomA[0] 8769 # for j in IndB[0]: 8770 # if Styles[i] == 'polyhedra': 8771 # atomData[i][2].append(np.inner(Amat,Dx[j])) 8772 # elif Styles[j] != 'polyhedra' and j > i: 8773 # atomData[i][2].append(Dx[j]*Radii[i]/sumR[j]) 8774 # atomData[j][2].append(Dx[j]*Radii[j]/sumR[j]) 8775 8776 peaks = [] 8777 mags = [] 8778 print ' Begin fourier map search  can take some time' 8779 time0 = time.time() 8780 generalData = data['General'] 8781 mapData = generalData['Map'] 8782 if len(mapData['rho']): 8783 pgbar = wx.ProgressDialog('Map search','No. Peaks found =',1001.0, 8784 style = wx.PD_ELAPSED_TIMEwx.PD_AUTO_HIDEwx.PD_CAN_ABORT) 8785 screenSize = wx.ClientDisplayRect() 8786 Size = pgbar.GetSize() 8787 Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x 8788 pgbar.SetPosition(wx.Point(screenSize[2]Size[0]305,screenSize[1]+5)) 8789 pgbar.SetSize(Size) 8790 try: 8791 peaks,mags,dzeros = G2mth.SearchMap(data,keepDup=True,Pgbar=pgbar) 8792 finally: 8793 pgbar.Destroy() 8794 sortIdx = np.argsort(mags.flatten()) 8795 if len(peaks): 8796 data['Map Peaks'] = np.concatenate((mags,peaks,dzeros),axis=1) 8797 print ' Map search finished, time = %.2fs'%(time.time()time0) 8798 Page = G2frame.dataDisplay.FindPage('Map peaks') 8799 G2frame.dataDisplay.ChangeSelection(Page) 8800 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.MapPeaksMenu) 8801 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE) 8802 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDA, id=G2gd.wxID_PEAKSDA) 8803 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE) 8804 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE) 8805 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR) 8806 UpdateDrawAtoms() 8807 FillMapPeaksGrid() 8808 else: 8809 print 'No map available' 8810 8811 def OnChargeFlip(event): 8812 generalData = data['General'] 8813 mapData = generalData['Map'] 8814 flipData = generalData['Flip'] 8815 reflName = flipData['RefList'] 8816 phaseName = generalData['Name'] 8817 if 'PWDR' in reflName: 8818 PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) 8819 reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) 8820 reflData = reflSets[phaseName] 8821 elif 'HKLF' in reflName: 8822 PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) 8823 reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1] 8824 else: 8825 print '**** ERROR  No data defined for charge flipping' 8826 return 8827 pgbar = wx.ProgressDialog('Charge flipping','Residual Rcf =',101.0, 8828 style = wx.PD_ELAPSED_TIMEwx.PD_AUTO_HIDEwx.PD_CAN_ABORT) 8829 screenSize = wx.ClientDisplayRect() 8830 Size = pgbar.GetSize() 8831 Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x 8832 pgbar.SetPosition(wx.Point(screenSize[2]Size[0]305,screenSize[1]+5)) 8833 pgbar.SetSize(Size) 8834 try: 8835 mapData.update(G2mth.ChargeFlip(data,reflData,pgbar)) 8836 finally: 8837 pgbar.Destroy() 8838 mapData['Flip'] = True 8839 mapSig = np.std(mapData['rho']) 8840 if not data['Drawing']: #if new drawing  no drawing data! 8841 SetupDrawingData() 8842 data['Drawing']['contourLevel'] = 1. 8843 data['Drawing']['mapSize'] = 10. 8844 print ' Charge flip map computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig) 8845 if mapData['Rcf'] < 99.: 8846 OnSearchMaps(event) #does a plot structure at end 8847 else: 8848 print 'Bad charge flip map  no peak search done' 8849 8850 def OnTextureRefine(event): 8851 print 'refine texture?' 8852 event.Skip() 8853 8854 def OnTextureClear(event): 8855 print 'clear texture?' 8856 event.Skip() 8857 8858 def OnPageChanged(event): 8859 page = event.GetSelection() 8860 text = G2frame.dataDisplay.GetPageText(page) 8861 if text == 'Atoms': 8862 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.AtomsMenu) 8863 G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD) 8864 G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomViewAdd, id=G2gd.wxID_ATOMSVIEWADD) 8865 G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT) 8866 G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomViewInsert, id=G2gd.wxID_ATOMVIEWINSERT) 8867 G2frame.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE) 8868 G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE) 8869 G2frame.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY) 8870 G2frame.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM) 8871 G2frame.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS) 8872 G2frame.dataFrame.Bind(wx.EVT_MENU, OnDistAngle, id=G2gd.wxID_ATOMSDISAGL) 8873 FillAtomsGrid() 8874 elif text == 'General': 8875 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataGeneral) 8876 G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC) 8877 G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH) 8878 G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP) 8879 G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourClear, id=G2gd.wxID_FOURCLEAR) 8880 UpdateGeneral() 8881 elif text == 'Data': 8882 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataMenu) 8883 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD) 8884 G2frame.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD) 8885 G2frame.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE) 8886 UpdateDData() 8887 G2plt.PlotSizeStrainPO(G2frame,data,Start=True) 8888 elif text == 'Draw Options': 8889 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataDrawOptions) 8890 UpdateDrawOptions() 8891 G2plt.PlotStructure(G2frame,data) 8892 elif text == 'Draw Atoms': 8893 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DrawAtomsMenu) 8894 G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE) 8895 G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL) 8896 G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR) 8897 G2frame.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR) 8898 G2frame.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT) 8899 G2frame.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV) 8900 G2frame.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM) 8901 G2frame.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD) 8902 G2frame.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL) 8903 G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE) 8904 G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawDistVP, id=G2gd.wxID_DRAWDISTVP) 8905 G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawDAT, id=G2gd.wxID_DRAWDISAGLTOR) 8906 G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawPlane, id=G2gd.wxID_DRAWPLANE) 8907 G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRBOND) 8908 G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRANGLE) 8909 G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRPLANE) 8910 G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRCHIRAL) 8911 UpdateDrawAtoms() 8912 G2plt.PlotStructure(G2frame,data) 8913 elif text == 'Pawley reflections': 8914 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.PawleyMenu) 8915 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD) 8916 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE) 8917 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyUpdate, id=G2gd.wxID_PAWLEYUPDATE) 8918 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE) 8919 FillPawleyReflectionsGrid() 8920 elif text == 'Texture': 8921 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.TextureMenu) 8922 G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureRefine, id=G2gd.wxID_REFINETEXTURE) 8923 G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureClear, id=G2gd.wxID_CLEARTEXTURE) 8924 UpdateTexture() 8925 G2plt.PlotTexture(G2frame,data,Start=True) 8926 elif text == 'Map peaks': 8927 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.MapPeaksMenu) 8928 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE) 8929 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksViewPoint, id=G2gd.wxID_PEAKSVIEWPT) 8930 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDistVP, id=G2gd.wxID_PEAKSDISTVP) 8931 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDA, id=G2gd.wxID_PEAKSDA) 8932 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE) 8933 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE) 8934 G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR) 8935 FillMapPeaksGrid() 8936 G2plt.PlotStructure(G2frame,data) 8937 8938 else: 8939 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.BlankMenu) 8940 event.Skip() 8941 8942 General = wx.Window(G2frame.dataDisplay) 8943 G2frame.dataDisplay.AddPage(General,'General') 8944 G2frame.dataFrame.SetMenuBar(G2frame.dataFrame.DataGeneral) 8945 G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC) 8946 G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH) 8947 G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP) 8948 G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourClear, id=G2gd.wxID_FOURCLEAR) 8949 SetupGeneral() 8950 GeneralData = data['General'] 8951 UpdateGeneral() 8952 8953 DData = wx.ScrolledWindow(G2frame.dataDisplay) 8954 G2frame.dataDisplay.AddPage(DData,'Data') 8955 Atoms = G2gd.GSGrid(G2frame.dataDisplay) 8956 G2frame.dataDisplay.AddPage(Atoms,'Atoms') 8957 drawOptions = wx.Window(G2frame.dataDisplay) 8958 G2frame.dataDisplay.AddPage(drawOptions,'Draw Options') 8959 drawAtoms = G2gd.GSGrid(G2frame.dataDisplay) 8960 G2frame.dataDisplay.AddPage(drawAtoms,'Draw Atoms') 8961 Texture = wx.ScrolledWindow(G2frame.dataDisplay) 8962 G2frame.dataDisplay.AddPage(Texture,'Texture') 8963 MapPeaks = G2gd.GSGrid(G2frame.dataDisplay) 8964 G2frame.dataDisplay.AddPage(MapPeaks,'Map peaks') 8965 G2frame.PawleyRefl = G2gd.GSGrid(G2frame.dataDisplay) 8966 G2frame.dataDisplay.AddPage(G2frame.PawleyRefl,'Pawley reflections') 8967 8968 G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged) 8969 G2frame.dataDisplay.SetSelection(oldPage) 8970 >>>>>>> .r762
Note: See TracChangeset
for help on using the changeset viewer.