From 7aecca8ec07279d9c257a2cf8f31c7f89ab6aa53 Mon Sep 17 00:00:00 2001 From: pospelov <pospelov@fz-juelich.de> Date: Wed, 20 Jun 2012 12:18:45 +0200 Subject: [PATCH] new ParameterPool --- App/src/TestDiffuseReflection.cpp | 2 + App/src/TestFresnelCoeff.cpp | 57 +--------- Core/Core.pro | 8 +- Core/inc/Convolve.h | 9 +- Core/inc/ICompositeIterator.h | 3 +- Core/inc/ICompositeSample.h | 14 ++- Core/inc/IFactory.h | 4 +- Core/inc/ISample.h | 32 +++++- Core/inc/Layer.h | 3 + Core/inc/LayerRoughness.h | 3 + Core/inc/MultiLayer.h | 10 +- Core/inc/ParameterPool.h | 80 +++++++++++++ Core/inc/Utils.h | 179 ++++++++++++++++++++++++++++++ Core/src/ICompositeSample.cpp | 9 +- Core/src/ISample.cpp | 147 +++++++++++++++++++++++- Core/src/Layer.cpp | 14 +++ Core/src/LayerRoughness.cpp | 15 ++- Core/src/MultiLayer.cpp | 20 +++- Core/src/ParameterPool.cpp | 148 ++++++++++++++++++++++++ Core/src/Utils.cpp | 1 + GISASFW.pro | 2 +- 21 files changed, 679 insertions(+), 81 deletions(-) create mode 100644 Core/inc/ParameterPool.h create mode 100644 Core/inc/Utils.h create mode 100644 Core/src/ParameterPool.cpp create mode 100644 Core/src/Utils.cpp diff --git a/App/src/TestDiffuseReflection.cpp b/App/src/TestDiffuseReflection.cpp index 0a3f9a4c14e..b63e7dfba07 100644 --- a/App/src/TestDiffuseReflection.cpp +++ b/App/src/TestDiffuseReflection.cpp @@ -23,6 +23,8 @@ TestDiffuseReflection::TestDiffuseReflection() : { std::cout << "TestDiffuseScattering::TestDiffuseReflection() -> Info." << std::endl; + // Performance log + // 18.06.2012 diffuse : Cpu Time = 7.67 seconds (MultilayerOffspecTestcase1a,MultilayerOffspecTestcase1b, MultilayerOffspecTestcase2a, MultilayerOffspecTestcase2b) } diff --git a/App/src/TestFresnelCoeff.cpp b/App/src/TestFresnelCoeff.cpp index 053df4f317b..8e53314a73c 100644 --- a/App/src/TestFresnelCoeff.cpp +++ b/App/src/TestFresnelCoeff.cpp @@ -37,7 +37,7 @@ void TestFresnelCoeff::execute() std::cout << "TestFresnelCoeff::execute() -> Info." << std::endl; // calculate fresnel coefficients for several standard multi-layer samples - test_standard(); + //test_standard(); // calculate fresnel coefficients for multi-layer with different roughnesses test_roughness(); @@ -235,62 +235,11 @@ void TestFresnelCoeff::draw_standard() /* ************************************************************************* */ void TestFresnelCoeff::test_roughness() { - std::cout << "TestFresnelCoeff::test_roughness() " << std::endl; m_sample = dynamic_cast<MultiLayer *>(SampleFactory::instance().createItem("SimpleMultilayer")); -// MaterialManager &matManager = MaterialManager::instance(); -// const IMaterial *mAmbience = matManager.addHomogeneousMaterial("ambience",complex_t(1.0, 0.0) ); -// const IMaterial *mSubstrate = matManager.addHomogeneousMaterial("substrate", complex_t(1.0-15e-6, 0) ); - -// m_sample = new MultiLayer; - -// Layer lAmbience; -// lAmbience.setMaterial(mAmbience, 0); -// m_sample->addLayer(lAmbience); - -// Layer lAir; -// lAir.setMaterial(mAmbience, 10*Units::nanometer); -// m_sample->addLayer(lAir); - -// Layer lSubstrate; -// lSubstrate.setMaterial(mSubstrate,0); -// m_sample->addLayer(lSubstrate); - - m_sample->print(); - - ICompositeIterator it=m_sample->createIterator(); - //it.print(); - it.first(); - std::cout << " XXX" << std::endl; - while(!it.is_done()) - { - std::cout << it.get_current() << " " << it.get_current()->getName() << " " << it.get_current()->getId() << std::endl; - it.next(); - } - - -// double a_roughness[]={0.0,1.0,10.0,100.0}; - -// // loop over standard samples defined in SampleFactory and StandardSamples -// for(size_t i_rough=0; i_rough<sizeof(a_roughness)/sizeof(double); i_rough++){ - -// for(int i_interface=0; i_interface<m_sample) - -// m_coeffs = new OutputData<OpticalFresnel::MultiLayerCoeff_t >; -// m_coeffs->addAxis(std::string("alpha_i"), 0.0*Units::degree, 2.0*Units::degree, 2000); -// m_coeffs->resetIndex(); -// while (m_coeffs->hasNext()) { -// double alpha_i = m_coeffs->getCurrentValueOfAxis<double>("alpha_i"); -// kvector_t kvec = kvector_t::LambdaAlphaPhi(1.54*Units::angstrom, -alpha_i, 0.0); - -// OpticalFresnel::MultiLayerCoeff_t coeffs; -// OpticalFresnel::execute(*m_sample, kvec, coeffs); - -// m_coeffs->next() = coeffs; - -// } // alpha_i - + ParameterPool *newpool = m_sample->createParameterTree(); + std::cout << *newpool << std::endl; } diff --git a/Core/Core.pro b/Core/Core.pro index e5faad3e42e..ab098b7d22f 100644 --- a/Core/Core.pro +++ b/Core/Core.pro @@ -40,7 +40,9 @@ SOURCES += \ src/Convolve.cpp \ src/INamed.cpp \ src/ICompositeSample.cpp \ - src/ICompositeIterator.cpp + src/ICompositeIterator.cpp \ + src/ParameterPool.cpp \ + src/Utils.cpp HEADERS += \ inc/ISample.h \ @@ -80,7 +82,9 @@ HEADERS += \ inc/Convolve.h \ inc/INamed.h \ inc/ICompositeSample.h \ - inc/ICompositeIterator.h + inc/ICompositeIterator.h \ + inc/ParameterPool.h \ + inc/Utils.h INCLUDEPATH += ./inc DEPENDPATH += ./inc diff --git a/Core/inc/Convolve.h b/Core/inc/Convolve.h index 9405f3ef2b4..35c0ab80c73 100644 --- a/Core/inc/Convolve.h +++ b/Core/inc/Convolve.h @@ -26,7 +26,8 @@ namespace MathFunctions //- ------------------------------------------------------------------- //! @class Convolve -//! @brief Convolution of two real vectors (1D or 2D ) using Fast Fourier Transformation. +//! @brief Convolution of two real vectors (in 1D or 2D ) using Fast Fourier +//! Transformation. //! //! Usage: //! std::vector<double> signal, kernel, result; @@ -42,15 +43,15 @@ namespace MathFunctions class Convolve { public: - Convolve(); - ~Convolve(); - //! definition of 1d vector of double typedef std::vector<double > double1d_t; //! definition of 2d vector of double typedef std::vector<double1d_t > double2d_t; + Convolve(); + ~Convolve(); + //! convolution modes //! use LINEAR_SAME or CIRCULAR_SAME_SHIFTED for maximum performance enum Mode { FFTW_LINEAR_FULL, FFTW_LINEAR_SAME_UNPADDED, FFTW_LINEAR_SAME, FFTW_LINEAR_VALID, FFTW_CIRCULAR_SAME, FFTW_CIRCULAR_SAME_SHIFTED, FFTW_UNDEFINED }; diff --git a/Core/inc/ICompositeIterator.h b/Core/inc/ICompositeIterator.h index 0af2ab51de1..71089736daf 100644 --- a/Core/inc/ICompositeIterator.h +++ b/Core/inc/ICompositeIterator.h @@ -95,6 +95,7 @@ public: } void next() { m_state_stack.top().next(); } + size_t size() { return m_state_stack.size(); } protected: std::stack<MementoState > m_state_stack; }; @@ -117,7 +118,7 @@ public: return *(m_memento_itor.get_current_itor()); } bool is_done() { return m_done; } - + size_t get_level() { return m_memento_itor.size(); } protected: MementoIterator m_memento_itor; ICompositeSample* m_root; diff --git a/Core/inc/ICompositeSample.h b/Core/inc/ICompositeSample.h index def514d106e..b7cfd8efc81 100644 --- a/Core/inc/ICompositeSample.h +++ b/Core/inc/ICompositeSample.h @@ -28,24 +28,32 @@ class ICompositeIterator; class ICompositeSample : public ISample { public: + //! definition of container for registered children typedef std::list<ISample *> samples_t; typedef samples_t::iterator iterator_t; ICompositeSample(); - + //! to confirm compound nature of given class virtual ICompositeSample *getCompositeSample() { return this; } + //! register/derigister child in the container virtual void registerChild(ISample *sample) { m_samples.push_back(sample); } virtual void deregisterChild(ISample *sample) { m_samples.remove(sample); } - //virtual ISample* getChild(size_t index) { return m_samples[ check_index(index) ]; } - + //! iteration over local registered children iterator_t begin_shallow() { return m_samples.begin(); } iterator_t end_shallow() { return m_samples.end(); } + //! size of children + virtual size_t size() const { return m_samples.size(); } + + //! create general iterator to walk through the tree of registered composite children ICompositeIterator createIterator(); + // return pointer to the new parameter pool which contains all local parameter plus all parameters + // from CompositeSample tree user has to take to delete it + // virtual ParameterPool *cloneParameterTree(); protected: ICompositeSample(const ICompositeSample &other); diff --git a/Core/inc/IFactory.h b/Core/inc/IFactory.h index 282bbad96e1..3e36861aa14 100644 --- a/Core/inc/IFactory.h +++ b/Core/inc/IFactory.h @@ -29,14 +29,14 @@ template<class IdentifierType, class AbstractProduct > class IFactory { public: - IFactory() : m_own_objects(false) { } - //! pointer to function which will be used to create object of AbstractProduct base type typedef AbstractProduct* (*CreateItemCallback) (); //! typedef for map which stores correspondance between object identifier and object creation function typedef std::map<IdentifierType, CreateItemCallback> CallbackMap_t; + IFactory() : m_own_objects(false) { } + //! create object by calling creation function corresponded to given identifier AbstractProduct *createItem(const IdentifierType &itemId) { diff --git a/Core/inc/ISample.h b/Core/inc/ISample.h index 75a47c1ba47..150fd67ac67 100644 --- a/Core/inc/ISample.h +++ b/Core/inc/ISample.h @@ -16,28 +16,52 @@ #include "INamed.h" #include "Exceptions.h" +#include "ParameterPool.h" class ICompositeSample; +//- ------------------------------------------------------------------- +//! @class ISample +//! @brief Definition of ISample which +//- ------------------------------------------------------------------- class ISample : public INamed { public: ISample(); - virtual ~ISample() {} + ISample(const ISample &other); + ISample &operator=(const ISample &other); + virtual ~ISample(); + //! return pointer to "this", if it is composite sample (to overload) virtual ICompositeSample *getCompositeSample() { return 0; } + + //! clone sample (to overload) virtual ISample *clone(); -// virtual void add(ISample* p_child); -// virtual void remove(ISample* p_child); -// virtual ISample* getChild(size_t index); + //! initialize pool parameters, i.e. register some of class members for later access via parameter pool (to overload) + virtual void init_parameters(); + //! (temporary for debugging) return sample Id long getId() const {return m_id; } + //! return pointer to the parameter pool + ParameterPool *getParameterPool() { return &m_parameters; } + + //! create new parameter pool which contains all local parameter and parameters of children + virtual ParameterPool *createParameterTree(); + + //! same as above, demonstration of iterators instead of nested calls + virtual ParameterPool *createParameterTreeTest(); + + //! add parameters from local pool to external pool and call recursion over direct children + virtual void addParametersToExternalPool(std::string path, ParameterPool *external_pool, int copy_number=-1); + protected: long m_id; //! temporary debug variable to track id of instance static long m_id_last; //! temporary debug variable to track id of instance + + ParameterPool m_parameters; //! parameter pool }; #endif // ISAMPLE_H diff --git a/Core/inc/Layer.h b/Core/inc/Layer.h index 3727fde98a4..6475c28f2c3 100644 --- a/Core/inc/Layer.h +++ b/Core/inc/Layer.h @@ -56,6 +56,9 @@ public: //! return refractive index of the layer's material virtual complex_t getRefractiveIndex() const { return (dynamic_cast<const HomogeneousMaterial *>(mp_material))->getRefractiveIndex(); } + //! initialize pool parameters, i.e. register some of class members for later access via parameter pool + virtual void init_parameters(); + private: const IMaterial* mp_material; //!< pointer to the material double m_thickness; //!< layer thickness in _angstrom_ diff --git a/Core/inc/LayerRoughness.h b/Core/inc/LayerRoughness.h index 9c994351220..5661fbdf9d9 100644 --- a/Core/inc/LayerRoughness.h +++ b/Core/inc/LayerRoughness.h @@ -55,6 +55,9 @@ public: //! return latteral correlation length inline double getLatteralCorrLength() const { return m_latteralCorrLength; } + //! initialize pool parameters, i.e. register some of class members for later access via parameter pool + virtual void init_parameters(); + protected: double m_sigma; //!< rms of roughness double m_hurstParameter; //!< Hurst parameter which describes how jagged the interface, 0<H<=1 diff --git a/Core/inc/MultiLayer.h b/Core/inc/MultiLayer.h index 8d65aca8822..55fea1a2f96 100644 --- a/Core/inc/MultiLayer.h +++ b/Core/inc/MultiLayer.h @@ -15,7 +15,6 @@ //! @date 01.04.2012 #include <vector> - #include "ICompositeSample.h" #include "Layer.h" #include "LayerInterface.h" @@ -73,9 +72,6 @@ public: //! return clone of multilayer with clones of all layers and recreated interfaces between layers virtual MultiLayer *clone() const; - //! print structure of multilayer - void print(); - //! set cross correlation length of roughnesses between interfaces inline void setCrossCorrLength(double crossCorrLength) { crossCorrLength!=0 ? m_crossCorrLength = crossCorrLength : throw LogicErrorException("Attempt to set crossCorrLength to zero"); } @@ -91,6 +87,12 @@ public: //! change thickness of layer void setLayerThickness(size_t i_layer, double thickness); + //! initialize pool parameters, i.e. register some of class members for later access via parameter pool + virtual void init_parameters(); + + //! print structure of multilayer + void print(); + private: //! hiding copy constructor & assignment operator MultiLayer(const MultiLayer &); diff --git a/Core/inc/ParameterPool.h b/Core/inc/ParameterPool.h new file mode 100644 index 00000000000..f82ab984700 --- /dev/null +++ b/Core/inc/ParameterPool.h @@ -0,0 +1,80 @@ +#ifndef PARAMETERPOOL_H +#define PARAMETERPOOL_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file ParameterPool.h +//! @brief Definition of Layer class +//! @author Scientific Computing Group at FRM II +//! @date 18.06.2012 + +#include "Exceptions.h" +#include <string> +#include <map> + + +//- ------------------------------------------------------------------- +//! @class ParameterPool +//! @brief Definition of ParameterPool to hold map of pointers to parameters +//! Names of parameters should be the different, otherwise exception is thrown +//- ------------------------------------------------------------------- +class ParameterPool +{ +public: + //! definition of parameter type and parameter container + typedef double * parameter_t; + typedef std::map<std::string, parameter_t > parametermap_t; + typedef parametermap_t::iterator iterator_t; + + ParameterPool(); + virtual ~ParameterPool(); + + //! simple clone + ParameterPool *clone(); + + //! clone with adding preffix to every parameter key + ParameterPool *cloneWithPrefix(std::string prefix); + + //! copy parameters of given pool to the external pool while adding prefix to local parameter keys + void copyToExternalPool(std::string prefix, ParameterPool *external_pool); + + //! clear and delete parameter map + void clear(); + + //! return size of parameter container + size_t size() const { return m_map ? m_map->size() : 0; } + + //! main method to register parameter in the container + bool registerParameter(std::string name, parameter_t par); + + //! access to parameter container + iterator_t begin() { return (m_map ? m_map->begin() : throw NullPointerException("ParameterPool::begin() -> Error! Non existing parameter map.")); } + iterator_t end() { return (m_map ? m_map->end() : throw NullPointerException("ParameterPool::end() -> Error! Non existing parameter map.")); } + + //! print parameter pool + friend std::ostream &operator<<(std::ostream &ostr, const ParameterPool &obj) + { + obj.print(ostr); return ostr; + } + + //! print content of parameter pool on the screen + void print(); + +protected: + //! hiding copy constructors and assignment operators to allow only conscious cloning + ParameterPool(const ParameterPool &other); + ParameterPool &operator=(const ParameterPool &other); + + //! print parameter pool content + virtual void print(std::ostream &ostr) const; + + parametermap_t *m_map; //! map of parameters +}; + +#endif // PARAMETERPOOL_H diff --git a/Core/inc/Utils.h b/Core/inc/Utils.h new file mode 100644 index 00000000000..4da38595e1a --- /dev/null +++ b/Core/inc/Utils.h @@ -0,0 +1,179 @@ +#ifndef UTILS_H +#define UTILS_H +// ******************************************************************** +// * The BornAgain project * +// * Simulation of neutron and x-ray scattering at grazing incidence * +// * * +// * LICENSE AND DISCLAIMER * +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris * +// * eget quam orci. Quisque porta varius dui, quis posuere nibh * +// * mollis quis. Mauris commodo rhoncus porttitor. * +// ******************************************************************** +//! @file Utils.h +//! @brief Definition of several helper classes +//! @author Scientific Computing Group at FRM II +//! @date 19.06.2012 + +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <sstream> + + +namespace Utils { + + +//- ------------------------------------------------------------------- +//! @class StringUsageMap +//! @brief Definition of StringUsageMap to control how often string is used +//- ------------------------------------------------------------------- +class StringUsageMap +{ +public: + typedef std::map<std::string, int> nstringmap_t; + typedef nstringmap_t::iterator iterator_t; + + StringUsageMap(){} + ~StringUsageMap(){} + + //! add string to the map to count number of times it was used + void add(std::string name) + { + m_current_string = name; + iterator_t it = m_nstringmap.find(name); + if(it != m_nstringmap.end() ) { + // such string already exists, incremeting usage counter + (*it).second++; + } else { + // such string doesnt exist, insert it with counter=1 + m_nstringmap.insert(nstringmap_t::value_type(name,1)); + } + } + + //! access to the map of strings + iterator_t begin() { return m_nstringmap.begin(); } + iterator_t end() { return m_nstringmap.end(); } + int &operator[](std::string name) { return m_nstringmap[name]; } + + //! get current string + std::string get_current() { return m_current_string; } + +private: + std::string m_current_string; + nstringmap_t m_nstringmap; +}; + + +//- ------------------------------------------------------------------- +//! @class StringSampleHelper +//! @brief Definition of StringSampleHelper to build the string representing +//! path in ISample parameter tree +//! +//! See example in ICompositeSample::getParameterTree() +//- ------------------------------------------------------------------- +class StringSampleHelper +{ +public: + typedef std::vector<StringUsageMap > nstringmap_t; + typedef nstringmap_t::iterator iterator_t; + + StringSampleHelper(){} + ~StringSampleHelper(){} + + void add(std::string name, int dirlevel) { + + while(dirlevel > (int)m_stringstack.size()-1) { + m_stringstack.push_back(StringUsageMap()); + } + + while(dirlevel < (int)m_stringstack.size()-1) { + m_stringstack.pop_back(); + } + + m_stringstack[dirlevel].add(name); + } + + //! return current path in parameter tree, like /multilayer/interface3/roughness/sigma + std::string get_path() + { + std::string result; + for(size_t i_level=0; i_level<m_stringstack.size(); i_level++) { + std::string currentLevelName = m_stringstack[i_level].get_current(); + StringUsageMap &strUsageMap = m_stringstack[i_level]; + // if such name has been already used on that level, built the level name using index number + std::ostringstream os; + int nOfUsage = strUsageMap[currentLevelName]; + result += std::string("/") + currentLevelName; + if(nOfUsage != 1) { + os<<nOfUsage; + result += os.str(); + } + } + return result; + } + + iterator_t begin() { return m_stringstack.begin(); } + iterator_t end() { return m_stringstack.end(); } + size_t size() const { return m_stringstack.size(); } + StringUsageMap &operator[](size_t i) { return m_stringstack[i]; } + StringUsageMap const &operator[](size_t i) const { return m_stringstack[i]; } + +protected: + std::vector<StringUsageMap > m_stringstack; +}; + + +} + + +#endif // UTILS_H + + +//class StringUsageDir +//{ +//public: +// typedef std::vector<StringUsageMap > nstringmap_t; +// typedef nstringmap_t::iterator iterator_t; + +// StringUsageDir(){} +// ~StringUsageDir(){} + +// bool add(std::string name, size_t dirlevel) { +// std::cout << "qqq " << name << " " << dirlevel << std::endl; +// // adjusting stack of dir names to current dirlevel +// while(m_stringstack.size() > dirlevel ) { +// m_stringstack.pop_back(); +// } +// // pushing new name in the stack +// m_stringstack.push_back(name); +// // adding new name in the map of used name to know how may times given name is repeated on current level +// if(dirlevel >= m_nstringdir.size() ) m_nstringdir.resize(dirlevel+1); +// return m_nstringdir[dirlevel].add(name); +// } + +// std::string get_path() +// { +// std::string result; +// for(size_t i_level=0; i_level<m_stringstack.size(); i_level++) { +// std::string ¤tLevelName = m_stringstack[i_level]; +// StringUsageMap &strUsageMap = m_nstringdir[i_level]; + +// std::ostringstream os; +// int nOfUsage = strUsageMap[currentLevelName]; +// if(nOfUsage != 1) os<<nOfUsage; +// result += std::string("/") + currentLevelName+os.str(); +// } +// return result; +// } + +// iterator_t begin() { return m_nstringdir.begin(); } +// iterator_t end() { return m_nstringdir.end(); } +// size_t size() const { return m_nstringdir.size(); } +// StringUsageMap &operator[](size_t i) { return m_nstringdir[i]; } +// StringUsageMap const &operator[](size_t i) const { return m_nstringdir[i]; } + +//protected: +// std::vector<StringUsageMap > m_nstringdir; +// std::vector<std::string > m_stringstack; +//}; diff --git a/Core/src/ICompositeSample.cpp b/Core/src/ICompositeSample.cpp index 802744c193d..08a6102924c 100644 --- a/Core/src/ICompositeSample.cpp +++ b/Core/src/ICompositeSample.cpp @@ -1,5 +1,9 @@ #include "ICompositeSample.h" #include "ICompositeIterator.h" +#include "Utils.h" +#include <vector> +#include <sstream> + ICompositeSample::ICompositeSample() @@ -8,8 +12,11 @@ ICompositeSample::ICompositeSample() } - +/* ************************************************************************* */ +// create general iterator to walk through the tree of registered composite children +/* ************************************************************************* */ ICompositeIterator ICompositeSample::createIterator() { return ICompositeIterator(this); } + diff --git a/Core/src/ISample.cpp b/Core/src/ISample.cpp index 8a19ac7b845..1f24cc73a9a 100644 --- a/Core/src/ISample.cpp +++ b/Core/src/ISample.cpp @@ -1,15 +1,160 @@ #include "ISample.h" +#include "ICompositeSample.h" +#include "ICompositeIterator.h" +#include "Utils.h" long ISample::m_id_last=0; ISample::ISample() { + // tracking index of created object for debugging purpose m_id = m_id_last; m_id_last++; } +/* ************************************************************************* */ +// copy constructor +// we are consciously not copying parameter pool, it should be done in child class +/* ************************************************************************* */ +ISample::ISample(const ISample &other) : INamed(other) +{ + +} + + +/* ************************************************************************* */ +// assignment operator +// we are consciously not copying parameter pool, it should be done in child class +/* ************************************************************************* */ +ISample &ISample::operator=(const ISample &other) +{ + if( this != &other) + { + INamed::operator=(other); + } + return *this; +} + + +ISample::~ISample() +{ + +} + + ISample *ISample::clone() { - throw NotImplementedException("ISample::clone() -> Error! The clone method is not implemented"); + throw NotImplementedException("ISample::clone() -> Error! Method is not implemented"); +} + + +void ISample::init_parameters() +{ + throw NotImplementedException("ISample::init_parameters() -> Error! Method is not implemented"); +} + + +/* ************************************************************************* */ +// create new parameter pool which contains all local parameter and parameters of children +// user have to delete it +/* ************************************************************************* */ +ParameterPool *ISample::createParameterTree() +{ + ParameterPool *newpool = new ParameterPool; + std::string path("/"); + addParametersToExternalPool(path, newpool); + return newpool; +} + + +/* ************************************************************************* */ +// add parameters from local pool to external pool and call recursion over direct children +/* ************************************************************************* */ +void ISample::addParametersToExternalPool(std::string path, ParameterPool *external_pool, int copy_number) +{ + // adding trailing slash, if it is not already there + if( path[path.length()-1] != '/' ) path += "/"; + + // constructing new path, using object name and copy number + std::ostringstream osCopyNumber; + if(copy_number >=0) osCopyNumber << copy_number; + path = path + getName() + osCopyNumber.str() + "/"; + + // copy local parameter to external pool + m_parameters.copyToExternalPool(path, external_pool); + + // going through direct children of given sample and copy they parameters recursively + ICompositeSample *sample = getCompositeSample(); + if( sample ) { + + // Here we need some default mechanism to handle cases with many children with same name. + // Lets run through all direct children and save they names + Utils::StringUsageMap strUsageMap; + for(ICompositeSample::iterator_t it=sample->begin_shallow(); it!=sample->end_shallow(); ++it) { + strUsageMap.add( path +(*it)->getName() ); // saving children name + } + + // Now we run through direct children again, adjusting copy number of children, if necessary + Utils::StringUsageMap strUsageMap2; + for(ICompositeSample::iterator_t it=sample->begin_shallow(); it!=sample->end_shallow(); ++it) { + std::string children_name = path +(*it)->getName(); + strUsageMap2.add(children_name); + int ncopy = strUsageMap2[children_name]; + + // if object is in single exemplar, we do not want any copy number + if(strUsageMap[children_name] == 1) ncopy = -1; + + (*it)->addParametersToExternalPool(path, external_pool, ncopy); + } + + } // sample + +} + + +/* ************************************************************************* */ +// same as above +// return new parameter pool which contains all local parameter as well as all +// parameters from CompositeSample; tree user has to take to delete it +// +// example shows how to walk through all subsamples using iterators instead +// of recursion +/* ************************************************************************* */ +ParameterPool *ISample::createParameterTreeTest() +{ + // cloning first local parameter pool + ParameterPool *newpool = m_parameters.cloneWithPrefix( std::string("/")+getName()+std::string("/")); + + // walking through children tree + ICompositeSample *sample = getCompositeSample(); + if( sample ) { + // using helper to get unique path in the tree as parameter names + Utils::StringSampleHelper strHelper; + strHelper.add(getName(), 0); // "folder" name, level of nesting (0 - for top level) + + // loop over children tree + ICompositeIterator it = sample->createIterator(); + it.first(); + while(!it.is_done()) + { + // adding child name to the path + strHelper.add(it.get_current()->getName(), it.get_level() ); + + // access to the poll parameter of child + ParameterPool *pool = it.get_current()->getParameterPool(); + if(pool->size()) { + for(ParameterPool::iterator_t ip=pool->begin(); ip!=pool->end(); ip++) { + //std::cout << (*ip).first << " " << (*ip).second << std::endl; + // adding parameter name to the path + strHelper.add( (*ip).first, it.get_level()+1 ); + // registering new parameter with full path + newpool->registerParameter(strHelper.get_path(), (*ip).second); + } + } + it.next(); + } + //std::cout << *newpool; + } + return newpool; } diff --git a/Core/src/Layer.cpp b/Core/src/Layer.cpp index 692d1f1d531..fd7576e166e 100644 --- a/Core/src/Layer.cpp +++ b/Core/src/Layer.cpp @@ -8,6 +8,7 @@ Layer::Layer() : mp_material(0), m_thickness(0) { setName("layer"); + init_parameters(); } @@ -15,6 +16,7 @@ Layer::Layer(const Layer &other) : ISample(other) { mp_material = other.mp_material; m_thickness = other.m_thickness; + init_parameters(); } @@ -25,6 +27,7 @@ Layer &Layer::operator=(const Layer &other) ISample::operator=(other); mp_material = other.mp_material; m_thickness = other.m_thickness; + init_parameters(); } return *this; } @@ -36,6 +39,17 @@ Layer::~Layer() } +/* ************************************************************************* */ +// initialize pool parameters, i.e. register some of class members for later +// access via parameter pool +/* ************************************************************************* */ +void Layer::init_parameters() +{ + getParameterPool()->clear(); + getParameterPool()->registerParameter("thickness", &m_thickness); +} + + /* ************************************************************************* */ // clone /* ************************************************************************* */ diff --git a/Core/src/LayerRoughness.cpp b/Core/src/LayerRoughness.cpp index f06979ee58d..e336a9a0551 100644 --- a/Core/src/LayerRoughness.cpp +++ b/Core/src/LayerRoughness.cpp @@ -5,22 +5,24 @@ LayerRoughness::LayerRoughness() : m_sigma(0), m_hurstParameter(0), m_latteralCorrLength(0) { setName("roughness"); + init_parameters(); } LayerRoughness::LayerRoughness(double sigma, double hurstParameter, double latteralCorrLength) : m_sigma(sigma), m_hurstParameter(hurstParameter), m_latteralCorrLength(latteralCorrLength) { - + setName("roughness"); + init_parameters(); } - LayerRoughness::LayerRoughness(const LayerRoughness &other) : IRoughness(other) { m_sigma = other.m_sigma; m_hurstParameter = other.m_hurstParameter; m_latteralCorrLength = other.m_latteralCorrLength; + init_parameters(); } @@ -32,11 +34,20 @@ LayerRoughness &LayerRoughness::operator=(const LayerRoughness &other) m_sigma = other.m_sigma; m_hurstParameter = other.m_hurstParameter; m_latteralCorrLength = other.m_latteralCorrLength; + init_parameters(); } return *this; } +void LayerRoughness::init_parameters() +{ + getParameterPool()->clear(); + getParameterPool()->registerParameter("sigma", &m_sigma); + getParameterPool()->registerParameter("hurst", &m_hurstParameter); + getParameterPool()->registerParameter("corrlength", &m_latteralCorrLength); +} + /* ************************************************************************* */ //! Power spectral density of the surface roughness is a result of two-dimensional diff --git a/Core/src/MultiLayer.cpp b/Core/src/MultiLayer.cpp index eb08780a63d..841b58df189 100644 --- a/Core/src/MultiLayer.cpp +++ b/Core/src/MultiLayer.cpp @@ -7,6 +7,7 @@ MultiLayer::MultiLayer() : m_crossCorrLength(0) { setName("multilayer"); + init_parameters(); } @@ -16,6 +17,17 @@ MultiLayer::~MultiLayer() } +/* ************************************************************************* */ +// initialize pool parameters, i.e. register some of class members for later +// access via parameter pool +/* ************************************************************************* */ +void MultiLayer::init_parameters() +{ + getParameterPool()->clear(); + getParameterPool()->registerParameter("crossCorrLength", &m_crossCorrLength); +} + + /* ************************************************************************* */ // clear MultiLayer contents including interfaces /* ************************************************************************* */ @@ -32,6 +44,8 @@ void MultiLayer::clear() m_interfaces.clear(); m_layers_z.clear(); + + getParameterPool()->clear(); } @@ -59,6 +73,8 @@ MultiLayer *MultiLayer::clone() const newMultiLayer->m_crossCorrLength = m_crossCorrLength; + newMultiLayer->init_parameters(); + return newMultiLayer; } @@ -109,8 +125,8 @@ void MultiLayer::print() } std::cout << std::endl; } - std::cout << "yyy" << std::endl; - std::cout << m_layers.size() << " " << m_interfaces.size() << " " << m_samples.size() << std::endl; + //std::cout << "yyy" << std::endl; + //std::cout << m_layers.size() << " " << m_interfaces.size() << " " << m_samples.size() << std::endl; } diff --git a/Core/src/ParameterPool.cpp b/Core/src/ParameterPool.cpp new file mode 100644 index 00000000000..c6468d57c8d --- /dev/null +++ b/Core/src/ParameterPool.cpp @@ -0,0 +1,148 @@ +#include "ParameterPool.h" +#include "Exceptions.h" +#include <iostream> +#include <sstream> + + +ParameterPool::ParameterPool() : m_map(0) +{ + +} + + +ParameterPool::~ParameterPool() +{ + clear(); +} + + + +/* ************************************************************************* */ +// copy constructor for completness +// declared private, to avoid unconscious copying of parameters, that pointing to previous owner +/* ************************************************************************* */ +ParameterPool::ParameterPool(const ParameterPool &other) +{ + m_map = 0; + if( other.m_map ) { + m_map = new parametermap_t; + // copying content of other's map + *m_map = *other.m_map; + } +} + + +/* ************************************************************************* */ +// assignment operator for completness +// declared private, to avoid unconscious copying of parameters, that pointing to previous owner +/* ************************************************************************* */ +ParameterPool &ParameterPool::operator=(const ParameterPool &other) +{ + if( this != &other) + { + m_map = 0; + if( other.m_map ) { + m_map = new parametermap_t; + // copying content of other's map + *m_map = *other.m_map; + } + } + return *this; +} + + +/* ************************************************************************* */ +// Clear the parameter container +/* ************************************************************************* */ +void ParameterPool::clear() +{ + if(m_map) { + m_map->clear(); + delete m_map; + m_map=0; + } +} + + +/* ************************************************************************* */ +// Clone method. Clones everything. +/* ************************************************************************* */ +ParameterPool *ParameterPool::clone() +{ + ParameterPool *new_pool = new ParameterPool; + if(m_map) { + new_pool->m_map = new parametermap_t; + *new_pool->m_map = *m_map; + } + return new_pool; +} + + +/* ************************************************************************* */ +// Clone method with adding preffix to parameter's keys +/* ************************************************************************* */ +ParameterPool *ParameterPool::cloneWithPrefix(std::string prefix) +{ + ParameterPool *new_pool = new ParameterPool; + if(m_map) { + for(parametermap_t::iterator it=m_map->begin(); it!= m_map->end(); ++it) + { + new_pool->registerParameter(prefix+it->first, it->second); + } + } + return new_pool; +} + + +/* ************************************************************************* */ +// copy parameters of given pool to the external pool while adding prefix to +// local parameter keys +/* ************************************************************************* */ +void ParameterPool::copyToExternalPool(std::string prefix, ParameterPool *external_pool) +{ + if(m_map) { + for(parametermap_t::iterator it=m_map->begin(); it!= m_map->end(); ++it) { + external_pool->registerParameter(prefix+it->first, it->second); + } + } +} + + +/* ************************************************************************* */ +// Registering parameter with given name. Name should be different for each +// register. +/* ************************************************************************* */ +bool ParameterPool::registerParameter(std::string name, parameter_t par) +{ + // create map if not exist + if( !m_map ) { + m_map = new parametermap_t; + } + + parametermap_t::iterator it = m_map->find(name); + if( it!=m_map->end() ) { + // such parameter already registered, throw exception + print(std::cout); + std::ostringstream os; + os << "ParameterPool::registerParameter() -> Warning! Registering parameter with same name '" << name << "'. Previous link will be replaced "; + throw RuntimeErrorException(os.str()); + } + return m_map->insert(parametermap_t::value_type(name, par)).second; +} + + +/* ************************************************************************* */ +// print content on the screen +/* ************************************************************************* */ +void ParameterPool::print(std::ostream &ostr) const +{ + ostr << "parameter pool: " << this << " map:" << m_map; + if(m_map) { + ostr << "size(): " << m_map->size() << std::endl; + for(parametermap_t::iterator it=m_map->begin(); it!= m_map->end(); it++) { + std::cout << (*it).first << " " << (*it).second << std::endl; + } + } +} + + diff --git a/Core/src/Utils.cpp b/Core/src/Utils.cpp new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/Core/src/Utils.cpp @@ -0,0 +1 @@ + diff --git a/GISASFW.pro b/GISASFW.pro index c2414637001..7c375fbb635 100644 --- a/GISASFW.pro +++ b/GISASFW.pro @@ -2,7 +2,7 @@ TEMPLATE = subdirs SUBDIRS += \ Core \ - ThirdParty/gtest \ +# ThirdParty/gtest \ # ThirdParty/fftw++ \ App \ UnitTests/TestCore -- GitLab