diff --git a/Core/Fitting/FitObjective.cpp b/Core/Fitting/FitObjective.cpp index c28dfdea5270cd2fef3dd6a2d5f0ab76268f4c4c..f5bc4a1bd1824c3da620c32c29a5fae4b303712e 100644 --- a/Core/Fitting/FitObjective.cpp +++ b/Core/Fitting/FitObjective.cpp @@ -112,6 +112,21 @@ size_t FitObjective::numberOfIterations() const return m_iteration_count; } +SimulationResult FitObjective::simulationResult(size_t i_item) const +{ + return m_fit_objects[check_index(i_item)]->simulationResult(); +} + +SimulationResult FitObjective::experimentalData(size_t i_item) const +{ + return m_fit_objects[check_index(i_item)]->experimentalData(); +} + +SimulationResult FitObjective::relativeDifference(size_t i_item) const +{ + return m_fit_objects[check_index(i_item)]->relativeDifference(); +} + void FitObjective::run_simulations(const Fit::Parameters& params) { if (m_fit_objects.empty()) @@ -132,3 +147,10 @@ double FitObjective::residual(double a, double b, double weight) const { return m_chi2_module->residual(a, b, weight); } + +size_t FitObjective::check_index(size_t index) const +{ + if (index >= m_fit_objects.size()) + throw std::runtime_error("FitObjective::check_index() -> Index outside of range"); + return index; +} diff --git a/Core/Fitting/FitObjective.h b/Core/Fitting/FitObjective.h index 1b1e14cb4750489502dbb37e20342bda2698d386..15f02f9c484db317e72b480c307df5fadec12cec 100644 --- a/Core/Fitting/FitObjective.h +++ b/Core/Fitting/FitObjective.h @@ -65,9 +65,22 @@ public: //! Returns current number of simulation runs. size_t numberOfIterations() const; + //! Returns simulation result. + //! @param i_item: the index of fit pair + SimulationResult simulationResult(size_t i_item = 0) const; + + //! Returns experimental data. + //! @param i_item: the index of fit pair + SimulationResult experimentalData(size_t i_item = 0) const; + + //! Returns relative difference between simulation and experimental data. + //! @param i_item: the index of fit pair + SimulationResult relativeDifference(size_t i_item = 0) const; + private: void run_simulations(const Fit::Parameters& params); double residual(double a, double b, double weight) const; + size_t check_index(size_t index) const; std::vector<double> m_experimental_array; std::vector<double> m_simulation_array; diff --git a/Core/Fitting/SimDataPair.cpp b/Core/Fitting/SimDataPair.cpp index 59352a749017db51461fa50c0abd2d643c9800b5..85b799093980bd1c90b228d1f2427d78408a31ab 100644 --- a/Core/Fitting/SimDataPair.cpp +++ b/Core/Fitting/SimDataPair.cpp @@ -15,6 +15,8 @@ #include "SimDataPair.h" #include "Simulation.h" #include "IntensityDataFunctions.h" +#include "UnitConverterUtils.h" +#include "Numeric.h" static_assert(std::is_copy_constructible<SimDataPair>::value == false, "SimDataPair should not be copy constructable"); @@ -68,6 +70,23 @@ SimulationResult SimDataPair::experimentalData() const return m_experimental_data; } +//! Returns relative difference between simulation and experimental data. + +SimulationResult SimDataPair::relativeDifference() const +{ + auto converter = UnitConverterUtils::createConverter(*m_simulation); + auto roi_data = UnitConverterUtils::createOutputData(*converter.get(), converter->defaultUnits()); + auto detector = m_simulation->getInstrument().getDetector(); + + detector->iterate([&](IDetector::const_iterator it){ + const size_t index = it.roiIndex(); + (*roi_data)[index] = Numeric::get_relative_difference( + m_simulation_result[index], m_experimental_data[index]); + }); + + return SimulationResult(*roi_data, *converter); +} + SimDataPair::~SimDataPair() = default; void SimDataPair::runSimulation(const Fit::Parameters& params) diff --git a/Core/Fitting/SimDataPair.h b/Core/Fitting/SimDataPair.h index 67d488bfbb81693f53354adbf7051b7e64df0dc8..ee903fbb7c777a3b70058d3708d8708b72334509 100644 --- a/Core/Fitting/SimDataPair.h +++ b/Core/Fitting/SimDataPair.h @@ -39,6 +39,8 @@ public: SimulationResult experimentalData() const; + SimulationResult relativeDifference() const; + void runSimulation(const Fit::Parameters& params); std::vector<double> experimental_array() const; diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py index 4e3bdb5fe3a97f10f51f1a60fad403e94b3cc6d6..344fbac8afe50940a44d1fc76c2f3f6ac209098b 100644 --- a/auto/Wrap/libBornAgainCore.py +++ b/auto/Wrap/libBornAgainCore.py @@ -7609,6 +7609,35 @@ class FitObjective(_object): return _libBornAgainCore.FitObjective_simulation_array(self) + def numberOfIterations(self): + """numberOfIterations(FitObjective self) -> size_t""" + return _libBornAgainCore.FitObjective_numberOfIterations(self) + + + def simulationResult(self, i_item=0): + """ + simulationResult(FitObjective self, size_t i_item=0) -> SimulationResult + simulationResult(FitObjective self) -> SimulationResult + """ + return _libBornAgainCore.FitObjective_simulationResult(self, i_item) + + + def experimentalData(self, i_item=0): + """ + experimentalData(FitObjective self, size_t i_item=0) -> SimulationResult + experimentalData(FitObjective self) -> SimulationResult + """ + return _libBornAgainCore.FitObjective_experimentalData(self, i_item) + + + def relativeDifference(self, i_item=0): + """ + relativeDifference(FitObjective self, size_t i_item=0) -> SimulationResult + relativeDifference(FitObjective self) -> SimulationResult + """ + return _libBornAgainCore.FitObjective_relativeDifference(self, i_item) + + def addSimulationAndData(self, callback, data, weight): self.wrp = SimulationBuilderWrapper(callback) return self.addSimulationAndData_cpp(self.wrp, data, weight) diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp index ebb212508aefc16a6c12ee742853f5be5f0ec69e..442480ab47170eb9617a357a8d80788e1bc99b80 100644 --- a/auto/Wrap/libBornAgainCore_wrap.cpp +++ b/auto/Wrap/libBornAgainCore_wrap.cpp @@ -50946,6 +50946,325 @@ fail: } +SWIGINTERN PyObject *_wrap_FitObjective_numberOfIterations(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + FitObjective *arg1 = (FitObjective *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + size_t result; + + if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_numberOfIterations",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_numberOfIterations" "', argument " "1"" of type '" "FitObjective const *""'"); + } + arg1 = reinterpret_cast< FitObjective * >(argp1); + result = ((FitObjective const *)arg1)->numberOfIterations(); + resultobj = SWIG_From_size_t(static_cast< size_t >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_simulationResult__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + FitObjective *arg1 = (FitObjective *) 0 ; + size_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + SimulationResult result; + + if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_simulationResult",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulationResult" "', argument " "1"" of type '" "FitObjective const *""'"); + } + arg1 = reinterpret_cast< FitObjective * >(argp1); + ecode2 = SWIG_AsVal_size_t(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_simulationResult" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = static_cast< size_t >(val2); + result = ((FitObjective const *)arg1)->simulationResult(arg2); + resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_simulationResult__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + FitObjective *arg1 = (FitObjective *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + SimulationResult result; + + if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_simulationResult",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulationResult" "', argument " "1"" of type '" "FitObjective const *""'"); + } + arg1 = reinterpret_cast< FitObjective * >(argp1); + result = ((FitObjective const *)arg1)->simulationResult(); + resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_simulationResult(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + Py_ssize_t ii; + + if (!PyTuple_Check(args)) SWIG_fail; + argc = args ? PyObject_Length(args) : 0; + for (ii = 0; (ii < 2) && (ii < argc); ii++) { + argv[ii] = PyTuple_GET_ITEM(args,ii); + } + if (argc == 1) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_FitObjective_simulationResult__SWIG_1(self, args); + } + } + if (argc == 2) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_FitObjective_simulationResult__SWIG_0(self, args); + } + } + } + +fail: + SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_simulationResult'.\n" + " Possible C/C++ prototypes are:\n" + " FitObjective::simulationResult(size_t) const\n" + " FitObjective::simulationResult() const\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_experimentalData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + FitObjective *arg1 = (FitObjective *) 0 ; + size_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + SimulationResult result; + + if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_experimentalData",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimentalData" "', argument " "1"" of type '" "FitObjective const *""'"); + } + arg1 = reinterpret_cast< FitObjective * >(argp1); + ecode2 = SWIG_AsVal_size_t(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_experimentalData" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = static_cast< size_t >(val2); + result = ((FitObjective const *)arg1)->experimentalData(arg2); + resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_experimentalData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + FitObjective *arg1 = (FitObjective *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + SimulationResult result; + + if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_experimentalData",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimentalData" "', argument " "1"" of type '" "FitObjective const *""'"); + } + arg1 = reinterpret_cast< FitObjective * >(argp1); + result = ((FitObjective const *)arg1)->experimentalData(); + resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_experimentalData(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + Py_ssize_t ii; + + if (!PyTuple_Check(args)) SWIG_fail; + argc = args ? PyObject_Length(args) : 0; + for (ii = 0; (ii < 2) && (ii < argc); ii++) { + argv[ii] = PyTuple_GET_ITEM(args,ii); + } + if (argc == 1) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_FitObjective_experimentalData__SWIG_1(self, args); + } + } + if (argc == 2) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_FitObjective_experimentalData__SWIG_0(self, args); + } + } + } + +fail: + SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_experimentalData'.\n" + " Possible C/C++ prototypes are:\n" + " FitObjective::experimentalData(size_t) const\n" + " FitObjective::experimentalData() const\n"); + return 0; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + FitObjective *arg1 = (FitObjective *) 0 ; + size_t arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + SimulationResult result; + + if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_relativeDifference",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_relativeDifference" "', argument " "1"" of type '" "FitObjective const *""'"); + } + arg1 = reinterpret_cast< FitObjective * >(argp1); + ecode2 = SWIG_AsVal_size_t(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_relativeDifference" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = static_cast< size_t >(val2); + result = ((FitObjective const *)arg1)->relativeDifference(arg2); + resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + FitObjective *arg1 = (FitObjective *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + SimulationResult result; + + if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_relativeDifference",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_relativeDifference" "', argument " "1"" of type '" "FitObjective const *""'"); + } + arg1 = reinterpret_cast< FitObjective * >(argp1); + result = ((FitObjective const *)arg1)->relativeDifference(); + resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference(PyObject *self, PyObject *args) { + Py_ssize_t argc; + PyObject *argv[3] = { + 0 + }; + Py_ssize_t ii; + + if (!PyTuple_Check(args)) SWIG_fail; + argc = args ? PyObject_Length(args) : 0; + for (ii = 0; (ii < 2) && (ii < argc); ii++) { + argv[ii] = PyTuple_GET_ITEM(args,ii); + } + if (argc == 1) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0); + _v = SWIG_CheckState(res); + if (_v) { + return _wrap_FitObjective_relativeDifference__SWIG_1(self, args); + } + } + if (argc == 2) { + int _v; + void *vptr = 0; + int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_size_t(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_FitObjective_relativeDifference__SWIG_0(self, args); + } + } + } + +fail: + SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_relativeDifference'.\n" + " Possible C/C++ prototypes are:\n" + " FitObjective::relativeDifference(size_t) const\n" + " FitObjective::relativeDifference() const\n"); + return 0; +} + + SWIGINTERN PyObject *FitObjective_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL; @@ -124326,6 +124645,19 @@ static PyMethodDef SwigMethods[] = { { (char *)"FitObjective_numberOfFitElements", _wrap_FitObjective_numberOfFitElements, METH_VARARGS, (char *)"FitObjective_numberOfFitElements(FitObjective self) -> size_t"}, { (char *)"FitObjective_experimental_array", _wrap_FitObjective_experimental_array, METH_VARARGS, (char *)"FitObjective_experimental_array(FitObjective self) -> vdouble1d_t"}, { (char *)"FitObjective_simulation_array", _wrap_FitObjective_simulation_array, METH_VARARGS, (char *)"FitObjective_simulation_array(FitObjective self) -> vdouble1d_t"}, + { (char *)"FitObjective_numberOfIterations", _wrap_FitObjective_numberOfIterations, METH_VARARGS, (char *)"FitObjective_numberOfIterations(FitObjective self) -> size_t"}, + { (char *)"FitObjective_simulationResult", _wrap_FitObjective_simulationResult, METH_VARARGS, (char *)"\n" + "simulationResult(size_t i_item=0) -> SimulationResult\n" + "FitObjective_simulationResult(FitObjective self) -> SimulationResult\n" + ""}, + { (char *)"FitObjective_experimentalData", _wrap_FitObjective_experimentalData, METH_VARARGS, (char *)"\n" + "experimentalData(size_t i_item=0) -> SimulationResult\n" + "FitObjective_experimentalData(FitObjective self) -> SimulationResult\n" + ""}, + { (char *)"FitObjective_relativeDifference", _wrap_FitObjective_relativeDifference, METH_VARARGS, (char *)"\n" + "relativeDifference(size_t i_item=0) -> SimulationResult\n" + "FitObjective_relativeDifference(FitObjective self) -> SimulationResult\n" + ""}, { (char *)"FitObjective_swigregister", FitObjective_swigregister, METH_VARARGS, NULL}, { (char *)"StandardNormal", _wrap_StandardNormal, METH_VARARGS, (char *)"\n" "StandardNormal(double x) -> double\n"