pySAXS.LS.SAXSparametersXML — pySAXS 77.September2012 documentation

### Navigation

- index
- modules |
- pySAXS 77.September2012 documentation »
- Module code »

# 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

    # ----------------------------------------------------------------------------------

    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

        def printTXT(self,txt="",par=""):
            if self.printout==None:
                print(str(txt)+str(par))
            else:
                self.printout(txt,par)

        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

        def set(self,variable,value):
            '''
            change the value of the specified variable
            '''
            if self.parameters.has_key(variable):
                self.parameters[variable].set(value)

        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

        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"

        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()

        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()

        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

        def xmlString(self):
            '''
            return a xml string
            '''
            x=self.xml()
            return ElementTree.tostring(x)

        def saveXML(self,filename):
            '''
            save in a xml file
            '''
            root_element=self.xml()
            el=ElementTree.ElementTree()
            el._setroot(root_element)
            el.write(filename)

        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()

        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"

        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)

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

    # ----------------------------------------------------------------------------------

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

        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)

        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)

        def calculTransm(self):
            '''
            calculate Transmission
            '''
            self.parameters['transmission'].value=self.parameters['Transmitted_Flux'].value/self.parameters['Incident_Flux'].value
            return self.parameters['transmission'].value

        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

        def calculTotalFlux(self):
            '''
            calculate Flux
            '''
            self.parameters['flux'].value = float(self.parameters['IncidentFlux'].value)*float(self.parameters['K'].value)
            return self.parameters['flux'].value

        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

        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

        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']

    #----------------------------------------------------------------------------------------------------

    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)

        def get(self):
            '''
            return the value of the parameter
            '''
            return self.value

        def set(self,value):
            '''
            set the value of the parameter
            '''
            self.value=value

        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

        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

        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

### Navigation

- index
- modules |
- pySAXS 77.September2012 documentation »
- Module code »