Changeset 764


Ignore:
Timestamp:
Sep 26, 2012 1:43:41 AM (9 years ago)
Author:
vondreele
Message:

messed up - these are the new versions

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIImath.py

    r763 r764  
    1 <<<<<<< .mine
    21# -*- coding: utf-8 -*-
    32#GSASIImath - major mathematics routines
     
    10471046    return Q
    10481047   
    1049 =======
    1050 # -*- coding: utf-8 -*-
    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.49012e-8,xtol=1.49012e-8, 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.e-14,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.e-14)[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 (chisq0-chisq1)/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.e-14)[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,(Tx-Ox))
    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 = VecB-VecA
    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,(TxT-Ox))**2))
    1267        
    1268     inv = Top/abs(Top)
    1269     cent = abs(Top)/100
    1270     op = abs(Top)%100-1
    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,(TxT-Ox))
    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 = VecB-VecA
    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)%100-1
    1314     opB = abs(TopB)%100-1
    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)%100-1]
    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 = V2-V1
    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)%100-1]
    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*P23-P13)/(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)%100-1]
    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 = V2-V1
    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*P23-P13)/(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)%100-1]
    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[M-3]
    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[M-3]:
    1602             sig = sigVals[M-3]
    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.545-math.log10(10*edig(esd)))
    1614    
    1615     mdec = lambda esd: -int(round(math.log10(abs(esd))))+1
    1616     ndec = lambda esd: int(1.545-math.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 'delt-F' 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*Fo-Fc' 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 += (jy-j)*'  '
    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 += (jy-j)*'  '
    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(hkl-hklHalf),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 = H-hkl
    1761             dang = ang-ang0
    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['k-factor']*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)/sumE-np.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    
    1858 def SearchMap(data,keepDup=False,Pgbar=None):
    1859    
    1860     norm = 1./(np.sqrt(3.)*np.sqrt(2.*np.pi)**3)
    1861    
    1862     def noEquivalent(xyz,peaks,SGData):                  #be careful where this is used - it's slow
    1863         equivs = G2spc.GenAtom(xyz,SGData)
    1864         xyzs = [equiv[0] for equiv in equivs]
    1865         for x in xyzs:
    1866             if True in [np.allclose(x,peak,atol=0.02) for peak in peaks]:
    1867                 return False
    1868         return True
    1869        
    1870     def noDuplicate(xyz,peaks,Amat):
    1871         XYZ = np.inner(Amat,xyz)
    1872         if True in [np.allclose(XYZ,np.inner(Amat,peak),atol=0.5) for peak in peaks]:
    1873             print ' Peak',xyz,' <0.5A from another peak'
    1874             return False
    1875         return True
    1876                            
    1877     def fixSpecialPos(xyz,SGData,Amat):
    1878         equivs = G2spc.GenAtom(xyz,SGData,Move=True)
    1879         X = []
    1880         xyzs = [equiv[0] for equiv in equivs]
    1881         for x in xyzs:
    1882             if np.sqrt(np.sum(np.inner(Amat,xyz-x)**2,axis=0))<0.5:
    1883                 X.append(x)
    1884         if len(X) > 1:
    1885             return np.average(X,axis=0)
    1886         else:
    1887             return xyz
    1888        
    1889     def findRoll(rhoMask,mapHalf):
    1890         indx = np.array(ma.nonzero(rhoMask)).T
    1891         rhoList = np.array([rho[i,j,k] for i,j,k in indx])
    1892         rhoMax = np.max(rhoList)
    1893         return mapHalf-indx[np.argmax(rhoList)]
    1894        
    1895     def rhoCalc(parms,rX,rY,rZ,res,SGLaue):
    1896         Mag,x0,y0,z0,sig = parms
    1897 #        if SGLaue in ['3','3m1','31m','6/m','6/mmm']:
    1898 #            return norm*Mag*np.exp(-((x0-rX)**2+(y0-rY)**2+(x0-rX)*(y0-rY)+(z0-rZ)**2)/(2.*sig**2))/(sig*res**3)
    1899 #        else:
    1900 #            return norm*Mag*np.exp(-((x0-rX)**2+(y0-rY)**2+(z0-rZ)**2)/(2.*sig**2))/(sig*res**3)
    1901         return norm*Mag*np.exp(-((x0-rX)**2+(y0-rY)**2+(z0-rZ)**2)/(2.*sig**2))/(sig*res**3)
    1902        
    1903     def peakFunc(parms,rX,rY,rZ,rho,res,SGLaue):
    1904         Mag,x0,y0,z0,sig = parms
    1905         M = rho-rhoCalc(parms,rX,rY,rZ,res,SGLaue)
    1906         return M
    1907        
    1908     def peakHess(parms,rX,rY,rZ,rho,res,SGLaue):
    1909         Mag,x0,y0,z0,sig = parms
    1910         dMdv = np.zeros(([5,]+list(rX.shape)))
    1911         delt = .01
    1912         for i in range(5):
    1913             parms[i] -= delt
    1914             rhoCm = rhoCalc(parms,rX,rY,rZ,res,SGLaue)
    1915             parms[i] += 2.*delt
    1916             rhoCp = rhoCalc(parms,rX,rY,rZ,res,SGLaue)
    1917             parms[i] -= delt
    1918             dMdv[i] = (rhoCp-rhoCm)/(2.*delt)
    1919         rhoC = rhoCalc(parms,rX,rY,rZ,res,SGLaue)
    1920         Vec = np.sum(np.sum(np.sum(dMdv*(rho-rhoC),axis=3),axis=2),axis=1)
    1921         dMdv = np.reshape(dMdv,(5,rX.size))
    1922         Hess = np.inner(dMdv,dMdv)
    1923        
    1924         return Vec,Hess
    1925        
    1926     generalData = data['General']
    1927     phaseName = generalData['Name']
    1928     SGData = generalData['SGData']
    1929     Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
    1930     drawingData = data['Drawing']
    1931     peaks = []
    1932     mags = []
    1933     dzeros = []
    1934     try:
    1935         mapData = generalData['Map']
    1936         contLevel = mapData['cutOff']*mapData['rhoMax']/100.
    1937         rho = copy.copy(mapData['rho'])     #don't mess up original
    1938         mapHalf = np.array(rho.shape)/2
    1939         res = mapData['Resolution']
    1940         incre = np.array(rho.shape)
    1941         step = max(1.0,1./res)+1
    1942         steps = np.array(3*[step,])
    1943     except KeyError:
    1944         print '**** ERROR - Fourier map not defined'
    1945         return peaks,mags
    1946     while True:
    1947         rhoMask = ma.array(rho,mask=(rho<contLevel))
    1948         if not ma.count(rhoMask):
    1949             break
    1950         rMI = findRoll(rhoMask,mapHalf)
    1951         rho = np.roll(np.roll(np.roll(rho,rMI[0],axis=0),rMI[1],axis=1),rMI[2],axis=2)
    1952         rMM = mapHalf-steps
    1953         rMP = mapHalf+steps+1
    1954         rhoPeak = rho[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]]
    1955         peakInt = np.sum(rhoPeak)*res**3
    1956         rX,rY,rZ = np.mgrid[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]]
    1957         x0 = [peakInt,mapHalf[0],mapHalf[1],mapHalf[2],2.0]          #magnitude, position & width(sig)
    1958         result = HessianLSQ(peakFunc,x0,Hess=peakHess,
    1959             args=(rX,rY,rZ,rhoPeak,res,SGData['SGLaue']),ftol=.01,maxcyc=10)
    1960         x1 = result[0]
    1961         if np.any(x1 < 0):
    1962             break
    1963         peak = (np.array(x1[1:4])-rMI)/incre
    1964         dzero = np.sqrt(np.sum(np.inner(Amat,peak)**2))
    1965         peak = fixSpecialPos(peak,SGData,Amat)
    1966         if not len(peaks):
    1967             peaks.append(peak)
    1968             mags.append(x1[0])
    1969             dzeros.append(dzero)
    1970         else:
    1971             if keepDup:
    1972                 if noDuplicate(peak,peaks,Amat):
    1973                     peaks.append(peak)
    1974                     mags.append(x1[0])
    1975                     dzeros.append(dzero)
    1976             elif noEquivalent(peak,peaks,SGData) and x1[0] > 0.:
    1977                 peaks.append(peak)
    1978                 mags.append(x1[0])
    1979                 dzeros.append(dzero)
    1980             GoOn = Pgbar.Update(len(peaks),newmsg='%s%d'%('No. Peaks found =',len(peaks)))[0]
    1981             if not GoOn or len(peaks) > 1000:
    1982                 break
    1983         rho[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]] = peakFunc(x1,rX,rY,rZ,rhoPeak,res,SGData['SGLaue'])
    1984         rho = np.roll(np.roll(np.roll(rho,-rMI[2],axis=2),-rMI[1],axis=1),-rMI[0],axis=0)
    1985 #    if SGData['SGInv']:                 #check origin location & fix it if needed - centrosymmetric only
    1986 #        Ocheck = np.zeros_like(rho)
    1987 #        for ipeak in peaks:
    1988 #            for opeak in peaks:           
    1989 #                dx = ((opeak-ipeak)*incre)%incre
    1990 #                if np.any(dx):      #avoid self vector
    1991 #                    Ocheck[dx[0],dx[1],dx[2]] += 1
    1992 #        dxMax = np.unravel_index(np.argmax(Ocheck),rho.shape)
    1993 #        print ' Inversion at:',dxMax,' shift by ;',dxMax-mapHalf
    1994 #        rho = np.roll(np.roll(np.roll(rho,dxMax[2],axis=2),dxMax[1],axis=1),dxMax[0],axis=0)
    1995 #        for peak in peaks:
    1996 #            peak = (peak-(dxMax+mapHalf)/incre)%1.0
    1997        
    1998     return np.array(peaks),np.array([mags,]).T,np.array([dzeros,]).T
    1999    
    2000 def sortArray(data,pos,reverse=False):
    2001     #data is a list of items
    2002     #sort by pos in list; reverse if True
    2003     T = []
    2004     for i,M in enumerate(data):
    2005         T.append((M[pos],i))
    2006     D = dict(zip(T,data))
    2007     T.sort()
    2008     if reverse:
    2009         T.reverse()
    2010     X = []
    2011     for key in T:
    2012         X.append(D[key])
    2013     return X
    2014                
    2015 def PeaksUnique(data,Ind):
    2016 
    2017     def noDuplicate(xyz,peaks,Amat):
    2018         if True in [np.allclose(np.inner(Amat,xyz),np.inner(Amat,peak),atol=0.5) for peak in peaks]:
    2019             return False
    2020         return True
    2021                            
    2022     generalData = data['General']
    2023     cell = generalData['Cell'][1:7]
    2024     Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])
    2025     A = G2lat.cell2A(cell)
    2026     SGData = generalData['SGData']
    2027     mapPeaks = data['Map Peaks']
    2028     Indx = {}
    2029     XYZ = {}
    2030     for ind in Ind:
    2031         XYZ[ind] = np.array(mapPeaks[ind][1:4])
    2032         Indx[ind] = True
    2033     for ind in Ind:
    2034         if Indx[ind]:
    2035             xyz = XYZ[ind]
    2036             for jnd in Ind:
    2037                 if ind != jnd and Indx[jnd]:                       
    2038                     Equiv = G2spc.GenAtom(XYZ[jnd],SGData,Move=True)
    2039                     xyzs = np.array([equiv[0] for equiv in Equiv])
    2040                     Indx[jnd] = noDuplicate(xyz,xyzs,Amat)
    2041     Ind = []
    2042     for ind in Indx:
    2043         if Indx[ind]:
    2044             Ind.append(ind)
    2045     return Ind
    2046    
    2047 def prodQQ(QA,QB):
    2048     ''' Grassman quaternion product
    2049         QA,QB quaternions; q=r+ai+bj+ck
    2050     '''
    2051     D = np.zeros(4)
    2052     D[0] = QA[0]*QB[0]-QA[1]*QB[1]-QA[2]*QB[2]-QA[3]*QB[3]
    2053     D[1] = QA[0]*QB[1]+QA[1]*QB[0]+QA[2]*QB[3]-QA[3]*QB[2]
    2054     D[2] = QA[0]*QB[2]-QA[1]*QB[3]+QA[2]*QB[0]+QA[3]*QB[1]
    2055     D[3] = QA[0]*QB[3]+QA[1]*QB[2]-QA[2]*QB[1]+QA[3]*QB[0]
    2056     return D
    2057    
    2058 def normQ(QA):
    2059     ''' get length of quaternion & normalize it
    2060         q=r+ai+bj+ck
    2061     '''
    2062     n = np.sqrt(np.sum(np.array(QA)**2))
    2063     return QA/n
    2064    
    2065 def invQ(Q):
    2066     '''
    2067         get inverse of quaternion
    2068         q=r+ai+bj+ck; q* = r-ai-bj-ck
    2069     '''
    2070     return Q*np.array([1,-1,-1,-1])
    2071    
    2072 def prodQVQ(Q,V):
    2073     ''' compute the quaternion vector rotation qvq-1 = v'
    2074         q=r+ai+bj+ck
    2075     '''
    2076     VP = np.zeros(3)
    2077     T2 = Q[0]*Q[1]
    2078     T3 = Q[0]*Q[2]
    2079     T4 = Q[0]*Q[3]
    2080     T5 = -Q[1]*Q[1]
    2081     T6 = Q[1]*Q[2]
    2082     T7 = Q[1]*Q[3]
    2083     T8 = -Q[2]*Q[2]
    2084     T9 = Q[2]*Q[3]
    2085     T10 = -Q[3]*Q[3]
    2086     VP[0] = 2.*((T8+T10)*V[0]+(T6-T4)*V[1]+(T3+T7)*V[2])+V[0]
    2087     VP[1] = 2.*((T4+T6)*V[0]+(T5+T10)*V[1]+(T9-T2)*V[2])+V[1]
    2088     VP[2] = 2.*((T7-T3)*V[0]+(T2+T9)*V[1]+(T5+T8)*V[2])+V[2]
    2089     return VP   
    2090    
    2091 def Q2Mat(Q):
    2092     ''' make rotation matrix from quaternion
    2093         q=r+ai+bj+ck
    2094     '''
    2095     aa = Q[0]**2
    2096     ab = Q[0]*Q[1]
    2097     ac = Q[0]*Q[2]
    2098     ad = Q[0]*Q[3]
    2099     bb = Q[1]**2
    2100     bc = Q[1]*Q[2]
    2101     bd = Q[1]*Q[3]
    2102     cc = Q[2]**2
    2103     cd = Q[2]*Q[3]
    2104     dd = Q[3]**2
    2105     M = [[aa+bb-cc-dd, 2.*(bc-ad),  2.*(ac+bd)],
    2106         [2*(ad+bc),   aa-bb+cc-dd,  2.*(cd-ab)],
    2107         [2*(bd-ac),    2.*(ab+cd), aa-bb-cc+dd]]
    2108     return np.array(M)
    2109    
    2110 def AV2Q(A,V):
    2111     ''' convert angle (radians -pi to pi) & vector to quaternion
    2112         q=r+ai+bj+ck
    2113     '''
    2114     Q = np.zeros(4)
    2115     d = np.sqrt(np.sum(np.array(V)**2))
    2116     if d:
    2117         V /= d
    2118     else:
    2119         return [1.,0.,0.,0.]    #identity
    2120     p = A/2.
    2121     Q[0] = np.cos(p)
    2122     s = np.sin(p)
    2123     Q[1:4] = V*s
    2124     return Q
    2125    
    2126 def AVdeg2Q(A,V):
    2127     ''' convert angle (degrees -180 to 180) & vector to quaternion
    2128         q=r+ai+bj+ck
    2129     '''
    2130     Q = np.zeros(4)
    2131     d = np.sqrt(np.sum(np.array(V)**2))
    2132     if d:
    2133         V /= d
    2134     else:
    2135         return [1.,0.,0.,0.]    #identity
    2136     p = A/2.
    2137     Q[0] = cosd(p)
    2138     S = sind(p)
    2139     Q[1:4] = V*S
    2140     return Q
    2141    
    2142 >>>>>>> .r762
  • trunk/GSASIIphsGUI.py

    r763 r764  
    1 <<<<<<< .mine
    21# -*- coding: utf-8 -*-
    32#GSASII - phase data display routines
     
    44814480    G2frame.dataDisplay.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, OnPageChanged)
    44824481    G2frame.dataDisplay.SetSelection(oldPage)
    4483 =======
    4484 # -*- coding: utf-8 -*-
    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.EXPAND|wx.BOTTOM|wx.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_VERTICAL|wx.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.EXPAND|wx.BOTTOM|wx.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.EXPAND|wx.BOTTOM|wx.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                 'k-factor':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[cs-1]*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[cs-1]*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 user-supplied 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_READONLY|wx.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_READONLY|wx.CB_DROPDOWN)
    5183                 isoSel.Bind(wx.EVT_COMBOBOX,OnIsotope)
    5184                 Indx[isoSel.GetId()] = elem
    5185                 elemSizer.Add(isoSel,1,wx.ALIGN_CENTER_VERTICAL|wx.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','delt-F','2*Fo-Fc','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_READONLY|wx.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_READONLY|wx.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['k-factor'] = res
    5365                 except ValueError:
    5366                     pass
    5367                 kFactor.SetValue("%.3f"%(Flip['k-factor']))          #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_READONLY|wx.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=' k-Factor (0.1-1.2): '),0,wx.ALIGN_CENTER_VERTICAL)
    5389             kFactor =  wx.TextCtrl(dataDisplay,value='%.3f'%(Flip['k-factor']),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][c-colLabels.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][c-1] = name[:2]+'(%d)'%(r+1)
    5671                         else:
    5672                             atomData[r][c-1] = 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(colU11-1,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][cid-1] = El[:2]+'(%d)'%(r+1)
    5896                             else:
    5897                                 atomData[r][cid-1] = 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][ct-1])
    6159             atXYZ.append(np.array(atomData[item][cx:cx+3]))
    6160             atSymOp.append(atomData[item][cs-1])
    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','1-letter','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','1-letter','chain']
    6227             Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,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) == '1-letter':
    6312                     SetChoice('1-letter',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','1-letter','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)*(1-2*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)*(1-2*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,xyz-xyzA)**2))
    6631                             if 0 < dist <= data['Drawing']['radiusFactor']*sumR:
    6632                                 if noDuplicate(xyz,atomData):
    6633                                     oprB = atomB[cx+3]
    6634                                     C = xyz-xyzB
    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(xyz-atom[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(xyz-atom[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 = Atoms-atomA[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(dist-data['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(face-bond))+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 = ct-1
    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.EXPAND|wx.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.EXPAND|wx.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.EXPAND|wx.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.EXPAND|wx.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.EXPAND|wx.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.EXPAND|wx.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.EXPAND|wx.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.EXPAND|wx.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.EXPAND|wx.RIGHT)
    7085            
    7086             slopSizer.Add(slideSizer,1,wx.EXPAND|wx.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((VB-VC)**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_READONLY|wx.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_READONLY|wx.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_READONLY|wx.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_READONLY|wx.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_READONLY|wx.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]/10-4,Size[1]/10-1)
    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_READONLY|wx.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 = ['March-Dollase','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_READONLY|wx.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_READONLY|wx.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=' March-Dollase 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_READONLY|wx.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_READONLY|wx.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]/10-4,Size[1]/10-1)
    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.e-2/(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:               #Debye-Scherrer - 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 += (jy-j)*'  '
    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 += (jy-j)*'  '
    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 = Atoms-atomA[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(dist-data['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_TIME|wx.PD_AUTO_HIDE|wx.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_TIME|wx.PD_AUTO_HIDE|wx.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.