From 1501ac2701be8158f169b69cb88cf42a6a1ba67a Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Mon, 30 May 2022 19:48:21 +0200
Subject: [PATCH] reimplement Powerfield using std::vector instead of LLData

---
 Base/Axis/Frame.cpp                           |  11 +-
 Base/Axis/Frame.h                             |   4 +-
 Device/Coord/CoordSystem1D.cpp                |   1 +
 Device/Coord/ICoordSystem.cpp                 |   1 +
 Device/Data/ArrayUtils.cpp                    |   2 +
 Device/Data/DataUtils.cpp                     |   3 +
 Device/Data/LLData.h                          | 310 ------------------
 Device/Data/Powerfield.cpp                    | 113 ++++++-
 Device/Data/Powerfield.h                      | 145 ++------
 Device/Detector/IDetector.cpp                 |   1 +
 Device/Detector/RectangularDetector.cpp       |   2 +
 Device/Detector/SphericalDetector.cpp         |   2 +
 Device/Histo/Histogram1D.cpp                  |   1 +
 Device/Histo/Histogram2D.cpp                  |   1 +
 Device/Histo/HistogramUtils.cpp               |   2 +
 Device/Histo/IHistogram.cpp                   |   1 +
 Device/Histo/IOFactory.cpp                    |   1 +
 Device/Histo/SimulationResult.cpp             |   8 +-
 Device/InputOutput/DataFormatUtils.cpp        |   1 +
 Device/InputOutput/ReadWriteINT.cpp           |   1 +
 Device/InputOutput/ReadWriteNicos.cpp         |   2 +
 Device/InputOutput/ReadWriteNumpyTXT.cpp      |   1 +
 Device/InputOutput/ReadWriteTiff.cpp          |   3 +
 .../ConvolutionDetectorResolution.cpp         |   7 +-
 GUI/Model/Data/IntensityDataItem.cpp          |   1 +
 GUI/Model/Data/SpecularDataItem.cpp           |   1 +
 GUI/Support/IO/IOUtils.cpp                    |   1 +
 GUI/Support/IO/ImportDataInfo.cpp             |   2 +
 .../AutomaticDataLoader1DResultModel.cpp      |   1 +
 GUI/View/PlotSpecular/SpecularPlot.cpp        |   1 +
 Sim/Export/SimulationToPython.cpp             |   2 +
 Sim/Fitting/FitObjective.cpp                  |   1 +
 Sim/Fitting/ObjectiveMetric.cpp               |   1 +
 Sim/Fitting/SimDataPair.cpp                   |   4 +-
 Sim/Simulation/DepthProbeSimulation.cpp       |   2 +
 Sim/Simulation/OffspecSimulation.cpp          |   1 +
 Sim/Simulation/ScatteringSimulation.cpp       |   2 +
 .../Core/CoreSpecial/CoreIOPathTest.cpp       |   1 +
 Tests/Functional/Core/Fitting/FitTests.cpp    |   1 +
 Tests/Functional/Suite/RunTest.cpp            |   1 +
 Tests/Unit/Device/ArrayUtilsTest.cpp          |   1 +
 Tests/Unit/Device/IOReaderWriterTest.cpp      |   1 +
 .../Device/IntensityDataFunctionsTest.cpp     |   1 +
 Tests/Unit/Device/LLDataTest.cpp              | 294 -----------------
 Tests/Unit/Device/PowerfieldTest.cpp          |   2 +
 Tests/Unit/Device/SphericalDetectorTest.cpp   |   1 +
 Tests/Unit/FittingTestHelper.h                |   1 +
 Tests/Unit/GUI/Utils.cpp                      |   1 +
 Tests/Unit/Sim/CoordSystem1DTest.cpp          |   1 +
 Tests/Unit/Sim/SpecularSimulationTest.cpp     |   1 +
 Wrap/Swig/libBornAgainDevice.i                |   2 +
 Wrap/Swig/libBornAgainSim.i                   |   5 +
 auto/Wrap/doxygenBase.i                       |   4 +-
 auto/Wrap/doxygenDevice.i                     |  83 ++---
 auto/Wrap/libBornAgainBase.py                 |   2 +-
 auto/Wrap/libBornAgainBase_wrap.cpp           |   4 +-
 auto/Wrap/libBornAgainDevice.py               |  28 +-
 auto/Wrap/libBornAgainDevice_wrap.cpp         | 239 ++++++++++----
 auto/Wrap/libBornAgainSim_wrap.cpp            |   5 +
 59 files changed, 440 insertions(+), 883 deletions(-)
 delete mode 100644 Device/Data/LLData.h
 delete mode 100644 Tests/Unit/Device/LLDataTest.cpp

diff --git a/Base/Axis/Frame.cpp b/Base/Axis/Frame.cpp
index 82c1d3e99cb..2081486a735 100644
--- a/Base/Axis/Frame.cpp
+++ b/Base/Axis/Frame.cpp
@@ -21,8 +21,17 @@ Frame::Frame(const std::vector<IAxis*>& axes)
     : m_axes(axes)
 {
     m_size = 1;
-    for (size_t k = 0; k < rank(); ++k)
+    for (size_t k = 0; k < rank(); ++k) {
+        ASSERT(axis(k).size() > 0);
         m_size *= axis(k).size();
+    }
+}
+
+Frame::~Frame() = default;
+
+std::vector<IAxis*> Frame::cloned_axes() const
+{
+    return m_axes.cloned_vector();
 }
 
 size_t Frame::projectedSize(size_t k_axis) const
diff --git a/Base/Axis/Frame.h b/Base/Axis/Frame.h
index 831c642ff6d..3a362ab49a5 100644
--- a/Base/Axis/Frame.h
+++ b/Base/Axis/Frame.h
@@ -28,7 +28,7 @@ class Frame {
 public:
     //! Constructor that takes ownership of supplied axes.
     Frame(const std::vector<IAxis*>& axes);
-    virtual ~Frame() {}
+    virtual ~Frame();
 
     //! Returns number of dimensions.
     size_t rank() const { return m_axes.size(); }
@@ -40,7 +40,7 @@ public:
     size_t projectedSize(size_t k_axis) const;
 
     //! Returns cloned axes.
-    std::vector<IAxis*> cloned_axes() const { return m_axes.cloned_vector(); }
+    std::vector<IAxis*> cloned_axes() const;
 
     //! Returns axis with given serial number
     const IAxis& axis(size_t k_axis) const { return *m_axes[k_axis]; }
diff --git a/Device/Coord/CoordSystem1D.cpp b/Device/Coord/CoordSystem1D.cpp
index a72d49148d9..ddfff64b08c 100644
--- a/Device/Coord/CoordSystem1D.cpp
+++ b/Device/Coord/CoordSystem1D.cpp
@@ -14,6 +14,7 @@
 
 #include "Device/Coord/CoordSystem1D.h"
 #include "Base/Axis/PointwiseAxis.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Const/Units.h"
 #include "Base/Math/Constants.h"
 #include "Base/Util/Assert.h"
diff --git a/Device/Coord/ICoordSystem.cpp b/Device/Coord/ICoordSystem.cpp
index 905f0082192..804e60cc9cd 100644
--- a/Device/Coord/ICoordSystem.cpp
+++ b/Device/Coord/ICoordSystem.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Device/Coord/ICoordSystem.h"
+#include "Base/Util/Assert.h"
 #include "Device/Coord/AxisNames.h"
 #include "Device/Data/Powerfield.h"
 
diff --git a/Device/Data/ArrayUtils.cpp b/Device/Data/ArrayUtils.cpp
index 057b7773e56..d0d84f66532 100644
--- a/Device/Data/ArrayUtils.cpp
+++ b/Device/Data/ArrayUtils.cpp
@@ -13,6 +13,8 @@
 //  ************************************************************************************************
 
 #include "Device/Data/ArrayUtils.h"
+#include "Base/Axis/FixedBinAxis.h"
+#include <stdexcept>
 
 std::pair<size_t, size_t> DataUtils::Array::getShape(const std::vector<std::vector<double>>& data)
 {
diff --git a/Device/Data/DataUtils.cpp b/Device/Data/DataUtils.cpp
index 9ddfc99b49f..ac1df3290ec 100644
--- a/Device/Data/DataUtils.cpp
+++ b/Device/Data/DataUtils.cpp
@@ -13,9 +13,12 @@
 //  ************************************************************************************************
 
 #include "Device/Data/DataUtils.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/Bin.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Math/FourierTransform.h"
 #include "Base/Math/Numeric.h"
+#include "Base/Util/Assert.h"
 #include "Device/Data/ArrayUtils.h"
 #include <functional>
 #include <iostream>
diff --git a/Device/Data/LLData.h b/Device/Data/LLData.h
deleted file mode 100644
index 78edd7d6fde..00000000000
--- a/Device/Data/LLData.h
+++ /dev/null
@@ -1,310 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      Device/Data/LLData.h
-//! @brief     Defines class LLData.
-//!
-//! @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)
-//
-//  ************************************************************************************************
-
-#ifndef USER_API
-#ifndef BORNAGAIN_DEVICE_DATA_LLDATA_H
-#define BORNAGAIN_DEVICE_DATA_LLDATA_H
-
-#include <algorithm>
-#include <limits>
-#include <numeric>
-#include <stdexcept>
-
-//! Template class to store data of any type in multi-dimensional space (low-level).
-
-template <class T>
-class LLData {
-public:
-    // construction, destruction and assignment
-    LLData(size_t rank, const int* sizes);
-    LLData(const LLData<T>& right);
-    LLData<T>& operator=(const LLData<T>& right);
-    ~LLData();
-
-    // accessors
-    T& operator[](size_t i);
-    const T& operator[](size_t i) const;
-
-    // arithmetic operations
-    LLData<T>& operator+=(const LLData<T>& right);
-    LLData<T>& operator-=(const LLData<T>& right);
-    LLData<T>& operator*=(const LLData<T>& right);
-    LLData<T>& operator/=(const LLData<T>& right);
-
-    // initialization, scaling
-    void setAll(const T& value);
-
-    // retrieve basic info
-    size_t getTotalSize() const;
-    inline size_t rank() const { return m_rank; }
-    const int* sizes() const { return m_sizes; }
-    T getTotalSum() const;
-    T max() const;
-
-private:
-    void allocate(size_t rank, const int* sizes);
-    void clear();
-    bool checkSizes(size_t rank, const int* sizes) const;
-    void swapContents(LLData<T>& other);
-    T getZeroElement() const;
-
-    size_t m_rank;
-    int* m_sizes;
-    T* m_data_array;
-};
-
-#ifndef SWIG
-
-// Global helper functions for arithmetic
-template <class T>
-LLData<T> operator+(const LLData<T>& left, const LLData<T>& right);
-template <class T>
-LLData<T> operator-(const LLData<T>& left, const LLData<T>& right);
-template <class T>
-LLData<T> operator*(const LLData<T>& left, const LLData<T>& right);
-template <class T>
-LLData<T> operator/(const LLData<T>& left, const LLData<T>& right);
-
-// Global helper functions for comparison
-template <class T>
-bool HaveSameSizes(const LLData<T>& left, const LLData<T>& right);
-
-template <class T>
-inline LLData<T>::LLData(size_t rank, const int* sizes)
-    : m_rank(0)
-    , m_sizes(nullptr)
-    , m_data_array(0)
-{
-    allocate(rank, sizes);
-}
-
-template <class T>
-LLData<T>::LLData(const LLData<T>& right)
-    : m_rank(0)
-    , m_sizes(nullptr)
-    , m_data_array(0)
-{
-    allocate(right.rank(), right.sizes());
-    for (size_t i = 0; i < getTotalSize(); ++i)
-        m_data_array[i] = right[i];
-}
-
-template <class T>
-LLData<T>::~LLData()
-{
-    clear();
-}
-
-template <class T>
-LLData<T>& LLData<T>::operator=(const LLData<T>& right)
-{
-    if (this != &right) {
-        LLData<T> copy(right);
-        swapContents(copy);
-    }
-    return *this;
-}
-
-template <class T>
-inline T& LLData<T>::operator[](size_t i)
-{
-    return m_data_array[i];
-}
-
-template <class T>
-inline const T& LLData<T>::operator[](size_t i) const
-{
-    return m_data_array[i];
-}
-
-template <class T>
-LLData<T>& LLData<T>::operator+=(const LLData<T>& right)
-{
-    if (!HaveSameSizes(*this, right))
-        throw std::runtime_error(
-            "Operation += on LLData requires both operands to have the same sizes");
-    for (size_t i = 0; i < getTotalSize(); ++i)
-        m_data_array[i] += right[i];
-    return *this;
-}
-
-template <class T>
-LLData<T>& LLData<T>::operator-=(const LLData& right)
-{
-    if (!HaveSameSizes(*this, right))
-        throw std::runtime_error(
-            "Operation -= on LLData requires both operands to have the same sizes");
-    for (size_t i = 0; i < getTotalSize(); ++i)
-        m_data_array[i] -= right[i];
-    return *this;
-}
-
-template <class T>
-LLData<T>& LLData<T>::operator*=(const LLData& right)
-{
-    if (!HaveSameSizes(*this, right))
-        throw std::runtime_error(
-            "Operation *= on LLData requires both operands to have the same sizes");
-    for (size_t i = 0; i < getTotalSize(); ++i)
-        m_data_array[i] *= right[i];
-    return *this;
-}
-
-template <class T>
-LLData<T>& LLData<T>::operator/=(const LLData& right)
-{
-    if (!HaveSameSizes(*this, right))
-        throw std::runtime_error(
-            "Operation /= on LLData requires both operands to have the same sizes");
-    for (size_t i = 0; i < getTotalSize(); ++i) {
-        double ratio;
-        if (std::abs(m_data_array[i] - right[i])
-            <= std::numeric_limits<double>::epsilon() * std::abs(right[i])) {
-            ratio = 1.0;
-        } else if (std::abs(right[i]) <= std::numeric_limits<double>::min())
-            ratio = double(m_data_array[i]) / std::numeric_limits<double>::min();
-        else
-            ratio = double(m_data_array[i] / right[i]);
-        m_data_array[i] = (T)ratio;
-    }
-    return *this;
-}
-
-template <class T>
-void LLData<T>::setAll(const T& value)
-{
-    std::fill(m_data_array, m_data_array + getTotalSize(), value);
-}
-
-template <class T>
-inline size_t LLData<T>::getTotalSize() const
-{
-    int result = std::accumulate(m_sizes, m_sizes + m_rank, 1, std::multiplies<int>{});
-    return static_cast<size_t>(result);
-}
-
-template <class T>
-T LLData<T>::getTotalSum() const
-{
-    return std::accumulate(m_data_array, m_data_array + getTotalSize(), getZeroElement());
-}
-
-template <class T>
-T LLData<T>::max() const
-{
-    return *std::max_element(m_data_array, m_data_array + getTotalSize());
-}
-
-template <class T>
-void LLData<T>::allocate(size_t rank, const int* sizes)
-{
-    clear();
-    if (!checkSizes(rank, sizes))
-        throw std::runtime_error("LLData<T>::allocate error: sizes must be > 0");
-
-    m_rank = rank;
-    if (m_rank) {
-        m_sizes = new int[m_rank];
-        std::copy(sizes, sizes + rank, m_sizes);
-        m_data_array = new T[getTotalSize()];
-    } else {
-        m_data_array = new T[1];
-    }
-}
-
-template <class T>
-void LLData<T>::clear()
-{
-    if (m_rank > 0) {
-        m_rank = 0;
-        delete[] m_data_array;
-        delete[] m_sizes;
-        m_data_array = nullptr;
-        m_sizes = nullptr;
-    } else {
-        delete[] m_data_array;
-    }
-}
-
-template <class T>
-inline bool LLData<T>::checkSizes(size_t rank, const int* sizes) const
-{
-    return std::all_of(sizes, sizes + rank, [](const int& dim) -> bool { return dim > 0; });
-}
-
-template <class T>
-void LLData<T>::swapContents(LLData<T>& other)
-{
-    std::swap(this->m_rank, other.m_rank);
-    std::swap(this->m_sizes, other.m_sizes);
-    std::swap(this->m_data_array, other.m_data_array);
-}
-
-template <class T>
-T LLData<T>::getZeroElement() const
-{
-    T result = 0;
-    return result;
-}
-
-template <class T>
-LLData<T> operator+(const LLData<T>& left, const LLData<T>& right)
-{
-    auto* p_result = new LLData<T>(left);
-    (*p_result) += right;
-    return *p_result;
-}
-
-template <class T>
-LLData<T> operator-(const LLData<T>& left, const LLData<T>& right)
-{
-    auto* p_result = new LLData<T>(left);
-    (*p_result) -= right;
-    return *p_result;
-}
-
-template <class T>
-LLData<T> operator*(const LLData<T>& left, const LLData<T>& right)
-{
-    auto* p_result = new LLData<T>(left);
-    (*p_result) *= right;
-    return *p_result;
-}
-
-template <class T>
-LLData<T> operator/(const LLData<T>& left, const LLData<T>& right)
-{
-    auto* p_result = new LLData<T>(left);
-    *p_result /= right;
-    return *p_result;
-}
-
-template <class T>
-bool HaveSameSizes(const LLData<T>& left, const LLData<T>& right)
-{
-    if (left.rank() != right.rank())
-        return false;
-    const int* ldims = left.sizes();
-    const int* rdims = right.sizes();
-    for (size_t i = 0; i < left.rank(); ++i) {
-        if (ldims[i] != rdims[i])
-            return false;
-    }
-    return true;
-}
-
-#endif // SWIG
-
-#endif // BORNAGAIN_DEVICE_DATA_LLDATA_H
-#endif // USER_API
diff --git a/Device/Data/Powerfield.cpp b/Device/Data/Powerfield.cpp
index cbc430abc8f..24cc9fae0b6 100644
--- a/Device/Data/Powerfield.cpp
+++ b/Device/Data/Powerfield.cpp
@@ -13,10 +13,110 @@
 //  ************************************************************************************************
 
 #include "Device/Data/Powerfield.h"
+#include "Base/Axis/FixedBinAxis.h"
+#include "Base/Axis/Frame.h"
+#include "Base/Util/Assert.h"
+#include "Base/Util/ThreadInfo.h"
+#include "Base/Py/PyCore.h"
+#include <algorithm>
 
-#ifdef BORNAGAIN_PYTHON
 
-#include "Base/Py/PyCore.h"
+Powerfield::Powerfield(Frame* frame, const std::vector<double>& vector)
+    : m_frame(frame)
+    , m_vec(vector)
+{
+}
+
+Powerfield::Powerfield(const std::vector<IAxis*>& axes, const std::vector<double>& vector)
+    : Powerfield(new Frame(axes), vector)
+{
+}
+
+Powerfield::Powerfield(const std::vector<IAxis*>& axes)
+    : m_frame(new Frame(axes))
+    , m_vec(m_frame->size())
+{
+}
+
+Powerfield::Powerfield(const IAxis& xAxis)
+    : Powerfield({xAxis.clone()})
+{
+}
+
+Powerfield::Powerfield(const IAxis& xAxis, const IAxis& yAxis)
+    : Powerfield({xAxis.clone(), yAxis.clone()})
+{
+}
+
+Powerfield::~Powerfield()
+{
+}
+
+Powerfield* Powerfield::clone() const
+{
+    return new Powerfield(m_frame->cloned_axes(), m_vec);
+}
+
+void Powerfield::setAllTo(const double& value)
+{
+    for (double& e: m_vec)
+        e = value;
+}
+
+void Powerfield::setVector(const std::vector<double>& vector)
+{
+    ASSERT(vector.size() == frame().size());
+    m_vec = vector;
+}
+
+const Frame& Powerfield::frame() const { return *m_frame; }
+size_t Powerfield::rank() const { return m_frame->rank(); }
+const IAxis& Powerfield::axis(size_t k) const { return m_frame->axis(k); }
+
+size_t Powerfield::allocatedSize() const
+{
+    ASSERT(frame().size()==m_vec.size());
+    return frame().size();
+}
+
+
+//! Returns true if object have same dimensions
+bool Powerfield::hasSameSizes(const Powerfield& other) const
+{
+    return frame().hasSameSizes(other.frame());
+}
+
+//! Returns true if object have same dimensions and shape of axis
+bool Powerfield::hasSameShape(const Powerfield& other) const
+{
+    return frame() == other.frame();
+}
+
+std::vector<double> Powerfield::cvector() const
+{
+    std::vector<double> ret(allocatedSize());
+    for (size_t i = 0; i < allocatedSize(); ++i)
+        ret[i] = (*this)[i];
+    return ret;
+}
+
+Powerfield* Powerfield::normalizedToMaximum()
+{
+    double maxval = maxVal();
+    ASSERT(maxval > 0);
+    std::vector<double> out(frame().size());
+    for (size_t i = 0; i < frame().size(); ++i)
+        out[i] = m_vec[i] / maxval;
+    return new Powerfield(m_frame->cloned_axes(), out);
+}
+
+double Powerfield::maxVal() const
+{
+    return *std::max_element(m_vec.begin(), m_vec.end());
+}
+
+
+#ifdef BORNAGAIN_PYTHON
 
 PyObject* Powerfield::getArray() const
 {
@@ -59,12 +159,3 @@ PyObject* Powerfield::getArray() const
 }
 
 #endif // BORNAGAIN_PYTHON
-
-const Powerfield& Powerfield::normalizedToMaximum()
-{
-    double maxval = m_ll_data->max();
-    ASSERT(maxval > 0);
-    for (size_t i = 0; i < m_ll_data->getTotalSize(); ++i)
-        (*this)[i] /= maxval;
-    return *this;
-}
diff --git a/Device/Data/Powerfield.h b/Device/Data/Powerfield.h
index 30bbd7d915f..da73e2f7c78 100644
--- a/Device/Data/Powerfield.h
+++ b/Device/Data/Powerfield.h
@@ -15,51 +15,51 @@
 #ifndef BORNAGAIN_DEVICE_DATA_POWERFIELD_H
 #define BORNAGAIN_DEVICE_DATA_POWERFIELD_H
 
-#include "Base/Axis/FixedBinAxis.h"
-#include "Base/Axis/Frame.h"
 #include "Base/Py/PyObject.h"
-#include "Base/Types/OwningVector.h"
-#include "Base/Util/Assert.h"
-#include "Base/Util/ThreadInfo.h"
-#include "Device/Data/LLData.h"
 #include <memory>
-#include <sstream>
 #include <vector>
 
 using std::size_t;
 
+class IAxis;
+class Frame;
+
 //! Stores radiation power per bin.
 //! @ingroup tools
 
 class Powerfield {
 public:
-    Powerfield(const IAxis& xAxis);
-    Powerfield(const IAxis& xAxis, const IAxis& yAxis);
+    //! Constructor that takes ownership of supplied frame.
+    Powerfield(Frame* frame, const std::vector<double>& vector);
     //! Constructor that takes ownership of supplied axes.
     Powerfield(const std::vector<IAxis*>& axes);
+    //! Constructor that takes ownership of supplied axes.
+    Powerfield(const std::vector<IAxis*>& axes, const std::vector<double>& vector);
+    //! Constructor that clones supplied axis.
+    Powerfield(const IAxis& xAxis);
+    //! Constructor that clones supplied axes.
+    Powerfield(const IAxis& xAxis, const IAxis& yAxis);
+
     Powerfield(const Powerfield&) = delete;
     Powerfield(Powerfield&&) = default;
-    const Powerfield& operator=(const Powerfield&) = delete;
+
     ~Powerfield();
     Powerfield* clone() const;
 
     // retrieve basic info
 
-    const Frame& frame() const { return *m_frame; }
-    size_t rank() const { return m_frame->rank(); }
-    const IAxis& axis(size_t k) const { return m_frame->axis(k); }
+    const Frame& frame() const;
+    size_t rank() const;
+    const IAxis& axis(size_t k) const;
 
     //! Returns total size of data buffer (product of bin number in every dimension).
-    size_t allocatedSize() const
-    {
-        if (m_ll_data)
-            return m_ll_data->getTotalSize();
-        return 0;
-    }
+    size_t allocatedSize() const;
 
     //! Returns copy of raw data vector
     std::vector<double> cvector() const;
 
+    double maxVal() const;
+
     // modifiers
 
     //! Sets content of output data to specific value
@@ -69,17 +69,15 @@ public:
     void setVector(const std::vector<double>& data_vector);
 
     //! indexed accessor
-    double& operator[](size_t index)
+    double& operator[](size_t i)
     {
-        ASSERT(m_ll_data);
-        return (*m_ll_data)[index];
+        return m_vec[i];
     }
 
-    //! indexed accessor (const)
-    const double& operator[](size_t index) const
+    //! ied accessor (const)
+    const double& operator[](size_t i) const
     {
-        ASSERT(m_ll_data);
-        return (*m_ll_data)[index];
+        return m_vec[i];
     }
 
     // helpers
@@ -95,102 +93,11 @@ public:
     PyObject* getArray() const;
 #endif
 
-    //! Allocates memory for current dimensions configuration
-    void allocate();
-
-    const Powerfield& normalizedToMaximum();
+    Powerfield* normalizedToMaximum();
 
 private:
-    LLData<double>* m_ll_data{nullptr};
     std::unique_ptr<Frame> m_frame;
+    std::vector<double> m_vec;
 };
 
-#ifndef USER_API
-
-// --------------------------------------------------------------------- //
-// Implementation
-// --------------------------------------------------------------------- //
-
-inline Powerfield::Powerfield(const std::vector<IAxis*>& axes)
-    : m_frame(new Frame(axes))
-{
-    for (const IAxis* ax : axes)
-        ASSERT(ax->size() > 0);
-    allocate();
-}
-
-inline Powerfield::Powerfield(const IAxis& xAxis)
-    : m_frame(new Frame({xAxis.clone()}))
-{
-    ASSERT(xAxis.size() > 0);
-    allocate();
-}
-
-inline Powerfield::Powerfield(const IAxis& xAxis, const IAxis& yAxis)
-    : m_frame(new Frame({xAxis.clone(), yAxis.clone()}))
-{
-    ASSERT(xAxis.size() > 0);
-    ASSERT(yAxis.size() > 0);
-    ASSERT(xAxis.axisName() != yAxis.axisName());
-    allocate();
-}
-
-inline Powerfield::~Powerfield()
-{
-    delete m_ll_data;
-}
-
-inline Powerfield* Powerfield::clone() const
-{
-    auto* result = new Powerfield(m_frame->cloned_axes());
-    (*result->m_ll_data) = *m_ll_data;
-    return result;
-}
-
-inline void Powerfield::setAllTo(const double& value)
-{
-    ASSERT(m_ll_data);
-    m_ll_data->setAll(value);
-}
-
-inline void Powerfield::allocate()
-{
-    delete m_ll_data;
-    auto* dims = new int[rank()];
-    for (size_t i = 0; i < rank(); ++i)
-        dims[i] = (int)axis(i).size();
-    m_ll_data = new LLData<double>(rank(), dims);
-    double default_value = {};
-    m_ll_data->setAll(default_value);
-    delete[] dims;
-}
-
-inline void Powerfield::setVector(const std::vector<double>& data_vector)
-{
-    ASSERT(data_vector.size() == allocatedSize());
-    for (size_t i = 0; i < allocatedSize(); ++i)
-        (*m_ll_data)[i] = data_vector[i];
-}
-
-//! Returns true if object have same dimensions
-inline bool Powerfield::hasSameSizes(const Powerfield& other) const
-{
-    return frame().hasSameSizes(other.frame());
-}
-
-//! Returns true if object have same dimensions and shape of axis
-inline bool Powerfield::hasSameShape(const Powerfield& other) const
-{
-    return frame() == other.frame();
-}
-
-inline std::vector<double> Powerfield::cvector() const
-{
-    std::vector<double> ret(allocatedSize());
-    for (size_t i = 0; i < allocatedSize(); ++i)
-        ret[i] = (*this)[i];
-    return ret;
-}
-
-#endif // USER_API
 #endif // BORNAGAIN_DEVICE_DATA_POWERFIELD_H
diff --git a/Device/Detector/IDetector.cpp b/Device/Detector/IDetector.cpp
index d79566e49cc..9bf2cb4506c 100644
--- a/Device/Detector/IDetector.cpp
+++ b/Device/Detector/IDetector.cpp
@@ -15,6 +15,7 @@
 #include "Device/Detector/IDetector.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/IAxis.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Const/Units.h"
 #include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
diff --git a/Device/Detector/RectangularDetector.cpp b/Device/Detector/RectangularDetector.cpp
index 10226f8b97f..8fb494b8810 100644
--- a/Device/Detector/RectangularDetector.cpp
+++ b/Device/Detector/RectangularDetector.cpp
@@ -13,10 +13,12 @@
 //  ************************************************************************************************
 
 #include "Device/Detector/RectangularDetector.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Axis/Bin.h"
 #include "Base/Const/Units.h"
 #include "Base/Math/Constants.h"
 #include "Base/Pixel/RectangularPixel.h"
+#include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Coord/CoordSystem2D.h"
 #include "Device/Resolution/IDetectorResolution.h"
diff --git a/Device/Detector/SphericalDetector.cpp b/Device/Detector/SphericalDetector.cpp
index b08e19471f6..5cbd016c694 100644
--- a/Device/Detector/SphericalDetector.cpp
+++ b/Device/Detector/SphericalDetector.cpp
@@ -14,9 +14,11 @@
 
 #include "Device/Detector/SphericalDetector.h"
 #include "Base/Axis/Bin.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Const/Units.h"
 #include "Base/Math/Constants.h"
 #include "Base/Pixel/SphericalPixel.h"
+#include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Coord/CoordSystem2D.h"
 #include "Device/Resolution/IDetectorResolution.h"
diff --git a/Device/Histo/Histogram1D.cpp b/Device/Histo/Histogram1D.cpp
index d975c484901..fda0d3bf16c 100644
--- a/Device/Histo/Histogram1D.cpp
+++ b/Device/Histo/Histogram1D.cpp
@@ -14,6 +14,7 @@
 
 #include "Device/Histo/Histogram1D.h"
 #include "Base/Axis/FixedBinAxis.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Axis/VariableBinAxis.h"
 #include "Base/Py/PyUtils.h"
 #include "Device/Data/CumulativeValue.h"
diff --git a/Device/Histo/Histogram2D.cpp b/Device/Histo/Histogram2D.cpp
index 2990ccad95c..44b9d1440fe 100644
--- a/Device/Histo/Histogram2D.cpp
+++ b/Device/Histo/Histogram2D.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Device/Histo/Histogram2D.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Axis/VariableBinAxis.h"
 #include "Device/Data/CumulativeValue.h"
 #include "Device/Data/Powerfield.h"
diff --git a/Device/Histo/HistogramUtils.cpp b/Device/Histo/HistogramUtils.cpp
index 65c0fe2364c..a0688295ad2 100644
--- a/Device/Histo/HistogramUtils.cpp
+++ b/Device/Histo/HistogramUtils.cpp
@@ -14,7 +14,9 @@
 
 #include "Device/Histo/HistogramUtils.h"
 #include "Base/Axis/Bin.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Math/Numeric.h"
+#include "Base/Util/Assert.h"
 #include "Device/Data/DataUtils.h"
 #include "Device/Data/Powerfield.h"
 #include "Device/Histo/Histogram2D.h"
diff --git a/Device/Histo/IHistogram.cpp b/Device/Histo/IHistogram.cpp
index 0a9d080850d..de5a49a8ad9 100644
--- a/Device/Histo/IHistogram.cpp
+++ b/Device/Histo/IHistogram.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Device/Histo/IHistogram.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Axis/Frame.h"
 #include "Base/Math/Numeric.h"
 #include "Base/Util/Assert.h"
diff --git a/Device/Histo/IOFactory.cpp b/Device/Histo/IOFactory.cpp
index 26e63448bb9..b75a2f1101c 100644
--- a/Device/Histo/IOFactory.cpp
+++ b/Device/Histo/IOFactory.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Device/Histo/IOFactory.h"
+#include "Base/Util/Assert.h"
 #include "Base/Util/FileSystemUtils.h"
 #include "Device/Histo/IHistogram.h"
 #include "Device/Histo/SimulationResult.h"
diff --git a/Device/Histo/SimulationResult.cpp b/Device/Histo/SimulationResult.cpp
index 7aa8aa8a4c8..fe024ff5bb0 100644
--- a/Device/Histo/SimulationResult.cpp
+++ b/Device/Histo/SimulationResult.cpp
@@ -13,8 +13,12 @@
 //  ************************************************************************************************
 
 #include "Device/Histo/SimulationResult.h"
+#include "Base/Axis/IAxis.h"
+#include "Base/Util/Assert.h"
 #include "Device/Histo/Histogram2D.h"
 
+#include <stdexcept>
+
 SimulationResult::SimulationResult(const Powerfield& data, const ICoordSystem& coords)
     : m_data(data.clone())
     , m_coordsys(coords.clone())
@@ -108,8 +112,8 @@ size_t SimulationResult::size() const
 
 SimulationResult SimulationResult::relativeToMaximum() const
 {
-    std::unique_ptr<Powerfield> data2{m_data->clone()};
-    return {data2->normalizedToMaximum(), m_coordsys->clone()};
+    std::unique_ptr<Powerfield> data2(m_data->normalizedToMaximum());
+    return {*data2, m_coordsys->clone()};
 }
 
 #ifdef BORNAGAIN_PYTHON
diff --git a/Device/InputOutput/DataFormatUtils.cpp b/Device/InputOutput/DataFormatUtils.cpp
index 3bb6ef71643..ca13b0ba22e 100644
--- a/Device/InputOutput/DataFormatUtils.cpp
+++ b/Device/InputOutput/DataFormatUtils.cpp
@@ -15,6 +15,7 @@
 #include "Device/InputOutput/DataFormatUtils.h"
 #include "Base/Axis/ConstKBinAxis.h"
 #include "Base/Axis/CustomBinAxis.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/PointwiseAxis.h"
 #include "Base/Util/FileSystemUtils.h"
 #include "Base/Util/StringUtils.h"
diff --git a/Device/InputOutput/ReadWriteINT.cpp b/Device/InputOutput/ReadWriteINT.cpp
index 4c7b6dc33e4..bb7a14813f2 100644
--- a/Device/InputOutput/ReadWriteINT.cpp
+++ b/Device/InputOutput/ReadWriteINT.cpp
@@ -14,6 +14,7 @@
 
 #include "Device/InputOutput/ReadWriteINT.h"
 #include "Base/Axis/Bin.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Util/StringUtils.h"
 #include "Device/Data/ArrayUtils.h"
 #include "Device/InputOutput/DataFormatUtils.h"
diff --git a/Device/InputOutput/ReadWriteNicos.cpp b/Device/InputOutput/ReadWriteNicos.cpp
index 7f2959495e4..e5f4bfca728 100644
--- a/Device/InputOutput/ReadWriteNicos.cpp
+++ b/Device/InputOutput/ReadWriteNicos.cpp
@@ -13,6 +13,8 @@
 //  ************************************************************************************************
 
 #include "Device/InputOutput/ReadWriteNicos.h"
+#include "Base/Axis/FixedBinAxis.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Util/StringUtils.h"
 #include <memory>
 
diff --git a/Device/InputOutput/ReadWriteNumpyTXT.cpp b/Device/InputOutput/ReadWriteNumpyTXT.cpp
index 21456603d24..5281771f437 100644
--- a/Device/InputOutput/ReadWriteNumpyTXT.cpp
+++ b/Device/InputOutput/ReadWriteNumpyTXT.cpp
@@ -14,6 +14,7 @@
 
 #include "Device/InputOutput/ReadWriteNumpyTXT.h"
 #include "Base/Axis/Bin.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Util/StringUtils.h"
 #include "Device/Data/ArrayUtils.h"
 #include "Device/InputOutput/DataFormatUtils.h"
diff --git a/Device/InputOutput/ReadWriteTiff.cpp b/Device/InputOutput/ReadWriteTiff.cpp
index 7c20bec1b0b..e858602ea47 100644
--- a/Device/InputOutput/ReadWriteTiff.cpp
+++ b/Device/InputOutput/ReadWriteTiff.cpp
@@ -15,6 +15,9 @@
 #ifdef BA_TIFF_SUPPORT
 
 #include "Device/InputOutput/ReadWriteTiff.h"
+#include "Base/Axis/FixedBinAxis.h"
+#include "Base/Axis/Frame.h"
+#include "Base/Util/Assert.h"
 #include "Base/Util/SysUtils.h"
 #include <cstring> // memcpy
 #include <memory>
diff --git a/Device/Resolution/ConvolutionDetectorResolution.cpp b/Device/Resolution/ConvolutionDetectorResolution.cpp
index 8788ad048b0..c2bdba4b7c2 100644
--- a/Device/Resolution/ConvolutionDetectorResolution.cpp
+++ b/Device/Resolution/ConvolutionDetectorResolution.cpp
@@ -13,7 +13,11 @@
 //  ************************************************************************************************
 
 #include "Device/Resolution/ConvolutionDetectorResolution.h"
+#include "Base/Axis/FixedBinAxis.h"
+#include "Base/Axis/Frame.h"
+#include "Base/Util/Assert.h"
 #include "Device/Resolution/Convolve.h"
+#include <stdexcept>
 
 ConvolutionDetectorResolution::ConvolutionDetectorResolution(cumulative_DF_1d res_function_1d)
     : m_rank(1)
@@ -103,7 +107,8 @@ void ConvolutionDetectorResolution::apply1dConvolution(Powerfield* p_intensity_m
     std::vector<double> result;
     Convolve().fftconvolve(source_vector, kernel, result);
     // Truncate negative values that can arise because of finite precision of Fourier Transform
-    std::for_each(result.begin(), result.end(), [](double& val) { val = std::max(0.0, val); });
+    for(double& e: result)
+        e = std::max(0.0, e);
     // Populate intensity map with results
     p_intensity_map->setVector(result);
 }
diff --git a/GUI/Model/Data/IntensityDataItem.cpp b/GUI/Model/Data/IntensityDataItem.cpp
index ab54e8e9e9d..21dcae91d1d 100644
--- a/GUI/Model/Data/IntensityDataItem.cpp
+++ b/GUI/Model/Data/IntensityDataItem.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Data/IntensityDataItem.h"
+#include "Base/Axis/IAxis.h"
 #include "GUI/Model/Data/JobItemUtils.h"
 #include "GUI/Model/Data/ProjectionItems.h"
 #include "GUI/Model/Device/AxesItems.h"
diff --git a/GUI/Model/Data/SpecularDataItem.cpp b/GUI/Model/Data/SpecularDataItem.cpp
index f1433c01e3a..38df8697750 100644
--- a/GUI/Model/Data/SpecularDataItem.cpp
+++ b/GUI/Model/Data/SpecularDataItem.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/Model/Data/SpecularDataItem.h"
+#include "Base/Axis/IAxis.h"
 #include "GUI/Model/Data/JobItemUtils.h"
 #include "GUI/Model/Device/AxesItems.h"
 #include "GUI/Support/IO/ImportDataInfo.h"
diff --git a/GUI/Support/IO/IOUtils.cpp b/GUI/Support/IO/IOUtils.cpp
index 9df7f512fa5..1e9c1063a33 100644
--- a/GUI/Support/IO/IOUtils.cpp
+++ b/GUI/Support/IO/IOUtils.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/Support/IO/IOUtils.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Util/Assert.h"
 #include "Device/Data/Powerfield.h"
 
diff --git a/GUI/Support/IO/ImportDataInfo.cpp b/GUI/Support/IO/ImportDataInfo.cpp
index 3c07705e87b..269d7885073 100644
--- a/GUI/Support/IO/ImportDataInfo.cpp
+++ b/GUI/Support/IO/ImportDataInfo.cpp
@@ -13,6 +13,8 @@
 //  ************************************************************************************************
 
 #include "GUI/Support/IO/ImportDataInfo.h"
+#include "Base/Axis/IAxis.h"
+#include "Base/Axis/Frame.h"
 #include "Device/Coord/AxisNames.h"
 #include "Device/Data/Powerfield.h"
 #include "GUI/Support/IO/IOUtils.h"
diff --git a/GUI/View/Loaders/AutomaticDataLoader1DResultModel.cpp b/GUI/View/Loaders/AutomaticDataLoader1DResultModel.cpp
index eb3732ff87f..8b777a7afa6 100644
--- a/GUI/View/Loaders/AutomaticDataLoader1DResultModel.cpp
+++ b/GUI/View/Loaders/AutomaticDataLoader1DResultModel.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/View/Loaders/AutomaticDataLoader1DResultModel.h"
+#include "Base/Axis/Frame.h"
 #include "GUI/Model/Data/RealDataItem.h"
 #include "GUI/Model/Data/SpecularDataItem.h"
 
diff --git a/GUI/View/PlotSpecular/SpecularPlot.cpp b/GUI/View/PlotSpecular/SpecularPlot.cpp
index d342e31bd43..a33230d66fd 100644
--- a/GUI/View/PlotSpecular/SpecularPlot.cpp
+++ b/GUI/View/PlotSpecular/SpecularPlot.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/View/PlotSpecular/SpecularPlot.h"
+#include "Base/Axis/Frame.h"
 #include "GUI/Model/Data/RealDataItem.h"
 #include "GUI/Model/Data/SpecularDataItem.h"
 #include "GUI/Model/Device/AxesItems.h"
diff --git a/Sim/Export/SimulationToPython.cpp b/Sim/Export/SimulationToPython.cpp
index 20943d51c38..b4da0b0d257 100644
--- a/Sim/Export/SimulationToPython.cpp
+++ b/Sim/Export/SimulationToPython.cpp
@@ -13,8 +13,10 @@
 //  ************************************************************************************************
 
 #include "Sim/Export/SimulationToPython.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Py/PyFmt.h"
 #include "Base/Util/Algorithms.h"
+#include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Beam/FootprintGauss.h"
 #include "Device/Beam/FootprintSquare.h"
diff --git a/Sim/Fitting/FitObjective.cpp b/Sim/Fitting/FitObjective.cpp
index 2dccd8849e4..d7b37c92a2f 100644
--- a/Sim/Fitting/FitObjective.cpp
+++ b/Sim/Fitting/FitObjective.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Sim/Fitting/FitObjective.h"
+#include "Base/Util/Assert.h"
 #include "Fit/Minimizer/MinimizerResult.h"
 #include "Sim/Fitting/FitStatus.h"
 #include "Sim/Fitting/ObjectiveMetric.h"
diff --git a/Sim/Fitting/ObjectiveMetric.cpp b/Sim/Fitting/ObjectiveMetric.cpp
index bb17940f3a9..8445d1830f2 100644
--- a/Sim/Fitting/ObjectiveMetric.cpp
+++ b/Sim/Fitting/ObjectiveMetric.cpp
@@ -18,6 +18,7 @@
 #include "Sim/Fitting/SimDataPair.h"
 #include <cmath>
 #include <limits>
+#include <stdexcept>
 
 namespace {
 
diff --git a/Sim/Fitting/SimDataPair.cpp b/Sim/Fitting/SimDataPair.cpp
index 2b3c7cc0c8b..9cabcabdf34 100644
--- a/Sim/Fitting/SimDataPair.cpp
+++ b/Sim/Fitting/SimDataPair.cpp
@@ -13,8 +13,10 @@
 //  ************************************************************************************************
 
 #include "Sim/Fitting/SimDataPair.h"
-
+#include "Base/Axis/IAxis.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Math/Numeric.h"
+#include "Base/Util/Assert.h"
 #include "Device/Coord/CoordSystem1D.h"
 #include "Device/Coord/CoordSystem2D.h"
 #include "Device/Data/DataUtils.h"
diff --git a/Sim/Simulation/DepthProbeSimulation.cpp b/Sim/Simulation/DepthProbeSimulation.cpp
index ef0c70de735..9e60a7ef013 100644
--- a/Sim/Simulation/DepthProbeSimulation.cpp
+++ b/Sim/Simulation/DepthProbeSimulation.cpp
@@ -14,6 +14,8 @@
 
 #include "Sim/Simulation/DepthProbeSimulation.h"
 #include "Base/Axis/Bin.h"
+#include "Base/Axis/FixedBinAxis.h"
+#include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Beam/IFootprintFactor.h"
 #include "Device/Coord/CoordSystem2D.h"
diff --git a/Sim/Simulation/OffspecSimulation.cpp b/Sim/Simulation/OffspecSimulation.cpp
index 9ce125f3bdb..50c1e97edb2 100644
--- a/Sim/Simulation/OffspecSimulation.cpp
+++ b/Sim/Simulation/OffspecSimulation.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Sim/Simulation/OffspecSimulation.h"
+#include "Base/Axis/IAxis.h"
 #include "Base/Axis/Bin.h"
 #include "Base/Pixel/RectangularPixel.h"
 #include "Base/Util/Assert.h"
diff --git a/Sim/Simulation/ScatteringSimulation.cpp b/Sim/Simulation/ScatteringSimulation.cpp
index 4ad8c22fb9c..fe33b233965 100644
--- a/Sim/Simulation/ScatteringSimulation.cpp
+++ b/Sim/Simulation/ScatteringSimulation.cpp
@@ -13,6 +13,8 @@
 //  ************************************************************************************************
 
 #include "Sim/Simulation/ScatteringSimulation.h"
+#include "Base/Axis/IAxis.h"
+#include "Base/Util/Assert.h"
 #include "Device/Coord/CoordSystem2D.h"
 #include "Device/Data/Powerfield.h"
 #include "Device/Detector/IDetector.h"
diff --git a/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp b/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp
index 7674278a76f..09577324a77 100644
--- a/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp
+++ b/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "BATesting.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Util/FileSystemUtils.h"
 #include "Device/Data/DataUtils.h"
 #include "Device/Histo/IOFactory.h"
diff --git a/Tests/Functional/Core/Fitting/FitTests.cpp b/Tests/Functional/Core/Fitting/FitTests.cpp
index 03fcb1f382e..a557617a2d0 100644
--- a/Tests/Functional/Core/Fitting/FitTests.cpp
+++ b/Tests/Functional/Core/Fitting/FitTests.cpp
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#include "Base/Axis/IAxis.h"
 #include "Base/Const/Units.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Detector/RectangularDetector.h"
diff --git a/Tests/Functional/Suite/RunTest.cpp b/Tests/Functional/Suite/RunTest.cpp
index b9a51f0d0ae..b3e24b20727 100644
--- a/Tests/Functional/Suite/RunTest.cpp
+++ b/Tests/Functional/Suite/RunTest.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Tests/Functional/Suite/RunTest.h"
+#include "Base/Axis/IAxis.h"
 #include "Device/Histo/SimulationResult.h"
 #include "Tests/Functional/Suite/TestSuite.h" // provides F_TEST macros to be executed by gtest
 #include <iostream>
diff --git a/Tests/Unit/Device/ArrayUtilsTest.cpp b/Tests/Unit/Device/ArrayUtilsTest.cpp
index b05d74704f3..53b9e9b66dc 100644
--- a/Tests/Unit/Device/ArrayUtilsTest.cpp
+++ b/Tests/Unit/Device/ArrayUtilsTest.cpp
@@ -1,4 +1,5 @@
 #include "Device/Data/ArrayUtils.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <vector>
 
diff --git a/Tests/Unit/Device/IOReaderWriterTest.cpp b/Tests/Unit/Device/IOReaderWriterTest.cpp
index 695bef17a61..8db9edf2059 100644
--- a/Tests/Unit/Device/IOReaderWriterTest.cpp
+++ b/Tests/Unit/Device/IOReaderWriterTest.cpp
@@ -1,6 +1,7 @@
 #include "Device/InputOutput/ReadWriteINT.h"
 #include "Device/InputOutput/ReadWriteNumpyTXT.h"
 #include "Device/InputOutput/ReadWriteTiff.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Tests/GTestWrapper/google_test.h"
 
 class IOReaderWriterTest : public ::testing::Test {
diff --git a/Tests/Unit/Device/IntensityDataFunctionsTest.cpp b/Tests/Unit/Device/IntensityDataFunctionsTest.cpp
index 4cf85e9781f..7c9044d8c33 100644
--- a/Tests/Unit/Device/IntensityDataFunctionsTest.cpp
+++ b/Tests/Unit/Device/IntensityDataFunctionsTest.cpp
@@ -1,3 +1,4 @@
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/VariableBinAxis.h"
 #include "Device/Data/DataUtils.h"
 #include "Tests/GTestWrapper/google_test.h"
diff --git a/Tests/Unit/Device/LLDataTest.cpp b/Tests/Unit/Device/LLDataTest.cpp
deleted file mode 100644
index 26b2ed094dd..00000000000
--- a/Tests/Unit/Device/LLDataTest.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-#include "Device/Data/LLData.h"
-#include "Tests/GTestWrapper/google_test.h"
-#include <algorithm>
-#include <heinz/Complex.h>
-
-class LLDataTest : public ::testing::Test {
-protected:
-    LLDataTest();
-    ~LLDataTest() override;
-
-    LLData<int>* int_data_0d;
-    LLData<float>* fl_data_1d;
-    LLData<double>* db_data_3d;
-};
-
-LLDataTest::LLDataTest()
-{
-    auto* dim0 = new int[0];
-
-    auto* dim1 = new int[1];
-    dim1[0] = 10;
-
-    auto* dim3 = new int[3];
-    dim3[0] = 10;
-    dim3[1] = 15;
-    dim3[2] = 20;
-
-    int_data_0d = new LLData<int>(0u, dim0);
-    fl_data_1d = new LLData<float>(1u, dim1);
-    db_data_3d = new LLData<double>(3u, dim3);
-
-    delete[] dim0;
-    delete[] dim1;
-    delete[] dim3;
-}
-
-LLDataTest::~LLDataTest()
-{
-    delete int_data_0d;
-    delete fl_data_1d;
-    delete db_data_3d;
-}
-
-
-TEST_F(LLDataTest, TotalSize)
-{
-    EXPECT_EQ(1u, int_data_0d->getTotalSize());
-    EXPECT_EQ(10u, fl_data_1d->getTotalSize());
-    EXPECT_EQ(3000u, db_data_3d->getTotalSize());
-}
-
-TEST_F(LLDataTest, GetRank)
-{
-    EXPECT_EQ(0u, int_data_0d->rank());
-    EXPECT_EQ(1u, fl_data_1d->rank());
-    EXPECT_EQ(3u, db_data_3d->rank());
-}
-
-TEST_F(LLDataTest, SetAll)
-{
-    db_data_3d->setAll(1.0);
-    EXPECT_DOUBLE_EQ((*db_data_3d)[0], 1.0);
-}
-
-TEST_F(LLDataTest, TotalSum)
-{
-    fl_data_1d->setAll(2.0);
-    EXPECT_FLOAT_EQ(fl_data_1d->getTotalSum(), 20.0);
-
-    db_data_3d->setAll(0.5);
-    EXPECT_DOUBLE_EQ(db_data_3d->getTotalSum(), 1500.0);
-}
-
-TEST_F(LLDataTest, GetDimensions)
-{
-    EXPECT_EQ(int_data_0d->sizes(), (int*)nullptr);
-    EXPECT_EQ(fl_data_1d->sizes()[0], 10);
-    EXPECT_EQ(db_data_3d->sizes()[1], 15);
-}
-
-TEST_F(LLDataTest, DataCopyingConstructor)
-{
-    auto* other_int_data_0d = new LLData<int>(*int_data_0d);
-    EXPECT_TRUE(HaveSameSizes(*int_data_0d, *other_int_data_0d));
-
-    fl_data_1d->setAll(1.2);
-    auto* other_fl_data_1d = new LLData<float>(*fl_data_1d);
-    EXPECT_TRUE(HaveSameSizes(*fl_data_1d, *other_fl_data_1d));
-    EXPECT_FLOAT_EQ((*other_fl_data_1d)[0], 1.2f);
-    EXPECT_FLOAT_EQ(fl_data_1d->getTotalSum(), other_fl_data_1d->getTotalSum());
-
-    db_data_3d->setAll(1.17);
-    auto* other_db_data_3d = new LLData<double>(*db_data_3d);
-    EXPECT_TRUE(HaveSameSizes(*db_data_3d, *other_db_data_3d));
-    EXPECT_DOUBLE_EQ((*other_db_data_3d)[10], 1.17);
-    EXPECT_DOUBLE_EQ(db_data_3d->getTotalSum(), other_db_data_3d->getTotalSum());
-
-    delete other_int_data_0d;
-    delete other_fl_data_1d;
-    delete other_db_data_3d;
-}
-
-TEST_F(LLDataTest, DataAssignment)
-{
-    auto* other_fl_data_1d = new LLData<float>(*fl_data_1d);
-    fl_data_1d->setAll(1.1f);
-    (*other_fl_data_1d) = (*fl_data_1d);
-    EXPECT_FLOAT_EQ((*other_fl_data_1d)[0], 1.1f);
-    EXPECT_FLOAT_EQ(fl_data_1d->getTotalSum(), other_fl_data_1d->getTotalSum());
-
-    auto* other_db_data_3d = new LLData<double>(*db_data_3d);
-    db_data_3d->setAll(1.27);
-    (*other_db_data_3d) = (*db_data_3d);
-    EXPECT_DOUBLE_EQ((*other_db_data_3d)[11], 1.27);
-    EXPECT_DOUBLE_EQ(db_data_3d->getTotalSum(), other_db_data_3d->getTotalSum());
-
-    delete other_fl_data_1d;
-    delete other_db_data_3d;
-}
-
-TEST_F(LLDataTest, Addition)
-{
-    auto* other_fl_data_1d = new LLData<float>(*fl_data_1d);
-    fl_data_1d->setAll(1.1f);
-    other_fl_data_1d->setAll(2.9f);
-    (*other_fl_data_1d) += (*fl_data_1d);
-    EXPECT_FLOAT_EQ((*other_fl_data_1d)[0], 4.0f);
-    EXPECT_FLOAT_EQ(other_fl_data_1d->getTotalSum(), 40.0f);
-
-    auto* other_db_data_3d = new LLData<double>(*db_data_3d);
-    db_data_3d->setAll(1.27);
-    other_db_data_3d->setAll(0.73);
-    (*other_db_data_3d) += (*db_data_3d);
-    EXPECT_DOUBLE_EQ((*other_db_data_3d)[11], 2.0);
-    EXPECT_DOUBLE_EQ(other_db_data_3d->getTotalSum(), 6000.0);
-
-    auto* odim1 = new int[1];
-    odim1[0] = 12;
-    auto* fl_data_1d2 = new LLData<float>(1u, odim1);
-    fl_data_1d2->setAll(10.0);
-
-    EXPECT_THROW((*fl_data_1d) += (*fl_data_1d2), std::runtime_error);
-
-    delete fl_data_1d2;
-    delete[] odim1;
-
-    delete other_fl_data_1d;
-    delete other_db_data_3d;
-}
-
-TEST_F(LLDataTest, Substraction)
-{
-    auto* other_fl_data_1d = new LLData<float>(*fl_data_1d);
-    fl_data_1d->setAll(1.15f);
-    other_fl_data_1d->setAll(5.15f);
-    (*other_fl_data_1d) -= (*fl_data_1d);
-    EXPECT_FLOAT_EQ((*other_fl_data_1d)[0], 4.0f);
-    EXPECT_FLOAT_EQ(other_fl_data_1d->getTotalSum(), 40.0f);
-
-    auto* other_db_data_3d = new LLData<double>(*db_data_3d);
-    db_data_3d->setAll(1.27);
-    other_db_data_3d->setAll(1.77);
-    (*other_db_data_3d) -= (*db_data_3d);
-    EXPECT_DOUBLE_EQ((*other_db_data_3d)[11], 0.5);
-    EXPECT_DOUBLE_EQ(other_db_data_3d->getTotalSum(), 1500.0);
-
-    auto* odim1 = new int[1];
-    odim1[0] = 12;
-    auto* fl_data_1d2 = new LLData<float>(1u, odim1);
-    fl_data_1d2->setAll(10.0);
-
-    EXPECT_THROW((*fl_data_1d) -= (*fl_data_1d2), std::runtime_error);
-
-    delete fl_data_1d2;
-    delete[] odim1;
-
-    delete other_fl_data_1d;
-    delete other_db_data_3d;
-}
-
-TEST_F(LLDataTest, Multiplication)
-{
-    auto* other_fl_data_1d = new LLData<float>(*fl_data_1d);
-    fl_data_1d->setAll(1.15f);
-    other_fl_data_1d->setAll(2.0f);
-    (*other_fl_data_1d) *= (*fl_data_1d);
-    EXPECT_FLOAT_EQ((*other_fl_data_1d)[0], 2.30f);
-    EXPECT_FLOAT_EQ(other_fl_data_1d->getTotalSum(), 23.0f);
-
-    auto* other_db_data_3d = new LLData<double>(*db_data_3d);
-    db_data_3d->setAll(1.25);
-    other_db_data_3d->setAll(2.0);
-    (*other_db_data_3d) *= (*db_data_3d);
-    EXPECT_DOUBLE_EQ((*other_db_data_3d)[11], 2.5);
-    EXPECT_DOUBLE_EQ(other_db_data_3d->getTotalSum(), 7500.0);
-
-    auto* odim1 = new int[1];
-    odim1[0] = 12;
-    auto* fl_data_1d2 = new LLData<float>(1u, odim1);
-    fl_data_1d2->setAll(10.0);
-
-    EXPECT_THROW((*fl_data_1d) *= (*fl_data_1d2), std::runtime_error);
-
-    delete fl_data_1d2;
-    delete[] odim1;
-
-    delete other_fl_data_1d;
-    delete other_db_data_3d;
-}
-
-TEST_F(LLDataTest, Division)
-{
-    auto* other_fl_data_1d = new LLData<float>(*fl_data_1d);
-    fl_data_1d->setAll(1.15f);
-    other_fl_data_1d->setAll(2.3f);
-    (*other_fl_data_1d) /= (*fl_data_1d);
-    EXPECT_FLOAT_EQ((*other_fl_data_1d)[0], 2.0f);
-    EXPECT_FLOAT_EQ(other_fl_data_1d->getTotalSum(), 20.0f);
-
-    auto* other_db_data_3d = new LLData<double>(*db_data_3d);
-    db_data_3d->setAll(1.25);
-    other_db_data_3d->setAll(2.5);
-    (*other_db_data_3d) /= (*db_data_3d);
-    EXPECT_DOUBLE_EQ((*other_db_data_3d)[11], 2.0);
-    EXPECT_DOUBLE_EQ(other_db_data_3d->getTotalSum(), 6000.0);
-
-    auto* odim1 = new int[1];
-    odim1[0] = 12;
-    auto* fl_data_1d2 = new LLData<float>(1u, odim1);
-    fl_data_1d2->setAll(10.0);
-
-    EXPECT_THROW((*fl_data_1d) /= (*fl_data_1d2), std::runtime_error);
-
-    delete fl_data_1d2;
-    delete[] odim1;
-    delete other_fl_data_1d;
-    delete other_db_data_3d;
-}
-
-TEST_F(LLDataTest, HaveSameSizes)
-{
-    auto* odim0 = new int[0];
-
-    auto* odim1 = new int[1];
-    odim1[0] = 10;
-
-    auto* odim3 = new int[3];
-    odim3[0] = 10;
-    odim3[1] = 15;
-    odim3[2] = 20;
-
-    auto* other_int_data_0d = new LLData<int>(0u, odim0);
-    auto* other_fl_data_1d = new LLData<float>(1u, odim1);
-    auto* other_db_data_3d = new LLData<double>(3u, odim3);
-
-    EXPECT_TRUE(HaveSameSizes(*int_data_0d, *other_int_data_0d));
-    EXPECT_TRUE(HaveSameSizes(*fl_data_1d, *other_fl_data_1d));
-    EXPECT_TRUE(HaveSameSizes(*db_data_3d, *other_db_data_3d));
-
-    odim3[1] = 25;
-    auto* some_other_db_data_3d = new LLData<double>(3u, odim3);
-    EXPECT_FALSE(HaveSameSizes(*db_data_3d, *some_other_db_data_3d));
-
-    delete other_int_data_0d;
-    delete other_fl_data_1d;
-    delete other_db_data_3d;
-    delete some_other_db_data_3d;
-    delete[] odim0;
-    delete[] odim1;
-    delete[] odim3;
-}
-
-TEST_F(LLDataTest, Accessors)
-{
-    for (size_t i = 0; i < fl_data_1d->getTotalSize(); ++i)
-        (*fl_data_1d)[i] = 0.5f * i;
-    EXPECT_FLOAT_EQ((*fl_data_1d)[2], 1.0f);
-
-    EXPECT_FLOAT_EQ(fl_data_1d->getTotalSum(), 22.5f);
-
-    for (size_t i = 0; i < db_data_3d->getTotalSize(); ++i)
-        (*db_data_3d)[i] = 0.2 * i;
-
-    EXPECT_DOUBLE_EQ((*db_data_3d)[2], 0.4);
-
-    EXPECT_DOUBLE_EQ(db_data_3d->getTotalSum(), 899700.0);
-}
-
-TEST_F(LLDataTest, Max)
-{
-    db_data_3d->setAll(15.);
-    (*db_data_3d)[13] = 60;
-    EXPECT_EQ(db_data_3d->max(), 60);
-}
diff --git a/Tests/Unit/Device/PowerfieldTest.cpp b/Tests/Unit/Device/PowerfieldTest.cpp
index db91f78007f..34869519b71 100644
--- a/Tests/Unit/Device/PowerfieldTest.cpp
+++ b/Tests/Unit/Device/PowerfieldTest.cpp
@@ -1,4 +1,6 @@
 #include "Base/Axis/Bin.h"
+#include "Base/Axis/Frame.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/VariableBinAxis.h"
 #include "Device/Data/DataUtils.h"
 #include "Tests/GTestWrapper/google_test.h"
diff --git a/Tests/Unit/Device/SphericalDetectorTest.cpp b/Tests/Unit/Device/SphericalDetectorTest.cpp
index 9204f0a248b..c03b1b12583 100644
--- a/Tests/Unit/Device/SphericalDetectorTest.cpp
+++ b/Tests/Unit/Device/SphericalDetectorTest.cpp
@@ -1,4 +1,5 @@
 #include "Device/Detector/SphericalDetector.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Const/Units.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Mask/DetectorMask.h"
diff --git a/Tests/Unit/FittingTestHelper.h b/Tests/Unit/FittingTestHelper.h
index 724318b6b82..8f2274b9398 100644
--- a/Tests/Unit/FittingTestHelper.h
+++ b/Tests/Unit/FittingTestHelper.h
@@ -1,6 +1,7 @@
 #ifndef BORNAGAIN_TESTS_UNIT_FITTINGTESTHELPER_H
 #define BORNAGAIN_TESTS_UNIT_FITTINGTESTHELPER_H
 
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Const/Units.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Data/Powerfield.h"
diff --git a/Tests/Unit/GUI/Utils.cpp b/Tests/Unit/GUI/Utils.cpp
index 59d49d763cd..a6a3b368b4a 100644
--- a/Tests/Unit/GUI/Utils.cpp
+++ b/Tests/Unit/GUI/Utils.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Tests/Unit/GUI/Utils.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Device/Data/DataUtils.h"
 #include "Device/Histo/IOFactory.h"
 #include "GUI/Model/Data/RealDataItem.h"
diff --git a/Tests/Unit/Sim/CoordSystem1DTest.cpp b/Tests/Unit/Sim/CoordSystem1DTest.cpp
index 7dca2a42a3f..a88fa71c985 100644
--- a/Tests/Unit/Sim/CoordSystem1DTest.cpp
+++ b/Tests/Unit/Sim/CoordSystem1DTest.cpp
@@ -1,4 +1,5 @@
 #include "Device/Coord/CoordSystem1D.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/PointwiseAxis.h"
 #include "Base/Axis/VariableBinAxis.h"
 #include "Base/Const/Units.h"
diff --git a/Tests/Unit/Sim/SpecularSimulationTest.cpp b/Tests/Unit/Sim/SpecularSimulationTest.cpp
index fc302c7b931..58145d5daf7 100644
--- a/Tests/Unit/Sim/SpecularSimulationTest.cpp
+++ b/Tests/Unit/Sim/SpecularSimulationTest.cpp
@@ -1,4 +1,5 @@
 #include "Sim/Simulation/SpecularSimulation.h"
+#include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/VariableBinAxis.h"
 #include "Base/Const/Units.h"
 #include "Base/Math/Constants.h"
diff --git a/Wrap/Swig/libBornAgainDevice.i b/Wrap/Swig/libBornAgainDevice.i
index 88d56377f55..2437ae17ab2 100644
--- a/Wrap/Swig/libBornAgainDevice.i
+++ b/Wrap/Swig/libBornAgainDevice.i
@@ -21,6 +21,8 @@
 %include "../../auto/Wrap/doxygenDevice.i"
 
 %{
+#include "Base/Axis/IAxis.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Element/PolMatrices.h"
 #include "Param/Distrib/ParameterDistribution.h"
 #include "Device/Beam/Beam.h"
diff --git a/Wrap/Swig/libBornAgainSim.i b/Wrap/Swig/libBornAgainSim.i
index ba452d81b7b..6e1f150f8eb 100644
--- a/Wrap/Swig/libBornAgainSim.i
+++ b/Wrap/Swig/libBornAgainSim.i
@@ -52,7 +52,12 @@
 
 %{
 #include "BAVersion.h"
+
+#include "Base/Axis/IAxis.h"
+#include "Base/Axis/Frame.h"
+
 #include "Fit/Minimizer/MinimizerResult.h"
+
 #include "Sample/Scattering/ISampleNode.h"
 
 #include "Sim/Background/ConstantBackground.h"
diff --git a/auto/Wrap/doxygenBase.i b/auto/Wrap/doxygenBase.i
index c546257c385..bf0ec1fe3dc 100644
--- a/auto/Wrap/doxygenBase.i
+++ b/auto/Wrap/doxygenBase.i
@@ -351,7 +351,7 @@ C++ includes: Frame.h
 Constructor that takes ownership of supplied axes. 
 ";
 
-%feature("docstring")  Frame::~Frame "virtual Frame::~Frame()
+%feature("docstring")  Frame::~Frame "Frame::~Frame()
 ";
 
 %feature("docstring")  Frame::rank "size_t Frame::rank() const
@@ -369,7 +369,7 @@ Returns total number of bins.
 Returns number of bins along axis. 
 ";
 
-%feature("docstring")  Frame::cloned_axes "std::vector<IAxis*> Frame::cloned_axes() const
+%feature("docstring")  Frame::cloned_axes "std::vector< IAxis * > Frame::cloned_axes() const
 
 Returns cloned axes. 
 ";
diff --git a/auto/Wrap/doxygenDevice.i b/auto/Wrap/doxygenDevice.i
index b554d15f49a..9d0bad6c8d5 100644
--- a/auto/Wrap/doxygenDevice.i
+++ b/auto/Wrap/doxygenDevice.i
@@ -1417,42 +1417,6 @@ Returns true if area defined by two bins is inside or on border of polygon (more
 ";
 
 
-// File: classLLData.xml
-%feature("docstring") LLData "
-
-Template class to store data of any type in multi-dimensional space (low-level).
-
-C++ includes: LLData.h
-";
-
-%feature("docstring")  LLData::LLData "LLData< T >::LLData(size_t rank, const int *sizes)
-";
-
-%feature("docstring")  LLData::LLData "LLData< T >::LLData(const LLData< T > &right)
-";
-
-%feature("docstring")  LLData::~LLData "LLData< T >::~LLData()
-";
-
-%feature("docstring")  LLData::setAll "void LLData< T >::setAll(const T &value)
-";
-
-%feature("docstring")  LLData::getTotalSize "size_t LLData< T >::getTotalSize() const
-";
-
-%feature("docstring")  LLData::rank "size_t LLData< T >::rank() const
-";
-
-%feature("docstring")  LLData::sizes "const int* LLData< T >::sizes() const
-";
-
-%feature("docstring")  LLData::getTotalSum "T LLData< T >::getTotalSum() const
-";
-
-%feature("docstring")  LLData::max "T LLData< T >::max() const
-";
-
-
 // File: classMaskPattern.xml
 %feature("docstring") MaskPattern "";
 
@@ -1610,10 +1574,9 @@ Stores radiation power per bin.
 C++ includes: Powerfield.h
 ";
 
-%feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(const IAxis &xAxis)
-";
+%feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(Frame *frame, const std::vector< double > &vector)
 
-%feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(const IAxis &xAxis, const IAxis &yAxis)
+Constructor that takes ownership of supplied frame. 
 ";
 
 %feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(const std::vector< IAxis * > &axes)
@@ -1621,6 +1584,21 @@ C++ includes: Powerfield.h
 Constructor that takes ownership of supplied axes. 
 ";
 
+%feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(const std::vector< IAxis * > &axes, const std::vector< double > &vector)
+
+Constructor that takes ownership of supplied axes. 
+";
+
+%feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(const IAxis &xAxis)
+
+Constructor that clones supplied axis. 
+";
+
+%feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(const IAxis &xAxis, const IAxis &yAxis)
+
+Constructor that clones supplied axes. 
+";
+
 %feature("docstring")  Powerfield::Powerfield "Powerfield::Powerfield(const Powerfield &)=delete
 ";
 
@@ -1633,13 +1611,13 @@ Constructor that takes ownership of supplied axes.
 %feature("docstring")  Powerfield::clone "Powerfield * Powerfield::clone() const
 ";
 
-%feature("docstring")  Powerfield::frame "const Frame& Powerfield::frame() const
+%feature("docstring")  Powerfield::frame "const Frame & Powerfield::frame() const
 ";
 
 %feature("docstring")  Powerfield::rank "size_t Powerfield::rank() const
 ";
 
-%feature("docstring")  Powerfield::axis "const IAxis& Powerfield::axis(size_t k) const
+%feature("docstring")  Powerfield::axis "const IAxis & Powerfield::axis(size_t k) const
 ";
 
 %feature("docstring")  Powerfield::allocatedSize "size_t Powerfield::allocatedSize() const
@@ -1652,6 +1630,9 @@ Returns total size of data buffer (product of bin number in every dimension).
 Returns copy of raw data vector. 
 ";
 
+%feature("docstring")  Powerfield::maxVal "double Powerfield::maxVal() const
+";
+
 %feature("docstring")  Powerfield::setAllTo "void Powerfield::setAllTo(const double &value)
 
 Sets content of output data to specific value. 
@@ -1681,12 +1662,7 @@ Returns true if object have same dimensions and shape of axis.
 Returns data as Python numpy array. 
 ";
 
-%feature("docstring")  Powerfield::allocate "void Powerfield::allocate()
-
-Allocates memory for current dimensions configuration. 
-";
-
-%feature("docstring")  Powerfield::normalizedToMaximum "const Powerfield & Powerfield::normalizedToMaximum()
+%feature("docstring")  Powerfield::normalizedToMaximum "Powerfield * Powerfield::normalizedToMaximum()
 ";
 
 
@@ -2216,16 +2192,16 @@ Returns default units to convert to.
 // File: namespace_0d21.xml
 
 
-// File: namespace_0d28.xml
+// File: namespace_0d27.xml
 
 
-// File: namespace_0d49.xml
+// File: namespace_0d48.xml
 
 
-// File: namespace_0d55.xml
+// File: namespace_0d54.xml
 
 
-// File: namespace_0d57.xml
+// File: namespace_0d56.xml
 
 
 // File: namespaceDataUtils.xml
@@ -2475,11 +2451,6 @@ Returns true if data in both files agree.
 // File: DataUtils_8h.xml
 
 
-// File: LLData_8h.xml
-%feature("docstring")  HaveSameSizes "bool HaveSameSizes(const LLData< T > &left, const LLData< T > &right)
-";
-
-
 // File: Powerfield_8cpp.xml
 
 
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index e672f96357d..01a5d958f0c 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -2806,7 +2806,7 @@ class Frame(object):
     def cloned_axes(self):
         r"""
         cloned_axes(Frame self) -> std::vector< IAxis *,std::allocator< IAxis * > >
-        std::vector<IAxis*> Frame::cloned_axes() const
+        std::vector< IAxis * > Frame::cloned_axes() const
 
         Returns cloned axes. 
 
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 86caec5b1e2..605080a26fa 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -30232,7 +30232,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "delete_Frame", _wrap_delete_Frame, METH_O, "\n"
 		"delete_Frame(Frame self)\n"
-		"virtual Frame::~Frame()\n"
+		"Frame::~Frame()\n"
 		"\n"
 		""},
 	 { "Frame_rank", _wrap_Frame_rank, METH_O, "\n"
@@ -30258,7 +30258,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "Frame_cloned_axes", _wrap_Frame_cloned_axes, METH_O, "\n"
 		"Frame_cloned_axes(Frame self) -> std::vector< IAxis *,std::allocator< IAxis * > >\n"
-		"std::vector<IAxis*> Frame::cloned_axes() const\n"
+		"std::vector< IAxis * > Frame::cloned_axes() const\n"
 		"\n"
 		"Returns cloned axes. \n"
 		"\n"
diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index 8d6aaf68d92..31705515f82 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -2057,9 +2057,11 @@ class Powerfield(object):
 
     def __init__(self, *args):
         r"""
+        __init__(Powerfield self, Frame frame, vdouble1d_t vector) -> Powerfield
+        __init__(Powerfield self, std::vector< IAxis *,std::allocator< IAxis * > > const & axes) -> Powerfield
+        __init__(Powerfield self, std::vector< IAxis *,std::allocator< IAxis * > > const & axes, vdouble1d_t vector) -> Powerfield
         __init__(Powerfield self, IAxis xAxis) -> Powerfield
         __init__(Powerfield self, IAxis xAxis, IAxis yAxis) -> Powerfield
-        __init__(Powerfield self, std::vector< IAxis *,std::allocator< IAxis * > > const & axes) -> Powerfield
         __init__(Powerfield self, Powerfield arg2) -> Powerfield
         Powerfield::Powerfield(Powerfield &&)=default
 
@@ -2078,7 +2080,7 @@ class Powerfield(object):
     def frame(self):
         r"""
         frame(Powerfield self) -> Frame
-        const Frame& Powerfield::frame() const
+        const Frame & Powerfield::frame() const
 
         """
         return _libBornAgainDevice.Powerfield_frame(self)
@@ -2094,7 +2096,7 @@ class Powerfield(object):
     def axis(self, k):
         r"""
         axis(Powerfield self, size_t k) -> IAxis
-        const IAxis& Powerfield::axis(size_t k) const
+        const IAxis & Powerfield::axis(size_t k) const
 
         """
         return _libBornAgainDevice.Powerfield_axis(self, k)
@@ -2119,6 +2121,14 @@ class Powerfield(object):
         """
         return _libBornAgainDevice.Powerfield_cvector(self)
 
+    def maxVal(self):
+        r"""
+        maxVal(Powerfield self) -> double
+        double Powerfield::maxVal() const
+
+        """
+        return _libBornAgainDevice.Powerfield_maxVal(self)
+
     def setAllTo(self, value):
         r"""
         setAllTo(Powerfield self, double const & value)
@@ -2173,20 +2183,10 @@ class Powerfield(object):
         """
         return _libBornAgainDevice.Powerfield_getArray(self)
 
-    def allocate(self):
-        r"""
-        allocate(Powerfield self)
-        void Powerfield::allocate()
-
-        Allocates memory for current dimensions configuration. 
-
-        """
-        return _libBornAgainDevice.Powerfield_allocate(self)
-
     def normalizedToMaximum(self):
         r"""
         normalizedToMaximum(Powerfield self) -> Powerfield
-        const Powerfield & Powerfield::normalizedToMaximum()
+        Powerfield * Powerfield::normalizedToMaximum()
 
         """
         return _libBornAgainDevice.Powerfield_normalizedToMaximum(self)
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index a824606fec3..640225fdb23 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -6691,6 +6691,8 @@ SWIGINTERN std::vector< std::pair< double,double > >::iterator std_vector_Sl_std
 SWIGINTERN std::vector< std::pair< double,double > >::iterator std_vector_Sl_std_pair_Sl_double_Sc_double_Sg__Sg__insert__SWIG_0(std::vector< std::pair< double,double > > *self,std::vector< std::pair< double,double > >::iterator pos,std::vector< std::pair< double,double > >::value_type const &x){ return self->insert(pos, x); }
 SWIGINTERN void std_vector_Sl_std_pair_Sl_double_Sc_double_Sg__Sg__insert__SWIG_1(std::vector< std::pair< double,double > > *self,std::vector< std::pair< double,double > >::iterator pos,std::vector< std::pair< double,double > >::size_type n,std::vector< std::pair< double,double > >::value_type const &x){ self->insert(pos, n, x); }
 
+#include "Base/Axis/IAxis.h"
+#include "Base/Axis/Frame.h"
 #include "Base/Element/PolMatrices.h"
 #include "Param/Distrib/ParameterDistribution.h"
 #include "Device/Beam/Beam.h"
@@ -26985,6 +26987,105 @@ SWIGINTERN PyObject *vector_R3_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject
 }
 
 SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  Frame *arg1 = (Frame *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
+  Powerfield *result = 0 ;
+  
+  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Frame, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Powerfield" "', argument " "1"" of type '" "Frame *""'"); 
+  }
+  arg1 = reinterpret_cast< Frame * >(argp1);
+  {
+    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
+    res2 = swig::asptr(swig_obj[1], &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_Powerfield" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Powerfield" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    arg2 = ptr;
+  }
+  result = (Powerfield *)new Powerfield(arg1,(std::vector< double,std::allocator< double > > const &)*arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Powerfield, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res2)) delete arg2;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  std::vector< IAxis *,std::allocator< IAxis * > > *arg1 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  Powerfield *result = 0 ;
+  
+  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Powerfield" "', argument " "1"" of type '" "std::vector< IAxis *,std::allocator< IAxis * > > const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Powerfield" "', argument " "1"" of type '" "std::vector< IAxis *,std::allocator< IAxis * > > const &""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< IAxis *,std::allocator< IAxis * > > * >(argp1);
+  result = (Powerfield *)new Powerfield((std::vector< IAxis *,std::allocator< IAxis * > > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Powerfield, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_2(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  std::vector< IAxis *,std::allocator< IAxis * > > *arg1 = 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
+  Powerfield *result = 0 ;
+  
+  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Powerfield" "', argument " "1"" of type '" "std::vector< IAxis *,std::allocator< IAxis * > > const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Powerfield" "', argument " "1"" of type '" "std::vector< IAxis *,std::allocator< IAxis * > > const &""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< IAxis *,std::allocator< IAxis * > > * >(argp1);
+  {
+    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
+    res2 = swig::asptr(swig_obj[1], &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_Powerfield" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Powerfield" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    arg2 = ptr;
+  }
+  result = (Powerfield *)new Powerfield((std::vector< IAxis *,std::allocator< IAxis * > > const &)*arg1,(std::vector< double,std::allocator< double > > const &)*arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Powerfield, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res2)) delete arg2;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_3(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   IAxis *arg1 = 0 ;
   void *argp1 = 0 ;
@@ -27008,7 +27109,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_4(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   IAxis *arg1 = 0 ;
   IAxis *arg2 = 0 ;
@@ -27043,31 +27144,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_2(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  std::vector< IAxis *,std::allocator< IAxis * > > *arg1 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  Powerfield *result = 0 ;
-  
-  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Powerfield" "', argument " "1"" of type '" "std::vector< IAxis *,std::allocator< IAxis * > > const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Powerfield" "', argument " "1"" of type '" "std::vector< IAxis *,std::allocator< IAxis * > > const &""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector< IAxis *,std::allocator< IAxis * > > * >(argp1);
-  result = (Powerfield *)new Powerfield((std::vector< IAxis *,std::allocator< IAxis * > > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Powerfield, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_3(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+SWIGINTERN PyObject *_wrap_new_Powerfield__SWIG_5(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   Powerfield *arg1 = 0 ;
   void *argp1 = 0 ;
@@ -27101,18 +27178,18 @@ SWIGINTERN PyObject *_wrap_new_Powerfield(PyObject *self, PyObject *args) {
   --argc;
   if (argc == 1) {
     int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_IAxis, SWIG_POINTER_NO_NULL | 0);
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t, SWIG_POINTER_NO_NULL | 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_new_Powerfield__SWIG_0(self, argc, argv);
+      return _wrap_new_Powerfield__SWIG_1(self, argc, argv);
     }
   }
   if (argc == 1) {
     int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t, SWIG_POINTER_NO_NULL | 0);
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_IAxis, SWIG_POINTER_NO_NULL | 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_new_Powerfield__SWIG_2(self, argc, argv);
+      return _wrap_new_Powerfield__SWIG_3(self, argc, argv);
     }
   }
   if (argc == 1) {
@@ -27121,7 +27198,20 @@ SWIGINTERN PyObject *_wrap_new_Powerfield(PyObject *self, PyObject *args) {
     int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_Powerfield, SWIG_POINTER_NO_NULL);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_new_Powerfield__SWIG_3(self, argc, argv);
+      return _wrap_new_Powerfield__SWIG_5(self, argc, argv);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_Frame, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      int res = swig::asptr(argv[1], (std::vector< double,std::allocator< double > >**)(0));
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        return _wrap_new_Powerfield__SWIG_0(self, argc, argv);
+      }
     }
   }
   if (argc == 2) {
@@ -27132,7 +27222,19 @@ SWIGINTERN PyObject *_wrap_new_Powerfield(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_IAxis, SWIG_POINTER_NO_NULL | 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_new_Powerfield__SWIG_1(self, argc, argv);
+        return _wrap_new_Powerfield__SWIG_4(self, argc, argv);
+      }
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t, SWIG_POINTER_NO_NULL | 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      int res = swig::asptr(argv[1], (std::vector< double,std::allocator< double > >**)(0));
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        return _wrap_new_Powerfield__SWIG_2(self, argc, argv);
       }
     }
   }
@@ -27140,9 +27242,11 @@ SWIGINTERN PyObject *_wrap_new_Powerfield(PyObject *self, PyObject *args) {
 fail:
   SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_Powerfield'.\n"
     "  Possible C/C++ prototypes are:\n"
+    "    Powerfield::Powerfield(Frame *,std::vector< double,std::allocator< double > > const &)\n"
+    "    Powerfield::Powerfield(std::vector< IAxis *,std::allocator< IAxis * > > const &)\n"
+    "    Powerfield::Powerfield(std::vector< IAxis *,std::allocator< IAxis * > > const &,std::vector< double,std::allocator< double > > const &)\n"
     "    Powerfield::Powerfield(IAxis const &)\n"
     "    Powerfield::Powerfield(IAxis const &,IAxis const &)\n"
-    "    Powerfield::Powerfield(std::vector< IAxis *,std::allocator< IAxis * > > const &)\n"
     "    Powerfield::Powerfield(Powerfield &&)\n");
   return 0;
 }
@@ -27315,6 +27419,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Powerfield_maxVal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Powerfield *arg1 = (Powerfield *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  double result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Powerfield, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Powerfield_maxVal" "', argument " "1"" of type '" "Powerfield const *""'"); 
+  }
+  arg1 = reinterpret_cast< Powerfield * >(argp1);
+  result = (double)((Powerfield const *)arg1)->maxVal();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_Powerfield_setAllTo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Powerfield *arg1 = (Powerfield *) 0 ;
@@ -27471,28 +27598,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_Powerfield_allocate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  Powerfield *arg1 = (Powerfield *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Powerfield, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Powerfield_allocate" "', argument " "1"" of type '" "Powerfield *""'"); 
-  }
-  arg1 = reinterpret_cast< Powerfield * >(argp1);
-  (arg1)->allocate();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_Powerfield_normalizedToMaximum(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Powerfield *arg1 = (Powerfield *) 0 ;
@@ -27508,7 +27613,7 @@ SWIGINTERN PyObject *_wrap_Powerfield_normalizedToMaximum(PyObject *SWIGUNUSEDPA
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Powerfield_normalizedToMaximum" "', argument " "1"" of type '" "Powerfield *""'"); 
   }
   arg1 = reinterpret_cast< Powerfield * >(argp1);
-  result = (Powerfield *) &(arg1)->normalizedToMaximum();
+  result = (Powerfield *)(arg1)->normalizedToMaximum();
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Powerfield, 0 |  0 );
   return resultobj;
 fail:
@@ -40169,9 +40274,11 @@ static PyMethodDef SwigMethods[] = {
 	 { "vector_R3_swigregister", vector_R3_swigregister, METH_O, NULL},
 	 { "vector_R3_swiginit", vector_R3_swiginit, METH_VARARGS, NULL},
 	 { "new_Powerfield", _wrap_new_Powerfield, METH_VARARGS, "\n"
+		"Powerfield(Frame frame, vdouble1d_t vector)\n"
+		"Powerfield(std::vector< IAxis *,std::allocator< IAxis * > > const & axes)\n"
+		"Powerfield(std::vector< IAxis *,std::allocator< IAxis * > > const & axes, vdouble1d_t vector)\n"
 		"Powerfield(IAxis xAxis)\n"
 		"Powerfield(IAxis xAxis, IAxis yAxis)\n"
-		"Powerfield(std::vector< IAxis *,std::allocator< IAxis * > > const & axes)\n"
 		"new_Powerfield(Powerfield arg1) -> Powerfield\n"
 		"Powerfield::Powerfield(Powerfield &&)=default\n"
 		"\n"
@@ -40188,7 +40295,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "Powerfield_frame", _wrap_Powerfield_frame, METH_O, "\n"
 		"Powerfield_frame(Powerfield self) -> Frame\n"
-		"const Frame& Powerfield::frame() const\n"
+		"const Frame & Powerfield::frame() const\n"
 		"\n"
 		""},
 	 { "Powerfield_rank", _wrap_Powerfield_rank, METH_O, "\n"
@@ -40198,7 +40305,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "Powerfield_axis", _wrap_Powerfield_axis, METH_VARARGS, "\n"
 		"Powerfield_axis(Powerfield self, size_t k) -> IAxis\n"
-		"const IAxis& Powerfield::axis(size_t k) const\n"
+		"const IAxis & Powerfield::axis(size_t k) const\n"
 		"\n"
 		""},
 	 { "Powerfield_allocatedSize", _wrap_Powerfield_allocatedSize, METH_O, "\n"
@@ -40215,6 +40322,11 @@ static PyMethodDef SwigMethods[] = {
 		"Returns copy of raw data vector. \n"
 		"\n"
 		""},
+	 { "Powerfield_maxVal", _wrap_Powerfield_maxVal, METH_O, "\n"
+		"Powerfield_maxVal(Powerfield self) -> double\n"
+		"double Powerfield::maxVal() const\n"
+		"\n"
+		""},
 	 { "Powerfield_setAllTo", _wrap_Powerfield_setAllTo, METH_VARARGS, "\n"
 		"Powerfield_setAllTo(Powerfield self, double const & value)\n"
 		"void Powerfield::setAllTo(const double &value)\n"
@@ -40254,16 +40366,9 @@ static PyMethodDef SwigMethods[] = {
 		"Returns data as Python numpy array. \n"
 		"\n"
 		""},
-	 { "Powerfield_allocate", _wrap_Powerfield_allocate, METH_O, "\n"
-		"Powerfield_allocate(Powerfield self)\n"
-		"void Powerfield::allocate()\n"
-		"\n"
-		"Allocates memory for current dimensions configuration. \n"
-		"\n"
-		""},
 	 { "Powerfield_normalizedToMaximum", _wrap_Powerfield_normalizedToMaximum, METH_O, "\n"
 		"Powerfield_normalizedToMaximum(Powerfield self) -> Powerfield\n"
-		"const Powerfield & Powerfield::normalizedToMaximum()\n"
+		"Powerfield * Powerfield::normalizedToMaximum()\n"
 		"\n"
 		""},
 	 { "Powerfield_swigregister", Powerfield_swigregister, METH_O, NULL},
diff --git a/auto/Wrap/libBornAgainSim_wrap.cpp b/auto/Wrap/libBornAgainSim_wrap.cpp
index 96b8895a66a..ef23859d141 100644
--- a/auto/Wrap/libBornAgainSim_wrap.cpp
+++ b/auto/Wrap/libBornAgainSim_wrap.cpp
@@ -6689,7 +6689,12 @@ SWIGINTERN std::vector< std::pair< double,double > >::iterator std_vector_Sl_std
 SWIGINTERN void std_vector_Sl_std_pair_Sl_double_Sc_double_Sg__Sg__insert__SWIG_1(std::vector< std::pair< double,double > > *self,std::vector< std::pair< double,double > >::iterator pos,std::vector< std::pair< double,double > >::size_type n,std::vector< std::pair< double,double > >::value_type const &x){ self->insert(pos, n, x); }
 
 #include "BAVersion.h"
+
+#include "Base/Axis/IAxis.h"
+#include "Base/Axis/Frame.h"
+
 #include "Fit/Minimizer/MinimizerResult.h"
+
 #include "Sample/Scattering/ISampleNode.h"
 
 #include "Sim/Background/ConstantBackground.h"
-- 
GitLab