Source code for pySAXS.LS.SAXSparametersXML

"""
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