From cd2d54e320644939b77ca6f79a5f9d63b855e741 Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Wed, 6 Aug 2014 09:36:27 +0200
Subject: [PATCH] Serialization of FixedBinAxis and new PythonAPI.

---
 Core/PythonAPI/inc/AngleBinAxis.pypp.h      |  11 +
 Core/PythonAPI/inc/FixedBinAxis.pypp.h      |  11 +
 Core/PythonAPI/inc/PythonCoreList.h         |   3 +
 Core/PythonAPI/inc/VariableBinAxis.pypp.h   |  11 +
 Core/PythonAPI/src/AngleBinAxis.pypp.cpp    | 244 ++++++++++++++++++++
 Core/PythonAPI/src/FixedBinAxis.pypp.cpp    | 240 +++++++++++++++++++
 Core/PythonAPI/src/IAxis.pypp.cpp           |  17 +-
 Core/PythonAPI/src/PythonModule.cpp         |   6 +
 Core/PythonAPI/src/VariableBinAxis.pypp.cpp | 232 +++++++++++++++++++
 Core/Tools/inc/OutputDataIOFactory.h        |   4 +-
 Core/Tools/inc/OutputDataIOHelper.h         |  38 +++
 Core/Tools/inc/OutputDataReadStrategy.h     |  14 +-
 Core/Tools/inc/OutputDataReader.h           |  18 +-
 Core/Tools/inc/OutputDataWriteStrategy.h    |  15 +-
 Core/Tools/inc/OutputDataWriter.h           |  20 +-
 Core/Tools/inc/Utils.h                      |   3 +
 Core/Tools/src/FixedBinAxis.cpp             |   3 +-
 Core/Tools/src/OutputDataIOFactory.cpp      |   8 +
 Core/Tools/src/OutputDataIOHelper.cpp       |  68 ++++++
 Core/Tools/src/OutputDataReadStrategy.cpp   |  25 ++
 Core/Tools/src/OutputDataReader.cpp         |  31 ++-
 Core/Tools/src/OutputDataWriteStrategy.cpp  |  30 +++
 Core/Tools/src/OutputDataWriter.cpp         |  39 ++++
 Core/Tools/src/Utils.cpp                    |   9 +
 Tests/UnitTests/TestCore/FixedBinAxisTest.h |  13 ++
 dev-tools/python-bindings/settings_core.py  |   3 +
 26 files changed, 1085 insertions(+), 31 deletions(-)
 create mode 100644 Core/PythonAPI/inc/AngleBinAxis.pypp.h
 create mode 100644 Core/PythonAPI/inc/FixedBinAxis.pypp.h
 create mode 100644 Core/PythonAPI/inc/VariableBinAxis.pypp.h
 create mode 100644 Core/PythonAPI/src/AngleBinAxis.pypp.cpp
 create mode 100644 Core/PythonAPI/src/FixedBinAxis.pypp.cpp
 create mode 100644 Core/PythonAPI/src/VariableBinAxis.pypp.cpp
 create mode 100644 Core/Tools/inc/OutputDataIOHelper.h
 create mode 100644 Core/Tools/src/OutputDataIOHelper.cpp

diff --git a/Core/PythonAPI/inc/AngleBinAxis.pypp.h b/Core/PythonAPI/inc/AngleBinAxis.pypp.h
new file mode 100644
index 00000000000..7d8f0a4a87e
--- /dev/null
+++ b/Core/PythonAPI/inc/AngleBinAxis.pypp.h
@@ -0,0 +1,11 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence
+//! @brief Automatically generated boost::python code for PythonCoreAPI
+
+#ifndef AngleBinAxis_hpp__pyplusplus_wrapper
+#define AngleBinAxis_hpp__pyplusplus_wrapper
+
+void register_AngleBinAxis_class();
+
+#endif//AngleBinAxis_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/FixedBinAxis.pypp.h b/Core/PythonAPI/inc/FixedBinAxis.pypp.h
new file mode 100644
index 00000000000..fed04134ed6
--- /dev/null
+++ b/Core/PythonAPI/inc/FixedBinAxis.pypp.h
@@ -0,0 +1,11 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence
+//! @brief Automatically generated boost::python code for PythonCoreAPI
+
+#ifndef FixedBinAxis_hpp__pyplusplus_wrapper
+#define FixedBinAxis_hpp__pyplusplus_wrapper
+
+void register_FixedBinAxis_class();
+
+#endif//FixedBinAxis_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/inc/PythonCoreList.h b/Core/PythonAPI/inc/PythonCoreList.h
index 738dccd1c8f..90ed5b0369e 100644
--- a/Core/PythonAPI/inc/PythonCoreList.h
+++ b/Core/PythonAPI/inc/PythonCoreList.h
@@ -6,6 +6,9 @@
 #include "IAxis.h"
 #include "AxisBin.h"
 #include "AxisDouble.h"
+#include "FixedBinAxis.h"
+#include "VariableBinAxis.h"
+#include "AngleBinAxis.h"
 #include "BasicVector3D.h"
 #include "BAVersion.h"
 #include "Bin.h"
diff --git a/Core/PythonAPI/inc/VariableBinAxis.pypp.h b/Core/PythonAPI/inc/VariableBinAxis.pypp.h
new file mode 100644
index 00000000000..c8ea5e11ac8
--- /dev/null
+++ b/Core/PythonAPI/inc/VariableBinAxis.pypp.h
@@ -0,0 +1,11 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence
+//! @brief Automatically generated boost::python code for PythonCoreAPI
+
+#ifndef VariableBinAxis_hpp__pyplusplus_wrapper
+#define VariableBinAxis_hpp__pyplusplus_wrapper
+
+void register_VariableBinAxis_class();
+
+#endif//VariableBinAxis_hpp__pyplusplus_wrapper
diff --git a/Core/PythonAPI/src/AngleBinAxis.pypp.cpp b/Core/PythonAPI/src/AngleBinAxis.pypp.cpp
new file mode 100644
index 00000000000..252792a7960
--- /dev/null
+++ b/Core/PythonAPI/src/AngleBinAxis.pypp.cpp
@@ -0,0 +1,244 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence
+//! @brief Automatically generated boost::python code for PythonCoreAPI
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter)
+GCC_DIAG_OFF(missing-field-initializers)
+#include "boost/python.hpp"
+GCC_DIAG_ON(unused-parameter)
+GCC_DIAG_ON(missing-field-initializers)
+#include "PythonCoreList.h"
+#include "AngleBinAxis.pypp.h"
+
+namespace bp = boost::python;
+
+struct AngleBinAxis_wrapper : AngleBinAxis, bp::wrapper< AngleBinAxis > {
+
+    AngleBinAxis_wrapper(AngleBinAxis const & arg )
+    : AngleBinAxis( arg )
+      , bp::wrapper< AngleBinAxis >(){
+        // copy constructor
+        
+    }
+
+    AngleBinAxis_wrapper(::std::string name, ::std::size_t nbins, double start, double end )
+    : AngleBinAxis( name, nbins, start, end )
+      , bp::wrapper< AngleBinAxis >(){
+        // constructor
+    
+    }
+
+    virtual ::AngleBinAxis * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else
+            return this->AngleBinAxis::clone(  );
+    }
+    
+    
+    ::AngleBinAxis * default_clone(  ) const  {
+        return AngleBinAxis::clone( );
+    }
+
+    virtual ::std::size_t findClosestIndex( double value ) const  {
+        if( bp::override func_findClosestIndex = this->get_override( "findClosestIndex" ) )
+            return func_findClosestIndex( value );
+        else
+            return this->AngleBinAxis::findClosestIndex( value );
+    }
+    
+    
+    ::std::size_t default_findClosestIndex( double value ) const  {
+        return AngleBinAxis::findClosestIndex( value );
+    }
+
+    virtual ::Bin1D getBin( ::std::size_t index ) const  {
+        if( bp::override func_getBin = this->get_override( "getBin" ) )
+            return func_getBin( index );
+        else
+            return this->AngleBinAxis::getBin( index );
+    }
+    
+    
+    ::Bin1D default_getBin( ::std::size_t index ) const  {
+        return AngleBinAxis::getBin( index );
+    }
+
+    virtual double getMax(  ) const  {
+        if( bp::override func_getMax = this->get_override( "getMax" ) )
+            return func_getMax(  );
+        else
+            return this->AngleBinAxis::getMax(  );
+    }
+    
+    
+    double default_getMax(  ) const  {
+        return AngleBinAxis::getMax( );
+    }
+
+    virtual double getMin(  ) const  {
+        if( bp::override func_getMin = this->get_override( "getMin" ) )
+            return func_getMin(  );
+        else
+            return this->AngleBinAxis::getMin(  );
+    }
+    
+    
+    double default_getMin(  ) const  {
+        return AngleBinAxis::getMin( );
+    }
+
+    virtual ::std::size_t getSize(  ) const  {
+        if( bp::override func_getSize = this->get_override( "getSize" ) )
+            return func_getSize(  );
+        else
+            return this->AngleBinAxis::getSize(  );
+    }
+    
+    
+    ::std::size_t default_getSize(  ) const  {
+        return AngleBinAxis::getSize( );
+    }
+
+    virtual double operator[]( ::std::size_t index ) const  {
+        if( bp::override func___getitem__ = this->get_override( "__getitem__" ) )
+            return func___getitem__( index );
+        else
+            return this->AngleBinAxis::operator[]( index );
+    }
+    
+    
+    double default___getitem__( ::std::size_t index ) const  {
+        return AngleBinAxis::operator[]( index );
+    }
+
+    virtual ::IAxis * createDoubleBinSize(  ) const  {
+        if( bp::override func_createDoubleBinSize = this->get_override( "createDoubleBinSize" ) )
+            return func_createDoubleBinSize(  );
+        else
+            return this->IAxis::createDoubleBinSize(  );
+    }
+    
+    
+    ::IAxis * default_createDoubleBinSize(  ) const  {
+        return IAxis::createDoubleBinSize( );
+    }
+
+};
+
+void register_AngleBinAxis_class(){
+
+    { //::AngleBinAxis
+        typedef bp::class_< AngleBinAxis_wrapper, bp::bases< IAxis > > AngleBinAxis_exposer_t;
+        AngleBinAxis_exposer_t AngleBinAxis_exposer = AngleBinAxis_exposer_t( "AngleBinAxis", bp::init< std::string, std::size_t, double, double >(( bp::arg("name"), bp::arg("nbins"), bp::arg("start"), bp::arg("end") )) );
+        bp::scope AngleBinAxis_scope( AngleBinAxis_exposer );
+        { //::AngleBinAxis::clone
+        
+            typedef ::AngleBinAxis * ( ::AngleBinAxis::*clone_function_type )(  ) const;
+            typedef ::AngleBinAxis * ( AngleBinAxis_wrapper::*default_clone_function_type )(  ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "clone"
+                , clone_function_type(&::AngleBinAxis::clone)
+                , default_clone_function_type(&AngleBinAxis_wrapper::default_clone)
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+        { //::AngleBinAxis::createIsGISAXSAxis
+        
+            typedef ::AngleBinAxis * ( *createIsGISAXSAxis_function_type )( ::std::string,::std::size_t,double,double );
+            
+            AngleBinAxis_exposer.def( 
+                "createIsGISAXSAxis"
+                , createIsGISAXSAxis_function_type( &::AngleBinAxis::createIsGISAXSAxis )
+                , ( bp::arg("name"), bp::arg("nbins"), bp::arg("start"), bp::arg("end") )
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+        { //::AngleBinAxis::findClosestIndex
+        
+            typedef ::std::size_t ( ::AngleBinAxis::*findClosestIndex_function_type )( double ) const;
+            typedef ::std::size_t ( AngleBinAxis_wrapper::*default_findClosestIndex_function_type )( double ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "findClosestIndex"
+                , findClosestIndex_function_type(&::AngleBinAxis::findClosestIndex)
+                , default_findClosestIndex_function_type(&AngleBinAxis_wrapper::default_findClosestIndex)
+                , ( bp::arg("value") ) );
+        
+        }
+        { //::AngleBinAxis::getBin
+        
+            typedef ::Bin1D ( ::AngleBinAxis::*getBin_function_type )( ::std::size_t ) const;
+            typedef ::Bin1D ( AngleBinAxis_wrapper::*default_getBin_function_type )( ::std::size_t ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "getBin"
+                , getBin_function_type(&::AngleBinAxis::getBin)
+                , default_getBin_function_type(&AngleBinAxis_wrapper::default_getBin)
+                , ( bp::arg("index") ) );
+        
+        }
+        { //::AngleBinAxis::getMax
+        
+            typedef double ( ::AngleBinAxis::*getMax_function_type )(  ) const;
+            typedef double ( AngleBinAxis_wrapper::*default_getMax_function_type )(  ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "getMax"
+                , getMax_function_type(&::AngleBinAxis::getMax)
+                , default_getMax_function_type(&AngleBinAxis_wrapper::default_getMax) );
+        
+        }
+        { //::AngleBinAxis::getMin
+        
+            typedef double ( ::AngleBinAxis::*getMin_function_type )(  ) const;
+            typedef double ( AngleBinAxis_wrapper::*default_getMin_function_type )(  ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "getMin"
+                , getMin_function_type(&::AngleBinAxis::getMin)
+                , default_getMin_function_type(&AngleBinAxis_wrapper::default_getMin) );
+        
+        }
+        { //::AngleBinAxis::getSize
+        
+            typedef ::std::size_t ( ::AngleBinAxis::*getSize_function_type )(  ) const;
+            typedef ::std::size_t ( AngleBinAxis_wrapper::*default_getSize_function_type )(  ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "getSize"
+                , getSize_function_type(&::AngleBinAxis::getSize)
+                , default_getSize_function_type(&AngleBinAxis_wrapper::default_getSize) );
+        
+        }
+        { //::AngleBinAxis::operator[]
+        
+            typedef double ( ::AngleBinAxis::*__getitem___function_type )( ::std::size_t ) const;
+            typedef double ( AngleBinAxis_wrapper::*default___getitem___function_type )( ::std::size_t ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "__getitem__"
+                , __getitem___function_type(&::AngleBinAxis::operator[])
+                , default___getitem___function_type(&AngleBinAxis_wrapper::default___getitem__)
+                , ( bp::arg("index") ) );
+        
+        }
+        { //::IAxis::createDoubleBinSize
+        
+            typedef ::IAxis * ( ::IAxis::*createDoubleBinSize_function_type )(  ) const;
+            typedef ::IAxis * ( AngleBinAxis_wrapper::*default_createDoubleBinSize_function_type )(  ) const;
+            
+            AngleBinAxis_exposer.def( 
+                "createDoubleBinSize"
+                , createDoubleBinSize_function_type(&::IAxis::createDoubleBinSize)
+                , default_createDoubleBinSize_function_type(&AngleBinAxis_wrapper::default_createDoubleBinSize)
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+        AngleBinAxis_exposer.staticmethod( "createIsGISAXSAxis" );
+    }
+
+}
diff --git a/Core/PythonAPI/src/FixedBinAxis.pypp.cpp b/Core/PythonAPI/src/FixedBinAxis.pypp.cpp
new file mode 100644
index 00000000000..22c07cf4c47
--- /dev/null
+++ b/Core/PythonAPI/src/FixedBinAxis.pypp.cpp
@@ -0,0 +1,240 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence
+//! @brief Automatically generated boost::python code for PythonCoreAPI
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter)
+GCC_DIAG_OFF(missing-field-initializers)
+#include "boost/python.hpp"
+GCC_DIAG_ON(unused-parameter)
+GCC_DIAG_ON(missing-field-initializers)
+#include "PythonCoreList.h"
+#include "FixedBinAxis.pypp.h"
+
+namespace bp = boost::python;
+
+struct FixedBinAxis_wrapper : FixedBinAxis, bp::wrapper< FixedBinAxis > {
+
+    FixedBinAxis_wrapper(FixedBinAxis const & arg )
+    : FixedBinAxis( arg )
+      , bp::wrapper< FixedBinAxis >(){
+        // copy constructor
+        
+    }
+
+    FixedBinAxis_wrapper(::std::string name )
+    : FixedBinAxis( name )
+      , bp::wrapper< FixedBinAxis >(){
+        // constructor
+    
+    }
+
+    FixedBinAxis_wrapper(::std::string name, ::std::size_t nbins, double start, double end )
+    : FixedBinAxis( name, nbins, start, end )
+      , bp::wrapper< FixedBinAxis >(){
+        // constructor
+    
+    }
+
+    virtual ::FixedBinAxis * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else
+            return this->FixedBinAxis::clone(  );
+    }
+    
+    
+    ::FixedBinAxis * default_clone(  ) const  {
+        return FixedBinAxis::clone( );
+    }
+
+    virtual ::std::size_t findClosestIndex( double value ) const  {
+        if( bp::override func_findClosestIndex = this->get_override( "findClosestIndex" ) )
+            return func_findClosestIndex( value );
+        else
+            return this->FixedBinAxis::findClosestIndex( value );
+    }
+    
+    
+    ::std::size_t default_findClosestIndex( double value ) const  {
+        return FixedBinAxis::findClosestIndex( value );
+    }
+
+    virtual ::Bin1D getBin( ::std::size_t index ) const  {
+        if( bp::override func_getBin = this->get_override( "getBin" ) )
+            return func_getBin( index );
+        else
+            return this->FixedBinAxis::getBin( index );
+    }
+    
+    
+    ::Bin1D default_getBin( ::std::size_t index ) const  {
+        return FixedBinAxis::getBin( index );
+    }
+
+    virtual double getMax(  ) const  {
+        if( bp::override func_getMax = this->get_override( "getMax" ) )
+            return func_getMax(  );
+        else
+            return this->FixedBinAxis::getMax(  );
+    }
+    
+    
+    double default_getMax(  ) const  {
+        return FixedBinAxis::getMax( );
+    }
+
+    virtual double getMin(  ) const  {
+        if( bp::override func_getMin = this->get_override( "getMin" ) )
+            return func_getMin(  );
+        else
+            return this->FixedBinAxis::getMin(  );
+    }
+    
+    
+    double default_getMin(  ) const  {
+        return FixedBinAxis::getMin( );
+    }
+
+    virtual ::std::size_t getSize(  ) const  {
+        if( bp::override func_getSize = this->get_override( "getSize" ) )
+            return func_getSize(  );
+        else
+            return this->FixedBinAxis::getSize(  );
+    }
+    
+    
+    ::std::size_t default_getSize(  ) const  {
+        return FixedBinAxis::getSize( );
+    }
+
+    virtual double operator[]( ::std::size_t index ) const  {
+        if( bp::override func___getitem__ = this->get_override( "__getitem__" ) )
+            return func___getitem__( index );
+        else
+            return this->FixedBinAxis::operator[]( index );
+    }
+    
+    
+    double default___getitem__( ::std::size_t index ) const  {
+        return FixedBinAxis::operator[]( index );
+    }
+
+    virtual ::IAxis * createDoubleBinSize(  ) const  {
+        if( bp::override func_createDoubleBinSize = this->get_override( "createDoubleBinSize" ) )
+            return func_createDoubleBinSize(  );
+        else
+            return this->IAxis::createDoubleBinSize(  );
+    }
+    
+    
+    ::IAxis * default_createDoubleBinSize(  ) const  {
+        return IAxis::createDoubleBinSize( );
+    }
+
+};
+
+void register_FixedBinAxis_class(){
+
+    { //::FixedBinAxis
+        typedef bp::class_< FixedBinAxis_wrapper, bp::bases< IAxis > > FixedBinAxis_exposer_t;
+        FixedBinAxis_exposer_t FixedBinAxis_exposer = FixedBinAxis_exposer_t( "FixedBinAxis", bp::init< std::string >(( bp::arg("name") )) );
+        bp::scope FixedBinAxis_scope( FixedBinAxis_exposer );
+        FixedBinAxis_exposer.def( bp::init< std::string, std::size_t, double, double >(( bp::arg("name"), bp::arg("nbins"), bp::arg("start"), bp::arg("end") )) );
+        { //::FixedBinAxis::clone
+        
+            typedef ::FixedBinAxis * ( ::FixedBinAxis::*clone_function_type )(  ) const;
+            typedef ::FixedBinAxis * ( FixedBinAxis_wrapper::*default_clone_function_type )(  ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "clone"
+                , clone_function_type(&::FixedBinAxis::clone)
+                , default_clone_function_type(&FixedBinAxis_wrapper::default_clone)
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+        { //::FixedBinAxis::findClosestIndex
+        
+            typedef ::std::size_t ( ::FixedBinAxis::*findClosestIndex_function_type )( double ) const;
+            typedef ::std::size_t ( FixedBinAxis_wrapper::*default_findClosestIndex_function_type )( double ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "findClosestIndex"
+                , findClosestIndex_function_type(&::FixedBinAxis::findClosestIndex)
+                , default_findClosestIndex_function_type(&FixedBinAxis_wrapper::default_findClosestIndex)
+                , ( bp::arg("value") ) );
+        
+        }
+        { //::FixedBinAxis::getBin
+        
+            typedef ::Bin1D ( ::FixedBinAxis::*getBin_function_type )( ::std::size_t ) const;
+            typedef ::Bin1D ( FixedBinAxis_wrapper::*default_getBin_function_type )( ::std::size_t ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "getBin"
+                , getBin_function_type(&::FixedBinAxis::getBin)
+                , default_getBin_function_type(&FixedBinAxis_wrapper::default_getBin)
+                , ( bp::arg("index") ) );
+        
+        }
+        { //::FixedBinAxis::getMax
+        
+            typedef double ( ::FixedBinAxis::*getMax_function_type )(  ) const;
+            typedef double ( FixedBinAxis_wrapper::*default_getMax_function_type )(  ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "getMax"
+                , getMax_function_type(&::FixedBinAxis::getMax)
+                , default_getMax_function_type(&FixedBinAxis_wrapper::default_getMax) );
+        
+        }
+        { //::FixedBinAxis::getMin
+        
+            typedef double ( ::FixedBinAxis::*getMin_function_type )(  ) const;
+            typedef double ( FixedBinAxis_wrapper::*default_getMin_function_type )(  ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "getMin"
+                , getMin_function_type(&::FixedBinAxis::getMin)
+                , default_getMin_function_type(&FixedBinAxis_wrapper::default_getMin) );
+        
+        }
+        { //::FixedBinAxis::getSize
+        
+            typedef ::std::size_t ( ::FixedBinAxis::*getSize_function_type )(  ) const;
+            typedef ::std::size_t ( FixedBinAxis_wrapper::*default_getSize_function_type )(  ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "getSize"
+                , getSize_function_type(&::FixedBinAxis::getSize)
+                , default_getSize_function_type(&FixedBinAxis_wrapper::default_getSize) );
+        
+        }
+        { //::FixedBinAxis::operator[]
+        
+            typedef double ( ::FixedBinAxis::*__getitem___function_type )( ::std::size_t ) const;
+            typedef double ( FixedBinAxis_wrapper::*default___getitem___function_type )( ::std::size_t ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "__getitem__"
+                , __getitem___function_type(&::FixedBinAxis::operator[])
+                , default___getitem___function_type(&FixedBinAxis_wrapper::default___getitem__)
+                , ( bp::arg("index") ) );
+        
+        }
+        { //::IAxis::createDoubleBinSize
+        
+            typedef ::IAxis * ( ::IAxis::*createDoubleBinSize_function_type )(  ) const;
+            typedef ::IAxis * ( FixedBinAxis_wrapper::*default_createDoubleBinSize_function_type )(  ) const;
+            
+            FixedBinAxis_exposer.def( 
+                "createDoubleBinSize"
+                , createDoubleBinSize_function_type(&::IAxis::createDoubleBinSize)
+                , default_createDoubleBinSize_function_type(&FixedBinAxis_wrapper::default_createDoubleBinSize)
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+    }
+
+}
diff --git a/Core/PythonAPI/src/IAxis.pypp.cpp b/Core/PythonAPI/src/IAxis.pypp.cpp
index 32133e4e205..13cab830173 100644
--- a/Core/PythonAPI/src/IAxis.pypp.cpp
+++ b/Core/PythonAPI/src/IAxis.pypp.cpp
@@ -28,9 +28,16 @@ struct IAxis_wrapper : IAxis, bp::wrapper< IAxis > {
         return func_clone(  );
     }
 
-    virtual ::IAxis * createDoubleBinSize(  ) const {
-        bp::override func_createDoubleBinSize = this->get_override( "createDoubleBinSize" );
-        return func_createDoubleBinSize(  );
+    virtual ::IAxis * createDoubleBinSize(  ) const  {
+        if( bp::override func_createDoubleBinSize = this->get_override( "createDoubleBinSize" ) )
+            return func_createDoubleBinSize(  );
+        else
+            return this->IAxis::createDoubleBinSize(  );
+    }
+    
+    
+    ::IAxis * default_createDoubleBinSize(  ) const  {
+        return IAxis::createDoubleBinSize( );
     }
 
     virtual ::std::size_t findClosestIndex( double value ) const {
@@ -89,10 +96,12 @@ void register_IAxis_class(){
         { //::IAxis::createDoubleBinSize
         
             typedef ::IAxis * ( ::IAxis::*createDoubleBinSize_function_type )(  ) const;
+            typedef ::IAxis * ( IAxis_wrapper::*default_createDoubleBinSize_function_type )(  ) const;
             
             IAxis_exposer.def( 
                 "createDoubleBinSize"
-                , bp::pure_virtual( createDoubleBinSize_function_type(&::IAxis::createDoubleBinSize) )
+                , createDoubleBinSize_function_type(&::IAxis::createDoubleBinSize)
+                , default_createDoubleBinSize_function_type(&IAxis_wrapper::default_createDoubleBinSize)
                 , bp::return_value_policy< bp::manage_new_object >() );
         
         }
diff --git a/Core/PythonAPI/src/PythonModule.cpp b/Core/PythonAPI/src/PythonModule.cpp
index f2398a0e15b..f1ff3cd8d35 100644
--- a/Core/PythonAPI/src/PythonModule.cpp
+++ b/Core/PythonAPI/src/PythonModule.cpp
@@ -60,10 +60,12 @@ GCC_DIAG_ON(missing-field-initializers)
 #include "DistributionCosine.pypp.h"
 #include "IResolutionFunction2D.pypp.h"
 #include "IFormFactorBorn.pypp.h"
+#include "VariableBinAxis.pypp.h"
 #include "MultiLayer.pypp.h"
 #include "DistributionLorentz.pypp.h"
 #include "FTDistribution2DCauchy.pypp.h"
 #include "FTDistribution2DVoigt.pypp.h"
+#include "AngleBinAxis.pypp.h"
 #include "ICompositeSample.pypp.h"
 #include "cvector_t.pypp.h"
 #include "ParameterPool.pypp.h"
@@ -127,6 +129,7 @@ GCC_DIAG_ON(missing-field-initializers)
 #include "Simulation.pypp.h"
 #include "ISample.pypp.h"
 #include "IObserver.pypp.h"
+#include "FixedBinAxis.pypp.h"
 #include "ParticleBuilder.pypp.h"
 #include "FormFactorSphereGaussianRadius.pypp.h"
 #include "Lattice2DIFParameters.pypp.h"
@@ -147,6 +150,7 @@ BOOST_PYTHON_MODULE(libBornAgainCore){
     register_vector_IFormFactorPtr_t_class();
     register_vector_kvector_t_class();
     register_IAxis_class();
+    register_AngleBinAxis_class();
     register_AxisBin_class();
     register_AxisDouble_class();
     register_IParameterized_class();
@@ -178,6 +182,7 @@ BOOST_PYTHON_MODULE(libBornAgainCore){
     register_FTDistribution2DGate_class();
     register_FTDistribution2DGauss_class();
     register_FTDistribution2DVoigt_class();
+    register_FixedBinAxis_class();
     register_IFormFactor_class();
     register_IFormFactorBorn_class();
     register_FormFactorAnisoPyramid_class();
@@ -260,6 +265,7 @@ BOOST_PYTHON_MODULE(libBornAgainCore){
     register_StochasticDoubleGaussian_class();
     register_StochasticSampledParameter_class();
     register_ThreadInfo_class();
+    register_VariableBinAxis_class();
     register_global_variables();
     register_free_functions();
 
diff --git a/Core/PythonAPI/src/VariableBinAxis.pypp.cpp b/Core/PythonAPI/src/VariableBinAxis.pypp.cpp
new file mode 100644
index 00000000000..27b2048c660
--- /dev/null
+++ b/Core/PythonAPI/src/VariableBinAxis.pypp.cpp
@@ -0,0 +1,232 @@
+// This file has been generated by Py++.
+
+// BornAgain: simulate and fit scattering at grazing incidence
+//! @brief Automatically generated boost::python code for PythonCoreAPI
+
+#include "Macros.h"
+GCC_DIAG_OFF(unused-parameter)
+GCC_DIAG_OFF(missing-field-initializers)
+#include "boost/python.hpp"
+GCC_DIAG_ON(unused-parameter)
+GCC_DIAG_ON(missing-field-initializers)
+#include "PythonCoreList.h"
+#include "VariableBinAxis.pypp.h"
+
+namespace bp = boost::python;
+
+struct VariableBinAxis_wrapper : VariableBinAxis, bp::wrapper< VariableBinAxis > {
+
+    VariableBinAxis_wrapper(VariableBinAxis const & arg )
+    : VariableBinAxis( arg )
+      , bp::wrapper< VariableBinAxis >(){
+        // copy constructor
+        
+    }
+
+    VariableBinAxis_wrapper(::std::string name, ::std::size_t nbins, ::std::vector< double > const & bin_edges )
+    : VariableBinAxis( name, nbins, boost::ref(bin_edges) )
+      , bp::wrapper< VariableBinAxis >(){
+        // constructor
+    
+    }
+
+    virtual ::VariableBinAxis * clone(  ) const  {
+        if( bp::override func_clone = this->get_override( "clone" ) )
+            return func_clone(  );
+        else
+            return this->VariableBinAxis::clone(  );
+    }
+    
+    
+    ::VariableBinAxis * default_clone(  ) const  {
+        return VariableBinAxis::clone( );
+    }
+
+    virtual ::std::size_t findClosestIndex( double value ) const  {
+        if( bp::override func_findClosestIndex = this->get_override( "findClosestIndex" ) )
+            return func_findClosestIndex( value );
+        else
+            return this->VariableBinAxis::findClosestIndex( value );
+    }
+    
+    
+    ::std::size_t default_findClosestIndex( double value ) const  {
+        return VariableBinAxis::findClosestIndex( value );
+    }
+
+    virtual ::Bin1D getBin( ::std::size_t index ) const  {
+        if( bp::override func_getBin = this->get_override( "getBin" ) )
+            return func_getBin( index );
+        else
+            return this->VariableBinAxis::getBin( index );
+    }
+    
+    
+    ::Bin1D default_getBin( ::std::size_t index ) const  {
+        return VariableBinAxis::getBin( index );
+    }
+
+    virtual double getMax(  ) const  {
+        if( bp::override func_getMax = this->get_override( "getMax" ) )
+            return func_getMax(  );
+        else
+            return this->VariableBinAxis::getMax(  );
+    }
+    
+    
+    double default_getMax(  ) const  {
+        return VariableBinAxis::getMax( );
+    }
+
+    virtual double getMin(  ) const  {
+        if( bp::override func_getMin = this->get_override( "getMin" ) )
+            return func_getMin(  );
+        else
+            return this->VariableBinAxis::getMin(  );
+    }
+    
+    
+    double default_getMin(  ) const  {
+        return VariableBinAxis::getMin( );
+    }
+
+    virtual ::std::size_t getSize(  ) const  {
+        if( bp::override func_getSize = this->get_override( "getSize" ) )
+            return func_getSize(  );
+        else
+            return this->VariableBinAxis::getSize(  );
+    }
+    
+    
+    ::std::size_t default_getSize(  ) const  {
+        return VariableBinAxis::getSize( );
+    }
+
+    virtual double operator[]( ::std::size_t index ) const  {
+        if( bp::override func___getitem__ = this->get_override( "__getitem__" ) )
+            return func___getitem__( index );
+        else
+            return this->VariableBinAxis::operator[]( index );
+    }
+    
+    
+    double default___getitem__( ::std::size_t index ) const  {
+        return VariableBinAxis::operator[]( index );
+    }
+
+    virtual ::IAxis * createDoubleBinSize(  ) const  {
+        if( bp::override func_createDoubleBinSize = this->get_override( "createDoubleBinSize" ) )
+            return func_createDoubleBinSize(  );
+        else
+            return this->IAxis::createDoubleBinSize(  );
+    }
+    
+    
+    ::IAxis * default_createDoubleBinSize(  ) const  {
+        return IAxis::createDoubleBinSize( );
+    }
+
+};
+
+void register_VariableBinAxis_class(){
+
+    { //::VariableBinAxis
+        typedef bp::class_< VariableBinAxis_wrapper, bp::bases< IAxis > > VariableBinAxis_exposer_t;
+        VariableBinAxis_exposer_t VariableBinAxis_exposer = VariableBinAxis_exposer_t( "VariableBinAxis", bp::init< std::string, std::size_t, std::vector< double > const & >(( bp::arg("name"), bp::arg("nbins"), bp::arg("bin_edges") )) );
+        bp::scope VariableBinAxis_scope( VariableBinAxis_exposer );
+        { //::VariableBinAxis::clone
+        
+            typedef ::VariableBinAxis * ( ::VariableBinAxis::*clone_function_type )(  ) const;
+            typedef ::VariableBinAxis * ( VariableBinAxis_wrapper::*default_clone_function_type )(  ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "clone"
+                , clone_function_type(&::VariableBinAxis::clone)
+                , default_clone_function_type(&VariableBinAxis_wrapper::default_clone)
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+        { //::VariableBinAxis::findClosestIndex
+        
+            typedef ::std::size_t ( ::VariableBinAxis::*findClosestIndex_function_type )( double ) const;
+            typedef ::std::size_t ( VariableBinAxis_wrapper::*default_findClosestIndex_function_type )( double ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "findClosestIndex"
+                , findClosestIndex_function_type(&::VariableBinAxis::findClosestIndex)
+                , default_findClosestIndex_function_type(&VariableBinAxis_wrapper::default_findClosestIndex)
+                , ( bp::arg("value") ) );
+        
+        }
+        { //::VariableBinAxis::getBin
+        
+            typedef ::Bin1D ( ::VariableBinAxis::*getBin_function_type )( ::std::size_t ) const;
+            typedef ::Bin1D ( VariableBinAxis_wrapper::*default_getBin_function_type )( ::std::size_t ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "getBin"
+                , getBin_function_type(&::VariableBinAxis::getBin)
+                , default_getBin_function_type(&VariableBinAxis_wrapper::default_getBin)
+                , ( bp::arg("index") ) );
+        
+        }
+        { //::VariableBinAxis::getMax
+        
+            typedef double ( ::VariableBinAxis::*getMax_function_type )(  ) const;
+            typedef double ( VariableBinAxis_wrapper::*default_getMax_function_type )(  ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "getMax"
+                , getMax_function_type(&::VariableBinAxis::getMax)
+                , default_getMax_function_type(&VariableBinAxis_wrapper::default_getMax) );
+        
+        }
+        { //::VariableBinAxis::getMin
+        
+            typedef double ( ::VariableBinAxis::*getMin_function_type )(  ) const;
+            typedef double ( VariableBinAxis_wrapper::*default_getMin_function_type )(  ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "getMin"
+                , getMin_function_type(&::VariableBinAxis::getMin)
+                , default_getMin_function_type(&VariableBinAxis_wrapper::default_getMin) );
+        
+        }
+        { //::VariableBinAxis::getSize
+        
+            typedef ::std::size_t ( ::VariableBinAxis::*getSize_function_type )(  ) const;
+            typedef ::std::size_t ( VariableBinAxis_wrapper::*default_getSize_function_type )(  ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "getSize"
+                , getSize_function_type(&::VariableBinAxis::getSize)
+                , default_getSize_function_type(&VariableBinAxis_wrapper::default_getSize) );
+        
+        }
+        { //::VariableBinAxis::operator[]
+        
+            typedef double ( ::VariableBinAxis::*__getitem___function_type )( ::std::size_t ) const;
+            typedef double ( VariableBinAxis_wrapper::*default___getitem___function_type )( ::std::size_t ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "__getitem__"
+                , __getitem___function_type(&::VariableBinAxis::operator[])
+                , default___getitem___function_type(&VariableBinAxis_wrapper::default___getitem__)
+                , ( bp::arg("index") ) );
+        
+        }
+        { //::IAxis::createDoubleBinSize
+        
+            typedef ::IAxis * ( ::IAxis::*createDoubleBinSize_function_type )(  ) const;
+            typedef ::IAxis * ( VariableBinAxis_wrapper::*default_createDoubleBinSize_function_type )(  ) const;
+            
+            VariableBinAxis_exposer.def( 
+                "createDoubleBinSize"
+                , createDoubleBinSize_function_type(&::IAxis::createDoubleBinSize)
+                , default_createDoubleBinSize_function_type(&VariableBinAxis_wrapper::default_createDoubleBinSize)
+                , bp::return_value_policy< bp::manage_new_object >() );
+        
+        }
+    }
+
+}
diff --git a/Core/Tools/inc/OutputDataIOFactory.h b/Core/Tools/inc/OutputDataIOFactory.h
index bd4516e110a..dcccfaada91 100644
--- a/Core/Tools/inc/OutputDataIOFactory.h
+++ b/Core/Tools/inc/OutputDataIOFactory.h
@@ -19,9 +19,11 @@
 #include "WinDllMacros.h"
 #include "OutputDataReader.h"
 #include "OutputDataWriter.h"
+
 #include <string>
 #include <boost/shared_ptr.hpp>
 
+template <class T> class OutputData;
 
 //! @class OutputDataIOFactory
 //! @ingroup tools
@@ -33,8 +35,6 @@ public:
     typedef boost::shared_ptr<OutputDataReader > OutputDataReader_t;
     typedef boost::shared_ptr<OutputDataWriter > OutputDataWriter_t;
 
-    OutputDataIOFactory(){}
-
     static OutputData<double > *readIntensityData(const std::string& file_name);
     static OutputDataReader_t getReader(const std::string& file_name);
 
diff --git a/Core/Tools/inc/OutputDataIOHelper.h b/Core/Tools/inc/OutputDataIOHelper.h
new file mode 100644
index 00000000000..d9db4de5de1
--- /dev/null
+++ b/Core/Tools/inc/OutputDataIOHelper.h
@@ -0,0 +1,38 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Tools/inc/OutputDataIOFactory.h
+//! @brief     Defines class OutputDataIOFactory.
+//!
+//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2013
+//! @authors   Scientific Computing Group at MLZ Garching
+//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef OUTPUTDATAIOHELPER_H
+#define OUTPUTDATAIOHELPER_H
+
+#include<string>
+#include <iostream>
+
+class IAxis;
+class FixedBinAxis;
+template <class T> class OutputData;
+
+namespace OutputDataIOHelper {
+
+const std::string FixedBinAxisType = "FixedBinAxis";
+
+IAxis *createAxis(std::istream &input_stream);
+FixedBinAxis *createFixedBinAxis(std::string line);
+
+void fillOutputData(OutputData<double> *data, std::istream &input_stream);
+
+}
+
+
+#endif
diff --git a/Core/Tools/inc/OutputDataReadStrategy.h b/Core/Tools/inc/OutputDataReadStrategy.h
index 83e98b896e4..7847154e1cf 100644
--- a/Core/Tools/inc/OutputDataReadStrategy.h
+++ b/Core/Tools/inc/OutputDataReadStrategy.h
@@ -16,9 +16,10 @@
 #ifndef OUTPUTDATAREADSTRATEGY_H
 #define OUTPUTDATAREADSTRATEGY_H
 
-#include "OutputData.h"
-#include "Types.h"
 #include <string>
+#include "WinDllMacros.h"
+template <class T> class OutputData;
+
 
 //! @class IOutputDataReadStrategy
 //! @ingroup tools_internal
@@ -88,6 +89,15 @@ public:
     OutputData<double > *readOutputData(std::istream& file_stream);
 };
 
+//! Strategy to read BornAgain native IntensityData from ASCII file
+
+class OutputDataReadStreamBA : public IOutputDataReadStrategy
+{
+public:
+    OutputData<double > *readOutputData(std::istream& file_stream);
+};
+
+
 #endif // OUTPUTDATAREADSTRATEGY_H
 
 
diff --git a/Core/Tools/inc/OutputDataReader.h b/Core/Tools/inc/OutputDataReader.h
index 94f144d2a44..9341229bd6a 100644
--- a/Core/Tools/inc/OutputDataReader.h
+++ b/Core/Tools/inc/OutputDataReader.h
@@ -16,8 +16,12 @@
 #ifndef OUTPUTDATAREADER_H
 #define OUTPUTDATAREADER_H
 
-#include "OutputDataReadStrategy.h"
 #include <string>
+#include "WinDllMacros.h"
+
+template <class T> class OutputData;
+class IOutputDataReadStrategy;
+
 
 //! @class OutputDataReader
 //! @ingroup tools
@@ -27,21 +31,17 @@ class BA_CORE_API_ OutputDataReader
 {
 public:
     OutputDataReader() : m_read_strategy(0) {}
-    OutputDataReader(const std::string& file_name) : m_file_name(file_name), m_read_strategy(0) {}
-    OutputDataReader(IOutputDataReadStrategy *read_strategy) : m_read_strategy(read_strategy) {}
-    virtual ~OutputDataReader() { delete m_read_strategy; }
+    OutputDataReader(const std::string& file_name);
+    OutputDataReader(IOutputDataReadStrategy *read_strategy);
+    virtual ~OutputDataReader();
 
     //! read output data from file (file name was set already from OutputDataIOFactory)
-//    OutputData<double > *getOutputData() { return getOutputData(m_file_name); }
     OutputData<double > *getOutputData();
 
     //! Sets concrete reading strategy
-    void setStrategy(IOutputDataReadStrategy *read_strategy) { delete m_read_strategy; m_read_strategy = read_strategy; }
+    void setStrategy(IOutputDataReadStrategy *read_strategy);
 
 private:
-//    //! read output data from file
-//    OutputData<double > *getOutputData(const std::string& file_name);
-
     std::string m_file_name;
     IOutputDataReadStrategy *m_read_strategy;
 };
diff --git a/Core/Tools/inc/OutputDataWriteStrategy.h b/Core/Tools/inc/OutputDataWriteStrategy.h
index dc5d6ac72af..3490ed0f136 100644
--- a/Core/Tools/inc/OutputDataWriteStrategy.h
+++ b/Core/Tools/inc/OutputDataWriteStrategy.h
@@ -16,10 +16,11 @@
 #ifndef OUTPUTDATAWRITESTRATEGY_H
 #define OUTPUTDATAWRITESTRATEGY_H
 
-#include "OutputData.h"
-#include "Types.h"
+#include "WinDllMacros.h"
 #include <string>
 
+template <class T> class OutputData;
+
 
 //! @class IOutputDataWriteStrategy
 //! @ingroup tools_internal
@@ -59,6 +60,16 @@ public:
     virtual void writeOutputData(const OutputData<double> &data, std::ostream &output_stream);
 };
 
+//! @class OutputDataWriteStreamBA
+//! @ingroup tools_internal
+//! @brief Strategy to write OutputData to special BornAgain ASCII format
+
+class OutputDataWriteStreamBA : public IOutputDataWriteStrategy
+{
+public:
+    virtual void writeOutputData(const OutputData<double> &data, std::ostream &output_stream);
+};
+
 
 #endif // OUTPUTDATAWRITESTRATEGY_H
 
diff --git a/Core/Tools/inc/OutputDataWriter.h b/Core/Tools/inc/OutputDataWriter.h
index 58bcc7a9a57..724b3d58d30 100644
--- a/Core/Tools/inc/OutputDataWriter.h
+++ b/Core/Tools/inc/OutputDataWriter.h
@@ -16,29 +16,29 @@
 #ifndef OUTPUTDATAWRITER_H
 #define OUTPUTDATAWRITER_H
 
-#include "OutputDataWriteStrategy.h"
+#include "WinDllMacros.h"
 #include <string>
 
+template <class T> class OutputData;
+
+class IOutputDataWriteStrategy;
+
 //! @class OutputDataWriter
 //! @ingroup tools
 //! @brief Write OutputData to file using different witing strategies
-
 class BA_CORE_API_ OutputDataWriter
 {
 public:
-    OutputDataWriter() : m_write_strategy(0) {}
-    OutputDataWriter(const std::string& file_name)
-    : m_file_name(file_name), m_write_strategy(0) {}
-    OutputDataWriter(IOutputDataWriteStrategy *write_strategy)
-    : m_write_strategy(write_strategy) {}
-    virtual ~OutputDataWriter() { delete m_write_strategy; }
+    OutputDataWriter();
+    OutputDataWriter(const std::string& file_name);
+    OutputDataWriter(IOutputDataWriteStrategy *write_strategy);
+    virtual ~OutputDataWriter();
 
     //! write output data to file
     void writeOutputData(const OutputData<double >& data);
 
     //! Sets concrete writing strategy
-    void setStrategy(IOutputDataWriteStrategy *write_strategy)
-    { delete m_write_strategy; m_write_strategy = write_strategy; }
+    void setStrategy(IOutputDataWriteStrategy *write_strategy);
 
 private:
     std::string m_file_name;
diff --git a/Core/Tools/inc/Utils.h b/Core/Tools/inc/Utils.h
index 1ed732f44a3..adce7fbfc0b 100644
--- a/Core/Tools/inc/Utils.h
+++ b/Core/Tools/inc/Utils.h
@@ -45,6 +45,9 @@ public:
     //! Split string into vector of string using delimeter.
     static std::vector<std::string> Split(const std::string& text,
                                           const std::string& delimeter);
+
+    //! Every character in 'text' which is contained in 'chars' will be replaced with space
+    static std::string ReplaceCharsWithSpaces(const std::string &text, const std::string &chars);
 };
 
 
diff --git a/Core/Tools/src/FixedBinAxis.cpp b/Core/Tools/src/FixedBinAxis.cpp
index b302fe55cc1..9a289b6cdf8 100644
--- a/Core/Tools/src/FixedBinAxis.cpp
+++ b/Core/Tools/src/FixedBinAxis.cpp
@@ -1,5 +1,6 @@
 #include "FixedBinAxis.h"
 #include "Exceptions.h"
+#include <iomanip>
 
 FixedBinAxis::FixedBinAxis(std::string name)
     : IAxis(name)
@@ -82,7 +83,7 @@ size_t FixedBinAxis::findClosestIndex(double value) const
 
 void FixedBinAxis::print(std::ostream& ostr) const
 {
-    ostr << "FixedBinAxis '" << m_name << "'" << getSize() << " " << getMin() << " " << getMax();
+    ostr << "FixedBinAxis(\"" << m_name << "\", " << getSize() << ", " << std::setprecision(10) << getMin() << ", " << getMax() << ")";
 }
 
 
diff --git a/Core/Tools/src/OutputDataIOFactory.cpp b/Core/Tools/src/OutputDataIOFactory.cpp
index 1456cc7b359..0480b994590 100644
--- a/Core/Tools/src/OutputDataIOFactory.cpp
+++ b/Core/Tools/src/OutputDataIOFactory.cpp
@@ -14,6 +14,10 @@
 // ************************************************************************** //
 
 #include "OutputDataIOFactory.h"
+#include "OutputDataReadStrategy.h"
+#include "OutputDataWriteStrategy.h"
+#include "OutputDataReader.h"
+#include "OutputDataWriter.h"
 #include "Exceptions.h"
 #include "Utils.h"
 #include "FileSystem.h"
@@ -38,6 +42,8 @@ OutputDataIOFactory::OutputDataReader_t OutputDataIOFactory::getReader(
         read_strategy = new OutputDataReadStreamV1();
     } else if ( Utils::FileSystem::GetFileMainExtension(file_name) == ".ima") {
         read_strategy = new OutputDataReadStreamIMA();
+    } else if ( Utils::FileSystem::GetFileMainExtension(file_name) == ".baint") {
+        read_strategy = new OutputDataReadStreamBA();
     } else {
         throw LogicErrorException("OutputDataIOFactory::getReader() -> Error. "
                 "Don't know how to read file '" + file_name+std::string("'"));
@@ -71,6 +77,8 @@ OutputDataIOFactory::OutputDataWriter_t OutputDataIOFactory::getWriter(
         write_strategy = new OutputDataWriteStreamIMA();
     }else if(Utils::FileSystem::GetFileExtension(file_name) == ".txt") {
         write_strategy = new OutputDataWriteStreamV1();
+    }else if(Utils::FileSystem::GetFileExtension(file_name) == ".baint") {
+        write_strategy = new OutputDataWriteStreamBA();
     } else {
         throw LogicErrorException("OutputDataIOFactory::getWriter() -> Error. "
                 "Don't know how to write file '" + file_name+std::string("'"));
diff --git a/Core/Tools/src/OutputDataIOHelper.cpp b/Core/Tools/src/OutputDataIOHelper.cpp
new file mode 100644
index 00000000000..b0bea04bd7c
--- /dev/null
+++ b/Core/Tools/src/OutputDataIOHelper.cpp
@@ -0,0 +1,68 @@
+#include "OutputDataIOHelper.h"
+#include "FixedBinAxis.h"
+#include "Exceptions.h"
+#include "Utils.h"
+#include "OutputData.h"
+#include <iostream>
+#include <algorithm>
+#include <boost/algorithm/string.hpp>
+
+IAxis *OutputDataIOHelper::createAxis(std::istream &input_stream)
+{
+    std::string line;
+    std::getline(input_stream, line);
+
+    if(line.find(FixedBinAxisType) != std::string::npos)
+    {
+        return createFixedBinAxis(line);
+    }
+    else {
+        throw Exceptions::LogicErrorException("OutputDataIOHelper::createAxis() -> Error. Unknown axis '"+line+"'");
+    }
+}
+
+
+// FixedBinAxis("axis0", 10, -1, 1)
+FixedBinAxis *OutputDataIOHelper::createFixedBinAxis(std::string line)
+{
+    boost::replace_all(line, FixedBinAxisType, "");
+    boost::replace_all(line, ",", " ");
+    boost::replace_all(line, "\"", " ");
+    boost::replace_all(line, "(", " ");
+    boost::replace_all(line, ")", " ");
+
+    std::string name;
+    int nbins(0);
+    double start(0), end(0);
+
+    std::istringstream iss(line);
+    if( !(iss >> name >> nbins >> start >> end) )
+        throw Exceptions::FormatErrorException("OutputDataIOHelper::createFixedBinAxis() -> Error. Can't parse the string.");
+
+    std::cout << line << " " << name << " " << nbins << " " << start << " " << end << std::endl;
+    FixedBinAxis *result = new FixedBinAxis(name, nbins, start, end);
+    return result;
+}
+
+
+
+
+void OutputDataIOHelper::fillOutputData(OutputData<double> *data, std::istream &input_stream)
+{
+    std::string line;
+
+    data->setAllTo(0.0);
+    OutputData<double>::iterator it = data->begin();
+
+    while( std::getline(input_stream, line) )
+    {
+        if(line.empty() || line[0] == '#') break;
+
+        std::istringstream iss(line);
+        std::string svalue;
+        while(iss >> svalue) {
+            *it = std::strtod(svalue.c_str(), NULL);
+            ++it;
+        }
+    }
+}
diff --git a/Core/Tools/src/OutputDataReadStrategy.cpp b/Core/Tools/src/OutputDataReadStrategy.cpp
index 6b12e326070..448d15f9a16 100644
--- a/Core/Tools/src/OutputDataReadStrategy.cpp
+++ b/Core/Tools/src/OutputDataReadStrategy.cpp
@@ -18,6 +18,8 @@
 #include "Exceptions.h"
 #include "Utils.h"
 #include "BornAgainNamespace.h"
+#include "OutputData.h"
+#include "OutputDataIOHelper.h"
 
 #include <iostream>
 #include <fstream>
@@ -171,3 +173,26 @@ OutputData<double > *OutputDataReadStreamV1::readOutputData(std::istream &input_
 }
 
 
+OutputData<double > *OutputDataReadStreamBA::readOutputData(std::istream &input_stream)
+{
+    OutputData<double > *result = new OutputData<double>;
+
+    std::string line;
+
+    while( std::getline(input_stream, line) )
+    {
+        if(line.empty()) continue;
+
+        if (line.find("axis") != std::string::npos) {
+            IAxis *axis = OutputDataIOHelper::createAxis(input_stream);
+            result->addAxis(*axis);
+        }
+
+        if (line.find("data") != std::string::npos) {
+            OutputDataIOHelper::fillOutputData(result, input_stream);
+        }
+    }
+
+    return result;
+}
+
diff --git a/Core/Tools/src/OutputDataReader.cpp b/Core/Tools/src/OutputDataReader.cpp
index 1a185680ce0..afd67b80d5e 100644
--- a/Core/Tools/src/OutputDataReader.cpp
+++ b/Core/Tools/src/OutputDataReader.cpp
@@ -12,12 +12,34 @@
 //! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
 //
 // ************************************************************************** //
-
+#include "OutputData.h"
 #include "OutputDataReader.h"
+#include "OutputDataReadStrategy.h"
 #include <fstream>
 #include <cassert>
 #include <iostream>
 
+OutputDataReader::OutputDataReader(const std::string &file_name)
+    : m_file_name(file_name)
+    , m_read_strategy(0)
+{
+
+}
+
+
+OutputDataReader::OutputDataReader(IOutputDataReadStrategy *read_strategy)
+    : m_read_strategy(read_strategy)
+{
+
+}
+
+
+OutputDataReader::~OutputDataReader()
+{
+    delete m_read_strategy;
+}
+
+
 OutputData<double > *OutputDataReader::getOutputData()
 {
     if(!m_read_strategy) {
@@ -45,3 +67,10 @@ OutputData<double > *OutputDataReader::getOutputData()
 }
 
 
+void OutputDataReader::setStrategy(IOutputDataReadStrategy *read_strategy)
+{
+    delete m_read_strategy;
+    m_read_strategy = read_strategy;
+}
+
+
diff --git a/Core/Tools/src/OutputDataWriteStrategy.cpp b/Core/Tools/src/OutputDataWriteStrategy.cpp
index 7a0f1adf1fc..dfc053ee710 100644
--- a/Core/Tools/src/OutputDataWriteStrategy.cpp
+++ b/Core/Tools/src/OutputDataWriteStrategy.cpp
@@ -14,6 +14,7 @@
 // ************************************************************************** //
 
 #include "OutputDataWriteStrategy.h"
+#include "OutputData.h"
 #include <iostream>
 #include <fstream>
 #include <sstream>
@@ -71,4 +72,33 @@ void OutputDataWriteStreamV1::writeOutputData(const OutputData<double> &data, st
 }
 
 
+void OutputDataWriteStreamBA::writeOutputData(const OutputData<double> &data, std::ostream &output_stream)
+{
+    output_stream << "# BornAgain Intensity Data" << std::endl;
+
+    for(size_t i=0; i<data.getRank(); ++i) {
+        const IAxis *axis = data.getAxis(i);
+        output_stream << std::endl;
+        output_stream << "# axis-" << i << std::endl;
+        output_stream << (*axis) << std::endl;
+    }
+
+    output_stream << std::endl;
+    output_stream << "# data" << std::endl;
+    OutputData<double>::const_iterator it = data.begin();
+    int ncol(0);
+    const int ncol_max(10);
+    while(it != data.end()) {
+        ncol++;
+        double z_value = *it++;
+        output_stream << std::scientific << std::setprecision(m_precision) << z_value << "    ";
+        if(ncol == ncol_max) {
+            output_stream << std::endl;
+            ncol = 0;
+        }
+    }
+    output_stream << std::endl;
+
+}
+
 
diff --git a/Core/Tools/src/OutputDataWriter.cpp b/Core/Tools/src/OutputDataWriter.cpp
index 0e4bb0cc852..2a362c3e71a 100644
--- a/Core/Tools/src/OutputDataWriter.cpp
+++ b/Core/Tools/src/OutputDataWriter.cpp
@@ -14,9 +14,40 @@
 // ************************************************************************** //
 
 #include "OutputDataWriter.h"
+#include "OutputDataWriteStrategy.h"
+#include "OutputData.h"
 #include <fstream>
 #include <cassert>
 
+
+OutputDataWriter::OutputDataWriter()
+    : m_write_strategy(0)
+{
+
+}
+
+
+OutputDataWriter::OutputDataWriter(const std::string &file_name)
+    : m_file_name(file_name),
+      m_write_strategy(0)
+{
+
+}
+
+
+OutputDataWriter::OutputDataWriter(IOutputDataWriteStrategy *write_strategy)
+    : m_write_strategy(write_strategy)
+{
+
+}
+
+
+OutputDataWriter::~OutputDataWriter()
+{
+    delete m_write_strategy;
+}
+
+
 void OutputDataWriter::writeOutputData(const OutputData<double >& data)
 {
     // opening file
@@ -36,3 +67,11 @@ void OutputDataWriter::writeOutputData(const OutputData<double >& data)
 }
 
 
+void OutputDataWriter::setStrategy(IOutputDataWriteStrategy *write_strategy)
+{
+    delete m_write_strategy;
+    m_write_strategy = write_strategy;
+}
+
+
+
diff --git a/Core/Tools/src/Utils.cpp b/Core/Tools/src/Utils.cpp
index 1946b17b10d..1708916fff3 100644
--- a/Core/Tools/src/Utils.cpp
+++ b/Core/Tools/src/Utils.cpp
@@ -113,6 +113,15 @@ std::vector<std::string> Utils::String::Split(
     return tokens;
 }
 
+std::string Utils::String::ReplaceCharsWithSpaces(const std::string &text, const std::string &chars)
+{
+    std::string line = text;
+    for(size_t i=0; i<chars.size(); ++i) {
+        std::replace(line.begin(), line.end(), chars[i], ' ');
+    }
+    return line;
+}
+
 
 
 
diff --git a/Tests/UnitTests/TestCore/FixedBinAxisTest.h b/Tests/UnitTests/TestCore/FixedBinAxisTest.h
index 67cc9cbcc72..d18f8c3145f 100644
--- a/Tests/UnitTests/TestCore/FixedBinAxisTest.h
+++ b/Tests/UnitTests/TestCore/FixedBinAxisTest.h
@@ -2,7 +2,9 @@
 #define FIXEDBINAXISTEST_H
 
 #include "FixedBinAxis.h"
+#include "OutputDataIOHelper.h"
 #include "gtest/gtest.h"
+#include <iostream>
 
 class FixedBinAxisTest: public ::testing::Test
 {
@@ -128,6 +130,17 @@ TEST_F(FixedBinAxisTest, CheckClone)
     delete clone;
 }
 
+TEST_F(FixedBinAxisTest, IOStream)
+{
+    FixedBinAxis axis("name", 99, -1.2, 5.4);
+
+    std::ostringstream oss;
+    oss << axis;
+
+    FixedBinAxis *result = OutputDataIOHelper::createFixedBinAxis(oss.str());
+    EXPECT_TRUE(axis == *result);
+    delete result;
+}
 
 
 #endif
diff --git a/dev-tools/python-bindings/settings_core.py b/dev-tools/python-bindings/settings_core.py
index 48624e20e97..13348cb51c0 100644
--- a/dev-tools/python-bindings/settings_core.py
+++ b/dev-tools/python-bindings/settings_core.py
@@ -39,6 +39,9 @@ include_dirs = [
 include_classes = [
     "AxisDouble",
     "AxisBin",
+    "FixedBinAxis",
+    "VariableBinAxis",
+    "AngleBinAxis",
     "BasicVector3D<double>",
     "BasicVector3D<std::complex<double> >",
     "Beam",
-- 
GitLab