コード例 #1
0
ファイル: utils.py プロジェクト: pquinn-dls/flupy
def createScatterModelFromDict(paramdict, linefunc):
    """
        
    Create and initialize a scatter peak model
    
    lmfit parse the arguments of the linefunc to create the model parameters.
    
    The dictionary input must contain:.
    paramdict["Acquisition_instrument"]["beam_energy"]  (keV)
    
    The method will look for the Compton parameter in paramdict["XRF"]["Scatter"]

    An example parameter is
    
    [area]
    bound_type  = Fixed, lohi or free   (dont' vary, bound, free)
    value       = 0.5  The guess value 
    min         = 0.0  Min used only if bound_type = lohi
    max         = 1.0  Max used only if bound_type = lohi

    if the arguments aren't in the dict or an empty dict is supplied
    the value default to 
    
    [param]
    bound_type  = free
    value       = 1.0  
    min         = -inf
    max         = +inf 

    
    Parameters:
    Inputs:
        
        paramdict  - dictionary containing the compton function parameters
        linefuc    - the function to use for the scatter peak 
    
    Output:
        
        model      - lmfit model of the compton peak with parameters initialized         
                   - lmfit model prefix set to scatter_
    
    
    """

    # typical names to help identify thr peak position from the parsed linefunc
    peakcenternames = ["beam_energy", "position", "peak", "centre", "center"]
    # prefix for the lmfit model
    prefix = "scatter_"
    # location of the dictionary parameter values....hopefully
    pdict = paramdict["XRFFit"]["scatter"]
    incident_energy = paramdict["Acquisition_instrument"]["XRF"]["beam_energy"]
    # create a lmfit model
    model = Model(linefunc, prefix=prefix)
    # now loop over the uninitialized model parameters and set them using the dictionary values
    for pname in model.param_names:
        pname = model._strip_prefix(pname)
        if pname in peakcenternames:
            varyp = 'fixed'
            model.set_param_hint(pname,
                                 value=incident_energy,
                                 vary=False,
                                 min=-np.inf,
                                 max=np.inf)
            continue
        if pname in pdict.keys():
            parm = pdict[pname]
            varyp = pdict[pname]["bound_type"]
            if varyp == 'lohi':
                model.set_param_hint(pname,
                                     value=parm["value"],
                                     vary=True,
                                     min=parm["min"],
                                     max=parm["max"])
            elif varyp == 'free':
                model.set_param_hint(pname,
                                     value=parm["value"],
                                     vary=True,
                                     min=-np.inf,
                                     max=np.inf)
            else:
                model.set_param_hint(pname,
                                     value=parm["value"],
                                     vary=False,
                                     min=parm["min"],
                                     max=parm["max"])
        else:
            # if the parameter isn't in the dictionary then just set it to 1
            # free to move and between -inf, +inf
            model.set_param_hint(pname,
                                 value=1.0,
                                 vary=True,
                                 min=-np.inf,
                                 max=np.inf)
    return model
コード例 #2
0
class XRFAllElementModel(Model):

    def __init__(self, exptdesc,linedict,xrffunc,comptonfunc, elasticfunc,*args,**kwargs):
        """

        An XRF spectrum model
        LMFIT offers a range of options for coupling parameters and models but in order to be able to do 
        this it needs to manipulate parameters - in particular string expressions and this leads 
        big slowdowns if you've a large number of models or coupled parameters.     
        To speed up the calculation rather than create the XRF spectrum from a sum of Gaussian Models
        we create a single model with many parameters.
        The basic lmfit model works as follows:
        parse the arguments of the input function.
        Build a list of param names from these arguments
        Apply paramhints to these param_names or make parameters from the param names
  
        This class will pass a basic line

        """
        # Pass an empty function to model
        super(XRFAllElementModel, self).__init__(None,*args, **kwargs)
        # Arguments need to be converted to  
        # a list of elements (the peaks -> translating to peak areas) + the line type arguments 
        # The basic model just assigns  
        # self.func = function
        # parses the function parameters to
        #
        # xrf line model
        self.xrfmodel = Model(xrffunc,prefix="xrf_")
        self.funcparams_all = self.xrfmodel.make_params()
        self.xrfparams = self.xrfmodel.make_params()   
        # elastic model
        self.elasticmodel = Model(elasticfunc,prefix="elastic_")
        self.elasticparams = self.elasticmodel.make_params()
        # compton model
        self.comptonmodel = Model(comptonfunc,prefix="compton_")
        self.comptonparams = self.comptonmodel.make_params()

        self.linedict = linedict
        self.exptdesc = exptdesc
        self.func = self.funcover
        
    def create_full_parameters(self):
        
        # remove the area and center parameter 
        # For each element in the linedict add a parameter
        # which will control the area
        self.funcparams_all = deepcopy(self.xrfparams)
        self.funcparams_all.pop("xrf_area",None)
        self.funcparams_all.pop("xrf_center",None)
        if [s for s in self.linedict if "compton" in s.lower()]:
            self.funcparams_all.update(self.comptonparams)
            self.funcparams_all.pop("compton_area",None)
            self.funcparams_all.pop("compton_center",None)
        if [s for s in self.linedict if "elastic" in s.lower()]:    
            self.funcparams_all.update(self.elasticparams)
            self.funcparams_all.pop("elastic_area",None)
            self.funcparams_all.pop("elastic_center",None)
        
        #
        # for each model set the parameters...
        #

        for key in self.funcparams_all:
            if key in self.comptonparams:
                ftype = self.comptonmodel.func.__name__
                pdict =self.exptdesc["lineshape"]["compton"][ftype]
                skey  =self.comptonmodel._strip_prefix(key)
                if skey in pdict:
                    self.funcparams_all[key].value = pdict[skey]["value"]
                    self.funcparams_all[key].min = pdict[skey]["min"]
                    self.funcparams_all[key].max = pdict[skey]["max"]
                    self.funcparams_all[key].vary = pdict[skey]["vary"]
            elif key in self.elasticparams:
                ftype = self.elasticmodel.func.__name__
                pdict =self.exptdesc["lineshape"]["elastic"][ftype]
                skey  =self.elasticmodel._strip_prefix(key)
                if skey in pdict:
                    self.funcparams_all[key].value = pdict[skey]["value"]
                    self.funcparams_all[key].min = pdict[skey]["min"]
                    self.funcparams_all[key].max = pdict[skey]["max"]
                    self.funcparams_all[key].vary = pdict[skey]["vary"]
            elif key in self.xrfparams:
                ftype =self.xrfmodel.func.__name__
                pdict =self.exptdesc["lineshape"]["element"][ftype]
                skey  =self.xrfmodel._strip_prefix(key)
                if skey in pdict:
                    self.funcparams_all[key].value = pdict[skey]["value"]
                    self.funcparams_all[key].min   = pdict[skey]["min"]
                    self.funcparams_all[key].max   = pdict[skey]["max"]
                    self.funcparams_all[key].vary  = pdict[skey]["vary"]
        # create a parameter for each line in the line dict...
        # exclude pileups from the parameters
        for key in self.linedict:
            if not '+' in key:  
                if "Elastic" in key:
                    self.funcparams_all.add(key,
                        **self.exptdesc["lineshape"]["elastic"]\
                        [self.elasticmodel.func.__name__]["area"])
                elif "Compton" in key:
                    print "here",key,self.comptonmodel.func.__name__
                    self.funcparams_all.add(key,
                        **self.exptdesc["lineshape"]["compton"]\
                        [self.comptonmodel.func.__name__]["area"])
                else:
                    self.funcparams_all.add(key,
                        **self.exptdesc["lineshape"]["element"]\
                        [self.xrfmodel.func.__name__]["area"])
コード例 #3
0
ファイル: utils.py プロジェクト: pquinn-dls/flupy
def createComptonModelFromDict(paramdict, linefunc):
    """
        
    Create and initialize a comptom model
    
    lmfit parse the arguments of the linefunc to create the model parameters.

    The dictionary input must contain:.

    paramdict["Acquisition_instrument"]["beam_energy"]  (keV)
    paramdict["Acquisition_instrument"]["XRF"]["Detector"]["scattering_angle"] (degrees)
    
    A dictionary input can be used to the the parameter values.
    The method will look for the Compton parameter in paramdict["XRF"]["compton"]
    
    An example parameter is
    
    [area]
    bound_type  = Fixed, lohi or free   (dont' vary, bound, free)
    value       = 0.5  The guess value 
    min         = 0.0  Min used only if bound_type = lohi
    max         = 1.0  Max used only if bound_type = lohi

    if the arguments aren't in the dict or an empty dict is supplied
    the value default to 
    
    [param]
    bound_type  = free
    value       = 1.0  
    min         = -inf
    max         = +inf 

    
    Parameters:
    Inputs:
        
        paramdict  - dictionary containing the compton function parameters
        linefuc    - the function to use for the compton peak 
    
    Output:
        
        model      - lmfit model of the compton peak with parameters initialized         
                   - lmfit model prefix set to compton_
    
    
    """

    prefix = "compton_"
    pdict = paramdict["XRFFit"]["compton"]
    incident_energy = paramdict["Acquisition_instrument"]["XRF"]["beam_energy"]
    angle = paramdict["Acquisition_instrument"]["XRF"]["Detector"][
        "scattering_angle"]
    model = Model(linefunc, prefix=prefix)
    compton_e = compton_energy(incident_energy, angle)
    print "compton e", compton_e
    for pname in model.param_names:
        pname = model._strip_prefix(pname)
        if pname in ["beam_energy", "centre", "center"]:
            varyp = 'fixed'
            model.set_param_hint(pname,
                                 value=compton_e,
                                 vary=False,
                                 min=-np.inf,
                                 max=np.inf)
            continue
        if pname in pdict.keys():
            parm = pdict[pname]
            varyp = pdict[pname]["bound_type"]
            print "pname", pname, parm["value"], varyp, pdict[pname]
            if varyp == 'lohi':
                model.set_param_hint(pname,
                                     value=parm["value"],
                                     vary=True,
                                     min=parm["min"],
                                     max=parm["max"])
            elif varyp == 'free':
                model.set_param_hint(pname,
                                     value=parm["value"],
                                     vary=True,
                                     min=-np.inf,
                                     max=np.inf)
            else:
                model.set_param_hint(pname,
                                     value=parm["value"],
                                     vary=False,
                                     min=parm["min"],
                                     max=parm["max"])
        else:
            model.set_param_hint(pname,
                                 value=1.0,
                                 vary=True,
                                 min=-np.inf,
                                 max=np.inf)
    return model