From fdf7af4b3067762d476d9fd6814218b3174961c4 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 19 Dec 2022 12:33:53 +0100 Subject: [PATCH] provide way to scale reflectometry simulation ex post; use it in RealLifeReflectometryFitting.py --- Device/Data/Datafield.cpp | 11 +-- Device/Data/Datafield.h | 5 +- Device/Histo/SimulationResult.cpp | 6 -- Device/Histo/SimulationResult.h | 4 +- .../specular/RealLifeReflectometryFitting.py | 6 +- auto/Wrap/libBornAgainDevice.py | 16 ++-- auto/Wrap/libBornAgainDevice_wrap.cpp | 92 ++++++++++--------- 7 files changed, 70 insertions(+), 70 deletions(-) diff --git a/Device/Data/Datafield.cpp b/Device/Data/Datafield.cpp index fd2be8c9c2f..ab4bfbe494b 100644 --- a/Device/Data/Datafield.cpp +++ b/Device/Data/Datafield.cpp @@ -156,15 +156,14 @@ std::vector<double> Datafield::flatVector() const return result; } -Datafield* Datafield::normalizedToMaximum() const +void Datafield::scale(double factor) { - double maxval = maxVal(); - ASSERT(maxval > 0); - std::vector<double> out(frame().size()); for (size_t i = 0; i < frame().size(); ++i) - out[i] = m_values[i] / maxval; + m_values[i] *= factor; - return new Datafield(m_frame->cloned_axes(), out); + if (!m_errSigmas.empty()) + for (size_t i = 0; i < frame().size(); ++i) + m_errSigmas[i] *= factor; } double Datafield::maxVal() const diff --git a/Device/Data/Datafield.h b/Device/Data/Datafield.h index f5428941dcc..7737e149e2a 100644 --- a/Device/Data/Datafield.h +++ b/Device/Data/Datafield.h @@ -81,6 +81,9 @@ public: //! ied accessor (const) const double& operator[](size_t i) const { return m_values[i]; } + //! Multiplies contents by constant factor + void scale(double factor); + // helpers //! Returns true if object have same dimensions and number of axes bins @@ -97,8 +100,6 @@ public: PyObject* npArray() const; #endif - Datafield* normalizedToMaximum() const; - //! Project a 2D histogram into 1D histogram along X. The projection is made //! from all bins along y-axis. Datafield* xProjection() const; diff --git a/Device/Histo/SimulationResult.cpp b/Device/Histo/SimulationResult.cpp index 653582ee20a..9e0368af47d 100644 --- a/Device/Histo/SimulationResult.cpp +++ b/Device/Histo/SimulationResult.cpp @@ -103,12 +103,6 @@ const double& SimulationResult::operator[](size_t i) const return (*m_data)[i]; } -SimulationResult SimulationResult::relativeToMaximum() const -{ - std::unique_ptr<Datafield> data2(m_data->normalizedToMaximum()); - return {*data2, m_coordsys->clone()}; -} - #ifdef BORNAGAIN_PYTHON PyObject* SimulationResult::array(Coords units) const { diff --git a/Device/Histo/SimulationResult.h b/Device/Histo/SimulationResult.h index 079ef64c778..5f856f28fc4 100644 --- a/Device/Histo/SimulationResult.h +++ b/Device/Histo/SimulationResult.h @@ -51,15 +51,13 @@ public: const ICoordSystem& converter() const; //! Data element access + Datafield& data_field() { return *m_data; } // TODO disambiguate name from datafield() size_t rank() const; double& operator[](size_t i); const double& operator[](size_t i) const; size_t size() const; bool empty() const { return size() == 0; } - //! Returns modified SimulationResult: all intensities dvided by maximum intensity - SimulationResult relativeToMaximum() const; - //! Returns intensity data as Python numpy array #ifdef BORNAGAIN_PYTHON PyObject* array(Coords units = Coords::UNDEFINED) const; diff --git a/Examples/fit/specular/RealLifeReflectometryFitting.py b/Examples/fit/specular/RealLifeReflectometryFitting.py index c9229d7bc81..c2f77907fbd 100755 --- a/Examples/fit/specular/RealLifeReflectometryFitting.py +++ b/Examples/fit/specular/RealLifeReflectometryFitting.py @@ -101,7 +101,6 @@ def create_simulation(sample, arg_dict, bin_start, bin_end): scan.setFootprintFactor(footprint) simulation = ba.SpecularSimulation(scan, sample) - simulation.beam().setIntensity(arg_dict["intensity"]) return simulation @@ -141,7 +140,10 @@ def run_simulation(arg_dict, bin_start=0, bin_end=-1): sample = buildSample(arg_dict) simulation = create_simulation(sample, arg_dict, bin_start, bin_end) - return simulation.simulate() + result = simulation.simulate() + result.data_field().scale(arg_dict["intensity"]) + + return result def chi_2(real_data, sim_data, weights): diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py index f5f2313d370..97ea1d4b488 100644 --- a/auto/Wrap/libBornAgainDevice.py +++ b/auto/Wrap/libBornAgainDevice.py @@ -2108,6 +2108,10 @@ class Datafield(object): r"""setVector(Datafield self, vdouble1d_t data_vector)""" return _libBornAgainDevice.Datafield_setVector(self, data_vector) + def scale(self, factor): + r"""scale(Datafield self, double factor)""" + return _libBornAgainDevice.Datafield_scale(self, factor) + def hasSameSizes(self, other): r"""hasSameSizes(Datafield self, Datafield other) -> bool""" return _libBornAgainDevice.Datafield_hasSameSizes(self, other) @@ -2127,10 +2131,6 @@ class Datafield(object): r"""npArray(Datafield self) -> PyObject *""" return _libBornAgainDevice.Datafield_npArray(self) - def normalizedToMaximum(self): - r"""normalizedToMaximum(Datafield self) -> Datafield""" - return _libBornAgainDevice.Datafield_normalizedToMaximum(self) - def xProjection(self, *args): r""" xProjection(Datafield self) -> Datafield @@ -3127,6 +3127,10 @@ class SimulationResult(object): r"""converter(SimulationResult self) -> ICoordSystem const &""" return _libBornAgainDevice.SimulationResult_converter(self) + def data_field(self): + r"""data_field(SimulationResult self) -> Datafield""" + return _libBornAgainDevice.SimulationResult_data_field(self) + def rank(self): r"""rank(SimulationResult self) -> size_t""" return _libBornAgainDevice.SimulationResult_rank(self) @@ -3139,10 +3143,6 @@ class SimulationResult(object): r"""empty(SimulationResult self) -> bool""" return _libBornAgainDevice.SimulationResult_empty(self) - def relativeToMaximum(self): - r"""relativeToMaximum(SimulationResult self) -> SimulationResult""" - return _libBornAgainDevice.SimulationResult_relativeToMaximum(self) - def array(self, *args): r"""array(SimulationResult self, Coords units=UNDEFINED) -> PyObject""" return _libBornAgainDevice.SimulationResult_array(self, *args) diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp index 1d004526aa7..68e56e1740d 100644 --- a/auto/Wrap/libBornAgainDevice_wrap.cpp +++ b/auto/Wrap/libBornAgainDevice_wrap.cpp @@ -28018,6 +28018,35 @@ fail: } +SWIGINTERN PyObject *_wrap_Datafield_scale(PyObject *self, PyObject *args) { + PyObject *resultobj = 0; + Datafield *arg1 = (Datafield *) 0 ; + double arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + double val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + if (!SWIG_Python_UnpackTuple(args, "Datafield_scale", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Datafield, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Datafield_scale" "', argument " "1"" of type '" "Datafield *""'"); + } + arg1 = reinterpret_cast< Datafield * >(argp1); + ecode2 = SWIG_AsVal_double(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Datafield_scale" "', argument " "2"" of type '" "double""'"); + } + arg2 = static_cast< double >(val2); + (arg1)->scale(arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_Datafield_hasSameSizes(PyObject *self, PyObject *args) { PyObject *resultobj = 0; Datafield *arg1 = (Datafield *) 0 ; @@ -28269,29 +28298,6 @@ fail: } -SWIGINTERN PyObject *_wrap_Datafield_normalizedToMaximum(PyObject *self, PyObject *args) { - PyObject *resultobj = 0; - Datafield *arg1 = (Datafield *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - Datafield *result = 0 ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Datafield, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Datafield_normalizedToMaximum" "', argument " "1"" of type '" "Datafield const *""'"); - } - arg1 = reinterpret_cast< Datafield * >(argp1); - result = (Datafield *)((Datafield const *)arg1)->normalizedToMaximum(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Datafield, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *_wrap_Datafield_xProjection__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) { PyObject *resultobj = 0; Datafield *arg1 = (Datafield *) 0 ; @@ -37131,30 +37137,30 @@ fail: } -SWIGINTERN PyObject *_wrap_SimulationResult_rank(PyObject *self, PyObject *args) { +SWIGINTERN PyObject *_wrap_SimulationResult_data_field(PyObject *self, PyObject *args) { PyObject *resultobj = 0; SimulationResult *arg1 = (SimulationResult *) 0 ; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; - size_t result; + Datafield *result = 0 ; if (!args) SWIG_fail; swig_obj[0] = args; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_SimulationResult, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_rank" "', argument " "1"" of type '" "SimulationResult const *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_data_field" "', argument " "1"" of type '" "SimulationResult *""'"); } arg1 = reinterpret_cast< SimulationResult * >(argp1); - result = ((SimulationResult const *)arg1)->rank(); - resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + result = (Datafield *) &(arg1)->data_field(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Datafield, 0 | 0 ); return resultobj; fail: return NULL; } -SWIGINTERN PyObject *_wrap_SimulationResult_size(PyObject *self, PyObject *args) { +SWIGINTERN PyObject *_wrap_SimulationResult_rank(PyObject *self, PyObject *args) { PyObject *resultobj = 0; SimulationResult *arg1 = (SimulationResult *) 0 ; void *argp1 = 0 ; @@ -37166,10 +37172,10 @@ SWIGINTERN PyObject *_wrap_SimulationResult_size(PyObject *self, PyObject *args) swig_obj[0] = args; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_SimulationResult, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_size" "', argument " "1"" of type '" "SimulationResult const *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_rank" "', argument " "1"" of type '" "SimulationResult const *""'"); } arg1 = reinterpret_cast< SimulationResult * >(argp1); - result = ((SimulationResult const *)arg1)->size(); + result = ((SimulationResult const *)arg1)->rank(); resultobj = SWIG_From_size_t(static_cast< size_t >(result)); return resultobj; fail: @@ -37177,46 +37183,46 @@ fail: } -SWIGINTERN PyObject *_wrap_SimulationResult_empty(PyObject *self, PyObject *args) { +SWIGINTERN PyObject *_wrap_SimulationResult_size(PyObject *self, PyObject *args) { PyObject *resultobj = 0; SimulationResult *arg1 = (SimulationResult *) 0 ; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; - bool result; + size_t result; if (!args) SWIG_fail; swig_obj[0] = args; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_SimulationResult, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_empty" "', argument " "1"" of type '" "SimulationResult const *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_size" "', argument " "1"" of type '" "SimulationResult const *""'"); } arg1 = reinterpret_cast< SimulationResult * >(argp1); - result = (bool)((SimulationResult const *)arg1)->empty(); - resultobj = SWIG_From_bool(static_cast< bool >(result)); + result = ((SimulationResult const *)arg1)->size(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); return resultobj; fail: return NULL; } -SWIGINTERN PyObject *_wrap_SimulationResult_relativeToMaximum(PyObject *self, PyObject *args) { +SWIGINTERN PyObject *_wrap_SimulationResult_empty(PyObject *self, PyObject *args) { PyObject *resultobj = 0; SimulationResult *arg1 = (SimulationResult *) 0 ; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; - SimulationResult result; + bool result; if (!args) SWIG_fail; swig_obj[0] = args; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_SimulationResult, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_relativeToMaximum" "', argument " "1"" of type '" "SimulationResult const *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationResult_empty" "', argument " "1"" of type '" "SimulationResult const *""'"); } arg1 = reinterpret_cast< SimulationResult * >(argp1); - result = ((SimulationResult const *)arg1)->relativeToMaximum(); - resultobj = SWIG_NewPointerObj((new SimulationResult(result)), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN | 0 ); + result = (bool)((SimulationResult const *)arg1)->empty(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); return resultobj; fail: return NULL; @@ -38297,6 +38303,7 @@ static PyMethodDef SwigMethods[] = { { "Datafield_minVal", _wrap_Datafield_minVal, METH_O, "Datafield_minVal(Datafield self) -> double"}, { "Datafield_setAllTo", _wrap_Datafield_setAllTo, METH_VARARGS, "Datafield_setAllTo(Datafield self, double const & value)"}, { "Datafield_setVector", _wrap_Datafield_setVector, METH_VARARGS, "Datafield_setVector(Datafield self, vdouble1d_t data_vector)"}, + { "Datafield_scale", _wrap_Datafield_scale, METH_VARARGS, "Datafield_scale(Datafield self, double factor)"}, { "Datafield_hasSameSizes", _wrap_Datafield_hasSameSizes, METH_VARARGS, "Datafield_hasSameSizes(Datafield self, Datafield other) -> bool"}, { "Datafield_hasSameShape", _wrap_Datafield_hasSameShape, METH_VARARGS, "Datafield_hasSameShape(Datafield self, Datafield other) -> bool"}, { "Datafield_crop", _wrap_Datafield_crop, METH_VARARGS, "\n" @@ -38304,7 +38311,6 @@ static PyMethodDef SwigMethods[] = { "Datafield_crop(Datafield self, double xmin, double xmax) -> Datafield\n" ""}, { "Datafield_npArray", _wrap_Datafield_npArray, METH_O, "Datafield_npArray(Datafield self) -> PyObject *"}, - { "Datafield_normalizedToMaximum", _wrap_Datafield_normalizedToMaximum, METH_O, "Datafield_normalizedToMaximum(Datafield self) -> Datafield"}, { "Datafield_xProjection", _wrap_Datafield_xProjection, METH_VARARGS, "\n" "Datafield_xProjection(Datafield self) -> Datafield\n" "Datafield_xProjection(Datafield self, double yvalue) -> Datafield\n" @@ -38599,10 +38605,10 @@ static PyMethodDef SwigMethods[] = { { "SimulationResult_axisMinMax", _wrap_SimulationResult_axisMinMax, METH_VARARGS, "SimulationResult_axisMinMax(SimulationResult self, size_t i, Coords units=UNDEFINED) -> pvacuum_double_t"}, { "SimulationResult_axisName", _wrap_SimulationResult_axisName, METH_VARARGS, "SimulationResult_axisName(SimulationResult self, size_t i, Coords units=UNDEFINED) -> std::string"}, { "SimulationResult_converter", _wrap_SimulationResult_converter, METH_O, "SimulationResult_converter(SimulationResult self) -> ICoordSystem const &"}, + { "SimulationResult_data_field", _wrap_SimulationResult_data_field, METH_O, "SimulationResult_data_field(SimulationResult self) -> Datafield"}, { "SimulationResult_rank", _wrap_SimulationResult_rank, METH_O, "SimulationResult_rank(SimulationResult self) -> size_t"}, { "SimulationResult_size", _wrap_SimulationResult_size, METH_O, "SimulationResult_size(SimulationResult self) -> size_t"}, { "SimulationResult_empty", _wrap_SimulationResult_empty, METH_O, "SimulationResult_empty(SimulationResult self) -> bool"}, - { "SimulationResult_relativeToMaximum", _wrap_SimulationResult_relativeToMaximum, METH_O, "SimulationResult_relativeToMaximum(SimulationResult self) -> SimulationResult"}, { "SimulationResult_array", _wrap_SimulationResult_array, METH_VARARGS, "SimulationResult_array(SimulationResult self, Coords units=UNDEFINED) -> PyObject"}, { "SimulationResult_convertedBinCenters", _wrap_SimulationResult_convertedBinCenters, METH_VARARGS, "\n" "SimulationResult_convertedBinCenters(SimulationResult self, Coords units=UNDEFINED) -> vdouble1d_t\n" -- GitLab