[1299] | 1 | # -*- coding: utf-8 -*- |
---|
| 2 | ''' |
---|
| 3 | *GSASIIstrMath - structure math routines* |
---|
| 4 | ----------------------------------------- |
---|
| 5 | ''' |
---|
| 6 | ########### SVN repository information ################### |
---|
| 7 | # $Date: 2019-03-05 20:57:21 +0000 (Tue, 05 Mar 2019) $ |
---|
| 8 | # $Author: vondreele $ |
---|
| 9 | # $Revision: 3835 $ |
---|
| 10 | # $URL: trunk/GSASIIstrMath.py $ |
---|
| 11 | # $Id: GSASIIstrMath.py 3835 2019-03-05 20:57:21Z vondreele $ |
---|
| 12 | ########### SVN repository information ################### |
---|
[3136] | 13 | from __future__ import division, print_function |
---|
[1299] | 14 | import time |
---|
| 15 | import copy |
---|
| 16 | import numpy as np |
---|
| 17 | import numpy.ma as ma |
---|
| 18 | import numpy.linalg as nl |
---|
| 19 | import scipy.stats as st |
---|
[3041] | 20 | import multiprocessing as mp |
---|
[1299] | 21 | import GSASIIpath |
---|
| 22 | GSASIIpath.SetVersionNumber("$Revision: 3835 $") |
---|
| 23 | import GSASIIElem as G2el |
---|
| 24 | import GSASIIlattice as G2lat |
---|
| 25 | import GSASIIspc as G2spc |
---|
| 26 | import GSASIIpwd as G2pwd |
---|
| 27 | import GSASIImapvars as G2mv |
---|
| 28 | import GSASIImath as G2mth |
---|
[1813] | 29 | import GSASIIobj as G2obj |
---|
[3041] | 30 | import GSASIImpsubs as G2mp |
---|
[3048] | 31 | #G2mp.InitMP(False) # This disables multiprocessing |
---|
[1299] | 32 | |
---|
| 33 | sind = lambda x: np.sin(x*np.pi/180.) |
---|
| 34 | cosd = lambda x: np.cos(x*np.pi/180.) |
---|
| 35 | tand = lambda x: np.tan(x*np.pi/180.) |
---|
| 36 | asind = lambda x: 180.*np.arcsin(x)/np.pi |
---|
| 37 | acosd = lambda x: 180.*np.arccos(x)/np.pi |
---|
| 38 | atan2d = lambda y,x: 180.*np.arctan2(y,x)/np.pi |
---|
| 39 | |
---|
[1884] | 40 | ateln2 = 8.0*np.log(2.0) |
---|
[1630] | 41 | twopi = 2.0*np.pi |
---|
| 42 | twopisq = 2.0*np.pi**2 |
---|
[2094] | 43 | nxs = np.newaxis |
---|
[1299] | 44 | |
---|
| 45 | ################################################################################ |
---|
| 46 | ##### Rigid Body Models |
---|
| 47 | ################################################################################ |
---|
| 48 | |
---|
| 49 | def ApplyRBModels(parmDict,Phases,rigidbodyDict,Update=False): |
---|
| 50 | ''' Takes RB info from RBModels in Phase and RB data in rigidbodyDict along with |
---|
| 51 | current RB values in parmDict & modifies atom contents (xyz & Uij) of parmDict |
---|
| 52 | ''' |
---|
| 53 | atxIds = ['Ax:','Ay:','Az:'] |
---|
| 54 | atuIds = ['AU11:','AU22:','AU33:','AU12:','AU13:','AU23:'] |
---|
| 55 | RBIds = rigidbodyDict.get('RBIds',{'Vector':[],'Residue':[]}) #these are lists of rbIds |
---|
| 56 | if not RBIds['Vector'] and not RBIds['Residue']: |
---|
| 57 | return |
---|
| 58 | VRBIds = RBIds['Vector'] |
---|
| 59 | RRBIds = RBIds['Residue'] |
---|
| 60 | if Update: |
---|
| 61 | RBData = rigidbodyDict |
---|
| 62 | else: |
---|
| 63 | RBData = copy.deepcopy(rigidbodyDict) # don't mess with original! |
---|
| 64 | if RBIds['Vector']: # first update the vector magnitudes |
---|
| 65 | VRBData = RBData['Vector'] |
---|
| 66 | for i,rbId in enumerate(VRBIds): |
---|
| 67 | if VRBData[rbId]['useCount']: |
---|
| 68 | for j in range(len(VRBData[rbId]['VectMag'])): |
---|
| 69 | name = '::RBV;'+str(j)+':'+str(i) |
---|
| 70 | VRBData[rbId]['VectMag'][j] = parmDict[name] |
---|
| 71 | for phase in Phases: |
---|
| 72 | Phase = Phases[phase] |
---|
| 73 | General = Phase['General'] |
---|
[1604] | 74 | cx,ct,cs,cia = General['AtomPtrs'] |
---|
[1299] | 75 | cell = General['Cell'][1:7] |
---|
| 76 | Amat,Bmat = G2lat.cell2AB(cell) |
---|
[1604] | 77 | AtLookup = G2mth.FillAtomLookUp(Phase['Atoms'],cia+8) |
---|
[1299] | 78 | pfx = str(Phase['pId'])+'::' |
---|
| 79 | if Update: |
---|
| 80 | RBModels = Phase['RBModels'] |
---|
| 81 | else: |
---|
| 82 | RBModels = copy.deepcopy(Phase['RBModels']) # again don't mess with original! |
---|
| 83 | for irb,RBObj in enumerate(RBModels.get('Vector',[])): |
---|
| 84 | jrb = VRBIds.index(RBObj['RBId']) |
---|
| 85 | rbsx = str(irb)+':'+str(jrb) |
---|
| 86 | for i,px in enumerate(['RBVPx:','RBVPy:','RBVPz:']): |
---|
| 87 | RBObj['Orig'][0][i] = parmDict[pfx+px+rbsx] |
---|
| 88 | for i,po in enumerate(['RBVOa:','RBVOi:','RBVOj:','RBVOk:']): |
---|
| 89 | RBObj['Orient'][0][i] = parmDict[pfx+po+rbsx] |
---|
| 90 | RBObj['Orient'][0] = G2mth.normQ(RBObj['Orient'][0]) |
---|
| 91 | TLS = RBObj['ThermalMotion'] |
---|
| 92 | if 'T' in TLS[0]: |
---|
| 93 | for i,pt in enumerate(['RBVT11:','RBVT22:','RBVT33:','RBVT12:','RBVT13:','RBVT23:']): |
---|
| 94 | TLS[1][i] = parmDict[pfx+pt+rbsx] |
---|
| 95 | if 'L' in TLS[0]: |
---|
| 96 | for i,pt in enumerate(['RBVL11:','RBVL22:','RBVL33:','RBVL12:','RBVL13:','RBVL23:']): |
---|
| 97 | TLS[1][i+6] = parmDict[pfx+pt+rbsx] |
---|
| 98 | if 'S' in TLS[0]: |
---|
| 99 | for i,pt in enumerate(['RBVS12:','RBVS13:','RBVS21:','RBVS23:','RBVS31:','RBVS32:','RBVSAA:','RBVSBB:']): |
---|
| 100 | TLS[1][i+12] = parmDict[pfx+pt+rbsx] |
---|
| 101 | if 'U' in TLS[0]: |
---|
| 102 | TLS[1][0] = parmDict[pfx+'RBVU:'+rbsx] |
---|
| 103 | XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Vector') |
---|
| 104 | UIJ = G2mth.UpdateRBUIJ(Bmat,Cart,RBObj) |
---|
| 105 | for i,x in enumerate(XYZ): |
---|
| 106 | atId = RBObj['Ids'][i] |
---|
| 107 | for j in [0,1,2]: |
---|
| 108 | parmDict[pfx+atxIds[j]+str(AtLookup[atId])] = x[j] |
---|
| 109 | if UIJ[i][0] == 'A': |
---|
| 110 | for j in range(6): |
---|
| 111 | parmDict[pfx+atuIds[j]+str(AtLookup[atId])] = UIJ[i][j+2] |
---|
| 112 | elif UIJ[i][0] == 'I': |
---|
| 113 | parmDict[pfx+'AUiso:'+str(AtLookup[atId])] = UIJ[i][1] |
---|
| 114 | |
---|
| 115 | for irb,RBObj in enumerate(RBModels.get('Residue',[])): |
---|
| 116 | jrb = RRBIds.index(RBObj['RBId']) |
---|
| 117 | rbsx = str(irb)+':'+str(jrb) |
---|
| 118 | for i,px in enumerate(['RBRPx:','RBRPy:','RBRPz:']): |
---|
| 119 | RBObj['Orig'][0][i] = parmDict[pfx+px+rbsx] |
---|
| 120 | for i,po in enumerate(['RBROa:','RBROi:','RBROj:','RBROk:']): |
---|
| 121 | RBObj['Orient'][0][i] = parmDict[pfx+po+rbsx] |
---|
| 122 | RBObj['Orient'][0] = G2mth.normQ(RBObj['Orient'][0]) |
---|
| 123 | TLS = RBObj['ThermalMotion'] |
---|
| 124 | if 'T' in TLS[0]: |
---|
| 125 | for i,pt in enumerate(['RBRT11:','RBRT22:','RBRT33:','RBRT12:','RBRT13:','RBRT23:']): |
---|
| 126 | RBObj['ThermalMotion'][1][i] = parmDict[pfx+pt+rbsx] |
---|
| 127 | if 'L' in TLS[0]: |
---|
| 128 | for i,pt in enumerate(['RBRL11:','RBRL22:','RBRL33:','RBRL12:','RBRL13:','RBRL23:']): |
---|
| 129 | RBObj['ThermalMotion'][1][i+6] = parmDict[pfx+pt+rbsx] |
---|
| 130 | if 'S' in TLS[0]: |
---|
| 131 | for i,pt in enumerate(['RBRS12:','RBRS13:','RBRS21:','RBRS23:','RBRS31:','RBRS32:','RBRSAA:','RBRSBB:']): |
---|
| 132 | RBObj['ThermalMotion'][1][i+12] = parmDict[pfx+pt+rbsx] |
---|
| 133 | if 'U' in TLS[0]: |
---|
| 134 | RBObj['ThermalMotion'][1][0] = parmDict[pfx+'RBRU:'+rbsx] |
---|
| 135 | for itors,tors in enumerate(RBObj['Torsions']): |
---|
| 136 | tors[0] = parmDict[pfx+'RBRTr;'+str(itors)+':'+rbsx] |
---|
| 137 | XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Residue') |
---|
| 138 | UIJ = G2mth.UpdateRBUIJ(Bmat,Cart,RBObj) |
---|
| 139 | for i,x in enumerate(XYZ): |
---|
| 140 | atId = RBObj['Ids'][i] |
---|
| 141 | for j in [0,1,2]: |
---|
| 142 | parmDict[pfx+atxIds[j]+str(AtLookup[atId])] = x[j] |
---|
| 143 | if UIJ[i][0] == 'A': |
---|
| 144 | for j in range(6): |
---|
| 145 | parmDict[pfx+atuIds[j]+str(AtLookup[atId])] = UIJ[i][j+2] |
---|
| 146 | elif UIJ[i][0] == 'I': |
---|
| 147 | parmDict[pfx+'AUiso:'+str(AtLookup[atId])] = UIJ[i][1] |
---|
| 148 | |
---|
| 149 | def ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase): |
---|
| 150 | 'Needs a doc string' |
---|
| 151 | atxIds = ['dAx:','dAy:','dAz:'] |
---|
| 152 | atuIds = ['AU11:','AU22:','AU33:','AU12:','AU13:','AU23:'] |
---|
| 153 | OIds = ['Oa:','Oi:','Oj:','Ok:'] |
---|
| 154 | RBIds = rigidbodyDict.get('RBIds',{'Vector':[],'Residue':[]}) #these are lists of rbIds |
---|
| 155 | if not RBIds['Vector'] and not RBIds['Residue']: |
---|
| 156 | return |
---|
| 157 | VRBIds = RBIds['Vector'] |
---|
| 158 | RRBIds = RBIds['Residue'] |
---|
| 159 | RBData = rigidbodyDict |
---|
| 160 | for item in parmDict: |
---|
| 161 | if 'RB' in item: |
---|
| 162 | dFdvDict[item] = 0. #NB: this is a vector which is no. refl. long & must be filled! |
---|
| 163 | General = Phase['General'] |
---|
[1604] | 164 | cx,ct,cs,cia = General['AtomPtrs'] |
---|
[1299] | 165 | cell = General['Cell'][1:7] |
---|
| 166 | Amat,Bmat = G2lat.cell2AB(cell) |
---|
| 167 | rpd = np.pi/180. |
---|
| 168 | rpd2 = rpd**2 |
---|
| 169 | g = nl.inv(np.inner(Bmat,Bmat)) |
---|
| 170 | gvec = np.sqrt(np.array([g[0][0]**2,g[1][1]**2,g[2][2]**2, |
---|
| 171 | g[0][0]*g[1][1],g[0][0]*g[2][2],g[1][1]*g[2][2]])) |
---|
[1604] | 172 | AtLookup = G2mth.FillAtomLookUp(Phase['Atoms'],cia+8) |
---|
[1299] | 173 | pfx = str(Phase['pId'])+'::' |
---|
| 174 | RBModels = Phase['RBModels'] |
---|
| 175 | for irb,RBObj in enumerate(RBModels.get('Vector',[])): |
---|
| 176 | VModel = RBData['Vector'][RBObj['RBId']] |
---|
| 177 | Q = RBObj['Orient'][0] |
---|
| 178 | jrb = VRBIds.index(RBObj['RBId']) |
---|
| 179 | rbsx = str(irb)+':'+str(jrb) |
---|
| 180 | dXdv = [] |
---|
| 181 | for iv in range(len(VModel['VectMag'])): |
---|
| 182 | dCdv = [] |
---|
| 183 | for vec in VModel['rbVect'][iv]: |
---|
| 184 | dCdv.append(G2mth.prodQVQ(Q,vec)) |
---|
| 185 | dXdv.append(np.inner(Bmat,np.array(dCdv)).T) |
---|
| 186 | XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Vector') |
---|
| 187 | for ia,atId in enumerate(RBObj['Ids']): |
---|
| 188 | atNum = AtLookup[atId] |
---|
| 189 | dx = 0.00001 |
---|
| 190 | for iv in range(len(VModel['VectMag'])): |
---|
| 191 | for ix in [0,1,2]: |
---|
| 192 | dFdvDict['::RBV;'+str(iv)+':'+str(jrb)] += dXdv[iv][ia][ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)] |
---|
| 193 | for i,name in enumerate(['RBVPx:','RBVPy:','RBVPz:']): |
---|
| 194 | dFdvDict[pfx+name+rbsx] += dFdvDict[pfx+atxIds[i]+str(atNum)] |
---|
| 195 | for iv in range(4): |
---|
| 196 | Q[iv] -= dx |
---|
| 197 | XYZ1 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q)) |
---|
| 198 | Q[iv] += 2.*dx |
---|
| 199 | XYZ2 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q)) |
---|
| 200 | Q[iv] -= dx |
---|
| 201 | dXdO = (XYZ2[ia]-XYZ1[ia])/(2.*dx) |
---|
| 202 | for ix in [0,1,2]: |
---|
| 203 | dFdvDict[pfx+'RBV'+OIds[iv]+rbsx] += dXdO[ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)] |
---|
| 204 | X = G2mth.prodQVQ(Q,Cart[ia]) |
---|
| 205 | dFdu = np.array([dFdvDict[pfx+Uid+str(AtLookup[atId])] for Uid in atuIds]).T/gvec |
---|
| 206 | dFdu = G2lat.U6toUij(dFdu.T) |
---|
| 207 | dFdu = np.tensordot(Amat,np.tensordot(Amat,dFdu,([1,0])),([0,1])) |
---|
| 208 | dFdu = G2lat.UijtoU6(dFdu) |
---|
| 209 | atNum = AtLookup[atId] |
---|
| 210 | if 'T' in RBObj['ThermalMotion'][0]: |
---|
| 211 | for i,name in enumerate(['RBVT11:','RBVT22:','RBVT33:','RBVT12:','RBVT13:','RBVT23:']): |
---|
| 212 | dFdvDict[pfx+name+rbsx] += dFdu[i] |
---|
| 213 | if 'L' in RBObj['ThermalMotion'][0]: |
---|
| 214 | dFdvDict[pfx+'RBVL11:'+rbsx] += rpd2*(dFdu[1]*X[2]**2+dFdu[2]*X[1]**2-dFdu[5]*X[1]*X[2]) |
---|
| 215 | dFdvDict[pfx+'RBVL22:'+rbsx] += rpd2*(dFdu[0]*X[2]**2+dFdu[2]*X[0]**2-dFdu[4]*X[0]*X[2]) |
---|
| 216 | dFdvDict[pfx+'RBVL33:'+rbsx] += rpd2*(dFdu[0]*X[1]**2+dFdu[1]*X[0]**2-dFdu[3]*X[0]*X[1]) |
---|
| 217 | dFdvDict[pfx+'RBVL12:'+rbsx] += rpd2*(-dFdu[3]*X[2]**2-2.*dFdu[2]*X[0]*X[1]+ |
---|
| 218 | dFdu[4]*X[1]*X[2]+dFdu[5]*X[0]*X[2]) |
---|
| 219 | dFdvDict[pfx+'RBVL13:'+rbsx] += rpd2*(-dFdu[4]*X[1]**2-2.*dFdu[1]*X[0]*X[2]+ |
---|
| 220 | dFdu[3]*X[1]*X[2]+dFdu[5]*X[0]*X[1]) |
---|
| 221 | dFdvDict[pfx+'RBVL23:'+rbsx] += rpd2*(-dFdu[5]*X[0]**2-2.*dFdu[0]*X[1]*X[2]+ |
---|
| 222 | dFdu[3]*X[0]*X[2]+dFdu[4]*X[0]*X[1]) |
---|
| 223 | if 'S' in RBObj['ThermalMotion'][0]: |
---|
| 224 | dFdvDict[pfx+'RBVS12:'+rbsx] += rpd*(dFdu[5]*X[1]-2.*dFdu[1]*X[2]) |
---|
| 225 | dFdvDict[pfx+'RBVS13:'+rbsx] += rpd*(-dFdu[5]*X[2]+2.*dFdu[2]*X[1]) |
---|
| 226 | dFdvDict[pfx+'RBVS21:'+rbsx] += rpd*(-dFdu[4]*X[0]+2.*dFdu[0]*X[2]) |
---|
| 227 | dFdvDict[pfx+'RBVS23:'+rbsx] += rpd*(dFdu[4]*X[2]-2.*dFdu[2]*X[0]) |
---|
| 228 | dFdvDict[pfx+'RBVS31:'+rbsx] += rpd*(dFdu[3]*X[0]-2.*dFdu[0]*X[1]) |
---|
| 229 | dFdvDict[pfx+'RBVS32:'+rbsx] += rpd*(-dFdu[3]*X[1]+2.*dFdu[1]*X[0]) |
---|
| 230 | dFdvDict[pfx+'RBVSAA:'+rbsx] += rpd*(dFdu[4]*X[1]-dFdu[3]*X[2]) |
---|
| 231 | dFdvDict[pfx+'RBVSBB:'+rbsx] += rpd*(dFdu[5]*X[0]-dFdu[3]*X[2]) |
---|
| 232 | if 'U' in RBObj['ThermalMotion'][0]: |
---|
| 233 | dFdvDict[pfx+'RBVU:'+rbsx] += dFdvDict[pfx+'AUiso:'+str(AtLookup[atId])] |
---|
| 234 | |
---|
| 235 | |
---|
| 236 | for irb,RBObj in enumerate(RBModels.get('Residue',[])): |
---|
| 237 | Q = RBObj['Orient'][0] |
---|
| 238 | jrb = RRBIds.index(RBObj['RBId']) |
---|
| 239 | torData = RBData['Residue'][RBObj['RBId']]['rbSeq'] |
---|
| 240 | rbsx = str(irb)+':'+str(jrb) |
---|
| 241 | XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Residue') |
---|
| 242 | for itors,tors in enumerate(RBObj['Torsions']): #derivative error? |
---|
| 243 | tname = pfx+'RBRTr;'+str(itors)+':'+rbsx |
---|
| 244 | orId,pvId = torData[itors][:2] |
---|
| 245 | pivotVec = Cart[orId]-Cart[pvId] |
---|
| 246 | QA = G2mth.AVdeg2Q(-0.001,pivotVec) |
---|
| 247 | QB = G2mth.AVdeg2Q(0.001,pivotVec) |
---|
| 248 | for ir in torData[itors][3]: |
---|
| 249 | atNum = AtLookup[RBObj['Ids'][ir]] |
---|
| 250 | rVec = Cart[ir]-Cart[pvId] |
---|
| 251 | dR = G2mth.prodQVQ(QB,rVec)-G2mth.prodQVQ(QA,rVec) |
---|
| 252 | dRdT = np.inner(Bmat,G2mth.prodQVQ(Q,dR))/.002 |
---|
| 253 | for ix in [0,1,2]: |
---|
| 254 | dFdvDict[tname] += dRdT[ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)] |
---|
| 255 | for ia,atId in enumerate(RBObj['Ids']): |
---|
| 256 | atNum = AtLookup[atId] |
---|
| 257 | dx = 0.00001 |
---|
| 258 | for i,name in enumerate(['RBRPx:','RBRPy:','RBRPz:']): |
---|
| 259 | dFdvDict[pfx+name+rbsx] += dFdvDict[pfx+atxIds[i]+str(atNum)] |
---|
| 260 | for iv in range(4): |
---|
| 261 | Q[iv] -= dx |
---|
| 262 | XYZ1 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q)) |
---|
| 263 | Q[iv] += 2.*dx |
---|
| 264 | XYZ2 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q)) |
---|
| 265 | Q[iv] -= dx |
---|
| 266 | dXdO = (XYZ2[ia]-XYZ1[ia])/(2.*dx) |
---|
| 267 | for ix in [0,1,2]: |
---|
| 268 | dFdvDict[pfx+'RBR'+OIds[iv]+rbsx] += dXdO[ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)] |
---|
| 269 | X = G2mth.prodQVQ(Q,Cart[ia]) |
---|
| 270 | dFdu = np.array([dFdvDict[pfx+Uid+str(AtLookup[atId])] for Uid in atuIds]).T/gvec |
---|
| 271 | dFdu = G2lat.U6toUij(dFdu.T) |
---|
| 272 | dFdu = np.tensordot(Amat.T,np.tensordot(Amat,dFdu,([1,0])),([0,1])) |
---|
| 273 | dFdu = G2lat.UijtoU6(dFdu) |
---|
| 274 | atNum = AtLookup[atId] |
---|
| 275 | if 'T' in RBObj['ThermalMotion'][0]: |
---|
| 276 | for i,name in enumerate(['RBRT11:','RBRT22:','RBRT33:','RBRT12:','RBRT13:','RBRT23:']): |
---|
| 277 | dFdvDict[pfx+name+rbsx] += dFdu[i] |
---|
| 278 | if 'L' in RBObj['ThermalMotion'][0]: |
---|
| 279 | dFdvDict[pfx+'RBRL11:'+rbsx] += rpd2*(dFdu[1]*X[2]**2+dFdu[2]*X[1]**2-dFdu[5]*X[1]*X[2]) |
---|
| 280 | dFdvDict[pfx+'RBRL22:'+rbsx] += rpd2*(dFdu[0]*X[2]**2+dFdu[2]*X[0]**2-dFdu[4]*X[0]*X[2]) |
---|
| 281 | dFdvDict[pfx+'RBRL33:'+rbsx] += rpd2*(dFdu[0]*X[1]**2+dFdu[1]*X[0]**2-dFdu[3]*X[0]*X[1]) |
---|
| 282 | dFdvDict[pfx+'RBRL12:'+rbsx] += rpd2*(-dFdu[3]*X[2]**2-2.*dFdu[2]*X[0]*X[1]+ |
---|
| 283 | dFdu[4]*X[1]*X[2]+dFdu[5]*X[0]*X[2]) |
---|
| 284 | dFdvDict[pfx+'RBRL13:'+rbsx] += rpd2*(dFdu[4]*X[1]**2-2.*dFdu[1]*X[0]*X[2]+ |
---|
| 285 | dFdu[3]*X[1]*X[2]+dFdu[5]*X[0]*X[1]) |
---|
| 286 | dFdvDict[pfx+'RBRL23:'+rbsx] += rpd2*(dFdu[5]*X[0]**2-2.*dFdu[0]*X[1]*X[2]+ |
---|
| 287 | dFdu[3]*X[0]*X[2]+dFdu[4]*X[0]*X[1]) |
---|
| 288 | if 'S' in RBObj['ThermalMotion'][0]: |
---|
| 289 | dFdvDict[pfx+'RBRS12:'+rbsx] += rpd*(dFdu[5]*X[1]-2.*dFdu[1]*X[2]) |
---|
| 290 | dFdvDict[pfx+'RBRS13:'+rbsx] += rpd*(-dFdu[5]*X[2]+2.*dFdu[2]*X[1]) |
---|
| 291 | dFdvDict[pfx+'RBRS21:'+rbsx] += rpd*(-dFdu[4]*X[0]+2.*dFdu[0]*X[2]) |
---|
| 292 | dFdvDict[pfx+'RBRS23:'+rbsx] += rpd*(dFdu[4]*X[2]-2.*dFdu[2]*X[0]) |
---|
| 293 | dFdvDict[pfx+'RBRS31:'+rbsx] += rpd*(dFdu[3]*X[0]-2.*dFdu[0]*X[1]) |
---|
| 294 | dFdvDict[pfx+'RBRS32:'+rbsx] += rpd*(-dFdu[3]*X[1]+2.*dFdu[1]*X[0]) |
---|
| 295 | dFdvDict[pfx+'RBRSAA:'+rbsx] += rpd*(dFdu[4]*X[1]-dFdu[3]*X[2]) |
---|
| 296 | dFdvDict[pfx+'RBRSBB:'+rbsx] += rpd*(dFdu[5]*X[0]-dFdu[3]*X[2]) |
---|
| 297 | if 'U' in RBObj['ThermalMotion'][0]: |
---|
| 298 | dFdvDict[pfx+'RBRU:'+rbsx] += dFdvDict[pfx+'AUiso:'+str(AtLookup[atId])] |
---|
| 299 | |
---|
| 300 | ################################################################################ |
---|
| 301 | ##### Penalty & restraint functions |
---|
| 302 | ################################################################################ |
---|
| 303 | |
---|
[1775] | 304 | def penaltyFxn(HistoPhases,calcControls,parmDict,varyList): |
---|
[3802] | 305 | 'Compute user-supplied and built-in restraint functions' |
---|
[1299] | 306 | Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases |
---|
| 307 | pNames = [] |
---|
| 308 | pVals = [] |
---|
| 309 | pWt = [] |
---|
| 310 | negWt = {} |
---|
| 311 | pWsum = {} |
---|
[2838] | 312 | pWnum = {} |
---|
[1299] | 313 | for phase in Phases: |
---|
| 314 | pId = Phases[phase]['pId'] |
---|
| 315 | negWt[pId] = Phases[phase]['General']['Pawley neg wt'] |
---|
| 316 | General = Phases[phase]['General'] |
---|
[1604] | 317 | cx,ct,cs,cia = General['AtomPtrs'] |
---|
[1299] | 318 | textureData = General['SH Texture'] |
---|
| 319 | SGData = General['SGData'] |
---|
[2512] | 320 | Atoms = Phases[phase]['Atoms'] |
---|
[1604] | 321 | AtLookup = G2mth.FillAtomLookUp(Phases[phase]['Atoms'],cia+8) |
---|
[1299] | 322 | cell = General['Cell'][1:7] |
---|
| 323 | Amat,Bmat = G2lat.cell2AB(cell) |
---|
| 324 | if phase not in restraintDict: |
---|
| 325 | continue |
---|
| 326 | phaseRest = restraintDict[phase] |
---|
| 327 | names = [['Bond','Bonds'],['Angle','Angles'],['Plane','Planes'], |
---|
| 328 | ['Chiral','Volumes'],['Torsion','Torsions'],['Rama','Ramas'], |
---|
[3802] | 329 | ['ChemComp','Sites'],['Texture','HKLs'],['General','General'],] |
---|
[1299] | 330 | for name,rest in names: |
---|
| 331 | pWsum[name] = 0. |
---|
[2838] | 332 | pWnum[name] = 0 |
---|
[3380] | 333 | if name not in phaseRest: |
---|
| 334 | continue |
---|
[1299] | 335 | itemRest = phaseRest[name] |
---|
| 336 | if itemRest[rest] and itemRest['Use']: |
---|
[3802] | 337 | wt = itemRest.get('wtFactor',1.) |
---|
[1299] | 338 | if name in ['Bond','Angle','Plane','Chiral']: |
---|
| 339 | for i,[indx,ops,obs,esd] in enumerate(itemRest[rest]): |
---|
| 340 | pNames.append(str(pId)+':'+name+':'+str(i)) |
---|
| 341 | XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx)) |
---|
| 342 | XYZ = G2mth.getSyXYZ(XYZ,ops,SGData) |
---|
| 343 | if name == 'Bond': |
---|
| 344 | calc = G2mth.getRestDist(XYZ,Amat) |
---|
| 345 | elif name == 'Angle': |
---|
| 346 | calc = G2mth.getRestAngle(XYZ,Amat) |
---|
| 347 | elif name == 'Plane': |
---|
| 348 | calc = G2mth.getRestPlane(XYZ,Amat) |
---|
| 349 | elif name == 'Chiral': |
---|
| 350 | calc = G2mth.getRestChiral(XYZ,Amat) |
---|
| 351 | pVals.append(obs-calc) |
---|
| 352 | pWt.append(wt/esd**2) |
---|
| 353 | pWsum[name] += wt*((obs-calc)/esd)**2 |
---|
[2838] | 354 | pWnum[name] += 1 |
---|
[1299] | 355 | elif name in ['Torsion','Rama']: |
---|
| 356 | coeffDict = itemRest['Coeff'] |
---|
| 357 | for i,[indx,ops,cofName,esd] in enumerate(itemRest[rest]): |
---|
| 358 | pNames.append(str(pId)+':'+name+':'+str(i)) |
---|
| 359 | XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx)) |
---|
| 360 | XYZ = G2mth.getSyXYZ(XYZ,ops,SGData) |
---|
| 361 | if name == 'Torsion': |
---|
| 362 | tor = G2mth.getRestTorsion(XYZ,Amat) |
---|
| 363 | restr,calc = G2mth.calcTorsionEnergy(tor,coeffDict[cofName]) |
---|
| 364 | else: |
---|
| 365 | phi,psi = G2mth.getRestRama(XYZ,Amat) |
---|
| 366 | restr,calc = G2mth.calcRamaEnergy(phi,psi,coeffDict[cofName]) |
---|
| 367 | pVals.append(restr) |
---|
| 368 | pWt.append(wt/esd**2) |
---|
| 369 | pWsum[name] += wt*(restr/esd)**2 |
---|
[2838] | 370 | pWnum[name] += 1 |
---|
[1299] | 371 | elif name == 'ChemComp': |
---|
| 372 | for i,[indx,factors,obs,esd] in enumerate(itemRest[rest]): |
---|
| 373 | pNames.append(str(pId)+':'+name+':'+str(i)) |
---|
[2512] | 374 | mul = np.array(G2mth.GetAtomItemsById(Atoms,AtLookup,indx,cs+1)) |
---|
[3423] | 375 | frac = np.array(G2mth.GetAtomFracByID(pId,parmDict,AtLookup,indx)) |
---|
[1299] | 376 | calc = np.sum(mul*frac*factors) |
---|
| 377 | pVals.append(obs-calc) |
---|
| 378 | pWt.append(wt/esd**2) |
---|
| 379 | pWsum[name] += wt*((obs-calc)/esd)**2 |
---|
[2838] | 380 | pWnum[name] += 1 |
---|
[1299] | 381 | elif name == 'Texture': |
---|
[3136] | 382 | SHkeys = list(textureData['SH Coeff'][1].keys()) |
---|
[1299] | 383 | SHCoef = G2mth.GetSHCoeff(pId,parmDict,SHkeys) |
---|
| 384 | shModels = ['cylindrical','none','shear - 2/m','rolling - mmm'] |
---|
| 385 | SamSym = dict(zip(shModels,['0','-1','2/m','mmm'])) |
---|
| 386 | for i,[hkl,grid,esd1,ifesd2,esd2] in enumerate(itemRest[rest]): |
---|
| 387 | PH = np.array(hkl) |
---|
| 388 | phi,beta = G2lat.CrsAng(np.array(hkl),cell,SGData) |
---|
| 389 | ODFln = G2lat.Flnh(False,SHCoef,phi,beta,SGData) |
---|
| 390 | R,P,Z = G2mth.getRestPolefig(ODFln,SamSym[textureData['Model']],grid) |
---|
[2815] | 391 | Z1 = ma.masked_greater(Z,0.0) #is this + or -? |
---|
[1299] | 392 | IndZ1 = np.array(ma.nonzero(Z1)) |
---|
| 393 | for ind in IndZ1.T: |
---|
| 394 | pNames.append('%d:%s:%d:%.2f:%.2f'%(pId,name,i,R[ind[0],ind[1]],P[ind[0],ind[1]])) |
---|
| 395 | pVals.append(Z1[ind[0]][ind[1]]) |
---|
| 396 | pWt.append(wt/esd1**2) |
---|
[1776] | 397 | pWsum[name] += wt*(-Z1[ind[0]][ind[1]]/esd1)**2 |
---|
[2838] | 398 | pWnum[name] += 1 |
---|
[1299] | 399 | if ifesd2: |
---|
| 400 | Z2 = 1.-Z |
---|
| 401 | for ind in np.ndindex(grid,grid): |
---|
| 402 | pNames.append('%d:%s:%d:%.2f:%.2f'%(pId,name+'-unit',i,R[ind[0],ind[1]],P[ind[0],ind[1]])) |
---|
[2815] | 403 | pVals.append(Z2[ind[0]][ind[1]]) |
---|
[1299] | 404 | pWt.append(wt/esd2**2) |
---|
[1776] | 405 | pWsum[name] += wt*(Z2/esd2)**2 |
---|
[2838] | 406 | pWnum[name] += 1 |
---|
[3802] | 407 | elif name == 'General': |
---|
| 408 | for i,(eq,obs,esd) in enumerate(itemRest[rest]): |
---|
| 409 | pNames.append(str(pId)+':'+name+':'+str(i)) |
---|
| 410 | calcobj = G2obj.ExpressionCalcObj(eq) |
---|
| 411 | calcobj.SetupCalc(parmDict) |
---|
| 412 | calc = calcobj.EvalExpression() |
---|
| 413 | pVals.append(obs-calc) |
---|
| 414 | pWt.append(wt/esd**2) |
---|
| 415 | pWsum[name] += wt*((obs-calc)/esd)**2 |
---|
| 416 | pWnum[name] += 1 |
---|
[1775] | 417 | |
---|
[1810] | 418 | for phase in Phases: |
---|
[1775] | 419 | name = 'SH-Pref.Ori.' |
---|
[1810] | 420 | pId = Phases[phase]['pId'] |
---|
| 421 | General = Phases[phase]['General'] |
---|
| 422 | SGData = General['SGData'] |
---|
| 423 | cell = General['Cell'][1:7] |
---|
[1775] | 424 | pWsum[name] = 0.0 |
---|
[2838] | 425 | pWnum[name] = 0 |
---|
[1775] | 426 | for hist in Phases[phase]['Histograms']: |
---|
[2715] | 427 | if not Phases[phase]['Histograms'][hist]['Use']: |
---|
| 428 | continue |
---|
[1816] | 429 | if hist in Histograms and 'PWDR' in hist: |
---|
[1775] | 430 | hId = Histograms[hist]['hId'] |
---|
| 431 | phfx = '%d:%d:'%(pId,hId) |
---|
| 432 | if calcControls[phfx+'poType'] == 'SH': |
---|
| 433 | toler = calcControls[phfx+'SHtoler'] |
---|
| 434 | wt = 1./toler**2 |
---|
[1793] | 435 | HKLs = np.array(calcControls[phfx+'SHhkl']) |
---|
[1777] | 436 | SHnames = calcControls[phfx+'SHnames'] |
---|
| 437 | SHcof = dict(zip(SHnames,[parmDict[phfx+cof] for cof in SHnames])) |
---|
[1775] | 438 | for i,PH in enumerate(HKLs): |
---|
| 439 | phi,beta = G2lat.CrsAng(PH,cell,SGData) |
---|
| 440 | SH3Coef = {} |
---|
| 441 | for item in SHcof: |
---|
| 442 | L,N = eval(item.strip('C')) |
---|
| 443 | SH3Coef['C%d,0,%d'%(L,N)] = SHcof[item] |
---|
| 444 | ODFln = G2lat.Flnh(False,SH3Coef,phi,beta,SGData) |
---|
| 445 | X = np.linspace(0,90.0,26) |
---|
[2815] | 446 | Y = ma.masked_greater(G2lat.polfcal(ODFln,'0',X,0.0),0.0) #+ or -? |
---|
[1775] | 447 | IndY = ma.nonzero(Y) |
---|
| 448 | for ind in IndY[0]: |
---|
| 449 | pNames.append('%d:%d:%s:%d:%.2f'%(pId,hId,name,i,X[ind])) |
---|
| 450 | pVals.append(Y[ind]) |
---|
| 451 | pWt.append(wt) |
---|
[1777] | 452 | pWsum[name] += wt*(Y[ind])**2 |
---|
[2838] | 453 | pWnum[name] += 1 |
---|
[1299] | 454 | pWsum['PWLref'] = 0. |
---|
[2858] | 455 | pWnum['PWLref'] = 0 |
---|
[1299] | 456 | for item in varyList: |
---|
| 457 | if 'PWLref' in item and parmDict[item] < 0.: |
---|
| 458 | pId = int(item.split(':')[0]) |
---|
| 459 | if negWt[pId]: |
---|
| 460 | pNames.append(item) |
---|
[2815] | 461 | pVals.append(parmDict[item]) |
---|
[1299] | 462 | pWt.append(negWt[pId]) |
---|
[2815] | 463 | pWsum['PWLref'] += negWt[pId]*(parmDict[item])**2 |
---|
[2858] | 464 | pWnum['PWLref'] += 1 |
---|
[1299] | 465 | pVals = np.array(pVals) |
---|
| 466 | pWt = np.array(pWt) #should this be np.sqrt? |
---|
[2838] | 467 | return pNames,pVals,pWt,pWsum,pWnum |
---|
[1299] | 468 | |
---|
[1775] | 469 | def penaltyDeriv(pNames,pVal,HistoPhases,calcControls,parmDict,varyList): |
---|
[3802] | 470 | '''Compute derivatives on user-supplied and built-in restraint |
---|
| 471 | (penalty) functions |
---|
| 472 | |
---|
| 473 | where pNames is list of restraint labels |
---|
| 474 | |
---|
| 475 | returns pDerv with partial derivatives by variable# in varList and |
---|
| 476 | restraint# in pNames (pDerv[variable#][restraint#]) |
---|
| 477 | ''' |
---|
[1299] | 478 | Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases |
---|
| 479 | pDerv = np.zeros((len(varyList),len(pVal))) |
---|
[3802] | 480 | for pName in pNames: # loop over restraints |
---|
| 481 | if 'General' == pName.split(':')[1]: |
---|
| 482 | # initialize for General restraint(s) here |
---|
| 483 | GeneralInit = True |
---|
| 484 | parmDict0 = parmDict.copy() |
---|
| 485 | # setup steps for each parameter |
---|
| 486 | stepDict = {} |
---|
| 487 | for parm in varyList: |
---|
[3806] | 488 | stepDict[parm] = G2obj.getVarStep(parm,parmDict) |
---|
[3802] | 489 | break |
---|
[1299] | 490 | for phase in Phases: |
---|
| 491 | # if phase not in restraintDict: |
---|
| 492 | # continue |
---|
| 493 | pId = Phases[phase]['pId'] |
---|
| 494 | General = Phases[phase]['General'] |
---|
[1604] | 495 | cx,ct,cs,cia = General['AtomPtrs'] |
---|
[1299] | 496 | SGData = General['SGData'] |
---|
[2512] | 497 | Atoms = Phases[phase]['Atoms'] |
---|
[1604] | 498 | AtLookup = G2mth.FillAtomLookUp(Phases[phase]['Atoms'],cia+8) |
---|
[1299] | 499 | cell = General['Cell'][1:7] |
---|
| 500 | Amat,Bmat = G2lat.cell2AB(cell) |
---|
| 501 | textureData = General['SH Texture'] |
---|
| 502 | |
---|
[3136] | 503 | SHkeys = list(textureData['SH Coeff'][1].keys()) |
---|
[1299] | 504 | SHCoef = G2mth.GetSHCoeff(pId,parmDict,SHkeys) |
---|
| 505 | shModels = ['cylindrical','none','shear - 2/m','rolling - mmm'] |
---|
| 506 | SamSym = dict(zip(shModels,['0','-1','2/m','mmm'])) |
---|
| 507 | sam = SamSym[textureData['Model']] |
---|
| 508 | phaseRest = restraintDict.get(phase,{}) |
---|
| 509 | names = {'Bond':'Bonds','Angle':'Angles','Plane':'Planes', |
---|
| 510 | 'Chiral':'Volumes','Torsion':'Torsions','Rama':'Ramas', |
---|
| 511 | 'ChemComp':'Sites','Texture':'HKLs'} |
---|
| 512 | lasthkl = np.array([0,0,0]) |
---|
[3802] | 513 | for ip,pName in enumerate(pNames): # loop over restraints |
---|
[1299] | 514 | pnames = pName.split(':') |
---|
| 515 | if pId == int(pnames[0]): |
---|
| 516 | name = pnames[1] |
---|
| 517 | if 'PWL' in pName: |
---|
| 518 | pDerv[varyList.index(pName)][ip] += 1. |
---|
| 519 | continue |
---|
[1775] | 520 | elif 'SH-' in pName: |
---|
| 521 | continue |
---|
[1299] | 522 | id = int(pnames[2]) |
---|
| 523 | itemRest = phaseRest[name] |
---|
| 524 | if name in ['Bond','Angle','Plane','Chiral']: |
---|
| 525 | indx,ops,obs,esd = itemRest[names[name]][id] |
---|
| 526 | dNames = [] |
---|
| 527 | for ind in indx: |
---|
| 528 | dNames += [str(pId)+'::dA'+Xname+':'+str(AtLookup[ind]) for Xname in ['x','y','z']] |
---|
| 529 | XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx)) |
---|
| 530 | if name == 'Bond': |
---|
| 531 | deriv = G2mth.getRestDeriv(G2mth.getRestDist,XYZ,Amat,ops,SGData) |
---|
| 532 | elif name == 'Angle': |
---|
| 533 | deriv = G2mth.getRestDeriv(G2mth.getRestAngle,XYZ,Amat,ops,SGData) |
---|
| 534 | elif name == 'Plane': |
---|
| 535 | deriv = G2mth.getRestDeriv(G2mth.getRestPlane,XYZ,Amat,ops,SGData) |
---|
| 536 | elif name == 'Chiral': |
---|
| 537 | deriv = G2mth.getRestDeriv(G2mth.getRestChiral,XYZ,Amat,ops,SGData) |
---|
| 538 | elif name in ['Torsion','Rama']: |
---|
| 539 | coffDict = itemRest['Coeff'] |
---|
| 540 | indx,ops,cofName,esd = itemRest[names[name]][id] |
---|
| 541 | dNames = [] |
---|
| 542 | for ind in indx: |
---|
| 543 | dNames += [str(pId)+'::dA'+Xname+':'+str(AtLookup[ind]) for Xname in ['x','y','z']] |
---|
| 544 | XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx)) |
---|
| 545 | if name == 'Torsion': |
---|
| 546 | deriv = G2mth.getTorsionDeriv(XYZ,Amat,coffDict[cofName]) |
---|
| 547 | else: |
---|
| 548 | deriv = G2mth.getRamaDeriv(XYZ,Amat,coffDict[cofName]) |
---|
| 549 | elif name == 'ChemComp': |
---|
| 550 | indx,factors,obs,esd = itemRest[names[name]][id] |
---|
| 551 | dNames = [] |
---|
| 552 | for ind in indx: |
---|
| 553 | dNames += [str(pId)+'::Afrac:'+str(AtLookup[ind])] |
---|
[2512] | 554 | mul = np.array(G2mth.GetAtomItemsById(Atoms,AtLookup,indx,cs+1)) |
---|
[1299] | 555 | deriv = mul*factors |
---|
| 556 | elif 'Texture' in name: |
---|
| 557 | deriv = [] |
---|
| 558 | dNames = [] |
---|
| 559 | hkl,grid,esd1,ifesd2,esd2 = itemRest[names[name]][id] |
---|
| 560 | hkl = np.array(hkl) |
---|
| 561 | if np.any(lasthkl-hkl): |
---|
| 562 | phi,beta = G2lat.CrsAng(np.array(hkl),cell,SGData) |
---|
| 563 | ODFln = G2lat.Flnh(False,SHCoef,phi,beta,SGData) |
---|
| 564 | lasthkl = copy.copy(hkl) |
---|
| 565 | if 'unit' in name: |
---|
| 566 | pass |
---|
| 567 | else: |
---|
| 568 | gam = float(pnames[3]) |
---|
| 569 | psi = float(pnames[4]) |
---|
| 570 | for SHname in ODFln: |
---|
| 571 | l,m,n = eval(SHname[1:]) |
---|
| 572 | Ksl = G2lat.GetKsl(l,m,sam,psi,gam)[0] |
---|
| 573 | dNames += [str(pId)+'::'+SHname] |
---|
| 574 | deriv.append(-ODFln[SHname][0]*Ksl/SHCoef[SHname]) |
---|
[3802] | 575 | elif name == 'General': |
---|
| 576 | deriv = [] |
---|
| 577 | dNames = [] |
---|
| 578 | eq,obs,esd = itemRest[name][id] |
---|
| 579 | calcobj = G2obj.ExpressionCalcObj(eq) |
---|
| 580 | parmlist = list(eq.assgnVars.values()) # parameters used in this expression |
---|
| 581 | for parm in parmlist: # expand list if any parms are determined by constraints |
---|
| 582 | if parm in G2mv.dependentVars: |
---|
| 583 | parmlist += G2mv.independentVars |
---|
| 584 | break |
---|
| 585 | for ind,var in enumerate(varyList): |
---|
| 586 | drv = 0 |
---|
| 587 | if var in parmlist: |
---|
| 588 | step = stepDict.get(var,1e-5) |
---|
| 589 | calc = [] |
---|
| 590 | # apply step to parameter |
---|
| 591 | oneparm = True |
---|
| 592 | for s in -step,2*step: |
---|
| 593 | parmDict[var] += s |
---|
| 594 | # extend shift if needed to other parameters |
---|
| 595 | if var in G2mv.independentVars: |
---|
| 596 | G2mv.Dict2Map(parmDict,[]) |
---|
| 597 | oneparm = False |
---|
| 598 | elif var in G2mv.dependentVars: |
---|
| 599 | G2mv.Map2Dict(parmDict,[]) |
---|
| 600 | oneparm = False |
---|
| 601 | if 'RB' in var: |
---|
| 602 | ApplyRBModels(parmDict,Phases,rigidbodyDict) |
---|
| 603 | # test |
---|
| 604 | oneparm = False |
---|
| 605 | calcobj.SetupCalc(parmDict) |
---|
| 606 | calc.append(calcobj.EvalExpression()) |
---|
| 607 | drv = (calc[1]-calc[0])*.5/step |
---|
| 608 | # restore the dict |
---|
| 609 | if oneparm: |
---|
| 610 | parmDict[var] = parmDict0[var] |
---|
| 611 | else: |
---|
| 612 | parmDict = parmDict0.copy() |
---|
| 613 | else: |
---|
| 614 | drv = 0 |
---|
| 615 | pDerv[ind][ip] = drv |
---|
| 616 | # Add derivatives into matrix, if needed |
---|
[1299] | 617 | for dName,drv in zip(dNames,deriv): |
---|
| 618 | try: |
---|
| 619 | ind = varyList.index(dName) |
---|
| 620 | pDerv[ind][ip] += drv |
---|
| 621 | except ValueError: |
---|
| 622 | pass |
---|
[1775] | 623 | |
---|
[1777] | 624 | lasthkl = np.array([0,0,0]) |
---|
| 625 | for ip,pName in enumerate(pNames): |
---|
| 626 | deriv = [] |
---|
| 627 | dNames = [] |
---|
| 628 | pnames = pName.split(':') |
---|
| 629 | if 'SH-' in pName and pId == int(pnames[0]): |
---|
| 630 | hId = int(pnames[1]) |
---|
| 631 | phfx = '%d:%d:'%(pId,hId) |
---|
| 632 | psi = float(pnames[4]) |
---|
| 633 | HKLs = calcControls[phfx+'SHhkl'] |
---|
| 634 | SHnames = calcControls[phfx+'SHnames'] |
---|
| 635 | SHcof = dict(zip(SHnames,[parmDict[phfx+cof] for cof in SHnames])) |
---|
| 636 | hkl = np.array(HKLs[int(pnames[3])]) |
---|
| 637 | if np.any(lasthkl-hkl): |
---|
| 638 | phi,beta = G2lat.CrsAng(np.array(hkl),cell,SGData) |
---|
| 639 | SH3Coef = {} |
---|
| 640 | for item in SHcof: |
---|
| 641 | L,N = eval(item.strip('C')) |
---|
| 642 | SH3Coef['C%d,0,%d'%(L,N)] = SHcof[item] |
---|
| 643 | ODFln = G2lat.Flnh(False,SH3Coef,phi,beta,SGData) |
---|
| 644 | lasthkl = copy.copy(hkl) |
---|
| 645 | for SHname in SHnames: |
---|
| 646 | l,n = eval(SHname[1:]) |
---|
| 647 | SH3name = 'C%d,0,%d'%(l,n) |
---|
| 648 | Ksl = G2lat.GetKsl(l,0,'0',psi,0.0)[0] |
---|
| 649 | dNames += [phfx+SHname] |
---|
| 650 | deriv.append(ODFln[SH3name][0]*Ksl/SHcof[SHname]) |
---|
| 651 | for dName,drv in zip(dNames,deriv): |
---|
| 652 | try: |
---|
| 653 | ind = varyList.index(dName) |
---|
| 654 | pDerv[ind][ip] += drv |
---|
| 655 | except ValueError: |
---|
| 656 | pass |
---|
[1299] | 657 | return pDerv |
---|
| 658 | |
---|
| 659 | ################################################################################ |
---|
| 660 | ##### Function & derivative calculations |
---|
| 661 | ################################################################################ |
---|
| 662 | |
---|
| 663 | def GetAtomFXU(pfx,calcControls,parmDict): |
---|
| 664 | 'Needs a doc string' |
---|
| 665 | Natoms = calcControls['Natoms'][pfx] |
---|
| 666 | Tdata = Natoms*[' ',] |
---|
| 667 | Mdata = np.zeros(Natoms) |
---|
| 668 | IAdata = Natoms*[' ',] |
---|
| 669 | Fdata = np.zeros(Natoms) |
---|
| 670 | Xdata = np.zeros((3,Natoms)) |
---|
| 671 | dXdata = np.zeros((3,Natoms)) |
---|
| 672 | Uisodata = np.zeros(Natoms) |
---|
| 673 | Uijdata = np.zeros((6,Natoms)) |
---|
[2478] | 674 | Gdata = np.zeros((3,Natoms)) |
---|
[1299] | 675 | keys = {'Atype:':Tdata,'Amul:':Mdata,'Afrac:':Fdata,'AI/A:':IAdata, |
---|
| 676 | 'dAx:':dXdata[0],'dAy:':dXdata[1],'dAz:':dXdata[2], |
---|
| 677 | 'Ax:':Xdata[0],'Ay:':Xdata[1],'Az:':Xdata[2],'AUiso:':Uisodata, |
---|
| 678 | 'AU11:':Uijdata[0],'AU22:':Uijdata[1],'AU33:':Uijdata[2], |
---|
[2478] | 679 | 'AU12:':Uijdata[3],'AU13:':Uijdata[4],'AU23:':Uijdata[5], |
---|
[2480] | 680 | 'AMx:':Gdata[0],'AMy:':Gdata[1],'AMz:':Gdata[2],} |
---|
[1299] | 681 | for iatm in range(Natoms): |
---|
| 682 | for key in keys: |
---|
| 683 | parm = pfx+key+str(iatm) |
---|
| 684 | if parm in parmDict: |
---|
| 685 | keys[key][iatm] = parmDict[parm] |
---|
[1924] | 686 | Fdata = np.where(Fdata,Fdata,1.e-8) #avoid divide by zero in derivative calc. |
---|
[3595] | 687 | Gdata = np.where(Gdata,Gdata,1.e-8) #avoid divide by zero in derivative calc. |
---|
| 688 | |
---|
[2478] | 689 | return Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata |
---|
[1299] | 690 | |
---|
[1618] | 691 | def GetAtomSSFXU(pfx,calcControls,parmDict): |
---|
| 692 | 'Needs a doc string' |
---|
| 693 | Natoms = calcControls['Natoms'][pfx] |
---|
[1625] | 694 | maxSSwave = calcControls['maxSSwave'][pfx] |
---|
[1618] | 695 | Nwave = {'F':maxSSwave['Sfrac'],'X':maxSSwave['Spos'],'Y':maxSSwave['Spos'],'Z':maxSSwave['Spos'], |
---|
[1630] | 696 | 'U':maxSSwave['Sadp'],'M':maxSSwave['Smag'],'T':maxSSwave['Spos']} |
---|
[1618] | 697 | XSSdata = np.zeros((6,maxSSwave['Spos'],Natoms)) |
---|
| 698 | FSSdata = np.zeros((2,maxSSwave['Sfrac'],Natoms)) |
---|
| 699 | USSdata = np.zeros((12,maxSSwave['Sadp'],Natoms)) |
---|
| 700 | MSSdata = np.zeros((6,maxSSwave['Smag'],Natoms)) |
---|
[1630] | 701 | waveTypes = [] |
---|
[1625] | 702 | keys = {'Fsin:':FSSdata[0],'Fcos:':FSSdata[1],'Fzero:':FSSdata[0],'Fwid:':FSSdata[1], |
---|
[2067] | 703 | 'Tmin:':XSSdata[0],'Tmax:':XSSdata[1],'Xmax:':XSSdata[2],'Ymax:':XSSdata[3],'Zmax:':XSSdata[4], |
---|
[1618] | 704 | 'Xsin:':XSSdata[0],'Ysin:':XSSdata[1],'Zsin:':XSSdata[2],'Xcos:':XSSdata[3],'Ycos:':XSSdata[4],'Zcos:':XSSdata[5], |
---|
| 705 | 'U11sin:':USSdata[0],'U22sin:':USSdata[1],'U33sin:':USSdata[2],'U12sin:':USSdata[3],'U13sin:':USSdata[4],'U23sin:':USSdata[5], |
---|
| 706 | 'U11cos:':USSdata[6],'U22cos:':USSdata[7],'U33cos:':USSdata[8],'U12cos:':USSdata[9],'U13cos:':USSdata[10],'U23cos:':USSdata[11], |
---|
| 707 | 'MXsin:':MSSdata[0],'MYsin:':MSSdata[1],'MZsin:':MSSdata[2],'MXcos:':MSSdata[3],'MYcos:':MSSdata[4],'MZcos:':MSSdata[5]} |
---|
| 708 | for iatm in range(Natoms): |
---|
[3764] | 709 | wavetype = [parmDict.get(pfx+kind+'waveType:'+str(iatm),'') for kind in ['F','P','A','M']] |
---|
| 710 | waveTypes.append(wavetype) |
---|
[1618] | 711 | for key in keys: |
---|
| 712 | for m in range(Nwave[key[0]]): |
---|
| 713 | parm = pfx+key+str(iatm)+':%d'%(m) |
---|
| 714 | if parm in parmDict: |
---|
[1630] | 715 | keys[key][m][iatm] = parmDict[parm] |
---|
[3764] | 716 | return waveTypes,FSSdata,XSSdata,USSdata,MSSdata |
---|
[1618] | 717 | |
---|
[1299] | 718 | def StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict): |
---|
| 719 | ''' Compute structure factors for all h,k,l for phase |
---|
| 720 | puts the result, F^2, in each ref[8] in refList |
---|
[2097] | 721 | operates on blocks of 100 reflections for speed |
---|
[1299] | 722 | input: |
---|
| 723 | |
---|
| 724 | :param dict refDict: where |
---|
[2097] | 725 | 'RefList' list where each ref = h,k,l,it,d,... |
---|
[1299] | 726 | 'FF' dict of form factors - filed in below |
---|
| 727 | :param np.array G: reciprocal metric tensor |
---|
| 728 | :param str pfx: phase id string |
---|
| 729 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 730 | :param dict calcControls: |
---|
| 731 | :param dict ParmDict: |
---|
| 732 | |
---|
| 733 | ''' |
---|
| 734 | phfx = pfx.split(':')[0]+hfx |
---|
| 735 | ast = np.sqrt(np.diag(G)) |
---|
| 736 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
| 737 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
| 738 | SGT = np.array([ops[1] for ops in SGData['SGOps']]) |
---|
| 739 | FFtables = calcControls['FFtables'] |
---|
| 740 | BLtables = calcControls['BLtables'] |
---|
[2480] | 741 | Amat,Bmat = G2lat.Gmat2AB(G) |
---|
[1878] | 742 | Flack = 1.0 |
---|
[1894] | 743 | if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict: |
---|
[1878] | 744 | Flack = 1.-2.*parmDict[phfx+'Flack'] |
---|
[1886] | 745 | TwinLaw = np.array([[[1,0,0],[0,1,0],[0,0,1]],]) |
---|
[1914] | 746 | TwDict = refDict.get('TwDict',{}) |
---|
[1886] | 747 | if 'S' in calcControls[hfx+'histType']: |
---|
[1923] | 748 | NTL = calcControls[phfx+'NTL'] |
---|
| 749 | NM = calcControls[phfx+'TwinNMN']+1 |
---|
[1886] | 750 | TwinLaw = calcControls[phfx+'TwinLaw'] |
---|
[1894] | 751 | TwinFr = np.array([parmDict[phfx+'TwinFr:'+str(i)] for i in range(len(TwinLaw))]) |
---|
[1917] | 752 | TwinInv = list(np.where(calcControls[phfx+'TwinInv'],-1,1)) |
---|
[2478] | 753 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 754 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 755 | if not Xdata.size: #no atoms in phase! |
---|
| 756 | return |
---|
[1453] | 757 | if 'NC' in calcControls[hfx+'histType']: |
---|
[1391] | 758 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam']) |
---|
[1453] | 759 | elif 'X' in calcControls[hfx+'histType']: |
---|
[1299] | 760 | FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata]) |
---|
| 761 | FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata]) |
---|
| 762 | Uij = np.array(G2lat.U6toUij(Uijdata)) |
---|
| 763 | bij = Mast*Uij.T |
---|
[2094] | 764 | blkSize = 100 #no. of reflections in a block - size seems optimal |
---|
[1299] | 765 | nRef = refDict['RefList'].shape[0] |
---|
[2750] | 766 | SQ = 1./(2.*refDict['RefList'].T[4])**2 |
---|
| 767 | if 'N' in calcControls[hfx+'histType']: |
---|
| 768 | dat = G2el.getBLvalues(BLtables) |
---|
[3136] | 769 | refDict['FF']['El'] = list(dat.keys()) |
---|
| 770 | refDict['FF']['FF'] = np.ones((nRef,len(dat)))*list(dat.values()) |
---|
[2750] | 771 | else: #'X' |
---|
| 772 | dat = G2el.getFFvalues(FFtables,0.) |
---|
[3136] | 773 | refDict['FF']['El'] = list(dat.keys()) |
---|
[2750] | 774 | refDict['FF']['FF'] = np.zeros((nRef,len(dat))) |
---|
| 775 | for iel,El in enumerate(refDict['FF']['El']): |
---|
| 776 | refDict['FF']['FF'].T[iel] = G2el.ScatFac(FFtables[El],SQ) |
---|
[1299] | 777 | #reflection processing begins here - big arrays! |
---|
[1910] | 778 | iBeg = 0 |
---|
[1299] | 779 | while iBeg < nRef: |
---|
| 780 | iFin = min(iBeg+blkSize,nRef) |
---|
[1886] | 781 | refl = refDict['RefList'][iBeg:iFin] #array(blkSize,nItems) |
---|
| 782 | H = refl.T[:3] #array(blkSize,3) |
---|
[1912] | 783 | H = np.squeeze(np.inner(H.T,TwinLaw)) #maybe array(blkSize,nTwins,3) or (blkSize,3) |
---|
[1913] | 784 | TwMask = np.any(H,axis=-1) |
---|
[1918] | 785 | if TwinLaw.shape[0] > 1 and TwDict: #need np.inner(TwinLaw[?],TwDict[iref][i])*TwinInv[i] |
---|
[1912] | 786 | for ir in range(blkSize): |
---|
| 787 | iref = ir+iBeg |
---|
[1914] | 788 | if iref in TwDict: |
---|
| 789 | for i in TwDict[iref]: |
---|
[1923] | 790 | for n in range(NTL): |
---|
| 791 | H[ir][i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM]) |
---|
[1913] | 792 | TwMask = np.any(H,axis=-1) |
---|
[1886] | 793 | SQ = 1./(2.*refl.T[4])**2 #array(blkSize) |
---|
| 794 | SQfactor = 4.0*SQ*twopisq #ditto prev. |
---|
[1453] | 795 | if 'T' in calcControls[hfx+'histType']: |
---|
[1459] | 796 | if 'P' in calcControls[hfx+'histType']: |
---|
| 797 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[14]) |
---|
| 798 | else: |
---|
| 799 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[12]) |
---|
[1886] | 800 | FP = np.repeat(FP.T,len(SGT)*len(TwinLaw),axis=0) |
---|
| 801 | FPP = np.repeat(FPP.T,len(SGT)*len(TwinLaw),axis=0) |
---|
| 802 | Uniq = np.inner(H,SGMT) |
---|
| 803 | Phi = np.inner(H,SGT) |
---|
| 804 | phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T).T+Phi.T).T |
---|
[1299] | 805 | sinp = np.sin(phase) |
---|
| 806 | cosp = np.cos(phase) |
---|
[2094] | 807 | biso = -SQfactor*Uisodata[:,nxs] |
---|
[1886] | 808 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT)*len(TwinLaw),axis=1).T |
---|
| 809 | HbH = -np.sum(Uniq.T*np.swapaxes(np.inner(bij,Uniq),2,-1),axis=1) |
---|
[1299] | 810 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0).T |
---|
[1886] | 811 | Tcorr = np.reshape(Tiso,Tuij.shape)*Tuij*Mdata*Fdata/len(SGMT) |
---|
[2506] | 812 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
[2478] | 813 | FF = np.repeat(refDict['FF']['FF'][iBeg:iFin].T[Tindx].T,len(SGT)*len(TwinLaw),axis=0) |
---|
[3320] | 814 | Bab = np.repeat(parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor),len(SGT)*len(TwinLaw)) |
---|
| 815 | if 'T' in calcControls[hfx+'histType']: #fa,fb are 2 X blkSize X nTwin X nOps x nAtoms |
---|
| 816 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-np.reshape(Flack*FPP,sinp.shape)*sinp*Tcorr]) |
---|
| 817 | fb = np.array([np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr,np.reshape(Flack*FPP,cosp.shape)*cosp*Tcorr]) |
---|
[1886] | 818 | else: |
---|
[3320] | 819 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-Flack*FPP*sinp*Tcorr]) |
---|
| 820 | fb = np.array([np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr,Flack*FPP*cosp*Tcorr]) |
---|
| 821 | fas = np.sum(np.sum(fa,axis=-1),axis=-1) #real 2 x blkSize x nTwin; sum over atoms & uniq hkl |
---|
| 822 | fbs = np.sum(np.sum(fb,axis=-1),axis=-1) #imag |
---|
| 823 | if SGData['SGInv']: #centrosymmetric; B=0 |
---|
| 824 | fbs[0] *= 0. |
---|
| 825 | fas[1] *= 0. |
---|
| 826 | if 'P' in calcControls[hfx+'histType']: #PXC, PNC & PNT: F^2 = A[0]^2 + A[1]^2 + B[0]^2 + B[1]^2 |
---|
| 827 | refl.T[9] = np.sum(fas**2,axis=0)+np.sum(fbs**2,axis=0) #add fam**2 & fbm**2 here |
---|
| 828 | refl.T[10] = atan2d(fbs[0],fas[0]) #ignore f' & f" |
---|
| 829 | else: #HKLF: F^2 = (A[0]+A[1])^2 + (B[0]+B[1])^2 |
---|
| 830 | if len(TwinLaw) > 1: |
---|
| 831 | refl.T[9] = np.sum(fas[:,:,0],axis=0)**2+np.sum(fbs[:,:,0],axis=0)**2 #FcT from primary twin element |
---|
| 832 | refl.T[7] = np.sum(TwinFr*TwMask*np.sum(fas,axis=0)**2,axis=-1)+ \ |
---|
| 833 | np.sum(TwinFr*TwMask*np.sum(fbs,axis=0)**2,axis=-1) #Fc sum over twins |
---|
| 834 | refl.T[10] = atan2d(fbs[0].T[0],fas[0].T[0]) #ignore f' & f" & use primary twin |
---|
| 835 | else: # checked correct!! |
---|
| 836 | refl.T[9] = np.sum(fas,axis=0)**2+np.sum(fbs,axis=0)**2 |
---|
| 837 | refl.T[7] = np.copy(refl.T[9]) |
---|
[1886] | 838 | refl.T[10] = atan2d(fbs[0],fas[0]) #ignore f' & f" |
---|
[2110] | 839 | # refl.T[10] = atan2d(np.sum(fbs,axis=0),np.sum(fas,axis=0)) #include f' & f" |
---|
[1299] | 840 | iBeg += blkSize |
---|
[2838] | 841 | # print 'sf time %.4f, nref %d, blkSize %d'%(time.time()-time0,nRef,blkSize) |
---|
[1299] | 842 | |
---|
[2094] | 843 | def StructureFactorDerv2(refDict,G,hfx,pfx,SGData,calcControls,parmDict): |
---|
[2097] | 844 | '''Compute structure factor derivatives on blocks of reflections - for powders/nontwins only |
---|
[2110] | 845 | faster than StructureFactorDerv - correct for powders/nontwins!! |
---|
| 846 | input: |
---|
| 847 | |
---|
| 848 | :param dict refDict: where |
---|
| 849 | 'RefList' list where each ref = h,k,l,it,d,... |
---|
| 850 | 'FF' dict of form factors - filled in below |
---|
| 851 | :param np.array G: reciprocal metric tensor |
---|
| 852 | :param str hfx: histogram id string |
---|
| 853 | :param str pfx: phase id string |
---|
| 854 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 855 | :param dict calcControls: |
---|
| 856 | :param dict parmDict: |
---|
| 857 | |
---|
| 858 | :returns: dict dFdvDict: dictionary of derivatives |
---|
[2094] | 859 | ''' |
---|
| 860 | phfx = pfx.split(':')[0]+hfx |
---|
| 861 | ast = np.sqrt(np.diag(G)) |
---|
| 862 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
[3803] | 863 | SGMT = np.array([ops[0] for ops in SGData['SGOps']]) |
---|
[2094] | 864 | SGT = np.array([ops[1] for ops in SGData['SGOps']]) |
---|
| 865 | FFtables = calcControls['FFtables'] |
---|
| 866 | BLtables = calcControls['BLtables'] |
---|
[2483] | 867 | Amat,Bmat = G2lat.Gmat2AB(G) |
---|
[2097] | 868 | nRef = len(refDict['RefList']) |
---|
[2478] | 869 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 870 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 871 | if not Xdata.size: #no atoms in phase! |
---|
| 872 | return {} |
---|
[2097] | 873 | mSize = len(Mdata) |
---|
| 874 | FF = np.zeros(len(Tdata)) |
---|
| 875 | if 'NC' in calcControls[hfx+'histType']: |
---|
| 876 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam']) |
---|
| 877 | elif 'X' in calcControls[hfx+'histType']: |
---|
| 878 | FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata]) |
---|
| 879 | FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata]) |
---|
| 880 | Uij = np.array(G2lat.U6toUij(Uijdata)) |
---|
| 881 | bij = Mast*Uij.T |
---|
| 882 | dFdvDict = {} |
---|
| 883 | dFdfr = np.zeros((nRef,mSize)) |
---|
| 884 | dFdx = np.zeros((nRef,mSize,3)) |
---|
| 885 | dFdui = np.zeros((nRef,mSize)) |
---|
| 886 | dFdua = np.zeros((nRef,mSize,6)) |
---|
| 887 | dFdbab = np.zeros((nRef,2)) |
---|
| 888 | dFdfl = np.zeros((nRef)) |
---|
| 889 | Flack = 1.0 |
---|
| 890 | if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict: |
---|
| 891 | Flack = 1.-2.*parmDict[phfx+'Flack'] |
---|
[3802] | 892 | # time0 = time.time() |
---|
[2097] | 893 | #reflection processing begins here - big arrays! |
---|
| 894 | iBeg = 0 |
---|
| 895 | blkSize = 32 #no. of reflections in a block - optimized for speed |
---|
| 896 | while iBeg < nRef: |
---|
| 897 | iFin = min(iBeg+blkSize,nRef) |
---|
| 898 | refl = refDict['RefList'][iBeg:iFin] #array(blkSize,nItems) |
---|
[2484] | 899 | H = refl.T[:3].T |
---|
[2097] | 900 | SQ = 1./(2.*refl.T[4])**2 # or (sin(theta)/lambda)**2 |
---|
| 901 | SQfactor = 8.0*SQ*np.pi**2 |
---|
| 902 | if 'T' in calcControls[hfx+'histType']: |
---|
| 903 | if 'P' in calcControls[hfx+'histType']: |
---|
| 904 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[14]) |
---|
| 905 | else: |
---|
| 906 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[12]) |
---|
| 907 | FP = np.repeat(FP.T,len(SGT),axis=0) |
---|
| 908 | FPP = np.repeat(FPP.T,len(SGT),axis=0) |
---|
| 909 | dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor) |
---|
| 910 | Bab = np.repeat(parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor),len(SGT)) |
---|
| 911 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
| 912 | FF = np.repeat(refDict['FF']['FF'][iBeg:iFin].T[Tindx].T,len(SGT),axis=0) |
---|
[2484] | 913 | Uniq = np.inner(H,SGMT) # array(nSGOp,3) |
---|
| 914 | Phi = np.inner(H,SGT) |
---|
[2097] | 915 | phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T).T+Phi.T).T |
---|
| 916 | sinp = np.sin(phase) #refBlk x nOps x nAtoms |
---|
| 917 | cosp = np.cos(phase) |
---|
| 918 | occ = Mdata*Fdata/len(SGT) |
---|
| 919 | biso = -SQfactor*Uisodata[:,nxs] |
---|
| 920 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT),axis=1).T |
---|
[3774] | 921 | HbH = -np.sum(Uniq.T*np.swapaxes(np.inner(bij,Uniq),2,-1),axis=1) |
---|
| 922 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0).T |
---|
[2097] | 923 | Tcorr = np.reshape(Tiso,Tuij.shape)*Tuij*Mdata*Fdata/len(SGMT) |
---|
[2753] | 924 | Hij = np.array([Mast*np.multiply.outer(U,U) for U in np.reshape(Uniq,(-1,3))]) #Nref*Nops,3,3 |
---|
| 925 | Hij = np.reshape(np.array([G2lat.UijtoU6(uij) for uij in Hij]),(-1,len(SGT),6)) #Nref,Nops,6 |
---|
[2097] | 926 | fot = np.reshape(((FF+FP).T-Bab).T,cosp.shape)*Tcorr |
---|
[2121] | 927 | if len(FPP.shape) > 1: |
---|
| 928 | fotp = np.reshape(FPP,cosp.shape)*Tcorr |
---|
| 929 | else: |
---|
| 930 | fotp = FPP*Tcorr |
---|
[2097] | 931 | if 'T' in calcControls[hfx+'histType']: |
---|
[2110] | 932 | fa = np.array([fot*cosp,-np.reshape(Flack*FPP,sinp.shape)*sinp*Tcorr]) |
---|
| 933 | fb = np.array([fot*sinp,np.reshape(Flack*FPP,cosp.shape)*cosp*Tcorr]) |
---|
[2097] | 934 | else: |
---|
[2110] | 935 | fa = np.array([fot*cosp,-Flack*FPP*sinp*Tcorr]) |
---|
| 936 | fb = np.array([fot*sinp,Flack*FPP*cosp*Tcorr]) |
---|
[2097] | 937 | fas = np.sum(np.sum(fa,axis=-1),axis=-1) #real sum over atoms & unique hkl array(2,refBlk,nTwins) |
---|
| 938 | fbs = np.sum(np.sum(fb,axis=-1),axis=-1) #imag sum over atoms & uniq hkl |
---|
[2121] | 939 | fax = np.array([-fot*sinp,-fotp*cosp]) #positions array(2,refBlk,nEqv,nAtoms) |
---|
[2097] | 940 | fbx = np.array([fot*cosp,-fotp*sinp]) |
---|
[2484] | 941 | #sum below is over Uniq |
---|
[2495] | 942 | dfadfr = np.sum(fa/occ,axis=-2) #array(2,refBlk,nAtom) Fdata != 0 avoids /0. problem |
---|
| 943 | dfadba = np.sum(-cosp*Tcorr,axis=-2) #array(refBlk,nAtom) |
---|
| 944 | dfadx = np.sum(twopi*Uniq[nxs,:,nxs,:,:]*np.swapaxes(fax,-2,-1)[:,:,:,:,nxs],axis=-2) |
---|
| 945 | dfadui = np.sum(-SQfactor[nxs,:,nxs,nxs]*fa,axis=-2) #array(Ops,refBlk,nAtoms) |
---|
| 946 | dfadua = np.sum(-Hij[nxs,:,nxs,:,:]*np.swapaxes(fa,-2,-1)[:,:,:,:,nxs],axis=-2) |
---|
[2097] | 947 | # array(2,refBlk,nAtom,3) & array(2,refBlk,nAtom,6) |
---|
| 948 | if not SGData['SGInv']: |
---|
[2495] | 949 | dfbdfr = np.sum(fb/occ,axis=-2) #Fdata != 0 avoids /0. problem |
---|
| 950 | dfbdba = np.sum(-sinp*Tcorr,axis=-2) |
---|
| 951 | dfadfl = np.sum(np.sum(-fotp*sinp,axis=-1),axis=-1) |
---|
| 952 | dfbdfl = np.sum(np.sum(fotp*cosp,axis=-1),axis=-1) |
---|
| 953 | dfbdx = np.sum(twopi*Uniq[nxs,:,nxs,:,:]*np.swapaxes(fbx,-2,-1)[:,:,:,:,nxs],axis=-2) |
---|
| 954 | dfbdui = np.sum(-SQfactor[nxs,:,nxs,nxs]*fb,axis=-2) |
---|
| 955 | dfbdua = np.sum(-Hij[nxs,:,nxs,:,:]*np.swapaxes(fb,-2,-1)[:,:,:,:,nxs],axis=-2) |
---|
[2097] | 956 | else: |
---|
| 957 | dfbdfr = np.zeros_like(dfadfr) |
---|
| 958 | dfbdx = np.zeros_like(dfadx) |
---|
| 959 | dfbdui = np.zeros_like(dfadui) |
---|
| 960 | dfbdua = np.zeros_like(dfadua) |
---|
| 961 | dfbdba = np.zeros_like(dfadba) |
---|
| 962 | dfadfl = 0.0 |
---|
| 963 | dfbdfl = 0.0 |
---|
| 964 | #NB: the above have been checked against PA(1:10,1:2) in strfctr.for for Al2O3! |
---|
| 965 | SA = fas[0]+fas[1] |
---|
| 966 | SB = fbs[0]+fbs[1] |
---|
| 967 | if 'P' in calcControls[hfx+'histType']: #checked perfect for centro & noncentro |
---|
[2495] | 968 | dFdfr[iBeg:iFin] = 2.*np.sum(fas[:,:,nxs]*dfadfr+fbs[:,:,nxs]*dfbdfr,axis=0)*Mdata/len(SGMT) |
---|
| 969 | dFdx[iBeg:iFin] = 2.*np.sum(fas[:,:,nxs,nxs]*dfadx+fbs[:,:,nxs,nxs]*dfbdx,axis=0) |
---|
| 970 | dFdui[iBeg:iFin] = 2.*np.sum(fas[:,:,nxs]*dfadui+fbs[:,:,nxs]*dfbdui,axis=0) |
---|
| 971 | dFdua[iBeg:iFin] = 2.*np.sum(fas[:,:,nxs,nxs]*dfadua+fbs[:,:,nxs,nxs]*dfbdua,axis=0) |
---|
[2097] | 972 | else: |
---|
| 973 | dFdfr[iBeg:iFin] = (2.*SA[:,nxs]*(dfadfr[0]+dfadfr[1])+2.*SB[:,nxs]*(dfbdfr[0]+dfbdfr[1]))*Mdata/len(SGMT) |
---|
| 974 | dFdx[iBeg:iFin] = 2.*SA[:,nxs,nxs]*(dfadx[0]+dfadx[1])+2.*SB[:,nxs,nxs]*(dfbdx[0]+dfbdx[1]) |
---|
| 975 | dFdui[iBeg:iFin] = 2.*SA[:,nxs]*(dfadui[0]+dfadui[1])+2.*SB[:,nxs]*(dfbdui[0]+dfbdui[1]) |
---|
| 976 | dFdua[iBeg:iFin] = 2.*SA[:,nxs,nxs]*(dfadua[0]+dfadua[1])+2.*SB[:,nxs,nxs]*(dfbdua[0]+dfbdua[1]) |
---|
| 977 | dFdfl[iBeg:iFin] = -SA*dfadfl-SB*dfbdfl #array(nRef,) |
---|
| 978 | dFdbab[iBeg:iFin] = 2.*(fas[0,nxs]*np.array([np.sum(dfadba.T*dBabdA,axis=0),np.sum(-dfadba.T*parmDict[phfx+'BabA']*SQfactor*dBabdA,axis=0)])+ \ |
---|
| 979 | fbs[0,nxs]*np.array([np.sum(dfbdba.T*dBabdA,axis=0),np.sum(-dfbdba.T*parmDict[phfx+'BabA']*SQfactor*dBabdA,axis=0)])).T |
---|
| 980 | iBeg += blkSize |
---|
[2838] | 981 | # print 'derv time %.4f, nref %d, blkSize %d'%(time.time()-time0,nRef,blkSize) |
---|
[2097] | 982 | #loop over atoms - each dict entry is list of derivatives for all the reflections |
---|
| 983 | for i in range(len(Mdata)): |
---|
| 984 | dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i] |
---|
| 985 | dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i] |
---|
| 986 | dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i] |
---|
| 987 | dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i] |
---|
| 988 | dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i] |
---|
| 989 | dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i] |
---|
| 990 | dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i] |
---|
| 991 | dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i] |
---|
[3414] | 992 | dFdvDict[pfx+'AU12:'+str(i)] = 2.*dFdua.T[3][i] |
---|
| 993 | dFdvDict[pfx+'AU13:'+str(i)] = 2.*dFdua.T[4][i] |
---|
| 994 | dFdvDict[pfx+'AU23:'+str(i)] = 2.*dFdua.T[5][i] |
---|
[2097] | 995 | dFdvDict[phfx+'Flack'] = 4.*dFdfl.T |
---|
| 996 | dFdvDict[phfx+'BabA'] = dFdbab.T[0] |
---|
| 997 | dFdvDict[phfx+'BabU'] = dFdbab.T[1] |
---|
| 998 | return dFdvDict |
---|
| 999 | |
---|
[3372] | 1000 | def MagStructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict): |
---|
| 1001 | ''' Compute neutron magnetic structure factors for all h,k,l for phase |
---|
| 1002 | puts the result, F^2, in each ref[8] in refList |
---|
| 1003 | operates on blocks of 100 reflections for speed |
---|
| 1004 | input: |
---|
| 1005 | |
---|
| 1006 | :param dict refDict: where |
---|
| 1007 | 'RefList' list where each ref = h,k,l,it,d,... |
---|
| 1008 | 'FF' dict of form factors - filed in below |
---|
| 1009 | :param np.array G: reciprocal metric tensor |
---|
| 1010 | :param str pfx: phase id string |
---|
| 1011 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 1012 | :param dict calcControls: |
---|
| 1013 | :param dict ParmDict: |
---|
[3755] | 1014 | |
---|
| 1015 | :returns: copy of new refList - used in calculating numerical derivatives |
---|
[3372] | 1016 | |
---|
| 1017 | ''' |
---|
| 1018 | g = nl.inv(G) |
---|
| 1019 | ast = np.sqrt(np.diag(G)) |
---|
| 1020 | ainv = np.sqrt(np.diag(g)) |
---|
| 1021 | GS = G/np.outer(ast,ast) |
---|
| 1022 | Ginv = g/np.outer(ainv,ainv) |
---|
| 1023 | uAmat = G2lat.Gmat2AB(GS)[0] |
---|
| 1024 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
| 1025 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
| 1026 | SGT = np.array([ops[1] for ops in SGData['SGOps']]) |
---|
| 1027 | Ncen = len(SGData['SGCen']) |
---|
| 1028 | Nops = len(SGMT)*Ncen |
---|
| 1029 | if not SGData['SGFixed']: |
---|
| 1030 | Nops *= (1+SGData['SGInv']) |
---|
| 1031 | MFtables = calcControls['MFtables'] |
---|
| 1032 | Bmat = G2lat.Gmat2AB(G)[1] |
---|
| 1033 | TwinLaw = np.ones(1) |
---|
| 1034 | # TwinLaw = np.array([[[1,0,0],[0,1,0],[0,0,1]],]) |
---|
| 1035 | # TwDict = refDict.get('TwDict',{}) |
---|
| 1036 | # if 'S' in calcControls[hfx+'histType']: |
---|
| 1037 | # NTL = calcControls[phfx+'NTL'] |
---|
| 1038 | # NM = calcControls[phfx+'TwinNMN']+1 |
---|
| 1039 | # TwinLaw = calcControls[phfx+'TwinLaw'] |
---|
| 1040 | # TwinFr = np.array([parmDict[phfx+'TwinFr:'+str(i)] for i in range(len(TwinLaw))]) |
---|
| 1041 | # TwinInv = list(np.where(calcControls[phfx+'TwinInv'],-1,1)) |
---|
| 1042 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 1043 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
| 1044 | if not Xdata.size: #no atoms in phase! |
---|
| 1045 | return |
---|
| 1046 | Mag = np.array([np.sqrt(np.inner(mag,np.inner(mag,Ginv))) for mag in Gdata.T]) |
---|
[3801] | 1047 | Gdata = np.inner(Gdata.T,np.swapaxes(SGMT,1,2)).T #apply sym. ops. |
---|
[3372] | 1048 | if SGData['SGInv'] and not SGData['SGFixed']: |
---|
| 1049 | Gdata = np.hstack((Gdata,-Gdata)) #inversion if any |
---|
| 1050 | Gdata = np.hstack([Gdata for icen in range(Ncen)]) #dup over cell centering--> [Mxyz,nops,natms] |
---|
| 1051 | Gdata = SGData['MagMom'][nxs,:,nxs]*Gdata #flip vectors according to spin flip * det(opM) |
---|
| 1052 | Mag = np.tile(Mag[:,nxs],Nops).T #make Mag same length as Gdata |
---|
[3805] | 1053 | Kdata = np.inner(Gdata.T,uAmat).T #Cartesian unit vectors |
---|
| 1054 | Kmean = np.mean(np.sqrt(np.sum(Kdata**2,axis=0)),axis=0) |
---|
| 1055 | Kdata /= Kmean |
---|
[3372] | 1056 | Uij = np.array(G2lat.U6toUij(Uijdata)) |
---|
| 1057 | bij = Mast*Uij.T |
---|
| 1058 | blkSize = 100 #no. of reflections in a block - size seems optimal |
---|
| 1059 | nRef = refDict['RefList'].shape[0] |
---|
| 1060 | SQ = 1./(2.*refDict['RefList'].T[4])**2 |
---|
| 1061 | refDict['FF']['El'] = list(MFtables.keys()) |
---|
| 1062 | refDict['FF']['MF'] = np.zeros((nRef,len(MFtables))) |
---|
| 1063 | for iel,El in enumerate(refDict['FF']['El']): |
---|
| 1064 | refDict['FF']['MF'].T[iel] = G2el.MagScatFac(MFtables[El],SQ) |
---|
| 1065 | #reflection processing begins here - big arrays! |
---|
| 1066 | iBeg = 0 |
---|
| 1067 | while iBeg < nRef: |
---|
| 1068 | iFin = min(iBeg+blkSize,nRef) |
---|
| 1069 | refl = refDict['RefList'][iBeg:iFin] #array(blkSize,nItems) |
---|
| 1070 | H = refl.T[:3].T #array(blkSize,3) |
---|
| 1071 | # H = np.squeeze(np.inner(H.T,TwinLaw)) #maybe array(blkSize,nTwins,3) or (blkSize,3) |
---|
| 1072 | # TwMask = np.any(H,axis=-1) |
---|
| 1073 | # if TwinLaw.shape[0] > 1 and TwDict: #need np.inner(TwinLaw[?],TwDict[iref][i])*TwinInv[i] |
---|
| 1074 | # for ir in range(blkSize): |
---|
| 1075 | # iref = ir+iBeg |
---|
| 1076 | # if iref in TwDict: |
---|
| 1077 | # for i in TwDict[iref]: |
---|
| 1078 | # for n in range(NTL): |
---|
| 1079 | # H[ir][i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM]) |
---|
| 1080 | # TwMask = np.any(H,axis=-1) |
---|
| 1081 | SQ = 1./(2.*refl.T[4])**2 #array(blkSize) |
---|
| 1082 | SQfactor = 4.0*SQ*twopisq #ditto prev. |
---|
| 1083 | Uniq = np.inner(H,SGMT) |
---|
| 1084 | Phi = np.inner(H,SGT) |
---|
| 1085 | phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T).T+Phi.T).T |
---|
| 1086 | biso = -SQfactor*Uisodata[:,nxs] |
---|
| 1087 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT)*len(TwinLaw),axis=1).T |
---|
| 1088 | HbH = -np.sum(Uniq.T*np.swapaxes(np.inner(bij,Uniq),2,-1),axis=1) |
---|
| 1089 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0).T |
---|
| 1090 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
| 1091 | MF = refDict['FF']['MF'][iBeg:iFin].T[Tindx].T #Nref,Natm |
---|
| 1092 | TMcorr = 0.539*(np.reshape(Tiso,Tuij.shape)*Tuij)[:,0,:]*Fdata*Mdata*MF/(2*Nops) #Nref,Natm |
---|
| 1093 | if SGData['SGInv']: |
---|
| 1094 | if not SGData['SGFixed']: |
---|
| 1095 | mphase = np.hstack((phase,-phase)) #OK |
---|
| 1096 | else: |
---|
| 1097 | mphase = phase |
---|
| 1098 | else: |
---|
| 1099 | mphase = phase # |
---|
| 1100 | mphase = np.array([mphase+twopi*np.inner(cen,H)[:,nxs,nxs] for cen in SGData['SGCen']]) |
---|
| 1101 | mphase = np.concatenate(mphase,axis=1) #Nref,full Nop,Natm |
---|
| 1102 | sinm = np.sin(mphase) #ditto - match magstrfc.for |
---|
| 1103 | cosm = np.cos(mphase) #ditto |
---|
| 1104 | HM = np.inner(Bmat.T,H) #put into cartesian space |
---|
| 1105 | HM = HM/np.sqrt(np.sum(HM**2,axis=0)) #Kdata = MAGS & HM = UVEC in magstrfc.for both OK |
---|
| 1106 | eDotK = np.sum(HM[:,:,nxs,nxs]*Kdata[:,nxs,:,:],axis=0) |
---|
| 1107 | Q = HM[:,:,nxs,nxs]*eDotK[nxs,:,:,:]-Kdata[:,nxs,:,:] #xyz,Nref,Nop,Natm = BPM in magstrfc.for OK |
---|
| 1108 | fam = Q*TMcorr[nxs,:,nxs,:]*cosm[nxs,:,:,:]*Mag[nxs,nxs,:,:] #ditto |
---|
| 1109 | fbm = Q*TMcorr[nxs,:,nxs,:]*sinm[nxs,:,:,:]*Mag[nxs,nxs,:,:] #ditto |
---|
[3812] | 1110 | fams = np.sum(np.sum(fam,axis=-1),axis=-1) #Mxyz,Nref Sum(sum(fam,atoms),ops) |
---|
| 1111 | fbms = np.sum(np.sum(fbm,axis=-1),axis=-1) #ditto |
---|
| 1112 | refl.T[9] = np.sum(fams**2,axis=0)+np.sum(fbms**2,axis=0) #Sum(fams**2,Mxyz) Re + Im |
---|
[3372] | 1113 | refl.T[7] = np.copy(refl.T[9]) |
---|
[3433] | 1114 | refl.T[10] = atan2d(fbms[0],fams[0]) #- what is phase for mag refl? |
---|
[3372] | 1115 | # if 'P' in calcControls[hfx+'histType']: #PXC, PNC & PNT: F^2 = A[0]^2 + A[1]^2 + B[0]^2 + B[1]^2 |
---|
| 1116 | # refl.T[9] = np.sum(fas**2,axis=0)+np.sum(fbs**2,axis=0) #add fam**2 & fbm**2 here |
---|
| 1117 | # refl.T[10] = atan2d(fbs[0],fas[0]) #ignore f' & f" |
---|
| 1118 | # else: #HKLF: F^2 = (A[0]+A[1])^2 + (B[0]+B[1])^2 |
---|
| 1119 | # if len(TwinLaw) > 1: |
---|
| 1120 | # refl.T[9] = np.sum(fas[:,:,0],axis=0)**2+np.sum(fbs[:,:,0],axis=0)**2 #FcT from primary twin element |
---|
| 1121 | # refl.T[7] = np.sum(TwinFr*TwMask*np.sum(fas,axis=0)**2,axis=-1)+ \ |
---|
| 1122 | # np.sum(TwinFr*TwMask*np.sum(fbs,axis=0)**2,axis=-1) #Fc sum over twins |
---|
| 1123 | # refl.T[10] = atan2d(fbs[0].T[0],fas[0].T[0]) #ignore f' & f" & use primary twin |
---|
| 1124 | # else: # checked correct!! |
---|
| 1125 | # refl.T[9] = np.sum(fas,axis=0)**2+np.sum(fbs,axis=0)**2 |
---|
| 1126 | # refl.T[7] = np.copy(refl.T[9]) |
---|
| 1127 | # refl.T[10] = atan2d(fbs[0],fas[0]) #ignore f' & f" |
---|
| 1128 | ## refl.T[10] = atan2d(np.sum(fbs,axis=0),np.sum(fas,axis=0)) #include f' & f" |
---|
| 1129 | iBeg += blkSize |
---|
| 1130 | # print 'sf time %.4f, nref %d, blkSize %d'%(time.time()-time0,nRef,blkSize) |
---|
[3754] | 1131 | return copy.deepcopy(refDict['RefList']) |
---|
[3372] | 1132 | |
---|
[3754] | 1133 | def MagStructureFactorDerv2(refDict,G,hfx,pfx,SGData,calcControls,parmDict): |
---|
[3755] | 1134 | '''Compute magnetic structure factor derivatives numerically - for powders/nontwins only |
---|
[3754] | 1135 | input: |
---|
| 1136 | |
---|
| 1137 | :param dict refDict: where |
---|
| 1138 | 'RefList' list where each ref = h,k,l,it,d,... |
---|
| 1139 | 'FF' dict of form factors - filled in below |
---|
| 1140 | :param np.array G: reciprocal metric tensor |
---|
| 1141 | :param str hfx: histogram id string |
---|
| 1142 | :param str pfx: phase id string |
---|
| 1143 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 1144 | :param dict calcControls: |
---|
| 1145 | :param dict parmDict: |
---|
| 1146 | |
---|
| 1147 | :returns: dict dFdvDict: dictionary of magnetic derivatives |
---|
| 1148 | ''' |
---|
| 1149 | |
---|
| 1150 | trefDict = copy.deepcopy(refDict) |
---|
[3755] | 1151 | dM = 1.e-6 |
---|
[3754] | 1152 | dFdvDict = {} |
---|
| 1153 | for parm in parmDict: |
---|
| 1154 | if 'AM' in parm: |
---|
| 1155 | parmDict[parm] += dM |
---|
| 1156 | prefList = MagStructureFactor2(trefDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
| 1157 | parmDict[parm] -= 2*dM |
---|
| 1158 | mrefList = MagStructureFactor2(trefDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
| 1159 | parmDict[parm] += dM |
---|
| 1160 | dFdvDict[parm] = (prefList[:,9]-mrefList[:,9])/(2.*dM) |
---|
| 1161 | return dFdvDict |
---|
| 1162 | |
---|
[3372] | 1163 | def MagStructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict): |
---|
[3754] | 1164 | '''Compute nonmagnetic structure factor derivatives on blocks of reflections in magnetic structures - for powders/nontwins only |
---|
[2495] | 1165 | input: |
---|
| 1166 | |
---|
| 1167 | :param dict refDict: where |
---|
| 1168 | 'RefList' list where each ref = h,k,l,it,d,... |
---|
| 1169 | 'FF' dict of form factors - filled in below |
---|
| 1170 | :param np.array G: reciprocal metric tensor |
---|
| 1171 | :param str hfx: histogram id string |
---|
| 1172 | :param str pfx: phase id string |
---|
| 1173 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 1174 | :param dict calcControls: |
---|
| 1175 | :param dict parmDict: |
---|
| 1176 | |
---|
| 1177 | :returns: dict dFdvDict: dictionary of derivatives |
---|
| 1178 | ''' |
---|
[3415] | 1179 | |
---|
[3372] | 1180 | g = nl.inv(G) |
---|
[2495] | 1181 | ast = np.sqrt(np.diag(G)) |
---|
[3372] | 1182 | ainv = np.sqrt(np.diag(g)) |
---|
[3338] | 1183 | GS = G/np.outer(ast,ast) |
---|
[3372] | 1184 | Ginv = g/np.outer(ainv,ainv) |
---|
| 1185 | uAmat = G2lat.Gmat2AB(GS)[0] |
---|
[2495] | 1186 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
| 1187 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
| 1188 | SGT = np.array([ops[1] for ops in SGData['SGOps']]) |
---|
| 1189 | Ncen = len(SGData['SGCen']) |
---|
[3340] | 1190 | Nops = len(SGMT)*Ncen |
---|
| 1191 | if not SGData['SGFixed']: |
---|
| 1192 | Nops *= (1+SGData['SGInv']) |
---|
| 1193 | Bmat = G2lat.Gmat2AB(G)[1] |
---|
[2495] | 1194 | nRef = len(refDict['RefList']) |
---|
| 1195 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 1196 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 1197 | if not Xdata.size: #no atoms in phase! |
---|
| 1198 | return {} |
---|
[2495] | 1199 | mSize = len(Mdata) |
---|
[3372] | 1200 | Mag = np.array([np.sqrt(np.inner(mag,np.inner(mag,Ginv))) for mag in Gdata.T]) |
---|
[3415] | 1201 | Gones = np.ones_like(Gdata) |
---|
[3801] | 1202 | Gdata = np.inner(Gdata.T,np.swapaxes(SGMT,1,2)).T #apply sym. ops. |
---|
[3415] | 1203 | Gones = np.inner(Gones.T,SGMT).T |
---|
[3232] | 1204 | if SGData['SGInv'] and not SGData['SGFixed']: |
---|
[2495] | 1205 | Gdata = np.hstack((Gdata,-Gdata)) #inversion if any |
---|
[3415] | 1206 | Gones = np.hstack((Gones,-Gones)) #inversion if any |
---|
[2495] | 1207 | Gdata = np.hstack([Gdata for icen in range(Ncen)]) #dup over cell centering |
---|
[3415] | 1208 | Gones = np.hstack([Gones for icen in range(Ncen)]) #dup over cell centering |
---|
[2495] | 1209 | Gdata = SGData['MagMom'][nxs,:,nxs]*Gdata #flip vectors according to spin flip |
---|
[3415] | 1210 | Gones = SGData['MagMom'][nxs,:,nxs]*Gones #flip vectors according to spin flip |
---|
[2548] | 1211 | Mag = np.tile(Mag[:,nxs],Nops).T #make Mag same length as Gdata |
---|
[3805] | 1212 | Kdata = np.inner(Gdata.T,uAmat).T #Cartesian unit vectors |
---|
| 1213 | Kmean = np.mean(np.sqrt(np.sum(Kdata**2,axis=0)),axis=0) |
---|
| 1214 | Kdata /= Kmean |
---|
[2495] | 1215 | Uij = np.array(G2lat.U6toUij(Uijdata)) |
---|
| 1216 | bij = Mast*Uij.T |
---|
| 1217 | dFdvDict = {} |
---|
| 1218 | dFdfr = np.zeros((nRef,mSize)) |
---|
| 1219 | dFdx = np.zeros((nRef,mSize,3)) |
---|
| 1220 | dFdui = np.zeros((nRef,mSize)) |
---|
| 1221 | dFdua = np.zeros((nRef,mSize,6)) |
---|
| 1222 | time0 = time.time() |
---|
| 1223 | #reflection processing begins here - big arrays! |
---|
| 1224 | iBeg = 0 |
---|
[3414] | 1225 | blkSize = 5 #no. of reflections in a block - optimized for speed |
---|
[2495] | 1226 | while iBeg < nRef: |
---|
| 1227 | iFin = min(iBeg+blkSize,nRef) |
---|
| 1228 | refl = refDict['RefList'][iBeg:iFin] #array(blkSize,nItems) |
---|
| 1229 | H = refl.T[:3].T |
---|
| 1230 | SQ = 1./(2.*refl.T[4])**2 # or (sin(theta)/lambda)**2 |
---|
| 1231 | SQfactor = 8.0*SQ*np.pi**2 |
---|
| 1232 | Uniq = np.inner(H,SGMT) # array(nSGOp,3) |
---|
| 1233 | Phi = np.inner(H,SGT) |
---|
| 1234 | phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T).T+Phi.T).T |
---|
[2523] | 1235 | occ = Mdata*Fdata/Nops |
---|
[2495] | 1236 | biso = -SQfactor*Uisodata[:,nxs] |
---|
| 1237 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT),axis=1).T |
---|
| 1238 | HbH = -np.sum(Uniq.T*np.swapaxes(np.inner(bij,Uniq),2,-1),axis=1) |
---|
| 1239 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0).T |
---|
| 1240 | Hij = np.array([Mast*np.multiply.outer(U,U) for U in np.reshape(Uniq,(-1,3))]) |
---|
[2546] | 1241 | Hij = np.reshape(np.array([G2lat.UijtoU6(uij) for uij in Hij]),(-1,len(SGT),6)) |
---|
[2495] | 1242 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
| 1243 | MF = refDict['FF']['MF'][iBeg:iFin].T[Tindx].T #Nref,Natm |
---|
[2695] | 1244 | TMcorr = 0.539*(np.reshape(Tiso,Tuij.shape)*Tuij)[:,0,:]*Fdata*Mdata*MF/(2*Nops) #Nref,Natm |
---|
[3340] | 1245 | if SGData['SGInv']: |
---|
| 1246 | if not SGData['SGFixed']: |
---|
| 1247 | mphase = np.hstack((phase,-phase)) #OK |
---|
| 1248 | Uniq = np.hstack((Uniq,-Uniq)) #Nref,Nops,hkl |
---|
| 1249 | Hij = np.hstack((Hij,Hij)) |
---|
| 1250 | else: |
---|
| 1251 | mphase = phase |
---|
[2495] | 1252 | else: |
---|
[3340] | 1253 | mphase = phase # |
---|
[2495] | 1254 | Hij = np.concatenate(np.array([Hij for cen in SGData['SGCen']]),axis=1) |
---|
| 1255 | Uniq = np.hstack([Uniq for cen in SGData['SGCen']]) |
---|
| 1256 | mphase = np.array([mphase+twopi*np.inner(cen,H)[:,nxs,nxs] for cen in SGData['SGCen']]) |
---|
| 1257 | mphase = np.concatenate(mphase,axis=1) #Nref,Nop,Natm |
---|
| 1258 | sinm = np.sin(mphase) #ditto - match magstrfc.for |
---|
| 1259 | cosm = np.cos(mphase) #ditto |
---|
| 1260 | HM = np.inner(Bmat.T,H) #put into cartesian space |
---|
[3372] | 1261 | HM = HM/np.sqrt(np.sum(HM**2,axis=0)) #unit cartesian vector for H |
---|
| 1262 | eDotK = np.sum(HM[:,:,nxs,nxs]*Kdata[:,nxs,:,:],axis=0) |
---|
| 1263 | Q = HM[:,:,nxs,nxs]*eDotK[nxs,:,:,:]-Kdata[:,nxs,:,:] #Mxyz,Nref,Nop,Natm = BPM in magstrfc.for OK |
---|
[2596] | 1264 | |
---|
[2508] | 1265 | fam = Q*TMcorr[nxs,:,nxs,:]*cosm[nxs,:,:,:]*Mag[nxs,nxs,:,:] #Mxyz,Nref,Nop,Natm |
---|
| 1266 | fbm = Q*TMcorr[nxs,:,nxs,:]*sinm[nxs,:,:,:]*Mag[nxs,nxs,:,:] |
---|
| 1267 | fams = np.sum(np.sum(fam,axis=-1),axis=-1) #Mxyz,Nref |
---|
| 1268 | fbms = np.sum(np.sum(fbm,axis=-1),axis=-1) |
---|
[2550] | 1269 | famx = -Q*TMcorr[nxs,:,nxs,:]*Mag[nxs,nxs,:,:]*sinm[nxs,:,:,:] #Mxyz,Nref,Nops,Natom |
---|
[2495] | 1270 | fbmx = Q*TMcorr[nxs,:,nxs,:]*Mag[nxs,nxs,:,:]*cosm[nxs,:,:,:] |
---|
[2506] | 1271 | #sums below are over Nops - real part |
---|
[2501] | 1272 | dfadfr = np.sum(fam/occ,axis=2) #array(Mxyz,refBlk,nAtom) Fdata != 0 avoids /0. problem deriv OK |
---|
[2522] | 1273 | dfadx = np.sum(twopi*Uniq[nxs,:,:,nxs,:]*famx[:,:,:,:,nxs],axis=2) #deriv OK |
---|
[2512] | 1274 | dfadui = np.sum(-SQfactor[:,nxs,nxs]*fam,axis=2) #array(Ops,refBlk,nAtoms) deriv OK |
---|
[3415] | 1275 | dfadua = np.sum(-Hij[nxs,:,:,nxs,:]*fam[:,:,:,:,nxs],axis=2) #deriv OK |
---|
[2506] | 1276 | # imaginary part; array(3,refBlk,nAtom,3) & array(3,refBlk,nAtom,6) |
---|
[2497] | 1277 | dfbdfr = np.sum(fbm/occ,axis=2) #array(mxyz,refBlk,nAtom) Fdata != 0 avoids /0. problem |
---|
[2522] | 1278 | dfbdx = np.sum(twopi*Uniq[nxs,:,:,nxs,:]*fbmx[:,:,:,:,nxs],axis=2) |
---|
[2497] | 1279 | dfbdui = np.sum(-SQfactor[:,nxs,nxs]*fbm,axis=2) #array(Ops,refBlk,nAtoms) |
---|
| 1280 | dfbdua = np.sum(-Hij[nxs,:,:,nxs,:]*fbm[:,:,:,:,nxs],axis=2) |
---|
[2506] | 1281 | #accumulate derivatives |
---|
[2534] | 1282 | dFdfr[iBeg:iFin] = 2.*np.sum((fams[:,:,nxs]*dfadfr+fbms[:,:,nxs]*dfbdfr)*Mdata/Nops,axis=0) #ok |
---|
[2752] | 1283 | dFdx[iBeg:iFin] = 2.*np.sum(fams[:,:,nxs,nxs]*dfadx+fbms[:,:,nxs,nxs]*dfbdx,axis=0) #ok |
---|
[2534] | 1284 | dFdui[iBeg:iFin] = 2.*np.sum(fams[:,:,nxs]*dfadui+fbms[:,:,nxs]*dfbdui,axis=0) #ok |
---|
[3414] | 1285 | dFdua[iBeg:iFin] = 2.*np.sum(fams[:,:,nxs,nxs]*dfadua+fbms[:,:,nxs,nxs]*dfbdua,axis=0) #ok |
---|
[2497] | 1286 | iBeg += blkSize |
---|
[3136] | 1287 | print (' %d derivative time %.4f\r'%(nRef,time.time()-time0)) |
---|
[2495] | 1288 | #loop over atoms - each dict entry is list of derivatives for all the reflections |
---|
| 1289 | for i in range(len(Mdata)): |
---|
| 1290 | dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i] |
---|
| 1291 | dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i] |
---|
| 1292 | dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i] |
---|
| 1293 | dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i] |
---|
| 1294 | dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i] |
---|
| 1295 | dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i] |
---|
| 1296 | dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i] |
---|
| 1297 | dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i] |
---|
[3414] | 1298 | dFdvDict[pfx+'AU12:'+str(i)] = 2.*dFdua.T[3][i] |
---|
| 1299 | dFdvDict[pfx+'AU13:'+str(i)] = 2.*dFdua.T[4][i] |
---|
| 1300 | dFdvDict[pfx+'AU23:'+str(i)] = 2.*dFdua.T[5][i] |
---|
[2495] | 1301 | return dFdvDict |
---|
[2520] | 1302 | |
---|
[2110] | 1303 | def StructureFactorDervTw2(refDict,G,hfx,pfx,SGData,calcControls,parmDict): |
---|
| 1304 | '''Compute structure factor derivatives on blocks of reflections - for twins only |
---|
| 1305 | faster than StructureFactorDervTw |
---|
| 1306 | input: |
---|
| 1307 | |
---|
| 1308 | :param dict refDict: where |
---|
| 1309 | 'RefList' list where each ref = h,k,l,it,d,... |
---|
| 1310 | 'FF' dict of form factors - filled in below |
---|
| 1311 | :param np.array G: reciprocal metric tensor |
---|
| 1312 | :param str hfx: histogram id string |
---|
| 1313 | :param str pfx: phase id string |
---|
| 1314 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 1315 | :param dict calcControls: |
---|
| 1316 | :param dict parmDict: |
---|
| 1317 | |
---|
| 1318 | :returns: dict dFdvDict: dictionary of derivatives |
---|
| 1319 | ''' |
---|
| 1320 | phfx = pfx.split(':')[0]+hfx |
---|
| 1321 | ast = np.sqrt(np.diag(G)) |
---|
| 1322 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
| 1323 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
| 1324 | SGT = np.array([ops[1] for ops in SGData['SGOps']]) |
---|
| 1325 | FFtables = calcControls['FFtables'] |
---|
| 1326 | BLtables = calcControls['BLtables'] |
---|
| 1327 | TwDict = refDict.get('TwDict',{}) |
---|
| 1328 | NTL = calcControls[phfx+'NTL'] |
---|
| 1329 | NM = calcControls[phfx+'TwinNMN']+1 |
---|
| 1330 | TwinLaw = calcControls[phfx+'TwinLaw'] |
---|
| 1331 | TwinFr = np.array([parmDict[phfx+'TwinFr:'+str(i)] for i in range(len(TwinLaw))]) |
---|
| 1332 | TwinInv = list(np.where(calcControls[phfx+'TwinInv'],-1,1)) |
---|
| 1333 | nTwin = len(TwinLaw) |
---|
| 1334 | nRef = len(refDict['RefList']) |
---|
[2478] | 1335 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 1336 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 1337 | if not Xdata.size: #no atoms in phase! |
---|
| 1338 | return {} |
---|
[2110] | 1339 | mSize = len(Mdata) |
---|
| 1340 | FF = np.zeros(len(Tdata)) |
---|
| 1341 | if 'NC' in calcControls[hfx+'histType']: |
---|
| 1342 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam']) |
---|
| 1343 | elif 'X' in calcControls[hfx+'histType']: |
---|
| 1344 | FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata]) |
---|
| 1345 | FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata]) |
---|
| 1346 | Uij = np.array(G2lat.U6toUij(Uijdata)) |
---|
| 1347 | bij = Mast*Uij.T |
---|
| 1348 | dFdvDict = {} |
---|
| 1349 | dFdfr = np.zeros((nRef,nTwin,mSize)) |
---|
| 1350 | dFdx = np.zeros((nRef,nTwin,mSize,3)) |
---|
| 1351 | dFdui = np.zeros((nRef,nTwin,mSize)) |
---|
| 1352 | dFdua = np.zeros((nRef,nTwin,mSize,6)) |
---|
| 1353 | dFdbab = np.zeros((nRef,nTwin,2)) |
---|
| 1354 | dFdtw = np.zeros((nRef,nTwin)) |
---|
| 1355 | time0 = time.time() |
---|
[2123] | 1356 | #reflection processing begins here - big arrays! |
---|
| 1357 | iBeg = 0 |
---|
| 1358 | blkSize = 16 #no. of reflections in a block - optimized for speed |
---|
| 1359 | while iBeg < nRef: |
---|
| 1360 | iFin = min(iBeg+blkSize,nRef) |
---|
| 1361 | refl = refDict['RefList'][iBeg:iFin] #array(blkSize,nItems) |
---|
| 1362 | H = refl.T[:3] |
---|
| 1363 | H = np.inner(H.T,TwinLaw) #array(3,nTwins) |
---|
[2110] | 1364 | TwMask = np.any(H,axis=-1) |
---|
[2123] | 1365 | for ir in range(blkSize): |
---|
| 1366 | iref = ir+iBeg |
---|
| 1367 | if iref in TwDict: |
---|
| 1368 | for i in TwDict[iref]: |
---|
| 1369 | for n in range(NTL): |
---|
| 1370 | H[ir][i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM]) |
---|
| 1371 | TwMask = np.any(H,axis=-1) |
---|
| 1372 | SQ = 1./(2.*refl.T[4])**2 # or (sin(theta)/lambda)**2 |
---|
[2110] | 1373 | SQfactor = 8.0*SQ*np.pi**2 |
---|
[2123] | 1374 | if 'T' in calcControls[hfx+'histType']: |
---|
| 1375 | if 'P' in calcControls[hfx+'histType']: |
---|
| 1376 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[14]) |
---|
| 1377 | else: |
---|
| 1378 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[12]) |
---|
| 1379 | FP = np.repeat(FP.T,len(SGT)*len(TwinLaw),axis=0) |
---|
| 1380 | FPP = np.repeat(FPP.T,len(SGT)*len(TwinLaw),axis=0) |
---|
[2110] | 1381 | dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor) |
---|
[2123] | 1382 | Bab = np.repeat(parmDict[phfx+'BabA']*dBabdA,len(SGT)*nTwin) |
---|
[2110] | 1383 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
[2123] | 1384 | FF = np.repeat(refDict['FF']['FF'][iBeg:iFin].T[Tindx].T,len(SGT)*len(TwinLaw),axis=0) |
---|
| 1385 | Uniq = np.inner(H,SGMT) # (nTwin,nSGOp,3) |
---|
[2110] | 1386 | Phi = np.inner(H,SGT) |
---|
| 1387 | phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T).T+Phi.T).T |
---|
| 1388 | sinp = np.sin(phase) |
---|
| 1389 | cosp = np.cos(phase) |
---|
| 1390 | occ = Mdata*Fdata/len(SGT) |
---|
| 1391 | biso = -SQfactor*Uisodata[:,nxs] |
---|
| 1392 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT)*nTwin,axis=1) |
---|
| 1393 | HbH = -np.sum(Uniq.T*np.swapaxes(np.inner(bij,Uniq),2,-1),axis=1) |
---|
| 1394 | Hij = np.array([Mast*np.multiply.outer(U,U) for U in np.reshape(Uniq,(-1,3))]) |
---|
[2546] | 1395 | Hij = np.reshape(np.array([G2lat.UijtoU6(uij) for uij in Hij]),(-1,nTwin,len(SGT),6)) |
---|
[2110] | 1396 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0) |
---|
[2123] | 1397 | Tcorr = (np.reshape(Tiso,Tuij.shape)*Tuij).T*Mdata*Fdata/len(SGMT) |
---|
| 1398 | fot = np.reshape(((FF+FP).T-Bab).T,cosp.shape)*Tcorr |
---|
[2110] | 1399 | fotp = FPP*Tcorr |
---|
[2123] | 1400 | if 'T' in calcControls[hfx+'histType']: #fa,fb are 2 X blkSize X nTwin X nOps x nAtoms |
---|
| 1401 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-np.reshape(FPP,sinp.shape)*sinp*Tcorr]) |
---|
| 1402 | fb = np.array([np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr,np.reshape(FPP,cosp.shape)*cosp*Tcorr]) |
---|
| 1403 | else: |
---|
| 1404 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-FPP*sinp*Tcorr]) |
---|
| 1405 | fb = np.array([np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr,FPP*cosp*Tcorr]) |
---|
[2110] | 1406 | fas = np.sum(np.sum(fa,axis=-1),axis=-1) #real sum over atoms & unique hkl array(2,nTwins) |
---|
[2094] | 1407 | fbs = np.sum(np.sum(fb,axis=-1),axis=-1) #imag sum over atoms & uniq hkl |
---|
[2110] | 1408 | if SGData['SGInv']: #centrosymmetric; B=0 |
---|
| 1409 | fbs[0] *= 0. |
---|
| 1410 | fas[1] *= 0. |
---|
[2123] | 1411 | fax = np.array([-fot*sinp,-fotp*cosp]) #positions array(2,nRef,ntwi,nEqv,nAtoms) |
---|
[2094] | 1412 | fbx = np.array([fot*cosp,-fotp*sinp]) |
---|
| 1413 | #sum below is over Uniq |
---|
[2123] | 1414 | dfadfr = np.sum(np.sum(fa/occ,axis=-2),axis=0) #array(2,nRef,ntwin,nAtom) Fdata != 0 avoids /0. problem |
---|
[2110] | 1415 | dfadba = np.sum(-cosp*Tcorr[:,nxs],axis=1) |
---|
[2123] | 1416 | dfadui = np.sum(np.sum(-SQfactor[nxs,:,nxs,nxs,nxs]*fa,axis=-2),axis=0) |
---|
| 1417 | dfadx = np.sum(np.sum(twopi*Uniq[nxs,:,:,:,nxs,:]*fax[:,:,:,:,:,nxs],axis=-3),axis=0) # nRef x nTwin x nAtoms x xyz; sum on ops & A,A' |
---|
| 1418 | dfadua = np.sum(np.sum(-Hij[nxs,:,:,:,nxs,:]*fa[:,:,:,:,:,nxs],axis=-3),axis=0) |
---|
[2094] | 1419 | if not SGData['SGInv']: |
---|
[2123] | 1420 | dfbdfr = np.sum(np.sum(fb/occ,axis=-2),axis=0) #Fdata != 0 avoids /0. problem |
---|
[2110] | 1421 | dfadba /= 2. |
---|
[2546] | 1422 | # dfbdba = np.sum(-sinp*Tcorr[:,nxs],axis=1)/2. |
---|
[2123] | 1423 | dfbdui = np.sum(np.sum(-SQfactor[nxs,:,nxs,nxs,nxs]*fb,axis=-2),axis=0) |
---|
| 1424 | dfbdx = np.sum(np.sum(twopi*Uniq[nxs,:,:,:,nxs,:]*fbx[:,:,:,:,:,nxs],axis=-3),axis=0) |
---|
| 1425 | dfbdua = np.sum(np.sum(-Hij[nxs,:,:,:,nxs,:]*fb[:,:,:,:,:,nxs],axis=-3),axis=0) |
---|
[2094] | 1426 | else: |
---|
| 1427 | dfbdfr = np.zeros_like(dfadfr) |
---|
| 1428 | dfbdx = np.zeros_like(dfadx) |
---|
| 1429 | dfbdui = np.zeros_like(dfadui) |
---|
| 1430 | dfbdua = np.zeros_like(dfadua) |
---|
[2546] | 1431 | # dfbdba = np.zeros_like(dfadba) |
---|
[2094] | 1432 | SA = fas[0]+fas[1] |
---|
| 1433 | SB = fbs[0]+fbs[1] |
---|
[2123] | 1434 | # GSASIIpath.IPyBreak() |
---|
| 1435 | dFdfr[iBeg:iFin] = ((2.*TwMask*SA)[:,:,nxs]*dfadfr+(2.*TwMask*SB)[:,:,nxs]*dfbdfr)*Mdata[nxs,nxs,:]/len(SGMT) |
---|
| 1436 | dFdx[iBeg:iFin] = (2.*TwMask*SA)[:,:,nxs,nxs]*dfadx+(2.*TwMask*SB)[:,:,nxs,nxs]*dfbdx |
---|
| 1437 | dFdui[iBeg:iFin] = (2.*TwMask*SA)[:,:,nxs]*dfadui+(2.*TwMask*SB)[:,:,nxs]*dfbdui |
---|
| 1438 | dFdua[iBeg:iFin] = (2.*TwMask*SA)[:,:,nxs,nxs]*dfadua+(2.*TwMask*SB)[:,:,nxs,nxs]*dfbdua |
---|
[2110] | 1439 | if SGData['SGInv']: #centrosymmetric; B=0 |
---|
[2123] | 1440 | dFdtw[iBeg:iFin] = np.sum(TwMask[nxs,:]*fas,axis=0)**2 |
---|
[2110] | 1441 | else: |
---|
[2123] | 1442 | dFdtw[iBeg:iFin] = np.sum(TwMask[nxs,:]*fas,axis=0)**2+np.sum(TwMask[nxs,:]*fbs,axis=0)**2 |
---|
| 1443 | # dFdbab[iBeg:iFin] = fas[0,:,nxs]*np.array([np.sum(dfadba*dBabdA),np.sum(-dfadba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T+ \ |
---|
| 1444 | # fbs[0,:,nxs]*np.array([np.sum(dfbdba*dBabdA),np.sum(-dfbdba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T |
---|
| 1445 | iBeg += blkSize |
---|
[2094] | 1446 | # GSASIIpath.IPyBreak() |
---|
[3136] | 1447 | print (' %d derivative time %.4f\r'%(len(refDict['RefList']),time.time()-time0)) |
---|
[2110] | 1448 | #loop over atoms - each dict entry is list of derivatives for all the reflections |
---|
[2123] | 1449 | for i in range(len(Mdata)): #these all OK |
---|
[2097] | 1450 | dFdvDict[pfx+'Afrac:'+str(i)] = np.sum(dFdfr.T[i]*TwinFr[:,nxs],axis=0) |
---|
| 1451 | dFdvDict[pfx+'dAx:'+str(i)] = np.sum(dFdx.T[0][i]*TwinFr[:,nxs],axis=0) |
---|
| 1452 | dFdvDict[pfx+'dAy:'+str(i)] = np.sum(dFdx.T[1][i]*TwinFr[:,nxs],axis=0) |
---|
| 1453 | dFdvDict[pfx+'dAz:'+str(i)] = np.sum(dFdx.T[2][i]*TwinFr[:,nxs],axis=0) |
---|
| 1454 | dFdvDict[pfx+'AUiso:'+str(i)] = np.sum(dFdui.T[i]*TwinFr[:,nxs],axis=0) |
---|
| 1455 | dFdvDict[pfx+'AU11:'+str(i)] = np.sum(dFdua.T[0][i]*TwinFr[:,nxs],axis=0) |
---|
| 1456 | dFdvDict[pfx+'AU22:'+str(i)] = np.sum(dFdua.T[1][i]*TwinFr[:,nxs],axis=0) |
---|
| 1457 | dFdvDict[pfx+'AU33:'+str(i)] = np.sum(dFdua.T[2][i]*TwinFr[:,nxs],axis=0) |
---|
[3414] | 1458 | dFdvDict[pfx+'AU12:'+str(i)] = 2.*np.sum(dFdua.T[3][i]*TwinFr[:,nxs],axis=0) |
---|
| 1459 | dFdvDict[pfx+'AU13:'+str(i)] = 2.*np.sum(dFdua.T[4][i]*TwinFr[:,nxs],axis=0) |
---|
| 1460 | dFdvDict[pfx+'AU23:'+str(i)] = 2.*np.sum(dFdua.T[5][i]*TwinFr[:,nxs],axis=0) |
---|
[2094] | 1461 | dFdvDict[phfx+'BabA'] = dFdbab.T[0] |
---|
| 1462 | dFdvDict[phfx+'BabU'] = dFdbab.T[1] |
---|
[2097] | 1463 | for i in range(nTwin): |
---|
| 1464 | dFdvDict[phfx+'TwinFr:'+str(i)] = dFdtw.T[i] |
---|
[2094] | 1465 | return dFdvDict |
---|
| 1466 | |
---|
[2115] | 1467 | def SStructureFactor(refDict,G,hfx,pfx,SGData,SSGData,calcControls,parmDict): |
---|
[1957] | 1468 | ''' |
---|
[2115] | 1469 | Compute super structure factors for all h,k,l,m for phase - no twins |
---|
| 1470 | puts the result, F^2, in each ref[9] in refList |
---|
| 1471 | works on blocks of 32 reflections for speed |
---|
[1957] | 1472 | input: |
---|
| 1473 | |
---|
| 1474 | :param dict refDict: where |
---|
[2097] | 1475 | 'RefList' list where each ref = h,k,l,m,it,d,... |
---|
[1957] | 1476 | 'FF' dict of form factors - filed in below |
---|
| 1477 | :param np.array G: reciprocal metric tensor |
---|
| 1478 | :param str pfx: phase id string |
---|
| 1479 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 1480 | :param dict calcControls: |
---|
| 1481 | :param dict ParmDict: |
---|
| 1482 | |
---|
[1980] | 1483 | ''' |
---|
[1957] | 1484 | phfx = pfx.split(':')[0]+hfx |
---|
| 1485 | ast = np.sqrt(np.diag(G)) |
---|
[3777] | 1486 | GS = G/np.outer(ast,ast) |
---|
| 1487 | uAmat = G2lat.Gmat2AB(GS)[0] |
---|
[1979] | 1488 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
[1958] | 1489 | SGInv = SGData['SGInv'] |
---|
[2038] | 1490 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
[3297] | 1491 | Ncen = len(SGData['SGCen']) |
---|
| 1492 | Nops = len(SGMT)*Ncen*(1+SGData['SGInv']) |
---|
[1957] | 1493 | SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']]) |
---|
| 1494 | SSGT = np.array([ops[1] for ops in SSGData['SSGOps']]) |
---|
[3830] | 1495 | SSCen = SSGData['SSGCen'] |
---|
[1957] | 1496 | FFtables = calcControls['FFtables'] |
---|
| 1497 | BLtables = calcControls['BLtables'] |
---|
[2546] | 1498 | MFtables = calcControls['MFtables'] |
---|
[3297] | 1499 | Amat,Bmat = G2lat.Gmat2AB(G) |
---|
[1979] | 1500 | Flack = 1.0 |
---|
| 1501 | if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict: |
---|
| 1502 | Flack = 1.-2.*parmDict[phfx+'Flack'] |
---|
[2478] | 1503 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 1504 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 1505 | if not Xdata.size: #no atoms in phase! |
---|
| 1506 | return |
---|
[3777] | 1507 | waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict) |
---|
[3808] | 1508 | ngl,nWaves,Fmod,Xmod,Umod,Mmod,glTau,glWt = G2mth.makeWaves(waveTypes,FSSdata,XSSdata,USSdata,MSSdata,Mast) #NB: Mmod is ReIm,Mxyz,Ntau,Natm |
---|
[3777] | 1509 | modQ = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']]) |
---|
[3297] | 1510 | |
---|
[3830] | 1511 | if parmDict[pfx+'isMag']: #This part correct for making modulated mag moments on equiv atoms |
---|
[3835] | 1512 | |
---|
[3818] | 1513 | GSdata = np.inner(Gdata.T,np.swapaxes(SGMT,1,2)) #apply sym. ops.--> Natm,Nops,Nxyz |
---|
| 1514 | if SGData['SGInv'] and not SGData['SGFixed']: #inversion if any |
---|
| 1515 | GSdata = np.hstack((GSdata,-GSdata)) |
---|
[3830] | 1516 | GSdata = np.hstack([GSdata for cen in SSCen]) #dup over cell centering - Natm,Nops,Mxyz |
---|
| 1517 | GSdata = SGData['MagMom'][nxs,:,nxs]*GSdata #flip vectors according to spin flip * det(opM) |
---|
[3835] | 1518 | GSdata = np.swapaxes(GSdata,0,1) #Nop,Natm,Mxyz |
---|
[3830] | 1519 | |
---|
[3835] | 1520 | mXYZ = np.array([[xyz[0] for xyz in list(G2spc.GenAtom(xyz,SGData,All=True,Move=True))] for xyz in (Xdata+dXdata).T])%1. #Natn,Nop,xyz |
---|
| 1521 | MmodA,MmodB = G2mth.MagMod(mXYZ,modQ,MSSdata) #Im sin/Re cos,Nops,Natm,Mxyz |
---|
| 1522 | |
---|
[3297] | 1523 | |
---|
[1957] | 1524 | FF = np.zeros(len(Tdata)) |
---|
| 1525 | if 'NC' in calcControls[hfx+'histType']: |
---|
| 1526 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam']) |
---|
[2076] | 1527 | elif 'X' in calcControls[hfx+'histType']: |
---|
[1957] | 1528 | FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata]) |
---|
| 1529 | FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata]) |
---|
[2038] | 1530 | Uij = np.array(G2lat.U6toUij(Uijdata)).T |
---|
| 1531 | bij = Mast*Uij |
---|
[3777] | 1532 | blkSize = 48 #no. of reflections in a block |
---|
[1979] | 1533 | nRef = refDict['RefList'].shape[0] |
---|
[2750] | 1534 | SQ = 1./(2.*refDict['RefList'].T[5])**2 |
---|
| 1535 | if 'N' in calcControls[hfx+'histType']: |
---|
| 1536 | dat = G2el.getBLvalues(BLtables) |
---|
[3136] | 1537 | refDict['FF']['El'] = list(dat.keys()) |
---|
| 1538 | refDict['FF']['FF'] = np.ones((nRef,len(dat)))*list(dat.values()) |
---|
[2750] | 1539 | refDict['FF']['MF'] = np.zeros((nRef,len(dat))) |
---|
| 1540 | for iel,El in enumerate(refDict['FF']['El']): |
---|
| 1541 | if El in MFtables: |
---|
| 1542 | refDict['FF']['MF'].T[iel] = G2el.MagScatFac(MFtables[El],SQ) |
---|
| 1543 | else: |
---|
| 1544 | dat = G2el.getFFvalues(FFtables,0.) |
---|
[3136] | 1545 | refDict['FF']['El'] = list(dat.keys()) |
---|
[2750] | 1546 | refDict['FF']['FF'] = np.zeros((nRef,len(dat))) |
---|
| 1547 | for iel,El in enumerate(refDict['FF']['El']): |
---|
| 1548 | refDict['FF']['FF'].T[iel] = G2el.ScatFac(FFtables[El],SQ) |
---|
[3802] | 1549 | # time0 = time.time() |
---|
[1979] | 1550 | #reflection processing begins here - big arrays! |
---|
| 1551 | iBeg = 0 |
---|
| 1552 | while iBeg < nRef: |
---|
| 1553 | iFin = min(iBeg+blkSize,nRef) |
---|
| 1554 | refl = refDict['RefList'][iBeg:iFin] #array(blkSize,nItems) |
---|
| 1555 | H = refl.T[:4] #array(blkSize,4) |
---|
[2038] | 1556 | HP = H[:3]+modQ[:,nxs]*H[3:] #projected hklm to hkl |
---|
[1979] | 1557 | SQ = 1./(2.*refl.T[5])**2 #array(blkSize) |
---|
| 1558 | SQfactor = 4.0*SQ*twopisq #ditto prev. |
---|
[1980] | 1559 | Uniq = np.inner(H.T,SSGMT) |
---|
[2038] | 1560 | UniqP = np.inner(HP.T,SGMT) |
---|
[1980] | 1561 | Phi = np.inner(H.T,SSGT) |
---|
[3778] | 1562 | if SGInv and not SGData['SGFixed']: #if centro - expand HKL sets |
---|
[1980] | 1563 | Uniq = np.hstack((Uniq,-Uniq)) |
---|
| 1564 | Phi = np.hstack((Phi,-Phi)) |
---|
[2038] | 1565 | UniqP = np.hstack((UniqP,-UniqP)) |
---|
[1979] | 1566 | if 'T' in calcControls[hfx+'histType']: |
---|
| 1567 | if 'P' in calcControls[hfx+'histType']: |
---|
| 1568 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[14]) |
---|
| 1569 | else: |
---|
| 1570 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[12]) |
---|
[2115] | 1571 | FP = np.repeat(FP.T,Uniq.shape[1],axis=0) |
---|
| 1572 | FPP = np.repeat(FPP.T,Uniq.shape[1],axis=0) |
---|
[3774] | 1573 | Bab = 0. |
---|
| 1574 | if phfx+'BabA' in parmDict: |
---|
| 1575 | Bab = np.repeat(parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor),Uniq.shape[1]) |
---|
[1957] | 1576 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
[2115] | 1577 | FF = np.repeat(refDict['FF']['FF'][iBeg:iFin].T[Tindx].T,Uniq.shape[1],axis=0) |
---|
[2040] | 1578 | phase = twopi*(np.inner(Uniq[:,:,:3],(dXdata.T+Xdata.T))-Phi[:,:,nxs]) |
---|
[3835] | 1579 | phase = np.hstack([phase for cen in SSCen]) |
---|
[1957] | 1580 | sinp = np.sin(phase) |
---|
| 1581 | cosp = np.cos(phase) |
---|
[1980] | 1582 | biso = -SQfactor*Uisodata[:,nxs] |
---|
[2115] | 1583 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),Uniq.shape[1],axis=1).T |
---|
[2038] | 1584 | HbH = -np.sum(UniqP[:,:,nxs,:]*np.inner(UniqP[:,:,:],bij),axis=-1) #use hklt proj to hkl |
---|
[1957] | 1585 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0) |
---|
[2038] | 1586 | Tcorr = np.reshape(Tiso,Tuij.shape)*Tuij*Mdata*Fdata/Uniq.shape[1] #refBlk x ops x atoms |
---|
[3297] | 1587 | |
---|
[3414] | 1588 | if 'N' in calcControls[hfx+'histType'] and parmDict[pfx+'isMag']: #TODO: mag math here?? |
---|
[3835] | 1589 | phasem = twopi*np.inner(H.T[:,:3],mXYZ) |
---|
| 1590 | phasem = np.swapaxes(phasem,1,2) |
---|
| 1591 | sinm = np.sin(phasem) |
---|
| 1592 | cosm = np.cos(phasem) |
---|
[3297] | 1593 | MF = refDict['FF']['MF'][iBeg:iFin].T[Tindx].T #Nref,Natm |
---|
| 1594 | TMcorr = 0.539*(np.reshape(Tiso,Tuij.shape)*Tuij)[:,0,:]*Fdata*Mdata*MF/(2*Nops) #Nref,Natm |
---|
[3812] | 1595 | |
---|
[3774] | 1596 | HM = np.inner(Bmat,HP.T) #put into cartesian space |
---|
[3297] | 1597 | HM = HM/np.sqrt(np.sum(HM**2,axis=0)) #Gdata = MAGS & HM = UVEC in magstrfc.for both OK |
---|
[3832] | 1598 | |
---|
[3835] | 1599 | fam0 = TMcorr[:,nxs,:,nxs]*GSdata[nxs,:,:,:]*cosm[:,:,:,nxs] |
---|
| 1600 | fbm0 = TMcorr[:,nxs,:,nxs]*GSdata[nxs,:,:,:]*sinm[:,:,:,nxs] |
---|
| 1601 | |
---|
| 1602 | fam = TMcorr[:,nxs,:,nxs]*(MmodB[nxs,:,:,:]*cosm[:,:,:,nxs]-np.sign(H[3])[:,nxs,nxs,nxs]*MmodA[nxs,:,:,:]*sinm[:,:,:,nxs]) #Nref,Nops,Natm,Mxyz |
---|
| 1603 | fbm = TMcorr[:,nxs,:,nxs]*(MmodB[nxs,:,:,:]*sinm[:,:,:,nxs]+np.sign(H[3])[:,nxs,nxs,nxs]*MmodA[nxs,:,:,:]*cosm[:,:,:,nxs]) |
---|
| 1604 | |
---|
| 1605 | famq = np.sum(np.sum(fam,axis=-2),axis=-2) #Nref,Mxyz; sum ops & atoms |
---|
| 1606 | fbmq = np.sum(np.sum(fbm,axis=-2),axis=-2) |
---|
[3832] | 1607 | |
---|
[3835] | 1608 | famq0 = np.sum(np.sum(fam0,axis=-2),axis=-2) |
---|
| 1609 | fbmq0 = np.sum(np.sum(fbm0,axis=-2),axis=-2) |
---|
[3777] | 1610 | |
---|
[3835] | 1611 | fas = np.sum(famq,axis=-1)**2-np.sum(HM.T*famq,axis=-1)**2 |
---|
| 1612 | fbs = np.sum(fbmq,axis=-1)**2-np.sum(HM.T*fbmq,axis=-1)**2 |
---|
[3832] | 1613 | |
---|
[3835] | 1614 | fas0 = np.sum(famq0,axis=-1)**2-np.sum(HM.T*famq0,axis=-1)**2 |
---|
| 1615 | fbs0 = np.sum(fbmq0,axis=-1)**2-np.sum(HM.T*fbmq0,axis=-1)**2 |
---|
| 1616 | |
---|
| 1617 | refl.T[10] = np.where(H[3],fas+fbs,fas0+fbs0) |
---|
| 1618 | refl.T[11] = np.where(H[3],atan2d(fas,fbs),atan2d(fas0,fbs0)) |
---|
[3777] | 1619 | |
---|
[3812] | 1620 | else: |
---|
| 1621 | GfpuA = G2mth.Modulation(Uniq,UniqP,nWaves,Fmod,Xmod,Umod,glTau,glWt) #2 x refBlk x sym X atoms |
---|
| 1622 | if 'T' in calcControls[hfx+'histType']: |
---|
| 1623 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-np.reshape(Flack*FPP,sinp.shape)*sinp*Tcorr]) |
---|
| 1624 | fb = np.array([np.reshape(Flack*FPP,cosp.shape)*cosp*Tcorr,np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr]) |
---|
| 1625 | else: |
---|
| 1626 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-Flack*FPP*sinp*Tcorr]) |
---|
| 1627 | fb = np.array([Flack*FPP*cosp*Tcorr,np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr]) |
---|
| 1628 | fag = fa*GfpuA[0]-fb*GfpuA[1] #real; 2 x refBlk x sym x atoms |
---|
| 1629 | fbg = fb*GfpuA[0]+fa*GfpuA[1] |
---|
| 1630 | fas = np.sum(np.sum(fag,axis=-1),axis=-1) #2 x refBlk; sum sym & atoms |
---|
| 1631 | fbs = np.sum(np.sum(fbg,axis=-1),axis=-1) |
---|
[3808] | 1632 | |
---|
[3818] | 1633 | refl.T[10] = np.sum(fas,axis=0)**2+np.sum(fbs,axis=0)**2 #square of sums |
---|
| 1634 | refl.T[11] = atan2d(fbs[0],fas[0]) #ignore f' & f" |
---|
[3774] | 1635 | if 'P' not in calcControls[hfx+'histType']: |
---|
| 1636 | refl.T[8] = np.copy(refl.T[10]) |
---|
[2115] | 1637 | iBeg += blkSize |
---|
[3759] | 1638 | # print ('nRef %d time %.4f\r'%(nRef,time.time()-time0)) |
---|
| 1639 | return copy.deepcopy(refDict['RefList']) |
---|
[2115] | 1640 | |
---|
| 1641 | def SStructureFactorTw(refDict,G,hfx,pfx,SGData,SSGData,calcControls,parmDict): |
---|
| 1642 | ''' |
---|
| 1643 | Compute super structure factors for all h,k,l,m for phase - twins only |
---|
| 1644 | puts the result, F^2, in each ref[8+im] in refList |
---|
| 1645 | works on blocks of 32 reflections for speed |
---|
| 1646 | input: |
---|
| 1647 | |
---|
| 1648 | :param dict refDict: where |
---|
| 1649 | 'RefList' list where each ref = h,k,l,m,it,d,... |
---|
| 1650 | 'FF' dict of form factors - filed in below |
---|
| 1651 | :param np.array G: reciprocal metric tensor |
---|
| 1652 | :param str pfx: phase id string |
---|
| 1653 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 1654 | :param dict calcControls: |
---|
| 1655 | :param dict ParmDict: |
---|
| 1656 | |
---|
| 1657 | ''' |
---|
| 1658 | phfx = pfx.split(':')[0]+hfx |
---|
| 1659 | ast = np.sqrt(np.diag(G)) |
---|
| 1660 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
| 1661 | SGInv = SGData['SGInv'] |
---|
| 1662 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
| 1663 | SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']]) |
---|
| 1664 | SSGT = np.array([ops[1] for ops in SSGData['SSGOps']]) |
---|
| 1665 | FFtables = calcControls['FFtables'] |
---|
| 1666 | BLtables = calcControls['BLtables'] |
---|
[2546] | 1667 | MFtables = calcControls['MFtables'] |
---|
[2115] | 1668 | Flack = 1.0 |
---|
| 1669 | if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict: |
---|
| 1670 | Flack = 1.-2.*parmDict[phfx+'Flack'] |
---|
| 1671 | TwinLaw = np.array([[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],]) #4D? |
---|
| 1672 | TwDict = refDict.get('TwDict',{}) |
---|
| 1673 | if 'S' in calcControls[hfx+'histType']: |
---|
| 1674 | NTL = calcControls[phfx+'NTL'] |
---|
| 1675 | NM = calcControls[phfx+'TwinNMN']+1 |
---|
| 1676 | TwinLaw = calcControls[phfx+'TwinLaw'] #this'll have to be 4D also... |
---|
| 1677 | TwinFr = np.array([parmDict[phfx+'TwinFr:'+str(i)] for i in range(len(TwinLaw))]) |
---|
| 1678 | TwinInv = list(np.where(calcControls[phfx+'TwinInv'],-1,1)) |
---|
[2478] | 1679 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 1680 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 1681 | if not Xdata.size: #no atoms in phase! |
---|
| 1682 | return |
---|
[2115] | 1683 | waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict) |
---|
[3268] | 1684 | ngl,nWaves,Fmod,Xmod,Umod,Mmod,glTau,glWt = G2mth.makeWaves(waveTypes,FSSdata,XSSdata,USSdata,Mast) |
---|
[2115] | 1685 | modQ = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']]) |
---|
| 1686 | FF = np.zeros(len(Tdata)) |
---|
| 1687 | if 'NC' in calcControls[hfx+'histType']: |
---|
| 1688 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam']) |
---|
| 1689 | elif 'X' in calcControls[hfx+'histType']: |
---|
| 1690 | FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata]) |
---|
| 1691 | FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata]) |
---|
| 1692 | Uij = np.array(G2lat.U6toUij(Uijdata)).T |
---|
| 1693 | bij = Mast*Uij |
---|
| 1694 | blkSize = 32 #no. of reflections in a block |
---|
| 1695 | nRef = refDict['RefList'].shape[0] |
---|
[2478] | 1696 | if not len(refDict['FF']): #no form factors - 1st time thru StructureFactor |
---|
| 1697 | SQ = 1./(2.*refDict['RefList'].T[5])**2 |
---|
[2115] | 1698 | if 'N' in calcControls[hfx+'histType']: |
---|
[2478] | 1699 | dat = G2el.getBLvalues(BLtables) |
---|
[3136] | 1700 | refDict['FF']['El'] = list(dat.keys()) |
---|
| 1701 | refDict['FF']['FF'] = np.ones((nRef,len(dat)))*list(dat.values()) |
---|
[2478] | 1702 | refDict['FF']['MF'] = np.zeros((nRef,len(dat))) |
---|
| 1703 | for iel,El in enumerate(refDict['FF']['El']): |
---|
| 1704 | if El in MFtables: |
---|
| 1705 | refDict['FF']['MF'].T[iel] = G2el.MagScatFac(MFtables[El],SQ) |
---|
[2115] | 1706 | else: |
---|
[2478] | 1707 | dat = G2el.getFFvalues(FFtables,0.) |
---|
[3136] | 1708 | refDict['FF']['El'] = list(dat.keys()) |
---|
[2478] | 1709 | refDict['FF']['FF'] = np.zeros((nRef,len(dat))) |
---|
| 1710 | for iel,El in enumerate(refDict['FF']['El']): |
---|
| 1711 | refDict['FF']['FF'].T[iel] = G2el.ScatFac(FFtables[El],SQ) |
---|
[3802] | 1712 | # time0 = time.time() |
---|
[2115] | 1713 | #reflection processing begins here - big arrays! |
---|
| 1714 | iBeg = 0 |
---|
| 1715 | while iBeg < nRef: |
---|
| 1716 | iFin = min(iBeg+blkSize,nRef) |
---|
| 1717 | refl = refDict['RefList'][iBeg:iFin] #array(blkSize,nItems) |
---|
| 1718 | H = refl[:,:4] #array(blkSize,4) |
---|
| 1719 | H3 = refl[:,:3] |
---|
| 1720 | HP = H[:,:3]+modQ[nxs,:]*H[:,3:] #projected hklm to hkl |
---|
| 1721 | HP = np.inner(HP,TwinLaw) #array(blkSize,nTwins,4) |
---|
| 1722 | H3 = np.inner(H3,TwinLaw) |
---|
| 1723 | TwMask = np.any(HP,axis=-1) |
---|
| 1724 | if TwinLaw.shape[0] > 1 and TwDict: #need np.inner(TwinLaw[?],TwDict[iref][i])*TwinInv[i] |
---|
| 1725 | for ir in range(blkSize): |
---|
| 1726 | iref = ir+iBeg |
---|
| 1727 | if iref in TwDict: |
---|
| 1728 | for i in TwDict[iref]: |
---|
| 1729 | for n in range(NTL): |
---|
| 1730 | HP[ir][i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM]) |
---|
| 1731 | H3[ir][i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM]) |
---|
| 1732 | TwMask = np.any(HP,axis=-1) |
---|
| 1733 | SQ = 1./(2.*refl.T[5])**2 #array(blkSize) |
---|
| 1734 | SQfactor = 4.0*SQ*twopisq #ditto prev. |
---|
| 1735 | Uniq = np.inner(H,SSGMT) |
---|
| 1736 | Uniq3 = np.inner(H3,SGMT) |
---|
| 1737 | UniqP = np.inner(HP,SGMT) |
---|
| 1738 | Phi = np.inner(H,SSGT) |
---|
| 1739 | if SGInv: #if centro - expand HKL sets |
---|
| 1740 | Uniq = np.hstack((Uniq,-Uniq)) |
---|
| 1741 | Uniq3 = np.hstack((Uniq3,-Uniq3)) |
---|
| 1742 | Phi = np.hstack((Phi,-Phi)) |
---|
| 1743 | UniqP = np.hstack((UniqP,-UniqP)) |
---|
| 1744 | if 'T' in calcControls[hfx+'histType']: |
---|
| 1745 | if 'P' in calcControls[hfx+'histType']: |
---|
| 1746 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[14]) |
---|
[1980] | 1747 | else: |
---|
[2115] | 1748 | FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[12]) |
---|
| 1749 | FP = np.repeat(FP.T,Uniq.shape[1]*len(TwinLaw),axis=0) |
---|
| 1750 | FPP = np.repeat(FPP.T,Uniq.shape[1]*len(TwinLaw),axis=0) |
---|
| 1751 | Bab = np.repeat(parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor),Uniq.shape[1]*len(TwinLaw)) |
---|
| 1752 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
| 1753 | FF = np.repeat(refDict['FF']['FF'][iBeg:iFin].T[Tindx].T,Uniq.shape[1]*len(TwinLaw),axis=0) |
---|
| 1754 | phase = twopi*(np.inner(Uniq3,(dXdata.T+Xdata.T))-Phi[:,nxs,:,nxs]) |
---|
| 1755 | sinp = np.sin(phase) |
---|
| 1756 | cosp = np.cos(phase) |
---|
| 1757 | biso = -SQfactor*Uisodata[:,nxs] |
---|
| 1758 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),Uniq.shape[1]*len(TwinLaw),axis=1).T |
---|
| 1759 | HbH = -np.sum(UniqP[:,:,:,nxs]*np.inner(UniqP[:,:,:],bij),axis=-1) #use hklt proj to hkl |
---|
| 1760 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0) |
---|
| 1761 | Tcorr = np.reshape(Tiso,Tuij.shape)*Tuij*Mdata*Fdata/Uniq.shape[1] #refBlk x ops x atoms |
---|
| 1762 | if 'T' in calcControls[hfx+'histType']: |
---|
| 1763 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-np.reshape(Flack*FPP,sinp.shape)*sinp*Tcorr]) |
---|
| 1764 | fb = np.array([np.reshape(Flack*FPP,cosp.shape)*cosp*Tcorr,np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr]) |
---|
| 1765 | else: |
---|
| 1766 | fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-Flack*FPP*sinp*Tcorr]) |
---|
| 1767 | fb = np.array([Flack*FPP*cosp*Tcorr,np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr]) |
---|
| 1768 | GfpuA = G2mth.ModulationTw(Uniq,UniqP,nWaves,Fmod,Xmod,Umod,glTau,glWt) #2 x refBlk x sym X atoms |
---|
| 1769 | fag = fa*GfpuA[0]-fb*GfpuA[1] #real; 2 x refBlk x sym x atoms |
---|
| 1770 | fbg = fb*GfpuA[0]+fa*GfpuA[1] |
---|
| 1771 | fas = np.sum(np.sum(fag,axis=-1),axis=-1) #2 x refBlk; sum sym & atoms |
---|
| 1772 | fbs = np.sum(np.sum(fbg,axis=-1),axis=-1) |
---|
| 1773 | refl.T[10] = np.sum(fas[:,:,0],axis=0)**2+np.sum(fbs[:,:,0],axis=0)**2 #FcT from primary twin element |
---|
| 1774 | refl.T[8] = np.sum(TwinFr*np.sum(TwMask[nxs,:,:]*fas,axis=0)**2,axis=-1)+ \ |
---|
| 1775 | np.sum(TwinFr*np.sum(TwMask[nxs,:,:]*fbs,axis=0)**2,axis=-1) #Fc sum over twins |
---|
| 1776 | refl.T[11] = atan2d(fbs[0].T[0],fas[0].T[0]) #ignore f' & f" |
---|
[1980] | 1777 | iBeg += blkSize |
---|
[3764] | 1778 | # print ('nRef %d time %.4f\r'%(nRef,time.time()-time0)) |
---|
[1980] | 1779 | |
---|
[1630] | 1780 | def SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict): |
---|
[2110] | 1781 | ''' |
---|
| 1782 | Compute super structure factor derivatives for all h,k,l,m for phase - no twins |
---|
[3759] | 1783 | Only Fourier component are done analytically here |
---|
[2110] | 1784 | input: |
---|
| 1785 | |
---|
| 1786 | :param dict refDict: where |
---|
| 1787 | 'RefList' list where each ref = h,k,l,m,it,d,... |
---|
| 1788 | 'FF' dict of form factors - filled in below |
---|
| 1789 | :param int im: = 1 (could be eliminated) |
---|
| 1790 | :param np.array G: reciprocal metric tensor |
---|
| 1791 | :param str hfx: histogram id string |
---|
| 1792 | :param str pfx: phase id string |
---|
| 1793 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 1794 | :param dict SSGData: super space group info. |
---|
| 1795 | :param dict calcControls: |
---|
| 1796 | :param dict ParmDict: |
---|
| 1797 | |
---|
| 1798 | :returns: dict dFdvDict: dictionary of derivatives |
---|
| 1799 | ''' |
---|
[1613] | 1800 | phfx = pfx.split(':')[0]+hfx |
---|
| 1801 | ast = np.sqrt(np.diag(G)) |
---|
| 1802 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
[1986] | 1803 | SGInv = SGData['SGInv'] |
---|
[2038] | 1804 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
[1630] | 1805 | SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']]) |
---|
| 1806 | SSGT = np.array([ops[1] for ops in SSGData['SSGOps']]) |
---|
[1613] | 1807 | FFtables = calcControls['FFtables'] |
---|
| 1808 | BLtables = calcControls['BLtables'] |
---|
| 1809 | nRef = len(refDict['RefList']) |
---|
[2478] | 1810 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 1811 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 1812 | if not Xdata.size: #no atoms in phase! |
---|
| 1813 | return {} |
---|
[1992] | 1814 | mSize = len(Mdata) #no. atoms |
---|
[1630] | 1815 | waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict) |
---|
[3268] | 1816 | ngl,nWaves,Fmod,Xmod,Umod,Mmod,glTau,glWt = G2mth.makeWaves(waveTypes,FSSdata,XSSdata,USSdata,MSSdata,Mast) |
---|
[3808] | 1817 | waveShapes,SCtauF,SCtauX,SCtauU,UmodAB = G2mth.makeWavesDerv(ngl,waveTypes,FSSdata,XSSdata,USSdata,Mast) |
---|
[2038] | 1818 | modQ = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']]) |
---|
[1613] | 1819 | FF = np.zeros(len(Tdata)) |
---|
| 1820 | if 'NC' in calcControls[hfx+'histType']: |
---|
| 1821 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam']) |
---|
| 1822 | elif 'X' in calcControls[hfx+'histType']: |
---|
| 1823 | FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata]) |
---|
| 1824 | FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata]) |
---|
[2038] | 1825 | Uij = np.array(G2lat.U6toUij(Uijdata)).T |
---|
| 1826 | bij = Mast*Uij |
---|
[1986] | 1827 | if not len(refDict['FF']): |
---|
| 1828 | if 'N' in calcControls[hfx+'histType']: |
---|
| 1829 | dat = G2el.getBLvalues(BLtables) #will need wave here for anom. neutron b's |
---|
| 1830 | else: |
---|
| 1831 | dat = G2el.getFFvalues(FFtables,0.) |
---|
[3136] | 1832 | refDict['FF']['El'] = list(dat.keys()) |
---|
[1986] | 1833 | refDict['FF']['FF'] = np.zeros((len(refDict['RefList']),len(dat))) |
---|
[1613] | 1834 | dFdvDict = {} |
---|
[2097] | 1835 | dFdfr = np.zeros((nRef,mSize)) |
---|
| 1836 | dFdx = np.zeros((nRef,mSize,3)) |
---|
| 1837 | dFdui = np.zeros((nRef,mSize)) |
---|
| 1838 | dFdua = np.zeros((nRef,mSize,6)) |
---|
| 1839 | dFdbab = np.zeros((nRef,2)) |
---|
| 1840 | dFdfl = np.zeros((nRef)) |
---|
| 1841 | dFdGf = np.zeros((nRef,mSize,FSSdata.shape[1],2)) |
---|
| 1842 | dFdGx = np.zeros((nRef,mSize,XSSdata.shape[1],6)) |
---|
| 1843 | dFdGu = np.zeros((nRef,mSize,USSdata.shape[1],12)) |
---|
[1986] | 1844 | Flack = 1.0 |
---|
| 1845 | if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict: |
---|
| 1846 | Flack = 1.-2.*parmDict[phfx+'Flack'] |
---|
| 1847 | time0 = time.time() |
---|
| 1848 | nRef = len(refDict['RefList'])/100 |
---|
[1613] | 1849 | for iref,refl in enumerate(refDict['RefList']): |
---|
| 1850 | if 'T' in calcControls[hfx+'histType']: |
---|
| 1851 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl.T[12+im]) |
---|
| 1852 | H = np.array(refl[:4]) |
---|
[2038] | 1853 | HP = H[:3]+modQ*H[3:] #projected hklm to hkl |
---|
[1613] | 1854 | SQ = 1./(2.*refl[4+im])**2 # or (sin(theta)/lambda)**2 |
---|
| 1855 | SQfactor = 8.0*SQ*np.pi**2 |
---|
[3774] | 1856 | Bab = 0.0 |
---|
| 1857 | if phfx+'BabA' in parmDict: |
---|
| 1858 | dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor) |
---|
| 1859 | Bab = parmDict[phfx+'BabA']*dBabdA |
---|
[1613] | 1860 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
| 1861 | FF = refDict['FF']['FF'][iref].T[Tindx] |
---|
[1986] | 1862 | Uniq = np.inner(H,SSGMT) |
---|
| 1863 | Phi = np.inner(H,SSGT) |
---|
[2038] | 1864 | UniqP = np.inner(HP,SGMT) |
---|
[1990] | 1865 | if SGInv: #if centro - expand HKL sets |
---|
| 1866 | Uniq = np.vstack((Uniq,-Uniq)) |
---|
| 1867 | Phi = np.hstack((Phi,-Phi)) |
---|
[2038] | 1868 | UniqP = np.vstack((UniqP,-UniqP)) |
---|
[1986] | 1869 | phase = twopi*(np.inner(Uniq[:,:3],(dXdata+Xdata).T)+Phi[:,nxs]) |
---|
[1613] | 1870 | sinp = np.sin(phase) |
---|
| 1871 | cosp = np.cos(phase) |
---|
[1990] | 1872 | occ = Mdata*Fdata/Uniq.shape[0] |
---|
[1986] | 1873 | biso = -SQfactor*Uisodata[:,nxs] |
---|
[2097] | 1874 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),Uniq.shape[0],axis=1).T #ops x atoms |
---|
[2038] | 1875 | HbH = -np.sum(UniqP[:,nxs,:3]*np.inner(UniqP[:,:3],bij),axis=-1) #ops x atoms |
---|
| 1876 | Hij = np.array([Mast*np.multiply.outer(U[:3],U[:3]) for U in UniqP]) #atoms x 3x3 |
---|
[2546] | 1877 | Hij = np.array([G2lat.UijtoU6(uij) for uij in Hij]) #atoms x 6 |
---|
[1986] | 1878 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0) #ops x atoms |
---|
[1990] | 1879 | Tcorr = np.reshape(Tiso,Tuij.shape)*Tuij*Mdata*Fdata/Uniq.shape[0] #ops x atoms |
---|
[1992] | 1880 | fot = (FF+FP-Bab)*Tcorr #ops x atoms |
---|
| 1881 | fotp = FPP*Tcorr #ops x atoms |
---|
[3808] | 1882 | GfpuA = G2mth.Modulation(Uniq,UniqP,nWaves,Fmod,Xmod,Umod,glTau,glWt) #2 x sym X atoms |
---|
[3759] | 1883 | dGdf,dGdx,dGdu = G2mth.ModulationDerv(Uniq,UniqP,Hij,nWaves,waveShapes,Fmod,Xmod,UmodAB,SCtauF,SCtauX,SCtauU,glTau,glWt) |
---|
[2046] | 1884 | # GfpuA is 2 x ops x atoms |
---|
[2070] | 1885 | # derivs are: ops x atoms x waves x 2,6,12, or 5 parms as [real,imag] parts |
---|
[2097] | 1886 | fa = np.array([((FF+FP).T-Bab).T*cosp*Tcorr,-Flack*FPP*sinp*Tcorr]) # array(2,nEqv,nAtoms) |
---|
[2046] | 1887 | fb = np.array([((FF+FP).T-Bab).T*sinp*Tcorr,Flack*FPP*cosp*Tcorr]) #or array(2,nEqv,nAtoms) |
---|
[1986] | 1888 | fag = fa*GfpuA[0]-fb*GfpuA[1] |
---|
| 1889 | fbg = fb*GfpuA[0]+fa*GfpuA[1] |
---|
[1613] | 1890 | |
---|
[2041] | 1891 | fas = np.sum(np.sum(fag,axis=1),axis=1) # 2 x twin |
---|
[1986] | 1892 | fbs = np.sum(np.sum(fbg,axis=1),axis=1) |
---|
[2097] | 1893 | fax = np.array([-fot*sinp,-fotp*cosp]) #positions; 2 x ops x atoms |
---|
[1986] | 1894 | fbx = np.array([fot*cosp,-fotp*sinp]) |
---|
| 1895 | fax = fax*GfpuA[0]-fbx*GfpuA[1] |
---|
| 1896 | fbx = fbx*GfpuA[0]+fax*GfpuA[1] |
---|
[1613] | 1897 | #sum below is over Uniq |
---|
[1986] | 1898 | dfadfr = np.sum(fag/occ,axis=1) #Fdata != 0 ever avoids /0. problem |
---|
[1990] | 1899 | dfbdfr = np.sum(fbg/occ,axis=1) #Fdata != 0 avoids /0. problem |
---|
[1992] | 1900 | dfadba = np.sum(-cosp*Tcorr[:,nxs],axis=1) |
---|
| 1901 | dfbdba = np.sum(-sinp*Tcorr[:,nxs],axis=1) |
---|
[1986] | 1902 | dfadui = np.sum(-SQfactor*fag,axis=1) |
---|
[1990] | 1903 | dfbdui = np.sum(-SQfactor*fbg,axis=1) |
---|
[2097] | 1904 | dfadx = np.sum(twopi*Uniq[:,:3]*np.swapaxes(fax,-2,-1)[:,:,:,nxs],axis=-2) #2 x nAtom x 3xyz; sum nOps |
---|
| 1905 | dfbdx = np.sum(twopi*Uniq[:,:3]*np.swapaxes(fbx,-2,-1)[:,:,:,nxs],axis=-2) |
---|
| 1906 | dfadua = np.sum(-Hij*np.swapaxes(fag,-2,-1)[:,:,:,nxs],axis=-2) #2 x nAtom x 6Uij; sum nOps |
---|
| 1907 | dfbdua = np.sum(-Hij*np.swapaxes(fbg,-2,-1)[:,:,:,nxs],axis=-2) #these are correct also for twins above |
---|
| 1908 | # array(2,nAtom,nWave,2) & array(2,nAtom,nWave,6) & array(2,nAtom,nWave,12); sum on nOps |
---|
| 1909 | dfadGf = np.sum(fa[:,:,:,nxs,nxs]*dGdf[0][nxs,:,:,:,:]-fb[:,:,:,nxs,nxs]*dGdf[1][nxs,:,:,:,:],axis=1) |
---|
| 1910 | dfbdGf = np.sum(fb[:,:,:,nxs,nxs]*dGdf[0][nxs,:,:,:,:]+fa[:,:,:,nxs,nxs]*dGdf[1][nxs,:,:,:,:],axis=1) |
---|
| 1911 | dfadGx = np.sum(fa[:,:,:,nxs,nxs]*dGdx[0][nxs,:,:,:,:]-fb[:,:,:,nxs,nxs]*dGdx[1][nxs,:,:,:,:],axis=1) |
---|
| 1912 | dfbdGx = np.sum(fb[:,:,:,nxs,nxs]*dGdx[0][nxs,:,:,:,:]+fa[:,:,:,nxs,nxs]*dGdx[1][nxs,:,:,:,:],axis=1) |
---|
| 1913 | dfadGu = np.sum(fa[:,:,:,nxs,nxs]*dGdu[0][nxs,:,:,:,:]-fb[:,:,:,nxs,nxs]*dGdu[1][nxs,:,:,:,:],axis=1) |
---|
| 1914 | dfbdGu = np.sum(fb[:,:,:,nxs,nxs]*dGdu[0][nxs,:,:,:,:]+fa[:,:,:,nxs,nxs]*dGdu[1][nxs,:,:,:,:],axis=1) |
---|
| 1915 | if not SGData['SGInv']: #Flack derivative |
---|
[1990] | 1916 | dfadfl = np.sum(-FPP*Tcorr*sinp) |
---|
| 1917 | dfbdfl = np.sum(FPP*Tcorr*cosp) |
---|
[1986] | 1918 | else: |
---|
[1990] | 1919 | dfadfl = 1.0 |
---|
| 1920 | dfbdfl = 1.0 |
---|
[2115] | 1921 | SA = fas[0]+fas[1] #float = A+A' |
---|
| 1922 | SB = fbs[0]+fbs[1] #float = B+B' |
---|
[2097] | 1923 | if 'P' in calcControls[hfx+'histType']: #checked perfect for centro & noncentro? |
---|
[2052] | 1924 | dFdfl[iref] = -SA*dfadfl-SB*dfbdfl #array(nRef,) |
---|
[2089] | 1925 | dFdfr[iref] = 2.*(fas[0]*dfadfr[0]+fas[1]*dfadfr[1])*Mdata/len(Uniq)+ \ |
---|
| 1926 | 2.*(fbs[0]*dfbdfr[0]-fbs[1]*dfbdfr[1])*Mdata/len(Uniq) |
---|
| 1927 | dFdx[iref] = 2.*(fas[0]*dfadx[0]+fas[1]*dfadx[1])+ \ |
---|
| 1928 | 2.*(fbs[0]*dfbdx[0]+fbs[1]*dfbdx[1]) |
---|
| 1929 | dFdui[iref] = 2.*(fas[0]*dfadui[0]+fas[1]*dfadui[1])+ \ |
---|
| 1930 | 2.*(fbs[0]*dfbdui[0]-fbs[1]*dfbdui[1]) |
---|
| 1931 | dFdua[iref] = 2.*(fas[0]*dfadua[0]+fas[1]*dfadua[1])+ \ |
---|
| 1932 | 2.*(fbs[0]*dfbdua[0]+fbs[1]*dfbdua[1]) |
---|
| 1933 | dFdGf[iref] = 2.*(fas[0]*dfadGf[0]+fas[1]*dfadGf[1])+ \ |
---|
| 1934 | 2.*(fbs[0]*dfbdGf[0]+fbs[1]*dfbdGf[1]) |
---|
| 1935 | dFdGx[iref] = 2.*(fas[0]*dfadGx[0]+fas[1]*dfadGx[1])+ \ |
---|
| 1936 | 2.*(fbs[0]*dfbdGx[0]-fbs[1]*dfbdGx[1]) |
---|
| 1937 | dFdGu[iref] = 2.*(fas[0]*dfadGu[0]+fas[1]*dfadGu[1])+ \ |
---|
| 1938 | 2.*(fbs[0]*dfbdGu[0]+fbs[1]*dfbdGu[1]) |
---|
[2097] | 1939 | else: #OK, I think |
---|
| 1940 | dFdfr[iref] = 2.*(SA*dfadfr[0]+SA*dfadfr[1]+SB*dfbdfr[0]+SB*dfbdfr[1])*Mdata/len(Uniq) #array(nRef,nAtom) |
---|
| 1941 | dFdx[iref] = 2.*(SA*dfadx[0]+SA*dfadx[1]+SB*dfbdx[0]+SB*dfbdx[1]) #array(nRef,nAtom,3) |
---|
| 1942 | dFdui[iref] = 2.*(SA*dfadui[0]+SA*dfadui[1]+SB*dfbdui[0]+SB*dfbdui[1]) #array(nRef,nAtom) |
---|
| 1943 | dFdua[iref] = 2.*(SA*dfadua[0]+SA*dfadua[1]+SB*dfbdua[0]+SB*dfbdua[1]) #array(nRef,nAtom,6) |
---|
| 1944 | dFdfl[iref] = -SA*dfadfl-SB*dfbdfl #array(nRef,) |
---|
| 1945 | |
---|
| 1946 | dFdGf[iref] = 2.*(SA*dfadGf[0]+SB*dfbdGf[1]) #array(nRef,natom,nwave,2) |
---|
| 1947 | dFdGx[iref] = 2.*(SA*dfadGx[0]+SB*dfbdGx[1]) #array(nRef,natom,nwave,6) |
---|
| 1948 | dFdGu[iref] = 2.*(SA*dfadGu[0]+SB*dfbdGu[1]) #array(nRef,natom,nwave,12) |
---|
[3774] | 1949 | if phfx+'BabA' in parmDict: |
---|
| 1950 | dFdbab[iref] = 2.*fas[0]*np.array([np.sum(dfadba*dBabdA),np.sum(-dfadba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T+ \ |
---|
| 1951 | 2.*fbs[0]*np.array([np.sum(dfbdba*dBabdA),np.sum(-dfbdba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T |
---|
[2097] | 1952 | #loop over atoms - each dict entry is list of derivatives for all the reflections |
---|
| 1953 | if not iref%100 : |
---|
[3136] | 1954 | print (' %d derivative time %.4f\r'%(iref,time.time()-time0),end='') |
---|
[2097] | 1955 | for i in range(len(Mdata)): #loop over atoms |
---|
| 1956 | dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i] |
---|
| 1957 | dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i] |
---|
| 1958 | dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i] |
---|
| 1959 | dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i] |
---|
| 1960 | dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i] |
---|
| 1961 | dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i] |
---|
| 1962 | dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i] |
---|
| 1963 | dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i] |
---|
[3414] | 1964 | dFdvDict[pfx+'AU12:'+str(i)] = 2.*dFdua.T[3][i] |
---|
| 1965 | dFdvDict[pfx+'AU13:'+str(i)] = 2.*dFdua.T[4][i] |
---|
| 1966 | dFdvDict[pfx+'AU23:'+str(i)] = 2.*dFdua.T[5][i] |
---|
[2097] | 1967 | for j in range(FSSdata.shape[1]): #loop over waves Fzero & Fwid? |
---|
| 1968 | dFdvDict[pfx+'Fsin:'+str(i)+':'+str(j)] = dFdGf.T[0][j][i] |
---|
| 1969 | dFdvDict[pfx+'Fcos:'+str(i)+':'+str(j)] = dFdGf.T[1][j][i] |
---|
| 1970 | nx = 0 |
---|
| 1971 | if waveTypes[i] in ['Block','ZigZag']: |
---|
| 1972 | nx = 1 |
---|
| 1973 | for j in range(XSSdata.shape[1]-nx): #loop over waves |
---|
| 1974 | dFdvDict[pfx+'Xsin:'+str(i)+':'+str(j+nx)] = dFdGx.T[0][j][i] |
---|
| 1975 | dFdvDict[pfx+'Ysin:'+str(i)+':'+str(j+nx)] = dFdGx.T[1][j][i] |
---|
| 1976 | dFdvDict[pfx+'Zsin:'+str(i)+':'+str(j+nx)] = dFdGx.T[2][j][i] |
---|
| 1977 | dFdvDict[pfx+'Xcos:'+str(i)+':'+str(j+nx)] = dFdGx.T[3][j][i] |
---|
| 1978 | dFdvDict[pfx+'Ycos:'+str(i)+':'+str(j+nx)] = dFdGx.T[4][j][i] |
---|
| 1979 | dFdvDict[pfx+'Zcos:'+str(i)+':'+str(j+nx)] = dFdGx.T[5][j][i] |
---|
| 1980 | for j in range(USSdata.shape[1]): #loop over waves |
---|
| 1981 | dFdvDict[pfx+'U11sin:'+str(i)+':'+str(j)] = dFdGu.T[0][j][i] |
---|
| 1982 | dFdvDict[pfx+'U22sin:'+str(i)+':'+str(j)] = dFdGu.T[1][j][i] |
---|
| 1983 | dFdvDict[pfx+'U33sin:'+str(i)+':'+str(j)] = dFdGu.T[2][j][i] |
---|
[3414] | 1984 | dFdvDict[pfx+'U12sin:'+str(i)+':'+str(j)] = 2.*dFdGu.T[3][j][i] |
---|
| 1985 | dFdvDict[pfx+'U13sin:'+str(i)+':'+str(j)] = 2.*dFdGu.T[4][j][i] |
---|
| 1986 | dFdvDict[pfx+'U23sin:'+str(i)+':'+str(j)] = 2.*dFdGu.T[5][j][i] |
---|
[2097] | 1987 | dFdvDict[pfx+'U11cos:'+str(i)+':'+str(j)] = dFdGu.T[6][j][i] |
---|
| 1988 | dFdvDict[pfx+'U22cos:'+str(i)+':'+str(j)] = dFdGu.T[7][j][i] |
---|
| 1989 | dFdvDict[pfx+'U33cos:'+str(i)+':'+str(j)] = dFdGu.T[8][j][i] |
---|
[3414] | 1990 | dFdvDict[pfx+'U12cos:'+str(i)+':'+str(j)] = 2.*dFdGu.T[9][j][i] |
---|
| 1991 | dFdvDict[pfx+'U13cos:'+str(i)+':'+str(j)] = 2.*dFdGu.T[10][j][i] |
---|
| 1992 | dFdvDict[pfx+'U23cos:'+str(i)+':'+str(j)] = 2.*dFdGu.T[11][j][i] |
---|
[2097] | 1993 | |
---|
[2115] | 1994 | dFdvDict[phfx+'Flack'] = 4.*dFdfl.T |
---|
[2097] | 1995 | dFdvDict[phfx+'BabA'] = dFdbab.T[0] |
---|
| 1996 | dFdvDict[phfx+'BabU'] = dFdbab.T[1] |
---|
| 1997 | return dFdvDict |
---|
[2110] | 1998 | |
---|
| 1999 | def SStructureFactorDerv2(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict): |
---|
[3759] | 2000 | ''' |
---|
| 2001 | Compute super structure factor derivatives for all h,k,l,m for phase - no twins |
---|
| 2002 | input: |
---|
| 2003 | |
---|
| 2004 | :param dict refDict: where |
---|
| 2005 | 'RefList' list where each ref = h,k,l,m,it,d,... |
---|
| 2006 | 'FF' dict of form factors - filled in below |
---|
| 2007 | :param int im: = 1 (could be eliminated) |
---|
| 2008 | :param np.array G: reciprocal metric tensor |
---|
| 2009 | :param str hfx: histogram id string |
---|
| 2010 | :param str pfx: phase id string |
---|
| 2011 | :param dict SGData: space group info. dictionary output from SpcGroup |
---|
| 2012 | :param dict SSGData: super space group info. |
---|
| 2013 | :param dict calcControls: |
---|
| 2014 | :param dict ParmDict: |
---|
| 2015 | |
---|
| 2016 | :returns: dict dFdvDict: dictionary of derivatives |
---|
| 2017 | ''' |
---|
| 2018 | |
---|
| 2019 | trefDict = copy.deepcopy(refDict) |
---|
[3764] | 2020 | dM = 1.e-4 |
---|
[2110] | 2021 | dFdvDict = {} |
---|
[3759] | 2022 | for parm in parmDict: |
---|
[3764] | 2023 | if parm == '0': |
---|
| 2024 | continue |
---|
[3777] | 2025 | if parm.split(':')[2] in ['Tmin','Tmax','Xmax','Ymax','Zmax','Fzero','Fwid', |
---|
| 2026 | 'MXsin','MXcos','MYsin','MYcos','MZsin','MZcos','AMx','AMy','AMz',]: |
---|
[3759] | 2027 | parmDict[parm] += dM |
---|
| 2028 | prefList = SStructureFactor(trefDict,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) |
---|
| 2029 | parmDict[parm] -= 2*dM |
---|
| 2030 | mrefList = SStructureFactor(trefDict,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) |
---|
| 2031 | parmDict[parm] += dM |
---|
[3764] | 2032 | dFdvDict[parm] = (prefList[:,9+im]-mrefList[:,9+im])/(2.*dM) |
---|
[2110] | 2033 | return dFdvDict |
---|
[2097] | 2034 | |
---|
| 2035 | def SStructureFactorDervTw(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict): |
---|
| 2036 | 'Needs a doc string' |
---|
| 2037 | phfx = pfx.split(':')[0]+hfx |
---|
| 2038 | ast = np.sqrt(np.diag(G)) |
---|
| 2039 | Mast = twopisq*np.multiply.outer(ast,ast) |
---|
| 2040 | SGInv = SGData['SGInv'] |
---|
| 2041 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
| 2042 | SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']]) |
---|
| 2043 | SSGT = np.array([ops[1] for ops in SSGData['SSGOps']]) |
---|
| 2044 | FFtables = calcControls['FFtables'] |
---|
| 2045 | BLtables = calcControls['BLtables'] |
---|
| 2046 | TwinLaw = np.array([[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],]) |
---|
| 2047 | TwDict = refDict.get('TwDict',{}) |
---|
| 2048 | if 'S' in calcControls[hfx+'histType']: |
---|
| 2049 | NTL = calcControls[phfx+'NTL'] |
---|
| 2050 | NM = calcControls[phfx+'TwinNMN']+1 |
---|
| 2051 | TwinLaw = calcControls[phfx+'TwinLaw'] |
---|
| 2052 | TwinInv = list(np.where(calcControls[phfx+'TwinInv'],-1,1)) |
---|
| 2053 | nTwin = len(TwinLaw) |
---|
| 2054 | nRef = len(refDict['RefList']) |
---|
[2478] | 2055 | Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata,Gdata = \ |
---|
| 2056 | GetAtomFXU(pfx,calcControls,parmDict) |
---|
[2750] | 2057 | if not Xdata.size: #no atoms in phase! |
---|
| 2058 | return {} |
---|
[2097] | 2059 | mSize = len(Mdata) #no. atoms |
---|
| 2060 | waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict) |
---|
[3808] | 2061 | ngl,nWaves,Fmod,Xmod,Umod,Mmod,glTau,glWt = G2mth.makeWaves(waveTypes,FSSdata,XSSdata,USSdata,MSSdata,Mast) #NB: Mmod is ReIm,Mxyz,Ntau,Natm |
---|
| 2062 | waveShapes,SCtauF,SCtauX,SCtauU,UmodAB = G2mth.makeWavesDerv(ngl,waveTypes,FSSdata,XSSdata,USSdata,Mast) |
---|
[2097] | 2063 | modQ = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']]) |
---|
| 2064 | FF = np.zeros(len(Tdata)) |
---|
| 2065 | if 'NC' in calcControls[hfx+'histType']: |
---|
| 2066 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam']) |
---|
| 2067 | elif 'X' in calcControls[hfx+'histType']: |
---|
| 2068 | FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata]) |
---|
| 2069 | FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata]) |
---|
| 2070 | Uij = np.array(G2lat.U6toUij(Uijdata)).T |
---|
| 2071 | bij = Mast*Uij |
---|
| 2072 | if not len(refDict['FF']): |
---|
| 2073 | if 'N' in calcControls[hfx+'histType']: |
---|
| 2074 | dat = G2el.getBLvalues(BLtables) #will need wave here for anom. neutron b's |
---|
[1986] | 2075 | else: |
---|
[2097] | 2076 | dat = G2el.getFFvalues(FFtables,0.) |
---|
[3136] | 2077 | refDict['FF']['El'] = list(dat.keys()) |
---|
[2097] | 2078 | refDict['FF']['FF'] = np.zeros((len(refDict['RefList']),len(dat))) |
---|
| 2079 | dFdvDict = {} |
---|
| 2080 | dFdfr = np.zeros((nRef,nTwin,mSize)) |
---|
| 2081 | dFdx = np.zeros((nRef,nTwin,mSize,3)) |
---|
| 2082 | dFdui = np.zeros((nRef,nTwin,mSize)) |
---|
| 2083 | dFdua = np.zeros((nRef,nTwin,mSize,6)) |
---|
| 2084 | dFdbab = np.zeros((nRef,nTwin,2)) |
---|
| 2085 | dFdtw = np.zeros((nRef,nTwin)) |
---|
| 2086 | dFdGf = np.zeros((nRef,nTwin,mSize,FSSdata.shape[1])) |
---|
| 2087 | dFdGx = np.zeros((nRef,nTwin,mSize,XSSdata.shape[1],3)) |
---|
| 2088 | dFdGz = np.zeros((nRef,nTwin,mSize,5)) |
---|
| 2089 | dFdGu = np.zeros((nRef,nTwin,mSize,USSdata.shape[1],6)) |
---|
| 2090 | Flack = 1.0 |
---|
| 2091 | if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict: |
---|
| 2092 | Flack = 1.-2.*parmDict[phfx+'Flack'] |
---|
| 2093 | time0 = time.time() |
---|
| 2094 | nRef = len(refDict['RefList'])/100 |
---|
| 2095 | for iref,refl in enumerate(refDict['RefList']): |
---|
| 2096 | if 'T' in calcControls[hfx+'histType']: |
---|
| 2097 | FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl.T[12+im]) |
---|
| 2098 | H = np.array(refl[:4]) |
---|
| 2099 | HP = H[:3]+modQ*H[3:] #projected hklm to hkl |
---|
| 2100 | H = np.inner(H.T,TwinLaw) #maybe array(4,nTwins) or (4) |
---|
| 2101 | TwMask = np.any(H,axis=-1) |
---|
| 2102 | if TwinLaw.shape[0] > 1 and TwDict: |
---|
| 2103 | if iref in TwDict: |
---|
| 2104 | for i in TwDict[iref]: |
---|
| 2105 | for n in range(NTL): |
---|
| 2106 | H[i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM]) |
---|
| 2107 | TwMask = np.any(H,axis=-1) |
---|
| 2108 | SQ = 1./(2.*refl[4+im])**2 # or (sin(theta)/lambda)**2 |
---|
| 2109 | SQfactor = 8.0*SQ*np.pi**2 |
---|
| 2110 | dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor) |
---|
| 2111 | Bab = parmDict[phfx+'BabA']*dBabdA |
---|
| 2112 | Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata]) |
---|
| 2113 | FF = refDict['FF']['FF'][iref].T[Tindx] |
---|
| 2114 | Uniq = np.inner(H,SSGMT) |
---|
| 2115 | Phi = np.inner(H,SSGT) |
---|
| 2116 | UniqP = np.inner(HP,SGMT) |
---|
| 2117 | if SGInv: #if centro - expand HKL sets |
---|
| 2118 | Uniq = np.vstack((Uniq,-Uniq)) |
---|
| 2119 | Phi = np.hstack((Phi,-Phi)) |
---|
| 2120 | UniqP = np.vstack((UniqP,-UniqP)) |
---|
| 2121 | phase = twopi*(np.inner(Uniq[:,:3],(dXdata+Xdata).T)+Phi[:,nxs]) |
---|
| 2122 | sinp = np.sin(phase) |
---|
| 2123 | cosp = np.cos(phase) |
---|
| 2124 | occ = Mdata*Fdata/Uniq.shape[0] |
---|
| 2125 | biso = -SQfactor*Uisodata[:,nxs] |
---|
| 2126 | Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),Uniq.shape[0]*len(TwinLaw),axis=1).T #ops x atoms |
---|
| 2127 | HbH = -np.sum(UniqP[:,nxs,:3]*np.inner(UniqP[:,:3],bij),axis=-1) #ops x atoms |
---|
| 2128 | Hij = np.array([Mast*np.multiply.outer(U[:3],U[:3]) for U in UniqP]) #atoms x 3x3 |
---|
[2546] | 2129 | Hij = np.squeeze(np.reshape(np.array([G2lat.UijtoU6(uij) for uij in Hij]),(nTwin,-1,6))) |
---|
[2097] | 2130 | Tuij = np.where(HbH<1.,np.exp(HbH),1.0) #ops x atoms |
---|
| 2131 | Tcorr = np.reshape(Tiso,Tuij.shape)*Tuij*Mdata*Fdata/Uniq.shape[0] #ops x atoms |
---|
| 2132 | fot = (FF+FP-Bab)*Tcorr #ops x atoms |
---|
| 2133 | fotp = FPP*Tcorr #ops x atoms |
---|
[3808] | 2134 | GfpuA = G2mth.Modulation(Uniq,UniqP,nWaves,Fmod,Xmod,Umod,glTau,glWt) #2 x sym X atoms |
---|
[2097] | 2135 | dGdf,dGdx,dGdu,dGdz = G2mth.ModulationDerv(Uniq,UniqP,Hij,nWaves,waveShapes,Fmod,Xmod,UmodAB,SCtauF,SCtauX,SCtauU,glTau,glWt) |
---|
| 2136 | # GfpuA is 2 x ops x atoms |
---|
| 2137 | # derivs are: ops x atoms x waves x 2,6,12, or 5 parms as [real,imag] parts |
---|
| 2138 | fa = np.array([((FF+FP).T-Bab).T*cosp*Tcorr,-Flack*FPP*sinp*Tcorr]) # array(2,nTwin,nEqv,nAtoms) |
---|
| 2139 | fb = np.array([((FF+FP).T-Bab).T*sinp*Tcorr,Flack*FPP*cosp*Tcorr]) #or array(2,nEqv,nAtoms) |
---|
| 2140 | fag = fa*GfpuA[0]-fb*GfpuA[1] |
---|
| 2141 | fbg = fb*GfpuA[0]+fa*GfpuA[1] |
---|
| 2142 | |
---|
| 2143 | fas = np.sum(np.sum(fag,axis=1),axis=1) # 2 x twin |
---|
| 2144 | fbs = np.sum(np.sum(fbg,axis=1),axis=1) |
---|
| 2145 | fax = np.array([-fot*sinp,-fotp*cosp]) #positions; 2 x twin x ops x atoms |
---|
| 2146 | fbx = np.array([fot*cosp,-fotp*sinp]) |
---|
| 2147 | fax = fax*GfpuA[0]-fbx*GfpuA[1] |
---|
| 2148 | fbx = fbx*GfpuA[0]+fax*GfpuA[1] |
---|
| 2149 | #sum below is over Uniq |
---|
| 2150 | dfadfr = np.sum(fag/occ,axis=1) #Fdata != 0 ever avoids /0. problem |
---|
| 2151 | dfbdfr = np.sum(fbg/occ,axis=1) #Fdata != 0 avoids /0. problem |
---|
| 2152 | dfadba = np.sum(-cosp*Tcorr[:,nxs],axis=1) |
---|
| 2153 | dfbdba = np.sum(-sinp*Tcorr[:,nxs],axis=1) |
---|
| 2154 | dfadui = np.sum(-SQfactor*fag,axis=1) |
---|
| 2155 | dfbdui = np.sum(-SQfactor*fbg,axis=1) |
---|
| 2156 | dfadx = np.array([np.sum(twopi*Uniq[it,:,:3]*np.swapaxes(fax,-2,-1)[:,it,:,:,nxs],axis=-2) for it in range(nTwin)]) |
---|
| 2157 | dfbdx = np.array([np.sum(twopi*Uniq[it,:,:3]*np.swapaxes(fbx,-2,-1)[:,it,:,:,nxs],axis=-2) for it in range(nTwin)]) |
---|
| 2158 | dfadua = np.array([np.sum(-Hij[it]*np.swapaxes(fag,-2,-1)[:,it,:,:,nxs],axis=-2) for it in range(nTwin)]) |
---|
| 2159 | dfbdua = np.array([np.sum(-Hij[it]*np.swapaxes(fbg,-2,-1)[:,it,:,:,nxs],axis=-2) for it in range(nTwin)]) |
---|
| 2160 | # array(2,nTwin,nAtom,3) & array(2,nTwin,nAtom,6) & array(2,nTwin,nAtom,12) |
---|
| 2161 | dfadGf = np.sum(fa[:,it,:,:,nxs,nxs]*dGdf[0][nxs,nxs,:,:,:,:]-fb[:,it,:,:,nxs,nxs]*dGdf[1][nxs,nxs,:,:,:,:],axis=1) |
---|
| 2162 | dfbdGf = np.sum(fb[:,it,:,:,nxs,nxs]*dGdf[0][nxs,nxs,:,:,:,:]+fa[:,it,:,:,nxs,nxs]*dGdf[1][nxs,nxs,:,:,:,:],axis=1) |
---|
| 2163 | dfadGx = np.sum(fa[:,it,:,:,nxs,nxs]*dGdx[0][nxs,nxs,:,:,:,:]-fb[:,it,:,:,nxs,nxs]*dGdx[1][nxs,nxs,:,:,:,:],axis=1) |
---|
| 2164 | dfbdGx = np.sum(fb[:,it,:,:,nxs,nxs]*dGdx[0][nxs,nxs,:,:,:,:]+fa[:,it,:,:,nxs,nxs]*dGdx[1][nxs,nxs,:,:,:,:],axis=1) |
---|
| 2165 | dfadGz = np.sum(fa[:,it,:,0,nxs,nxs]*dGdz[0][nxs,nxs,:,:,:]-fb[:,it,:,0,nxs,nxs]*dGdz[1][nxs,nxs,:,:,:],axis=1) |
---|
| 2166 | dfbdGz = np.sum(fb[:,it,:,0,nxs,nxs]*dGdz[0][nxs,nxs,:,:,:]+fa[:,it,:,0,nxs,nxs]*dGdz[1][nxs,nxs,:,:,:],axis=1) |
---|
| 2167 | dfadGu = np.sum(fa[:,it,:,:,nxs,nxs]*dGdu[0][nxs,nxs,:,:,:,:]-fb[:,it,:,:,nxs,nxs]*dGdu[1][nxs,nxs,:,:,:,:],axis=1) |
---|
| 2168 | dfbdGu = np.sum(fb[:,it,:,:,nxs,nxs]*dGdu[0][nxs,nxs,:,:,:,:]+fa[:,it,:,:,nxs,nxs]*dGdu[1][nxs,nxs,:,:,:,:],axis=1) |
---|
| 2169 | # GSASIIpath.IPyBreak() |
---|
| 2170 | #NB: the above have been checked against PA(1:10,1:2) in strfctr.for for Al2O3! |
---|
| 2171 | SA = fas[0]+fas[1] #float = A+A' (might be array[nTwin]) |
---|
| 2172 | SB = fbs[0]+fbs[1] #float = B+B' (might be array[nTwin]) |
---|
| 2173 | dFdfr[iref] = [2.*TwMask[it]*(SA[it]*dfadfr[0][it]+SA[it]*dfadfr[1][it]+SB[it]*dfbdfr[0][it]+SB[it]*dfbdfr[1][it])*Mdata/len(Uniq[it]) for it in range(nTwin)] |
---|
| 2174 | dFdx[iref] = [2.*TwMask[it]*(SA[it]*dfadx[it][0]+SA[it]*dfadx[it][1]+SB[it]*dfbdx[it][0]+SB[it]*dfbdx[it][1]) for it in range(nTwin)] |
---|
| 2175 | dFdui[iref] = [2.*TwMask[it]*(SA[it]*dfadui[it][0]+SA[it]*dfadui[it][1]+SB[it]*dfbdui[it][0]+SB[it]*dfbdui[it][1]) for it in range(nTwin)] |
---|
| 2176 | dFdua[iref] = [2.*TwMask[it]*(SA[it]*dfadua[it][0]+SA[it]*dfadua[it][1]+SB[it]*dfbdua[it][0]+SB[it]*dfbdua[it][1]) for it in range(nTwin)] |
---|
| 2177 | dFdtw[iref] = np.sum(TwMask*fas,axis=0)**2+np.sum(TwMask*fbs,axis=0)**2 |
---|
[2046] | 2178 | |
---|
[2097] | 2179 | dFdGf[iref] = [2.*TwMask[it]*(SA[it]*dfadGf[1]+SB[it]*dfbdGf[1]) for it in range(nTwin)] |
---|
| 2180 | dFdGx[iref] = [2.*TwMask[it]*(SA[it]*dfadGx[1]+SB[it]*dfbdGx[1]) for it in range(nTwin)] |
---|
| 2181 | dFdGz[iref] = [2.*TwMask[it]*(SA[it]*dfadGz[1]+SB[it]*dfbdGz[1]) for it in range(nTwin)] |
---|
| 2182 | dFdGu[iref] = [2.*TwMask[it]*(SA[it]*dfadGu[1]+SB[it]*dfbdGu[1]) for it in range(nTwin)] |
---|
[2089] | 2183 | # GSASIIpath.IPyBreak() |
---|
[1986] | 2184 | dFdbab[iref] = 2.*fas[0]*np.array([np.sum(dfadba*dBabdA),np.sum(-dfadba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T+ \ |
---|
| 2185 | 2.*fbs[0]*np.array([np.sum(dfbdba*dBabdA),np.sum(-dfbdba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T |
---|
[1613] | 2186 | #loop over atoms - each dict entry is list of derivatives for all the reflections |
---|
[2005] | 2187 | if not iref%100 : |
---|
[3136] | 2188 | print (' %d derivative time %.4f\r'%(iref,time.time()-time0),end='') |
---|
[2075] | 2189 | for i in range(len(Mdata)): #loop over atoms |
---|
[1613] | 2190 | dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i] |
---|
| 2191 | dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i] |
---|
| 2192 | dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i] |
---|
| 2193 | dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i] |
---|
| 2194 | dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i] |
---|
| 2195 | dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i] |
---|
| 2196 | dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i] |
---|
| 2197 | dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i] |
---|
[3414] | 2198 | dFdvDict[pfx+'AU12:'+str(i)] = 2.*dFdua.T[3][i] |
---|
| 2199 | dFdvDict[pfx+'AU13:'+str(i)] = 2.*dFdua.T[4][i] |
---|
| 2200 | dFdvDict[pfx+'AU23:'+str(i)] = 2.*dFdua.T[5][i] |
---|
[2041] | 2201 | for j in range(FSSdata.shape[1]): #loop over waves Fzero & Fwid? |
---|
| 2202 | dFdvDict[pfx+'Fsin:'+str(i)+':'+str(j)] = dFdGf.T[0][j][i] |
---|
| 2203 | dFdvDict[pfx+'Fcos:'+str(i)+':'+str(j)] = dFdGf.T[1][j][i] |
---|
[2075] | 2204 | nx = 0 |
---|
| 2205 | if waveTypes[i] in ['Block','ZigZag']: |
---|
| 2206 | nx = 1 |
---|
| 2207 | dFdvDict[pfx+'Tmin:'+str(i)+':0'] = dFdGz.T[0][i] #ZigZag/Block waves (if any) |
---|
| 2208 | dFdvDict[pfx+'Tmax:'+str(i)+':0'] = dFdGz.T[1][i] |
---|
| 2209 | dFdvDict[pfx+'Xmax:'+str(i)+':0'] = dFdGz.T[2][i] |
---|
| 2210 | dFdvDict[pfx+'Ymax:'+str(i)+':0'] = dFdGz.T[3][i] |
---|
| 2211 | dFdvDict[pfx+'Zmax:'+str(i)+':0'] = dFdGz.T[4][i] |
---|
| 2212 | for j in range(XSSdata.shape[1]-nx): #loop over waves |
---|
| 2213 | dFdvDict[pfx+'Xsin:'+str(i)+':'+str(j+nx)] = dFdGx.T[0][j][i] |
---|
| 2214 | dFdvDict[pfx+'Ysin:'+str(i)+':'+str(j+nx)] = dFdGx.T[1][j][i] |
---|
| 2215 | dFdvDict[pfx+'Zsin:'+str(i)+':'+str(j+nx)] = dFdGx.T[2][j][i] |
---|
| 2216 | dFdvDict[pfx+'Xcos:'+str(i)+':'+str(j+nx)] = dFdGx.T[3][j][i] |
---|
| 2217 | dFdvDict[pfx+'Ycos:'+str(i)+':'+str(j+nx)] = dFdGx.T[4][j][i] |
---|
| 2218 | dFdvDict[pfx+'Zcos:'+str(i)+':'+str(j+nx)] = dFdGx.T[5][j][i] |
---|
[2041] | 2219 | for j in range(USSdata.shape[1]): #loop over waves |
---|
[2038] | 2220 | dFdvDict[pfx+'U11sin:'+str(i)+':'+str(j)] = dFdGu.T[0][j][i] |
---|
| 2221 | dFdvDict[pfx+'U22sin:'+str(i)+':'+str(j)] = dFdGu.T[1][j][i] |
---|
| 2222 | dFdvDict[pfx+'U33sin:'+str(i)+':'+str(j)] = dFdGu.T[2][j][i] |
---|
[3414] | 2223 | dFdvDict[pfx+'U12sin:'+str(i)+':'+str(j)] = 2.*dFdGu.T[3][j][i] |
---|
| 2224 | dFdvDict[pfx+'U13sin:'+str(i)+':'+str(j)] = 2.*dFdGu.T[4][j][i] |
---|
| 2225 | dFdvDict[pfx+'U23sin:'+str(i)+':'+str(j)] = 2.*dFdGu.T[5][j][i] |
---|
[2038] | 2226 | dFdvDict[pfx+'U11cos:'+str(i)+':'+str(j)] = dFdGu.T[6][j][i] |
---|
| 2227 | dFdvDict[pfx+'U22cos:'+str(i)+':'+str(j)] = dFdGu.T[7][j][i] |
---|
| 2228 | dFdvDict[pfx+'U33cos:'+str(i)+':'+str(j)] = dFdGu.T[8][j][i] |
---|
[3414] | 2229 | dFdvDict[pfx+'U12cos:'+str(i)+':'+str(j)] = 2.*dFdGu.T[9][j][i] |
---|
| 2230 | dFdvDict[pfx+'U13cos:'+str(i)+':'+str(j)] = 2.*dFdGu.T[10][j][i] |
---|
| 2231 | dFdvDict[pfx+'U23cos:'+str(i)+':'+str(j)] = 2.*dFdGu.T[11][j][i] |
---|
[2038] | 2232 | |
---|
[2089] | 2233 | # GSASIIpath.IPyBreak() |
---|
[1878] | 2234 | dFdvDict[phfx+'BabA'] = dFdbab.T[0] |
---|
| 2235 | dFdvDict[phfx+'BabU'] = dFdbab.T[1] |
---|
[1613] | 2236 | return dFdvDict |
---|
| 2237 | |
---|
[1595] | 2238 | def SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varyList): |
---|
[1465] | 2239 | ''' Single crystal extinction function; returns extinction & derivative |
---|
[1299] | 2240 | ''' |
---|
[1460] | 2241 | extCor = 1.0 |
---|
[1299] | 2242 | dervDict = {} |
---|
[1857] | 2243 | dervCor = 1.0 |
---|
[1299] | 2244 | if calcControls[phfx+'EType'] != 'None': |
---|
[1595] | 2245 | SQ = 1/(4.*ref[4+im]**2) |
---|
[1453] | 2246 | if 'C' in parmDict[hfx+'Type']: |
---|
| 2247 | cos2T = 1.0-2.*SQ*parmDict[hfx+'Lam']**2 #cos(2theta) |
---|
| 2248 | else: #'T' |
---|
[1595] | 2249 | cos2T = 1.0-2.*SQ*ref[12+im]**2 #cos(2theta) |
---|
[1299] | 2250 | if 'SXC' in parmDict[hfx+'Type']: |
---|
| 2251 | AV = 7.9406e5/parmDict[pfx+'Vol']**2 |
---|
| 2252 | PL = np.sqrt(1.0-cos2T**2)/parmDict[hfx+'Lam'] |
---|
| 2253 | P12 = (calcControls[phfx+'Cos2TM']+cos2T**4)/(calcControls[phfx+'Cos2TM']+cos2T**2) |
---|
[1776] | 2254 | PLZ = AV*P12*ref[9+im]*parmDict[hfx+'Lam']**2 |
---|
[1299] | 2255 | elif 'SNT' in parmDict[hfx+'Type']: |
---|
| 2256 | AV = 1.e7/parmDict[pfx+'Vol']**2 |
---|
[1453] | 2257 | PL = SQ |
---|
[1776] | 2258 | PLZ = AV*ref[9+im]*ref[12+im]**2 |
---|
[1299] | 2259 | elif 'SNC' in parmDict[hfx+'Type']: |
---|
| 2260 | AV = 1.e7/parmDict[pfx+'Vol']**2 |
---|
| 2261 | PL = np.sqrt(1.0-cos2T**2)/parmDict[hfx+'Lam'] |
---|
[1776] | 2262 | PLZ = AV*ref[9+im]*parmDict[hfx+'Lam']**2 |
---|
[1299] | 2263 | |
---|
| 2264 | if 'Primary' in calcControls[phfx+'EType']: |
---|
| 2265 | PLZ *= 1.5 |
---|
| 2266 | else: |
---|
[1453] | 2267 | if 'C' in parmDict[hfx+'Type']: |
---|
| 2268 | PLZ *= calcControls[phfx+'Tbar'] |
---|
| 2269 | else: #'T' |
---|
[1595] | 2270 | PLZ *= ref[13+im] #t-bar |
---|
[1299] | 2271 | if 'Primary' in calcControls[phfx+'EType']: |
---|
[1453] | 2272 | PLZ *= 1.5 |
---|
[1299] | 2273 | PSIG = parmDict[phfx+'Ep'] |
---|
| 2274 | elif 'I & II' in calcControls[phfx+'EType']: |
---|
| 2275 | PSIG = parmDict[phfx+'Eg']/np.sqrt(1.+(parmDict[phfx+'Es']*PL/parmDict[phfx+'Eg'])**2) |
---|
| 2276 | elif 'Type II' in calcControls[phfx+'EType']: |
---|
| 2277 | PSIG = parmDict[phfx+'Es'] |
---|
| 2278 | else: # 'Secondary Type I' |
---|
| 2279 | PSIG = parmDict[phfx+'Eg']/PL |
---|
| 2280 | |
---|
| 2281 | AG = 0.58+0.48*cos2T+0.24*cos2T**2 |
---|
| 2282 | AL = 0.025+0.285*cos2T |
---|
| 2283 | BG = 0.02-0.025*cos2T |
---|
| 2284 | BL = 0.15-0.2*(0.75-cos2T)**2 |
---|
| 2285 | if cos2T < 0.: |
---|
| 2286 | BL = -0.45*cos2T |
---|
| 2287 | CG = 2. |
---|
| 2288 | CL = 2. |
---|
| 2289 | PF = PLZ*PSIG |
---|
| 2290 | |
---|
| 2291 | if 'Gaussian' in calcControls[phfx+'EApprox']: |
---|
| 2292 | PF4 = 1.+CG*PF+AG*PF**2/(1.+BG*PF) |
---|
| 2293 | extCor = np.sqrt(PF4) |
---|
| 2294 | PF3 = 0.5*(CG+2.*AG*PF/(1.+BG*PF)-AG*PF**2*BG/(1.+BG*PF)**2)/(PF4*extCor) |
---|
| 2295 | else: |
---|
| 2296 | PF4 = 1.+CL*PF+AL*PF**2/(1.+BL*PF) |
---|
| 2297 | extCor = np.sqrt(PF4) |
---|
| 2298 | PF3 = 0.5*(CL+2.*AL*PF/(1.+BL*PF)-AL*PF**2*BL/(1.+BL*PF)**2)/(PF4*extCor) |
---|
| 2299 | |
---|
[1857] | 2300 | dervCor = (1.+PF)*PF3 #extinction corr for other derivatives |
---|
[1299] | 2301 | if 'Primary' in calcControls[phfx+'EType'] and phfx+'Ep' in varyList: |
---|
[1595] | 2302 | dervDict[phfx+'Ep'] = -ref[7+im]*PLZ*PF3 |
---|
[1299] | 2303 | if 'II' in calcControls[phfx+'EType'] and phfx+'Es' in varyList: |
---|
[1595] | 2304 | dervDict[phfx+'Es'] = -ref[7+im]*PLZ*PF3*(PSIG/parmDict[phfx+'Es'])**3 |
---|
[1299] | 2305 | if 'I' in calcControls[phfx+'EType'] and phfx+'Eg' in varyList: |
---|
[1595] | 2306 | dervDict[phfx+'Eg'] = -ref[7+im]*PLZ*PF3*(PSIG/parmDict[phfx+'Eg'])**3*PL**2 |
---|
[1299] | 2307 | |
---|
[1857] | 2308 | return 1./extCor,dervDict,dervCor |
---|
[1299] | 2309 | |
---|
| 2310 | def Dict2Values(parmdict, varylist): |
---|
| 2311 | '''Use before call to leastsq to setup list of values for the parameters |
---|
| 2312 | in parmdict, as selected by key in varylist''' |
---|
| 2313 | return [parmdict[key] for key in varylist] |
---|
| 2314 | |
---|
[1320] | 2315 | def Values2Dict(parmdict, varylist, values): |
---|
| 2316 | ''' Use after call to leastsq to update the parameter dictionary with |
---|
| 2317 | values corresponding to keys in varylist''' |
---|
| 2318 | parmdict.update(zip(varylist,values)) |
---|
[1299] | 2319 | |
---|
| 2320 | def GetNewCellParms(parmDict,varyList): |
---|
| 2321 | 'Needs a doc string' |
---|
| 2322 | newCellDict = {} |
---|
| 2323 | Anames = ['A'+str(i) for i in range(6)] |
---|
| 2324 | Ddict = dict(zip(['D11','D22','D33','D12','D13','D23'],Anames)) |
---|
| 2325 | for item in varyList: |
---|
| 2326 | keys = item.split(':') |
---|
| 2327 | if keys[2] in Ddict: |
---|
| 2328 | key = keys[0]+'::'+Ddict[keys[2]] #key is e.g. '0::A0' |
---|
| 2329 | parm = keys[0]+'::'+keys[2] #parm is e.g. '0::D11' |
---|
[1562] | 2330 | newCellDict[parm] = [key,parmDict[key]+parmDict[item]] |
---|
[1482] | 2331 | return newCellDict # is e.g. {'0::D11':A0-D11} |
---|
[1299] | 2332 | |
---|
| 2333 | def ApplyXYZshifts(parmDict,varyList): |
---|
| 2334 | ''' |
---|
| 2335 | takes atom x,y,z shift and applies it to corresponding atom x,y,z value |
---|
| 2336 | |
---|
| 2337 | :param dict parmDict: parameter dictionary |
---|
[1335] | 2338 | :param list varyList: list of variables (not used!) |
---|
[1299] | 2339 | :returns: newAtomDict - dictionary of new atomic coordinate names & values; key is parameter shift name |
---|
| 2340 | |
---|
| 2341 | ''' |
---|
| 2342 | newAtomDict = {} |
---|
| 2343 | for item in parmDict: |
---|
| 2344 | if 'dA' in item: |
---|
| 2345 | parm = ''.join(item.split('d')) |
---|
| 2346 | parmDict[parm] += parmDict[item] |
---|
| 2347 | newAtomDict[item] = [parm,parmDict[parm]] |
---|
| 2348 | return newAtomDict |
---|
| 2349 | |
---|
[1595] | 2350 | def SHTXcal(refl,im,g,pfx,hfx,SGData,calcControls,parmDict): |
---|
[1299] | 2351 | 'Spherical harmonics texture' |
---|
| 2352 | IFCoup = 'Bragg' in calcControls[hfx+'instType'] |
---|
[1459] | 2353 | if 'T' in calcControls[hfx+'histType']: |
---|
| 2354 | tth = parmDict[hfx+'2-theta'] |
---|
| 2355 | else: |
---|
[1595] | 2356 | tth = refl[5+im] |
---|
[1299] | 2357 | odfCor = 1.0 |
---|
| 2358 | H = refl[:3] |
---|
| 2359 | cell = G2lat.Gmat2cell(g) |
---|
| 2360 | Sangls = [parmDict[pfx+'SH omega'],parmDict[pfx+'SH chi'],parmDict[pfx+'SH phi']] |
---|
[1767] | 2361 | Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']] |
---|
[1299] | 2362 | phi,beta = G2lat.CrsAng(H,cell,SGData) |
---|
[1459] | 2363 | psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) #ignore 2 sets of angle derivs. |
---|
[1299] | 2364 | SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],parmDict[pfx+'SHmodel'],parmDict[pfx+'SHorder']) |
---|
| 2365 | for item in SHnames: |
---|
| 2366 | L,M,N = eval(item.strip('C')) |
---|
| 2367 | Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta) |
---|
| 2368 | Ksl,x,x = G2lat.GetKsl(L,M,parmDict[pfx+'SHmodel'],psi,gam) |
---|
| 2369 | Lnorm = G2lat.Lnorm(L) |
---|
| 2370 | odfCor += parmDict[pfx+item]*Lnorm*Kcl*Ksl |
---|
| 2371 | return odfCor |
---|
| 2372 | |
---|
[1595] | 2373 | def SHTXcalDerv(refl,im,g,pfx,hfx,SGData,calcControls,parmDict): |
---|
[1299] | 2374 | 'Spherical harmonics texture derivatives' |
---|
[1459] | 2375 | if 'T' in calcControls[hfx+'histType']: |
---|
| 2376 | tth = parmDict[hfx+'2-theta'] |
---|
| 2377 | else: |
---|
[1595] | 2378 | tth = refl[5+im] |
---|
[1299] | 2379 | IFCoup = 'Bragg' in calcControls[hfx+'instType'] |
---|
| 2380 | odfCor = 1.0 |
---|
| 2381 | dFdODF = {} |
---|
| 2382 | dFdSA = [0,0,0] |
---|
| 2383 | H = refl[:3] |
---|
| 2384 | cell = G2lat.Gmat2cell(g) |
---|
| 2385 | Sangls = [parmDict[pfx+'SH omega'],parmDict[pfx+'SH chi'],parmDict[pfx+'SH phi']] |
---|
[1767] | 2386 | Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']] |
---|
[1299] | 2387 | phi,beta = G2lat.CrsAng(H,cell,SGData) |
---|
[1459] | 2388 | psi,gam,dPSdA,dGMdA = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) |
---|
[1299] | 2389 | SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],parmDict[pfx+'SHmodel'],parmDict[pfx+'SHorder']) |
---|
| 2390 | for item in SHnames: |
---|
| 2391 | L,M,N = eval(item.strip('C')) |
---|
| 2392 | Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta) |
---|
| 2393 | Ksl,dKsdp,dKsdg = G2lat.GetKsl(L,M,parmDict[pfx+'SHmodel'],psi,gam) |
---|
| 2394 | Lnorm = G2lat.Lnorm(L) |
---|
| 2395 | odfCor += parmDict[pfx+item]*Lnorm*Kcl*Ksl |
---|
| 2396 | dFdODF[pfx+item] = Lnorm*Kcl*Ksl |
---|
| 2397 | for i in range(3): |
---|
| 2398 | dFdSA[i] += parmDict[pfx+item]*Lnorm*Kcl*(dKsdp*dPSdA[i]+dKsdg*dGMdA[i]) |
---|
| 2399 | return odfCor,dFdODF,dFdSA |
---|
| 2400 | |
---|
[1595] | 2401 | def SHPOcal(refl,im,g,phfx,hfx,SGData,calcControls,parmDict): |
---|
[1299] | 2402 | 'spherical harmonics preferred orientation (cylindrical symmetry only)' |
---|
[1459] | 2403 | if 'T' in calcControls[hfx+'histType']: |
---|
| 2404 | tth = parmDict[hfx+'2-theta'] |
---|
| 2405 | else: |
---|
[1595] | 2406 | tth = refl[5+im] |
---|
[1299] | 2407 | odfCor = 1.0 |
---|
| 2408 | H = refl[:3] |
---|
| 2409 | cell = G2lat.Gmat2cell(g) |
---|
[1835] | 2410 | Sangls = [0.,0.,0.] |
---|
[1299] | 2411 | if 'Bragg' in calcControls[hfx+'instType']: |
---|
| 2412 | Gangls = [0.,90.,0.,parmDict[hfx+'Azimuth']] |
---|
| 2413 | IFCoup = True |
---|
| 2414 | else: |
---|
[1791] | 2415 | Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']] |
---|
[1299] | 2416 | IFCoup = False |
---|
| 2417 | phi,beta = G2lat.CrsAng(H,cell,SGData) |
---|
[1835] | 2418 | psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) #ignore 2 sets of angle derivs. |
---|
[1777] | 2419 | SHnames = calcControls[phfx+'SHnames'] |
---|
[1299] | 2420 | for item in SHnames: |
---|
| 2421 | L,N = eval(item.strip('C')) |
---|
[1812] | 2422 | Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta) |
---|
| 2423 | Ksl,x,x = G2lat.GetKsl(L,0,'0',psi,gam) |
---|
| 2424 | Lnorm = G2lat.Lnorm(L) |
---|
| 2425 | odfCor += parmDict[phfx+item]*Lnorm*Kcl*Ksl |
---|
[1299] | 2426 | return np.squeeze(odfCor) |
---|
| 2427 | |
---|
[1595] | 2428 | def SHPOcalDerv(refl,im,g,phfx,hfx,SGData,calcControls,parmDict): |
---|
[1299] | 2429 | 'spherical harmonics preferred orientation derivatives (cylindrical symmetry only)' |
---|
[1459] | 2430 | if 'T' in calcControls[hfx+'histType']: |
---|
| 2431 | tth = parmDict[hfx+'2-theta'] |
---|
| 2432 | else: |
---|
[1595] | 2433 | tth = refl[5+im] |
---|
[1299] | 2434 | odfCor = 1.0 |
---|
| 2435 | dFdODF = {} |
---|
| 2436 | H = refl[:3] |
---|
| 2437 | cell = G2lat.Gmat2cell(g) |
---|
[1835] | 2438 | Sangls = [0.,0.,0.] |
---|
[1299] | 2439 | if 'Bragg' in calcControls[hfx+'instType']: |
---|
| 2440 | Gangls = [0.,90.,0.,parmDict[hfx+'Azimuth']] |
---|
| 2441 | IFCoup = True |
---|
| 2442 | else: |
---|
[1791] | 2443 | Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']] |
---|
[1299] | 2444 | IFCoup = False |
---|
| 2445 | phi,beta = G2lat.CrsAng(H,cell,SGData) |
---|
[1835] | 2446 | psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) #ignore 2 sets of angle derivs. |
---|
[1777] | 2447 | SHnames = calcControls[phfx+'SHnames'] |
---|
[1299] | 2448 | for item in SHnames: |
---|
| 2449 | L,N = eval(item.strip('C')) |
---|
[1812] | 2450 | Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta) |
---|
| 2451 | Ksl,x,x = G2lat.GetKsl(L,0,'0',psi,gam) |
---|
| 2452 | Lnorm = G2lat.Lnorm(L) |
---|
| 2453 | odfCor += parmDict[phfx+item]*Lnorm*Kcl*Ksl |
---|
| 2454 | dFdODF[phfx+item] = Kcl*Ksl*Lnorm |
---|
[1299] | 2455 | return odfCor,dFdODF |
---|
| 2456 | |
---|
[1595] | 2457 | def GetPrefOri(uniq,G,g,phfx,hfx,SGData,calcControls,parmDict): |
---|
[1460] | 2458 | 'March-Dollase preferred orientation correction' |
---|
[1299] | 2459 | POcorr = 1.0 |
---|
[1460] | 2460 | MD = parmDict[phfx+'MD'] |
---|
| 2461 | if MD != 1.0: |
---|
| 2462 | MDAxis = calcControls[phfx+'MDAxis'] |
---|
| 2463 | sumMD = 0 |
---|
| 2464 | for H in uniq: |
---|
| 2465 | cosP,sinP = G2lat.CosSinAngle(H,MDAxis,G) |
---|
| 2466 | A = 1.0/np.sqrt((MD*cosP)**2+sinP**2/MD) |
---|
| 2467 | sumMD += A**3 |
---|
| 2468 | POcorr = sumMD/len(uniq) |
---|
[1299] | 2469 | return POcorr |
---|
| 2470 | |
---|
[1595] | 2471 | def GetPrefOriDerv(refl,im,uniq,G,g,phfx,hfx,SGData,calcControls,parmDict): |
---|
[1299] | 2472 | 'Needs a doc string' |
---|
| 2473 | POcorr = 1.0 |
---|
| 2474 | POderv = {} |
---|
| 2475 | if calcControls[phfx+'poType'] == 'MD': |
---|
| 2476 | MD = parmDict[phfx+'MD'] |
---|
| 2477 | MDAxis = calcControls[phfx+'MDAxis'] |
---|
| 2478 | sumMD = 0 |
---|
| 2479 | sumdMD = 0 |
---|
| 2480 | for H in uniq: |
---|
| 2481 | cosP,sinP = G2lat.CosSinAngle(H,MDAxis,G) |
---|
| 2482 | A = 1.0/np.sqrt((MD*cosP)**2+sinP**2/MD) |
---|
| 2483 | sumMD += A**3 |
---|
| 2484 | sumdMD -= (1.5*A**5)*(2.0*MD*cosP**2-(sinP/MD)**2) |
---|
| 2485 | POcorr = sumMD/len(uniq) |
---|
| 2486 | POderv[phfx+'MD'] = sumdMD/len(uniq) |
---|
| 2487 | else: #spherical harmonics |
---|
| 2488 | if calcControls[phfx+'SHord']: |
---|
[1595] | 2489 | POcorr,POderv = SHPOcalDerv(refl,im,g,phfx,hfx,SGData,calcControls,parmDict) |
---|
[1299] | 2490 | return POcorr,POderv |
---|
| 2491 | |
---|
[1595] | 2492 | def GetAbsorb(refl,im,hfx,calcControls,parmDict): |
---|
[1299] | 2493 | 'Needs a doc string' |
---|
| 2494 | if 'Debye' in calcControls[hfx+'instType']: |
---|
[1459] | 2495 | if 'T' in calcControls[hfx+'histType']: |
---|
[1766] | 2496 | return G2pwd.Absorb('Cylinder',parmDict[hfx+'Absorption']*refl[14+im],abs(parmDict[hfx+'2-theta']),0,0) |
---|
[1459] | 2497 | else: |
---|
[1595] | 2498 | return G2pwd.Absorb('Cylinder',parmDict[hfx+'Absorption'],refl[5+im],0,0) |
---|
[1299] | 2499 | else: |
---|
[1595] | 2500 | return G2pwd.SurfaceRough(parmDict[hfx+'SurfRoughA'],parmDict[hfx+'SurfRoughB'],refl[5+im]) |
---|
[1299] | 2501 | |
---|
[1595] | 2502 | def GetAbsorbDerv(refl,im,hfx,calcControls,parmDict): |
---|
[1299] | 2503 | 'Needs a doc string' |
---|
| 2504 | if 'Debye' in calcControls[hfx+'instType']: |
---|
[1459] | 2505 | if 'T' in calcControls[hfx+'histType']: |
---|
[1766] | 2506 | return G2pwd.AbsorbDerv('Cylinder',parmDict[hfx+'Absorption']*refl[14+im],abs(parmDict[hfx+'2-theta']),0,0) |
---|
[1459] | 2507 | else: |
---|
[1595] | 2508 | return G2pwd.AbsorbDerv('Cylinder',parmDict[hfx+'Absorption'],refl[5+im],0,0) |
---|
[1299] | 2509 | else: |
---|
[1595] | 2510 | return np.array(G2pwd.SurfaceRoughDerv(parmDict[hfx+'SurfRoughA'],parmDict[hfx+'SurfRoughB'],refl[5+im])) |
---|
[1460] | 2511 | |
---|
[1595] | 2512 | def GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict): |
---|
[1460] | 2513 | 'Needs a doc string' |
---|
| 2514 | coef = np.array([-0.5,0.25,-0.10416667,0.036458333,-0.0109375,2.8497409E-3]) |
---|
[1465] | 2515 | pi2 = np.sqrt(2./np.pi) |
---|
[1460] | 2516 | if 'T' in calcControls[hfx+'histType']: |
---|
[1766] | 2517 | sth2 = sind(abs(parmDict[hfx+'2-theta'])/2.)**2 |
---|
[1595] | 2518 | wave = refl[14+im] |
---|
[1460] | 2519 | else: #'C'W |
---|
[1595] | 2520 | sth2 = sind(refl[5+im]/2.)**2 |
---|
[1460] | 2521 | wave = parmDict.get(hfx+'Lam',parmDict.get(hfx+'Lam1',1.0)) |
---|
| 2522 | c2th = 1.-2.0*sth2 |
---|
[1595] | 2523 | flv2 = refl[9+im]*(wave/parmDict[pfx+'Vol'])**2 |
---|
[1460] | 2524 | if 'X' in calcControls[hfx+'histType']: |
---|
| 2525 | flv2 *= 0.079411*(1.0+c2th**2)/2.0 |
---|
| 2526 | xfac = flv2*parmDict[phfx+'Extinction'] |
---|
| 2527 | exb = 1.0 |
---|
| 2528 | if xfac > -1.: |
---|
[1874] | 2529 | exb = 1./np.sqrt(1.+xfac) |
---|
[1460] | 2530 | exl = 1.0 |
---|
| 2531 | if 0 < xfac <= 1.: |
---|
| 2532 | xn = np.array([xfac**(i+1) for i in range(6)]) |
---|
[1761] | 2533 | exl += np.sum(xn*coef) |
---|
[1460] | 2534 | elif xfac > 1.: |
---|
| 2535 | xfac2 = 1./np.sqrt(xfac) |
---|
| 2536 | exl = pi2*(1.-0.125/xfac)*xfac2 |
---|
| 2537 | return exb*sth2+exl*(1.-sth2) |
---|
[1299] | 2538 | |
---|
[1595] | 2539 | def GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict): |
---|
[1460] | 2540 | 'Needs a doc string' |
---|
[1761] | 2541 | coef = np.array([-0.5,0.25,-0.10416667,0.036458333,-0.0109375,2.8497409E-3]) |
---|
| 2542 | pi2 = np.sqrt(2./np.pi) |
---|
| 2543 | if 'T' in calcControls[hfx+'histType']: |
---|
[1766] | 2544 | sth2 = sind(abs(parmDict[hfx+'2-theta'])/2.)**2 |
---|
[1761] | 2545 | wave = refl[14+im] |
---|
| 2546 | else: #'C'W |
---|
| 2547 | sth2 = sind(refl[5+im]/2.)**2 |
---|
| 2548 | wave = parmDict.get(hfx+'Lam',parmDict.get(hfx+'Lam1',1.0)) |
---|
| 2549 | c2th = 1.-2.0*sth2 |
---|
| 2550 | flv2 = refl[9+im]*(wave/parmDict[pfx+'Vol'])**2 |
---|
| 2551 | if 'X' in calcControls[hfx+'histType']: |
---|
| 2552 | flv2 *= 0.079411*(1.0+c2th**2)/2.0 |
---|
| 2553 | xfac = flv2*parmDict[phfx+'Extinction'] |
---|
| 2554 | dbde = -500.*flv2 |
---|
| 2555 | if xfac > -1.: |
---|
[1874] | 2556 | dbde = -0.5*flv2/np.sqrt(1.+xfac)**3 |
---|
[1761] | 2557 | dlde = 0. |
---|
| 2558 | if 0 < xfac <= 1.: |
---|
| 2559 | xn = np.array([i*flv2*xfac**i for i in [1,2,3,4,5,6]]) |
---|
| 2560 | dlde = np.sum(xn*coef) |
---|
| 2561 | elif xfac > 1.: |
---|
| 2562 | xfac2 = 1./np.sqrt(xfac) |
---|
| 2563 | dlde = flv2*pi2*xfac2*(-1./xfac+0.375/xfac**2) |
---|
| 2564 | |
---|
| 2565 | return dbde*sth2+dlde*(1.-sth2) |
---|
[1460] | 2566 | |
---|
[1595] | 2567 | def GetIntensityCorr(refl,im,uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict): |
---|
[1299] | 2568 | 'Needs a doc string' #need powder extinction! |
---|
[1595] | 2569 | Icorr = parmDict[phfx+'Scale']*parmDict[hfx+'Scale']*refl[3+im] #scale*multiplicity |
---|
[1299] | 2570 | if 'X' in parmDict[hfx+'Type']: |
---|
[1595] | 2571 | Icorr *= G2pwd.Polarization(parmDict[hfx+'Polariz.'],refl[5+im],parmDict[hfx+'Azimuth'])[0] |
---|
[1460] | 2572 | POcorr = 1.0 |
---|
[1770] | 2573 | if pfx+'SHorder' in parmDict: #generalized spherical harmonics texture - takes precidence |
---|
[1595] | 2574 | POcorr = SHTXcal(refl,im,g,pfx,hfx,SGData,calcControls,parmDict) |
---|
[1460] | 2575 | elif calcControls[phfx+'poType'] == 'MD': #March-Dollase |
---|
[1595] | 2576 | POcorr = GetPrefOri(uniq,G,g,phfx,hfx,SGData,calcControls,parmDict) |
---|
[1460] | 2577 | elif calcControls[phfx+'SHord']: #cylindrical spherical harmonics |
---|
[1595] | 2578 | POcorr = SHPOcal(refl,im,g,phfx,hfx,SGData,calcControls,parmDict) |
---|
[1460] | 2579 | Icorr *= POcorr |
---|
| 2580 | AbsCorr = 1.0 |
---|
[1595] | 2581 | AbsCorr = GetAbsorb(refl,im,hfx,calcControls,parmDict) |
---|
[1460] | 2582 | Icorr *= AbsCorr |
---|
[1595] | 2583 | ExtCorr = GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict) |
---|
[1460] | 2584 | Icorr *= ExtCorr |
---|
| 2585 | return Icorr,POcorr,AbsCorr,ExtCorr |
---|
[1299] | 2586 | |
---|
[1595] | 2587 | def GetIntensityDerv(refl,im,wave,uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict): |
---|
[1299] | 2588 | 'Needs a doc string' #need powder extinction derivs! |
---|
| 2589 | dIdsh = 1./parmDict[hfx+'Scale'] |
---|
| 2590 | dIdsp = 1./parmDict[phfx+'Scale'] |
---|
| 2591 | if 'X' in parmDict[hfx+'Type']: |
---|
[1595] | 2592 | pola,dIdPola = G2pwd.Polarization(parmDict[hfx+'Polariz.'],refl[5+im],parmDict[hfx+'Azimuth']) |
---|
[1299] | 2593 | dIdPola /= pola |
---|
| 2594 | else: #'N' |
---|
| 2595 | dIdPola = 0.0 |
---|
| 2596 | dFdODF = {} |
---|
| 2597 | dFdSA = [0,0,0] |
---|
[1461] | 2598 | dIdPO = {} |
---|
[1299] | 2599 | if pfx+'SHorder' in parmDict: |
---|
[1595] | 2600 | odfCor,dFdODF,dFdSA = SHTXcalDerv(refl,im,g,pfx,hfx,SGData,calcControls,parmDict) |
---|
[1299] | 2601 | for iSH in dFdODF: |
---|
| 2602 | dFdODF[iSH] /= odfCor |
---|
| 2603 | for i in range(3): |
---|
| 2604 | dFdSA[i] /= odfCor |
---|
[1460] | 2605 | elif calcControls[phfx+'poType'] == 'MD' or calcControls[phfx+'SHord']: |
---|
[1595] | 2606 | POcorr,dIdPO = GetPrefOriDerv(refl,im,uniq,G,g,phfx,hfx,SGData,calcControls,parmDict) |
---|
[1460] | 2607 | for iPO in dIdPO: |
---|
| 2608 | dIdPO[iPO] /= POcorr |
---|
[1466] | 2609 | if 'T' in parmDict[hfx+'Type']: |
---|
[1595] | 2610 | dFdAb = GetAbsorbDerv(refl,im,hfx,calcControls,parmDict)*wave/refl[16+im] #wave/abs corr |
---|
| 2611 | dFdEx = GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict)/refl[17+im] #/ext corr |
---|
[1466] | 2612 | else: |
---|
[1595] | 2613 | dFdAb = GetAbsorbDerv(refl,im,hfx,calcControls,parmDict)*wave/refl[13+im] #wave/abs corr |
---|
| 2614 | dFdEx = GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict)/refl[14+im] #/ext corr |
---|
[1460] | 2615 | return dIdsh,dIdsp,dIdPola,dIdPO,dFdODF,dFdSA,dFdAb,dFdEx |
---|
[1299] | 2616 | |
---|
[1595] | 2617 | def GetSampleSigGam(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict): |
---|
[1299] | 2618 | 'Needs a doc string' |
---|
[1484] | 2619 | if 'C' in calcControls[hfx+'histType']: #All checked & OK |
---|
[1595] | 2620 | costh = cosd(refl[5+im]/2.) |
---|
[1459] | 2621 | #crystallite size |
---|
| 2622 | if calcControls[phfx+'SizeType'] == 'isotropic': |
---|
| 2623 | Sgam = 1.8*wave/(np.pi*parmDict[phfx+'Size;i']*costh) |
---|
| 2624 | elif calcControls[phfx+'SizeType'] == 'uniaxial': |
---|
| 2625 | H = np.array(refl[:3]) |
---|
| 2626 | P = np.array(calcControls[phfx+'SizeAxis']) |
---|
| 2627 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
| 2628 | Sgam = (1.8*wave/np.pi)/(parmDict[phfx+'Size;i']*parmDict[phfx+'Size;a']*costh) |
---|
| 2629 | Sgam *= np.sqrt((sinP*parmDict[phfx+'Size;a'])**2+(cosP*parmDict[phfx+'Size;i'])**2) |
---|
| 2630 | else: #ellipsoidal crystallites |
---|
[3383] | 2631 | Sij =[parmDict[phfx+'Size;%d'%(i)] for i in range(6)] |
---|
[1459] | 2632 | H = np.array(refl[:3]) |
---|
| 2633 | lenR = G2pwd.ellipseSize(H,Sij,GB) |
---|
| 2634 | Sgam = 1.8*wave/(np.pi*costh*lenR) |
---|
| 2635 | #microstrain |
---|
| 2636 | if calcControls[phfx+'MustrainType'] == 'isotropic': |
---|
[1595] | 2637 | Mgam = 0.018*parmDict[phfx+'Mustrain;i']*tand(refl[5+im]/2.)/np.pi |
---|
[1459] | 2638 | elif calcControls[phfx+'MustrainType'] == 'uniaxial': |
---|
| 2639 | H = np.array(refl[:3]) |
---|
| 2640 | P = np.array(calcControls[phfx+'MustrainAxis']) |
---|
| 2641 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
| 2642 | Si = parmDict[phfx+'Mustrain;i'] |
---|
| 2643 | Sa = parmDict[phfx+'Mustrain;a'] |
---|
[1595] | 2644 | Mgam = 0.018*Si*Sa*tand(refl[5+im]/2.)/(np.pi*np.sqrt((Si*cosP)**2+(Sa*sinP)**2)) |
---|
[1459] | 2645 | else: #generalized - P.W. Stephens model |
---|
[1479] | 2646 | Strms = G2spc.MustrainCoeff(refl[:3],SGData) |
---|
| 2647 | Sum = 0 |
---|
| 2648 | for i,strm in enumerate(Strms): |
---|
[2155] | 2649 | Sum += parmDict[phfx+'Mustrain;'+str(i)]*strm |
---|
[1595] | 2650 | Mgam = 0.018*refl[4+im]**2*tand(refl[5+im]/2.)*np.sqrt(Sum)/np.pi |
---|
[1484] | 2651 | elif 'T' in calcControls[hfx+'histType']: #All checked & OK |
---|
[1459] | 2652 | #crystallite size |
---|
[1484] | 2653 | if calcControls[phfx+'SizeType'] == 'isotropic': #OK |
---|
[1595] | 2654 | Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/parmDict[phfx+'Size;i'] |
---|
[1484] | 2655 | elif calcControls[phfx+'SizeType'] == 'uniaxial': #OK |
---|
[1459] | 2656 | H = np.array(refl[:3]) |
---|
| 2657 | P = np.array(calcControls[phfx+'SizeAxis']) |
---|
| 2658 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
[1595] | 2659 | Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/(parmDict[phfx+'Size;i']*parmDict[phfx+'Size;a']) |
---|
[1484] | 2660 | Sgam *= np.sqrt((sinP*parmDict[phfx+'Size;a'])**2+(cosP*parmDict[phfx+'Size;i'])**2) |
---|
| 2661 | else: #ellipsoidal crystallites #OK |
---|
[3383] | 2662 | Sij =[parmDict[phfx+'Size;%d'%(i)] for i in range(6)] |
---|
[1459] | 2663 | H = np.array(refl[:3]) |
---|
| 2664 | lenR = G2pwd.ellipseSize(H,Sij,GB) |
---|
[1595] | 2665 | Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/lenR |
---|
[1459] | 2666 | #microstrain |
---|
[1484] | 2667 | if calcControls[phfx+'MustrainType'] == 'isotropic': #OK |
---|
[1595] | 2668 | Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*parmDict[phfx+'Mustrain;i'] |
---|
[1484] | 2669 | elif calcControls[phfx+'MustrainType'] == 'uniaxial': #OK |
---|
[1459] | 2670 | H = np.array(refl[:3]) |
---|
| 2671 | P = np.array(calcControls[phfx+'MustrainAxis']) |
---|
| 2672 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
| 2673 | Si = parmDict[phfx+'Mustrain;i'] |
---|
| 2674 | Sa = parmDict[phfx+'Mustrain;a'] |
---|
[1595] | 2675 | Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*Si*Sa/np.sqrt((Si*cosP)**2+(Sa*sinP)**2) |
---|
[1484] | 2676 | else: #generalized - P.W. Stephens model OK |
---|
| 2677 | Strms = G2spc.MustrainCoeff(refl[:3],SGData) |
---|
[1479] | 2678 | Sum = 0 |
---|
| 2679 | for i,strm in enumerate(Strms): |
---|
[2155] | 2680 | Sum += parmDict[phfx+'Mustrain;'+str(i)]*strm |
---|
[1595] | 2681 | Mgam = 1.e-6*parmDict[hfx+'difC']*np.sqrt(Sum)*refl[4+im]**3 |
---|
[1459] | 2682 | |
---|
[1299] | 2683 | gam = Sgam*parmDict[phfx+'Size;mx']+Mgam*parmDict[phfx+'Mustrain;mx'] |
---|
| 2684 | sig = (Sgam*(1.-parmDict[phfx+'Size;mx']))**2+(Mgam*(1.-parmDict[phfx+'Mustrain;mx']))**2 |
---|
| 2685 | sig /= ateln2 |
---|
| 2686 | return sig,gam |
---|
| 2687 | |
---|
[1595] | 2688 | def GetSampleSigGamDerv(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict): |
---|
[1299] | 2689 | 'Needs a doc string' |
---|
| 2690 | gamDict = {} |
---|
| 2691 | sigDict = {} |
---|
[1484] | 2692 | if 'C' in calcControls[hfx+'histType']: #All checked & OK |
---|
[1595] | 2693 | costh = cosd(refl[5+im]/2.) |
---|
| 2694 | tanth = tand(refl[5+im]/2.) |
---|
[1459] | 2695 | #crystallite size derivatives |
---|
| 2696 | if calcControls[phfx+'SizeType'] == 'isotropic': |
---|
[3383] | 2697 | Sgam = 1.8*wave/(np.pi*costh*parmDict[phfx+'Size;i']) |
---|
| 2698 | gamDict[phfx+'Size;i'] = -1.8*wave*parmDict[phfx+'Size;mx']/(np.pi*costh*parmDict[phfx+'Size;i']**2) |
---|
[1459] | 2699 | sigDict[phfx+'Size;i'] = -3.6*Sgam*wave*(1.-parmDict[phfx+'Size;mx'])**2/(np.pi*costh*ateln2) |
---|
| 2700 | elif calcControls[phfx+'SizeType'] == 'uniaxial': |
---|
| 2701 | H = np.array(refl[:3]) |
---|
| 2702 | P = np.array(calcControls[phfx+'SizeAxis']) |
---|
| 2703 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
| 2704 | Si = parmDict[phfx+'Size;i'] |
---|
| 2705 | Sa = parmDict[phfx+'Size;a'] |
---|
[1484] | 2706 | gami = 1.8*wave/(costh*np.pi*Si*Sa) |
---|
[1459] | 2707 | sqtrm = np.sqrt((sinP*Sa)**2+(cosP*Si)**2) |
---|
| 2708 | Sgam = gami*sqtrm |
---|
[1484] | 2709 | dsi = gami*Si*cosP**2/sqtrm-Sgam/Si |
---|
| 2710 | dsa = gami*Sa*sinP**2/sqtrm-Sgam/Sa |
---|
[1459] | 2711 | gamDict[phfx+'Size;i'] = dsi*parmDict[phfx+'Size;mx'] |
---|
| 2712 | gamDict[phfx+'Size;a'] = dsa*parmDict[phfx+'Size;mx'] |
---|
| 2713 | sigDict[phfx+'Size;i'] = 2.*dsi*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2 |
---|
| 2714 | sigDict[phfx+'Size;a'] = 2.*dsa*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2 |
---|
| 2715 | else: #ellipsoidal crystallites |
---|
| 2716 | const = 1.8*wave/(np.pi*costh) |
---|
[3383] | 2717 | Sij =[parmDict[phfx+'Size;%d'%(i)] for i in range(6)] |
---|
[1459] | 2718 | H = np.array(refl[:3]) |
---|
| 2719 | lenR,dRdS = G2pwd.ellipseSizeDerv(H,Sij,GB) |
---|
| 2720 | Sgam = const/lenR |
---|
[3383] | 2721 | for i,item in enumerate([phfx+'Size;%d'%(j) for j in range(6)]): |
---|
[1459] | 2722 | gamDict[item] = -(const/lenR**2)*dRdS[i]*parmDict[phfx+'Size;mx'] |
---|
| 2723 | sigDict[item] = -2.*Sgam*(const/lenR**2)*dRdS[i]*(1.-parmDict[phfx+'Size;mx'])**2/ateln2 |
---|
| 2724 | gamDict[phfx+'Size;mx'] = Sgam |
---|
| 2725 | sigDict[phfx+'Size;mx'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])/ateln2 |
---|
| 2726 | |
---|
| 2727 | #microstrain derivatives |
---|
| 2728 | if calcControls[phfx+'MustrainType'] == 'isotropic': |
---|
[1595] | 2729 | Mgam = 0.018*parmDict[phfx+'Mustrain;i']*tand(refl[5+im]/2.)/np.pi |
---|
[1459] | 2730 | gamDict[phfx+'Mustrain;i'] = 0.018*tanth*parmDict[phfx+'Mustrain;mx']/np.pi |
---|
| 2731 | sigDict[phfx+'Mustrain;i'] = 0.036*Mgam*tanth*(1.-parmDict[phfx+'Mustrain;mx'])**2/(np.pi*ateln2) |
---|
| 2732 | elif calcControls[phfx+'MustrainType'] == 'uniaxial': |
---|
| 2733 | H = np.array(refl[:3]) |
---|
| 2734 | P = np.array(calcControls[phfx+'MustrainAxis']) |
---|
| 2735 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
| 2736 | Si = parmDict[phfx+'Mustrain;i'] |
---|
| 2737 | Sa = parmDict[phfx+'Mustrain;a'] |
---|
| 2738 | gami = 0.018*Si*Sa*tanth/np.pi |
---|
| 2739 | sqtrm = np.sqrt((Si*cosP)**2+(Sa*sinP)**2) |
---|
| 2740 | Mgam = gami/sqtrm |
---|
| 2741 | dsi = -gami*Si*cosP**2/sqtrm**3 |
---|
| 2742 | dsa = -gami*Sa*sinP**2/sqtrm**3 |
---|
| 2743 | gamDict[phfx+'Mustrain;i'] = (Mgam/Si+dsi)*parmDict[phfx+'Mustrain;mx'] |
---|
| 2744 | gamDict[phfx+'Mustrain;a'] = (Mgam/Sa+dsa)*parmDict[phfx+'Mustrain;mx'] |
---|
| 2745 | sigDict[phfx+'Mustrain;i'] = 2*(Mgam/Si+dsi)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2 |
---|
| 2746 | sigDict[phfx+'Mustrain;a'] = 2*(Mgam/Sa+dsa)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2 |
---|
| 2747 | else: #generalized - P.W. Stephens model |
---|
[1595] | 2748 | const = 0.018*refl[4+im]**2*tanth/np.pi |
---|
[1479] | 2749 | Strms = G2spc.MustrainCoeff(refl[:3],SGData) |
---|
| 2750 | Sum = 0 |
---|
| 2751 | for i,strm in enumerate(Strms): |
---|
[2155] | 2752 | Sum += parmDict[phfx+'Mustrain;'+str(i)]*strm |
---|
| 2753 | gamDict[phfx+'Mustrain;'+str(i)] = strm*parmDict[phfx+'Mustrain;mx']/2. |
---|
| 2754 | sigDict[phfx+'Mustrain;'+str(i)] = strm*(1.-parmDict[phfx+'Mustrain;mx'])**2 |
---|
[1479] | 2755 | Mgam = const*np.sqrt(Sum) |
---|
| 2756 | for i in range(len(Strms)): |
---|
[2155] | 2757 | gamDict[phfx+'Mustrain;'+str(i)] *= Mgam/Sum |
---|
| 2758 | sigDict[phfx+'Mustrain;'+str(i)] *= const**2/ateln2 |
---|
[1459] | 2759 | gamDict[phfx+'Mustrain;mx'] = Mgam |
---|
| 2760 | sigDict[phfx+'Mustrain;mx'] = -2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])/ateln2 |
---|
[1484] | 2761 | else: #'T'OF - All checked & OK |
---|
| 2762 | if calcControls[phfx+'SizeType'] == 'isotropic': #OK |
---|
[1595] | 2763 | Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/parmDict[phfx+'Size;i'] |
---|
[1484] | 2764 | gamDict[phfx+'Size;i'] = -Sgam*parmDict[phfx+'Size;mx']/parmDict[phfx+'Size;i'] |
---|
| 2765 | sigDict[phfx+'Size;i'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])**2/(ateln2*parmDict[phfx+'Size;i']) |
---|
| 2766 | elif calcControls[phfx+'SizeType'] == 'uniaxial': #OK |
---|
[1595] | 2767 | const = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2 |
---|
[1459] | 2768 | H = np.array(refl[:3]) |
---|
| 2769 | P = np.array(calcControls[phfx+'SizeAxis']) |
---|
| 2770 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
| 2771 | Si = parmDict[phfx+'Size;i'] |
---|
| 2772 | Sa = parmDict[phfx+'Size;a'] |
---|
[1484] | 2773 | gami = const/(Si*Sa) |
---|
[1459] | 2774 | sqtrm = np.sqrt((sinP*Sa)**2+(cosP*Si)**2) |
---|
[1484] | 2775 | Sgam = gami*sqtrm |
---|
| 2776 | dsi = gami*Si*cosP**2/sqtrm-Sgam/Si |
---|
| 2777 | dsa = gami*Sa*sinP**2/sqtrm-Sgam/Sa |
---|
| 2778 | gamDict[phfx+'Size;i'] = dsi*parmDict[phfx+'Size;mx'] |
---|
| 2779 | gamDict[phfx+'Size;a'] = dsa*parmDict[phfx+'Size;mx'] |
---|
[1459] | 2780 | sigDict[phfx+'Size;i'] = 2.*dsi*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2 |
---|
| 2781 | sigDict[phfx+'Size;a'] = 2.*dsa*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2 |
---|
[1484] | 2782 | else: #OK ellipsoidal crystallites |
---|
[1595] | 2783 | const = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2 |
---|
[3383] | 2784 | Sij =[parmDict[phfx+'Size;%d'%(i)] for i in range(6)] |
---|
[1459] | 2785 | H = np.array(refl[:3]) |
---|
| 2786 | lenR,dRdS = G2pwd.ellipseSizeDerv(H,Sij,GB) |
---|
| 2787 | Sgam = const/lenR |
---|
[3383] | 2788 | for i,item in enumerate([phfx+'Size;%d'%(j) for j in range(6)]): |
---|
[1459] | 2789 | gamDict[item] = -(const/lenR**2)*dRdS[i]*parmDict[phfx+'Size;mx'] |
---|
| 2790 | sigDict[item] = -2.*Sgam*(const/lenR**2)*dRdS[i]*(1.-parmDict[phfx+'Size;mx'])**2/ateln2 |
---|
[1484] | 2791 | gamDict[phfx+'Size;mx'] = Sgam #OK |
---|
| 2792 | sigDict[phfx+'Size;mx'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])/ateln2 #OK |
---|
[1459] | 2793 | |
---|
| 2794 | #microstrain derivatives |
---|
| 2795 | if calcControls[phfx+'MustrainType'] == 'isotropic': |
---|
[1595] | 2796 | Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*parmDict[phfx+'Mustrain;i'] |
---|
| 2797 | gamDict[phfx+'Mustrain;i'] = 1.e-6*refl[4+im]*parmDict[hfx+'difC']*parmDict[phfx+'Mustrain;mx'] #OK |
---|
[1484] | 2798 | sigDict[phfx+'Mustrain;i'] = 2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])**2/(ateln2*parmDict[phfx+'Mustrain;i']) |
---|
[1459] | 2799 | elif calcControls[phfx+'MustrainType'] == 'uniaxial': |
---|
| 2800 | H = np.array(refl[:3]) |
---|
| 2801 | P = np.array(calcControls[phfx+'MustrainAxis']) |
---|
| 2802 | cosP,sinP = G2lat.CosSinAngle(H,P,G) |
---|
| 2803 | Si = parmDict[phfx+'Mustrain;i'] |
---|
| 2804 | Sa = parmDict[phfx+'Mustrain;a'] |
---|
[1595] | 2805 | gami = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*Si*Sa |
---|
[1459] | 2806 | sqtrm = np.sqrt((Si*cosP)**2+(Sa*sinP)**2) |
---|
| 2807 | Mgam = gami/sqtrm |
---|
| 2808 | dsi = -gami*Si*cosP**2/sqtrm**3 |
---|
| 2809 | dsa = -gami*Sa*sinP**2/sqtrm**3 |
---|
[1484] | 2810 | gamDict[phfx+'Mustrain;i'] = (Mgam/Si+dsi)*parmDict[phfx+'Mustrain;mx'] |
---|
| 2811 | gamDict[phfx+'Mustrain;a'] = (Mgam/Sa+dsa)*parmDict[phfx+'Mustrain;mx'] |
---|
| 2812 | sigDict[phfx+'Mustrain;i'] = 2*(Mgam/Si+dsi)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2 |
---|
| 2813 | sigDict[phfx+'Mustrain;a'] = 2*(Mgam/Sa+dsa)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2 |
---|
| 2814 | else: #generalized - P.W. Stephens model OK |
---|
[1479] | 2815 | Strms = G2spc.MustrainCoeff(refl[:3],SGData) |
---|
[1595] | 2816 | const = 1.e-6*parmDict[hfx+'difC']*refl[4+im]**3 |
---|
[1484] | 2817 | Sum = 0 |
---|
[1479] | 2818 | for i,strm in enumerate(Strms): |
---|
[2155] | 2819 | Sum += parmDict[phfx+'Mustrain;'+str(i)]*strm |
---|
| 2820 | gamDict[phfx+'Mustrain;'+str(i)] = strm*parmDict[phfx+'Mustrain;mx']/2. |
---|
| 2821 | sigDict[phfx+'Mustrain;'+str(i)] = strm*(1.-parmDict[phfx+'Mustrain;mx'])**2 |
---|
[1484] | 2822 | Mgam = const*np.sqrt(Sum) |
---|
[1479] | 2823 | for i in range(len(Strms)): |
---|
[2155] | 2824 | gamDict[phfx+'Mustrain;'+str(i)] *= Mgam/Sum |
---|
| 2825 | sigDict[phfx+'Mustrain;'+str(i)] *= const**2/ateln2 |
---|
[1459] | 2826 | gamDict[phfx+'Mustrain;mx'] = Mgam |
---|
| 2827 | sigDict[phfx+'Mustrain;mx'] = -2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])/ateln2 |
---|
| 2828 | |
---|
[1299] | 2829 | return sigDict,gamDict |
---|
| 2830 | |
---|
[1597] | 2831 | def GetReflPos(refl,im,wave,A,pfx,hfx,calcControls,parmDict): |
---|
[1299] | 2832 | 'Needs a doc string' |
---|
[1597] | 2833 | if im: |
---|
| 2834 | h,k,l,m = refl[:4] |
---|
| 2835 | vec = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']]) |
---|
| 2836 | d = 1./np.sqrt(G2lat.calc_rDsqSS(np.array([h,k,l,m]),A,vec)) |
---|
| 2837 | else: |
---|
| 2838 | h,k,l = refl[:3] |
---|
| 2839 | d = 1./np.sqrt(G2lat.calc_rDsq(np.array([h,k,l]),A)) |
---|
[1595] | 2840 | refl[4+im] = d |
---|
[1459] | 2841 | if 'C' in calcControls[hfx+'histType']: |
---|
| 2842 | pos = 2.0*asind(wave/(2.0*d))+parmDict[hfx+'Zero'] |
---|
| 2843 | const = 9.e-2/(np.pi*parmDict[hfx+'Gonio. radius']) #shifts in microns |
---|
| 2844 | if 'Bragg' in calcControls[hfx+'instType']: |
---|
| 2845 | pos -= const*(4.*parmDict[hfx+'Shift']*cosd(pos/2.0)+ \ |
---|
| 2846 | parmDict[hfx+'Transparency']*sind(pos)*100.0) #trans(=1/mueff) in cm |
---|
| 2847 | else: #Debye-Scherrer - simple but maybe not right |
---|
| 2848 | pos -= const*(parmDict[hfx+'DisplaceX']*cosd(pos)+parmDict[hfx+'DisplaceY']*sind(pos)) |
---|
| 2849 | elif 'T' in calcControls[hfx+'histType']: |
---|
[1475] | 2850 | pos = parmDict[hfx+'difC']*d+parmDict[hfx+'difA']*d**2+parmDict[hfx+'difB']/d+parmDict[hfx+'Zero'] |
---|
[1459] | 2851 | #do I need sample position effects - maybe? |
---|
[1299] | 2852 | return pos |
---|
| 2853 | |
---|
[1597] | 2854 | def GetReflPosDerv(refl,im,wave,A,pfx,hfx,calcControls,parmDict): |
---|
[1299] | 2855 | 'Needs a doc string' |
---|
| 2856 | dpr = 180./np.pi |
---|
[1597] | 2857 | if im: |
---|
| 2858 | h,k,l,m = refl[:4] |
---|
| 2859 | vec = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']]) |
---|
| 2860 | dstsq = G2lat.calc_rDsqSS(np.array([h,k,l,m]),A,vec) |
---|
[2089] | 2861 | h,k,l = [h+m*vec[0],k+m*vec[1],l+m*vec[2]] #do proj of hklm to hkl so dPdA & dPdV come out right |
---|
[1597] | 2862 | else: |
---|
| 2863 | m = 0 |
---|
| 2864 | h,k,l = refl[:3] |
---|
| 2865 | dstsq = G2lat.calc_rDsq(np.array([h,k,l]),A) |
---|
[1299] | 2866 | dst = np.sqrt(dstsq) |
---|
[1459] | 2867 | dsp = 1./dst |
---|
| 2868 | if 'C' in calcControls[hfx+'histType']: |
---|
[1595] | 2869 | pos = refl[5+im]-parmDict[hfx+'Zero'] |
---|
[1459] | 2870 | const = dpr/np.sqrt(1.0-wave**2*dstsq/4.0) |
---|
| 2871 | dpdw = const*dst |
---|
[1561] | 2872 | dpdA = np.array([h**2,k**2,l**2,h*k,h*l,k*l])*const*wave/(2.0*dst) |
---|
[1459] | 2873 | dpdZ = 1.0 |
---|
[1597] | 2874 | dpdV = np.array([2.*h*A[0]+k*A[3]+l*A[4],2*k*A[1]+h*A[3]+l*A[5], |
---|
| 2875 | 2*l*A[2]+h*A[4]+k*A[5]])*m*const*wave/(2.0*dst) |
---|
| 2876 | shft = 9.e-2/(np.pi*parmDict[hfx+'Gonio. radius']) #shifts in microns |
---|
[1459] | 2877 | if 'Bragg' in calcControls[hfx+'instType']: |
---|
[1597] | 2878 | dpdSh = -4.*shft*cosd(pos/2.0) |
---|
| 2879 | dpdTr = -shft*sind(pos)*100.0 |
---|
| 2880 | return dpdA,dpdw,dpdZ,dpdSh,dpdTr,0.,0.,dpdV |
---|
[1459] | 2881 | else: #Debye-Scherrer - simple but maybe not right |
---|
[1597] | 2882 | dpdXd = -shft*cosd(pos) |
---|
| 2883 | dpdYd = -shft*sind(pos) |
---|
| 2884 | return dpdA,dpdw,dpdZ,0.,0.,dpdXd,dpdYd,dpdV |
---|
[1459] | 2885 | elif 'T' in calcControls[hfx+'histType']: |
---|
[1482] | 2886 | dpdA = -np.array([h**2,k**2,l**2,h*k,h*l,k*l])*parmDict[hfx+'difC']*dsp**3/2. |
---|
[1459] | 2887 | dpdZ = 1.0 |
---|
| 2888 | dpdDC = dsp |
---|
| 2889 | dpdDA = dsp**2 |
---|
[1475] | 2890 | dpdDB = 1./dsp |
---|
[1597] | 2891 | dpdV = np.array([2.*h*A[0]+k*A[3]+l*A[4],2*k*A[1]+h*A[3]+l*A[5], |
---|
[2089] | 2892 | 2*l*A[2]+h*A[4]+k*A[5]])*m*parmDict[hfx+'difC']*dsp**3/2. |
---|
[1597] | 2893 | return dpdA,dpdZ,dpdDC,dpdDA,dpdDB,dpdV |
---|
[1299] | 2894 | |
---|
[1595] | 2895 | def GetHStrainShift(refl,im,SGData,phfx,hfx,calcControls,parmDict): |
---|
[1299] | 2896 | 'Needs a doc string' |
---|
| 2897 | laue = SGData['SGLaue'] |
---|
| 2898 | uniq = SGData['SGUniq'] |
---|
| 2899 | h,k,l = refl[:3] |
---|
| 2900 | if laue in ['m3','m3m']: |
---|
| 2901 | Dij = parmDict[phfx+'D11']*(h**2+k**2+l**2)+ \ |
---|
[1595] | 2902 | refl[4+im]**2*parmDict[phfx+'eA']*((h*k)**2+(h*l)**2+(k*l)**2)/(h**2+k**2+l**2)**2 |
---|
[1299] | 2903 | elif laue in ['6/m','6/mmm','3m1','31m','3']: |
---|
| 2904 | Dij = parmDict[phfx+'D11']*(h**2+k**2+h*k)+parmDict[phfx+'D33']*l**2 |
---|
| 2905 | elif laue in ['3R','3mR']: |
---|
| 2906 | Dij = parmDict[phfx+'D11']*(h**2+k**2+l**2)+parmDict[phfx+'D12']*(h*k+h*l+k*l) |
---|
| 2907 | elif laue in ['4/m','4/mmm']: |
---|
| 2908 | Dij = parmDict[phfx+'D11']*(h**2+k**2)+parmDict[phfx+'D33']*l**2 |
---|
| 2909 | elif laue in ['mmm']: |
---|
| 2910 | Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2 |
---|
| 2911 | elif laue in ['2/m']: |
---|
| 2912 | Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2 |
---|
| 2913 | if uniq == 'a': |
---|
| 2914 | Dij += parmDict[phfx+'D23']*k*l |
---|
| 2915 | elif uniq == 'b': |
---|
| 2916 | Dij += parmDict[phfx+'D13']*h*l |
---|
| 2917 | elif uniq == 'c': |
---|
| 2918 | Dij += parmDict[phfx+'D12']*h*k |
---|
| 2919 | else: |
---|
| 2920 | Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2+ \ |
---|
| 2921 | parmDict[phfx+'D12']*h*k+parmDict[phfx+'D13']*h*l+parmDict[phfx+'D23']*k*l |
---|
[1478] | 2922 | if 'C' in calcControls[hfx+'histType']: |
---|
[1595] | 2923 | return -180.*Dij*refl[4+im]**2*tand(refl[5+im]/2.0)/np.pi |
---|
[1478] | 2924 | else: |
---|
[1595] | 2925 | return -Dij*parmDict[hfx+'difC']*refl[4+im]**2/2. |
---|
[1299] | 2926 | |
---|
[1595] | 2927 | def GetHStrainShiftDerv(refl,im,SGData,phfx,hfx,calcControls,parmDict): |
---|
[1299] | 2928 | 'Needs a doc string' |
---|
| 2929 | laue = SGData['SGLaue'] |
---|
| 2930 | uniq = SGData['SGUniq'] |
---|
| 2931 | h,k,l = refl[:3] |
---|
| 2932 | if laue in ['m3','m3m']: |
---|
| 2933 | dDijDict = {phfx+'D11':h**2+k**2+l**2, |
---|
[1595] | 2934 | phfx+'eA':refl[4+im]**2*((h*k)**2+(h*l)**2+(k*l)**2)/(h**2+k**2+l**2)**2} |
---|
[1299] | 2935 | elif laue in ['6/m','6/mmm','3m1','31m','3']: |
---|
| 2936 | dDijDict = {phfx+'D11':h**2+k**2+h*k,phfx+'D33':l**2} |
---|
| 2937 | elif laue in ['3R','3mR']: |
---|
| 2938 | dDijDict = {phfx+'D11':h**2+k**2+l**2,phfx+'D12':h*k+h*l+k*l} |
---|
| 2939 | elif laue in ['4/m','4/mmm']: |
---|
| 2940 | dDijDict = {phfx+'D11':h**2+k**2,phfx+'D33':l**2} |
---|
| 2941 | elif laue in ['mmm']: |
---|
| 2942 | dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2} |
---|
| 2943 | elif laue in ['2/m']: |
---|
| 2944 | dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2} |
---|
| 2945 | if uniq == 'a': |
---|
| 2946 | dDijDict[phfx+'D23'] = k*l |
---|
| 2947 | elif uniq == 'b': |
---|
| 2948 | dDijDict[phfx+'D13'] = h*l |
---|
| 2949 | elif uniq == 'c': |
---|
| 2950 | dDijDict[phfx+'D12'] = h*k |
---|
| 2951 | else: |
---|
| 2952 | dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2, |
---|
| 2953 | phfx+'D12':h*k,phfx+'D13':h*l,phfx+'D23':k*l} |
---|
[1478] | 2954 | if 'C' in calcControls[hfx+'histType']: |
---|
| 2955 | for item in dDijDict: |
---|
[1595] | 2956 | dDijDict[item] *= 180.0*refl[4+im]**2*tand(refl[5+im]/2.0)/np.pi |
---|
[1478] | 2957 | else: |
---|
| 2958 | for item in dDijDict: |
---|
[1595] | 2959 | dDijDict[item] *= -parmDict[hfx+'difC']*refl[4+im]**3/2. |
---|
[1299] | 2960 | return dDijDict |
---|
| 2961 | |
---|
[1559] | 2962 | def GetDij(phfx,SGData,parmDict): |
---|
| 2963 | HSvals = [parmDict[phfx+name] for name in G2spc.HStrainNames(SGData)] |
---|
| 2964 | return G2spc.HStrainVals(HSvals,SGData) |
---|
| 2965 | |
---|
[1299] | 2966 | def GetFobsSq(Histograms,Phases,parmDict,calcControls): |
---|
[3041] | 2967 | '''Compute the observed structure factors for Powder histograms and store in reflection array |
---|
| 2968 | Multiprocessing support added |
---|
| 2969 | ''' |
---|
[3095] | 2970 | if GSASIIpath.GetConfigValue('Show_timing',False): |
---|
[3041] | 2971 | starttime = time.time() #; print 'start GetFobsSq' |
---|
[3136] | 2972 | histoList = list(Histograms.keys()) |
---|
[1299] | 2973 | histoList.sort() |
---|
[3041] | 2974 | Ka2 = shl = lamRatio = kRatio = None |
---|
[1299] | 2975 | for histogram in histoList: |
---|
| 2976 | if 'PWDR' in histogram[:4]: |
---|
| 2977 | Histogram = Histograms[histogram] |
---|
| 2978 | hId = Histogram['hId'] |
---|
| 2979 | hfx = ':%d:'%(hId) |
---|
| 2980 | Limits = calcControls[hfx+'Limits'] |
---|
[1459] | 2981 | if 'C' in calcControls[hfx+'histType']: |
---|
| 2982 | shl = max(parmDict[hfx+'SH/L'],0.0005) |
---|
| 2983 | Ka2 = False |
---|
| 2984 | kRatio = 0.0 |
---|
[3136] | 2985 | if hfx+'Lam1' in list(parmDict.keys()): |
---|
[1459] | 2986 | Ka2 = True |
---|
| 2987 | lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1']) |
---|
| 2988 | kRatio = parmDict[hfx+'I(L2)/I(L1)'] |
---|
[1299] | 2989 | x,y,w,yc,yb,yd = Histogram['Data'] |
---|
[2130] | 2990 | xMask = ma.getmaskarray(x) |
---|
[1299] | 2991 | xB = np.searchsorted(x,Limits[0]) |
---|
| 2992 | xF = np.searchsorted(x,Limits[1]) |
---|
| 2993 | ymb = np.array(y-yb) |
---|
| 2994 | ymb = np.where(ymb,ymb,1.0) |
---|
| 2995 | ycmb = np.array(yc-yb) |
---|
| 2996 | ratio = 1./np.where(ycmb,ycmb/ymb,1.e10) |
---|
| 2997 | refLists = Histogram['Reflection Lists'] |
---|
| 2998 | for phase in refLists: |
---|
[1606] | 2999 | if phase not in Phases: #skips deleted or renamed phases silently! |
---|
| 3000 | continue |
---|
[1299] | 3001 | Phase = Phases[phase] |
---|
[1595] | 3002 | im = 0 |
---|
[2405] | 3003 | if Phase['General'].get('Modulated',False): |
---|
[1595] | 3004 | im = 1 |
---|
[1299] | 3005 | pId = Phase['pId'] |
---|
| 3006 | phfx = '%d:%d:'%(pId,hId) |
---|
| 3007 | refDict = refLists[phase] |
---|
| 3008 | sumFo = 0.0 |
---|
| 3009 | sumdF = 0.0 |
---|
| 3010 | sumFosq = 0.0 |
---|
| 3011 | sumdFsq = 0.0 |
---|
[1682] | 3012 | sumInt = 0.0 |
---|
[2130] | 3013 | nExcl = 0 |
---|
[3041] | 3014 | # test to see if we are using multiprocessing below |
---|
| 3015 | useMP,ncores = G2mp.InitMP() |
---|
| 3016 | if len(refDict['RefList']) < 100: useMP = False |
---|
| 3017 | if useMP: # multiprocessing: create a set of initialized Python processes |
---|
| 3018 | MPpool = mp.Pool(G2mp.ncores,G2mp.InitFobsSqGlobals, |
---|
| 3019 | [x,ratio,shl,xB,xF,im,lamRatio,kRatio,xMask,Ka2]) |
---|
| 3020 | profArgs = [[] for i in range(G2mp.ncores)] |
---|
| 3021 | else: |
---|
| 3022 | G2mp.InitFobsSqGlobals(x,ratio,shl,xB,xF,im,lamRatio,kRatio,xMask,Ka2) |
---|
| 3023 | if 'C' in calcControls[hfx+'histType']: |
---|
| 3024 | # are we multiprocessing? |
---|
| 3025 | for iref,refl in enumerate(refDict['RefList']): |
---|
| 3026 | if useMP: |
---|
| 3027 | profArgs[iref%G2mp.ncores].append((refl,iref)) |
---|
| 3028 | else: |
---|
| 3029 | icod= G2mp.ComputeFobsSqCW(refl,iref) |
---|
| 3030 | if type(icod) is tuple: |
---|
| 3031 | refl[8+im] = icod[0] |
---|
| 3032 | sumInt += icod[1] |
---|
| 3033 | if parmDict[phfx+'LeBail']: refl[9+im] = refl[8+im] |
---|
| 3034 | elif icod == -1: |
---|
| 3035 | refl[3+im] *= -1 |
---|
| 3036 | nExcl += 1 |
---|
| 3037 | elif icod == -2: |
---|
| 3038 | break |
---|
| 3039 | if useMP: |
---|
| 3040 | for sInt,resList in MPpool.imap_unordered(G2mp.ComputeFobsSqCWbatch,profArgs): |
---|
| 3041 | sumInt += sInt |
---|
| 3042 | for refl8im,irefl in resList: |
---|
| 3043 | if refl8im is None: |
---|
| 3044 | refDict['RefList'][irefl][3+im] *= -1 |
---|
| 3045 | nExcl += 1 |
---|
| 3046 | else: |
---|
| 3047 | refDict['RefList'][irefl][8+im] = refl8im |
---|
| 3048 | if parmDict[phfx+'LeBail']: |
---|
| 3049 | refDict['RefList'][irefl][9+im] = refDict['RefList'][irefl][8+im] |
---|
| 3050 | elif 'T' in calcControls[hfx+'histType']: |
---|
| 3051 | for iref,refl in enumerate(refDict['RefList']): |
---|
| 3052 | if useMP: |
---|
| 3053 | profArgs[iref%G2mp.ncores].append((refl,iref)) |
---|
| 3054 | else: |
---|
| 3055 | icod= G2mp.ComputeFobsSqTOF(refl,iref) |
---|
| 3056 | if type(icod) is tuple: |
---|
| 3057 | refl[8+im] = icod[0] |
---|
| 3058 | sumInt += icod[1] |
---|
| 3059 | if parmDict[phfx+'LeBail']: refl[9+im] = refl[8+im] |
---|
| 3060 | elif icod == -1: |
---|
| 3061 | refl[3+im] *= -1 |
---|
| 3062 | nExcl += 1 |
---|
| 3063 | elif icod == -2: |
---|
| 3064 | break |
---|
| 3065 | if useMP: |
---|
| 3066 | for sInt,resList in MPpool.imap_unordered(G2mp.ComputeFobsSqTOFbatch,profArgs): |
---|
| 3067 | sumInt += sInt |
---|
| 3068 | for refl8im,irefl in resList: |
---|
| 3069 | if refl8im is None: |
---|
| 3070 | refDict['RefList'][irefl][3+im] *= -1 |
---|
| 3071 | nExcl += 1 |
---|
| 3072 | else: |
---|
| 3073 | refDict['RefList'][irefl][8+im] = refl8im |
---|
| 3074 | if parmDict[phfx+'LeBail']: |
---|
| 3075 | refDict['RefList'][irefl][9+im] = refDict['RefList'][irefl][8+im] |
---|
[3129] | 3076 | if useMP: MPpool.terminate() |
---|
[3041] | 3077 | sumFo = 0.0 |
---|
| 3078 | sumdF = 0.0 |
---|
| 3079 | sumFosq = 0.0 |
---|
| 3080 | sumdFsq = 0.0 |
---|
| 3081 | for iref,refl in enumerate(refDict['RefList']): |
---|
[1595] | 3082 | Fo = np.sqrt(np.abs(refl[8+im])) |
---|
| 3083 | Fc = np.sqrt(np.abs(refl[9]+im)) |
---|
[1299] | 3084 | sumFo += Fo |
---|
[1595] | 3085 | sumFosq += refl[8+im]**2 |
---|
[1299] | 3086 | sumdF += np.abs(Fo-Fc) |
---|
[1595] | 3087 | sumdFsq += (refl[8+im]-refl[9+im])**2 |
---|
[1606] | 3088 | if sumFo: |
---|
| 3089 | Histogram['Residuals'][phfx+'Rf'] = min(100.,(sumdF/sumFo)*100.) |
---|
| 3090 | Histogram['Residuals'][phfx+'Rf^2'] = min(100.,np.sqrt(sumdFsq/sumFosq)*100.) |
---|
| 3091 | else: |
---|
| 3092 | Histogram['Residuals'][phfx+'Rf'] = 100. |
---|
| 3093 | Histogram['Residuals'][phfx+'Rf^2'] = 100. |
---|
[1682] | 3094 | Histogram['Residuals'][phfx+'sumInt'] = sumInt |
---|
[2130] | 3095 | Histogram['Residuals'][phfx+'Nref'] = len(refDict['RefList'])-nExcl |
---|
[1299] | 3096 | Histogram['Residuals']['hId'] = hId |
---|
| 3097 | elif 'HKLF' in histogram[:4]: |
---|
| 3098 | Histogram = Histograms[histogram] |
---|
| 3099 | Histogram['Residuals']['hId'] = Histograms[histogram]['hId'] |
---|
[3095] | 3100 | if GSASIIpath.GetConfigValue('Show_timing',False): |
---|
[3136] | 3101 | print ('GetFobsSq t=',time.time()-starttime) |
---|
[1299] | 3102 | |
---|
| 3103 | def getPowderProfile(parmDict,x,varylist,Histogram,Phases,calcControls,pawleyLookup): |
---|
[2894] | 3104 | 'Computes the powder pattern for a histogram based on contributions from all used phases' |
---|
[3095] | 3105 | if GSASIIpath.GetConfigValue('Show_timing',False): starttime = time.time() |
---|
[1299] | 3106 | |
---|
[1595] | 3107 | def GetReflSigGamCW(refl,im,wave,G,GB,phfx,calcControls,parmDict): |
---|
[1299] | 3108 | U = parmDict[hfx+'U'] |
---|
| 3109 | V = parmDict[hfx+'V'] |
---|
| 3110 | W = parmDict[hfx+'W'] |
---|
| 3111 | X = parmDict[hfx+'X'] |
---|
| 3112 | Y = parmDict[hfx+'Y'] |
---|
[3157] | 3113 | Z = parmDict[hfx+'Z'] |
---|
[1595] | 3114 | tanPos = tand(refl[5+im]/2.0) |
---|
| 3115 | Ssig,Sgam = GetSampleSigGam(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict) |
---|
[1299] | 3116 | sig = U*tanPos**2+V*tanPos+W+Ssig #save peak sigma |
---|
| 3117 | sig = max(0.001,sig) |
---|
[3157] | 3118 | gam = X/cosd(refl[5+im]/2.0)+Y*tanPos+Sgam+Z #save peak gamma |
---|
[1299] | 3119 | gam = max(0.001,gam) |
---|
| 3120 | return sig,gam |
---|
| 3121 | |
---|
[1595] | 3122 | def GetReflSigGamTOF(refl,im,G,GB,phfx,calcControls,parmDict): |
---|
| 3123 | sig = parmDict[hfx+'sig-0']+parmDict[hfx+'sig-1']*refl[4+im]**2+ \ |
---|
[3157] | 3124 | parmDict[hfx+'sig-2']*refl[4+im]**4+parmDict[hfx+'sig-q']*refl[4+im] |
---|
| 3125 | gam = parmDict[hfx+'X']*refl[4+im]+parmDict[hfx+'Y']*refl[4+im]**2+parmDict[hfx+'Z'] |
---|
[1595] | 3126 | Ssig,Sgam = GetSampleSigGam(refl,im,0.0,G,GB,SGData,hfx,phfx,calcControls,parmDict) |
---|
[1478] | 3127 | sig += Ssig |
---|
| 3128 | gam += Sgam |
---|
[1459] | 3129 | return sig,gam |
---|
| 3130 | |
---|
[1595] | 3131 | def GetReflAlpBet(refl,im,hfx,parmDict): |
---|
| 3132 | alp = parmDict[hfx+'alpha']/refl[4+im] |
---|
| 3133 | bet = parmDict[hfx+'beta-0']+parmDict[hfx+'beta-1']/refl[4+im]**4+parmDict[hfx+'beta-q']/refl[4+im]**2 |
---|
[1459] | 3134 | return alp,bet |
---|
[1559] | 3135 | |
---|
[1299] | 3136 | hId = Histogram['hId'] |
---|
| 3137 | hfx = ':%d:'%(hId) |
---|
| 3138 | bakType = calcControls[hfx+'bakType'] |
---|
[1682] | 3139 | yb,Histogram['sumBk'] = G2pwd.getBackground(hfx,parmDict,bakType,calcControls[hfx+'histType'],x) |
---|
[1299] | 3140 | yc = np.zeros_like(yb) |
---|
[3000] | 3141 | cw = np.diff(ma.getdata(x)) |
---|
[1461] | 3142 | cw = np.append(cw,cw[-1]) |
---|
[1299] | 3143 | |
---|
| 3144 | if 'C' in calcControls[hfx+'histType']: |
---|
| 3145 | shl = max(parmDict[hfx+'SH/L'],0.002) |
---|
| 3146 | Ka2 = False |
---|
[3136] | 3147 | if hfx+'Lam1' in (parmDict.keys()): |
---|
[1299] | 3148 | wave = parmDict[hfx+'Lam1'] |
---|
| 3149 | Ka2 = True |
---|
| 3150 | lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1']) |
---|
| 3151 | kRatio = parmDict[hfx+'I(L2)/I(L1)'] |
---|
| 3152 | else: |
---|
| 3153 | wave = parmDict[hfx+'Lam'] |
---|
[3041] | 3154 | else: |
---|
| 3155 | shl = 0. |
---|
[1299] | 3156 | for phase in Histogram['Reflection Lists']: |
---|
| 3157 | refDict = Histogram['Reflection Lists'][phase] |
---|
[1606] | 3158 | if phase not in Phases: #skips deleted or renamed phases silently! |
---|
| 3159 | continue |
---|
[1299] | 3160 | Phase = Phases[phase] |
---|
| 3161 | pId = Phase['pId'] |
---|
| 3162 | pfx = '%d::'%(pId) |
---|
| 3163 | phfx = '%d:%d:'%(pId,hId) |
---|
| 3164 | hfx = ':%d:'%(hId) |
---|
| 3165 | SGData = Phase['General']['SGData'] |
---|
| 3166 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
[1595] | 3167 | im = 0 |
---|
[2405] | 3168 | if Phase['General'].get('Modulated',False): |
---|
[1595] | 3169 | SSGData = Phase['General']['SSGData'] |
---|
| 3170 | im = 1 #offset in SS reflection list |
---|
| 3171 | #?? |
---|
[1560] | 3172 | Dij = GetDij(phfx,SGData,parmDict) |
---|
[3219] | 3173 | A = [parmDict[pfx+'A%d'%(i)]+Dij[i] for i in range(6)] #TODO: need to do someting if Dij << 0. |
---|
[1299] | 3174 | G,g = G2lat.A2Gmat(A) #recip & real metric tensors |
---|
[2240] | 3175 | if np.any(np.diag(G)<0.) or np.any(np.isnan(A)): |
---|
[1815] | 3176 | raise G2obj.G2Exception('invalid metric tensor \n cell/Dij refinement not advised') |
---|
[1299] | 3177 | GA,GB = G2lat.Gmat2AB(G) #Orthogonalization matricies |
---|
| 3178 | Vst = np.sqrt(nl.det(G)) #V* |
---|
[2732] | 3179 | if not Phase['General'].get('doPawley') and not parmDict[phfx+'LeBail']: |
---|
[1618] | 3180 | if im: |
---|
[2115] | 3181 | SStructureFactor(refDict,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) |
---|
[3320] | 3182 | elif parmDict[pfx+'isMag'] and 'N' in calcControls[hfx+'histType']: |
---|
| 3183 | MagStructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
[1618] | 3184 | else: |
---|
| 3185 | StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
[1495] | 3186 | badPeak = False |
---|
[3041] | 3187 | # test to see if we are using multiprocessing here |
---|
| 3188 | useMP,ncores = G2mp.InitMP() |
---|
| 3189 | if len(refDict['RefList']) < 100: useMP = False |
---|
| 3190 | if useMP: # multiprocessing: create a set of initialized Python processes |
---|
| 3191 | MPpool = mp.Pool(ncores,G2mp.InitPwdrProfGlobals,[im,shl,x]) |
---|
| 3192 | profArgs = [[] for i in range(ncores)] |
---|
| 3193 | if 'C' in calcControls[hfx+'histType']: |
---|
| 3194 | for iref,refl in enumerate(refDict['RefList']): |
---|
[1595] | 3195 | if im: |
---|
| 3196 | h,k,l,m = refl[:4] |
---|
| 3197 | else: |
---|
| 3198 | h,k,l = refl[:3] |
---|
[1299] | 3199 | Uniq = np.inner(refl[:3],SGMT) |
---|
[1597] | 3200 | refl[5+im] = GetReflPos(refl,im,wave,A,pfx,hfx,calcControls,parmDict) #corrected reflection position |
---|
[1595] | 3201 | Lorenz = 1./(2.*sind(refl[5+im]/2.)**2*cosd(refl[5+im]/2.)) #Lorentz correction |
---|
| 3202 | refl[6+im:8+im] = GetReflSigGamCW(refl,im,wave,G,GB,phfx,calcControls,parmDict) #peak sig & gam |
---|
| 3203 | refl[11+im:15+im] = GetIntensityCorr(refl,im,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict) |
---|
| 3204 | refl[11+im] *= Vst*Lorenz |
---|
[1459] | 3205 | |
---|
[1299] | 3206 | if Phase['General'].get('doPawley'): |
---|
| 3207 | try: |
---|
[1595] | 3208 | if im: |
---|
| 3209 | pInd = pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)]) |
---|
| 3210 | else: |
---|
| 3211 | pInd = pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)]) |
---|
| 3212 | refl[9+im] = parmDict[pInd] |
---|
[1299] | 3213 | except KeyError: |
---|
| 3214 | # print ' ***Error %d,%d,%d missing from Pawley reflection list ***'%(h,k,l) |
---|
| 3215 | continue |
---|
[1595] | 3216 | Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl) |
---|
| 3217 | iBeg = np.searchsorted(x,refl[5+im]-fmin) |
---|
| 3218 | iFin = np.searchsorted(x,refl[5+im]+fmax) |
---|
[1299] | 3219 | if not iBeg+iFin: #peak below low limit - skip peak |
---|
| 3220 | continue |
---|
| 3221 | elif not iBeg-iFin: #peak above high limit - done |
---|
| 3222 | break |
---|
[1494] | 3223 | elif iBeg > iFin: #bad peak coeff - skip |
---|
[1495] | 3224 | badPeak = True |
---|
[1494] | 3225 | continue |
---|
[3041] | 3226 | if useMP: |
---|
| 3227 | profArgs[iref%ncores].append((refl[5+im],refl,iBeg,iFin,1.)) |
---|
| 3228 | else: |
---|
| 3229 | yc[iBeg:iFin] += refl[11+im]*refl[9+im]*G2pwd.getFCJVoigt3(refl[5+im],refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg:iFin])) #>90% of time spent here |
---|
[1299] | 3230 | if Ka2: |
---|
[1595] | 3231 | pos2 = refl[5+im]+lamRatio*tand(refl[5+im]/2.0) # + 360/pi * Dlam/lam * tan(th) |
---|
| 3232 | Wd,fmin,fmax = G2pwd.getWidthsCW(pos2,refl[6+im],refl[7+im],shl) |
---|
[1299] | 3233 | iBeg = np.searchsorted(x,pos2-fmin) |
---|
| 3234 | iFin = np.searchsorted(x,pos2+fmax) |
---|
| 3235 | if not iBeg+iFin: #peak below low limit - skip peak |
---|
| 3236 | continue |
---|
| 3237 | elif not iBeg-iFin: #peak above high limit - done |
---|
| 3238 | return yc,yb |
---|
[1494] | 3239 | elif iBeg > iFin: #bad peak coeff - skip |
---|
| 3240 | continue |
---|
[3041] | 3241 | if useMP: |
---|
| 3242 | profArgs[iref%ncores].append((pos2,refl,iBeg,iFin,kRatio)) |
---|
| 3243 | else: |
---|
| 3244 | yc[iBeg:iFin] += refl[11+im]*refl[9+im]*kRatio*G2pwd.getFCJVoigt3(pos2,refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg:iFin])) #and here |
---|
| 3245 | elif 'T' in calcControls[hfx+'histType']: |
---|
| 3246 | for iref,refl in enumerate(refDict['RefList']): |
---|
[3231] | 3247 | if im: |
---|
| 3248 | h,k,l,m = refl[:4] |
---|
| 3249 | else: |
---|
| 3250 | h,k,l = refl[:3] |
---|
[1459] | 3251 | Uniq = np.inner(refl[:3],SGMT) |
---|
[3000] | 3252 | refl[5+im] = GetReflPos(refl,im,0.0,A,pfx,hfx,calcControls,parmDict) #corrected reflection position - #TODO - what about tabluated offset? |
---|
[1766] | 3253 | Lorenz = sind(abs(parmDict[hfx+'2-theta'])/2)*refl[4+im]**4 #TOF Lorentz correction |
---|
[1595] | 3254 | # refl[5+im] += GetHStrainShift(refl,im,SGData,phfx,hfx,calcControls,parmDict) #apply hydrostatic strain shift |
---|
| 3255 | refl[6+im:8+im] = GetReflSigGamTOF(refl,im,G,GB,phfx,calcControls,parmDict) #peak sig & gam |
---|
[3000] | 3256 | refl[12+im:14+im] = GetReflAlpBet(refl,im,hfx,parmDict) #TODO - skip if alp, bet tabulated? |
---|
[1595] | 3257 | refl[11+im],refl[15+im],refl[16+im],refl[17+im] = GetIntensityCorr(refl,im,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict) |
---|
| 3258 | refl[11+im] *= Vst*Lorenz |
---|
[1459] | 3259 | if Phase['General'].get('doPawley'): |
---|
| 3260 | try: |
---|
[1595] | 3261 | if im: |
---|
| 3262 | pInd =pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)]) |
---|
| 3263 | else: |
---|
| 3264 | pInd =pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)]) |
---|
| 3265 | refl[9+im] = parmDict[pInd] |
---|
[1459] | 3266 | except KeyError: |
---|
| 3267 | # print ' ***Error %d,%d,%d missing from Pawley reflection list ***'%(h,k,l) |
---|
| 3268 | continue |
---|
[1595] | 3269 | Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im]) |
---|
| 3270 | iBeg = np.searchsorted(x,refl[5+im]-fmin) |
---|
| 3271 | iFin = np.searchsorted(x,refl[5+im]+fmax) |
---|
[1459] | 3272 | if not iBeg+iFin: #peak below low limit - skip peak |
---|
| 3273 | continue |
---|
| 3274 | elif not iBeg-iFin: #peak above high limit - done |
---|
| 3275 | break |
---|
[1494] | 3276 | elif iBeg > iFin: #bad peak coeff - skip |
---|
[1495] | 3277 | badPeak = True |
---|
[1494] | 3278 | continue |
---|
[3041] | 3279 | if useMP: |
---|
| 3280 | profArgs[iref%ncores].append((refl[5+im],refl,iBeg,iFin)) |
---|
| 3281 | else: |
---|
| 3282 | yc[iBeg:iFin] += refl[11+im]*refl[9+im]*G2pwd.getEpsVoigt(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im],ma.getdata(x[iBeg:iFin]))/cw[iBeg:iFin] |
---|
[1299] | 3283 | # print 'profile calc time: %.3fs'%(time.time()-time0) |
---|
[3041] | 3284 | if useMP and 'C' in calcControls[hfx+'histType']: |
---|
| 3285 | for y in MPpool.imap_unordered(G2mp.ComputePwdrProfCW,profArgs): |
---|
| 3286 | yc += y |
---|
| 3287 | MPpool.terminate() |
---|
| 3288 | elif useMP: |
---|
| 3289 | for y in MPpool.imap_unordered(G2mp.ComputePwdrProfTOF,profArgs): |
---|
| 3290 | yc += y |
---|
| 3291 | MPpool.terminate() |
---|
[1495] | 3292 | if badPeak: |
---|
[3136] | 3293 | print ('ouch #4 bad profile coefficients yield negative peak width; some reflections skipped') |
---|
[3095] | 3294 | if GSASIIpath.GetConfigValue('Show_timing',False): |
---|
[3136] | 3295 | print ('getPowderProfile t=%.3f'%time.time()-starttime) |
---|
[1299] | 3296 | return yc,yb |
---|
| 3297 | |
---|
[3004] | 3298 | def getPowderProfileDervMP(args): |
---|
| 3299 | '''Computes the derivatives of the computed powder pattern with respect to all |
---|
| 3300 | refined parameters. |
---|
| 3301 | Multiprocessing version. |
---|
| 3302 | ''' |
---|
[3136] | 3303 | import pytexture as ptx |
---|
| 3304 | ptx.pyqlmninit() #initialize fortran arrays for spherical harmonics for each processor |
---|
[3005] | 3305 | parmDict,x,varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup,dependentVars = args[:9] |
---|
[3004] | 3306 | prc=0 |
---|
| 3307 | tprc=1 |
---|
[3005] | 3308 | if len(args) >= 10: prc=args[9] |
---|
| 3309 | if len(args) >= 11: tprc=args[10] |
---|
[3004] | 3310 | def cellVaryDerv(pfx,SGData,dpdA): |
---|
| 3311 | if SGData['SGLaue'] in ['-1',]: |
---|
| 3312 | return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]], |
---|
| 3313 | [pfx+'A3',dpdA[3]],[pfx+'A4',dpdA[4]],[pfx+'A5',dpdA[5]]] |
---|
| 3314 | elif SGData['SGLaue'] in ['2/m',]: |
---|
| 3315 | if SGData['SGUniq'] == 'a': |
---|
| 3316 | return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A5',dpdA[5]]] |
---|
| 3317 | elif SGData['SGUniq'] == 'b': |
---|
| 3318 | return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A4',dpdA[4]]] |
---|
| 3319 | else: |
---|
| 3320 | return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A3',dpdA[3]]] |
---|
| 3321 | elif SGData['SGLaue'] in ['mmm',]: |
---|
| 3322 | return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]]] |
---|
| 3323 | elif SGData['SGLaue'] in ['4/m','4/mmm']: |
---|
| 3324 | return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]] |
---|
| 3325 | elif SGData['SGLaue'] in ['6/m','6/mmm','3m1', '31m', '3']: |
---|
| 3326 | return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]] |
---|
| 3327 | elif SGData['SGLaue'] in ['3R', '3mR']: |
---|
| 3328 | return [[pfx+'A0',dpdA[0]+dpdA[1]+dpdA[2]],[pfx+'A3',dpdA[3]+dpdA[4]+dpdA[5]]] |
---|
| 3329 | elif SGData['SGLaue'] in ['m3m','m3']: |
---|
| 3330 | return [[pfx+'A0',dpdA[0]]] |
---|
| 3331 | |
---|
| 3332 | # create a list of dependent variables and set up a dictionary to hold their derivatives |
---|
[3005] | 3333 | # dependentVars = G2mv.GetDependentVars() |
---|
[3004] | 3334 | depDerivDict = {} |
---|
| 3335 | for j in dependentVars: |
---|
| 3336 | depDerivDict[j] = np.zeros(shape=(len(x))) |
---|
[3005] | 3337 | # print 'dependent vars',dependentVars |
---|
[3004] | 3338 | hId = Histogram['hId'] |
---|
| 3339 | hfx = ':%d:'%(hId) |
---|
| 3340 | bakType = calcControls[hfx+'bakType'] |
---|
| 3341 | dMdv = np.zeros(shape=(len(varylist),len(x))) |
---|
| 3342 | dMdb,dMddb,dMdpk = G2pwd.getBackgroundDerv(hfx,parmDict,bakType,calcControls[hfx+'histType'],x) |
---|
| 3343 | if prc == 0 and hfx+'Back;0' in varylist: # for now assume that Back;x vars to not appear in constraints |
---|
| 3344 | bBpos = varylist.index(hfx+'Back;0') |
---|
| 3345 | dMdv[bBpos:bBpos+len(dMdb)] += dMdb #TODO crash if bck parms tossed |
---|
| 3346 | names = [hfx+'DebyeA',hfx+'DebyeR',hfx+'DebyeU'] |
---|
| 3347 | for name in varylist: |
---|
| 3348 | if prc == 0 and 'Debye' in name: |
---|
| 3349 | id = int(name.split(';')[-1]) |
---|
| 3350 | parm = name[:int(name.rindex(';'))] |
---|
| 3351 | ip = names.index(parm) |
---|
| 3352 | dMdv[varylist.index(name)] += dMddb[3*id+ip] |
---|
| 3353 | names = [hfx+'BkPkpos',hfx+'BkPkint',hfx+'BkPksig',hfx+'BkPkgam'] |
---|
| 3354 | for name in varylist: |
---|
| 3355 | if prc == 0 and 'BkPk' in name: |
---|
| 3356 | parm,id = name.split(';') |
---|
| 3357 | id = int(id) |
---|
| 3358 | if parm in names: |
---|
| 3359 | ip = names.index(parm) |
---|
| 3360 | dMdv[varylist.index(name)] += dMdpk[4*id+ip] |
---|
| 3361 | cw = np.diff(ma.getdata(x)) |
---|
| 3362 | cw = np.append(cw,cw[-1]) |
---|
| 3363 | Ka2 = False #also for TOF! |
---|
| 3364 | if 'C' in calcControls[hfx+'histType']: |
---|
| 3365 | shl = max(parmDict[hfx+'SH/L'],0.002) |
---|
[3136] | 3366 | if hfx+'Lam1' in (parmDict.keys()): |
---|
[3004] | 3367 | wave = parmDict[hfx+'Lam1'] |
---|
| 3368 | Ka2 = True |
---|
| 3369 | lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1']) |
---|
| 3370 | kRatio = parmDict[hfx+'I(L2)/I(L1)'] |
---|
| 3371 | else: |
---|
| 3372 | wave = parmDict[hfx+'Lam'] |
---|
| 3373 | for phase in Histogram['Reflection Lists']: |
---|
| 3374 | refDict = Histogram['Reflection Lists'][phase] |
---|
| 3375 | if phase not in Phases: #skips deleted or renamed phases silently! |
---|
| 3376 | continue |
---|
| 3377 | Phase = Phases[phase] |
---|
| 3378 | SGData = Phase['General']['SGData'] |
---|
| 3379 | SGMT = np.array([ops[0].T for ops in SGData['SGOps']]) |
---|
| 3380 | im = 0 |
---|
| 3381 | if Phase['General'].get('Modulated',False): |
---|
| 3382 | SSGData = Phase['General']['SSGData'] |
---|
| 3383 | im = 1 #offset in SS reflection list |
---|
| 3384 | #?? |
---|
| 3385 | pId = Phase['pId'] |
---|
| 3386 | pfx = '%d::'%(pId) |
---|
| 3387 | phfx = '%d:%d:'%(pId,hId) |
---|
| 3388 | Dij = GetDij(phfx,SGData,parmDict) |
---|
| 3389 | A = [parmDict[pfx+'A%d'%(i)]+Dij[i] for i in range(6)] |
---|
| 3390 | G,g = G2lat.A2Gmat(A) #recip & real metric tensors |
---|
| 3391 | GA,GB = G2lat.Gmat2AB(G) #Orthogonalization matricies |
---|
| 3392 | if not Phase['General'].get('doPawley') and not parmDict[phfx+'LeBail']: |
---|
| 3393 | if im: |
---|
| 3394 | dFdvDict = SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) |
---|
[3759] | 3395 | dFdvDict.update(SStructureFactorDerv2(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)) |
---|
[3004] | 3396 | else: |
---|
[3754] | 3397 | if Phase['General']['Type'] == 'magnetic': |
---|
[3372] | 3398 | dFdvDict = MagStructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
[3754] | 3399 | dFdvDict.update(MagStructureFactorDerv2(refDict,G,hfx,pfx,SGData,calcControls,parmDict)) |
---|
[3004] | 3400 | else: |
---|
| 3401 | dFdvDict = StructureFactorDerv2(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
| 3402 | ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase) |
---|
| 3403 | # determine the parameters that will have derivatives computed only at end |
---|
| 3404 | nonatomvarylist = [] |
---|
| 3405 | for name in varylist: |
---|
| 3406 | if '::RBV;' not in name: |
---|
| 3407 | try: |
---|
| 3408 | aname = name.split(pfx)[1][:2] |
---|
| 3409 | if aname not in ['Af','dA','AU','RB','AM','Xs','Xc','Ys','Yc','Zs','Zc', \ |
---|
[3777] | 3410 | 'Tm','Xm','Ym','Zm','U1','U2','U3','MX','MY','MZ']: continue # skip anything not an atom or rigid body param |
---|
[3004] | 3411 | except IndexError: |
---|
| 3412 | continue |
---|
| 3413 | nonatomvarylist.append(name) |
---|
| 3414 | nonatomdependentVars = [] |
---|
| 3415 | for name in dependentVars: |
---|
| 3416 | if '::RBV;' not in name: |
---|
| 3417 | try: |
---|
| 3418 | aname = name.split(pfx)[1][:2] |
---|
| 3419 | if aname not in ['Af','dA','AU','RB','AM','Xs','Xc','Ys','Yc','Zs','Zc', \ |
---|
[3777] | 3420 | 'Tm','Xm','Ym','Zm','U1','U2','U3','MX','MY','MZ']: continue # skip anything not an atom or rigid body param |
---|
[3004] | 3421 | except IndexError: |
---|
| 3422 | continue |
---|
| 3423 | nonatomdependentVars.append(name) |
---|
| 3424 | #========================================================================================== |
---|
| 3425 | #========================================================================================== |
---|
| 3426 | for iref in range(prc,len(refDict['RefList']),tprc): |
---|
| 3427 | refl = refDict['RefList'][iref] |
---|
| 3428 | if im: |
---|
| 3429 | h,k,l,m = refl[:4] |
---|
| 3430 | else: |
---|
| 3431 | h,k,l = refl[:3] |
---|
| 3432 | Uniq = np.inner(refl[:3],SGMT) |
---|
| 3433 | if 'T' in calcControls[hfx+'histType']: |
---|
| 3434 | wave = refl[14+im] |
---|
| 3435 | dIdsh,dIdsp,dIdpola,dIdPO,dFdODF,dFdSA,dFdAb,dFdEx = GetIntensityDerv(refl,im,wave,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict) |
---|
| 3436 | if 'C' in calcControls[hfx+'histType']: #CW powder |
---|
| 3437 | Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl) |
---|
| 3438 | else: #'T'OF |
---|
| 3439 | Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im]) |
---|
| 3440 | iBeg = np.searchsorted(x,refl[5+im]-fmin) |
---|
| 3441 | iFin = np.searchsorted(x,refl[5+im]+fmax) |
---|
| 3442 | if not iBeg+iFin: #peak below low limit - skip peak |
---|
| 3443 | continue |
---|
| 3444 | elif not iBeg-iFin: #peak above high limit - done |
---|
| 3445 | break |
---|
| 3446 | pos = refl[5+im] |
---|
| 3447 | if 'C' in calcControls[hfx+'histType']: |
---|
| 3448 | tanth = tand(pos/2.0) |
---|
| 3449 | costh = cosd(pos/2.0) |
---|
| 3450 | lenBF = iFin-iBeg |
---|
| 3451 | dMdpk = np.zeros(shape=(6,lenBF)) |
---|
| 3452 | dMdipk = G2pwd.getdFCJVoigt3(refl[5+im],refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg:iFin])) |
---|
| 3453 | for i in range(5): |
---|
| 3454 | dMdpk[i] += 100.*cw[iBeg:iFin]*refl[11+im]*refl[9+im]*dMdipk[i] |
---|
| 3455 | dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'sig':dMdpk[2],'gam':dMdpk[3],'shl':dMdpk[4],'L1/L2':np.zeros_like(dMdpk[0])} |
---|
| 3456 | if Ka2: |
---|
| 3457 | pos2 = refl[5+im]+lamRatio*tanth # + 360/pi * Dlam/lam * tan(th) |
---|
| 3458 | iBeg2 = np.searchsorted(x,pos2-fmin) |
---|
| 3459 | iFin2 = np.searchsorted(x,pos2+fmax) |
---|
| 3460 | if iBeg2-iFin2: |
---|
| 3461 | lenBF2 = iFin2-iBeg2 |
---|
| 3462 | dMdpk2 = np.zeros(shape=(6,lenBF2)) |
---|
| 3463 | dMdipk2 = G2pwd.getdFCJVoigt3(pos2,refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg2:iFin2])) |
---|
| 3464 | for i in range(5): |
---|
| 3465 | dMdpk2[i] = 100.*cw[iBeg2:iFin2]*refl[11+im]*refl[9+im]*kRatio*dMdipk2[i] |
---|
| 3466 | dMdpk2[5] = 100.*cw[iBeg2:iFin2]*refl[11+im]*dMdipk2[0] |
---|
| 3467 | dervDict2 = {'int':dMdpk2[0],'pos':dMdpk2[1],'sig':dMdpk2[2],'gam':dMdpk2[3],'shl':dMdpk2[4],'L1/L2':dMdpk2[5]*refl[9]} |
---|
| 3468 | else: #'T'OF |
---|
| 3469 | lenBF = iFin-iBeg |
---|
| 3470 | if lenBF < 0: #bad peak coeff |
---|
| 3471 | break |
---|
| 3472 | dMdpk = np.zeros(shape=(6,lenBF)) |
---|
| 3473 | dMdipk = G2pwd.getdEpsVoigt(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im],ma.getdata(x[iBeg:iFin])) |
---|
| 3474 | for i in range(6): |
---|
| 3475 | dMdpk[i] += refl[11+im]*refl[9+im]*dMdipk[i] #cw[iBeg:iFin]* |
---|
| 3476 | dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'alp':dMdpk[2],'bet':dMdpk[3],'sig':dMdpk[4],'gam':dMdpk[5]} |
---|
| 3477 | if Phase['General'].get('doPawley'): |
---|
| 3478 | dMdpw = np.zeros(len(x)) |
---|
| 3479 | try: |
---|
| 3480 | if im: |
---|
| 3481 | pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)]) |
---|
| 3482 | else: |
---|
| 3483 | pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)]) |
---|
| 3484 | idx = varylist.index(pIdx) |
---|
| 3485 | dMdpw[iBeg:iFin] = dervDict['int']/refl[9+im] |
---|
| 3486 | if Ka2: #not for TOF either |
---|
| 3487 | dMdpw[iBeg2:iFin2] += dervDict2['int']/refl[9+im] |
---|
| 3488 | dMdv[idx] = dMdpw |
---|
| 3489 | except: # ValueError: |
---|
| 3490 | pass |
---|
| 3491 | if 'C' in calcControls[hfx+'histType']: |
---|
| 3492 | dpdA,dpdw,dpdZ,dpdSh,dpdTr,dpdX,dpdY,dpdV = GetReflPosDerv(refl,im,wave,A,pfx,hfx,calcControls,parmDict) |
---|
| 3493 | names = {hfx+'Scale':[dIdsh,'int'],hfx+'Polariz.':[dIdpola,'int'],phfx+'Scale':[dIdsp,'int'], |
---|
| 3494 | hfx+'U':[tanth**2,'sig'],hfx+'V':[tanth,'sig'],hfx+'W':[1.0,'sig'], |
---|
[3157] | 3495 | hfx+'X':[1.0/costh,'gam'],hfx+'Y':[tanth,'gam'],hfx+'Z':[1.0,'gam'],hfx+'SH/L':[1.0,'shl'], |
---|
[3004] | 3496 | hfx+'I(L2)/I(L1)':[1.0,'L1/L2'],hfx+'Zero':[dpdZ,'pos'],hfx+'Lam':[dpdw,'pos'], |
---|
| 3497 | hfx+'Shift':[dpdSh,'pos'],hfx+'Transparency':[dpdTr,'pos'],hfx+'DisplaceX':[dpdX,'pos'], |
---|
| 3498 | hfx+'DisplaceY':[dpdY,'pos'],} |
---|
| 3499 | if 'Bragg' in calcControls[hfx+'instType']: |
---|
| 3500 | names.update({hfx+'SurfRoughA':[dFdAb[0],'int'], |
---|
| 3501 | hfx+'SurfRoughB':[dFdAb[1],'int'],}) |
---|
| 3502 | else: |
---|
| 3503 | names.update({hfx+'Absorption':[dFdAb,'int'],}) |
---|
| 3504 | else: #'T'OF |
---|
| 3505 | dpdA,dpdZ,dpdDC,dpdDA,dpdDB,dpdV = GetReflPosDerv(refl,im,0.0,A,pfx,hfx,calcControls,parmDict) |
---|
| 3506 | names = {hfx+'Scale':[dIdsh,'int'],phfx+'Scale':[dIdsp,'int'], |
---|
| 3507 | hfx+'difC':[dpdDC,'pos'],hfx+'difA':[dpdDA,'pos'],hfx+'difB':[dpdDB,'pos'], |
---|
[3157] | 3508 | hfx+'Zero':[dpdZ,'pos'],hfx+'X':[refl[4+im],'gam'],hfx+'Y':[refl[4+im]**2,'gam'],hfx+'Z':[1.0,'gam'], |
---|
[3004] | 3509 | hfx+'alpha':[1./refl[4+im],'alp'],hfx+'beta-0':[1.0,'bet'],hfx+'beta-1':[1./refl[4+im]**4,'bet'], |
---|
| 3510 | hfx+'beta-q':[1./refl[4+im]**2,'bet'],hfx+'sig-0':[1.0,'sig'],hfx+'sig-1':[refl[4+im]**2,'sig'], |
---|
[3157] | 3511 | hfx+'sig-2':[refl[4+im]**4,'sig'],hfx+'sig-q':[refl[4+im],'sig'], |
---|
[3004] | 3512 | hfx+'Absorption':[dFdAb,'int'],phfx+'Extinction':[dFdEx,'int'],} |
---|
| 3513 | for name in names: |
---|
| 3514 | item = names[name] |
---|
| 3515 | if name in varylist: |
---|
| 3516 | dMdv[varylist.index(name)][iBeg:iFin] += item[0]*dervDict[item[1]] |
---|
| 3517 | if Ka2 and iFin2-iBeg2: |
---|
| 3518 | dMdv[varylist.index(name)][iBeg2:iFin2] += item[0]*dervDict2[item[1]] |
---|
| 3519 | elif name in dependentVars: |
---|
| 3520 | depDerivDict[name][iBeg:iFin] += item[0]*dervDict[item[1]] |
---|
| 3521 | if Ka2 and iFin2-iBeg2: |
---|
| 3522 | depDerivDict[name][iBeg2:iFin2] += item[0]*dervDict2[item[1]] |
---|
| 3523 | for iPO in dIdPO: |
---|
| 3524 | if iPO in varylist: |
---|
| 3525 | dMdv[varylist.index(iPO)][iBeg:iFin] += dIdPO[iPO]*dervDict['int'] |
---|
| 3526 | if Ka2 and iFin2-iBeg2: |
---|
| 3527 | dMdv[varylist.index(iPO)][iBeg2:iFin2] += dIdPO[iPO]*dervDict2['int'] |
---|
| 3528 | elif iPO in dependentVars: |
---|
| 3529 | depDerivDict[iPO][iBeg:iFin] += dIdPO[iPO]*dervDict['int'] |
---|
| 3530 | if Ka2 and iFin2-iBeg2: |
---|
| 3531 | depDerivDict[iPO][iBeg2:iFin2] += dIdPO[iPO]*dervDict2['int'] |
---|
| 3532 | for i,name in enumerate(['omega','chi','phi']): |
---|
| 3533 | aname = pfx+'SH '+name |
---|
| 3534 | if aname in varylist: |
---|
| 3535 | dMdv[varylist.index(aname)][iBeg:iFin] += dFdSA[i]*dervDict['int'] |
---|
| 3536 | if Ka2 and iFin2-iBeg2: |
---|
| 3537 | dMdv[varylist.index(aname)][iBeg2:iFin2] += dFdSA[i]*dervDict2['int'] |
---|
| 3538 | elif aname in dependentVars: |
---|
| 3539 | depDerivDict[aname][iBeg:iFin] += dFdSA[i]*dervDict['int'] |
---|
| 3540 | if Ka2 and iFin2-iBeg2: |
---|
| 3541 | depDerivDict[aname][iBeg2:iFin2] += dFdSA[i]*dervDict2['int'] |
---|
| 3542 | for iSH in dFdODF: |
---|
| 3543 | if iSH in varylist: |
---|
| 3544 | dMdv[varylist.index(iSH)][iBeg:iFin] += dFdODF[iSH]*dervDict['int'] |
---|
| 3545 | if Ka2 and iFin2-iBeg2: |
---|
| 3546 | dMdv[varylist.index(iSH)][iBeg2:iFin2] += dFdODF[iSH]*dervDict2['int'] |
---|
| 3547 | elif iSH in dependentVars: |
---|
| 3548 | depDerivDict[iSH][iBeg:iFin] += dFdODF[iSH]*dervDict['int'] |
---|
| 3549 | if Ka2 and iFin2-iBeg2: |
---|
| 3550 | depDerivDict[iSH][iBeg2:iFin2] += dFdODF[iSH]*dervDict2['int'] |
---|
| 3551 | cellDervNames = cellVaryDerv(pfx,SGData,dpdA) |
---|
| 3552 | for name,dpdA in cellDervNames: |
---|
| 3553 | if name in varylist: |
---|
| 3554 | dMdv[varylist.index(name)][iBeg:iFin] += dpdA*dervDict['pos'] |
---|
| 3555 | if Ka2 and iFin2-iBeg2: |
---|
| 3556 | dMdv[varylist.index(name)][iBeg2:iFin2] += dpdA*dervDict2['pos'] |
---|
| 3557 | elif name in dependentVars: #need to scale for mixed phase constraints? |
---|
| 3558 | depDerivDict[name][iBeg:iFin] += dpdA*dervDict['pos'] |
---|
| 3559 | if Ka2 and iFin2-iBeg2: |
---|
| 3560 | depDerivDict[name][iBeg2:iFin2] += dpdA*dervDict2['pos'] |
---|
| 3561 | dDijDict = GetHStrainShiftDerv(refl,im,SGData,phfx,hfx,calcControls,parmDict) |
---|
| 3562 | for name in dDijDict: |
---|
| 3563 | if name in varylist: |
---|
| 3564 | dMdv[varylist.index(name)][iBeg:iFin] += dDijDict[name]*dervDict['pos'] |
---|
| 3565 | if Ka2 and iFin2-iBeg2: |
---|
| 3566 | dMdv[varylist.index(name)][iBeg2:iFin2] += dDijDict[name]*dervDict2['pos'] |
---|
| 3567 | elif name in dependentVars: |
---|
| 3568 | depDerivDict[name][iBeg:iFin] += dDijDict[name]*dervDict['pos'] |
---|
| 3569 | if Ka2 and iFin2-iBeg2: |
---|
| 3570 | depDerivDict[name][iBeg2:iFin2] += dDijDict[name]*dervDict2['pos'] |
---|
| 3571 | for i,name in enumerate([pfx+'mV0',pfx+'mV1',pfx+'mV2']): |
---|
| 3572 | if name in varylist: |
---|
| 3573 | dMdv[varylist.index(name)][iBeg:iFin] += dpdV[i]*dervDict['pos'] |
---|
| 3574 | if Ka2 and iFin2-iBeg2: |
---|
| 3575 | dMdv[varylist.index(name)][iBeg2:iFin2] += dpdV[i]*dervDict2['pos'] |
---|
| 3576 | elif name in dependentVars: |
---|
| 3577 | depDerivDict[name][iBeg:iFin] += dpdV[i]*dervDict['pos'] |
---|
| 3578 | if Ka2 and iFin2-iBeg2: |
---|
| 3579 | depDerivDict[name][iBeg2:iFin2] += dpdV[i]*dervDict2['pos'] |
---|
| 3580 | if 'C' in calcControls[hfx+'histType']: |
---|
| 3581 | sigDict,gamDict = GetSampleSigGamDerv(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict) |
---|
| 3582 | else: #'T'OF |
---|
| 3583 | sigDict,gamDict = GetSampleSigGamDerv(refl,im,0.0,G,GB,SGData,hfx,phfx,calcControls,parmDict) |
---|
| 3584 | for name in gamDict: |
---|
| 3585 | if name in varylist: |
---|
| 3586 | dMdv[varylist.index(name)][iBeg:iFin] += gamDict[name]*dervDict['gam'] |
---|
| 3587 | if Ka2 and iFin2-iBeg2: |
---|
| 3588 | dMdv[varylist.index(name)][iBeg2:iFin2] += gamDict[name]*dervDict2['gam'] |
---|
| 3589 | elif name in dependentVars: |
---|
| 3590 | depDerivDict[name][iBeg:iFin] += gamDict[name]*dervDict['gam'] |
---|
| 3591 | if Ka2 and iFin2-iBeg2: |
---|
| 3592 | depDerivDict[name][iBeg2:iFin2] += gamDict[name]*dervDict2['gam'] |
---|
| 3593 | for name in sigDict: |
---|
| 3594 | if name in varylist: |
---|
| 3595 | dMdv[varylist.index(name)][iBeg:iFin] += sigDict[name]*dervDict['sig'] |
---|
| 3596 | if Ka2 and iFin2-iBeg2: |
---|
| 3597 | dMdv[varylist.index(name)][iBeg2:iFin2] += sigDict[name]*dervDict2['sig'] |
---|
| 3598 | elif name in dependentVars: |
---|
| 3599 | depDerivDict[name][iBeg:iFin] += sigDict[name]*dervDict['sig'] |
---|
| 3600 | if Ka2 and iFin2-iBeg2: |
---|
| 3601 | depDerivDict[name][iBeg2:iFin2] += sigDict[name]*dervDict2['sig'] |
---|
| 3602 | for name in ['BabA','BabU']: |
---|
| 3603 | if refl[9+im]: |
---|
| 3604 | if phfx+name in varylist: |
---|
| 3605 | dMdv[varylist.index(phfx+name)][iBeg:iFin] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict['int']/refl[9+im] |
---|
| 3606 | if Ka2 and iFin2-iBeg2: |
---|
| 3607 | dMdv[varylist.index(phfx+name)][iBeg2:iFin2] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict2['int']/refl[9+im] |
---|
| 3608 | elif phfx+name in dependentVars: |
---|
| 3609 | depDerivDict[phfx+name][iBeg:iFin] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict['int']/refl[9+im] |
---|
| 3610 | if Ka2 and iFin2-iBeg2: |
---|
| 3611 | depDerivDict[phfx+name][iBeg2:iFin2] += parmDict[phfx+'Scale']*dFdvDict[phfx+name][iref]*dervDict2['int']/refl[9+im] |
---|
| 3612 | if not Phase['General'].get('doPawley') and not parmDict[phfx+'LeBail']: |
---|
| 3613 | #do atom derivatives - for RB,F,X & U so far - how do I scale mixed phase constraints? |
---|
| 3614 | corr = 0. |
---|
| 3615 | corr2 = 0. |
---|
| 3616 | if refl[9+im]: |
---|
| 3617 | corr = dervDict['int']/refl[9+im] |
---|
[3773] | 3618 | if Ka2 and iFin2-iBeg2: |
---|
| 3619 | corr2 = dervDict2['int']/refl[9+im] |
---|
[3004] | 3620 | for name in nonatomvarylist: |
---|
| 3621 | dMdv[varylist.index(name)][iBeg:iFin] += dFdvDict[name][iref]*corr |
---|
| 3622 | if Ka2 and iFin2-iBeg2: |
---|
| 3623 | dMdv[varylist.index(name)][iBeg2:iFin2] += dFdvDict[name][iref]*corr2 |
---|
| 3624 | for name in nonatomdependentVars: |
---|
| 3625 | depDerivDict[name][iBeg:iFin] += dFdvDict[name][iref]*corr |
---|
| 3626 | if Ka2 and iFin2-iBeg2: |
---|
| 3627 | depDerivDict[name][iBeg2:iFin2] += dFdvDict[name][iref]*corr2 |
---|
| 3628 | # now process derivatives in constraints |
---|
| 3629 | dMdv[:,ma.getmaskarray(x)] = 0. # instead of masking, zero out masked values |
---|
[3093] | 3630 | #G2mv.Dict2Deriv(varylist,depDerivDict,dMdv) |
---|
| 3631 | return dMdv,depDerivDict |
---|
[1456] | 3632 | |
---|
[1787] | 3633 | def UserRejectHKL(ref,im,userReject): |
---|
| 3634 | if ref[5+im]/ref[6+im] < userReject['minF/sig']: |
---|
| 3635 | return False |
---|
| 3636 | elif userReject['MaxD'] < ref[4+im] > userReject['MinD']: |
---|
| 3637 | return False |
---|
| 3638 | elif ref[11+im] < userReject['MinExt']: |
---|
| 3639 | return False |
---|
| 3640 | elif abs(ref[5+im]-ref[7+im])/ref[6+im] > userReject['MaxDF/F']: |
---|
| 3641 | return False |
---|
| 3642 | return True |
---|
| 3643 | |
---|
[1456] | 3644 | def dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict): |
---|
[1459] | 3645 | '''Loop over reflections in a HKLF histogram and compute derivatives of the fitting |
---|
[1456] | 3646 | model (M) with respect to all parameters. Independent and dependant dM/dp arrays |
---|
| 3647 | are returned to either dervRefine or HessRefine. |
---|
[1299] | 3648 | |
---|
[1456] | 3649 | :returns: |
---|
| 3650 | ''' |
---|
| 3651 | hId = Histogram['hId'] |
---|
| 3652 | hfx = ':%d:'%(hId) |
---|
| 3653 | pfx = '%d::'%(Phase['pId']) |
---|
| 3654 | phfx = '%d:%d:'%(Phase['pId'],hId) |
---|
| 3655 | SGData = Phase['General']['SGData'] |
---|
[1595] | 3656 | im = 0 |
---|
[2405] | 3657 | if Phase['General'].get('Modulated',False): |
---|
[1595] | 3658 | SSGData = Phase['General']['SSGData'] |
---|
| 3659 | im = 1 #offset in SS reflection list |
---|
[1456] | 3660 | A = [parmDict[pfx+'A%d'%(i)] for i in range(6)] |
---|
| 3661 | G,g = G2lat.A2Gmat(A) #recip & real metric tensors |
---|
[2094] | 3662 | TwinLaw = calcControls[phfx+'TwinLaw'] |
---|
[1456] | 3663 | refDict = Histogram['Data'] |
---|
[1923] | 3664 | if parmDict[phfx+'Scale'] < 0.: |
---|
| 3665 | parmDict[phfx+'Scale'] = .001 |
---|
[2097] | 3666 | if im: # split to nontwin/twin versions |
---|
| 3667 | if len(TwinLaw) > 1: |
---|
[3759] | 3668 | dFdvDict = SStructureFactorDervTw(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) #not ok |
---|
[2097] | 3669 | else: |
---|
[2123] | 3670 | dFdvDict = SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) #OK |
---|
[3759] | 3671 | dFdvDict.update(SStructureFactorDerv2(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)) |
---|
[1618] | 3672 | else: |
---|
[2094] | 3673 | if len(TwinLaw) > 1: |
---|
[2110] | 3674 | dFdvDict = StructureFactorDervTw2(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
| 3675 | else: #correct!! |
---|
[3755] | 3676 | if Phase['General']['Type'] == 'magnetic': |
---|
| 3677 | dFdvDict = MagStructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
| 3678 | dFdvDict.update(MagStructureFactorDerv2(refDict,G,hfx,pfx,SGData,calcControls,parmDict)) |
---|
[2495] | 3679 | else: |
---|
| 3680 | dFdvDict = StructureFactorDerv2(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
[1456] | 3681 | ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase) |
---|
| 3682 | dMdvh = np.zeros((len(varylist),len(refDict['RefList']))) |
---|
| 3683 | dependentVars = G2mv.GetDependentVars() |
---|
| 3684 | depDerivDict = {} |
---|
| 3685 | for j in dependentVars: |
---|
| 3686 | depDerivDict[j] = np.zeros(shape=(len(refDict['RefList']))) |
---|
| 3687 | wdf = np.zeros(len(refDict['RefList'])) |
---|
| 3688 | if calcControls['F**2']: |
---|
| 3689 | for iref,ref in enumerate(refDict['RefList']): |
---|
[1595] | 3690 | if ref[6+im] > 0: |
---|
[1857] | 3691 | dervDict,dervCor = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist+dependentVars)[1:] |
---|
[1595] | 3692 | w = 1.0/ref[6+im] |
---|
[1787] | 3693 | if ref[3+im] > 0: |
---|
[1595] | 3694 | wdf[iref] = w*(ref[5+im]-ref[7+im]) |
---|
[1456] | 3695 | for j,var in enumerate(varylist): |
---|
| 3696 | if var in dFdvDict: |
---|
[1595] | 3697 | dMdvh[j][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1456] | 3698 | for var in dependentVars: |
---|
| 3699 | if var in dFdvDict: |
---|
[1595] | 3700 | depDerivDict[var][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1456] | 3701 | if phfx+'Scale' in varylist: |
---|
[1923] | 3702 | dMdvh[varylist.index(phfx+'Scale')][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale'] #OK |
---|
[1456] | 3703 | elif phfx+'Scale' in dependentVars: |
---|
[1923] | 3704 | depDerivDict[phfx+'Scale'][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale'] #OK |
---|
[1456] | 3705 | for item in ['Ep','Es','Eg']: |
---|
[1493] | 3706 | if phfx+item in varylist and phfx+item in dervDict: |
---|
[1595] | 3707 | dMdvh[varylist.index(phfx+item)][iref] = w*dervDict[phfx+item]/ref[11+im] #OK |
---|
[1493] | 3708 | elif phfx+item in dependentVars and phfx+item in dervDict: |
---|
[1595] | 3709 | depDerivDict[phfx+item][iref] = w*dervDict[phfx+item]/ref[11+im] #OK |
---|
[1456] | 3710 | for item in ['BabA','BabU']: |
---|
| 3711 | if phfx+item in varylist: |
---|
[2838] | 3712 | dMdvh[varylist.index(phfx+item)][iref] = w*dFdvDict[phfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1456] | 3713 | elif phfx+item in dependentVars: |
---|
[2838] | 3714 | depDerivDict[phfx+item][iref] = w*dFdvDict[phfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1857] | 3715 | else: #F refinement |
---|
[1456] | 3716 | for iref,ref in enumerate(refDict['RefList']): |
---|
[1595] | 3717 | if ref[5+im] > 0.: |
---|
[1857] | 3718 | dervDict,dervCor = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist+dependentVars)[1:] |
---|
[1595] | 3719 | Fo = np.sqrt(ref[5+im]) |
---|
| 3720 | Fc = np.sqrt(ref[7+im]) |
---|
| 3721 | w = 1.0/ref[6+im] |
---|
[1787] | 3722 | if ref[3+im] > 0: |
---|
[1864] | 3723 | wdf[iref] = 2.0*Fc*w*(Fo-Fc) |
---|
[1456] | 3724 | for j,var in enumerate(varylist): |
---|
| 3725 | if var in dFdvDict: |
---|
[1595] | 3726 | dMdvh[j][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1456] | 3727 | for var in dependentVars: |
---|
| 3728 | if var in dFdvDict: |
---|
[1595] | 3729 | depDerivDict[var][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1456] | 3730 | if phfx+'Scale' in varylist: |
---|
[1923] | 3731 | dMdvh[varylist.index(phfx+'Scale')][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale'] #OK |
---|
[1456] | 3732 | elif phfx+'Scale' in dependentVars: |
---|
[1923] | 3733 | depDerivDict[phfx+'Scale'][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale'] #OK |
---|
[1864] | 3734 | for item in ['Ep','Es','Eg']: #OK! |
---|
[1493] | 3735 | if phfx+item in varylist and phfx+item in dervDict: |
---|
[1862] | 3736 | dMdvh[varylist.index(phfx+item)][iref] = w*dervDict[phfx+item]/ref[11+im] |
---|
[1493] | 3737 | elif phfx+item in dependentVars and phfx+item in dervDict: |
---|
[1862] | 3738 | depDerivDict[phfx+item][iref] = w*dervDict[phfx+item]/ref[11+im] |
---|
[1456] | 3739 | for item in ['BabA','BabU']: |
---|
| 3740 | if phfx+item in varylist: |
---|
[2096] | 3741 | dMdvh[varylist.index(phfx+item)][iref] = w*dFdvDict[phfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1456] | 3742 | elif phfx+item in dependentVars: |
---|
[2096] | 3743 | depDerivDict[phfx+item][iref] = w*dFdvDict[phfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im] |
---|
[1456] | 3744 | return dMdvh,depDerivDict,wdf |
---|
| 3745 | |
---|
| 3746 | |
---|
[1299] | 3747 | def dervRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg): |
---|
| 3748 | '''Loop over histograms and compute derivatives of the fitting |
---|
| 3749 | model (M) with respect to all parameters. Results are returned in |
---|
| 3750 | a Jacobian matrix (aka design matrix) of dimensions (n by m) where |
---|
| 3751 | n is the number of parameters and m is the number of data |
---|
| 3752 | points. This can exceed memory when m gets large. This routine is |
---|
| 3753 | used when refinement derivatives are selected as "analtytic |
---|
| 3754 | Jacobian" in Controls. |
---|
| 3755 | |
---|
| 3756 | :returns: Jacobian numpy.array dMdv for all histograms concatinated |
---|
| 3757 | ''' |
---|
| 3758 | parmDict.update(zip(varylist,values)) |
---|
| 3759 | G2mv.Dict2Map(parmDict,varylist) |
---|
| 3760 | Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases |
---|
[3005] | 3761 | dependentVars = G2mv.GetDependentVars() |
---|
[3136] | 3762 | histoList = list(Histograms.keys()) |
---|
[1299] | 3763 | histoList.sort() |
---|
[3149] | 3764 | First = True |
---|
[1299] | 3765 | for histogram in histoList: |
---|
| 3766 | if 'PWDR' in histogram[:4]: |
---|
| 3767 | Histogram = Histograms[histogram] |
---|
| 3768 | hId = Histogram['hId'] |
---|
| 3769 | hfx = ':%d:'%(hId) |
---|
| 3770 | wtFactor = calcControls[hfx+'wtFactor'] |
---|
| 3771 | Limits = calcControls[hfx+'Limits'] |
---|
| 3772 | x,y,w,yc,yb,yd = Histogram['Data'] |
---|
| 3773 | xB = np.searchsorted(x,Limits[0]) |
---|
[2754] | 3774 | xF = np.searchsorted(x,Limits[1])+1 |
---|
[3093] | 3775 | dMdv,depDerivDict = getPowderProfileDervMP([parmDict,x[xB:xF], |
---|
[3068] | 3776 | varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup,dependentVars]) |
---|
[3093] | 3777 | G2mv.Dict2Deriv(varylist,depDerivDict,dMdv) |
---|
| 3778 | dMdvh = np.sqrt(w[xB:xF])*dMdv |
---|
[1299] | 3779 | elif 'HKLF' in histogram[:4]: |
---|
| 3780 | Histogram = Histograms[histogram] |
---|
| 3781 | phase = Histogram['Reflection Lists'] |
---|
| 3782 | Phase = Phases[phase] |
---|
[1456] | 3783 | dMdvh,depDerivDict,wdf = dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict) |
---|
| 3784 | hfx = ':%d:'%(Histogram['hId']) |
---|
[1299] | 3785 | wtFactor = calcControls[hfx+'wtFactor'] |
---|
| 3786 | # now process derivatives in constraints |
---|
| 3787 | G2mv.Dict2Deriv(varylist,depDerivDict,dMdvh) |
---|
| 3788 | else: |
---|
| 3789 | continue #skip non-histogram entries |
---|
[3149] | 3790 | if First: |
---|
| 3791 | dMdv = np.sqrt(wtFactor)*dMdvh |
---|
| 3792 | First = False |
---|
| 3793 | else: |
---|
[1299] | 3794 | dMdv = np.concatenate((dMdv.T,np.sqrt(wtFactor)*dMdvh.T)).T |
---|
| 3795 | |
---|
[2732] | 3796 | GetFobsSq(Histograms,Phases,parmDict,calcControls) |
---|
[2838] | 3797 | pNames,pVals,pWt,pWsum,pWnum = penaltyFxn(HistoPhases,calcControls,parmDict,varylist) |
---|
[1299] | 3798 | if np.any(pVals): |
---|
[1775] | 3799 | dpdv = penaltyDeriv(pNames,pVals,HistoPhases,calcControls,parmDict,varylist) |
---|
[1299] | 3800 | dMdv = np.concatenate((dMdv.T,(np.sqrt(pWt)*dpdv).T)).T |
---|
| 3801 | |
---|
| 3802 | return dMdv |
---|
| 3803 | |
---|
| 3804 | def HessRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg): |
---|
| 3805 | '''Loop over histograms and compute derivatives of the fitting |
---|
| 3806 | model (M) with respect to all parameters. For each histogram, the |
---|
| 3807 | Jacobian matrix, dMdv, with dimensions (n by m) where n is the |
---|
| 3808 | number of parameters and m is the number of data points *in the |
---|
| 3809 | histogram*. The (n by n) Hessian is computed from each Jacobian |
---|
| 3810 | and it is returned. This routine is used when refinement |
---|
| 3811 | derivatives are selected as "analtytic Hessian" in Controls. |
---|
| 3812 | |
---|
| 3813 | :returns: Vec,Hess where Vec is the least-squares vector and Hess is the Hessian |
---|
| 3814 | ''' |
---|
| 3815 | parmDict.update(zip(varylist,values)) |
---|
| 3816 | G2mv.Dict2Map(parmDict,varylist) |
---|
| 3817 | Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases |
---|
[3005] | 3818 | dependentVars = G2mv.GetDependentVars() |
---|
[1915] | 3819 | #fixup H atom positions here? |
---|
[1299] | 3820 | ApplyRBModels(parmDict,Phases,rigidbodyDict) #,Update=True?? |
---|
| 3821 | Hess = np.empty(0) |
---|
[2546] | 3822 | Vec = np.empty(0) |
---|
[3136] | 3823 | histoList = list(Histograms.keys()) |
---|
[1299] | 3824 | histoList.sort() |
---|
| 3825 | for histogram in histoList: |
---|
| 3826 | if 'PWDR' in histogram[:4]: |
---|
| 3827 | Histogram = Histograms[histogram] |
---|
| 3828 | hId = Histogram['hId'] |
---|
| 3829 | hfx = ':%d:'%(hId) |
---|
| 3830 | wtFactor = calcControls[hfx+'wtFactor'] |
---|
| 3831 | Limits = calcControls[hfx+'Limits'] |
---|
| 3832 | x,y,w,yc,yb,yd = Histogram['Data'] |
---|
| 3833 | W = wtFactor*w |
---|
| 3834 | dy = y-yc |
---|
| 3835 | xB = np.searchsorted(x,Limits[0]) |
---|
[2754] | 3836 | xF = np.searchsorted(x,Limits[1])+1 |
---|
[3041] | 3837 | useMP,ncores = G2mp.InitMP() |
---|
[3095] | 3838 | if GSASIIpath.GetConfigValue('Show_timing',False): starttime = time.time() |
---|
[3041] | 3839 | if useMP: |
---|
[3004] | 3840 | MPpool = mp.Pool(ncores) |
---|
| 3841 | dMdvh = None |
---|
[3093] | 3842 | depDerivDict = None |
---|
[3004] | 3843 | profArgs = [ |
---|
[3005] | 3844 | (parmDict,x[xB:xF],varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup,dependentVars, |
---|
[3004] | 3845 | i,ncores) for i in range(ncores)] |
---|
[3093] | 3846 | for dmdv,depDerivs in MPpool.imap_unordered(getPowderProfileDervMP,profArgs): |
---|
[3004] | 3847 | if dMdvh is None: |
---|
| 3848 | dMdvh = dmdv |
---|
[3093] | 3849 | depDerivDict = depDerivs |
---|
[3004] | 3850 | else: |
---|
| 3851 | dMdvh += dmdv |
---|
[3093] | 3852 | for key in depDerivs.keys(): depDerivDict[key] += depDerivs[key] |
---|
[3129] | 3853 | MPpool.terminate() |
---|
[3004] | 3854 | else: |
---|
[3093] | 3855 | dMdvh,depDerivDict = getPowderProfileDervMP([parmDict,x[xB:xF], |
---|
[3041] | 3856 | varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup,dependentVars]) |
---|
| 3857 | #dMdvh = getPowderProfileDerv(parmDict,x[xB:xF], |
---|
| 3858 | # varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup,dependentVars) |
---|
[3093] | 3859 | G2mv.Dict2Deriv(varylist,depDerivDict,dMdvh) |
---|
[3136] | 3860 | if GSASIIpath.GetConfigValue('Show_timing',False): print ('getPowderProfileDerv t=%.3f'%time.time()-starttime) |
---|
[2094] | 3861 | Wt = ma.sqrt(W[xB:xF])[nxs,:] |
---|
| 3862 | Dy = dy[xB:xF][nxs,:] |
---|
[1299] | 3863 | dMdvh *= Wt |
---|
| 3864 | if dlg: |
---|
[1591] | 3865 | dlg.Update(Histogram['Residuals']['wR'],newmsg='Hessian for histogram %d\nAll data Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%')) |
---|
[3254] | 3866 | dlg.Raise() |
---|
[1299] | 3867 | if len(Hess): |
---|
| 3868 | Hess += np.inner(dMdvh,dMdvh) |
---|
| 3869 | dMdvh *= Wt*Dy |
---|
| 3870 | Vec += np.sum(dMdvh,axis=1) |
---|
| 3871 | else: |
---|
| 3872 | Hess = np.inner(dMdvh,dMdvh) |
---|
| 3873 | dMdvh *= Wt*Dy |
---|
| 3874 | Vec = np.sum(dMdvh,axis=1) |
---|
| 3875 | elif 'HKLF' in histogram[:4]: |
---|
| 3876 | Histogram = Histograms[histogram] |
---|
| 3877 | phase = Histogram['Reflection Lists'] |
---|
| 3878 | Phase = Phases[phase] |
---|
[1456] | 3879 | dMdvh,depDerivDict,wdf = dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict) |
---|
[1299] | 3880 | hId = Histogram['hId'] |
---|
[1456] | 3881 | hfx = ':%d:'%(Histogram['hId']) |
---|
[1299] | 3882 | wtFactor = calcControls[hfx+'wtFactor'] |
---|
| 3883 | # now process derivatives in constraints |
---|
| 3884 | G2mv.Dict2Deriv(varylist,depDerivDict,dMdvh) |
---|
[1453] | 3885 | # print 'matrix build time: %.3f'%(time.time()-time0) |
---|
[1299] | 3886 | |
---|
| 3887 | if dlg: |
---|
| 3888 | dlg.Update(Histogram['Residuals']['wR'],newmsg='Hessian for histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0] |
---|
[3254] | 3889 | dlg.Raise() |
---|
[1299] | 3890 | if len(Hess): |
---|
| 3891 | Vec += wtFactor*np.sum(dMdvh*wdf,axis=1) |
---|
| 3892 | Hess += wtFactor*np.inner(dMdvh,dMdvh) |
---|
| 3893 | else: |
---|
| 3894 | Vec = wtFactor*np.sum(dMdvh*wdf,axis=1) |
---|
| 3895 | Hess = wtFactor*np.inner(dMdvh,dMdvh) |
---|
| 3896 | else: |
---|
| 3897 | continue #skip non-histogram entries |
---|
[2732] | 3898 | GetFobsSq(Histograms,Phases,parmDict,calcControls) |
---|
[2838] | 3899 | pNames,pVals,pWt,pWsum,pWnum = penaltyFxn(HistoPhases,calcControls,parmDict,varylist) |
---|
[1299] | 3900 | if np.any(pVals): |
---|
[1775] | 3901 | dpdv = penaltyDeriv(pNames,pVals,HistoPhases,calcControls,parmDict,varylist) |
---|
[2808] | 3902 | Vec -= np.sum(dpdv*pWt*pVals,axis=1) |
---|
[1299] | 3903 | Hess += np.inner(dpdv*pWt,dpdv) |
---|
| 3904 | return Vec,Hess |
---|
| 3905 | |
---|
[1676] | 3906 | def errRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg=None): |
---|
| 3907 | '''Computes the point-by-point discrepancies between every data point in every histogram |
---|
[2110] | 3908 | and the observed value. Used in the Jacobian, Hessian & numeric least-squares to compute function |
---|
[1676] | 3909 | |
---|
| 3910 | :returns: an np array of differences between observed and computed diffraction values. |
---|
| 3911 | ''' |
---|
[1322] | 3912 | Values2Dict(parmDict, varylist, values) |
---|
[1299] | 3913 | G2mv.Dict2Map(parmDict,varylist) |
---|
| 3914 | Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases |
---|
| 3915 | M = np.empty(0) |
---|
| 3916 | SumwYo = 0 |
---|
| 3917 | Nobs = 0 |
---|
[1782] | 3918 | Nrej = 0 |
---|
[1800] | 3919 | Next = 0 |
---|
[1299] | 3920 | ApplyRBModels(parmDict,Phases,rigidbodyDict) |
---|
[1915] | 3921 | #fixup Hatom positions here.... |
---|
[3136] | 3922 | histoList = list(Histograms.keys()) |
---|
[1299] | 3923 | histoList.sort() |
---|
| 3924 | for histogram in histoList: |
---|
| 3925 | if 'PWDR' in histogram[:4]: |
---|
| 3926 | Histogram = Histograms[histogram] |
---|
| 3927 | hId = Histogram['hId'] |
---|
| 3928 | hfx = ':%d:'%(hId) |
---|
| 3929 | wtFactor = calcControls[hfx+'wtFactor'] |
---|
| 3930 | Limits = calcControls[hfx+'Limits'] |
---|
| 3931 | x,y,w,yc,yb,yd = Histogram['Data'] |
---|
| 3932 | yc *= 0.0 #zero full calcd profiles |
---|
| 3933 | yb *= 0.0 |
---|
| 3934 | yd *= 0.0 |
---|
| 3935 | xB = np.searchsorted(x,Limits[0]) |
---|
[2754] | 3936 | xF = np.searchsorted(x,Limits[1])+1 |
---|
[1299] | 3937 | yc[xB:xF],yb[xB:xF] = getPowderProfile(parmDict,x[xB:xF], |
---|
| 3938 | varylist,Histogram,Phases,calcControls,pawleyLookup) |
---|
| 3939 | yc[xB:xF] += yb[xB:xF] |
---|
| 3940 | if not np.any(y): #fill dummy data |
---|
[2797] | 3941 | try: |
---|
| 3942 | rv = st.poisson(yc[xB:xF]) |
---|
| 3943 | y[xB:xF] = rv.rvs() |
---|
| 3944 | except ValueError: |
---|
| 3945 | y[xB:xF] = yc[xB:xF] |
---|
[1299] | 3946 | Z = np.ones_like(yc[xB:xF]) |
---|
| 3947 | Z[1::2] *= -1 |
---|
| 3948 | y[xB:xF] = yc[xB:xF]+np.abs(y[xB:xF]-yc[xB:xF])*Z |
---|
| 3949 | w[xB:xF] = np.where(y[xB:xF]>0.,1./y[xB:xF],1.0) |
---|
| 3950 | yd[xB:xF] = y[xB:xF]-yc[xB:xF] |
---|
| 3951 | W = wtFactor*w |
---|
[2616] | 3952 | wdy = -ma.sqrt(w[xB:xF])*(yd[xB:xF]) |
---|
| 3953 | Histogram['Residuals']['Durbin-Watson'] = ma.sum(ma.diff(wdy)**2)/ma.sum(wdy**2) |
---|
| 3954 | wdy *= wtFactor |
---|
[1299] | 3955 | Histogram['Residuals']['Nobs'] = ma.count(x[xB:xF]) |
---|
| 3956 | Nobs += Histogram['Residuals']['Nobs'] |
---|
| 3957 | Histogram['Residuals']['sumwYo'] = ma.sum(W[xB:xF]*y[xB:xF]**2) |
---|
| 3958 | SumwYo += Histogram['Residuals']['sumwYo'] |
---|
| 3959 | Histogram['Residuals']['R'] = min(100.,ma.sum(ma.abs(yd[xB:xF]))/ma.sum(y[xB:xF])*100.) |
---|
| 3960 | Histogram['Residuals']['wR'] = min(100.,ma.sqrt(ma.sum(wdy**2)/Histogram['Residuals']['sumwYo'])*100.) |
---|
| 3961 | sumYmB = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],ma.abs(y[xB:xF]-yb[xB:xF]),0.)) |
---|
| 3962 | sumwYmB2 = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],W[xB:xF]*(y[xB:xF]-yb[xB:xF])**2,0.)) |
---|
| 3963 | sumYB = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],ma.abs(y[xB:xF]-yc[xB:xF])*ma.abs(y[xB:xF]-yb[xB:xF])/y[xB:xF],0.)) |
---|
| 3964 | sumwYB2 = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],W[xB:xF]*(ma.abs(y[xB:xF]-yc[xB:xF])*ma.abs(y[xB:xF]-yb[xB:xF])/y[xB:xF])**2,0.)) |
---|
| 3965 | Histogram['Residuals']['Rb'] = min(100.,100.*sumYB/sumYmB) |
---|
| 3966 | Histogram['Residuals']['wRb'] = min(100.,100.*ma.sqrt(sumwYB2/sumwYmB2)) |
---|
| 3967 | Histogram['Residuals']['wRmin'] = min(100.,100.*ma.sqrt(Histogram['Residuals']['Nobs']/Histogram['Residuals']['sumwYo'])) |
---|
| 3968 | if dlg: |
---|
| 3969 | dlg.Update(Histogram['Residuals']['wR'],newmsg='For histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0] |
---|
[3254] | 3970 | dlg.Raise() |
---|
[1299] | 3971 | M = np.concatenate((M,wdy)) |
---|
| 3972 | #end of PWDR processing |
---|
| 3973 | elif 'HKLF' in histogram[:4]: |
---|
| 3974 | Histogram = Histograms[histogram] |
---|
| 3975 | Histogram['Residuals'] = {} |
---|
| 3976 | phase = Histogram['Reflection Lists'] |
---|
| 3977 | Phase = Phases[phase] |
---|
| 3978 | hId = Histogram['hId'] |
---|
| 3979 | hfx = ':%d:'%(hId) |
---|
| 3980 | wtFactor = calcControls[hfx+'wtFactor'] |
---|
| 3981 | pfx = '%d::'%(Phase['pId']) |
---|
| 3982 | phfx = '%d:%d:'%(Phase['pId'],hId) |
---|
| 3983 | SGData = Phase['General']['SGData'] |
---|
[2115] | 3984 | TwinLaw = calcControls[phfx+'TwinLaw'] |
---|
[1595] | 3985 | im = 0 |
---|
[1923] | 3986 | if parmDict[phfx+'Scale'] < 0.: |
---|
| 3987 | parmDict[phfx+'Scale'] = .001 |
---|
[2405] | 3988 | if Phase['General'].get('Modulated',False): |
---|
[1595] | 3989 | SSGData = Phase['General']['SSGData'] |
---|
| 3990 | im = 1 #offset in SS reflection list |
---|
[1299] | 3991 | A = [parmDict[pfx+'A%d'%(i)] for i in range(6)] |
---|
| 3992 | G,g = G2lat.A2Gmat(A) #recip & real metric tensors |
---|
| 3993 | refDict = Histogram['Data'] |
---|
[1613] | 3994 | if im: |
---|
[2115] | 3995 | if len(TwinLaw) > 1: |
---|
| 3996 | SStructureFactorTw(refDict,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) |
---|
| 3997 | else: |
---|
| 3998 | SStructureFactor(refDict,G,hfx,pfx,SGData,SSGData,calcControls,parmDict) |
---|
[1613] | 3999 | else: |
---|
[1618] | 4000 | StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict) |
---|
[1453] | 4001 | # print 'sf-calc time: %.3f'%(time.time()-time0) |
---|
[1299] | 4002 | df = np.zeros(len(refDict['RefList'])) |
---|
| 4003 | sumwYo = 0 |
---|
| 4004 | sumFo = 0 |
---|
| 4005 | sumFo2 = 0 |
---|
[2078] | 4006 | sumFc2 = 0 |
---|
[1299] | 4007 | sumdF = 0 |
---|
| 4008 | sumdF2 = 0 |
---|
[1958] | 4009 | if im: |
---|
| 4010 | sumSSFo = np.zeros(10) |
---|
| 4011 | sumSSFo2 = np.zeros(10) |
---|
| 4012 | sumSSdF = np.zeros(10) |
---|
| 4013 | sumSSdF2 = np.zeros(10) |
---|
| 4014 | sumSSwYo = np.zeros(10) |
---|
| 4015 | sumSSwdf2 = np.zeros(10) |
---|
| 4016 | SSnobs = np.zeros(10) |
---|
[1299] | 4017 | nobs = 0 |
---|
[1782] | 4018 | nrej = 0 |
---|
[1800] | 4019 | next = 0 |
---|
[1958] | 4020 | maxH = 0 |
---|
[1299] | 4021 | if calcControls['F**2']: |
---|
| 4022 | for i,ref in enumerate(refDict['RefList']): |
---|
[1595] | 4023 | if ref[6+im] > 0: |
---|
[1604] | 4024 | ref[11+im] = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist)[0] |
---|
[1784] | 4025 | w = 1.0/ref[6+im] # 1/sig(F^2) |
---|
[1886] | 4026 | ref[7+im] *= parmDict[phfx+'Scale']*ref[11+im] #correct Fc^2 for extinction |
---|
[1595] | 4027 | ref[8+im] = ref[5+im]/(parmDict[phfx+'Scale']*ref[11+im]) |
---|
[1797] | 4028 | if UserRejectHKL(ref,im,calcControls['UsrReject']) and ref[3+im]: #skip sp.gp. absences (mul=0) |
---|
[1787] | 4029 | ref[3+im] = abs(ref[3+im]) #mark as allowed |
---|
[1595] | 4030 | Fo = np.sqrt(ref[5+im]) |
---|
[1299] | 4031 | sumFo += Fo |
---|
[1595] | 4032 | sumFo2 += ref[5+im] |
---|
[2078] | 4033 | sumFc2 += ref[7+im] |
---|
[1595] | 4034 | sumdF += abs(Fo-np.sqrt(ref[7+im])) |
---|
| 4035 | sumdF2 += abs(ref[5+im]-ref[7+im]) |
---|
[1299] | 4036 | nobs += 1 |
---|
[1595] | 4037 | df[i] = -w*(ref[5+im]-ref[7+im]) |
---|
[1784] | 4038 | sumwYo += (w*ref[5+im])**2 #w*Fo^2 |
---|
[1958] | 4039 | if im: #accumulate super lattice sums |
---|
| 4040 | ind = int(abs(ref[3])) |
---|
| 4041 | sumSSFo[ind] += Fo |
---|
| 4042 | sumSSFo2[ind] += ref[5+im] |
---|
| 4043 | sumSSdF[ind] += abs(Fo-np.sqrt(ref[7+im])) |
---|
| 4044 | sumSSdF2[ind] += abs(ref[5+im]-ref[7+im]) |
---|
| 4045 | sumSSwYo[ind] += (w*ref[5+im])**2 #w*Fo^2 |
---|
| 4046 | sumSSwdf2[ind] += df[i]**2 |
---|
| 4047 | SSnobs[ind] += 1 |
---|
| 4048 | maxH = max(maxH,ind) |
---|
[1782] | 4049 | else: |
---|
[1800] | 4050 | if ref[3+im]: |
---|
| 4051 | ref[3+im] = -abs(ref[3+im]) #mark as rejected |
---|
| 4052 | nrej += 1 |
---|
| 4053 | else: #sp.gp.extinct |
---|
| 4054 | next += 1 |
---|
[1299] | 4055 | else: |
---|
| 4056 | for i,ref in enumerate(refDict['RefList']): |
---|
[1595] | 4057 | if ref[5+im] > 0.: |
---|
| 4058 | ref[11+im] = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist)[0] |
---|
[1886] | 4059 | ref[7+im] *= parmDict[phfx+'Scale']*ref[11+im] #correct Fc^2 for extinction |
---|
[1595] | 4060 | ref[8+im] = ref[5+im]/(parmDict[phfx+'Scale']*ref[11+im]) |
---|
| 4061 | Fo = np.sqrt(ref[5+im]) |
---|
| 4062 | Fc = np.sqrt(ref[7+im]) |
---|
[1864] | 4063 | w = 2.0*Fo/ref[6+im] # 1/sig(F)? |
---|
[1797] | 4064 | if UserRejectHKL(ref,im,calcControls['UsrReject']) and ref[3+im]: #skip sp.gp. absences (mul=0) |
---|
[1787] | 4065 | ref[3+im] = abs(ref[3+im]) #mark as allowed |
---|
[1299] | 4066 | sumFo += Fo |
---|
[1595] | 4067 | sumFo2 += ref[5+im] |
---|
[2078] | 4068 | sumFc2 += ref[7+im] |
---|
[1299] | 4069 | sumdF += abs(Fo-Fc) |
---|
[1595] | 4070 | sumdF2 += abs(ref[5+im]-ref[7+im]) |
---|
[1299] | 4071 | nobs += 1 |
---|
| 4072 | df[i] = -w*(Fo-Fc) |
---|
| 4073 | sumwYo += (w*Fo)**2 |
---|
[1958] | 4074 | if im: |
---|
| 4075 | ind = int(abs(ref[3])) |
---|
| 4076 | sumSSFo[ind] += Fo |
---|
| 4077 | sumSSFo2[ind] += ref[5+im] |
---|
| 4078 | sumSSdF[ind] += abs(Fo-Fc) |
---|
| 4079 | sumSSdF2[ind] += abs(ref[5+im]-ref[7+im]) |
---|
| 4080 | sumSSwYo[ind] += (w*Fo)**2 |
---|
| 4081 | sumSSwdf2[ind] += df[i]**2 |
---|
| 4082 | SSnobs[ind] += 1 |
---|
| 4083 | maxH = max(maxH,ind) |
---|
[1782] | 4084 | else: |
---|
[1800] | 4085 | if ref[3+im]: |
---|
| 4086 | ref[3+im] = -abs(ref[3+im]) #mark as rejected |
---|
| 4087 | nrej += 1 |
---|
| 4088 | else: #sp.gp.extinct |
---|
| 4089 | next += 1 |
---|
[2078] | 4090 | Scale = sumFo2/sumFc2 |
---|
| 4091 | if (Scale < 0.8 or Scale > 1.2) and phfx+'Scale' in varylist: |
---|
[3240] | 4092 | print ('New scale: %.4f'%(Scale*parmDict[phfx+'Scale'])) |
---|
[2078] | 4093 | indx = varylist.index(phfx+'Scale') |
---|
| 4094 | values[indx] = Scale*parmDict[phfx+'Scale'] |
---|
[1299] | 4095 | Histogram['Residuals']['Nobs'] = nobs |
---|
| 4096 | Histogram['Residuals']['sumwYo'] = sumwYo |
---|
| 4097 | SumwYo += sumwYo |
---|
[1784] | 4098 | Histogram['Residuals']['wR'] = min(100.,np.sqrt(np.sum(df**2)/sumwYo)*100.) |
---|
[1299] | 4099 | Histogram['Residuals'][phfx+'Rf'] = 100.*sumdF/sumFo |
---|
| 4100 | Histogram['Residuals'][phfx+'Rf^2'] = 100.*sumdF2/sumFo2 |
---|
| 4101 | Histogram['Residuals'][phfx+'Nref'] = nobs |
---|
[1782] | 4102 | Histogram['Residuals'][phfx+'Nrej'] = nrej |
---|
[1800] | 4103 | Histogram['Residuals'][phfx+'Next'] = next |
---|
[1958] | 4104 | if im: |
---|
| 4105 | Histogram['Residuals'][phfx+'SSRf'] = 100.*sumSSdF[:maxH+1]/sumSSFo[:maxH+1] |
---|
| 4106 | Histogram['Residuals'][phfx+'SSRf^2'] = 100.*sumSSdF2[:maxH+1]/sumSSFo2[:maxH+1] |
---|
| 4107 | Histogram['Residuals'][phfx+'SSNref'] = SSnobs[:maxH+1] |
---|
| 4108 | Histogram['Residuals']['SSwR'] = np.sqrt(sumSSwdf2[:maxH+1]/sumSSwYo[:maxH+1])*100. |
---|
[1299] | 4109 | Nobs += nobs |
---|
[1782] | 4110 | Nrej += nrej |
---|
[1800] | 4111 | Next += next |
---|
[1299] | 4112 | if dlg: |
---|
| 4113 | dlg.Update(Histogram['Residuals']['wR'],newmsg='For histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0] |
---|
[3254] | 4114 | dlg.Raise() |
---|
[1299] | 4115 | M = np.concatenate((M,wtFactor*df)) |
---|
| 4116 | # end of HKLF processing |
---|
[2862] | 4117 | # GetFobsSq(Histograms,Phases,parmDict,calcControls) |
---|
[1299] | 4118 | Histograms['sumwYo'] = SumwYo |
---|
| 4119 | Histograms['Nobs'] = Nobs |
---|
[1782] | 4120 | Histograms['Nrej'] = Nrej |
---|
[1800] | 4121 | Histograms['Next'] = Next |
---|
[1299] | 4122 | Rw = min(100.,np.sqrt(np.sum(M**2)/SumwYo)*100.) |
---|
| 4123 | if dlg: |
---|
| 4124 | GoOn = dlg.Update(Rw,newmsg='%s%8.3f%s'%('All data Rw =',Rw,'%'))[0] |
---|
| 4125 | if not GoOn: |
---|
| 4126 | parmDict['saved values'] = values |
---|
| 4127 | dlg.Destroy() |
---|
[1813] | 4128 | raise G2obj.G2Exception('User abort') #Abort!! |
---|
[2838] | 4129 | pDict,pVals,pWt,pWsum,pWnum = penaltyFxn(HistoPhases,calcControls,parmDict,varylist) |
---|
[1365] | 4130 | if len(pVals): |
---|
[1299] | 4131 | pSum = np.sum(pWt*pVals**2) |
---|
| 4132 | for name in pWsum: |
---|
[1775] | 4133 | if pWsum[name]: |
---|
[3136] | 4134 | print (' Penalty function for %5d %8ss = %12.5g'%(pWnum[name],name,pWsum[name])) |
---|
| 4135 | print ('Total penalty function: %12.5g on %d terms'%(pSum,len(pVals))) |
---|
[1299] | 4136 | Nobs += len(pVals) |
---|
| 4137 | M = np.concatenate((M,np.sqrt(pWt)*pVals)) |
---|
| 4138 | return M |
---|