コード例 #1
0
    def structure(self, structure):
        self._structure = structure
        p = Parameters(name="instrument parameters")
        p.extend([self.scale, self.bkg, self.dq, self.q_offset])

        self._parameters = Parameters(name=self.name)
        self._parameters.extend([p, structure.parameters])
コード例 #2
0
    def structure(self, structure):
        self._structure = structure
        p = Parameters(name='instrument parameters')
        p.extend([self.scale, self.bkg, self.dq])

        self._parameters = Parameters(name=self.name)
        self._parameters.extend([p, structure.parameters])
コード例 #3
0
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([
         self.polymer_sld.parameters, self.phi_0, self.gamma, self.alpha,
         self.delta, self.rough
     ])
     return p
コード例 #4
0
ファイル: spline.py プロジェクト: llimeht/refnx
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([
         self.extent, self.dz, self.vs, self.left_slab.parameters,
         self.right_slab.parameters, self.solvent.parameters
     ])
     return p
コード例 #5
0
    def structure(self, structure):
        self._structure = structure
        p = Parameters(name="instrument parameters")
        p.extend([self.wav, self.delOffset])

        self._parameters = Parameters(name=self.name)
        self._parameters.extend([p, structure.parameters])
コード例 #6
0
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([self.apm,
               self.b_heads_real, self.b_heads_imag, self.vm_heads,
               self.thickness_heads,
               self.b_tails_real, self.b_tails_imag, self.vm_tails,
               self.thickness_tails, self.rough_head_tail,
               self.rough_preceding_mono])
     return p
コード例 #7
0
    def parameters(self):
        p = Parameters(name=self.name)
        p.extend([self.apm, self.nWater,
                  self.b_heads_real, self.b_heads_imag, self.vm_heads,
                  self.thickness_heads,
                  self.b_tails_real, self.b_tails_imag, self.vm_tails,
                  self.thickness_tails, self.roughness, self.solv_rough])

        return p
コード例 #8
0
ファイル: mol_vol.py プロジェクト: symmy596/lipids_at_airdes
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([
         self.b_heads_real, self.b_heads_imag, self.b_tails_real,
         self.b_tails_imag, self.thick_heads, self.thick_tails,
         self.tail_mol_vol, self.head_mol_vol, self.rough_head_tail,
         self.rough_preceding_mono, self.phit, self.phih
     ])
     return p
コード例 #9
0
class SLD(object):
    """
    Object representing freely varying SLD of a material

    Parameters
    ----------
    value : float or complex
        Scattering length density of a material.
        Units (10**-6 Angstrom**-2)
    name : str, optional
        Name of material.

    Notes
    -----
    An SLD object can be used to create a Slab:

    >>> # an SLD object representing Silicon Dioxide
    >>> sio2 = SLD(3.47, name='SiO2')
    >>> # create a Slab of SiO2 20 A in thickness, with a 3 A roughness
    >>> sio2_layer = SLD(20, 3)

    """
    def __init__(self, value, name=''):
        self.name = name
        if isinstance(value, complex):
            self.real = Parameter(value.real, name='%s - sld' % name)
            self.imag = Parameter(value.imag, name='%s - isld' % name)
        elif isinstance(value, SLD):
            self.real = value.real
            self.imag = value.imag
        else:
            self.real = Parameter(value, name='%s - sld' % name)
            self.imag = Parameter(0, name='%s - isld' % name)

        self._parameters = Parameters(name=name)
        self._parameters.extend([self.real, self.imag])

    def __repr__(self):
        sld = complex(self.real.value, self.imag.value)
        return 'SLD = {0} x10**-6 Å**-2'.format(sld)

    def __call__(self, thick=0, rough=0):
        return Slab(thick, self, rough, name=self.name)

    def __or__(self, other):
        # c = self | other
        slab = self()
        return slab | other

    @property
    def parameters(self):
        """
        :class:`refnx.analysis.Parameters` associated with this component

        """
        self._parameters.name = self.name
        return self._parameters
コード例 #10
0
ファイル: structure.py プロジェクト: brotwasme/refnx2019
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters`, all the parameters associated with
        this structure.

        """
        p = Parameters(name='Stack - {0}'.format(self.name))
        p.append(self.repeats)
        p.extend([component.parameters for component in self.components])
        return p
コード例 #11
0
ファイル: structure.py プロジェクト: brotwasme/refnx2019
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters`, all the parameters associated with
        this structure.

        """
        p = Parameters(name='Structure - {0}'.format(self.name))
        p.extend([component.parameters for component in self.components])
        if self._solvent is not None:
            p.append(self.solvent.parameters)
        return p
コード例 #12
0
ファイル: make_egg.py プロジェクト: brotwasme/refnx2019
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([
         self.interface_air_protein,
         self.interface_protein_solvent,
         self.protein_length,
         self.number_of_water_molecules,
         self.interface_width_air_solvent,
         #self.interface_width_protein_solvent,
         self.sld_of_protein,
         self.d2o_to_h2o_ratio
     ])
     return p
コード例 #13
0
    def parameters(self):
        p = Parameters(name=self.name)
        p.extend([
            self.apm, self.b_heads_real, self.b_heads_imag, self.vm_heads,
            self.thickness_heads, self.b_tails_real, self.b_tails_imag,
            self.vm_tails, self.thickness_tails, self.rough_head_tail,
            self.rough_preceding_mono
        ])
        if self.head_solvent is not None:
            p.append(self.head_solvent.parameters)
        if self.tail_solvent is not None:
            p.append(self.tail_solvent.parameters)

        return p
コード例 #14
0
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters` - parameters associated with this
        model.

        """
        p = Parameters(name='instrument parameters')
        p.extend([self.scales, self.bkg, self.dq])

        self._parameters = Parameters(name=self.name)
        self._parameters.append([p])
        self._parameters.extend(
            [structure.parameters for structure in self._structures])
        return self._parameters
コード例 #15
0
 def parameters(self):
     para = Parameters(name=self.name)
     para.extend([
         self.water_per_lipid_head,
         self.water_per_lipid_tail,
         self.b_h,
         self.bi_h,
         self.b_t,
         self.bi_t,
         self.apm,
         self.roughness,
         self.volume_heads,
         self.volume_tails,
     ])
     return para
コード例 #16
0
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([self.thick])
     # p.extend(self.sld.parameters)
     p.extend([self.rough, self.vol_protein, self.vfsolv])
     # p.name = self.name
     # p.extend([self.vol_protein,
     # self.PLratio])#,self.solventSLD
     # if isinstance(solventSLD, SLD):
     #     p.extend([self.solventSLD.parameters])
     # elif isinstance(solventSLD, complex):
     #     self.solventSLD = SLD(solventSLD)
     # else:
     #     p.extend([self.solventSLD
     return p
コード例 #17
0
    def parameters(self):
        p = Parameters(name=self.name)
        p.extend([
            self.Popc.s_sld, self.Popc.water_per_lipid_head,
            self.Popc.water_per_lipid_tail, self.Popc.b_heads_real,
            self.Popc.b_heads_imag, self.Popc.b_tails_real,
            self.Popc.b_tails_imag, self.Popc.vm_heads, self.Popc.vm_tails,
            self.Popg.s_sld, self.Popg.water_per_lipid_head,
            self.Popg.water_per_lipid_tail, self.Popg.b_heads_real,
            self.Popg.b_heads_imag, self.Popg.b_tails_real,
            self.Popg.b_tails_imag, self.Popg.vm_heads, self.Popg.vm_tails,
            self.apm, self.roughness_top, self.roughness_bottom, self.ratio,
            self.volFrac
        ])
        return p


#     def logp(self):
#         return 0
コード例 #18
0
ファイル: structure.py プロジェクト: brotwasme/refnx2019
    def __init__(self, thick, sld, rough, name='', vfsolv=0, interface=None):
        super(Slab, self).__init__(name=name)
        self.thick = possibly_create_parameter(thick, name='%s - thick' % name)
        if isinstance(sld, SLD):
            self.sld = sld
        else:
            self.sld = SLD(sld)
        self.rough = possibly_create_parameter(rough, name='%s - rough' % name)
        self.vfsolv = (possibly_create_parameter(vfsolv,
                                                 name='%s - volfrac solvent' %
                                                 name))

        p = Parameters(name=self.name)
        p.extend([
            self.thick, self.sld.real, self.sld.imag, self.rough, self.vfsolv
        ])

        self._parameters = p
        self.interfaces = interface
コード例 #19
0
ファイル: brush.py プロジェクト: llimeht/refnx
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([self.gamma, self.dz, self.vf,
               self.polymer_sld.parameters])
     p.extend([slab.parameters for slab in self.left_slabs])
     p.extend([slab.parameters for slab in self.right_slabs])
     return p
コード例 #20
0
ファイル: FreeformVFP.py プロジェクト: igresh/refnxtoolbox
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([self.adsorbed_amount, self.dzf, self.vff,
               self.polymer_sld.parameters])
     p.extend([slab.parameters for slab in self.left_slabs])
     p.extend([slab.parameters for slab in self.right_slabs])
     return p
コード例 #21
0
 def parameters(self):
     """
     Returns
     -------
     Parameter, array_like
         An array of the parameters in the fitting.
     """
     p = Parameters(name=self.name)
     p.extend([
         self.vol[0],
         self.vol[1],
         self.realb[0],
         self.realb[1],
         self.imagb[0],
         self.imagb[1],
         self.d[0],
         self.d[1],
         self.phi[0],
         self.phi[1],
         self.sigma,
     ])
     return p
コード例 #22
0
ファイル: two_layer.py プロジェクト: arm61/model_select
    def parameters(self):
        """
        Parameters for the model.

        Returns:
            (refnx.analysis.Parameters) Model parameters.
        """
        para = Parameters(name=self.name)
        para.extend([
            self.b_real_h,
            self.b_imag_h,
            self.b_real_t,
            self.b_imag_t,
            self.thick_h,
            self.thick_t,
            self.mol_vol_h,
            self.mol_vol_t,
            self.rough_h_t,
            self.rough_t_a,
            self.phi_h,
            self.phi_t,
        ])
        return para
コード例 #23
0
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters` - parameters associated with this
        model.

        """
        p = Parameters(name='meta instrument parameters')
        p.extend([self.bkg, self.dq])
        p.extend(self.additional_params)
        self._parameters = Parameters(name=self.name)

        for model, scale in zip(self.models, self._scales):
            p.extend([scale])
            p.extend(model.parameters.flattened())

        self._parameters.append(p)
   
        return self._parameters
コード例 #24
0
ファイル: structure.py プロジェクト: brotwasme/refnx2019
class SLD(object):
    """
    Object representing freely varying SLD of a material

    Parameters
    ----------
    value : float, complex, Parameter, Parameters
        Scattering length density of a material.
        Units (10**-6 Angstrom**-2)
    name : str, optional
        Name of material.

    Notes
    -----
    An SLD object can be used to create a Slab:

    >>> # an SLD object representing Silicon Dioxide
    >>> sio2 = SLD(3.47, name='SiO2')
    >>> # create a Slab of SiO2 20 A in thickness, with a 3 A roughness
    >>> sio2_layer = sio2(20, 3)

    The SLD object can also be made from a complex number, or from Parameters

    >>> sio2 = SLD(3.47+0.01j)
    >>> re = Parameter(3.47)
    >>> im = Parameter(0.01)
    >>> sio2 = SLD(re)
    >>> sio2 = SLD([re, im])
    """
    def __init__(self, value, name=''):
        self.name = name

        self.imag = Parameter(0, name='%s - isld' % name)
        if isinstance(value, numbers.Real):
            self.real = Parameter(value.real, name='%s - sld' % name)
        elif isinstance(value, numbers.Complex):
            self.real = Parameter(value.real, name='%s - sld' % name)
            self.imag = Parameter(value.imag, name='%s - isld' % name)
        elif isinstance(value, SLD):
            self.real = value.real
            self.imag = value.imag
        elif isinstance(value, Parameter):
            self.real = value
        elif (hasattr(value, '__len__') and isinstance(value[0], Parameter)
              and isinstance(value[1], Parameter)):
            self.real = value[0]
            self.imag = value[1]

        self._parameters = Parameters(name=name)
        self._parameters.extend([self.real, self.imag])

    def __repr__(self):
        return ("SLD([{real!r}, {imag!r}],"
                " name={name!r})".format(**self.__dict__))

    def __str__(self):
        sld = complex(self.real.value, self.imag.value)
        return 'SLD = {0} x10**-6 Å**-2'.format(sld)

    def __complex__(self):
        return complex(self.real.value, self.imag.value)

    def __call__(self, thick=0, rough=0):
        """
        Create a :class:`Slab`.

        Parameters
        ----------
        thick: refnx.analysis.Parameter or float
            Thickness of slab in Angstrom
        rough: refnx.analysis.Parameter or float
            Roughness of slab in Angstrom

        Returns
        -------
        slab : refnx.reflect.Slab
            The newly made Slab.

        Example
        --------

        >>> # an SLD object representing Silicon Dioxide
        >>> sio2 = SLD(3.47, name='SiO2')
        >>> # create a Slab of SiO2 20 A in thickness, with a 3 A roughness
        >>> sio2_layer = sio2(20, 3)

        """
        return Slab(thick, self, rough, name=self.name)

    def __or__(self, other):
        # c = self | other
        slab = self()
        return slab | other

    @property
    def parameters(self):
        """
        :class:`refnx.analysis.Parameters` associated with this component

        """
        self._parameters.name = self.name
        return self._parameters
コード例 #25
0
 def parameters(self):
     p = Parameters(name=self.name)
     p.extend([self.extent, self.decay, self.rough])
     return p
コード例 #26
0
class MixedReflectModel(object):
    r"""
    Calculates an incoherent average of reflectivities from a sequence of
    structures. Such a situation may occur if a sample is not uniform over its
    illuminated area.

    Parameters
    ----------
    structures : sequence of refnx.reflect.Structure
        The interfacial structures to incoherently average
    scales : None, sequence of float or refnx.analysis.Parameter, optional
        scale factors. The reflectivities calculated from each of the
        structures are multiplied by their respective scale factor during
        overall summation. These values are turned into Parameters during the
        construction of this object.
        You must supply a scale factor for each of the structures. If `scales`
        is `None`, then default scale factors are used:
        `[1 / len(structures)] * len(structures)`. It is a good idea to set the
        lower bound of each scale factor to zero (not done by default).
    bkg : float or refnx.analysis.Parameter, optional
        linear background added to the overall reflectivity. This is turned
        into a Parameter during the construction of this object.
    name : str, optional
        Name of the mixed Model
    dq : float or refnx.analysis.Parameter, optional

        - `dq == 0` then no resolution smearing is employed.
        - `dq` is a float or refnx.analysis.Parameter
           a constant dQ/Q resolution smearing is employed.  For 5% resolution
           smearing supply 5.

        However, if `x_err` is supplied to the `model` method, then that
        overrides any setting given here. This value is turned into
        a Parameter during the construction of this object.
    threads: int, optional
        Specifies the number of threads for parallel calculation. This
        option is only applicable if you are using the ``_creflect``
        module. The option is ignored if using the pure python calculator,
        ``_reflect``. If `threads == -1` then all available processors are
        used.
    quad_order: int, optional
        the order of the Gaussian quadrature polynomial for doing the
        resolution smearing. default = 17. Don't choose less than 13. If
        quad_order == 'ultimate' then adaptive quadrature is used. Adaptive
        quadrature will always work, but takes a _long_ time (2 or 3 orders
        of magnitude longer). Fixed quadrature will always take a lot less
        time. BUT it won't necessarily work across all samples. For
        example, 13 points may be fine for a thin layer, but will be
        atrocious at describing a multilayer with bragg peaks.
    dq_type: {'pointwise', 'constant'}, optional
        Chooses whether pointwise or constant dQ/Q resolution smearing (see
        `dq` keyword) is used. To use pointwise smearing the `x_err` keyword
        provided to `Objective.model` method must be an array, otherwise the
        smearing falls back to 'constant'.
    q_offset: float or refnx.analysis.Parameter, optional
        Compensates for uncertainties in the angle at which the measurement is
        performed. A positive/negative `q_offset` corresponds to a situation
        where the measured q values (incident angle) may have been under/over
        estimated, and has the effect of shifting the calculated model to
        lower/higher effective q values.
    """

    def __init__(
        self,
        structures,
        scales=None,
        bkg=1e-7,
        name="",
        dq=5.0,
        threads=-1,
        quad_order=17,
        dq_type="pointwise",
        q_offset=0.0,
    ):
        self.name = name
        self._parameters = None
        self.threads = threads
        self.quad_order = quad_order

        # all reflectometry models need a scale factor and background. Set
        # them all to 1 by default.
        pscales = Parameters(name="scale factors")

        if scales is not None and len(structures) == len(scales):
            tscales = scales
        elif scales is not None and len(structures) != len(scales):
            raise ValueError(
                "You need to supply scale factor for each" " structure"
            )
        else:
            tscales = [1 / len(structures)] * len(structures)

        for scale in tscales:
            p_scale = possibly_create_parameter(scale, name="scale")
            pscales.append(p_scale)

        self._scales = pscales
        self._bkg = possibly_create_parameter(bkg, name="bkg")

        # we can optimize the resolution (but this is always overridden by
        # x_err if supplied. There is therefore possibly no dependence on it.
        self._dq = possibly_create_parameter(dq, name="dq - resolution")
        self.dq_type = dq_type

        self._q_offset = possibly_create_parameter(q_offset, name="q_offset")

        self._structures = structures

    def __repr__(self):
        s = (
            f"MixedReflectModel({self._structures!r},"
            f" scales={self._scales!r}, bkg={self._bkg!r},"
            f" name={self.name!r}, dq={self._dq!r},"
            f" threads={self.threads!r}, quad_order={self.quad_order!r},"
            f" dq_type={self.dq_type!r}, q_offset={self.q_offset!r})"
        )
        return s

    def __call__(self, x, p=None, x_err=None):
        r"""
        Calculate the generative model

        Parameters
        ----------
        x : float or np.ndarray
            q values for the calculation.
        p : refnx.analysis.Parameters, optional
            parameters required to calculate the model
        x_err : np.ndarray
            dq resolution smearing values for the dataset being considered.

        Returns
        -------
        reflectivity : np.ndarray
            Calculated reflectivity

        """
        return self.model(x, p=p, x_err=x_err)

    @property
    def dq(self):
        r"""
        :class:`refnx.analysis.Parameter`

            - `dq.value == 0`
               no resolution smearing is employed.
            - `dq.value > 0`
               a constant dQ/Q resolution smearing is employed.  For 5%
               resolution smearing supply 5. However, if `x_err` is supplied to
               the `model` method, then that overrides any setting reported
               here.

        """
        return self._dq

    @dq.setter
    def dq(self, value):
        self._dq.value = value

    @property
    def q_offset(self):
        r"""
        :class:`refnx.analysis.Parameter` - compensates for any angular
        misalignment during an experiment.

        """
        return self._q_offset

    @q_offset.setter
    def q_offset(self, value):
        self._q_offset.value = value

    @property
    def scales(self):
        r"""
        :class:`refnx.analysis.Parameter` - the reflectivity from each of the
        structures are multiplied by these values to account for patchiness.
        """
        return self._scales

    @property
    def bkg(self):
        r"""
        :class:`refnx.analysis.Parameter` - linear background added to all
        model values.

        """
        return self._bkg

    @bkg.setter
    def bkg(self, value):
        self._bkg.value = value

    def model(self, x, p=None, x_err=None):
        r"""
        Calculate the reflectivity of this model

        Parameters
        ----------
        x : float or np.ndarray
            q values for the calculation.
        p : refnx.analysis.Parameter, optional
            parameters required to calculate the model
        x_err : np.ndarray
            dq resolution smearing values for the dataset being considered.

        Returns
        -------
        reflectivity : np.ndarray

        """
        if p is not None:
            self.parameters.pvals = np.array(p)
        if x_err is None or self.dq_type == "constant":
            # fallback to what this object was constructed with
            x_err = float(self.dq)

        scales = np.array(self.scales)

        y = np.zeros_like(x)

        for scale, structure in zip(scales, self.structures):
            y += reflectivity(
                x + self.q_offset.value,
                structure.slabs()[..., :4],
                scale=scale,
                dq=x_err,
                threads=self.threads,
                quad_order=self.quad_order,
            )

        return y + self.bkg.value

    def logp(self):
        r"""
        Additional log-probability terms for the reflectivity model. Do not
        include log-probability terms for model parameters, these are
        automatically calculated elsewhere.

        Returns
        -------
        logp : float
            log-probability of structure.

        """
        logp = 0
        for structure in self._structures:
            logp += structure.logp()

        return logp

    @property
    def structures(self):
        r"""
        list of :class:`refnx.reflect.Structure` that describe the patchiness
        of the surface.

        """
        return self._structures

    @property
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters` - parameters associated with this
        model.

        """
        p = Parameters(name="instrument parameters")
        p.extend([self.scales, self.bkg, self.dq, self.q_offset])

        self._parameters = Parameters(name=self.name)
        self._parameters.append([p])
        self._parameters.extend(
            [structure.parameters for structure in self._structures]
        )
        return self._parameters
コード例 #27
0
class ReflectModel(object):
    r"""
    Parameters
    ----------
    structure : refnx.reflect.Structure
        The interfacial structure.
    scale : float or refnx.analysis.Parameter, optional
        scale factor. All model values are multiplied by this value before
        the background is added. This is turned into a Parameter during the
        construction of this object.
    bkg : float or refnx.analysis.Parameter, optional
        Q-independent constant background added to all model values. This is
        turned into a Parameter during the construction of this object.
    name : str, optional
        Name of the Model
    dq : float or refnx.analysis.Parameter, optional

        - `dq == 0` then no resolution smearing is employed.
        - `dq` is a float or refnx.analysis.Parameter
           a constant dQ/Q resolution smearing is employed.  For 5% resolution
           smearing supply 5.

        This value is turned into a Parameter during the construction of this
        object.
    threads: int, optional
        Specifies the number of threads for parallel calculation. This
        option is only applicable if you are using the ``_creflect``
        module. The option is ignored if using the pure python calculator,
        ``_reflect``. If `threads == -1` then all available processors are
        used.
    quad_order: int, optional
        the order of the Gaussian quadrature polynomial for doing the
        resolution smearing. default = 17. Don't choose less than 13. If
        quad_order == 'ultimate' then adaptive quadrature is used. Adaptive
        quadrature will always work, but takes a _long_ time (2 or 3 orders
        of magnitude longer). Fixed quadrature will always take a lot less
        time. BUT it won't necessarily work across all samples. For
        example, 13 points may be fine for a thin layer, but will be
        atrocious at describing a multilayer with bragg peaks.
    dq_type: {'pointwise', 'constant'}, optional
        Chooses whether pointwise or constant dQ/Q resolution smearing (see
        `dq` keyword) is used. To use pointwise smearing the `x_err` keyword
        provided to `Objective.model` method must be an array, otherwise the
        smearing falls back to 'constant'.
    q_offset: float or refnx.analysis.Parameter, optional
        Compensates for uncertainties in the angle at which the measurement is
        performed. A positive/negative `q_offset` corresponds to a situation
        where the measured q values (incident angle) may have been under/over
        estimated, and has the effect of shifting the calculated model to
        lower/higher effective q values.
    """

    def __init__(
        self,
        structure,
        scale=1,
        bkg=1e-7,
        name="",
        dq=5.0,
        threads=-1,
        quad_order=17,
        dq_type="pointwise",
        q_offset=0,
    ):
        self.name = name
        self._parameters = None
        self.threads = threads
        self.quad_order = quad_order

        # to make it more like a refnx.analysis.Model
        self.fitfunc = None

        # all reflectometry models need a scale factor and background
        self._scale = possibly_create_parameter(scale, name="scale")
        self._bkg = possibly_create_parameter(bkg, name="bkg")

        # we can optimize the resolution (but this is always overridden by
        # x_err if supplied. There is therefore possibly no dependence on it.
        self._dq = possibly_create_parameter(dq, name="dq - resolution")
        self.dq_type = dq_type

        self._q_offset = possibly_create_parameter(q_offset, name="q_offset")

        self._structure = None
        self.structure = structure

    def __call__(self, x, p=None, x_err=None):
        r"""
        Calculate the generative model

        Parameters
        ----------
        x : float or np.ndarray
            q values for the calculation.
        p : refnx.analysis.Parameters, optional
            parameters required to calculate the model
        x_err : np.ndarray
            dq resolution smearing values for the dataset being considered.

        Returns
        -------
        reflectivity : np.ndarray
            Calculated reflectivity
        """
        return self.model(x, p=p, x_err=x_err)

    def __repr__(self):
        return (
            f"ReflectModel({self._structure!r}, name={self.name!r},"
            f" scale={self.scale!r}, bkg={self.bkg!r},"
            f" dq={self.dq!r}, threads={self.threads},"
            f" quad_order={self.quad_order!r}, dq_type={self.dq_type!r},"
            f" q_offset={self.q_offset!r})"
        )

    @property
    def dq(self):
        r"""
        :class:`refnx.analysis.Parameter`

            - `dq.value == 0`
               no resolution smearing is employed.
            - `dq.value > 0`
               a constant dQ/Q resolution smearing is employed.  For 5%
               resolution smearing supply 5. However, if `x_err` is supplied to
               the `model` method, then that overrides any setting reported
               here.

        """
        return self._dq

    @dq.setter
    def dq(self, value):
        self._dq.value = value

    @property
    def scale(self):
        r"""
        :class:`refnx.analysis.Parameter` - all model values are multiplied by
        this value before the background is added.

        """
        return self._scale

    @scale.setter
    def scale(self, value):
        self._scale.value = value

    @property
    def q_offset(self):
        r"""
        :class:`refnx.analysis.Parameter` - compensates for any angular
        misalignment during an experiment.

        """
        return self._q_offset

    @q_offset.setter
    def q_offset(self, value):
        self._q_offset.value = value

    @property
    def bkg(self):
        r"""
        :class:`refnx.analysis.Parameter` - linear background added to all
        model values.

        """
        return self._bkg

    @bkg.setter
    def bkg(self, value):
        self._bkg.value = value

    def model(self, x, p=None, x_err=None):
        r"""
        Calculate the reflectivity of this model

        Parameters
        ----------
        x : float or np.ndarray
            q values for the calculation.
        p : refnx.analysis.Parameters, optional
            parameters required to calculate the model
        x_err : np.ndarray
            dq resolution smearing values for the dataset being considered.

        Returns
        -------
        reflectivity : np.ndarray
            Calculated reflectivity

        """
        if p is not None:
            self.parameters.pvals = np.array(p)
        if x_err is None or self.dq_type == "constant":
            # fallback to what this object was constructed with
            x_err = float(self.dq)

        return reflectivity(
            x + self.q_offset.value,
            self.structure.slabs()[..., :4],
            scale=self.scale.value,
            bkg=self.bkg.value,
            dq=x_err,
            threads=self.threads,
            quad_order=self.quad_order,
        )

    def logp(self):
        r"""
        Additional log-probability terms for the reflectivity model. Do not
        include log-probability terms for model parameters, these are
        automatically included elsewhere.

        Returns
        -------
        logp : float
            log-probability of structure.

        """
        return self.structure.logp()

    @property
    def structure(self):
        r"""
        :class:`refnx.reflect.Structure` - object describing the interface of
        a reflectometry sample.

        """
        return self._structure

    @structure.setter
    def structure(self, structure):
        self._structure = structure
        p = Parameters(name="instrument parameters")
        p.extend([self.scale, self.bkg, self.dq, self.q_offset])

        self._parameters = Parameters(name=self.name)
        self._parameters.extend([p, structure.parameters])

    @property
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters` - parameters associated with this
        model.

        """
        self.structure = self._structure
        return self._parameters
コード例 #28
0
class RI(Scatterer):
    """
    Object representing a materials wavelength-dependent refractive index.

    A concern is how it needs to be linked to a model. This is to get around
    a major rewrite of refnx, but isn't the most elegant system.

    Another issue is that optical parameters are supplied in units of micro
    meters ('cause thats what seems to be used in refractive index repos and
    cauchy models), the wavelength of the incident radiation is supplied in
    nanometers (thats typical) and the fitting is done in angstroms. Very
    unpleasent.

    Parameters
    ----------
    value : tuple, string
        Scattering length density of a material.
        Units (10**-6 Angstrom**-2)
    A : float or parameter
        Cauchy parameter A. If not none RI will use the cauchy model.
        Default None.
    B : float or parameter
        Cauchy parameter B in um^2. Default 0.
    C : float or parameter
        Cauchy parameter C in um^4. Default 0.
    name : str, optional
        Name of material.

    Notes
    -----
    An SLD object can be used to create a Slab:

    >>> # an SLD object representing Silicon Dioxide
    >>> sio2 = SLD(3.47, name='SiO2')
    >>> # create a Slab of SiO2 20 A in thickness, with a 3 A roughness
    >>> sio2_layer = sio2(20, 3)

    The SLD object can also be made from a complex number, or from Parameters

    >>> sio2 = SLD(3.47+0.01j)
    >>> re = Parameter(3.47)
    >>> im = Parameter(0.01)
    >>> sio2 = SLD(re)
    >>> sio2 = SLD([re, im])
    """
    def __init__(self, value=None, A=None, B=0, C=0, name=""):
        if (type(value) is str
                and name == ""):  # if there is no name get it from the path
            name = os.path.basename(value).split(".")[0]

        super(RI, self).__init__(name=name)

        assert np.logical_xor(
            value is None,
            A is None), "Supply either values or cauchy parameters"

        if value is not None:
            if type(value) is str:

                try:
                    self._wav, self._RI, self._EC = np.loadtxt(
                        value, skiprows=1, delimiter=",", encoding="utf8").T
                except ValueError:
                    self._wav, self._RI = np.loadtxt(
                        value,
                        skiprows=1,
                        delimiter=",",
                        usecols=[0, 1],
                        encoding="utf8",
                    ).T
                    self._EC = np.zeros_like(self._wav)

            elif len(value) == 2:
                self._RI, self._EC = value
                self._wav = None
            elif len(value) == 3:
                self._wav, self._RI, self._EC = value
            else:
                raise TypeError("format not recognised")
            # convert wavelength from um to nm
            self._wav = self._wav * 1000
        else:
            self._wav = None
            self._RI = None
            self._EC = None

        self.model = None
        self.set_wav = None
        self._default_wav = 658
        self._parameters = Parameters(name=name)

        if A is not None:
            self.A = possibly_create_parameter(A, name=f"{name} - cauchy A")
            self.B = possibly_create_parameter(B, name=f"{name} - cauchy B")
            self.C = possibly_create_parameter(C, name=f"{name} - cauchy C")
            self._parameters.extend([self.A, self.B, self.C])

        # The RI needs access to the model to calculate the refractive index.
        # Can't think of a better way of doing this
        # reflect_modelSE is going to auto-link this when its called.

    @property
    def real(self):
        """Refractive index, n."""

        if self.model is not None:
            wavelength = self.model.wav
        elif self.set_wav is not None:
            wavelength = self.set_wav
        else:
            wavelength = self._default_wav
            warnings.warn("Using default wavelength (model not linked)")

        if np.any(self._wav):
            # TODO - raise a warning if the wavelength supplied is outside the
            # wavelength range covered by the data file.

            return Parameter(np.interp(wavelength, self._wav, self._RI))

        elif self.A is not None:
            return Parameter(self.A.value + (self.B.value * 1000**2) /
                             (wavelength**2) + (self.C.value**1000**4) /
                             (wavelength**4))
        else:
            return Parameter(value=self._RI)

    @property
    def imag(self, wavelength=None):
        """Extinction coefficent, k."""

        if self.model is not None:
            wavelength = self.model.wav
        elif self.set_wav is not None:
            wavelength = self.set_wav
        else:
            wavelength = self._default_wav
            warnings.warn("Using default wavelength (model not linked)")

        if np.any(self._wav):
            # TODO - raise a warning if the wavelength supplied is outside the
            # wavelength range covered by the data file.

            return Parameter(np.interp(wavelength, self._wav, self._EC))
        elif self.A is not None:
            return Parameter(0)
        else:
            return Parameter(value=self._EC)

    @property
    def parameters(self):
        return self._parameters

    def __repr__(self):
        return str(f"n: {self.real.value}, k: {self.imag.value}")

    def __complex__(self):
        sldc = complex(self.real.value, self.imag.value)
        return sldc
コード例 #29
0
class ReflectModel(object):
    r"""
    Parameters
    ----------
    structure : refnx.reflect.Structure
        The interfacial structure.
    scale : float or refnx.analysis.Parameter, optional
        scale factor. All model values are multiplied by this value before
        the background is added. This is turned into a Parameter during the
        construction of this object.
    bkg : float or refnx.analysis.Parameter, optional
        Q-independent constant background added to all model values. This is
        turned into a Parameter during the construction of this object.
    name : str, optional
        Name of the Model
    dq : float or refnx.analysis.Parameter, optional

        - `dq == 0` then no resolution smearing is employed.
        - `dq` is a float or refnx.analysis.Parameter
           a constant dQ/Q resolution smearing is employed.  For 5% resolution
           smearing supply 5.

        However, if `x_err` is supplied to the `model` method, then that
        overrides any setting given here. This value is turned into
        a Parameter during the construction of this object.
    threads: int, optional
        Specifies the number of threads for parallel calculation. This
        option is only applicable if you are using the ``_creflect``
        module. The option is ignored if using the pure python calculator,
        ``_reflect``. If `threads == 0` then all available processors are
        used.
    quad_order: int, optional
        the order of the Gaussian quadrature polynomial for doing the
        resolution smearing. default = 17. Don't choose less than 13. If
        quad_order == 'ultimate' then adaptive quadrature is used. Adaptive
        quadrature will always work, but takes a _long_ time (2 or 3 orders
        of magnitude longer). Fixed quadrature will always take a lot less
        time. BUT it won't necessarily work across all samples. For
        example, 13 points may be fine for a thin layer, but will be
        atrocious at describing a multilayer with bragg peaks.

    """
    def __init__(self,
                 structure,
                 scale=1,
                 bkg=1e-7,
                 name='',
                 dq=5.,
                 threads=0,
                 quad_order=17):
        self.name = name
        self._parameters = None
        self.threads = threads
        self.quad_order = quad_order

        # to make it more like a refnx.analysis.Model
        self.fitfunc = None

        # all reflectometry models need a scale factor and background
        self._scale = possibly_create_parameter(scale, name='scale')
        self._bkg = possibly_create_parameter(bkg, name='bkg')

        # we can optimize the resolution (but this is always overridden by
        # x_err if supplied. There is therefore possibly no dependence on it.
        self._dq = possibly_create_parameter(dq, name='dq - resolution')

        self._structure = None
        self.structure = structure

    def __call__(self, x, p=None, x_err=None):
        r"""
        Calculate the generative model

        Parameters
        ----------
        x : float or np.ndarray
            q values for the calculation.
        p : refnx.analysis.Parameters, optional
            parameters required to calculate the model
        x_err : np.ndarray
            dq resolution smearing values for the dataset being considered.

        Returns
        -------
        reflectivity : np.ndarray
            Calculated reflectivity
        """
        return self.model(x, p=p, x_err=x_err)

    @property
    def dq(self):
        r"""
        :class:`refnx.analysis.Parameter`

            - `dq.value == 0`
               no resolution smearing is employed.
            - `dq.value > 0`
               a constant dQ/Q resolution smearing is employed.  For 5%
               resolution smearing supply 5. However, if `x_err` is supplied to
               the `model` method, then that overrides any setting reported
               here.

        """
        return self._dq

    @dq.setter
    def dq(self, value):
        self._dq.value = value

    @property
    def scale(self):
        r"""
        :class:`refnx.analysis.Parameter` - all model values are multiplied by
        this value before the background is added.

        """
        return self._scale

    @scale.setter
    def scale(self, value):
        self._scale.value = value

    @property
    def bkg(self):
        r"""
        :class:`refnx.analysis.Parameter` - linear background added to all
        model values.

        """
        return self._bkg

    @bkg.setter
    def bkg(self, value):
        self._bkg.value = value

    def model(self, x, p=None, x_err=None):
        r"""
        Calculate the reflectivity of this model

        Parameters
        ----------
        x : float or np.ndarray
            q values for the calculation.
        p : refnx.analysis.Parameters, optional
            parameters required to calculate the model
        x_err : np.ndarray
            dq resolution smearing values for the dataset being considered.

        Returns
        -------
        reflectivity : np.ndarray
            Calculated reflectivity

        """
        if p is not None:
            self.parameters.pvals = np.array(p)
        if x_err is None:
            # fallback to what this object was constructed with
            x_err = float(self.dq)

        return reflectivity(x,
                            self.structure.slabs[..., :4],
                            scale=self.scale.value,
                            bkg=self.bkg.value,
                            dq=x_err,
                            threads=self.threads,
                            quad_order=self.quad_order)

    def logp(self):
        r"""
        Additional log-probability terms for the reflectivity model. Do not
        include log-probability terms for model parameters, these are
        automatically included elsewhere.

        Returns
        -------
        logp : float
            log-probability of structure.

        """
        return self.structure.logp()

    @property
    def structure(self):
        r"""
        :class:`refnx.reflect.Structure` - object describing the interface of
        a reflectometry sample.

        """
        return self._structure

    @structure.setter
    def structure(self, structure):
        self._structure = structure
        p = Parameters(name='instrument parameters')
        p.extend([self.scale, self.bkg, self.dq])

        self._parameters = Parameters(name=self.name)
        self._parameters.extend([p, structure.parameters])

    @property
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters` - parameters associated with this
        model.

        """
        self.structure = self._structure
        return self._parameters
コード例 #30
0
class ReflectModelSE(object):
    r"""
    Parameters
    ----------
    structure : refnx.reflect.Structure
        The interfacial structure.
    name : str, optional
        Name of the Model
    """
    def __init__(
        self,
        structure,
        wavelength,
        delta_offset=0,
        name=None,
    ):
        self.name = name
        self.DeltaOffset = delta_offset
        self._parameters = None
        self._flip_delta = False

        # to make it more like a refnx.analysis.Model
        self.fitfunc = None

        # all reflectometry models need a scale factor and background
        self._wav = possibly_create_parameter(wavelength, name="wavelength")

        self._structure = None
        self.structure = structure

        self.DeltaOffset = possibly_create_parameter(delta_offset,
                                                     name="delta offset")

        # THIS IS REALLY QUENSTIONABLE
        for x in self._structure:
            try:
                x.sld.model = self
            except AttributeError:
                print("it appears you are using SLD's instead of RIs")

    def __call__(self, aoi, p=None):
        r"""
        Calculate the generative model

        Parameters
        ----------
        x : float or np.ndarray
            q values for the calculation.
        p : refnx.analysis.Parameters, optional
            parameters required to calculate the model
        x_err : np.ndarray
            dq resolution smearing values for the dataset being considered.

        Returns
        -------
        reflectivity : np.ndarray
            Calculated reflectivity
        """
        return self.model(aoi, p=p)

    def __repr__(self):
        return (f"ReflectModel({self._structure!r}, name={self.name!r},"
                f" wavelength={self.wav!r},"
                f" delta_offset = {self.delOffset!r} ")

    @property
    def wav(self):
        r"""
        :class:`refnx.analysis.Parameter` - all model values are multiplied by
        this value before the background is added.

        """
        return self._wav

    @wav.setter
    def wav(self, value):
        self._wav.value = value

    @property
    def delOffset(self):
        """
        :class:`refnx.analysis.Parameter` - the calculated delta offset specific
        to the ellipsometer and experimental setup used.

        """
        return self.DeltaOffset

    @delOffset.setter
    def delOffset(self, value):
        self.DeltaOffset.value = value

    def model(self, aoi, p=None):
        r"""
        Calculate the reflectivity of this model

        Parameters
        ----------
        aoi : float or np.ndarray
            aoi values for the calculation.
        p : refnx.analysis.Parameters, optional
            parameters required to calculate the model

        Returns
        -------
        reflectivity : np.ndarray
            Calculated reflectivity

        """
        if p is not None:
            self.parameters.pvals = np.array(p)

        return Delta_Psi_TMM(
            AOI=aoi,
            layers=self.structure.slabs()[..., :4],
            wavelength=self.wav.value,
            delta_offset=self.delOffset.value,
            reflect_delta=self._flip_delta,
        )

    def logp(self):
        r"""
        Additional log-probability terms for the reflectivity model. Do not
        include log-probability terms for model parameters, these are
        automatically included elsewhere.

        Returns
        -------
        logp : float
            log-probability of structure.

        """
        return self.structure.logp()

    @property
    def structure(self):
        r"""
        :class:`refnx.reflect.Structure` - object describing the interface of
        a reflectometry sample.

        """
        return self._structure

    @structure.setter
    def structure(self, structure):
        self._structure = structure
        p = Parameters(name="instrument parameters")
        p.extend([self.wav, self.delOffset])

        self._parameters = Parameters(name=self.name)
        self._parameters.extend([p, structure.parameters])

    @property
    def parameters(self):
        r"""
        :class:`refnx.analysis.Parameters` - parameters associated with this
        model.

        """
        self.structure = self._structure
        return self._parameters