Example #1
0
def Smear(q, C, dC, extrapname, sFinal, slitlength, quiet = False, weighted_transition=True):
    '''
    Smear the data of C(q) into S(q) using the slit-length
    weighting function :func:`~jldesmear.api.smear.Plengt()` and an extrapolation
    of the data to avoid truncation errors.  Assume that
    :func:`~jldesmear.api.smear.Plengt()` goes to zero for ``l > l_o`` (the slit length).
    
    Also assume that the slit length function is symmetrical
    about ``l = zero``.
    
    .. math::

        S(q) = 2 \int_0^{l_o} P_l(l) \ C(\sqrt{q^2+l^2}) \ dl
    
    This routine is written so that if :func:`~jldesmear.api.smear.Plengt()` is changed
    (for example) to a Gaussian, that no further modification
    is necessary to the integration procedure.  That is,
    this routine will integrate the data out to "slitlength" (``l_o``).
    
    :param numpy.ndarray q: magnitude of scattering vector
    :param numpy.ndarray C: unsmeared data is C(q) +/- dC(q)
    :param numpy.ndarray dC: estimated uncertainties of C
    :param str extrapname: one of ``constant | linear | powerlaw | Porod``
    :param float sFinal: fit extrapolation to I(q) for q >= sFinal
    :param float slitlength: l_o, same units as q
    :param bool quiet: if True, then no printed output from this routine
    :param bool weighted_transition: if True, make a weighted transition between sFinal <= q < qMax
    :return: tuple of (S, extrap)
    :rtype: (numpy.ndarray, object)
    :var numpy.ndarray S: smeared version of C
    '''
    # make the slit-length weighting function
    NumPts = len(q)
    q0 = q[0]
    qMax = q[-1]
    qRange = qMax - q0
    x = slitlength * (q - q0) / qRange      # use "x" rather than "l" to avoid typos
    w = Plengt(x, slitlength)               # w = P_l(l) or P_l(x)

    # prepare for interpolation of existing data, log(I)
    interp = interp1d(q, numpy.log(C))

    # select and fit the extrapolation
    if extrapolation.functions is None:
        extrapolation.discover_extrapolations()
    try:
        extrap = prepare_extrapolation(q, C, dC, extrapname, sFinal)
    except Exception:
        message = "prepare_extrapolation had a problem: " + str(sys.exc_info)
        raise Exception, message

    S = numpy.ndarray((NumPts,))     # slit-smeared intensity (to be the result)

    for i, qNow in enumerate(q):
        if not quiet: toolbox.Spinner(i)
        Ic = w * get_Ic(qNow, sFinal, qMax, x, interp, extrap, weighted_transition)
        S[i] = 2 * numpy.trapz(Ic, x)  # symmetrical about zero

    return S, extrap
Example #2
0
def prepare_extrapolation(q, C, dC, extrapname, sFinal):
    '''
    Pick the extrapolation function for smearing
    
    :param numpy.ndarray q: magnitude of scattering vector
    :param numpy.ndarray C: array (list) such that data is C(q) +/- dC(q)
    :param numpy.ndarray dC: estimated uncertainties of C
    :param str extrapname: one of ``constant``, ``linear``, ``powerlaw``, or ``Porod``
    :param float sFinal: fit extrapolation to I(q) for q >= sFinal
    :return: function object of selected extrapolation
    :rtype: object
    '''
    if sFinal > q[-1]:
        raise Exception, "no data to fit extrapolation"
    for i in range(len(q)):
        start = i
        if q[i] > sFinal:
            break
    if len(q) - start < 2:
        raise Exception, "not enough data to fit"

    functions = extrapolation.discover_extrapolations()
    if extrapname not in functions.keys():
        msg = "did not identify extrapolation function: " + extrapname
        raise RuntimeError, msg
    extrap = functions[extrapname]()
    extrap.fit(q[start:-1], C[start:-1], dC[start:-1])
    return extrap
Example #3
0
    def _init_Adjustables_Panel(self, parent):
        '''contains adjustable parameters'''
        box = QGroupBox('Adjustable parameters', parent)

        layout = QGridLayout()
        box.setLayout(layout)
        
        row = 0
        tip = 'desmearing slit length, l_o'
        self.slitlength = QLineEdit()
        self.slitlength.setToolTip(tip)
        self.slitlength.setStatusTip(tip)
        layout.addWidget(QLabel('l_o'), row, 0)
        layout.addWidget(self.slitlength, row, 1)
        self.slitlength.setText('0.1')

        row += 1
        tip = 'functional form of extrapolation for desmearing'
        functions = extrapolation.discover_extrapolations()
        self.extrapolation = QComboBox()
        self.extrapolation.insertItems(999, sorted(functions.keys()))
        self.extrapolation.setToolTip(tip)
        self.extrapolation.setStatusTip(tip)
        layout.addWidget(QLabel('extrap'), row, 0)
        layout.addWidget(self.extrapolation, row, 1)
        self.setExtrapolationMethod('constant')

        row += 1
        tip = 'evaluate extrapolation constants based on data for q > q_F'
        self.qFinal = QLineEdit()
        self.qFinal.setToolTip(tip)
        self.qFinal.setStatusTip(tip)
        layout.addWidget(QLabel('q_F'), row, 0)
        layout.addWidget(self.qFinal, row, 1)
        self.qFinal.setText('0.1')

        row += 1
        tip = 'functional form of desmearing feedback, always use "fast"'
        self.feedback = QComboBox()
        self.feedback.insertItems(999, sorted(desmear.Weighting_Methods.keys()))
        self.feedback.setCurrentIndex(2)
        self.feedback.setToolTip(tip)
        self.feedback.setStatusTip(tip)
        layout.addWidget(QLabel('feedback'), row, 0)
        layout.addWidget(self.feedback, row, 1)
        self.setFeedbackMethod('fast')

        row += 1
        tip = 'specifies number of desmearing iterations, N_i'
        self.num_iterations = QSpinBox()
        self.num_iterations.setRange(2, 1000)
        self.num_iterations.setToolTip(tip)
        self.num_iterations.setStatusTip(tip)
        layout.addWidget(QLabel('N_i'), row, 0)
        layout.addWidget(self.num_iterations, row, 1)
        self.num_iterations.setValue(10)
        
        return box
Example #4
0
    def read(self, filename):
        '''
        read desmearing parameters from a command input file
        
        :param str filename: full path to the command input file
        :returns: instance of :class:`jldesmear.api.info.Info`
        '''
        def get_buf_item(key, item=0):
            return buf[key].split()[item]

        ext = '.inp'
        if not filename.endswith(ext): return None
        if not os.path.exists(filename): return None

        self.info = info.Info()

        # read a .inp file
        self.info.parameterfile = filename
        path = os.path.dirname(filename)
        owd = os.getcwd()
        os.chdir(path)
        buf = open(os.path.abspath(filename), 'r').readlines()
        if len(buf) < 7:
            msg = "not enough information in command input file: " + filename
            raise RuntimeError, msg
        
        functions = extrapolation.discover_extrapolations()

        self.info.fileio_class = self
        self.info.filename = filename
        self.info.quiet = True
        self.info.callback = None
        
        self.info.infile = os.path.abspath(os.path.join(path, get_buf_item(0)))
        self.info.outfile = os.path.abspath(os.path.join(path, get_buf_item(1)))
        self.info.slitlength = float(get_buf_item(2))
        self.info.extrapname = get_buf_item(3)
        self.info.sFinal = float(get_buf_item(4))
        self.info.NumItr = int(get_buf_item(5))
        self.info.LakeWeighting = get_buf_item(6)
        self.info.extrap = functions[self.info.extrapname]

        os.chdir(owd)
        
        return self.info