Source code for pySAXS.LS.LSusaxs

"""
pySAXS routines for ultra small angle xray scattering.
Lake deconvolution
background substraction,...

version LSusaxs replacing LSreg by OT 7-2012
version 0.1 22/03/2006
version OS 20/11/2009
"""
#import scipy.io  as SPio remplaced by Numpy.loadtxt()
from scipy.optimize import leastsq
from scipy import interpolate
import os
from string import rsplit
import numpy
import time as t
import pySAXS

file_resfunc=os.path.dirname(pySAXS.__file__) + os.sep +"saxsdata"+os.sep+"usaxs_res_func.dat"


'''def ReadUSAXSData(filename):
    return SPio.array_import.read_array(filename,columns=(0,-2),lines=(1,-1))

def WriteUSAXSdata(filename,data):
    return SPio.array_import.write_array(filename,data,separator=' ')
'''
[docs]def BackgroundCorrection(I,bkg): return I-bkg
[docs]def QtoTheta(q,wavelength):#Converts q to theta return numpy.arcsin(q*wavelength)/(2.*numpy.pi)
[docs]def ThetatoQ(Theta,wavelength):#Converts theta to q return 4.*(numpy.pi/wavelength)*numpy.sin(Theta/2.)
[docs]def ZeroCentre(q,I):#Converts the q making the peak at zero return (q-q[numpy.argmax(I)])
[docs]def select(q,I,n): ''' Selects the q,I for n points around the maximum ''' x=ZeroCentre(q,I) sel= numpy.arange(numpy.argmax(I)-n,numpy.argmax(I)+n) y_sel=numpy.take(I, sel) x_sel=numpy.take(q, sel) return x_sel,y_sel
[docs]def somme(q,I): ''' This gives the sum(I*delta q) ''' #print 'Area in the central beam', numpy.trapz(y,x) return numpy.trapz(I,q)
[docs]def gaussian(par, x): f=par[0]*(numpy.exp(-par[1]*(x-par[2])*(x-par[2]))) return f
[docs]def residuals(par, y, x): err = (y-gaussian(par,x)) return err
[docs]def FitGauss(q,I,n,a0,a1,a2,tol=1e-15,it=2000): q1,I1=select(q,I,n) #I1=select(q,I,n)[1] plsq = leastsq(residuals, ([a0,a1,a2]), args=(I1, q1), ftol=tol, maxfev=it) #print plsq[0] return gaussian(plsq[0],q1),q1,I1,plsq[0]
[docs]def Qscalemod(dq,q,step): return q+dq+step
[docs]def InterpolateForCommonvalue(qexp,Iexp,qrock,Irock): sel_qmin=numpy.max(numpy.min(qrock),numpy.min(qexp)) sel_qmax=numpy.min(numpy.max(qrock),numpy.max(qexp)) qnew1=numpy.repeat(qexp,qexp>=sel_qmin) #qnew=numpy.repeat(qexp,(qexp>=min(qrock))) #qnew=numpy.repeat(qexp,(qexp<=max(qrock))) qnew=numpy.repeat(qnew1,qnew1<=sel_qmax) #spl_samp=interpolate.splrep(qexp,Iexp, k=3) #Ip_samp=interpolate.splev(qnew,spl_samp) Isamp=interpolate.interp1d(qexp,Iexp, kind='linear') Ip_samp=Isamp(qnew) #spl_rock=interpolate.splrep(qrock,Irock, k=3) #Ip_rock=interpolate.splev(qnew,spl_rock) Irocking=interpolate.interp1d(qrock,Irock, kind='linear') Ip_rock=Irocking(qnew) return qnew,Ip_samp,Ip_rock
[docs]def TransmissionValue(nsamp,nrock): ''' calculate transmission : nsamp/nrock ''' return nsamp/nrock
[docs]def TrCorrectedProf(qexp,Iexp,qrock,Irock,thickness,central_area,T): ''' Transmission corrected profile ''' qnew=InterpolateForCommonvalue(qexp,Iexp,qrock,Irock)[0] Ip_samp=InterpolateForCommonvalue(qexp,Iexp,qrock,Irock)[1] Ip_rock=InterpolateForCommonvalue(qexp,Iexp,qrock,Irock)[2] Ic1=(Ip_samp/T)-Ip_rock Ic=Ic1/(central_area*thickness) return qnew,Ic
[docs]def read_res_function(): ''' read the resolution function from the specified filename ''' res=Numpy.loadtxt(file_resfunc) #res=SPio.array_import.read_array(file_resfunc,columns=(0,-1),lines=(0,-1)) return res
[docs]def interpolate_res_func(x,resx=None,resy=None): ''' Interpolated resolution function obtained from res_func.dat file if resx and resy are not None, use this datas ''' if resx!=None: beta=resx#res[:,0] v=resy#res[:,1] else: read_res_function() beta=res[:,0] v=res[:,1] vf=interpolate.interp1d(beta,v, kind='linear') vf_intp=vf(x) return vf_intp
[docs]def porod(par, q):#Gives power law like Porod law f=par[0]*(q**(- par[1]) ) return f
[docs]def smooth(y,ns):#Average point smoothing for i in range(len(y)-2*ns): y[i+ns]=sum(numpy.take(y,[i+ns-1,i+ns,i+ns+1]))/(2.*ns+1.) return y #****************************************************************************** #-----Start of Deconvolution program------------------------------------------
[docs]def lake(qexp,Iexp,it,type,ns,m,resx,resy): ''' Deconvolution subroutine based on Lake method ''' #res=read_res_function(file_resfunc) Iexp0=Iexp qexp0=qexp for ii in range(0,it): last=Iexp.shape[0]-1 sel=numpy.arange(last-9,last) I_sel=numpy.take(Iexp, sel) q_sel=numpy.take(qexp, sel) def residual(par, y, q): err = (y-porod(par,q)) return err a0=Iexp0[0] a1=4. plsq = leastsq(residual, numpy.array([a0,a1]), args=(I_sel, q_sel), ftol=1e-15, maxfev=2000) def I(q): In=numpy.zeros(len(qexp)) q1=numpy.repeat(q,q<=qexp[last]) q2=numpy.repeat(q,q>qexp[last]) In1=interpolate.interp1d(qexp,Iexp, kind='linear') In_a=In1(q1) if type=='Constant background': In_b=numpy.ones(len(q2))*Iexp[last] elif type=='Power law': In_b=porod(plsq[0],q2) q1_list=q1.tolist() q2_list=q2.tolist() q1_list.extend(q2_list) In_a_list=In_a.tolist() In_b_list=In_b.tolist() In_a_list.extend(In_b_list) return numpy.array(In_a_list) def inte(x): int1=interpolate_res_func(x,resx,resy)*I((qexp*qexp+x*x)**0.5) return int1 def sm1(): l_limit=0. n = 100 u_limit = 2.*qexp[last] h=( u_limit - l_limit)/float(n) sum=(inte(l_limit) + inte(u_limit))*0.5 for i in range(1,n): x=l_limit+float(i*h) sum = sum + inte(x) return sum*h sm=2.*sm1() Icor=numpy.zeros(len(qexp)) Icor=(Iexp/sm)*Iexp0 Icor=smooth(Icor,ns) Iexp=Icor if (ii==it-1): break return Icor #************************************************************************ #----End of deconvolution program---------------------------------------- #************************************************************************ #--------Please donot modify------------------------------------------------
[docs]def USAXS_count_convolute(q,Iabs,N0dX,thick,wavelength): ''' This subroutine calculates the counts that will be observed on USAXS for a particular model with q,I in cm-1 ''' qexp=q Iexp=Iabs last=Iexp.shape[0]-1 def I(q):#Interpolated In=numpy.zeros(len(qexp)) q1=numpy.repeat(q,q<=qexp[last]) q2=numpy.repeat(q,q>qexp[last]) In1=interpolate.interp1d(qexp,Iexp, kind='linear') In_a=In1(q1) In_b=numpy.ones(len(q2))*Iexp[last] q1_list=q1.tolist() q2_list=q2.tolist() q1_list.extend(q2_list) In_a_list=In_a.tolist() In_b_list=In_b.tolist() In_a_list.extend(In_b_list) return numpy.array(In_a_list) def inte(x):#Integrand for sm1() int1=interpolate_res_func(x)*I((qexp*qexp+x*x)**0.5) return int1 def sm1(): l_limit=0. n = 100 u_limit = 2.*qexp[last] h=( u_limit - l_limit)/float(n) sum=(inte(l_limit) + inte(u_limit))*0.5 for i in range(1,n): x=l_limit+float(i*h) sum = sum + inte(x) return sum*h sm=sm1() return 2.*sm*N0dX*thick #----------------End of USAXS convolute---------------------
[docs]def CalTransmission(mu_p,rho_p,mu_S,rho_S,phim_p,rho_soln,t): ''' Calculates the transmission value for given sample parameters--- ''' mubyrho=(mu_p/rho_p)*phim_p+(mu_S/rho_S)*(1.-phim_p) T=numpy.exp(-mubyrho*rho_soln*t) return T #print CalTransmission(193.305,8.9,6.06,1.188,0.435,1.9,0.0065) #-----
[docs]def GoodnessOfFit(xexp,yexp,fmodel,par): ''' This calculates the goodness of a fit ''' ymodel=fmodel(xexp,*par) SStot=sum((yexp-mean(yexp))**2.) SSreg=sum((ymodel-yexp)**2.) return 1.-(SSreg/SStot) #---------END----------------------
[docs]def calculate_res_func_USAXS(filename,c,step,boun): ''' This routine calculates the resolution function for the USAXS c is the slit length step is the step size for the V(beta) profile boun is the extreme left/right beta value for the V(beta) for which it shoule calculate the V(beta) ''' gplt = Gnuplot.Gnuplot() gplt.reset() beam=SPio.array_import.read_array(filename,columns=(0,-1),lines=(1,-1)) w=beam[:,0] z=beam[:,1] r=numpy.arange(-2*c,2*c,c*step) last=len(z)-1 def I(x): x0=numpy.repeat(x,x<w[0]) x1a=numpy.repeat(x,x<=w[last]) x1=numpy.repeat(x1a,x1a>w[0]) x2=numpy.repeat(x,x>w[last]) In1=interpolate.interp1d(w,z, kind='linear') In_a=In1(x1) In_b=numpy.zeros(len(x2)) In_c=numpy.zeros(len(x0)) x0_list=x0.tolist() x1_list=x1.tolist() x2_list=x2.tolist() x0_list.extend(x1_list) x0_list.extend(x2_list) In_0_list=In_c.tolist() In_1_list=In_a.tolist() In_2_list=In_b.tolist() In_0_list.extend(In_1_list) In_0_list.extend(In_2_list) return numpy.array(In_0_list) def inte(x): int1=I(x) return int1 def v1(u): l_limit=u-c n = 100 u_limit = u+c h=( u_limit - l_limit)/float(n) sum=(inte(l_limit) + inte(u_limit))*0.5 for i in range(1,n): x=l_limit+float(i*h) sum = sum + inte(x) return sum*h v=[] for i in range(len(r)): v.append(v1(r[i])[0]) v=v/max(v) r_low=numpy.arange(-boun,-2*c,(boun-2.*c)/len(r)) r_high=numpy.arange(2*c,boun,(-2.*c+boun)/len(r)) v_low=numpy.zeros(len(r_low)) v_high=numpy.zeros(len(r_high)) vf1=numpy.concatenate((v_low,v)) vfinal=numpy.concatenate((vf1,v_high)) rf1=numpy.concatenate((r_low,r)) rfinal=numpy.concatenate((rf1,r_high)) data=numpy.zeros((len(rfinal),2)) data[:,0]=rfinal data[:,1]=vfinal WriteUSAXSdata(file_resfunc,data) #GD3=Gnuplot.Data(rfinal,vfinal,with_='linespoints') #gplt.plot(GD3) return rfinal,vfinal #------------------------------------END------------------------------