diff --git a/Core/Parametrization/ParameterPool.cpp b/Core/Parametrization/ParameterPool.cpp index b56c0c065e09b3b3ded48bc33c06220cae0262a2..3fbbdd7a2863e01fa8dec0bcc92108abbdb96c9d 100644 --- a/Core/Parametrization/ParameterPool.cpp +++ b/Core/Parametrization/ParameterPool.cpp @@ -154,7 +154,7 @@ void ParameterPool::setParameterValue(const std::string& name, double value) } } -//! Sets parameter value. +//! Sets value of the nonzero parameters that match _pattern_ ('*' allowed), or throws. int ParameterPool::setMatchedParametersValue(const std::string& pattern, double value) { @@ -170,6 +170,15 @@ int ParameterPool::setMatchedParametersValue(const std::string& pattern, double return npars; } +//! Sets value of the one parameter that matches _pattern_ ('*' allowed), or throws. + +void ParameterPool::setUniqueMatchValue(const std::string& pattern, double value) +{ + if (setMatchedParametersValue(pattern, value) != 1) + throw Exceptions::RuntimeErrorException( + "ParameterPool::setUniqueMatchValue: pattern '"+pattern+"' is not unique"); +} + std::vector<std::string> ParameterPool::getParameterNames() const { std::vector<std::string> result; diff --git a/Core/Parametrization/ParameterPool.h b/Core/Parametrization/ParameterPool.h index 5a20d5930b3a681a758142e72998e1432eaff4f0..34074790065f5055da644d9f1775d43de89788ae 100644 --- a/Core/Parametrization/ParameterPool.h +++ b/Core/Parametrization/ParameterPool.h @@ -69,6 +69,7 @@ public: void setParameterValue(const std::string& name, double value); int setMatchedParametersValue(const std::string& wildcards, double value); + void setUniqueMatchValue(const std::string& pattern, double value); std::vector<std::string> getParameterNames() const; diff --git a/Core/Particle/ParticleDistribution.cpp b/Core/Particle/ParticleDistribution.cpp index 096365499c32e64649dc21fbda5a8dd1c486837d..f0d78c269f2d87625491f843605e1bbcdd87c7d9 100644 --- a/Core/Particle/ParticleDistribution.cpp +++ b/Core/Particle/ParticleDistribution.cpp @@ -45,11 +45,6 @@ ParticleDistribution* ParticleDistribution::cloneInvertB() const "cloneInvertB: should never be called"); } -void ParticleDistribution::accept(ISampleVisitor* visitor) const -{ - visitor->visit(this); -} - std::string ParticleDistribution::to_str(int indent) const { std::stringstream ss; @@ -68,53 +63,31 @@ const IMaterial* ParticleDistribution::getAmbientMaterial() const return mP_particle->getAmbientMaterial(); } -//! Initializes list of new particles generated according to a distribution. +//! Returns particle clones with parameter values drawn from distribution. + std::vector<const IParticle*> ParticleDistribution::generateParticles() const { - std::unique_ptr<ParameterPool> P_pool(createDistributedParameterPool()); + std::unique_ptr<ParameterPool> P_pool {mP_particle->createParameterTree()}; std::string main_par_name = m_par_distribution.getMainParameterName(); - RealParameter* main_par = P_pool->getUniqueMatch(main_par_name); - double main_par_value = main_par->getValue(); - std::vector<std::string> linked_par_names = m_par_distribution.getLinkedParameterNames(); - std::map<std::string, double> linked_par_ratio_map; - for (const std::string& name: linked_par_names) { - RealParameter* linked_par = P_pool->getUniqueMatch(name); - double linked_par_value = linked_par->getValue(); - double linked_ratio = main_par_value == 0 ? 1.0 : linked_par_value / main_par_value; - linked_par_ratio_map[name] = linked_ratio; - } + double main_par_value = P_pool->getUniqueMatch(main_par_name)->getValue(); + + // Preset link ratios: + std::map<std::string, double> linked_ratios; + for (const std::string& name: m_par_distribution.getLinkedParameterNames()) + linked_ratios[name] = main_par_value == 0 ? 1.0 : + P_pool->getUniqueMatch(name)->getValue() / main_par_value; + + // Draw distribution samples; for each sample, create one particle clone: std::vector<ParameterSample> main_par_samples = m_par_distribution.generateSamples(); std::vector<const IParticle*> result; for (const ParameterSample& main_sample: main_par_samples ) { - double particle_abundance = getAbundance() * main_sample.weight; IParticle* p_particle_clone = mP_particle->clone(); - std::unique_ptr<ParameterPool> P_new_pool(p_particle_clone->createParameterTree()); - int changed = P_new_pool->setMatchedParametersValue(main_par_name, main_sample.value); - if (changed != 1) - throw Exceptions::RuntimeErrorException( - "ParticleDistribution::generateParticles: " - "main parameter name matches nothing or more than one parameter"); - for (std::map<std::string, double>::const_iterator it = linked_par_ratio_map.begin(); - it != linked_par_ratio_map.end(); ++it) { - double new_linked_value = main_sample.value * it->second; - changed = P_new_pool->setMatchedParametersValue(it->first, new_linked_value); - if (changed != 1) - throw Exceptions::RuntimeErrorException( - "ParticleDistribution::generateParticles: " - "linked parameter name matches nothing or more than one parameter"); - } - p_particle_clone->setAbundance(particle_abundance); + std::unique_ptr<ParameterPool> P_new_pool {p_particle_clone->createParameterTree()}; + P_new_pool->setUniqueMatchValue(main_par_name, main_sample.value); + for (auto it = linked_ratios.begin(); it != linked_ratios.end(); ++it) + P_new_pool->setUniqueMatchValue(it->first, main_sample.value * it->second); + p_particle_clone->setAbundance(getAbundance() * main_sample.weight); result.push_back(p_particle_clone); } return result; } - -ParameterPool* ParticleDistribution::createDistributedParameterPool() const -{ - return mP_particle->createParameterTree(); -} - -const IParticle* ParticleDistribution::getParticle() const -{ - return mP_particle.get(); -} diff --git a/Core/Particle/ParticleDistribution.h b/Core/Particle/ParticleDistribution.h index 42a9c1740a0eee710aacfbf4f3295934ef476356..3316bd5e4347cea212a5b70426ef9ff430a76e80 100644 --- a/Core/Particle/ParticleDistribution.h +++ b/Core/Particle/ParticleDistribution.h @@ -32,7 +32,7 @@ public: virtual ParticleDistribution* clone() const; virtual ParticleDistribution* cloneInvertB() const; - virtual void accept(ISampleVisitor* visitor) const; + void accept(ISampleVisitor* visitor) const override final { visitor->visit(this); } //! Returns textual representation of *this and its descendants. virtual std::string to_str(int indent=0) const; @@ -49,11 +49,8 @@ public: //! Returns the distributed parameter data ParameterDistribution getParameterDistribution() const { return m_par_distribution; } - //! Returns the parameter pool that can be used for parameter distributions - ParameterPool* createDistributedParameterPool() const; - //! Returns particle. - const IParticle* getParticle() const; + const IParticle* getParticle() const { return mP_particle.get(); } private: std::unique_ptr<IParticle> mP_particle; diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py index 7d42c5be601c70b1ba457c8ab1f416cf46dbea66..2d4d797c310f61442802ce3fbc9119382fe59504 100644 --- a/auto/Wrap/libBornAgainCore.py +++ b/auto/Wrap/libBornAgainCore.py @@ -22483,6 +22483,11 @@ class ParameterPool(_object): return _libBornAgainCore.ParameterPool_setMatchedParametersValue(self, wildcards, value) + def setUniqueMatchValue(self, pattern, value): + """setUniqueMatchValue(ParameterPool self, std::string const & pattern, double value)""" + return _libBornAgainCore.ParameterPool_setUniqueMatchValue(self, pattern, value) + + def getParameterNames(self): """ getParameterNames(ParameterPool self) -> vector_string_t @@ -23103,18 +23108,6 @@ class ParticleDistribution(IAbstractParticle): return _libBornAgainCore.ParticleDistribution_getParameterDistribution(self) - def createDistributedParameterPool(self): - """ - createDistributedParameterPool(ParticleDistribution self) -> ParameterPool - - ParameterPool * ParticleDistribution::createDistributedParameterPool() const - - Returns the parameter pool that can be used for parameter distributions. - - """ - return _libBornAgainCore.ParticleDistribution_createDistributedParameterPool(self) - - def getParticle(self): """ getParticle(ParticleDistribution self) -> IParticle diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp index 0c9cbd8d25f7e0f9f38ed2ae73c1a77f83962056..b07ae3b2078836926fb1e3a644fa229a392431a8 100644 --- a/auto/Wrap/libBornAgainCore_wrap.cpp +++ b/auto/Wrap/libBornAgainCore_wrap.cpp @@ -92792,6 +92792,52 @@ fail: } +SWIGINTERN PyObject *_wrap_ParameterPool_setUniqueMatchValue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + ParameterPool *arg1 = (ParameterPool *) 0 ; + std::string *arg2 = 0 ; + double arg3 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 = SWIG_OLDOBJ ; + double val3 ; + int ecode3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OOO:ParameterPool_setUniqueMatchValue",&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ParameterPool, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ParameterPool_setUniqueMatchValue" "', argument " "1"" of type '" "ParameterPool *""'"); + } + arg1 = reinterpret_cast< ParameterPool * >(argp1); + { + std::string *ptr = (std::string *)0; + res2 = SWIG_AsPtr_std_string(obj1, &ptr); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ParameterPool_setUniqueMatchValue" "', argument " "2"" of type '" "std::string const &""'"); + } + if (!ptr) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ParameterPool_setUniqueMatchValue" "', argument " "2"" of type '" "std::string const &""'"); + } + arg2 = ptr; + } + ecode3 = SWIG_AsVal_double(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ParameterPool_setUniqueMatchValue" "', argument " "3"" of type '" "double""'"); + } + arg3 = static_cast< double >(val3); + (arg1)->setUniqueMatchValue((std::string const &)*arg2,arg3); + resultobj = SWIG_Py_Void(); + if (SWIG_IsNewObj(res2)) delete arg2; + return resultobj; +fail: + if (SWIG_IsNewObj(res2)) delete arg2; + return NULL; +} + + SWIGINTERN PyObject *_wrap_ParameterPool_getParameterNames(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; ParameterPool *arg1 = (ParameterPool *) 0 ; @@ -94814,28 +94860,6 @@ fail: } -SWIGINTERN PyObject *_wrap_ParticleDistribution_createDistributedParameterPool(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - ParticleDistribution *arg1 = (ParticleDistribution *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - ParameterPool *result = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:ParticleDistribution_createDistributedParameterPool",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ParticleDistribution, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ParticleDistribution_createDistributedParameterPool" "', argument " "1"" of type '" "ParticleDistribution const *""'"); - } - arg1 = reinterpret_cast< ParticleDistribution * >(argp1); - result = (ParameterPool *)((ParticleDistribution const *)arg1)->createDistributedParameterPool(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ParameterPool, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *_wrap_ParticleDistribution_getParticle(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; ParticleDistribution *arg1 = (ParticleDistribution *) 0 ; @@ -111947,6 +111971,7 @@ static PyMethodDef SwigMethods[] = { "Sets parameter value. \n" "\n" ""}, + { (char *)"ParameterPool_setUniqueMatchValue", _wrap_ParameterPool_setUniqueMatchValue, METH_VARARGS, (char *)"ParameterPool_setUniqueMatchValue(ParameterPool self, std::string const & pattern, double value)"}, { (char *)"ParameterPool_getParameterNames", _wrap_ParameterPool_getParameterNames, METH_VARARGS, (char *)"\n" "ParameterPool_getParameterNames(ParameterPool self) -> vector_string_t\n" "\n" @@ -112302,14 +112327,6 @@ static PyMethodDef SwigMethods[] = { "Returns the distributed parameter data. \n" "\n" ""}, - { (char *)"ParticleDistribution_createDistributedParameterPool", _wrap_ParticleDistribution_createDistributedParameterPool, METH_VARARGS, (char *)"\n" - "ParticleDistribution_createDistributedParameterPool(ParticleDistribution self) -> ParameterPool\n" - "\n" - "ParameterPool * ParticleDistribution::createDistributedParameterPool() const\n" - "\n" - "Returns the parameter pool that can be used for parameter distributions. \n" - "\n" - ""}, { (char *)"ParticleDistribution_getParticle", _wrap_ParticleDistribution_getParticle, METH_VARARGS, (char *)"\n" "ParticleDistribution_getParticle(ParticleDistribution self) -> IParticle\n" "\n"