diff --git a/Base/Axis/Frame.cpp b/Base/Axis/Frame.cpp
index 38847e0d0f0350a154d937f563d12d442d1a50b7..ddc66982a7660c6be867a71a58333af9143ba5d1 100644
--- a/Base/Axis/Frame.cpp
+++ b/Base/Axis/Frame.cpp
@@ -165,3 +165,9 @@ Frame* Frame::flat() const
             outaxes.emplace_back(s->clone());
     return new Frame(std::move(outaxes));
 }
+
+void Frame::setScale(size_t k_axis, Scale* scale)
+{
+    m_axes.replace_at(k_axis, scale);
+    m_size = FrameUtil::product_size(m_axes.reference());
+}
diff --git a/Base/Axis/Frame.h b/Base/Axis/Frame.h
index 58215319a14f5813120285e8be8b43883e65c677..5cbc1e9d9ed8df921267f47f65a86a4276aaaa8b 100644
--- a/Base/Axis/Frame.h
+++ b/Base/Axis/Frame.h
@@ -83,6 +83,7 @@ public:
     Frame* flat() const;
 
 #ifndef SWIG
+    void setScale(size_t k_axis, Scale* scale);
     std::vector<const Scale*> clonedAxes() const;
 
 private:
diff --git a/Base/Types/OwningVector.h b/Base/Types/OwningVector.h
index bac97140c22896f1944a71999f2b99172e91928d..ca8e04b40c2614adde7fa2389e2e2d38c6b470fc 100644
--- a/Base/Types/OwningVector.h
+++ b/Base/Types/OwningVector.h
@@ -18,6 +18,7 @@
 #ifndef BORNAGAIN_BASE_TYPES_OWNINGVECTOR_H
 #define BORNAGAIN_BASE_TYPES_OWNINGVECTOR_H
 
+#include "Base/Util/Assert.h"
 #include <cstddef>
 #include <utility>
 #include <vector>
@@ -45,9 +46,6 @@ public:
     OwningVector& operator=(OwningVector&& other) = default;
 
     void reserve(size_t n) { m_v.reserve(n); }
-    void emplace_back(T* e) { m_v.emplace_back(e); }
-    void insert_at(size_t index, T* e) { m_v.insert(m_v.begin() + index, e); }
-
     void clear()
     {
         for (T* e : *this)
@@ -82,6 +80,15 @@ public:
         m_v.erase(m_v.begin() + i);
         return result;
     }
+    void emplace_back(T* e) { m_v.emplace_back(e); }
+    void insert_at(size_t i, T* e) { m_v.insert(m_v.begin() + i, e); }
+    void replace_at(size_t i, T* e)
+    {
+        ASSERT(i < m_v.size());
+        delete m_v[i];
+        m_v[i] = e;
+    }
+
 
     T* release_back()
     {
diff --git a/Device/Data/Datafield.cpp b/Device/Data/Datafield.cpp
index 6ab5ce4a88b64390bc828646a61e3828ecd19bcc..e1429ba1347a32beb38748eed8f183db1899a7d0 100644
--- a/Device/Data/Datafield.cpp
+++ b/Device/Data/Datafield.cpp
@@ -255,6 +255,7 @@ double Datafield::minVal() const
 
 Datafield* Datafield::crop(double xmin, double ymin, double xmax, double ymax) const
 {
+    ASSERT(false); // needs renovation, similar to Datafield::crop(double xmin, double xmax)
     const auto xclipped = std::make_unique<Scale>(xAxis().clipped(xmin, xmax));
     const auto yclipped = std::make_unique<Scale>(yAxis().clipped(ymin, ymax));
 
@@ -271,22 +272,30 @@ Datafield* Datafield::crop(double xmin, double ymin, double xmax, double ymax) c
 
 Datafield* Datafield::crop(double xmin, double xmax) const
 {
-    const auto xclipped = std::make_unique<Scale>(xAxis().clipped(xmin, xmax));
+    std::vector<Bin1D> outbins;
+    for (size_t i = 0; i < xAxis().size(); ++i) {
+        const double x = xAxis().binCenter(i);
+        if (xmin <= x && x <= xmax)
+            outbins.push_back(xAxis().bin(i));
+    }
+
+    auto* xclipped = new Scale(xAxis().axisLabel(), outbins);
 
     const size_t N = size();
-    std::vector<double> out(N);
-    std::vector<double> errout(hasErrorSigmas() ? N : 0);
-    size_t iout = 0;
+    std::vector<double> out;
+    std::vector<double> errout;
     for (size_t i = 0; i < N; ++i) {
         const double x = frame().projectedCoord(i, 0);
-        if (xclipped->rangeComprises(x)) {
-            out[iout] = m_values[i];
+        if (xmin <= x && x <= xmax) {
+            out.push_back(m_values[i]);
             if (hasErrorSigmas())
-                errout[iout] = m_errSigmas[i];
-            ++iout;
+                errout.push_back(m_errSigmas[i]);
         }
     }
-    return new Datafield(frame().clone(), out, errout);
+    Frame* outframe = frame().clone();
+    outframe->setScale(0, xclipped);
+    ASSERT(outframe->xAxis().size() == out.size());
+    return new Datafield(outframe, out, errout);
 }
 
 #ifdef BORNAGAIN_PYTHON