From a588d14057bc916fb4d913b526d175da968744b8 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Wed, 24 Aug 2016 15:15:18 +0200 Subject: [PATCH] ProgressHandler is now a member of Simulation. --- Core/Basics/ISingleton.h | 24 +++--- Core/Computation/MainComputation.cpp | 9 +- Core/Computation/MainComputation.h | 22 ++--- Core/Computation/ProgressHandler.cpp | 40 +++++---- Core/Computation/ProgressHandler.h | 28 +++--- Core/Computation/ProgressHandlerDWBA.cpp | 52 ------------ Core/Computation/ProgressHandlerDWBA.h | 40 --------- Core/Lattice/Lattice.cpp | 10 --- Core/Lattice/Lattice.h | 4 +- .../IInterferenceFunctionStrategy.cpp | 2 +- Core/Simulation/Simulation.cpp | 14 +-- Core/Simulation/Simulation.h | 7 +- GUI/coregui/Models/JobWorker.cpp | 20 ++--- GUI/coregui/Models/JobWorker.h | 4 +- Tests/Functional/Core/CoreStandardTest.cpp | 4 +- Tests/Functional/GUI/GUIStandardTest.cpp | 4 +- .../PyCore/export/PyExportStandardTest.cpp | 5 +- .../TestMachinery/IFunctionalTest.h | 3 +- .../TestMachinery/IReferencedTest.h | 5 +- .../TestMachinery/IStandardTest.cpp | 15 ++-- .../Functional/TestMachinery/IStandardTest.h | 6 +- auto/Wrap/libBornAgainCore.py | 18 ++-- auto/Wrap/libBornAgainCore_wrap.cpp | 85 ++++++------------- cmake/bornagain/modules/SetupCoverage.cmake | 1 + 24 files changed, 135 insertions(+), 287 deletions(-) delete mode 100644 Core/Computation/ProgressHandlerDWBA.cpp delete mode 100644 Core/Computation/ProgressHandlerDWBA.h diff --git a/Core/Basics/ISingleton.h b/Core/Basics/ISingleton.h index ce15f6341df..2fbc1861c2a 100644 --- a/Core/Basics/ISingleton.h +++ b/Core/Basics/ISingleton.h @@ -18,42 +18,40 @@ #include <iostream> #include <mutex> -#include <stdexcept> // need overlooked by g++ 5.4 +#include <stdexcept> -//! @class ISingleton +//! Base class for singletons. //! @ingroup tools_internal -//! @brief Singleton pattern. template <class T> class ISingleton { public: - static T& instance() - { + static T& instance() { static std::mutex single_mutex; std::unique_lock<std::mutex> single_lock( single_mutex ); if( !m_instance) { if( m_destroyed ) - throw std::runtime_error("Bug in ISingleton: object was destructed!"); + // In BornAgain, an ISingleton is deleted when and only when the application + // terminates. Therefore there is no point in re-creating a deleted ISingleton. + // To be 110% sure, we explicitly forbid re-creation. + throw std::runtime_error("Invalid attempt to re-create a deleted ISingleton"); static T theInstance; m_instance = &theInstance; } - return *m_instance; - } + return *m_instance; } protected: ISingleton(){} - virtual ~ISingleton() - { + virtual ~ISingleton() { m_instance = nullptr; - m_destroyed = true; - } + m_destroyed = true; } private: ISingleton(const ISingleton&) = delete; ISingleton& operator=(const ISingleton&) = delete; static T* m_instance; - static bool m_destroyed; + static bool m_destroyed; //!< to detect re-creation }; // for templated classes, initializations go into the .h file: diff --git a/Core/Computation/MainComputation.cpp b/Core/Computation/MainComputation.cpp index 138d1d384b1..3771c1f1b45 100644 --- a/Core/Computation/MainComputation.cpp +++ b/Core/Computation/MainComputation.cpp @@ -26,7 +26,6 @@ #include "RoughMultiLayerComputation.h" #include "ScalarSpecularInfoMap.h" #include "ProgressHandler.h" -#include "ProgressHandlerDWBA.h" #include "SimulationElement.h" #include "SpecularMagnetic.h" #include "SpecularMatrix.h" @@ -37,10 +36,11 @@ MainComputation::MainComputation( const MultiLayer* p_multi_layer, const SimulationOptions& options, - ProgressHandler* progress, + ProgressHandler& progress, const std::vector<SimulationElement>::iterator& begin_it, const std::vector<SimulationElement>::iterator& end_it) : m_sim_options(options) + , m_progress(&progress) , mp_roughness_computation(nullptr) { mp_multi_layer = p_multi_layer->clone(); @@ -49,10 +49,6 @@ MainComputation::MainComputation( m_begin_it = begin_it; m_end_it = end_it; - // initialising call backs - if (progress) - m_progress.setCallback( [&] (int n) {return progress->update(n);} ); - for (size_t i=0; i<mp_multi_layer->getNumberOfLayers(); ++i) { m_layer_computation.push_back({}); for (size_t j=0; j<mp_multi_layer->getLayer(i)->getNumberOfLayouts(); ++j) @@ -115,6 +111,7 @@ void MainComputation::runProtected() mp_roughness_computation->eval(layer_elements.begin(), layer_elements.end()); addElementsWithWeight(layer_elements.begin(), layer_elements.end(), m_begin_it, 1.0); } + m_progress->incrementDone(1); } void MainComputation::collectRTCoefficientsScalar() diff --git a/Core/Computation/MainComputation.h b/Core/Computation/MainComputation.h index e99ab7e3426..3c4bea57b06 100644 --- a/Core/Computation/MainComputation.h +++ b/Core/Computation/MainComputation.h @@ -19,7 +19,6 @@ #include "ComputationOutcome.h" #include "Complex.h" #include "INoncopyable.h" -#include "ProgressHandlerDWBA.h" #include "SimulationOptions.h" #include <vector> @@ -29,7 +28,11 @@ class RoughMultiLayerComputation; class ProgressHandler; class SimulationElement; -//! Performs a DWBA calculation with given sample and simulation parameters +//! Performs a single-threaded DWBA computation with given sample and simulation parameters, +//! for a given span of detector bins. +//! +//! Controlled by the multi-threading machinery in Simulation::runSingleSimulation(). +//! //! @ingroup algorithms_internal class BA_CORE_API_ MainComputation : public INoncopyable @@ -38,7 +41,7 @@ public: MainComputation( const MultiLayer* p_multi_layer, const SimulationOptions& options, - ProgressHandler* progress, + ProgressHandler& progress, const std::vector<SimulationElement>::iterator& begin_it, const std::vector<SimulationElement>::iterator& end_it); ~MainComputation(); @@ -55,16 +58,15 @@ private: void collectRTCoefficientsScalar(); void collectRTCoefficientsMatrix(); - //! Iterators that defines the sequence of elements that this simulation will work on - std::vector<SimulationElement>::iterator m_begin_it, m_end_it; - + MultiLayer* mp_multi_layer; SimulationOptions m_sim_options; + ProgressHandler* m_progress; + //! these iterators define the span of detector bins this simulation will work on + std::vector<SimulationElement>::iterator m_begin_it, m_end_it; - ProgressHandlerDWBA m_progress; - - std::vector<std::vector<DecoratedLayerComputation*>> m_layer_computation; - MultiLayer* mp_multi_layer; RoughMultiLayerComputation* mp_roughness_computation; + std::vector<std::vector<DecoratedLayerComputation*>> m_layer_computation; + ComputationOutcome m_outcome; }; diff --git a/Core/Computation/ProgressHandler.cpp b/Core/Computation/ProgressHandler.cpp index c7fb3f30130..385089a7095 100644 --- a/Core/Computation/ProgressHandler.cpp +++ b/Core/Computation/ProgressHandler.cpp @@ -18,33 +18,31 @@ #include "LayerInterface.h" #include "MultiLayer.h" #include <mutex> +#include <stdexcept> -ProgressHandler::ProgressHandler() - : m_callback(nullptr) - , m_completed_nticks(0) - , m_expected_nticks(0) - , m_percentage_done(0) -{} +void ProgressHandler::subscribe(ProgressHandler::Callback_t inform) +{ + if (m_inform) + throw std::runtime_error("Invalid call of ProgressHandler::subscribe: " + "currently, no more than one subscriber is allowed"); + m_inform = inform; +} -//! Collects number of ticks processed by different Computation's. -//! Calculates general progress and inform GUI if progress has changed. -//! Return flag is obtained from GUI and transferred to Computation to ask -//! them to stop calculations. -bool ProgressHandler::update(size_t ticks_done) +//! Increments number of completed computation steps (ticks). +//! Performs callback (method m_inform) to inform the subscriber about +//! the state of the computation and to obtain as return value a flag +//! that indicates whether to continue the computation. Returns the +//! value of that flag to request the owner to terminate. +bool ProgressHandler::incrementDone(size_t ticks_done) { static std::mutex single_mutex; std::unique_lock<std::mutex> single_lock( single_mutex ); - // this flag is to inform Simulation that GUI wants it to be terminated - bool continue_calculations(true); - m_completed_nticks += ticks_done; + if (m_completed_nticks > m_expected_nticks) + m_expected_nticks = m_completed_nticks+1; - m_percentage_done = int(100.*m_completed_nticks/m_expected_nticks); - //std::cout << "ProgressHandler::update done" << ticks_done << " of " << m_expected_nticks - // << " => progress:" << progress << std::endl; - if(m_callback) - continue_calculations = m_callback(m_percentage_done); // report to gui - - return continue_calculations; + if(!m_inform) + return true; + return m_inform(percentage_done()); // report to subscriber, and get continuation flag } diff --git a/Core/Computation/ProgressHandler.h b/Core/Computation/ProgressHandler.h index 3e8a3ae681a..da16437298f 100644 --- a/Core/Computation/ProgressHandler.h +++ b/Core/Computation/ProgressHandler.h @@ -22,29 +22,35 @@ class MultiLayer; -//! Provides the functionality to calculate the progress of running simulation and report it to GUI. -//! -//! Thread safe to be used from Computation. +//! Maintains information about progress of a computation. +//! Owner is the computation, which periodically calls the thread-safe function incrementDone(..). +//! An application (GUI or script) may subscribe(..) to be informed about progress. +//! It is then periodically called back by inform(..). +//! The return value of inform(..) can be used to request termination of the computation. //! //! @ingroup algorithms_internal -class BA_CORE_API_ ProgressHandler : public INoncopyable +class BA_CORE_API_ ProgressHandler { public: typedef std::function<bool(size_t)> Callback_t; - ProgressHandler(); - - void setCallback(ProgressHandler::Callback_t callback) { m_callback = callback; } + ProgressHandler() : m_inform(nullptr), m_expected_nticks(0), m_completed_nticks(0) {} + ProgressHandler(const ProgressHandler& other) + : m_inform(nullptr) // not clear whether we want to copy subscriptions + , m_expected_nticks(other.m_expected_nticks) + , m_completed_nticks(other.m_completed_nticks) {} + void subscribe(ProgressHandler::Callback_t callback); + void reset() { m_completed_nticks = 0; } void setExpectedNTicks(size_t n) { m_expected_nticks = n; } + bool incrementDone(size_t ticks_done); - bool update(size_t ticks_done); + int percentage_done() const { return 100.*m_completed_nticks/m_expected_nticks; } private: - ProgressHandler::Callback_t m_callback; - size_t m_completed_nticks; + ProgressHandler::Callback_t m_inform; size_t m_expected_nticks; - int m_percentage_done; + size_t m_completed_nticks; }; #endif // PROGRESSHANDLER_H diff --git a/Core/Computation/ProgressHandlerDWBA.cpp b/Core/Computation/ProgressHandlerDWBA.cpp deleted file mode 100644 index ac3a1d3fd13..00000000000 --- a/Core/Computation/ProgressHandlerDWBA.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************** // -// -// BornAgain: simulate and fit scattering at grazing incidence -// -//! @file Core/Computation/ProgressHandlerDWBA.cpp -//! @brief Implements class ProgressHandlerDWBA. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2015 -//! @authors Scientific Computing Group at MLZ Garching -//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke -// -// ************************************************************************** // - -#include "ProgressHandlerDWBA.h" - -ProgressHandlerDWBA::ProgressHandlerDWBA() - : m_nitems(0) - , m_nitems_total(0) - , m_report_every_nth(100) -{} - - -//! Method increments number of items processed. -//! Every n'th processed item the Simulation is informed via thread safe callback. -//! Return flag false is used to inform DWBSimulation to interrupt calculations. -bool ProgressHandlerDWBA::update() -{ - bool continue_calculations(true); - if(!m_callback) - return continue_calculations; - - m_nitems_total++; - m_nitems++; - if(m_nitems >= m_report_every_nth) { - continue_calculations = m_callback(m_nitems); // report to the Simulation - m_nitems=0; - } - return continue_calculations; -} - - -//! finalize report to the simulation -bool ProgressHandlerDWBA::finished() -{ - if(m_callback) { - m_callback(m_nitems); // report to the Simulation - m_nitems = 0; - } - return true; -} diff --git a/Core/Computation/ProgressHandlerDWBA.h b/Core/Computation/ProgressHandlerDWBA.h deleted file mode 100644 index 44f1ff875e7..00000000000 --- a/Core/Computation/ProgressHandlerDWBA.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************** // -// -// BornAgain: simulate and fit scattering at grazing incidence -// -//! @file Core/Computation/ProgressHandlerDWBA.h -//! @brief Defines class ProgressHandlerDWBA. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2015 -//! @authors Scientific Computing Group at MLZ Garching -//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke -// -// ************************************************************************** // - -#ifndef PROGRESSHANDLERDWBA_H -#define PROGRESSHANDLERDWBA_H - -#include "ProgressHandler.h" - -//! Holds number of items processed by Computation, -//! and informs Simulation every time n items have been processed. -//! @ingroup algorithms_internal - -class ProgressHandlerDWBA -{ -public: - ProgressHandlerDWBA(); - void setCallback(ProgressHandler::Callback_t callback) { m_callback = callback; } - ProgressHandler::Callback_t getCallback() const { return m_callback; } - bool update(); - bool finished(); -private: - ProgressHandler::Callback_t m_callback; - long m_nitems; - long m_nitems_total; - long m_report_every_nth; -}; - -#endif // PROGRESSHANDLERDWBA_H diff --git a/Core/Lattice/Lattice.cpp b/Core/Lattice/Lattice.cpp index ceca2754dbf..b11284cfe00 100644 --- a/Core/Lattice/Lattice.cpp +++ b/Core/Lattice/Lattice.cpp @@ -19,21 +19,12 @@ #include "Transform3D.h" #include <gsl/gsl_linalg.h> -Lattice::Lattice() -: mp_selection_rule(0) -, m_cache_ok(false) -, m_is_zero(true) -{ - initialize(); -} - Lattice::Lattice(const kvector_t a1, const kvector_t a2, const kvector_t a3) : mp_selection_rule(0) , m_a1(a1) , m_a2(a2) , m_a3(a3) , m_cache_ok(false) -, m_is_zero(false) { initialize(); } @@ -44,7 +35,6 @@ Lattice::Lattice(const Lattice& lattice) , m_a2(lattice.m_a2) , m_a3(lattice.m_a3) , m_cache_ok(false) -, m_is_zero(false) { initialize(); if( lattice.mp_selection_rule ) setSelectionRule(*lattice.mp_selection_rule); diff --git a/Core/Lattice/Lattice.h b/Core/Lattice/Lattice.h index 7302a60f0b0..493e726e11a 100644 --- a/Core/Lattice/Lattice.h +++ b/Core/Lattice/Lattice.h @@ -28,7 +28,7 @@ class Transform3D; class BA_CORE_API_ Lattice { public: - Lattice(); + Lattice() =delete; Lattice(const kvector_t a1, const kvector_t a2, const kvector_t a3); Lattice(const Lattice& lattice); ~Lattice(); @@ -87,7 +87,7 @@ private: kvector_t m_a1, m_a2, m_a3; //!< Basis vectors in real space mutable kvector_t m_b1, m_b2, m_b3; //!< Cache of basis vectors in reciprocal space //! Boolean indicating if the reciprocal vectors are already initialized in the cache - mutable bool m_cache_ok, m_is_zero; + mutable bool m_cache_ok; }; #endif // LATTICE_H diff --git a/Core/Multilayer/IInterferenceFunctionStrategy.cpp b/Core/Multilayer/IInterferenceFunctionStrategy.cpp index 71aabfcfe1f..229fe229699 100644 --- a/Core/Multilayer/IInterferenceFunctionStrategy.cpp +++ b/Core/Multilayer/IInterferenceFunctionStrategy.cpp @@ -157,6 +157,6 @@ double IInterferenceFunctionStrategy::evaluate_for_fixed_angles_pol( SimulationElement* pars = static_cast<SimulationElement*>(params); SimulationElement sim_element(*pars, par0, par1); - calculateFormFactorLists(sim_element); + calculateFormFactorListPol(sim_element); return pars->getIntegrationFactor(par0, par1) * evaluateForMatrixList(sim_element, m_ff_pol); } diff --git a/Core/Simulation/Simulation.cpp b/Core/Simulation/Simulation.cpp index fa9b73280f4..749e56e6f6b 100644 --- a/Core/Simulation/Simulation.cpp +++ b/Core/Simulation/Simulation.cpp @@ -27,7 +27,6 @@ #include <thread> Simulation::Simulation() - : m_progress(nullptr) {} Simulation::~Simulation() {} // forward class declaration prevents move to .h @@ -61,15 +60,18 @@ void Simulation::prepareSimulation() //! Run simulation with possible averaging over parameter distributions void Simulation::runSimulation() { + updateSample(); + if (!mP_sample) + throw Exceptions::NullPointerException("Simulation::runSimulation() -> Error! No sample."); + prepareSimulation(); size_t param_combinations = m_distribution_handler.getTotalNumberOfSamples(); - if (m_progress) { - int prefac = ( mP_sample->totalNofLayouts()>0 ? 1 : 0 ) - + ( mP_sample->hasRoughness() ? 1 : 0 ); - m_progress->setExpectedNTicks(prefac*param_combinations*getNumberOfSimulationElements()); - } + m_progress.reset(); + int prefac = ( mP_sample->totalNofLayouts()>0 ? 1 : 0 ) + + ( mP_sample->hasRoughness() ? 1 : 0 ); + m_progress.setExpectedNTicks(prefac*param_combinations*getNumberOfSimulationElements()); // no averaging needed: if (param_combinations == 1) { diff --git a/Core/Simulation/Simulation.h b/Core/Simulation/Simulation.h index ae86809d6cd..ab13bac6bcd 100644 --- a/Core/Simulation/Simulation.h +++ b/Core/Simulation/Simulation.h @@ -81,15 +81,14 @@ public: const DistributionHandler& getDistributionHandler() const; - //! sets progress handler (used by GUI) - void setProgressHandler(ProgressHandler* progress) { m_progress = progress; } - //unused friend class OMPISimulation; void setOptions(const SimulationOptions& options) { m_options = options; } const SimulationOptions& getOptions() const { return m_options; } SimulationOptions& getOptions() { return m_options; } + ProgressHandler& progressHandler() { return m_progress; } + protected: Simulation(const Simulation& other); @@ -123,7 +122,7 @@ protected: std::shared_ptr<IMultiLayerBuilder> mp_sample_builder; SimulationOptions m_options; DistributionHandler m_distribution_handler; - ProgressHandler* m_progress; + ProgressHandler m_progress; std::vector<SimulationElement> m_sim_elements; private: diff --git a/GUI/coregui/Models/JobWorker.cpp b/GUI/coregui/Models/JobWorker.cpp index 58dff1d6c3d..75d306405a7 100644 --- a/GUI/coregui/Models/JobWorker.cpp +++ b/GUI/coregui/Models/JobWorker.cpp @@ -32,13 +32,6 @@ JobWorker::JobWorker(QString identifier, GISASSimulation *simulation) } -int JobWorker::getProgress() const -{ - // sometimes simulation underestimate the number of iterations required - // and progress can be greater than 100 - return m_percentage_done < 100 ? m_percentage_done : 100; -} - void JobWorker::start() { qDebug() << "JobRunner::start() " << m_simulation; @@ -47,11 +40,9 @@ void JobWorker::start() emit started(); if(m_simulation) { - std::unique_ptr<ProgressHandler> progressHandler(new ProgressHandler()); - ProgressHandler::Callback_t callback = [this] (int percentage_done) { - return simulationProgressCallback(percentage_done); }; - progressHandler->setCallback(callback); - m_simulation->setProgressHandler(progressHandler.get()); + m_simulation->progressHandler().subscribe( + [this] (int percentage_done) { + return calledbackByProgressHandler(percentage_done); } ); m_job_status = Constants::STATUS_RUNNING; @@ -84,8 +75,9 @@ void JobWorker::start() emit finished(); } -//! function which is called by the simulation to report its progress -bool JobWorker::simulationProgressCallback(int percentage_done) +//! Informs us about progress of the simulation. Returns true if we want to continue the simulation. +//! To be registered as callback function via ProgressHandler::subscribe(). +bool JobWorker::calledbackByProgressHandler(int percentage_done) { if (percentage_done > m_percentage_done) { m_percentage_done = percentage_done; diff --git a/GUI/coregui/Models/JobWorker.h b/GUI/coregui/Models/JobWorker.h index 01392462f4e..d11e29cb6bb 100644 --- a/GUI/coregui/Models/JobWorker.h +++ b/GUI/coregui/Models/JobWorker.h @@ -34,9 +34,9 @@ public: QString getIdentifier() const { return m_identifier; } void setIdentifier(QString identifier) { m_identifier = identifier; } - int getProgress() const; + int getProgress() const { return m_percentage_done; } - bool simulationProgressCallback(int); + bool calledbackByProgressHandler(int); bool isTerminated() { return m_terminate_request_flag; } diff --git a/Tests/Functional/Core/CoreStandardTest.cpp b/Tests/Functional/Core/CoreStandardTest.cpp index a3873ee17f8..7dca9c2bc79 100644 --- a/Tests/Functional/Core/CoreStandardTest.cpp +++ b/Tests/Functional/Core/CoreStandardTest.cpp @@ -21,8 +21,8 @@ class CoreStandardTest : public IStandardTest { public: CoreStandardTest() : IStandardTest("CoreStandardTest") {} - IFunctionalTest* getTest() const { return new CoreTest( - getName(), getTestDescription(), getSimulation(), getTestThreshold() ); } + std::unique_ptr<IFunctionalTest> getTest() const { return std::unique_ptr<IFunctionalTest> + (new CoreTest(getName(), getTestDescription(), getSimulation(), getTestThreshold())); } }; //! Runs CoreTest on a standard simulation indicated by argv[1]. diff --git a/Tests/Functional/GUI/GUIStandardTest.cpp b/Tests/Functional/GUI/GUIStandardTest.cpp index 579866ef0c5..5b9cee985d1 100644 --- a/Tests/Functional/GUI/GUIStandardTest.cpp +++ b/Tests/Functional/GUI/GUIStandardTest.cpp @@ -22,8 +22,8 @@ class GUIStandardTest : public IStandardTest { public: GUIStandardTest() : IStandardTest("GUIStandardTest") {} - IFunctionalTest* getTest() const { return new GUITest( - getName(), getTestDescription(), getSimulation(), getTestThreshold()); } + std::unique_ptr<IFunctionalTest> getTest() const { return std::unique_ptr<IFunctionalTest> + (new GUITest(getName(), getTestDescription(), getSimulation(), getTestThreshold())); } }; //! Runs GUITest on a standard simulation indicated by argv[1]. diff --git a/Tests/Functional/PyCore/export/PyExportStandardTest.cpp b/Tests/Functional/PyCore/export/PyExportStandardTest.cpp index aae3c878d93..8e25a6e43fc 100644 --- a/Tests/Functional/PyCore/export/PyExportStandardTest.cpp +++ b/Tests/Functional/PyCore/export/PyExportStandardTest.cpp @@ -21,8 +21,9 @@ class PyExportStandardTest : public IStandardTest { public: PyExportStandardTest() : IStandardTest("PyExport") {} - IFunctionalTest* getTest() const { return new PyExportTest( - getName(), getTestDescription(), getSimulation(), getTestThreshold()); } + std::unique_ptr<IFunctionalTest> getTest() const { return std::unique_ptr<IFunctionalTest> + (new PyExportTest( + getName(), getTestDescription(), getSimulation(), getTestThreshold())); } }; //! Runs PyExportTest on a standard simulation indicated by argv[1]. diff --git a/Tests/Functional/TestMachinery/IFunctionalTest.h b/Tests/Functional/TestMachinery/IFunctionalTest.h index 35f79c6e28e..6505504681a 100644 --- a/Tests/Functional/TestMachinery/IFunctionalTest.h +++ b/Tests/Functional/TestMachinery/IFunctionalTest.h @@ -19,9 +19,8 @@ #include "INamed.h" #include <map> +//! Base class for all functional tests. //! @class IFunctionalTest -//! @ingroup standard_samples -//! @brief Base class for all functional tests. class IFunctionalTest : public INamed { diff --git a/Tests/Functional/TestMachinery/IReferencedTest.h b/Tests/Functional/TestMachinery/IReferencedTest.h index 0ad31b69e98..26d1b899a0f 100644 --- a/Tests/Functional/TestMachinery/IReferencedTest.h +++ b/Tests/Functional/TestMachinery/IReferencedTest.h @@ -21,9 +21,8 @@ #include <map> #include <string> -//! @class IReferencedTest +//! Base class for tests that compare results with reference data. //! @ingroup standard_samples -//! @brief Base class for tests that compare results with reference data. class IReferencedTest : public IFunctionalTest { @@ -33,7 +32,7 @@ public: : IFunctionalTest(name, description), m_threshold(threshold) {} virtual ~IReferencedTest() {} - bool runTest() = 0; + bool runTest() =0; protected: double m_threshold; diff --git a/Tests/Functional/TestMachinery/IStandardTest.cpp b/Tests/Functional/TestMachinery/IStandardTest.cpp index f30d4477e46..86cc02619bd 100644 --- a/Tests/Functional/TestMachinery/IStandardTest.cpp +++ b/Tests/Functional/TestMachinery/IStandardTest.cpp @@ -47,8 +47,7 @@ bool IStandardTest::execute(int argc, char** argv) { bool IStandardTest::execute_onetest() { setName( m_info->m_test_name ); - IFunctionalTest* test( getTest() ); - return test->runTest(); + return getTest()->runTest(); } //! Runs all available subtests, and returns true if all succeed @@ -73,13 +72,10 @@ bool IStandardTest::execute_subtests() for (size_t i = 0; i < n_subtests; ++i) { setName( m_info->m_test_name + "_" + subtest_names[i] ); m_subtest_item = subtest_registry->getItem(subtest_names[i]); - IFunctionalTest* subtest( getTest() ); std::cout << "IStandardTest::execute() -> " << getName() << " " << i+1 << "/" << n_subtests << " (" << subtest_names[i] << ")\n"; - if(!subtest->runTest()) { + if(!getTest()->runTest()) ++number_of_failed_tests; - delete subtest; - } } delete subtest_registry; @@ -99,13 +95,12 @@ double IStandardTest::getTestThreshold() const { return m_info->m_threshold; } GISASSimulation* IStandardTest::getSimulation() const { - SimulationFactory sim_registry; - GISASSimulation* result = sim_registry.createItem(m_info->m_simulation_name); - SampleBuilderFactory sample_factory; std::shared_ptr<IMultiLayerBuilder> sample_builder( - sample_factory.createItem(m_info->m_sample_builder_name) ); + SampleBuilderFactory().createItem(m_info->m_sample_builder_name) ); if(m_subtest_item) sample_builder->set_subtest(m_subtest_item); + + GISASSimulation* result = SimulationFactory().createItem(m_info->m_simulation_name); result->setSampleBuilder(sample_builder); return result; } diff --git a/Tests/Functional/TestMachinery/IStandardTest.h b/Tests/Functional/TestMachinery/IStandardTest.h index 0b911b04d6c..cfdc51e258a 100644 --- a/Tests/Functional/TestMachinery/IStandardTest.h +++ b/Tests/Functional/TestMachinery/IStandardTest.h @@ -17,14 +17,15 @@ #define ISTANDARDTEST_H #include "INamed.h" +#include <memory> class GISASSimulation; class IFunctionalTest; class SimulationInfo; class IParameterized; +//! Base class for Core/PyCore/GUI tests that involve standard simulations. //! @class IStandardTest -//! @brief Base class for Core/PyCore/GUI tests that involve standard simulations. //! For Foo in {Core, PyCore, GUI}, the functional test mechanism is as follows: //! @@ -60,7 +61,8 @@ public: bool execute(int argc, char** argv); - virtual IFunctionalTest* getTest() const = 0; //!< overloaded in (Core|Py|GUI)Suite.cpp + //! Returns a specific standard functional test kernel like CoreTest, PyExportTest, GUITest. + virtual std::unique_ptr<IFunctionalTest> getTest() const = 0; protected: virtual GISASSimulation* getSimulation() const; diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py index fc39af307ba..7f0e38eabd1 100644 --- a/auto/Wrap/libBornAgainCore.py +++ b/auto/Wrap/libBornAgainCore.py @@ -14927,18 +14927,6 @@ class Simulation(ICloneable, IParameterized): return _libBornAgainCore.Simulation_getDistributionHandler(self) - def setProgressHandler(self, progress): - """ - setProgressHandler(Simulation self, ProgressHandler * progress) - - void Simulation::setProgressHandler(ProgressHandler *progress) - - sets progress handler (used by GUI) - - """ - return _libBornAgainCore.Simulation_setProgressHandler(self, progress) - - def setOptions(self, options): """ setOptions(Simulation self, SimulationOptions options) @@ -14959,6 +14947,11 @@ class Simulation(ICloneable, IParameterized): """ return _libBornAgainCore.Simulation_getOptions(self, *args) + + def progressHandler(self): + """progressHandler(Simulation self) -> ProgressHandler &""" + return _libBornAgainCore.Simulation_progressHandler(self) + Simulation_swigregister = _libBornAgainCore.Simulation_swigregister Simulation_swigregister(Simulation) @@ -19586,7 +19579,6 @@ class Lattice(_object): def __init__(self, *args): """ - __init__(Lattice self) -> Lattice __init__(Lattice self, kvector_t a1, kvector_t a2, kvector_t a3) -> Lattice __init__(Lattice self, Lattice lattice) -> Lattice diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp index 8a030750383..897712410c3 100644 --- a/auto/Wrap/libBornAgainCore_wrap.cpp +++ b/auto/Wrap/libBornAgainCore_wrap.cpp @@ -68747,36 +68747,6 @@ fail: } -SWIGINTERN PyObject *_wrap_Simulation_setProgressHandler(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - Simulation *arg1 = (Simulation *) 0 ; - ProgressHandler *arg2 = (ProgressHandler *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:Simulation_setProgressHandler",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Simulation, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Simulation_setProgressHandler" "', argument " "1"" of type '" "Simulation *""'"); - } - arg1 = reinterpret_cast< Simulation * >(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ProgressHandler, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Simulation_setProgressHandler" "', argument " "2"" of type '" "ProgressHandler *""'"); - } - arg2 = reinterpret_cast< ProgressHandler * >(argp2); - (arg1)->setProgressHandler(arg2); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *_wrap_Simulation_setOptions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; Simulation *arg1 = (Simulation *) 0 ; @@ -68894,6 +68864,28 @@ fail: } +SWIGINTERN PyObject *_wrap_Simulation_progressHandler(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + Simulation *arg1 = (Simulation *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + ProgressHandler *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:Simulation_progressHandler",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Simulation, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Simulation_progressHandler" "', argument " "1"" of type '" "Simulation *""'"); + } + arg1 = reinterpret_cast< Simulation * >(argp1); + result = (ProgressHandler *) &(arg1)->progressHandler(); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ProgressHandler, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *Simulation_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL; @@ -83673,19 +83665,6 @@ SWIGINTERN PyObject *IsGISAXSDetector_swigregister(PyObject *SWIGUNUSEDPARM(self } SWIGINTERN PyObject *_wrap_new_Lattice__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - Lattice *result = 0 ; - - if (!PyArg_ParseTuple(args,(char *)":new_Lattice")) SWIG_fail; - result = (Lattice *)new Lattice(); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_Lattice__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; kvector_t arg1 ; kvector_t arg2 ; @@ -83749,7 +83728,7 @@ fail: } -SWIGINTERN PyObject *_wrap_new_Lattice__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { +SWIGINTERN PyObject *_wrap_new_Lattice__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; Lattice *arg1 = 0 ; void *argp1 = 0 ; @@ -83786,15 +83765,12 @@ SWIGINTERN PyObject *_wrap_new_Lattice(PyObject *self, PyObject *args) { for (ii = 0; (ii < 3) && (ii < argc); ii++) { argv[ii] = PyTuple_GET_ITEM(args,ii); } - if (argc == 0) { - return _wrap_new_Lattice__SWIG_0(self, args); - } if (argc == 1) { int _v; int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice, 0); _v = SWIG_CheckState(res); if (_v) { - return _wrap_new_Lattice__SWIG_2(self, args); + return _wrap_new_Lattice__SWIG_1(self, args); } } if (argc == 3) { @@ -83808,7 +83784,7 @@ SWIGINTERN PyObject *_wrap_new_Lattice(PyObject *self, PyObject *args) { int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_BasicVector3DT_double_t, 0); _v = SWIG_CheckState(res); if (_v) { - return _wrap_new_Lattice__SWIG_1(self, args); + return _wrap_new_Lattice__SWIG_0(self, args); } } } @@ -83817,7 +83793,6 @@ SWIGINTERN PyObject *_wrap_new_Lattice(PyObject *self, PyObject *args) { fail: SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_Lattice'.\n" " Possible C/C++ prototypes are:\n" - " Lattice::Lattice()\n" " Lattice::Lattice(kvector_t const,kvector_t const,kvector_t const)\n" " Lattice::Lattice(Lattice const &)\n"); return 0; @@ -107616,14 +107591,6 @@ static PyMethodDef SwigMethods[] = { "const DistributionHandler & Simulation::getDistributionHandler() const \n" "\n" ""}, - { (char *)"Simulation_setProgressHandler", _wrap_Simulation_setProgressHandler, METH_VARARGS, (char *)"\n" - "Simulation_setProgressHandler(Simulation self, ProgressHandler * progress)\n" - "\n" - "void Simulation::setProgressHandler(ProgressHandler *progress)\n" - "\n" - "sets progress handler (used by GUI) \n" - "\n" - ""}, { (char *)"Simulation_setOptions", _wrap_Simulation_setOptions, METH_VARARGS, (char *)"\n" "Simulation_setOptions(Simulation self, SimulationOptions options)\n" "\n" @@ -107637,6 +107604,7 @@ static PyMethodDef SwigMethods[] = { "SimulationOptions& Simulation::getOptions()\n" "\n" ""}, + { (char *)"Simulation_progressHandler", _wrap_Simulation_progressHandler, METH_VARARGS, (char *)"Simulation_progressHandler(Simulation self) -> ProgressHandler &"}, { (char *)"Simulation_swigregister", Simulation_swigregister, METH_VARARGS, NULL}, { (char *)"new_SimulationOptions", _wrap_new_SimulationOptions, METH_VARARGS, (char *)"\n" "new_SimulationOptions() -> SimulationOptions\n" @@ -110212,7 +110180,6 @@ static PyMethodDef SwigMethods[] = { ""}, { (char *)"IsGISAXSDetector_swigregister", IsGISAXSDetector_swigregister, METH_VARARGS, NULL}, { (char *)"new_Lattice", _wrap_new_Lattice, METH_VARARGS, (char *)"\n" - "Lattice()\n" "Lattice(kvector_t a1, kvector_t a2, kvector_t a3)\n" "new_Lattice(Lattice lattice) -> Lattice\n" "\n" diff --git a/cmake/bornagain/modules/SetupCoverage.cmake b/cmake/bornagain/modules/SetupCoverage.cmake index 811b7bb0151..9842182f80d 100644 --- a/cmake/bornagain/modules/SetupCoverage.cmake +++ b/cmake/bornagain/modules/SetupCoverage.cmake @@ -8,6 +8,7 @@ set(coverage_ignore_dirs "'/usr/*'") list(APPEND coverage_ignore_dirs "'*/auto/*'") +list(APPEND coverage_ignore_dirs "'*/Tests/*'") list(APPEND coverage_ignore_dirs "'*/ThirdParty/*'") list(APPEND coverage_ignore_dirs "'*/build/*'") list(APPEND coverage_ignore_dirs "'*/GUI/externals/*'") -- GitLab