Skip to content
Snippets Groups Projects
Frame.cpp 2.61 KiB
Newer Older
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Base/Axis/Frame.cpp
//! @brief     Implements class Frame.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "Base/Axis/Frame.h"
#include "Base/Axis/Bin.h"
Wuttke, Joachim's avatar
Wuttke, Joachim committed
#include "Base/Axis/IAxis.h"
#include "Base/Util/Assert.h"

Frame::Frame(const std::vector<IAxis*>& axes)
    : m_axes(axes)
{
}

const IAxis& Frame::axis(size_t serial_number) const
{
    return *m_axes[serial_number];
}

Wuttke, Joachim's avatar
Wuttke, Joachim committed
double Frame::getAxisValue(size_t i_flat, size_t k_axis) const
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    auto axis_index = getAxisBinIndex(i_flat, k_axis);
    return (*m_axes[k_axis])[axis_index];
Wuttke, Joachim's avatar
Wuttke, Joachim committed
Bin1D Frame::getAxisBin(size_t i_flat, size_t k_axis) const
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    auto axis_index = getAxisBinIndex(i_flat, k_axis);
    return m_axes[k_axis]->bin(axis_index);
Wuttke, Joachim's avatar
Wuttke, Joachim committed
std::vector<int> Frame::getAxesBinIndices(size_t i_flat) const
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    size_t remainder = i_flat;
    std::vector<int> result;
    result.resize(rank());
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    for (size_t k = 0; k < rank(); ++k) {
        result[rank() - 1 - k] = (int)(remainder % m_axes[rank() - 1 - k]->size());
        remainder /= m_axes[rank() - 1 - k]->size();
Wuttke, Joachim's avatar
Wuttke, Joachim committed
size_t Frame::getAxisBinIndex(size_t i_flat, size_t k_axis) const
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    size_t remainder(i_flat);
    for (size_t k = 0; k < rank(); ++k) {
        size_t kk = rank() - 1 - k;
        size_t result = remainder % m_axes[kk]->size();
        if (k_axis == kk)
            return result;
Wuttke, Joachim's avatar
Wuttke, Joachim committed
        remainder /= m_axes[kk]->size();
    }
    ASSERT(0);
}

size_t Frame::toGlobalIndex(const std::vector<unsigned>& axes_indices) const
{
    ASSERT(axes_indices.size() == rank());
    size_t result = 0;
    size_t step_size = 1;
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    for (size_t k = rank(); k > 0; --k) {
        ASSERT(axes_indices[k - 1] < m_axes[k - 1]->size());
        result += axes_indices[k - 1] * step_size;
        step_size *= m_axes[k - 1]->size();
    }
    return result;
}

size_t Frame::findGlobalIndex(const std::vector<double>& coordinates) const
{
    ASSERT(coordinates.size() == rank());
    std::vector<unsigned> axes_indexes;
    axes_indexes.resize(rank());
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    for (size_t k = 0; k < rank(); ++k)
        axes_indexes[k] = static_cast<unsigned>(m_axes[k]->findClosestIndex(coordinates[k]));
    return toGlobalIndex(axes_indexes);
}