diff --git a/Base/Vector/Direction.h b/Base/Vector/Direction.h
index f74b6295ce9727f94d0e115b6c643e504d26996b..e7bf7959242e97251326c06285d2865ac76adac7 100644
--- a/Base/Vector/Direction.h
+++ b/Base/Vector/Direction.h
@@ -32,6 +32,8 @@ public:
     //! Returns Cartesian 3D vector
     kvector_t vector() const;
 
+    Direction zReflected() const { return {-m_alpha, m_phi}; }
+
 private:
     double m_alpha;
     double m_phi;
diff --git a/Core/Simulation/ISimulation.cpp b/Core/Simulation/ISimulation.cpp
index 643b50b9e2c1995f6b5c92a531ff5f264fafca37..7dd372723bc4cc9f1b38a661f619f68ce44d2d59 100644
--- a/Core/Simulation/ISimulation.cpp
+++ b/Core/Simulation/ISimulation.cpp
@@ -44,7 +44,7 @@ size_t getStartIndex(size_t n_handlers, size_t current_handler, size_t n_element
     return start_index;
 }
 
-size_t getNumberOfElements(size_t n_handlers, size_t current_handler, size_t n_elements)
+size_t batchSize(size_t n_handlers, size_t current_handler, size_t n_elements)
 {
     const size_t handler_size = getIndexStep(n_elements, static_cast<size_t>(n_handlers));
     const size_t start_index = current_handler * handler_size;
@@ -173,7 +173,7 @@ void ISimulation::runSimulation()
     const size_t current_batch = m_options.getCurrentBatch();
 
     const size_t batch_start = getStartIndex(n_batches, current_batch, total_size);
-    const size_t batch_size = getNumberOfElements(n_batches, current_batch, total_size);
+    const size_t batch_size = batchSize(n_batches, current_batch, total_size);
     if (batch_size == 0)
         return;
 
@@ -300,7 +300,7 @@ void ISimulation::runSingleSimulation(const ProcessedSample& re_sample, size_t b
     for (size_t i_thread = 0; i_thread < n_threads; ++i_thread) {
 
         const size_t thread_start = batch_start + getStartIndex(n_threads, i_thread, batch_size);
-        const size_t thread_size = getNumberOfElements(n_threads, i_thread, batch_size);
+        const size_t thread_size = batchSize(n_threads, i_thread, batch_size);
         if (thread_size == 0)
             break;
         computations.emplace_back(createComputation(re_sample, thread_start, thread_size));
diff --git a/Device/Beam/Beam.cpp b/Device/Beam/Beam.cpp
index c3bc776403abb75eb691fb6474e0cf9ba1897b00..3677a927a63033e4abacb3c9203f43c6c07d5bcb 100644
--- a/Device/Beam/Beam.cpp
+++ b/Device/Beam/Beam.cpp
@@ -83,17 +83,11 @@ Beam* Beam::clone() const
     return new Beam(*this);
 }
 
-
-kvector_t Beam::getCentralK() const
-{
-    return M_TWOPI / m_wavelength * Direction(-direction().alpha(), direction().phi()).vector();
-}
-
 void Beam::setWavelength(double wavelength)
 {
     if (wavelength <= 0.0)
         throw std::runtime_error(
-            "Beam::setCentralK() -> Error. Wavelength can't be negative or zero.");
+            "Invalid beam parameter: Wavelength can't be negative or zero.");
     m_wavelength = wavelength;
 }
 
@@ -101,7 +95,7 @@ void Beam::setDirection(const Direction& direction)
 {
     if (direction.alpha() < 0.0)
         throw std::runtime_error(
-            "Beam::setCentralK() -> Error. Inclination angle alpha_i can't be negative.");
+            "Invalid beam parameter: Inclination angle alpha_i can't be negative.");
     // m_direction = direction;
     m_alpha = direction.alpha();
     m_phi = direction.phi();
diff --git a/Device/Beam/Beam.h b/Device/Beam/Beam.h
index 039b62a9c27b2689e20190af9842c42f145e0129..65cb91cf1e2c55365f52bbad658d5a3eb6114522 100644
--- a/Device/Beam/Beam.h
+++ b/Device/Beam/Beam.h
@@ -46,8 +46,6 @@ public:
     double wavelength() const { return m_wavelength; }
     // Direction& direction() { return m_direction; }
     Direction direction() const { return {m_alpha, m_phi}; } // TODO -> const .. &
-    //! Returns the wavevector
-    kvector_t getCentralK() const;
 
     kvector_t getBlochVector() const;
     //! Returns footprint factor.
diff --git a/Device/Detector/IDetector.h b/Device/Detector/IDetector.h
index a977d904ed72b33eb63982afde77b0b152421636..a9c4be11e490512e76e73d257f00f7707363f02f 100644
--- a/Device/Detector/IDetector.h
+++ b/Device/Detector/IDetector.h
@@ -22,8 +22,8 @@
 #include "Device/Detector/SimulationAreaIterator.h"
 #include "Device/ProDetector/DetectionProperties.h"
 
-class Beam;
 class DetectorMask;
+class Direction;
 class IAxis;
 class IDetectorResolution;
 class IResolutionFunction2D;
@@ -57,7 +57,7 @@ public:
     virtual ~IDetector();
 
     //! Inits detector with the beam settings
-    virtual void init(const Beam&) {}
+    virtual void setDetectorNormal(const Direction&) {} // nontrivial only for RectangularDetector
 
     void addAxis(const IAxis& axis);
 
diff --git a/Device/Detector/RectangularDetector.cpp b/Device/Detector/RectangularDetector.cpp
index d2256b38a19bba3c6eff0076d3d069787b8ccf84..9a37b29972f80e9a616b8ae7eb3288ac1f9f7f82 100644
--- a/Device/Detector/RectangularDetector.cpp
+++ b/Device/Detector/RectangularDetector.cpp
@@ -56,12 +56,10 @@ RectangularDetector* RectangularDetector::clone() const
     return new RectangularDetector(*this);
 }
 
-void RectangularDetector::init(const Beam& beam)
+void RectangularDetector::setDetectorNormal(const Direction& direction)
 {
-    double alpha_i = beam.direction().alpha();
-    kvector_t central_k = beam.getCentralK();
-    initNormalVector(central_k);
-    initUandV(alpha_i);
+    initNormalVector(direction.vector());
+    initUandV(-direction.alpha());
 }
 
 void RectangularDetector::setPosition(const kvector_t normal_to_detector, double u0, double v0,
diff --git a/Device/Detector/RectangularDetector.h b/Device/Detector/RectangularDetector.h
index 9053322c8fbd28a2dfde724b9d9fdf40b2e94ea2..a033577b1be9d3750e208dcdc68f54ae8c08ef5d 100644
--- a/Device/Detector/RectangularDetector.h
+++ b/Device/Detector/RectangularDetector.h
@@ -48,7 +48,7 @@ public:
 
     ~RectangularDetector();
 
-    void init(const Beam& beam) override;
+    void setDetectorNormal(const Direction& direction) override;
 
     void setPosition(const kvector_t normal_to_detector, double u0, double v0,
                      const kvector_t direction = kvector_t(0.0, -1.0, 0.0));
diff --git a/Device/Instrument/Instrument.cpp b/Device/Instrument/Instrument.cpp
index 032fd89fcf73b2d5ffc3248b2b095c4b6ebcdb1a..803ac9fb5169a196bd6e9b3dfdba25c4d29e4a91 100644
--- a/Device/Instrument/Instrument.cpp
+++ b/Device/Instrument/Instrument.cpp
@@ -71,7 +71,7 @@ void Instrument::initDetector()
     if (!m_detector)
         throw std::runtime_error(
             "Instrument::initDetector() -> Error. Detector is not initialized.");
-    m_detector->init(beam());
+    m_detector->setDetectorNormal(beam().direction().zReflected());
 }
 
 std::vector<const INode*> Instrument::getChildren() const
diff --git a/GUI/Models/DomainObjectBuilder.cpp b/GUI/Models/DomainObjectBuilder.cpp
index a06f9bf2710c77404f78b37c74094dccdc3c17b5..7f429a984bb7da87a9b92715c54d7df75d476b9e 100644
--- a/GUI/Models/DomainObjectBuilder.cpp
+++ b/GUI/Models/DomainObjectBuilder.cpp
@@ -82,9 +82,3 @@ GUI::Model::DomainObjectBuilder::buildInterferenceFunction(const SessionItem& it
     ASSERT(iffItem);
     return iffItem->createInterferenceFunction();
 }
-
-std::unique_ptr<Instrument>
-GUI::Model::DomainObjectBuilder::buildInstrument(const InstrumentItem& instrumentItem)
-{
-    return instrumentItem.createInstrument();
-}
diff --git a/GUI/Models/DomainObjectBuilder.h b/GUI/Models/DomainObjectBuilder.h
index c183f9915a4232d52fb645d3c1fa684c7db5b85b..31babfbc873c9ac6b511e45a891e2d56cdd9296b 100644
--- a/GUI/Models/DomainObjectBuilder.h
+++ b/GUI/Models/DomainObjectBuilder.h
@@ -35,7 +35,6 @@ std::unique_ptr<MultiLayer> buildMultiLayer(const MultiLayerItem& multilayer_ite
 std::unique_ptr<Layer> buildLayer(const LayerItem& item);
 std::unique_ptr<ParticleLayout> buildParticleLayout(const ParticleLayoutItem& item);
 std::unique_ptr<IInterferenceFunction> buildInterferenceFunction(const SessionItem& item);
-std::unique_ptr<Instrument> buildInstrument(const InstrumentItem& instrumentItem);
 
 } // namespace GUI::Model::DomainObjectBuilder
 
diff --git a/GUI/Models/DomainSimulationBuilder.cpp b/GUI/Models/DomainSimulationBuilder.cpp
index 68685da3ec7b3de75b9c89ca692fc3f9c758c7fa..dc143500290d95d6ab794500dbb9454611bbcf85 100644
--- a/GUI/Models/DomainSimulationBuilder.cpp
+++ b/GUI/Models/DomainSimulationBuilder.cpp
@@ -42,7 +42,7 @@ std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLaye
                                                        const GISASInstrumentItem* instrumentItem,
                                                        const SimulationOptionsItem* optionsItem)
 {
-    auto instrument = GUI::Model::DomainObjectBuilder::buildInstrument(*instrumentItem);
+    std::unique_ptr<const Instrument> instrument = instrumentItem->createInstrument();
     std::unique_ptr<GISASSimulation> ret{
         new GISASSimulation(instrument->beam(), *multilayer, instrument->detector())};
 
@@ -63,7 +63,7 @@ createOffSpecularSimulation(std::unique_ptr<MultiLayer> multilayer,
                             const OffSpecularInstrumentItem* instrumentItem,
                             const SimulationOptionsItem* optionsItem)
 {
-    auto instrument = GUI::Model::DomainObjectBuilder::buildInstrument(*instrumentItem);
+    std::unique_ptr<const Instrument> instrument = instrumentItem->createInstrument();
     std::unique_ptr<OffSpecularSimulation> ret{
         new OffSpecularSimulation(instrument->beam(), *multilayer, instrument->detector())};
 
diff --git a/GUI/Models/InstrumentItems.cpp b/GUI/Models/InstrumentItems.cpp
index 61cf866e757c31bcbfe20f77cf2d4dbea4c89093..bbfa0b183684e321734d132eea3952b417ee3583 100644
--- a/GUI/Models/InstrumentItems.cpp
+++ b/GUI/Models/InstrumentItems.cpp
@@ -103,14 +103,6 @@ bool InstrumentItem::alignedWith(const RealDataItem* item) const
     return shape() == item->shape();
 }
 
-std::unique_ptr<Instrument> InstrumentItem::createInstrument() const
-{
-    std::unique_ptr<Instrument> result(new Instrument);
-    result->setBeam(*beamItem()->createBeam());
-
-    return result;
-}
-
 InstrumentItem::InstrumentItem(const QString& modelType) : SessionItem(modelType)
 {
     setItemName(modelType);
@@ -199,7 +191,8 @@ bool SpecularInstrumentItem::alignedWith(const RealDataItem* item) const
 
 ICoordSystem* SpecularInstrumentItem::createCoordSystem() const
 {
-    const auto instrument = createInstrument();
+    std::unique_ptr<Instrument> instrument(new Instrument);
+    instrument->setBeam(*beamItem()->createBeam());
     auto axis_item = beamItem()->currentInclinationAxisItem();
     if (auto pointwise_axis = dynamic_cast<PointwiseAxisItem*>(axis_item)) {
         if (!pointwise_axis->containsNonXMLData()) // workaround for loading project
@@ -250,11 +243,6 @@ SpecularBeamItem* DepthProbeInstrumentItem::beamItem() const
     return beam<SpecularBeamItem>();
 }
 
-std::unique_ptr<Instrument> DepthProbeInstrumentItem::createInstrument() const
-{
-    throw std::runtime_error("DepthProbeInstrumentItem::createInstrument()");
-}
-
 std::vector<int> DepthProbeInstrumentItem::shape() const
 {
     return std::vector<int>(); // no certain shape to avoid linking to real data
@@ -344,10 +332,11 @@ void Instrument2DItem::importMasks(const MaskContainerItem* maskContainer)
 
 std::unique_ptr<Instrument> Instrument2DItem::createInstrument() const
 {
-    auto result = InstrumentItem::createInstrument();
-    result->setDetector(*detectorItem()->createDetector());
+    std::unique_ptr<Instrument> instrument(new Instrument);
+    instrument->setBeam(*beamItem()->createBeam());
+    instrument->setDetector(*detectorItem()->createDetector());
 
-    return result;
+    return instrument;
 }
 
 bool Instrument2DItem::isDetectorPropertyName(const QString& name)
diff --git a/GUI/Models/InstrumentItems.h b/GUI/Models/InstrumentItems.h
index 4fd6e456d373a504fc8cf691f877c7d90406d1b7..00c75e882947542bce71277fe16230aea9c1127a 100644
--- a/GUI/Models/InstrumentItems.h
+++ b/GUI/Models/InstrumentItems.h
@@ -47,7 +47,6 @@ public:
     GroupItem* backgroundGroup();
     template <typename T> T* setBackgroundType();
 
-    virtual std::unique_ptr<Instrument> createInstrument() const;
     virtual std::vector<int> shape() const = 0;
     virtual void clearMasks() {}
     virtual void importMasks(const MaskContainerItem*) {}
@@ -98,7 +97,6 @@ public:
 
     SpecularBeamItem* beamItem() const override;
 
-    std::unique_ptr<Instrument> createInstrument() const override;
     std::vector<int> shape() const override;
     void updateToRealData(const RealDataItem* item) override;
     virtual QString defaultName() const override;
@@ -128,7 +126,7 @@ public:
     void clearMasks() override;
     void importMasks(const MaskContainerItem* maskContainer) override;
 
-    std::unique_ptr<Instrument> createInstrument() const override;
+    std::unique_ptr<Instrument> createInstrument() const;
 
     static bool isDetectorPropertyName(const QString& name);
 
diff --git a/GUI/Models/InstrumentModel.cpp b/GUI/Models/InstrumentModel.cpp
index 20508db7b667ec4d4f62e165efd261870f3a8f52..38411fb41945b3d7f11aa697895bcf0ebf6c3428 100644
--- a/GUI/Models/InstrumentModel.cpp
+++ b/GUI/Models/InstrumentModel.cpp
@@ -76,6 +76,11 @@ QVector<InstrumentItem*> InstrumentModel::instrumentItems() const
     return topItems<InstrumentItem>();
 }
 
+QVector<Instrument2DItem*> InstrumentModel::instrument2DItems() const
+{
+    return topItems<Instrument2DItem>();
+}
+
 InstrumentItem* InstrumentModel::findInstrumentById(const QString& instrumentId) const
 {
     for (auto instrument : instrumentItems())
diff --git a/GUI/Models/InstrumentModel.h b/GUI/Models/InstrumentModel.h
index 5e3e9005efcdf07896fc905d11904f8894bd30db..d278169a0461a36731b2bbb7dae22279c970c74c 100644
--- a/GUI/Models/InstrumentModel.h
+++ b/GUI/Models/InstrumentModel.h
@@ -18,6 +18,7 @@
 #include "GUI/Models/SessionModel.h"
 
 class InstrumentItem;
+class Instrument2DItem;
 
 class InstrumentModel : public SessionModel {
     Q_OBJECT
@@ -31,6 +32,7 @@ public:
     virtual void readFrom(QXmlStreamReader* reader, MessageService* messageService = 0) override;
 
     QVector<InstrumentItem*> instrumentItems() const;
+    QVector<Instrument2DItem*> instrument2DItems() const;
 
     InstrumentItem* findInstrumentById(const QString& instrumentId) const;
     bool instrumentExists(const QString& instrumentId) const;
diff --git a/GUI/Models/JobItem.cpp b/GUI/Models/JobItem.cpp
index ee89bab505ba26e74a101524dea3b760befc81b7..d4367482455646cdf4aea27dc282e7784a7fa4a6 100644
--- a/GUI/Models/JobItem.cpp
+++ b/GUI/Models/JobItem.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/Models/JobItem.h"
+#include "Base/Utils/Assert.h"
 #include "GUI/Models/Data1DViewItem.h"
 #include "GUI/Models/Error.h"
 #include "GUI/Models/FitSuiteItem.h"
@@ -243,6 +244,13 @@ InstrumentItem* JobItem::instrumentItem()
     return dynamic_cast<InstrumentItem*>(getItem(T_INSTRUMENT));
 }
 
+Instrument2DItem* JobItem::instrument2DItem()
+{
+    auto* result = dynamic_cast<Instrument2DItem*>(getItem(T_INSTRUMENT));
+    ASSERT(result);
+    return result;
+}
+
 InstrumentItem* JobItem::copyInstrumentIntoJob(const InstrumentItem* instrument)
 {
     return model()->copyItem(instrument, this, T_INSTRUMENT);
diff --git a/GUI/Models/JobItem.h b/GUI/Models/JobItem.h
index 2c9cb2b54a2820fba27e26b29e263d14a10e5ab0..323fe4d6a4963002241a6a0751ef77b6dbe25441 100644
--- a/GUI/Models/JobItem.h
+++ b/GUI/Models/JobItem.h
@@ -23,6 +23,7 @@ class Data1DViewItem;
 class FitParameterContainerItem;
 class FitSuiteItem;
 class InstrumentItem;
+class Instrument2DItem;
 class IntensityDataItem;
 class MaterialItemContainer;
 class MultiLayerItem;
@@ -98,6 +99,7 @@ public:
     MultiLayerItem* sampleItem();
     MultiLayerItem* copySampleIntoJob(const MultiLayerItem* sample);
 
+    Instrument2DItem* instrument2DItem();
     InstrumentItem* instrumentItem();
     InstrumentItem* copyInstrumentIntoJob(const InstrumentItem* instrument);
 
diff --git a/GUI/Models/JobItemUtils.cpp b/GUI/Models/JobItemUtils.cpp
index 8fd615b385d11f25e31b7d28153bb059b875a41c..5826f77b11eede9fcfd92d85e125eda06c247518 100644
--- a/GUI/Models/JobItemUtils.cpp
+++ b/GUI/Models/JobItemUtils.cpp
@@ -111,7 +111,7 @@ void GUI::Model::JobItemUtils::setIntensityItemCoords(DataItem* intensityItem,
 }
 
 void GUI::Model::JobItemUtils::createDefaultDetectorMap(DataItem* intensityItem,
-                                                        const InstrumentItem* instrumentItem)
+                                                        const Instrument2DItem* instrumentItem)
 {
     const auto converter = instrumentItem->createCoordSystem();
     auto output_data = converter->createOutputData(converter->defaultUnits());
diff --git a/GUI/Models/JobItemUtils.h b/GUI/Models/JobItemUtils.h
index d15c2ce4129ee43f9593d9bd88c257be80b53d9e..2f6630dc4479706a43b94845f57ad01d0877d6b2 100644
--- a/GUI/Models/JobItemUtils.h
+++ b/GUI/Models/JobItemUtils.h
@@ -21,6 +21,7 @@
 
 class DataItem;
 class InstrumentItem;
+class Instrument2DItem;
 class JobItem;
 class ISimulation;
 class ICoordSystem;
@@ -43,7 +44,7 @@ void setIntensityItemCoords(DataItem* intensityItem, const InstrumentItem* instr
 
 void setIntensityItemCoords(DataItem* intensityItem, const ICoordSystem& converter);
 
-void createDefaultDetectorMap(DataItem* intensityItem, const InstrumentItem* instrumentItem);
+void createDefaultDetectorMap(DataItem* intensityItem, const Instrument2DItem* instrumentItem);
 
 //! Sets simulation results into the DataItem
 void setResults(DataItem* intensityItem, const ISimulation* simulation);
diff --git a/GUI/Models/JobModelFunctions.cpp b/GUI/Models/JobModelFunctions.cpp
index f8c4affe234bb3f51072082306ecaa8ed19da721..06d4c962a935e5bcebabaac747e3d89bc635d0b9 100644
--- a/GUI/Models/JobModelFunctions.cpp
+++ b/GUI/Models/JobModelFunctions.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/Models/JobModelFunctions.h"
+#include "Base/Utils/Assert.h"
 #include "Device/Instrument/Instrument.h"
 #include "GUI/Models/Data1DViewItem.h"
 #include "GUI/Models/DataPropertyContainer.h"
@@ -36,25 +37,73 @@
 #include <map>
 
 namespace {
+
 //! Links RealDataItem to the JobItem's instrument.
 // (re-)Linking is necessary because of following reason
 // 1) Copying of RealDataItem from RealDataModel on board of JobItem requires relink to the copied
 //    insturment
 // 2) During relink all masks (if exists) will be converted to the default units of current detector
-void processInstrumentLink(JobItem* jobItem);
+void processInstrumentLink(JobItem* jobItem)
+{
+    RealDataItem* realData = jobItem->realDataItem();
+    if (!realData)
+        throw Error("GUI::Model::JobFunctions::processInstrumentLink() -> Error. No data.");
+
+    realData->setInstrumentId(jobItem->instrumentItem()->id());
+    realData->updateToInstrument(jobItem->instrumentItem());
+}
 
 //! Copies masks and ROI from RealDataItem on board of instrument.
-void copyMasksToInstrument(JobItem* jobItem);
+void copyMasksToInstrument(JobItem* jobItem)
+{
+    auto mask_container = jobItem->realDataItem()->maskContainerItem();
+    jobItem->instrumentItem()->importMasks(mask_container);
+}
 
 //! Crops RealDataItem to the region of interest.
-void cropRealData(JobItem* jobItem);
+void cropRealData(JobItem* jobItem)
+{
+    ASSERT(jobItem->instrumentItem()->is<Instrument2DItem>());
+
+    RealDataItem* realData = jobItem->realDataItem();
+
+    // adjusting real data to the size of region of interest
+    IntensityDataItem* intensityItem = realData->intensityDataItem();
+
+    std::unique_ptr<OutputData<double>> origData(intensityItem->getOutputData()->clone());
+
+    auto instrument_item = jobItem->instrument2DItem();
+    GUI::Model::JobItemUtils::createDefaultDetectorMap(intensityItem, instrument_item);
+
+    instrument_item->createInstrument()->getDetector()->iterateOverNonMaskedPoints(
+        [&](IDetector::const_iterator it) {
+        auto cropped_data = intensityItem->getOutputData();
+        (*cropped_data)[it.roiIndex()] = (*origData)[it.detectorIndex()];
+    });
+
+    intensityItem->updateDataRange();
+}
 
 //! Creates necessary fit containers for jobItem intended for fitting.
-void createFitContainers(JobItem* jobItem);
+void createFitContainers(JobItem* jobItem)
+{
+    FitSuiteItem* fitSuiteItem = jobItem->createFitSuiteItem();
+
+    fitSuiteItem->createFitParametersContainer();
+    fitSuiteItem->createMinimizerContainer();
+}
+
+PointwiseAxisItem* getPointwiseAxisItem(const SpecularInstrumentItem* instrument)
+{
+    return instrument->beamItem()->inclinationAxisGroup()->firstChildOfType<PointwiseAxisItem>();
+}
 
-PointwiseAxisItem* getPointwiseAxisItem(const SpecularInstrumentItem* instrument);
 } // namespace
 
+//  ************************************************************************************************
+//  class implementation
+//  ************************************************************************************************
+
 void GUI::Model::JobFunctions::initDataView(JobItem* job_item)
 {
     ASSERT(job_item && job_item->isValidForFitting());
@@ -140,8 +189,7 @@ void GUI::Model::JobFunctions::setupJobItemOutput(JobItem* jobItem)
     else if (isIntensityInstrument)
         jobItem->setDataType<IntensityDataItem>();
     else
-        throw Error("GUI::Model::JobFunctions::setupJobItemOutput() -> Error. "
-                    "Unsupported instrument type");
+        ASSERT(0);
 }
 
 //! Setups JobItem for fit.
@@ -149,15 +197,12 @@ void GUI::Model::JobFunctions::setupJobItemOutput(JobItem* jobItem)
 void GUI::Model::JobFunctions::setupJobItemForFit(JobItem* jobItem,
                                                   const RealDataItem* realDataItem)
 {
-    if (!jobItem->instrumentItem())
-        throw Error("GUI::Model::JobFunctions::processInstrumentLink() -> Error. "
-                    "No instrument.");
+    ASSERT(jobItem->instrumentItem());
 
     copyRealDataItem(jobItem, realDataItem);
     processInstrumentLink(jobItem);
     copyMasksToInstrument(jobItem);
 
-    // TODO: remove if when other simulation types are ready for roi & masks
     if (jobItem->instrumentItem()->is<GISASInstrumentItem>())
         cropRealData(jobItem);
     if (jobItem->instrumentItem()->is<SpecularInstrumentItem>())
@@ -206,54 +251,3 @@ const JobItem* GUI::Model::JobFunctions::findJobItem(const SessionItem* item)
         item = item->parent();
     return static_cast<const JobItem*>(item);
 }
-
-namespace {
-void processInstrumentLink(JobItem* jobItem)
-{
-    RealDataItem* realData = jobItem->realDataItem();
-    if (!realData)
-        throw Error("GUI::Model::JobFunctions::processInstrumentLink() -> Error. No data.");
-
-    realData->setInstrumentId(jobItem->instrumentItem()->id());
-    realData->updateToInstrument(jobItem->instrumentItem());
-}
-
-void copyMasksToInstrument(JobItem* jobItem)
-{
-    auto mask_container = jobItem->realDataItem()->maskContainerItem();
-    jobItem->instrumentItem()->importMasks(mask_container);
-}
-
-void cropRealData(JobItem* jobItem)
-{
-    RealDataItem* realData = jobItem->realDataItem();
-
-    // adjusting real data to the size of region of interest
-    IntensityDataItem* intensityItem = realData->intensityDataItem();
-
-    std::unique_ptr<OutputData<double>> origData(intensityItem->getOutputData()->clone());
-
-    GUI::Model::JobItemUtils::createDefaultDetectorMap(intensityItem, jobItem->instrumentItem());
-
-    auto instrument = jobItem->instrumentItem()->createInstrument();
-    instrument->getDetector()->iterateOverNonMaskedPoints([&](IDetector::const_iterator it) {
-        auto cropped_data = intensityItem->getOutputData();
-        (*cropped_data)[it.roiIndex()] = (*origData)[it.detectorIndex()];
-    });
-
-    intensityItem->updateDataRange();
-}
-
-void createFitContainers(JobItem* jobItem)
-{
-    FitSuiteItem* fitSuiteItem = jobItem->createFitSuiteItem();
-
-    fitSuiteItem->createFitParametersContainer();
-    fitSuiteItem->createMinimizerContainer();
-}
-
-PointwiseAxisItem* getPointwiseAxisItem(const SpecularInstrumentItem* instrument)
-{
-    return instrument->beamItem()->inclinationAxisGroup()->firstChildOfType<PointwiseAxisItem>();
-}
-} // namespace
diff --git a/Tests/Unit/Core/RectangularDetectorTest.cpp b/Tests/Unit/Core/RectangularDetectorTest.cpp
index bef20b36ef40c964e4f6c375316e00786d2fa0b9..de7640fae09571aa8725c73ad95feb8fb18375ce 100644
--- a/Tests/Unit/Core/RectangularDetectorTest.cpp
+++ b/Tests/Unit/Core/RectangularDetectorTest.cpp
@@ -2,6 +2,7 @@
 #include "Base/Const/Units.h"
 #include "Base/Utils/Algorithms.h"
 #include "Core/Simulation/GISASSimulation.h"
+#include "Device/Beam/Beam.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <iostream>
 #include <memory>
@@ -79,7 +80,7 @@ TEST_F(RectangularDetectorTest, PerpToSample)
     // initializing with the simulation
     GISASSimulation simulation;
     simulation.setBeamParameters(1.0, 10.0 * Units::deg, 0.0);
-    det.init(simulation.beam());
+    det.setDetectorNormal(simulation.beam().direction().zReflected());
     EXPECT_TRUE(kvector_t(distance, 0, 0) == det.getNormalVector());
     EXPECT_TRUE(kvector_t(0.0, -1.0, 0.0) == det.getDirectionVector());
 }
@@ -107,7 +108,7 @@ TEST_F(RectangularDetectorTest, PerpToDirectBeam)
     // initializing with the simulation
     GISASSimulation simulation;
     simulation.setBeamParameters(1.0, alpha_i, 0.0);
-    det.init(simulation.beam());
+    det.setDetectorNormal(simulation.beam().direction().zReflected());
     kvector_t normal(distance * cos(alpha_i), 0.0, -1.0 * distance * sin(alpha_i));
     EXPECT_TRUE(isEqual(normal, det.getNormalVector()));
     EXPECT_TRUE(kvector_t(0.0, -1.0, 0.0) == det.getDirectionVector());
@@ -136,7 +137,7 @@ TEST_F(RectangularDetectorTest, PerpToReflectedBeam)
     // initializing with the simulation
     GISASSimulation simulation;
     simulation.setBeamParameters(1.0, alpha_i, 0.0);
-    det.init(simulation.beam());
+    det.setDetectorNormal(simulation.beam().direction().zReflected());
     kvector_t normal(distance * cos(alpha_i), 0.0, 1.0 * distance * sin(alpha_i));
     EXPECT_TRUE(isEqual(normal, det.getNormalVector()));
     EXPECT_TRUE(kvector_t(0.0, -1.0, 0.0) == det.getDirectionVector());
@@ -176,7 +177,7 @@ TEST_F(RectangularDetectorTest, PerpToReflectedBeamDpos)
     // initializing with the simulation
     GISASSimulation simulation;
     simulation.setBeamParameters(1.0, alpha_i, 0.0);
-    det.init(simulation.beam());
+    det.setDetectorNormal(simulation.beam().direction().zReflected());
 
     kvector_t normal(distance * cos(alpha_i), 0.0, 1.0 * distance * sin(alpha_i));
     EXPECT_TRUE(isEqual(normal, det.getNormalVector()));
diff --git a/Tests/Unit/Device/BeamTest.cpp b/Tests/Unit/Device/BeamTest.cpp
index 049b2039a22952fcd4ecb6918ef36e2e10e11b22..420e70e6fdc0800089d69756f710a335089046e5 100644
--- a/Tests/Unit/Device/BeamTest.cpp
+++ b/Tests/Unit/Device/BeamTest.cpp
@@ -9,43 +9,6 @@
 class BeamTest : public ::testing::Test {
 };
 
-TEST_F(BeamTest, BeamInitialState)
-{
-    Beam beam = Beam::horizontalBeam();
-    EXPECT_DOUBLE_EQ(M_TWOPI, beam.getCentralK()[0]);
-    EXPECT_EQ(0.0, beam.getCentralK()[1]);
-    EXPECT_EQ(0.0, beam.getCentralK()[2]);
-    EXPECT_EQ(1.0, beam.intensity());
-    // EXPECT_EQ(size_t(4), beam.parameterPool()->size());
-    //    EXPECT_EQ(1.0, beam.parameterPool()->parameter("Intensity")->value());
-    //    EXPECT_EQ(1.0, beam.parameterPool()->parameter("Wavelength")->value());
-    //    EXPECT_EQ(0.0, beam.parameterPool()->parameter("Alpha")->value());
-    //    EXPECT_EQ(0.0, beam.parameterPool()->parameter("Phi")->value());
-    //    EXPECT_EQ(complex_t(0.5, 0.0), beam.getPolarization()(0, 0));
-    //    EXPECT_EQ(complex_t(0.5, 0.0), beam.getPolarization()(1, 1));
-}
-
-TEST_F(BeamTest, BeamAssignment)
-{
-    kvector_t polarization(0.0, 0.0, 0.2);
-
-    std::unique_ptr<Beam> P_beam{new Beam(2.0, 1.0, {1.0, 1.0})};
-    P_beam->setPolarization(polarization);
-
-    Beam beam_copy = *P_beam;
-    EXPECT_NEAR(1.83423, beam_copy.getCentralK()[0], 0.00001);
-    EXPECT_NEAR(-2.85664, beam_copy.getCentralK()[1], 0.00001);
-    EXPECT_NEAR(-5.28712, beam_copy.getCentralK()[2], 0.00001);
-    EXPECT_EQ(double(2.0), beam_copy.intensity());
-    /* TEMPORARILY DISABLED getParameterPool()
-    EXPECT_EQ(size_t(4), beam_copy.getParameterPool()->size());
-    EXPECT_EQ(double(2.0),
-              beam_copy.getParameterPool()->getParameter("Intensity").getValue());
-    EXPECT_EQ(complex_t(0.6, 0.0), beam_copy.getPolarization()(0, 0));
-    EXPECT_EQ(complex_t(0.4, 0.0), beam_copy.getPolarization()(1, 1));
-    */
-}
-
 TEST_F(BeamTest, BeamPolarization)
 {
     Beam beam = Beam::horizontalBeam();
diff --git a/Tests/Unit/Device/RectangularConverterTest.cpp b/Tests/Unit/Device/RectangularConverterTest.cpp
index 856a225d39c432f88a6936abf8c0a61477124c08..11a61c6b0b96ea136ec4395b619647e142ff8be9 100644
--- a/Tests/Unit/Device/RectangularConverterTest.cpp
+++ b/Tests/Unit/Device/RectangularConverterTest.cpp
@@ -1,4 +1,5 @@
 #include "Base/Const/Units.h"
+#include "Base/Math/Constants.h"
 #include "Base/Pixel/RectangularPixel.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Detector/RectangularDetector.h"
@@ -29,11 +30,11 @@ ImageCoordsTest::ImageCoordsTest()
     : m_detector(det_nx, det_width, det_ny, det_height), m_beam(1.0, 1.0, {1 * Units::deg, 0})
 {
     m_detector.setPerpendicularToSampleX(det_distance, det_width / 2.0, 0.0);
-    m_detector.init(m_beam);
+    m_detector.setDetectorNormal(m_beam.direction().zReflected());
     m_phi = std::atan2(det_width / 2.0, det_distance);
     m_alpha = std::atan2(det_height, det_distance / std::cos(m_phi));
-    auto k_i = m_beam.getCentralK();
-    m_kiz = k_i.z();
+    const auto k_i = M_TWOPI / m_beam.wavelength() * m_beam.direction().vector();
+    m_kiz = - k_i.z();
     double K = 2.0 * M_PI / m_beam.wavelength();
     m_kfy = K * std::sin(m_phi);
     m_kfz = K * std::sin(m_alpha);
diff --git a/Tests/Unit/Device/SphericalConverterTest.cpp b/Tests/Unit/Device/SphericalConverterTest.cpp
index 8e540bfe9e0905f8a3144ccb531dec5057f301d1..01aa984b9ae42e820536335517eb463e8f0aa723 100644
--- a/Tests/Unit/Device/SphericalConverterTest.cpp
+++ b/Tests/Unit/Device/SphericalConverterTest.cpp
@@ -1,4 +1,5 @@
 #include "Base/Const/Units.h"
+#include "Base/Math/Constants.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Detector/SphericalDetector.h"
 #include "Device/Coord/CoordSystem2D.h"
@@ -18,8 +19,8 @@ SphericalCoordsTest::SphericalCoordsTest()
     : m_detector(100, 0.0, 5.0 * Units::deg, 70, -2.0 * Units::deg, 1.5)
     , m_beam(1.0, 1.0, {1 * Units::deg, 0})
 {
-    const auto k_i = m_beam.getCentralK();
-    m_kiz = k_i.z();
+    const auto k_i = M_TWOPI / m_beam.wavelength() * m_beam.direction().vector();
+    m_kiz = -k_i.z();
     const double K = 2.0 * M_PI / m_beam.wavelength();
     m_kfy = K * std::sin(5.0 * Units::deg);
     m_kfz1 = K * std::sin(-2.0 * Units::deg);
diff --git a/Tests/Unit/GUI/TestProjectDocument.cpp b/Tests/Unit/GUI/TestProjectDocument.cpp
index 2b23efa451dd50ac60faf18fce7d6fd4d08b7a43..1292cb33904ea2be22bc726400c912c090ca9fab 100644
--- a/Tests/Unit/GUI/TestProjectDocument.cpp
+++ b/Tests/Unit/GUI/TestProjectDocument.cpp
@@ -105,7 +105,7 @@ TEST_F(TestProjectDocument, test_projectDocumentWithData)
     ASSERT(realData);
     DataItem* intensityItem = realData->dataItem();
     GUI::Model::JobItemUtils::createDefaultDetectorMap(
-        intensityItem, models.instrumentModel()->instrumentItems().front());
+        intensityItem, models.instrumentModel()->instrument2DItems().front());
     intensityItem->setFileName("realdata.int.gz");
 
     ProjectDocument document;
diff --git a/Tests/Unit/GUI/TestSaveService.cpp b/Tests/Unit/GUI/TestSaveService.cpp
index d7e514c2c9244bbb23385a05ff670f4f86161e09..8ef7da72626ba81d286603baa4d29d582d7c780d 100644
--- a/Tests/Unit/GUI/TestSaveService.cpp
+++ b/Tests/Unit/GUI/TestSaveService.cpp
@@ -177,7 +177,7 @@ TEST_F(TestSaveService, test_saveServiceWithData)
     ASSERT(realData);
     DataItem* intensityItem = realData->dataItem();
     GUI::Model::JobItemUtils::createDefaultDetectorMap(
-        intensityItem, models.instrumentModel()->instrumentItems().front());
+        intensityItem, models.instrumentModel()->instrument2DItems().front());
     intensityItem->setFileName("realdata.int.gz");
 
     std::unique_ptr<ProjectDocument> document(new ProjectDocument);
@@ -211,7 +211,7 @@ TEST_F(TestSaveService, test_autosaveEnabled)
     RealDataItem* realData = GuiUnittestUtils::createRealData("RealData", *models.realDataModel());
     DataItem* intensityItem = realData->dataItem();
     GUI::Model::JobItemUtils::createDefaultDetectorMap(
-        intensityItem, models.instrumentModel()->instrumentItems().front());
+        intensityItem, models.instrumentModel()->instrument2DItems().front());
     intensityItem->setFileName("realdata.int.gz");
 
     std::unique_ptr<ProjectDocument> document(new ProjectDocument(projectFileName));
diff --git a/auto/Wrap/doxygenBase.i b/auto/Wrap/doxygenBase.i
index ac21410930c53406622cab6fea71be8d30844ece..2456bec78d806cfdbcd1a308810575edee110875 100644
--- a/auto/Wrap/doxygenBase.i
+++ b/auto/Wrap/doxygenBase.i
@@ -411,6 +411,9 @@ C++ includes: Direction.h
 Returns Cartesian 3D vector. 
 ";
 
+%feature("docstring")  Direction::zReflected "Direction Direction::zReflected() const
+";
+
 
 // File: classFixedBinAxis.xml
 %feature("docstring") FixedBinAxis "
diff --git a/auto/Wrap/doxygenDevice.i b/auto/Wrap/doxygenDevice.i
index 8ae68c3d5e52c531d1fd4a4eb3746a3585a790ea..5c904268faa10f3e07e3bd3b334be2660b753a37 100644
--- a/auto/Wrap/doxygenDevice.i
+++ b/auto/Wrap/doxygenDevice.i
@@ -95,11 +95,6 @@ Returns the beam intensity in neutrons/sec.
 %feature("docstring")  Beam::direction "Direction Beam::direction() const
 ";
 
-%feature("docstring")  Beam::getCentralK "kvector_t Beam::getCentralK() const
-
-Returns the wavevector. 
-";
-
 %feature("docstring")  Beam::getBlochVector "kvector_t Beam::getBlochVector() const
 ";
 
@@ -996,7 +991,7 @@ C++ includes: IDetector.h
 %feature("docstring")  IDetector::~IDetector "IDetector::~IDetector()
 ";
 
-%feature("docstring")  IDetector::init "virtual void IDetector::init(const Beam &)
+%feature("docstring")  IDetector::setDetectorNormal "virtual void IDetector::setDetectorNormal(const Direction &)
 
 Inits detector with the beam settings. 
 ";
@@ -2397,7 +2392,7 @@ Height of the detector in mm along y-direction
 %feature("docstring")  RectangularDetector::~RectangularDetector "RectangularDetector::~RectangularDetector()
 ";
 
-%feature("docstring")  RectangularDetector::init "void RectangularDetector::init(const Beam &beam) override
+%feature("docstring")  RectangularDetector::setDetectorNormal "void RectangularDetector::setDetectorNormal(const Direction &direction) override
 
 Inits detector with the beam settings. 
 ";
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 1f4ca15f9dcbd107e645fe697bd88a6a75191e4b..0307c18124b3d1b2dc83b51b20afb22214b47056 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1823,6 +1823,14 @@ class Direction(object):
 
         """
         return _libBornAgainBase.Direction_vector(self)
+
+    def zReflected(self):
+        r"""
+        zReflected(Direction self) -> Direction
+        Direction Direction::zReflected() const
+
+        """
+        return _libBornAgainBase.Direction_zReflected(self)
     __swig_destroy__ = _libBornAgainBase.delete_Direction
 
 # Register Direction in _libBornAgainBase:
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 4f9a37f925e8aee2012b82b68a6c629bcfc92b5b..b1f1999913ee9bc8c863064f4a7d1e1812b94082 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -24559,6 +24559,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Direction_zReflected(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Direction *arg1 = (Direction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  Direction result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Direction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Direction_zReflected" "', argument " "1"" of type '" "Direction const *""'"); 
+  }
+  arg1 = reinterpret_cast< Direction * >(argp1);
+  result = ((Direction const *)arg1)->zReflected();
+  resultobj = SWIG_NewPointerObj((new Direction(static_cast< const Direction& >(result))), SWIGTYPE_p_Direction, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_delete_Direction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Direction *arg1 = (Direction *) 0 ;
@@ -33520,6 +33543,11 @@ static PyMethodDef SwigMethods[] = {
 		"Returns Cartesian 3D vector. \n"
 		"\n"
 		""},
+	 { "Direction_zReflected", _wrap_Direction_zReflected, METH_O, "\n"
+		"Direction_zReflected(Direction self) -> Direction\n"
+		"Direction Direction::zReflected() const\n"
+		"\n"
+		""},
 	 { "delete_Direction", _wrap_delete_Direction, METH_O, "delete_Direction(Direction self)"},
 	 { "Direction_swigregister", Direction_swigregister, METH_O, NULL},
 	 { "Direction_swiginit", Direction_swiginit, METH_VARARGS, NULL},
diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index c4dab083422bd622cac733ef047b98efe840c8c3..af438da7d5bb01ab73056b55d9192114d490126b 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -2765,16 +2765,6 @@ class Beam(libBornAgainParam.INode):
         """
         return _libBornAgainDevice.Beam_direction(self)
 
-    def getCentralK(self):
-        r"""
-        getCentralK(Beam self) -> kvector_t
-        kvector_t Beam::getCentralK() const
-
-        Returns the wavevector. 
-
-        """
-        return _libBornAgainDevice.Beam_getCentralK(self)
-
     def getBlochVector(self):
         r"""
         getBlochVector(Beam self) -> kvector_t
@@ -3923,15 +3913,15 @@ class IDetector(libBornAgainBase.ICloneable, libBornAgainParam.INode):
         return _libBornAgainDevice.IDetector_clone(self)
     __swig_destroy__ = _libBornAgainDevice.delete_IDetector
 
-    def init(self, arg2):
+    def setDetectorNormal(self, arg2):
         r"""
-        init(IDetector self, Beam arg2)
-        virtual void IDetector::init(const Beam &)
+        setDetectorNormal(IDetector self, Direction const & arg2)
+        virtual void IDetector::setDetectorNormal(const Direction &)
 
         Inits detector with the beam settings. 
 
         """
-        return _libBornAgainDevice.IDetector_init(self, arg2)
+        return _libBornAgainDevice.IDetector_setDetectorNormal(self, arg2)
 
     def addAxis(self, axis):
         r"""
@@ -4372,15 +4362,15 @@ class RectangularDetector(IDetector2D):
         return _libBornAgainDevice.RectangularDetector_accept(self, visitor)
     __swig_destroy__ = _libBornAgainDevice.delete_RectangularDetector
 
-    def init(self, beam):
+    def setDetectorNormal(self, direction):
         r"""
-        init(RectangularDetector self, Beam beam)
-        void RectangularDetector::init(const Beam &beam) override
+        setDetectorNormal(RectangularDetector self, Direction const & direction)
+        void RectangularDetector::setDetectorNormal(const Direction &direction) override
 
         Inits detector with the beam settings. 
 
         """
-        return _libBornAgainDevice.RectangularDetector_init(self, beam)
+        return _libBornAgainDevice.RectangularDetector_setDetectorNormal(self, direction)
 
     def setPosition(self, *args):
         r"""
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index c4207133f5befe5133b8d17d7599b70ccefa9a9a..d1ef4a5727968fa75a476f8e00cc645b9fbea25a 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -31283,29 +31283,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_Beam_getCentralK(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  Beam *arg1 = (Beam *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  kvector_t result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Beam, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Beam_getCentralK" "', argument " "1"" of type '" "Beam const *""'"); 
-  }
-  arg1 = reinterpret_cast< Beam * >(argp1);
-  result = ((Beam const *)arg1)->getCentralK();
-  resultobj = SWIG_NewPointerObj((new kvector_t(static_cast< const kvector_t& >(result))), SWIGTYPE_p_BasicVector3DT_double_t, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_Beam_getBlochVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Beam *arg1 = (Beam *) 0 ;
@@ -35685,31 +35662,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IDetector_init(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IDetector_setDetectorNormal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDetector *arg1 = (IDetector *) 0 ;
-  Beam *arg2 = 0 ;
+  Direction *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject *swig_obj[2] ;
   
-  if (!SWIG_Python_UnpackTuple(args, "IDetector_init", 2, 2, swig_obj)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "IDetector_setDetectorNormal", 2, 2, swig_obj)) SWIG_fail;
   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_init" "', argument " "1"" of type '" "IDetector *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector_setDetectorNormal" "', argument " "1"" of type '" "IDetector *""'"); 
   }
   arg1 = reinterpret_cast< IDetector * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Beam,  0  | 0);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Direction,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IDetector_init" "', argument " "2"" of type '" "Beam const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IDetector_setDetectorNormal" "', argument " "2"" of type '" "Direction const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IDetector_init" "', argument " "2"" of type '" "Beam const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IDetector_setDetectorNormal" "', argument " "2"" of type '" "Direction const &""'"); 
   }
-  arg2 = reinterpret_cast< Beam * >(argp2);
-  (arg1)->init((Beam const &)*arg2);
+  arg2 = reinterpret_cast< Direction * >(argp2);
+  (arg1)->setDetectorNormal((Direction const &)*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -37147,31 +37124,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_RectangularDetector_init(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_RectangularDetector_setDetectorNormal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   RectangularDetector *arg1 = (RectangularDetector *) 0 ;
-  Beam *arg2 = 0 ;
+  Direction *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject *swig_obj[2] ;
   
-  if (!SWIG_Python_UnpackTuple(args, "RectangularDetector_init", 2, 2, swig_obj)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "RectangularDetector_setDetectorNormal", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RectangularDetector, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RectangularDetector_init" "', argument " "1"" of type '" "RectangularDetector *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RectangularDetector_setDetectorNormal" "', argument " "1"" of type '" "RectangularDetector *""'"); 
   }
   arg1 = reinterpret_cast< RectangularDetector * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Beam,  0  | 0);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Direction,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "RectangularDetector_init" "', argument " "2"" of type '" "Beam const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "RectangularDetector_setDetectorNormal" "', argument " "2"" of type '" "Direction const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RectangularDetector_init" "', argument " "2"" of type '" "Beam const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RectangularDetector_setDetectorNormal" "', argument " "2"" of type '" "Direction const &""'"); 
   }
-  arg2 = reinterpret_cast< Beam * >(argp2);
-  (arg1)->init((Beam const &)*arg2);
+  arg2 = reinterpret_cast< Direction * >(argp2);
+  (arg1)->setDetectorNormal((Direction const &)*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -45016,13 +44993,6 @@ static PyMethodDef SwigMethods[] = {
 		"Direction Beam::direction() const\n"
 		"\n"
 		""},
-	 { "Beam_getCentralK", _wrap_Beam_getCentralK, METH_O, "\n"
-		"Beam_getCentralK(Beam self) -> kvector_t\n"
-		"kvector_t Beam::getCentralK() const\n"
-		"\n"
-		"Returns the wavevector. \n"
-		"\n"
-		""},
 	 { "Beam_getBlochVector", _wrap_Beam_getBlochVector, METH_O, "\n"
 		"Beam_getBlochVector(Beam self) -> kvector_t\n"
 		"kvector_t Beam::getBlochVector() const\n"
@@ -45633,9 +45603,9 @@ static PyMethodDef SwigMethods[] = {
 		"IDetector::~IDetector()\n"
 		"\n"
 		""},
-	 { "IDetector_init", _wrap_IDetector_init, METH_VARARGS, "\n"
-		"IDetector_init(IDetector self, Beam arg2)\n"
-		"virtual void IDetector::init(const Beam &)\n"
+	 { "IDetector_setDetectorNormal", _wrap_IDetector_setDetectorNormal, METH_VARARGS, "\n"
+		"IDetector_setDetectorNormal(IDetector self, Direction const & arg2)\n"
+		"virtual void IDetector::setDetectorNormal(const Direction &)\n"
 		"\n"
 		"Inits detector with the beam settings. \n"
 		"\n"
@@ -45924,9 +45894,9 @@ static PyMethodDef SwigMethods[] = {
 		"RectangularDetector::~RectangularDetector()\n"
 		"\n"
 		""},
-	 { "RectangularDetector_init", _wrap_RectangularDetector_init, METH_VARARGS, "\n"
-		"RectangularDetector_init(RectangularDetector self, Beam beam)\n"
-		"void RectangularDetector::init(const Beam &beam) override\n"
+	 { "RectangularDetector_setDetectorNormal", _wrap_RectangularDetector_setDetectorNormal, METH_VARARGS, "\n"
+		"RectangularDetector_setDetectorNormal(RectangularDetector self, Direction const & direction)\n"
+		"void RectangularDetector::setDetectorNormal(const Direction &direction) override\n"
 		"\n"
 		"Inits detector with the beam settings. \n"
 		"\n"