Skip to content
Snippets Groups Projects
Frame.cpp 5.24 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"
Wuttke, Joachim's avatar
Wuttke, Joachim committed
#include "Base/Axis/FrameTrafo.h"
Wuttke, Joachim's avatar
Wuttke, Joachim committed
#include "Base/Axis/FrameUtil.h"
#include "Base/Axis/Scale.h"
#include "Base/Util/Assert.h"
Wuttke, Joachim's avatar
Wuttke, Joachim committed
#include "Base/Util/StringUtil.h"
Wuttke, Joachim's avatar
Wuttke, Joachim committed
Frame::Frame(CloneableVector<const Scale> axes, CloneableVector<const FrameTrafo> trafos)
    : m_axes(std::move(axes))
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    , m_trafos(std::move(trafos))
    , m_size(FrameUtil::product_size(m_axes.reference()))
Wuttke, Joachim's avatar
Wuttke, Joachim committed
Frame::Frame(CloneableVector<const Scale> axes)
    : Frame(axes, {})
{
}

Frame::Frame(const Scale* ax0)
    : Frame(std::vector<const Scale*>{ax0})
Frame::Frame(const Scale* ax0, const Scale* ax1)
    : Frame(std::vector<const Scale*>{ax0, ax1})
Wuttke, Joachim's avatar
Wuttke, Joachim committed
Frame::Frame(const Frame&) = default;

Frame::~Frame() = default;

Wuttke, Joachim's avatar
Wuttke, Joachim committed
Frame* Frame::clone() const
{
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    return new Frame(*this);
Wuttke, Joachim's avatar
Wuttke, Joachim committed
void Frame::setAxes(CloneableVector<const Scale> axes)
{
    std::swap(m_axes, axes);
    m_size = FrameUtil::product_size(m_axes.reference());
Wuttke, Joachim's avatar
Wuttke, Joachim committed
}

void Frame::addTrafo(FrameTrafo* trafo)
{
    m_trafos.emplace_back(trafo);
}

const FrameTrafo& Frame::findTrafo(const std::string& name) const
{
    for (const FrameTrafo* trafo : m_trafos)
        if (trafo->name == name)
            return *trafo;
    throw std::runtime_error("Requested unavailable trafo '" + name
                             + "' ; available: " + Base::String::join(availableTrafos(), ", "));
}

size_t Frame::rank() const
{
    return m_axes.size();
}

size_t Frame::size() const
{
    return m_size;
}

const Scale& Frame::axis(size_t k_axis) const
    ASSERT(k_axis < rank());
    return *m_axes.at(k_axis);
}
const Scale& Frame::xAxis() const
{
    return *m_axes.at(0);
}
const Scale& Frame::yAxis() const
    ASSERT(1 < rank());
    return *m_axes.at(1);
}

Wuttke, Joachim's avatar
..  
Wuttke, Joachim committed
size_t Frame::projectedSize(size_t k_axis) const
{
    ASSERT(k_axis < rank());
Wuttke, Joachim's avatar
..  
Wuttke, Joachim committed
    return m_axes[k_axis]->size();
double Frame::projectedCoord(size_t i_flat, size_t k_axis) const
    auto axis_index = projectedIndex(i_flat, k_axis);
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    return m_axes[k_axis]->binCenter(axis_index);
std::vector<int> Frame::allIndices(size_t i_flat) const
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    std::vector<int> result(rank());
    for (size_t k = 0; k < rank(); ++k)
        result[k] = projectedIndex(i_flat, k);
size_t Frame::projectedIndex(size_t i_flat, size_t k_axis) const
    ASSERT(k_axis < rank());
    if (rank() == 1)
    if (rank() == 2) {
Wuttke, Joachim's avatar
Wuttke, Joachim committed
        if (k_axis == 0)
            return (i_flat / m_axes[1]->size()) % m_axes[0]->size();
Wuttke, Joachim's avatar
Wuttke, Joachim committed
        if (k_axis == 1)
            return i_flat % m_axes[1]->size();
        ASSERT_NEVER;
    ASSERT_NEVER;
}

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 (int k = rank() - 1; k >= 0; --k) {
        ASSERT(axes_indices[k] < m_axes[k]->size());
        result += axes_indices[k] * step_size;
        step_size *= m_axes[k]->size();
bool Frame::operator==(const Frame& o) const
{
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    if (rank() != o.rank())
        return false;
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    for (size_t k = 0; k < rank(); ++k)
        if (axis(k) != o.axis(k))
            return false;
    return true;
}

Wuttke, Joachim's avatar
Wuttke, Joachim committed
std::vector<const Scale*> Frame::clonedAxes() const
{
    return m_axes.cloned_vector();
}

bool Frame::hasSameSizes(const Frame& o) const
{
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    if (rank() != o.rank())
        return false;
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    for (size_t k = 0; k < rank(); ++k)
        if (axis(k).size() != o.axis(k).size())
            return false;
    return true;
}
Wuttke, Joachim's avatar
Wuttke, Joachim committed
std::vector<std::string> Frame::availableTrafos() const
{
    std::vector<std::string> result;
    for (const FrameTrafo* trafo : m_trafos)
        result.push_back(trafo->name);
    return result;
}

Wuttke, Joachim's avatar
Wuttke, Joachim committed
Frame* Frame::transformedFrame(const std::string& key) const
Wuttke, Joachim's avatar
Wuttke, Joachim committed
{
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    const FrameTrafo& trafo = findTrafo(key);
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    ASSERT(trafo.coords.size() == rank());
    std::vector<const Scale*> outaxes;
    for (size_t k = 0; k < rank(); ++k) {
        Scale* s = new Scale(axis(k).plottableScale(trafo.coords[k], trafo.axTrafos[k]));
        outaxes.emplace_back(s);
    }
    return new Frame(std::move(outaxes));
}

Wuttke, Joachim's avatar
Wuttke, Joachim committed
Frame* Frame::plottableFrame(std::vector<std::string> labels) const
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    ASSERT(labels.size() == rank() || labels.size() == 0);
    std::vector<const Scale*> outaxes;
Wuttke, Joachim's avatar
Wuttke, Joachim committed
    for (size_t k = 0; k < rank(); ++k) {
        Scale* s =
            new Scale(labels.size() ? axis(k).plottableScale(labels[k]) : axis(k).plottableScale());
        outaxes.emplace_back(s);
    }
    return new Frame(std::move(outaxes));
}

Frame* Frame::flat() const
{
    std::vector<const Scale*> outaxes;
    for (const Scale* s : m_axes)
        if (s->size() > 1)
            outaxes.emplace_back(s->clone());
    return new Frame(std::move(outaxes));
}