"""
project : pySAXS
description : class for radial average parameters
authors : Olivier Tache
Last changes :
2012 : replacing the old SAXSparameters
IMPORTANT HERE :
THE INITIALS PARAMETERS FOR ABSOLUTE SCALE
"""
xml_init='<parameters>\
<comment datatype="string" description="comment" order="10">comment</comment>\
<D datatype="float" description="Detector to sample distance (cm)" order="3">1.0</D>\
<TransmittedFlux datatype="float" description="Transmitted Flux" order="12">-1.0</TransmittedFlux>\
<transmission datatype="float" description="Transmission" order="13" formula="TransmittedFlux/IncidentFlux">-1.0</transmission>\
<flux datatype="float" description="Total Flux = Incident Flux * K (ph/s)" order="17" formula="IncidentFlux*K">1.0</flux>\
<K datatype="float" description="K constant" order="16">1.0</K>\
<thickness datatype="float" description="Thickness" order="14">-1.0</thickness>\
<DeltaOmega datatype="float" description="Delta Omega" order="15" formula="(pixel_size/D)**2">1.0</DeltaOmega>\
<filename datatype="file" description="Filename" order="1">param.par</filename>\
<q_by_pixel datatype="float" description="q by pixel (-1 if not used)" order="5">-1.0</q_by_pixel>\
<backgd_by_s datatype="float" description="Background by second" order="7">0.0</backgd_by_s>\
<backgd_by_pix datatype="float" description="Background by pixel" order="8">0.0</backgd_by_pix>\
<backgd datatype="float" description="Total background (B by pixel + B by s * time)" order="9" formula="backgd_by_pix+backgd_by_s*time">0.0</backgd>\
<time datatype="float" description="Exposition time (s)" order="6">1.0</time>\
<wavelength datatype="float" description="Wavelength (A)" order="2">1.542</wavelength>\
<IncidentFlux datatype="float" description="Incident Flux" order="11">-1.0</IncidentFlux>\
<pixel_size datatype="int" description="Pixel size (cm)" order="4">1</pixel_size>\
</parameters>'
#-------------------------------------------------
from numpy import *
from xml.etree import ElementTree
from pySAXS.tools import xmltools
# ----------------------------------------------------------------------------------
[docs]class SAXSparameters:
"""
Radial Average Parameters -
"""
def __init__(self,printout=None):
self.parameters={}
self.printout=printout
element=ElementTree.XML(xml_init)
self.getFromXML(element)
def __repr__(self):
chaine=""
for var in self.parameters:
chaine+=str(var)+" = "+str(self.parameters[var])+"\n"
return chaine
[docs] def printTXT(self,txt="",par=""):
if self.printout==None:
print(str(txt)+str(par))
else:
self.printout(txt,par)
[docs] def get(self,variable):
'''
return the value of the specified variable
'''
if self.parameters.has_key(variable):
return self.parameters[variable].get()
else:
return None
[docs] def set(self,variable,value):
'''
change the value of the specified variable
'''
if self.parameters.has_key(variable):
self.parameters[variable].set(value)
[docs] def order(self):
'''
return a list with dictionnary key ordered
'''
l={}
for name in self.parameters:
l[self.parameters[name].order]=name
list_ordered=[]
for ord in l:
list_ordered.append(l[ord])
return list_ordered
[docs] def save_printable(self,file_name):
'''
save in a txt file
'''
f=open(file_name,mode='w')
f.write(self.__repr__())
f.close()
print file_name," saved"
[docs] def save(self,file_name):
'''
save in a pickle (binary) file
'''
import pickle
f=open(file_name,mode='w')
pickle.dump(self.parameters,f)
f.close()
[docs] def load(self,file_name):
'''
load from a pickle (binary) file
'''
import pickle
f=open(file_name,mode='r')
par=pickle.load(f)
for name in par:
if self.parameters.has_key(name):
self.parameters[name]=datatype(self.parameters[name])(par[name])
else:
self.parameters[name]=par[name]
f.close()
[docs] def xml(self):
'''
return an xml object
'''
root_element = ElementTree.Element("parameters")
for keys, param in self.parameters.items():
root_element.append(param.xml())
return root_element
[docs] def xmlString(self):
'''
return a xml string
'''
x=self.xml()
return ElementTree.tostring(x)
[docs] def saveXML(self,filename):
'''
save in a xml file
'''
root_element=self.xml()
el=ElementTree.ElementTree()
el._setroot(root_element)
el.write(filename)
[docs] def getFromXML(self,xmlElement):
"""
get parameters from xml element
"""
for subelement in xmlElement:
#get all element in root element
tag=subelement.tag #get tag ie <time> or <flux>
#print tag
newpar=parameter(tag,parent=self)
newpar.getfromXML(subelement)
self.parameters[tag]=newpar
#self.__repr__()
self.goodCalculation()
[docs] def goodCalculation(self):
'''
modify some parameter for good calculation :
- backg=dbackgd_by_pix+backgd_by_s*time
- transmission=TransmittedFlux/IncidentFlux
- DeltaOmega=(pixel_size/D)**2
- flux=IncidentFlux*K
'''
self.parameters['backgd'].formula="backgd_by_pix+backgd_by_s*time"
self.parameters['transmission'].formula="TransmittedFlux/IncidentFlux"
self.parameters['DeltaOmega'].formula="(pixel_size/D)**2"
self.parameters['flux'].formula="IncidentFlux*K"
[docs] def openXML(self,filename):
'''
read from a xml file
'''
self.__init__(self.printout)
element=ElementTree.parse(filename)
root=element.getroot()
if root.tag=='parameters':
self.getFromXML(root)
[docs] def calculate_All(self):
'''
calculate all the functions defined
'''
#print self.parameters.items()
for key,values in self.parameters.items():
#print key
res=values.eval()
if values.formula<>None:
self.printTXT(str(key)+"="+values.formula+"="+str(res))
# ----------------------------------------------------------------------------------
[docs] def eval_function(self,formula):
'''
return the evaluated value
'''
#create the dict
d={}
for key, val in self.parameters.items():
d[key]=val.value
#print formula,"<--",d
try:
ret=eval(formula,d)
return ret
except NameError,e:
self.printTXT("Formula error in xml expression ("+formula+') :' +str( e))
[docs] def calculate_q_by_pix(self):
"""
calculate q by pix in A-1 from parameters (RAP)
"""
self.parameters['q_by_pixel']=self.calculate_q(1)
[docs] def calculate_q(self,n):
"""
calculate q in A-1 from parameters
n : pixel number
----------------------------------
q=(4*pi/lambda)*sin(theta/2)
with tan(theta)=d/D
D : sample detector distance
d : pixel number (n) * pixel size
"""
if self.parameters['q_by_pixel'].value<=0:
self.printTXT('q=(4*pi/lambda)*sin(theta/2) with tan(theta)=d/D D : sample detector distance d : pixel number (n) * pixel size')
return ((4*pi)/float(self.parameters['wavelength'].value))*sin(arctan((float(self.parameters['pixel_size'].value)*n)/float(self.parameters['D'].value))/2)
else:
return n*float(self.parameters['q_by_pixel'].value)
[docs] def calculTransm(self):
'''
calculate Transmission
'''
self.parameters['transmission'].value=self.parameters['Transmitted_Flux'].value/self.parameters['Incident_Flux'].value
return self.parameters['transmission'].value
[docs] def calculDeltaOmega(self):
'''
calculate DeltaOmega
'''
#--deltaomega
#print "DeltaOmega=(pixel size / distance sample detector)^2"
self.parameters['DeltaOmega'].value=(float(self.parameters['pixel_size'].value) / float(self.parameters['D'].value))**2
return self.parameters['DeltaOmega'].value
[docs] def calculTotalFlux(self):
'''
calculate Flux
'''
self.parameters['flux'].value = float(self.parameters['IncidentFlux'].value)*float(self.parameters['K'].value)
return self.parameters['flux'].value
[docs] def calculBack(self):
'''
calculate background
'''
self.parameters['backgd'].value=float(self.parameters['backgd_by_pix'].value)+float(self.parameters['backgd_by_s'].value)*float(self.parameters['time'].value)
return self.parameters['backgd'].value
[docs] def calculate_i(self,n,b=None,deviation=None,bdeviation=None):
'''
Calculate i in cm-1 from parameters
n : raw intensity
b : empty cell to substract
deviation : absolute deviation for i
bdeviation : absolute deviation for background
-----------------------------------
DeltaOmega=(pixel size / distance sample detector)^2
Flux = (monitor/transmission)*K
Intensity=(n-background)/(time * DeltaOmega * Transmission * Thickness * Flux)
if empty cell (b) then Final Intensity=( Intensity(with Thickness=1) - empty cell)/thickness
'''
self.printTXT("---- setting absolute scale ----")
#--deltaomega
self.printTXT("DeltaOmega=(pixel size / distance sample detector)^2")
self.printTXT('Delta Omega is : ',self.parameters['DeltaOmega'].value)
#-- flux
self.printTXT("Flux = (monitor/transmission)*K")
self.printTXT( "Flux is : (cps/s) ", self.parameters['flux'].value)
#-- background
self.printTXT( "background is", self.parameters['backgd'].value)
if deviation!=None:
newdeviation=deviation
#-- I
if b==None:
self.printTXT( "Intensity=(n-background)/(time * DeltaOmega * Transmission * Thickness * Flux)")
i=(n-self.parameters['backgd'].value)/(float(self.parameters['time'].value)*self.parameters['DeltaOmega'].value*float(self.parameters['transmission'].value)*float(self.parameters['thickness'].value)*float(self.parameters['flux'].value))
if deviation!=None:
self.printTXT( "Calculating deviation")
newdeviation=deviation/(float(self.parameters['time'].value)*self.parameters['DeltaOmega'].value*float(self.parameters['transmission'].value)*float(self.parameters['thickness'].value)*float(self.parameters['flux'].value))
else:
self.printTXT( "Intensity=(n-background)/(time * DeltaOmega * Transmission * Flux)")
i=(n-self.parameters['backgd'].value)/(float(self.parameters['time'].value)*self.parameters['DeltaOmega'].value*float(self.parameters['transmission'].value)*float(self.parameters['flux'].value))
self.printTXT( "Final Intensity=( Intensity - empty cell)/thickness")
i=(i-b)/float(self.parameters['thickness'].value)
if (bdeviation!=None) and (deviation!=None):
newdeviation=deviation/(float(self.parameters['time'].value)*self.parameters['DeltaOmega'].value*float(self.parameters['transmission'].value)*float(self.parameters['thickness'].value)*float(self.parameters['flux'].value))
newdeviation=(newdeviation-bdeviation)/float(self.parameters['thickness'].value)
else:
self.printTXT( "background deviation is not specified, impossible to manage deviation ")
deviation=None
self.printTXT( "---- intensity scaled for "+str(len(n))," datas ----")
if deviation!=None:
return i,newdeviation
else:
return i,None
[docs] def importOLD(self,filename):
'''
let us to import a old parameter file
'''
from pySAXS.LS import SAXSparametersOLD
p=SAXSparametersOLD.SAXSparametersOLD()
p.load(filename)
self.parameters['filename'].value=p.parameters['filename']
self.parameters['wavelength'].value=p.parameters['wavelength']
self.parameters['D'].value=p.parameters['D']
self.parameters['pixel_size'].value=p.parameters['pixel size']
self.parameters['q_by_pixel'].value=p.parameters['q by pixel']
self.parameters['time'].value=p.parameters['time']
self.parameters['backgd_by_s'].value=p.parameters['backgd by s']
self.parameters['backgd_by_pix'].value=p.parameters['backgd by pix']
self.parameters['backgd'].value=p.parameters['backgd']
self.parameters['comment'].value=p.parameters['comment']
self.parameters['IncidentFlux'].value=p.parameters['Incident Flux']
self.parameters['TransmittedFlux'].value=p.parameters['Transmitted Flux']
self.parameters['transmission'].value=p.parameters['transmission']
self.parameters['thickness'].value=p.parameters['thickness']
self.parameters['DeltaOmega'].value=p.parameters['DeltaOmega']
self.parameters['K'].value=p.parameters['K']
self.parameters['flux'].value=p.parameters['flux']
#----------------------------------------------------------------------------------------------------
[docs]class parameter:
'''
class for parameters
'''
def __init__(self,name, value=None,description="",order=-1,formula=None,datatype=None,parent=None):
self.name=name
self.value=value
self.description=description
self.order=order
self.formula=formula
self.datatype=datatype
self._parent=parent
def __repr__(self):
if self.formula<>"" and self.formula<>None:
return "("+self.description+") : "+str(self.value)+ " CALCULATED from "+self.formula
else :
return "("+self.description+") : "+str(self.value)
[docs] def get(self):
'''
return the value of the parameter
'''
return self.value
[docs] def set(self,value):
'''
set the value of the parameter
'''
self.value=value
[docs] def eval(self):
'''if self.evaluationFunction<>None:
self.value=self.evaluationFunction()
return self.value
'''
if self.formula<>"" and self.formula<>None and self._parent<>None:
val=self._parent.eval_function(self.formula)
self.value=val
return self.value
[docs] def xml(self):
'''
return an element xml
<time description='time(s)' order='2' formula='e=mc**2' datatype='float'>1.25</time>
'''
attrib={}
if self.description<>None:
attrib["description"]=self.description
if self.order<>None:
attrib["order"]=str(self.order)
if self.formula<>None:
attrib["formula"]=str(self.formula)
if self.datatype<>None:
attrib["datatype"]=xmltools.getDatatype(self.value)
#attrib["datatype"]=str(self.datatype)
#else:
xml = ElementTree.Element(self.name,attrib)
xml.text=str(self.value)
# ie : <time description='time in s' order=0 datatype=''>3600.0</time>
return xml
[docs] def getfromXML(self,xmlElement):
'''
initialization given by xml element
'''
self.name=xmlElement.tag
attrib=xmlElement.attrib
text=xmlElement.text
self.description=None
self.order=None
self.formula=None
self.datatype=None
if (attrib.has_key('description')):
self.description=attrib['description']
if (attrib.has_key('order')):
self.order=int(attrib['order'])
if (attrib.has_key('formula')):
self.formula=attrib['formula']
if (attrib.has_key('datatype')):
self.datatype=attrib['datatype']
self.value=xmltools.convertText(xmlElement.text,self.datatype)
else:
self.value=text
return self