From 1d54f296331bd0799a4bf09a0bf121cc870522e1 Mon Sep 17 00:00:00 2001
From: Walter Van Herck <w.van.herck@fz-juelich.de>
Date: Mon, 17 Dec 2012 15:32:12 +0100
Subject: [PATCH] Changed all form factor evaluate functions to accept only
 outgoing wave vector bin

---
 App/src/TestFormFactor.cpp                    |  3 +-
 App/src/TestMiscellaneous.cpp                 | 13 +++--
 .../inc/DecouplingApproximationStrategy.h     |  2 +-
 .../inc/IInterferenceFunctionStrategy.h       |  3 +-
 Core/Algorithms/inc/LayerDWBASimulation.h     | 15 ++---
 .../LocalMonodisperseApproximationStrategy.h  |  2 +-
 .../src/DecouplingApproximationStrategy.cpp   |  8 +--
 Core/Algorithms/src/DiffuseDWBASimulation.cpp | 16 +++---
 Core/Algorithms/src/LayerDWBASimulation.cpp   |  8 +++
 .../src/LayerDecoratorDWBASimulation.cpp      |  9 +--
 ...LocalMonodisperseApproximationStrategy.cpp |  8 +--
 Core/FormFactors/inc/FormFactorCrystal.h      |  7 ++-
 Core/FormFactors/inc/FormFactorCylinder.h     |  1 -
 Core/FormFactors/inc/FormFactorDWBA.h         | 39 +------------
 Core/FormFactors/inc/FormFactorDWBAConstZ.h   |  2 +-
 .../inc/FormFactorDecoratorDebyeWaller.h      |  9 +--
 .../inc/FormFactorDecoratorFactor.h           |  6 +-
 .../FormFactorDecoratorMultiPositionFactor.h  |  9 +--
 .../inc/FormFactorDecoratorPositionFactor.h   | 10 ++--
 .../inc/FormFactorDecoratorTransformation.h   | 18 +++---
 Core/FormFactors/inc/FormFactorFullSphere.h   |  1 -
 Core/FormFactors/inc/FormFactorGauss.h        |  1 -
 Core/FormFactors/inc/FormFactorLorentz.h      |  1 -
 .../inc/FormFactorParallelepiped.h            |  2 -
 Core/FormFactors/inc/FormFactorPrism3.h       |  2 -
 Core/FormFactors/inc/FormFactorPyramid.h      |  1 -
 .../inc/FormFactorSphereGaussianRadius.h      |  5 +-
 Core/FormFactors/inc/FormFactorWeighted.h     |  2 +-
 Core/FormFactors/inc/IFormFactor.h            | 19 +++++--
 Core/FormFactors/inc/IFormFactorBorn.h        | 34 ++++++++---
 .../inc/IFormFactorBornSeparable.h            | 23 ++++----
 Core/FormFactors/src/FormFactorCrystal.cpp    | 23 +++++++-
 Core/FormFactors/src/FormFactorDWBA.cpp       | 56 ++++---------------
 Core/FormFactors/src/FormFactorDWBAConstZ.cpp | 21 +------
 .../src/FormFactorDecoratorTransformation.cpp |  1 -
 Core/FormFactors/src/FormFactorWeighted.cpp   |  4 +-
 Core/FormFactors/src/IFormFactorBorn.cpp      | 28 ++++------
 Core/Tools/inc/Bin.h                          |  3 +
 38 files changed, 193 insertions(+), 222 deletions(-)

diff --git a/App/src/TestFormFactor.cpp b/App/src/TestFormFactor.cpp
index 75b3644abb9..e76f72cfead 100644
--- a/App/src/TestFormFactor.cpp
+++ b/App/src/TestFormFactor.cpp
@@ -42,7 +42,8 @@ void TestFormFactor::execute()
         double alpha_f = M_PI*(*p_z_axis)[index_z]/180.0;
         cvector_t k_f;
         k_f.setLambdaAlphaPhi(lambda, alpha_f, phi_f);
-        *it = std::pow(std::abs(m_ff.evaluate(k_i, k_f, alpha_i, alpha_f)),2);
+        Bin1DCVector k_f_zero_bin(k_f, k_f);
+        *it = std::pow(std::abs(m_ff.evaluate(k_i, k_f_zero_bin, alpha_i, alpha_f)),2);
         ++it;
     }
     draw();
diff --git a/App/src/TestMiscellaneous.cpp b/App/src/TestMiscellaneous.cpp
index 119724b3436..039c9a8766c 100644
--- a/App/src/TestMiscellaneous.cpp
+++ b/App/src/TestMiscellaneous.cpp
@@ -236,18 +236,19 @@ void TestMiscellaneous::test_FormFactor()
 
         cvector_t q(x,y,z);
         cvector_t q0(0,0,0);
-        double value = std::abs(ff.evaluate(q,q0, 0.0, 0.0));
-        if(iz==50) h2->Fill(x,y,std::abs(ff.evaluate(q,q0, 0.0, 0.0)));
+        Bin1DCVector q0_bin(q0, q0);
+        double value = std::abs(ff.evaluate(q,q0_bin, 0.0, 0.0));
+        if(iz==50) h2->Fill(x,y,std::abs(ff.evaluate(q,q0_bin, 0.0, 0.0)));
 
-        h3->Fill(x,y,z,std::abs(ff.evaluate(q,q0, 0.0, 0.0)));
+        h3->Fill(x,y,z,std::abs(ff.evaluate(q,q0_bin, 0.0, 0.0)));
 
         if(iy==0 && iz==0) {
             cvector_t kx(x,1.0,1.0);
             cvector_t ky(1.0,x,1.0);
             cvector_t kz(1.0,1.0,x);
-            h1[0]->Fill(x, std::abs(ff.evaluate(kx,q0, 0.0, 0.0)));
-            h1[1]->Fill(x, std::abs(ff.evaluate(ky,q0, 0.0, 0.0)));
-            h1[2]->Fill(x, std::abs(ff.evaluate(kz,q0, 0.0, 0.0)));
+            h1[0]->Fill(x, std::abs(ff.evaluate(kx,q0_bin, 0.0, 0.0)));
+            h1[1]->Fill(x, std::abs(ff.evaluate(ky,q0_bin, 0.0, 0.0)));
+            h1[2]->Fill(x, std::abs(ff.evaluate(kz,q0_bin, 0.0, 0.0)));
         }
 
         vh2_xy[iz] ->Fill(x,y,value);
diff --git a/Core/Algorithms/inc/DecouplingApproximationStrategy.h b/Core/Algorithms/inc/DecouplingApproximationStrategy.h
index 665720c9d9c..1b6e3214b5f 100644
--- a/Core/Algorithms/inc/DecouplingApproximationStrategy.h
+++ b/Core/Algorithms/inc/DecouplingApproximationStrategy.h
@@ -26,7 +26,7 @@ public:
     virtual void init(const std::vector<IFormFactor *> &form_factors,
             const std::vector<double> &fractions,
             const std::vector<IInterferenceFunction *> &interference_functions);
-    virtual double evaluate(const cvector_t &k_i, const cvector_t &k_f,
+    virtual double evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin,
             double alpha_i, double alpha_f) const;
 private:
     bool checkVectorSizes();
diff --git a/Core/Algorithms/inc/IInterferenceFunctionStrategy.h b/Core/Algorithms/inc/IInterferenceFunctionStrategy.h
index e98dc3ce3d3..abaa04a2f14 100644
--- a/Core/Algorithms/inc/IInterferenceFunctionStrategy.h
+++ b/Core/Algorithms/inc/IInterferenceFunctionStrategy.h
@@ -17,6 +17,7 @@
 #include "Types.h"
 #include "IFormFactor.h"
 #include "IInterferenceFunction.h"
+#include "Bin.h"
 
 #include <vector>
 
@@ -27,7 +28,7 @@ public:
     virtual void init(const std::vector<IFormFactor *> &form_factors,
             const std::vector<double> &fractions,
             const std::vector<IInterferenceFunction *> &interference_functions);
-    virtual double evaluate(const cvector_t &k_i, const cvector_t &k_f,
+    virtual double evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin,
             double alpha_i, double alpha_f) const=0;
 protected:
     void deleteVectors();
diff --git a/Core/Algorithms/inc/LayerDWBASimulation.h b/Core/Algorithms/inc/LayerDWBASimulation.h
index f0a14436212..dbc8de41660 100644
--- a/Core/Algorithms/inc/LayerDWBASimulation.h
+++ b/Core/Algorithms/inc/LayerDWBASimulation.h
@@ -20,21 +20,22 @@
 class LayerDWBASimulation : public DWBASimulation
 {
 public:
-    LayerDWBASimulation();
-    virtual ~LayerDWBASimulation();
+   LayerDWBASimulation();
+   virtual ~LayerDWBASimulation();
 
    void setKzFunction(const IDoubleToComplexMap &kz_function);
    void setReflectionTransmissionFunction(const IDoubleToPairOfComplexMap &rt_map);
    void setKzAndRTFunctions(const IDoubleToComplexMap &kz_function, const IDoubleToPairOfComplexMap &rt_map);
 
 protected:
-    IDoubleToComplexMap *mp_kz_function;
-    IDoubleToPairOfComplexMap *mp_RT_function;
+   Bin1DCVector getKfBin(double wavelength, const Bin1D &alpha_bin, const Bin1D &phi_bin);
+   IDoubleToComplexMap *mp_kz_function;
+   IDoubleToPairOfComplexMap *mp_RT_function;
 
 private:
-    //! copy constructor and assignment operator are hidden
-    LayerDWBASimulation(const LayerDWBASimulation &);
-    LayerDWBASimulation &operator=(const LayerDWBASimulation &);
+   //! copy constructor and assignment operator are hidden
+   LayerDWBASimulation(const LayerDWBASimulation &);
+   LayerDWBASimulation &operator=(const LayerDWBASimulation &);
 };
 
 #endif /* LAYERDWBASIMULATION_H_ */
diff --git a/Core/Algorithms/inc/LocalMonodisperseApproximationStrategy.h b/Core/Algorithms/inc/LocalMonodisperseApproximationStrategy.h
index 723cc78b5e8..88248221712 100644
--- a/Core/Algorithms/inc/LocalMonodisperseApproximationStrategy.h
+++ b/Core/Algorithms/inc/LocalMonodisperseApproximationStrategy.h
@@ -25,7 +25,7 @@ public:
     virtual void init(const std::vector<IFormFactor *> &form_factors,
             const std::vector<double> &fractions,
             const std::vector<IInterferenceFunction *> &interference_functions);
-    virtual double evaluate(const cvector_t &k_i, const cvector_t &k_f,
+    virtual double evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin,
             double alpha_i, double alpha_f) const;
 private:
     bool checkVectorSizes();
diff --git a/Core/Algorithms/src/DecouplingApproximationStrategy.cpp b/Core/Algorithms/src/DecouplingApproximationStrategy.cpp
index 806bfa1fc89..06da60a892e 100644
--- a/Core/Algorithms/src/DecouplingApproximationStrategy.cpp
+++ b/Core/Algorithms/src/DecouplingApproximationStrategy.cpp
@@ -16,19 +16,19 @@ void DecouplingApproximationStrategy::init(
     }
 }
 
-double DecouplingApproximationStrategy::evaluate(const cvector_t &k_i,
-        const cvector_t &k_f, double alpha_i, double alpha_f) const
+double DecouplingApproximationStrategy::evaluate(const cvector_t& k_i,
+        const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
     double intensity = 0.0;
     complex_t amplitude = complex_t(0.0, 0.0);
     for (size_t i=0; i<m_form_factors.size(); ++i) {
-        complex_t ff = m_form_factors[i]->evaluate(k_i, k_f, alpha_i, alpha_f);
+        complex_t ff = m_form_factors[i]->evaluate(k_i, k_f_bin, alpha_i, alpha_f);
         double fraction = m_fractions[i];
         amplitude += fraction*ff;
         intensity += fraction*(std::norm(ff));
     }
     double amplitude_norm = std::norm(amplitude);
-    double itf_function = m_interference_functions[0]->evaluate(k_i-k_f);
+    double itf_function = m_interference_functions[0]->evaluate(k_i-k_f_bin.getMidPoint());
     return intensity + amplitude_norm*(itf_function-1.0);
 }
 
diff --git a/Core/Algorithms/src/DiffuseDWBASimulation.cpp b/Core/Algorithms/src/DiffuseDWBASimulation.cpp
index 356703ac397..c74f83050db 100644
--- a/Core/Algorithms/src/DiffuseDWBASimulation.cpp
+++ b/Core/Algorithms/src/DiffuseDWBASimulation.cpp
@@ -17,26 +17,24 @@ DiffuseDWBASimulation::~DiffuseDWBASimulation()
 
 void DiffuseDWBASimulation::run()
 {
-    const std::string s_phi_f(NDetector2d::PHI_AXIS_NAME);
-    const std::string s_alpha_f(NDetector2d::ALPHA_AXIS_NAME);
-
     std::vector<DiffuseFormFactorTerm *> diffuse_terms;
     size_t nbr_heights = 50;
     size_t samples_per_particle = 9;
     initDiffuseFormFactorTerms(diffuse_terms, nbr_heights, samples_per_particle);
     double wavevector_scattering_factor = M_PI/getWaveLength()/getWaveLength();
+    cvector_t k_ij = m_ki;
+    k_ij.setZ(-mp_kz_function->evaluate(-m_alpha_i));
 
     DWBASimulation::iterator it_intensity = begin();
     while ( it_intensity != end() ) {
-        double phi_f = getDWBAIntensity().getValueOfAxis(s_phi_f, it_intensity.getIndex());
-        double alpha_f = getDWBAIntensity().getValueOfAxis(s_alpha_f, it_intensity.getIndex());
+        Bin1D phi_bin = getDWBAIntensity().getBinOfAxis(NDetector2d::PHI_AXIS_NAME, it_intensity.getIndex());
+        Bin1D alpha_bin = getDWBAIntensity().getBinOfAxis(NDetector2d::ALPHA_AXIS_NAME, it_intensity.getIndex());
+        double alpha_f = alpha_bin.getMidPoint();
         if (alpha_f<0) {
             ++it_intensity;
             continue;
         }
-        cvector_t k_f;
-        k_f.setLambdaAlphaPhi(getWaveLength(), alpha_f, phi_f);
-        k_f.setZ(mp_kz_function->evaluate(alpha_f));
+        Bin1DCVector k_f_bin = getKfBin(getWaveLength(), alpha_bin, phi_bin);
 
         double total_intensity = 0.0;
         for (size_t i=0; i<diffuse_terms.size(); ++i) {
@@ -44,7 +42,7 @@ void DiffuseDWBASimulation::run()
             complex_t amplitude(0.0, 0.0);
             double intensity = 0.0;
             for (size_t j=0; j<p_diffuse_term->m_form_factors.size(); ++j) {
-                complex_t amp = p_diffuse_term->m_form_factors[j]->evaluate(m_ki, k_f, -m_alpha_i, alpha_f);
+                complex_t amp = p_diffuse_term->m_form_factors[j]->evaluate(k_ij, k_f_bin, -m_alpha_i, alpha_f);
                 amplitude += p_diffuse_term->m_probabilities[j]*amp;
                 intensity += p_diffuse_term->m_probabilities[j]*std::norm(amp);
             }
diff --git a/Core/Algorithms/src/LayerDWBASimulation.cpp b/Core/Algorithms/src/LayerDWBASimulation.cpp
index 4c43ebbbc61..058b245801b 100644
--- a/Core/Algorithms/src/LayerDWBASimulation.cpp
+++ b/Core/Algorithms/src/LayerDWBASimulation.cpp
@@ -29,3 +29,11 @@ void LayerDWBASimulation::setKzAndRTFunctions(const IDoubleToComplexMap &kz_func
     setKzFunction(kz_function);
     setReflectionTransmissionFunction(rt_map);
 }
+
+Bin1DCVector LayerDWBASimulation::getKfBin(double wavelength, const Bin1D& alpha_bin, const Bin1D& phi_bin)
+{
+    Bin1DCVector k_f_bin(wavelength, alpha_bin, phi_bin);
+    k_f_bin.m_q_lower.setZ(mp_kz_function->evaluate(alpha_bin.m_lower));
+    k_f_bin.m_q_upper.setZ(mp_kz_function->evaluate(alpha_bin.m_upper));
+    return k_f_bin;
+}
diff --git a/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp b/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp
index 4ffd0ed59f4..e6d917e636a 100644
--- a/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp
+++ b/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp
@@ -85,6 +85,9 @@ void LayerDecoratorDWBASimulation::calculateCoherentIntensity(IInterferenceFunct
     double wavelength = getWaveLength();
     double total_surface_density = mp_layer_decorator->getTotalParticleSurfaceDensity();
 
+    cvector_t k_ij = m_ki;
+    k_ij.setZ(-mp_kz_function->evaluate(-m_alpha_i));
+
     DWBASimulation::iterator it_intensity = begin();
     while ( it_intensity != end() )
     {
@@ -95,10 +98,8 @@ void LayerDecoratorDWBASimulation::calculateCoherentIntensity(IInterferenceFunct
             ++it_intensity;
             continue;
         }
-        Bin1DCVector k_f_bin(wavelength, alpha_bin, phi_bin);
-        cvector_t k_f = k_f_bin.getMidPoint();
-        k_f.setZ(mp_kz_function->evaluate(alpha_f));
-        *it_intensity = p_strategy->evaluate(m_ki, k_f, -m_alpha_i, alpha_f)*total_surface_density;
+        Bin1DCVector k_f_bin = getKfBin(wavelength, alpha_bin, phi_bin);
+        *it_intensity = p_strategy->evaluate(k_ij, k_f_bin, -m_alpha_i, alpha_f)*total_surface_density;
         ++it_intensity;
     }
 }
diff --git a/Core/Algorithms/src/LocalMonodisperseApproximationStrategy.cpp b/Core/Algorithms/src/LocalMonodisperseApproximationStrategy.cpp
index eedea35b345..0d980249f20 100644
--- a/Core/Algorithms/src/LocalMonodisperseApproximationStrategy.cpp
+++ b/Core/Algorithms/src/LocalMonodisperseApproximationStrategy.cpp
@@ -16,13 +16,13 @@ void LocalMonodisperseApproximationStrategy::init(
     }
 }
 
-double LocalMonodisperseApproximationStrategy::evaluate(
-        const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+double LocalMonodisperseApproximationStrategy::evaluate(const cvector_t& k_i,
+        const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
     double intensity = 0.0;
     for (size_t i=0; i<m_form_factors.size(); ++i) {
-        complex_t ff = m_form_factors[i]->evaluate(k_i, k_f, alpha_i, alpha_f);
-        double itf_function = m_interference_functions[i]->evaluate(k_i-k_f);
+        complex_t ff = m_form_factors[i]->evaluate(k_i, k_f_bin, alpha_i, alpha_f);
+        double itf_function = m_interference_functions[i]->evaluate(k_i-k_f_bin.getMidPoint());
         double fraction = m_fractions[i];
         intensity += fraction*(itf_function*std::norm(ff));
     }
diff --git a/Core/FormFactors/inc/FormFactorCrystal.h b/Core/FormFactors/inc/FormFactorCrystal.h
index eaf7d37005e..0aba2cee293 100644
--- a/Core/FormFactors/inc/FormFactorCrystal.h
+++ b/Core/FormFactors/inc/FormFactorCrystal.h
@@ -38,8 +38,13 @@ public:
         mp_meso_form_factor->setBinSizes(delta_qy, delta_qz);
     }
 
-protected:
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
+
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
+
+protected:
+    virtual double getVolume() const;
+
 private:
     void calculateLargestReciprocalDistance();
     Lattice m_lattice;
diff --git a/Core/FormFactors/inc/FormFactorCylinder.h b/Core/FormFactors/inc/FormFactorCylinder.h
index bcf47a5cd75..7a860d36941 100644
--- a/Core/FormFactors/inc/FormFactorCylinder.h
+++ b/Core/FormFactors/inc/FormFactorCylinder.h
@@ -30,7 +30,6 @@ public:
 
     virtual double getHeight() const { return m_height; }
 
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
 private:
diff --git a/Core/FormFactors/inc/FormFactorDWBA.h b/Core/FormFactors/inc/FormFactorDWBA.h
index 729781129e2..33ba353ca39 100644
--- a/Core/FormFactors/inc/FormFactorDWBA.h
+++ b/Core/FormFactors/inc/FormFactorDWBA.h
@@ -26,20 +26,6 @@ public:
 
     virtual FormFactorDWBA *clone() const;
 
-//    void setTransmissionFunction(const IDoubleToComplexFunction &p_T)
-//    {
-//        mp_T = p_T.clone();
-//    }
-//    void setReflectionFunction(const IDoubleToComplexFunction &p_R)
-//    {
-//        mp_R = p_R.clone();
-//    }
-
-//    void setReflectionTransmissionFunction(const IDoubleToComplexFunction &p_rt)
-//    {
-//        mp_RT = p_rt.clone();
-//    }
-
     void setReflectionTransmissionFunction(const IDoubleToPairOfComplexMap &p_rt)
     {
         delete mp_RT;
@@ -47,40 +33,21 @@ public:
     }
 
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
+
 protected:
     //! copy constructor and assignment operator are hidden since there is a clone method
     FormFactorDWBA(const FormFactorDWBA &);
     FormFactorDWBA &operator=(const FormFactorDWBA &);
 
-//    complex_t getT(double alpha) const;
-//    complex_t getR(double alpha) const;
-//    complex_t getX(double alpha) const;
     const complexpair_t &getRT(double alpha) const;
-    void calculateTerms(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    void calculateTerms(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
-//    IDoubleToComplexFunction *mp_T;
-//    IDoubleToComplexFunction *mp_R;
     IDoubleToPairOfComplexMap *mp_RT;
 
     mutable complex_t m_term_S, m_term_RS, m_term_SR, m_term_RSR;
 };
 
-//inline complex_t FormFactorDWBA::getT(double alpha) const
-//{
-//    return mp_T->evaluate(alpha);
-//}
-
-//inline complex_t FormFactorDWBA::getR(double alpha) const
-//{
-//    return mp_R->evaluate(alpha);
-//}
-
-//inline complex_t FormFactorDWBA::getX(double alpha) const
-//{
-//    return getR(alpha)/getT(alpha);
-//}
-
 inline const complexpair_t &FormFactorDWBA::getRT(double alpha) const
 {
     return mp_RT->evaluate(alpha);
diff --git a/Core/FormFactors/inc/FormFactorDWBAConstZ.h b/Core/FormFactors/inc/FormFactorDWBAConstZ.h
index 5ff0a84bd1b..996f1c11d38 100644
--- a/Core/FormFactors/inc/FormFactorDWBAConstZ.h
+++ b/Core/FormFactors/inc/FormFactorDWBAConstZ.h
@@ -23,7 +23,7 @@ public:
     virtual ~FormFactorDWBAConstZ();
     virtual FormFactorDWBAConstZ *clone() const;
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f,
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin,
     		double alpha_i, double alpha_f) const;
 protected:
     double m_depth;
diff --git a/Core/FormFactors/inc/FormFactorDecoratorDebyeWaller.h b/Core/FormFactors/inc/FormFactorDecoratorDebyeWaller.h
index 9fab511bd4e..db7a5f99712 100644
--- a/Core/FormFactors/inc/FormFactorDecoratorDebyeWaller.h
+++ b/Core/FormFactors/inc/FormFactorDecoratorDebyeWaller.h
@@ -26,7 +26,7 @@ public:
     virtual FormFactorDecoratorDebyeWaller *clone() const;
     virtual ~FormFactorDecoratorDebyeWaller() {}
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
     virtual int getNumberOfStochasticParameters() const;
 
@@ -78,13 +78,14 @@ inline FormFactorDecoratorDebyeWaller* FormFactorDecoratorDebyeWaller::clone() c
     return new FormFactorDecoratorDebyeWaller(mp_form_factor->clone(), m_h_dw_factor, m_r_dw_factor);
 }
 
-inline complex_t FormFactorDecoratorDebyeWaller::evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+inline complex_t FormFactorDecoratorDebyeWaller::evaluate(const cvector_t& k_i,
+        const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
-    cvector_t q = k_i - k_f;
+    cvector_t q = k_i - k_f_bin.getMidPoint();
     double qr2 = std::norm(q.x()) + std::norm(q.y());
     double qz2 = std::norm(q.z());
     double dw = std::exp(-qz2*m_h_dw_factor-qr2*m_r_dw_factor);
-    return dw*mp_form_factor->evaluate(k_i, k_f, alpha_i, alpha_f);
+    return dw*mp_form_factor->evaluate(k_i, k_f_bin, alpha_i, alpha_f);
 }
 
 inline int FormFactorDecoratorDebyeWaller::getNumberOfStochasticParameters() const
diff --git a/Core/FormFactors/inc/FormFactorDecoratorFactor.h b/Core/FormFactors/inc/FormFactorDecoratorFactor.h
index c6f1c9a996f..08bb8fd4259 100644
--- a/Core/FormFactors/inc/FormFactorDecoratorFactor.h
+++ b/Core/FormFactors/inc/FormFactorDecoratorFactor.h
@@ -24,7 +24,7 @@ public:
     virtual FormFactorDecoratorFactor *clone() const;
     virtual ~FormFactorDecoratorFactor() {}
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
     virtual int getNumberOfStochasticParameters() const;
 
@@ -45,9 +45,9 @@ inline FormFactorDecoratorFactor* FormFactorDecoratorFactor::clone() const
     return new FormFactorDecoratorFactor(mp_form_factor->clone(), m_factor);
 }
 
-inline complex_t FormFactorDecoratorFactor::evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+inline complex_t FormFactorDecoratorFactor::evaluate(const cvector_t& k_i, const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
-    return m_factor*mp_form_factor->evaluate(k_i, k_f, alpha_i, alpha_f);
+    return m_factor*mp_form_factor->evaluate(k_i, k_f_bin, alpha_i, alpha_f);
 }
 
 inline int FormFactorDecoratorFactor::getNumberOfStochasticParameters() const
diff --git a/Core/FormFactors/inc/FormFactorDecoratorMultiPositionFactor.h b/Core/FormFactors/inc/FormFactorDecoratorMultiPositionFactor.h
index 7b4a336e1df..9fef1e4ce14 100644
--- a/Core/FormFactors/inc/FormFactorDecoratorMultiPositionFactor.h
+++ b/Core/FormFactors/inc/FormFactorDecoratorMultiPositionFactor.h
@@ -23,7 +23,7 @@ public:
     virtual ~FormFactorDecoratorMultiPositionFactor() {};
     virtual FormFactorDecoratorMultiPositionFactor *clone() const;
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
     virtual int getNumberOfStochasticParameters() const {
         return mp_form_factor->getNumberOfStochasticParameters();
@@ -46,10 +46,11 @@ inline FormFactorDecoratorMultiPositionFactor* FormFactorDecoratorMultiPositionF
     return new FormFactorDecoratorMultiPositionFactor(*mp_form_factor, m_positions);
 }
 
-inline complex_t FormFactorDecoratorMultiPositionFactor::evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+inline complex_t FormFactorDecoratorMultiPositionFactor::evaluate(const cvector_t& k_i,
+        const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
-    cvector_t q = k_i - k_f;
-    return getPositionsFactor(q)*mp_form_factor->evaluate(k_i, k_f, alpha_i, alpha_f);
+    cvector_t q = k_i - k_f_bin.getMidPoint();
+    return getPositionsFactor(q)*mp_form_factor->evaluate(k_i, k_f_bin, alpha_i, alpha_f);
 }
 
 inline complex_t FormFactorDecoratorMultiPositionFactor::getPositionsFactor(cvector_t q) const
diff --git a/Core/FormFactors/inc/FormFactorDecoratorPositionFactor.h b/Core/FormFactors/inc/FormFactorDecoratorPositionFactor.h
index b0525b9c607..ee09352e677 100644
--- a/Core/FormFactors/inc/FormFactorDecoratorPositionFactor.h
+++ b/Core/FormFactors/inc/FormFactorDecoratorPositionFactor.h
@@ -27,7 +27,7 @@ public:
     virtual ~FormFactorDecoratorPositionFactor() {}
     virtual FormFactorDecoratorPositionFactor *clone() const;
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
     virtual int getNumberOfStochasticParameters() const {
         return mp_form_factor->getNumberOfStochasticParameters();
@@ -49,13 +49,13 @@ inline FormFactorDecoratorPositionFactor* FormFactorDecoratorPositionFactor::clo
     return new FormFactorDecoratorPositionFactor(*mp_form_factor, m_position);
 }
 
-inline complex_t FormFactorDecoratorPositionFactor::evaluate(const cvector_t &k_i,
-        const cvector_t &k_f, double alpha_i, double alpha_f) const
+inline complex_t FormFactorDecoratorPositionFactor::evaluate(const cvector_t& k_i,
+        const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
-    cvector_t q = k_i - k_f;
+    cvector_t q = k_i - k_f_bin.getMidPoint();
     complex_t qr = q.x()*m_position.x() + q.y()*m_position.y() + q.z()*m_position.z();
     complex_t pos_factor = std::exp(complex_t(0.0, 1.0)*qr);
-    return pos_factor*mp_form_factor->evaluate(k_i, k_f, alpha_i, alpha_f);
+    return pos_factor*mp_form_factor->evaluate(k_i, k_f_bin, alpha_i, alpha_f);
 }
 
 #endif /* FORMFACTORDECORATORPOSITIONFACTOR_H_ */
diff --git a/Core/FormFactors/inc/FormFactorDecoratorTransformation.h b/Core/FormFactors/inc/FormFactorDecoratorTransformation.h
index f0e42174d69..644887fe642 100644
--- a/Core/FormFactors/inc/FormFactorDecoratorTransformation.h
+++ b/Core/FormFactors/inc/FormFactorDecoratorTransformation.h
@@ -25,7 +25,8 @@ public:
     virtual FormFactorDecoratorTransformation *clone() const;
     virtual ~FormFactorDecoratorTransformation();
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
+
     virtual int getNumberOfStochasticParameters() const;
 
 protected:
@@ -55,14 +56,17 @@ inline FormFactorDecoratorTransformation::~FormFactorDecoratorTransformation()
     delete mp_inverse_transform;
 }
 
-inline complex_t FormFactorDecoratorTransformation::evaluate(const cvector_t &k_i, const cvector_t &k_f,
+inline complex_t FormFactorDecoratorTransformation::evaluate(const cvector_t& k_i, const Bin1DCVector& k_f_bin,
         double alpha_i, double alpha_f) const
 {
-    cvector_t newki(k_i);
-    cvector_t newkf(k_f);
-    newki.transform(*mp_inverse_transform);
-    newkf.transform(*mp_inverse_transform);
-    return mp_form_factor->evaluate(newki, newkf, alpha_i, alpha_f);
+    cvector_t new_ki(k_i);
+    cvector_t new_kf_lower(k_f_bin.m_q_lower);
+    cvector_t new_kf_upper(k_f_bin.m_q_upper);
+    new_ki.transform(*mp_inverse_transform);
+    new_kf_lower.transform(*mp_inverse_transform);
+    new_kf_upper.transform(*mp_inverse_transform);
+    Bin1DCVector new_kf_bin(new_kf_lower, new_kf_upper);
+    return mp_form_factor->evaluate(new_ki, new_kf_bin, alpha_i, alpha_f);
 }
 
 inline int FormFactorDecoratorTransformation::getNumberOfStochasticParameters() const
diff --git a/Core/FormFactors/inc/FormFactorFullSphere.h b/Core/FormFactors/inc/FormFactorFullSphere.h
index c69d3471dbf..e6bd0a52a91 100644
--- a/Core/FormFactors/inc/FormFactorFullSphere.h
+++ b/Core/FormFactors/inc/FormFactorFullSphere.h
@@ -32,7 +32,6 @@ public:
 
     virtual double getHeight() const { return 2.0*m_radius; }
 
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
 private:
diff --git a/Core/FormFactors/inc/FormFactorGauss.h b/Core/FormFactors/inc/FormFactorGauss.h
index 3dce81ba6f5..7502f852dd6 100644
--- a/Core/FormFactors/inc/FormFactorGauss.h
+++ b/Core/FormFactors/inc/FormFactorGauss.h
@@ -28,7 +28,6 @@ public:
 
     virtual int getNumberOfStochasticParameters() const { return 2; }
 
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
 private:
diff --git a/Core/FormFactors/inc/FormFactorLorentz.h b/Core/FormFactors/inc/FormFactorLorentz.h
index 10adb8eccce..ed7cc2a2172 100644
--- a/Core/FormFactors/inc/FormFactorLorentz.h
+++ b/Core/FormFactors/inc/FormFactorLorentz.h
@@ -28,7 +28,6 @@ public:
 
     virtual int getNumberOfStochasticParameters() const { return 2; }
 
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
 private:
diff --git a/Core/FormFactors/inc/FormFactorParallelepiped.h b/Core/FormFactors/inc/FormFactorParallelepiped.h
index 913d2b69875..4b5da7425e7 100644
--- a/Core/FormFactors/inc/FormFactorParallelepiped.h
+++ b/Core/FormFactors/inc/FormFactorParallelepiped.h
@@ -35,8 +35,6 @@ public:
 
     virtual double getHeight() const { return m_height; }
 
-
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
 private:
diff --git a/Core/FormFactors/inc/FormFactorPrism3.h b/Core/FormFactors/inc/FormFactorPrism3.h
index 0cc9249c71c..d32ecbe16f5 100644
--- a/Core/FormFactors/inc/FormFactorPrism3.h
+++ b/Core/FormFactors/inc/FormFactorPrism3.h
@@ -30,8 +30,6 @@ public:
 
     virtual double getHeight() const { return m_height; }
 
-
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
 private:
diff --git a/Core/FormFactors/inc/FormFactorPyramid.h b/Core/FormFactors/inc/FormFactorPyramid.h
index 5bb8d76139c..6bb373c723f 100644
--- a/Core/FormFactors/inc/FormFactorPyramid.h
+++ b/Core/FormFactors/inc/FormFactorPyramid.h
@@ -38,7 +38,6 @@ public:
 
     virtual double getHeight() const { return m_height; }
 
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
 private:
diff --git a/Core/FormFactors/inc/FormFactorSphereGaussianRadius.h b/Core/FormFactors/inc/FormFactorSphereGaussianRadius.h
index a8b83fcbecb..7ccfb587da8 100644
--- a/Core/FormFactors/inc/FormFactorSphereGaussianRadius.h
+++ b/Core/FormFactors/inc/FormFactorSphereGaussianRadius.h
@@ -32,14 +32,13 @@ public:
 
     virtual double getHeight() const { return p_ff_sphere->getHeight(); }
 
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 private:
     double calculateMeanR3() const;
     double m_mean; //!< This is the mean radius
     double m_sigma;
     double m_mean_r3; //!< This is the radius that gives the mean volume
-    IFormFactor *p_ff_sphere;
+    FormFactorFullSphere *p_ff_sphere;
     cvector_t m_zero_vector;
 };
 
@@ -75,7 +74,7 @@ inline complex_t FormFactorSphereGaussianRadius::evaluate_for_q(const cvector_t
 {
     double q2 = std::norm(q.x()) + std::norm(q.y()) + std::norm(q.z());
     double dw = std::exp(-q2*m_sigma*m_sigma/2.0);
-    return dw*p_ff_sphere->evaluate(q, m_zero_vector, 0.0, 0.0);
+    return dw*p_ff_sphere->evaluate_for_q(q);
 }
 
 inline double FormFactorSphereGaussianRadius::calculateMeanR3() const
diff --git a/Core/FormFactors/inc/FormFactorWeighted.h b/Core/FormFactors/inc/FormFactorWeighted.h
index e4d9967882f..c2ec2da19cb 100644
--- a/Core/FormFactors/inc/FormFactorWeighted.h
+++ b/Core/FormFactors/inc/FormFactorWeighted.h
@@ -27,7 +27,7 @@ public:
 
     virtual void setAmbientRefractiveIndex(complex_t refractive_index);
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
     virtual int getNumberOfStochasticParameters() const;
 
diff --git a/Core/FormFactors/inc/IFormFactor.h b/Core/FormFactors/inc/IFormFactor.h
index 1b40c1eb3cb..e034c20fbd2 100644
--- a/Core/FormFactors/inc/IFormFactor.h
+++ b/Core/FormFactors/inc/IFormFactor.h
@@ -18,6 +18,7 @@
 #include "ISample.h"
 #include "MemberFunctionIntegrator.h"
 #include "MathFunctions.h"
+#include "Bin.h"
 
 
 //- -------------------------------------------------------------------
@@ -38,10 +39,19 @@ public:
     //! pass the refractive index of the ambient material in which this particle is embedded
     virtual void setAmbientRefractiveIndex(complex_t refractive_index) { (void)refractive_index; }
 
-    //! calculate scattering amplitude for complex wavevectors
+    //! calculate scattering amplitude for complex wavevector bin
     //! @param k_i   incoming wavevector
-    //! @param k_f   outgoing wavevector
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const=0;
+    //! @param k_f_bin   outgoing wavevector bin
+    //! @param alpha_i incident angle wrt scattering surface
+    //! @param alpha_f outgoing angle wrt scattering surface
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const=0;
+//    {
+//        (void)k_i;
+//        (void)k_f_bin;
+//        (void)alpha_i;
+//        (void)alpha_f;
+//        return complex_t(0.0, 0.0);
+//    }
 
     //! return number of variable/stochastic parameters
     virtual int getNumberOfStochasticParameters() const { return 0; }
@@ -76,7 +86,8 @@ public:
 inline double IFormFactor::getVolume() const
 {
     cvector_t zero;
-    return std::abs(evaluate(zero, zero, 0.0, 0.0));
+    Bin1DCVector zero_bin(zero, zero);
+    return std::abs(evaluate(zero, zero_bin, 0.0, 0.0));
 }
 
 inline double IFormFactor::getHeight() const
diff --git a/Core/FormFactors/inc/IFormFactorBorn.h b/Core/FormFactors/inc/IFormFactorBorn.h
index 18e5f8223ae..b9dc274fc2b 100644
--- a/Core/FormFactors/inc/IFormFactorBorn.h
+++ b/Core/FormFactors/inc/IFormFactorBorn.h
@@ -30,28 +30,31 @@ public:
     virtual ~IFormFactorBorn() {}
     virtual IFormFactorBorn *clone() const=0;
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
     virtual void setBinSizes(double delta_qy, double delta_qz);
 
-protected:
     //! evaluate scattering amplitude for complex wavevector
     //! @param q  wavevector transfer \f$q\equiv k_i-k_f\f$
     virtual complex_t evaluate_for_q(const cvector_t &q) const=0;
 
+protected:
     //! override volume getter to avoid infinite loop caused by big bin approximation
     virtual double getVolume() const;
 
     //! calculate radial part of scattering amplitude for large bins
-    double bigRadialPart(const cvector_t& q) const;
+    double bigRadialPart(const Bin1DCVector& q_bin) const;
 
     //! calculate z-part of scattering amplitude for large bins
-    complex_t bigZPart(const cvector_t& q) const;
+    complex_t bigZPart(const Bin1DCVector& q_bin) const;
 
     bool m_use_large_bin_approximation_radial;  //!< indicates if large bin size approximation should be used in the qx-qy direction
     bool m_use_large_bin_approximation_z;  //!< indicates if large bin size approximation should be used in the qz direction
     double m_bin_qy, m_bin_qz;  //!< the sizes of the bins in q space
 private:
+    //! determine if a large bin size approximation should be used
+    bool useLargeBinApproximation(const Bin1DCVector &q_bin) const;
+
     //! calculates an approximate intensity that does not contain rapid oscillations
     double bigRadialIntegrand(double qR, void *params) const;
 
@@ -59,15 +62,15 @@ private:
     double bigZPartIntegral(double qH2) const;
 };
 
-inline complex_t IFormFactorBorn::evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+inline complex_t IFormFactorBorn::evaluate(const cvector_t& k_i, const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
     (void)alpha_i;
     (void)alpha_f;
-    cvector_t q = k_i - k_f;
-    if (m_use_large_bin_approximation_radial || m_use_large_bin_approximation_z) {
-        return getVolume()*bigZPart(q)*bigRadialPart(q);
+    Bin1DCVector q_bin(k_i - k_f_bin.m_q_lower, k_i - k_f_bin.m_q_upper);
+    if (useLargeBinApproximation(q_bin)) {
+        return getVolume()*bigZPart(q_bin)*bigRadialPart(q_bin);
     }
-    return evaluate_for_q(q);
+    return evaluate_for_q(q_bin.getMidPoint());
 }
 
 inline double IFormFactorBorn::getVolume() const
@@ -76,4 +79,17 @@ inline double IFormFactorBorn::getVolume() const
     return std::abs(evaluate_for_q(zero));
 }
 
+inline bool IFormFactorBorn::useLargeBinApproximation(const Bin1DCVector &q_bin) const
+{
+    double delta_qr = std::abs( q_bin.getDelta().magxy() );
+    if ( delta_qr > M_PI/2.0/getRadius() ) {
+        return true;
+    }
+    double delta_qz = std::abs( q_bin.getDelta().z() );
+    if ( delta_qz > M_PI/2.0/getHeight() ) {
+        return true;
+    }
+    return false;
+}
+
 #endif /* IFORMFACTORBORN_H_ */
diff --git a/Core/FormFactors/inc/IFormFactorBornSeparable.h b/Core/FormFactors/inc/IFormFactorBornSeparable.h
index f3d6e8fecd9..93fc8409362 100644
--- a/Core/FormFactors/inc/IFormFactorBornSeparable.h
+++ b/Core/FormFactors/inc/IFormFactorBornSeparable.h
@@ -31,11 +31,11 @@ public:
     virtual ~IFormFactorBornSeparable() {}
     virtual IFormFactorBornSeparable *clone() const=0;
 
-    virtual complex_t evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const;
+    virtual complex_t evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin, double alpha_i, double alpha_f) const;
 
-protected:
     virtual complex_t evaluate_for_q(const cvector_t &q) const;
 
+protected:
     //! evaluate radial part of scattering amplitude for complex wavevector
     virtual complex_t evaluate_for_q_radial(const cvector_t &q) const=0;
 
@@ -43,21 +43,24 @@ protected:
     virtual complex_t evaluate_for_q_z(const cvector_t &q) const=0;
 };
 
-inline complex_t IFormFactorBornSeparable::evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+inline complex_t IFormFactorBornSeparable::evaluate(const cvector_t& k_i,
+        const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
     (void)alpha_i;
     (void)alpha_f;
     complex_t radial, zpart;
-    cvector_t q = k_i - k_f;
-    if (m_use_large_bin_approximation_radial) {
-        radial = bigRadialPart(q);
+    Bin1DCVector q_bin(k_i - k_f_bin.m_q_lower, k_i - k_f_bin.m_q_upper);
+    double delta_qr = std::abs( q_bin.getDelta().magxy() );
+    if ( delta_qr > M_PI/2.0/getRadius() ) {
+        radial = bigRadialPart(q_bin);
     } else {
-        radial = evaluate_for_q_radial(q);
+    radial = evaluate_for_q_radial(q_bin.getMidPoint());
     }
-    if (m_use_large_bin_approximation_z) {
-        zpart = bigZPart(q);
+    double delta_qz = std::abs( q_bin.getDelta().z() );
+    if ( delta_qz > M_PI/2.0/getHeight() ) {
+        zpart = bigZPart(q_bin);
     } else {
-        zpart = evaluate_for_q_z(q);
+        zpart = evaluate_for_q_z(q_bin.getMidPoint());
     }
     return getVolume()*radial*zpart;
 }
diff --git a/Core/FormFactors/src/FormFactorCrystal.cpp b/Core/FormFactors/src/FormFactorCrystal.cpp
index 5d0f3b2da6b..c15c7f52499 100644
--- a/Core/FormFactors/src/FormFactorCrystal.cpp
+++ b/Core/FormFactors/src/FormFactorCrystal.cpp
@@ -40,7 +40,18 @@ void FormFactorCrystal::setAmbientRefractiveIndex(
 
 complex_t FormFactorCrystal::evaluate_for_q(const cvector_t &q) const
 {
+    (void)q;
+    throw LogicErrorException("evaluate_for_q() should never be called explicitly for FormFactorCrystal");
+}
+
+complex_t FormFactorCrystal::evaluate(const cvector_t& k_i,
+        const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
+{
+    (void)alpha_i;
+    (void)alpha_f;
     // construct a real reciprocal vector
+    Bin1DCVector q_bin(k_i - k_f_bin.m_q_lower, k_i - k_f_bin.m_q_upper);
+    cvector_t q = q_bin.getMidPoint();
     kvector_t q_real(q.x().real(), q.y().real(), q.z().real());
     cvector_t k_zero;
     // calculate the used radius in function of the reciprocal lattice scale
@@ -57,9 +68,10 @@ complex_t FormFactorCrystal::evaluate_for_q(const cvector_t &q) const
     //for (std::vector<kvector_t>::const_iterator it = rec_vectors.begin(); it != rec_vectors.end(); ++it) {
     for (KVectorContainer::const_iterator it = rec_vectors.begin(); it != rec_vectors.end(); ++it) {
         cvector_t q_i((*it).x(), (*it).y(), (*it).z());
-        cvector_t q_min_q_i = q - q_i;
-        complex_t basis_factor = mp_basis_form_factor->evaluate(q_i, k_zero, 0.0, 0.0);
-        complex_t meso_factor = mp_meso_form_factor->evaluate(q_min_q_i, k_zero, 0.0, 0.0);
+        Bin1DCVector min_q_i_zero_bin(-q_i, -q_i);
+        Bin1DCVector q_i_min_q(q_i - q_bin.m_q_lower, q_i - q_bin.m_q_upper);
+        complex_t basis_factor = mp_basis_form_factor->evaluate(k_zero, min_q_i_zero_bin, 0.0, 0.0);
+        complex_t meso_factor = mp_meso_form_factor->evaluate(k_zero, q_i_min_q, 0.0, 0.0);
         result += basis_factor*meso_factor;
     }
     // the transformed delta train gets a factor of (2pi)^3/V, but the (2pi)^3 is cancelled by the convolution of Fourier transforms :
@@ -67,6 +79,11 @@ complex_t FormFactorCrystal::evaluate_for_q(const cvector_t &q) const
     return result/volume;
 }
 
+double FormFactorCrystal::getVolume() const
+{
+    return mp_meso_form_factor->getVolume();
+}
+
 void FormFactorCrystal::calculateLargestReciprocalDistance()
 {
     kvector_t a1 = m_lattice.getBasisVectorA();
diff --git a/Core/FormFactors/src/FormFactorDWBA.cpp b/Core/FormFactors/src/FormFactorDWBA.cpp
index a0559340c01..271d24a15c8 100644
--- a/Core/FormFactors/src/FormFactorDWBA.cpp
+++ b/Core/FormFactors/src/FormFactorDWBA.cpp
@@ -2,7 +2,6 @@
 
 FormFactorDWBA::FormFactorDWBA(IFormFactor *p_form_factor)
     : IFormFactorDecorator(p_form_factor)
-//    , mp_T(0), mp_R(0)
     , mp_RT(0)
 {
     setName("FormFactorDWBA");
@@ -10,67 +9,34 @@ FormFactorDWBA::FormFactorDWBA(IFormFactor *p_form_factor)
 
 FormFactorDWBA::~FormFactorDWBA()
 {
-//    delete mp_T;
-//    delete mp_R;
     delete mp_RT;
 }
 
-complex_t FormFactorDWBA::evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+complex_t FormFactorDWBA::evaluate(const cvector_t& k_i, const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
-    calculateTerms(k_i, k_f, alpha_i, alpha_f);
+    calculateTerms(k_i, k_f_bin, alpha_i, alpha_f);
     return m_term_S + m_term_RS + m_term_SR + m_term_RSR;
 }
 
-
-//void FormFactorDWBA::calculateTerms(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const {
-//    cvector_t k_itilde(k_i.x(), k_i.y(), -k_i.z());
-//    cvector_t k_ftilde(k_f.x(), k_f.y(), -k_f.z());
-//    // The four different scattering contributions; S stands for scattering off the particle, R for reflection off the layer interface
-//    m_term_S = getT(alpha_i)*mp_form_factor->evaluate(k_i, k_f, alpha_i, alpha_f)*getT(alpha_f);
-//    m_term_RS = getR(alpha_i)*mp_form_factor->evaluate(k_itilde, k_f, alpha_i, alpha_f)*getT(alpha_f);
-//    m_term_SR = getT(alpha_i)*mp_form_factor->evaluate(k_i, k_ftilde, alpha_i, alpha_f)*getR(alpha_f);
-//    m_term_RSR = getR(alpha_i)*mp_form_factor->evaluate(k_itilde, k_ftilde, alpha_i, alpha_f)*getR(alpha_f);
-//}
-
-//void FormFactorDWBA::calculateTerms(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const {
-//    cvector_t k_itilde(k_i.x(), k_i.y(), -k_i.z());
-//    cvector_t k_ftilde(k_f.x(), k_f.y(), -k_f.z());
-//    // The four different scattering contributions; S stands for scattering off the particle, R for reflection off the layer interface
-//    complex_t T_alpha_i = getT(alpha_i);
-//    complex_t R_alpha_i = getR(alpha_i);
-//    complex_t T_alpha_f = getT(alpha_f);
-//    complex_t R_alpha_f = getR(alpha_f);
-//    m_term_S = T_alpha_i*mp_form_factor->evaluate(k_i, k_f, alpha_i, alpha_f)*T_alpha_f;
-//    m_term_RS = R_alpha_i*mp_form_factor->evaluate(k_itilde, k_f, alpha_i, alpha_f)*T_alpha_f;
-//    m_term_SR = T_alpha_i*mp_form_factor->evaluate(k_i, k_ftilde, alpha_i, alpha_f)*R_alpha_f;
-//    m_term_RSR = R_alpha_i*mp_form_factor->evaluate(k_itilde, k_ftilde, alpha_i, alpha_f)*R_alpha_f;
-//}
-
-void FormFactorDWBA::calculateTerms(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const {
+void FormFactorDWBA::calculateTerms(const cvector_t& k_i, const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
+{
     cvector_t k_itilde(k_i.x(), k_i.y(), -k_i.z());
-    cvector_t k_ftilde(k_f.x(), k_f.y(), -k_f.z());
+    Bin1DCVector k_f_bin_tilde =  k_f_bin;
+    k_f_bin_tilde.m_q_lower.setZ( -k_f_bin_tilde.m_q_lower.z() );
+    k_f_bin_tilde.m_q_upper.setZ( -k_f_bin_tilde.m_q_upper.z() );
     // The four different scattering contributions; S stands for scattering off the particle, R for reflection off the layer interface
     const complexpair_t &ai_RT = getRT(alpha_i);
     const complexpair_t &af_RT = getRT(alpha_f);
 
-//    complex_t T_alpha_i = getT(alpha_i);
-//    complex_t R_alpha_i = getR(alpha_i);
-//    complex_t T_alpha_f = getT(alpha_f);
-//    complex_t R_alpha_f = getR(alpha_f);
-    m_term_S = ai_RT.second*mp_form_factor->evaluate(k_i, k_f, alpha_i, alpha_f)*af_RT.second;
-    m_term_RS = ai_RT.first*mp_form_factor->evaluate(k_itilde, k_f, alpha_i, alpha_f)*af_RT.second;
-    m_term_SR = ai_RT.second*mp_form_factor->evaluate(k_i, k_ftilde, alpha_i, alpha_f)*af_RT.first;
-    m_term_RSR = ai_RT.first*mp_form_factor->evaluate(k_itilde, k_ftilde, alpha_i, alpha_f)*af_RT.first;
+    m_term_S = ai_RT.second*mp_form_factor->evaluate(k_i, k_f_bin, alpha_i, alpha_f)*af_RT.second;
+    m_term_RS = ai_RT.first*mp_form_factor->evaluate(k_itilde, k_f_bin, alpha_i, alpha_f)*af_RT.second;
+    m_term_SR = ai_RT.second*mp_form_factor->evaluate(k_i, k_f_bin_tilde, alpha_i, alpha_f)*af_RT.first;
+    m_term_RSR = ai_RT.first*mp_form_factor->evaluate(k_itilde, k_f_bin_tilde, alpha_i, alpha_f)*af_RT.first;
 }
 
-
 FormFactorDWBA* FormFactorDWBA::clone() const
 {
     FormFactorDWBA *p_new = new FormFactorDWBA(mp_form_factor->clone());
-//    p_new->setTransmissionFunction(mp_T->clone());
-//    p_new->setReflectionFunction(mp_R->clone());
-//    p_new->setTransmissionFunction(*mp_T);
-//    p_new->setReflectionFunction(*mp_R);
     p_new->setReflectionTransmissionFunction(*mp_RT);
     return p_new;
 }
diff --git a/Core/FormFactors/src/FormFactorDWBAConstZ.cpp b/Core/FormFactors/src/FormFactorDWBAConstZ.cpp
index db8b5447e10..442a8b0fe10 100644
--- a/Core/FormFactors/src/FormFactorDWBAConstZ.cpp
+++ b/Core/FormFactors/src/FormFactorDWBAConstZ.cpp
@@ -11,12 +11,12 @@ FormFactorDWBAConstZ::~FormFactorDWBAConstZ()
 {
 }
 
-complex_t FormFactorDWBAConstZ::evaluate(const cvector_t &k_i, const cvector_t &k_f,
+complex_t FormFactorDWBAConstZ::evaluate(const cvector_t &k_i, const Bin1DCVector &k_f_bin,
 		double alpha_i, double alpha_f) const
 {
-	calculateTerms(k_i, k_f, alpha_i, alpha_f);
+	calculateTerms(k_i, k_f_bin, alpha_i, alpha_f);
 	complex_t k_iz = k_i.z();
-	complex_t k_fz = k_f.z();
+	complex_t k_fz = k_f_bin.getMidPoint().z();
 	m_term_S *= getDepthPhase(k_iz-k_fz);
 	m_term_RS *= getDepthPhase(-k_iz-k_fz);
 	m_term_SR *= getDepthPhase(k_iz+k_fz);
@@ -24,24 +24,9 @@ complex_t FormFactorDWBAConstZ::evaluate(const cvector_t &k_i, const cvector_t &
 	return m_term_S + m_term_RS + m_term_SR + m_term_RSR;
 }
 
-//FormFactorDWBAConstZ* FormFactorDWBAConstZ::clone() const
-//{
-//    FormFactorDWBAConstZ *p_new = new FormFactorDWBAConstZ(mp_form_factor->clone(), m_depth);
-//    p_new->setTransmissionFunction(*mp_T);
-//    p_new->setReflectionFunction(*mp_R);
-//    return p_new;
-//}
-
 FormFactorDWBAConstZ* FormFactorDWBAConstZ::clone() const
 {
     FormFactorDWBAConstZ *p_new = new FormFactorDWBAConstZ(mp_form_factor->clone(), m_depth);
     p_new->setReflectionTransmissionFunction(*mp_RT);
     return p_new;
 }
-
-
-//complex_t FormFactorDWBAConstZ::getDepthPhase(const complex_t &q_z) const
-//{
-//	complex_t exponent = -complex_t(0.0,1.0)*q_z*m_depth; // Minus sign for depth (m_depth > 0)
-//	return std::exp(exponent);
-//}
diff --git a/Core/FormFactors/src/FormFactorDecoratorTransformation.cpp b/Core/FormFactors/src/FormFactorDecoratorTransformation.cpp
index c378eb9f79d..a2e6b5dbdba 100644
--- a/Core/FormFactors/src/FormFactorDecoratorTransformation.cpp
+++ b/Core/FormFactors/src/FormFactorDecoratorTransformation.cpp
@@ -1,2 +1 @@
 #include "FormFactorDecoratorTransformation.h"
-
diff --git a/Core/FormFactors/src/FormFactorWeighted.cpp b/Core/FormFactors/src/FormFactorWeighted.cpp
index 5ad7499d63f..f40b89fb123 100644
--- a/Core/FormFactors/src/FormFactorWeighted.cpp
+++ b/Core/FormFactors/src/FormFactorWeighted.cpp
@@ -35,11 +35,11 @@ void FormFactorWeighted::setAmbientRefractiveIndex(complex_t refractive_index)
     }
 }
 
-complex_t FormFactorWeighted::evaluate(const cvector_t &k_i, const cvector_t &k_f, double alpha_i, double alpha_f) const
+complex_t FormFactorWeighted::evaluate(const cvector_t& k_i, const Bin1DCVector& k_f_bin, double alpha_i, double alpha_f) const
 {
     complex_t result(0.0, 0.0);
     for (size_t index=0; index<m_form_factors.size(); ++index) {
-        complex_t ff_evaluate = m_form_factors[index]->evaluate(k_i, k_f, alpha_i, alpha_f);
+        complex_t ff_evaluate = m_form_factors[index]->evaluate(k_i, k_f_bin, alpha_i, alpha_f);
         result += m_weights[index]*ff_evaluate;
     }
     return result;
diff --git a/Core/FormFactors/src/IFormFactorBorn.cpp b/Core/FormFactors/src/IFormFactorBorn.cpp
index 28d27f04510..c71d64aa860 100644
--- a/Core/FormFactors/src/IFormFactorBorn.cpp
+++ b/Core/FormFactors/src/IFormFactorBorn.cpp
@@ -26,31 +26,22 @@ void IFormFactorBorn::setBinSizes(double delta_qy, double delta_qz)
     }
 }
 
-double IFormFactorBorn::bigRadialPart(const cvector_t& q) const
+double IFormFactorBorn::bigRadialPart(const Bin1DCVector& q_bin) const
 {
-    // radial part
-    double qR = std::abs(q.magxy()*getRadius());
-
-    // radial parameters
-    double effective_bin_size_r = m_bin_qy*getRadius();
-    double qRmin = qR - effective_bin_size_r/2.0;
-    double qRmax = qR + effective_bin_size_r/2.0;
-
     // modulus of the radial part
     MemberFunctionIntegrator<IFormFactorBorn>::mem_function p_mf = &IFormFactorBorn::bigRadialIntegrand;
     MemberFunctionIntegrator<IFormFactorBorn> integrator(p_mf, this);
-    double average_intensity = integrator.integrate(qRmin, qRmax, (void*)0)/effective_bin_size_r;
+    double average_intensity = integrator.integrate(0.0, 1.0, (void*)(&q_bin));
     return std::sqrt(average_intensity);
 }
 
-complex_t IFormFactorBorn::bigZPart(const cvector_t& q) const
+complex_t IFormFactorBorn::bigZPart(const Bin1DCVector& q_bin) const
 {
     // bin sizes in qz-direction times the height
-    complex_t qH2_c = q.z()*getHeight()/2.0;
-    double qH2 = std::abs(qH2_c);
-    double effective_bin_size_h2 = m_bin_qz*getHeight()/2.0; // qH2 is only half qz*H !
-    double qH2min = qH2 - effective_bin_size_h2/2.0;
-    double qH2max = qH2 + effective_bin_size_h2/2.0;
+    complex_t qH2_c = q_bin.getMidPoint().z()*getHeight()/2.0;
+    double qH2min = std::abs( q_bin.m_q_lower.z() )*getHeight()/2.0;
+    double qH2max = std::abs( q_bin.m_q_upper.z() )*getHeight()/2.0;
+    double effective_bin_size_h2 = std::abs(qH2max - qH2min);
 
     // phase from the height of the particle
     complex_t z_phase = std::exp(complex_t(0.0, 1.0)*qH2_c);
@@ -62,9 +53,10 @@ complex_t IFormFactorBorn::bigZPart(const cvector_t& q) const
     return z_phase*z_modulus;
 }
 
-double IFormFactorBorn::bigRadialIntegrand(double qR, void* params) const
+double IFormFactorBorn::bigRadialIntegrand(double t, void* params) const
 {
-    (void)params;
+    const Bin1DCVector *p_q_bin = static_cast<const Bin1DCVector *>(params);
+    double qR = std::abs( (p_q_bin->m_q_lower + t*p_q_bin->getDelta()).magxy() )*getRadius();
     static double a = 1.0;
     static double b = std::sqrt(M_PI/3.0/std::sqrt(3.0));
 
diff --git a/Core/Tools/inc/Bin.h b/Core/Tools/inc/Bin.h
index f17acbaccd1..42070f2f195 100644
--- a/Core/Tools/inc/Bin.h
+++ b/Core/Tools/inc/Bin.h
@@ -39,10 +39,13 @@ struct Bin1D
 struct Bin1DCVector
 {
     Bin1DCVector() {}
+    Bin1DCVector(const cvector_t &lower, const cvector_t &upper)
+        : m_q_lower(lower), m_q_upper(upper) {}
     Bin1DCVector(double wavelength, const Bin1D &alpha_bin, const Bin1D &phi_bin);
     cvector_t m_q_lower;  //!< lower bound of the bin
     cvector_t m_q_upper;  //!< upper bound of the bin
     cvector_t getMidPoint() const { return (m_q_lower + m_q_upper)/2.0; }
+    cvector_t getDelta() const { return m_q_upper - m_q_lower; }
 };
 
 //! equality operator for bins
-- 
GitLab