diff --git a/Core/PythonAPI/inc/FTDistribution2DCauchy.pypp.h b/Core/PythonAPI/inc/FTDistribution2DCauchy.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..8d8a3b8b61737323d4f58395b33ea70fa242738e
--- /dev/null
+++ b/Core/PythonAPI/inc/FTDistribution2DCauchy.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef FTDistribution2DCauchy_hpp__pyplusplus_wrapper
+#define FTDistribution2DCauchy_hpp__pyplusplus_wrapper
+
+void register_FTDistribution2DCauchy_class();
+
+#endif//FTDistribution2DCauchy_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/FormFactorBox.pypp.h b/Core/PythonAPI/inc/FormFactorBox.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..b90f796eab2bf8758e47e7a105a2b532ce384919
--- /dev/null
+++ b/Core/PythonAPI/inc/FormFactorBox.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef FormFactorBox_hpp__pyplusplus_wrapper
+#define FormFactorBox_hpp__pyplusplus_wrapper
+
+void register_FormFactorBox_class();
+
+#endif//FormFactorBox_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/IFTDistribution1D.pypp.h b/Core/PythonAPI/inc/IFTDistribution1D.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7f75d2e51dcaeb69132d5ab2f29d4d95c4e133d
--- /dev/null
+++ b/Core/PythonAPI/inc/IFTDistribution1D.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef IFTDistribution1D_hpp__pyplusplus_wrapper
+#define IFTDistribution1D_hpp__pyplusplus_wrapper
+
+void register_IFTDistribution1D_class();
+
+#endif//IFTDistribution1D_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/IFTDistribution2D.pypp.h b/Core/PythonAPI/inc/IFTDistribution2D.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..289bff6fe13fd0a5ba4cb50b1ffeb5e177b894c3
--- /dev/null
+++ b/Core/PythonAPI/inc/IFTDistribution2D.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef IFTDistribution2D_hpp__pyplusplus_wrapper
+#define IFTDistribution2D_hpp__pyplusplus_wrapper
+
+void register_IFTDistribution2D_class();
+
+#endif//IFTDistribution2D_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/InterferenceFunction2DLattice.pypp.h b/Core/PythonAPI/inc/InterferenceFunction2DLattice.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..dca4fea5d7746fd374591ab64a408e39e73a65f5
--- /dev/null
+++ b/Core/PythonAPI/inc/InterferenceFunction2DLattice.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef InterferenceFunction2DLattice_hpp__pyplusplus_wrapper
+#define InterferenceFunction2DLattice_hpp__pyplusplus_wrapper
+
+void register_InterferenceFunction2DLattice_class();
+
+#endif//InterferenceFunction2DLattice_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/InterferenceFunction2DParaCrystal.pypp.h b/Core/PythonAPI/inc/InterferenceFunction2DParaCrystal.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..599d61f1655d64dddc89669246f28a08a07fe847
--- /dev/null
+++ b/Core/PythonAPI/inc/InterferenceFunction2DParaCrystal.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef InterferenceFunction2DParaCrystal_hpp__pyplusplus_wrapper
+#define InterferenceFunction2DParaCrystal_hpp__pyplusplus_wrapper
+
+void register_InterferenceFunction2DParaCrystal_class();
+
+#endif//InterferenceFunction2DParaCrystal_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/Lattice2DIFParameters.pypp.h b/Core/PythonAPI/inc/Lattice2DIFParameters.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b7c2effbfbd394864b0067414fc79e94893764b
--- /dev/null
+++ b/Core/PythonAPI/inc/Lattice2DIFParameters.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef Lattice2DIFParameters_hpp__pyplusplus_wrapper
+#define Lattice2DIFParameters_hpp__pyplusplus_wrapper
+
+void register_Lattice2DIFParameters_class();
+
+#endif//Lattice2DIFParameters_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/ParticleBuilder.pypp.h b/Core/PythonAPI/inc/ParticleBuilder.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4d9df48a64956e0291dba286d6a77ec2d908548
--- /dev/null
+++ b/Core/PythonAPI/inc/ParticleBuilder.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef ParticleBuilder_hpp__pyplusplus_wrapper
+#define ParticleBuilder_hpp__pyplusplus_wrapper
+
+void register_ParticleBuilder_class();
+
+#endif//ParticleBuilder_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/PositionParticleInfo.pypp.h b/Core/PythonAPI/inc/PositionParticleInfo.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a0448a335fe92bf2a3a93df24364d44e9a4f750
--- /dev/null
+++ b/Core/PythonAPI/inc/PositionParticleInfo.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef PositionParticleInfo_hpp__pyplusplus_wrapper
+#define PositionParticleInfo_hpp__pyplusplus_wrapper
+
+void register_PositionParticleInfo_class();
+
+#endif//PositionParticleInfo_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/SimulationParameters.pypp.h b/Core/PythonAPI/inc/SimulationParameters.pypp.h
new file mode 100644
index 0000000000000000000000000000000000000000..1499898318348467f30d54547620af9be8dd671e
--- /dev/null
+++ b/Core/PythonAPI/inc/SimulationParameters.pypp.h
@@ -0,0 +1,8 @@
+// This file has been generated by Py++.
+
+#ifndef SimulationParameters_hpp__pyplusplus_wrapper
+#define SimulationParameters_hpp__pyplusplus_wrapper
+
+void register_SimulationParameters_class();
+
+#endif//SimulationParameters_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/src/FTDistribution2DCauchy.pypp.cpp b/Core/PythonAPI/src/FTDistribution2DCauchy.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..90b704baa8b4843033081a2c27ab248cd9dbf0c5
--- /dev/null
+++ b/Core/PythonAPI/src/FTDistribution2DCauchy.pypp.cpp
@@ -0,0 +1,209 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "FTDistribution2DCauchy.pypp.h"
+
+namespace bp = boost::python;
+
+struct FTDistribution2DCauchy_wrapper : FTDistribution2DCauchy, bp::wrapper< FTDistribution2DCauchy > {
+
+    FTDistribution2DCauchy_wrapper(FTDistribution2DCauchy const & arg )
+    : FTDistribution2DCauchy( arg )
+      , bp::wrapper< FTDistribution2DCauchy >(){
+        // copy constructor
+        
+    }
+
+    FTDistribution2DCauchy_wrapper(double omega_x, double omega_y )
+    : FTDistribution2DCauchy( omega_x, omega_y )
+      , bp::wrapper< FTDistribution2DCauchy >(){
+        // constructor
+    
+    }
+
+    virtual ::FTDistribution2DCauchy * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else{
+            return this->FTDistribution2DCauchy::clone(  );
+        }
+    }
+    
+    ::FTDistribution2DCauchy * default_clone(  ) const  {
+        return FTDistribution2DCauchy::clone( );
+    }
+
+    virtual double evaluate( double qx, double qy ) const  {
+        if( bp::override func_evaluate = this->get_override( "evaluate" ) )
+            return func_evaluate( qx, qy );
+        else{
+            return this->FTDistribution2DCauchy::evaluate( qx, qy );
+        }
+    }
+    
+    double default_evaluate( double qx, double qy ) const  {
+        return FTDistribution2DCauchy::evaluate( qx, qy );
+    }
+
+    virtual void transformToStarBasis( double qX, double qY, double alpha, double a, double b, double & qa, double & qb ) const  {
+        if( bp::override func_transformToStarBasis = this->get_override( "transformToStarBasis" ) )
+            func_transformToStarBasis( qX, qY, alpha, a, b, qa, qb );
+        else{
+            this->FTDistribution2DCauchy::transformToStarBasis( qX, qY, alpha, a, b, qa, qb );
+        }
+    }
+    
+    void default_transformToStarBasis( double qX, double qY, double alpha, double a, double b, double & qa, double & qb ) const  {
+        FTDistribution2DCauchy::transformToStarBasis( qX, qY, alpha, a, b, qa, qb );
+    }
+
+    virtual bool areParametersChanged(  ) {
+        if( bp::override func_areParametersChanged = this->get_override( "areParametersChanged" ) )
+            return func_areParametersChanged(  );
+        else{
+            return this->IParameterized::areParametersChanged(  );
+        }
+    }
+    
+    bool default_areParametersChanged(  ) {
+        return IParameterized::areParametersChanged( );
+    }
+
+    virtual ::ParameterPool * createParameterTree(  ) const  {
+        if( bp::override func_createParameterTree = this->get_override( "createParameterTree" ) )
+            return func_createParameterTree(  );
+        else{
+            return this->IParameterized::createParameterTree(  );
+        }
+    }
+    
+    ::ParameterPool * default_createParameterTree(  ) const  {
+        return IParameterized::createParameterTree( );
+    }
+
+    virtual void printParameters(  ) const  {
+        if( bp::override func_printParameters = this->get_override( "printParameters" ) )
+            func_printParameters(  );
+        else{
+            this->IParameterized::printParameters(  );
+        }
+    }
+    
+    void default_printParameters(  ) const  {
+        IParameterized::printParameters( );
+    }
+
+    virtual void setParametersAreChanged(  ) {
+        if( bp::override func_setParametersAreChanged = this->get_override( "setParametersAreChanged" ) )
+            func_setParametersAreChanged(  );
+        else{
+            this->IParameterized::setParametersAreChanged(  );
+        }
+    }
+    
+    void default_setParametersAreChanged(  ) {
+        IParameterized::setParametersAreChanged( );
+    }
+
+};
+
+void register_FTDistribution2DCauchy_class(){
+
+    bp::class_< FTDistribution2DCauchy_wrapper, bp::bases< IFTDistribution2D > >( "FTDistribution2DCauchy", bp::init< double, double >(( bp::arg("omega_x"), bp::arg("omega_y") )) )    
+        .def( 
+            "clone"
+            , (::FTDistribution2DCauchy * ( ::FTDistribution2DCauchy::* )(  ) const)(&::FTDistribution2DCauchy::clone)
+            , (::FTDistribution2DCauchy * ( FTDistribution2DCauchy_wrapper::* )(  ) const)(&FTDistribution2DCauchy_wrapper::default_clone)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "evaluate"
+            , (double ( ::FTDistribution2DCauchy::* )( double,double ) const)(&::FTDistribution2DCauchy::evaluate)
+            , (double ( FTDistribution2DCauchy_wrapper::* )( double,double ) const)(&FTDistribution2DCauchy_wrapper::default_evaluate)
+            , ( bp::arg("qx"), bp::arg("qy") ) )    
+        .def( 
+            "transformToStarBasis"
+            , (void ( ::FTDistribution2DCauchy::* )( double,double,double,double,double,double &,double & ) const)(&::FTDistribution2DCauchy::transformToStarBasis)
+            , (void ( FTDistribution2DCauchy_wrapper::* )( double,double,double,double,double,double &,double & ) const)(&FTDistribution2DCauchy_wrapper::default_transformToStarBasis)
+            , ( bp::arg("qX"), bp::arg("qY"), bp::arg("alpha"), bp::arg("a"), bp::arg("b"), bp::arg("qa"), bp::arg("qb") ) )    
+        .def( 
+            "areParametersChanged"
+            , (bool ( ::IParameterized::* )(  ) )(&::IParameterized::areParametersChanged)
+            , (bool ( FTDistribution2DCauchy_wrapper::* )(  ) )(&FTDistribution2DCauchy_wrapper::default_areParametersChanged) )    
+        .def( 
+            "createParameterTree"
+            , (::ParameterPool * ( ::IParameterized::* )(  ) const)(&::IParameterized::createParameterTree)
+            , (::ParameterPool * ( FTDistribution2DCauchy_wrapper::* )(  ) const)(&FTDistribution2DCauchy_wrapper::default_createParameterTree)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "printParameters"
+            , (void ( ::IParameterized::* )(  ) const)(&::IParameterized::printParameters)
+            , (void ( FTDistribution2DCauchy_wrapper::* )(  ) const)(&FTDistribution2DCauchy_wrapper::default_printParameters) )    
+        .def( 
+            "setParametersAreChanged"
+            , (void ( ::IParameterized::* )(  ) )(&::IParameterized::setParametersAreChanged)
+            , (void ( FTDistribution2DCauchy_wrapper::* )(  ) )(&FTDistribution2DCauchy_wrapper::default_setParametersAreChanged) );
+
+}
diff --git a/Core/PythonAPI/src/FormFactorBox.pypp.cpp b/Core/PythonAPI/src/FormFactorBox.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..296cb73a1e3657577e8f12d822fd5cbcd438b380
--- /dev/null
+++ b/Core/PythonAPI/src/FormFactorBox.pypp.cpp
@@ -0,0 +1,336 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "FormFactorBox.pypp.h"
+
+namespace bp = boost::python;
+
+struct FormFactorBox_wrapper : FormFactorBox, bp::wrapper< FormFactorBox > {
+
+    FormFactorBox_wrapper(double radius, double width, double height )
+    : FormFactorBox( radius, width, height )
+      , bp::wrapper< FormFactorBox >(){
+        // constructor
+    
+    }
+
+    virtual ::FormFactorBox * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else{
+            return this->FormFactorBox::clone(  );
+        }
+    }
+    
+    ::FormFactorBox * default_clone(  ) const  {
+        return FormFactorBox::clone( );
+    }
+
+    virtual ::complex_t evaluate_for_q( ::cvector_t const & q ) const  {
+        if( bp::override func_evaluate_for_q = this->get_override( "evaluate_for_q" ) )
+            return func_evaluate_for_q( boost::ref(q) );
+        else{
+            return this->FormFactorBox::evaluate_for_q( boost::ref(q) );
+        }
+    }
+    
+    ::complex_t default_evaluate_for_q( ::cvector_t const & q ) const  {
+        return FormFactorBox::evaluate_for_q( boost::ref(q) );
+    }
+
+    virtual double getHeight(  ) const  {
+        if( bp::override func_getHeight = this->get_override( "getHeight" ) )
+            return func_getHeight(  );
+        else{
+            return this->FormFactorBox::getHeight(  );
+        }
+    }
+    
+    double default_getHeight(  ) const  {
+        return FormFactorBox::getHeight( );
+    }
+
+    virtual int getNumberOfStochasticParameters(  ) const  {
+        if( bp::override func_getNumberOfStochasticParameters = this->get_override( "getNumberOfStochasticParameters" ) )
+            return func_getNumberOfStochasticParameters(  );
+        else{
+            return this->FormFactorBox::getNumberOfStochasticParameters(  );
+        }
+    }
+    
+    int default_getNumberOfStochasticParameters(  ) const  {
+        return FormFactorBox::getNumberOfStochasticParameters( );
+    }
+
+    virtual double getRadius(  ) const  {
+        if( bp::override func_getRadius = this->get_override( "getRadius" ) )
+            return func_getRadius(  );
+        else{
+            return this->FormFactorBox::getRadius(  );
+        }
+    }
+    
+    double default_getRadius(  ) const  {
+        return FormFactorBox::getRadius( );
+    }
+
+    virtual double getVolume(  ) const  {
+        if( bp::override func_getVolume = this->get_override( "getVolume" ) )
+            return func_getVolume(  );
+        else{
+            return this->FormFactorBox::getVolume(  );
+        }
+    }
+    
+    double default_getVolume(  ) const  {
+        return FormFactorBox::getVolume( );
+    }
+
+    virtual bool areParametersChanged(  ) {
+        if( bp::override func_areParametersChanged = this->get_override( "areParametersChanged" ) )
+            return func_areParametersChanged(  );
+        else{
+            return this->IParameterized::areParametersChanged(  );
+        }
+    }
+    
+    bool default_areParametersChanged(  ) {
+        return IParameterized::areParametersChanged( );
+    }
+
+    virtual void createDistributedFormFactors( ::std::vector< IFormFactor* > & form_factors, ::std::vector< double > & probabilities, ::size_t nbr_samples ) const  {
+        if( bp::override func_createDistributedFormFactors = this->get_override( "createDistributedFormFactors" ) )
+            func_createDistributedFormFactors( boost::ref(form_factors), boost::ref(probabilities), nbr_samples );
+        else{
+            this->IFormFactor::createDistributedFormFactors( boost::ref(form_factors), boost::ref(probabilities), nbr_samples );
+        }
+    }
+    
+    void default_createDistributedFormFactors( ::std::vector< IFormFactor* > & form_factors, ::std::vector< double > & probabilities, ::size_t nbr_samples ) const  {
+        IFormFactor::createDistributedFormFactors( boost::ref(form_factors), boost::ref(probabilities), nbr_samples );
+    }
+
+    virtual ::ParameterPool * createParameterTree(  ) const  {
+        if( bp::override func_createParameterTree = this->get_override( "createParameterTree" ) )
+            return func_createParameterTree(  );
+        else{
+            return this->IParameterized::createParameterTree(  );
+        }
+    }
+    
+    ::ParameterPool * default_createParameterTree(  ) const  {
+        return IParameterized::createParameterTree( );
+    }
+
+    virtual ::complex_t evaluate( ::cvector_t const & k_i, ::Bin1DCVector const & k_f_bin, double alpha_i, double alpha_f ) const  {
+        if( bp::override func_evaluate = this->get_override( "evaluate" ) )
+            return func_evaluate( boost::ref(k_i), boost::ref(k_f_bin), alpha_i, alpha_f );
+        else{
+            return this->IFormFactorBorn::evaluate( boost::ref(k_i), boost::ref(k_f_bin), alpha_i, alpha_f );
+        }
+    }
+    
+    ::complex_t default_evaluate( ::cvector_t const & k_i, ::Bin1DCVector const & k_f_bin, double alpha_i, double alpha_f ) const  {
+        return IFormFactorBorn::evaluate( boost::ref(k_i), boost::ref(k_f_bin), alpha_i, alpha_f );
+    }
+
+    virtual bool isDistributedFormFactor(  ) const  {
+        if( bp::override func_isDistributedFormFactor = this->get_override( "isDistributedFormFactor" ) )
+            return func_isDistributedFormFactor(  );
+        else{
+            return this->IFormFactor::isDistributedFormFactor(  );
+        }
+    }
+    
+    bool default_isDistributedFormFactor(  ) const  {
+        return IFormFactor::isDistributedFormFactor( );
+    }
+
+    virtual void printParameters(  ) const  {
+        if( bp::override func_printParameters = this->get_override( "printParameters" ) )
+            func_printParameters(  );
+        else{
+            this->IParameterized::printParameters(  );
+        }
+    }
+    
+    void default_printParameters(  ) const  {
+        IParameterized::printParameters( );
+    }
+
+    virtual void print_structure(  ) {
+        if( bp::override func_print_structure = this->get_override( "print_structure" ) )
+            func_print_structure(  );
+        else{
+            this->ISample::print_structure(  );
+        }
+    }
+    
+    void default_print_structure(  ) {
+        ISample::print_structure( );
+    }
+
+    virtual void setAmbientRefractiveIndex( ::complex_t const & refractive_index ) {
+        if( bp::override func_setAmbientRefractiveIndex = this->get_override( "setAmbientRefractiveIndex" ) )
+            func_setAmbientRefractiveIndex( boost::ref(refractive_index) );
+        else{
+            this->IFormFactor::setAmbientRefractiveIndex( boost::ref(refractive_index) );
+        }
+    }
+    
+    void default_setAmbientRefractiveIndex( ::complex_t const & refractive_index ) {
+        IFormFactor::setAmbientRefractiveIndex( boost::ref(refractive_index) );
+    }
+
+    virtual void setParametersAreChanged(  ) {
+        if( bp::override func_setParametersAreChanged = this->get_override( "setParametersAreChanged" ) )
+            func_setParametersAreChanged(  );
+        else{
+            this->IParameterized::setParametersAreChanged(  );
+        }
+    }
+    
+    void default_setParametersAreChanged(  ) {
+        IParameterized::setParametersAreChanged( );
+    }
+
+};
+
+void register_FormFactorBox_class(){
+
+    bp::class_< FormFactorBox_wrapper, bp::bases< IFormFactorBorn >, boost::noncopyable >( "FormFactorBox", bp::init< double, double, double >(( bp::arg("radius"), bp::arg("width"), bp::arg("height") )) )    
+        .def( 
+            "clone"
+            , (::FormFactorBox * ( ::FormFactorBox::* )(  ) const)(&::FormFactorBox::clone)
+            , (::FormFactorBox * ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_clone)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "evaluate_for_q"
+            , (::complex_t ( ::FormFactorBox::* )( ::cvector_t const & ) const)(&::FormFactorBox::evaluate_for_q)
+            , (::complex_t ( FormFactorBox_wrapper::* )( ::cvector_t const & ) const)(&FormFactorBox_wrapper::default_evaluate_for_q)
+            , ( bp::arg("q") ) )    
+        .def( 
+            "getHeight"
+            , (double ( ::FormFactorBox::* )(  ) const)(&::FormFactorBox::getHeight)
+            , (double ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_getHeight) )    
+        .def( 
+            "getNumberOfStochasticParameters"
+            , (int ( ::FormFactorBox::* )(  ) const)(&::FormFactorBox::getNumberOfStochasticParameters)
+            , (int ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_getNumberOfStochasticParameters) )    
+        .def( 
+            "getRadius"
+            , (double ( ::FormFactorBox::* )(  ) const)(&::FormFactorBox::getRadius)
+            , (double ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_getRadius) )    
+        .def( 
+            "getVolume"
+            , (double ( ::FormFactorBox::* )(  ) const)(&::FormFactorBox::getVolume)
+            , (double ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_getVolume) )    
+        .def( 
+            "getwidth"
+            , (double ( ::FormFactorBox::* )(  ) const)( &::FormFactorBox::getwidth ) )    
+        .def( 
+            "areParametersChanged"
+            , (bool ( ::IParameterized::* )(  ) )(&::IParameterized::areParametersChanged)
+            , (bool ( FormFactorBox_wrapper::* )(  ) )(&FormFactorBox_wrapper::default_areParametersChanged) )    
+        .def( 
+            "createDistributedFormFactors"
+            , (void ( ::IFormFactor::* )( ::std::vector< IFormFactor* > &,::std::vector< double > &,::size_t ) const)(&::IFormFactor::createDistributedFormFactors)
+            , (void ( FormFactorBox_wrapper::* )( ::std::vector< IFormFactor* > &,::std::vector< double > &,::size_t ) const)(&FormFactorBox_wrapper::default_createDistributedFormFactors)
+            , ( bp::arg("form_factors"), bp::arg("probabilities"), bp::arg("nbr_samples") )
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "createParameterTree"
+            , (::ParameterPool * ( ::IParameterized::* )(  ) const)(&::IParameterized::createParameterTree)
+            , (::ParameterPool * ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_createParameterTree)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "evaluate"
+            , (::complex_t ( ::IFormFactorBorn::* )( ::cvector_t const &,::Bin1DCVector const &,double,double ) const)(&::IFormFactorBorn::evaluate)
+            , (::complex_t ( FormFactorBox_wrapper::* )( ::cvector_t const &,::Bin1DCVector const &,double,double ) const)(&FormFactorBox_wrapper::default_evaluate)
+            , ( bp::arg("k_i"), bp::arg("k_f_bin"), bp::arg("alpha_i"), bp::arg("alpha_f") ) )    
+        .def( 
+            "isDistributedFormFactor"
+            , (bool ( ::IFormFactor::* )(  ) const)(&::IFormFactor::isDistributedFormFactor)
+            , (bool ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_isDistributedFormFactor) )    
+        .def( 
+            "printParameters"
+            , (void ( ::IParameterized::* )(  ) const)(&::IParameterized::printParameters)
+            , (void ( FormFactorBox_wrapper::* )(  ) const)(&FormFactorBox_wrapper::default_printParameters) )    
+        .def( 
+            "print_structure"
+            , (void ( ::ISample::* )(  ) )(&::ISample::print_structure)
+            , (void ( FormFactorBox_wrapper::* )(  ) )(&FormFactorBox_wrapper::default_print_structure) )    
+        .def( 
+            "setAmbientRefractiveIndex"
+            , (void ( ::IFormFactor::* )( ::complex_t const & ) )(&::IFormFactor::setAmbientRefractiveIndex)
+            , (void ( FormFactorBox_wrapper::* )( ::complex_t const & ) )(&FormFactorBox_wrapper::default_setAmbientRefractiveIndex)
+            , ( bp::arg("refractive_index") ) )    
+        .def( 
+            "setParametersAreChanged"
+            , (void ( ::IParameterized::* )(  ) )(&::IParameterized::setParametersAreChanged)
+            , (void ( FormFactorBox_wrapper::* )(  ) )(&FormFactorBox_wrapper::default_setParametersAreChanged) );
+
+}
diff --git a/Core/PythonAPI/src/IFTDistribution1D.pypp.cpp b/Core/PythonAPI/src/IFTDistribution1D.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f3d81c5972d402c5be9f73d5b143c352ded617a9
--- /dev/null
+++ b/Core/PythonAPI/src/IFTDistribution1D.pypp.cpp
@@ -0,0 +1,95 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "IFTDistribution1D.pypp.h"
+
+namespace bp = boost::python;
+
+struct IFTDistribution1D_wrapper : IFTDistribution1D, bp::wrapper< IFTDistribution1D > {
+
+    IFTDistribution1D_wrapper(double omega )
+    : IFTDistribution1D( omega )
+      , bp::wrapper< IFTDistribution1D >(){
+        // constructor
+    
+    }
+
+    virtual double evaluate( double q ) const {
+        bp::override func_evaluate = this->get_override( "evaluate" );
+        return func_evaluate( q );
+    }
+
+};
+
+void register_IFTDistribution1D_class(){
+
+    bp::class_< IFTDistribution1D_wrapper, boost::noncopyable >( "IFTDistribution1D", bp::init< double >(( bp::arg("omega") )) )    
+        .def( 
+            "evaluate"
+            , bp::pure_virtual( (double ( ::IFTDistribution1D::* )( double ) const)(&::IFTDistribution1D::evaluate) )
+            , ( bp::arg("q") ) );
+
+}
diff --git a/Core/PythonAPI/src/IFTDistribution2D.pypp.cpp b/Core/PythonAPI/src/IFTDistribution2D.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e6e4f147f7b79484599bd44223effce41dc38124
--- /dev/null
+++ b/Core/PythonAPI/src/IFTDistribution2D.pypp.cpp
@@ -0,0 +1,188 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "IFTDistribution2D.pypp.h"
+
+namespace bp = boost::python;
+
+struct IFTDistribution2D_wrapper : IFTDistribution2D, bp::wrapper< IFTDistribution2D > {
+
+    IFTDistribution2D_wrapper(double omega_x, double omega_y )
+    : IFTDistribution2D( omega_x, omega_y )
+      , bp::wrapper< IFTDistribution2D >(){
+        // constructor
+    
+    }
+
+    virtual ::IFTDistribution2D * clone(  ) const {
+        bp::override func_clone = this->get_override( "clone" );
+        return func_clone(  );
+    }
+
+    virtual double evaluate( double qx, double qy ) const {
+        bp::override func_evaluate = this->get_override( "evaluate" );
+        return func_evaluate( qx, qy );
+    }
+
+    virtual void transformToStarBasis( double qX, double qY, double alpha, double a, double b, double & qa, double & qb ) const {
+        bp::override func_transformToStarBasis = this->get_override( "transformToStarBasis" );
+        func_transformToStarBasis( qX, qY, alpha, a, b, qa, qb );
+    }
+
+    virtual bool areParametersChanged(  ) {
+        if( bp::override func_areParametersChanged = this->get_override( "areParametersChanged" ) )
+            return func_areParametersChanged(  );
+        else{
+            return this->IParameterized::areParametersChanged(  );
+        }
+    }
+    
+    bool default_areParametersChanged(  ) {
+        return IParameterized::areParametersChanged( );
+    }
+
+    virtual ::ParameterPool * createParameterTree(  ) const  {
+        if( bp::override func_createParameterTree = this->get_override( "createParameterTree" ) )
+            return func_createParameterTree(  );
+        else{
+            return this->IParameterized::createParameterTree(  );
+        }
+    }
+    
+    ::ParameterPool * default_createParameterTree(  ) const  {
+        return IParameterized::createParameterTree( );
+    }
+
+    virtual void printParameters(  ) const  {
+        if( bp::override func_printParameters = this->get_override( "printParameters" ) )
+            func_printParameters(  );
+        else{
+            this->IParameterized::printParameters(  );
+        }
+    }
+    
+    void default_printParameters(  ) const  {
+        IParameterized::printParameters( );
+    }
+
+    virtual void setParametersAreChanged(  ) {
+        if( bp::override func_setParametersAreChanged = this->get_override( "setParametersAreChanged" ) )
+            func_setParametersAreChanged(  );
+        else{
+            this->IParameterized::setParametersAreChanged(  );
+        }
+    }
+    
+    void default_setParametersAreChanged(  ) {
+        IParameterized::setParametersAreChanged( );
+    }
+
+};
+
+void register_IFTDistribution2D_class(){
+
+    bp::class_< IFTDistribution2D_wrapper, bp::bases< IParameterized >, boost::noncopyable >( "IFTDistribution2D", bp::init< double, double >(( bp::arg("omega_x"), bp::arg("omega_y") )) )    
+        .def( 
+            "clone"
+            , bp::pure_virtual( (::IFTDistribution2D * ( ::IFTDistribution2D::* )(  ) const)(&::IFTDistribution2D::clone) )
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "evaluate"
+            , bp::pure_virtual( (double ( ::IFTDistribution2D::* )( double,double ) const)(&::IFTDistribution2D::evaluate) )
+            , ( bp::arg("qx"), bp::arg("qy") ) )    
+        .def( 
+            "getDelta"
+            , (double ( ::IFTDistribution2D::* )(  ) const)( &::IFTDistribution2D::getDelta ) )    
+        .def( 
+            "getGamma"
+            , (double ( ::IFTDistribution2D::* )(  ) const)( &::IFTDistribution2D::getGamma ) )    
+        .def( 
+            "setGamma"
+            , (void ( ::IFTDistribution2D::* )( double ) )( &::IFTDistribution2D::setGamma )
+            , ( bp::arg("gamma") ) )    
+        .def( 
+            "transformToStarBasis"
+            , bp::pure_virtual( (void ( ::IFTDistribution2D::* )( double,double,double,double,double,double &,double & ) const)(&::IFTDistribution2D::transformToStarBasis) )
+            , ( bp::arg("qX"), bp::arg("qY"), bp::arg("alpha"), bp::arg("a"), bp::arg("b"), bp::arg("qa"), bp::arg("qb") ) )    
+        .def( 
+            "areParametersChanged"
+            , (bool ( ::IParameterized::* )(  ) )(&::IParameterized::areParametersChanged)
+            , (bool ( IFTDistribution2D_wrapper::* )(  ) )(&IFTDistribution2D_wrapper::default_areParametersChanged) )    
+        .def( 
+            "createParameterTree"
+            , (::ParameterPool * ( ::IParameterized::* )(  ) const)(&::IParameterized::createParameterTree)
+            , (::ParameterPool * ( IFTDistribution2D_wrapper::* )(  ) const)(&IFTDistribution2D_wrapper::default_createParameterTree)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "printParameters"
+            , (void ( ::IParameterized::* )(  ) const)(&::IParameterized::printParameters)
+            , (void ( IFTDistribution2D_wrapper::* )(  ) const)(&IFTDistribution2D_wrapper::default_printParameters) )    
+        .def( 
+            "setParametersAreChanged"
+            , (void ( ::IParameterized::* )(  ) )(&::IParameterized::setParametersAreChanged)
+            , (void ( IFTDistribution2D_wrapper::* )(  ) )(&IFTDistribution2D_wrapper::default_setParametersAreChanged) );
+
+}
diff --git a/Core/PythonAPI/src/InterferenceFunction2DLattice.pypp.cpp b/Core/PythonAPI/src/InterferenceFunction2DLattice.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ad6bbe44f24d757b1fd98899ef215c498194d64
--- /dev/null
+++ b/Core/PythonAPI/src/InterferenceFunction2DLattice.pypp.cpp
@@ -0,0 +1,221 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "InterferenceFunction2DLattice.pypp.h"
+
+namespace bp = boost::python;
+
+struct InterferenceFunction2DLattice_wrapper : InterferenceFunction2DLattice, bp::wrapper< InterferenceFunction2DLattice > {
+
+    InterferenceFunction2DLattice_wrapper(::Lattice2DIFParameters const & lattice_params )
+    : InterferenceFunction2DLattice( boost::ref(lattice_params) )
+      , bp::wrapper< InterferenceFunction2DLattice >(){
+        // constructor
+    
+    }
+
+    virtual ::InterferenceFunction2DLattice * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else{
+            return this->InterferenceFunction2DLattice::clone(  );
+        }
+    }
+    
+    ::InterferenceFunction2DLattice * default_clone(  ) const  {
+        return InterferenceFunction2DLattice::clone( );
+    }
+
+    virtual double evaluate( ::cvector_t const & q ) const  {
+        if( bp::override func_evaluate = this->get_override( "evaluate" ) )
+            return func_evaluate( boost::ref(q) );
+        else{
+            return this->InterferenceFunction2DLattice::evaluate( boost::ref(q) );
+        }
+    }
+    
+    double default_evaluate( ::cvector_t const & q ) const  {
+        return InterferenceFunction2DLattice::evaluate( boost::ref(q) );
+    }
+
+    virtual bool areParametersChanged(  ) {
+        if( bp::override func_areParametersChanged = this->get_override( "areParametersChanged" ) )
+            return func_areParametersChanged(  );
+        else{
+            return this->IParameterized::areParametersChanged(  );
+        }
+    }
+    
+    bool default_areParametersChanged(  ) {
+        return IParameterized::areParametersChanged( );
+    }
+
+    virtual ::ParameterPool * createParameterTree(  ) const  {
+        if( bp::override func_createParameterTree = this->get_override( "createParameterTree" ) )
+            return func_createParameterTree(  );
+        else{
+            return this->IParameterized::createParameterTree(  );
+        }
+    }
+    
+    ::ParameterPool * default_createParameterTree(  ) const  {
+        return IParameterized::createParameterTree( );
+    }
+
+    virtual double getKappa(  ) const  {
+        if( bp::override func_getKappa = this->get_override( "getKappa" ) )
+            return func_getKappa(  );
+        else{
+            return this->IInterferenceFunction::getKappa(  );
+        }
+    }
+    
+    double default_getKappa(  ) const  {
+        return IInterferenceFunction::getKappa( );
+    }
+
+    virtual void printParameters(  ) const  {
+        if( bp::override func_printParameters = this->get_override( "printParameters" ) )
+            func_printParameters(  );
+        else{
+            this->IParameterized::printParameters(  );
+        }
+    }
+    
+    void default_printParameters(  ) const  {
+        IParameterized::printParameters( );
+    }
+
+    virtual void print_structure(  ) {
+        if( bp::override func_print_structure = this->get_override( "print_structure" ) )
+            func_print_structure(  );
+        else{
+            this->ISample::print_structure(  );
+        }
+    }
+    
+    void default_print_structure(  ) {
+        ISample::print_structure( );
+    }
+
+    virtual void setParametersAreChanged(  ) {
+        if( bp::override func_setParametersAreChanged = this->get_override( "setParametersAreChanged" ) )
+            func_setParametersAreChanged(  );
+        else{
+            this->IParameterized::setParametersAreChanged(  );
+        }
+    }
+    
+    void default_setParametersAreChanged(  ) {
+        IParameterized::setParametersAreChanged( );
+    }
+
+};
+
+void register_InterferenceFunction2DLattice_class(){
+
+    bp::class_< InterferenceFunction2DLattice_wrapper, bp::bases< IInterferenceFunction >, boost::noncopyable >( "InterferenceFunction2DLattice", bp::init< Lattice2DIFParameters const & >(( bp::arg("lattice_params") )) )    
+        .def( 
+            "clone"
+            , (::InterferenceFunction2DLattice * ( ::InterferenceFunction2DLattice::* )(  ) const)(&::InterferenceFunction2DLattice::clone)
+            , (::InterferenceFunction2DLattice * ( InterferenceFunction2DLattice_wrapper::* )(  ) const)(&InterferenceFunction2DLattice_wrapper::default_clone)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "evaluate"
+            , (double ( ::InterferenceFunction2DLattice::* )( ::cvector_t const & ) const)(&::InterferenceFunction2DLattice::evaluate)
+            , (double ( InterferenceFunction2DLattice_wrapper::* )( ::cvector_t const & ) const)(&InterferenceFunction2DLattice_wrapper::default_evaluate)
+            , ( bp::arg("q") ) )    
+        .def( 
+            "setProbabilityDistribution"
+            , (void ( ::InterferenceFunction2DLattice::* )( ::IFTDistribution2D const & ) )( &::InterferenceFunction2DLattice::setProbabilityDistribution )
+            , ( bp::arg("pdf") ) )    
+        .def( 
+            "areParametersChanged"
+            , (bool ( ::IParameterized::* )(  ) )(&::IParameterized::areParametersChanged)
+            , (bool ( InterferenceFunction2DLattice_wrapper::* )(  ) )(&InterferenceFunction2DLattice_wrapper::default_areParametersChanged) )    
+        .def( 
+            "createParameterTree"
+            , (::ParameterPool * ( ::IParameterized::* )(  ) const)(&::IParameterized::createParameterTree)
+            , (::ParameterPool * ( InterferenceFunction2DLattice_wrapper::* )(  ) const)(&InterferenceFunction2DLattice_wrapper::default_createParameterTree)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "getKappa"
+            , (double ( ::IInterferenceFunction::* )(  ) const)(&::IInterferenceFunction::getKappa)
+            , (double ( InterferenceFunction2DLattice_wrapper::* )(  ) const)(&InterferenceFunction2DLattice_wrapper::default_getKappa) )    
+        .def( 
+            "printParameters"
+            , (void ( ::IParameterized::* )(  ) const)(&::IParameterized::printParameters)
+            , (void ( InterferenceFunction2DLattice_wrapper::* )(  ) const)(&InterferenceFunction2DLattice_wrapper::default_printParameters) )    
+        .def( 
+            "print_structure"
+            , (void ( ::ISample::* )(  ) )(&::ISample::print_structure)
+            , (void ( InterferenceFunction2DLattice_wrapper::* )(  ) )(&InterferenceFunction2DLattice_wrapper::default_print_structure) )    
+        .def( 
+            "setParametersAreChanged"
+            , (void ( ::IParameterized::* )(  ) )(&::IParameterized::setParametersAreChanged)
+            , (void ( InterferenceFunction2DLattice_wrapper::* )(  ) )(&InterferenceFunction2DLattice_wrapper::default_setParametersAreChanged) );
+
+}
diff --git a/Core/PythonAPI/src/InterferenceFunction2DParaCrystal.pypp.cpp b/Core/PythonAPI/src/InterferenceFunction2DParaCrystal.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dc8e25286847890cabafe752c5d385165a2bc3cd
--- /dev/null
+++ b/Core/PythonAPI/src/InterferenceFunction2DParaCrystal.pypp.cpp
@@ -0,0 +1,241 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "InterferenceFunction2DParaCrystal.pypp.h"
+
+namespace bp = boost::python;
+
+struct InterferenceFunction2DParaCrystal_wrapper : InterferenceFunction2DParaCrystal, bp::wrapper< InterferenceFunction2DParaCrystal > {
+
+    InterferenceFunction2DParaCrystal_wrapper(double length_1, double length_2, double alpha_lattice, double xi=0.0, double corr_length=0.0 )
+    : InterferenceFunction2DParaCrystal( length_1, length_2, alpha_lattice, xi, corr_length )
+      , bp::wrapper< InterferenceFunction2DParaCrystal >(){
+        // constructor
+    
+    }
+
+    virtual ::InterferenceFunction2DParaCrystal * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else{
+            return this->InterferenceFunction2DParaCrystal::clone(  );
+        }
+    }
+    
+    ::InterferenceFunction2DParaCrystal * default_clone(  ) const  {
+        return InterferenceFunction2DParaCrystal::clone( );
+    }
+
+    virtual double evaluate( ::cvector_t const & q ) const  {
+        if( bp::override func_evaluate = this->get_override( "evaluate" ) )
+            return func_evaluate( boost::ref(q) );
+        else{
+            return this->InterferenceFunction2DParaCrystal::evaluate( boost::ref(q) );
+        }
+    }
+    
+    double default_evaluate( ::cvector_t const & q ) const  {
+        return InterferenceFunction2DParaCrystal::evaluate( boost::ref(q) );
+    }
+
+    virtual bool areParametersChanged(  ) {
+        if( bp::override func_areParametersChanged = this->get_override( "areParametersChanged" ) )
+            return func_areParametersChanged(  );
+        else{
+            return this->IParameterized::areParametersChanged(  );
+        }
+    }
+    
+    bool default_areParametersChanged(  ) {
+        return IParameterized::areParametersChanged( );
+    }
+
+    virtual ::ParameterPool * createParameterTree(  ) const  {
+        if( bp::override func_createParameterTree = this->get_override( "createParameterTree" ) )
+            return func_createParameterTree(  );
+        else{
+            return this->IParameterized::createParameterTree(  );
+        }
+    }
+    
+    ::ParameterPool * default_createParameterTree(  ) const  {
+        return IParameterized::createParameterTree( );
+    }
+
+    virtual double getKappa(  ) const  {
+        if( bp::override func_getKappa = this->get_override( "getKappa" ) )
+            return func_getKappa(  );
+        else{
+            return this->IInterferenceFunction::getKappa(  );
+        }
+    }
+    
+    double default_getKappa(  ) const  {
+        return IInterferenceFunction::getKappa( );
+    }
+
+    virtual void printParameters(  ) const  {
+        if( bp::override func_printParameters = this->get_override( "printParameters" ) )
+            func_printParameters(  );
+        else{
+            this->IParameterized::printParameters(  );
+        }
+    }
+    
+    void default_printParameters(  ) const  {
+        IParameterized::printParameters( );
+    }
+
+    virtual void print_structure(  ) {
+        if( bp::override func_print_structure = this->get_override( "print_structure" ) )
+            func_print_structure(  );
+        else{
+            this->ISample::print_structure(  );
+        }
+    }
+    
+    void default_print_structure(  ) {
+        ISample::print_structure( );
+    }
+
+    virtual void setParametersAreChanged(  ) {
+        if( bp::override func_setParametersAreChanged = this->get_override( "setParametersAreChanged" ) )
+            func_setParametersAreChanged(  );
+        else{
+            this->IParameterized::setParametersAreChanged(  );
+        }
+    }
+    
+    void default_setParametersAreChanged(  ) {
+        IParameterized::setParametersAreChanged( );
+    }
+
+};
+
+void register_InterferenceFunction2DParaCrystal_class(){
+
+    bp::class_< InterferenceFunction2DParaCrystal_wrapper, bp::bases< IInterferenceFunction >, boost::noncopyable >( "InterferenceFunction2DParaCrystal", bp::init< double, double, double, bp::optional< double, double > >(( bp::arg("length_1"), bp::arg("length_2"), bp::arg("alpha_lattice"), bp::arg("xi")=0.0, bp::arg("corr_length")=0.0 )) )    
+        .def( 
+            "clone"
+            , (::InterferenceFunction2DParaCrystal * ( ::InterferenceFunction2DParaCrystal::* )(  ) const)(&::InterferenceFunction2DParaCrystal::clone)
+            , (::InterferenceFunction2DParaCrystal * ( InterferenceFunction2DParaCrystal_wrapper::* )(  ) const)(&InterferenceFunction2DParaCrystal_wrapper::default_clone)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "createHexagonal"
+            , (::InterferenceFunction2DParaCrystal * (*)( double,double,double,double ))( &::InterferenceFunction2DParaCrystal::createHexagonal )
+            , ( bp::arg("peak_distance"), bp::arg("corr_length")=0.0, bp::arg("domain_size_1")=0.0, bp::arg("domain_size_2")=0.0 )
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "createSquare"
+            , (::InterferenceFunction2DParaCrystal * (*)( double,double,double,double ))( &::InterferenceFunction2DParaCrystal::createSquare )
+            , ( bp::arg("peak_distance"), bp::arg("corr_length")=0.0, bp::arg("domain_size_1")=0.0, bp::arg("domain_size_2")=0.0 )
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "evaluate"
+            , (double ( ::InterferenceFunction2DParaCrystal::* )( ::cvector_t const & ) const)(&::InterferenceFunction2DParaCrystal::evaluate)
+            , (double ( InterferenceFunction2DParaCrystal_wrapper::* )( ::cvector_t const & ) const)(&InterferenceFunction2DParaCrystal_wrapper::default_evaluate)
+            , ( bp::arg("q") ) )    
+        .def( 
+            "setDomainSizes"
+            , (void ( ::InterferenceFunction2DParaCrystal::* )( double,double ) )( &::InterferenceFunction2DParaCrystal::setDomainSizes )
+            , ( bp::arg("size_1"), bp::arg("size_2") ) )    
+        .def( 
+            "setIntegrationOverXi"
+            , (void ( ::InterferenceFunction2DParaCrystal::* )( bool ) )( &::InterferenceFunction2DParaCrystal::setIntegrationOverXi )
+            , ( bp::arg("integrate_xi") ) )    
+        .def( 
+            "setProbabilityDistributions"
+            , (void ( ::InterferenceFunction2DParaCrystal::* )( ::IFTDistribution2D const &,::IFTDistribution2D const & ) )( &::InterferenceFunction2DParaCrystal::setProbabilityDistributions )
+            , ( bp::arg("pdf_1"), bp::arg("pdf_2") ) )    
+        .def( 
+            "areParametersChanged"
+            , (bool ( ::IParameterized::* )(  ) )(&::IParameterized::areParametersChanged)
+            , (bool ( InterferenceFunction2DParaCrystal_wrapper::* )(  ) )(&InterferenceFunction2DParaCrystal_wrapper::default_areParametersChanged) )    
+        .def( 
+            "createParameterTree"
+            , (::ParameterPool * ( ::IParameterized::* )(  ) const)(&::IParameterized::createParameterTree)
+            , (::ParameterPool * ( InterferenceFunction2DParaCrystal_wrapper::* )(  ) const)(&InterferenceFunction2DParaCrystal_wrapper::default_createParameterTree)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "getKappa"
+            , (double ( ::IInterferenceFunction::* )(  ) const)(&::IInterferenceFunction::getKappa)
+            , (double ( InterferenceFunction2DParaCrystal_wrapper::* )(  ) const)(&InterferenceFunction2DParaCrystal_wrapper::default_getKappa) )    
+        .def( 
+            "printParameters"
+            , (void ( ::IParameterized::* )(  ) const)(&::IParameterized::printParameters)
+            , (void ( InterferenceFunction2DParaCrystal_wrapper::* )(  ) const)(&InterferenceFunction2DParaCrystal_wrapper::default_printParameters) )    
+        .def( 
+            "print_structure"
+            , (void ( ::ISample::* )(  ) )(&::ISample::print_structure)
+            , (void ( InterferenceFunction2DParaCrystal_wrapper::* )(  ) )(&InterferenceFunction2DParaCrystal_wrapper::default_print_structure) )    
+        .def( 
+            "setParametersAreChanged"
+            , (void ( ::IParameterized::* )(  ) )(&::IParameterized::setParametersAreChanged)
+            , (void ( InterferenceFunction2DParaCrystal_wrapper::* )(  ) )(&InterferenceFunction2DParaCrystal_wrapper::default_setParametersAreChanged) )    
+        .staticmethod( "createHexagonal" )    
+        .staticmethod( "createSquare" );
+
+}
diff --git a/Core/PythonAPI/src/Lattice2DIFParameters.pypp.cpp b/Core/PythonAPI/src/Lattice2DIFParameters.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cb6ed1a23327f68de54dc849f8af00c93f85c845
--- /dev/null
+++ b/Core/PythonAPI/src/Lattice2DIFParameters.pypp.cpp
@@ -0,0 +1,83 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "Lattice2DIFParameters.pypp.h"
+
+namespace bp = boost::python;
+
+void register_Lattice2DIFParameters_class(){
+
+    bp::class_< Lattice2DIFParameters >( "Lattice2DIFParameters" )    
+        .def_readwrite( "m_angle", &Lattice2DIFParameters::m_angle )    
+        .def_readwrite( "m_corr_length_1", &Lattice2DIFParameters::m_corr_length_1 )    
+        .def_readwrite( "m_corr_length_2", &Lattice2DIFParameters::m_corr_length_2 )    
+        .def_readwrite( "m_domain_size_1", &Lattice2DIFParameters::m_domain_size_1 )    
+        .def_readwrite( "m_domain_size_2", &Lattice2DIFParameters::m_domain_size_2 )    
+        .def_readwrite( "m_length_1", &Lattice2DIFParameters::m_length_1 )    
+        .def_readwrite( "m_length_2", &Lattice2DIFParameters::m_length_2 )    
+        .def_readwrite( "m_xi", &Lattice2DIFParameters::m_xi );
+
+}
diff --git a/Core/PythonAPI/src/ParticleBuilder.pypp.cpp b/Core/PythonAPI/src/ParticleBuilder.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6202b540a371ca134bb51ae85ec39afa2fe9114
--- /dev/null
+++ b/Core/PythonAPI/src/ParticleBuilder.pypp.cpp
@@ -0,0 +1,83 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "ParticleBuilder.pypp.h"
+
+namespace bp = boost::python;
+
+void register_ParticleBuilder_class(){
+
+    bp::class_< ParticleBuilder >( "ParticleBuilder", bp::init< >() )    
+        .def( 
+            "plantParticles"
+            , (void ( ::ParticleBuilder::* )( ::ParticleDecoration & ) )( &::ParticleBuilder::plantParticles )
+            , ( bp::arg("decor") ) )    
+        .def( 
+            "setPrototype"
+            , (void ( ::ParticleBuilder::* )( ::Particle const &,::std::string,::StochasticParameter< double > const &,double ) )( &::ParticleBuilder::setPrototype )
+            , ( bp::arg("particle"), bp::arg("name"), bp::arg("param"), bp::arg("scale")=1.0e+0 ) );
+
+}
diff --git a/Core/PythonAPI/src/PositionParticleInfo.pypp.cpp b/Core/PythonAPI/src/PositionParticleInfo.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d1965416ab78831523cdf98b80a3b4e3b70aec3f
--- /dev/null
+++ b/Core/PythonAPI/src/PositionParticleInfo.pypp.cpp
@@ -0,0 +1,238 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "PositionParticleInfo.pypp.h"
+
+namespace bp = boost::python;
+
+struct PositionParticleInfo_wrapper : PositionParticleInfo, bp::wrapper< PositionParticleInfo > {
+
+    virtual ::PositionParticleInfo * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else{
+            return this->PositionParticleInfo::clone(  );
+        }
+    }
+    
+    ::PositionParticleInfo * default_clone(  ) const  {
+        return PositionParticleInfo::clone( );
+    }
+
+    virtual bool areParametersChanged(  ) {
+        if( bp::override func_areParametersChanged = this->get_override( "areParametersChanged" ) )
+            return func_areParametersChanged(  );
+        else{
+            return this->IParameterized::areParametersChanged(  );
+        }
+    }
+    
+    bool default_areParametersChanged(  ) {
+        return IParameterized::areParametersChanged( );
+    }
+
+    virtual ::ParameterPool * createParameterTree(  ) const  {
+        if( bp::override func_createParameterTree = this->get_override( "createParameterTree" ) )
+            return func_createParameterTree(  );
+        else{
+            return this->IParameterized::createParameterTree(  );
+        }
+    }
+    
+    ::ParameterPool * default_createParameterTree(  ) const  {
+        return IParameterized::createParameterTree( );
+    }
+
+    virtual ::ICompositeSample * getCompositeSample(  ) {
+        if( bp::override func_getCompositeSample = this->get_override( "getCompositeSample" ) )
+            return func_getCompositeSample(  );
+        else{
+            return this->ICompositeSample::getCompositeSample(  );
+        }
+    }
+    
+    ::ICompositeSample * default_getCompositeSample(  ) {
+        return ICompositeSample::getCompositeSample( );
+    }
+
+    virtual ::ICompositeSample const * getCompositeSample(  ) const  {
+        if( bp::override func_getCompositeSample = this->get_override( "getCompositeSample" ) )
+            return func_getCompositeSample(  );
+        else{
+            return this->ICompositeSample::getCompositeSample(  );
+        }
+    }
+    
+    ::ICompositeSample const * default_getCompositeSample(  ) const  {
+        return ICompositeSample::getCompositeSample( );
+    }
+
+    virtual void printParameters(  ) const  {
+        if( bp::override func_printParameters = this->get_override( "printParameters" ) )
+            func_printParameters(  );
+        else{
+            this->IParameterized::printParameters(  );
+        }
+    }
+    
+    void default_printParameters(  ) const  {
+        IParameterized::printParameters( );
+    }
+
+    virtual void print_structure(  ) {
+        if( bp::override func_print_structure = this->get_override( "print_structure" ) )
+            func_print_structure(  );
+        else{
+            this->ISample::print_structure(  );
+        }
+    }
+    
+    void default_print_structure(  ) {
+        ISample::print_structure( );
+    }
+
+    virtual void setParametersAreChanged(  ) {
+        if( bp::override func_setParametersAreChanged = this->get_override( "setParametersAreChanged" ) )
+            func_setParametersAreChanged(  );
+        else{
+            this->IParameterized::setParametersAreChanged(  );
+        }
+    }
+    
+    void default_setParametersAreChanged(  ) {
+        IParameterized::setParametersAreChanged( );
+    }
+
+    virtual ::size_t size(  ) const  {
+        if( bp::override func_size = this->get_override( "size" ) )
+            return func_size(  );
+        else{
+            return this->ICompositeSample::size(  );
+        }
+    }
+    
+    ::size_t default_size(  ) const  {
+        return ICompositeSample::size( );
+    }
+
+};
+
+void register_PositionParticleInfo_class(){
+
+    bp::class_< PositionParticleInfo_wrapper, bp::bases< ParticleInfo >, boost::noncopyable >( "PositionParticleInfo", bp::no_init )    
+        .def( 
+            "clone"
+            , (::PositionParticleInfo * ( ::PositionParticleInfo::* )(  ) const)(&::PositionParticleInfo::clone)
+            , (::PositionParticleInfo * ( PositionParticleInfo_wrapper::* )(  ) const)(&PositionParticleInfo_wrapper::default_clone)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "getParticle"
+            , (::Particle const * ( ::PositionParticleInfo::* )(  ) const)( &::PositionParticleInfo::getParticle )
+            , bp::return_value_policy< bp::reference_existing_object >() )    
+        .def( 
+            "getPosition"
+            , (::kvector_t ( ::PositionParticleInfo::* )(  ) const)( &::PositionParticleInfo::getPosition ) )    
+        .def( 
+            "setPosition"
+            , (void ( ::PositionParticleInfo::* )( ::kvector_t ) )( &::PositionParticleInfo::setPosition )
+            , ( bp::arg("position") ) )    
+        .def( 
+            "areParametersChanged"
+            , (bool ( ::IParameterized::* )(  ) )(&::IParameterized::areParametersChanged)
+            , (bool ( PositionParticleInfo_wrapper::* )(  ) )(&PositionParticleInfo_wrapper::default_areParametersChanged) )    
+        .def( 
+            "createParameterTree"
+            , (::ParameterPool * ( ::IParameterized::* )(  ) const)(&::IParameterized::createParameterTree)
+            , (::ParameterPool * ( PositionParticleInfo_wrapper::* )(  ) const)(&PositionParticleInfo_wrapper::default_createParameterTree)
+            , bp::return_value_policy< bp::manage_new_object >() )    
+        .def( 
+            "getCompositeSample"
+            , (::ICompositeSample * ( ::ICompositeSample::* )(  ) )(&::ICompositeSample::getCompositeSample)
+            , (::ICompositeSample * ( PositionParticleInfo_wrapper::* )(  ) )(&PositionParticleInfo_wrapper::default_getCompositeSample)
+            , bp::return_value_policy< bp::reference_existing_object >() )    
+        .def( 
+            "getCompositeSample"
+            , (::ICompositeSample const * ( ::ICompositeSample::* )(  ) const)(&::ICompositeSample::getCompositeSample)
+            , (::ICompositeSample const * ( PositionParticleInfo_wrapper::* )(  ) const)(&PositionParticleInfo_wrapper::default_getCompositeSample)
+            , bp::return_value_policy< bp::reference_existing_object >() )    
+        .def( 
+            "printParameters"
+            , (void ( ::IParameterized::* )(  ) const)(&::IParameterized::printParameters)
+            , (void ( PositionParticleInfo_wrapper::* )(  ) const)(&PositionParticleInfo_wrapper::default_printParameters) )    
+        .def( 
+            "print_structure"
+            , (void ( ::ISample::* )(  ) )(&::ISample::print_structure)
+            , (void ( PositionParticleInfo_wrapper::* )(  ) )(&PositionParticleInfo_wrapper::default_print_structure) )    
+        .def( 
+            "setParametersAreChanged"
+            , (void ( ::IParameterized::* )(  ) )(&::IParameterized::setParametersAreChanged)
+            , (void ( PositionParticleInfo_wrapper::* )(  ) )(&PositionParticleInfo_wrapper::default_setParametersAreChanged) )    
+        .def( 
+            "size"
+            , (::size_t ( ::ICompositeSample::* )(  ) const)(&::ICompositeSample::size)
+            , (::size_t ( PositionParticleInfo_wrapper::* )(  ) const)(&PositionParticleInfo_wrapper::default_size) );
+
+}
diff --git a/Core/PythonAPI/src/SimulationParameters.pypp.cpp b/Core/PythonAPI/src/SimulationParameters.pypp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5b36dbd2bba8d9a43a1f9edad232d660c7952949
--- /dev/null
+++ b/Core/PythonAPI/src/SimulationParameters.pypp.cpp
@@ -0,0 +1,101 @@
+// This file has been generated by Py++.
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter);
+GCC_DIAG_OFF(missing-field-initializers);
+#include "boost/python.hpp"
+#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
+GCC_DIAG_ON(unused-parameter);
+GCC_DIAG_ON(missing-field-initializers);
+#include "BasicVector3D.h"
+#include "FormFactorCrystal.h"
+#include "FormFactorCylinder.h"
+#include "FormFactorDecoratorDebyeWaller.h"
+#include "FormFactorFullSphere.h"
+#include "FormFactorGauss.h"
+#include "FormFactorLorentz.h"
+#include "FormFactorPrism3.h"
+#include "FormFactorBox.h"
+#include "FormFactorPyramid.h"
+#include "FormFactorSphereGaussianRadius.h"
+#include "FTDistributions.h"
+#include "HomogeneousMaterial.h"
+#include "ICloneable.h"
+#include "IClusteredParticles.h"
+#include "ICompositeSample.h"
+#include "IDecoration.h"
+#include "IFormFactor.h"
+#include "IFormFactorBorn.h"
+#include "IFormFactorDecorator.h"
+#include "IInterferenceFunction.h"
+#include "InterferenceFunctionNone.h"
+#include "InterferenceFunction1DParaCrystal.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "InterferenceFunction2DLattice.h"
+#include "IMaterial.h"
+#include "IParameterized.h"
+#include "ISample.h"
+#include "ISampleBuilder.h"
+#include "ISelectionRule.h"
+#include "ISingleton.h"
+#include "Lattice.h"
+#include "Lattice2DIFParameters.h"
+#include "LatticeBasis.h"
+#include "Layer.h"
+#include "LayerDecorator.h"
+#include "LayerRoughness.h"
+#include "MaterialManager.h"
+#include "MesoCrystal.h"
+#include "MultiLayer.h"
+#include "Particle.h"
+#include "Crystal.h"
+#include "ParticleDecoration.h"
+#include "ParticleBuilder.h"
+#include "OpticalFresnel.h"
+#include "ParameterPool.h"
+#include "PositionParticleInfo.h"
+#include "ParticleInfo.h"
+#include "DiffuseParticleInfo.h"
+#include "PythonOutputData.h"
+#include "PythonPlusplusHelper.h"
+#include "RealParameterWrapper.h"
+#include "Simulation.h"
+#include "SimulationParameters.h"
+#include "Transform3D.h"
+#include "Units.h"
+#include "Types.h"
+#include "SimulationParameters.pypp.h"
+
+namespace bp = boost::python;
+
+void register_SimulationParameters_class(){
+
+    { //::SimulationParameters
+        typedef bp::class_< SimulationParameters > SimulationParameters_exposer_t;
+        SimulationParameters_exposer_t SimulationParameters_exposer = SimulationParameters_exposer_t( "SimulationParameters", bp::init< >() );
+        bp::scope SimulationParameters_scope( SimulationParameters_exposer );
+        bp::enum_< SimulationParameters::EFramework>("EFramework")
+            .value("DWBA", SimulationParameters::DWBA)
+            .value("BA", SimulationParameters::BA)
+            .export_values()
+            ;
+        bp::enum_< SimulationParameters::EInterferenceApproximation>("EInterferenceApproximation")
+            .value("DA", SimulationParameters::DA)
+            .value("LMA", SimulationParameters::LMA)
+            .value("SSCA", SimulationParameters::SSCA)
+            .value("ISGISAXSMOR", SimulationParameters::ISGISAXSMOR)
+            .export_values()
+            ;
+        bp::enum_< SimulationParameters::ELatticeType>("ELatticeType")
+            .value("NONE", SimulationParameters::NONE)
+            .value("LATTICE", SimulationParameters::LATTICE)
+            .value("PARA1D", SimulationParameters::PARA1D)
+            .value("PARA1DFINITE", SimulationParameters::PARA1DFINITE)
+            .export_values()
+            ;
+        SimulationParameters_exposer.def_readwrite( "me_framework", &SimulationParameters::me_framework );
+        SimulationParameters_exposer.def_readwrite( "me_if_approx", &SimulationParameters::me_if_approx );
+        SimulationParameters_exposer.def_readwrite( "me_lattice_type", &SimulationParameters::me_lattice_type );
+    }
+
+}
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS03/IsGISAXS03.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS03/IsGISAXS03.cpp
index e869bfc2baf89878339d419ca3f3780c17b467dd..2251ddb7307d9e8b97ff6d03db76f1aeeaff4cc2 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS03/IsGISAXS03.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS03/IsGISAXS03.cpp
@@ -162,8 +162,8 @@ int FunctionalTests::IsGISAXS03::analyseResults()
 
     // retrieving reference data and generated examples
     for(size_t i=0; i<tocompare.size(); ++i) {
-        OutputData<double> *reference = OutputDataIOFactory::getOutputData(tocompare[i].isginame);
-        OutputData<double> *m_result = OutputDataIOFactory::getOutputData(tocompare[i].thisname);
+        OutputData<double> *reference = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].isginame);
+        OutputData<double> *m_result = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].thisname);
 
     // calculating average relative difference
     *m_result -= *reference;
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS04/IsGISAXS04.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS04/IsGISAXS04.cpp
index 8dcecb0972376654f4f96f0e08be6a987f2d7ade..641e764f9e7e597cbdf89e2491e2a54a709e8b4e 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS04/IsGISAXS04.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS04/IsGISAXS04.cpp
@@ -118,8 +118,8 @@ int FunctionalTests::IsGISAXS04::analyseResults()
        bool status_ok(true);
 
        for(size_t i=0; i<tocompare.size(); ++i) {
-           OutputData<double> *reference = OutputDataIOFactory::getOutputData(tocompare[i].isginame);
-           OutputData<double> *m_result = OutputDataIOFactory::getOutputData(tocompare[i].thisname);
+           OutputData<double> *reference = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].isginame);
+           OutputData<double> *m_result = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].thisname);
 
        // calculating average relative difference
        *m_result -= *reference;
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS06/IsGISAXS06.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS06/IsGISAXS06.cpp
index 012692888d3e408b00caae28df8315f881236426..5666c21ab796c36039f9298739407648c07cf8cc 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS06/IsGISAXS06.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS06/IsGISAXS06.cpp
@@ -20,7 +20,9 @@ FunctionalTests::IsGISAXS06::IsGISAXS06()
     : m_name("IsGISAXS06")
     , m_description("2D lattice with different disorder")
     , m_result(0)
-{}
+{
+    m_data_path = Utils::FileSystem::GetHomePath()+"Tests/FunctionalTests/TestCore/IsGISAXS06/";
+}
 
 //-----------------------------------------------------
 //IsGISAXS6_lattice()
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS08/IsGISAXS08.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS08/IsGISAXS08.cpp
index 1fc3ef2cfc4f8a2c16973279c5c88d429f3e6963..8ced280e8d84ac467b22300921eb0ec790c97065 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS08/IsGISAXS08.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS08/IsGISAXS08.cpp
@@ -120,8 +120,8 @@ int FunctionalTests::IsGISAXS08::analyseResults()
 
     // retrieving reference data and generated examples
     for(size_t i=0; i<tocompare.size(); ++i) {
-        OutputData<double> *reference = OutputDataIOFactory::getOutputData(tocompare[i].isginame);
-        OutputData<double> *m_result = OutputDataIOFactory::getOutputData(tocompare[i].thisname);
+        OutputData<double> *reference = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].isginame);
+        OutputData<double> *m_result = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].thisname);
         std::string descript  = tocompare[i].descr;
 
     // calculating average relative difference
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
index 10926da097d953f149870c277f0bc73faf1983a1..d81bfbaee38c8c386a62c1f0f680cea6b8e99573 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
@@ -31,23 +31,21 @@ void FunctionalTests::IsGISAXS09::runpyramidZ0()
     // ---------------------
     // building sample
     // ---------------------
-        MultiLayer multi_layer;
-        const IMaterial *p_air_material = MaterialManager::instance().addHomogeneousMaterial("Air", 1.0, 0.0);
-        const IMaterial *p_substrate_material = MaterialManager::instance().addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
-        Layer air_layer;
-        air_layer.setMaterial(p_air_material);
-        Layer substrate_layer;
-        substrate_layer.setMaterial(p_substrate_material);
-
-        complex_t n_particle(1.0-6e-4, 2e-8);
-        ParticleDecoration particle_decoration(new Particle(n_particle, new FormFactorPyramid(5*Units::nanometer, 5*Units::nanometer, Units::deg2rad(54.73 ) ) ) );
-        //InterferenceFunction1DParaCrystal *interference = new InterferenceFunction1DParaCrystal(20*Units::nanometer, 7*Units::nanometer, 1e7*Units::nanometer);
-        particle_decoration.addInterferenceFunction(new InterferenceFunctionNone());
-        //particle_decoration.addInterferenceFunction(interference);
-        LayerDecorator air_layer_decorator(air_layer, particle_decoration);
-
-        multi_layer.addLayer(air_layer_decorator);
-        multi_layer.addLayer(substrate_layer);
+    MultiLayer multi_layer;
+    const IMaterial *p_air_material = MaterialManager::instance().addHomogeneousMaterial("Air", 1.0, 0.0);
+    const IMaterial *p_substrate_material = MaterialManager::instance().addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
+    Layer air_layer;
+    air_layer.setMaterial(p_air_material);
+    Layer substrate_layer;
+    substrate_layer.setMaterial(p_substrate_material);
+
+    complex_t n_particle(1.0-6e-4, 2e-8);
+    ParticleDecoration particle_decoration(new Particle(n_particle, new FormFactorPyramid(5*Units::nanometer, 5*Units::nanometer, Units::deg2rad(54.73 ) ) ) );
+    particle_decoration.addInterferenceFunction(new InterferenceFunctionNone());
+    LayerDecorator air_layer_decorator(air_layer, particle_decoration);
+
+    multi_layer.addLayer(air_layer_decorator);
+    multi_layer.addLayer(substrate_layer);
 
     // ---------------------
     // building simulation
@@ -71,33 +69,31 @@ void FunctionalTests::IsGISAXS09::runpyramidZ45()
     // ---------------------
     // building sample
     // ---------------------
-        MultiLayer multi_layer;
-        const IMaterial *p_air_material = MaterialManager::instance().addHomogeneousMaterial("Air", 1.0, 0.0);
-        const IMaterial *p_substrate_material = MaterialManager::instance().addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
-        Layer air_layer;
-        air_layer.setMaterial(p_air_material);
-        Layer substrate_layer;
-        substrate_layer.setMaterial(p_substrate_material);
+    MultiLayer multi_layer;
+    const IMaterial *p_air_material = MaterialManager::instance().addHomogeneousMaterial("Air", 1.0, 0.0);
+    const IMaterial *p_substrate_material = MaterialManager::instance().addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
+    Layer air_layer;
+    air_layer.setMaterial(p_air_material);
+    Layer substrate_layer;
+    substrate_layer.setMaterial(p_substrate_material);
 
-        complex_t n_particle(1.0-6e-4, 2e-8);
+    complex_t n_particle(1.0-6e-4, 2e-8);
+    const double angle_around_z = 45.*Units::degree;
+    Particle *pyramid = new Particle(n_particle, new FormFactorPyramid(5*Units::nanometer, 5*Units::nanometer, Units::deg2rad(54.73)) );
 
-        const double angle_around_z = 45.*Units::degree;
+    Geometry::Transform3D *transform = new Geometry::RotateZ3D(angle_around_z);
 
-        Particle *pyramid = new Particle(n_particle, new FormFactorPyramid(5*Units::nanometer, 5*Units::nanometer, Units::deg2rad(54.73)) );
+    ParticleDecoration particle_decoration;
 
-        Geometry::Transform3D *transform = new Geometry::RotateZ3D(angle_around_z);
+    particle_decoration.addParticle(pyramid, transform);
+    particle_decoration.addInterferenceFunction(new InterferenceFunctionNone());
+    //InterferenceFunction1DParaCrystal *interference = new InterferenceFunction1DParaCrystal(20*Units::nanometer, 7*Units::nanometer, 1e7*Units::nanometer);
+    //particle_decoration.addInterferenceFunction(interference);
 
-        ParticleDecoration particle_decoration;
+    LayerDecorator air_layer_decorator(air_layer, particle_decoration);
 
-        particle_decoration.addParticle(pyramid, transform);
-        //particle_decoration.addInterferenceFunction(new InterferenceFunctionNone());
-        InterferenceFunction1DParaCrystal *interference = new InterferenceFunction1DParaCrystal(20*Units::nanometer, 7*Units::nanometer, 1e7*Units::nanometer);
-        particle_decoration.addInterferenceFunction(interference);
-
-        LayerDecorator air_layer_decorator(air_layer, particle_decoration);
-
-        multi_layer.addLayer(air_layer_decorator);
-        multi_layer.addLayer(substrate_layer);
+    multi_layer.addLayer(air_layer_decorator);
+    multi_layer.addLayer(substrate_layer);
 
     // ---------------------
     // building simulation
@@ -129,8 +125,8 @@ int FunctionalTests::IsGISAXS09::analyseResults()
     bool status_ok(true);
 
     for(size_t i=0; i<tocompare.size(); ++i) {
-        OutputData<double> *reference = OutputDataIOFactory::getOutputData(tocompare[i].isginame);
-        OutputData<double> *m_result = OutputDataIOFactory::getOutputData(tocompare[i].thisname);
+        OutputData<double> *reference = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].isginame);
+        OutputData<double> *m_result = OutputDataIOFactory::getOutputData(m_data_path+tocompare[i].thisname);
 
     // calculating average relative difference
     *m_result -= *reference;
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs010.py b/Tests/FunctionalTests/TestPyCore/isgisaxs010.py
new file mode 100644
index 0000000000000000000000000000000000000000..f1a637a5c9a1f6c2754244dfed21b972c6f117c5
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs010.py
@@ -0,0 +1,98 @@
+# IsGISAXS010 example: Cylinders with interference on top of substrate
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+
+# ----------------------------------
+# describe sample and run simulation
+# ----------------------------------
+def RunSimulation():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-5e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-5e-5, 2e-8)
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    interference = InterferenceFunction1DParaCrystal(20.0*nanometer,7*nanometer, 1e7*nanometer)
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(cylinder, 0.0, 1.0)
+    particle_decoration.addInterferenceFunction(interference)
+    # air layer with particles and substrate form multi layer
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f = gzip.open(path+'../TestCore/IsGISAXS010/isgisaxs010_reference.ima.gz', 'rb')
+    reference=numpy.fromstring(f.read(),numpy.float64,sep=' ')
+    f.close()
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result = RunSimulation()
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS010" + " " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs011.py b/Tests/FunctionalTests/TestPyCore/isgisaxs011.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffdeabedcb5caaf72105315824c69bd332679ba9
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs011.py
@@ -0,0 +1,105 @@
+# IsGISAXS011 example: Core shell nanoparticles
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+
+# ----------------------------------
+# describe sample and run simulation
+# ----------------------------------
+def RunSimulation():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+   
+    # collection of particles
+    n_particle_shell = complex(1.0-1e-4, 2e-8)
+    n_particle_core = complex(1.0-6e-5, 2e-8)
+    #parallelepiped1_ff = FormFactorParallelepiped(8*nanometer, 8*nanometer)
+    #parallelepiped2_ff = FormFactorParallelepiped(7*nanometer, 6*nanometer)
+    parallelepiped1_ff = FormFactorBox(8*nanometer, 8*nanometer, 8*nanometer)
+    parallelepiped2_ff = FormFactorBox(7*nanometer, 7*nanometer,6*nanometer)
+    shell_particle = Particle(n_particle_shell, parallelepiped1_ff)
+    core_particle = Particle(n_particle_core, parallelepiped2_ff)
+    core_position = kvector_t(0.0, 0.0, 0.0)
+    ##########################################
+    particle = ParticleCoreShell(shell_particle, core_particle, core_position)
+    particle_decoration= ParticleDecoration(particle.clone())
+    interference = InterferenceFunctionNone()
+    particle_decoration.addInterferenceFunction(interference)
+     
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    ## intensity data
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f = gzip.open(path+'../TestCore/IsGISAXS011/isgisaxs011_reference.ima.gz', 'rb')
+    reference=numpy.fromstring(f.read(),numpy.float64,sep=' ')
+    f.close()
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result = RunSimulation()
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS011" + "Core shell nanoparticles " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs015.py b/Tests/FunctionalTests/TestPyCore/isgisaxs015.py
new file mode 100644
index 0000000000000000000000000000000000000000..387beb5dd1c221f90b4d59da9b5c794b4c9d9019
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs015.py
@@ -0,0 +1,111 @@
+# IsGISAXS015 example: Size spacing correlation approximation
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+# ----------------------------------
+# describe sample and run simulation
+# ----------------------------------
+def RunSimulation():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    interference = InterferenceFunction1DParaCrystal(15.0*nanometer,5*nanometer, 1e3*nanometer)
+    interference.setKappa(4.02698)
+    particle_decoration = ParticleDecoration()
+    particle_prototype = Particle(n_particle, cylinder_ff)
+    stochastic_radius = StochasticSampledParameter(StochasticDoubleGaussian(5.0*nanometer, 1.25*nanometer), 30, 2)
+    
+    particle_builder = ParticleBuilder()
+    particle_builder.setPrototype(particle_prototype, "/Particle/FormFactorCylinder/radius", stochastic_radius)
+    particle_builder.plantParticles(particle_decoration)
+    #Set height of each particle to its radius (H/R fixed)
+    p_parameters = ParameterPool(particle_decoration.createParameterTree())
+    nbr_replacements = p_parameters.fixRatioBetweenParameters("height", "radius", 1.0)
+    print "Number of replacements: ", nbr_replacements
+    particle_decoration.addInterferenceFunction(interference)    
+    
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+   
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(150,0.05*degree, 1.5*degree, 150, 0.05*degree, 1.5*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+
+    sim_params = SimulationParameters()
+    sim_params.me_if_approx = SimulationParameters.SSCA
+    simulation.setSimulationParameters(sim_params)
+    
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    ## intensity data
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f = gzip.open(path+'../TestCore/IsGISAXS015/isgisaxs015_reference.ima.gz', 'rb')
+    reference=numpy.fromstring(f.read(),numpy.float64,sep=' ')
+    f.close()
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result = RunSimulation()
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS015" + " Size spacing correlation approximation " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs02.py b/Tests/FunctionalTests/TestPyCore/isgisaxs02.py
new file mode 100644
index 0000000000000000000000000000000000000000..8881901495ddf6f5565601afc5c5a8150fdfa452
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs02.py
@@ -0,0 +1,123 @@
+# IsGISAXS02 example: Mixture cylinder particles with different size distribution
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+
+# ----------------------------------
+# describe sample and run simulation
+# ----------------------------------
+def RunSimulation():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)
+    radius1 = 5.0*nanometer
+    radius2 = 10.0*nanometer
+    height1 = radius1
+    height2 = radius2
+    cylinder_ff1 = FormFactorCylinder(height1, radius1)
+    cylinder1 = Particle(n_particle, cylinder_ff1)
+    cylinder_ff2 = FormFactorCylinder(height2, radius2)
+    cylinder2 = Particle(n_particle, cylinder_ff2)  
+    nbins = 150
+    sigma1 = radius1*0.2
+    sigma2 = radius2*0.02
+     
+    nfwhm = 3
+    #to have xmin=average-nfwhm*FWHM, xmax=average+nfwhm*FWHM
+    #(nfwhm = xR/2, where xR is what is defined in isgisaxs *.inp file)
+    stochastic_gaussian1 = StochasticDoubleGaussian(radius1, sigma1)
+    stochastic_gaussian2 = StochasticDoubleGaussian(radius2, sigma2)
+    par1 = StochasticSampledParameter(stochastic_gaussian1 , nbins, nfwhm)
+    par2 = StochasticSampledParameter(stochastic_gaussian2, nbins, nfwhm)
+   
+    #Building nano particles
+    builder = ParticleBuilder()
+    builder.setPrototype(cylinder1,"/Particle/FormFactorCylinder/radius", par1, 0.95)
+    builder.plantParticles(particle_decoration)
+    builder.setPrototype(cylinder2,"/Particle/FormFactorCylinder/radius", par2, 0.05)
+    builder.plantParticles(particle_decoration)
+
+    particle_decoration = ParticleDecoration()
+    interference = InterferenceFunctionNone()
+    particle_decoration.addInterferenceFunction(interference)
+    #making layer holding all whose nano particles
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100, 0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+  
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    # intensity data
+    return GetOutputData(simulation)
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f = gzip.open(path+'../TestCore/IsGISAXS02/isgisaxs02_reference.ima.gz', 'rb')
+    reference=numpy.fromstring(f.read(),numpy.float64,sep=' ')
+    f.close()
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result = RunSimulation()
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS02" + "Mixture cylinder particles with different size distribution " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs03.py b/Tests/FunctionalTests/TestPyCore/isgisaxs03.py
new file mode 100644
index 0000000000000000000000000000000000000000..b0e6ac6f23658bfa0b2e8bf9230b15ea9160f831
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs03.py
@@ -0,0 +1,184 @@
+# IsGISAXS03 example: Cylinder formfactor in BA and DWBA
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+# ----------------------------------
+# describe sample and run simulation
+# ----------------------------------
+def RunSimulationDWBA():
+    
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )    
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)    
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(cylinder, 0.0, 1.0)
+    interference = InterferenceFunctionNone()
+    particle_decoration.addInterferenceFunction(interference)
+    # air layer with particles and substrate form multi layer
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    # intensity data
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - IsGISAXS3 functional test: cylinder in the air
+# ----------------------------------
+def RunSimulationBA():
+     # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(cylinder, 0.0, 1.0)
+    interference = InterferenceFunctionNone()
+    particle_decoration.addInterferenceFunction(interference)
+    
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - IsGISAXS3 functional test: cylinder in the air with size distribution
+# ----------------------------------
+def RunSimulationBA_Size():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    
+    n_particle = complex(1.0-6e-4, 2e-8)
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    particle_decoration = ParticleDecoration()
+    # preparing prototype of nano particle
+    radius = 5*nanometer
+    sigma = 0.2*radius
+    nano_particle = Particle(n_particle, cylinder_ff)
+    # radius of nanoparticles will be sampled with gaussian probability
+    nbins = 100
+    nfwhm = 2
+    stochastic_gaussian = StochasticDoubleGaussian(radius, sigma)
+    par = StochasticSampledParameter(stochastic_gaussian, nbins, nfwhm)
+
+    builder = ParticleBuilder()
+    builder.setPrototype(nano_particle,"/Particle/FormFactorCylinder/radius", par)
+    builder.plantParticles(particle_decoration)
+    interference = InterferenceFunctionNone()
+    particle_decoration.addInterferenceFunction(interference)    
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)  
+    multi_layer.addLayer(air_layer_decorator)
+
+    # build and run experiment  
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+      
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    fBA = gzip.open(path+'../TestCore/IsGISAXS03/isgisaxs03_reference_BA.ima.gz', 'rb')
+    referenceBA=numpy.fromstring(fBA.read(),numpy.float64,sep=' ')
+    fBA.close()
+    fBA_Size = gzip.open(path+'../TestCore/IsGISAXS03/isgisaxs03_reference_BA_size.ima.gz', 'rb')
+    referenceBA_Size=numpy.fromstring(fBA_Size.read(),numpy.float64,sep=' ')
+    fBA_Size.close()
+    fDWBA = gzip.open(path+'../TestCore/IsGISAXS03/isgisaxs03_reference_DWBA.ima.gz', 'rb')
+    referenceDWBA=numpy.fromstring(fDWBA.read(),numpy.float64,sep=' ')
+    fDWBA.close()
+    reference=numpy.concatenate((referenceBA,referenceBA_Size,referenceDWBA),axis=0)  
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    resultBA = RunSimulationBA()
+    resultDWBA = RunSimulationDWBA()
+    resultBA_Size = RunSimulationBA_Size()
+    result = numpy.concatenate((resultBA,resultBA_Size,resultDWBA),axis=0)
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS03" + " Cylinder formfactor in BA and DWBA " + status
+
+   
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs04.py b/Tests/FunctionalTests/TestPyCore/isgisaxs04.py
new file mode 100644
index 0000000000000000000000000000000000000000..3d6833515cfa0a674596438b3da45cd91f2b6c8f
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs04.py
@@ -0,0 +1,145 @@
+# IsGISAXS04 example: 1D and 2D paracrystal
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+# ----------------------------------
+# describe sample and run simulation - 1DDL structure factor
+# ----------------------------------
+def RunSimulation1():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)   
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    interference = InterferenceFunction1DParaCrystal(20.0*nanometer,7*nanometer, 1e3*nanometer)
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(cylinder, 0.0, 1.0)
+    particle_decoration.addInterferenceFunction(interference)
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    ## intensity data
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - 2DDL structure factor
+# ----------------------------------
+def RunSimulation2():
+#    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)
+    
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+
+    interference = InterferenceFunction2DParaCrystal.createHexagonal(20.0*nanometer, 0.0,20.0*micrometer, 20.0*micrometer)
+    pdf = FTDistribution2DCauchy(1.0*nanometer, 1.0*nanometer)
+    interference.setProbabilityDistributions(pdf, pdf)
+
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(cylinder, 0.0, 1.0)
+    particle_decoration.addInterferenceFunction(interference)
+    
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    #gsl_set_error_handler_off()
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f1 = gzip.open(path+'../TestCore/IsGISAXS04/isgisaxs04_reference_1DDL.ima.gz', 'rb')
+    reference1=numpy.fromstring(f1.read(),numpy.float64,sep=' ')
+    f1.close()
+    f2 = gzip.open(path+'../TestCore/IsGISAXS04/isgisaxs04_reference_2DDLh.ima.gz', 'rb')
+    reference2=numpy.fromstring(f2.read(),numpy.float64,sep=' ')
+    f2.close()
+    reference=numpy.concatenate((reference1,reference2),axis=0)
+    return reference2
+    #return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result1 = RunSimulation1()
+    result2 = RunSimulation2()
+    result = numpy.concatenate((result1,result2),axis=0) 
+    reference = GetReferenceData()
+    
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS04" + " 1D and 2D paracrystal " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs06.py b/Tests/FunctionalTests/TestPyCore/isgisaxs06.py
new file mode 100644
index 0000000000000000000000000000000000000000..98064647ed1ab542f7e677303d053b63ff54bfb5
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs06.py
@@ -0,0 +1,332 @@
+# IsGISAXS06 example: 2D lattice with different disorder
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+M_PI = numpy.pi
+
+# ----------------------------------
+# describe sample and run simulation
+# ----------------------------------
+def RunSimulation_lattice():
+# defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    lattice_params = Lattice2DIFParameters()
+    m_length_1 = 10.0*nanometer
+    m_length_2 = 10.0*nanometer
+    m_angle = 90.0*degree
+    m_xi = 0.0*degree
+    m_domain_size_1 = 20000.0*nanometer
+    m_domain_size_2 = 20000.0*nanometer
+    m_corr_length_1 = 300.0*nanometer/2.0/M_PI
+    m_corr_length_2 = 100.0*nanometer/2.0/M_PI
+   
+    interference = InterferenceFunction2DLattice(lattice_params)
+    pdf = FTDistribution2DCauchy(300.0*nanometer/2.0/M_PI, 100.0*nanometer/2.0/M_PI)
+    interference.setProbabilityDistribution(pdf)
+    
+    n_particle = complex(1.0-6e-4, 2e-8)
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff.clone())
+    position = kvector_t(0.0, 0.0, 0.0)
+    particle_decoration = ParticleDecoration()
+    particle_info =  PositionParticleInfo(cylinder, 0, position, 1.0)
+    particle_decoration.addParticleInfo(particle_info)
+    particle_decoration.addInterferenceFunction(interference)
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    
+    sim_params= SimulationParameters()
+    sim_params.me_framework = SimulationParameters.DWBA
+    sim_params.me_if_approx = SimulationParameters.LMA
+    sim_params.me_lattice_type = SimulationParameters.LATTICE
+    simulation.setSimulationParameters(sim_params)
+    
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - cylinders lattice centered
+# ----------------------------------
+def RunSimulation_centered():
+# defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    lattice_params = Lattice2DIFParameters()
+    m_length_1 = 10.0*nanometer
+    m_length_2 = 10.0*nanometer
+    m_angle = 90.0*degree
+    m_xi = 0.0*degree
+    m_domain_size_1 = 20000.0*nanometer
+    m_domain_size_2 = 20000.0*nanometer
+    m_corr_length_1 = 300.0*nanometer/2.0/M_PI
+    m_corr_length_2 = 100.0*nanometer/2.0/M_PI
+    interference = InterferenceFunction2DLattice(lattice_params)
+    pdf = FTDistribution2DCauchy(300.0*nanometer/2.0/M_PI, 100.0*nanometer/2.0/M_PI)
+    interference.setProbabilityDistribution(pdf)
+    
+    n_particle = complex(1.0-6e-4, 2e-8)
+    particle_decoration = ParticleDecoration()
+    position = kvector_t(0.0, 0.0, 0.0)
+    # particle 1
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    position = kvector_t(0.0, 0.0, 0.0)
+    particle_info = PositionParticleInfo(cylinder, 0, position, 1.0)
+    particle_decoration.addParticleInfo(particle_info)
+    # particle 2
+    position_2 = kvector_t(5.0*nanometer, 5.0*nanometer, 0.0)
+    particle_info.setPosition(position_2)  
+    particle_decoration.addParticleInfo(particle_info)
+    particle_decoration.addInterferenceFunction(interference)
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    
+    sim_params= SimulationParameters()
+    sim_params.me_framework = SimulationParameters.DWBA
+    sim_params.me_if_approx = SimulationParameters.LMA
+    sim_params.me_lattice_type = SimulationParameters.LATTICE
+    simulation.setSimulationParameters(sim_params)
+    
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - cylinders lattice rotated
+# ----------------------------------
+def RunSimulation_rotated():
+# defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    lattice_params = Lattice2DIFParameters()
+    m_length_1 = 10.0*nanometer
+    m_length_2 = 10.0*nanometer
+    m_angle = 90.0*degree
+    m_xi = 30.0*degree
+    m_domain_size_1 = 20000.0*nanometer
+    m_domain_size_2 = 20000.0*nanometer
+    m_corr_length_1 = 300.0*nanometer/2.0/M_PI
+    m_corr_length_2 = 100.0*nanometer/2.0/M_PI
+    interference = InterferenceFunction2DLattice(lattice_params)
+    pdf = FTDistribution2DCauchy(300.0*nanometer/2.0/M_PI, 100.0*nanometer/2.0/M_PI)
+    pdf.setGamma(30.0*degree)
+    interference.setProbabilityDistribution(pdf)
+    
+    n_particle = complex(1.0-6e-4, 2e-8)
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    position = kvector_t(0.0, 0.0, 0.0)
+    particle_decoration = ParticleDecoration()
+    particle_info =  PositionParticleInfo(cylinder, 0, position, 1.0)
+    particle_decoration.addParticleInfo(particle_info)
+    particle_decoration.addInterferenceFunction(interference)
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    
+    sim_params = SimulationParameters()
+    sim_params.me_framework = SimulationParameters.DWBA
+    sim_params.me_if_approx = SimulationParameters.LMA
+    sim_params.me_lattice_type = SimulationParameters.LATTICE
+    simulation.setSimulationParameters(sim_params)
+    
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - lattice variants
+# ----------------------------------
+def RunSimulation_variants():
+
+    # building simulation
+    simulation.runSimulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    
+    sim_params = SimulationParameters()
+    sim_params.me_framework = SimulationParameters.DWBA
+    sim_params.me_if_approx = SimulationParameters.LMA
+    sim_params.me_lattice_type = SimulationParameters.LATTICE
+    simulation.setSimulationParameters(sim_params)
+
+    # running simulation and copying data
+    OutputDatap_total = simulation.getOutputDataClone()
+    p_total.setAllTo(0.0)
+    nbins = 3
+    xi_min = 0.0*degree
+    xi_max = 240.0*degree
+    xi= StochasticSampledParameter(StochasticDoubleGate(xi_min, xi_max), nbins, xi_min, xi_max)
+    #for size_t i in range(xi.getNbins()) :
+    for i in range(xi.getNbins()) :
+        xi_value = xi.getBinValue(i)
+        probability = xi.getNormalizedProbability(i)
+        m_builder.setXi(xi_value)
+#             MultiLayer *p_sample = dynamic_cast<MultiLayer *>(m_builder.buildSample());
+        p_sample =  buildSample()
+        simulation.setSample(p_sample)
+        simulation.runSimulation()
+        delete p_sample
+        p_single_output = simulation.getOutputDataClone()
+        p_single_output.scaleAll(probability)
+        p_total += p_single_output
+        delete p_single_output
+        
+    return GetOutputData(simulation)
+    delete p_total
+
+
+# IsGISAXS6 functional test sample builder for varying xi angle
+def buildSample():
+#ISample* FunctionalTests::IsGISAXS06::LatticeVariantBuilder::buildSample() const
+
+    n_particle = complex(1.0-6e-4, 2e-8)
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    lattice_params = Lattice2DIFParameters()
+    m_length_1 = 10.0*nanometer
+    m_length_2 = 10.0*nanometer
+    m_angle = 90.0*degree
+    m_domain_size_1 = 20000.0*nanometer
+    m_domain_size_2 = 20000.0*nanometer
+    m_corr_length_1 = 300.0*nanometer/2.0/M_PI
+    m_corr_length_2 = 100.0*nanometer/2.0/M_PI
+    p_interference_function = InterferenceFunction2DLattice(lattice_params)
+    pdf = FTDistribution2DCauchy (300.0*nanometer/2.0/M_PI, 100.0*nanometer/2.0/M_PI)
+    p_interference_function.setProbabilityDistribution(pdf)
+
+    particle_decoration = ParticleDecoration()
+    # particle
+    ff_cyl = FormFactorCylinder(5.0*nanometer, 5.0*nanometer)
+    position = kvector_t(0.0, 0.0, 0.0)
+    cylinder = Particle(n_particle, ff_cyl.clone())
+    particle_info = PositionParticleInfo( cylinder , 0, position, 1.0)
+    particle_decoration.addParticleInfo(particle_info)
+    particle_decoration.addInterferenceFunction(p_interference_function)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    return p_multi_layer
+
+      
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    flattice = gzip.open(path+'../TestCore/IsGISAXS06/isgisaxs06_reference_lattice.ima.gz', 'rb')
+    referencelattice=numpy.fromstring(flattice.read(),numpy.float64,sep=' ')
+    flattice.close()
+    fcentered = gzip.open(path+'../TestCore/IsGISAXS06/isgisaxs06_reference_centered.ima.gz', 'rb')
+    referencecentered=numpy.fromstring(fBA_Size.read(),numpy.float64,sep=' ')
+    frotated.close()
+    frotated = gzip.open(path+'../TestCore/IsGISAXS06/isgisaxs06_reference_rotated.ima.gz', 'rb')
+    referencerotated=numpy.fromstring(fDWBA.read(),numpy.float64,sep=' ')
+    frotated.close()
+    fvariants = gzip.open(path+'../TestCore/IsGISAXS06/isgisaxs06_reference_variants.ima.gz', 'rb')
+    referencevariants=numpy.fromstring(fDWBA.read(),numpy.float64,sep=' ')
+    fvariants.close()
+    reference=numpy.concatenate((referencelattice,referencecentered,referencerotated,referencevariants),axis=0)  
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result_lattice = RunSimulation_lattice()
+    result_centered = RunSimulation_centered()
+    result_rotated = RunSimulation_rotated()
+    result_variants = RunSimulation_variants()
+    
+    result = numpy.concatenate((result_lattice,result_centered,result_rotated,result_variants),axis=0)
+    #result = numpy.concatenate((result_lattice,result_centered,result_rotated),axis=0) 
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS06" + " 2D lattice with different disorder " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
+
+
+ 
+ 
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs07.py b/Tests/FunctionalTests/TestPyCore/isgisaxs07.py
new file mode 100644
index 0000000000000000000000000000000000000000..34fc17db8214dc6fa0e0c315f953285606fdc070
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs07.py
@@ -0,0 +1,183 @@
+# IsGISAXS07 example: Mixture of different particles defined in morphology file
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+
+# ----------------------------------
+# describe sample and run simulation
+# ----------------------------------
+def RunSimulation():
+    
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)   
+    particle_decoration = ParticleDecoration()
+
+
+    
+    #PositionParticleInfo particle_info1(new Particle(n_particle, ff1), 0, pos1, 0.5);
+    #particle_decoration.addParticleInfo(particle_info1);
+    #
+    # add particle number 1:
+    ff1 = FormFactorBox(1.0*nanometer, 1.0*nanometer,1.0*nanometer)
+    pos1 = kvector_t(0.0*nanometer, 0.0*nanometer, 0.0)
+    particle1 = Particle(n_particle, ff1)
+    particle_info1 = PositionParticleInfo(particle1, 0, pos1, 0.5)
+    particle_decoration.addParticleInfo(particle_info1)
+    #add particle number 2:
+    ff2 = FormFactorBox(1.0*nanometer, 2.0*nanometer,1.0*nanometer)
+    pos2 = kvector_t(5.0*nanometer, 5.0*nanometer, 0.0)
+    rotate3d2 = RotateZ3D(10*degree)
+    p_rot2 = Transform3D(rotate3d2)
+    particle2 = Particle(n_particle, ff2)   
+    particle_info2 = PositionParticleInfo(particle2, p_rot2, pos2, 0.5)
+    particle_decoration.addParticleInfo(particle_info2)
+    #add particle number 3:
+    ff3 = FormFactorBox(1.0*nanometer, 3.0*nanometer,1.0*nanometer)
+    pos3 = kvector_t(-5.0*nanometer, -5.0*nanometer, 0.0)
+    rotate3d3 = RotateZ3D(20*degree)
+    p_rot3 = Transform3D(rotate3d3)   
+    particle3 = Particle(n_particle, ff3)
+    particle_info3 = PositionParticleInfo(particle3, p_rot3, pos3, 0.5)
+    particle_decoration.addParticleInfo(particle_info3)
+    #add particle number 4:
+    ff4 = FormFactorBox(1.0*nanometer, 4.0*nanometer,1.0*nanometer)
+    pos4 = kvector_t(5.0*nanometer, -5.0*nanometer, 0.0)
+    rotate3d4 = RotateZ3D(30*degree)
+    p_rot4 = Transform3D(rotate3d4)   
+    particle4 = Particle(n_particle, ff4)   
+    particle_info4 = PositionParticleInfo(particle4, p_rot4, pos4, 0.5)
+    particle_decoration.addParticleInfo(particle_info4)
+    #add particle number 5:
+    ff5 = FormFactorBox(1.0*nanometer, 5.0*nanometer,1.0*nanometer)
+    pos5 = kvector_t(-5.0*nanometer, 5.0*nanometer, 0.0)
+    rotate3d5 = RotateZ3D(40*degree)
+    p_rot5 = Transform3D(rotate3d5)   
+    particle5 = Particle(n_particle, ff5)   
+    particle_info5 =  PositionParticleInfo(particle5, p_rot5, pos5, 0.5)
+    particle_decoration.addParticleInfo(particle_info5)
+    #add particle number 6:
+    ff6 = FormFactorBox(1.0*nanometer, 1.0*nanometer,1.0*nanometer)
+    pos6 = kvector_t(0.0*nanometer, 0.0*nanometer, 0.0)
+    rotate3d6 = RotateZ3D(50*degree)
+    p_rot6 = Transform3D(rotate3d6)
+    particle6 = Particle(n_particle, ff6)   
+    particle_info6 = PositionParticleInfo(particle6, p_rot6, pos6, 0.5)
+    particle_decoration.addParticleInfo(particle_info6)
+    #add particle number 7:
+    ff7 = FormFactorBox(1.0*nanometer, 2.0*nanometer,1.0*nanometer)
+    pos7 = kvector_t(5.0*nanometer, 5.0*nanometer, 0.0)
+    rotate3d7 = RotateZ3D(60*degree)
+    p_rot7 = Transform3D(rotate3d7)
+    particle7 = Particle(n_particle, ff7)
+    particle_info7 = PositionParticleInfo(particle7, p_rot7, pos7, 0.5)
+    particle_decoration.addParticleInfo(particle_info7)
+    #add particle number 8:
+    ff8 = FormFactorBox(1.0*nanometer, 3.0*nanometer,1.0*nanometer)
+    pos8 = kvector_t(-5.0*nanometer, -5.0*nanometer, 0.0)
+    rotate3d8 = RotateZ3D(70*degree)
+    p_rot8 = Transform3D(rotate3d8)
+    particle8 = Particle(n_particle, ff8)    
+    particle_info8 = PositionParticleInfo(particle8 , p_rot8, pos8, 0.5)
+    particle_decoration.addParticleInfo(particle_info8)
+    #add particle number 9:
+    ff9 = FormFactorBox(1.0*nanometer, 4.0*nanometer,1.0*nanometer)
+    pos9 = kvector_t(5.0*nanometer, -5.0*nanometer, 0.0)
+    rotate3d9 = RotateZ3D(80*degree)
+    p_rot9 = Transform3D(rotate3d9)
+    particle9 = Particle(n_particle, ff9)     
+    particle_info9 = PositionParticleInfo(particle9, p_rot9, pos9, 0.5)
+    particle_decoration.addParticleInfo(particle_info9)
+    #add particle number 10:
+    ff10 = FormFactorBox(1.0*nanometer, 5.0*nanometer,1.0*nanometer)
+    pos10 = kvector_t(-5.0*nanometer, 5.0*nanometer, 0.0)
+    rotate3d10 = RotateZ3D(90*degree)
+    p_rot10 = Transform3D(rotate3d10)
+    particle10 = Particle(n_particle, ff10)
+    particle_info10 = PositionParticleInfo(particle10, p_rot10, pos10, 0.5)
+    particle_decoration.addParticleInfo(particle_info10)
+
+    # air layer with particles and substrate form multi layer
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+  
+    #build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 1.0*degree, 100, 0.0*degree, 1.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, 0.0*degree, 0.0*degree)
+
+    sim_params = SimulationParameters()
+    sim_params.me_if_approx = SimulationParameters.ISGISAXSMOR
+    simulation.setSimulationParameters(sim_params)
+ 
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    ## intensity data
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f = gzip.open(path+'../TestCore/IsGISAXS07/isgisaxs07_reference.ima.gz', 'rb')
+    reference=numpy.fromstring(f.read(),numpy.float64,sep=' ')
+    f.close()
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result = RunSimulation()
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS07" + " Mixture of different particles defined in morphology file " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs08.py b/Tests/FunctionalTests/TestPyCore/isgisaxs08.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ad1dff34b9aa9ad30cee4c7093644a6371cef4c
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs08.py
@@ -0,0 +1,149 @@
+# IsGISAXS08 example: 2DDL paracrystal
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+M_PI = numpy.pi
+# ----------------------------------
+# describe sample and run simulation - 
+# ----------------------------------
+def RunSimulation1():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)   
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    interference = InterferenceFunction2DParaCrystal(10.0*nanometer, 10.0*nanometer, M_PI/2.0, 0.0, 0.0)
+    interference.setDomainSizes(20.0*micrometer, 20.0*micrometer)
+    pdf1 = FTDistribution2DCauchy(0.5*nanometer, 2.0*nanometer)
+    pdf2 = FTDistribution2DCauchy(0.5*nanometer, 2.0*nanometer)
+    interference.setProbabilityDistributions(pdf1, pdf2)
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(cylinder, 0.0, 1.0)
+    particle_decoration.addInterferenceFunction(interference)
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    ## intensity data
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - 2D paracrystal lattice with isotropic pdfs
+# ----------------------------------
+def RunSimulation2():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)
+    cylinder_ff = FormFactorCylinder(5*nanometer, 5*nanometer)
+    cylinder = Particle(n_particle, cylinder_ff)
+    interference = InterferenceFunction2DParaCrystal(10.0*nanometer, 10.0*nanometer, M_PI/2.0, 0.0, 0.0)
+    interference.setDomainSizes(20.0*micrometer, 20.0*micrometer)
+    pdf1 = FTDistribution2DCauchy(0.5*nanometer, 0.5*nanometer)
+    pdf2 = FTDistribution2DCauchy(0.5*nanometer, 0.5*nanometer)
+    interference.setProbabilityDistributions(pdf1, pdf2)
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(cylinder, 0.0, 1.0)
+    particle_decoration.addInterferenceFunction(interference)
+    
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f1 = gzip.open(path+'../TestCore/IsGISAXS08/isgisaxs08_reference_2DDL_lattice.ima.gz', 'rb')
+    reference1=numpy.fromstring(f1.read(),numpy.float64,sep=' ')
+    f1.close()
+    f2 = gzip.open(path+'../TestCore/IsGISAXS08/isgisaxs08_reference_2DDL_lattice2.ima.gz', 'rb')
+    reference2=numpy.fromstring(f2.read(),numpy.float64,sep=' ')
+    f2.close()
+    reference=numpy.concatenate((reference1,reference2),axis=0)    
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result1 = RunSimulation1()
+    result2 = RunSimulation2()
+    result = numpy.concatenate((result1,result2),axis=0) 
+    reference = GetReferenceData()
+
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS08" + " 2DDL paracrystal " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+
diff --git a/Tests/FunctionalTests/TestPyCore/isgisaxs09.py b/Tests/FunctionalTests/TestPyCore/isgisaxs09.py
new file mode 100644
index 0000000000000000000000000000000000000000..ee5e9ee870f7b914503fe40ff998db59e465ade8
--- /dev/null
+++ b/Tests/FunctionalTests/TestPyCore/isgisaxs09.py
@@ -0,0 +1,157 @@
+# IsGISAXS09 example: Pyramids on top of substrate - Rotated pyramids on top of substrate
+import sys
+import os
+import numpy
+import gzip
+
+sys.path.append(os.path.abspath(
+                os.path.join(os.path.split(__file__)[0],
+                '..', '..', '..', 'lib')))
+
+from libBornAgainCore import *
+
+# ----------------------------------
+# describe sample and run simulation - Pyramid
+# ----------------------------------
+def RunSimulation1():
+    # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)   
+    pyramid_ff = FormFactorPyramid(5*nanometer, 5*nanometer, deg2rad(54.73 ) )
+    pyramid = Particle(n_particle, pyramid_ff)
+    interference = InterferenceFunctionNone()
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(pyramid, 0.0, 1.0)
+    particle_decoration.addInterferenceFunction(interference)
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    ## intensity data
+    return GetOutputData(simulation)
+
+
+# ----------------------------------
+# describe sample and run simulation - Rotated Pyramid
+# ----------------------------------
+def RunSimulation2():
+   # defining materials
+    matMng = MaterialManager.instance()
+    mAmbience = matMng.addHomogeneousMaterial("Air", 1.0, 0.0 )
+    mSubstrate = matMng.addHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8 )
+    # collection of particles
+    n_particle = complex(1.0-6e-4, 2e-8)   
+    pyramid_ff = FormFactorPyramid(5*nanometer, 5*nanometer, deg2rad(54.73 ) )
+    pyramid = Particle(n_particle, pyramid_ff)
+    interference = InterferenceFunctionNone()
+    angle_around_z = 45.*degree
+    rotatez3d = RotateZ3D(angle_around_z)
+    transform = Transform3D(rotatez3d)
+    particle_decoration = ParticleDecoration()
+    particle_decoration.addParticle(pyramid, transform)
+    
+    particle_decoration.addInterferenceFunction(interference)
+
+    air_layer = Layer(mAmbience)
+    air_layer_decorator = LayerDecorator(air_layer, particle_decoration)
+    substrate_layer = Layer(mSubstrate, 0)
+    
+    multi_layer = MultiLayer()
+    multi_layer.addLayer(air_layer_decorator)
+    multi_layer.addLayer(substrate_layer)
+    # build and run experiment
+    simulation = Simulation()
+    simulation.setDetectorParameters(100,0.0*degree, 2.0*degree, 100, 0.0*degree, 2.0*degree, True)
+    simulation.setBeamParameters(1.0*angstrom, -0.2*degree, 0.0*degree)
+    simulation.setSample(multi_layer)
+    simulation.runSimulation()
+    ## intensity data
+    return GetOutputData(simulation)
+
+
+
+
+        
+
+       
+
+       
+      
+
+    
+
+      
+
+
+# ----------------------------------
+# read reference data from file
+# ----------------------------------
+def GetReferenceData():
+    path = os.path.split(__file__)[0]
+    if path: path +="/"
+    f1 = gzip.open(path+'../TestCore/IsGISAXS09/isgisaxs09_reference_pyramid_Z0.ima.gz', 'rb')
+    reference1=numpy.fromstring(f1.read(),numpy.float64,sep=' ')
+    f1.close()   
+    f2 = gzip.open(path+'../TestCore/IsGISAXS09/isgisaxs09_reference_pyramid_Z45.ima.gz', 'rb')
+    reference2=numpy.fromstring(f2.read(),numpy.float64,sep=' ')
+    f2.close()
+    reference=numpy.concatenate((reference1,reference2),axis=0)    
+    return reference
+
+
+# --------------------------------------------------------------
+# calculate numeric difference between result and reference data
+# --------------------------------------------------------------
+def GetDifference(data, reference):
+    reference = reference.reshape(data.shape)
+    # calculating relative average difference
+    data -= reference
+    diff=0.0
+    epsilon = sys.float_info.epsilon
+    for x, y in numpy.ndindex(data.shape):
+        v1 = data[x][y]
+        v2 = reference[x][y]
+        if v1 <= epsilon and v2 <= epsilon:
+            diff += 0.0
+        elif(v2 <= epsilon):
+            diff += abs(v1/epsilon)
+        else:
+            diff += abs(v1/v2)
+    return diff/data.size
+
+
+# --------------------------------------------------------------
+# run test and analyse test results
+# --------------------------------------------------------------
+def RunTest():
+    result1 = RunSimulation1()
+    result2 = RunSimulation2()
+    result = numpy.concatenate((result1,result2),axis=0) 
+    reference = GetReferenceData()
+    
+    diff = GetDifference(result, reference)
+    status = "OK"
+    if(diff > 1e-10): status = "FAILED"
+    return "IsGISAXS09" + " Pyramids on top of substrate - Rotated pyramids on top of substrate " + status
+
+
+#-------------------------------------------------------------
+# main()
+#-------------------------------------------------------------
+if __name__ == '__main__':
+  print RunTest()
+
+