Changeset 537 for trunk/GSASIImath.py


Ignore:
Timestamp:
Apr 13, 2012 11:34:34 AM (13 years ago)
Author:
vondreele
Message:

some refactoring/rearrangement in GSASIIgrid.py
fixes to powderFxyeSave
move Fourier & map search math to GSASIImath.py
implement plot of map peaks & their move to atom list
begin charge flipping GUI

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/GSASIImath.py

    r530 r537  
    1212import numpy as np
    1313import numpy.linalg as nl
     14import numpy.ma as ma
    1415import cPickle
    1516import time
    1617import math
     18import copy
    1719import GSASIIpath
     20import GSASIIlattice as G2lat
    1821import GSASIIspc as G2spc
    1922import scipy.optimize as so
     
    514517            return text
    515518
    516    
     519def FourierMap(data,reflData):
     520   
     521    import scipy.fftpack as fft
     522    generalData = data['General']
     523    if not generalData['Map']['MapType']:
     524        print '**** ERROR - Fourier map not defined'
     525        return
     526    mapData = generalData['Map']
     527    dmin = mapData['Resolution']
     528    SGData = generalData['SGData']
     529    cell = generalData['Cell'][1:8]       
     530    A = G2lat.cell2A(cell[:6])
     531    Hmax = np.asarray(G2lat.getHKLmax(dmin,SGData,A),dtype='i')+1
     532    Fhkl = np.zeros(shape=2*Hmax,dtype='c16')
     533#    Fhkl[0,0,0] = generalData['F000X']
     534    time0 = time.time()
     535    for ref in reflData:
     536        if ref[4] >= dmin:
     537            for i,hkl in enumerate(ref[11]):
     538                hkl = np.asarray(hkl,dtype='i')
     539                Fosq,Fcsq,ph = ref[8:11]
     540                dp = 360.*ref[12][i]
     541                a = cosd(ph+dp)
     542                b = sind(ph+dp)
     543                phasep = complex(a,b)
     544                phasem = complex(a,-b)
     545                if 'Fobs' in mapData['MapType']:
     546                    F = np.sqrt(Fosq)
     547                    h,k,l = hkl+Hmax
     548                    Fhkl[h,k,l] = F*phasep
     549                    h,k,l = -hkl+Hmax
     550                    Fhkl[h,k,l] = F*phasem
     551                elif 'Fcalc' in mapData['MapType']:
     552                    F = np.sqrt(Fcsq)
     553                    h,k,l = hkl+Hmax
     554                    Fhkl[h,k,l] = F*phasep
     555                    h,k,l = -hkl+Hmax
     556                    Fhkl[h,k,l] = F*phasem
     557                elif 'delt-F' in mapData['MapType']:
     558                    dF = np.sqrt(Fosq)-np.sqrt(Fcsq)
     559                    h,k,l = hkl+Hmax
     560                    Fhkl[h,k,l] = dF*phasep
     561                    h,k,l = -hkl+Hmax
     562                    Fhkl[h,k,l] = dF*phasem
     563                elif '2*Fo-Fc' in mapData['MapType']:
     564                    F = 2.*np.sqrt(Fosq)-np.sqrt(Fcsq)
     565                    h,k,l = hkl+Hmax
     566                    Fhkl[h,k,l] = F*phasep
     567                    h,k,l = -hkl+Hmax
     568                    Fhkl[h,k,l] = F*phasem
     569                elif 'Patterson' in mapData['MapType']:
     570                    h,k,l = hkl+Hmax
     571                    Fhkl[h,k,l] = complex(Fosq,0.)
     572                    h,k,l = -hkl+Hmax
     573                    Fhkl[h,k,l] = complex(Fosq,0.)
     574    Fhkl = fft.fftshift(Fhkl)
     575    rho = fft.fftn(Fhkl)/cell[6]
     576    print 'Fourier map time: %.4f'%(time.time()-time0),'no. elements: %d'%(Fhkl.size)
     577    mapData['rho'] = np.real(rho)
     578    mapData['rhoMax'] = max(np.max(mapData['rho']),-np.min(mapData['rho']))
     579    return mapData
     580   
     581def SearchMap(data,keepDup=False):
     582   
     583    norm = 1./(np.sqrt(3.)*np.sqrt(2.*np.pi)**3)
     584   
     585    def noDuplicate(xyz,peaks,SGData):                  #be careful where this is used - it's slow
     586        equivs = G2spc.GenAtom(xyz,SGData)
     587        xyzs = [equiv[0] for equiv in equivs]
     588        for x in xyzs:
     589            if True in [np.allclose(x,peak,atol=0.002) for peak in peaks]:
     590                return False
     591        return True
     592           
     593    def findRoll(rhoMask,mapHalf):
     594        indx = np.array(ma.nonzero(rhoMask)).T
     595        rhoList = np.array([rho[i,j,k] for i,j,k in indx])
     596        rhoMax = np.max(rhoList)
     597        return mapHalf-indx[np.argmax(rhoList)]
     598       
     599    def rhoCalc(parms,rX,rY,rZ,res,SGLaue):
     600        Mag,x0,y0,z0,sig = parms
     601        if SGLaue in ['3','3m1','31m','6/m','6/mmm']:
     602            return norm*Mag*np.exp(-((x0-rX)**2+(y0-rY)**2+(x0-rX)*(y0-rY)+(z0-rZ)**2)/(2.*sig**2))/(sig*res**3)
     603        else:
     604            return norm*Mag*np.exp(-((x0-rX)**2+(y0-rY)**2+(z0-rZ)**2)/(2.*sig**2))/(sig*res**3)
     605       
     606    def peakFunc(parms,rX,rY,rZ,rho,res,SGLaue):
     607        Mag,x0,y0,z0,sig = parms
     608        M = rho-rhoCalc(parms,rX,rY,rZ,res,SGLaue)
     609        return M
     610       
     611    def peakHess(parms,rX,rY,rZ,rho,res,SGLaue):
     612        Mag,x0,y0,z0,sig = parms
     613        dMdv = np.zeros(([5,]+list(rX.shape)))
     614        delt = .01
     615        for i in range(5):
     616            parms[i] -= delt
     617            rhoCm = rhoCalc(parms,rX,rY,rZ,res,SGLaue)
     618            parms[i] += 2.*delt
     619            rhoCp = rhoCalc(parms,rX,rY,rZ,res,SGLaue)
     620            parms[i] -= delt
     621            dMdv[i] = (rhoCp-rhoCm)/(2.*delt)
     622        rhoC = rhoCalc(parms,rX,rY,rZ,res,SGLaue)
     623        Vec = np.sum(np.sum(np.sum(dMdv*(rho-rhoC),axis=3),axis=2),axis=1)
     624        dMdv = np.reshape(dMdv,(5,rX.size))
     625        Hess = np.inner(dMdv,dMdv)
     626       
     627        return Vec,Hess
     628       
     629    generalData = data['General']
     630    phaseName = generalData['Name']
     631    SGData = generalData['SGData']
     632    cell = generalData['Cell'][1:8]       
     633    A = G2lat.cell2A(cell[:6])
     634    drawingData = data['Drawing']
     635    peaks = []
     636    mags = []
     637    try:
     638        mapData = generalData['Map']
     639        contLevel = mapData['cutOff']*mapData['rhoMax']/100.
     640        rho = copy.copy(mapData['rho'])     #don't mess up original
     641        mapHalf = np.array(rho.shape)/2
     642        res = mapData['Resolution']
     643        incre = 1./np.array(rho.shape)
     644        step = max(1.0,1./res)+1
     645        steps = np.array(3*[step,])
     646    except KeyError:
     647        print '**** ERROR - Fourier map not defined'
     648        return peaks,mags
     649    while True:
     650        rhoMask = ma.array(rho,mask=(rho<contLevel))
     651        if not ma.count(rhoMask):
     652            break
     653        rMI = findRoll(rhoMask,mapHalf)
     654        rho = np.roll(np.roll(np.roll(rho,rMI[0],axis=0),rMI[1],axis=1),rMI[2],axis=2)
     655        rMM = mapHalf-steps
     656        rMP = mapHalf+steps+1
     657        rhoPeak = rho[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]]
     658        peakInt = np.sum(rhoPeak)*res**3
     659        rX,rY,rZ = np.mgrid[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]]
     660        x0 = [peakInt,mapHalf[0],mapHalf[1],mapHalf[2],2.0]          #magnitude, position & width(sig)
     661        result = HessianLSQ(peakFunc,x0,Hess=peakHess,
     662            args=(rX,rY,rZ,rhoPeak,res,SGData['SGLaue']),ftol=.0001,maxcyc=100)
     663        x1 = result[0]
     664        if np.any(x1 < 0):
     665            break
     666        peak = (np.array(x1[1:4])-rMI)*incre
     667        if not len(peaks):
     668            peaks.append(peak)
     669            mags.append(x1[0])
     670        else:
     671            if keepDup:
     672                peaks.append(peak)
     673                mags.append(x1[0])
     674            elif noDuplicate(peak,peaks,SGData) and x1[0] > 0.:
     675                peaks.append(peak)
     676                mags.append(x1[0])
     677        rho[rMM[0]:rMP[0],rMM[1]:rMP[1],rMM[2]:rMP[2]] = peakFunc(result[0],rX,rY,rZ,rhoPeak,res,SGData['SGLaue'])
     678        rho = np.roll(np.roll(np.roll(rho,-rMI[2],axis=2),-rMI[1],axis=1),-rMI[0],axis=0)
     679    return np.array(peaks),np.array([mags,]).T
Note: See TracChangeset for help on using the changeset viewer.