Source code for pySAXS.LS.invariant

'''
calculation of invariant
'''
import numpy
from scipy import integrate
from scipy import interpolate
from scipy import special
from math import  *
import pySAXS.LS.LSsca as LSsca

[docs]class invariant: ''' class for calculation of invariant from data in i(q) ''' def __init__(self,q,i,printout=None,radius=300.0,verbose=True): self.q=q self.i=i self.printout=printout self.verbose=verbose self.radius=radius self.I0=0.0 self.Istar=0.0 self.qmini=numpy.min(self.q) self.qmaxi=numpy.max(self.q) self.radius=300.0 self.P1=0.0 self.P2=0.0 self.P3= 0.0 #results---- self.invariant=0.0 #final result : invariant=P1+P2+P3 self.volume=0.0 # particle volume if verbose: self.printTXT('--- Initializing invariant calculation ---') #---- for low q range (guinier) self.LowQq=LSsca.Qlogspace(self.qmini/10,self.qmini,100) self.calculateI0() self.LowQi=numpy.array(LSsca.Guinier(self.LowQq, self.I0, self.radius)) self.A=self.i[0] #---- for high q range (Porod) #the last nbp points where i>0 ipositive=self.i[numpy.where(self.i>0)] nbp=int(len(ipositive)/3) av=numpy.average(ipositive[-nbp:]) self.B=av*self.qmaxi**4.0*1e32 if self.verbose: self.printTXT('I at qmin : '+str(self.A)) self.printTXT('Intensity average for last '+str(nbp)+' positive points = '+str(av)) self.HighQq=LSsca.Qlogspace(self.qmaxi,self.qmaxi*10.0,100) self.HighQi=LSsca.Porod(self.HighQq,self.B)
[docs] def calculateI0(self): ''' calculate I0 I0 = Istar * exp(qmini ** 2 * radius ** 2 / 3.0) Istar is interpolation at qmin ''' f = interpolate.interp1d(self.q, self.i) if numpy.min(self.q) < self.qmini: self.Istar = f(self.qmini) else: self.Istar = self.i[0] self.I0 = self.Istar * exp(self.qmini ** 2 * self.radius ** 2 / 3.0) if self.verbose: self.printTXT("I*=" + str(self.Istar) + " I0=" + str(self.I0)) return self.I0
[docs] def calculate(self,radius=None,qmin=None,qmax=None,extrapolation=None): ''' calculate invariant and particle volume ''' if self.verbose: self.printTXT("--- Calculating Invariant ---") if qmin!=None: self.qmini = qmin if qmax!=None: self.qmaxi = qmax if radius!=None: self.radius=radius if extrapolation!=None: self.B = float(extrapolation) if self.verbose: self.printTXT("qmin="+str(self.qmini)+" qmax="+str(self.qmaxi)+" radius="+str(self.radius)+" extrapolation="+str(self.B)) #update q et i inside the qmini, qmaxi range imax=int(max(numpy.argwhere(self.q<self.qmaxi))) imin=int(min(numpy.argwhere(self.q>self.qmini))) qc=self.q[imin:imax] ic=self.i[imin:imax] self.LowQq=LSsca.Qlogspace(self.qmini/10,self.qmini,100) #calculate I0 self.calculateI0() self.LowQi=numpy.array(LSsca.Guinier(self.LowQq, self.I0, self.radius)) self.A=self.i[0] #porod on high q self.HighQq=LSsca.Qlogspace(self.qmaxi,self.qmaxi*20.0,100) self.HighQi=LSsca.Porod(self.HighQq,self.B) #calculation pp1=(3.0*self.Istar)/(2*self.radius**2) pp2=exp(self.qmini**2*self.radius**2/3.0) pp3=((3.*pi)**0.5)/(2*self.radius) pp4=special.erf(self.qmini*self.radius/(3.0**0.5)) self.P1=pp1*(-self.qmini+pp2*pp3*pp4)*1e24 self.P2=integrate.trapz(ic*qc*qc*1e16,qc*1e8) self.P3= self.B/(self.qmaxi*1e8) self.invariant=self.P1+self.P2+self.P3 ''' calculate the particle volume Vpart=2 * PI**2 * I(0) / invariant ''' self.volume=2*pi**2*self.I0/self.invariant if self.verbose: '''self.printTXT("P1 (cm-4)=",self.P1) self.printTXT("P2 (cm-4)=",self.P2) self.printTXT("P3 (cm-4)=",self.P3)''' self.printTXT("Invariant (cm-4) = P1+P2+P3 =",self.invariant) self.printTXT("Particle Volume = 2 * PI**2 * I0 / invariant ="+str(self.volume)+" cm3") return self.invariant
[docs] def getInvariant(self): ''' return the calculate value use calculate() function before ''' return self.invariant
[docs] def getVolume(self): ''' return the calculate volume for a particule use calculate() function before ''' return self.volume
[docs] def printTXT(self,txt="",par=""): ''' for printing messages ''' if self.printout==None: print(str(txt)+str(par)) else: self.printout(txt,par)