diff --git a/App/src/TestIsGISAXS12.cpp b/App/src/TestIsGISAXS12.cpp index 7709e17a176fa90198cbbba16729df401dadcc25..fdc74005c7e899a2cee234d89d382b4b7695235b 100644 --- a/App/src/TestIsGISAXS12.cpp +++ b/App/src/TestIsGISAXS12.cpp @@ -36,8 +36,6 @@ #include "ParticleBuilder.h" #include "ParticleLayout.h" #include "ResolutionFunction2DSimple.h" -#include "StochasticGaussian.h" -#include "StochasticSampledParameter.h" #include "Units.h" #include "Utils.h" #include "FileSystem.h" @@ -260,9 +258,9 @@ void TestIsGISAXS12::run_isgisaxs_fit() hreal->DrawCopy(); hsimul->DrawCopy("same"); if(i_set==0) { - leg1->AddEntry(hreal,"BornAgain data","lp"); - leg1->AddEntry(hsimul,"BornAgain simul","lp"); - } + leg1->AddEntry(hreal,"BornAgain data","lp"); + leg1->AddEntry(hsimul,"BornAgain simul","lp"); + } } c2->cd(1); leg1->Draw(); c2->cd(2); leg1->Draw(); @@ -501,10 +499,8 @@ ISample *TestIsGISAXS12::TestSampleBuilder::buildSample() const double sigma1 = radius1*m_dispersion_radius1; double sigma2 = radius2*m_dispersion_radius2; int nfwhm(2); // to have xmin=average-nfwhm*FWHM, xmax=average+nfwhm*FWHM (nfwhm = xR/2, where xR is what is defined in isgisaxs *.inp file) - StochasticDoubleGaussian sg1(radius1, sigma1); - StochasticDoubleGaussian sg2(radius2, sigma2); - StochasticSampledParameter par1(sg1, nbins, nfwhm); - StochasticSampledParameter par2(sg2, nbins, nfwhm); + DistributionGaussian gauss1(radius1, sigma1); + DistributionGaussian gauss2(radius2, sigma2); ParticleLayout particle_layout; InterferenceFunction1DParaCrystal *p_interference_function = @@ -516,9 +512,11 @@ ISample *TestIsGISAXS12::TestSampleBuilder::buildSample() const // building nano particles ParticleBuilder builder; - builder.setPrototype(cylinder1,"/Particle/FormFactorCylinder/radius", par1, particle_probability1); + builder.setPrototype(cylinder1,"/Particle/FormFactorCylinder/radius", gauss1, + nbins, nfwhm, particle_probability1); builder.plantParticles(particle_layout); - builder.setPrototype(cylinder2,"/Particle/FormFactorCylinder/radius", par2, particle_probability2); + builder.setPrototype(cylinder2,"/Particle/FormFactorCylinder/radius", gauss2, + nbins, nfwhm, particle_probability2); builder.plantParticles(particle_layout); air_layer.addLayout(particle_layout); diff --git a/App/src/TestIsGISAXS5.cpp b/App/src/TestIsGISAXS5.cpp index 3e596220c38376454ba2103d2abf458445cb539e..c2a3a4b0c302b921c478b3d8ed49c72a61308e92 100644 --- a/App/src/TestIsGISAXS5.cpp +++ b/App/src/TestIsGISAXS5.cpp @@ -35,8 +35,6 @@ #include "ParticleBuilder.h" #include "ParticleLayout.h" #include "ResolutionFunction2DSimple.h" -#include "StochasticGaussian.h" -#include "StochasticSampledParameter.h" #include "Units.h" #include "Utils.h" @@ -206,9 +204,9 @@ void TestIsGISAXS5::run_isgisaxs_fit() hreal->DrawCopy(); hsimul->DrawCopy("same"); if(i_set==0) { - leg1->AddEntry(hreal,"BornAgain data","lp"); - leg1->AddEntry(hsimul,"BornAgain simul","lp"); - } + leg1->AddEntry(hreal,"BornAgain data","lp"); + leg1->AddEntry(hsimul,"BornAgain simul","lp"); + } } c2->cd(1); leg1->Draw(); c2->cd(2); leg1->Draw(); @@ -292,8 +290,7 @@ ISample *TestIsGISAXS5::SampleBuilder::buildSample() const int nbins=20; double sigma = m_particle_radius*m_dispersion_radius; int nfwhm(2); // to have xmin=average-nfwhm*FWHM, xmax=average+nfwhm*FWHM (nfwhm = xR/2, where xR is what is defined in isgisaxs *.inp file) - StochasticDoubleGaussian sg(m_particle_radius, sigma); - StochasticSampledParameter stochastic_parameter(sg, nbins, nfwhm); + DistributionGaussian gauss(m_particle_radius, sigma); ParticleLayout particle_layout; InterferenceFunction1DParaCrystal *p_interference_function = @@ -305,7 +302,8 @@ ISample *TestIsGISAXS5::SampleBuilder::buildSample() const // building nano particles ParticleBuilder builder; - builder.setPrototype(cylinder,"/Particle/FormFactorCylinder/radius", stochastic_parameter); + builder.setPrototype(cylinder,"/Particle/FormFactorCylinder/radius", gauss, + nbins, nfwhm); builder.plantParticles(particle_layout); // making layer holding all whose nano particles diff --git a/Core/Samples/inc/ParticleBuilder.h b/Core/Samples/inc/ParticleBuilder.h index d81992ba2e7f35a51ca22ed13d994b84f24976f5..11ac7dc09f148008338fb022c6de0a1e9d012b88 100644 --- a/Core/Samples/inc/ParticleBuilder.h +++ b/Core/Samples/inc/ParticleBuilder.h @@ -17,7 +17,7 @@ #define PARTICLEBUILDER_H #include "Particle.h" -#include "IStochasticParameter.h" +#include "Distributions.h" #include "ParticleLayout.h" //! @class ParticleBuilder @@ -35,16 +35,21 @@ public: //! @param name parameter name in the parameter pool of given prototype //! @param parameter variation type //! @param scale global scale factor for probabilities - void setPrototype(const Particle& particle, std::string name, const StochasticParameter<double>& param, double scale=1.0); + void setPrototype(const Particle& particle, std::string name, + const IDistribution1D& param, size_t nbr_samples, + double sigma_factor=0.0, double scale=1.0); //! plant particles in given decoration - void plantParticles(ParticleLayout& decor); + void plantParticles(ParticleLayout& layout); private: - Particle *m_prototype; //!< prototype of the particle, all particles will be cloned from it - std::string m_parameter_name; //!< name of parameter to variate - StochasticParameter<double > *m_parameter; - double m_scale; //!< global scale factor for probabilities + //! prototype of the particle, all particles will be cloned from it + Particle *mp_prototype; + std::string m_parameter_name; //!< name of parameter to vary + IDistribution1D *mp_distribution; //!< distribution for the parameter + size_t m_nbr_samples; //!< number of particles to be created + double m_sigma_factor; //!< range of parameter in FWHM + double m_scale; //!< global scale factor for probabilities }; #endif // PARTICLEBUILDER_H diff --git a/Core/Samples/src/ParticleBuilder.cpp b/Core/Samples/src/ParticleBuilder.cpp index 605031a25232a59d66e512644a8a5aa948a41958..f4530febeb1442583195f9247b9f448c65403365 100644 --- a/Core/Samples/src/ParticleBuilder.cpp +++ b/Core/Samples/src/ParticleBuilder.cpp @@ -16,67 +16,78 @@ #include "ParticleBuilder.h" #include "ParticleLayout.h" #include "Numeric.h" -#include "StochasticSampledParameter.h" #include <numeric> #include <algorithm> -ParticleBuilder::ParticleBuilder() : - m_prototype(0), m_parameter(0), m_scale(0) +ParticleBuilder::ParticleBuilder() + : mp_prototype(0) + , mp_distribution(0) + , m_nbr_samples(0) + , m_sigma_factor(0.0) + , m_scale(0) { } ParticleBuilder::~ParticleBuilder() { - delete m_prototype; - delete m_parameter; + delete mp_prototype; + delete mp_distribution; } //! Sets prototype for particle production -void ParticleBuilder::setPrototype(const Particle& particle, std::string name, const StochasticParameter<double>& param, double scale) +void ParticleBuilder::setPrototype(const Particle &particle, std::string name, + const IDistribution1D ¶m, size_t nbr_samples, double sigma_factor, + double scale) { - delete m_prototype; - m_prototype = particle.clone(); + delete mp_prototype; + mp_prototype = particle.clone(); m_parameter_name = name; - delete m_parameter; - m_parameter = param.clone(); + delete mp_distribution; + mp_distribution = param.clone(); + m_nbr_samples = nbr_samples; + m_sigma_factor = sigma_factor; m_scale = scale; } //! plant particles in given decoration -void ParticleBuilder::plantParticles(ParticleLayout& decor) +void ParticleBuilder::plantParticles(ParticleLayout& layout) { - if( !m_prototype ) throw NullPointerException("ParticleBuilder::plantParticle() -> Error. No prototype is defined"); + if( !mp_prototype ) throw NullPointerException( + "ParticleBuilder::plantParticle() -> Error. No prototype is defined"); - if( !m_parameter ) throw NullPointerException("ParticleBuilder::plantParticle() -> Error. No parameter is defined"); + if( !mp_distribution ) throw NullPointerException( + "ParticleBuilder::plantParticle() -> Error. No distribution is defined"); - ParameterPool *pool = m_prototype->createParameterTree(); + ParameterPool *pool = mp_prototype->createParameterTree(); - StochasticSampledParameter *sampled_parameter = dynamic_cast<StochasticSampledParameter *>(m_parameter); - if( !sampled_parameter) { - throw LogicErrorException("ParticleBuilder::plantParticle() -> Error. Not supported parameter type"); + // generate parameter samples + std::vector<ParameterSample> samples = + mp_distribution->generateSamples(m_nbr_samples, m_sigma_factor); + + // find maximum weight + double max_weight = 0.0; + for(std::vector<ParameterSample>::const_iterator it = samples.begin(); + it != samples.end(); ++it) { + max_weight = std::max(max_weight, it->weight); } - // calculating sum of all weights, and maximum value - std::vector<double> weights; - for(size_t i=0; i<sampled_parameter->getNbins(); ++i) weights.push_back(sampled_parameter->probabilityBinDensity(i)); - double maximum_value = *std::max_element(weights.begin(), weights.end()); - double sum_of_weights = std::accumulate(weights.begin(), weights.end(), 0.0); // loop over sampled parameter values - for(size_t i=0; i<sampled_parameter->getNbins(); ++i) { + for(std::vector<ParameterSample>::const_iterator it = samples.begin(); + it != samples.end(); ++it) { - double weight = sampled_parameter->probabilityBinDensity(i); - double value = sampled_parameter->getBinValue(i); + double weight = it->weight; + double value = it->value; // changing value of the particle's parameter and making clone pool->setParameterValue(m_parameter_name, value); - Particle *particle = m_prototype->clone(); + Particle *particle = mp_prototype->clone(); - if(weight/maximum_value > Numeric::probthreshold) { // isgisaxs way - decor.addParticle(*particle, 0.0, weight/sum_of_weights*m_scale); + if(weight/max_weight > Numeric::probthreshold) { // isgisaxs way + layout.addParticle(*particle, 0.0, weight*m_scale); } delete particle; diff --git a/Core/StandardSamples/IsGISAXS02Builder.cpp b/Core/StandardSamples/IsGISAXS02Builder.cpp index 6df79cb3bfd77ce4d3685b325c96c5d60a54ddb1..94480d7359cc63258fc9d05e6aaf90f05d299032 100644 --- a/Core/StandardSamples/IsGISAXS02Builder.cpp +++ b/Core/StandardSamples/IsGISAXS02Builder.cpp @@ -18,11 +18,8 @@ #include "ParticleLayout.h" #include "Materials.h" #include "FormFactorCylinder.h" -//#include "FormFactorPrism3.h" #include "Units.h" #include "InterferenceFunctionNone.h" -#include "StochasticSampledParameter.h" -#include "StochasticGaussian.h" #include "ParticleBuilder.h" @@ -73,17 +70,17 @@ ISample *IsGISAXS02Builder::buildSample() const double sigma1 = m_radius1*m_sigma1_ratio; double sigma2 = m_radius2*m_sigma2_ratio; int nfwhm(3); // to have xmin=average-nfwhm*FWHM, xmax=average+nfwhm*FWHM (nfwhm = xR/2, where xR is what is defined in isgisaxs *.inp file) - StochasticDoubleGaussian sg1(m_radius1, sigma1); - StochasticDoubleGaussian sg2(m_radius2, sigma2); - StochasticSampledParameter par1(sg1, nbins, nfwhm); - StochasticSampledParameter par2(sg2, nbins, nfwhm); + DistributionGaussian gauss1(m_radius1, sigma1); + DistributionGaussian gauss2(m_radius2, sigma2); // building nano particles ParticleBuilder builder; - builder.setPrototype(cylinder1,"/Particle/FormFactorCylinder/radius", par1, 0.95); + builder.setPrototype(cylinder1,"/Particle/FormFactorCylinder/radius", gauss1, + nbins, nfwhm, 0.95); builder.plantParticles(particle_layout); - builder.setPrototype(cylinder2,"/Particle/FormFactorCylinder/radius", par2, 0.05); + builder.setPrototype(cylinder2,"/Particle/FormFactorCylinder/radius", gauss2, + nbins, nfwhm, 0.05); builder.plantParticles(particle_layout); particle_layout.addInterferenceFunction(new InterferenceFunctionNone()); diff --git a/Core/StandardSamples/IsGISAXS03Builder.cpp b/Core/StandardSamples/IsGISAXS03Builder.cpp index e5949ca93d850be2f8817c2dfc740cc693efc317..23be06c91f90c17ba08621ad0f5c50152f0e89aa 100644 --- a/Core/StandardSamples/IsGISAXS03Builder.cpp +++ b/Core/StandardSamples/IsGISAXS03Builder.cpp @@ -20,8 +20,7 @@ #include "FormFactorCylinder.h" #include "Units.h" #include "InterferenceFunctionNone.h" -#include "StochasticSampledParameter.h" -#include "StochasticGaussian.h" +#include "Distributions.h" #include "ParticleBuilder.h" @@ -144,11 +143,11 @@ ISample *IsGISAXS03BASizeBuilder::buildSample() const FormFactorCylinder p_ff_cylinder( m_radius, m_height); Particle nano_particle(particle_material, p_ff_cylinder); // radius of nanoparticles will be sampled with gaussian probability - int nbins(100), nfwhm(2); - StochasticDoubleGaussian double_gaussian(m_radius, sigma); - StochasticSampledParameter par(double_gaussian, nbins, nfwhm); + int n_samples(100), nfwhm(2); + DistributionGaussian gauss(m_radius, sigma); ParticleBuilder builder; - builder.setPrototype(nano_particle,"/Particle/FormFactorCylinder/radius", par); + builder.setPrototype(nano_particle,"/Particle/FormFactorCylinder/radius", + gauss, n_samples, nfwhm); builder.plantParticles(particle_layout); particle_layout.addInterferenceFunction(new InterferenceFunctionNone()); diff --git a/Core/StandardSamples/IsGISAXS15Builder.cpp b/Core/StandardSamples/IsGISAXS15Builder.cpp index e85d1d2d1a6c7bda3a8768a3e99bac8d5d75db70..2925902c32556057f2c6db5ee2c355e1a1a1a0f1 100644 --- a/Core/StandardSamples/IsGISAXS15Builder.cpp +++ b/Core/StandardSamples/IsGISAXS15Builder.cpp @@ -20,8 +20,6 @@ #include "Units.h" #include "InterferenceFunction1DParaCrystal.h" #include "FormFactorCylinder.h" -#include "StochasticGaussian.h" -#include "StochasticSampledParameter.h" #include "ParticleBuilder.h" @@ -49,11 +47,10 @@ ISample *IsGISAXS15Builder::buildSample() const FormFactorCylinder ff_cylinder(5.0*Units::nanometer, 5.0*Units::nanometer); Particle particle_prototype(particle_material, ff_cylinder); - StochasticDoubleGaussian sg(5.0*Units::nanometer, 1.25*Units::nanometer); - StochasticSampledParameter stochastic_radius(sg,30, 2); + DistributionGaussian gauss(5.0*Units::nanometer, 1.25*Units::nanometer); ParticleBuilder particle_builder; particle_builder.setPrototype(particle_prototype, - "/Particle/FormFactorCylinder/radius", stochastic_radius); + "/Particle/FormFactorCylinder/radius", gauss, 30, 2.0); particle_builder.plantParticles(particle_layout); // Set height of each particle to its radius (H/R fixed)