diff --git a/Device/Detector/IDetector.cpp b/Device/Detector/IDetector.cpp
index 34d69468936503bc7444b3ae6e9bfdad7b8e4467..3a29471ddc337fb9bf61f91eb759e9648710107b 100644
--- a/Device/Detector/IDetector.cpp
+++ b/Device/Detector/IDetector.cpp
@@ -18,8 +18,8 @@
 #include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Detector/SimulationAreaIterator.h"
-#include "Device/Mask/DetectorMask.h"
 #include "Device/Mask/InfinitePlane.h"
+#include "Device/Mask/MaskStack.h"
 #include "Device/Resolution/ConvolutionDetectorResolution.h"
 #include <iostream>
 
@@ -77,7 +77,7 @@ IDetector::IDetector(const IDetector& other)
     , m_frame(other.m_frame->clone())
     , m_polAnalyzer(other.m_polAnalyzer)
     , m_resolution(other.m_resolution ? other.m_resolution->clone() : nullptr)
-    , m_mask(std::make_unique<DetectorMask>(*other.m_mask))
+    , m_mask(std::make_unique<MaskStack>(*other.m_mask))
 {
 }
 
@@ -87,7 +87,12 @@ void IDetector::setFrame(Frame* frame)
 {
     ASSERT(frame->rank() == 2);
     m_frame.reset(frame);
-    m_mask.reset(new DetectorMask(m_frame->axis(0), m_frame->axis(1)));
+    m_mask.reset(new MaskStack());
+}
+
+const Frame& IDetector::frame() const
+{
+    return *m_frame;
 }
 
 const Scale& IDetector::axis(size_t i) const
@@ -243,7 +248,7 @@ void IDetector::maskAll()
     addMask(InfinitePlane(), true);
 }
 
-const DetectorMask* IDetector::detectorMask() const
+const MaskStack* IDetector::detectorMask() const
 {
     return m_mask.get();
 }
diff --git a/Device/Detector/IDetector.h b/Device/Detector/IDetector.h
index 0b300bd67aa6d8f95b5747b7ed6c819474208ee4..24ac59492f6f18e7cc9140c8784b1ea56bc2e0dd 100644
--- a/Device/Detector/IDetector.h
+++ b/Device/Detector/IDetector.h
@@ -21,7 +21,7 @@
 
 class Beam;
 class Datafield;
-class DetectorMask;
+class MaskStack;
 class Frame;
 class IDetectorResolution;
 class IPixel;
@@ -65,7 +65,8 @@ public:
 
     std::vector<const INode*> nodeChildren() const override;
 
-    const DetectorMask* detectorMask() const;
+    const Frame& frame() const;
+    const MaskStack* detectorMask() const;
 
     //! Adds mask of given shape to the stack of detector masks. The mask value 'true' means
     //! that the channel will be excluded from the simulation. The mask which is added last
@@ -161,7 +162,7 @@ private:
     std::unique_ptr<Frame> m_frame;
     PolFilter m_polAnalyzer;
     std::unique_ptr<IDetectorResolution> m_resolution;
-    std::unique_ptr<DetectorMask> m_mask;
+    std::unique_ptr<MaskStack> m_mask;
 #endif // SWIG
 };
 
diff --git a/Device/Detector/SimulationAreaIterator.cpp b/Device/Detector/SimulationAreaIterator.cpp
index 513283a47f03ac8ef487db89e606356fb8d679e6..45554bc1bc50d6b974a26ecdfefd6d04fc105d88 100644
--- a/Device/Detector/SimulationAreaIterator.cpp
+++ b/Device/Detector/SimulationAreaIterator.cpp
@@ -15,7 +15,7 @@
 #include "Device/Detector/SimulationAreaIterator.h"
 #include "Base/Util/Assert.h"
 #include "Device/Detector/IDetector.h"
-#include "Device/Mask/DetectorMask.h"
+#include "Device/Mask/MaskStack.h"
 
 SimulationAreaIterator::SimulationAreaIterator(const IDetector* detector, size_t start_at_index)
     : m_detector(detector)
@@ -49,10 +49,7 @@ size_t SimulationAreaIterator::detectorIndex() const
 
 SimulationAreaIterator& SimulationAreaIterator::operator++()
 {
-    size_t index = nextIndex(m_index);
-    if (index != m_index)
-        m_index = index;
-
+    m_index = nextIndex(m_index);
     return *this;
 }
 
@@ -77,7 +74,7 @@ bool SimulationAreaIterator::isMasked(size_t index) const
 {
     const auto* masks = m_detector->detectorMask();
     const auto detectorIndex = m_detector->regionOfInterestIndexToDetectorIndex(index);
-    return masks && masks->isMasked(detectorIndex);
+    return masks && masks->isMasked(detectorIndex, m_detector->frame());
 }
 
 bool SimulationAreaIterator::operator==(const SimulationAreaIterator& other) const
@@ -85,8 +82,3 @@ bool SimulationAreaIterator::operator==(const SimulationAreaIterator& other) con
     ASSERT(m_detector == other.m_detector);
     return m_index == other.m_index;
 }
-
-bool SimulationAreaIterator::operator!=(const SimulationAreaIterator& right) const
-{
-    return !(*this == right);
-}
diff --git a/Device/Detector/SimulationAreaIterator.h b/Device/Detector/SimulationAreaIterator.h
index 1cd0deb3d267ee82f7dcce8d8f0e34fdfd327606..92c08afe96bb10bc685abbeda7412aae91ebec21 100644
--- a/Device/Detector/SimulationAreaIterator.h
+++ b/Device/Detector/SimulationAreaIterator.h
@@ -36,10 +36,9 @@ public:
     size_t detectorIndex() const;
 
     bool operator==(const SimulationAreaIterator& other) const;
-    bool operator!=(const SimulationAreaIterator& right) const;
+    bool operator!=(const SimulationAreaIterator& other) const { return !operator==(other); }
 
-    //! prefix increment
-    SimulationAreaIterator& operator++();
+    SimulationAreaIterator& operator++(); //!< prefix increment
 
 private:
     explicit SimulationAreaIterator(const IDetector* detector, size_t start_at_index);
diff --git a/Device/Mask/DetectorMask.cpp b/Device/Mask/DetectorMask.cpp
deleted file mode 100644
index 63cd1f77cbfbfedc3eb3c06a785dcbf720d47882..0000000000000000000000000000000000000000
--- a/Device/Mask/DetectorMask.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      Device/Mask/DetectorMask.cpp
-//! @brief     Implements class DetectorMask.
-//!
-//! @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 "Device/Mask/DetectorMask.h"
-#include "Base/Axis/Scale.h"
-#include "Device/Data/Datafield.h"
-#include "Device/Mask/IShape2D.h"
-
-MaskPattern::MaskPattern(IShape2D* shape_, bool doMask_)
-    : shape(shape_)
-    , doMask(doMask_)
-{
-}
-MaskPattern::~MaskPattern()
-{
-    delete shape;
-}
-MaskPattern* MaskPattern::clone() const
-{
-    return new MaskPattern(shape->clone(), doMask);
-}
-
-DetectorMask::DetectorMask(const Scale& xAxis, const Scale& yAxis)
-    : m_xAxis(xAxis.clone())
-    , m_yAxis(yAxis.clone())
-    , m_masked(xAxis.size() * yAxis.size(), false)
-{
-}
-
-DetectorMask::~DetectorMask() = default;
-
-DetectorMask::DetectorMask(const DetectorMask& other)
-    : m_xAxis(other.m_xAxis->clone())
-    , m_yAxis(other.m_yAxis->clone())
-    , m_stack(other.m_stack)
-    , m_masked(other.m_masked)
-{
-}
-
-void DetectorMask::addMask(const IShape2D& shape, bool mask_value)
-{
-    m_stack.emplace_back(new MaskPattern(shape.clone(), mask_value));
-    process_masks();
-}
-
-bool DetectorMask::isMasked(size_t i_flat) const
-{
-    return m_masked[i_flat];
-}
-
-bool DetectorMask::hasMasks() const
-{
-    return !m_stack.empty();
-}
-
-size_t DetectorMask::numberOfMasks() const
-{
-    return m_stack.size();
-}
-
-const MaskPattern* DetectorMask::patternAt(size_t iMask) const
-{
-    return m_stack.at(iMask);
-}
-
-void DetectorMask::process_masks()
-{
-    m_masked.clear();
-    m_masked.resize(m_xAxis->size() * m_yAxis->size(), false);
-
-    if (m_stack.empty())
-        return;
-
-    for (size_t i_flat = 0; i_flat < m_masked.size(); ++i_flat) {
-        Bin1D binx = m_xAxis->bin(i_flat % m_xAxis->size());
-        Bin1D biny = m_yAxis->bin(i_flat / m_xAxis->size());
-        // setting mask to the data starting from last shape added
-        for (int k = m_stack.size() - 1; k >= 0; --k) {
-            const MaskPattern* const pat = m_stack[k];
-            if (pat->shape->contains(binx, biny)) {
-                m_masked[i_flat] = pat->doMask;
-                break; // i_flat is covered by the shape, stop looking further
-            }
-        }
-    }
-}
diff --git a/Device/Mask/MaskStack.cpp b/Device/Mask/MaskStack.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bcd743188e7657e75bce54ceeee48bf04bd6df3d
--- /dev/null
+++ b/Device/Mask/MaskStack.cpp
@@ -0,0 +1,67 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      Device/Mask/MaskStack.cpp
+//! @brief     Implements class MaskStack.
+//!
+//! @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 "Device/Mask/MaskStack.h"
+#include "Base/Axis/Frame.h"
+#include "Base/Axis/Scale.h"
+#include "Device/Data/Datafield.h"
+#include "Device/Mask/IShape2D.h"
+
+MaskPattern::MaskPattern(IShape2D* shape_, bool doMask_)
+    : shape(shape_)
+    , doMask(doMask_)
+{
+}
+MaskPattern::~MaskPattern()
+{
+    delete shape;
+}
+MaskPattern* MaskPattern::clone() const
+{
+    return new MaskPattern(shape->clone(), doMask);
+}
+
+void MaskStack::addMask(const IShape2D& shape, bool mask_value)
+{
+    m_stack.emplace_back(new MaskPattern(shape.clone(), mask_value));
+}
+
+bool MaskStack::isMasked(size_t i_flat, const Frame& frame) const
+{
+    size_t nx = frame.projectedSize(0);
+    Bin1D binx = frame.xAxis().bin(i_flat % nx);
+    Bin1D biny = frame.yAxis().bin(i_flat / nx);
+
+    for (int k = m_stack.size() - 1; k >= 0; --k) {
+        const MaskPattern* const pat = m_stack[k];
+        if (pat->shape->contains(binx, biny))
+            return pat->doMask;
+    }
+    return false;
+}
+
+bool MaskStack::hasMasks() const
+{
+    return !m_stack.empty();
+}
+
+size_t MaskStack::numberOfMasks() const
+{
+    return m_stack.size();
+}
+
+const MaskPattern* MaskStack::patternAt(size_t iMask) const
+{
+    return m_stack.at(iMask);
+}
diff --git a/Device/Mask/DetectorMask.h b/Device/Mask/MaskStack.h
similarity index 68%
rename from Device/Mask/DetectorMask.h
rename to Device/Mask/MaskStack.h
index d4328a76d2cedfb7828408a7d77e232e6faf1653..89d7057b5d0cf5b863472cda7cdd07fbfcf8b972 100644
--- a/Device/Mask/DetectorMask.h
+++ b/Device/Mask/MaskStack.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit reflection and scattering
 //
-//! @file      Device/Mask/DetectorMask.h
-//! @brief     Defines class DetectorMask.
+//! @file      Device/Mask/MaskStack.h
+//! @brief     Defines class MaskStack.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -15,16 +15,14 @@
 #ifdef SWIG
 #error no need to expose this header to Swig
 #endif
-#ifndef BORNAGAIN_DEVICE_MASK_DETECTORMASK_H
-#define BORNAGAIN_DEVICE_MASK_DETECTORMASK_H
-
-#include <memory>
+#ifndef BORNAGAIN_DEVICE_MASK_MASKSTACK_H
+#define BORNAGAIN_DEVICE_MASK_MASKSTACK_H
 
 #include "Base/Types/CloneableVector.h"
+#include <memory>
 
-class Datafield;
 class IShape2D;
-class Scale;
+class Frame;
 
 class MaskPattern {
 public:
@@ -38,17 +36,13 @@ public:
 
 //! Collection of detector masks.
 
-class DetectorMask {
+class MaskStack {
 public:
-    DetectorMask(const Scale& xAxis, const Scale& yAxis);
-    ~DetectorMask();
-    DetectorMask(const DetectorMask& other);
-
     //! Add mask to the stack of detector masks.
     //! Argument mask_value=true means that the area will be excluded from the analysis.
     void addMask(const IShape2D& shape, bool mask_value);
 
-    bool isMasked(size_t i_flat) const;
+    bool isMasked(size_t i_flat, const Frame& frame) const;
 
     //! Returns true if has masks
     bool hasMasks() const;
@@ -58,15 +52,7 @@ public:
     const MaskPattern* patternAt(size_t iMask) const;
 
 private:
-    void process_masks();
-
-    //... primary data:
-    const Scale* m_xAxis;
-    const Scale* m_yAxis;
     CloneableVector<MaskPattern> m_stack;
-
-    //... cached secondary data:
-    std::vector<bool> m_masked;
 };
 
-#endif // BORNAGAIN_DEVICE_MASK_DETECTORMASK_H
+#endif // BORNAGAIN_DEVICE_MASK_MASKSTACK_H
diff --git a/GUI/Model/Data/MaskResultsPresenter.cpp b/GUI/Model/Data/MaskResultsPresenter.cpp
index 73fb5359161f7c7974d66eaaac0a355a1d43c6db..0e3d7b545b8d2e7b453f6cf99bcc7b6e99c916fe 100644
--- a/GUI/Model/Data/MaskResultsPresenter.cpp
+++ b/GUI/Model/Data/MaskResultsPresenter.cpp
@@ -14,8 +14,8 @@
 
 #include "GUI/Model/Data/MaskResultsPresenter.h"
 #include "Device/Data/Datafield.h"
-#include "Device/Mask/DetectorMask.h"
 #include "Device/Mask/IShape2D.h"
+#include "Device/Mask/MaskStack.h"
 #include "GUI/Model/Data/Data2DItem.h"
 #include "GUI/Model/Mask/MaskItems.h"
 #include <QVBoxLayout>
@@ -82,7 +82,7 @@ Datafield* MaskResultsPresenter::createMaskPresentation() const
     // Requesting mask information
     std::unique_ptr<IShape2D> roi;
     Datafield* result = m_data2DItem->c_field()->clone();
-    DetectorMask detectorMask(result->axis(0), result->axis(1));
+    MaskStack detectorMask;
     const double scale = 1.0;
     const QVector<MaskItem*> maskItems = m_data2DItem->maskContainerItem()->maskItems();
     for (auto maskIter = maskItems.rbegin(); maskIter != maskItems.rend(); maskIter++)
@@ -103,7 +103,7 @@ Datafield* MaskResultsPresenter::createMaskPresentation() const
         return nullptr;
 
     for (size_t i = 0; i < result->size(); ++i)
-        if (detectorMask.isMasked(i))
+        if (detectorMask.isMasked(i, result->frame()))
             (*result)[i] = 0.0;
 
     return result;
diff --git a/GUI/Model/FromCore/ItemizeSimulation.cpp b/GUI/Model/FromCore/ItemizeSimulation.cpp
index b1a55c4ba14a0d28707eaf50c9b312b164493d4c..71c43b48137ac0c37a7a9a5821b8f739eae2166b 100644
--- a/GUI/Model/FromCore/ItemizeSimulation.cpp
+++ b/GUI/Model/FromCore/ItemizeSimulation.cpp
@@ -17,10 +17,10 @@
 #include "Base/Const/Units.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Detector/OffspecDetector.h"
-#include "Device/Mask/DetectorMask.h"
 #include "Device/Mask/Ellipse.h"
 #include "Device/Mask/InfinitePlane.h"
 #include "Device/Mask/Line.h"
+#include "Device/Mask/MaskStack.h"
 #include "Device/Mask/Polygon.h"
 #include "Device/Mask/Rectangle.h"
 #include "Device/Resolution/ConvolutionDetectorResolution.h"
@@ -132,7 +132,7 @@ void setMaskContainer(MaskContainerItem* destMaskItems, const IDetector& detecto
     }
 }
 
-void setDetectorMasks(DetectorItem* detector_item, const IDetector& detector)
+void setMaskStacks(DetectorItem* detector_item, const IDetector& detector)
 {
     if ((detector.detectorMask() && detector.detectorMask()->hasMasks())
         || detector.hasExplicitRegionOfInterest()) {
@@ -271,7 +271,7 @@ void updateDetector(GISASInstrumentItem* instrument_item, const FlatDetector& de
     auto* detector_item = instrument_item->detectorItem();
 
     setDetectorResolution(detector_item, detector);
-    setDetectorMasks(detector_item, detector);
+    setMaskStacks(detector_item, detector);
     setPolarizer2(instrument_item, detector.analyzer());
 }
 
diff --git a/Sim/Export/SimulationToPython.cpp b/Sim/Export/SimulationToPython.cpp
index d770db8995d7d7c5f0bd6667868f40008a6f7d57..2b28ba95c698a90ca34d97e96573f6bac4f5b188 100644
--- a/Sim/Export/SimulationToPython.cpp
+++ b/Sim/Export/SimulationToPython.cpp
@@ -22,7 +22,7 @@
 #include "Device/Detector/FlatDetector.h"
 #include "Device/Detector/OffspecDetector.h"
 #include "Device/Detector/SphericalDetector.h"
-#include "Device/Mask/DetectorMask.h"
+#include "Device/Mask/MaskStack.h"
 #include "Device/Resolution/ConvolutionDetectorResolution.h"
 #include "Device/Resolution/ResolutionFunction2DGaussian.h"
 #include "Param/Distrib/Distributions.h"
@@ -175,7 +175,7 @@ std::string defineDetector(const IDetector& detector)
     }
 
     //... Mask
-    const DetectorMask* detectorMask = detector.detectorMask();
+    const MaskStack* detectorMask = detector.detectorMask();
     if (detectorMask && detectorMask->hasMasks()) {
         result << "\n";
         for (size_t i_mask = 0; i_mask < detectorMask->numberOfMasks(); ++i_mask) {
diff --git a/Tests/Unit/Device/SimulationAreaTest.cpp b/Tests/Unit/Device/SimulationAreaTest.cpp
deleted file mode 100644
index 4bef02e1987fb9c26e156e02249caf97e805db58..0000000000000000000000000000000000000000
--- a/Tests/Unit/Device/SimulationAreaTest.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "Device/Detector/SimulationAreaIterator.h"
-#include "Device/Detector/SphericalDetector.h"
-#include "Device/Mask/Rectangle.h"
-#include "Tests/GTestWrapper/google_test.h"
-#include <iostream>
-#include <memory>
-
-//! Iteration over non-masked detector
-
-TEST(SimulationAreaTest, plain)
-{
-    SphericalDetector detector(4, -1.0, 3.0, 2, 0.0, 2.0);
-
-    std::vector<size_t> expectedIndexes = {0, 1, 2, 3, 4, 5, 6, 7};
-
-    std::vector<size_t> indexes;
-    std::vector<size_t> detectorIndexes;
-    detector.iterateOverNonMaskedPoints([&](const auto it) {
-        indexes.push_back(it.roiIndex());
-        detectorIndexes.push_back(it.detectorIndex());
-    });
-    EXPECT_EQ(indexes, expectedIndexes);
-    EXPECT_EQ(detectorIndexes, expectedIndexes);
-}
-
-//! Iteration over masked detector
-
-TEST(SimulationAreaTest, masked)
-{
-    SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0);
-    detector.addMask(Rectangle(0.1, 1.1, 2.9, 2.9), true);
-    detector.addMask(Rectangle(3.1, 3.1, 3.9, 3.9), true);
-
-    std::vector<size_t> expectedIndexes = {0, 1, 2, 3, 4, 5, 9, 10, 14, 15, 16, 17, 18};
-    std::vector<size_t> indexes;
-    detector.iterateOverNonMaskedPoints([&](const auto it) { indexes.push_back(it.roiIndex()); });
-    EXPECT_EQ(indexes, expectedIndexes);
-}
-
-//! Iteration over the detector with first and last bin masked
-
-TEST(SimulationAreaTest, maskedCorners)
-{
-    SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0);
-    detector.addMask(Rectangle(-0.9, 0.1, -0.1, 0.9), true);
-    detector.addMask(Rectangle(3.1, 3.1, 3.9, 3.9), true);
-
-    std::vector<size_t> expectedIndexes = {1,  2,  3,  4,  5,  6,  7,  8,  9,
-                                           10, 11, 12, 13, 14, 15, 16, 17, 18};
-    std::vector<size_t> indexes;
-    detector.iterateOverNonMaskedPoints([&](const auto it) { indexes.push_back(it.roiIndex()); });
-    EXPECT_EQ(indexes, expectedIndexes);
-}
-
-//! Iteration when whole detector is masked
-
-TEST(SimulationAreaTest, maskedAll)
-{
-    SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0);
-    detector.addMask(Rectangle(-0.9, 0.1, 3.9, 3.9), true);
-
-    std::vector<size_t> indexes;
-
-    detector.iterateOverNonMaskedPoints([&](const auto it) { indexes.push_back(it.roiIndex()); });
-
-    EXPECT_EQ(indexes.size(), 0);
-}
-
-//! Iteration when RegionOfInterest and masks are present
-
-TEST(SimulationAreaTest, maskAndRoi)
-{
-    SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0);
-    detector.setRegionOfInterest(0.1, 1.1, 2.9, 3.9);
-    detector.addMask(Rectangle(-0.9, 0.1, 0.9, 1.9), true);
-
-    std::vector<size_t> detectorIndexes;
-    std::vector<size_t> roiIndexes;
-    detector.iterateOverNonMaskedPoints([&](const auto it) {
-        detectorIndexes.push_back(it.detectorIndex());
-        roiIndexes.push_back(it.roiIndex());
-    });
-    EXPECT_EQ(detectorIndexes, std::vector<size_t>({7, 8, 11, 12, 13, 16, 17, 18}));
-    EXPECT_EQ(roiIndexes, std::vector<size_t>({1, 2, 3, 4, 5, 6, 7, 8}));
-}
diff --git a/Tests/Unit/Device/SphericalDetectorTest.cpp b/Tests/Unit/Device/SphericalDetectorTest.cpp
index 0975097892a811fb6a9b86189352ef439185f78d..4c4eb0e6fba5fc64fd3da7e2898577033487b6d4 100644
--- a/Tests/Unit/Device/SphericalDetectorTest.cpp
+++ b/Tests/Unit/Device/SphericalDetectorTest.cpp
@@ -5,7 +5,7 @@
 #include "Base/Const/Units.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Detector/SimulationAreaIterator.h"
-#include "Device/Mask/DetectorMask.h"
+#include "Device/Mask/MaskStack.h"
 #include "Device/Mask/Polygon.h"
 #include "Device/Mask/Rectangle.h"
 #include "Device/Resolution/ConvolutionDetectorResolution.h"
diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index d7435172631f2b3df639dec94b12761de12b632d..6ef9ecab66279bee5aa530d2356d4a05f0672de0 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -2678,8 +2678,12 @@ class IDetector(libBornAgainBase.ICloneable, libBornAgainParam.INode):
         r"""nodeChildren(IDetector self) -> std::vector< INode const *,std::allocator< INode const * > >"""
         return _libBornAgainDevice.IDetector_nodeChildren(self)
 
+    def frame(self):
+        r"""frame(IDetector self) -> Frame"""
+        return _libBornAgainDevice.IDetector_frame(self)
+
     def detectorMask(self):
-        r"""detectorMask(IDetector self) -> DetectorMask const *"""
+        r"""detectorMask(IDetector self) -> MaskStack const *"""
         return _libBornAgainDevice.IDetector_detectorMask(self)
 
     def addMask(self, shape, mask_value=True):
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index aad1e3c5ee91e44d9606207b4e695656c526cbc3..58e7d684b1d3e1b8921516421c7d5cdbad66272d 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -3390,23 +3390,23 @@ namespace Swig {
 #define SWIGTYPE_p_Bin1D swig_types[1]
 #define SWIGTYPE_p_Coordinate swig_types[2]
 #define SWIGTYPE_p_Datafield swig_types[3]
-#define SWIGTYPE_p_DetectorMask swig_types[4]
-#define SWIGTYPE_p_Ellipse swig_types[5]
-#define SWIGTYPE_p_FlatDetector swig_types[6]
-#define SWIGTYPE_p_FootprintGauss swig_types[7]
-#define SWIGTYPE_p_FootprintSquare swig_types[8]
-#define SWIGTYPE_p_Frame swig_types[9]
-#define SWIGTYPE_p_HorizontalLine swig_types[10]
-#define SWIGTYPE_p_ICloneable swig_types[11]
-#define SWIGTYPE_p_IDetector swig_types[12]
-#define SWIGTYPE_p_IDetectorResolution swig_types[13]
-#define SWIGTYPE_p_IFootprint swig_types[14]
-#define SWIGTYPE_p_INode swig_types[15]
-#define SWIGTYPE_p_IPixel swig_types[16]
-#define SWIGTYPE_p_IResolutionFunction2D swig_types[17]
-#define SWIGTYPE_p_IShape2D swig_types[18]
-#define SWIGTYPE_p_ImportSettings1D swig_types[19]
-#define SWIGTYPE_p_Line swig_types[20]
+#define SWIGTYPE_p_Ellipse swig_types[4]
+#define SWIGTYPE_p_FlatDetector swig_types[5]
+#define SWIGTYPE_p_FootprintGauss swig_types[6]
+#define SWIGTYPE_p_FootprintSquare swig_types[7]
+#define SWIGTYPE_p_Frame swig_types[8]
+#define SWIGTYPE_p_HorizontalLine swig_types[9]
+#define SWIGTYPE_p_ICloneable swig_types[10]
+#define SWIGTYPE_p_IDetector swig_types[11]
+#define SWIGTYPE_p_IDetectorResolution swig_types[12]
+#define SWIGTYPE_p_IFootprint swig_types[13]
+#define SWIGTYPE_p_INode swig_types[14]
+#define SWIGTYPE_p_IPixel swig_types[15]
+#define SWIGTYPE_p_IResolutionFunction2D swig_types[16]
+#define SWIGTYPE_p_IShape2D swig_types[17]
+#define SWIGTYPE_p_ImportSettings1D swig_types[18]
+#define SWIGTYPE_p_Line swig_types[19]
+#define SWIGTYPE_p_MaskStack swig_types[20]
 #define SWIGTYPE_p_OffspecDetector swig_types[21]
 #define SWIGTYPE_p_PolFilter swig_types[22]
 #define SWIGTYPE_p_Polygon swig_types[23]
@@ -35979,13 +35979,46 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IDetector_frame(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  IDetector *arg1 = (IDetector *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  Frame *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IDetector, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector_frame" "', argument " "1"" of type '" "IDetector const *""'"); 
+  }
+  arg1 = reinterpret_cast< IDetector * >(argp1);
+  {
+    try {
+      result = (Frame *) &((IDetector const *)arg1)->frame();
+    } catch (const std::exception& ex) {
+      // message shown in the Python interpreter
+      const std::string msg {
+        "BornAgain C++ Exception: " + std::string(ex.what())
+      };
+      SWIG_exception(SWIG_RuntimeError, msg.c_str());
+    }
+  }
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Frame, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_IDetector_detectorMask(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IDetector *arg1 = (IDetector *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  DetectorMask *result = 0 ;
+  MaskStack *result = 0 ;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
@@ -35996,7 +36029,7 @@ SWIGINTERN PyObject *_wrap_IDetector_detectorMask(PyObject *self, PyObject *args
   arg1 = reinterpret_cast< IDetector * >(argp1);
   {
     try {
-      result = (DetectorMask *)((IDetector const *)arg1)->detectorMask();
+      result = (MaskStack *)((IDetector const *)arg1)->detectorMask();
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -36005,7 +36038,7 @@ SWIGINTERN PyObject *_wrap_IDetector_detectorMask(PyObject *self, PyObject *args
       SWIG_exception(SWIG_RuntimeError, msg.c_str());
     }
   }
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DetectorMask, 0 |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_MaskStack, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -43690,7 +43723,8 @@ static PyMethodDef SwigMethods[] = {
 	 { "IDetector_setDetectorResolution", _wrap_IDetector_setDetectorResolution, METH_VARARGS, "IDetector_setDetectorResolution(IDetector self, IDetectorResolution detector_resolution)"},
 	 { "IDetector_setResolutionFunction", _wrap_IDetector_setResolutionFunction, METH_VARARGS, "IDetector_setResolutionFunction(IDetector self, IResolutionFunction2D resFunc)"},
 	 { "IDetector_nodeChildren", _wrap_IDetector_nodeChildren, METH_O, "IDetector_nodeChildren(IDetector self) -> std::vector< INode const *,std::allocator< INode const * > >"},
-	 { "IDetector_detectorMask", _wrap_IDetector_detectorMask, METH_O, "IDetector_detectorMask(IDetector self) -> DetectorMask const *"},
+	 { "IDetector_frame", _wrap_IDetector_frame, METH_O, "IDetector_frame(IDetector self) -> Frame"},
+	 { "IDetector_detectorMask", _wrap_IDetector_detectorMask, METH_O, "IDetector_detectorMask(IDetector self) -> MaskStack const *"},
 	 { "IDetector_addMask", _wrap_IDetector_addMask, METH_VARARGS, "IDetector_addMask(IDetector self, IShape2D shape, bool mask_value=True)"},
 	 { "IDetector_maskAll", _wrap_IDetector_maskAll, METH_O, "IDetector_maskAll(IDetector self)"},
 	 { "IDetector_axis", _wrap_IDetector_axis, METH_VARARGS, "IDetector_axis(IDetector self, size_t i) -> Scale"},
@@ -43922,7 +43956,6 @@ static swig_type_info _swigt__p_Beam = {"_p_Beam", "Beam *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Bin1D = {"_p_Bin1D", "Bin1D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Coordinate = {"_p_Coordinate", "Coordinate *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Datafield = {"_p_Datafield", "Datafield *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_DetectorMask = {"_p_DetectorMask", "DetectorMask *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Ellipse = {"_p_Ellipse", "Ellipse *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FlatDetector = {"_p_FlatDetector", "FlatDetector *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FootprintGauss = {"_p_FootprintGauss", "FootprintGauss *", 0, 0, (void*)0, 0};
@@ -43939,6 +43972,7 @@ static swig_type_info _swigt__p_IResolutionFunction2D = {"_p_IResolutionFunction
 static swig_type_info _swigt__p_IShape2D = {"_p_IShape2D", "IShape2D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ImportSettings1D = {"_p_ImportSettings1D", "ImportSettings1D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Line = {"_p_Line", "Line *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_MaskStack = {"_p_MaskStack", "MaskStack *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_OffspecDetector = {"_p_OffspecDetector", "OffspecDetector *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_PolFilter = {"_p_PolFilter", "PolFilter *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Polygon = {"_p_Polygon", "Polygon *", 0, 0, (void*)0, 0};
@@ -44010,7 +44044,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_Bin1D,
   &_swigt__p_Coordinate,
   &_swigt__p_Datafield,
-  &_swigt__p_DetectorMask,
   &_swigt__p_Ellipse,
   &_swigt__p_FlatDetector,
   &_swigt__p_FootprintGauss,
@@ -44027,6 +44060,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IShape2D,
   &_swigt__p_ImportSettings1D,
   &_swigt__p_Line,
+  &_swigt__p_MaskStack,
   &_swigt__p_OffspecDetector,
   &_swigt__p_PolFilter,
   &_swigt__p_Polygon,
@@ -44098,7 +44132,6 @@ static swig_cast_info _swigc__p_Beam[] = {  {&_swigt__p_Beam, 0, 0, 0},{0, 0, 0,
 static swig_cast_info _swigc__p_Bin1D[] = {  {&_swigt__p_Bin1D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Coordinate[] = {  {&_swigt__p_Coordinate, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Datafield[] = {  {&_swigt__p_Datafield, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_DetectorMask[] = {  {&_swigt__p_DetectorMask, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Ellipse[] = {  {&_swigt__p_Ellipse, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FlatDetector[] = {  {&_swigt__p_FlatDetector, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FootprintGauss[] = {  {&_swigt__p_FootprintGauss, 0, 0, 0},{0, 0, 0, 0}};
@@ -44115,6 +44148,7 @@ static swig_cast_info _swigc__p_IResolutionFunction2D[] = {  {&_swigt__p_IResolu
 static swig_cast_info _swigc__p_IShape2D[] = {  {&_swigt__p_IShape2D, 0, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_IShape2D, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_IShape2D, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_IShape2D, 0, 0},  {&_swigt__p_Polygon, _p_PolygonTo_p_IShape2D, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_IShape2D, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_IShape2D, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ImportSettings1D[] = {  {&_swigt__p_ImportSettings1D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Line[] = {  {&_swigt__p_Line, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_MaskStack[] = {  {&_swigt__p_MaskStack, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_OffspecDetector[] = {  {&_swigt__p_OffspecDetector, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_PolFilter[] = {  {&_swigt__p_PolFilter, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Polygon[] = {  {&_swigt__p_Polygon, 0, 0, 0},{0, 0, 0, 0}};
@@ -44186,7 +44220,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_Bin1D,
   _swigc__p_Coordinate,
   _swigc__p_Datafield,
-  _swigc__p_DetectorMask,
   _swigc__p_Ellipse,
   _swigc__p_FlatDetector,
   _swigc__p_FootprintGauss,
@@ -44203,6 +44236,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IShape2D,
   _swigc__p_ImportSettings1D,
   _swigc__p_Line,
+  _swigc__p_MaskStack,
   _swigc__p_OffspecDetector,
   _swigc__p_PolFilter,
   _swigc__p_Polygon,