예제 #1
0
/** Calculate the derivatives of the newly smoothed data using the spline
 * Wraps CubicSpline derivative1D
 *
 * @param inputWorkspace :: The input workspace
 * @param outputWorkspace :: The output workspace
 * @param order :: The order of derivatives to calculate
 * @param row :: The row of spectra to use
 */
void SplineSmoothing::calculateDerivatives(
    const MatrixWorkspace &inputWorkspace,
    API::MatrixWorkspace &outputWorkspace, const int order,
    const size_t row) const {
    const auto &xIn = inputWorkspace.x(row);
    const double *xValues = &(xIn[0]);
    double *yValues = &(outputWorkspace.mutableY(order - 1)[0]);
    const size_t nData = xIn.size();

    m_cspline->derivative1D(yValues, xValues, nData, order);
}
예제 #2
0
/** Calculate smoothing of the data using the spline
 * Wraps CubicSpline function1D
 *
 * @param inputWorkspace :: The input workspace
 * @param outputWorkspace :: The output workspace
 * @param row :: The row of spectra to use
 */
void SplineSmoothing::calculateSmoothing(const MatrixWorkspace &inputWorkspace,
        MatrixWorkspace &outputWorkspace,
        size_t row) const {
    // define the spline's parameters
    const auto &xIn = inputWorkspace.x(row);
    const size_t nData = xIn.size();
    const double *xValues = &(xIn[0]);
    double *yValues = &(outputWorkspace.mutableY(row)[0]);

    // calculate the smoothing
    m_cspline->function1D(yValues, xValues, nData);
}
예제 #3
0
/** Defines the points used to make the spline by iteratively creating more
 *smoothing points
 * until all smoothing points fall within a certain error tolerance
 *
 * @param inputWorkspace :: The input workspace containing noisy data
 * @param row :: The row of spectra to use
 */
void SplineSmoothing::selectSmoothingPoints(
    const MatrixWorkspace &inputWorkspace, const size_t row) {
    std::set<int> smoothPts;
    const auto &xs = inputWorkspace.x(row);
    const auto &ys = inputWorkspace.y(row);

    // retrieving number of breaks
    int maxBreaks = static_cast<int>(getProperty("MaxNumberOfBreaks"));

    int xSize = static_cast<int>(xs.size());

    // evenly space initial points over data set
    int delta;

    // if retrieved value is default zero/default
    bool incBreaks = false;

    if (maxBreaks != 0) {
        // number of points to start with
        int numSmoothPts(maxBreaks);
        delta = xSize / numSmoothPts;
        // include maxBreaks when != 0
        incBreaks = true;
    } else {
        int numSmoothPts(M_START_SMOOTH_POINTS);
        delta = xSize / numSmoothPts;
    }

    for (int i = 0; i < xSize; i += delta) {
        smoothPts.insert(i);
    }
    smoothPts.insert(xSize - 1);

    bool resmooth(true);
    while (resmooth) {

        if (incBreaks) {
            if (smoothPts.size() > static_cast<unsigned>(maxBreaks + 2)) {
                break;
            }

        } else if (!incBreaks) {
            if (smoothPts.size() >= xs.size() - 1) {
                break;
            }
        }

        addSmoothingPoints(smoothPts, &xs[0], &ys[0]);
        resmooth = false;

        // calculate the spline and retrieve smoothed points
        boost::shared_array<double> ysmooth(new double[xSize]);
        m_cspline->function1D(ysmooth.get(), &xs[0], xSize);

        // iterate over smoothing points
        auto iter = smoothPts.cbegin();
        int start = *iter;

        for (++iter; iter != smoothPts.cend(); ++iter) {
            int end = *iter;

            // check each point falls within our range of error.
            bool accurate = checkSmoothingAccuracy(start, end, &ys[0], ysmooth.get());

            // if not, flag for resmoothing and add another point between these two
            // data points
            if (!accurate) {
                resmooth = true;
                smoothPts.insert((start + end) / 2);
            }

            start = end;
        }
    }
}