diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp
index b2babbaf5fb639162af66cbbc3cec4d39a431794..93a502ae537024b466bca1c3671eafa9b11282df 100644
--- a/GUI/Model/Device/InstrumentItems.cpp
+++ b/GUI/Model/Device/InstrumentItems.cpp
@@ -382,6 +382,7 @@ ISimulation* SpecularInstrumentItem::createSimulation(const MultiLayer& sample)
     BasicAxisItem* const axis_item = beamItem()->inclinationAxisItem();
 
     AlphaScan scan(*axis_item->createAxis(Units::deg));
+    scan.setIntensity(beamItem()->intensity());
 
     FootprintItemCatalog::CatalogedType* const footprint_item =
         beamItem()->footprintSelection().currentItem();
diff --git a/GUI/Model/FromCore/ItemizeSimulation.cpp b/GUI/Model/FromCore/ItemizeSimulation.cpp
index 8da6bbb0e02fa3488968502ccd8b1c5831bb4855..a8b7b3d177ac02bcb9245c814b59a76accee962f 100644
--- a/GUI/Model/FromCore/ItemizeSimulation.cpp
+++ b/GUI/Model/FromCore/ItemizeSimulation.cpp
@@ -419,7 +419,7 @@ SpecularInstrumentItem* createSpecularInstrumentItem(const SpecularSimulation& s
 
     const ISpecularScan* scan = simulation.scan();
 
-    beam_item->setIntensity(1.0); // TODO ISSUE #303
+    beam_item->setIntensity(scan->intensity());
     beam_item->setWavelength(scan->wavelength());
     beam_item->setInclinationAngle(0.0); // inclination angle is hardcoded
     beam_item->setAzimuthalAngle(0.0);   // azimuthal angle is hardcoded
diff --git a/Sim/Scan/AlphaScan.cpp b/Sim/Scan/AlphaScan.cpp
index b565d34fc93b8142d685cb8c7ccac3664306eb51..a414cc10b31650cdf4cff83e539faa942b3d4ca3 100644
--- a/Sim/Scan/AlphaScan.cpp
+++ b/Sim/Scan/AlphaScan.cpp
@@ -54,6 +54,7 @@ AlphaScan::AlphaScan(int nbins, double alpha_i_min, double alpha_i_max)
 AlphaScan* AlphaScan::clone() const
 {
     auto* result = new AlphaScan(*m_axis);
+    result->setIntensity(intensity());
     result->setFootprintFactor(m_footprint.get());
 
     if (m_lambda_distrib)
diff --git a/Sim/Scan/ISpecularScan.cpp b/Sim/Scan/ISpecularScan.cpp
index 861e015f680d18c6fac5911f0c7419b711a48d76..7c9c9f4ec522a61414b10d70448f8ec6a347158f 100644
--- a/Sim/Scan/ISpecularScan.cpp
+++ b/Sim/Scan/ISpecularScan.cpp
@@ -26,6 +26,11 @@ ISpecularScan::ISpecularScan(IAxis* axis, double lambda0)
 
 ISpecularScan::~ISpecularScan() = default;
 
+void ISpecularScan::setIntensity(double intensity)
+{
+    m_intensity = intensity;
+}
+
 void ISpecularScan::setPolarization(R3 bloch_vector)
 {
     m_beamPolarization.reset(new R3(bloch_vector));
diff --git a/Sim/Scan/ISpecularScan.h b/Sim/Scan/ISpecularScan.h
index b859d0d90ea211145b3b9f0a3d88327006b702bc..06a0fb9e8ea71f60bcfb3af731693d94cc806c29 100644
--- a/Sim/Scan/ISpecularScan.h
+++ b/Sim/Scan/ISpecularScan.h
@@ -37,6 +37,9 @@ public:
 
     ISpecularScan* clone() const override = 0;
 
+    //! Sets the intensity fudge factor
+    void setIntensity(double intensity);
+
     //! Sets the polarization density matrix according to the given Bloch vector
     void setPolarization(R3 bloch_vector);
 
@@ -54,6 +57,11 @@ public:
         return m_lambda0;
     }
 
+    double intensity() const
+    {
+        return m_intensity;
+    }
+
     SpinMatrix polarizerMatrix() const;
     SpinMatrix analyzerMatrix() const;
 
@@ -84,6 +92,7 @@ public:
 protected:
     const std::unique_ptr<IAxis> m_axis;
     double m_lambda0;
+    double m_intensity = 1; //!< Fudge factor to adjust for imperfect normalization of exp. data
     std::unique_ptr<R3> m_beamPolarization; //!< Bloch vector encoding the beam's polarization
     std::unique_ptr<PolFilter> m_polAnalyzer;
 #endif // SWIG
diff --git a/Sim/Scan/QzScan.cpp b/Sim/Scan/QzScan.cpp
index cbd40a7248e79292396095fb6a9ea56cacc1a64b..fec6018925f50b88e6bc52e5b0aecbceb0139365 100644
--- a/Sim/Scan/QzScan.cpp
+++ b/Sim/Scan/QzScan.cpp
@@ -56,6 +56,7 @@ QzScan::~QzScan() = default;
 QzScan* QzScan::clone() const
 {
     auto* result = new QzScan(*m_axis);
+    result->setIntensity(intensity());
     if (m_qz_distrib) {
         result->m_qz_distrib.reset(m_qz_distrib->clone());
         result->m_resol_width = m_resol_width;
diff --git a/Sim/Simulation/SpecularSimulation.cpp b/Sim/Simulation/SpecularSimulation.cpp
index 0afa47651111790fcd485f89915fe7f9279ffc5b..cc25952b685c0b2a2a98d5d03f0116e65acfbe0b 100644
--- a/Sim/Simulation/SpecularSimulation.cpp
+++ b/Sim/Simulation/SpecularSimulation.cpp
@@ -79,7 +79,7 @@ SimulationResult SpecularSimulation::packResult()
     std::vector<double> vec(m_scan->nScan(), 0.0);
     for (size_t i = 0; i < nElements(); i++) {
         const SpecularElement& ele = m_eles.at(i);
-        vec.at(ele.i_out()) += m_cache.at(i) * ele.weight();
+        vec.at(ele.i_out()) += m_scan->intensity() * m_cache.at(i) * ele.weight();
     }
 
     Datafield data({m_scan->coordinateAxis()->clone()}, vec);
diff --git a/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_0.int.gz b/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_0.int.gz
index b2f16487df55dc272d22685ea73d23edec67c7ec..980f5373ed49843c2b1bbf9fb00d98152a0a2814 100644
Binary files a/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_0.int.gz and b/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_0.int.gz differ
diff --git a/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_Q.int.gz b/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_Q.int.gz
index bfc3be38bd780895131b22400fcf0d96f31df1e9..88238ece61b859ca3393ca7660e65d73463ffd22 100644
Binary files a/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_Q.int.gz and b/Tests/ReferenceData/Suite/InstrumentDefinitionComparison_Q.int.gz differ
diff --git a/Tests/SimFactory/MakeSimulations.cpp b/Tests/SimFactory/MakeSimulations.cpp
index 1c8d34cbd0d61dc06a559c2ea3d68ae325df3bff..d2b26237d99224e32de6efe3cebcc7d9eedd8a31 100644
--- a/Tests/SimFactory/MakeSimulations.cpp
+++ b/Tests/SimFactory/MakeSimulations.cpp
@@ -359,9 +359,10 @@ ISpecularScan* test::makeSimulation::BasicSpecularScan(bool vsQ)
 }
 
 std::unique_ptr<SpecularSimulation> test::makeSimulation::BasicSpecular(const MultiLayer& sample,
-                                                                        bool vsQ)
+                                                                        bool vsQ, double intensity)
 {
     std::unique_ptr<ISpecularScan> scan(BasicSpecularScan(vsQ));
+    scan->setIntensity(intensity);
 
     auto result = std::make_unique<SpecularSimulation>(*scan, sample);
     result->options().setUseAvgMaterials(true);
diff --git a/Tests/SimFactory/MakeSimulations.h b/Tests/SimFactory/MakeSimulations.h
index 9a62d181635f365a2cc146db5eaa6a4fb7b31805..b5636938d87f86905f7a76ee3c95fabcfeeb7b47 100644
--- a/Tests/SimFactory/MakeSimulations.h
+++ b/Tests/SimFactory/MakeSimulations.h
@@ -57,7 +57,8 @@ std::unique_ptr<ScatteringSimulation> ExtraLongWavelengthGISAS(const MultiLayer&
 std::unique_ptr<OffspecSimulation> MiniOffspec(const MultiLayer& sample);
 
 ISpecularScan* BasicSpecularScan(bool vsQ);
-std::unique_ptr<SpecularSimulation> BasicSpecular(const MultiLayer& sample, bool vsQ);
+std::unique_ptr<SpecularSimulation> BasicSpecular(const MultiLayer& sample, bool vsQ,
+                                                  double intensity = 1.);
 std::unique_ptr<SpecularSimulation> BasicYPolarizedSpecular(const MultiLayer& sample,
                                                             const std::string& polCase, bool vsQ);
 std::unique_ptr<SpecularSimulation> SpecularWithGaussianBeam(const MultiLayer& sample);
diff --git a/Tests/Suite/Common/TestSuite.h b/Tests/Suite/Common/TestSuite.h
index b3cbe0cdb659c2a3ff022c16e374db4052b04221..79c733c60ebe42b6ec4bc50b78a4bf52b9a26435 100644
--- a/Tests/Suite/Common/TestSuite.h
+++ b/Tests/Suite/Common/TestSuite.h
@@ -690,11 +690,12 @@ TEST(TESTNAME, SpecularWithSlicing3)
 }
 
 TEST(TESTNAME, InstrumentDefinitionComparison)
+// also tests persistent result for the intensity fudge parameter
 {
     auto* sample = ExemplarySamples::createPlainMultiLayerBySLD();
-    auto sim = test::makeSimulation::BasicSpecular(*sample, false);
+    auto sim = test::makeSimulation::BasicSpecular(*sample, false, 1.05);
     EXPECT_TRUE(runTest("InstrumentDefinitionComparison_0", *sim, 1e-10));
-    auto simQ = test::makeSimulation::BasicSpecular(*sample, true);
+    auto simQ = test::makeSimulation::BasicSpecular(*sample, true, 1.05);
     EXPECT_TRUE(runTest("InstrumentDefinitionComparison_Q", *simQ, 1e-10));
 }
 
diff --git a/auto/Wrap/libBornAgainSim.py b/auto/Wrap/libBornAgainSim.py
index 8922bc5253404d8e7f4ba679c21893a4a4384fe4..518ca0ba900cf18aa509c96a5c25fb8a1261c843 100644
--- a/auto/Wrap/libBornAgainSim.py
+++ b/auto/Wrap/libBornAgainSim.py
@@ -2536,6 +2536,10 @@ class ISpecularScan(libBornAgainBase.ICloneable):
         r"""clone(ISpecularScan self) -> ISpecularScan"""
         return _libBornAgainSim.ISpecularScan_clone(self)
 
+    def setIntensity(self, intensity):
+        r"""setIntensity(ISpecularScan self, double intensity)"""
+        return _libBornAgainSim.ISpecularScan_setIntensity(self, intensity)
+
     def setPolarization(self, bloch_vector):
         r"""setPolarization(ISpecularScan self, R3 bloch_vector)"""
         return _libBornAgainSim.ISpecularScan_setPolarization(self, bloch_vector)
diff --git a/auto/Wrap/libBornAgainSim_wrap.cpp b/auto/Wrap/libBornAgainSim_wrap.cpp
index 52a725c89738f055136e4da8ac2370479e0d64ba..dd51898bbd111d1335454ea09aa29edee5f61e53 100644
--- a/auto/Wrap/libBornAgainSim_wrap.cpp
+++ b/auto/Wrap/libBornAgainSim_wrap.cpp
@@ -31940,6 +31940,35 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_ISpecularScan_setIntensity(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  ISpecularScan *arg1 = (ISpecularScan *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "ISpecularScan_setIntensity", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ISpecularScan, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ISpecularScan_setIntensity" "', argument " "1"" of type '" "ISpecularScan *""'"); 
+  }
+  arg1 = reinterpret_cast< ISpecularScan * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ISpecularScan_setIntensity" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setIntensity(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_ISpecularScan_setPolarization(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   ISpecularScan *arg1 = (ISpecularScan *) 0 ;
@@ -36311,6 +36340,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "FitObjective_swiginit", FitObjective_swiginit, METH_VARARGS, NULL},
 	 { "delete_ISpecularScan", _wrap_delete_ISpecularScan, METH_O, "delete_ISpecularScan(ISpecularScan self)"},
 	 { "ISpecularScan_clone", _wrap_ISpecularScan_clone, METH_O, "ISpecularScan_clone(ISpecularScan self) -> ISpecularScan"},
+	 { "ISpecularScan_setIntensity", _wrap_ISpecularScan_setIntensity, METH_VARARGS, "ISpecularScan_setIntensity(ISpecularScan self, double intensity)"},
 	 { "ISpecularScan_setPolarization", _wrap_ISpecularScan_setPolarization, METH_VARARGS, "ISpecularScan_setPolarization(ISpecularScan self, R3 bloch_vector)"},
 	 { "ISpecularScan_setAnalyzer", _wrap_ISpecularScan_setAnalyzer, METH_VARARGS, "ISpecularScan_setAnalyzer(ISpecularScan self, R3 direction, double efficiency, double total_transmission)"},
 	 { "ISpecularScan_swigregister", ISpecularScan_swigregister, METH_O, NULL},