source: trunk/GSASIIstrMath.py @ 1977

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

More modulation structure factor stuff, begin SSF derivatives

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 147.8 KB
Line 
1# -*- coding: utf-8 -*-
2'''
3*GSASIIstrMath - structure math routines*
4-----------------------------------------
5'''
6########### SVN repository information ###################
7# $Date: 2015-09-23 20:28:12 +0000 (Wed, 23 Sep 2015) $
8# $Author: vondreele $
9# $Revision: 1977 $
10# $URL: trunk/GSASIIstrMath.py $
11# $Id: GSASIIstrMath.py 1977 2015-09-23 20:28:12Z vondreele $
12########### SVN repository information ###################
13import time
14import copy
15import numpy as np
16import numpy.ma as ma
17import numpy.linalg as nl
18import scipy.optimize as so
19import scipy.stats as st
20import GSASIIpath
21GSASIIpath.SetVersionNumber("$Revision: 1977 $")
22import GSASIIElem as G2el
23import GSASIIlattice as G2lat
24import GSASIIspc as G2spc
25import GSASIIpwd as G2pwd
26import GSASIImapvars as G2mv
27import GSASIImath as G2mth
28import GSASIIobj as G2obj
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*np.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,calcControls,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*(-Z1[ind[0]][ind[1]]/esd1)**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*(Z2/esd2)**2
399       
400    for phase in Phases:
401        name = 'SH-Pref.Ori.'
402        pId = Phases[phase]['pId']
403        General = Phases[phase]['General']
404        SGData = General['SGData']
405        cell = General['Cell'][1:7]
406        pWsum[name] = 0.0
407        for hist in Phases[phase]['Histograms']:
408            if hist in Histograms and 'PWDR' in hist:
409                hId = Histograms[hist]['hId']
410                phfx = '%d:%d:'%(pId,hId)
411                if calcControls[phfx+'poType'] == 'SH':
412                    toler = calcControls[phfx+'SHtoler']
413                    wt = 1./toler**2
414                    HKLs = np.array(calcControls[phfx+'SHhkl'])
415                    SHnames = calcControls[phfx+'SHnames']
416                    SHcof = dict(zip(SHnames,[parmDict[phfx+cof] for cof in SHnames]))
417                    for i,PH in enumerate(HKLs):
418                        phi,beta = G2lat.CrsAng(PH,cell,SGData)
419                        SH3Coef = {}
420                        for item in SHcof:
421                            L,N = eval(item.strip('C'))
422                            SH3Coef['C%d,0,%d'%(L,N)] = SHcof[item]                       
423                        ODFln = G2lat.Flnh(False,SH3Coef,phi,beta,SGData)
424                        X = np.linspace(0,90.0,26)
425                        Y = -ma.masked_greater(G2lat.polfcal(ODFln,'0',X,0.0),0.0)
426                        IndY = ma.nonzero(Y)
427                        for ind in IndY[0]:
428                            pNames.append('%d:%d:%s:%d:%.2f'%(pId,hId,name,i,X[ind]))
429                            pVals.append(Y[ind])
430                            pWt.append(wt)
431                            pWsum[name] += wt*(Y[ind])**2
432    pWsum['PWLref'] = 0.
433    for item in varyList:
434        if 'PWLref' in item and parmDict[item] < 0.:
435            pId = int(item.split(':')[0])
436            if negWt[pId]:
437                pNames.append(item)
438                pVals.append(-parmDict[item])
439                pWt.append(negWt[pId])
440                pWsum['PWLref'] += negWt[pId]*(-parmDict[item])**2
441    pVals = np.array(pVals)
442    pWt = np.array(pWt)         #should this be np.sqrt?
443    return pNames,pVals,pWt,pWsum
444   
445def penaltyDeriv(pNames,pVal,HistoPhases,calcControls,parmDict,varyList):
446    'Needs a doc string'
447    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
448    pDerv = np.zeros((len(varyList),len(pVal)))
449    for phase in Phases:
450#        if phase not in restraintDict:
451#            continue
452        pId = Phases[phase]['pId']
453        General = Phases[phase]['General']
454        cx,ct,cs,cia = General['AtomPtrs']
455        SGData = General['SGData']
456        AtLookup = G2mth.FillAtomLookUp(Phases[phase]['Atoms'],cia+8)
457        cell = General['Cell'][1:7]
458        Amat,Bmat = G2lat.cell2AB(cell)
459        textureData = General['SH Texture']
460
461        SHkeys = textureData['SH Coeff'][1].keys()
462        SHCoef = G2mth.GetSHCoeff(pId,parmDict,SHkeys)
463        shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
464        SamSym = dict(zip(shModels,['0','-1','2/m','mmm']))
465        sam = SamSym[textureData['Model']]
466        phaseRest = restraintDict.get(phase,{})
467        names = {'Bond':'Bonds','Angle':'Angles','Plane':'Planes',
468            'Chiral':'Volumes','Torsion':'Torsions','Rama':'Ramas',
469            'ChemComp':'Sites','Texture':'HKLs'}
470        lasthkl = np.array([0,0,0])
471        for ip,pName in enumerate(pNames):
472            pnames = pName.split(':')
473            if pId == int(pnames[0]):
474                name = pnames[1]
475                if 'PWL' in pName:
476                    pDerv[varyList.index(pName)][ip] += 1.
477                    continue
478                elif 'SH-' in pName:
479                    continue
480                id = int(pnames[2]) 
481                itemRest = phaseRest[name]
482                if name in ['Bond','Angle','Plane','Chiral']:
483                    indx,ops,obs,esd = itemRest[names[name]][id]
484                    dNames = []
485                    for ind in indx:
486                        dNames += [str(pId)+'::dA'+Xname+':'+str(AtLookup[ind]) for Xname in ['x','y','z']]
487                    XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx))
488                    if name == 'Bond':
489                        deriv = G2mth.getRestDeriv(G2mth.getRestDist,XYZ,Amat,ops,SGData)
490                    elif name == 'Angle':
491                        deriv = G2mth.getRestDeriv(G2mth.getRestAngle,XYZ,Amat,ops,SGData)
492                    elif name == 'Plane':
493                        deriv = G2mth.getRestDeriv(G2mth.getRestPlane,XYZ,Amat,ops,SGData)
494                    elif name == 'Chiral':
495                        deriv = G2mth.getRestDeriv(G2mth.getRestChiral,XYZ,Amat,ops,SGData)
496                elif name in ['Torsion','Rama']:
497                    coffDict = itemRest['Coeff']
498                    indx,ops,cofName,esd = itemRest[names[name]][id]
499                    dNames = []
500                    for ind in indx:
501                        dNames += [str(pId)+'::dA'+Xname+':'+str(AtLookup[ind]) for Xname in ['x','y','z']]
502                    XYZ = np.array(G2mth.GetAtomCoordsByID(pId,parmDict,AtLookup,indx))
503                    if name == 'Torsion':
504                        deriv = G2mth.getTorsionDeriv(XYZ,Amat,coffDict[cofName])
505                    else:
506                        deriv = G2mth.getRamaDeriv(XYZ,Amat,coffDict[cofName])
507                elif name == 'ChemComp':
508                    indx,factors,obs,esd = itemRest[names[name]][id]
509                    dNames = []
510                    for ind in indx:
511                        dNames += [str(pId)+'::Afrac:'+str(AtLookup[ind])]
512                        mul = np.array(G2mth.GetAtomItemsById(Atoms,AtLookUp,indx,cs+1))
513                        deriv = mul*factors
514                elif 'Texture' in name:
515                    deriv = []
516                    dNames = []
517                    hkl,grid,esd1,ifesd2,esd2 = itemRest[names[name]][id]
518                    hkl = np.array(hkl)
519                    if np.any(lasthkl-hkl):
520                        PH = np.array(hkl)
521                        phi,beta = G2lat.CrsAng(np.array(hkl),cell,SGData)
522                        ODFln = G2lat.Flnh(False,SHCoef,phi,beta,SGData)
523                        lasthkl = copy.copy(hkl)                       
524                    if 'unit' in name:
525                        pass
526                    else:
527                        gam = float(pnames[3])
528                        psi = float(pnames[4])
529                        for SHname in ODFln:
530                            l,m,n = eval(SHname[1:])
531                            Ksl = G2lat.GetKsl(l,m,sam,psi,gam)[0]
532                            dNames += [str(pId)+'::'+SHname]
533                            deriv.append(-ODFln[SHname][0]*Ksl/SHCoef[SHname])
534                for dName,drv in zip(dNames,deriv):
535                    try:
536                        ind = varyList.index(dName)
537                        pDerv[ind][ip] += drv
538                    except ValueError:
539                        pass
540       
541        lasthkl = np.array([0,0,0])
542        for ip,pName in enumerate(pNames):
543            deriv = []
544            dNames = []
545            pnames = pName.split(':')
546            if 'SH-' in pName and pId == int(pnames[0]):
547                hId = int(pnames[1])
548                phfx = '%d:%d:'%(pId,hId)
549                psi = float(pnames[4])
550                HKLs = calcControls[phfx+'SHhkl']
551                SHnames = calcControls[phfx+'SHnames']
552                SHcof = dict(zip(SHnames,[parmDict[phfx+cof] for cof in SHnames]))
553                hkl = np.array(HKLs[int(pnames[3])])     
554                if np.any(lasthkl-hkl):
555                    PH = np.array(hkl)
556                    phi,beta = G2lat.CrsAng(np.array(hkl),cell,SGData)
557                    SH3Coef = {}
558                    for item in SHcof:
559                        L,N = eval(item.strip('C'))
560                        SH3Coef['C%d,0,%d'%(L,N)] = SHcof[item]                       
561                    ODFln = G2lat.Flnh(False,SH3Coef,phi,beta,SGData)
562                    lasthkl = copy.copy(hkl)                       
563                for SHname in SHnames:
564                    l,n = eval(SHname[1:])
565                    SH3name = 'C%d,0,%d'%(l,n)
566                    Ksl = G2lat.GetKsl(l,0,'0',psi,0.0)[0]
567                    dNames += [phfx+SHname]
568                    deriv.append(ODFln[SH3name][0]*Ksl/SHcof[SHname])
569            for dName,drv in zip(dNames,deriv):
570                try:
571                    ind = varyList.index(dName)
572                    pDerv[ind][ip] += drv
573                except ValueError:
574                    pass
575    return pDerv
576
577################################################################################
578##### Function & derivative calculations
579################################################################################       
580                   
581def GetAtomFXU(pfx,calcControls,parmDict):
582    'Needs a doc string'
583    Natoms = calcControls['Natoms'][pfx]
584    Tdata = Natoms*[' ',]
585    Mdata = np.zeros(Natoms)
586    IAdata = Natoms*[' ',]
587    Fdata = np.zeros(Natoms)
588    FFdata = []
589    BLdata = []
590    Xdata = np.zeros((3,Natoms))
591    dXdata = np.zeros((3,Natoms))
592    Uisodata = np.zeros(Natoms)
593    Uijdata = np.zeros((6,Natoms))
594    keys = {'Atype:':Tdata,'Amul:':Mdata,'Afrac:':Fdata,'AI/A:':IAdata,
595        'dAx:':dXdata[0],'dAy:':dXdata[1],'dAz:':dXdata[2],
596        'Ax:':Xdata[0],'Ay:':Xdata[1],'Az:':Xdata[2],'AUiso:':Uisodata,
597        'AU11:':Uijdata[0],'AU22:':Uijdata[1],'AU33:':Uijdata[2],
598        'AU12:':Uijdata[3],'AU13:':Uijdata[4],'AU23:':Uijdata[5]}
599    for iatm in range(Natoms):
600        for key in keys:
601            parm = pfx+key+str(iatm)
602            if parm in parmDict:
603                keys[key][iatm] = parmDict[parm]
604    Fdata = np.where(Fdata,Fdata,1.e-8)         #avoid divide by zero in derivative calc.
605    return Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata
606   
607def GetAtomSSFXU(pfx,calcControls,parmDict):
608    'Needs a doc string'
609    Natoms = calcControls['Natoms'][pfx]
610    maxSSwave = calcControls['maxSSwave'][pfx]
611    Nwave = {'F':maxSSwave['Sfrac'],'X':maxSSwave['Spos'],'Y':maxSSwave['Spos'],'Z':maxSSwave['Spos'],
612        'U':maxSSwave['Sadp'],'M':maxSSwave['Smag'],'T':maxSSwave['Spos']}
613    XSSdata = np.zeros((6,maxSSwave['Spos'],Natoms))
614    FSSdata = np.zeros((2,maxSSwave['Sfrac'],Natoms))
615    USSdata = np.zeros((12,maxSSwave['Sadp'],Natoms))
616    MSSdata = np.zeros((6,maxSSwave['Smag'],Natoms))
617    waveTypes = []
618    keys = {'Fsin:':FSSdata[0],'Fcos:':FSSdata[1],'Fzero:':FSSdata[0],'Fwid:':FSSdata[1],
619        'Tzero:':XSSdata[0],'Xslope:':XSSdata[1],'Yslope:':XSSdata[2],'Zslope:':XSSdata[3],
620        'Xsin:':XSSdata[0],'Ysin:':XSSdata[1],'Zsin:':XSSdata[2],'Xcos:':XSSdata[3],'Ycos:':XSSdata[4],'Zcos:':XSSdata[5],
621        'U11sin:':USSdata[0],'U22sin:':USSdata[1],'U33sin:':USSdata[2],'U12sin:':USSdata[3],'U13sin:':USSdata[4],'U23sin:':USSdata[5],
622        'U11cos:':USSdata[6],'U22cos:':USSdata[7],'U33cos:':USSdata[8],'U12cos:':USSdata[9],'U13cos:':USSdata[10],'U23cos:':USSdata[11],
623        'MXsin:':MSSdata[0],'MYsin:':MSSdata[1],'MZsin:':MSSdata[2],'MXcos:':MSSdata[3],'MYcos:':MSSdata[4],'MZcos:':MSSdata[5]}
624    for iatm in range(Natoms):
625        waveTypes.append(parmDict[pfx+'waveType:'+str(iatm)])
626        for key in keys:
627            for m in range(Nwave[key[0]]):
628                parm = pfx+key+str(iatm)+':%d'%(m)
629                if parm in parmDict:
630                    keys[key][m][iatm] = parmDict[parm]
631    return waveTypes,FSSdata,XSSdata,USSdata,MSSdata
632   
633def GetSSTauM(SGOps,SSOps,pfx,calcControls,XData):
634   
635    Natoms = calcControls['Natoms'][pfx]
636    maxSSwave = calcControls['maxSSwave'][pfx]
637    Smult = np.zeros((Natoms,len(SGOps)))
638    TauT = np.zeros((Natoms,len(SGOps)))
639    for ix,xyz in enumerate(XData.T):
640        for isym,(sop,ssop) in enumerate(zip(SGOps,SSOps)):
641            sdet,ssdet,dtau,dT,tauT = G2spc.getTauT(0,sop,ssop,xyz)
642            Smult[ix][isym] = sdet
643            TauT[ix][isym] = tauT
644    return Smult,TauT
645   
646def StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict):
647    ''' Compute structure factors for all h,k,l for phase
648    puts the result, F^2, in each ref[8] in refList
649    input:
650   
651    :param dict refDict: where
652        'RefList' list where each ref = h,k,l,m,d,...
653        'FF' dict of form factors - filed in below
654    :param np.array G:      reciprocal metric tensor
655    :param str pfx:    phase id string
656    :param dict SGData: space group info. dictionary output from SpcGroup
657    :param dict calcControls:
658    :param dict ParmDict:
659
660    '''       
661    phfx = pfx.split(':')[0]+hfx
662    ast = np.sqrt(np.diag(G))
663    Mast = twopisq*np.multiply.outer(ast,ast)
664    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
665    SGT = np.array([ops[1] for ops in SGData['SGOps']])
666    FFtables = calcControls['FFtables']
667    BLtables = calcControls['BLtables']
668    Flack = 1.0
669    if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict:
670        Flack = 1.-2.*parmDict[phfx+'Flack']
671    TwinLaw = np.array([[[1,0,0],[0,1,0],[0,0,1]],])
672    TwDict = refDict.get('TwDict',{})           
673    if 'S' in calcControls[hfx+'histType']:
674        NTL = calcControls[phfx+'NTL']
675        NM = calcControls[phfx+'TwinNMN']+1
676        TwinLaw = calcControls[phfx+'TwinLaw']
677        TwinFr = np.array([parmDict[phfx+'TwinFr:'+str(i)] for i in range(len(TwinLaw))])
678        TwinInv = list(np.where(calcControls[phfx+'TwinInv'],-1,1))
679    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
680    FF = np.zeros(len(Tdata))
681    if 'NC' in calcControls[hfx+'histType']:
682        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
683    elif 'X' in calcControls[hfx+'histType']:
684        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
685        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
686    Uij = np.array(G2lat.U6toUij(Uijdata))
687    bij = Mast*Uij.T
688    blkSize = 100       #no. of reflections in a block
689    nRef = refDict['RefList'].shape[0]
690    if not len(refDict['FF']):                #no form factors - 1st time thru StructureFactor
691        if 'N' in calcControls[hfx+'histType']:
692            dat = G2el.getBLvalues(BLtables)
693            refDict['FF']['El'] = dat.keys()
694            refDict['FF']['FF'] = np.ones((nRef,len(dat)))*dat.values()           
695        else:       #'X'
696            dat = G2el.getFFvalues(FFtables,0.)
697            refDict['FF']['El'] = dat.keys()
698            refDict['FF']['FF'] = np.ones((nRef,len(dat)))
699            for iref,ref in enumerate(refDict['RefList']):
700                SQ = 1./(2.*ref[4])**2
701                dat = G2el.getFFvalues(FFtables,SQ)
702                refDict['FF']['FF'][iref] *= dat.values()
703#reflection processing begins here - big arrays!
704    iBeg = 0
705    while iBeg < nRef:
706        iFin = min(iBeg+blkSize,nRef)
707        refl = refDict['RefList'][iBeg:iFin]    #array(blkSize,nItems)
708        H = refl.T[:3]                          #array(blkSize,3)
709        H = np.squeeze(np.inner(H.T,TwinLaw))   #maybe array(blkSize,nTwins,3) or (blkSize,3)
710        TwMask = np.any(H,axis=-1)
711        if TwinLaw.shape[0] > 1 and TwDict: #need np.inner(TwinLaw[?],TwDict[iref][i])*TwinInv[i]
712            for ir in range(blkSize):
713                iref = ir+iBeg
714                if iref in TwDict:
715                    for i in TwDict[iref]:
716                        for n in range(NTL):
717                            H[ir][i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM])
718            TwMask = np.any(H,axis=-1)
719        SQ = 1./(2.*refl.T[4])**2               #array(blkSize)
720        SQfactor = 4.0*SQ*twopisq               #ditto prev.
721        if 'T' in calcControls[hfx+'histType']:
722            if 'P' in calcControls[hfx+'histType']:
723                FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[14])
724            else:
725                FP,FPP = G2el.BlenResTOF(Tdata,BLtables,refl.T[12])
726            FP = np.repeat(FP.T,len(SGT)*len(TwinLaw),axis=0)
727            FPP = np.repeat(FPP.T,len(SGT)*len(TwinLaw),axis=0)
728        Bab = np.repeat(parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor),len(SGT)*len(TwinLaw))
729        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
730        FF = np.repeat(refDict['FF']['FF'][iBeg:iFin].T[Tindx].T,len(SGT)*len(TwinLaw),axis=0)
731        Uniq = np.inner(H,SGMT)
732        Phi = np.inner(H,SGT)
733        phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T).T+Phi.T).T
734        sinp = np.sin(phase)
735        cosp = np.cos(phase)
736        biso = -SQfactor*Uisodata[:,np.newaxis]
737        Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT)*len(TwinLaw),axis=1).T
738        HbH = -np.sum(Uniq.T*np.swapaxes(np.inner(bij,Uniq),2,-1),axis=1)
739        Tuij = np.where(HbH<1.,np.exp(HbH),1.0).T
740        Tcorr = np.reshape(Tiso,Tuij.shape)*Tuij*Mdata*Fdata/len(SGMT)
741        if 'T' in calcControls[hfx+'histType']:
742            fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-np.reshape(Flack*FPP,sinp.shape)*sinp*Tcorr])
743            fb = np.array([np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr,np.reshape(Flack*FPP,cosp.shape)*cosp*Tcorr])
744        else:
745            fa = np.array([np.reshape(((FF+FP).T-Bab).T,cosp.shape)*cosp*Tcorr,-Flack*FPP*sinp*Tcorr])
746            fb = np.array([np.reshape(((FF+FP).T-Bab).T,sinp.shape)*sinp*Tcorr,Flack*FPP*cosp*Tcorr])
747        fas = np.sum(np.sum(fa,axis=-1),axis=-1)       #real sum over atoms & unique hkl
748        fbs = np.sum(np.sum(fb,axis=-1),axis=-1)  #imag sum over atoms & uniq hkl
749        if SGData['SGInv']: #centrosymmetric; B=0
750            fbs[0] *= 0.
751        if 'P' in calcControls[hfx+'histType']:
752            refl.T[9] = np.sum(fas**2,axis=0)+np.sum(fbs**2,axis=0)
753            refl.T[10] = atan2d(fbs[0],fas[0])  #ignore f' & f"
754        else:
755            if len(TwinLaw) > 1:
756                refl.T[9] = np.sum(fas[:,:,0]**2,axis=0)+np.sum(fbs[:,:,0]**2,axis=0)   #FcT from primary twin element
757                refl.T[7] = np.sum(TwinFr*np.sum(TwMask[np.newaxis,:,:]*fas,axis=0)**2,axis=-1)+   \
758                    np.sum(TwinFr*np.sum(TwMask[np.newaxis,:,:]*fbs,axis=0)**2,axis=-1)                        #Fc sum over twins
759                refl.T[10] = atan2d(fbs[0].T[0],fas[0].T[0])  #ignore f' & f"
760            else:
761                refl.T[9] = np.sum(fas,axis=0)**2+np.sum(fbs,axis=0)**2
762                refl.T[7] = np.copy(refl.T[9])               
763                refl.T[10] = atan2d(fbs[0],fas[0])  #ignore f' & f"
764#        refl.T[10] = atan2d(np.sum(fbs,axis=0),np.sum(fas,axis=0)) #include f' & f"
765        iBeg += blkSize
766   
767def StructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict):
768    'Needs a doc string'
769    phfx = pfx.split(':')[0]+hfx
770    ast = np.sqrt(np.diag(G))
771    Mast = twopisq*np.multiply.outer(ast,ast)
772    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
773    SGT = np.array([ops[1] for ops in SGData['SGOps']])
774    FFtables = calcControls['FFtables']
775    BLtables = calcControls['BLtables']
776    TwinLaw = np.array([[[1,0,0],[0,1,0],[0,0,1]],])
777    TwDict = refDict.get('TwDict',{})           
778    if 'S' in calcControls[hfx+'histType']:
779        NTL = calcControls[phfx+'NTL']
780        NM = calcControls[phfx+'TwinNMN']+1
781        TwinLaw = calcControls[phfx+'TwinLaw']
782        TwinFr = np.array([parmDict[phfx+'TwinFr:'+str(i)] for i in range(len(TwinLaw))])
783        TwinInv = list(np.where(calcControls[phfx+'TwinInv'],-1,1))
784    nTwin = len(TwinLaw)       
785    nRef = len(refDict['RefList'])
786    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
787    mSize = len(Mdata)
788    FF = np.zeros(len(Tdata))
789    if 'NC' in calcControls[hfx+'histType']:
790        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
791    elif 'X' in calcControls[hfx+'histType']:
792        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
793        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
794    Uij = np.array(G2lat.U6toUij(Uijdata))
795    bij = Mast*Uij.T
796    dFdvDict = {}
797    if nTwin > 1:
798        dFdfr = np.zeros((nRef,nTwin,mSize))
799        dFdx = np.zeros((nRef,nTwin,mSize,3))
800        dFdui = np.zeros((nRef,nTwin,mSize))
801        dFdua = np.zeros((nRef,nTwin,mSize,6))
802        dFdbab = np.zeros((nRef,nTwin,2))
803        dFdfl = np.zeros((nRef,nTwin))
804        dFdtw = np.zeros((nRef,nTwin))
805    else:
806        dFdfr = np.zeros((nRef,mSize))
807        dFdx = np.zeros((nRef,mSize,3))
808        dFdui = np.zeros((nRef,mSize))
809        dFdua = np.zeros((nRef,mSize,6))
810        dFdbab = np.zeros((nRef,2))
811        dFdfl = np.zeros((nRef))
812        dFdtw = np.zeros((nRef))
813    Flack = 1.0
814    if not SGData['SGInv'] and 'S' in calcControls[hfx+'histType'] and phfx+'Flack' in parmDict:
815        Flack = 1.-2.*parmDict[phfx+'Flack']
816    time0 = time.time()
817    nref = len(refDict['RefList'])/100   
818    for iref,refl in enumerate(refDict['RefList']):
819        if 'T' in calcControls[hfx+'histType']:
820            FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl.T[12])
821        H = np.array(refl[:3])
822        H = np.squeeze(np.inner(H.T,TwinLaw))   #maybe array(3,nTwins) or (3)
823        TwMask = np.any(H,axis=-1)
824        if TwinLaw.shape[0] > 1 and TwDict:
825            if iref in TwDict:
826                for i in TwDict[iref]:
827                    for n in range(NTL):
828                        H[i+n*NM] = np.inner(TwinLaw[n*NM],np.array(TwDict[iref][i])*TwinInv[i+n*NM])
829            TwMask = np.any(H,axis=-1)
830        SQ = 1./(2.*refl[4])**2             # or (sin(theta)/lambda)**2
831        SQfactor = 8.0*SQ*np.pi**2
832        dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor)
833        Bab = parmDict[phfx+'BabA']*dBabdA
834        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
835        FF = refDict['FF']['FF'][iref].T[Tindx].T
836        Uniq = np.inner(H,SGMT)             # array(nSGOp,3) or (nTwin,nSGOp,3)
837        Phi = np.inner(H,SGT)
838        phase = twopi*(np.inner(Uniq,(dXdata+Xdata).T).T+Phi.T).T
839        sinp = np.sin(phase)
840        cosp = np.cos(phase)
841        occ = Mdata*Fdata/len(SGT)
842        biso = -SQfactor*Uisodata[:,np.newaxis]
843        Tiso = np.repeat(np.where(biso<1.,np.exp(biso),1.0),len(SGT)*nTwin,axis=1)
844        HbH = -np.sum(Uniq.T*np.swapaxes(np.inner(bij,Uniq),2,-1),axis=1)
845        Hij = np.array([Mast*np.multiply.outer(U,U) for U in np.reshape(Uniq,(-1,3))])
846        Hij = np.squeeze(np.reshape(np.array([G2lat.UijtoU6(Uij) for Uij in Hij]),(nTwin,-1,6)))
847        Tuij = np.where(HbH<1.,np.exp(HbH),1.0)
848        Tcorr = (np.reshape(Tiso,Tuij.shape)*Tuij).T*occ
849        fot = (FF+FP-Bab)*Tcorr
850        fotp = FPP*Tcorr       
851        fa = np.array([((FF+FP).T-Bab).T*cosp*Tcorr,-Flack*FPP*sinp*Tcorr]) # array(2,nTwin,nEqv,nAtoms)
852        fb = np.array([((FF+FP).T-Bab).T*sinp*Tcorr,Flack*FPP*cosp*Tcorr])
853        fas = np.sum(np.sum(fa,axis=-1),axis=-1)      #real sum over atoms & unique hkl array(2,nTwins)
854        fbs = np.sum(np.sum(fb,axis=-1),axis=-1)      #imag sum over atoms & uniq hkl
855        fax = np.array([-fot*sinp,-fotp*cosp])   #positions array(2,ntwi,nEqv,nAtoms)
856        fbx = np.array([fot*cosp,-fotp*sinp])
857        #sum below is over Uniq
858        dfadfr = np.sum(fa/occ,axis=-2)        #array(2,ntwin,nAtom) Fdata != 0 avoids /0. problem
859        dfadba = np.sum(-cosp*Tcorr[:,np.newaxis],axis=1)
860        dfadui = np.sum(-SQfactor*fa,axis=-2)
861        if nTwin > 1:
862            dfadx = np.array([np.sum(twopi*Uniq[it]*np.swapaxes(fax,-2,-1)[:,it,:,:,np.newaxis],axis=-2) for it in range(nTwin)])
863            dfadua = np.array([np.sum(-Hij[it]*np.swapaxes(fa,-2,-1)[:,it,:,:,np.newaxis],axis=-2) for it in range(nTwin)])
864            # array(nTwin,2,nAtom,3) & array(nTwin,2,nAtom,6)
865        else:
866            dfadx = np.sum(twopi*Uniq*np.swapaxes(fax,-2,-1)[:,:,:,np.newaxis],axis=-2)
867            dfadua = np.sum(-Hij*np.swapaxes(fa,-2,-1)[:,:,:,np.newaxis],axis=-2)
868            # array(2,nAtom,3) & array(2,nAtom,6)
869        if not SGData['SGInv']:
870            dfbdfr = np.sum(fb/occ,axis=-2)        #Fdata != 0 avoids /0. problem
871            dfbdba = np.sum(-sinp*Tcorr[:,np.newaxis],axis=1)
872            dfbdui = np.sum(-SQfactor*fb,axis=-2)
873            if len(TwinLaw) > 1:
874                dfbdx = np.array([np.sum(twopi*Uniq[it]*np.swapaxes(fbx,-2,-1)[:,it,:,:,np.newaxis],axis=2) for it in range(nTwin)])           
875                dfbdua = np.array([np.sum(-Hij[it]*np.swapaxes(fb,-2,-1)[:,it,:,:,np.newaxis],axis=2) for it in range(nTwin)])
876            else:
877                dfadfl = np.sum(-FPP*Tcorr*sinp)
878                dfbdfl = np.sum(FPP*Tcorr*cosp)
879                dfbdx = np.sum(twopi*Uniq*np.swapaxes(fbx,-2,-1)[:,:,:,np.newaxis],axis=2)           
880                dfbdua = np.sum(-Hij*np.swapaxes(fb,-2,-1)[:,:,:,np.newaxis],axis=2)
881        else:
882            dfbdfr = np.zeros_like(dfadfr)
883            dfbdx = np.zeros_like(dfadx)
884            dfbdui = np.zeros_like(dfadui)
885            dfbdua = np.zeros_like(dfadua)
886            dfbdba = np.zeros_like(dfadba)
887            dfadfl = 0.0
888            dfbdfl = 0.0
889        #NB: the above have been checked against PA(1:10,1:2) in strfctr.for for Al2O3!   
890        if 'P' in calcControls[hfx+'histType']: #checked perfect for centro & noncentro
891            dFdfr[iref] = 2.*(fas[0]*dfadfr[0]+fas[1]*dfadfr[1])*Mdata/len(Uniq)+   \
892                2.*(fbs[0]*dfbdfr[0]-fbs[1]*dfbdfr[1])*Mdata/len(Uniq)
893            dFdx[iref] = 2.*(fas[0]*dfadx[0]+fas[1]*dfadx[1])+  \
894                2.*(fbs[0]*dfbdx[0]+fbs[1]*dfbdx[1])
895            dFdui[iref] = 2.*(fas[0]*dfadui[0]+fas[1]*dfadui[1])+   \
896                2.*(fbs[0]*dfbdui[0]-fbs[1]*dfbdui[1])
897            dFdua[iref] = 2.*(fas[0]*dfadua[0]+fas[1]*dfadua[1])+   \
898                2.*(fbs[0]*dfbdua[0]+fbs[1]*dfbdua[1])
899        else:
900            SA = fas[0]-fbs[1]
901            SB = fbs[0]+fas[1]
902            if nTwin > 1:
903                dFdfr[iref] = [2.*TwMask[it]*SA[it]*(dfadfr[0][it]+dfbdfr[1][it])*Mdata/len(Uniq[it])+ \
904                    2.*TwMask[it]*SB[it]*(dfbdfr[0][it]+dfadfr[1][it])*Mdata/len(Uniq[it]) for it in range(nTwin)]
905                dFdx[iref] = [2.*TwMask[it]*SA[it]*(dfadx[it][0]+dfbdx[it][1])+2.*TwMask[it]*SB[it]*(dfbdx[it][0]+dfadx[it][1]) for it in range(nTwin)]
906                dFdui[iref] = [2.*TwMask[it]*SA[it]*(dfadui[0][it]+dfbdui[1][it])+2.*TwMask[it]*SB[it]*(dfbdui[0][it]+dfadui[1][it]) for it in range(nTwin)]
907                dFdua[iref] = [2.*TwMask[it]*SA[it]*(dfadua[it][0]+dfbdua[it][1])+2.*TwMask[it]*SB[it]*(dfbdua[it][0]+dfadua[it][1]) for it in range(nTwin)]
908                dFdtw[iref] = np.sum(TwMask*fas,axis=0)**2+np.sum(TwMask*fbs,axis=0)**2
909               
910            else:   #these are good for no twin single crystals
911                dFdfr[iref] = 2.*SA*(dfadfr[0]+dfbdfr[1])*Mdata/len(Uniq)+ \
912                    2.*SB*(dfbdfr[0]+dfadfr[1])*Mdata/len(Uniq) #array(nRef,nAtom)
913                dFdx[iref] = 2.*SA*(dfadx[0]+dfbdx[1])+2.*SB*(dfbdx[0]+dfadx[1])    #array(nRef,nAtom,3)
914                dFdui[iref] = 2.*SA*(dfadui[0]+dfbdui[1])+2.*SB*(dfbdui[0]+dfadui[1])   #array(nRef,nAtom)
915                dFdua[iref] = 2.*SA*(dfadua[0]+dfbdua[1])+2.*SB*(dfbdua[0]+dfadua[1])    #array(nRef,nAtom,6)
916                dFdfl[iref] = -SA*dfadfl-SB*dfbdfl  #array(nRef,)
917                dFdbab[iref] = 2.*fas[0]*np.array([np.sum(dfadba*dBabdA),np.sum(-dfadba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T+ \
918                    2.*fbs[0]*np.array([np.sum(dfbdba*dBabdA),np.sum(-dfbdba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T
919    print ' derivative time %.4f\r'%(time.time()-time0)
920        #loop over atoms - each dict entry is list of derivatives for all the reflections
921    if nTwin > 1:
922        for i in range(len(Mdata)):     #these all OK?
923            dFdvDict[pfx+'Afrac:'+str(i)] = np.sum(dFdfr.T[i]*TwinFr[:,np.newaxis],axis=0)
924            dFdvDict[pfx+'dAx:'+str(i)] = np.sum(dFdx.T[0][i]*TwinFr[:,np.newaxis],axis=0)
925            dFdvDict[pfx+'dAy:'+str(i)] = np.sum(dFdx.T[1][i]*TwinFr[:,np.newaxis],axis=0)
926            dFdvDict[pfx+'dAz:'+str(i)] = np.sum(dFdx.T[2][i]*TwinFr[:,np.newaxis],axis=0)
927            dFdvDict[pfx+'AUiso:'+str(i)] = np.sum(dFdui.T[i]*TwinFr[:,np.newaxis],axis=0)
928            dFdvDict[pfx+'AU11:'+str(i)] = np.sum(dFdua.T[0][i]*TwinFr[:,np.newaxis],axis=0)
929            dFdvDict[pfx+'AU22:'+str(i)] = np.sum(dFdua.T[1][i]*TwinFr[:,np.newaxis],axis=0)
930            dFdvDict[pfx+'AU33:'+str(i)] = np.sum(dFdua.T[2][i]*TwinFr[:,np.newaxis],axis=0)
931            dFdvDict[pfx+'AU12:'+str(i)] = np.sum(0.5*dFdua.T[3][i]*TwinFr[:,np.newaxis],axis=0)
932            dFdvDict[pfx+'AU13:'+str(i)] = np.sum(0.5*dFdua.T[4][i]*TwinFr[:,np.newaxis],axis=0)
933            dFdvDict[pfx+'AU23:'+str(i)] = np.sum(0.5*dFdua.T[5][i]*TwinFr[:,np.newaxis],axis=0)
934    else:
935        for i in range(len(Mdata)):
936            dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i]
937            dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i]
938            dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i]
939            dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i]
940            dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i]
941            dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i]
942            dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i]
943            dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i]
944            dFdvDict[pfx+'AU12:'+str(i)] = 0.5*dFdua.T[3][i]
945            dFdvDict[pfx+'AU13:'+str(i)] = 0.5*dFdua.T[4][i]
946            dFdvDict[pfx+'AU23:'+str(i)] = 0.5*dFdua.T[5][i]
947        dFdvDict[phfx+'Flack'] = 4.*dFdfl.T
948    dFdvDict[phfx+'BabA'] = dFdbab.T[0]
949    dFdvDict[phfx+'BabU'] = dFdbab.T[1]
950    if nTwin > 1:
951        for i in range(nTwin):
952            dFdvDict[phfx+'TwinFr:'+str(i)] = dFdtw.T[i]
953    return dFdvDict
954   
955def SStructureFactor(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict):
956    '''
957    Compute super structure factors for all h,k,l,m for phase
958    puts the result, F^2, in each ref[8+im] in refList
959    input:
960   
961    :param dict refDict: where
962        'RefList' list where each ref = h,k,l,m,d,...
963        'FF' dict of form factors - filed in below
964    :param np.array G:      reciprocal metric tensor
965    :param str pfx:    phase id string
966    :param dict SGData: space group info. dictionary output from SpcGroup
967    :param dict calcControls:
968    :param dict ParmDict:
969
970    '''       
971    phfx = pfx.split(':')[0]+hfx
972    ast = np.sqrt(np.diag(G))
973    Mast = twopisq*np.multiply.outer(ast,ast)
974   
975    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
976    SGInv = SGData['SGInv']
977    SGT = np.array([ops[1] for ops in SGData['SGOps']])
978    SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
979    SSGT = np.array([ops[1] for ops in SSGData['SSGOps']])
980    FFtables = calcControls['FFtables']
981    BLtables = calcControls['BLtables']
982    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
983    waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict)
984    SStauM = list(GetSSTauM(SGData['SGOps'],SSGData['SSGOps'],pfx,calcControls,Xdata))
985    if SGData['SGInv']:
986        SStauM[0] = np.hstack((SStauM[0],SStauM[0]))
987        SStauM[1] = np.hstack((SStauM[1],SStauM[1]))
988    modQ = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']])
989    FF = np.zeros(len(Tdata))
990    if 'NC' in calcControls[hfx+'histType']:
991        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
992    else:
993        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
994        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
995    Uij = np.array(G2lat.U6toUij(Uijdata))
996    bij = Mast*Uij.T
997    if not len(refDict['FF']):
998        if 'N' in calcControls[hfx+'histType']:
999            dat = G2el.getBLvalues(BLtables)        #will need wave here for anom. neutron b's
1000        else:
1001            dat = G2el.getFFvalues(FFtables,0.)       
1002        refDict['FF']['El'] = dat.keys()
1003        refDict['FF']['FF'] = np.zeros((len(refDict['RefList']),len(dat)))
1004    time0 = time.time()
1005    nref = len(refDict['RefList'])/100   
1006    for iref,refl in enumerate(refDict['RefList']):
1007        if 'NT' in calcControls[hfx+'histType']:
1008            FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl[14+im])
1009        fbs = np.array([0,0])
1010        H = refl[:4]
1011        SQ = 1./(2.*refl[4+im])**2
1012        SQfactor = 4.0*SQ*twopisq
1013        Bab = parmDict[phfx+'BabA']*np.exp(-parmDict[phfx+'BabU']*SQfactor)
1014        if not np.any(refDict['FF']['FF'][iref]):                #no form factors - 1st time thru StructureFactor
1015            if 'N' in calcControls[hfx+'histType']:
1016                dat = G2el.getBLvalues(BLtables)
1017                refDict['FF']['FF'][iref] = dat.values()
1018            else:       #'X'
1019                dat = G2el.getFFvalues(FFtables,SQ)
1020                refDict['FF']['FF'][iref] = dat.values()
1021        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
1022        FF = refDict['FF']['FF'][iref][Tindx]
1023        HM = np.zeros(4)
1024        HM[:3] += H[3]*modQ
1025        HM += H
1026        Uniq = np.inner(HM[:3],SGMT)
1027        SSUniq = np.inner(HM,SSGMT)
1028        Phi = np.inner(HM[:3],SGT)
1029        SSPhi = np.inner(HM,SSGT)
1030        if SGInv:   #if centro - expand HKL sets
1031            Uniq = np.vstack((Uniq,-Uniq))
1032            SSUniq = np.vstack((SSUniq,-SSUniq))
1033            Phi = np.hstack((Phi,-Phi))
1034            SSPhi = np.hstack((SSPhi,-SSPhi))
1035#        GSASIIpath.IPyBreak()
1036        GfpuA = G2mth.Modulation(waveTypes,SSUniq,FSSdata,XSSdata,USSdata,Mast)
1037        phase = twopi*(np.inner(Uniq,(dXdata.T+Xdata.T))+SSPhi[:,np.newaxis])
1038        sinp = np.sin(phase)
1039        cosp = np.cos(phase)
1040        biso = -SQfactor*Uisodata
1041        Tiso = np.where(biso<1.,np.exp(biso),1.0)
1042        HbH = np.array([-np.inner(h,np.inner(bij,h)) for h in Uniq])
1043        Tuij = np.where(HbH<1.,np.exp(HbH),1.0)
1044        Tcorr = Tiso*Tuij*Mdata*Fdata/len(Uniq)
1045        fa = np.array([(FF+FP-Bab)*cosp*Tcorr,-FPP*sinp*Tcorr])     #2 x sym x atoms
1046        fb = np.array([(FF+FP-Bab)*sinp*Tcorr,FPP*cosp*Tcorr])
1047        fa *= GfpuA
1048        fb *= GfpuA       
1049        fas = np.real(np.sum(np.sum(fa,axis=1),axis=1))
1050        fbs = np.real(np.sum(np.sum(fb,axis=1),axis=1))
1051        fasq = fas**2
1052        fbsq = fbs**2        #imaginary
1053        refl[9+im] = np.sum(fasq)+np.sum(fbsq)
1054        refl[7+im] = np.sum(fasq)+np.sum(fbsq)
1055        refl[10+im] = atan2d(fbs[0],fas[0])
1056        if not iref%nref: print 'ref no. %d time %.4f\r'%(iref,time.time()-time0),
1057    print '\nref no. %d time %.4f\r'%(iref,time.time()-time0)
1058   
1059def SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict):
1060    'Needs a doc string'
1061    phfx = pfx.split(':')[0]+hfx
1062    ast = np.sqrt(np.diag(G))
1063    Mast = twopisq*np.multiply.outer(ast,ast)
1064    SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
1065    SGT = np.array([ops[1] for ops in SGData['SGOps']])
1066    SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
1067    SSGT = np.array([ops[1] for ops in SSGData['SSGOps']])
1068    FFtables = calcControls['FFtables']
1069    BLtables = calcControls['BLtables']
1070    nRef = len(refDict['RefList'])
1071    Tdata,Mdata,Fdata,Xdata,dXdata,IAdata,Uisodata,Uijdata = GetAtomFXU(pfx,calcControls,parmDict)
1072    waveTypes,FSSdata,XSSdata,USSdata,MSSdata = GetAtomSSFXU(pfx,calcControls,parmDict)
1073    SStauM = GetSSTauM(SGData['SGOps'],SSGData['SSGOps'],pfx,calcControls,Xdata)
1074    mSize = len(Mdata)
1075    FF = np.zeros(len(Tdata))
1076    if 'NC' in calcControls[hfx+'histType']:
1077        FP,FPP = G2el.BlenResCW(Tdata,BLtables,parmDict[hfx+'Lam'])
1078    elif 'X' in calcControls[hfx+'histType']:
1079        FP = np.array([FFtables[El][hfx+'FP'] for El in Tdata])
1080        FPP = np.array([FFtables[El][hfx+'FPP'] for El in Tdata])
1081    Uij = np.array(G2lat.U6toUij(Uijdata))
1082    bij = Mast*Uij.T
1083    dFdvDict = {}
1084    dFdfr = np.zeros((nRef,mSize))
1085    dFdx = np.zeros((nRef,mSize,3))
1086    dFdui = np.zeros((nRef,mSize))
1087    dFdua = np.zeros((nRef,mSize,6))
1088    dFdbab = np.zeros((nRef,2))
1089    for iref,refl in enumerate(refDict['RefList']):
1090        if 'T' in calcControls[hfx+'histType']:
1091            FP,FPP = G2el.BlenResCW(Tdata,BLtables,refl.T[12+im])
1092        H = np.array(refl[:4])
1093        SQ = 1./(2.*refl[4+im])**2             # or (sin(theta)/lambda)**2
1094        SQfactor = 8.0*SQ*np.pi**2
1095        dBabdA = np.exp(-parmDict[phfx+'BabU']*SQfactor)
1096        Bab = parmDict[phfx+'BabA']*dBabdA
1097        Tindx = np.array([refDict['FF']['El'].index(El) for El in Tdata])
1098        FF = refDict['FF']['FF'][iref].T[Tindx]
1099        Uniq = np.inner(H[:3],SGMT)
1100        SSUniq = np.inner(H,SSGMT)
1101        Phi = np.inner(H[:3],SGT)
1102        SSPhi = np.inner(H,SSGT)
1103        GfpuA = G2mth.Modulation(waveTypes,SSUniq,FSSdata,XSSdata,USSdata,Mast)
1104        dGAdk = G2mth.ModulationDerv(waveTypes,SSUniq,FSSdata,XSSdata,USSdata,Mast)
1105        #need ModulationDerv here dGAdXsin, etc 
1106        phase = twopi*(np.inner((dXdata.T+Xdata.T),Uniq)+SSPhi[np.newaxis,:])
1107        sinp = np.sin(phase)
1108        cosp = np.cos(phase)
1109        occ = Mdata*Fdata/len(Uniq)
1110        biso = -SQfactor*Uisodata
1111        Tiso = np.where(biso<1.,np.exp(biso),1.0)
1112        HbH = -np.inner(H[:3],np.inner(bij,H[:3]))
1113        Hij = np.array([Mast*np.multiply.outer(U,U) for U in Uniq])
1114        Hij = np.array([G2lat.UijtoU6(Uij) for Uij in Hij])
1115        Tuij = np.where(HbH<1.,np.exp(HbH),1.0)
1116        Tcorr = Tiso*Tuij
1117        fot = (FF+FP-Bab)*occ*Tcorr
1118        fotp = FPP*occ*Tcorr
1119        fa *= GfpuA
1120        fb *= GfpuA       
1121       
1122        fas = np.sum(np.sum(fa,axis=1),axis=1)
1123        fbs = np.sum(np.sum(fb,axis=1),axis=1)
1124        fax = np.array([-fot[:,np.newaxis]*sinp,-fotp[:,np.newaxis]*sinp])   #positions
1125        fbx = np.array([fot[:,np.newaxis]*cosp,-fot[:,np.newaxis]*cosp])
1126        fax = fax*GfpuA[:,:,np.newaxis]-fbx*GfpuB[:,:,np.newaxis]
1127        fbx = fbx*GfpuA[:,:,np.newaxis]+fax*GfpuB[:,:,np.newaxis]
1128        #sum below is over Uniq
1129        dfadfr = np.sum(fa/occ[:,np.newaxis],axis=2)        #Fdata != 0 ever avoids /0. problem
1130        dfadx = np.sum(twopi*Uniq*fax[:,:,:,np.newaxis],axis=2)
1131        dfadui = np.sum(-SQfactor*fa,axis=2)
1132        dfadua = np.sum(-Hij*fa[:,:,:,np.newaxis],axis=2)
1133        dfadba = np.sum(-cosp*(occ*Tcorr)[:,np.newaxis],axis=1)
1134        #NB: the above have been checked against PA(1:10,1:2) in strfctr.for for al2O3!   
1135        dFdfr[iref] = 2.*(fas[0]*dfadfr[0]+fas[1]*dfadfr[1])*Mdata/len(Uniq)
1136        dFdx[iref] = 2.*(fas[0]*dfadx[0]+fas[1]*dfadx[1])
1137        dFdui[iref] = 2.*(fas[0]*dfadui[0]+fas[1]*dfadui[1])
1138        dFdua[iref] = 2.*(fas[0]*dfadua[0]+fas[1]*dfadua[1])
1139        dFdbab[iref] = 2.*fas[0]*np.array([np.sum(dfadba*dBabdA),np.sum(-dfadba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T
1140        #need dFdXsin, etc for modulations...
1141        if not SGData['SGInv']:
1142            dfbdfr = np.sum(fb/occ[:,np.newaxis],axis=2)        #Fdata != 0 ever avoids /0. problem
1143            dfbdx = np.sum(twopi*Uniq*fbx[:,:,:,np.newaxis],axis=2)           
1144            dfbdui = np.sum(-SQfactor*fb,axis=2)
1145            dfbdua = np.sum(-Hij*fb[:,:,:,np.newaxis],axis=2)
1146            dfbdba = np.sum(-sinp*(occ*Tcorr)[:,np.newaxis],axis=1)
1147            dFdfr[iref] += 2.*(fbs[0]*dfbdfr[0]-fbs[1]*dfbdfr[1])*Mdata/len(Uniq)
1148            dFdx[iref] += 2.*(fbs[0]*dfbdx[0]+fbs[1]*dfbdx[1])
1149            dFdui[iref] += 2.*(fbs[0]*dfbdui[0]-fbs[1]*dfbdui[1])
1150            dFdua[iref] += 2.*(fbs[0]*dfbdua[0]+fbs[1]*dfbdua[1])
1151            dFdbab[iref] += 2.*fbs[0]*np.array([np.sum(dfbdba*dBabdA),np.sum(-dfbdba*parmDict[phfx+'BabA']*SQfactor*dBabdA)]).T
1152        #need dFdXsin, etc for modulations...
1153        #loop over atoms - each dict entry is list of derivatives for all the reflections
1154    for i in range(len(Mdata)):     
1155        dFdvDict[pfx+'Afrac:'+str(i)] = dFdfr.T[i]
1156        dFdvDict[pfx+'dAx:'+str(i)] = dFdx.T[0][i]
1157        dFdvDict[pfx+'dAy:'+str(i)] = dFdx.T[1][i]
1158        dFdvDict[pfx+'dAz:'+str(i)] = dFdx.T[2][i]
1159        dFdvDict[pfx+'AUiso:'+str(i)] = dFdui.T[i]
1160        dFdvDict[pfx+'AU11:'+str(i)] = dFdua.T[0][i]
1161        dFdvDict[pfx+'AU22:'+str(i)] = dFdua.T[1][i]
1162        dFdvDict[pfx+'AU33:'+str(i)] = dFdua.T[2][i]
1163        dFdvDict[pfx+'AU12:'+str(i)] = .5*dFdua.T[3][i]
1164        dFdvDict[pfx+'AU13:'+str(i)] = .5*dFdua.T[4][i]
1165        dFdvDict[pfx+'AU23:'+str(i)] = .5*dFdua.T[5][i]
1166        #need dFdvDict[pfx+'Xsin:'+str[i]:str(m)], etc for modulations...
1167    dFdvDict[phfx+'BabA'] = dFdbab.T[0]
1168    dFdvDict[phfx+'BabU'] = dFdbab.T[1]
1169    return dFdvDict
1170   
1171def SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varyList):
1172    ''' Single crystal extinction function; returns extinction & derivative
1173    '''
1174    extCor = 1.0
1175    dervDict = {}
1176    dervCor = 1.0
1177    if calcControls[phfx+'EType'] != 'None':
1178        SQ = 1/(4.*ref[4+im]**2)
1179        if 'C' in parmDict[hfx+'Type']:           
1180            cos2T = 1.0-2.*SQ*parmDict[hfx+'Lam']**2           #cos(2theta)
1181        else:   #'T'
1182            cos2T = 1.0-2.*SQ*ref[12+im]**2                       #cos(2theta)           
1183        if 'SXC' in parmDict[hfx+'Type']:
1184            AV = 7.9406e5/parmDict[pfx+'Vol']**2
1185            PL = np.sqrt(1.0-cos2T**2)/parmDict[hfx+'Lam']
1186            P12 = (calcControls[phfx+'Cos2TM']+cos2T**4)/(calcControls[phfx+'Cos2TM']+cos2T**2)
1187            PLZ = AV*P12*ref[9+im]*parmDict[hfx+'Lam']**2
1188        elif 'SNT' in parmDict[hfx+'Type']:
1189            AV = 1.e7/parmDict[pfx+'Vol']**2
1190            PL = SQ
1191            PLZ = AV*ref[9+im]*ref[12+im]**2
1192        elif 'SNC' in parmDict[hfx+'Type']:
1193            AV = 1.e7/parmDict[pfx+'Vol']**2
1194            PL = np.sqrt(1.0-cos2T**2)/parmDict[hfx+'Lam']
1195            PLZ = AV*ref[9+im]*parmDict[hfx+'Lam']**2
1196           
1197        if 'Primary' in calcControls[phfx+'EType']:
1198            PLZ *= 1.5
1199        else:
1200            if 'C' in parmDict[hfx+'Type']:
1201                PLZ *= calcControls[phfx+'Tbar']
1202            else: #'T'
1203                PLZ *= ref[13+im]      #t-bar
1204        if 'Primary' in calcControls[phfx+'EType']:
1205            PLZ *= 1.5
1206            PSIG = parmDict[phfx+'Ep']
1207        elif 'I & II' in calcControls[phfx+'EType']:
1208            PSIG = parmDict[phfx+'Eg']/np.sqrt(1.+(parmDict[phfx+'Es']*PL/parmDict[phfx+'Eg'])**2)
1209        elif 'Type II' in calcControls[phfx+'EType']:
1210            PSIG = parmDict[phfx+'Es']
1211        else:       # 'Secondary Type I'
1212            PSIG = parmDict[phfx+'Eg']/PL
1213           
1214        AG = 0.58+0.48*cos2T+0.24*cos2T**2
1215        AL = 0.025+0.285*cos2T
1216        BG = 0.02-0.025*cos2T
1217        BL = 0.15-0.2*(0.75-cos2T)**2
1218        if cos2T < 0.:
1219            BL = -0.45*cos2T
1220        CG = 2.
1221        CL = 2.
1222        PF = PLZ*PSIG
1223       
1224        if 'Gaussian' in calcControls[phfx+'EApprox']:
1225            PF4 = 1.+CG*PF+AG*PF**2/(1.+BG*PF)
1226            extCor = np.sqrt(PF4)
1227            PF3 = 0.5*(CG+2.*AG*PF/(1.+BG*PF)-AG*PF**2*BG/(1.+BG*PF)**2)/(PF4*extCor)
1228        else:
1229            PF4 = 1.+CL*PF+AL*PF**2/(1.+BL*PF)
1230            extCor = np.sqrt(PF4)
1231            PF3 = 0.5*(CL+2.*AL*PF/(1.+BL*PF)-AL*PF**2*BL/(1.+BL*PF)**2)/(PF4*extCor)
1232
1233        dervCor = (1.+PF)*PF3   #extinction corr for other derivatives
1234        if 'Primary' in calcControls[phfx+'EType'] and phfx+'Ep' in varyList:
1235            dervDict[phfx+'Ep'] = -ref[7+im]*PLZ*PF3
1236        if 'II' in calcControls[phfx+'EType'] and phfx+'Es' in varyList:
1237            dervDict[phfx+'Es'] = -ref[7+im]*PLZ*PF3*(PSIG/parmDict[phfx+'Es'])**3
1238        if 'I' in calcControls[phfx+'EType'] and phfx+'Eg' in varyList:
1239            dervDict[phfx+'Eg'] = -ref[7+im]*PLZ*PF3*(PSIG/parmDict[phfx+'Eg'])**3*PL**2
1240               
1241    return 1./extCor,dervDict,dervCor
1242   
1243def Dict2Values(parmdict, varylist):
1244    '''Use before call to leastsq to setup list of values for the parameters
1245    in parmdict, as selected by key in varylist'''
1246    return [parmdict[key] for key in varylist] 
1247   
1248def Values2Dict(parmdict, varylist, values):
1249    ''' Use after call to leastsq to update the parameter dictionary with
1250    values corresponding to keys in varylist'''
1251    parmdict.update(zip(varylist,values))
1252   
1253def GetNewCellParms(parmDict,varyList):
1254    'Needs a doc string'
1255    newCellDict = {}
1256    Anames = ['A'+str(i) for i in range(6)]
1257    Ddict = dict(zip(['D11','D22','D33','D12','D13','D23'],Anames))
1258    for item in varyList:
1259        keys = item.split(':')
1260        if keys[2] in Ddict:
1261            key = keys[0]+'::'+Ddict[keys[2]]       #key is e.g. '0::A0'
1262            parm = keys[0]+'::'+keys[2]             #parm is e.g. '0::D11'
1263            newCellDict[parm] = [key,parmDict[key]+parmDict[item]]
1264    return newCellDict          # is e.g. {'0::D11':A0-D11}
1265   
1266def ApplyXYZshifts(parmDict,varyList):
1267    '''
1268    takes atom x,y,z shift and applies it to corresponding atom x,y,z value
1269   
1270    :param dict parmDict: parameter dictionary
1271    :param list varyList: list of variables (not used!)
1272    :returns: newAtomDict - dictionary of new atomic coordinate names & values; key is parameter shift name
1273
1274    '''
1275    newAtomDict = {}
1276    for item in parmDict:
1277        if 'dA' in item:
1278            parm = ''.join(item.split('d'))
1279            parmDict[parm] += parmDict[item]
1280            newAtomDict[item] = [parm,parmDict[parm]]
1281    return newAtomDict
1282   
1283def SHTXcal(refl,im,g,pfx,hfx,SGData,calcControls,parmDict):
1284    'Spherical harmonics texture'
1285    IFCoup = 'Bragg' in calcControls[hfx+'instType']
1286    if 'T' in calcControls[hfx+'histType']:
1287        tth = parmDict[hfx+'2-theta']
1288    else:
1289        tth = refl[5+im]
1290    odfCor = 1.0
1291    H = refl[:3]
1292    cell = G2lat.Gmat2cell(g)
1293    Sangls = [parmDict[pfx+'SH omega'],parmDict[pfx+'SH chi'],parmDict[pfx+'SH phi']]
1294    Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']]
1295    phi,beta = G2lat.CrsAng(H,cell,SGData)
1296    psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) #ignore 2 sets of angle derivs.
1297    SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],parmDict[pfx+'SHmodel'],parmDict[pfx+'SHorder'])
1298    for item in SHnames:
1299        L,M,N = eval(item.strip('C'))
1300        Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta)
1301        Ksl,x,x = G2lat.GetKsl(L,M,parmDict[pfx+'SHmodel'],psi,gam)
1302        Lnorm = G2lat.Lnorm(L)
1303        odfCor += parmDict[pfx+item]*Lnorm*Kcl*Ksl
1304    return odfCor
1305   
1306def SHTXcalDerv(refl,im,g,pfx,hfx,SGData,calcControls,parmDict):
1307    'Spherical harmonics texture derivatives'
1308    if 'T' in calcControls[hfx+'histType']:
1309        tth = parmDict[hfx+'2-theta']
1310    else:
1311        tth = refl[5+im]
1312    IFCoup = 'Bragg' in calcControls[hfx+'instType']
1313    odfCor = 1.0
1314    dFdODF = {}
1315    dFdSA = [0,0,0]
1316    H = refl[:3]
1317    cell = G2lat.Gmat2cell(g)
1318    Sangls = [parmDict[pfx+'SH omega'],parmDict[pfx+'SH chi'],parmDict[pfx+'SH phi']]
1319    Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']]
1320    phi,beta = G2lat.CrsAng(H,cell,SGData)
1321    psi,gam,dPSdA,dGMdA = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup)
1322    SHnames = G2lat.GenSHCoeff(SGData['SGLaue'],parmDict[pfx+'SHmodel'],parmDict[pfx+'SHorder'])
1323    for item in SHnames:
1324        L,M,N = eval(item.strip('C'))
1325        Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta)
1326        Ksl,dKsdp,dKsdg = G2lat.GetKsl(L,M,parmDict[pfx+'SHmodel'],psi,gam)
1327        Lnorm = G2lat.Lnorm(L)
1328        odfCor += parmDict[pfx+item]*Lnorm*Kcl*Ksl
1329        dFdODF[pfx+item] = Lnorm*Kcl*Ksl
1330        for i in range(3):
1331            dFdSA[i] += parmDict[pfx+item]*Lnorm*Kcl*(dKsdp*dPSdA[i]+dKsdg*dGMdA[i])
1332    return odfCor,dFdODF,dFdSA
1333   
1334def SHPOcal(refl,im,g,phfx,hfx,SGData,calcControls,parmDict):
1335    'spherical harmonics preferred orientation (cylindrical symmetry only)'
1336    if 'T' in calcControls[hfx+'histType']:
1337        tth = parmDict[hfx+'2-theta']
1338    else:
1339        tth = refl[5+im]
1340    odfCor = 1.0
1341    H = refl[:3]
1342    cell = G2lat.Gmat2cell(g)
1343    Sangls = [0.,0.,0.]
1344    if 'Bragg' in calcControls[hfx+'instType']:
1345        Gangls = [0.,90.,0.,parmDict[hfx+'Azimuth']]
1346        IFCoup = True
1347    else:
1348        Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']]
1349        IFCoup = False
1350    phi,beta = G2lat.CrsAng(H,cell,SGData)
1351    psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) #ignore 2 sets of angle derivs.
1352    SHnames = calcControls[phfx+'SHnames']
1353    for item in SHnames:
1354        L,N = eval(item.strip('C'))
1355        Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta)
1356        Ksl,x,x = G2lat.GetKsl(L,0,'0',psi,gam)
1357        Lnorm = G2lat.Lnorm(L)
1358        odfCor += parmDict[phfx+item]*Lnorm*Kcl*Ksl
1359    return np.squeeze(odfCor)
1360   
1361def SHPOcalDerv(refl,im,g,phfx,hfx,SGData,calcControls,parmDict):
1362    'spherical harmonics preferred orientation derivatives (cylindrical symmetry only)'
1363    if 'T' in calcControls[hfx+'histType']:
1364        tth = parmDict[hfx+'2-theta']
1365    else:
1366        tth = refl[5+im]
1367    odfCor = 1.0
1368    dFdODF = {}
1369    H = refl[:3]
1370    cell = G2lat.Gmat2cell(g)
1371    Sangls = [0.,0.,0.]
1372    if 'Bragg' in calcControls[hfx+'instType']:
1373        Gangls = [0.,90.,0.,parmDict[hfx+'Azimuth']]
1374        IFCoup = True
1375    else:
1376        Gangls = [parmDict[hfx+'Phi'],parmDict[hfx+'Chi'],parmDict[hfx+'Omega'],parmDict[hfx+'Azimuth']]
1377        IFCoup = False
1378    phi,beta = G2lat.CrsAng(H,cell,SGData)
1379    psi,gam,x,x = G2lat.SamAng(tth/2.,Gangls,Sangls,IFCoup) #ignore 2 sets of angle derivs.
1380    SHnames = calcControls[phfx+'SHnames']
1381    for item in SHnames:
1382        L,N = eval(item.strip('C'))
1383        Kcl = G2lat.GetKcl(L,N,SGData['SGLaue'],phi,beta)
1384        Ksl,x,x = G2lat.GetKsl(L,0,'0',psi,gam)
1385        Lnorm = G2lat.Lnorm(L)
1386        odfCor += parmDict[phfx+item]*Lnorm*Kcl*Ksl
1387        dFdODF[phfx+item] = Kcl*Ksl*Lnorm
1388    return odfCor,dFdODF
1389   
1390def GetPrefOri(uniq,G,g,phfx,hfx,SGData,calcControls,parmDict):
1391    'March-Dollase preferred orientation correction'
1392    POcorr = 1.0
1393    MD = parmDict[phfx+'MD']
1394    if MD != 1.0:
1395        MDAxis = calcControls[phfx+'MDAxis']
1396        sumMD = 0
1397        for H in uniq:           
1398            cosP,sinP = G2lat.CosSinAngle(H,MDAxis,G)
1399            A = 1.0/np.sqrt((MD*cosP)**2+sinP**2/MD)
1400            sumMD += A**3
1401        POcorr = sumMD/len(uniq)
1402    return POcorr
1403   
1404def GetPrefOriDerv(refl,im,uniq,G,g,phfx,hfx,SGData,calcControls,parmDict):
1405    'Needs a doc string'
1406    POcorr = 1.0
1407    POderv = {}
1408    if calcControls[phfx+'poType'] == 'MD':
1409        MD = parmDict[phfx+'MD']
1410        MDAxis = calcControls[phfx+'MDAxis']
1411        sumMD = 0
1412        sumdMD = 0
1413        for H in uniq:           
1414            cosP,sinP = G2lat.CosSinAngle(H,MDAxis,G)
1415            A = 1.0/np.sqrt((MD*cosP)**2+sinP**2/MD)
1416            sumMD += A**3
1417            sumdMD -= (1.5*A**5)*(2.0*MD*cosP**2-(sinP/MD)**2)
1418        POcorr = sumMD/len(uniq)
1419        POderv[phfx+'MD'] = sumdMD/len(uniq)
1420    else:   #spherical harmonics
1421        if calcControls[phfx+'SHord']:
1422            POcorr,POderv = SHPOcalDerv(refl,im,g,phfx,hfx,SGData,calcControls,parmDict)
1423    return POcorr,POderv
1424   
1425def GetAbsorb(refl,im,hfx,calcControls,parmDict):
1426    'Needs a doc string'
1427    if 'Debye' in calcControls[hfx+'instType']:
1428        if 'T' in calcControls[hfx+'histType']:
1429            return G2pwd.Absorb('Cylinder',parmDict[hfx+'Absorption']*refl[14+im],abs(parmDict[hfx+'2-theta']),0,0)
1430        else:
1431            return G2pwd.Absorb('Cylinder',parmDict[hfx+'Absorption'],refl[5+im],0,0)
1432    else:
1433        return G2pwd.SurfaceRough(parmDict[hfx+'SurfRoughA'],parmDict[hfx+'SurfRoughB'],refl[5+im])
1434   
1435def GetAbsorbDerv(refl,im,hfx,calcControls,parmDict):
1436    'Needs a doc string'
1437    if 'Debye' in calcControls[hfx+'instType']:
1438        if 'T' in calcControls[hfx+'histType']:
1439            return G2pwd.AbsorbDerv('Cylinder',parmDict[hfx+'Absorption']*refl[14+im],abs(parmDict[hfx+'2-theta']),0,0)
1440        else:
1441            return G2pwd.AbsorbDerv('Cylinder',parmDict[hfx+'Absorption'],refl[5+im],0,0)
1442    else:
1443        return np.array(G2pwd.SurfaceRoughDerv(parmDict[hfx+'SurfRoughA'],parmDict[hfx+'SurfRoughB'],refl[5+im]))
1444       
1445def GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict):
1446    'Needs a doc string'
1447    coef = np.array([-0.5,0.25,-0.10416667,0.036458333,-0.0109375,2.8497409E-3])
1448    pi2 = np.sqrt(2./np.pi)
1449    if 'T' in calcControls[hfx+'histType']:
1450        sth2 = sind(abs(parmDict[hfx+'2-theta'])/2.)**2
1451        wave = refl[14+im]
1452    else:   #'C'W
1453        sth2 = sind(refl[5+im]/2.)**2
1454        wave = parmDict.get(hfx+'Lam',parmDict.get(hfx+'Lam1',1.0))
1455    c2th = 1.-2.0*sth2
1456    flv2 = refl[9+im]*(wave/parmDict[pfx+'Vol'])**2
1457    if 'X' in calcControls[hfx+'histType']:
1458        flv2 *= 0.079411*(1.0+c2th**2)/2.0
1459    xfac = flv2*parmDict[phfx+'Extinction']
1460    exb = 1.0
1461    if xfac > -1.:
1462        exb = 1./np.sqrt(1.+xfac)
1463    exl = 1.0
1464    if 0 < xfac <= 1.:
1465        xn = np.array([xfac**(i+1) for i in range(6)])
1466        exl += np.sum(xn*coef)
1467    elif xfac > 1.:
1468        xfac2 = 1./np.sqrt(xfac)
1469        exl = pi2*(1.-0.125/xfac)*xfac2
1470    return exb*sth2+exl*(1.-sth2)
1471   
1472def GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict):
1473    'Needs a doc string'
1474    coef = np.array([-0.5,0.25,-0.10416667,0.036458333,-0.0109375,2.8497409E-3])
1475    pi2 = np.sqrt(2./np.pi)
1476    if 'T' in calcControls[hfx+'histType']:
1477        sth2 = sind(abs(parmDict[hfx+'2-theta'])/2.)**2
1478        wave = refl[14+im]
1479    else:   #'C'W
1480        sth2 = sind(refl[5+im]/2.)**2
1481        wave = parmDict.get(hfx+'Lam',parmDict.get(hfx+'Lam1',1.0))
1482    c2th = 1.-2.0*sth2
1483    flv2 = refl[9+im]*(wave/parmDict[pfx+'Vol'])**2
1484    if 'X' in calcControls[hfx+'histType']:
1485        flv2 *= 0.079411*(1.0+c2th**2)/2.0
1486    xfac = flv2*parmDict[phfx+'Extinction']
1487    dbde = -500.*flv2
1488    if xfac > -1.:
1489        dbde = -0.5*flv2/np.sqrt(1.+xfac)**3
1490    dlde = 0.
1491    if 0 < xfac <= 1.:
1492        xn = np.array([i*flv2*xfac**i for i in [1,2,3,4,5,6]])
1493        dlde = np.sum(xn*coef)
1494    elif xfac > 1.:
1495        xfac2 = 1./np.sqrt(xfac)
1496        dlde = flv2*pi2*xfac2*(-1./xfac+0.375/xfac**2)
1497       
1498    return dbde*sth2+dlde*(1.-sth2)
1499   
1500def GetIntensityCorr(refl,im,uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict):
1501    'Needs a doc string'    #need powder extinction!
1502    Icorr = parmDict[phfx+'Scale']*parmDict[hfx+'Scale']*refl[3+im]               #scale*multiplicity
1503    if 'X' in parmDict[hfx+'Type']:
1504        Icorr *= G2pwd.Polarization(parmDict[hfx+'Polariz.'],refl[5+im],parmDict[hfx+'Azimuth'])[0]
1505    POcorr = 1.0
1506    if pfx+'SHorder' in parmDict:                 #generalized spherical harmonics texture - takes precidence
1507        POcorr = SHTXcal(refl,im,g,pfx,hfx,SGData,calcControls,parmDict)
1508    elif calcControls[phfx+'poType'] == 'MD':         #March-Dollase
1509        POcorr = GetPrefOri(uniq,G,g,phfx,hfx,SGData,calcControls,parmDict)
1510    elif calcControls[phfx+'SHord']:                #cylindrical spherical harmonics
1511        POcorr = SHPOcal(refl,im,g,phfx,hfx,SGData,calcControls,parmDict)
1512    Icorr *= POcorr
1513    AbsCorr = 1.0
1514    AbsCorr = GetAbsorb(refl,im,hfx,calcControls,parmDict)
1515    Icorr *= AbsCorr
1516    ExtCorr = GetPwdrExt(refl,im,pfx,phfx,hfx,calcControls,parmDict)
1517    Icorr *= ExtCorr
1518    return Icorr,POcorr,AbsCorr,ExtCorr
1519   
1520def GetIntensityDerv(refl,im,wave,uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict):
1521    'Needs a doc string'    #need powder extinction derivs!
1522    dIdsh = 1./parmDict[hfx+'Scale']
1523    dIdsp = 1./parmDict[phfx+'Scale']
1524    if 'X' in parmDict[hfx+'Type']:
1525        pola,dIdPola = G2pwd.Polarization(parmDict[hfx+'Polariz.'],refl[5+im],parmDict[hfx+'Azimuth'])
1526        dIdPola /= pola
1527    else:       #'N'
1528        dIdPola = 0.0
1529    dFdODF = {}
1530    dFdSA = [0,0,0]
1531    dIdPO = {}
1532    if pfx+'SHorder' in parmDict:
1533        odfCor,dFdODF,dFdSA = SHTXcalDerv(refl,im,g,pfx,hfx,SGData,calcControls,parmDict)
1534        for iSH in dFdODF:
1535            dFdODF[iSH] /= odfCor
1536        for i in range(3):
1537            dFdSA[i] /= odfCor
1538    elif calcControls[phfx+'poType'] == 'MD' or calcControls[phfx+'SHord']:
1539        POcorr,dIdPO = GetPrefOriDerv(refl,im,uniq,G,g,phfx,hfx,SGData,calcControls,parmDict)       
1540        for iPO in dIdPO:
1541            dIdPO[iPO] /= POcorr
1542    if 'T' in parmDict[hfx+'Type']:
1543        dFdAb = GetAbsorbDerv(refl,im,hfx,calcControls,parmDict)*wave/refl[16+im] #wave/abs corr
1544        dFdEx = GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict)/refl[17+im]    #/ext corr
1545    else:
1546        dFdAb = GetAbsorbDerv(refl,im,hfx,calcControls,parmDict)*wave/refl[13+im] #wave/abs corr
1547        dFdEx = GetPwdrExtDerv(refl,im,pfx,phfx,hfx,calcControls,parmDict)/refl[14+im]    #/ext corr       
1548    return dIdsh,dIdsp,dIdPola,dIdPO,dFdODF,dFdSA,dFdAb,dFdEx
1549       
1550def GetSampleSigGam(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict):
1551    'Needs a doc string'
1552    if 'C' in calcControls[hfx+'histType']:     #All checked & OK
1553        costh = cosd(refl[5+im]/2.)
1554        #crystallite size
1555        if calcControls[phfx+'SizeType'] == 'isotropic':
1556            Sgam = 1.8*wave/(np.pi*parmDict[phfx+'Size;i']*costh)
1557        elif calcControls[phfx+'SizeType'] == 'uniaxial':
1558            H = np.array(refl[:3])
1559            P = np.array(calcControls[phfx+'SizeAxis'])
1560            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1561            Sgam = (1.8*wave/np.pi)/(parmDict[phfx+'Size;i']*parmDict[phfx+'Size;a']*costh)
1562            Sgam *= np.sqrt((sinP*parmDict[phfx+'Size;a'])**2+(cosP*parmDict[phfx+'Size;i'])**2)
1563        else:           #ellipsoidal crystallites
1564            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1565            H = np.array(refl[:3])
1566            lenR = G2pwd.ellipseSize(H,Sij,GB)
1567            Sgam = 1.8*wave/(np.pi*costh*lenR)
1568        #microstrain               
1569        if calcControls[phfx+'MustrainType'] == 'isotropic':
1570            Mgam = 0.018*parmDict[phfx+'Mustrain;i']*tand(refl[5+im]/2.)/np.pi
1571        elif calcControls[phfx+'MustrainType'] == 'uniaxial':
1572            H = np.array(refl[:3])
1573            P = np.array(calcControls[phfx+'MustrainAxis'])
1574            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1575            Si = parmDict[phfx+'Mustrain;i']
1576            Sa = parmDict[phfx+'Mustrain;a']
1577            Mgam = 0.018*Si*Sa*tand(refl[5+im]/2.)/(np.pi*np.sqrt((Si*cosP)**2+(Sa*sinP)**2))
1578        else:       #generalized - P.W. Stephens model
1579            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1580            Sum = 0
1581            for i,strm in enumerate(Strms):
1582                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1583            Mgam = 0.018*refl[4+im]**2*tand(refl[5+im]/2.)*np.sqrt(Sum)/np.pi
1584    elif 'T' in calcControls[hfx+'histType']:       #All checked & OK
1585        #crystallite size
1586        if calcControls[phfx+'SizeType'] == 'isotropic':    #OK
1587            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/parmDict[phfx+'Size;i']
1588        elif calcControls[phfx+'SizeType'] == 'uniaxial':   #OK
1589            H = np.array(refl[:3])
1590            P = np.array(calcControls[phfx+'SizeAxis'])
1591            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1592            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/(parmDict[phfx+'Size;i']*parmDict[phfx+'Size;a'])
1593            Sgam *= np.sqrt((sinP*parmDict[phfx+'Size;a'])**2+(cosP*parmDict[phfx+'Size;i'])**2)
1594        else:           #ellipsoidal crystallites   #OK
1595            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1596            H = np.array(refl[:3])
1597            lenR = G2pwd.ellipseSize(H,Sij,GB)
1598            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/lenR
1599        #microstrain               
1600        if calcControls[phfx+'MustrainType'] == 'isotropic':    #OK
1601            Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*parmDict[phfx+'Mustrain;i']
1602        elif calcControls[phfx+'MustrainType'] == 'uniaxial':   #OK
1603            H = np.array(refl[:3])
1604            P = np.array(calcControls[phfx+'MustrainAxis'])
1605            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1606            Si = parmDict[phfx+'Mustrain;i']
1607            Sa = parmDict[phfx+'Mustrain;a']
1608            Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*Si*Sa/np.sqrt((Si*cosP)**2+(Sa*sinP)**2)
1609        else:       #generalized - P.W. Stephens model  OK
1610            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1611            Sum = 0
1612            for i,strm in enumerate(Strms):
1613                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1614            Mgam = 1.e-6*parmDict[hfx+'difC']*np.sqrt(Sum)*refl[4+im]**3
1615           
1616    gam = Sgam*parmDict[phfx+'Size;mx']+Mgam*parmDict[phfx+'Mustrain;mx']
1617    sig = (Sgam*(1.-parmDict[phfx+'Size;mx']))**2+(Mgam*(1.-parmDict[phfx+'Mustrain;mx']))**2
1618    sig /= ateln2
1619    return sig,gam
1620       
1621def GetSampleSigGamDerv(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict):
1622    'Needs a doc string'
1623    gamDict = {}
1624    sigDict = {}
1625    if 'C' in calcControls[hfx+'histType']:         #All checked & OK
1626        costh = cosd(refl[5+im]/2.)
1627        tanth = tand(refl[5+im]/2.)
1628        #crystallite size derivatives
1629        if calcControls[phfx+'SizeType'] == 'isotropic':
1630            Sgam = 1.8*wave/(np.pi*parmDict[phfx+'Size;i']*costh)
1631            gamDict[phfx+'Size;i'] = -1.8*wave*parmDict[phfx+'Size;mx']/(np.pi*costh)
1632            sigDict[phfx+'Size;i'] = -3.6*Sgam*wave*(1.-parmDict[phfx+'Size;mx'])**2/(np.pi*costh*ateln2)
1633        elif calcControls[phfx+'SizeType'] == 'uniaxial':
1634            H = np.array(refl[:3])
1635            P = np.array(calcControls[phfx+'SizeAxis'])
1636            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1637            Si = parmDict[phfx+'Size;i']
1638            Sa = parmDict[phfx+'Size;a']
1639            gami = 1.8*wave/(costh*np.pi*Si*Sa)
1640            sqtrm = np.sqrt((sinP*Sa)**2+(cosP*Si)**2)
1641            Sgam = gami*sqtrm
1642            dsi = gami*Si*cosP**2/sqtrm-Sgam/Si
1643            dsa = gami*Sa*sinP**2/sqtrm-Sgam/Sa
1644            gamDict[phfx+'Size;i'] = dsi*parmDict[phfx+'Size;mx']
1645            gamDict[phfx+'Size;a'] = dsa*parmDict[phfx+'Size;mx']
1646            sigDict[phfx+'Size;i'] = 2.*dsi*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1647            sigDict[phfx+'Size;a'] = 2.*dsa*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1648        else:           #ellipsoidal crystallites
1649            const = 1.8*wave/(np.pi*costh)
1650            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1651            H = np.array(refl[:3])
1652            lenR,dRdS = G2pwd.ellipseSizeDerv(H,Sij,GB)
1653            Sgam = const/lenR
1654            for i,item in enumerate([phfx+'Size:%d'%(j) for j in range(6)]):
1655                gamDict[item] = -(const/lenR**2)*dRdS[i]*parmDict[phfx+'Size;mx']
1656                sigDict[item] = -2.*Sgam*(const/lenR**2)*dRdS[i]*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1657        gamDict[phfx+'Size;mx'] = Sgam
1658        sigDict[phfx+'Size;mx'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])/ateln2
1659               
1660        #microstrain derivatives               
1661        if calcControls[phfx+'MustrainType'] == 'isotropic':
1662            Mgam = 0.018*parmDict[phfx+'Mustrain;i']*tand(refl[5+im]/2.)/np.pi
1663            gamDict[phfx+'Mustrain;i'] =  0.018*tanth*parmDict[phfx+'Mustrain;mx']/np.pi
1664            sigDict[phfx+'Mustrain;i'] =  0.036*Mgam*tanth*(1.-parmDict[phfx+'Mustrain;mx'])**2/(np.pi*ateln2)       
1665        elif calcControls[phfx+'MustrainType'] == 'uniaxial':
1666            H = np.array(refl[:3])
1667            P = np.array(calcControls[phfx+'MustrainAxis'])
1668            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1669            Si = parmDict[phfx+'Mustrain;i']
1670            Sa = parmDict[phfx+'Mustrain;a']
1671            gami = 0.018*Si*Sa*tanth/np.pi
1672            sqtrm = np.sqrt((Si*cosP)**2+(Sa*sinP)**2)
1673            Mgam = gami/sqtrm
1674            dsi = -gami*Si*cosP**2/sqtrm**3
1675            dsa = -gami*Sa*sinP**2/sqtrm**3
1676            gamDict[phfx+'Mustrain;i'] = (Mgam/Si+dsi)*parmDict[phfx+'Mustrain;mx']
1677            gamDict[phfx+'Mustrain;a'] = (Mgam/Sa+dsa)*parmDict[phfx+'Mustrain;mx']
1678            sigDict[phfx+'Mustrain;i'] = 2*(Mgam/Si+dsi)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2
1679            sigDict[phfx+'Mustrain;a'] = 2*(Mgam/Sa+dsa)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2       
1680        else:       #generalized - P.W. Stephens model
1681            const = 0.018*refl[4+im]**2*tanth/np.pi
1682            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1683            Sum = 0
1684            for i,strm in enumerate(Strms):
1685                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1686                gamDict[phfx+'Mustrain:'+str(i)] = strm*parmDict[phfx+'Mustrain;mx']/2.
1687                sigDict[phfx+'Mustrain:'+str(i)] = strm*(1.-parmDict[phfx+'Mustrain;mx'])**2
1688            Mgam = const*np.sqrt(Sum)
1689            for i in range(len(Strms)):
1690                gamDict[phfx+'Mustrain:'+str(i)] *= Mgam/Sum
1691                sigDict[phfx+'Mustrain:'+str(i)] *= const**2/ateln2
1692        gamDict[phfx+'Mustrain;mx'] = Mgam
1693        sigDict[phfx+'Mustrain;mx'] = -2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])/ateln2
1694    else:   #'T'OF - All checked & OK
1695        if calcControls[phfx+'SizeType'] == 'isotropic':    #OK
1696            Sgam = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2/parmDict[phfx+'Size;i']
1697            gamDict[phfx+'Size;i'] = -Sgam*parmDict[phfx+'Size;mx']/parmDict[phfx+'Size;i']
1698            sigDict[phfx+'Size;i'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])**2/(ateln2*parmDict[phfx+'Size;i'])
1699        elif calcControls[phfx+'SizeType'] == 'uniaxial':   #OK
1700            const = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2
1701            H = np.array(refl[:3])
1702            P = np.array(calcControls[phfx+'SizeAxis'])
1703            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1704            Si = parmDict[phfx+'Size;i']
1705            Sa = parmDict[phfx+'Size;a']
1706            gami = const/(Si*Sa)
1707            sqtrm = np.sqrt((sinP*Sa)**2+(cosP*Si)**2)
1708            Sgam = gami*sqtrm
1709            dsi = gami*Si*cosP**2/sqtrm-Sgam/Si
1710            dsa = gami*Sa*sinP**2/sqtrm-Sgam/Sa
1711            gamDict[phfx+'Size;i'] = dsi*parmDict[phfx+'Size;mx']
1712            gamDict[phfx+'Size;a'] = dsa*parmDict[phfx+'Size;mx']
1713            sigDict[phfx+'Size;i'] = 2.*dsi*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1714            sigDict[phfx+'Size;a'] = 2.*dsa*Sgam*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1715        else:           #OK  ellipsoidal crystallites
1716            const = 1.e-4*parmDict[hfx+'difC']*refl[4+im]**2
1717            Sij =[parmDict[phfx+'Size:%d'%(i)] for i in range(6)]
1718            H = np.array(refl[:3])
1719            lenR,dRdS = G2pwd.ellipseSizeDerv(H,Sij,GB)
1720            Sgam = const/lenR
1721            for i,item in enumerate([phfx+'Size:%d'%(j) for j in range(6)]):
1722                gamDict[item] = -(const/lenR**2)*dRdS[i]*parmDict[phfx+'Size;mx']
1723                sigDict[item] = -2.*Sgam*(const/lenR**2)*dRdS[i]*(1.-parmDict[phfx+'Size;mx'])**2/ateln2
1724        gamDict[phfx+'Size;mx'] = Sgam  #OK
1725        sigDict[phfx+'Size;mx'] = -2.*Sgam**2*(1.-parmDict[phfx+'Size;mx'])/ateln2  #OK
1726               
1727        #microstrain derivatives               
1728        if calcControls[phfx+'MustrainType'] == 'isotropic':
1729            Mgam = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*parmDict[phfx+'Mustrain;i']
1730            gamDict[phfx+'Mustrain;i'] =  1.e-6*refl[4+im]*parmDict[hfx+'difC']*parmDict[phfx+'Mustrain;mx']   #OK
1731            sigDict[phfx+'Mustrain;i'] =  2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])**2/(ateln2*parmDict[phfx+'Mustrain;i'])       
1732        elif calcControls[phfx+'MustrainType'] == 'uniaxial':
1733            H = np.array(refl[:3])
1734            P = np.array(calcControls[phfx+'MustrainAxis'])
1735            cosP,sinP = G2lat.CosSinAngle(H,P,G)
1736            Si = parmDict[phfx+'Mustrain;i']
1737            Sa = parmDict[phfx+'Mustrain;a']
1738            gami = 1.e-6*parmDict[hfx+'difC']*refl[4+im]*Si*Sa
1739            sqtrm = np.sqrt((Si*cosP)**2+(Sa*sinP)**2)
1740            Mgam = gami/sqtrm
1741            dsi = -gami*Si*cosP**2/sqtrm**3
1742            dsa = -gami*Sa*sinP**2/sqtrm**3
1743            gamDict[phfx+'Mustrain;i'] = (Mgam/Si+dsi)*parmDict[phfx+'Mustrain;mx']
1744            gamDict[phfx+'Mustrain;a'] = (Mgam/Sa+dsa)*parmDict[phfx+'Mustrain;mx']
1745            sigDict[phfx+'Mustrain;i'] = 2*(Mgam/Si+dsi)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2
1746            sigDict[phfx+'Mustrain;a'] = 2*(Mgam/Sa+dsa)*Mgam*(1.-parmDict[phfx+'Mustrain;mx'])**2/ateln2       
1747        else:       #generalized - P.W. Stephens model OK
1748            pwrs = calcControls[phfx+'MuPwrs']
1749            Strms = G2spc.MustrainCoeff(refl[:3],SGData)
1750            const = 1.e-6*parmDict[hfx+'difC']*refl[4+im]**3
1751            Sum = 0
1752            for i,strm in enumerate(Strms):
1753                Sum += parmDict[phfx+'Mustrain:'+str(i)]*strm
1754                gamDict[phfx+'Mustrain:'+str(i)] = strm*parmDict[phfx+'Mustrain;mx']/2.
1755                sigDict[phfx+'Mustrain:'+str(i)] = strm*(1.-parmDict[phfx+'Mustrain;mx'])**2
1756            Mgam = const*np.sqrt(Sum)
1757            for i in range(len(Strms)):
1758                gamDict[phfx+'Mustrain:'+str(i)] *= Mgam/Sum
1759                sigDict[phfx+'Mustrain:'+str(i)] *= const**2/ateln2       
1760        gamDict[phfx+'Mustrain;mx'] = Mgam
1761        sigDict[phfx+'Mustrain;mx'] = -2.*Mgam**2*(1.-parmDict[phfx+'Mustrain;mx'])/ateln2
1762       
1763    return sigDict,gamDict
1764       
1765def GetReflPos(refl,im,wave,A,pfx,hfx,calcControls,parmDict):
1766    'Needs a doc string'
1767    if im:
1768        h,k,l,m = refl[:4]
1769        vec = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']])
1770        d = 1./np.sqrt(G2lat.calc_rDsqSS(np.array([h,k,l,m]),A,vec))
1771    else:
1772        h,k,l = refl[:3]
1773        d = 1./np.sqrt(G2lat.calc_rDsq(np.array([h,k,l]),A))
1774    refl[4+im] = d
1775    if 'C' in calcControls[hfx+'histType']:
1776        pos = 2.0*asind(wave/(2.0*d))+parmDict[hfx+'Zero']
1777        const = 9.e-2/(np.pi*parmDict[hfx+'Gonio. radius'])                  #shifts in microns
1778        if 'Bragg' in calcControls[hfx+'instType']:
1779            pos -= const*(4.*parmDict[hfx+'Shift']*cosd(pos/2.0)+ \
1780                parmDict[hfx+'Transparency']*sind(pos)*100.0)            #trans(=1/mueff) in cm
1781        else:               #Debye-Scherrer - simple but maybe not right
1782            pos -= const*(parmDict[hfx+'DisplaceX']*cosd(pos)+parmDict[hfx+'DisplaceY']*sind(pos))
1783    elif 'T' in calcControls[hfx+'histType']:
1784        pos = parmDict[hfx+'difC']*d+parmDict[hfx+'difA']*d**2+parmDict[hfx+'difB']/d+parmDict[hfx+'Zero']
1785        #do I need sample position effects - maybe?
1786    return pos
1787
1788def GetReflPosDerv(refl,im,wave,A,pfx,hfx,calcControls,parmDict):
1789    'Needs a doc string'
1790    dpr = 180./np.pi
1791    if im:
1792        h,k,l,m = refl[:4]
1793        vec = np.array([parmDict[pfx+'mV0'],parmDict[pfx+'mV1'],parmDict[pfx+'mV2']])
1794        dstsq = G2lat.calc_rDsqSS(np.array([h,k,l,m]),A,vec)
1795    else:
1796        m = 0
1797        h,k,l = refl[:3]       
1798        dstsq = G2lat.calc_rDsq(np.array([h,k,l]),A)
1799    dst = np.sqrt(dstsq)
1800    dsp = 1./dst
1801    if 'C' in calcControls[hfx+'histType']:
1802        pos = refl[5+im]-parmDict[hfx+'Zero']
1803        const = dpr/np.sqrt(1.0-wave**2*dstsq/4.0)
1804        dpdw = const*dst
1805        dpdA = np.array([h**2,k**2,l**2,h*k,h*l,k*l])*const*wave/(2.0*dst)
1806        dpdZ = 1.0
1807        dpdV = np.array([2.*h*A[0]+k*A[3]+l*A[4],2*k*A[1]+h*A[3]+l*A[5],
1808            2*l*A[2]+h*A[4]+k*A[5]])*m*const*wave/(2.0*dst)
1809        shft = 9.e-2/(np.pi*parmDict[hfx+'Gonio. radius'])                  #shifts in microns
1810        if 'Bragg' in calcControls[hfx+'instType']:
1811            dpdSh = -4.*shft*cosd(pos/2.0)
1812            dpdTr = -shft*sind(pos)*100.0
1813            return dpdA,dpdw,dpdZ,dpdSh,dpdTr,0.,0.,dpdV
1814        else:               #Debye-Scherrer - simple but maybe not right
1815            dpdXd = -shft*cosd(pos)
1816            dpdYd = -shft*sind(pos)
1817            return dpdA,dpdw,dpdZ,0.,0.,dpdXd,dpdYd,dpdV
1818    elif 'T' in calcControls[hfx+'histType']:
1819        dpdA = -np.array([h**2,k**2,l**2,h*k,h*l,k*l])*parmDict[hfx+'difC']*dsp**3/2.
1820        dpdZ = 1.0
1821        dpdDC = dsp
1822        dpdDA = dsp**2
1823        dpdDB = 1./dsp
1824        dpdV = np.array([2.*h*A[0]+k*A[3]+l*A[4],2*k*A[1]+h*A[3]+l*A[5],
1825            2*l*A[2]+h*A[4]+k*A[5]])*m**parmDict[hfx+'difC']*dsp**3/2.
1826        return dpdA,dpdZ,dpdDC,dpdDA,dpdDB,dpdV
1827           
1828def GetHStrainShift(refl,im,SGData,phfx,hfx,calcControls,parmDict):
1829    'Needs a doc string'
1830    laue = SGData['SGLaue']
1831    uniq = SGData['SGUniq']
1832    h,k,l = refl[:3]
1833    if laue in ['m3','m3m']:
1834        Dij = parmDict[phfx+'D11']*(h**2+k**2+l**2)+ \
1835            refl[4+im]**2*parmDict[phfx+'eA']*((h*k)**2+(h*l)**2+(k*l)**2)/(h**2+k**2+l**2)**2
1836    elif laue in ['6/m','6/mmm','3m1','31m','3']:
1837        Dij = parmDict[phfx+'D11']*(h**2+k**2+h*k)+parmDict[phfx+'D33']*l**2
1838    elif laue in ['3R','3mR']:
1839        Dij = parmDict[phfx+'D11']*(h**2+k**2+l**2)+parmDict[phfx+'D12']*(h*k+h*l+k*l)
1840    elif laue in ['4/m','4/mmm']:
1841        Dij = parmDict[phfx+'D11']*(h**2+k**2)+parmDict[phfx+'D33']*l**2
1842    elif laue in ['mmm']:
1843        Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2
1844    elif laue in ['2/m']:
1845        Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2
1846        if uniq == 'a':
1847            Dij += parmDict[phfx+'D23']*k*l
1848        elif uniq == 'b':
1849            Dij += parmDict[phfx+'D13']*h*l
1850        elif uniq == 'c':
1851            Dij += parmDict[phfx+'D12']*h*k
1852    else:
1853        Dij = parmDict[phfx+'D11']*h**2+parmDict[phfx+'D22']*k**2+parmDict[phfx+'D33']*l**2+ \
1854            parmDict[phfx+'D12']*h*k+parmDict[phfx+'D13']*h*l+parmDict[phfx+'D23']*k*l
1855    if 'C' in calcControls[hfx+'histType']:
1856        return -180.*Dij*refl[4+im]**2*tand(refl[5+im]/2.0)/np.pi
1857    else:
1858        return -Dij*parmDict[hfx+'difC']*refl[4+im]**2/2.
1859           
1860def GetHStrainShiftDerv(refl,im,SGData,phfx,hfx,calcControls,parmDict):
1861    'Needs a doc string'
1862    laue = SGData['SGLaue']
1863    uniq = SGData['SGUniq']
1864    h,k,l = refl[:3]
1865    if laue in ['m3','m3m']:
1866        dDijDict = {phfx+'D11':h**2+k**2+l**2,
1867            phfx+'eA':refl[4+im]**2*((h*k)**2+(h*l)**2+(k*l)**2)/(h**2+k**2+l**2)**2}
1868    elif laue in ['6/m','6/mmm','3m1','31m','3']:
1869        dDijDict = {phfx+'D11':h**2+k**2+h*k,phfx+'D33':l**2}
1870    elif laue in ['3R','3mR']:
1871        dDijDict = {phfx+'D11':h**2+k**2+l**2,phfx+'D12':h*k+h*l+k*l}
1872    elif laue in ['4/m','4/mmm']:
1873        dDijDict = {phfx+'D11':h**2+k**2,phfx+'D33':l**2}
1874    elif laue in ['mmm']:
1875        dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2}
1876    elif laue in ['2/m']:
1877        dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2}
1878        if uniq == 'a':
1879            dDijDict[phfx+'D23'] = k*l
1880        elif uniq == 'b':
1881            dDijDict[phfx+'D13'] = h*l
1882        elif uniq == 'c':
1883            dDijDict[phfx+'D12'] = h*k
1884    else:
1885        dDijDict = {phfx+'D11':h**2,phfx+'D22':k**2,phfx+'D33':l**2,
1886            phfx+'D12':h*k,phfx+'D13':h*l,phfx+'D23':k*l}
1887    if 'C' in calcControls[hfx+'histType']:
1888        for item in dDijDict:
1889            dDijDict[item] *= 180.0*refl[4+im]**2*tand(refl[5+im]/2.0)/np.pi
1890    else:
1891        for item in dDijDict:
1892            dDijDict[item] *= -parmDict[hfx+'difC']*refl[4+im]**3/2.
1893    return dDijDict
1894   
1895def GetDij(phfx,SGData,parmDict):
1896    HSvals = [parmDict[phfx+name] for name in G2spc.HStrainNames(SGData)]
1897    return G2spc.HStrainVals(HSvals,SGData)
1898               
1899def GetFobsSq(Histograms,Phases,parmDict,calcControls):
1900    'Needs a doc string'
1901    histoList = Histograms.keys()
1902    histoList.sort()
1903    for histogram in histoList:
1904        if 'PWDR' in histogram[:4]:
1905            Histogram = Histograms[histogram]
1906            hId = Histogram['hId']
1907            hfx = ':%d:'%(hId)
1908            Limits = calcControls[hfx+'Limits']
1909            if 'C' in calcControls[hfx+'histType']:
1910                shl = max(parmDict[hfx+'SH/L'],0.0005)
1911                Ka2 = False
1912                kRatio = 0.0
1913                if hfx+'Lam1' in parmDict.keys():
1914                    Ka2 = True
1915                    lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1'])
1916                    kRatio = parmDict[hfx+'I(L2)/I(L1)']
1917            x,y,w,yc,yb,yd = Histogram['Data']
1918            xB = np.searchsorted(x,Limits[0])
1919            xF = np.searchsorted(x,Limits[1])
1920            ymb = np.array(y-yb)
1921            ymb = np.where(ymb,ymb,1.0)
1922            ycmb = np.array(yc-yb)
1923            ratio = 1./np.where(ycmb,ycmb/ymb,1.e10)         
1924            refLists = Histogram['Reflection Lists']
1925            for phase in refLists:
1926                if phase not in Phases:     #skips deleted or renamed phases silently!
1927                    continue
1928                Phase = Phases[phase]
1929                im = 0
1930                if Phase['General']['Type'] in ['modulated','magnetic']:
1931                    im = 1
1932                pId = Phase['pId']
1933                phfx = '%d:%d:'%(pId,hId)
1934                refDict = refLists[phase]
1935                sumFo = 0.0
1936                sumdF = 0.0
1937                sumFosq = 0.0
1938                sumdFsq = 0.0
1939                sumInt = 0.0
1940                for refl in refDict['RefList']:
1941                    if 'C' in calcControls[hfx+'histType']:
1942                        yp = np.zeros_like(yb)
1943                        Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl)
1944                        iBeg = max(xB,np.searchsorted(x,refl[5+im]-fmin))
1945                        iFin = max(xB,min(np.searchsorted(x,refl[5+im]+fmax),xF))
1946                        iFin2 = iFin
1947                        if not iBeg+iFin:       #peak below low limit - skip peak
1948                            continue
1949                        elif not iBeg-iFin:     #peak above high limit - done
1950                            break
1951                        elif iBeg < iFin:
1952                            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
1953                            sumInt += refl[11+im]*refl[9+im]
1954                            if Ka2:
1955                                pos2 = refl[5+im]+lamRatio*tand(refl[5+im]/2.0)       # + 360/pi * Dlam/lam * tan(th)
1956                                Wd,fmin,fmax = G2pwd.getWidthsCW(pos2,refl[6+im],refl[7+im],shl)
1957                                iBeg2 = max(xB,np.searchsorted(x,pos2-fmin))
1958                                iFin2 = min(np.searchsorted(x,pos2+fmax),xF)
1959                                if iFin2 > iBeg2: 
1960                                    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
1961                                    sumInt += refl[11+im]*refl[9+im]*kRatio
1962                            refl[8+im] = np.sum(np.where(ratio[iBeg:iFin2]>0.,yp[iBeg:iFin2]*ratio[iBeg:iFin2]/(refl[11+im]*(1.+kRatio)),0.0))
1963                               
1964                    elif 'T' in calcControls[hfx+'histType']:
1965                        yp = np.zeros_like(yb)
1966                        Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im])
1967                        iBeg = max(xB,np.searchsorted(x,refl[5+im]-fmin))
1968                        iFin = max(xB,min(np.searchsorted(x,refl[5+im]+fmax),xF))
1969                        if iBeg < iFin:
1970                            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
1971                            refl[8+im] = np.sum(np.where(ratio[iBeg:iFin]>0.,yp[iBeg:iFin]*ratio[iBeg:iFin]/refl[11+im],0.0))
1972                            sumInt += refl[11+im]*refl[9+im]
1973                    Fo = np.sqrt(np.abs(refl[8+im]))
1974                    Fc = np.sqrt(np.abs(refl[9]+im))
1975                    sumFo += Fo
1976                    sumFosq += refl[8+im]**2
1977                    sumdF += np.abs(Fo-Fc)
1978                    sumdFsq += (refl[8+im]-refl[9+im])**2
1979                if sumFo:
1980                    Histogram['Residuals'][phfx+'Rf'] = min(100.,(sumdF/sumFo)*100.)
1981                    Histogram['Residuals'][phfx+'Rf^2'] = min(100.,np.sqrt(sumdFsq/sumFosq)*100.)
1982                else:
1983                    Histogram['Residuals'][phfx+'Rf'] = 100.
1984                    Histogram['Residuals'][phfx+'Rf^2'] = 100.
1985                Histogram['Residuals'][phfx+'sumInt'] = sumInt
1986                Histogram['Residuals'][phfx+'Nref'] = len(refDict['RefList'])
1987                Histogram['Residuals']['hId'] = hId
1988        elif 'HKLF' in histogram[:4]:
1989            Histogram = Histograms[histogram]
1990            Histogram['Residuals']['hId'] = Histograms[histogram]['hId']
1991               
1992def getPowderProfile(parmDict,x,varylist,Histogram,Phases,calcControls,pawleyLookup):
1993    'Needs a doc string'
1994   
1995    def GetReflSigGamCW(refl,im,wave,G,GB,phfx,calcControls,parmDict):
1996        U = parmDict[hfx+'U']
1997        V = parmDict[hfx+'V']
1998        W = parmDict[hfx+'W']
1999        X = parmDict[hfx+'X']
2000        Y = parmDict[hfx+'Y']
2001        tanPos = tand(refl[5+im]/2.0)
2002        Ssig,Sgam = GetSampleSigGam(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict)
2003        sig = U*tanPos**2+V*tanPos+W+Ssig     #save peak sigma
2004        sig = max(0.001,sig)
2005        gam = X/cosd(refl[5+im]/2.0)+Y*tanPos+Sgam     #save peak gamma
2006        gam = max(0.001,gam)
2007        return sig,gam
2008               
2009    def GetReflSigGamTOF(refl,im,G,GB,phfx,calcControls,parmDict):
2010        sig = parmDict[hfx+'sig-0']+parmDict[hfx+'sig-1']*refl[4+im]**2+   \
2011            parmDict[hfx+'sig-2']*refl[4+im]**4+parmDict[hfx+'sig-q']/refl[4+im]**2
2012        gam = parmDict[hfx+'X']*refl[4+im]+parmDict[hfx+'Y']*refl[4+im]**2
2013        Ssig,Sgam = GetSampleSigGam(refl,im,0.0,G,GB,SGData,hfx,phfx,calcControls,parmDict)
2014        sig += Ssig
2015        gam += Sgam
2016        return sig,gam
2017       
2018    def GetReflAlpBet(refl,im,hfx,parmDict):
2019        alp = parmDict[hfx+'alpha']/refl[4+im]
2020        bet = parmDict[hfx+'beta-0']+parmDict[hfx+'beta-1']/refl[4+im]**4+parmDict[hfx+'beta-q']/refl[4+im]**2
2021        return alp,bet
2022       
2023    hId = Histogram['hId']
2024    hfx = ':%d:'%(hId)
2025    bakType = calcControls[hfx+'bakType']
2026    yb,Histogram['sumBk'] = G2pwd.getBackground(hfx,parmDict,bakType,calcControls[hfx+'histType'],x)
2027    yc = np.zeros_like(yb)
2028    cw = np.diff(x)
2029    cw = np.append(cw,cw[-1])
2030       
2031    if 'C' in calcControls[hfx+'histType']:   
2032        shl = max(parmDict[hfx+'SH/L'],0.002)
2033        Ka2 = False
2034        if hfx+'Lam1' in parmDict.keys():
2035            wave = parmDict[hfx+'Lam1']
2036            Ka2 = True
2037            lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1'])
2038            kRatio = parmDict[hfx+'I(L2)/I(L1)']
2039        else:
2040            wave = parmDict[hfx+'Lam']
2041    for phase in Histogram['Reflection Lists']:
2042        refDict = Histogram['Reflection Lists'][phase]
2043        if phase not in Phases:     #skips deleted or renamed phases silently!
2044            continue
2045        Phase = Phases[phase]
2046        pId = Phase['pId']
2047        pfx = '%d::'%(pId)
2048        phfx = '%d:%d:'%(pId,hId)
2049        hfx = ':%d:'%(hId)
2050        SGData = Phase['General']['SGData']
2051        SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
2052        im = 0
2053        if Phase['General']['Type'] in ['modulated','magnetic']:
2054            SSGData = Phase['General']['SSGData']
2055            SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
2056            im = 1  #offset in SS reflection list
2057            #??
2058        Dij = GetDij(phfx,SGData,parmDict)
2059        A = [parmDict[pfx+'A%d'%(i)]+Dij[i] for i in range(6)]
2060        G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
2061        if np.any(np.diag(G)<0.):
2062            raise G2obj.G2Exception('invalid metric tensor \n cell/Dij refinement not advised')
2063        GA,GB = G2lat.Gmat2AB(G)    #Orthogonalization matricies
2064        Vst = np.sqrt(nl.det(G))    #V*
2065        if not Phase['General'].get('doPawley'):
2066            time0 = time.time()
2067            if im:
2068                SStructureFactor(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
2069            else:
2070                StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
2071#            print 'sf calc time: %.3fs'%(time.time()-time0)
2072        time0 = time.time()
2073        badPeak = False
2074        for iref,refl in enumerate(refDict['RefList']):
2075            if 'C' in calcControls[hfx+'histType']:
2076                if im:
2077                    h,k,l,m = refl[:4]
2078                else:
2079                    h,k,l = refl[:3]
2080                Uniq = np.inner(refl[:3],SGMT)
2081                refl[5+im] = GetReflPos(refl,im,wave,A,pfx,hfx,calcControls,parmDict)         #corrected reflection position
2082                Lorenz = 1./(2.*sind(refl[5+im]/2.)**2*cosd(refl[5+im]/2.))           #Lorentz correction
2083                refl[6+im:8+im] = GetReflSigGamCW(refl,im,wave,G,GB,phfx,calcControls,parmDict)    #peak sig & gam
2084                refl[11+im:15+im] = GetIntensityCorr(refl,im,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict)
2085                refl[11+im] *= Vst*Lorenz
2086                 
2087                if Phase['General'].get('doPawley'):
2088                    try:
2089                        if im:
2090                            pInd = pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)])
2091                        else:
2092                            pInd = pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)])
2093                        refl[9+im] = parmDict[pInd]
2094                    except KeyError:
2095#                        print ' ***Error %d,%d,%d missing from Pawley reflection list ***'%(h,k,l)
2096                        continue
2097                Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl)
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                elif iBeg > iFin:   #bad peak coeff - skip
2105                    badPeak = True
2106                    continue
2107                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
2108                if Ka2:
2109                    pos2 = refl[5+im]+lamRatio*tand(refl[5+im]/2.0)       # + 360/pi * Dlam/lam * tan(th)
2110                    Wd,fmin,fmax = G2pwd.getWidthsCW(pos2,refl[6+im],refl[7+im],shl)
2111                    iBeg = np.searchsorted(x,pos2-fmin)
2112                    iFin = np.searchsorted(x,pos2+fmax)
2113                    if not iBeg+iFin:       #peak below low limit - skip peak
2114                        continue
2115                    elif not iBeg-iFin:     #peak above high limit - done
2116                        return yc,yb
2117                    elif iBeg > iFin:   #bad peak coeff - skip
2118                        continue
2119                    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
2120            elif 'T' in calcControls[hfx+'histType']:
2121                h,k,l = refl[:3]
2122                Uniq = np.inner(refl[:3],SGMT)
2123                refl[5+im] = GetReflPos(refl,im,0.0,A,pfx,hfx,calcControls,parmDict)         #corrected reflection position
2124                Lorenz = sind(abs(parmDict[hfx+'2-theta'])/2)*refl[4+im]**4                                                #TOF Lorentz correction
2125#                refl[5+im] += GetHStrainShift(refl,im,SGData,phfx,hfx,calcControls,parmDict)               #apply hydrostatic strain shift
2126                refl[6+im:8+im] = GetReflSigGamTOF(refl,im,G,GB,phfx,calcControls,parmDict)    #peak sig & gam
2127                refl[12+im:14+im] = GetReflAlpBet(refl,im,hfx,parmDict)
2128                refl[11+im],refl[15+im],refl[16+im],refl[17+im] = GetIntensityCorr(refl,im,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict)
2129                refl[11+im] *= Vst*Lorenz
2130                if Phase['General'].get('doPawley'):
2131                    try:
2132                        if im:
2133                            pInd =pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)])
2134                        else:
2135                            pInd =pfx+'PWLref:%d'%(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)])
2136                        refl[9+im] = parmDict[pInd]
2137                    except KeyError:
2138#                        print ' ***Error %d,%d,%d missing from Pawley reflection list ***'%(h,k,l)
2139                        continue
2140                Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im])
2141                iBeg = np.searchsorted(x,refl[5+im]-fmin)
2142                iFin = np.searchsorted(x,refl[5+im]+fmax)
2143                if not iBeg+iFin:       #peak below low limit - skip peak
2144                    continue
2145                elif not iBeg-iFin:     #peak above high limit - done
2146                    break
2147                elif iBeg > iFin:   #bad peak coeff - skip
2148                    badPeak = True
2149                    continue
2150                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]
2151#        print 'profile calc time: %.3fs'%(time.time()-time0)
2152    if badPeak:
2153        print 'ouch #4 bad profile coefficients yield negative peak width; some reflections skipped' 
2154    return yc,yb
2155   
2156def getPowderProfileDerv(parmDict,x,varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup):
2157    'Needs a doc string'
2158   
2159    def cellVaryDerv(pfx,SGData,dpdA): 
2160        if SGData['SGLaue'] in ['-1',]:
2161            return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],
2162                [pfx+'A3',dpdA[3]],[pfx+'A4',dpdA[4]],[pfx+'A5',dpdA[5]]]
2163        elif SGData['SGLaue'] in ['2/m',]:
2164            if SGData['SGUniq'] == 'a':
2165                return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A5',dpdA[5]]]
2166            elif SGData['SGUniq'] == 'b':
2167                return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A4',dpdA[4]]]
2168            else:
2169                return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]],[pfx+'A3',dpdA[3]]]
2170        elif SGData['SGLaue'] in ['mmm',]:
2171            return [[pfx+'A0',dpdA[0]],[pfx+'A1',dpdA[1]],[pfx+'A2',dpdA[2]]]
2172        elif SGData['SGLaue'] in ['4/m','4/mmm']:
2173            return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]]
2174        elif SGData['SGLaue'] in ['6/m','6/mmm','3m1', '31m', '3']:
2175            return [[pfx+'A0',dpdA[0]],[pfx+'A2',dpdA[2]]]
2176        elif SGData['SGLaue'] in ['3R', '3mR']:
2177            return [[pfx+'A0',dpdA[0]+dpdA[1]+dpdA[2]],[pfx+'A3',dpdA[3]+dpdA[4]+dpdA[5]]]                       
2178        elif SGData['SGLaue'] in ['m3m','m3']:
2179            return [[pfx+'A0',dpdA[0]]]
2180           
2181    # create a list of dependent variables and set up a dictionary to hold their derivatives
2182    dependentVars = G2mv.GetDependentVars()
2183    depDerivDict = {}
2184    for j in dependentVars:
2185        depDerivDict[j] = np.zeros(shape=(len(x)))
2186    #print 'dependent vars',dependentVars
2187    lenX = len(x)               
2188    hId = Histogram['hId']
2189    hfx = ':%d:'%(hId)
2190    bakType = calcControls[hfx+'bakType']
2191    dMdv = np.zeros(shape=(len(varylist),len(x)))
2192    dMdb,dMddb,dMdpk = G2pwd.getBackgroundDerv(hfx,parmDict,bakType,calcControls[hfx+'histType'],x)
2193    if hfx+'Back;0' in varylist: # for now assume that Back;x vars to not appear in constraints
2194        bBpos =varylist.index(hfx+'Back;0')
2195        dMdv[bBpos:bBpos+len(dMdb)] = dMdb
2196    names = [hfx+'DebyeA',hfx+'DebyeR',hfx+'DebyeU']
2197    for name in varylist:
2198        if 'Debye' in name:
2199            id = int(name.split(';')[-1])
2200            parm = name[:int(name.rindex(';'))]
2201            ip = names.index(parm)
2202            dMdv[varylist.index(name)] = dMddb[3*id+ip]
2203    names = [hfx+'BkPkpos',hfx+'BkPkint',hfx+'BkPksig',hfx+'BkPkgam']
2204    for name in varylist:
2205        if 'BkPk' in name:
2206            parm,id = name.split(';')
2207            id = int(id)
2208            if parm in names:
2209                ip = names.index(parm)
2210                dMdv[varylist.index(name)] = dMdpk[4*id+ip]
2211    cw = np.diff(x)
2212    cw = np.append(cw,cw[-1])
2213    Ka2 = False #also for TOF!
2214    if 'C' in calcControls[hfx+'histType']:   
2215        shl = max(parmDict[hfx+'SH/L'],0.002)
2216        if hfx+'Lam1' in parmDict.keys():
2217            wave = parmDict[hfx+'Lam1']
2218            Ka2 = True
2219            lamRatio = 360*(parmDict[hfx+'Lam2']-parmDict[hfx+'Lam1'])/(np.pi*parmDict[hfx+'Lam1'])
2220            kRatio = parmDict[hfx+'I(L2)/I(L1)']
2221        else:
2222            wave = parmDict[hfx+'Lam']
2223    for phase in Histogram['Reflection Lists']:
2224        refDict = Histogram['Reflection Lists'][phase]
2225        if phase not in Phases:     #skips deleted or renamed phases silently!
2226            continue
2227        Phase = Phases[phase]
2228        SGData = Phase['General']['SGData']
2229        SGMT = np.array([ops[0].T for ops in SGData['SGOps']])
2230        im = 0
2231        if Phase['General']['Type'] in ['modulated','magnetic']:
2232            SSGData = Phase['General']['SSGData']
2233            SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
2234            im = 1  #offset in SS reflection list
2235            #??
2236        pId = Phase['pId']
2237        pfx = '%d::'%(pId)
2238        phfx = '%d:%d:'%(pId,hId)
2239        Dij = GetDij(phfx,SGData,parmDict)
2240        A = [parmDict[pfx+'A%d'%(i)]+Dij[i] for i in range(6)]
2241        G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
2242        GA,GB = G2lat.Gmat2AB(G)    #Orthogonalization matricies
2243        if not Phase['General'].get('doPawley'):
2244            time0 = time.time()
2245            if im:
2246                dFdvDict = SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
2247            else:
2248                dFdvDict = StructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
2249#            print 'sf-derv time %.3fs'%(time.time()-time0)
2250            ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase)
2251        time0 = time.time()
2252        for iref,refl in enumerate(refDict['RefList']):
2253            if im:
2254                h,k,l,m = refl[:4]
2255            else:
2256                h,k,l = refl[:3]
2257            Uniq = np.inner(refl[:3],SGMT)
2258            if 'T' in calcControls[hfx+'histType']:
2259                wave = refl[14+im]
2260            dIdsh,dIdsp,dIdpola,dIdPO,dFdODF,dFdSA,dFdAb,dFdEx = GetIntensityDerv(refl,im,wave,Uniq,G,g,pfx,phfx,hfx,SGData,calcControls,parmDict)
2261            if 'C' in calcControls[hfx+'histType']:        #CW powder
2262                Wd,fmin,fmax = G2pwd.getWidthsCW(refl[5+im],refl[6+im],refl[7+im],shl)
2263            else: #'T'OF
2264                Wd,fmin,fmax = G2pwd.getWidthsTOF(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im])
2265            iBeg = np.searchsorted(x,refl[5+im]-fmin)
2266            iFin = np.searchsorted(x,refl[5+im]+fmax)
2267            if not iBeg+iFin:       #peak below low limit - skip peak
2268                continue
2269            elif not iBeg-iFin:     #peak above high limit - done
2270                break
2271            pos = refl[5+im]
2272            if 'C' in calcControls[hfx+'histType']:
2273                tanth = tand(pos/2.0)
2274                costh = cosd(pos/2.0)
2275                lenBF = iFin-iBeg
2276                dMdpk = np.zeros(shape=(6,lenBF))
2277                dMdipk = G2pwd.getdFCJVoigt3(refl[5+im],refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg:iFin]))
2278                for i in range(5):
2279                    dMdpk[i] += 100.*cw[iBeg:iFin]*refl[11+im]*refl[9+im]*dMdipk[i]
2280                dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'sig':dMdpk[2],'gam':dMdpk[3],'shl':dMdpk[4],'L1/L2':np.zeros_like(dMdpk[0])}
2281                if Ka2:
2282                    pos2 = refl[5+im]+lamRatio*tanth       # + 360/pi * Dlam/lam * tan(th)
2283                    iBeg2 = np.searchsorted(x,pos2-fmin)
2284                    iFin2 = np.searchsorted(x,pos2+fmax)
2285                    if iBeg2-iFin2:
2286                        lenBF2 = iFin2-iBeg2
2287                        dMdpk2 = np.zeros(shape=(6,lenBF2))
2288                        dMdipk2 = G2pwd.getdFCJVoigt3(pos2,refl[6+im],refl[7+im],shl,ma.getdata(x[iBeg2:iFin2]))
2289                        for i in range(5):
2290                            dMdpk2[i] = 100.*cw[iBeg2:iFin2]*refl[11+im]*refl[9+im]*kRatio*dMdipk2[i]
2291                        dMdpk2[5] = 100.*cw[iBeg2:iFin2]*refl[11+im]*dMdipk2[0]
2292                        dervDict2 = {'int':dMdpk2[0],'pos':dMdpk2[1],'sig':dMdpk2[2],'gam':dMdpk2[3],'shl':dMdpk2[4],'L1/L2':dMdpk2[5]*refl[9]}
2293            else:   #'T'OF
2294                lenBF = iFin-iBeg
2295                if lenBF < 0:   #bad peak coeff
2296                    break
2297                dMdpk = np.zeros(shape=(6,lenBF))
2298                dMdipk = G2pwd.getdEpsVoigt(refl[5+im],refl[12+im],refl[13+im],refl[6+im],refl[7+im],ma.getdata(x[iBeg:iFin]))
2299                for i in range(6):
2300                    dMdpk[i] += refl[11+im]*refl[9+im]*dMdipk[i]      #cw[iBeg:iFin]*
2301                dervDict = {'int':dMdpk[0],'pos':dMdpk[1],'alp':dMdpk[2],'bet':dMdpk[3],'sig':dMdpk[4],'gam':dMdpk[5]}           
2302            if Phase['General'].get('doPawley'):
2303                dMdpw = np.zeros(len(x))
2304                try:
2305                    if im:
2306                        pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d,%d'%(h,k,l,m)])
2307                    else:
2308                        pIdx = pfx+'PWLref:'+str(pawleyLookup[pfx+'%d,%d,%d'%(h,k,l)])
2309                    idx = varylist.index(pIdx)
2310                    dMdpw[iBeg:iFin] = dervDict['int']/refl[9+im]
2311                    if Ka2: #not for TOF either
2312                        dMdpw[iBeg2:iFin2] += dervDict2['int']/refl[9+im]
2313                    dMdv[idx] = dMdpw
2314                except: # ValueError:
2315                    pass
2316            if 'C' in calcControls[hfx+'histType']:
2317                dpdA,dpdw,dpdZ,dpdSh,dpdTr,dpdX,dpdY,dpdV = GetReflPosDerv(refl,im,wave,A,pfx,hfx,calcControls,parmDict)
2318                names = {hfx+'Scale':[dIdsh,'int'],hfx+'Polariz.':[dIdpola,'int'],phfx+'Scale':[dIdsp,'int'],
2319                    hfx+'U':[tanth**2,'sig'],hfx+'V':[tanth,'sig'],hfx+'W':[1.0,'sig'],
2320                    hfx+'X':[1.0/costh,'gam'],hfx+'Y':[tanth,'gam'],hfx+'SH/L':[1.0,'shl'],
2321                    hfx+'I(L2)/I(L1)':[1.0,'L1/L2'],hfx+'Zero':[dpdZ,'pos'],hfx+'Lam':[dpdw,'pos'],
2322                    hfx+'Shift':[dpdSh,'pos'],hfx+'Transparency':[dpdTr,'pos'],hfx+'DisplaceX':[dpdX,'pos'],
2323                    hfx+'DisplaceY':[dpdY,'pos'],}
2324                if 'Bragg' in calcControls[hfx+'instType']:
2325                    names.update({hfx+'SurfRoughA':[dFdAb[0],'int'],
2326                        hfx+'SurfRoughB':[dFdAb[1],'int'],})
2327                else:
2328                    names.update({hfx+'Absorption':[dFdAb,'int'],})
2329            else:   #'T'OF
2330                dpdA,dpdZ,dpdDC,dpdDA,dpdDB,dpdV = GetReflPosDerv(refl,im,0.0,A,pfx,hfx,calcControls,parmDict)
2331                names = {hfx+'Scale':[dIdsh,'int'],phfx+'Scale':[dIdsp,'int'],
2332                    hfx+'difC':[dpdDC,'pos'],hfx+'difA':[dpdDA,'pos'],hfx+'difB':[dpdDB,'pos'],
2333                    hfx+'Zero':[dpdZ,'pos'],hfx+'X':[refl[4+im],'gam'],hfx+'Y':[refl[4+im]**2,'gam'],
2334                    hfx+'alpha':[1./refl[4+im],'alp'],hfx+'beta-0':[1.0,'bet'],hfx+'beta-1':[1./refl[4+im]**4,'bet'],
2335                    hfx+'beta-q':[1./refl[4+im]**2,'bet'],hfx+'sig-0':[1.0,'sig'],hfx+'sig-1':[refl[4+im]**2,'sig'],
2336                    hfx+'sig-2':[refl[4+im]**4,'sig'],hfx+'sig-q':[1./refl[4+im]**2,'sig'],
2337                    hfx+'Absorption':[dFdAb,'int'],phfx+'Extinction':[dFdEx,'int'],}
2338            for name in names:
2339                item = names[name]
2340                if name in varylist:
2341                    dMdv[varylist.index(name)][iBeg:iFin] += item[0]*dervDict[item[1]]
2342                    if Ka2 and iFin2-iBeg2:
2343                        dMdv[varylist.index(name)][iBeg2:iFin2] += item[0]*dervDict2[item[1]]
2344                elif name in dependentVars:
2345                    depDerivDict[name][iBeg:iFin] += item[0]*dervDict[item[1]]
2346                    if Ka2 and iFin2-iBeg2:
2347                        depDerivDict[name][iBeg2:iFin2] += item[0]*dervDict2[item[1]]
2348            for iPO in dIdPO:
2349                if iPO in varylist:
2350                    dMdv[varylist.index(iPO)][iBeg:iFin] += dIdPO[iPO]*dervDict['int']
2351                    if Ka2 and iFin2-iBeg2:
2352                        dMdv[varylist.index(iPO)][iBeg2:iFin2] += dIdPO[iPO]*dervDict2['int']
2353                elif iPO in dependentVars:
2354                    depDerivDict[iPO][iBeg:iFin] += dIdPO[iPO]*dervDict['int']
2355                    if Ka2 and iFin2-iBeg2:
2356                        depDerivDict[iPO][iBeg2:iFin2] += dIdPO[iPO]*dervDict2['int']
2357            for i,name in enumerate(['omega','chi','phi']):
2358                aname = pfx+'SH '+name
2359                if aname in varylist:
2360                    dMdv[varylist.index(aname)][iBeg:iFin] += dFdSA[i]*dervDict['int']
2361                    if Ka2 and iFin2-iBeg2:
2362                        dMdv[varylist.index(aname)][iBeg2:iFin2] += dFdSA[i]*dervDict2['int']
2363                elif aname in dependentVars:
2364                    depDerivDict[aname][iBeg:iFin] += dFdSA[i]*dervDict['int']
2365                    if Ka2 and iFin2-iBeg2:
2366                        depDerivDict[aname][iBeg2:iFin2] += dFdSA[i]*dervDict2['int']
2367            for iSH in dFdODF:
2368                if iSH in varylist:
2369                    dMdv[varylist.index(iSH)][iBeg:iFin] += dFdODF[iSH]*dervDict['int']
2370                    if Ka2 and iFin2-iBeg2:
2371                        dMdv[varylist.index(iSH)][iBeg2:iFin2] += dFdODF[iSH]*dervDict2['int']
2372                elif iSH in dependentVars:
2373                    depDerivDict[iSH][iBeg:iFin] += dFdODF[iSH]*dervDict['int']
2374                    if Ka2 and iFin2-iBeg2:
2375                        depDerivDict[iSH][iBeg2:iFin2] += dFdODF[iSH]*dervDict2['int']
2376            cellDervNames = cellVaryDerv(pfx,SGData,dpdA)
2377            for name,dpdA in cellDervNames:
2378                if name in varylist:
2379                    dMdv[varylist.index(name)][iBeg:iFin] += dpdA*dervDict['pos']
2380                    if Ka2 and iFin2-iBeg2:
2381                        dMdv[varylist.index(name)][iBeg2:iFin2] += dpdA*dervDict2['pos']
2382                elif name in dependentVars:
2383                    depDerivDict[name][iBeg:iFin] += dpdA*dervDict['pos']
2384                    if Ka2 and iFin2-iBeg2:
2385                        depDerivDict[name][iBeg2:iFin2] += dpdA*dervDict2['pos']
2386            dDijDict = GetHStrainShiftDerv(refl,im,SGData,phfx,hfx,calcControls,parmDict)
2387            for name in dDijDict:
2388                if name in varylist:
2389                    dMdv[varylist.index(name)][iBeg:iFin] += dDijDict[name]*dervDict['pos']
2390                    if Ka2 and iFin2-iBeg2:
2391                        dMdv[varylist.index(name)][iBeg2:iFin2] += dDijDict[name]*dervDict2['pos']
2392                elif name in dependentVars:
2393                    depDerivDict[name][iBeg:iFin] += dDijDict[name]*dervDict['pos']
2394                    if Ka2 and iFin2-iBeg2:
2395                        depDerivDict[name][iBeg2:iFin2] += dDijDict[name]*dervDict2['pos']
2396            for i,name in enumerate([pfx+'mV0',pfx+'mV1',pfx+'mV2']):
2397                if name in varylist:
2398                    dMdv[varylist.index(name)][iBeg:iFin] += dpdV[i]*dervDict['pos']
2399                    if Ka2 and iFin2-iBeg2:
2400                        dMdv[varylist.index(name)][iBeg2:iFin2] += dpdV[i]*dervDict2['pos']
2401                elif name in dependentVars:
2402                    depDerivDict[name][iBeg:iFin] += dpdV[i]*dervDict['pos']
2403                    if Ka2 and iFin2-iBeg2:
2404                        depDerivDict[name][iBeg2:iFin2] += dpdV[i]*dervDict2['pos']
2405            if 'C' in calcControls[hfx+'histType']:
2406                sigDict,gamDict = GetSampleSigGamDerv(refl,im,wave,G,GB,SGData,hfx,phfx,calcControls,parmDict)
2407            else:   #'T'OF
2408                sigDict,gamDict = GetSampleSigGamDerv(refl,im,0.0,G,GB,SGData,hfx,phfx,calcControls,parmDict)
2409            for name in gamDict:
2410                if name in varylist:
2411                    dMdv[varylist.index(name)][iBeg:iFin] += gamDict[name]*dervDict['gam']
2412                    if Ka2 and iFin2-iBeg2:
2413                        dMdv[varylist.index(name)][iBeg2:iFin2] += gamDict[name]*dervDict2['gam']
2414                elif name in dependentVars:
2415                    depDerivDict[name][iBeg:iFin] += gamDict[name]*dervDict['gam']
2416                    if Ka2 and iFin2-iBeg2:
2417                        depDerivDict[name][iBeg2:iFin2] += gamDict[name]*dervDict2['gam']
2418            for name in sigDict:
2419                if name in varylist:
2420                    dMdv[varylist.index(name)][iBeg:iFin] += sigDict[name]*dervDict['sig']
2421                    if Ka2 and iFin2-iBeg2:
2422                        dMdv[varylist.index(name)][iBeg2:iFin2] += sigDict[name]*dervDict2['sig']
2423                elif name in dependentVars:
2424                    depDerivDict[name][iBeg:iFin] += sigDict[name]*dervDict['sig']
2425                    if Ka2 and iFin2-iBeg2:
2426                        depDerivDict[name][iBeg2:iFin2] += sigDict[name]*dervDict2['sig']
2427            for name in ['BabA','BabU']:
2428                if refl[9+im]:
2429                    if phfx+name in varylist:
2430                        dMdv[varylist.index(phfx+name)][iBeg:iFin] += dFdvDict[pfx+name][iref]*dervDict['int']/refl[9+im]
2431                        if Ka2 and iFin2-iBeg2:
2432                            dMdv[varylist.index(phfx+name)][iBeg2:iFin2] += dFdvDict[pfx+name][iref]*dervDict2['int']/refl[9+im]
2433                    elif phfx+name in dependentVars:                   
2434                        depDerivDict[phfx+name][iBeg:iFin] += dFdvDict[pfx+name][iref]*dervDict['int']/refl[9+im]
2435                        if Ka2 and iFin2-iBeg2:
2436                            depDerivDict[phfx+name][iBeg2:iFin2] += dFdvDict[pfx+name][iref]*dervDict2['int']/refl[9+im]                 
2437            if not Phase['General'].get('doPawley'):
2438                #do atom derivatives -  for RB,F,X & U so far             
2439                corr = dervDict['int']/refl[9+im]
2440                if Ka2 and iFin2-iBeg2:
2441                    corr2 = dervDict2['int']/refl[9+im]
2442                for name in varylist+dependentVars:
2443                    if '::RBV;' in name:
2444                        pass
2445                    else:
2446                        try:
2447                            aname = name.split(pfx)[1][:2]
2448                            if aname not in ['Af','dA','AU','RB']: continue # skip anything not an atom or rigid body param
2449                        except IndexError:
2450                            continue
2451                    if name in varylist:
2452                        dMdv[varylist.index(name)][iBeg:iFin] += dFdvDict[name][iref]*corr
2453                        if Ka2 and iFin2-iBeg2:
2454                            dMdv[varylist.index(name)][iBeg2:iFin2] += dFdvDict[name][iref]*corr2
2455                    elif name in dependentVars:
2456                        depDerivDict[name][iBeg:iFin] += dFdvDict[name][iref]*corr
2457                        if Ka2 and iFin2-iBeg2:
2458                            depDerivDict[name][iBeg2:iFin2] += dFdvDict[name][iref]*corr2
2459    #        print 'profile derv time: %.3fs'%(time.time()-time0)
2460    # now process derivatives in constraints
2461    G2mv.Dict2Deriv(varylist,depDerivDict,dMdv)
2462    return dMdv
2463   
2464def UserRejectHKL(ref,im,userReject):
2465    if ref[5+im]/ref[6+im] < userReject['minF/sig']:
2466        return False
2467    elif userReject['MaxD'] < ref[4+im] > userReject['MinD']:
2468        return False
2469    elif ref[11+im] < userReject['MinExt']:
2470        return False
2471    elif abs(ref[5+im]-ref[7+im])/ref[6+im] > userReject['MaxDF/F']:
2472        return False
2473    return True
2474   
2475def dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict):
2476    '''Loop over reflections in a HKLF histogram and compute derivatives of the fitting
2477    model (M) with respect to all parameters.  Independent and dependant dM/dp arrays
2478    are returned to either dervRefine or HessRefine.
2479
2480    :returns:
2481    '''
2482    nobs = Histogram['Residuals']['Nobs']
2483    hId = Histogram['hId']
2484    hfx = ':%d:'%(hId)
2485    pfx = '%d::'%(Phase['pId'])
2486    phfx = '%d:%d:'%(Phase['pId'],hId)
2487    SGData = Phase['General']['SGData']
2488    im = 0
2489    if Phase['General']['Type'] in ['modulated','magnetic']:
2490        SSGData = Phase['General']['SSGData']
2491        SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
2492        im = 1  #offset in SS reflection list
2493    A = [parmDict[pfx+'A%d'%(i)] for i in range(6)]
2494    G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
2495    refDict = Histogram['Data']
2496    if parmDict[phfx+'Scale'] < 0.:
2497        parmDict[phfx+'Scale'] = .001
2498    if im:
2499        dFdvDict = SStructureFactorDerv(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
2500    else:
2501        dFdvDict = StructureFactorDerv(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
2502    ApplyRBModelDervs(dFdvDict,parmDict,rigidbodyDict,Phase)
2503    dMdvh = np.zeros((len(varylist),len(refDict['RefList'])))
2504    dependentVars = G2mv.GetDependentVars()
2505    depDerivDict = {}
2506    for j in dependentVars:
2507        depDerivDict[j] = np.zeros(shape=(len(refDict['RefList'])))
2508    wdf = np.zeros(len(refDict['RefList']))
2509    if calcControls['F**2']:
2510        for iref,ref in enumerate(refDict['RefList']):
2511            if ref[6+im] > 0:
2512                dervDict,dervCor = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist+dependentVars)[1:]
2513                w = 1.0/ref[6+im]
2514                if ref[3+im] > 0:
2515                    wdf[iref] = w*(ref[5+im]-ref[7+im])
2516                    for j,var in enumerate(varylist):
2517                        if var in dFdvDict:
2518                            dMdvh[j][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2519                    for var in dependentVars:
2520                        if var in dFdvDict:
2521                            depDerivDict[var][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2522                    if phfx+'Scale' in varylist:
2523                        dMdvh[varylist.index(phfx+'Scale')][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale']  #OK
2524                    elif phfx+'Scale' in dependentVars:
2525                        depDerivDict[phfx+'Scale'][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale']   #OK
2526                    for item in ['Ep','Es','Eg']:
2527                        if phfx+item in varylist and phfx+item in dervDict:
2528                            dMdvh[varylist.index(phfx+item)][iref] = w*dervDict[phfx+item]/ref[11+im]  #OK
2529                        elif phfx+item in dependentVars and phfx+item in dervDict:
2530                            depDerivDict[phfx+item][iref] = w*dervDict[phfx+item]/ref[11+im]  #OK
2531                    for item in ['BabA','BabU']:
2532                        if phfx+item in varylist:
2533                            dMdvh[varylist.index(phfx+item)][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2534                        elif phfx+item in dependentVars:
2535                            depDerivDict[phfx+item][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2536    else:   #F refinement
2537        for iref,ref in enumerate(refDict['RefList']):
2538            if ref[5+im] > 0.:
2539                dervDict,dervCor = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist+dependentVars)[1:]
2540                Fo = np.sqrt(ref[5+im])
2541                Fc = np.sqrt(ref[7+im])
2542                w = 1.0/ref[6+im]
2543                if ref[3+im] > 0:
2544                    wdf[iref] = 2.0*Fc*w*(Fo-Fc)
2545                    for j,var in enumerate(varylist):
2546                        if var in dFdvDict:
2547                            dMdvh[j][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2548                    for var in dependentVars:
2549                        if var in dFdvDict:
2550                            depDerivDict[var][iref] = w*dFdvDict[var][iref]*parmDict[phfx+'Scale']*ref[11+im]
2551                    if phfx+'Scale' in varylist:
2552                        dMdvh[varylist.index(phfx+'Scale')][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale']  #OK
2553                    elif phfx+'Scale' in dependentVars:
2554                        depDerivDict[phfx+'Scale'][iref] = w*ref[7+im]*ref[11+im]/parmDict[phfx+'Scale']   #OK                   
2555                    for item in ['Ep','Es','Eg']:   #OK!
2556                        if phfx+item in varylist and phfx+item in dervDict:
2557                            dMdvh[varylist.index(phfx+item)][iref] = w*dervDict[phfx+item]/ref[11+im] 
2558                        elif phfx+item in dependentVars and phfx+item in dervDict:
2559                            depDerivDict[phfx+item][iref] = w*dervDict[phfx+item]/ref[11+im]
2560                    for item in ['BabA','BabU']:
2561                        if phfx+item in varylist:
2562                            dMdvh[varylist.index(phfx+item)][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2563                        elif phfx+item in dependentVars:
2564                            depDerivDict[phfx+item][iref] = w*dFdvDict[pfx+item][iref]*parmDict[phfx+'Scale']*ref[11+im]
2565    return dMdvh,depDerivDict,wdf
2566   
2567
2568def dervRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg):
2569    '''Loop over histograms and compute derivatives of the fitting
2570    model (M) with respect to all parameters.  Results are returned in
2571    a Jacobian matrix (aka design matrix) of dimensions (n by m) where
2572    n is the number of parameters and m is the number of data
2573    points. This can exceed memory when m gets large. This routine is
2574    used when refinement derivatives are selected as "analtytic
2575    Jacobian" in Controls.
2576
2577    :returns: Jacobian numpy.array dMdv for all histograms concatinated
2578    '''
2579    parmDict.update(zip(varylist,values))
2580    G2mv.Dict2Map(parmDict,varylist)
2581    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
2582    nvar = len(varylist)
2583    dMdv = np.empty(0)
2584    histoList = Histograms.keys()
2585    histoList.sort()
2586    for histogram in histoList:
2587        if 'PWDR' in histogram[:4]:
2588            Histogram = Histograms[histogram]
2589            hId = Histogram['hId']
2590            hfx = ':%d:'%(hId)
2591            wtFactor = calcControls[hfx+'wtFactor']
2592            Limits = calcControls[hfx+'Limits']
2593            x,y,w,yc,yb,yd = Histogram['Data']
2594            xB = np.searchsorted(x,Limits[0])
2595            xF = np.searchsorted(x,Limits[1])
2596            dMdvh = np.sqrt(w[xB:xF])*getPowderProfileDerv(parmDict,x[xB:xF],
2597                varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup)
2598        elif 'HKLF' in histogram[:4]:
2599            Histogram = Histograms[histogram]
2600            phase = Histogram['Reflection Lists']
2601            Phase = Phases[phase]
2602            dMdvh,depDerivDict,wdf = dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict)
2603            hfx = ':%d:'%(Histogram['hId'])
2604            wtFactor = calcControls[hfx+'wtFactor']
2605            # now process derivatives in constraints
2606            G2mv.Dict2Deriv(varylist,depDerivDict,dMdvh)
2607        else:
2608            continue        #skip non-histogram entries
2609        if len(dMdv):
2610            dMdv = np.concatenate((dMdv.T,np.sqrt(wtFactor)*dMdvh.T)).T
2611        else:
2612            dMdv = np.sqrt(wtFactor)*dMdvh
2613           
2614    pNames,pVals,pWt,pWsum = penaltyFxn(HistoPhases,calcControls,parmDict,varylist)
2615    if np.any(pVals):
2616        dpdv = penaltyDeriv(pNames,pVals,HistoPhases,calcControls,parmDict,varylist)
2617        dMdv = np.concatenate((dMdv.T,(np.sqrt(pWt)*dpdv).T)).T
2618       
2619    return dMdv
2620
2621def HessRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg):
2622    '''Loop over histograms and compute derivatives of the fitting
2623    model (M) with respect to all parameters.  For each histogram, the
2624    Jacobian matrix, dMdv, with dimensions (n by m) where n is the
2625    number of parameters and m is the number of data points *in the
2626    histogram*. The (n by n) Hessian is computed from each Jacobian
2627    and it is returned.  This routine is used when refinement
2628    derivatives are selected as "analtytic Hessian" in Controls.
2629
2630    :returns: Vec,Hess where Vec is the least-squares vector and Hess is the Hessian
2631    '''
2632    parmDict.update(zip(varylist,values))
2633    G2mv.Dict2Map(parmDict,varylist)
2634    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
2635    #fixup H atom positions here?
2636    ApplyRBModels(parmDict,Phases,rigidbodyDict)        #,Update=True??
2637    nvar = len(varylist)
2638    Hess = np.empty(0)
2639    histoList = Histograms.keys()
2640    histoList.sort()
2641    for histogram in histoList:
2642        if 'PWDR' in histogram[:4]:
2643            Histogram = Histograms[histogram]
2644            hId = Histogram['hId']
2645            hfx = ':%d:'%(hId)
2646            wtFactor = calcControls[hfx+'wtFactor']
2647            Limits = calcControls[hfx+'Limits']
2648            x,y,w,yc,yb,yd = Histogram['Data']
2649            W = wtFactor*w
2650            dy = y-yc
2651            xB = np.searchsorted(x,Limits[0])
2652            xF = np.searchsorted(x,Limits[1])
2653            dMdvh = getPowderProfileDerv(parmDict,x[xB:xF],
2654                varylist,Histogram,Phases,rigidbodyDict,calcControls,pawleyLookup)
2655            Wt = ma.sqrt(W[xB:xF])[np.newaxis,:]
2656            Dy = dy[xB:xF][np.newaxis,:]
2657            dMdvh *= Wt
2658            if dlg:
2659                dlg.Update(Histogram['Residuals']['wR'],newmsg='Hessian for histogram %d\nAll data Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))
2660            if len(Hess):
2661                Hess += np.inner(dMdvh,dMdvh)
2662                dMdvh *= Wt*Dy
2663                Vec += np.sum(dMdvh,axis=1)
2664            else:
2665                Hess = np.inner(dMdvh,dMdvh)
2666                dMdvh *= Wt*Dy
2667                Vec = np.sum(dMdvh,axis=1)
2668        elif 'HKLF' in histogram[:4]:
2669            Histogram = Histograms[histogram]
2670            phase = Histogram['Reflection Lists']
2671            Phase = Phases[phase]
2672            dMdvh,depDerivDict,wdf = dervHKLF(Histogram,Phase,calcControls,varylist,parmDict,rigidbodyDict)
2673            hId = Histogram['hId']
2674            hfx = ':%d:'%(Histogram['hId'])
2675            wtFactor = calcControls[hfx+'wtFactor']
2676            # now process derivatives in constraints
2677            G2mv.Dict2Deriv(varylist,depDerivDict,dMdvh)
2678#            print 'matrix build time: %.3f'%(time.time()-time0)
2679
2680            if dlg:
2681                dlg.Update(Histogram['Residuals']['wR'],newmsg='Hessian for histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0]
2682            if len(Hess):
2683                Vec += wtFactor*np.sum(dMdvh*wdf,axis=1)
2684                Hess += wtFactor*np.inner(dMdvh,dMdvh)
2685            else:
2686                Vec = wtFactor*np.sum(dMdvh*wdf,axis=1)
2687                Hess = wtFactor*np.inner(dMdvh,dMdvh)
2688        else:
2689            continue        #skip non-histogram entries
2690    pNames,pVals,pWt,pWsum = penaltyFxn(HistoPhases,calcControls,parmDict,varylist)
2691    if np.any(pVals):
2692        dpdv = penaltyDeriv(pNames,pVals,HistoPhases,calcControls,parmDict,varylist)
2693        Vec += np.sum(dpdv*pWt*pVals,axis=1)
2694        Hess += np.inner(dpdv*pWt,dpdv)
2695    return Vec,Hess
2696
2697def errRefine(values,HistoPhases,parmDict,varylist,calcControls,pawleyLookup,dlg=None):       
2698    '''Computes the point-by-point discrepancies between every data point in every histogram
2699    and the observed value
2700   
2701    :returns: an np array of differences between observed and computed diffraction values.
2702    '''
2703    Values2Dict(parmDict, varylist, values)
2704    G2mv.Dict2Map(parmDict,varylist)
2705    Histograms,Phases,restraintDict,rigidbodyDict = HistoPhases
2706    M = np.empty(0)
2707    SumwYo = 0
2708    Nobs = 0
2709    Nrej = 0
2710    Next = 0
2711    ApplyRBModels(parmDict,Phases,rigidbodyDict)
2712    #fixup Hatom positions here....
2713    histoList = Histograms.keys()
2714    histoList.sort()
2715    for histogram in histoList:
2716        if 'PWDR' in histogram[:4]:
2717            Histogram = Histograms[histogram]
2718            hId = Histogram['hId']
2719            hfx = ':%d:'%(hId)
2720            wtFactor = calcControls[hfx+'wtFactor']
2721            Limits = calcControls[hfx+'Limits']
2722            x,y,w,yc,yb,yd = Histogram['Data']
2723            yc *= 0.0                           #zero full calcd profiles
2724            yb *= 0.0
2725            yd *= 0.0
2726            xB = np.searchsorted(x,Limits[0])
2727            xF = np.searchsorted(x,Limits[1])
2728            yc[xB:xF],yb[xB:xF] = getPowderProfile(parmDict,x[xB:xF],
2729                varylist,Histogram,Phases,calcControls,pawleyLookup)
2730            yc[xB:xF] += yb[xB:xF]
2731            if not np.any(y):                   #fill dummy data
2732                rv = st.poisson(yc[xB:xF])
2733                y[xB:xF] = rv.rvs()
2734                Z = np.ones_like(yc[xB:xF])
2735                Z[1::2] *= -1
2736                y[xB:xF] = yc[xB:xF]+np.abs(y[xB:xF]-yc[xB:xF])*Z
2737                w[xB:xF] = np.where(y[xB:xF]>0.,1./y[xB:xF],1.0)
2738            yd[xB:xF] = y[xB:xF]-yc[xB:xF]
2739            W = wtFactor*w
2740            wdy = -ma.sqrt(W[xB:xF])*(yd[xB:xF])
2741            Histogram['Residuals']['Nobs'] = ma.count(x[xB:xF])
2742            Nobs += Histogram['Residuals']['Nobs']
2743            Histogram['Residuals']['sumwYo'] = ma.sum(W[xB:xF]*y[xB:xF]**2)
2744            SumwYo += Histogram['Residuals']['sumwYo']
2745            Histogram['Residuals']['R'] = min(100.,ma.sum(ma.abs(yd[xB:xF]))/ma.sum(y[xB:xF])*100.)
2746            Histogram['Residuals']['wR'] = min(100.,ma.sqrt(ma.sum(wdy**2)/Histogram['Residuals']['sumwYo'])*100.)
2747            sumYmB = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],ma.abs(y[xB:xF]-yb[xB:xF]),0.))
2748            sumwYmB2 = ma.sum(ma.where(yc[xB:xF]!=yb[xB:xF],W[xB:xF]*(y[xB:xF]-yb[xB:xF])**2,0.))
2749            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.))
2750            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.))
2751            Histogram['Residuals']['Rb'] = min(100.,100.*sumYB/sumYmB)
2752            Histogram['Residuals']['wRb'] = min(100.,100.*ma.sqrt(sumwYB2/sumwYmB2))
2753            Histogram['Residuals']['wRmin'] = min(100.,100.*ma.sqrt(Histogram['Residuals']['Nobs']/Histogram['Residuals']['sumwYo']))
2754            if dlg:
2755                dlg.Update(Histogram['Residuals']['wR'],newmsg='For histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0]
2756            M = np.concatenate((M,wdy))
2757#end of PWDR processing
2758        elif 'HKLF' in histogram[:4]:
2759            Histogram = Histograms[histogram]
2760            Histogram['Residuals'] = {}
2761            phase = Histogram['Reflection Lists']
2762            Phase = Phases[phase]
2763            hId = Histogram['hId']
2764            hfx = ':%d:'%(hId)
2765            wtFactor = calcControls[hfx+'wtFactor']
2766            pfx = '%d::'%(Phase['pId'])
2767            phfx = '%d:%d:'%(Phase['pId'],hId)
2768            SGData = Phase['General']['SGData']
2769            im = 0
2770            if parmDict[phfx+'Scale'] < 0.:
2771                parmDict[phfx+'Scale'] = .001               
2772            if Phase['General']['Type'] in ['modulated','magnetic']:
2773                SSGData = Phase['General']['SSGData']
2774                SSGMT = np.array([ops[0].T for ops in SSGData['SSGOps']])
2775                im = 1  #offset in SS reflection list
2776            A = [parmDict[pfx+'A%d'%(i)] for i in range(6)]
2777            G,g = G2lat.A2Gmat(A)       #recip & real metric tensors
2778            refDict = Histogram['Data']
2779            time0 = time.time()
2780            if im:
2781                SStructureFactor(refDict,im,G,hfx,pfx,SGData,SSGData,calcControls,parmDict)
2782            else:
2783                StructureFactor2(refDict,G,hfx,pfx,SGData,calcControls,parmDict)
2784#            print 'sf-calc time: %.3f'%(time.time()-time0)
2785            df = np.zeros(len(refDict['RefList']))
2786            sumwYo = 0
2787            sumFo = 0
2788            sumFo2 = 0
2789            sumdF = 0
2790            sumdF2 = 0
2791            if im:
2792                sumSSFo = np.zeros(10)
2793                sumSSFo2 = np.zeros(10)
2794                sumSSdF = np.zeros(10)
2795                sumSSdF2 = np.zeros(10)
2796                sumSSwYo = np.zeros(10)
2797                sumSSwdf2 = np.zeros(10)
2798                SSnobs = np.zeros(10)
2799            nobs = 0
2800            nrej = 0
2801            next = 0
2802            maxH = 0
2803            if calcControls['F**2']:
2804                for i,ref in enumerate(refDict['RefList']):
2805                    if ref[6+im] > 0:
2806                        ref[11+im] = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist)[0]
2807                        w = 1.0/ref[6+im]   # 1/sig(F^2)
2808                        ref[7+im] *= parmDict[phfx+'Scale']*ref[11+im]  #correct Fc^2 for extinction
2809                        ref[8+im] = ref[5+im]/(parmDict[phfx+'Scale']*ref[11+im])
2810                        if UserRejectHKL(ref,im,calcControls['UsrReject']) and ref[3+im]:    #skip sp.gp. absences (mul=0)
2811                            ref[3+im] = abs(ref[3+im])      #mark as allowed
2812                            Fo = np.sqrt(ref[5+im])
2813                            sumFo += Fo
2814                            sumFo2 += ref[5+im]
2815                            sumdF += abs(Fo-np.sqrt(ref[7+im]))
2816                            sumdF2 += abs(ref[5+im]-ref[7+im])
2817                            nobs += 1
2818                            df[i] = -w*(ref[5+im]-ref[7+im])
2819                            sumwYo += (w*ref[5+im])**2      #w*Fo^2
2820                            if im:  #accumulate super lattice sums
2821                                ind = int(abs(ref[3]))
2822                                sumSSFo[ind] += Fo
2823                                sumSSFo2[ind] += ref[5+im]
2824                                sumSSdF[ind] += abs(Fo-np.sqrt(ref[7+im]))
2825                                sumSSdF2[ind] += abs(ref[5+im]-ref[7+im])
2826                                sumSSwYo[ind] += (w*ref[5+im])**2      #w*Fo^2
2827                                sumSSwdf2[ind] +=  df[i]**2
2828                                SSnobs[ind] += 1
2829                                maxH = max(maxH,ind)                           
2830                        else:
2831                            if ref[3+im]:
2832                                ref[3+im] = -abs(ref[3+im])      #mark as rejected
2833                                nrej += 1
2834                            else:   #sp.gp.extinct
2835                                next += 1
2836            else:
2837                for i,ref in enumerate(refDict['RefList']):
2838                    if ref[5+im] > 0.:
2839                        ref[11+im] = SCExtinction(ref,im,phfx,hfx,pfx,calcControls,parmDict,varylist)[0]
2840                        ref[7+im] *= parmDict[phfx+'Scale']*ref[11+im]    #correct Fc^2 for extinction
2841                        ref[8+im] = ref[5+im]/(parmDict[phfx+'Scale']*ref[11+im])
2842                        Fo = np.sqrt(ref[5+im])
2843                        Fc = np.sqrt(ref[7+im])
2844                        w = 2.0*Fo/ref[6+im]    # 1/sig(F)?
2845                        if UserRejectHKL(ref,im,calcControls['UsrReject']) and ref[3+im]:    #skip sp.gp. absences (mul=0)
2846                            ref[3+im] = abs(ref[3+im])      #mark as allowed
2847                            sumFo += Fo
2848                            sumFo2 += ref[5+im]
2849                            sumdF += abs(Fo-Fc)
2850                            sumdF2 += abs(ref[5+im]-ref[7+im])
2851                            nobs += 1
2852                            df[i] = -w*(Fo-Fc)
2853                            sumwYo += (w*Fo)**2
2854                            if im:
2855                                ind = int(abs(ref[3]))
2856                                sumSSFo[ind] += Fo
2857                                sumSSFo2[ind] += ref[5+im]
2858                                sumSSdF[ind] += abs(Fo-Fc)
2859                                sumSSdF2[ind] += abs(ref[5+im]-ref[7+im])
2860                                sumSSwYo[ind] += (w*Fo)**2                                                           
2861                                sumSSwdf2[ind] +=  df[i]**2
2862                                SSnobs[ind] += 1                           
2863                                maxH = max(maxH,ind)                           
2864                        else:
2865                            if ref[3+im]:
2866                                ref[3+im] = -abs(ref[3+im])      #mark as rejected
2867                                nrej += 1
2868                            else:   #sp.gp.extinct
2869                                next += 1
2870            Histogram['Residuals']['Nobs'] = nobs
2871            Histogram['Residuals']['sumwYo'] = sumwYo
2872            SumwYo += sumwYo
2873            Histogram['Residuals']['wR'] = min(100.,np.sqrt(np.sum(df**2)/sumwYo)*100.)
2874            Histogram['Residuals'][phfx+'Rf'] = 100.*sumdF/sumFo
2875            Histogram['Residuals'][phfx+'Rf^2'] = 100.*sumdF2/sumFo2
2876            Histogram['Residuals'][phfx+'Nref'] = nobs
2877            Histogram['Residuals'][phfx+'Nrej'] = nrej
2878            Histogram['Residuals'][phfx+'Next'] = next
2879            if im:
2880                Histogram['Residuals'][phfx+'SSRf'] = 100.*sumSSdF[:maxH+1]/sumSSFo[:maxH+1]
2881                Histogram['Residuals'][phfx+'SSRf^2'] = 100.*sumSSdF2[:maxH+1]/sumSSFo2[:maxH+1]
2882                Histogram['Residuals'][phfx+'SSNref'] = SSnobs[:maxH+1]
2883                Histogram['Residuals']['SSwR'] = np.sqrt(sumSSwdf2[:maxH+1]/sumSSwYo[:maxH+1])*100.               
2884            Nobs += nobs
2885            Nrej += nrej
2886            Next += next
2887            if dlg:
2888                dlg.Update(Histogram['Residuals']['wR'],newmsg='For histogram %d Rw=%8.3f%s'%(hId,Histogram['Residuals']['wR'],'%'))[0]
2889            M = np.concatenate((M,wtFactor*df))
2890# end of HKLF processing
2891    Histograms['sumwYo'] = SumwYo
2892    Histograms['Nobs'] = Nobs
2893    Histograms['Nrej'] = Nrej
2894    Histograms['Next'] = Next
2895    Rw = min(100.,np.sqrt(np.sum(M**2)/SumwYo)*100.)
2896    if dlg:
2897        GoOn = dlg.Update(Rw,newmsg='%s%8.3f%s'%('All data Rw =',Rw,'%'))[0]
2898        if not GoOn:
2899            parmDict['saved values'] = values
2900            dlg.Destroy()
2901            raise G2obj.G2Exception('User abort')         #Abort!!
2902    pDict,pVals,pWt,pWsum = penaltyFxn(HistoPhases,calcControls,parmDict,varylist)
2903    if len(pVals):
2904        pSum = np.sum(pWt*pVals**2)
2905        for name in pWsum:
2906            if pWsum[name]:
2907                print '  Penalty function for %8s = %12.5g'%(name,pWsum[name])
2908        print 'Total penalty function: %12.5g on %d terms'%(pSum,len(pVals))
2909        Nobs += len(pVals)
2910        M = np.concatenate((M,np.sqrt(pWt)*pVals))
2911    return M
2912                       
Note: See TracBrowser for help on using the repository browser.