diff --git a/Core/Instrument/DetectorMask.cpp b/Core/Instrument/DetectorMask.cpp index f7748da479a589cea2f69dd3c0fcb6dac9e025be..faf3b6bcf80fec48869f6f56d5f74bf65c1a063b 100644 --- a/Core/Instrument/DetectorMask.cpp +++ b/Core/Instrument/DetectorMask.cpp @@ -56,6 +56,10 @@ void DetectorMask::addMask(const Geometry::IShape2D& shape, bool mask_value) void DetectorMask::initMaskData(const IDetector2D& detector) { + if(detector.getDimension() != 2) + throw Exceptions::RuntimeErrorException("DetectorMask::initMaskData() -> Error. Attempt " + "to add masks to uninitialized detector."); + assert(m_shapes.size() == m_mask_of_shape.size()); m_mask_data.clear(); diff --git a/Core/Instrument/IDetector2D.h b/Core/Instrument/IDetector2D.h index cdcf91363fbd6e2c365bfb2eef86b4362cf76db6..85a8ea390c4eafe9fd39014ee5148d58526950d7 100644 --- a/Core/Instrument/IDetector2D.h +++ b/Core/Instrument/IDetector2D.h @@ -147,7 +147,7 @@ public: //! Returns region of interest if exists. const Geometry::Rectangle* regionOfInterest() const; - //! Sets rectangular region of interest with lower left and uppre right corners defined. + //! Sets rectangular region of interest with lower left and upper right corners defined. void setRegionOfInterest(double xlow, double ylow, double xup, double yup); //! Resets region of interest making whole detector plane available for the simulation. diff --git a/Core/Simulation/GISASSimulation.cpp b/Core/Simulation/GISASSimulation.cpp index 10bbd93639325f5c0f63d63ddbcdfdc976598173..3a4dab29418077bc0313e394e992da7e47140aaf 100644 --- a/Core/Simulation/GISASSimulation.cpp +++ b/Core/Simulation/GISASSimulation.cpp @@ -127,6 +127,16 @@ std::string GISASSimulation::addParametersToExternalPool( return new_path; } +void GISASSimulation::setRegionOfInterest(double xlow, double ylow, double xup, double yup) +{ + m_instrument.getDetector()->setRegionOfInterest(xlow, ylow, xup, yup); +} + +void GISASSimulation::resetRegionOfInterest() +{ + m_instrument.getDetector()->resetRegionOfInterest(); +} + void GISASSimulation::removeMasks() { m_instrument.getDetector()->removeMasks(); diff --git a/Core/Simulation/GISASSimulation.h b/Core/Simulation/GISASSimulation.h index 13bc37e8724c6d961394ce9c3c16c424242bc6e1..ea61457fc47799d7de78f13b09224a74d69c6748 100644 --- a/Core/Simulation/GISASSimulation.h +++ b/Core/Simulation/GISASSimulation.h @@ -93,6 +93,12 @@ public: std::string addParametersToExternalPool( const std::string& path, ParameterPool* external_pool, int copy_number = -1) const final; + //! Sets rectangular region of interest with lower left and upper right corners defined. + void setRegionOfInterest(double xlow, double ylow, double xup, double yup); + + //! Resets region of interest making whole detector plane available for the simulation. + void resetRegionOfInterest(); + private: GISASSimulation(const GISASSimulation& other); diff --git a/Core/StandardSamples/SimulationFactory.cpp b/Core/StandardSamples/SimulationFactory.cpp index 8093fe7d17ca602db8756e4c0614ebbbe5c6954a..c91e4b3c796dbc16d756f269c3d56ce7fab6b9ca 100644 --- a/Core/StandardSamples/SimulationFactory.cpp +++ b/Core/StandardSamples/SimulationFactory.cpp @@ -97,4 +97,13 @@ SimulationFactory::SimulationFactory() StandardSimulations::MiniGISASMonteCarlo, "GISAS simulation with small 25x25 detector and phi[-2,2], theta[0,2], " "in Monte-Carlo mode"); + + // region of interest + + registerItem("SphericalDetWithRoi", + StandardSimulations::SphericalDetWithRoi, + "Spherical detector with ROI and mask"); + registerItem("RectDetWithRoi", + StandardSimulations::RectDetWithRoi, + "Rectangular detector with ROI and mask"); } diff --git a/Core/StandardSamples/StandardSimulations.cpp b/Core/StandardSamples/StandardSimulations.cpp index b5b946d4d78e8012957813aada2cf3e98a56dccc..af4a8d62d9277b020e6bd922b1a4d2e718a3b77f 100644 --- a/Core/StandardSamples/StandardSimulations.cpp +++ b/Core/StandardSamples/StandardSimulations.cpp @@ -51,7 +51,8 @@ GISASSimulation* StandardSimulations::PolarizedDWBAMagCylinders2() return result; } -//! Basic GISAS simulation with the detector phi[0,2], theta[0,2] +//! Basic GISAS simulation with the detector phi[0,2], theta[0,2]. + GISASSimulation* StandardSimulations::BasicGISAS() { GISASSimulation* result = new GISASSimulation(); @@ -61,7 +62,8 @@ GISASSimulation* StandardSimulations::BasicGISAS() return result; } -//! Basic GISAS for polarization studies +//! Basic GISAS for polarization studies. + GISASSimulation* StandardSimulations::BasicGISAS00() { GISASSimulation* result = BasicGISAS(); @@ -71,7 +73,8 @@ GISASSimulation* StandardSimulations::BasicGISAS00() return result; } -//! GISAS simulation with small detector and phi[-2,2], theta[0,2] +//! GISAS simulation with small detector and phi[-2,2], theta[0,2]. + GISASSimulation* StandardSimulations::MiniGISAS() { GISASSimulation* result = new GISASSimulation(); @@ -81,7 +84,8 @@ GISASSimulation* StandardSimulations::MiniGISAS() return result; } -//! GISAS simulation with small detector and phi[-1,1], theta[0,1] +//! GISAS simulation with small detector and phi[-1,1], theta[0,1]. + GISASSimulation* StandardSimulations::MiniGISAS_v2() { GISASSimulation* result = new GISASSimulation(); @@ -91,6 +95,8 @@ GISASSimulation* StandardSimulations::MiniGISAS_v2() return result; } +//! GISAS simulation with beam divergence applied. + GISASSimulation* StandardSimulations::MiniGISASBeamDivergence() { GISASSimulation* result = MiniGISAS(); @@ -112,6 +118,8 @@ GISASSimulation* StandardSimulations::MiniGISASBeamDivergence() return result; } +//! GISAS simulation with multiple masks on the detector plane. + GISASSimulation* StandardSimulations::GISASWithMasks() { GISASSimulation* result = new GISASSimulation(); @@ -143,6 +151,8 @@ GISASSimulation* StandardSimulations::GISASWithMasks() return result; } +//! GISAS simulation with detector resolution. + GISASSimulation* StandardSimulations::MiniGISASDetectorResolution() { GISASSimulation* result = MiniGISAS(); @@ -151,7 +161,8 @@ GISASSimulation* StandardSimulations::MiniGISASDetectorResolution() return result; } -//! GISAS simulation with large detector to test performance +//! GISAS simulation with large detector to test performance. + GISASSimulation* StandardSimulations::MaxiGISAS() { GISASSimulation* result = new GISASSimulation(); @@ -161,7 +172,8 @@ GISASSimulation* StandardSimulations::MaxiGISAS() return result; } -//! Basic GISAS for polarization studies +//! Basic GISAS for polarization studies. + GISASSimulation* StandardSimulations::MaxiGISAS00() { GISASSimulation* result = MaxiGISAS(); @@ -171,8 +183,8 @@ GISASSimulation* StandardSimulations::MaxiGISAS00() return result; } +//! Typical IsGISAXS simulation with the detector phi[-1,1], theta[0,2]. -//! Typical IsGISAXS simulation with the detector phi[-1,1], theta[0,2] GISASSimulation* StandardSimulations::IsGISAXSSimulation1() { GISASSimulation* result = new GISASSimulation(); @@ -184,8 +196,8 @@ GISASSimulation* StandardSimulations::IsGISAXSSimulation1() return result; } +//! Typical IsGISAXS simulation with the detector phi[0,2], theta[0,2]. -//! Typical IsGISAXS simulation with the detector phi[0,2], theta[0,2] GISASSimulation* StandardSimulations::IsGISAXSSimulation2() { GISASSimulation* result = new GISASSimulation(); @@ -197,6 +209,8 @@ GISASSimulation* StandardSimulations::IsGISAXSSimulation2() return result; } +//! GISAS simulation with generic rectangular detector. + GISASSimulation* StandardSimulations::RectDetectorGeneric() { GISASSimulation* result = new GISASSimulation(); @@ -210,6 +224,8 @@ GISASSimulation* StandardSimulations::RectDetectorGeneric() return result; } +//! GISAS simulation with the rectangular detector perpendicular to the sample. + GISASSimulation* StandardSimulations::RectDetectorPerpToSample() { GISASSimulation* result = new GISASSimulation(); @@ -222,6 +238,7 @@ GISASSimulation* StandardSimulations::RectDetectorPerpToSample() return result; } +//! GISAS simulation with the rectangular detector perpendicular to the direct beam. GISASSimulation* StandardSimulations::RectDetectorPerpToDirectBeam() { @@ -235,6 +252,7 @@ GISASSimulation* StandardSimulations::RectDetectorPerpToDirectBeam() return result; } +//! GISAS simulation with the rectangular detector perpendicular to the reflected beam. GISASSimulation* StandardSimulations::RectDetectorPerpToReflectedBeam() { @@ -248,6 +266,8 @@ GISASSimulation* StandardSimulations::RectDetectorPerpToReflectedBeam() return result; } +//! GISAS simulation with the rectangular detector perpendicular to the reflected beam when +//! the coordinates of direct beam are known. GISASSimulation* StandardSimulations::RectDetectorPerpToReflectedBeamDpos() { @@ -262,6 +282,7 @@ GISASSimulation* StandardSimulations::RectDetectorPerpToReflectedBeamDpos() return result; } +//! GISAS simulation with Monte-Carlo integration switched ON. GISASSimulation* StandardSimulations::MiniGISASMonteCarlo() { @@ -269,3 +290,29 @@ GISASSimulation* StandardSimulations::MiniGISASMonteCarlo() result->getOptions().setMonteCarloIntegration(true, 100); return result; } + +//! GISAS simulation with spherical detector, region of interest and mask. + +GISASSimulation *StandardSimulations::SphericalDetWithRoi() { + GISASSimulation *result = new GISASSimulation(); + result->setDetectorParameters(40, -2.0 * Units::degree, 2.0 * Units::degree, + 30, 0.0 * Units::degree, 3.0 * Units::degree); + result->setBeamParameters(1.0 * Units::angstrom, 0.2 * Units::degree, + 0.0 * Units::degree); + result->addMask(Geometry::Rectangle(-0.5 * Units::degree, 0.3 * Units::degree, + -0.2 * Units::degree, + 0.6 * Units::degree)); + result->setRegionOfInterest(-1.5 * Units::degree, 0.25 * Units::degree, + 1.5 * Units::degree, 1.75 * Units::degree); + return result; +} + +//! GISAS simulation with rectangular detector, region of interest and mask. + +GISASSimulation* StandardSimulations::RectDetWithRoi() +{ + GISASSimulation* result = RectDetectorPerpToDirectBeam(); + result->addMask(Geometry::Rectangle(3.0, 4.0, 5.0, 7.0)); + result->setRegionOfInterest(2.0, 3.0, 18.0, 15.0); + return result; +} diff --git a/Core/StandardSamples/StandardSimulations.h b/Core/StandardSamples/StandardSimulations.h index bc11b50d5f1a6f8f6b924a9c4471059125f7e097..dd658b89c9bfcf97c18c06383e17ce91e31ecca5 100644 --- a/Core/StandardSamples/StandardSimulations.h +++ b/Core/StandardSamples/StandardSimulations.h @@ -43,6 +43,8 @@ GISASSimulation* RectDetectorPerpToDirectBeam(); GISASSimulation* RectDetectorPerpToReflectedBeam(); GISASSimulation* RectDetectorPerpToReflectedBeamDpos(); GISASSimulation* MiniGISASMonteCarlo(); +GISASSimulation* SphericalDetWithRoi(); +GISASSimulation* RectDetWithRoi(); } #endif // STANDARDSIMULATIONS_H diff --git a/Tests/Functional/Core/CMakeLists.txt b/Tests/Functional/Core/CMakeLists.txt index 400dd50036ffd5dc2c91fde7b422eb79613d271d..963c00b8f15deb1de9b6f076cb64824046b11de1 100644 --- a/Tests/Functional/Core/CMakeLists.txt +++ b/Tests/Functional/Core/CMakeLists.txt @@ -56,6 +56,8 @@ set(test_cases TransformBox TriangularRipple TwoTypesCylindersDistribution + SphericalDetWithRoi + RectDetWithRoi ) # Other tests: diff --git a/Tests/Functional/TestMachinery/StandardSimulationsRegistry.cpp b/Tests/Functional/TestMachinery/StandardSimulationsRegistry.cpp index 33acf4264f6b219b2c64df008b1f607137b41c23..5528bc30008fca132eb1131f5af4e2c7bdb62cf8 100644 --- a/Tests/Functional/TestMachinery/StandardSimulationsRegistry.cpp +++ b/Tests/Functional/TestMachinery/StandardSimulationsRegistry.cpp @@ -331,6 +331,20 @@ StandardSimulationsRegistry::StandardSimulationsRegistry() "LargeCylindersInDWBABuilder", "None", 5e-1); + + add("SphericalDetWithRoi", + "Spherical detector with ROI and mask defined", + "SphericalDetWithRoi", + "CylindersAndPrismsBuilder", + "None", + 1e-10); + + add("RectDetWithRoi", + "Rectangular detector with ROI and mask defined", + "RectDetWithRoi", + "CylindersAndPrismsBuilder", + "None", + 1e-10); } void StandardSimulationsRegistry::add( diff --git a/Tests/ReferenceData/StandardSuite/RectDetWithRoi.int.gz b/Tests/ReferenceData/StandardSuite/RectDetWithRoi.int.gz new file mode 100644 index 0000000000000000000000000000000000000000..33fd2d809492e8967697f7b1f84c687e20ef0f4b Binary files /dev/null and b/Tests/ReferenceData/StandardSuite/RectDetWithRoi.int.gz differ diff --git a/Tests/ReferenceData/StandardSuite/SphericalDetWithRoi.int.gz b/Tests/ReferenceData/StandardSuite/SphericalDetWithRoi.int.gz new file mode 100644 index 0000000000000000000000000000000000000000..3215790914f9f57f03ab4a4f10ea834c27d3b66a Binary files /dev/null and b/Tests/ReferenceData/StandardSuite/SphericalDetWithRoi.int.gz differ diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py index a814c0ed7a20a6f62eac28af6c521fcb203af40b..29daaa94d3835d9863ceefad00cc835a5daaec88 100644 --- a/auto/Wrap/libBornAgainCore.py +++ b/auto/Wrap/libBornAgainCore.py @@ -15575,6 +15575,16 @@ class GISASSimulation(Simulation): """ return _libBornAgainCore.GISASSimulation_maskAll(self) + + def setRegionOfInterest(self, xlow, ylow, xup, yup): + """setRegionOfInterest(GISASSimulation self, double xlow, double ylow, double xup, double yup)""" + return _libBornAgainCore.GISASSimulation_setRegionOfInterest(self, xlow, ylow, xup, yup) + + + def resetRegionOfInterest(self): + """resetRegionOfInterest(GISASSimulation self)""" + return _libBornAgainCore.GISASSimulation_resetRegionOfInterest(self) + GISASSimulation_swigregister = _libBornAgainCore.GISASSimulation_swigregister GISASSimulation_swigregister(GISASSimulation) diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp index a3221c56b0d8c5a24c4fcbb1396fd56ba733c7b9..f743cef0b193f02093edaa53a7be96434c47e210 100644 --- a/auto/Wrap/libBornAgainCore_wrap.cpp +++ b/auto/Wrap/libBornAgainCore_wrap.cpp @@ -71039,6 +71039,84 @@ fail: } +SWIGINTERN PyObject *_wrap_GISASSimulation_setRegionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + GISASSimulation *arg1 = (GISASSimulation *) 0 ; + double arg2 ; + double arg3 ; + double arg4 ; + double arg5 ; + void *argp1 = 0 ; + int res1 = 0 ; + double val2 ; + int ecode2 = 0 ; + double val3 ; + int ecode3 = 0 ; + double val4 ; + int ecode4 = 0 ; + double val5 ; + int ecode5 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"OOOOO:GISASSimulation_setRegionOfInterest",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GISASSimulation, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GISASSimulation_setRegionOfInterest" "', argument " "1"" of type '" "GISASSimulation *""'"); + } + arg1 = reinterpret_cast< GISASSimulation * >(argp1); + ecode2 = SWIG_AsVal_double(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GISASSimulation_setRegionOfInterest" "', argument " "2"" of type '" "double""'"); + } + arg2 = static_cast< double >(val2); + ecode3 = SWIG_AsVal_double(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "GISASSimulation_setRegionOfInterest" "', argument " "3"" of type '" "double""'"); + } + arg3 = static_cast< double >(val3); + ecode4 = SWIG_AsVal_double(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "GISASSimulation_setRegionOfInterest" "', argument " "4"" of type '" "double""'"); + } + arg4 = static_cast< double >(val4); + ecode5 = SWIG_AsVal_double(obj4, &val5); + if (!SWIG_IsOK(ecode5)) { + SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "GISASSimulation_setRegionOfInterest" "', argument " "5"" of type '" "double""'"); + } + arg5 = static_cast< double >(val5); + (arg1)->setRegionOfInterest(arg2,arg3,arg4,arg5); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_GISASSimulation_resetRegionOfInterest(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + GISASSimulation *arg1 = (GISASSimulation *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:GISASSimulation_resetRegionOfInterest",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GISASSimulation, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GISASSimulation_resetRegionOfInterest" "', argument " "1"" of type '" "GISASSimulation *""'"); + } + arg1 = reinterpret_cast< GISASSimulation * >(argp1); + (arg1)->resetRegionOfInterest(); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *GISASSimulation_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL; @@ -108750,6 +108828,8 @@ static PyMethodDef SwigMethods[] = { "Put the mask for all detector channels (i.e. exclude whole detector from the analysis) \n" "\n" ""}, + { (char *)"GISASSimulation_setRegionOfInterest", _wrap_GISASSimulation_setRegionOfInterest, METH_VARARGS, (char *)"GISASSimulation_setRegionOfInterest(GISASSimulation self, double xlow, double ylow, double xup, double yup)"}, + { (char *)"GISASSimulation_resetRegionOfInterest", _wrap_GISASSimulation_resetRegionOfInterest, METH_VARARGS, (char *)"GISASSimulation_resetRegionOfInterest(GISASSimulation self)"}, { (char *)"GISASSimulation_swigregister", GISASSimulation_swigregister, METH_VARARGS, NULL}, { (char *)"delete_IHistogram", _wrap_delete_IHistogram, METH_VARARGS, (char *)"\n" "delete_IHistogram(IHistogram self)\n"