source: trunk/GSASIIstrMath.py @ 1682

Last change on this file since 1682 was 1682, checked in by vondreele, 8 years ago

do sums of Bragg intensity, and background terms put results into .lst file

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 133.7 KB
Line 
1# -*- coding: utf-8 -*-
2'''
3*GSASIIstrMath - structure math routines*
4-----------------------------------------
5'''
6########### SVN repository information ###################
7# $Date: 2015-02-28 15:16:41 +0000 (Sat, 28 Feb 2015) $
8# $Author: vondreele $
9# $Revision: 1682 $
10# $URL: trunk/GSASIIstrMath.py $
11# $Id: GSASIIstrMath.py 1682 2015-02-28 15:16:41Z vondreele $
12########### SVN repository information ###################
13import time
14import math
15import copy
16import numpy as np
17import numpy.ma as ma
18import numpy.linalg as nl
19import scipy.optimize as so
20import scipy.stats as st
21import GSASIIpath
22GSASIIpath.SetVersionNumber("$Revision: 1682 $")
23import GSASIIElem as G2el
24import GSASIIlattice as G2lat
25import GSASIIspc as G2spc
26import GSASIIpwd as G2pwd
27import GSASIImapvars as G2mv
28import GSASIImath as G2mth
29
30sind = lambda x: np.sin(x*np.pi/180.)
31cosd = lambda x: np.cos(x*np.pi/180.)
32tand = lambda x: np.tan(x*np.pi/180.)
33asind = lambda x: 180.*np.arcsin(x)/np.pi
34acosd = lambda x: 180.*np.arccos(x)/np.pi
35atan2d = lambda y,x: 180.*np.arctan2(y,x)/np.pi
36   
37ateln2 = 8.0*math.log(2.0)
38twopi = 2.0*np.pi
39twopisq = 2.0*np.pi**2
40
41################################################################################
42##### Rigid Body Models
43################################################################################
44       
45def ApplyRBModels(parmDict,Phases,rigidbodyDict,Update=False):
46    ''' Takes RB info from RBModels in Phase and RB data in rigidbodyDict along with
47    current RB values in parmDict & modifies atom contents (xyz & Uij) of parmDict
48    '''
49    atxIds = ['Ax:','Ay:','Az:']
50    atuIds = ['AU11:','AU22:','AU33:','AU12:','AU13:','AU23:']
51    RBIds = rigidbodyDict.get('RBIds',{'Vector':[],'Residue':[]})  #these are lists of rbIds
52    if not RBIds['Vector'] and not RBIds['Residue']:
53        return
54    VRBIds = RBIds['Vector']
55    RRBIds = RBIds['Residue']
56    if Update:
57        RBData = rigidbodyDict
58    else:
59        RBData = copy.deepcopy(rigidbodyDict)     # don't mess with original!
60    if RBIds['Vector']:                       # first update the vector magnitudes
61        VRBData = RBData['Vector']
62        for i,rbId in enumerate(VRBIds):
63            if VRBData[rbId]['useCount']:
64                for j in range(len(VRBData[rbId]['VectMag'])):
65                    name = '::RBV;'+str(j)+':'+str(i)
66                    VRBData[rbId]['VectMag'][j] = parmDict[name]
67    for phase in Phases:
68        Phase = Phases[phase]
69        General = Phase['General']
70        cx,ct,cs,cia = General['AtomPtrs']
71        cell = General['Cell'][1:7]
72        Amat,Bmat = G2lat.cell2AB(cell)
73        AtLookup = G2mth.FillAtomLookUp(Phase['Atoms'],cia+8)
74        pfx = str(Phase['pId'])+'::'
75        if Update:
76            RBModels = Phase['RBModels']
77        else:
78            RBModels =  copy.deepcopy(Phase['RBModels']) # again don't mess with original!
79        for irb,RBObj in enumerate(RBModels.get('Vector',[])):
80            jrb = VRBIds.index(RBObj['RBId'])
81            rbsx = str(irb)+':'+str(jrb)
82            for i,px in enumerate(['RBVPx:','RBVPy:','RBVPz:']):
83                RBObj['Orig'][0][i] = parmDict[pfx+px+rbsx]
84            for i,po in enumerate(['RBVOa:','RBVOi:','RBVOj:','RBVOk:']):
85                RBObj['Orient'][0][i] = parmDict[pfx+po+rbsx]
86            RBObj['Orient'][0] = G2mth.normQ(RBObj['Orient'][0])
87            TLS = RBObj['ThermalMotion']
88            if 'T' in TLS[0]:
89                for i,pt in enumerate(['RBVT11:','RBVT22:','RBVT33:','RBVT12:','RBVT13:','RBVT23:']):
90                    TLS[1][i] = parmDict[pfx+pt+rbsx]
91            if 'L' in TLS[0]:
92                for i,pt in enumerate(['RBVL11:','RBVL22:','RBVL33:','RBVL12:','RBVL13:','RBVL23:']):
93                    TLS[1][i+6] = parmDict[pfx+pt+rbsx]
94            if 'S' in TLS[0]:
95                for i,pt in enumerate(['RBVS12:','RBVS13:','RBVS21:','RBVS23:','RBVS31:','RBVS32:','RBVSAA:','RBVSBB:']):
96                    TLS[1][i+12] = parmDict[pfx+pt+rbsx]
97            if 'U' in TLS[0]:
98                TLS[1][0] = parmDict[pfx+'RBVU:'+rbsx]
99            XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Vector')
100            UIJ = G2mth.UpdateRBUIJ(Bmat,Cart,RBObj)
101            for i,x in enumerate(XYZ):
102                atId = RBObj['Ids'][i]
103                for j in [0,1,2]:
104                    parmDict[pfx+atxIds[j]+str(AtLookup[atId])] = x[j]
105                if UIJ[i][0] == 'A':
106                    for j in range(6):
107                        parmDict[pfx+atuIds[j]+str(AtLookup[atId])] = UIJ[i][j+2]
108                elif UIJ[i][0] == 'I':
109                    parmDict[pfx+'AUiso:'+str(AtLookup[atId])] = UIJ[i][1]
110           
111        for irb,RBObj in enumerate(RBModels.get('Residue',[])):
112            jrb = RRBIds.index(RBObj['RBId'])
113            rbsx = str(irb)+':'+str(jrb)
114            for i,px in enumerate(['RBRPx:','RBRPy:','RBRPz:']):
115                RBObj['Orig'][0][i] = parmDict[pfx+px+rbsx]
116            for i,po in enumerate(['RBROa:','RBROi:','RBROj:','RBROk:']):
117                RBObj['Orient'][0][i] = parmDict[pfx+po+rbsx]               
118            RBObj['Orient'][0] = G2mth.normQ(RBObj['Orient'][0])
119            TLS = RBObj['ThermalMotion']
120            if 'T' in TLS[0]:
121                for i,pt in enumerate(['RBRT11:','RBRT22:','RBRT33:','RBRT12:','RBRT13:','RBRT23:']):
122                    RBObj['ThermalMotion'][1][i] = parmDict[pfx+pt+rbsx]
123            if 'L' in TLS[0]:
124                for i,pt in enumerate(['RBRL11:','RBRL22:','RBRL33:','RBRL12:','RBRL13:','RBRL23:']):
125                    RBObj['ThermalMotion'][1][i+6] = parmDict[pfx+pt+rbsx]
126            if 'S' in TLS[0]:
127                for i,pt in enumerate(['RBRS12:','RBRS13:','RBRS21:','RBRS23:','RBRS31:','RBRS32:','RBRSAA:','RBRSBB:']):
128                    RBObj['ThermalMotion'][1][i+12] = parmDict[pfx+pt+rbsx]
129            if 'U' in TLS[0]:
130                RBObj['ThermalMotion'][1][0] = parmDict[pfx+'RBRU:'+rbsx]
131            for itors,tors in enumerate(RBObj['Torsions']):
132                tors[0] = parmDict[pfx+'RBRTr;'+str(itors)+':'+rbsx]
133            XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Residue')
134            UIJ = G2mth.UpdateRBUIJ(Bmat,Cart,RBObj)
135            for i,x in enumerate(XYZ):
136                atId = RBObj['Ids'][i]
137                for j in [0,1,2]:
138                    parmDict[pfx+atxIds[j]+str(AtLookup[atId])] = x[j]
139                if UIJ[i][0] == 'A':
140                    for j in range(6):
141                        parmDict[pfx+atuIds[j]+str(AtLookup[atId])] = UIJ[i][j+2]
142                elif UIJ[i][0] == 'I':
143                    parmDict[pfx+'AUiso:'+str(AtLookup[atId])] = UIJ[i][1]
144                   
145def ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase):
146    'Needs a doc string'
147    atxIds = ['dAx:','dAy:','dAz:']
148    atuIds = ['AU11:','AU22:','AU33:','AU12:','AU13:','AU23:']
149    TIds = ['T11:','T22:','T33:','T12:','T13:','T23:']
150    LIds = ['L11:','L22:','L33:','L12:','L13:','L23:']
151    SIds = ['S12:','S13:','S21:','S23:','S31:','S32:','SAA:','SBB:']
152    PIds = ['Px:','Py:','Pz:']
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']
164    cx,ct,cs,cia = General['AtomPtrs']
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]]))
172    AtLookup = G2mth.FillAtomLookUp(Phase['Atoms'],cia+8)
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        Pos = RBObj['Orig'][0]
179        jrb = VRBIds.index(RBObj['RBId'])
180        rbsx = str(irb)+':'+str(jrb)
181        dXdv = []
182        for iv in range(len(VModel['VectMag'])):
183            dCdv = []
184            for vec in VModel['rbVect'][iv]:
185                dCdv.append(G2mth.prodQVQ(Q,vec))
186            dXdv.append(np.inner(Bmat,np.array(dCdv)).T)
187        XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Vector')
188        for ia,atId in enumerate(RBObj['Ids']):
189            atNum = AtLookup[atId]
190            dx = 0.00001
191            for iv in range(len(VModel['VectMag'])):
192                for ix in [0,1,2]:
193                    dFdvDict['::RBV;'+str(iv)+':'+str(jrb)] += dXdv[iv][ia][ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)]
194            for i,name in enumerate(['RBVPx:','RBVPy:','RBVPz:']):
195                dFdvDict[pfx+name+rbsx] += dFdvDict[pfx+atxIds[i]+str(atNum)]
196            for iv in range(4):
197                Q[iv] -= dx
198                XYZ1 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q))
199                Q[iv] += 2.*dx
200                XYZ2 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q))
201                Q[iv] -= dx
202                dXdO = (XYZ2[ia]-XYZ1[ia])/(2.*dx)
203                for ix in [0,1,2]:
204                    dFdvDict[pfx+'RBV'+OIds[iv]+rbsx] += dXdO[ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)]
205            X = G2mth.prodQVQ(Q,Cart[ia])
206            dFdu = np.array([dFdvDict[pfx+Uid+str(AtLookup[atId])] for Uid in atuIds]).T/gvec
207            dFdu = G2lat.U6toUij(dFdu.T)
208            dFdu = np.tensordot(Amat,np.tensordot(Amat,dFdu,([1,0])),([0,1]))           
209            dFdu = G2lat.UijtoU6(dFdu)
210            atNum = AtLookup[atId]
211            if 'T' in RBObj['ThermalMotion'][0]:
212                for i,name in enumerate(['RBVT11:','RBVT22:','RBVT33:','RBVT12:','RBVT13:','RBVT23:']):
213                    dFdvDict[pfx+name+rbsx] += dFdu[i]
214            if 'L' in RBObj['ThermalMotion'][0]:
215                dFdvDict[pfx+'RBVL11:'+rbsx] += rpd2*(dFdu[1]*X[2]**2+dFdu[2]*X[1]**2-dFdu[5]*X[1]*X[2])
216                dFdvDict[pfx+'RBVL22:'+rbsx] += rpd2*(dFdu[0]*X[2]**2+dFdu[2]*X[0]**2-dFdu[4]*X[0]*X[2])
217                dFdvDict[pfx+'RBVL33:'+rbsx] += rpd2*(dFdu[0]*X[1]**2+dFdu[1]*X[0]**2-dFdu[3]*X[0]*X[1])
218                dFdvDict[pfx+'RBVL12:'+rbsx] += rpd2*(-dFdu[3]*X[2]**2-2.*dFdu[2]*X[0]*X[1]+
219                    dFdu[4]*X[1]*X[2]+dFdu[5]*X[0]*X[2])
220                dFdvDict[pfx+'RBVL13:'+rbsx] += rpd2*(-dFdu[4]*X[1]**2-2.*dFdu[1]*X[0]*X[2]+
221                    dFdu[3]*X[1]*X[2]+dFdu[5]*X[0]*X[1])
222                dFdvDict[pfx+'RBVL23:'+rbsx] += rpd2*(-dFdu[5]*X[0]**2-2.*dFdu[0]*X[1]*X[2]+
223                    dFdu[3]*X[0]*X[2]+dFdu[4]*X[0]*X[1])
224            if 'S' in RBObj['ThermalMotion'][0]:
225                dFdvDict[pfx+'RBVS12:'+rbsx] += rpd*(dFdu[5]*X[1]-2.*dFdu[1]*X[2])
226                dFdvDict[pfx+'RBVS13:'+rbsx] += rpd*(-dFdu[5]*X[2]+2.*dFdu[2]*X[1])
227                dFdvDict[pfx+'RBVS21:'+rbsx] += rpd*(-dFdu[4]*X[0]+2.*dFdu[0]*X[2])
228                dFdvDict[pfx+'RBVS23:'+rbsx] += rpd*(dFdu[4]*X[2]-2.*dFdu[2]*X[0])
229                dFdvDict[pfx+'RBVS31:'+rbsx] += rpd*(dFdu[3]*X[0]-2.*dFdu[0]*X[1])
230                dFdvDict[pfx+'RBVS32:'+rbsx] += rpd*(-dFdu[3]*X[1]+2.*dFdu[1]*X[0])
231                dFdvDict[pfx+'RBVSAA:'+rbsx] += rpd*(dFdu[4]*X[1]-dFdu[3]*X[2])
232                dFdvDict[pfx+'RBVSBB:'+rbsx] += rpd*(dFdu[5]*X[0]-dFdu[3]*X[2])
233            if 'U' in RBObj['ThermalMotion'][0]:
234                dFdvDict[pfx+'RBVU:'+rbsx] += dFdvDict[pfx+'AUiso:'+str(AtLookup[atId])]
235
236
237    for irb,RBObj in enumerate(RBModels.get('Residue',[])):
238        Q = RBObj['Orient'][0]
239        Pos = RBObj['Orig'][0]
240        jrb = RRBIds.index(RBObj['RBId'])
241        torData = RBData['Residue'][RBObj['RBId']]['rbSeq']
242        rbsx = str(irb)+':'+str(jrb)
243        XYZ,Cart = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Residue')
244        for itors,tors in enumerate(RBObj['Torsions']):     #derivative error?
245            tname = pfx+'RBRTr;'+str(itors)+':'+rbsx           
246            orId,pvId = torData[itors][:2]
247            pivotVec = Cart[orId]-Cart[pvId]
248            QA = G2mth.AVdeg2Q(-0.001,pivotVec)
249            QB = G2mth.AVdeg2Q(0.001,pivotVec)
250            for ir in torData[itors][3]:
251                atNum = AtLookup[RBObj['Ids'][ir]]
252                rVec = Cart[ir]-Cart[pvId]
253                dR = G2mth.prodQVQ(QB,rVec)-G2mth.prodQVQ(QA,rVec)
254                dRdT = np.inner(Bmat,G2mth.prodQVQ(Q,dR))/.002
255                for ix in [0,1,2]:
256                    dFdvDict[tname] += dRdT[ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)]
257        for ia,atId in enumerate(RBObj['Ids']):
258            atNum = AtLookup[atId]
259            dx = 0.00001
260            for i,name in enumerate(['RBRPx:','RBRPy:','RBRPz:']):
261                dFdvDict[pfx+name+rbsx] += dFdvDict[pfx+atxIds[i]+str(atNum)]
262            for iv in range(4):
263                Q[iv] -= dx
264                XYZ1 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q))
265                Q[iv] += 2.*dx
266                XYZ2 = G2mth.RotateRBXYZ(Bmat,Cart,G2mth.normQ(Q))
267                Q[iv] -= dx
268                dXdO = (XYZ2[ia]-XYZ1[ia])/(2.*dx)
269                for ix in [0,1,2]:
270                    dFdvDict[pfx+'RBR'+OIds[iv]+rbsx] += dXdO[ix]*dFdvDict[pfx+atxIds[ix]+str(atNum)]
271            X = G2mth.prodQVQ(Q,Cart[ia])
272            dFdu = np.array([dFdvDict[pfx+Uid+str(AtLookup[atId])] for Uid in atuIds]).T/gvec
273            dFdu = G2lat.U6toUij(dFdu.T)
274            dFdu = np.tensordot(Amat.T,np.tensordot(Amat,dFdu,([1,0])),([0,1]))
275            dFdu = G2lat.UijtoU6(dFdu)
276            atNum = AtLookup[atId]
277            if 'T' in RBObj['ThermalMotion'][0]:
278                for i,name in enumerate(['RBRT11:','RBRT22:','RBRT33:','RBRT12:','RBRT13:','RBRT23:']):
279                    dFdvDict[pfx+name+rbsx] += dFdu[i]
280            if 'L' in RBObj['ThermalMotion'][0]:
281                dFdvDict[pfx+'RBRL11:'+rbsx] += rpd2*(dFdu[1]*X[2]**2+dFdu[2]*X[1]**2-dFdu[5]*X[1]*X[2])
282                dFdvDict[pfx+'RBRL22:'+rbsx] += rpd2*(dFdu[0]*X[2]**2+dFdu[2]*X[0]**2-dFdu[4]*X[0]*X[2])
283                dFdvDict[pfx+'RBRL33:'+rbsx] += rpd2*(dFdu[0]*X[1]**2+dFdu[1]*X[0]**2-dFdu[3]*X[0]*X[1])
284                dFdvDict[pfx+'RBRL12:'+rbsx] += rpd2*(-dFdu[3]*X[2]**2-2.*dFdu[2]*X[0]*X[1]+
285                    dFdu[4]*X[1]*X[2]+dFdu[5]*X[0]*X[2])
286                dFdvDict[pfx+'RBRL13:'+rbsx] += rpd2*(dFdu[4]*X[1]**2-2.*dFdu[1]*X[0]*X[2]+
287                    dFdu[3]*X[1]*X[2]+dFdu[5]*X[0]*X[1])
288                dFdvDict[pfx+'RBRL23:'+rbsx] += rpd2*(dFdu[5]*X[0]**2-2.*dFdu[0]*X[1]*X[2]+
289                    dFdu[3]*X[0]*X[2]+dFdu[4]*X[0]*X[1])
290            if 'S' in RBObj['ThermalMotion'][0]:
291                dFdvDict[pfx+'RBRS12:'+rbsx] += rpd*(dFdu[5]*X[1]-2.*dFdu[1]*X[2])
292                dFdvDict[pfx+'RBRS13:'+rbsx] += rpd*(-dFdu[5]*X[2]+2.*dFdu[2]*X[1])
293                dFdvDict[pfx+'RBRS21:'+rbsx] += rpd*(-dFdu[4]*X[0]+2.*dFdu[0]*X[2])
294                dFdvDict[pfx+'RBRS23:'+rbsx] += rpd*(dFdu[4]*X[2]-2.*dFdu[2]*X[0])
295                dFdvDict[pfx+'RBRS31:'+rbsx] += rpd*(dFdu[3]*X[0]-2.*dFdu[0]*X[1])
296                dFdvDict[pfx+'RBRS32:'+rbsx] += rpd*(-dFdu[3]*X[1]+2.*dFdu[1]*X[0])
297                dFdvDict[pfx+'RBRSAA:'+rbsx] += rpd*(dFdu[4]*X[1]-dFdu[3]*X[2])
298                dFdvDict[pfx+'RBRSBB:'+rbsx] += rpd*(dFdu[5]*X[0]-dFdu[3]*X[2])
299            if 'U' in RBObj['ThermalMotion'][0]:
300                dFdvDict[pfx+'RBRU:'+rbsx] += dFdvDict[pfx+'AUiso:'+str(AtLookup[atId])]
301   
302################################################################################
303##### Penalty & restraint functions
304################################################################################
305
306def penaltyFxn(HistoPhases,parmDict,varyList):
307    'Needs a doc string'
308    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
309    pNames = []
310    pVals = []
311    pWt = []
312    negWt = {}
313    pWsum = {}
314    for phase in Phases:
315        pId = Phases[phase]['pId']
316        negWt[pId] = Phases[phase]['General']['Pawley neg wt']
317        General = Phases[phase]['General']
318        cx,ct,cs,cia = General['AtomPtrs']
319        textureData = General['SH Texture']
320        SGData = General['SGData']
321        AtLookup = G2mth.FillAtomLookUp(Phases[phase]['Atoms'],cia+8)
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'],
329            ['ChemComp','Sites'],['Texture','HKLs']]
330        for name,rest in names:
331            pWsum[name] = 0.
332            itemRest = phaseRest[name]
333            if itemRest[rest] and itemRest['Use']:
334                wt = itemRest['wtFactor']
335                if name in ['Bond','Angle','Plane','Chiral']:
336                    for i,[indx,ops,obs,esd] in enumerate(itemRest[rest]):
337                        pNames.append(str(pId)+':'+name+':'+str(i))
338                        XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx))
339                        XYZ = G2mth.getSyXYZ(XYZ,ops,SGData)
340                        if name == 'Bond':
341                            calc = G2mth.getRestDist(XYZ,Amat)
342                        elif name == 'Angle':
343                            calc = G2mth.getRestAngle(XYZ,Amat)
344                        elif name == 'Plane':
345                            calc = G2mth.getRestPlane(XYZ,Amat)
346                        elif name == 'Chiral':
347                            calc = G2mth.getRestChiral(XYZ,Amat)
348                        pVals.append(obs-calc)
349                        pWt.append(wt/esd**2)
350                        pWsum[name] += wt*((obs-calc)/esd)**2
351                elif name in ['Torsion','Rama']:
352                    coeffDict = itemRest['Coeff']
353                    for i,[indx,ops,cofName,esd] in enumerate(itemRest[rest]):
354                        pNames.append(str(pId)+':'+name+':'+str(i))
355                        XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx))
356                        XYZ = G2mth.getSyXYZ(XYZ,ops,SGData)
357                        if name == 'Torsion':
358                            tor = G2mth.getRestTorsion(XYZ,Amat)
359                            restr,calc = G2mth.calcTorsionEnergy(tor,coeffDict[cofName])
360                        else:
361                            phi,psi = G2mth.getRestRama(XYZ,Amat)
362                            restr,calc = G2mth.calcRamaEnergy(phi,psi,coeffDict[cofName])                               
363                        pVals.append(restr)
364                        pWt.append(wt/esd**2)
365                        pWsum[name] += wt*(restr/esd)**2
366                elif name == 'ChemComp':
367                    for i,[indx,factors,obs,esd] in enumerate(itemRest[rest]):
368                        pNames.append(str(pId)+':'+name+':'+str(i))
369                        mul = np.array(G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,cs+1))
370                        frac = np.array(G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,cs-1))
371                        calc = np.sum(mul*frac*factors)
372                        pVals.append(obs-calc)
373                        pWt.append(wt/esd**2)                   
374                        pWsum[name] += wt*((obs-calc)/esd)**2
375                elif name == 'Texture':
376                    SHkeys = textureData['SH Coeff'][1].keys()
377                    SHCoef = G2mth.GetSHCoeff(pId,parmDict,SHkeys)
378                    shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
379                    SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
380                    for i,[hkl,grid,esd1,ifesd2,esd2] in enumerate(itemRest[rest]):
381                        PH = np.array(hkl)
382                        phi,beta = G2lat.CrsAng(np.array(hkl),cell,SGData)
383                        ODFln = G2lat.Flnh(False,SHCoef,phi,beta,SGData)
384                        R,P,Z = G2mth.getRestPolefig(ODFln,SamSym[textureData['Model']],grid)
385                        Z1 = -ma.masked_greater(Z,0.0)
386                        IndZ1 = np.array(ma.nonzero(Z1))
387                        for ind in IndZ1.T:
388                            pNames.append('%d:%s:%d:%.2f:%.2f'%(pId,name,i,R[ind[0],ind[1]],P[ind[0],ind[1]]))
389                            pVals.append(Z1[ind[0]][ind[1]])
390                            pWt.append(wt/esd1**2)
391                            pWsum[name] += wt*((obs-calc)/esd)**2
392                        if ifesd2:
393                            Z2 = 1.-Z
394                            for ind in np.ndindex(grid,grid):
395                                pNames.append('%d:%s:%d:%.2f:%.2f'%(pId,name+'-unit',i,R[ind[0],ind[1]],P[ind[0],ind[1]]))
396                                pVals.append(Z1[ind[0]][ind[1]])
397                                pWt.append(wt/esd2**2)
398                                pWsum[name] += wt*((obs-calc)/esd)**2
399         
400    pWsum['PWLref'] = 0.
401    for item in varyList:
402        if 'PWLref' in item and parmDict[item] < 0.:
403            pId = int(item.split(':')[0])
404            if negWt[pId]:
405                pNames.append(item)
406                pVals.append(-parmDict[item])
407                pWt.append(negWt[pId])
408                pWsum['PWLref'] += negWt[pId]*(-parmDict[item])**2
409    pVals = np.array(pVals)
410    pWt = np.array(pWt)         #should this be np.sqrt?
411    return pNames,pVals,pWt,pWsum
412   
413def penaltyDeriv(pNames,pVal,HistoPhases,parmDict,varyList):
414    'Needs a doc string'
415    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
416    pDerv = np.zeros((len(varyList),len(pVal)))
417    for phase in Phases:
418#        if phase not in restraintDict:
419#            continue
420        pId = Phases[phase]['pId']
421        General = Phases[phase]['General']
422        cx,ct,cs,cia = General['AtomPtrs']
423        SGData = General['SGData']
424        AtLookup = G2mth.FillAtomLookUp(Phases[phase]['Atoms'],cia+8)
425        cell = General['Cell'][1:7]
426        Amat,Bmat = G2lat.cell2AB(cell)
427        textureData = General['SH Texture']
428
429        SHkeys = textureData['SH Coeff'][1].keys()
430        SHCoef = G2mth.GetSHCoeff(pId,parmDict,SHkeys)
431        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
432        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
433        sam = SamSym[textureData['Model']]
434        phaseRest = restraintDict.get(phase,{})
435        names = {'Bond':'Bonds','Angle':'Angles','Plane':'Planes',
436            'Chiral':'Volumes','Torsion':'Torsions','Rama':'Ramas',
437            'ChemComp':'Sites','Texture':'HKLs'}
438        lasthkl = np.array([0,0,0])
439        for ip,pName in enumerate(pNames):
440            pnames = pName.split(':')
441            if pId == int(pnames[0]):
442                name = pnames[1]
443                if 'PWL' in pName:
444                    pDerv[varyList.index(pName)][ip] += 1.
445                    continue
446                id = int(pnames[2]) 
447                itemRest = phaseRest[name]
448                if name in ['Bond','Angle','Plane','Chiral']:
449                    indx,ops,obs,esd = itemRest[names[name]][id]
450                    dNames = []
451                    for ind in indx:
452                        dNames += [str(pId)+'::dA'+Xname+':'+str(AtLookup[ind]) for Xname in ['x','y','z']]
453                    XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx))
454                    if name == 'Bond':
455                        deriv = G2mth.getRestDeriv(G2mth.getRestDist,XYZ,Amat,ops,SGData)
456                    elif name == 'Angle':
457                        deriv = G2mth.getRestDeriv(G2mth.getRestAngle,XYZ,Amat,ops,SGData)
458                    elif name == 'Plane':
459                        deriv = G2mth.getRestDeriv(G2mth.getRestPlane,XYZ,Amat,ops,SGData)
460                    elif name == 'Chiral':
461                        deriv = G2mth.getRestDeriv(G2mth.getRestChiral,XYZ,Amat,ops,SGData)
462                elif name in ['Torsion','Rama']:
463                    coffDict = itemRest['Coeff']
464                    indx,ops,cofName,esd = itemRest[names[name]][id]
465                    dNames = []
466                    for ind in indx:
467                        dNames += [str(pId)+'::dA'+Xname+':'+str(AtLookup[ind]) for Xname in ['x','y','z']]
468                    XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx))
469                    if name == 'Torsion':
470                        deriv = G2mth.getTorsionDeriv(XYZ,Amat,coffDict[cofName])
471                    else:
472                        deriv = G2mth.getRamaDeriv(XYZ,Amat,coffDict[cofName])
473                elif name == 'ChemComp':
474                    indx,factors,obs,esd = itemRest[names[name]][id]
475                    dNames = []
476                    for ind in indx:
477                        dNames += [str(pId)+'::Afrac:'+str(AtLookup[ind])]
478                        mul = np.array(G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,cs+1))
479                        deriv = mul*factors
480                elif 'Texture' in name:
481                    deriv = []
482                    dNames = []
483                    hkl,grid,esd1,ifesd2,esd2 = itemRest[names[name]][id]
484                    hkl = np.array(hkl)
485                    if np.any(lasthkl-hkl):
486                        PH = np.array(hkl)
487                        phi,beta = G2lat.CrsAng(np.array(hkl),cell,SGData)
488                        ODFln = G2lat.Flnh(False,SHCoef,phi,beta,SGData)
489                        lasthkl = copy.copy(hkl)                       
490                    if 'unit' in name:
491                        pass
492                    else:
493                        gam = float(pnames[3])
494                        psi = float(pnames[4])
495                        for SHname in ODFln:
496                            l,m,n = eval(SHname[1:])
497                            Ksl = G2lat.GetKsl(l,m,sam,psi,gam)[0]
498                            dNames += [str(pId)+'::'+SHname]
499                            deriv.append(-ODFln[SHname][0]*Ksl/SHCoef[SHname])
500                for dName,drv in zip(dNames,deriv):
501                    try:
502                        ind = varyList.index(dName)
503                        pDerv[ind][ip] += drv
504                    except ValueError:
505                        pass
506    return pDerv
507
508################################################################################
509##### Function & derivative calculations
510################################################################################       
511                   
512def GetAtomFXU(pfx,calcControls,parmDict):
513    'Needs a doc string'
514    Natoms = calcControls['Natoms'][pfx]
515    Tdata = Natoms*[' ',]
516    Mdata = np.zeros(Natoms)
517    IAdata = Natoms*[' ',]
518    Fdata = np.zeros(Natoms)
519    FFdata = []
520    BLdata = []
521    Xdata = np.zeros((3,Natoms))
522    dXdata = np.zeros((3,Natoms))
523    Uisodata = np.zeros(Natoms)
524    Uijdata = np.zeros((6,Natoms))
525    keys = {'Atype:':Tdata,'Amul:':Mdata,'Afrac:':Fdata,'AI/A:':IAdata,
526        'dAx:':dXdata[0],'dAy:':dXdata[1],'dAz:':dXdata[2],
527        'Ax:':Xdata[0],'Ay:':Xdata[1],'Az:':Xdata[2],'AUiso:':Uisodata,
528        'AU11:':Uijdata[0],'AU22:':Uijdata[1],'AU33:':Uijdata[2],
529        'AU12:':Uijdata[3],'AU13:':Uijdata[4],'AU23:':Uijdata[5]}
530    for iatm in range(Natoms):
531        for key in keys:
532            parm = pfx+key+str(iatm)
533            if parm in parmDict:
534                keys[key][iatm] = parmDict[parm]
535    Fdata = np.where(Fdata,Fdata,1.e-8)         #avoid divide by zero in derivative calc.?
536    return Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata
537   
538def GetAtomSSFXU(pfx,calcControls,parmDict):
539    'Needs a doc string'
540    Natoms = calcControls['Natoms'][pfx]
541    maxSSwave = calcControls['maxSSwave'][pfx]
542    Nwave = {'F':maxSSwave['Sfrac'],'X':maxSSwave['Spos'],'Y':maxSSwave['Spos'],'Z':maxSSwave['Spos'],
543        'U':maxSSwave['Sadp'],'M':maxSSwave['Smag'],'T':maxSSwave['Spos']}
544    XSSdata = np.zeros((6,maxSSwave['Spos'],Natoms))
545    FSSdata = np.zeros((2,maxSSwave['Sfrac'],Natoms))
546    USSdata = np.zeros((12,maxSSwave['Sadp'],Natoms))
547    MSSdata = np.zeros((6,maxSSwave['Smag'],Natoms))
548    waveTypes = []
549    keys = {'Fsin:':FSSdata[0],'Fcos:':FSSdata[1],'Fzero:':FSSdata[0],'Fwid:':FSSdata[1],
550        'Tzero:':XSSdata[0],'Xslope:':XSSdata[1],'Yslope:':XSSdata[2],'Zslope:':XSSdata[3],
551        'Xsin:':XSSdata[0],'Ysin:':XSSdata[1],'Zsin:':XSSdata[2],'Xcos:':XSSdata[3],'Ycos:':XSSdata[4],'Zcos:':XSSdata[5],
552        'U11sin:':USSdata[0],'U22sin:':USSdata[1],'U33sin:':USSdata[2],'U12sin:':USSdata[3],'U13sin:':USSdata[4],'U23sin:':USSdata[5],
553        'U11cos:':USSdata[6],'U22cos:':USSdata[7],'U33cos:':USSdata[8],'U12cos:':USSdata[9],'U13cos:':USSdata[10],'U23cos:':USSdata[11],
554        'MXsin:':MSSdata[0],'MYsin:':MSSdata[1],'MZsin:':MSSdata[2],'MXcos:':MSSdata[3],'MYcos:':MSSdata[4],'MZcos:':MSSdata[5]}
555    for iatm in range(Natoms):
556        waveTypes.append(parmDict[pfx+'waveType:'+str(iatm)])
557        for key in keys:
558            for m in range(Nwave[key[0]]):
559                parm = pfx+key+str(iatm)+':%d'%(m)
560                if parm in parmDict:
561                    keys[key][m][iatm] = parmDict[parm]
562    return waveTypes,FSSdata.squeeze(),XSSdata.squeeze(),USSdata.squeeze(),MSSdata.squeeze()   
563   
564def StructureFactor(refDict,G,hfx,pfx,SGData,calcControls,parmDict):
565    ''' Not Used: here only for comparison the StructureFactor2 - faster version
566    Compute structure factors for all h,k,l for phase
567    puts the result, F^2, in each ref[8] in refList
568    input:
569   
570    :param dict refDict: where
571        'RefList' list where each ref = h,k,l,m,d,...
572        'FF' dict of form factors - filed in below
573    :param np.array G:      reciprocal metric tensor
574    :param str pfx:    phase id string
575    :param dict SGData: space group info. dictionary output from SpcGroup
576    :param dict calcControls:
577    :param dict ParmDict:
578
579    '''       
580    phfx = pfx.split(':')[0]+hfx
581    ast = np.sqrt(np.diag(G))
582    Mast = twopisq*np.multiply.outer(ast,ast)
583    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
584    SGT = np.array([ops[1] for ops in SGData['SGOps']])
585    FFtables = calcControls['FFtables']
586    BLtables = calcControls['BLtables']
587    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
588    FF = np.zeros(len(Tdata))
589    if 'NC' in calcControls[hfx+'histType']:
590        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
591    else:
592        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
593        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
594    Uij = np.array(G2lat.U6toUij(Uijdata))
595    bij = Mast*Uij.T
596    if not len(refDict['FF']):
597        if 'N' in calcControls[hfx+'histType']:
598            dat = G2el.getBLvalues(BLtables)        #will need wave here for anom. neutron b's
599        else:
600            dat = G2el.getFFvalues(FFtables,0.)       
601        refDict['FF']['El'] = dat.keys()
602        refDict['FF']['FF'] = np.zeros((len(refDict['RefList']),len(dat)))   
603    for iref,refl in enumerate(refDict['RefList']):
604        if 'NT' in calcControls[hfx+'histType']:
605            FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl[14])
606        fbs = np.array([0,0])
607        H = refl[:3]
608        SQ = 1./(2.*refl[4])**2
609        SQfactor = 4.0*SQ*twopisq
610        Bab = parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor)
611        if not np.any(refDict['FF']['FF'][iref]):                #no form factors - 1st time thru StructureFactor
612            if 'N' in calcControls[hfx+'histType']:
613                dat = G2el.getBLvalues(BLtables)
614                refDict['FF']['FF'][iref] = dat.values()
615            else:       #'X'
616                dat = G2el.getFFvalues(FFtables,SQ)
617                refDict['FF']['FF'][iref] = dat.values()
618        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
619        FF = refDict['FF']['FF'][iref][Tindx]
620        Uniq = np.inner(H,SGMT)
621        Phi = np.inner(H,SGT)
622        phase = twopi*(np.inner(Uniq,(dXdata.T+Xdata.T))+Phi[:,np.newaxis])
623        sinp = np.sin(phase)
624        cosp = np.cos(phase)
625        biso = -SQfactor*Uisodata
626        Tiso = np.where(biso<1.,np.exp(biso),1.0)
627        HbH = np.array([-np.inner(h,np.inner(bij,h)) for h in Uniq])
628        Tuij = np.where(HbH<1.,np.exp(HbH),1.0)
629        Tcorr = Tiso*Tuij*Mdata*Fdata/len(Uniq)
630        fa = np.array([(FF+FP-Bab)*cosp*Tcorr,-FPP*sinp*Tcorr])
631        fas = np.sum(np.sum(fa,axis=1),axis=1)        #real
632        if not SGData['SGInv']:
633            fb = np.array([(FF+FP-Bab)*sinp*Tcorr,FPP*cosp*Tcorr])
634            fbs = np.sum(np.sum(fb,axis=1),axis=1)
635        fasq = fas**2
636        fbsq = fbs**2        #imaginary
637        refl[9] = np.sum(fasq)+np.sum(fbsq)
638        refl[10] = atan2d(fbs[0],fas[0])
639   
640def SStructureFactor(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict):
641    '''
642    Compute super structure factors for all h,k,l,m for phase
643    puts the result, F^2, in each ref[8+im] in refList
644    input:
645   
646    :param dict refDict: where
647        'RefList' list where each ref = h,k,l,m,d,...
648        'FF' dict of form factors - filed in below
649    :param np.array G:      reciprocal metric tensor
650    :param str pfx:    phase id string
651    :param dict SGData: space group info. dictionary output from SpcGroup
652    :param dict calcControls:
653    :param dict ParmDict:
654
655    '''       
656    phfx = pfx.split(':')[0]+hfx
657    ast = np.sqrt(np.diag(G))
658    Mast = twopisq*np.multiply.outer(ast,ast)
659    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
660    SGT = np.array([ops[1] for ops in SGData['SGOps']])
661    SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
662    SSGT = np.array([ops[1] for ops in SSGData['SSGOps']])
663    FFtables = calcControls['FFtables']
664    BLtables = calcControls['BLtables']
665    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
666    waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict)
667    FF = np.zeros(len(Tdata))
668    if 'NC' in calcControls[hfx+'histType']:
669        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
670    else:
671        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
672        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
673    Uij = np.array(G2lat.U6toUij(Uijdata))
674    bij = Mast*Uij.T
675    if not len(refDict['FF']):
676        if 'N' in calcControls[hfx+'histType']:
677            dat = G2el.getBLvalues(BLtables)        #will need wave here for anom. neutron b's
678        else:
679            dat = G2el.getFFvalues(FFtables,0.)       
680        refDict['FF']['El'] = dat.keys()
681        refDict['FF']['FF'] = np.zeros((len(refDict['RefList']),len(dat)))   
682    for iref,refl in enumerate(refDict['RefList']):
683        if 'NT' in calcControls[hfx+'histType']:
684            FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl[14+im])
685        fbs = np.array([0,0])
686        H = refl[:4]
687        SQ = 1./(2.*refl[4+im])**2
688        SQfactor = 4.0*SQ*twopisq
689        Bab = parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor)
690        if not np.any(refDict['FF']['FF'][iref]):                #no form factors - 1st time thru StructureFactor
691            if 'N' in calcControls[hfx+'histType']:
692                dat = G2el.getBLvalues(BLtables)
693                refDict['FF']['FF'][iref] = dat.values()
694            else:       #'X'
695                dat = G2el.getFFvalues(FFtables,SQ)
696                refDict['FF']['FF'][iref] = dat.values()
697        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
698        FF = refDict['FF']['FF'][iref][Tindx]
699        Uniq = np.inner(H[:3],SGMT)
700        SSUniq = np.inner(H,SSGMT)
701        Phi = np.inner(H[:3],SGT)
702        SSPhi = np.inner(H,SSGT)
703        GfpuA,GfpuB = G2mth.Modulation(waveTypes,SSUniq,SSPhi,FSSdata,XSSdata,USSdata)       
704        phase = twopi*(np.inner(Uniq,(dXdata.T+Xdata.T))+Phi[:,np.newaxis])
705        sinp = np.sin(phase)
706        cosp = np.cos(phase)
707        biso = -SQfactor*Uisodata
708        Tiso = np.where(biso<1.,np.exp(biso),1.0)
709        HbH = np.array([-np.inner(h,np.inner(bij,h)) for h in Uniq])
710        Tuij = np.where(HbH<1.,np.exp(HbH),1.0)
711        Tcorr = Tiso*Tuij*Mdata*Fdata/len(Uniq)
712        fa = np.array([(FF+FP-Bab)*cosp*Tcorr,-FPP*sinp*Tcorr])
713        fb = np.zeros_like(fa)
714        if not SGData['SGInv']:
715            fb = np.array([(FF+FP-Bab)*sinp*Tcorr,FPP*cosp*Tcorr])
716        fa = fa*GfpuA-fb*GfpuB
717        fb = fb*GfpuA+fa*GfpuB
718        fas = np.real(np.sum(np.sum(fa,axis=1),axis=1))        #real
719        fbs = np.real(np.sum(np.sum(fb,axis=1),axis=1))
720           
721        fasq = fas**2
722        fbsq = fbs**2        #imaginary
723        refl[9+im] = np.sum(fasq)+np.sum(fbsq)
724        refl[10+im] = atan2d(fbs[0],fas[0])
725   
726def StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict):
727    ''' Compute structure factors for all h,k,l for phase
728    puts the result, F^2, in each ref[8] in refList
729    input:
730   
731    :param dict refDict: where
732        'RefList' list where each ref = h,k,l,m,d,...
733        'FF' dict of form factors - filed in below
734    :param np.array G:      reciprocal metric tensor
735    :param str pfx:    phase id string
736    :param dict SGData: space group info. dictionary output from SpcGroup
737    :param dict calcControls:
738    :param dict ParmDict:
739
740    '''       
741    phfx = pfx.split(':')[0]+hfx
742    ast = np.sqrt(np.diag(G))
743    Mast = twopisq*np.multiply.outer(ast,ast)
744    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
745    SGT = np.array([ops[1] for ops in SGData['SGOps']])
746    FFtables = calcControls['FFtables']
747    BLtables = calcControls['BLtables']
748    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
749    FF = np.zeros(len(Tdata))
750    if 'NC' in calcControls[hfx+'histType']:
751        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
752    elif 'X' in calcControls[hfx+'histType']:
753        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
754        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
755    Uij = np.array(G2lat.U6toUij(Uijdata))
756    bij = Mast*Uij.T
757    blkSize = 100       #no. of reflections in a block
758    nRef = refDict['RefList'].shape[0]
759    if not len(refDict['FF']):                #no form factors - 1st time thru StructureFactor
760        if 'N' in calcControls[hfx+'histType']:
761            dat = G2el.getBLvalues(BLtables)
762            refDict['FF']['El'] = dat.keys()
763            refDict['FF']['FF'] = np.ones((nRef,len(dat)))*dat.values()           
764        else:       #'X'
765            dat = G2el.getFFvalues(FFtables,0.)
766            refDict['FF']['El'] = dat.keys()
767            refDict['FF']['FF'] = np.ones((nRef,len(dat)))
768            for iref,ref in enumerate(refDict['RefList']):
769                SQ = 1./(2.*ref[4])**2
770                dat = G2el.getFFvalues(FFtables,SQ)
771                refDict['FF']['FF'][iref] *= dat.values()
772#reflection processing begins here - big arrays!
773    iBeg = 0           
774    while iBeg < nRef:
775        iFin = min(iBeg+blkSize,nRef)
776        refl = refDict['RefList'][iBeg:iFin]
777        H = refl.T[:3]
778        SQ = 1./(2.*refl.T[4])**2
779        SQfactor = 4.0*SQ*twopisq
780        if 'T' in calcControls[hfx+'histType']:
781            if 'P' in calcControls[hfx+'histType']:
782                FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[14])
783            else:
784                FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[12])
785            FP = np.repeat(FP.T,len(SGT),axis=0)
786            FPP = np.repeat(FPP.T,len(SGT),axis=0)
787        Bab = np.repeat(parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor),len(SGT))
788        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
789        FF = np.repeat(refDict['FF']['FF'][iBeg:iFin].T[Tindx].T,len(SGT),axis=0)
790        Uniq = np.reshape(np.inner(H.T,SGMT),(-1,3))
791        Phi = np.inner(H.T,SGT).flatten()
792        phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T)+Phi[:,np.newaxis])
793        sinp = np.sin(phase)
794        cosp = np.cos(phase)
795        biso = -SQfactor*Uisodata[:,np.newaxis]
796        Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT),axis=1).T
797        HbH = -np.sum(Uniq.T*np.inner(bij,Uniq),axis=1)
798        Tuij = np.where(HbH<1.,np.exp(HbH),1.0).T
799        Tcorr = Tiso*Tuij*Mdata*Fdata/len(SGMT)
800        fa = np.array([((FF+FP).T-Bab).T*cosp*Tcorr,-FPP*sinp*Tcorr])
801        fa = np.reshape(fa,(2,len(refl),len(SGT),len(Mdata)))
802        fas = np.sum(np.sum(fa,axis=2),axis=2)        #real
803        fbs = np.zeros_like(fas)
804        if not SGData['SGInv']:
805            fb = np.array([((FF+FP).T-Bab).T*sinp*Tcorr,FPP*cosp*Tcorr])
806            fb = np.reshape(fb,(2,len(refl),len(SGT),len(Mdata)))
807            fbs = np.sum(np.sum(fb,axis=2),axis=2)
808        fasq = fas**2
809        fbsq = fbs**2        #imaginary
810        refl.T[9] = np.sum(fasq,axis=0)+np.sum(fbsq,axis=0)
811        refl.T[10] = atan2d(fbs[0],fas[0])
812        iBeg += blkSize
813   
814def StructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict):
815    'Needs a doc string'
816    phfx = pfx.split(':')[0]+hfx
817    ast = np.sqrt(np.diag(G))
818    Mast = twopisq*np.multiply.outer(ast,ast)
819    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
820    SGT = np.array([ops[1] for ops in SGData['SGOps']])
821    FFtables = calcControls['FFtables']
822    BLtables = calcControls['BLtables']
823    nRef = len(refDict['RefList'])
824    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
825    mSize = len(Mdata)
826    FF = np.zeros(len(Tdata))
827    if 'NC' in calcControls[hfx+'histType']:
828        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
829    elif 'X' in calcControls[hfx+'histType']:
830        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
831        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
832    Uij = np.array(G2lat.U6toUij(Uijdata))
833    bij = Mast*Uij.T
834    dFdvDict = {}
835    dFdfr = np.zeros((nRef,mSize))
836    dFdx = np.zeros((nRef,mSize,3))
837    dFdui = np.zeros((nRef,mSize))
838    dFdua = np.zeros((nRef,mSize,6))
839    dFdbab = np.zeros((nRef,2))
840    for iref,refl in enumerate(refDict['RefList']):
841        if 'T' in calcControls[hfx+'histType']:
842            FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl.T[12])
843        H = np.array(refl[:3])
844        SQ = 1./(2.*refl[4])**2             # or (sin(theta)/lambda)**2
845        SQfactor = 8.0*SQ*np.pi**2
846        dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor)
847        Bab = parmDict[phfx+'BabA']*dBabdA
848        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
849        FF = refDict['FF']['FF'][iref].T[Tindx]
850        Uniq = np.inner(H,SGMT)
851        Phi = np.inner(H,SGT)
852        phase = twopi*(np.inner((dXdata.T+Xdata.T),Uniq)+Phi[np.newaxis,:])
853        sinp = np.sin(phase)
854        cosp = np.cos(phase)
855        occ = Mdata*Fdata/len(Uniq)
856        biso = -SQfactor*Uisodata
857        Tiso = np.where(biso<1.,np.exp(biso),1.0)
858        HbH = -np.inner(H,np.inner(bij,H))
859        Hij = np.array([Mast*np.multiply.outer(U,U) for U in Uniq])
860        Hij = np.array([G2lat.UijtoU6(Uij) for Uij in Hij])
861        Tuij = np.where(HbH<1.,np.exp(HbH),1.0)
862        Tcorr = Tiso*Tuij
863        fot = (FF+FP-Bab)*occ*Tcorr
864        fotp = FPP*occ*Tcorr
865        fa = np.array([fot[:,np.newaxis]*cosp,fotp[:,np.newaxis]*cosp])       #non positions
866        fb = np.array([fot[:,np.newaxis]*sinp,-fotp[:,np.newaxis]*sinp])
867       
868        fas = np.sum(np.sum(fa,axis=1),axis=1)
869        fbs = np.sum(np.sum(fb,axis=1),axis=1)
870        fax = np.array([-fot[:,np.newaxis]*sinp,-fotp[:,np.newaxis]*sinp])   #positions
871        fbx = np.array([fot[:,np.newaxis]*cosp,-fot[:,np.newaxis]*cosp])
872        #sum below is over Uniq
873        dfadfr = np.sum(fa/occ[:,np.newaxis],axis=2)        #Fdata != 0 ever avoids /0. problem
874        dfadx = np.sum(twopi*Uniq*fax[:,:,:,np.newaxis],axis=2)
875        dfadui = np.sum(-SQfactor*fa,axis=2)
876        dfadua = np.sum(-Hij*fa[:,:,:,np.newaxis],axis=2)
877        dfadba = np.sum(-cosp*(occ*Tcorr)[:,np.newaxis],axis=1)
878        #NB: the above have been checked against PA(1:10,1:2) in strfctr.for for al2O3!   
879        dFdfr[iref] = 2.*(fas[0]*dfadfr[0]+fas[1]*dfadfr[1])*Mdata/len(Uniq)
880        dFdx[iref] = 2.*(fas[0]*dfadx[0]+fas[1]*dfadx[1])
881        dFdui[iref] = 2.*(fas[0]*dfadui[0]+fas[1]*dfadui[1])
882        dFdua[iref] = 2.*(fas[0]*dfadua[0]+fas[1]*dfadua[1])
883        dFdbab[iref] = 2.*fas[0]*np.array([np.sum(dfadba*dBabdA),np.sum(-dfadba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T
884        if not SGData['SGInv']:
885            dfbdfr = np.sum(fb/occ[:,np.newaxis],axis=2)        #Fdata != 0 ever avoids /0. problem
886            dfbdx = np.sum(twopi*Uniq*fbx[:,:,:,np.newaxis],axis=2)           
887            dfbdui = np.sum(-SQfactor*fb,axis=2)
888            dfbdua = np.sum(-Hij*fb[:,:,:,np.newaxis],axis=2)
889            dfbdba = np.sum(-sinp*(occ*Tcorr)[:,np.newaxis],axis=1)
890            dFdfr[iref] += 2.*(fbs[0]*dfbdfr[0]-fbs[1]*dfbdfr[1])*Mdata/len(Uniq)
891            dFdx[iref] += 2.*(fbs[0]*dfbdx[0]+fbs[1]*dfbdx[1])
892            dFdui[iref] += 2.*(fbs[0]*dfbdui[0]-fbs[1]*dfbdui[1])
893            dFdua[iref] += 2.*(fbs[0]*dfbdua[0]+fbs[1]*dfbdua[1])
894            dFdbab[iref] += 2.*fbs[0]*np.array([np.sum(dfbdba*dBabdA),np.sum(-dfbdba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T
895        #loop over atoms - each dict entry is list of derivatives for all the reflections
896    for i in range(len(Mdata)):     
897        dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i]
898        dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i]
899        dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i]
900        dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i]
901        dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i]
902        dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i]
903        dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i]
904        dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i]
905        dFdvDict[pfx+'AU12:'+str(i)] = 2.*dFdua.T[3][i]
906        dFdvDict[pfx+'AU13:'+str(i)] = 2.*dFdua.T[4][i]
907        dFdvDict[pfx+'AU23:'+str(i)] = 2.*dFdua.T[5][i]
908    dFdvDict[pfx+'BabA'] = dFdbab.T[0]
909    dFdvDict[pfx+'BabU'] = dFdbab.T[1]
910    return dFdvDict
911   
912def SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict):
913    'Needs a doc string'
914    phfx = pfx.split(':')[0]+hfx
915    ast = np.sqrt(np.diag(G))
916    Mast = twopisq*np.multiply.outer(ast,ast)
917    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
918    SGT = np.array([ops[1] for ops in SGData['SGOps']])
919    SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
920    SSGT = np.array([ops[1] for ops in SSGData['SSGOps']])
921    FFtables = calcControls['FFtables']
922    BLtables = calcControls['BLtables']
923    nRef = len(refDict['RefList'])
924    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
925    waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict)
926    mSize = len(Mdata)
927    FF = np.zeros(len(Tdata))
928    if 'NC' in calcControls[hfx+'histType']:
929        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
930    elif 'X' in calcControls[hfx+'histType']:
931        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
932        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
933    Uij = np.array(G2lat.U6toUij(Uijdata))
934    bij = Mast*Uij.T
935    dFdvDict = {}
936    dFdfr = np.zeros((nRef,mSize))
937    dFdx = np.zeros((nRef,mSize,3))
938    dFdui = np.zeros((nRef,mSize))
939    dFdua = np.zeros((nRef,mSize,6))
940    dFdbab = np.zeros((nRef,2))
941    for iref,refl in enumerate(refDict['RefList']):
942        if 'T' in calcControls[hfx+'histType']:
943            FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl.T[12+im])
944        H = np.array(refl[:4])
945        SQ = 1./(2.*refl[4+im])**2             # or (sin(theta)/lambda)**2
946        SQfactor = 8.0*SQ*np.pi**2
947        dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor)
948        Bab = parmDict[phfx+'BabA']*dBabdA
949        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
950        FF = refDict['FF']['FF'][iref].T[Tindx]
951        Uniq = np.inner(H[:3],SGMT)
952        SSUniq = np.inner(H,SSGMT)
953        Phi = np.inner(H[:3],SGT)
954        SSPhi = np.inner(H,SSGT)
955        GfpuA,GfpuB = G2mth.Modulation(waveTypes,SSUniq,SSPhi,FSSdata,XSSdata,USSdata)
956        dGAdk,dGBdk = G2mth.ModulationDerv(waveTypes,SSUniq,SSPhi,FSSdata,XSSdata,USSdata)
957        #need ModulationDerv here dGAdXsin, etc 
958        phase = twopi*(np.inner((dXdata.T+Xdata.T),Uniq)+Phi[np.newaxis,:])
959        sinp = np.sin(phase)
960        cosp = np.cos(phase)
961        occ = Mdata*Fdata/len(Uniq)
962        biso = -SQfactor*Uisodata
963        Tiso = np.where(biso<1.,np.exp(biso),1.0)
964        HbH = -np.inner(H[:3],np.inner(bij,H[:3]))
965        Hij = np.array([Mast*np.multiply.outer(U,U) for U in Uniq])
966        Hij = np.array([G2lat.UijtoU6(Uij) for Uij in Hij])
967        Tuij = np.where(HbH<1.,np.exp(HbH),1.0)
968        Tcorr = Tiso*Tuij
969        fot = (FF+FP-Bab)*occ*Tcorr
970        fotp = FPP*occ*Tcorr
971        fa = np.array([fot[:,np.newaxis]*cosp,fotp[:,np.newaxis]*cosp])       #non positions
972        fb = np.array([fot[:,np.newaxis]*sinp,-fotp[:,np.newaxis]*sinp])
973        GfpuA = np.swapaxes(GfpuA,1,2)
974        GfpuB = np.swapaxes(GfpuB,1,2)
975        fa = fa*GfpuA-fb*GfpuB
976        fb = fb*GfpuA+fa*GfpuB
977       
978        fas = np.sum(np.sum(fa,axis=1),axis=1)
979        fbs = np.sum(np.sum(fb,axis=1),axis=1)
980        fax = np.array([-fot[:,np.newaxis]*sinp,-fotp[:,np.newaxis]*sinp])   #positions
981        fbx = np.array([fot[:,np.newaxis]*cosp,-fot[:,np.newaxis]*cosp])
982        fax = fax*GfpuA-fbx*GfpuB
983        fbx = fbx*GfpuA+fax*GfpuB
984        #sum below is over Uniq
985        dfadfr = np.sum(fa/occ[:,np.newaxis],axis=2)        #Fdata != 0 ever avoids /0. problem
986        dfadx = np.sum(twopi*Uniq*fax[:,:,:,np.newaxis],axis=2)
987        dfadui = np.sum(-SQfactor*fa,axis=2)
988        dfadua = np.sum(-Hij*fa[:,:,:,np.newaxis],axis=2)
989        dfadba = np.sum(-cosp*(occ*Tcorr)[:,np.newaxis],axis=1)
990        #NB: the above have been checked against PA(1:10,1:2) in strfctr.for for al2O3!   
991        dFdfr[iref] = 2.*(fas[0]*dfadfr[0]+fas[1]*dfadfr[1])*Mdata/len(Uniq)
992        dFdx[iref] = 2.*(fas[0]*dfadx[0]+fas[1]*dfadx[1])
993        dFdui[iref] = 2.*(fas[0]*dfadui[0]+fas[1]*dfadui[1])
994        dFdua[iref] = 2.*(fas[0]*dfadua[0]+fas[1]*dfadua[1])
995        dFdbab[iref] = 2.*fas[0]*np.array([np.sum(dfadba*dBabdA),np.sum(-dfadba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T
996        #need dFdXsin, etc for modulations...
997        if not SGData['SGInv']:
998            dfbdfr = np.sum(fb/occ[:,np.newaxis],axis=2)        #Fdata != 0 ever avoids /0. problem
999            dfbdx = np.sum(twopi*Uniq*fbx[:,:,:,np.newaxis],axis=2)           
1000            dfbdui = np.sum(-SQfactor*fb,axis=2)
1001            dfbdua = np.sum(-Hij*fb[:,:,:,np.newaxis],axis=2)
1002            dfbdba = np.sum(-sinp*(occ*Tcorr)[:,np.newaxis],axis=1)
1003            dFdfr[iref] += 2.*(fbs[0]*dfbdfr[0]-fbs[1]*dfbdfr[1])*Mdata/len(Uniq)
1004            dFdx[iref] += 2.*(fbs[0]*dfbdx[0]+fbs[1]*dfbdx[1])
1005            dFdui[iref] += 2.*(fbs[0]*dfbdui[0]-fbs[1]*dfbdui[1])
1006            dFdua[iref] += 2.*(fbs[0]*dfbdua[0]+fbs[1]*dfbdua[1])
1007            dFdbab[iref] += 2.*fbs[0]*np.array([np.sum(dfbdba*dBabdA),np.sum(-dfbdba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T
1008        #need dFdXsin, etc for modulations...
1009        #loop over atoms - each dict entry is list of derivatives for all the reflections
1010    for i in range(len(Mdata)):     
1011        dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i]
1012        dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i]
1013        dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i]
1014        dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i]
1015        dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i]
1016        dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i]
1017        dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i]
1018        dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i]
1019        dFdvDict[pfx+'AU12:'+str(i)] = 2.*dFdua.T[3][i]
1020        dFdvDict[pfx+'AU13:'+str(i)] = 2.*dFdua.T[4][i]
1021        dFdvDict[pfx+'AU23:'+str(i)] = 2.*dFdua.T[5][i]
1022        #need dFdvDict[pfx+'Xsin:'+str[i]:str(m)], etc for modulations...
1023    dFdvDict[pfx+'BabA'] = dFdbab.T[0]
1024    dFdvDict[pfx+'BabU'] = dFdbab.T[1]
1025    return dFdvDict
1026   
1027def SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varyList):
1028    ''' Single crystal extinction function; returns extinction & derivative
1029    '''
1030    extCor = 1.0
1031    dervDict = {}
1032    if calcControls[phfx+'EType'] != 'None':
1033        SQ = 1/(4.*ref[4+im]**2)
1034        if 'C' in parmDict[hfx+'Type']:           
1035            cos2T = 1.0-2.*SQ*parmDict[hfx+'Lam']**2           #cos(2theta)
1036        else:   #'T'
1037            cos2T = 1.0-2.*SQ*ref[12+im]**2                       #cos(2theta)           
1038        if 'SXC' in parmDict[hfx+'Type']:
1039            AV = 7.9406e5/parmDict[pfx+'Vol']**2
1040            PL = np.sqrt(1.0-cos2T**2)/parmDict[hfx+'Lam']
1041            P12 = (calcControls[phfx+'Cos2TM']+cos2T**4)/(calcControls[phfx+'Cos2TM']+cos2T**2)
1042            PLZ = AV*P12*ref[7+im]*parmDict[hfx+'Lam']**2
1043        elif 'SNT' in parmDict[hfx+'Type']:
1044            AV = 1.e7/parmDict[pfx+'Vol']**2
1045            PL = SQ
1046            PLZ = AV*ref[7+im]*ref[12+im]**2
1047        elif 'SNC' in parmDict[hfx+'Type']:
1048            AV = 1.e7/parmDict[pfx+'Vol']**2
1049            PL = np.sqrt(1.0-cos2T**2)/parmDict[hfx+'Lam']
1050            PLZ = AV*ref[9]*parmDict[hfx+'Lam']**2      #Fcsq as per GSAS, why not FcTsq (ref[9])?
1051           
1052        if 'Primary' in calcControls[phfx+'EType']:
1053            PLZ *= 1.5
1054        else:
1055            if 'C' in parmDict[hfx+'Type']:
1056                PLZ *= calcControls[phfx+'Tbar']
1057            else: #'T'
1058                PLZ *= ref[13+im]      #t-bar
1059        if 'Primary' in calcControls[phfx+'EType']:
1060            PLZ *= 1.5
1061            PSIG = parmDict[phfx+'Ep']
1062        elif 'I & II' in calcControls[phfx+'EType']:
1063            PSIG = parmDict[phfx+'Eg']/np.sqrt(1.+(parmDict[phfx+'Es']*PL/parmDict[phfx+'Eg'])**2)
1064        elif 'Type II' in calcControls[phfx+'EType']:
1065            PSIG = parmDict[phfx+'Es']
1066        else:       # 'Secondary Type I'
1067            PSIG = parmDict[phfx+'Eg']/PL
1068           
1069        AG = 0.58+0.48*cos2T+0.24*cos2T**2
1070        AL = 0.025+0.285*cos2T
1071        BG = 0.02-0.025*cos2T
1072        BL = 0.15-0.2*(0.75-cos2T)**2
1073        if cos2T < 0.:
1074            BL = -0.45*cos2T
1075        CG = 2.
1076        CL = 2.
1077        PF = PLZ*PSIG
1078       
1079        if 'Gaussian' in calcControls[phfx+'EApprox']:
1080            PF4 = 1.+CG*PF+AG*PF**2/(1.+BG*PF)
1081            extCor = np.sqrt(PF4)
1082            PF3 = 0.5*(CG+2.*AG*PF/(1.+BG*PF)-AG*PF**2*BG/(1.+BG*PF)**2)/(PF4*extCor)
1083        else:
1084            PF4 = 1.+CL*PF+AL*PF**2/(1.+BL*PF)
1085            extCor = np.sqrt(PF4)
1086            PF3 = 0.5*(CL+2.*AL*PF/(1.+BL*PF)-AL*PF**2*BL/(1.+BL*PF)**2)/(PF4*extCor)
1087
1088        if 'Primary' in calcControls[phfx+'EType'] and phfx+'Ep' in varyList:
1089            dervDict[phfx+'Ep'] = -ref[7+im]*PLZ*PF3
1090        if 'II' in calcControls[phfx+'EType'] and phfx+'Es' in varyList:
1091            dervDict[phfx+'Es'] = -ref[7+im]*PLZ*PF3*(PSIG/parmDict[phfx+'Es'])**3
1092        if 'I' in calcControls[phfx+'EType'] and phfx+'Eg' in varyList:
1093            dervDict[phfx+'Eg'] = -ref[7+im]*PLZ*PF3*(PSIG/parmDict[phfx+'Eg'])**3*PL**2
1094               
1095    return 1./extCor,dervDict
1096   
1097def Dict2Values(parmdict, varylist):
1098    '''Use before call to leastsq to setup list of values for the parameters
1099    in parmdict, as selected by key in varylist'''
1100    return [parmdict[key] for key in varylist] 
1101   
1102def Values2Dict(parmdict, varylist, values):
1103    ''' Use after call to leastsq to update the parameter dictionary with
1104    values corresponding to keys in varylist'''
1105    parmdict.update(zip(varylist,values))
1106   
1107def GetNewCellParms(parmDict,varyList):
1108    'Needs a doc string'
1109    newCellDict = {}
1110    Anames = ['A'+str(i) for i in range(6)]
1111    Ddict = dict(zip(['D11','D22','D33','D12','D13','D23'],Anames))
1112    for item in varyList:
1113        keys = item.split(':')
1114        if keys[2] in Ddict:
1115            key = keys[0]+'::'+Ddict[keys[2]]       #key is e.g. '0::A0'
1116            parm = keys[0]+'::'+keys[2]             #parm is e.g. '0::D11'
1117            newCellDict[parm] = [key,parmDict[key]+parmDict[item]]
1118    return newCellDict          # is e.g. {'0::D11':A0-D11}
1119   
1120def ApplyXYZshifts(parmDict,varyList):
1121    '''
1122    takes atom x,y,z shift and applies it to corresponding atom x,y,z value
1123   
1124    :param dict parmDict: parameter dictionary
1125    :param list varyList: list of variables (not used!)
1126    :returns: newAtomDict - dictionary of new atomic coordinate names & values; key is parameter shift name
1127
1128    '''
1129    newAtomDict = {}
1130    for item in parmDict:
1131        if 'dA' in item:
1132            parm = ''.join(item.split('d'))
1133            parmDict[parm] += parmDict[item]
1134            newAtomDict[item] = [parm,parmDict[parm]]
1135    return newAtomDict
1136   
1137def SHTXcal(refl,im,g,pfx,hfx,SGData,calcControls,parmDict):
1138    'Spherical harmonics texture'
1139    IFCoup = 'Bragg' in calcControls[hfx+'instType']
1140    if 'T' in calcControls[hfx+'histType']:
1141        tth = parmDict[hfx+'2-theta']
1142    else:
1143        tth = refl[5+im]
1144    odfCor = 1.0
1145    H = refl[:3]
1146    cell = G2lat.Gmat2cell(g)
1147    Sangls = [parmDict[pfx+'SH omega'],parmDict[pfx+'SH chi'],parmDict[pfx+'SH phi']]
1148    Gangls = [parmDict[hfx+'Omega'],parmDict[hfx+'Chi'],parmDict[hfx+'Phi'],parmDict[hfx+'Azimuth']]
1149    phi,beta = G2lat.CrsAng(H,cell,SGData)
1150    psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) #ignore 2 sets of angle derivs.
1151    SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],parmDict[pfx+'SHmodel'],parmDict[pfx+'SHorder'])
1152    for item in SHnames:
1153        L,M,N = eval(item.strip('C'))
1154        Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta)
1155        Ksl,x,x = G2lat.GetKsl(L,M,parmDict[pfx+'SHmodel'],psi,gam)
1156        Lnorm = G2lat.Lnorm(L)
1157        odfCor += parmDict[pfx+item]*Lnorm*Kcl*Ksl
1158    return odfCor
1159   
1160def SHTXcalDerv(refl,im,g,pfx,hfx,SGData,calcControls,parmDict):
1161    'Spherical harmonics texture derivatives'
1162    if 'T' in calcControls[hfx+'histType']:
1163        tth = parmDict[hfx+'2-theta']
1164    else:
1165        tth = refl[5+im]
1166    FORPI = 4.0*np.pi
1167    IFCoup = 'Bragg' in calcControls[hfx+'instType']
1168    odfCor = 1.0
1169    dFdODF = {}
1170    dFdSA = [0,0,0]
1171    H = refl[:3]
1172    cell = G2lat.Gmat2cell(g)
1173    Sangls = [parmDict[pfx+'SH omega'],parmDict[pfx+'SH chi'],parmDict[pfx+'SH phi']]
1174    Gangls = [parmDict[hfx+'Omega'],parmDict[hfx+'Chi'],parmDict[hfx+'Phi'],parmDict[hfx+'Azimuth']]
1175    phi,beta = G2lat.CrsAng(H,cell,SGData)
1176    psi,gam,dPSdA,dGMdA = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup)
1177    SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],parmDict[pfx+'SHmodel'],parmDict[pfx+'SHorder'])
1178    for item in SHnames:
1179        L,M,N = eval(item.strip('C'))
1180        Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta)
1181        Ksl,dKsdp,dKsdg = G2lat.GetKsl(L,M,parmDict[pfx+'SHmodel'],psi,gam)
1182        Lnorm = G2lat.Lnorm(L)
1183        odfCor += parmDict[pfx+item]*Lnorm*Kcl*Ksl
1184        dFdODF[pfx+item] = Lnorm*Kcl*Ksl
1185        for i in range(3):
1186            dFdSA[i] += parmDict[pfx+item]*Lnorm*Kcl*(dKsdp*dPSdA[i]+dKsdg*dGMdA[i])
1187    return odfCor,dFdODF,dFdSA
1188   
1189def SHPOcal(refl,im,g,phfx,hfx,SGData,calcControls,parmDict):
1190    'spherical harmonics preferred orientation (cylindrical symmetry only)'
1191    if 'T' in calcControls[hfx+'histType']:
1192        tth = parmDict[hfx+'2-theta']
1193    else:
1194        tth = refl[5+im]
1195    odfCor = 1.0
1196    H = refl[:3]
1197    cell = G2lat.Gmat2cell(g)
1198    Sangl = [0.,0.,0.]
1199    if 'Bragg' in calcControls[hfx+'instType']:
1200        Gangls = [0.,90.,0.,parmDict[hfx+'Azimuth']]
1201        IFCoup = True
1202    else:
1203        Gangls = [0.,0.,0.,parmDict[hfx+'Azimuth']]
1204        IFCoup = False
1205    phi,beta = G2lat.CrsAng(H,cell,SGData)
1206    psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangl,IFCoup) #ignore 2 sets of angle derivs.
1207    SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',calcControls[phfx+'SHord'],False)
1208    for item in SHnames:
1209        L,N = eval(item.strip('C'))
1210        Kcsl,Lnorm = G2lat.GetKclKsl(L,N,SGData['SGLaue'],psi,phi,beta)
1211        odfCor += parmDict[phfx+item]*Lnorm*Kcsl
1212    return np.squeeze(odfCor)
1213   
1214def SHPOcalDerv(refl,im,g,phfx,hfx,SGData,calcControls,parmDict):
1215    'spherical harmonics preferred orientation derivatives (cylindrical symmetry only)'
1216    if 'T' in calcControls[hfx+'histType']:
1217        tth = parmDict[hfx+'2-theta']
1218    else:
1219        tth = refl[5+im]
1220    FORPI = 12.5663706143592
1221    odfCor = 1.0
1222    dFdODF = {}
1223    H = refl[:3]
1224    cell = G2lat.Gmat2cell(g)
1225    Sangl = [0.,0.,0.]
1226    if 'Bragg' in calcControls[hfx+'instType']:
1227        Gangls = [0.,90.,0.,parmDict[hfx+'Azimuth']]
1228        IFCoup = True
1229    else:
1230        Gangls = [0.,0.,0.,parmDict[hfx+'Azimuth']]
1231        IFCoup = False
1232    phi,beta = G2lat.CrsAng(H,cell,SGData)
1233    psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangl,IFCoup) #ignore 2 sets of angle derivs.
1234    SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',calcControls[phfx+'SHord'],False)
1235    for item in SHnames:
1236        L,N = eval(item.strip('C'))
1237        Kcsl,Lnorm = G2lat.GetKclKsl(L,N,SGData['SGLaue'],psi,phi,beta) 
1238        odfCor += parmDict[phfx+item]*Lnorm*Kcsl
1239        dFdODF[phfx+item] = Kcsl*Lnorm
1240    return odfCor,dFdODF
1241   
1242def GetPrefOri(uniq,G,g,phfx,hfx,SGData,calcControls,parmDict):
1243    'March-Dollase preferred orientation correction'
1244    POcorr = 1.0
1245    MD = parmDict[phfx+'MD']
1246    if MD != 1.0:
1247        MDAxis = calcControls[phfx+'MDAxis']
1248        sumMD = 0
1249        for H in uniq:           
1250            cosP,sinP = G2lat.CosSinAngle(H,MDAxis,G)
1251            A = 1.0/np.sqrt((MD*cosP)**2+sinP**2/MD)
1252            sumMD += A**3
1253        POcorr = sumMD/len(uniq)
1254    return POcorr
1255   
1256def GetPrefOriDerv(refl,im,uniq,G,g,phfx,hfx,SGData,calcControls,parmDict):
1257    'Needs a doc string'
1258    POcorr = 1.0
1259    POderv = {}
1260    if calcControls[phfx+'poType'] == 'MD':
1261        MD = parmDict[phfx+'MD']
1262        MDAxis = calcControls[phfx+'MDAxis']
1263        sumMD = 0
1264        sumdMD = 0
1265        for H in uniq:           
1266            cosP,sinP = G2lat.CosSinAngle(H,MDAxis,G)
1267            A = 1.0/np.sqrt((MD*cosP)**2+sinP**2/MD)
1268            sumMD += A**3
1269            sumdMD -= (1.5*A**5)*(2.0*MD*cosP**2-(sinP/MD)**2)
1270        POcorr = sumMD/len(uniq)
1271        POderv[phfx+'MD'] = sumdMD/len(uniq)
1272    else:   #spherical harmonics
1273        if calcControls[phfx+'SHord']:
1274            POcorr,POderv = SHPOcalDerv(refl,im,g,phfx,hfx,SGData,calcControls,parmDict)
1275    return POcorr,POderv
1276   
1277def GetAbsorb(refl,im,hfx,calcControls,parmDict):
1278    'Needs a doc string'
1279    if 'Debye' in calcControls[hfx+'instType']:
1280        if 'T' in calcControls[hfx+'histType']:
1281            return G2pwd.Absorb('Cylinder',parmDict[hfx+'Absorption']*refl[14+im],parmDict[hfx+'2-theta'],0,0)
1282        else:
1283            return G2pwd.Absorb('Cylinder',parmDict[hfx+'Absorption'],refl[5+im],0,0)
1284    else:
1285        return G2pwd.SurfaceRough(parmDict[hfx+'SurfRoughA'],parmDict[hfx+'SurfRoughB'],refl[5+im])
1286   
1287def GetAbsorbDerv(refl,im,hfx,calcControls,parmDict):
1288    'Needs a doc string'
1289    if 'Debye' in calcControls[hfx+'instType']:
1290        if 'T' in calcControls[hfx+'histType']:
1291            return G2pwd.AbsorbDerv('Cylinder',parmDict[hfx+'Absorption']*refl[14+im],parmDict[hfx+'2-theta'],0,0)
1292        else:
1293            return G2pwd.AbsorbDerv('Cylinder',parmDict[hfx+'Absorption'],refl[5+im],0,0)
1294    else:
1295        return np.array(G2pwd.SurfaceRoughDerv(parmDict[hfx+'SurfRoughA'],parmDict[hfx+'SurfRoughB'],refl[5+im]))
1296       
1297def GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict):
1298    'Needs a doc string'
1299    coef = np.array([-0.5,0.25,-0.10416667,0.036458333,-0.0109375,2.8497409E-3])
1300    pi2 = np.sqrt(2./np.pi)
1301    if 'T' in calcControls[hfx+'histType']:
1302        sth2 = sind(parmDict[hfx+'2-theta']/2.)**2
1303        wave = refl[14+im]
1304    else:   #'C'W
1305        sth2 = sind(refl[5+im]/2.)**2
1306        wave = parmDict.get(hfx+'Lam',parmDict.get(hfx+'Lam1',1.0))
1307    c2th = 1.-2.0*sth2
1308    flv2 = refl[9+im]*(wave/parmDict[pfx+'Vol'])**2
1309    if 'X' in calcControls[hfx+'histType']:
1310        flv2 *= 0.079411*(1.0+c2th**2)/2.0
1311    xfac = flv2*parmDict[phfx+'Extinction']
1312    exb = 1.0
1313    if xfac > -1.:
1314        exb = 1./(1.+xfac)
1315    exl = 1.0
1316    if 0 < xfac <= 1.:
1317        xn = np.array([xfac**(i+1) for i in range(6)])
1318        exl = np.sum(xn*coef)
1319    elif xfac > 1.:
1320        xfac2 = 1./np.sqrt(xfac)
1321        exl = pi2*(1.-0.125/xfac)*xfac2
1322    return exb*sth2+exl*(1.-sth2)
1323   
1324def GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict):
1325    'Needs a doc string'
1326    delt = 0.001
1327    parmDict[phfx+'Extinction'] += delt
1328    plus = GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict)
1329    parmDict[phfx+'Extinction'] -= 2.*delt
1330    minus = GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict)
1331    parmDict[phfx+'Extinction'] += delt
1332    return (plus-minus)/(2.*delt)   
1333   
1334def GetIntensityCorr(refl,im,uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict):
1335    'Needs a doc string'    #need powder extinction!
1336    Icorr = parmDict[phfx+'Scale']*parmDict[hfx+'Scale']*refl[3+im]               #scale*multiplicity
1337    if 'X' in parmDict[hfx+'Type']:
1338        Icorr *= G2pwd.Polarization(parmDict[hfx+'Polariz.'],refl[5+im],parmDict[hfx+'Azimuth'])[0]
1339    POcorr = 1.0
1340    if pfx+'SHorder' in parmDict:                 #generalized spherical harmonics texture
1341        POcorr = SHTXcal(refl,im,g,pfx,hfx,SGData,calcControls,parmDict)
1342    elif calcControls[phfx+'poType'] == 'MD':         #March-Dollase
1343        POcorr = GetPrefOri(uniq,G,g,phfx,hfx,SGData,calcControls,parmDict)
1344    elif calcControls[phfx+'SHord']:                #cylindrical spherical harmonics
1345        POcorr = SHPOcal(refl,im,g,phfx,hfx,SGData,calcControls,parmDict)
1346    Icorr *= POcorr
1347    AbsCorr = 1.0
1348    AbsCorr = GetAbsorb(refl,im,hfx,calcControls,parmDict)
1349    Icorr *= AbsCorr
1350    ExtCorr = GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict)
1351    Icorr *= ExtCorr
1352    return Icorr,POcorr,AbsCorr,ExtCorr
1353   
1354def GetIntensityDerv(refl,im,wave,uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict):
1355    'Needs a doc string'    #need powder extinction derivs!
1356    dIdsh = 1./parmDict[hfx+'Scale']
1357    dIdsp = 1./parmDict[phfx+'Scale']
1358    if 'X' in parmDict[hfx+'Type']:
1359        pola,dIdPola = G2pwd.Polarization(parmDict[hfx+'Polariz.'],refl[5+im],parmDict[hfx+'Azimuth'])
1360        dIdPola /= pola
1361    else:       #'N'
1362        dIdPola = 0.0
1363    dFdODF = {}
1364    dFdSA = [0,0,0]
1365    dIdPO = {}
1366    if pfx+'SHorder' in parmDict:
1367        odfCor,dFdODF,dFdSA = SHTXcalDerv(refl,im,g,pfx,hfx,SGData,calcControls,parmDict)
1368        for iSH in dFdODF:
1369            dFdODF[iSH] /= odfCor
1370        for i in range(3):
1371            dFdSA[i] /= odfCor
1372    elif calcControls[phfx+'poType'] == 'MD' or calcControls[phfx+'SHord']:
1373        POcorr,dIdPO = GetPrefOriDerv(refl,im,uniq,G,g,phfx,hfx,SGData,calcControls,parmDict)       
1374        for iPO in dIdPO:
1375            dIdPO[iPO] /= POcorr
1376    if 'T' in parmDict[hfx+'Type']:
1377        dFdAb = GetAbsorbDerv(refl,im,hfx,calcControls,parmDict)*wave/refl[16+im] #wave/abs corr
1378        dFdEx = GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict)/refl[17+im]    #/ext corr
1379    else:
1380        dFdAb = GetAbsorbDerv(refl,im,hfx,calcControls,parmDict)*wave/refl[13+im] #wave/abs corr
1381        dFdEx = GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict)/refl[14+im]    #/ext corr       
1382    return dIdsh,dIdsp,dIdPola,dIdPO,dFdODF,dFdSA,dFdAb,dFdEx
1383       
1384def GetSampleSigGam(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict):
1385    'Needs a doc string'
1386    if 'C' in calcControls[hfx+'histType']:     #All checked & OK
1387        costh = cosd(refl[5+im]/2.)
1388        #crystallite size
1389        if calcControls[phfx+'SizeType'] == 'isotropic':
1390            Sgam = 1.8*wave/(np.pi*parmDict[phfx+'Size;i']*costh)
1391        elif calcControls[phfx+'SizeType'] == 'uniaxial':
1392            H = np.array(refl[:3])
1393            P = np.array(calcControls[phfx+'SizeAxis'])
1394            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1395            Sgam = (1.8*wave/np.pi)/(parmDict[phfx+'Size;i']*parmDict[phfx+'Size;a']*costh)
1396            Sgam *= np.sqrt((sinP*parmDict[phfx+'Size;a'])**2+(cosP*parmDict[phfx+'Size;i'])**2)
1397        else:           #ellipsoidal crystallites
1398            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1399            H = np.array(refl[:3])
1400            lenR = G2pwd.ellipseSize(H,Sij,GB)
1401            Sgam = 1.8*wave/(np.pi*costh*lenR)
1402        #microstrain               
1403        if calcControls[phfx+'MustrainType'] == 'isotropic':
1404            Mgam = 0.018*parmDict[phfx+'Mustrain;i']*tand(refl[5+im]/2.)/np.pi
1405        elif calcControls[phfx+'MustrainType'] == 'uniaxial':
1406            H = np.array(refl[:3])
1407            P = np.array(calcControls[phfx+'MustrainAxis'])
1408            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1409            Si = parmDict[phfx+'Mustrain;i']
1410            Sa = parmDict[phfx+'Mustrain;a']
1411            Mgam = 0.018*Si*Sa*tand(refl[5+im]/2.)/(np.pi*np.sqrt((Si*cosP)**2+(Sa*sinP)**2))
1412        else:       #generalized - P.W. Stephens model
1413            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1414            Sum = 0
1415            for i,strm in enumerate(Strms):
1416                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1417            Mgam = 0.018*refl[4+im]**2*tand(refl[5+im]/2.)*np.sqrt(Sum)/np.pi
1418    elif 'T' in calcControls[hfx+'histType']:       #All checked & OK
1419        #crystallite size
1420        if calcControls[phfx+'SizeType'] == 'isotropic':    #OK
1421            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/parmDict[phfx+'Size;i']
1422        elif calcControls[phfx+'SizeType'] == 'uniaxial':   #OK
1423            H = np.array(refl[:3])
1424            P = np.array(calcControls[phfx+'SizeAxis'])
1425            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1426            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/(parmDict[phfx+'Size;i']*parmDict[phfx+'Size;a'])
1427            Sgam *= np.sqrt((sinP*parmDict[phfx+'Size;a'])**2+(cosP*parmDict[phfx+'Size;i'])**2)
1428        else:           #ellipsoidal crystallites   #OK
1429            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1430            H = np.array(refl[:3])
1431            lenR = G2pwd.ellipseSize(H,Sij,GB)
1432            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/lenR
1433        #microstrain               
1434        if calcControls[phfx+'MustrainType'] == 'isotropic':    #OK
1435            Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*parmDict[phfx+'Mustrain;i']
1436        elif calcControls[phfx+'MustrainType'] == 'uniaxial':   #OK
1437            H = np.array(refl[:3])
1438            P = np.array(calcControls[phfx+'MustrainAxis'])
1439            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1440            Si = parmDict[phfx+'Mustrain;i']
1441            Sa = parmDict[phfx+'Mustrain;a']
1442            Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*Si*Sa/np.sqrt((Si*cosP)**2+(Sa*sinP)**2)
1443        else:       #generalized - P.W. Stephens model  OK
1444            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1445            Sum = 0
1446            for i,strm in enumerate(Strms):
1447                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1448            Mgam = 1.e-6*parmDict[hfx+'difC']*np.sqrt(Sum)*refl[4+im]**3
1449           
1450    gam = Sgam*parmDict[phfx+'Size;mx']+Mgam*parmDict[phfx+'Mustrain;mx']
1451    sig = (Sgam*(1.-parmDict[phfx+'Size;mx']))**2+(Mgam*(1.-parmDict[phfx+'Mustrain;mx']))**2
1452    sig /= ateln2
1453    return sig,gam
1454       
1455def GetSampleSigGamDerv(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict):
1456    'Needs a doc string'
1457    gamDict = {}
1458    sigDict = {}
1459    if 'C' in calcControls[hfx+'histType']:         #All checked & OK
1460        costh = cosd(refl[5+im]/2.)
1461        tanth = tand(refl[5+im]/2.)
1462        #crystallite size derivatives
1463        if calcControls[phfx+'SizeType'] == 'isotropic':
1464            Sgam = 1.8*wave/(np.pi*parmDict[phfx+'Size;i']*costh)
1465            gamDict[phfx+'Size;i'] = -1.8*wave*parmDict[phfx+'Size;mx']/(np.pi*costh)
1466            sigDict[phfx+'Size;i'] = -3.6*Sgam*wave*(1.-parmDict[phfx+'Size;mx'])**2/(np.pi*costh*ateln2)
1467        elif calcControls[phfx+'SizeType'] == 'uniaxial':
1468            H = np.array(refl[:3])
1469            P = np.array(calcControls[phfx+'SizeAxis'])
1470            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1471            Si = parmDict[phfx+'Size;i']
1472            Sa = parmDict[phfx+'Size;a']
1473            gami = 1.8*wave/(costh*np.pi*Si*Sa)
1474            sqtrm = np.sqrt((sinP*Sa)**2+(cosP*Si)**2)
1475            Sgam = gami*sqtrm
1476            dsi = gami*Si*cosP**2/sqtrm-Sgam/Si
1477            dsa = gami*Sa*sinP**2/sqtrm-Sgam/Sa
1478            gamDict[phfx+'Size;i'] = dsi*parmDict[phfx+'Size;mx']
1479            gamDict[phfx+'Size;a'] = dsa*parmDict[phfx+'Size;mx']
1480            sigDict[phfx+'Size;i'] = 2.*dsi*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1481            sigDict[phfx+'Size;a'] = 2.*dsa*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1482        else:           #ellipsoidal crystallites
1483            const = 1.8*wave/(np.pi*costh)
1484            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1485            H = np.array(refl[:3])
1486            lenR,dRdS = G2pwd.ellipseSizeDerv(H,Sij,GB)
1487            Sgam = const/lenR
1488            for i,item in enumerate([phfx+'Size:%d'%(j) for j in range(6)]):
1489                gamDict[item] = -(const/lenR**2)*dRdS[i]*parmDict[phfx+'Size;mx']
1490                sigDict[item] = -2.*Sgam*(const/lenR**2)*dRdS[i]*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1491        gamDict[phfx+'Size;mx'] = Sgam
1492        sigDict[phfx+'Size;mx'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])/ateln2
1493               
1494        #microstrain derivatives               
1495        if calcControls[phfx+'MustrainType'] == 'isotropic':
1496            Mgam = 0.018*parmDict[phfx+'Mustrain;i']*tand(refl[5+im]/2.)/np.pi
1497            gamDict[phfx+'Mustrain;i'] =  0.018*tanth*parmDict[phfx+'Mustrain;mx']/np.pi
1498            sigDict[phfx+'Mustrain;i'] =  0.036*Mgam*tanth*(1.-parmDict[phfx+'Mustrain;mx'])**2/(np.pi*ateln2)       
1499        elif calcControls[phfx+'MustrainType'] == 'uniaxial':
1500            H = np.array(refl[:3])
1501            P = np.array(calcControls[phfx+'MustrainAxis'])
1502            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1503            Si = parmDict[phfx+'Mustrain;i']
1504            Sa = parmDict[phfx+'Mustrain;a']
1505            gami = 0.018*Si*Sa*tanth/np.pi
1506            sqtrm = np.sqrt((Si*cosP)**2+(Sa*sinP)**2)
1507            Mgam = gami/sqtrm
1508            dsi = -gami*Si*cosP**2/sqtrm**3
1509            dsa = -gami*Sa*sinP**2/sqtrm**3
1510            gamDict[phfx+'Mustrain;i'] = (Mgam/Si+dsi)*parmDict[phfx+'Mustrain;mx']
1511            gamDict[phfx+'Mustrain;a'] = (Mgam/Sa+dsa)*parmDict[phfx+'Mustrain;mx']
1512            sigDict[phfx+'Mustrain;i'] = 2*(Mgam/Si+dsi)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2
1513            sigDict[phfx+'Mustrain;a'] = 2*(Mgam/Sa+dsa)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2       
1514        else:       #generalized - P.W. Stephens model
1515            const = 0.018*refl[4+im]**2*tanth/np.pi
1516            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1517            Sum = 0
1518            for i,strm in enumerate(Strms):
1519                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1520                gamDict[phfx+'Mustrain:'+str(i)] = strm*parmDict[phfx+'Mustrain;mx']/2.
1521                sigDict[phfx+'Mustrain:'+str(i)] = strm*(1.-parmDict[phfx+'Mustrain;mx'])**2
1522            Mgam = const*np.sqrt(Sum)
1523            for i in range(len(Strms)):
1524                gamDict[phfx+'Mustrain:'+str(i)] *= Mgam/Sum
1525                sigDict[phfx+'Mustrain:'+str(i)] *= const**2/ateln2
1526        gamDict[phfx+'Mustrain;mx'] = Mgam
1527        sigDict[phfx+'Mustrain;mx'] = -2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])/ateln2
1528    else:   #'T'OF - All checked & OK
1529        if calcControls[phfx+'SizeType'] == 'isotropic':    #OK
1530            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/parmDict[phfx+'Size;i']
1531            gamDict[phfx+'Size;i'] = -Sgam*parmDict[phfx+'Size;mx']/parmDict[phfx+'Size;i']
1532            sigDict[phfx+'Size;i'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])**2/(ateln2*parmDict[phfx+'Size;i'])
1533        elif calcControls[phfx+'SizeType'] == 'uniaxial':   #OK
1534            const = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2
1535            H = np.array(refl[:3])
1536            P = np.array(calcControls[phfx+'SizeAxis'])
1537            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1538            Si = parmDict[phfx+'Size;i']
1539            Sa = parmDict[phfx+'Size;a']
1540            gami = const/(Si*Sa)
1541            sqtrm = np.sqrt((sinP*Sa)**2+(cosP*Si)**2)
1542            Sgam = gami*sqtrm
1543            dsi = gami*Si*cosP**2/sqtrm-Sgam/Si
1544            dsa = gami*Sa*sinP**2/sqtrm-Sgam/Sa
1545            gamDict[phfx+'Size;i'] = dsi*parmDict[phfx+'Size;mx']
1546            gamDict[phfx+'Size;a'] = dsa*parmDict[phfx+'Size;mx']
1547            sigDict[phfx+'Size;i'] = 2.*dsi*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1548            sigDict[phfx+'Size;a'] = 2.*dsa*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1549        else:           #OK  ellipsoidal crystallites
1550            const = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2
1551            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1552            H = np.array(refl[:3])
1553            lenR,dRdS = G2pwd.ellipseSizeDerv(H,Sij,GB)
1554            Sgam = const/lenR
1555            for i,item in enumerate([phfx+'Size:%d'%(j) for j in range(6)]):
1556                gamDict[item] = -(const/lenR**2)*dRdS[i]*parmDict[phfx+'Size;mx']
1557                sigDict[item] = -2.*Sgam*(const/lenR**2)*dRdS[i]*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1558        gamDict[phfx+'Size;mx'] = Sgam  #OK
1559        sigDict[phfx+'Size;mx'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])/ateln2  #OK
1560               
1561        #microstrain derivatives               
1562        if calcControls[phfx+'MustrainType'] == 'isotropic':
1563            Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*parmDict[phfx+'Mustrain;i']
1564            gamDict[phfx+'Mustrain;i'] =  1.e-6*refl[4+im]*parmDict[hfx+'difC']*parmDict[phfx+'Mustrain;mx']   #OK
1565            sigDict[phfx+'Mustrain;i'] =  2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])**2/(ateln2*parmDict[phfx+'Mustrain;i'])       
1566        elif calcControls[phfx+'MustrainType'] == 'uniaxial':
1567            H = np.array(refl[:3])
1568            P = np.array(calcControls[phfx+'MustrainAxis'])
1569            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1570            Si = parmDict[phfx+'Mustrain;i']
1571            Sa = parmDict[phfx+'Mustrain;a']
1572            gami = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*Si*Sa
1573            sqtrm = np.sqrt((Si*cosP)**2+(Sa*sinP)**2)
1574            Mgam = gami/sqtrm
1575            dsi = -gami*Si*cosP**2/sqtrm**3
1576            dsa = -gami*Sa*sinP**2/sqtrm**3
1577            gamDict[phfx+'Mustrain;i'] = (Mgam/Si+dsi)*parmDict[phfx+'Mustrain;mx']
1578            gamDict[phfx+'Mustrain;a'] = (Mgam/Sa+dsa)*parmDict[phfx+'Mustrain;mx']
1579            sigDict[phfx+'Mustrain;i'] = 2*(Mgam/Si+dsi)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2
1580            sigDict[phfx+'Mustrain;a'] = 2*(Mgam/Sa+dsa)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2       
1581        else:       #generalized - P.W. Stephens model OK
1582            pwrs = calcControls[phfx+'MuPwrs']
1583            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1584            const = 1.e-6*parmDict[hfx+'difC']*refl[4+im]**3
1585            Sum = 0
1586            for i,strm in enumerate(Strms):
1587                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1588                gamDict[phfx+'Mustrain:'+str(i)] = strm*parmDict[phfx+'Mustrain;mx']/2.
1589                sigDict[phfx+'Mustrain:'+str(i)] = strm*(1.-parmDict[phfx+'Mustrain;mx'])**2
1590            Mgam = const*np.sqrt(Sum)
1591            for i in range(len(Strms)):
1592                gamDict[phfx+'Mustrain:'+str(i)] *= Mgam/Sum
1593                sigDict[phfx+'Mustrain:'+str(i)] *= const**2/ateln2       
1594        gamDict[phfx+'Mustrain;mx'] = Mgam
1595        sigDict[phfx+'Mustrain;mx'] = -2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])/ateln2
1596       
1597    return sigDict,gamDict
1598       
1599def GetReflPos(refl,im,wave,A,pfx,hfx,calcControls,parmDict):
1600    'Needs a doc string'
1601    if im:
1602        h,k,l,m = refl[:4]
1603        vec = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']])
1604        d = 1./np.sqrt(G2lat.calc_rDsqSS(np.array([h,k,l,m]),A,vec))
1605    else:
1606        h,k,l = refl[:3]
1607        d = 1./np.sqrt(G2lat.calc_rDsq(np.array([h,k,l]),A))
1608    refl[4+im] = d
1609    if 'C' in calcControls[hfx+'histType']:
1610        pos = 2.0*asind(wave/(2.0*d))+parmDict[hfx+'Zero']
1611        const = 9.e-2/(np.pi*parmDict[hfx+'Gonio. radius'])                  #shifts in microns
1612        if 'Bragg' in calcControls[hfx+'instType']:
1613            pos -= const*(4.*parmDict[hfx+'Shift']*cosd(pos/2.0)+ \
1614                parmDict[hfx+'Transparency']*sind(pos)*100.0)            #trans(=1/mueff) in cm
1615        else:               #Debye-Scherrer - simple but maybe not right
1616            pos -= const*(parmDict[hfx+'DisplaceX']*cosd(pos)+parmDict[hfx+'DisplaceY']*sind(pos))
1617    elif 'T' in calcControls[hfx+'histType']:
1618        pos = parmDict[hfx+'difC']*d+parmDict[hfx+'difA']*d**2+parmDict[hfx+'difB']/d+parmDict[hfx+'Zero']
1619        #do I need sample position effects - maybe?
1620    return pos
1621
1622def GetReflPosDerv(refl,im,wave,A,pfx,hfx,calcControls,parmDict):
1623    'Needs a doc string'
1624    dpr = 180./np.pi
1625    if im:
1626        h,k,l,m = refl[:4]
1627        vec = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']])
1628        dstsq = G2lat.calc_rDsqSS(np.array([h,k,l,m]),A,vec)
1629    else:
1630        m = 0
1631        h,k,l = refl[:3]       
1632        dstsq = G2lat.calc_rDsq(np.array([h,k,l]),A)
1633    dst = np.sqrt(dstsq)
1634    dsp = 1./dst
1635    if 'C' in calcControls[hfx+'histType']:
1636        pos = refl[5+im]-parmDict[hfx+'Zero']
1637        const = dpr/np.sqrt(1.0-wave**2*dstsq/4.0)
1638        dpdw = const*dst
1639        dpdA = np.array([h**2,k**2,l**2,h*k,h*l,k*l])*const*wave/(2.0*dst)
1640        dpdZ = 1.0
1641        dpdV = np.array([2.*h*A[0]+k*A[3]+l*A[4],2*k*A[1]+h*A[3]+l*A[5],
1642            2*l*A[2]+h*A[4]+k*A[5]])*m*const*wave/(2.0*dst)
1643        shft = 9.e-2/(np.pi*parmDict[hfx+'Gonio. radius'])                  #shifts in microns
1644        if 'Bragg' in calcControls[hfx+'instType']:
1645            dpdSh = -4.*shft*cosd(pos/2.0)
1646            dpdTr = -shft*sind(pos)*100.0
1647            return dpdA,dpdw,dpdZ,dpdSh,dpdTr,0.,0.,dpdV
1648        else:               #Debye-Scherrer - simple but maybe not right
1649            dpdXd = -shft*cosd(pos)
1650            dpdYd = -shft*sind(pos)
1651            return dpdA,dpdw,dpdZ,0.,0.,dpdXd,dpdYd,dpdV
1652    elif 'T' in calcControls[hfx+'histType']:
1653        dpdA = -np.array([h**2,k**2,l**2,h*k,h*l,k*l])*parmDict[hfx+'difC']*dsp**3/2.
1654        dpdZ = 1.0
1655        dpdDC = dsp
1656        dpdDA = dsp**2
1657        dpdDB = 1./dsp
1658        dpdV = np.array([2.*h*A[0]+k*A[3]+l*A[4],2*k*A[1]+h*A[3]+l*A[5],
1659            2*l*A[2]+h*A[4]+k*A[5]])*m**parmDict[hfx+'difC']*dsp**3/2.
1660        return dpdA,dpdZ,dpdDC,dpdDA,dpdDB,dpdV
1661           
1662def GetHStrainShift(refl,im,SGData,phfx,hfx,calcControls,parmDict):
1663    'Needs a doc string'
1664    laue = SGData['SGLaue']
1665    uniq = SGData['SGUniq']
1666    h,k,l = refl[:3]
1667    if laue in ['m3','m3m']:
1668        Dij = parmDict[phfx+'D11']*(h**2+k**2+l**2)+ \
1669            refl[4+im]**2*parmDict[phfx+'eA']*((h*k)**2+(h*l)**2+(k*l)**2)/(h**2+k**2+l**2)**2
1670    elif laue in ['6/m','6/mmm','3m1','31m','3']:
1671        Dij = parmDict[phfx+'D11']*(h**2+k**2+h*k)+parmDict[phfx+'D33']*l**2
1672    elif laue in ['3R','3mR']:
1673        Dij = parmDict[phfx+'D11']*(h**2+k**2+l**2)+parmDict[phfx+'D12']*(h*k+h*l+k*l)
1674    elif laue in ['4/m','4/mmm']:
1675        Dij = parmDict[phfx+'D11']*(h**2+k**2)+parmDict[phfx+'D33']*l**2
1676    elif laue in ['mmm']:
1677        Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2
1678    elif laue in ['2/m']:
1679        Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2
1680        if uniq == 'a':
1681            Dij += parmDict[phfx+'D23']*k*l
1682        elif uniq == 'b':
1683            Dij += parmDict[phfx+'D13']*h*l
1684        elif uniq == 'c':
1685            Dij += parmDict[phfx+'D12']*h*k
1686    else:
1687        Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2+ \
1688            parmDict[phfx+'D12']*h*k+parmDict[phfx+'D13']*h*l+parmDict[phfx+'D23']*k*l
1689    if 'C' in calcControls[hfx+'histType']:
1690        return -180.*Dij*refl[4+im]**2*tand(refl[5+im]/2.0)/np.pi
1691    else:
1692        return -Dij*parmDict[hfx+'difC']*refl[4+im]**2/2.
1693           
1694def GetHStrainShiftDerv(refl,im,SGData,phfx,hfx,calcControls,parmDict):
1695    'Needs a doc string'
1696    laue = SGData['SGLaue']
1697    uniq = SGData['SGUniq']
1698    h,k,l = refl[:3]
1699    if laue in ['m3','m3m']:
1700        dDijDict = {phfx+'D11':h**2+k**2+l**2,
1701            phfx+'eA':refl[4+im]**2*((h*k)**2+(h*l)**2+(k*l)**2)/(h**2+k**2+l**2)**2}
1702    elif laue in ['6/m','6/mmm','3m1','31m','3']:
1703        dDijDict = {phfx+'D11':h**2+k**2+h*k,phfx+'D33':l**2}
1704    elif laue in ['3R','3mR']:
1705        dDijDict = {phfx+'D11':h**2+k**2+l**2,phfx+'D12':h*k+h*l+k*l}
1706    elif laue in ['4/m','4/mmm']:
1707        dDijDict = {phfx+'D11':h**2+k**2,phfx+'D33':l**2}
1708    elif laue in ['mmm']:
1709        dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2}
1710    elif laue in ['2/m']:
1711        dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2}
1712        if uniq == 'a':
1713            dDijDict[phfx+'D23'] = k*l
1714        elif uniq == 'b':
1715            dDijDict[phfx+'D13'] = h*l
1716        elif uniq == 'c':
1717            dDijDict[phfx+'D12'] = h*k
1718            names.append()
1719    else:
1720        dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2,
1721            phfx+'D12':h*k,phfx+'D13':h*l,phfx+'D23':k*l}
1722    if 'C' in calcControls[hfx+'histType']:
1723        for item in dDijDict:
1724            dDijDict[item] *= 180.0*refl[4+im]**2*tand(refl[5+im]/2.0)/np.pi
1725    else:
1726        for item in dDijDict:
1727            dDijDict[item] *= -parmDict[hfx+'difC']*refl[4+im]**3/2.
1728    return dDijDict
1729   
1730def GetDij(phfx,SGData,parmDict):
1731    HSvals = [parmDict[phfx+name] for name in G2spc.HStrainNames(SGData)]
1732    return G2spc.HStrainVals(HSvals,SGData)
1733               
1734def GetFobsSq(Histograms,Phases,parmDict,calcControls):
1735    'Needs a doc string'
1736    histoList = Histograms.keys()
1737    histoList.sort()
1738    for histogram in histoList:
1739        if 'PWDR' in histogram[:4]:
1740            Histogram = Histograms[histogram]
1741            hId = Histogram['hId']
1742            hfx = ':%d:'%(hId)
1743            Limits = calcControls[hfx+'Limits']
1744            if 'C' in calcControls[hfx+'histType']:
1745                shl = max(parmDict[hfx+'SH/L'],0.0005)
1746                Ka2 = False
1747                kRatio = 0.0
1748                if hfx+'Lam1' in parmDict.keys():
1749                    Ka2 = True
1750                    lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1'])
1751                    kRatio = parmDict[hfx+'I(L2)/I(L1)']
1752            x,y,w,yc,yb,yd = Histogram['Data']
1753            xB = np.searchsorted(x,Limits[0])
1754            xF = np.searchsorted(x,Limits[1])
1755            ymb = np.array(y-yb)
1756            ymb = np.where(ymb,ymb,1.0)
1757            ycmb = np.array(yc-yb)
1758            ratio = 1./np.where(ycmb,ycmb/ymb,1.e10)         
1759            refLists = Histogram['Reflection Lists']
1760            for phase in refLists:
1761                if phase not in Phases:     #skips deleted or renamed phases silently!
1762                    continue
1763                Phase = Phases[phase]
1764                im = 0
1765                if Phase['General']['Type'] in ['modulated','magnetic']:
1766                    im = 1
1767                pId = Phase['pId']
1768                phfx = '%d:%d:'%(pId,hId)
1769                refDict = refLists[phase]
1770                sumFo = 0.0
1771                sumdF = 0.0
1772                sumFosq = 0.0
1773                sumdFsq = 0.0
1774                sumInt = 0.0
1775                for refl in refDict['RefList']:
1776                    if 'C' in calcControls[hfx+'histType']:
1777                        yp = np.zeros_like(yb)
1778                        Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl)
1779                        iBeg = max(xB,np.searchsorted(x,refl[5+im]-fmin))
1780                        iFin = max(xB,min(np.searchsorted(x,refl[5+im]+fmax),xF))
1781                        iFin2 = iFin
1782                        if not iBeg+iFin:       #peak below low limit - skip peak
1783                            continue
1784                        elif not iBeg-iFin:     #peak above high limit - done
1785                            break
1786                        elif iBeg < iFin:
1787                            yp[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
1788                            sumInt += refl[11+im]*refl[9+im]
1789                            if Ka2:
1790                                pos2 = refl[5+im]+lamRatio*tand(refl[5+im]/2.0)       # + 360/pi * Dlam/lam * tan(th)
1791                                Wd,fmin,fmax = G2pwd.getWidthsCW(pos2,refl[6+im],refl[7+im],shl)
1792                                iBeg2 = max(xB,np.searchsorted(x,pos2-fmin))
1793                                iFin2 = min(np.searchsorted(x,pos2+fmax),xF)
1794                                yp[iBeg2:iFin2] += refl[11+im]*refl[9+im]*kRatio*G2pwd.getFCJVoigt3(pos2,refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg2:iFin2]))        #and here
1795                                sumInt += refl[11+im]*refl[9+im]*kRatio
1796                            refl[8+im] = np.sum(np.where(ratio[iBeg:iFin2]>0.,yp[iBeg:iFin2]*ratio[iBeg:iFin2]/(refl[11+im]*(1.+kRatio)),0.0))
1797                               
1798                    elif 'T' in calcControls[hfx+'histType']:
1799                        yp = np.zeros_like(yb)
1800                        Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im])
1801                        iBeg = max(xB,np.searchsorted(x,refl[5+im]-fmin))
1802                        iFin = max(xB,min(np.searchsorted(x,refl[5+im]+fmax),xF))
1803                        if iBeg < iFin:
1804                            yp[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]))  #>90% of time spent here
1805                            refl[8+im] = np.sum(np.where(ratio[iBeg:iFin]>0.,yp[iBeg:iFin]*ratio[iBeg:iFin]/refl[11+im],0.0))
1806                            sumInt += refl[11+im]*refl[9+im]
1807                    Fo = np.sqrt(np.abs(refl[8+im]))
1808                    Fc = np.sqrt(np.abs(refl[9]+im))
1809                    sumFo += Fo
1810                    sumFosq += refl[8+im]**2
1811                    sumdF += np.abs(Fo-Fc)
1812                    sumdFsq += (refl[8+im]-refl[9+im])**2
1813                if sumFo:
1814                    Histogram['Residuals'][phfx+'Rf'] = min(100.,(sumdF/sumFo)*100.)
1815                    Histogram['Residuals'][phfx+'Rf^2'] = min(100.,np.sqrt(sumdFsq/sumFosq)*100.)
1816                else:
1817                    Histogram['Residuals'][phfx+'Rf'] = 100.
1818                    Histogram['Residuals'][phfx+'Rf^2'] = 100.
1819                Histogram['Residuals'][phfx+'sumInt'] = sumInt
1820                Histogram['Residuals'][phfx+'Nref'] = len(refDict['RefList'])
1821                Histogram['Residuals']['hId'] = hId
1822        elif 'HKLF' in histogram[:4]:
1823            Histogram = Histograms[histogram]
1824            Histogram['Residuals']['hId'] = Histograms[histogram]['hId']
1825               
1826def getPowderProfile(parmDict,x,varylist,Histogram,Phases,calcControls,pawleyLookup):
1827    'Needs a doc string'
1828   
1829    def GetReflSigGamCW(refl,im,wave,G,GB,phfx,calcControls,parmDict):
1830        U = parmDict[hfx+'U']
1831        V = parmDict[hfx+'V']
1832        W = parmDict[hfx+'W']
1833        X = parmDict[hfx+'X']
1834        Y = parmDict[hfx+'Y']
1835        tanPos = tand(refl[5+im]/2.0)
1836        Ssig,Sgam = GetSampleSigGam(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict)
1837        sig = U*tanPos**2+V*tanPos+W+Ssig     #save peak sigma
1838        sig = max(0.001,sig)
1839        gam = X/cosd(refl[5+im]/2.0)+Y*tanPos+Sgam     #save peak gamma
1840        gam = max(0.001,gam)
1841        return sig,gam
1842               
1843    def GetReflSigGamTOF(refl,im,G,GB,phfx,calcControls,parmDict):
1844        sig = parmDict[hfx+'sig-0']+parmDict[hfx+'sig-1']*refl[4+im]**2+   \
1845            parmDict[hfx+'sig-2']*refl[4+im]**4+parmDict[hfx+'sig-q']/refl[4+im]**2
1846        gam = parmDict[hfx+'X']*refl[4+im]+parmDict[hfx+'Y']*refl[4+im]**2
1847        Ssig,Sgam = GetSampleSigGam(refl,im,0.0,G,GB,SGData,hfx,phfx,calcControls,parmDict)
1848        sig += Ssig
1849        gam += Sgam
1850        return sig,gam
1851       
1852    def GetReflAlpBet(refl,im,hfx,parmDict):
1853        alp = parmDict[hfx+'alpha']/refl[4+im]
1854        bet = parmDict[hfx+'beta-0']+parmDict[hfx+'beta-1']/refl[4+im]**4+parmDict[hfx+'beta-q']/refl[4+im]**2
1855        return alp,bet
1856       
1857    hId = Histogram['hId']
1858    hfx = ':%d:'%(hId)
1859    bakType = calcControls[hfx+'bakType']
1860    yb,Histogram['sumBk'] = G2pwd.getBackground(hfx,parmDict,bakType,calcControls[hfx+'histType'],x)
1861    yc = np.zeros_like(yb)
1862    cw = np.diff(x)
1863    cw = np.append(cw,cw[-1])
1864       
1865    if 'C' in calcControls[hfx+'histType']:   
1866        shl = max(parmDict[hfx+'SH/L'],0.002)
1867        Ka2 = False
1868        if hfx+'Lam1' in parmDict.keys():
1869            wave = parmDict[hfx+'Lam1']
1870            Ka2 = True
1871            lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1'])
1872            kRatio = parmDict[hfx+'I(L2)/I(L1)']
1873        else:
1874            wave = parmDict[hfx+'Lam']
1875    for phase in Histogram['Reflection Lists']:
1876        refDict = Histogram['Reflection Lists'][phase]
1877        if phase not in Phases:     #skips deleted or renamed phases silently!
1878            continue
1879        Phase = Phases[phase]
1880        pId = Phase['pId']
1881        pfx = '%d::'%(pId)
1882        phfx = '%d:%d:'%(pId,hId)
1883        hfx = ':%d:'%(hId)
1884        SGData = Phase['General']['SGData']
1885        SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
1886        im = 0
1887        if Phase['General']['Type'] in ['modulated','magnetic']:
1888            SSGData = Phase['General']['SSGData']
1889            SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
1890            im = 1  #offset in SS reflection list
1891            #??
1892        Dij = GetDij(phfx,SGData,parmDict)
1893        A = [parmDict[pfx+'A%d'%(i)]+Dij[i] for i in range(6)]
1894        G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
1895        GA,GB = G2lat.Gmat2AB(G)    #Orthogonalization matricies
1896        Vst = np.sqrt(nl.det(G))    #V*
1897        if not Phase['General'].get('doPawley'):
1898            time0 = time.time()
1899            if im:
1900                SStructureFactor(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
1901            else:
1902                StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
1903#            print 'sf calc time: %.3fs'%(time.time()-time0)
1904        time0 = time.time()
1905        badPeak = False
1906        for iref,refl in enumerate(refDict['RefList']):
1907            if 'C' in calcControls[hfx+'histType']:
1908                if im:
1909                    h,k,l,m = refl[:4]
1910                else:
1911                    h,k,l = refl[:3]
1912                Uniq = np.inner(refl[:3],SGMT)
1913                refl[5+im] = GetReflPos(refl,im,wave,A,pfx,hfx,calcControls,parmDict)         #corrected reflection position
1914                Lorenz = 1./(2.*sind(refl[5+im]/2.)**2*cosd(refl[5+im]/2.))           #Lorentz correction
1915#                refl[5+im] += GetHStrainShift(refl,im,SGData,phfx,hfx,calcControls,parmDict)               #apply hydrostatic strain shift
1916                refl[6+im:8+im] = GetReflSigGamCW(refl,im,wave,G,GB,phfx,calcControls,parmDict)    #peak sig & gam
1917                refl[11+im:15+im] = GetIntensityCorr(refl,im,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict)
1918                refl[11+im] *= Vst*Lorenz
1919                 
1920                if Phase['General'].get('doPawley'):
1921                    try:
1922                        if im:
1923                            pInd = pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)])
1924                        else:
1925                            pInd = pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)])
1926                        refl[9+im] = parmDict[pInd]
1927                    except KeyError:
1928#                        print ' ***Error %d,%d,%d missing from Pawley reflection list ***'%(h,k,l)
1929                        continue
1930                Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl)
1931                iBeg = np.searchsorted(x,refl[5+im]-fmin)
1932                iFin = np.searchsorted(x,refl[5+im]+fmax)
1933                if not iBeg+iFin:       #peak below low limit - skip peak
1934                    continue
1935                elif not iBeg-iFin:     #peak above high limit - done
1936                    break
1937                elif iBeg > iFin:   #bad peak coeff - skip
1938                    badPeak = True
1939                    continue
1940                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
1941                if Ka2:
1942                    pos2 = refl[5+im]+lamRatio*tand(refl[5+im]/2.0)       # + 360/pi * Dlam/lam * tan(th)
1943                    Wd,fmin,fmax = G2pwd.getWidthsCW(pos2,refl[6+im],refl[7+im],shl)
1944                    iBeg = np.searchsorted(x,pos2-fmin)
1945                    iFin = np.searchsorted(x,pos2+fmax)
1946                    if not iBeg+iFin:       #peak below low limit - skip peak
1947                        continue
1948                    elif not iBeg-iFin:     #peak above high limit - done
1949                        return yc,yb
1950                    elif iBeg > iFin:   #bad peak coeff - skip
1951                        continue
1952                    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
1953            elif 'T' in calcControls[hfx+'histType']:
1954                h,k,l = refl[:3]
1955                Uniq = np.inner(refl[:3],SGMT)
1956                refl[5+im] = GetReflPos(refl,im,0.0,A,pfx,hfx,calcControls,parmDict)         #corrected reflection position
1957                Lorenz = sind(parmDict[hfx+'2-theta']/2)*refl[4+im]**4                                                #TOF Lorentz correction
1958#                refl[5+im] += GetHStrainShift(refl,im,SGData,phfx,hfx,calcControls,parmDict)               #apply hydrostatic strain shift
1959                refl[6+im:8+im] = GetReflSigGamTOF(refl,im,G,GB,phfx,calcControls,parmDict)    #peak sig & gam
1960                refl[12+im:14+im] = GetReflAlpBet(refl,im,hfx,parmDict)
1961                refl[11+im],refl[15+im],refl[16+im],refl[17+im] = GetIntensityCorr(refl,im,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict)
1962                refl[11+im] *= Vst*Lorenz
1963                if Phase['General'].get('doPawley'):
1964                    try:
1965                        if im:
1966                            pInd =pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)])
1967                        else:
1968                            pInd =pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)])
1969                        refl[9+im] = parmDict[pInd]
1970                    except KeyError:
1971#                        print ' ***Error %d,%d,%d missing from Pawley reflection list ***'%(h,k,l)
1972                        continue
1973                Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im])
1974                iBeg = np.searchsorted(x,refl[5+im]-fmin)
1975                iFin = np.searchsorted(x,refl[5+im]+fmax)
1976                if not iBeg+iFin:       #peak below low limit - skip peak
1977                    continue
1978                elif not iBeg-iFin:     #peak above high limit - done
1979                    break
1980                elif iBeg > iFin:   #bad peak coeff - skip
1981                    badPeak = True
1982                    continue
1983                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]
1984#        print 'profile calc time: %.3fs'%(time.time()-time0)
1985    if badPeak:
1986        print 'ouch #4 bad profile coefficients yield negative peak width; some reflections skipped' 
1987    return yc,yb
1988   
1989def getPowderProfileDerv(parmDict,x,varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup):
1990    'Needs a doc string'
1991   
1992    def cellVaryDerv(pfx,SGData,dpdA): 
1993        if SGData['SGLaue'] in ['-1',]:
1994            return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],
1995                [pfx+'A3',dpdA[3]],[pfx+'A4',dpdA[4]],[pfx+'A5',dpdA[5]]]
1996        elif SGData['SGLaue'] in ['2/m',]:
1997            if SGData['SGUniq'] == 'a':
1998                return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A3',dpdA[3]]]
1999            elif SGData['SGUniq'] == 'b':
2000                return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A4',dpdA[4]]]
2001            else:
2002                return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A5',dpdA[5]]]
2003        elif SGData['SGLaue'] in ['mmm',]:
2004            return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]]]
2005        elif SGData['SGLaue'] in ['4/m','4/mmm']:
2006            return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]]
2007        elif SGData['SGLaue'] in ['6/m','6/mmm','3m1', '31m', '3']:
2008            return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]]
2009        elif SGData['SGLaue'] in ['3R', '3mR']:
2010            return [[pfx+'A0',dpdA[0]+dpdA[1]+dpdA[2]],[pfx+'A3',dpdA[3]+dpdA[4]+dpdA[5]]]                       
2011        elif SGData['SGLaue'] in ['m3m','m3']:
2012            return [[pfx+'A0',dpdA[0]]]
2013           
2014    # create a list of dependent variables and set up a dictionary to hold their derivatives
2015    dependentVars = G2mv.GetDependentVars()
2016    depDerivDict = {}
2017    for j in dependentVars:
2018        depDerivDict[j] = np.zeros(shape=(len(x)))
2019    #print 'dependent vars',dependentVars
2020    lenX = len(x)               
2021    hId = Histogram['hId']
2022    hfx = ':%d:'%(hId)
2023    bakType = calcControls[hfx+'bakType']
2024    dMdv = np.zeros(shape=(len(varylist),len(x)))
2025    dMdb,dMddb,dMdpk = G2pwd.getBackgroundDerv(hfx,parmDict,bakType,calcControls[hfx+'histType'],x)
2026    if hfx+'Back;0' in varylist: # for now assume that Back;x vars to not appear in constraints
2027        bBpos =varylist.index(hfx+'Back;0')
2028        dMdv[bBpos:bBpos+len(dMdb)] = dMdb
2029    names = [hfx+'DebyeA',hfx+'DebyeR',hfx+'DebyeU']
2030    for name in varylist:
2031        if 'Debye' in name:
2032            id = int(name.split(';')[-1])
2033            parm = name[:int(name.rindex(';'))]
2034            ip = names.index(parm)
2035            dMdv[varylist.index(name)] = dMddb[3*id+ip]
2036    names = [hfx+'BkPkpos',hfx+'BkPkint',hfx+'BkPksig',hfx+'BkPkgam']
2037    for name in varylist:
2038        if 'BkPk' in name:
2039            parm,id = name.split(';')
2040            id = int(id)
2041            if parm in names:
2042                ip = names.index(parm)
2043                dMdv[varylist.index(name)] = dMdpk[4*id+ip]
2044    cw = np.diff(x)
2045    cw = np.append(cw,cw[-1])
2046    Ka2 = False #also for TOF!
2047    if 'C' in calcControls[hfx+'histType']:   
2048        shl = max(parmDict[hfx+'SH/L'],0.002)
2049        if hfx+'Lam1' in parmDict.keys():
2050            wave = parmDict[hfx+'Lam1']
2051            Ka2 = True
2052            lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1'])
2053            kRatio = parmDict[hfx+'I(L2)/I(L1)']
2054        else:
2055            wave = parmDict[hfx+'Lam']
2056    for phase in Histogram['Reflection Lists']:
2057        refDict = Histogram['Reflection Lists'][phase]
2058        if phase not in Phases:     #skips deleted or renamed phases silently!
2059            continue
2060        Phase = Phases[phase]
2061        SGData = Phase['General']['SGData']
2062        SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
2063        im = 0
2064        if Phase['General']['Type'] in ['modulated','magnetic']:
2065            SSGData = Phase['General']['SSGData']
2066            SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
2067            im = 1  #offset in SS reflection list
2068            #??
2069        pId = Phase['pId']
2070        pfx = '%d::'%(pId)
2071        phfx = '%d:%d:'%(pId,hId)
2072        Dij = GetDij(phfx,SGData,parmDict)
2073        A = [parmDict[pfx+'A%d'%(i)]+Dij[i] for i in range(6)]
2074        G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
2075        GA,GB = G2lat.Gmat2AB(G)    #Orthogonalization matricies
2076        if not Phase['General'].get('doPawley'):
2077            time0 = time.time()
2078            if im:
2079                dFdvDict = SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
2080            else:
2081                dFdvDict = StructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
2082#            print 'sf-derv time %.3fs'%(time.time()-time0)
2083            ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase)
2084        time0 = time.time()
2085        for iref,refl in enumerate(refDict['RefList']):
2086            if im:
2087                h,k,l,m = refl[:4]
2088            else:
2089                h,k,l = refl[:3]
2090            Uniq = np.inner(refl[:3],SGMT)
2091            if 'T' in calcControls[hfx+'histType']:
2092                wave = refl[14+im]
2093            dIdsh,dIdsp,dIdpola,dIdPO,dFdODF,dFdSA,dFdAb,dFdEx = GetIntensityDerv(refl,im,wave,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict)
2094            if 'C' in calcControls[hfx+'histType']:        #CW powder
2095                Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl)
2096            else: #'T'OF
2097                Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im])
2098            iBeg = np.searchsorted(x,refl[5+im]-fmin)
2099            iFin = np.searchsorted(x,refl[5+im]+fmax)
2100            if not iBeg+iFin:       #peak below low limit - skip peak
2101                continue
2102            elif not iBeg-iFin:     #peak above high limit - done
2103                break
2104            pos = refl[5+im]
2105            if 'C' in calcControls[hfx+'histType']:
2106                tanth = tand(pos/2.0)
2107                costh = cosd(pos/2.0)
2108                lenBF = iFin-iBeg
2109                dMdpk = np.zeros(shape=(6,lenBF))
2110                dMdipk = G2pwd.getdFCJVoigt3(refl[5+im],refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg:iFin]))
2111                for i in range(5):
2112                    dMdpk[i] += 100.*cw[iBeg:iFin]*refl[11+im]*refl[9+im]*dMdipk[i]
2113                dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'sig':dMdpk[2],'gam':dMdpk[3],'shl':dMdpk[4],'L1/L2':np.zeros_like(dMdpk[0])}
2114                if Ka2:
2115                    pos2 = refl[5+im]+lamRatio*tanth       # + 360/pi * Dlam/lam * tan(th)
2116                    iBeg2 = np.searchsorted(x,pos2-fmin)
2117                    iFin2 = np.searchsorted(x,pos2+fmax)
2118                    if iBeg2-iFin2:
2119                        lenBF2 = iFin2-iBeg2
2120                        dMdpk2 = np.zeros(shape=(6,lenBF2))
2121                        dMdipk2 = G2pwd.getdFCJVoigt3(pos2,refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg2:iFin2]))
2122                        for i in range(5):
2123                            dMdpk2[i] = 100.*cw[iBeg2:iFin2]*refl[11+im]*refl[9+im]*kRatio*dMdipk2[i]
2124                        dMdpk2[5] = 100.*cw[iBeg2:iFin2]*refl[11+im]*dMdipk2[0]
2125                        dervDict2 = {'int':dMdpk2[0],'pos':dMdpk2[1],'sig':dMdpk2[2],'gam':dMdpk2[3],'shl':dMdpk2[4],'L1/L2':dMdpk2[5]*refl[9]}
2126            else:   #'T'OF
2127                lenBF = iFin-iBeg
2128                if lenBF < 0:   #bad peak coeff
2129                    break
2130                dMdpk = np.zeros(shape=(6,lenBF))
2131                dMdipk = G2pwd.getdEpsVoigt(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im],ma.getdata(x[iBeg:iFin]))
2132                for i in range(6):
2133                    dMdpk[i] += refl[11+im]*refl[9+im]*dMdipk[i]      #cw[iBeg:iFin]*
2134                dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'alp':dMdpk[2],'bet':dMdpk[3],'sig':dMdpk[4],'gam':dMdpk[5]}           
2135            if Phase['General'].get('doPawley'):
2136                dMdpw = np.zeros(len(x))
2137                try:
2138                    if im:
2139                        pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)])
2140                    else:
2141                        pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)])
2142                    idx = varylist.index(pIdx)
2143                    dMdpw[iBeg:iFin] = dervDict['int']/refl[9+im]
2144                    if Ka2: #not for TOF either
2145                        dMdpw[iBeg2:iFin2] += dervDict2['int']/refl[9+im]
2146                    dMdv[idx] = dMdpw
2147                except: # ValueError:
2148                    pass
2149            if 'C' in calcControls[hfx+'histType']:
2150                dpdA,dpdw,dpdZ,dpdSh,dpdTr,dpdX,dpdY,dpdV = GetReflPosDerv(refl,im,wave,A,pfx,hfx,calcControls,parmDict)
2151                names = {hfx+'Scale':[dIdsh,'int'],hfx+'Polariz.':[dIdpola,'int'],phfx+'Scale':[dIdsp,'int'],
2152                    hfx+'U':[tanth**2,'sig'],hfx+'V':[tanth,'sig'],hfx+'W':[1.0,'sig'],
2153                    hfx+'X':[1.0/costh,'gam'],hfx+'Y':[tanth,'gam'],hfx+'SH/L':[1.0,'shl'],
2154                    hfx+'I(L2)/I(L1)':[1.0,'L1/L2'],hfx+'Zero':[dpdZ,'pos'],hfx+'Lam':[dpdw,'pos'],
2155                    hfx+'Shift':[dpdSh,'pos'],hfx+'Transparency':[dpdTr,'pos'],hfx+'DisplaceX':[dpdX,'pos'],
2156                    hfx+'DisplaceY':[dpdY,'pos'],}
2157                if 'Bragg' in calcControls[hfx+'instType']:
2158                    names.update({hfx+'SurfRoughA':[dFdAb[0],'int'],
2159                        hfx+'SurfRoughB':[dFdAb[1],'int'],})
2160                else:
2161                    names.update({hfx+'Absorption':[dFdAb,'int'],})
2162            else:   #'T'OF
2163                dpdA,dpdZ,dpdDC,dpdDA,dpdDB,dpdV = GetReflPosDerv(refl,im,0.0,A,pfx,hfx,calcControls,parmDict)
2164                names = {hfx+'Scale':[dIdsh,'int'],phfx+'Scale':[dIdsp,'int'],
2165                    hfx+'difC':[dpdDC,'pos'],hfx+'difA':[dpdDA,'pos'],hfx+'difB':[dpdDB,'pos'],
2166                    hfx+'Zero':[dpdZ,'pos'],hfx+'X':[refl[4+im],'gam'],hfx+'Y':[refl[4+im]**2,'gam'],
2167                    hfx+'alpha':[1./refl[4+im],'alp'],hfx+'beta-0':[1.0,'bet'],hfx+'beta-1':[1./refl[4+im]**4,'bet'],
2168                    hfx+'beta-q':[1./refl[4+im]**2,'bet'],hfx+'sig-0':[1.0,'sig'],hfx+'sig-1':[refl[4+im]**2,'sig'],
2169                    hfx+'sig-2':[refl[4+im]**4,'sig'],hfx+'sig-q':[1./refl[4+im]**2,'sig'],
2170                    hfx+'Absorption':[dFdAb,'int'],phfx+'Extinction':[dFdEx,'int'],}
2171            for name in names:
2172                item = names[name]
2173                if name in varylist:
2174                    dMdv[varylist.index(name)][iBeg:iFin] += item[0]*dervDict[item[1]]
2175                    if Ka2:
2176                        dMdv[varylist.index(name)][iBeg2:iFin2] += item[0]*dervDict2[item[1]]
2177                elif name in dependentVars:
2178                    depDerivDict[name][iBeg:iFin] += item[0]*dervDict[item[1]]
2179                    if Ka2:
2180                        depDerivDict[name][iBeg2:iFin2] += item[0]*dervDict2[item[1]]
2181            for iPO in dIdPO:
2182                if iPO in varylist:
2183                    dMdv[varylist.index(iPO)][iBeg:iFin] += dIdPO[iPO]*dervDict['int']
2184                    if Ka2:
2185                        dMdv[varylist.index(iPO)][iBeg2:iFin2] += dIdPO[iPO]*dervDict2['int']
2186                elif iPO in dependentVars:
2187                    depDerivDict[iPO][iBeg:iFin] += dIdPO[iPO]*dervDict['int']
2188                    if Ka2:
2189                        depDerivDict[iPO][iBeg2:iFin2] += dIdPO[iPO]*dervDict2['int']
2190            for i,name in enumerate(['omega','chi','phi']):
2191                aname = pfx+'SH '+name
2192                if aname in varylist:
2193                    dMdv[varylist.index(aname)][iBeg:iFin] += dFdSA[i]*dervDict['int']
2194                    if Ka2:
2195                        dMdv[varylist.index(aname)][iBeg2:iFin2] += dFdSA[i]*dervDict2['int']
2196                elif aname in dependentVars:
2197                    depDerivDict[aname][iBeg:iFin] += dFdSA[i]*dervDict['int']
2198                    if Ka2:
2199                        depDerivDict[aname][iBeg2:iFin2] += dFdSA[i]*dervDict2['int']
2200            for iSH in dFdODF:
2201                if iSH in varylist:
2202                    dMdv[varylist.index(iSH)][iBeg:iFin] += dFdODF[iSH]*dervDict['int']
2203                    if Ka2:
2204                        dMdv[varylist.index(iSH)][iBeg2:iFin2] += dFdODF[iSH]*dervDict2['int']
2205                elif iSH in dependentVars:
2206                    depDerivDict[iSH][iBeg:iFin] += dFdODF[iSH]*dervDict['int']
2207                    if Ka2:
2208                        depDerivDict[iSH][iBeg2:iFin2] += dFdODF[iSH]*dervDict2['int']
2209            cellDervNames = cellVaryDerv(pfx,SGData,dpdA)
2210            for name,dpdA in cellDervNames:
2211                if name in varylist:
2212                    dMdv[varylist.index(name)][iBeg:iFin] += dpdA*dervDict['pos']
2213                    if Ka2:
2214                        dMdv[varylist.index(name)][iBeg2:iFin2] += dpdA*dervDict2['pos']
2215                elif name in dependentVars:
2216                    depDerivDict[name][iBeg:iFin] += dpdA*dervDict['pos']
2217                    if Ka2:
2218                        depDerivDict[name][iBeg2:iFin2] += dpdA*dervDict2['pos']
2219            dDijDict = GetHStrainShiftDerv(refl,im,SGData,phfx,hfx,calcControls,parmDict)
2220            for name in dDijDict:
2221                if name in varylist:
2222                    dMdv[varylist.index(name)][iBeg:iFin] += dDijDict[name]*dervDict['pos']
2223                    if Ka2:
2224                        dMdv[varylist.index(name)][iBeg2:iFin2] += dDijDict[name]*dervDict2['pos']
2225                elif name in dependentVars:
2226                    depDerivDict[name][iBeg:iFin] += dDijDict[name]*dervDict['pos']
2227                    if Ka2:
2228                        depDerivDict[name][iBeg2:iFin2] += dDijDict[name]*dervDict2['pos']
2229            for i,name in enumerate([pfx+'mV0',pfx+'mV1',pfx+'mV2']):
2230                if name in varylist:
2231                    dMdv[varylist.index(name)][iBeg:iFin] += dpdV[i]*dervDict['pos']
2232                    if Ka2:
2233                        dMdv[varylist.index(name)][iBeg2:iFin2] += dpdV[i]*dervDict2['pos']
2234                elif name in dependentVars:
2235                    depDerivDict[name][iBeg:iFin] += dpdV[i]*dervDict['pos']
2236                    if Ka2:
2237                        depDerivDict[name][iBeg2:iFin2] += dpdV[i]*dervDict2['pos']
2238            if 'C' in calcControls[hfx+'histType']:
2239                sigDict,gamDict = GetSampleSigGamDerv(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict)
2240            else:   #'T'OF
2241                sigDict,gamDict = GetSampleSigGamDerv(refl,im,0.0,G,GB,SGData,hfx,phfx,calcControls,parmDict)
2242            for name in gamDict:
2243                if name in varylist:
2244                    dMdv[varylist.index(name)][iBeg:iFin] += gamDict[name]*dervDict['gam']
2245                    if Ka2:
2246                        dMdv[varylist.index(name)][iBeg2:iFin2] += gamDict[name]*dervDict2['gam']
2247                elif name in dependentVars:
2248                    depDerivDict[name][iBeg:iFin] += gamDict[name]*dervDict['gam']
2249                    if Ka2:
2250                        depDerivDict[name][iBeg2:iFin2] += gamDict[name]*dervDict2['gam']
2251            for name in sigDict:
2252                if name in varylist:
2253                    dMdv[varylist.index(name)][iBeg:iFin] += sigDict[name]*dervDict['sig']
2254                    if Ka2:
2255                        dMdv[varylist.index(name)][iBeg2:iFin2] += sigDict[name]*dervDict2['sig']
2256                elif name in dependentVars:
2257                    depDerivDict[name][iBeg:iFin] += sigDict[name]*dervDict['sig']
2258                    if Ka2:
2259                        depDerivDict[name][iBeg2:iFin2] += sigDict[name]*dervDict2['sig']
2260            for name in ['BabA','BabU']:
2261                if refl[9+im]:
2262                    if phfx+name in varylist:
2263                        dMdv[varylist.index(phfx+name)][iBeg:iFin] += dFdvDict[pfx+name][iref]*dervDict['int']/refl[9+im]
2264                        if Ka2:
2265                            dMdv[varylist.index(phfx+name)][iBeg2:iFin2] += dFdvDict[pfx+name][iref]*dervDict2['int']/refl[9+im]
2266                    elif phfx+name in dependentVars:                   
2267                        depDerivDict[phfx+name][iBeg:iFin] += dFdvDict[pfx+name][iref]*dervDict['int']/refl[9+im]
2268                        if Ka2:
2269                            depDerivDict[phfx+name][iBeg2:iFin2] += dFdvDict[pfx+name][iref]*dervDict2['int']/refl[9+im]                 
2270            if not Phase['General'].get('doPawley'):
2271                #do atom derivatives -  for RB,F,X & U so far             
2272                corr = dervDict['int']/refl[9+im]
2273                if Ka2:
2274                    corr2 = dervDict2['int']/refl[9+im]
2275                for name in varylist+dependentVars:
2276                    if '::RBV;' in name:
2277                        pass
2278                    else:
2279                        try:
2280                            aname = name.split(pfx)[1][:2]
2281                            if aname not in ['Af','dA','AU','RB']: continue # skip anything not an atom or rigid body param
2282                        except IndexError:
2283                            continue
2284                    if name in varylist:
2285                        dMdv[varylist.index(name)][iBeg:iFin] += dFdvDict[name][iref]*corr
2286                        if Ka2:
2287                            dMdv[varylist.index(name)][iBeg2:iFin2] += dFdvDict[name][iref]*corr2
2288                    elif name in dependentVars:
2289                        depDerivDict[name][iBeg:iFin] += dFdvDict[name][iref]*corr
2290                        if Ka2:
2291                            depDerivDict[name][iBeg2:iFin2] += dFdvDict[name][iref]*corr2
2292    #        print 'profile derv time: %.3fs'%(time.time()-time0)
2293    # now process derivatives in constraints
2294    G2mv.Dict2Deriv(varylist,depDerivDict,dMdv)
2295    return dMdv
2296   
2297def dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict):
2298    '''Loop over reflections in a HKLF histogram and compute derivatives of the fitting
2299    model (M) with respect to all parameters.  Independent and dependant dM/dp arrays
2300    are returned to either dervRefine or HessRefine.
2301
2302    :returns:
2303    '''
2304    nobs = Histogram['Residuals']['Nobs']
2305    hId = Histogram['hId']
2306    hfx = ':%d:'%(hId)
2307    pfx = '%d::'%(Phase['pId'])
2308    phfx = '%d:%d:'%(Phase['pId'],hId)
2309    SGData = Phase['General']['SGData']
2310    im = 0
2311    if Phase['General']['Type'] in ['modulated','magnetic']:
2312        SSGData = Phase['General']['SSGData']
2313        SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
2314        im = 1  #offset in SS reflection list
2315        #??
2316    A = [parmDict[pfx+'A%d'%(i)] for i in range(6)]
2317    G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
2318    refDict = Histogram['Data']
2319    if im:
2320        dFdvDict = SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
2321    else:
2322        dFdvDict = StructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
2323    ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase)
2324    dMdvh = np.zeros((len(varylist),len(refDict['RefList'])))
2325    dependentVars = G2mv.GetDependentVars()
2326    depDerivDict = {}
2327    for j in dependentVars:
2328        depDerivDict[j] = np.zeros(shape=(len(refDict['RefList'])))
2329    wdf = np.zeros(len(refDict['RefList']))
2330    if calcControls['F**2']:
2331        for iref,ref in enumerate(refDict['RefList']):
2332            if ref[6+im] > 0:
2333                dervDict = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist+dependentVars)[1] 
2334                w = 1.0/ref[6+im]
2335                if w*ref[5+im] >= calcControls['minF/sig']:
2336                    wdf[iref] = w*(ref[5+im]-ref[7+im])
2337                    for j,var in enumerate(varylist):
2338                        if var in dFdvDict:
2339                            dMdvh[j][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2340                    for var in dependentVars:
2341                        if var in dFdvDict:
2342                            depDerivDict[var][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2343                    if phfx+'Scale' in varylist:
2344                        dMdvh[varylist.index(phfx+'Scale')][iref] = w*ref[9+im]*ref[11+im]
2345                    elif phfx+'Scale' in dependentVars:
2346                        depDerivDict[phfx+'Scale'][iref] = w*ref[9+im]*ref[11+im]
2347                    for item in ['Ep','Es','Eg']:
2348                        if phfx+item in varylist and phfx+item in dervDict:
2349                            dMdvh[varylist.index(phfx+item)][iref] = w*dervDict[phfx+item]/ref[11+im]  #OK
2350                        elif phfx+item in dependentVars and phfx+item in dervDict:
2351                            depDerivDict[phfx+item][iref] = w*dervDict[phfx+item]/ref[11+im]  #OK
2352                    for item in ['BabA','BabU']:
2353                        if phfx+item in varylist:
2354                            dMdvh[varylist.index(phfx+item)][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2355                        elif phfx+item in dependentVars:
2356                            depDerivDict[phfx+item][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2357    else:
2358        for iref,ref in enumerate(refDict['RefList']):
2359            if ref[5+im] > 0.:
2360                dervDict = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist+dependentVars)[1]
2361                Fo = np.sqrt(ref[5+im])
2362                Fc = np.sqrt(ref[7+im])
2363                w = 1.0/ref[6+im]
2364                if 2.0*Fo*w*Fo >= calcControls['minF/sig']:
2365                    wdf[iref] = 2.0*Fo*w*(Fo-Fc)
2366                    for j,var in enumerate(varylist):
2367                        if var in dFdvDict:
2368                            dMdvh[j][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2369                    for var in dependentVars:
2370                        if var in dFdvDict:
2371                            depDerivDict[var][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2372                    if phfx+'Scale' in varylist:
2373                        dMdvh[varylist.index(phfx+'Scale')][iref] = w*ref[9+im]*ref[11+im]
2374                    elif phfx+'Scale' in dependentVars:
2375                        depDerivDict[phfx+'Scale'][iref] = w*ref[9+im]*ref[11+im]                           
2376                    for item in ['Ep','Es','Eg']:
2377                        if phfx+item in varylist and phfx+item in dervDict:
2378                            dMdvh[varylist.index(phfx+item)][iref] = w*dervDict[phfx+item]/ref[11+im]  #correct
2379                        elif phfx+item in dependentVars and phfx+item in dervDict:
2380                            depDerivDict[phfx+item][iref] = w*dervDict[phfx+item]/ref[11+im]
2381                    for item in ['BabA','BabU']:
2382                        if phfx+item in varylist:
2383                            dMdvh[varylist.index(phfx+item)][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2384                        elif phfx+item in dependentVars:
2385                            depDerivDict[phfx+item][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2386    return dMdvh,depDerivDict,wdf
2387   
2388
2389def dervRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg):
2390    '''Loop over histograms and compute derivatives of the fitting
2391    model (M) with respect to all parameters.  Results are returned in
2392    a Jacobian matrix (aka design matrix) of dimensions (n by m) where
2393    n is the number of parameters and m is the number of data
2394    points. This can exceed memory when m gets large. This routine is
2395    used when refinement derivatives are selected as "analtytic
2396    Jacobian" in Controls.
2397
2398    :returns: Jacobian numpy.array dMdv for all histograms concatinated
2399    '''
2400    parmDict.update(zip(varylist,values))
2401    G2mv.Dict2Map(parmDict,varylist)
2402    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
2403    nvar = len(varylist)
2404    dMdv = np.empty(0)
2405    histoList = Histograms.keys()
2406    histoList.sort()
2407    for histogram in histoList:
2408        if 'PWDR' in histogram[:4]:
2409            Histogram = Histograms[histogram]
2410            hId = Histogram['hId']
2411            hfx = ':%d:'%(hId)
2412            wtFactor = calcControls[hfx+'wtFactor']
2413            Limits = calcControls[hfx+'Limits']
2414            x,y,w,yc,yb,yd = Histogram['Data']
2415            xB = np.searchsorted(x,Limits[0])
2416            xF = np.searchsorted(x,Limits[1])
2417            dMdvh = np.sqrt(w[xB:xF])*getPowderProfileDerv(parmDict,x[xB:xF],
2418                varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup)
2419        elif 'HKLF' in histogram[:4]:
2420            Histogram = Histograms[histogram]
2421            phase = Histogram['Reflection Lists']
2422            Phase = Phases[phase]
2423            dMdvh,depDerivDict,wdf = dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict)
2424            hfx = ':%d:'%(Histogram['hId'])
2425            wtFactor = calcControls[hfx+'wtFactor']
2426            # now process derivatives in constraints
2427            G2mv.Dict2Deriv(varylist,depDerivDict,dMdvh)
2428        else:
2429            continue        #skip non-histogram entries
2430        if len(dMdv):
2431            dMdv = np.concatenate((dMdv.T,np.sqrt(wtFactor)*dMdvh.T)).T
2432        else:
2433            dMdv = np.sqrt(wtFactor)*dMdvh
2434           
2435    pNames,pVals,pWt,pWsum = penaltyFxn(HistoPhases,parmDict,varylist)
2436    if np.any(pVals):
2437        dpdv = penaltyDeriv(pNames,pVals,HistoPhases,parmDict,varylist)
2438        dMdv = np.concatenate((dMdv.T,(np.sqrt(pWt)*dpdv).T)).T
2439       
2440    return dMdv
2441
2442def HessRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg):
2443    '''Loop over histograms and compute derivatives of the fitting
2444    model (M) with respect to all parameters.  For each histogram, the
2445    Jacobian matrix, dMdv, with dimensions (n by m) where n is the
2446    number of parameters and m is the number of data points *in the
2447    histogram*. The (n by n) Hessian is computed from each Jacobian
2448    and it is returned.  This routine is used when refinement
2449    derivatives are selected as "analtytic Hessian" in Controls.
2450
2451    :returns: Vec,Hess where Vec is the least-squares vector and Hess is the Hessian
2452    '''
2453    parmDict.update(zip(varylist,values))
2454    G2mv.Dict2Map(parmDict,varylist)
2455    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
2456    ApplyRBModels(parmDict,Phases,rigidbodyDict)        #,Update=True??
2457    nvar = len(varylist)
2458    Hess = np.empty(0)
2459    histoList = Histograms.keys()
2460    histoList.sort()
2461    for histogram in histoList:
2462        if 'PWDR' in histogram[:4]:
2463            Histogram = Histograms[histogram]
2464            hId = Histogram['hId']
2465            hfx = ':%d:'%(hId)
2466            wtFactor = calcControls[hfx+'wtFactor']
2467            Limits = calcControls[hfx+'Limits']
2468            x,y,w,yc,yb,yd = Histogram['Data']
2469            W = wtFactor*w
2470            dy = y-yc
2471            xB = np.searchsorted(x,Limits[0])
2472            xF = np.searchsorted(x,Limits[1])
2473            dMdvh = getPowderProfileDerv(parmDict,x[xB:xF],
2474                varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup)
2475            Wt = ma.sqrt(W[xB:xF])[np.newaxis,:]
2476            Dy = dy[xB:xF][np.newaxis,:]
2477            dMdvh *= Wt
2478            if dlg:
2479                dlg.Update(Histogram['Residuals']['wR'],newmsg='Hessian for histogram %d\nAll data Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))
2480            if len(Hess):
2481                Hess += np.inner(dMdvh,dMdvh)
2482                dMdvh *= Wt*Dy
2483                Vec += np.sum(dMdvh,axis=1)
2484            else:
2485                Hess = np.inner(dMdvh,dMdvh)
2486                dMdvh *= Wt*Dy
2487                Vec = np.sum(dMdvh,axis=1)
2488        elif 'HKLF' in histogram[:4]:
2489            Histogram = Histograms[histogram]
2490            phase = Histogram['Reflection Lists']
2491            Phase = Phases[phase]
2492            dMdvh,depDerivDict,wdf = dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict)
2493            hId = Histogram['hId']
2494            hfx = ':%d:'%(Histogram['hId'])
2495            wtFactor = calcControls[hfx+'wtFactor']
2496            # now process derivatives in constraints
2497            G2mv.Dict2Deriv(varylist,depDerivDict,dMdvh)
2498#            print 'matrix build time: %.3f'%(time.time()-time0)
2499
2500            if dlg:
2501                dlg.Update(Histogram['Residuals']['wR'],newmsg='Hessian for histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0]
2502            if len(Hess):
2503                Vec += wtFactor*np.sum(dMdvh*wdf,axis=1)
2504                Hess += wtFactor*np.inner(dMdvh,dMdvh)
2505            else:
2506                Vec = wtFactor*np.sum(dMdvh*wdf,axis=1)
2507                Hess = wtFactor*np.inner(dMdvh,dMdvh)
2508        else:
2509            continue        #skip non-histogram entries
2510    pNames,pVals,pWt,pWsum = penaltyFxn(HistoPhases,parmDict,varylist)
2511    if np.any(pVals):
2512        dpdv = penaltyDeriv(pNames,pVals,HistoPhases,parmDict,varylist)
2513        Vec += np.sum(dpdv*pWt*pVals,axis=1)
2514        Hess += np.inner(dpdv*pWt,dpdv)
2515    return Vec,Hess
2516
2517def errRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg=None):       
2518    '''Computes the point-by-point discrepancies between every data point in every histogram
2519    and the observed value
2520   
2521    :returns: an np array of differences between observed and computed diffraction values.
2522    '''
2523    Values2Dict(parmDict, varylist, values)
2524    G2mv.Dict2Map(parmDict,varylist)
2525    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
2526    M = np.empty(0)
2527    SumwYo = 0
2528    Nobs = 0
2529    ApplyRBModels(parmDict,Phases,rigidbodyDict)
2530    histoList = Histograms.keys()
2531    histoList.sort()
2532    for histogram in histoList:
2533        if 'PWDR' in histogram[:4]:
2534            Histogram = Histograms[histogram]
2535            hId = Histogram['hId']
2536            hfx = ':%d:'%(hId)
2537            wtFactor = calcControls[hfx+'wtFactor']
2538            Limits = calcControls[hfx+'Limits']
2539            x,y,w,yc,yb,yd = Histogram['Data']
2540            yc *= 0.0                           #zero full calcd profiles
2541            yb *= 0.0
2542            yd *= 0.0
2543            xB = np.searchsorted(x,Limits[0])
2544            xF = np.searchsorted(x,Limits[1])
2545            yc[xB:xF],yb[xB:xF] = getPowderProfile(parmDict,x[xB:xF],
2546                varylist,Histogram,Phases,calcControls,pawleyLookup)
2547            yc[xB:xF] += yb[xB:xF]
2548            if not np.any(y):                   #fill dummy data
2549                rv = st.poisson(yc[xB:xF])
2550                y[xB:xF] = rv.rvs()
2551                Z = np.ones_like(yc[xB:xF])
2552                Z[1::2] *= -1
2553                y[xB:xF] = yc[xB:xF]+np.abs(y[xB:xF]-yc[xB:xF])*Z
2554                w[xB:xF] = np.where(y[xB:xF]>0.,1./y[xB:xF],1.0)
2555            yd[xB:xF] = y[xB:xF]-yc[xB:xF]
2556            W = wtFactor*w
2557            wdy = -ma.sqrt(W[xB:xF])*(yd[xB:xF])
2558            Histogram['Residuals']['Nobs'] = ma.count(x[xB:xF])
2559            Nobs += Histogram['Residuals']['Nobs']
2560            Histogram['Residuals']['sumwYo'] = ma.sum(W[xB:xF]*y[xB:xF]**2)
2561            SumwYo += Histogram['Residuals']['sumwYo']
2562            Histogram['Residuals']['R'] = min(100.,ma.sum(ma.abs(yd[xB:xF]))/ma.sum(y[xB:xF])*100.)
2563            Histogram['Residuals']['wR'] = min(100.,ma.sqrt(ma.sum(wdy**2)/Histogram['Residuals']['sumwYo'])*100.)
2564            sumYmB = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],ma.abs(y[xB:xF]-yb[xB:xF]),0.))
2565            sumwYmB2 = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],W[xB:xF]*(y[xB:xF]-yb[xB:xF])**2,0.))
2566            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.))
2567            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.))
2568            Histogram['Residuals']['Rb'] = min(100.,100.*sumYB/sumYmB)
2569            Histogram['Residuals']['wRb'] = min(100.,100.*ma.sqrt(sumwYB2/sumwYmB2))
2570            Histogram['Residuals']['wRmin'] = min(100.,100.*ma.sqrt(Histogram['Residuals']['Nobs']/Histogram['Residuals']['sumwYo']))
2571            if dlg:
2572                dlg.Update(Histogram['Residuals']['wR'],newmsg='For histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0]
2573            M = np.concatenate((M,wdy))
2574#end of PWDR processing
2575        elif 'HKLF' in histogram[:4]:
2576            Histogram = Histograms[histogram]
2577            Histogram['Residuals'] = {}
2578            phase = Histogram['Reflection Lists']
2579            Phase = Phases[phase]
2580            hId = Histogram['hId']
2581            hfx = ':%d:'%(hId)
2582            wtFactor = calcControls[hfx+'wtFactor']
2583            pfx = '%d::'%(Phase['pId'])
2584            phfx = '%d:%d:'%(Phase['pId'],hId)
2585            SGData = Phase['General']['SGData']
2586            im = 0
2587            if Phase['General']['Type'] in ['modulated','magnetic']:
2588                SSGData = Phase['General']['SSGData']
2589                SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
2590                im = 1  #offset in SS reflection list
2591                #??
2592            A = [parmDict[pfx+'A%d'%(i)] for i in range(6)]
2593            G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
2594            refDict = Histogram['Data']
2595            time0 = time.time()
2596            if im:
2597                SStructureFactor(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
2598            else:
2599                StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
2600#            print 'sf-calc time: %.3f'%(time.time()-time0)
2601            df = np.zeros(len(refDict['RefList']))
2602            sumwYo = 0
2603            sumFo = 0
2604            sumFo2 = 0
2605            sumdF = 0
2606            sumdF2 = 0
2607            nobs = 0
2608            if calcControls['F**2']:
2609                for i,ref in enumerate(refDict['RefList']):
2610                    if ref[6+im] > 0:
2611                        ref[11+im] = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist)[0]
2612                        w = 1.0/ref[6+im]
2613                        ref[7+im] = parmDict[phfx+'Scale']*ref[9+im]*ref[11+im]  #correct Fc^2 for extinction
2614                        ref[8+im] = ref[5+im]/(parmDict[phfx+'Scale']*ref[11+im])
2615                        if w*ref[5+im] >= calcControls['minF/sig']:
2616                            Fo = np.sqrt(ref[5+im])
2617                            sumFo += Fo
2618                            sumFo2 += ref[5+im]
2619                            sumdF += abs(Fo-np.sqrt(ref[7+im]))
2620                            sumdF2 += abs(ref[5+im]-ref[7+im])
2621                            nobs += 1
2622                            df[i] = -w*(ref[5+im]-ref[7+im])
2623                            sumwYo += (w*ref[5+im])**2
2624            else:
2625                for i,ref in enumerate(refDict['RefList']):
2626                    if ref[5+im] > 0.:
2627                        ref[11+im] = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist)[0]
2628                        ref[7+im] = parmDict[phfx+'Scale']*ref[9+im]*ref[11+im]    #correct Fc^2 for extinction
2629                        ref[8+im] = ref[5+im]/(parmDict[phfx+'Scale']*ref[11+im])
2630                        Fo = np.sqrt(ref[5+im])
2631                        Fc = np.sqrt(ref[7+im])
2632                        w = 2.0*Fo/ref[6+im]
2633                        if w*Fo >= calcControls['minF/sig']:
2634                            sumFo += Fo
2635                            sumFo2 += ref[5+im]
2636                            sumdF += abs(Fo-Fc)
2637                            sumdF2 += abs(ref[5+im]-ref[7+im])
2638                            nobs += 1
2639                            df[i] = -w*(Fo-Fc)
2640                            sumwYo += (w*Fo)**2
2641            Histogram['Residuals']['Nobs'] = nobs
2642            Histogram['Residuals']['sumwYo'] = sumwYo
2643            SumwYo += sumwYo
2644            Histogram['Residuals']['wR'] = min(100.,np.sqrt(np.sum(df**2)/Histogram['Residuals']['sumwYo'])*100.)
2645            Histogram['Residuals'][phfx+'Rf'] = 100.*sumdF/sumFo
2646            Histogram['Residuals'][phfx+'Rf^2'] = 100.*sumdF2/sumFo2
2647            Histogram['Residuals'][phfx+'Nref'] = nobs
2648            Nobs += nobs
2649            if dlg:
2650                dlg.Update(Histogram['Residuals']['wR'],newmsg='For histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0]
2651            M = np.concatenate((M,wtFactor*df))
2652# end of HKLF processing
2653    Histograms['sumwYo'] = SumwYo
2654    Histograms['Nobs'] = Nobs
2655    Rw = min(100.,np.sqrt(np.sum(M**2)/SumwYo)*100.)
2656    if dlg:
2657        GoOn = dlg.Update(Rw,newmsg='%s%8.3f%s'%('All data Rw =',Rw,'%'))[0]
2658        if not GoOn:
2659            parmDict['saved values'] = values
2660            dlg.Destroy()
2661            raise Exception         #Abort!!
2662    pDict,pVals,pWt,pWsum = penaltyFxn(HistoPhases,parmDict,varylist)
2663    if len(pVals):
2664        pSum = np.sum(pWt*pVals**2)
2665        for name in pWsum:
2666            if pWsum:
2667                print '  Penalty function for %8s = %12.5g'%(name,pWsum[name])
2668        print 'Total penalty function: %12.5g on %d terms'%(pSum,len(pVals))
2669        Nobs += len(pVals)
2670        M = np.concatenate((M,np.sqrt(pWt)*pVals))
2671    return M
2672                       
Note: See TracBrowser for help on using the repository browser.