From 8930aa117903a289cfe2fd29283494e5df2aeecc Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 23 Oct 2017 11:57:16 +0100 Subject: [PATCH 001/364] Re #20991: Updated reflectometry IDFs. --- instrument/INTER_Definition.xml | 365 +++++++++--------------------- instrument/INTER_Parameters.xml | 2 +- instrument/OFFSPEC_Definition.xml | 86 ++++++- instrument/OFFSPEC_Parameters.xml | 2 +- instrument/POLREF_Parameters.xml | 2 +- instrument/SURF_Definition.xml | 171 ++++---------- 6 files changed, 228 insertions(+), 400 deletions(-) diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml index f93d09929fa4..b97f9efa1ee9 100644 --- a/instrument/INTER_Definition.xml +++ b/instrument/INTER_Definition.xml @@ -1,10 +1,13 @@ - + + @@ -16,77 +19,51 @@ - - - - - - - - - - - - - - - - - - + + + + + + + 40mm(H) x 60mm(W) + + + + + + + + + + + + + + + - + - + - - + - + - - + + + + - - - + + + - @@ -94,30 +71,23 @@ - + - + - - + - + + + - - - + + + - @@ -125,85 +95,35 @@ - + - + - - + + - + + + - - - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - + --> @@ -211,24 +131,23 @@ - - - - - + + + + - + - + - + - - + ypixels="243" ystart="y" ystep="+0.0012" > - + @@ -239,98 +158,50 @@ + + - - - - - - - - - - 40mm(H) x 60mm(W) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + - - - - - - + + - - - - + + + - - - - - + + + + + - + - + - - - + + + - + - + @@ -340,55 +211,37 @@ - - - - - - - - - - - - + + + + - + - + - + - + - + - + - + - + - diff --git a/instrument/INTER_Parameters.xml b/instrument/INTER_Parameters.xml index c1b83a0dae49..f48d4bb7b479 100644 --- a/instrument/INTER_Parameters.xml +++ b/instrument/INTER_Parameters.xml @@ -49,7 +49,7 @@ - + diff --git a/instrument/OFFSPEC_Definition.xml b/instrument/OFFSPEC_Definition.xml index 93c11222f1af..94d53d284cd9 100644 --- a/instrument/OFFSPEC_Definition.xml +++ b/instrument/OFFSPEC_Definition.xml @@ -22,22 +22,27 @@ - - + + + 40mm(H) x 60mm(W) + + - - - + + + + + + - @@ -51,9 +56,10 @@ + + - @@ -67,7 +73,9 @@ - + + + @@ -91,9 +99,15 @@ - + + + - + + + + + @@ -707,7 +721,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/instrument/OFFSPEC_Parameters.xml b/instrument/OFFSPEC_Parameters.xml index e3e5d0f4383c..b455953c6b09 100644 --- a/instrument/OFFSPEC_Parameters.xml +++ b/instrument/OFFSPEC_Parameters.xml @@ -52,7 +52,7 @@ - + diff --git a/instrument/POLREF_Parameters.xml b/instrument/POLREF_Parameters.xml index 41f38a23ab40..ad3e8cdc1bc0 100644 --- a/instrument/POLREF_Parameters.xml +++ b/instrument/POLREF_Parameters.xml @@ -52,7 +52,7 @@ - + diff --git a/instrument/SURF_Definition.xml b/instrument/SURF_Definition.xml index 41da6e138099..3ed89df68093 100644 --- a/instrument/SURF_Definition.xml +++ b/instrument/SURF_Definition.xml @@ -1,10 +1,13 @@ + + @@ -16,40 +19,31 @@ - + - - Noticed the face of the monitors/detector shapes that faces the - beam/sample path is in this IDF defined to be the y-z plane. - - Note the status of the instrument during a run is stored in the - logfile RunNo_status.txt - --> - - - - + + + - + @@ -66,9 +60,11 @@ + + - + @@ -82,20 +78,15 @@ - - + - + + + - - - + - + @@ -114,27 +105,13 @@ - + + + - + - - - - @@ -152,32 +129,10 @@ - - - - - - - - - 10mm(H) x 40mm(W) - - - - - - - - - - - - - - + @@ -185,7 +140,7 @@ - + @@ -195,7 +150,7 @@ - + @@ -203,7 +158,7 @@ - + @@ -224,7 +179,6 @@ - @@ -232,8 +186,6 @@ - - @@ -248,48 +200,5 @@ - + From 08b308ba9561eb18ef1399a683a5ba947430930b Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 23 Oct 2017 15:26:23 +0100 Subject: [PATCH 002/364] Re #20991 Updated unit tests to reflect changes in INTER IDF. --- .../Algorithms/test/SpecularReflectionPositionCorrect2Test.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h b/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h index e9e8e0b82c02..abb29b7f35ec 100644 --- a/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h +++ b/Framework/Algorithms/test/SpecularReflectionPositionCorrect2Test.h @@ -164,7 +164,7 @@ class SpecularReflectionPositionCorrect2Test : public CxxTest::TestSuite { auto detIn = instrIn->getComponentByName("point-detector")->getPos(); auto detOut = instrOut->getComponentByName("point-detector")->getPos(); TS_ASSERT_EQUALS(detIn.X(), detOut.X()); - TS_ASSERT_DELTA(detOut.Z(), 19.69921, 1e-5); + TS_ASSERT_DELTA(detOut.Z(), 2.66221, 1e-5); TS_ASSERT_DELTA(detOut.Y(), 0.06506, 1e-5); } @@ -205,7 +205,7 @@ class SpecularReflectionPositionCorrect2Test : public CxxTest::TestSuite { auto detIn = instrIn->getComponentByName("linear-detector")->getPos(); auto detOut = instrOut->getComponentByName("linear-detector")->getPos(); TS_ASSERT_EQUALS(detIn.X(), detOut.X()); - TS_ASSERT_DELTA(detOut.Z(), 20.19906, 1e-5); + TS_ASSERT_DELTA(detOut.Z(), 3.162055, 1e-5); TS_ASSERT_DELTA(detOut.Y(), 0.07728, 1e-5); } }; From 0ab88089ea36d83a81b69065335ecf0ef7a20308 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 23 Oct 2017 15:27:46 +0100 Subject: [PATCH 003/364] Re #20991 Fixed error in ystart position - set to 0.0. --- instrument/INTER_Definition.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml index b97f9efa1ee9..30de73384f33 100644 --- a/instrument/INTER_Definition.xml +++ b/instrument/INTER_Definition.xml @@ -145,7 +145,7 @@ + ypixels="243" ystart="0.0" ystep="+0.0012" > From bb0d84a52f7705a19a1ce2cd84b8552f64a5a651 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 25 Oct 2017 09:58:17 +0100 Subject: [PATCH 004/364] Re #20991 Fixed name of key TransRunEndOverlap -> TransRunStartOverlap --- instrument/INTER_Parameters.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrument/INTER_Parameters.xml b/instrument/INTER_Parameters.xml index f48d4bb7b479..c1b83a0dae49 100644 --- a/instrument/INTER_Parameters.xml +++ b/instrument/INTER_Parameters.xml @@ -49,7 +49,7 @@ - + From 39de4d48e2adf33e8a4dd2ea34308293e79586e8 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 25 Oct 2017 10:27:43 +0100 Subject: [PATCH 005/364] Re #20991 Applied TransRunEndOverlap fix for OFFSPEC and POLREF. --- instrument/OFFSPEC_Parameters.xml | 6 +++--- instrument/POLREF_Parameters.xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/instrument/OFFSPEC_Parameters.xml b/instrument/OFFSPEC_Parameters.xml index b455953c6b09..d7162b2148b2 100644 --- a/instrument/OFFSPEC_Parameters.xml +++ b/instrument/OFFSPEC_Parameters.xml @@ -47,14 +47,14 @@ - + - + - + diff --git a/instrument/POLREF_Parameters.xml b/instrument/POLREF_Parameters.xml index ad3e8cdc1bc0..0b15c8dc07bc 100644 --- a/instrument/POLREF_Parameters.xml +++ b/instrument/POLREF_Parameters.xml @@ -20,7 +20,7 @@ - + @@ -52,10 +52,10 @@ - + - + From 8e4c3633d54a9480632a46ff88fc7b7c26f00f12 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 25 Oct 2017 15:20:03 +0100 Subject: [PATCH 006/364] Re #20991 Applied shift of -17.037 to slit z values in INTER IDF. --- instrument/INTER_Definition.xml | 160 ++++++++++++++++---------------- 1 file changed, 79 insertions(+), 81 deletions(-) diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml index 30de73384f33..4959e47513e4 100644 --- a/instrument/INTER_Definition.xml +++ b/instrument/INTER_Definition.xml @@ -1,13 +1,13 @@ - - - + @@ -28,41 +28,41 @@ 40mm(H) x 60mm(W) - - + + - - - - + + + + - + - + - + - + - + - + - - + + - - - + + + @@ -71,22 +71,22 @@ - + - + - + - + - + - - + + @@ -95,35 +95,35 @@ - + - + - - + + - + - + - - + + + --> @@ -131,23 +131,23 @@ - - - + + + - + - - - + @@ -159,49 +159,47 @@ - - - + - + - + - + - - - + + + - - - - - - - + + + + + + + - + - - - - + + + + - + - + @@ -214,34 +212,34 @@ - - + + + - - + - + - + - + - + - + - + - + - From 306c9893d85fa244897c66f0a9c56b4f9dfa0880 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 26 Oct 2017 16:49:41 +0100 Subject: [PATCH 007/364] Re #20991 set end date INTER IDF and added _2017 suffix to new one. --- instrument/INTER_Definition.xml | 255 +++++++++++++++++++++------ instrument/INTER_Definition_2017.xml | 246 ++++++++++++++++++++++++++ 2 files changed, 449 insertions(+), 52 deletions(-) create mode 100644 instrument/INTER_Definition_2017.xml diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml index 4959e47513e4..7c2abca487fe 100644 --- a/instrument/INTER_Definition.xml +++ b/instrument/INTER_Definition.xml @@ -1,13 +1,12 @@ - - + @@ -19,34 +18,57 @@ - - - - - - - - 40mm(H) x 60mm(W) - - - - - - - - - + + + + + + + + + + + + + + + - - + - - + + @@ -56,14 +78,17 @@ - - - + + @@ -78,16 +103,23 @@ + - - - + + @@ -105,12 +137,23 @@ - - - + + + @@ -132,13 +175,53 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -158,45 +241,95 @@ - - + + + + + + + + + + 40mm(H) x 60mm(W) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + + + - + - + - + - + - + - + @@ -209,15 +342,33 @@ + + + + - + + + + + diff --git a/instrument/INTER_Definition_2017.xml b/instrument/INTER_Definition_2017.xml new file mode 100644 index 000000000000..62aceb3e8c05 --- /dev/null +++ b/instrument/INTER_Definition_2017.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + 40mm(H) x 60mm(W) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 141b8717e820714cd9a72b4427b9b42bf8534e58 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Feb 2018 16:12:45 +0000 Subject: [PATCH 008/364] Re #21749: Revert changes made to OFFSPEC files. --- instrument/OFFSPEC_Definition.xml | 86 ++++--------------------------- instrument/OFFSPEC_Parameters.xml | 4 +- 2 files changed, 12 insertions(+), 78 deletions(-) diff --git a/instrument/OFFSPEC_Definition.xml b/instrument/OFFSPEC_Definition.xml index 94d53d284cd9..93c11222f1af 100644 --- a/instrument/OFFSPEC_Definition.xml +++ b/instrument/OFFSPEC_Definition.xml @@ -22,27 +22,22 @@ + - - - 40mm(H) x 60mm(W) - - + - - - - - + + + - + @@ -56,10 +51,9 @@ - - + @@ -73,9 +67,7 @@ - - - + @@ -99,15 +91,9 @@ - - - + - - - - - + @@ -721,59 +707,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/instrument/OFFSPEC_Parameters.xml b/instrument/OFFSPEC_Parameters.xml index d7162b2148b2..e3e5d0f4383c 100644 --- a/instrument/OFFSPEC_Parameters.xml +++ b/instrument/OFFSPEC_Parameters.xml @@ -47,7 +47,7 @@ - + @@ -55,6 +55,6 @@ - + From 3b1381e6e8a975fe84a9bb5210d3642efedc290b Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Fri, 16 Feb 2018 15:50:50 +0000 Subject: [PATCH 009/364] Re #20991: Updated old INTER IDF + set last modified dates. --- instrument/INTER_Definition.xml | 242 +++++---------------------- instrument/INTER_Definition_2017.xml | 2 +- 2 files changed, 47 insertions(+), 197 deletions(-) diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml index 7c2abca487fe..f27b4c9f7e55 100644 --- a/instrument/INTER_Definition.xml +++ b/instrument/INTER_Definition.xml @@ -1,12 +1,14 @@ + - + last-modified="2018-02-16 00:00:00"> + @@ -18,57 +20,34 @@ - - - - - - - - - - - - - - + + + + + + + + 40mm(H) x 60mm(W) + + + + + + + - + - + + + + - + - @@ -78,17 +57,14 @@ + + - + - @@ -103,23 +79,16 @@ - + + - + - @@ -137,23 +106,12 @@ + + - - - + @@ -175,53 +133,13 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -241,57 +159,12 @@ + - - - - - - - - - - 40mm(H) x 60mm(W) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + @@ -299,15 +172,10 @@ - - - - - - + - + @@ -317,7 +185,7 @@ - + @@ -325,7 +193,7 @@ - + @@ -342,33 +210,15 @@ - - - - - - - - - + diff --git a/instrument/INTER_Definition_2017.xml b/instrument/INTER_Definition_2017.xml index 62aceb3e8c05..f7ea30668640 100644 --- a/instrument/INTER_Definition_2017.xml +++ b/instrument/INTER_Definition_2017.xml @@ -7,7 +7,7 @@ name="INTER" valid-from="2017-02-14 00:00:00" valid-to= "2100-01-31 23:59:59" - last-modified="2010-11-04 00:00:00"> + last-modified="2018-02-16 00:00:00"> From f230ea48d11110859872e9c23f6217a5dfd3d98c Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Fri, 16 Feb 2018 15:56:51 +0000 Subject: [PATCH 010/364] Re #20991: Revert changes to POLREF_Parameters.xml --- instrument/POLREF_Parameters.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrument/POLREF_Parameters.xml b/instrument/POLREF_Parameters.xml index 0b15c8dc07bc..41f38a23ab40 100644 --- a/instrument/POLREF_Parameters.xml +++ b/instrument/POLREF_Parameters.xml @@ -20,7 +20,7 @@ - + @@ -55,7 +55,7 @@ - + From c831d036549ad2083c532fff172b3ede8575c553 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 23 Nov 2017 11:00:29 +0000 Subject: [PATCH 011/364] Add consolidated GeometryRenderer re #21248 --- Framework/Geometry/CMakeLists.txt | 2 + .../inc/MantidGeometry/GeometryRenderer.h | 102 +++++ Framework/Geometry/src/GeometryRenderer.cpp | 388 ++++++++++++++++++ 3 files changed, 492 insertions(+) create mode 100644 Framework/Geometry/inc/MantidGeometry/GeometryRenderer.h create mode 100644 Framework/Geometry/src/GeometryRenderer.cpp diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index 3b142099c6db..81769cb07b7b 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -42,6 +42,7 @@ set ( SRC_FILES src/Crystal/SymmetryOperationSymbolParser.cpp src/Crystal/UnitCell.cpp src/Crystal/V3R.cpp + src/GeometryRenderer.cpp src/IObjComponent.cpp src/Instrument.cpp src/Instrument/CompAssembly.cpp @@ -194,6 +195,7 @@ set ( INC_FILES inc/MantidGeometry/Crystal/UnitCell.h inc/MantidGeometry/Crystal/V3R.h inc/MantidGeometry/DllConfig.h + inc/MantidGeometry/GeometryRenderer.h inc/MantidGeometry/ICompAssembly.h inc/MantidGeometry/IComponent.h inc/MantidGeometry/IDetector.h diff --git a/Framework/Geometry/inc/MantidGeometry/GeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/GeometryRenderer.h new file mode 100644 index 000000000000..f8b40b6cc3eb --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/GeometryRenderer.h @@ -0,0 +1,102 @@ +#ifndef MANTID_GEOMETRY_GEOMETRYRENDERER_H_ +#define MANTID_GEOMETRY_GEOMETRYRENDERER_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Rendering/OpenGL_Headers.h" + +class TopoDS_Shape; + +namespace Mantid { +namespace Kernel { +class V3D; +} +namespace Geometry { +class RectangularDetector; +class StructuredDetector; +class IObjComponent; + +/** GeometryRenderer : Handles rendering of geometry within mantid. + + Copyright © 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class MANTID_GEOMETRY_DLL GeometryRenderer { + enum class RenderMode { Basic, Volumetric }; + + enum class RenderShape { + Sphere, + Cube, + Cone, + Hexahedron, + Cylinder, + SegmentedCylinder + }; + +public: + GeometryRenderer() = default; + ~GeometryRenderer() = default; + + template + void Render(Args &&... args, RenderMode mode = RenderMode::Basic) const; + +private: + RenderMode m_RenderMode; + // general geometry + /// Render IObjComponent + void doRender(IObjComponent *ObjComp) const; + /// Render Traingulated Surface + void doRender(int noPts, int noFaces, double *points, int *faces) const; + /// Render OpenCascade Shape + void doRender(TopoDS_Shape *ObjSurf) const; + + // shapes + /// Renders a sphere + void doRender(const Kernel::V3D ¢er, double radius) const; + /// Renders a cuboid + void doRender(const Kernel::V3D &Point1, const Kernel::V3D &Point2, + const Kernel::V3D &Point3, const Kernel::V3D &Point4) const; + /// Renders a Hexahedron from the input values + void doRender(const std::vector &points) const; + /// Renders a Cone from the input values + void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height) const; + /// Renders a Cylinder/Segmented cylinder from the input values + void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, bool segmented = false) const; + /// Renders a Bitmap (used for rendering RectangularDetector) + void doRender(const RectangularDetector *rectDet) const; + /// Renders structured geometry (used for rendering StructuredDetector) + void doRender(const StructuredDetector *structDet) const; +}; + +template +void GeometryRenderer::Render(Args &&... args, RenderMode mode) const { + // Wait for no OopenGL error + while (glGetError() != GL_NO_ERROR) + ; + m_renderMode = mode; + doRender(std::forward(args)...); +} + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_GEOMETRYRENDERER_H_ */ \ No newline at end of file diff --git a/Framework/Geometry/src/GeometryRenderer.cpp b/Framework/Geometry/src/GeometryRenderer.cpp new file mode 100644 index 000000000000..5ff4efafd434 --- /dev/null +++ b/Framework/Geometry/src/GeometryRenderer.cpp @@ -0,0 +1,388 @@ +#include "MantidGeometry/GeometryRenderer.h" +#include "MantidGeometry/Instrument/ObjComponent.h" +#include "MantidGeometry/Instrument/RectangularDetector.h" +#include "MantidGeometry/Instrument/StructuredDetector.h" +#include "MantidGeometry/Surfaces/Cone.h" +#include "MantidGeometry/Surfaces/Cylinder.h" +#include "MantidGeometry/Surfaces/Sphere.h" +#include "MantidKernel/Quat.h" +#include "MantidKernel/WarningSuppressions.h" + +// Squash a warning coming out of an OpenCascade header +#ifdef __INTEL_COMPILER +#pragma warning disable 191 +#endif +// Opencascade defines _USE_MATH_DEFINES without checking whether it is already +// used. +// Undefine it here before we include the headers to avoid a warning +#ifdef _MSC_VER +#undef _USE_MATH_DEFINES +#ifdef M_SQRT1_2 +#undef M_SQRT1_2 +#endif +#endif + +GCC_DIAG_OFF(conversion) +// clang-format off +GCC_DIAG_OFF(cast - qual) +// clang-format on +#include +#include +#include +#include +#include +#include +#include +#include +#include +GCC_DIAG_ON(conversion) +// clang-format off +GCC_DIAG_ON(cast - qual) +// clang-format on + +#ifdef __INTEL_COMPILER +#pragma warning enable 191 +#endif + +namespace Mantid { +namespace Geometry { +using Kernel::Quat; +using Kernel::V3D; + +// Render IObjectComponent +void GeometryRenderer::doRender(IObjComponent *ObjComp) const { + glPushMatrix(); + V3D pos = ObjComp->getPos(); + Quat rot = ObjComp->getRotation(); + double rotGL[16]; + rot.GLMatrix(&rotGL[0]); + glTranslated(pos[0], pos[1], pos[2]); + glMultMatrixd(rotGL); + V3D scaleFactor = ObjComp->getScaleFactor(); + glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); + ObjComp->drawObject(); + glPopMatrix(); +} + +// Render triangulated surface +void GeometryRenderer::doRender(int noPts, int noFaces, double *points, + int *faces) const { + (void)noPts; // Avoid compiler warning + glBegin(GL_TRIANGLES); + V3D normal; + for (int i = 0; i < noFaces; i++) { + int index1 = faces[i * 3] * 3; + int index2 = faces[i * 3 + 1] * 3; + int index3 = faces[i * 3 + 2] * 3; + // Calculate normal and normalize + V3D v1(points[index1], points[index1 + 1], points[index1 + 2]); + V3D v2(points[index2], points[index2 + 1], points[index2 + 2]); + V3D v3(points[index3], points[index3 + 1], points[index3 + 2]); + normal = (v1 - v2).cross_prod(v2 - v3); + normal.normalize(); + glNormal3d(normal[0], normal[1], normal[2]); + glVertex3dv(points + index1); + glVertex3dv(points + index2); + glVertex3dv(points + index3); + } + glEnd(); +} + +// Render OpenCascade Shape +void GeometryRenderer::doRender(TopoDS_Shape *ObjSurf) const { + glBegin(GL_TRIANGLES); + if ((ObjSurf != nullptr) && !ObjSurf->IsNull()) { + TopExp_Explorer Ex; + for (Ex.Init(*ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) { + TopoDS_Face F = TopoDS::Face(Ex.Current()); + TopLoc_Location L; + Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); + TColgp_Array1OfPnt tab(1, (facing->NbNodes())); + tab = facing->Nodes(); + Poly_Array1OfTriangle tri(1, facing->NbTriangles()); + tri = facing->Triangles(); + for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { + Poly_Triangle trian = tri.Value(i); + Standard_Integer index1, index2, index3; + trian.Get(index1, index2, index3); + gp_Pnt point1 = tab.Value(index1); + gp_Pnt point2 = tab.Value(index2); + gp_Pnt point3 = tab.Value(index3); + gp_XYZ pt1 = tab.Value(index1).XYZ(); + gp_XYZ pt2 = tab.Value(index2).XYZ(); + gp_XYZ pt3 = tab.Value(index3).XYZ(); + + gp_XYZ v1 = pt2 - pt1; + gp_XYZ v2 = pt3 - pt2; + + gp_XYZ normal = v1 ^ v2; + normal.Normalize(); + glNormal3d(normal.X(), normal.Y(), normal.Z()); + glVertex3d(point1.X(), point1.Y(), point1.Z()); + glVertex3d(point2.X(), point2.Y(), point2.Z()); + glVertex3d(point3.X(), point3.Y(), point3.Z()); + } + } + } + glEnd(); +} + +// Render Sphere +void GeometryRenderer::doRender(const Kernel::V3D ¢er, + double radius) const { + // create glu sphere + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + glPushMatrix(); + glTranslated(center[0], center[1], center[2]); + gluSphere(qobj, radius, Sphere::g_nslices, Sphere::g_nstacks); + glPopMatrix(); + gluDeleteQuadric(qobj); +} + +// Render Cuboid +void GeometryRenderer::doRender(const V3D &Point1, const V3D &Point2, + const V3D &Point3, const V3D &Point4) const { + V3D vec0 = Point1; + V3D vec1 = Point2 - Point1; + V3D vec2 = Point3 - Point1; + V3D vec3 = Point4 - Point1; + V3D vertex[8]; + vertex[0] = vec0; + vertex[1] = vec0 + vec3; + vertex[2] = vec0 + vec3 + vec1; + vertex[3] = vec0 + vec1; + vertex[4] = vec0 + vec2; + vertex[5] = vec0 + vec2 + vec3; + vertex[6] = vec0 + vec2 + vec3 + vec1; + vertex[7] = vec0 + vec1 + vec2; + + int faceindex[6][4] = { + {0, 1, 2, 3}, // top + {0, 3, 7, 4}, // left + {3, 2, 6, 7}, // back + {2, 1, 5, 6}, // right + {0, 4, 5, 1}, // front + {4, 7, 6, 5}, // bottom + }; + V3D normal; + // first face + glBegin(GL_QUADS); + for (auto &row : faceindex) { + normal = (vertex[row[0]] - vertex[row[1]]) + .cross_prod((vertex[row[0]] - vertex[row[2]])); + normal.normalize(); + glNormal3d(normal[0], normal[1], normal[2]); + for (const int ij : row) { + if (ij == 0) + glTexCoord2i(0, 0); + if (ij == 1) + glTexCoord2i(1, 0); + if (ij == 2) + glTexCoord2i(1, 1); + if (ij == 3) + glTexCoord2i(0, 1); + if (ij == 4) + glTexCoord2i(0, 0); + if (ij == 5) + glTexCoord2i(1, 0); + if (ij == 6) + glTexCoord2i(1, 1); + if (ij == 7) + glTexCoord2i(0, 1); + glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]); + } + } + glEnd(); +} + +// Render Hexahedron +void GeometryRenderer::doRender(const std::vector &points) const { + glBegin(GL_QUADS); + // bottom + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + // front + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + // right + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + // back + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + // left + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + // top + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + + glEnd(); +} + +// Render Cone +void GeometryRenderer::doRender(const Kernel::V3D ¢er, + const Kernel::V3D &axis, double radius, + double height) const { + glPushMatrix(); + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + glTranslated(center[0], center[1], center[2]); + GLdouble mat[16]; + V3D unit(0, 0, 1); + Quat rot(unit, axis); + rot.GLMatrix(&mat[0]); + glMultMatrixd(mat); + gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, + Geometry::Cone::g_nstacks); + glTranslated(0.0, 0.0, height); + gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); + glPopMatrix(); +} + +// Render Cylinder +void GeometryRenderer::doRender(const Kernel::V3D ¢er, + const Kernel::V3D &axis, double radius, + double height, bool segmented) const { + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + gluQuadricTexture(qobj, true); + glPushMatrix(); + glTranslated(center[0], center[1], center[2]); + GLdouble mat[16]; + V3D unit(0, 0, 1); + Quat rot(unit, axis); + rot.GLMatrix(&mat[0]); + glMultMatrixd(mat); + gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, + segmented ? 1 : Cylinder::g_nstacks); + gluQuadricTexture(qobj, false); + gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); + glTranslated(0.0, 0.0, height); + gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); + glPopMatrix(); +} + +// Render Bitmap for RectangularDetector +void GeometryRenderer::doRender(const RectangularDetector *rectDet) const { + // Because texture colours are combined with the geometry colour + // make sure the current colour is white + glColor3f(1.0f, 1.0f, 1.0f); + + // Nearest-neighbor scaling + GLint texParam = GL_NEAREST; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam); + + glEnable(GL_TEXTURE_2D); // enable texture mapping + + int texx, texy; + rectDet->getTextureSize(texx, texy); + double tex_frac_x = (1.0 * rectDet->xpixels()) / (texx); + double tex_frac_y = (1.0 * rectDet->ypixels()) / (texy); + + glBegin(GL_QUADS); + + glTexCoord2f(0.0, 0.0); + V3D pos; + pos = rectDet->getRelativePosAtXY(0, 0); + pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (-0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glTexCoord2f(static_cast(tex_frac_x), 0.0); + pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, 0); + pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (-0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glTexCoord2f(static_cast(tex_frac_x), + static_cast(tex_frac_y)); + pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, + rectDet->ypixels() - 1); + pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (+0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glTexCoord2f(0.0, static_cast(tex_frac_y)); + pos = rectDet->getRelativePosAtXY(0, rectDet->ypixels() - 1); + pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (+0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glEnd(); + if (glGetError() > 0) + std::cout << "OpenGL error in BitmapGeometryHandler::Render \n"; + + glDisable( + GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. +} + +void GeometryRenderer::doRender(const StructuredDetector *structDet) const { + auto xVerts = structDet->getXValues(); + auto yVerts = structDet->getYValues(); + auto r = structDet->getR(); + auto g = structDet->getG(); + auto b = structDet->getB(); + + if (xVerts.size() != yVerts.size()) + return; + + auto w = structDet->xPixels() + 1; + auto h = structDet->yPixels() + 1; + + glBegin(GL_QUADS); + + for (size_t iy = 0; iy < h - 1; iy++) { + for (size_t ix = 0; ix < w - 1; ix++) { + + glColor3ub((GLubyte)r[(iy * (w - 1)) + ix], + (GLubyte)g[(iy * (w - 1)) + ix], + (GLubyte)b[(iy * (w - 1)) + ix]); + V3D pos; + pos = V3D(xVerts[(iy * w) + ix + w], yVerts[(iy * w) + ix + w], 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + pos = V3D(xVerts[(iy * w) + ix + w + 1], yVerts[(iy * w) + ix + w + 1], + 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + pos = V3D(xVerts[(iy * w) + ix + 1], yVerts[(iy * w) + ix + 1], 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + pos = V3D(xVerts[(iy * w) + ix], yVerts[(iy * w) + ix], 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + } + } + + glEnd(); + + if (glGetError() > 0) + std::cout << "OpenGL error in StructuredGeometryHandler::Render \n"; + + glDisable( + GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. +} +} // namespace Geometry +} // namespace Mantid From 38725dcee99705631ba01aa9a59b5ea7e2e25a31 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 23 Nov 2017 11:49:24 +0000 Subject: [PATCH 012/364] Add GeometryRenderer to BitmapGeometryHandler re #21248 --- Framework/Geometry/CMakeLists.txt | 4 +- .../Rendering/GeometryHandler.h | 3 + .../{ => Rendering}/GeometryRenderer.h | 14 ++-- .../src/Rendering/BitmapGeometryHandler.cpp | 68 +------------------ .../src/Rendering/GeometryHandler.cpp | 4 +- .../src/{ => Rendering}/GeometryRenderer.cpp | 2 +- 6 files changed, 19 insertions(+), 76 deletions(-) rename Framework/Geometry/inc/MantidGeometry/{ => Rendering}/GeometryRenderer.h (89%) rename Framework/Geometry/src/{ => Rendering}/GeometryRenderer.cpp (99%) diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index 81769cb07b7b..26425dd51736 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -42,7 +42,6 @@ set ( SRC_FILES src/Crystal/SymmetryOperationSymbolParser.cpp src/Crystal/UnitCell.cpp src/Crystal/V3R.cpp - src/GeometryRenderer.cpp src/IObjComponent.cpp src/Instrument.cpp src/Instrument/CompAssembly.cpp @@ -112,6 +111,7 @@ set ( SRC_FILES src/Rendering/BitmapGeometryHandler.cpp src/Rendering/CacheGeometryGenerator.cpp src/Rendering/CacheGeometryHandler.cpp + src/Rendering/GeometryRenderer.cpp src/Rendering/CacheGeometryRenderer.cpp src/Rendering/GeometryHandler.cpp src/Rendering/GluGeometryHandler.cpp @@ -195,7 +195,6 @@ set ( INC_FILES inc/MantidGeometry/Crystal/UnitCell.h inc/MantidGeometry/Crystal/V3R.h inc/MantidGeometry/DllConfig.h - inc/MantidGeometry/GeometryRenderer.h inc/MantidGeometry/ICompAssembly.h inc/MantidGeometry/IComponent.h inc/MantidGeometry/IDetector.h @@ -284,6 +283,7 @@ set ( INC_FILES inc/MantidGeometry/Rendering/OCGeometryGenerator.h inc/MantidGeometry/Rendering/OCGeometryHandler.h inc/MantidGeometry/Rendering/OCGeometryRenderer.h + inc/MantidGeometry/Rendering/GeometryRenderer.h inc/MantidGeometry/Rendering/OpenGL_Headers.h inc/MantidGeometry/Rendering/StructuredGeometryHandler.h inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 01d600433e4b..cacfe454cd43 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -5,6 +5,7 @@ #include "MantidKernel/Logger.h" #include "MantidKernel/V3D.h" #include +#include "MantidGeometry/Rendering/GeometryRenderer.h" #include namespace Mantid { @@ -13,6 +14,7 @@ namespace Geometry { class IObjComponent; class ObjComponent; class CSGObject; +class GeometryRenderer; /** \class GeometryHandler @@ -48,6 +50,7 @@ class MANTID_GEOMETRY_DLL GeometryHandler { static Kernel::Logger &PLog; ///< The official logger protected: + GeometryRenderer m_renderer; IObjComponent *ObjComp; ///< ObjComponent that uses this geometry handler CSGObject *Obj; ///< Object that uses this geometry handler bool boolTriangulated; ///< state of the geometry triangulation diff --git a/Framework/Geometry/inc/MantidGeometry/GeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h similarity index 89% rename from Framework/Geometry/inc/MantidGeometry/GeometryRenderer.h rename to Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h index f8b40b6cc3eb..f8f545fb56fc 100644 --- a/Framework/Geometry/inc/MantidGeometry/GeometryRenderer.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h @@ -39,6 +39,7 @@ class IObjComponent; Code Documentation is available at: */ class MANTID_GEOMETRY_DLL GeometryRenderer { +public: enum class RenderMode { Basic, Volumetric }; enum class RenderShape { @@ -50,15 +51,15 @@ class MANTID_GEOMETRY_DLL GeometryRenderer { SegmentedCylinder }; -public: GeometryRenderer() = default; ~GeometryRenderer() = default; - template - void Render(Args &&... args, RenderMode mode = RenderMode::Basic) const; + template void Render(RenderMode mode, Args &&... args) &; + + template void Render(Args &&... args) &; private: - RenderMode m_RenderMode; + RenderMode m_renderMode; // general geometry /// Render IObjComponent void doRender(IObjComponent *ObjComp) const; @@ -88,7 +89,7 @@ class MANTID_GEOMETRY_DLL GeometryRenderer { }; template -void GeometryRenderer::Render(Args &&... args, RenderMode mode) const { +void GeometryRenderer::Render(RenderMode mode, Args &&... args) & { // Wait for no OopenGL error while (glGetError() != GL_NO_ERROR) ; @@ -96,6 +97,9 @@ void GeometryRenderer::Render(Args &&... args, RenderMode mode) const { doRender(std::forward(args)...); } +template void GeometryRenderer::Render(Args &&... args) & { + Render(RenderMode::Basic, std::forward(args)...); +} } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp index abf8021c0a6c..14e0651b33cc 100644 --- a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp @@ -58,73 +58,7 @@ void BitmapGeometryHandler::Triangulate() { //---------------------------------------------------------------------------------------------- ///< Render Object or ObjComponent void BitmapGeometryHandler::Render() { - // std::cout << "BitmapGeometryHandler::Render() called\n"; - V3D pos; - - // Wait for no error - while (glGetError() != GL_NO_ERROR) - ; - - // Because texture colours are combined with the geometry colour - // make sure the current colour is white - glColor3f(1.0f, 1.0f, 1.0f); - - // Nearest-neighbor scaling - GLint texParam = GL_NEAREST; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam); - - glEnable(GL_TEXTURE_2D); // enable texture mapping - - int texx, texy; - m_rectDet->getTextureSize(texx, texy); - double tex_frac_x = (1.0 * m_rectDet->xpixels()) / (texx); - double tex_frac_y = (1.0 * m_rectDet->ypixels()) / (texy); - - // Point to the ID of the texture that was created before - in - // RectangularDetectorActor. - // int texture_id = m_rectDet->getTextureID(); - // glBindTexture (GL_TEXTURE_2D, texture_id); - // if (glGetError()>0) std::cout << "OpenGL error in glBindTexture \n"; - - glBegin(GL_QUADS); - - glTexCoord2f(0.0, 0.0); - pos = m_rectDet->getRelativePosAtXY(0, 0); - pos += V3D(m_rectDet->xstep() * (-0.5), m_rectDet->ystep() * (-0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glTexCoord2f(static_cast(tex_frac_x), 0.0); - pos = m_rectDet->getRelativePosAtXY(m_rectDet->xpixels() - 1, 0); - pos += V3D(m_rectDet->xstep() * (+0.5), m_rectDet->ystep() * (-0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glTexCoord2f(static_cast(tex_frac_x), - static_cast(tex_frac_y)); - pos = m_rectDet->getRelativePosAtXY(m_rectDet->xpixels() - 1, - m_rectDet->ypixels() - 1); - pos += V3D(m_rectDet->xstep() * (+0.5), m_rectDet->ystep() * (+0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glTexCoord2f(0.0, static_cast(tex_frac_y)); - pos = m_rectDet->getRelativePosAtXY(0, m_rectDet->ypixels() - 1); - pos += V3D(m_rectDet->xstep() * (-0.5), m_rectDet->ystep() * (+0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glEnd(); - if (glGetError() > 0) - std::cout << "OpenGL error in BitmapGeometryHandler::Render \n"; - - glDisable( - GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. + m_renderer.Render(m_rectDet); } //---------------------------------------------------------------------------------------------- diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 1d8612460364..e15226cc82c6 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -1,4 +1,5 @@ #include "MantidGeometry/Rendering/GeometryHandler.h" +#include "MantidKernel/make_unique.h" namespace Mantid { namespace Geometry { @@ -7,7 +8,8 @@ namespace Geometry { * @param[in] comp * This geometry handler will be ObjComponent's geometry handler */ -GeometryHandler::GeometryHandler(IObjComponent *comp) : Obj() { +GeometryHandler::GeometryHandler(IObjComponent *comp) + : Obj() { ObjComp = comp; boolTriangulated = true; boolIsInitialized = false; diff --git a/Framework/Geometry/src/GeometryRenderer.cpp b/Framework/Geometry/src/Rendering/GeometryRenderer.cpp similarity index 99% rename from Framework/Geometry/src/GeometryRenderer.cpp rename to Framework/Geometry/src/Rendering/GeometryRenderer.cpp index 5ff4efafd434..50f5656d01a3 100644 --- a/Framework/Geometry/src/GeometryRenderer.cpp +++ b/Framework/Geometry/src/Rendering/GeometryRenderer.cpp @@ -1,4 +1,4 @@ -#include "MantidGeometry/GeometryRenderer.h" +#include "MantidGeometry/Rendering/GeometryRenderer.h" #include "MantidGeometry/Instrument/ObjComponent.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Instrument/StructuredDetector.h" From a495797f8ea40179002db66c4a3fbeaacc5b53a4 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 23 Nov 2017 15:26:46 +0000 Subject: [PATCH 013/364] updated other handlers and removed renderers re #21248 --- Framework/Geometry/CMakeLists.txt | 6 - .../Rendering/CacheGeometryHandler.h | 3 - .../Rendering/CacheGeometryRenderer.h | 57 ---- .../Rendering/GeometryRenderer.h | 63 +++- .../Rendering/GluGeometryHandler.h | 3 - .../Rendering/GluGeometryRenderer.h | 91 ------ .../Rendering/OCGeometryHandler.h | 4 +- .../Rendering/OCGeometryRenderer.h | 57 ---- .../src/Rendering/BitmapGeometryHandler.cpp | 2 +- .../src/Rendering/CacheGeometryHandler.cpp | 15 +- .../src/Rendering/CacheGeometryRenderer.cpp | 76 ----- .../src/Rendering/GeometryRenderer.cpp | 61 +++- .../src/Rendering/GluGeometryHandler.cpp | 44 +-- .../src/Rendering/GluGeometryRenderer.cpp | 298 ------------------ .../src/Rendering/OCGeometryHandler.cpp | 28 +- .../src/Rendering/OCGeometryRenderer.cpp | 196 ------------ .../Rendering/StructuredGeometryHandler.cpp | 53 +--- .../src/Rendering/vtkGeometryCacheWriter.cpp | 1 + 18 files changed, 135 insertions(+), 923 deletions(-) delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryRenderer.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryRenderer.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryRenderer.h delete mode 100644 Framework/Geometry/src/Rendering/CacheGeometryRenderer.cpp delete mode 100644 Framework/Geometry/src/Rendering/GluGeometryRenderer.cpp delete mode 100644 Framework/Geometry/src/Rendering/OCGeometryRenderer.cpp diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index 26425dd51736..0daa550f2d33 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -112,10 +112,8 @@ set ( SRC_FILES src/Rendering/CacheGeometryGenerator.cpp src/Rendering/CacheGeometryHandler.cpp src/Rendering/GeometryRenderer.cpp - src/Rendering/CacheGeometryRenderer.cpp src/Rendering/GeometryHandler.cpp src/Rendering/GluGeometryHandler.cpp - src/Rendering/GluGeometryRenderer.cpp src/Rendering/StructuredGeometryHandler.cpp src/Rendering/vtkGeometryCacheReader.cpp src/Rendering/vtkGeometryCacheWriter.cpp @@ -135,7 +133,6 @@ set ( SRC_FILES set ( OPENCASCADE_SRC src/Rendering/OCGeometryGenerator.cpp src/Rendering/OCGeometryHandler.cpp - src/Rendering/OCGeometryRenderer.cpp ) set ( SRC_UNITY_IGNORE_FILES src/Instrument/CompAssembly.cpp @@ -276,13 +273,10 @@ set ( INC_FILES inc/MantidGeometry/Rendering/BitmapGeometryHandler.h inc/MantidGeometry/Rendering/CacheGeometryGenerator.h inc/MantidGeometry/Rendering/CacheGeometryHandler.h - inc/MantidGeometry/Rendering/CacheGeometryRenderer.h inc/MantidGeometry/Rendering/GeometryHandler.h inc/MantidGeometry/Rendering/GluGeometryHandler.h - inc/MantidGeometry/Rendering/GluGeometryRenderer.h inc/MantidGeometry/Rendering/OCGeometryGenerator.h inc/MantidGeometry/Rendering/OCGeometryHandler.h - inc/MantidGeometry/Rendering/OCGeometryRenderer.h inc/MantidGeometry/Rendering/GeometryRenderer.h inc/MantidGeometry/Rendering/OpenGL_Headers.h inc/MantidGeometry/Rendering/StructuredGeometryHandler.h diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h index 84246c28b736..418a8163f2ce 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h @@ -11,7 +11,6 @@ class V3D; namespace Geometry { class GeometryHandler; -class CacheGeometryRenderer; class CacheGeometryGenerator; class IObjComponent; class CSGObject; @@ -50,8 +49,6 @@ class CSGObject; */ class MANTID_GEOMETRY_DLL CacheGeometryHandler : public GeometryHandler { private: - CacheGeometryRenderer *Renderer; ///< Geometry renderer variable used for - /// rendering Object/ObjComponent CacheGeometryGenerator * Triangulator; ///< Geometry generator to triangulate Object diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryRenderer.h deleted file mode 100644 index 708cb3b70b21..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryRenderer.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef CACHE_GEOMETRYRENDERER_H -#define CACHE_GEOMETRYRENDERER_H - -#include "MantidGeometry/DllConfig.h" - -namespace Mantid { -namespace Kernel { -class V3D; -} -namespace Geometry { -class IObjComponent; -/** - \class CacheGeometryRenderer - \brief rendering geometry using opengl from the geometry cache. - \author Srikanth Nagella - \date Jan 2009 - \version 1.0 - - This is an concrete class for rendering cached geometry using opengl. - - Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MANTID_GEOMETRY_DLL CacheGeometryRenderer { -public: - /// Render using an object component - void Render(IObjComponent *ObjComp) const; - /// Render using triangulation information - void Render(int noPts, int noFaces, double *points, int *faces) const; - /// Initialize using triangulation information - void Initialize(int noPts, int noFaces, double *points, int *faces) const; - /// Initialize using an object component - void Initialize(IObjComponent *ObjComp); -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h index f8f545fb56fc..f7bc0a5facb7 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h @@ -41,25 +41,52 @@ class IObjComponent; class MANTID_GEOMETRY_DLL GeometryRenderer { public: enum class RenderMode { Basic, Volumetric }; - - enum class RenderShape { - Sphere, - Cube, - Cone, - Hexahedron, - Cylinder, - SegmentedCylinder - }; - GeometryRenderer() = default; ~GeometryRenderer() = default; - template void Render(RenderMode mode, Args &&... args) &; + /// General method for rendering geometry + template + void render(RenderMode mode, Args &&... args) const &; - template void Render(Args &&... args) &; + /// Render Basic geometry without transparency (non-volumetric) + template void render(Args &&... args) const &; + + /// Render IObjComponent + void renderIObjComponent(IObjComponent *objComp, + RenderMode mode = RenderMode::Basic) const; + /// Render Traingulated Surface + void renderTriangulated(int noPts, int noFaces, double *points, int *faces, + RenderMode mode = RenderMode::Basic) const; + /// Render OpenCascade Shape + void renderOpenCascade(TopoDS_Shape *objSurf, + RenderMode mode = RenderMode::Basic) const; + /// Renders a sphere + void renderSphere(const Kernel::V3D ¢er, double radius, + RenderMode mode = RenderMode::Basic) const; + /// Renders a cuboid + void renderCuboid(const Kernel::V3D &Point1, const Kernel::V3D &Point2, + const Kernel::V3D &Point3, const Kernel::V3D &Point4, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Hexahedron from the input values + void renderHexahedron(const std::vector &points, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Cone from the input values + void renderCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Cylinder/Segmented cylinder from the input values + void renderCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, bool segmented = false, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Bitmap (used for rendering RectangularDetector) + void renderBitmap(const RectangularDetector *rectDet, + RenderMode mode = RenderMode::Basic) const; + /// Renders structured geometry (used for rendering StructuredDetector) + void renderStructured(const StructuredDetector *structDet, + RenderMode mode = RenderMode::Basic) const; private: - RenderMode m_renderMode; + mutable RenderMode m_renderMode; // general geometry /// Render IObjComponent void doRender(IObjComponent *ObjComp) const; @@ -81,7 +108,7 @@ class MANTID_GEOMETRY_DLL GeometryRenderer { double radius, double height) const; /// Renders a Cylinder/Segmented cylinder from the input values void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, bool segmented = false) const; + double radius, double height, bool segmented) const; /// Renders a Bitmap (used for rendering RectangularDetector) void doRender(const RectangularDetector *rectDet) const; /// Renders structured geometry (used for rendering StructuredDetector) @@ -89,7 +116,7 @@ class MANTID_GEOMETRY_DLL GeometryRenderer { }; template -void GeometryRenderer::Render(RenderMode mode, Args &&... args) & { +void GeometryRenderer::render(RenderMode mode, Args &&... args) const & { // Wait for no OopenGL error while (glGetError() != GL_NO_ERROR) ; @@ -97,9 +124,11 @@ void GeometryRenderer::Render(RenderMode mode, Args &&... args) & { doRender(std::forward(args)...); } -template void GeometryRenderer::Render(Args &&... args) & { - Render(RenderMode::Basic, std::forward(args)...); +template +void GeometryRenderer::render(Args &&... args) const & { + render(RenderMode::Basic, std::forward(args)...); } + } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h index d8497b6cc5d3..04c8cf36264f 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h @@ -10,7 +10,6 @@ class V3D; } namespace Geometry { class GeometryHandler; -class GluGeometryRenderer; class IObjComponent; class CSGObject; /** @@ -61,8 +60,6 @@ class MANTID_GEOMETRY_DLL GluGeometryHandler : public GeometryHandler { private: static Kernel::Logger &PLog; ///< The official logger - std::unique_ptr Renderer; ///< Geometry renderer variable - /// used for rendering /// Object/ObjComponent std::vector m_points; double radius; ///. - - File change history is stored at: -*/ -class MANTID_GEOMETRY_DLL GluGeometryRenderer { -public: - /// Renders an object component - void Render(IObjComponent *ObjComp) const; - /// Renders a Sphere from the input values - void RenderSphere(const Kernel::V3D ¢er, double radius); - /// Renders a Cuboid from the input values - void RenderCube(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4); - /// Renders a Hexahedron from the input values - void RenderHexahedron(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4, - const Kernel::V3D &Point5, const Kernel::V3D &Point6, - const Kernel::V3D &Point7, const Kernel::V3D &Point8); - /// Renders a Cone from the input values - void RenderCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height); - /// Renders a Cylinder from the input values - void RenderCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height); - /// Renders a Segmented Cylinder from the input values - void RenderSegmentedCylinder(const Kernel::V3D ¢er, - const Kernel::V3D &axis, double radius, - double height); - /// Creates a sphere from the input values - void CreateSphere(const Kernel::V3D ¢er, double radius); - /// Creates a cuboid from the input values - void CreateCube(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4); - /// Creates a Hexahedron from the input values - void CreateHexahedron(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4, - const Kernel::V3D &Point5, const Kernel::V3D &Point6, - const Kernel::V3D &Point7, const Kernel::V3D &Point8); - /// Creates a Cone from the input values - void CreateCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height); - /// Creates a cylinder from the input values - void CreateCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height); - /// Creates a segmented cylinder from the input values - void CreateSegmentedCylinder(const Kernel::V3D ¢er, - const Kernel::V3D &axis, double radius, - double height); -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h index b6482ce7e574..00bf28e653a4 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h @@ -2,12 +2,12 @@ #define OC_GEOMETRYHANDLER_H #include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" namespace Mantid { namespace Geometry { class GeometryHandler; -class OCGeometryRenderer; class OCGeometryGenerator; class IObjComponent; class CSGObject; @@ -50,8 +50,6 @@ class CSGObject; class MANTID_GEOMETRY_DLL OCGeometryHandler : public GeometryHandler { private: static Kernel::Logger &PLog; ///< The official logger - OCGeometryRenderer *Renderer; ///< Geometry renderer variable used for - /// rendering Object/ObjComponent OCGeometryGenerator * Triangulator; ///< Geometry generator to triangulate Object public: diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryRenderer.h deleted file mode 100644 index a9ab4715e1a4..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryRenderer.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef OC_GEOMETRYRENDERER_H -#define OC_GEOMETRYRENDERER_H - -#include "MantidGeometry/DllConfig.h" -#include "MantidKernel/Logger.h" -class TopoDS_Shape; -namespace Mantid { - -namespace Geometry { -class IObjComponent; -/** - \class OCGeometryRenderer - \brief rendering geometry primitives of OpenCascade - \author Srikanth Nagella - \date July 2008 - \version 1.0 - - This is an concrete class for rendering GtsSurface using opengl. - - Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MANTID_GEOMETRY_DLL OCGeometryRenderer { -private: - static Kernel::Logger &PLog; ///< The official logger - void RenderTopoDS(TopoDS_Shape *ObjSurf); - -public: - void Render(TopoDS_Shape *ObjSurf); - void Render(IObjComponent *ObjComp); - void Initialize(TopoDS_Shape *ObjSurf); - void Initialize(IObjComponent *ObjComp); - void WriteVTK(TopoDS_Shape *out); -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp index 14e0651b33cc..16f4e64eb05c 100644 --- a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp @@ -58,7 +58,7 @@ void BitmapGeometryHandler::Triangulate() { //---------------------------------------------------------------------------------------------- ///< Render Object or ObjComponent void BitmapGeometryHandler::Render() { - m_renderer.Render(m_rectDet); + m_renderer.render(m_rectDet); } //---------------------------------------------------------------------------------------------- diff --git a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp index 73b21d125a5b..b718baedc4df 100644 --- a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp @@ -2,7 +2,6 @@ #include "MantidGeometry/Instrument/ObjComponent.h" #include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/CacheGeometryHandler.h" -#include "MantidGeometry/Rendering/CacheGeometryRenderer.h" #include "MantidGeometry/Rendering/CacheGeometryGenerator.h" #include "MantidKernel/MultiThreaded.h" @@ -14,24 +13,20 @@ namespace Geometry { CacheGeometryHandler::CacheGeometryHandler(IObjComponent *comp) : GeometryHandler(comp) { Triangulator = nullptr; - Renderer = new CacheGeometryRenderer(); } CacheGeometryHandler::CacheGeometryHandler(boost::shared_ptr obj) : GeometryHandler(obj) { Triangulator = new CacheGeometryGenerator(obj.get()); - Renderer = new CacheGeometryRenderer(); } CacheGeometryHandler::CacheGeometryHandler(CSGObject *obj) : GeometryHandler(obj) { Triangulator = new CacheGeometryGenerator(obj); - Renderer = new CacheGeometryRenderer(); } boost::shared_ptr CacheGeometryHandler::clone() const { auto clone = boost::make_shared(*this); - clone->Renderer = new CacheGeometryRenderer(*(this->Renderer)); if (this->Triangulator) clone->Triangulator = new CacheGeometryGenerator(this->Obj); else @@ -42,8 +37,6 @@ boost::shared_ptr CacheGeometryHandler::clone() const { CacheGeometryHandler::~CacheGeometryHandler() { if (Triangulator != nullptr) delete Triangulator; - if (Renderer != nullptr) - delete Renderer; } GeometryHandler *CacheGeometryHandler::createInstance(IObjComponent *comp) { @@ -72,11 +65,11 @@ void CacheGeometryHandler::Render() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - Renderer->Render( + m_renderer.renderTriangulated( Triangulator->getNumberOfPoints(), Triangulator->getNumberOfTriangles(), Triangulator->getTriangleVertices(), Triangulator->getTriangleFaces()); } else if (ObjComp != nullptr) { - Renderer->Render(ObjComp); + m_renderer.render(ObjComp); } } @@ -85,11 +78,11 @@ void CacheGeometryHandler::Initialize() { Obj->updateGeometryHandler(); if (!boolTriangulated) Triangulate(); - Renderer->Initialize( + m_renderer.renderTriangulated( Triangulator->getNumberOfPoints(), Triangulator->getNumberOfTriangles(), Triangulator->getTriangleVertices(), Triangulator->getTriangleFaces()); } else if (ObjComp != nullptr) { - Renderer->Initialize(ObjComp); + m_renderer.render(ObjComp); } } diff --git a/Framework/Geometry/src/Rendering/CacheGeometryRenderer.cpp b/Framework/Geometry/src/Rendering/CacheGeometryRenderer.cpp deleted file mode 100644 index a34f7e042fb5..000000000000 --- a/Framework/Geometry/src/Rendering/CacheGeometryRenderer.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "MantidGeometry/Rendering/CacheGeometryRenderer.h" -#include "MantidGeometry/Rendering/OpenGL_Headers.h" -#include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidKernel/Quat.h" -#include - -namespace Mantid { -namespace Geometry { -using Kernel::V3D; -using Kernel::Quat; - -/** - * Render ObjComponent - * @param ObjComp :: input to render - */ -void CacheGeometryRenderer::Render(IObjComponent *ObjComp) const { - glPushMatrix(); - V3D pos = ObjComp->getPos(); - Quat rot = ObjComp->getRotation(); - double rotGL[16]; - rot.GLMatrix(&rotGL[0]); - glTranslated(pos[0], pos[1], pos[2]); - glMultMatrixd(rotGL); - V3D scaleFactor = ObjComp->getScaleFactor(); - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - ObjComp->drawObject(); - glPopMatrix(); -} - -void CacheGeometryRenderer::Render(int noPts, int noFaces, double *points, - int *faces) const { - (void)noPts; - (void)noFaces; - (void)points; - (void)faces; // Avoid compiler warning - Initialize(noPts, noFaces, points, faces); -} - -void CacheGeometryRenderer::Initialize(int noPts, int noFaces, double *points, - int *faces) const { - (void)noPts; // Avoid compiler warning - glBegin(GL_TRIANGLES); - V3D normal; - for (int i = 0; i < noFaces; i++) { - int index1 = faces[i * 3] * 3; - int index2 = faces[i * 3 + 1] * 3; - int index3 = faces[i * 3 + 2] * 3; - // Calculate normal and normalize - V3D v1(points[index1], points[index1 + 1], points[index1 + 2]); - V3D v2(points[index2], points[index2 + 1], points[index2 + 2]); - V3D v3(points[index3], points[index3 + 1], points[index3 + 2]); - normal = (v1 - v2).cross_prod(v2 - v3); - normal.normalize(); - glNormal3d(normal[0], normal[1], normal[2]); - glVertex3dv(points + index1); - glVertex3dv(points + index2); - glVertex3dv(points + index3); - } - glEnd(); -} - -void CacheGeometryRenderer::Initialize(IObjComponent *ObjComp) { - glPushMatrix(); - V3D pos = ObjComp->getPos(); - Quat rot = ObjComp->getRotation(); - double rotGL[16]; - rot.GLMatrix(&rotGL[0]); - glTranslated(pos[0], pos[1], pos[2]); - glMultMatrixd(rotGL); - V3D scaleFactor = ObjComp->getScaleFactor(); - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - ObjComp->drawObject(); - glPopMatrix(); -} -} -} diff --git a/Framework/Geometry/src/Rendering/GeometryRenderer.cpp b/Framework/Geometry/src/Rendering/GeometryRenderer.cpp index 50f5656d01a3..7a7f07edd137 100644 --- a/Framework/Geometry/src/Rendering/GeometryRenderer.cpp +++ b/Framework/Geometry/src/Rendering/GeometryRenderer.cpp @@ -49,6 +49,63 @@ namespace Geometry { using Kernel::Quat; using Kernel::V3D; +void GeometryRenderer::renderIObjComponent(IObjComponent *objComp, + RenderMode mode) const { + render(mode, objComp); +} + +void GeometryRenderer::renderTriangulated(int noPts, int noFaces, + double *points, int *faces, + RenderMode mode) const { + render(mode, noPts, noFaces, points, faces); +} + +void GeometryRenderer::renderOpenCascade(TopoDS_Shape *objSurf, + RenderMode mode) const { + render(mode, objSurf); +} + +void GeometryRenderer::renderSphere(const Kernel::V3D ¢er, double radius, + RenderMode mode) const { + render(mode, center, radius); +} + +void GeometryRenderer::renderCuboid(const Kernel::V3D &Point1, + const Kernel::V3D &Point2, + const Kernel::V3D &Point3, + const Kernel::V3D &Point4, + RenderMode mode) const { + render(mode, Point1, Point2, Point3, Point4); +} + +void GeometryRenderer::renderHexahedron(const std::vector &points, + RenderMode mode) const { + render(mode, points); +} + +void GeometryRenderer::renderCone(const Kernel::V3D ¢er, + const Kernel::V3D &axis, double radius, + double height, RenderMode mode) const { + render(mode, center, axis, radius, height); +} + +void GeometryRenderer::renderCylinder(const Kernel::V3D ¢er, + const Kernel::V3D &axis, double radius, + double height, bool segmented, + RenderMode mode) const { + render(mode, center, axis, radius, height, segmented); +} + +void GeometryRenderer::renderBitmap(const RectangularDetector *rectDet, + RenderMode mode) const { + render(mode, rectDet); +} + +void GeometryRenderer::renderStructured(const StructuredDetector *structDet, + RenderMode mode) const { + render(mode, structDet); +} + // Render IObjectComponent void GeometryRenderer::doRender(IObjComponent *ObjComp) const { glPushMatrix(); @@ -332,7 +389,7 @@ void GeometryRenderer::doRender(const RectangularDetector *rectDet) const { glEnd(); if (glGetError() > 0) - std::cout << "OpenGL error in BitmapGeometryHandler::Render \n"; + std::cout << "OpenGL error in BitmapGeometryHandler::render \n"; glDisable( GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. @@ -379,7 +436,7 @@ void GeometryRenderer::doRender(const StructuredDetector *structDet) const { glEnd(); if (glGetError() > 0) - std::cout << "OpenGL error in StructuredGeometryHandler::Render \n"; + std::cout << "OpenGL error in StructuredGeometryHandler::render \n"; glDisable( GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. diff --git a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp index 03afce3a4ba8..4c2c8e1a93b5 100644 --- a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp @@ -2,7 +2,6 @@ #include "MantidGeometry/Instrument/ObjComponent.h" #include "MantidGeometry/Objects/CSGObject.h" #include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidGeometry/Rendering/GluGeometryRenderer.h" #include "MantidKernel/make_unique.h" #include @@ -12,24 +11,20 @@ namespace Geometry { using Kernel::V3D; GluGeometryHandler::GluGeometryHandler(IObjComponent *comp) - : GeometryHandler(comp), - Renderer(Kernel::make_unique()), radius(0.0), - height(0.0), type(GeometryType::NOSHAPE) {} + : GeometryHandler(comp), radius(0.0), height(0.0), + type(GeometryType::NOSHAPE) {} GluGeometryHandler::GluGeometryHandler(boost::shared_ptr obj) - : GeometryHandler(std::move(obj)), - Renderer(Kernel::make_unique()), radius(0.0), - height(0.0), type(GeometryType::NOSHAPE) {} + : GeometryHandler(std::move(obj)), radius(0.0), height(0.0), + type(GeometryType::NOSHAPE) {} GluGeometryHandler::GluGeometryHandler(CSGObject *obj) - : GeometryHandler(obj), - Renderer(Kernel::make_unique()), radius(0.0), - height(0.0), type(GeometryType::NOSHAPE) {} + : GeometryHandler(obj), radius(0.0), height(0.0), + type(GeometryType::NOSHAPE) {} GluGeometryHandler::GluGeometryHandler(const GluGeometryHandler &other) : GeometryHandler(other), m_points(other.m_points), radius(other.radius), height(other.height), type(other.type) { - this->Renderer = Kernel::make_unique(); } boost::shared_ptr GluGeometryHandler::clone() const { @@ -61,31 +56,31 @@ void GluGeometryHandler::Render() { if (Obj != nullptr) { switch (type) { case GeometryType::CUBOID: - Renderer->RenderCube(m_points[0], m_points[1], m_points[2], m_points[3]); + m_renderer.renderCuboid(m_points[0], m_points[1], m_points[2], + m_points[3]); break; case GeometryType::HEXAHEDRON: - Renderer->RenderHexahedron(m_points[0], m_points[1], m_points[2], - m_points[3], m_points[4], m_points[5], - m_points[6], m_points[7]); + m_renderer.renderHexahedron( + std::vector{m_points[0], m_points[1], m_points[2], m_points[3], + m_points[4], m_points[5], m_points[6], m_points[7]}); break; case GeometryType::SPHERE: - Renderer->RenderSphere(m_points[0], radius); + m_renderer.renderSphere(m_points[0], radius); break; case GeometryType::CYLINDER: - Renderer->RenderCylinder(m_points[0], m_points[1], radius, height); + m_renderer.renderCylinder(m_points[0], m_points[1], radius, height); break; case GeometryType::CONE: - Renderer->RenderCone(m_points[0], m_points[1], radius, height); + m_renderer.renderCone(m_points[0], m_points[1], radius, height); break; case GeometryType::SEGMENTED_CYLINDER: - Renderer->RenderSegmentedCylinder(m_points[0], m_points[1], radius, - height); + m_renderer.renderCylinder(m_points[0], m_points[1], radius, height, true); break; case GeometryType::NOSHAPE: break; } } else if (ObjComp != nullptr) { - Renderer->Render(ObjComp); + m_renderer.render(ObjComp); } } @@ -112,12 +107,7 @@ void GluGeometryHandler::GetObjectGeom(int &mytype, } } -void GluGeometryHandler::Initialize() { - if (Obj != nullptr) { - // There is no initialization or probably call render - Render(); - } -} +void GluGeometryHandler::Initialize() { Render(); } void GluGeometryHandler::setCuboid(const V3D &p1, const V3D &p2, const V3D &p3, const V3D &p4) { diff --git a/Framework/Geometry/src/Rendering/GluGeometryRenderer.cpp b/Framework/Geometry/src/Rendering/GluGeometryRenderer.cpp deleted file mode 100644 index fca52b379211..000000000000 --- a/Framework/Geometry/src/Rendering/GluGeometryRenderer.cpp +++ /dev/null @@ -1,298 +0,0 @@ -#include "MantidGeometry/Rendering/GluGeometryRenderer.h" -#include "MantidGeometry/Rendering/OpenGL_Headers.h" -#include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidKernel/Quat.h" -#include "MantidGeometry/Surfaces/Cylinder.h" -#include "MantidGeometry/Surfaces/Cone.h" -#include "MantidGeometry/Surfaces/Sphere.h" -#include - -namespace Mantid { -namespace Geometry { -using Kernel::V3D; -using Kernel::Quat; - -void GluGeometryRenderer::RenderSphere(const V3D ¢er, double radius) { - while (glGetError() != GL_NO_ERROR) - ; - CreateSphere(center, radius); -} - -void GluGeometryRenderer::RenderCube(const V3D &Point1, const V3D &Point2, - const V3D &Point3, const V3D &Point4) { - while (glGetError() != GL_NO_ERROR) - ; - CreateCube(Point1, Point2, Point3, Point4); -} - -void GluGeometryRenderer::RenderHexahedron( - const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4, - const Kernel::V3D &Point5, const Kernel::V3D &Point6, - const Kernel::V3D &Point7, const Kernel::V3D &Point8) { - - while (glGetError() != GL_NO_ERROR) - ; - CreateHexahedron(Point1, Point2, Point3, Point4, Point5, Point6, Point7, - Point8); -} - -void GluGeometryRenderer::RenderCone(const V3D ¢er, const V3D &axis, - double radius, double height) { - while (glGetError() != GL_NO_ERROR) - ; - CreateCone(center, axis, radius, height); -} - -void GluGeometryRenderer::RenderCylinder(const V3D ¢er, const V3D &axis, - double radius, double height) { - while (glGetError() != GL_NO_ERROR) - ; - CreateCylinder(center, axis, radius, height); -} - -void GluGeometryRenderer::RenderSegmentedCylinder(const V3D ¢er, - const V3D &axis, - double radius, - double height) { - while (glGetError() != GL_NO_ERROR) - ; - CreateSegmentedCylinder(center, axis, radius, height); -} - -/** - * Render ObjComponent - * @param ObjComp :: input to render - */ -void GluGeometryRenderer::Render(IObjComponent *ObjComp) const { - glPushMatrix(); - V3D pos = ObjComp->getPos(); - Quat rot = ObjComp->getRotation(); - double rotGL[16]; - rot.GLMatrix(&rotGL[0]); - glTranslated(pos[0], pos[1], pos[2]); - glMultMatrixd(rotGL); - ObjComp->drawObject(); - glPopMatrix(); -} - -/** - * Creates a GLU Sphere - * @param center :: center of the sphere - * @param radius :: radius of the sphere - */ -void GluGeometryRenderer::CreateSphere(const V3D ¢er, double radius) { - // create glu sphere - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - glPushMatrix(); - glTranslated(center[0], center[1], center[2]); - gluSphere(qobj, radius, Geometry::Sphere::g_nslices, - Geometry::Sphere::g_nstacks); - glPopMatrix(); - gluDeleteQuadric(qobj); -} - -/** - * Creates a Cube - * @param Point1 :: first point of the cube - * @param Point2 :: second point of the cube - * @param Point3 :: thrid point of the cube - * @param Point4 :: fourth point of the cube - */ -void GluGeometryRenderer::CreateCube(const V3D &Point1, const V3D &Point2, - const V3D &Point3, const V3D &Point4) { - V3D vec0 = Point1; - V3D vec1 = Point2 - Point1; - V3D vec2 = Point3 - Point1; - V3D vec3 = Point4 - Point1; - V3D vertex[8]; - vertex[0] = vec0; - vertex[1] = vec0 + vec3; - vertex[2] = vec0 + vec3 + vec1; - vertex[3] = vec0 + vec1; - vertex[4] = vec0 + vec2; - vertex[5] = vec0 + vec2 + vec3; - vertex[6] = vec0 + vec2 + vec3 + vec1; - vertex[7] = vec0 + vec1 + vec2; - // int - // faceindex[6][4]={{0,1,2,3},{0,3,7,4},{3,2,6,7},{2,1,5,6},{0,4,5,1},{4,7,6,5}}; - // int - // faceindex[6][4]={{0,3,2,1},{0,4,7,3},{3,7,6,2},{2,6,5,1},{0,1,5,4},{4,5,6,7}}; - int faceindex[6][4] = { - {0, 1, 2, 3}, // top - {0, 3, 7, 4}, // left - {3, 2, 6, 7}, // back - {2, 1, 5, 6}, // right - {0, 4, 5, 1}, // front - {4, 7, 6, 5}, // bottom - }; - V3D normal; - // first face - glBegin(GL_QUADS); - for (auto &row : faceindex) { - normal = (vertex[row[0]] - vertex[row[1]]) - .cross_prod((vertex[row[0]] - vertex[row[2]])); - normal.normalize(); - glNormal3d(normal[0], normal[1], normal[2]); - for (const int ij : row) { - if (ij == 0) - glTexCoord2i(0, 0); - if (ij == 1) - glTexCoord2i(1, 0); - if (ij == 2) - glTexCoord2i(1, 1); - if (ij == 3) - glTexCoord2i(0, 1); - if (ij == 4) - glTexCoord2i(0, 0); - if (ij == 5) - glTexCoord2i(1, 0); - if (ij == 6) - glTexCoord2i(1, 1); - if (ij == 7) - glTexCoord2i(0, 1); - glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]); - } - } - glEnd(); -} - -/** -* Creates a Hexahedron -* @param Point1 :: first point of the hexahedron -* @param Point2 :: second point of the hexahedron -* @param Point3 :: third point of the hexahedron -* @param Point4 :: fourth point of the hexahedron -* @param Point5 :: fifth point of the hexahedron -* @param Point6 :: sixth point of the hexahedron -* @param Point7 :: seventh point of the hexahedron -* @param Point8 :: eigth point of the hexahedron -*/ -void GluGeometryRenderer::CreateHexahedron( - const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4, - const Kernel::V3D &Point5, const Kernel::V3D &Point6, - const Kernel::V3D &Point7, const Kernel::V3D &Point8) { - - glBegin(GL_QUADS); - - // bottom - glVertex3d(Point1.X(), Point1.Y(), Point1.Z()); - glVertex3d(Point2.X(), Point2.Y(), Point2.Z()); - glVertex3d(Point3.X(), Point3.Y(), Point3.Z()); - glVertex3d(Point4.X(), Point4.Y(), Point4.Z()); - - // front - glVertex3d(Point2.X(), Point2.Y(), Point2.Z()); - glVertex3d(Point6.X(), Point6.Y(), Point6.Z()); - glVertex3d(Point7.X(), Point7.Y(), Point7.Z()); - glVertex3d(Point3.X(), Point3.Y(), Point3.Z()); - - // right - glVertex3d(Point3.X(), Point3.Y(), Point3.Z()); - glVertex3d(Point7.X(), Point7.Y(), Point7.Z()); - glVertex3d(Point8.X(), Point8.Y(), Point8.Z()); - glVertex3d(Point4.X(), Point4.Y(), Point4.Z()); - - // back - glVertex3d(Point4.X(), Point4.Y(), Point4.Z()); - glVertex3d(Point8.X(), Point8.Y(), Point8.Z()); - glVertex3d(Point5.X(), Point5.Y(), Point5.Z()); - glVertex3d(Point1.X(), Point1.Y(), Point1.Z()); - - // left - glVertex3d(Point1.X(), Point1.Y(), Point1.Z()); - glVertex3d(Point5.X(), Point5.Y(), Point5.Z()); - glVertex3d(Point6.X(), Point6.Y(), Point6.Z()); - glVertex3d(Point2.X(), Point2.Y(), Point2.Z()); - - // top - glVertex3d(Point5.X(), Point5.Y(), Point5.Z()); - glVertex3d(Point6.X(), Point6.Y(), Point6.Z()); - glVertex3d(Point7.X(), Point7.Y(), Point7.Z()); - glVertex3d(Point8.X(), Point8.Y(), Point8.Z()); - - glEnd(); -} - -/** - * Creates a Cone - * @param center :: center of the cone - * @param axis :: axis of the cone - * @param radius :: radius of the cone - * @param height :: height of the cone - */ -void GluGeometryRenderer::CreateCone(const V3D ¢er, const V3D &axis, - double radius, double height) { - glPushMatrix(); - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - glTranslated(center[0], center[1], center[2]); - GLdouble mat[16]; - V3D unit(0, 0, 1); - Quat rot(unit, axis); - rot.GLMatrix(&mat[0]); - glMultMatrixd(mat); - gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, - Geometry::Cone::g_nstacks); - glTranslated(0.0, 0.0, height); - gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); - glPopMatrix(); -} - -/** - * Create a Cylinder - * @param center :: center of the cylinder - * @param axis :: axis of the cylinder - * @param radius :: radius of the cylinder - * @param height :: height of the cylinder - */ -void GluGeometryRenderer::CreateCylinder(const V3D ¢er, const V3D &axis, - double radius, double height) { - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - gluQuadricTexture(qobj, true); - glPushMatrix(); - glTranslated(center[0], center[1], center[2]); - GLdouble mat[16]; - V3D unit(0, 0, 1); - Quat rot(unit, axis); - rot.GLMatrix(&mat[0]); - glMultMatrixd(mat); - gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, - Cylinder::g_nstacks); - gluQuadricTexture(qobj, false); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glTranslated(0.0, 0.0, height); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glPopMatrix(); -} - -void GluGeometryRenderer::CreateSegmentedCylinder(const V3D ¢er, - const V3D &axis, - double radius, - double height) { - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - gluQuadricTexture(qobj, true); - glPushMatrix(); - glTranslated(center[0], center[1], center[2]); - GLdouble mat[16]; - V3D unit(0, 0, 1); - Quat rot(unit, axis); - rot.GLMatrix(&mat[0]); - glMultMatrixd(mat); - gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, 1); - gluQuadricTexture(qobj, false); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glTranslated(0.0, 0.0, height); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glPopMatrix(); -} -} -} diff --git a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp index 739bc990dc9c..b1b95ce04d4b 100644 --- a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp @@ -1,9 +1,5 @@ #include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidGeometry/Rendering/OCGeometryHandler.h" #include "MantidGeometry/Rendering/OCGeometryGenerator.h" -#include "MantidGeometry/Rendering/OCGeometryRenderer.h" #include @@ -12,23 +8,19 @@ namespace Geometry { OCGeometryHandler::OCGeometryHandler(IObjComponent *comp) : GeometryHandler(comp) { Triangulator = nullptr; - Renderer = new OCGeometryRenderer(); } OCGeometryHandler::OCGeometryHandler(boost::shared_ptr obj) : GeometryHandler(obj) { Triangulator = new OCGeometryGenerator(obj.get()); - Renderer = new OCGeometryRenderer(); } OCGeometryHandler::OCGeometryHandler(CSGObject *obj) : GeometryHandler(obj) { Triangulator = new OCGeometryGenerator(obj); - Renderer = new OCGeometryRenderer(); } boost::shared_ptr OCGeometryHandler::clone() const { auto clone = boost::make_shared(*this); - clone->Renderer = new OCGeometryRenderer(*(this->Renderer)); if (this->Triangulator) clone->Triangulator = new OCGeometryGenerator(this->Obj); return clone; @@ -37,8 +29,6 @@ boost::shared_ptr OCGeometryHandler::clone() const { OCGeometryHandler::~OCGeometryHandler() { if (Triangulator != nullptr) delete Triangulator; - if (Renderer != nullptr) - delete Renderer; } GeometryHandler *OCGeometryHandler::createInstance(IObjComponent *comp) { @@ -66,21 +56,13 @@ void OCGeometryHandler::Render() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - Renderer->Render(Triangulator->getObjectSurface()); + m_renderer.render(Triangulator->getObjectSurface()); } else if (ObjComp != nullptr) { - Renderer->Render(ObjComp); + m_renderer.render(ObjComp); } } -void OCGeometryHandler::Initialize() { - if (Obj != nullptr) { - if (!boolTriangulated) - Triangulate(); - Renderer->Initialize(Triangulator->getObjectSurface()); - } else if (ObjComp != nullptr) { - Renderer->Initialize(ObjComp); - } -} +void OCGeometryHandler::Initialize() { Render(); } int OCGeometryHandler::NumberOfTriangles() { if (Obj != nullptr) { @@ -121,5 +103,5 @@ int *OCGeometryHandler::getTriangleFaces() { return nullptr; } } -} -} +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/OCGeometryRenderer.cpp b/Framework/Geometry/src/Rendering/OCGeometryRenderer.cpp deleted file mode 100644 index 1f899f84b1a7..000000000000 --- a/Framework/Geometry/src/Rendering/OCGeometryRenderer.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include "MantidGeometry/Rendering/OCGeometryRenderer.h" -#include "MantidGeometry/Rendering/OpenGL_Headers.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidKernel/V3D.h" -#include "MantidKernel/Quat.h" -#include "MantidKernel/WarningSuppressions.h" -#include - -// Squash a warning coming out of an OpenCascade header -#ifdef __INTEL_COMPILER -#pragma warning disable 191 -#endif -// Opencascade defines _USE_MATH_DEFINES without checking whether it is already -// used. -// Undefine it here before we include the headers to avoid a warning -#ifdef _MSC_VER -#undef _USE_MATH_DEFINES -#ifdef M_SQRT1_2 -#undef M_SQRT1_2 -#endif -#endif - -GCC_DIAG_OFF(conversion) -// clang-format off -GCC_DIAG_OFF(cast-qual) -// clang-format on -#include -#include -#include -#include -#include -#include -#include -#include -#include -GCC_DIAG_ON(conversion) -// clang-format off -GCC_DIAG_ON(cast-qual) -// clang-format on - -#ifdef __INTEL_COMPILER -#pragma warning enable 191 -#endif - -namespace Mantid { -namespace Geometry { -using Kernel::V3D; -using Kernel::Quat; - -/** - * Renders Object surface given as OpenCascade topology shape - * @param ObjSurf :: object's surface stored in topology shape - */ -void OCGeometryRenderer::Render(TopoDS_Shape *ObjSurf) { Initialize(ObjSurf); } - -/** - * Render ObjComponent - * @param ObjComp :: input to render - */ -void OCGeometryRenderer::Render(IObjComponent *ObjComp) { - if (ObjComp == nullptr) - return; - glPushMatrix(); - V3D pos = ObjComp->getPos(); - Quat rot = ObjComp->getRotation(); - double rotGL[16]; - rot.GLMatrix(&rotGL[0]); - glTranslated(pos[0], pos[1], pos[2]); - glMultMatrixd(rotGL); - V3D scaleFactor = ObjComp->getScaleFactor(); - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - ObjComp->drawObject(); - glPopMatrix(); -} - -/** - * Initialze the object surface for rendering - * @param ObjSurf :: input to create display list - */ -void OCGeometryRenderer::Initialize(TopoDS_Shape *ObjSurf) { - glBegin(GL_TRIANGLES); - // Here goes the traversing through TopoDS_Shape triangles - RenderTopoDS(ObjSurf); - glEnd(); -} - -/** - * Initializes creates a display for the input ObjComponent - * @param ObjComp :: input object component for creating display - */ -void OCGeometryRenderer::Initialize(IObjComponent *ObjComp) { - glPushMatrix(); - V3D pos = ObjComp->getPos(); - Quat rot = ObjComp->getRotation(); - double rotGL[16]; - rot.GLMatrix(&rotGL[0]); - glTranslated(pos[0], pos[1], pos[2]); - glMultMatrixd(rotGL); - V3D scaleFactor = ObjComp->getScaleFactor(); - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - ObjComp->drawObject(); - glPopMatrix(); -} - -/** - * Renders TopoDS Shape by traversing through the TopoDS_Shape - */ -void OCGeometryRenderer::RenderTopoDS(TopoDS_Shape *ObjSurf) { - if ((ObjSurf != nullptr) && !ObjSurf->IsNull()) { - TopExp_Explorer Ex; - for (Ex.Init(*ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - TColgp_Array1OfPnt tab(1, (facing->NbNodes())); - tab = facing->Nodes(); - Poly_Array1OfTriangle tri(1, facing->NbTriangles()); - tri = facing->Triangles(); - for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { - Poly_Triangle trian = tri.Value(i); - Standard_Integer index1, index2, index3; - trian.Get(index1, index2, index3); - gp_Pnt point1 = tab.Value(index1); - gp_Pnt point2 = tab.Value(index2); - gp_Pnt point3 = tab.Value(index3); - gp_XYZ pt1 = tab.Value(index1).XYZ(); - gp_XYZ pt2 = tab.Value(index2).XYZ(); - gp_XYZ pt3 = tab.Value(index3).XYZ(); - - gp_XYZ v1 = pt2 - pt1; - gp_XYZ v2 = pt3 - pt2; - - gp_XYZ normal = v1 ^ v2; - normal.Normalize(); - glNormal3d(normal.X(), normal.Y(), normal.Z()); - glVertex3d(point1.X(), point1.Y(), point1.Z()); - glVertex3d(point2.X(), point2.Y(), point2.Z()); - glVertex3d(point3.X(), point3.Y(), point3.Z()); - } - } - } -} - -/** - * Writes out a vtk 2.0 file, currently hardcoded to c:\\outputcascade.vtk - */ -void OCGeometryRenderer::WriteVTK(TopoDS_Shape *out) { - FILE *fp = fopen("C:\\outputcascade.vtk", "w+"); - fprintf(fp, "# vtk DataFile Version 2.0 \nOpenCascade data\nASCII\n"); - fprintf(fp, "DATASET POLYDATA\n"); - // BRepMesh::Mesh(out,0.1); - TopExp_Explorer Ex; - int countVert = 0; - int countFace = 0; - for (Ex.Init(*out, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - countVert += facing->NbNodes(); - countFace += facing->NbTriangles(); - } - fprintf(fp, "POINTS %d float\n", countVert); - for (Ex.Init(*out, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - TColgp_Array1OfPnt tab(1, (facing->NbNodes())); - tab = facing->Nodes(); - for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) { - gp_Pnt pnt = tab.Value(i); - fprintf(fp, "%f %f %f\n", pnt.X(), pnt.Y(), pnt.Z()); - } - } - fprintf(fp, "POLYGONS %d %d\n", countFace, countFace * 4); - int maxindex = 0; - for (Ex.Init(*out, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - TColgp_Array1OfPnt tab(1, (facing->NbNodes())); - tab = facing->Nodes(); - Poly_Array1OfTriangle tri(1, facing->NbTriangles()); - tri = facing->Triangles(); - for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { - Poly_Triangle trian = tri.Value(i); - Standard_Integer index1, index2, index3; - trian.Get(index1, index2, index3); - fprintf(fp, "3 %d %d %d\n", maxindex + index1 - 1, maxindex + index2 - 1, - maxindex + index3 - 1); - } - maxindex += facing->NbNodes(); - } - fclose(fp); -} -} -} diff --git a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp b/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp index cb756fdfad08..67c14abdd765 100644 --- a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp @@ -54,58 +54,7 @@ void StructuredGeometryHandler::Triangulate() { //---------------------------------------------------------------------------------------------- ///< Draw pixels according to StructuredDetector vertices -void StructuredGeometryHandler::Render() { - V3D pos; - - // Wait for no error - while (glGetError() != GL_NO_ERROR) - ; - - auto xVerts = m_Det->getXValues(); - auto yVerts = m_Det->getYValues(); - auto r = m_Det->getR(); - auto g = m_Det->getG(); - auto b = m_Det->getB(); - - if (xVerts.size() != yVerts.size()) - return; - - auto w = m_Det->xPixels() + 1; - auto h = m_Det->yPixels() + 1; - - glBegin(GL_QUADS); - - for (size_t iy = 0; iy < h - 1; iy++) { - for (size_t ix = 0; ix < w - 1; ix++) { - - glColor3ub((GLubyte)r[(iy * (w - 1)) + ix], - (GLubyte)g[(iy * (w - 1)) + ix], - (GLubyte)b[(iy * (w - 1)) + ix]); - - pos = V3D(xVerts[(iy * w) + ix + w], yVerts[(iy * w) + ix + w], 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix + w + 1], yVerts[(iy * w) + ix + w + 1], - 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix + 1], yVerts[(iy * w) + ix + 1], 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix], yVerts[(iy * w) + ix], 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - } - } - - glEnd(); - - if (glGetError() > 0) - std::cout << "OpenGL error in StructuredGeometryHandler::Render \n"; - - glDisable( - GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. -} +void StructuredGeometryHandler::Render() { m_renderer.render(m_Det); } //---------------------------------------------------------------------------------------------- ///< Prepare/Initialize Object/ObjComponent to be rendered diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp index 8b23a7a86a41..47a8719cffdf 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp @@ -164,6 +164,7 @@ void vtkGeometryCacheWriter::write() { writer.setOptions(XMLWriter::PRETTY_PRINT); std::ofstream file; try { + g_log.information("Writing Geometry Cache file to " + mFileName); file.open(mFileName.c_str(), std::ios::trunc); writer.writeNode(file, mDoc); file.close(); From 7453eee53d87fd6353b31168e46c0c329d9d395e Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 28 Nov 2017 12:54:05 +0000 Subject: [PATCH 014/364] Changes to renderer and triangulators re #21248 --- Framework/Geometry/CMakeLists.txt | 10 +- .../inc/MantidGeometry/Objects/CSGObject.h | 9 +- .../Rendering/BitmapGeometryHandler.h | 25 - .../Rendering/CacheGeometryGenerator.h | 71 --- .../Rendering/CacheGeometryHandler.h | 23 +- .../Rendering/GeometryHandler.h | 27 +- .../Rendering/GeometryTriangulator.h | 84 ++++ .../Rendering/OCGeometryGenerator.h | 83 ---- .../Rendering/OCGeometryHandler.h | 19 +- .../inc/MantidGeometry/Rendering/Renderer.h | 141 ++++++ .../Rendering/StructuredGeometryHandler.h | 25 - .../Rendering/vtkGeometryCacheReader.h | 6 +- Framework/Geometry/src/Objects/CSGObject.cpp | 33 +- .../src/Rendering/CacheGeometryGenerator.cpp | 83 ---- .../src/Rendering/CacheGeometryHandler.cpp | 74 +-- .../src/Rendering/GeometryTriangulator.cpp | 231 +++++++++ .../src/Rendering/OCGeometryGenerator.cpp | 215 --------- .../src/Rendering/OCGeometryHandler.cpp | 58 ++- Framework/Geometry/src/Rendering/Renderer.cpp | 441 ++++++++++++++++++ .../src/Rendering/vtkGeometryCacheReader.cpp | 43 +- .../src/Rendering/vtkGeometryCacheWriter.cpp | 12 +- 21 files changed, 1076 insertions(+), 637 deletions(-) delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryGenerator.h create mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryGenerator.h create mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h delete mode 100644 Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp create mode 100644 Framework/Geometry/src/Rendering/GeometryTriangulator.cpp delete mode 100644 Framework/Geometry/src/Rendering/OCGeometryGenerator.cpp create mode 100644 Framework/Geometry/src/Rendering/Renderer.cpp diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index 0daa550f2d33..729f043040a7 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -109,14 +109,14 @@ set ( SRC_FILES src/Objects/ShapeFactory.cpp src/Objects/Track.cpp src/Rendering/BitmapGeometryHandler.cpp - src/Rendering/CacheGeometryGenerator.cpp src/Rendering/CacheGeometryHandler.cpp - src/Rendering/GeometryRenderer.cpp src/Rendering/GeometryHandler.cpp + src/Rendering/Renderer.cpp src/Rendering/GluGeometryHandler.cpp src/Rendering/StructuredGeometryHandler.cpp src/Rendering/vtkGeometryCacheReader.cpp src/Rendering/vtkGeometryCacheWriter.cpp + src/Rendering/GeometryTriangulator.cpp src/Surfaces/Cone.cpp src/Surfaces/Cylinder.cpp src/Surfaces/General.cpp @@ -131,7 +131,6 @@ set ( SRC_FILES ) set ( OPENCASCADE_SRC - src/Rendering/OCGeometryGenerator.cpp src/Rendering/OCGeometryHandler.cpp ) @@ -271,17 +270,16 @@ set ( INC_FILES inc/MantidGeometry/Objects/ShapeFactory.h inc/MantidGeometry/Objects/Track.h inc/MantidGeometry/Rendering/BitmapGeometryHandler.h - inc/MantidGeometry/Rendering/CacheGeometryGenerator.h inc/MantidGeometry/Rendering/CacheGeometryHandler.h inc/MantidGeometry/Rendering/GeometryHandler.h + inc/MantidGeometry/Rendering/Renderer.h inc/MantidGeometry/Rendering/GluGeometryHandler.h - inc/MantidGeometry/Rendering/OCGeometryGenerator.h inc/MantidGeometry/Rendering/OCGeometryHandler.h - inc/MantidGeometry/Rendering/GeometryRenderer.h inc/MantidGeometry/Rendering/OpenGL_Headers.h inc/MantidGeometry/Rendering/StructuredGeometryHandler.h inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h inc/MantidGeometry/Rendering/vtkGeometryCacheWriter.h + inc/MantidGeometry/Rendering/GeometryTriangulator.h inc/MantidGeometry/Surfaces/BaseVisit.h inc/MantidGeometry/Surfaces/Cone.h inc/MantidGeometry/Surfaces/Cylinder.h diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index 9011b3196b08..afffe49b9283 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -10,6 +10,7 @@ #include "BoundingBox.h" #include #include +#include namespace Mantid { //---------------------------------------------------------------------- @@ -256,11 +257,11 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { /// a pointer to a class for writing to the geometry cache boost::shared_ptr vtkCacheWriter; void updateGeometryHandler(); + size_t numberOfTriangles() const; + size_t numberOfVertices() const; /// for solid angle from triangulation - int NumberOfTriangles() const; - int NumberOfPoints() const; - int *getTriangleFaces() const; - double *getTriangleVertices() const; + boost::optional &>getTriangleFaces() const; + boost::optional &>getTriangleVertices() const; /// original shape xml used to generate this object. std::string m_shapeXML; /// Optional string identifier diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h index a984a0bd4d2f..a0da6f818df2 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h @@ -80,31 +80,6 @@ class MANTID_GEOMETRY_DLL BitmapGeometryHandler : public GeometryHandler { override; ///< Prepare/Initialize Object/ObjComponent to be rendered /// Returns true if the shape can be triangulated bool canTriangulate() override { return false; } - /// get the number of triangles - int NumberOfTriangles() override { return 0; } - /// get the number of points or vertices - int NumberOfPoints() override { return 0; } - /// Extract the vertices of the triangles - double *getTriangleVertices() override { return nullptr; } - /// Extract the Faces of the triangles - int *getTriangleFaces() override { return nullptr; } - /// Sets the geometry cache using the triangulation information provided - void setGeometryCache(int noPts, int noFaces, double *pts, - int *faces) override { - (void)noPts; - (void)noFaces; - (void)pts; - (void)faces; // Avoid compiler warning - }; - /// return the actual type and points of one of the "standard" objects, - /// cuboid/cone/cyl/sphere - void GetObjectGeom(int &mytype, std::vector &vectors, - double &myradius, double &myheight) override { - (void)mytype; - (void)vectors; - (void)myradius; - (void)myheight; // Avoid compiler warning - }; }; } // NAMESPACE Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryGenerator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryGenerator.h deleted file mode 100644 index 0e93311b9ac2..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryGenerator.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef CACHE_GEOMETRYGENERATOR_H -#define CACHE_GEOMETRYGENERATOR_H - -#include "MantidGeometry/DllConfig.h" - -namespace Mantid { - -namespace Geometry { - -/** - \class CacheGeometryGenerator - \brief Generates geometry using other geometry handlers or keeps the cache of - the triangles - \author Mr. Srikanth Nagella - \date Jan 2009 - \version 1.0 - - This class is an cache for the geometry triangles and if needed generates the - triangles using - other GeometryHandlers. - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class CSGObject; -class MANTID_GEOMETRY_DLL CacheGeometryGenerator { -private: - CSGObject *Obj; ///< Input Object - int mNoOfVertices; ///< number of vertices - int mNoOfTriangles; ///< number of triangles - double *mPoints; /// + m_triangulator; ///< Triangulates geometry public: CacheGeometryHandler(IObjComponent *comp); ///< Constructor CacheGeometryHandler(boost::shared_ptr obj); ///< Constructor CacheGeometryHandler(CSGObject *obj); ///< Constructor + CacheGeometryHandler(const CacheGeometryHandler &handler); boost::shared_ptr clone() const override; ~CacheGeometryHandler() override; ///< Destructor GeometryHandler *createInstance(IObjComponent *comp) override; @@ -66,13 +71,15 @@ class MANTID_GEOMETRY_DLL CacheGeometryHandler : public GeometryHandler { void Render() override; void Initialize() override; bool canTriangulate() override { return true; } - int NumberOfTriangles() override; - int NumberOfPoints() override; - double *getTriangleVertices() override; - int *getTriangleFaces() override; + /// get the number of triangles + size_t numberOfTriangles() override; + /// get the number of points or vertices + size_t numberOfPoints() override; + boost::optional &> getTriangleVertices() override; + boost::optional &> getTriangleFaces() override; /// Sets the geometry cache using the triangulation information provided - void setGeometryCache(int noPts, int noFaces, double *pts, - int *faces) override; + void setGeometryCache(size_t nPts, size_t nFaces, std::vector &&pts, + std::vector &&faces) override; }; } // NAMESPACE Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index cacfe454cd43..fb90fa5acacc 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -5,8 +5,9 @@ #include "MantidKernel/Logger.h" #include "MantidKernel/V3D.h" #include -#include "MantidGeometry/Rendering/GeometryRenderer.h" +#include "MantidGeometry/Rendering/Renderer.h" #include +#include namespace Mantid { @@ -50,7 +51,7 @@ class MANTID_GEOMETRY_DLL GeometryHandler { static Kernel::Logger &PLog; ///< The official logger protected: - GeometryRenderer m_renderer; + detail::Renderer m_renderer; IObjComponent *ObjComp; ///< ObjComponent that uses this geometry handler CSGObject *Obj; ///< Object that uses this geometry handler bool boolTriangulated; ///< state of the geometry triangulation @@ -60,6 +61,7 @@ class MANTID_GEOMETRY_DLL GeometryHandler { GeometryHandler(IObjComponent *comp); ///< Constructor GeometryHandler(boost::shared_ptr obj); /// clone() const = 0; ///< Virtual copy constructor virtual ~GeometryHandler(); @@ -84,18 +86,23 @@ class MANTID_GEOMETRY_DLL GeometryHandler { /// Returns true if the shape can be triangulated virtual bool canTriangulate() { return false; } /// get the number of triangles - virtual int NumberOfTriangles() { return 0; } + virtual size_t numberOfTriangles() { return 0; } /// get the number of points or vertices - virtual int NumberOfPoints() { return 0; } + virtual size_t numberOfPoints() { return 0; } /// Extract the vertices of the triangles - virtual double *getTriangleVertices() { return nullptr; } + virtual boost::optional &> getTriangleVertices() { + return boost::none; + } /// Extract the Faces of the triangles - virtual int *getTriangleFaces() { return nullptr; } + virtual boost::optional &> getTriangleFaces() { + return boost::none; + } /// Sets the geometry cache using the triangulation information provided - virtual void setGeometryCache(int noPts, int noFaces, double *pts, - int *faces) { - UNUSED_ARG(noPts); - UNUSED_ARG(noFaces); + virtual void setGeometryCache(size_t nPts, size_t nFaces, + std::vector &&pts, + std::vector &&faces) { + UNUSED_ARG(nPts); + UNUSED_ARG(nFaces); UNUSED_ARG(pts); UNUSED_ARG(faces); }; diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h new file mode 100644 index 000000000000..945d35d7c74d --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -0,0 +1,84 @@ +#ifndef MANTID_GEOMETRY_SURFACETRIANGULATOR_H_ +#define MANTID_GEOMETRY_SURFACETRIANGULATOR_H_ + +#include "MantidGeometry/DllConfig.h" +#include + +class TopoDS_Shape; + +namespace Mantid { +namespace Geometry { +class Object; + +namespace detail { +/** GeometryTriangulator : Triangulates object surfaces. May or may not use + opencascade. + + Copyright © 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class MANTID_GEOMETRY_DLL GeometryTriangulator { +private: + bool m_isTriangulated; + size_t m_nFaces; + size_t m_nPoints; + std::vector m_points; ///< double array or points + std::vector m_faces; ///< Integer array of faces + const Object *m_obj; ///< Input Object + void checkTriangulated(); + +public: + GeometryTriangulator(const Object *obj); + ~GeometryTriangulator(); + void triangulate(); + void setGeometryCache(size_t nPoints, size_t nFaces, + std::vector &&points, std::vector &&faces); + /// Return the number of triangle faces + size_t numTriangleFaces(); + /// Return the number of triangle vertices + size_t numTriangleVertices(); + /// get a pointer to the 3x(NumberOfPoints) coordinates (x1,y1,z1,x2..) of + /// mesh + const std::vector &getTriangleVertices(); + /// get a pointer to the 3x(NumberOFaces) integers describing points forming + /// faces (p1,p2,p3)(p4,p5,p6). + const std::vector &getTriangleFaces(); +#ifdef ENABLE_OPENCASCADE +private: + TopoDS_Shape *m_objSurface; ///< Storage for the output surface + /// Analyze the object + /// OpenCascade analysis of object surface + void OCAnalyzeObject(); + size_t numPoints() const; + size_t numFaces() const; + void setupPoints(); + void setupFaces(); + +public: + /// Return OpenCascade surface. + TopoDS_Shape *getOCSurface(); +#endif +}; +} // namespace detail +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_SURFACETRIANGULATOR_H_ */ \ No newline at end of file diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryGenerator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryGenerator.h deleted file mode 100644 index 7433fcc7d2da..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryGenerator.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef OC_GEOMETRYGENERATOR_H -#define OC_GEOMETRYGENERATOR_H - -#include "MantidGeometry/DllConfig.h" - -class TopoDS_Shape; - -namespace Mantid { -namespace Geometry { -class CSGObject; -class Intersection; -class Union; -class SurfPoint; -class CompGrp; -class CompObj; -class BoolValue; -class Rule; -class Surface; -class Cylinder; -class Sphere; -class Cone; -class Plane; -class Torus; - -/** - \class OCGeometryGenerator - \brief Generates OpenCascade geometry from the ObjComponent - \author Mr. Srikanth Nagella - \date 4.08.2008 - \version 1.0 - - This class is an OpenCascade geometry generation that takes in input as - ObjComponent. - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MANTID_GEOMETRY_DLL OCGeometryGenerator { -private: - const CSGObject *Obj; ///< Input Object - TopoDS_Shape *ObjSurface; ///< Storage for the output surface - /// Analyze the object - void AnalyzeObject(); - -public: - OCGeometryGenerator(const CSGObject *obj); - ~OCGeometryGenerator(); - void Generate(); - TopoDS_Shape *getObjectSurface(); - /// return number of triangles in mesh (0 for special shapes) - int getNumberOfTriangles(); - /// return number of points used in mesh (o for special shapes) - int getNumberOfPoints(); - /// get a pointer to the 3x(NumberOfPoints) coordinates (x1,y1,z1,x2..) of - /// mesh - double *getTriangleVertices(); - /// get a pointer to the 3x(NumberOFaces) integers describing points forming - /// faces (p1,p2,p3)(p4,p5,p6). - int *getTriangleFaces(); -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h index 00bf28e653a4..f638cf2939f6 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h @@ -8,9 +8,11 @@ namespace Mantid { namespace Geometry { class GeometryHandler; -class OCGeometryGenerator; class IObjComponent; class CSGObject; +namespace detail { +class GeometryTriangulator; +} /** \class OCGeometryHandler \brief Place holder for OpenCascade library geometry triangulation and @@ -50,12 +52,13 @@ class CSGObject; class MANTID_GEOMETRY_DLL OCGeometryHandler : public GeometryHandler { private: static Kernel::Logger &PLog; ///< The official logger - OCGeometryGenerator * - Triangulator; ///< Geometry generator to triangulate Object + std::unique_ptr + m_triangulator; ///< Geometry generator to triangulate Object public: OCGeometryHandler(IObjComponent *comp); ///< Constructor OCGeometryHandler(boost::shared_ptr obj); ///< Constructor OCGeometryHandler(CSGObject *obj); ///< Constructor + OCGeometryHandler(const OCGeometryHandler &handler); boost::shared_ptr clone() const override; ///< Virtual copy constructor ~OCGeometryHandler() override; ///< Destructor @@ -67,14 +70,14 @@ class MANTID_GEOMETRY_DLL OCGeometryHandler : public GeometryHandler { void Initialize() override; /// Returns true if the shape can be triangulated bool canTriangulate() override { return true; } - /// get the number of Triangles - int NumberOfTriangles() override; + /// get the number of triangles + size_t numberOfTriangles() override; /// get the number of points or vertices - int NumberOfPoints() override; + size_t numberOfPoints() override; /// Extract the vertices of the triangles - double *getTriangleVertices() override; + boost::optional &> getTriangleVertices() override; /// Extract the Faces of the triangles - int *getTriangleFaces() override; + boost::optional &> getTriangleFaces() override; }; } // NAMESPACE Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h new file mode 100644 index 000000000000..86902702410b --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h @@ -0,0 +1,141 @@ +#ifndef MANTID_GEOMETRY_RENDERER_H_ +#define MANTID_GEOMETRY_RENDERER_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Rendering/OpenGL_Headers.h" +#include + +class TopoDS_Shape; + +namespace Mantid { +namespace Kernel { +class V3D; +} +namespace Geometry { +class RectangularDetector; +class StructuredDetector; +class IObjComponent; + + namespace detail + { + class GeometryTriangulator; + } + +/** Renderer : Handles rendering details of geometry within mantid. + + Copyright © 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +namespace detail { +class MANTID_GEOMETRY_DLL Renderer { +public: + enum class RenderMode { Basic, Volumetric }; + Renderer() = default; + ~Renderer() = default; + + /// General method for rendering geometry + template + void render(RenderMode mode, Args &&... args) const &; + + /// Render Basic geometry without transparency (non-volumetric) + template void render(Args &&... args) const &; + + /// Render IObjComponent + void renderIObjComponent(IObjComponent *objComp, + RenderMode mode = RenderMode::Basic) const; + /// Render Traingulated Surface + void renderTriangulated(detail::GeometryTriangulator &triangulator, + RenderMode mode = RenderMode::Basic) const; + /// Render OpenCascade Shape + void renderOpenCascade(TopoDS_Shape *objSurf, + RenderMode mode = RenderMode::Basic) const; + /// Renders a sphere + void renderSphere(const Kernel::V3D ¢er, double radius, + RenderMode mode = RenderMode::Basic) const; + /// Renders a cuboid + void renderCuboid(const Kernel::V3D &Point1, const Kernel::V3D &Point2, + const Kernel::V3D &Point3, const Kernel::V3D &Point4, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Hexahedron from the input values + void renderHexahedron(const std::vector &points, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Cone from the input values + void renderCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Cylinder/Segmented cylinder from the input values + void renderCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, bool segmented = false, + RenderMode mode = RenderMode::Basic) const; + /// Renders a Bitmap (used for rendering RectangularDetector) + void renderBitmap(const RectangularDetector *rectDet, + RenderMode mode = RenderMode::Basic) const; + /// Renders structured geometry (used for rendering StructuredDetector) + void renderStructured(const StructuredDetector *structDet, + RenderMode mode = RenderMode::Basic) const; + +private: + mutable RenderMode m_renderMode; + // general geometry + /// Render IObjComponent + void doRender(IObjComponent *ObjComp) const; + /// Render Traingulated Surface + void doRender(GeometryTriangulator &triangulator) const; + /// Render OpenCascade Shape + void doRender(TopoDS_Shape *ObjSurf) const; + + // shapes + /// Renders a sphere + void doRender(const Kernel::V3D ¢er, double radius) const; + /// Renders a cuboid + void doRender(const Kernel::V3D &Point1, const Kernel::V3D &Point2, + const Kernel::V3D &Point3, const Kernel::V3D &Point4) const; + /// Renders a Hexahedron from the input values + void doRender(const std::vector &points) const; + /// Renders a Cone from the input values + void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height) const; + /// Renders a Cylinder/Segmented cylinder from the input values + void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, bool segmented) const; + /// Renders a Bitmap (used for rendering RectangularDetector) + void doRender(const RectangularDetector *rectDet) const; + /// Renders structured geometry (used for rendering StructuredDetector) + void doRender(const StructuredDetector *structDet) const; +}; + +template +void Renderer::render(RenderMode mode, Args &&... args) const & { + // Wait for no OopenGL error + while (glGetError() != GL_NO_ERROR) + ; + m_renderMode = mode; + doRender(std::forward(args)...); +} + +template void Renderer::render(Args &&... args) const & { + render(RenderMode::Basic, std::forward(args)...); +} +} // namespace detail +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_RENDERER_H_ */ \ No newline at end of file diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h index 2985f21c5d5d..98f366a542e0 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h @@ -69,31 +69,6 @@ class MANTID_GEOMETRY_DLL StructuredGeometryHandler : public GeometryHandler { override; ///< Prepare/Initialize Object/ObjComponent to be rendered /// Returns true if the shape can be triangulated bool canTriangulate() override { return false; } - /// get the number of triangles - int NumberOfTriangles() override { return 0; } - /// get the number of points or vertices - int NumberOfPoints() override { return 0; } - /// Extract the vertices of the triangles - double *getTriangleVertices() override { return nullptr; } - /// Extract the Faces of the triangles - int *getTriangleFaces() override { return nullptr; } - /// Sets the geometry cache using the triangulation information provided - void setGeometryCache(int noPts, int noFaces, double *pts, - int *faces) override { - (void)noPts; - (void)noFaces; - (void)pts; - (void)faces; // Avoid compiler warning - }; - /// return the actual type and points of one of the "standard" objects, - /// cuboid/cone/cyl/sphere - void GetObjectGeom(int &mytype, std::vector &vectors, - double &myradius, double &myheight) override { - (void)mytype; - (void)vectors; - (void)myradius; - (void)myheight; // Avoid compiler warning - }; }; } // NAMESPACE Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h b/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h index bd264ce85ac6..1240b5d2f5ec 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h @@ -53,8 +53,10 @@ class MANTID_GEOMETRY_DLL vtkGeometryCacheReader { // Private Methods void Init(); Poco::XML::Element *getElementByObjectName(std::string name); - void readPoints(Poco::XML::Element *pEle, int *noOfPoints, double **points); - void readTriangles(Poco::XML::Element *pEle, int *noOfTriangles, int **faces); + void readPoints(Poco::XML::Element *pEle, int noOfPoints, + std::vector &points); + void readTriangles(Poco::XML::Element *pEle, int noOfTriangles, + std::vector &faces); public: vtkGeometryCacheReader(std::string filename); diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index f2338669e101..a03b8c05e153 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -810,7 +810,7 @@ int CSGObject::calcValidType(const Kernel::V3D &Pt, * shape. */ double CSGObject::solidAngle(const Kernel::V3D &observer) const { - if (this->NumberOfTriangles() > 30000) + if (this->numberOfTriangles() > 30000) return rayTraceSolidAngle(observer); return triangleSolidAngle(observer); } @@ -1013,7 +1013,7 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const { // Maximum of 4 vectors depending on the type geometry_vectors.reserve(4); this->GetObjectGeom(type, geometry_vectors, radius, height); - int nTri = this->NumberOfTriangles(); + auto nTri = this->numberOfTriangles(); // Cylinders are by far the most frequently used GluGeometryHandler::GeometryType gluType = static_cast(type); @@ -1038,8 +1038,8 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const { { return rayTraceSolidAngle(observer); } else { // Compute a generic shape that has been triangulated - double *vertices = this->getTriangleVertices(); - int *faces = this->getTriangleFaces(); + const auto &vertices = this->getTriangleVertices().get(); + const auto &faces = this->getTriangleFaces().get(); double sangle(0.0), sneg(0.0); for (int i = 0; i < nTri; i++) { int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2]; @@ -1090,7 +1090,7 @@ double CSGObject::triangleSolidAngle(const V3D &observer, } } - int nTri = this->NumberOfTriangles(); + auto nTri = this->numberOfTriangles(); // // If triangulation is not available fall back to ray tracing method, unless // object is a standard shape, currently Cuboid or Sphere. Should add Cylinder @@ -1122,8 +1122,8 @@ double CSGObject::triangleSolidAngle(const V3D &observer, // return rayTraceSolidAngle(observer); // so is this } - double *vertices = this->getTriangleVertices(); - int *faces = this->getTriangleFaces(); + const auto &vertices = this->getTriangleVertices().get(); + const auto &faces = this->getTriangleFaces().get(); double sangle(0.0), sneg(0.0); for (int i = 0; i < nTri; i++) { int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2]; @@ -1717,10 +1717,10 @@ void CSGObject::calcBoundingBoxByRule() { */ void CSGObject::calcBoundingBoxByVertices() { // Grab vertex information - auto vertCount = this->NumberOfPoints(); - auto vertArray = this->getTriangleVertices(); + auto vertCount = this->numberOfVertices(); + const auto &vertArray = this->getTriangleVertices().get(); - if (vertCount && vertArray) { + if (vertCount > 0) { // Unreasonable extents to be overwritten by loop constexpr double huge = 1e10; double minX, maxX, minY, maxY, minZ, maxZ; @@ -2155,22 +2155,21 @@ int CSGObject::NumberOfPoints() const { return 0; return m_handler->NumberOfPoints(); } - /** * get vertices */ -double *CSGObject::getTriangleVertices() const { - if (m_handler == nullptr) - return nullptr; +boost::optional &>CSGObject::getTriangleVertices() const { + if (handle == nullptr) + return boost::none; return m_handler->getTriangleVertices(); } /** * get faces */ -int *CSGObject::getTriangleFaces() const { - if (m_handler == nullptr) - return nullptr; +boost::optional &> CSGObject::getTriangleFaces() const { + if (handle == nullptr) + return boost::none; return m_handler->getTriangleFaces(); } diff --git a/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp b/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp deleted file mode 100644 index 962595f767ce..000000000000 --- a/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include "MantidKernel/Matrix.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Rendering/CacheGeometryGenerator.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" - -#ifdef ENABLE_OPENCASCADE -#include "MantidGeometry/Rendering/OCGeometryHandler.h" -#endif - -namespace Mantid { - -namespace Geometry { -/** - * Constructor - * @param obj :: input object - */ -CacheGeometryGenerator::CacheGeometryGenerator(CSGObject *obj) : Obj(obj) { - mNoOfVertices = 0; - mNoOfTriangles = 0; - mFaces = nullptr; - mPoints = nullptr; -} - -/** - * Generate geometry, if there is no cache then it uses OpenCascade to generate - * surface triangles. - */ -void CacheGeometryGenerator::Generate() { - if (mNoOfVertices <= - 0) // There are no triangles defined to use OpenCascade handler - { -#ifdef ENABLE_OPENCASCADE - OCGeometryHandler h(Obj); - mNoOfVertices = h.NumberOfPoints(); - mNoOfTriangles = h.NumberOfTriangles(); - mPoints = h.getTriangleVertices(); - mFaces = h.getTriangleFaces(); -#endif - } -} - -/** - * Destroy the surface generated for the object - */ -CacheGeometryGenerator::~CacheGeometryGenerator() { - if (mFaces != nullptr) - delete[] mFaces; - if (mPoints != nullptr) - delete[] mPoints; -} - -int CacheGeometryGenerator::getNumberOfTriangles() { return mNoOfTriangles; } - -int CacheGeometryGenerator::getNumberOfPoints() { return mNoOfVertices; } - -double *CacheGeometryGenerator::getTriangleVertices() { return mPoints; } - -int *CacheGeometryGenerator::getTriangleFaces() { return mFaces; } - -/** - Sets the geometry cache using the triangulation information provided - @param noPts :: the number of points - @param noFaces :: the number of faces - @param pts :: a double array of the points - @param faces :: an int array of the faces -*/ -void CacheGeometryGenerator::setGeometryCache(int noPts, int noFaces, - double *pts, int *faces) { - if (mPoints != nullptr) - delete[] mPoints; - if (mFaces != nullptr) - delete[] mFaces; - mNoOfVertices = noPts; - mNoOfTriangles = noFaces; - mPoints = pts; - mFaces = faces; -} - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid diff --git a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp index b718baedc4df..56b21884aecb 100644 --- a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp @@ -2,7 +2,7 @@ #include "MantidGeometry/Instrument/ObjComponent.h" #include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/CacheGeometryHandler.h" -#include "MantidGeometry/Rendering/CacheGeometryGenerator.h" +#include "MantidGeometry/Rendering/GeometryTriangulator.h" #include "MantidKernel/MultiThreaded.h" #include @@ -10,33 +10,43 @@ namespace Mantid { namespace Geometry { +using namespace detail; CacheGeometryHandler::CacheGeometryHandler(IObjComponent *comp) : GeometryHandler(comp) { - Triangulator = nullptr; + m_triangulator = nullptr; } CacheGeometryHandler::CacheGeometryHandler(boost::shared_ptr obj) : GeometryHandler(obj) { - Triangulator = new CacheGeometryGenerator(obj.get()); + m_triangulator.reset(new GeometryTriangulator(obj.get())); } CacheGeometryHandler::CacheGeometryHandler(CSGObject *obj) : GeometryHandler(obj) { - Triangulator = new CacheGeometryGenerator(obj); + m_triangulator.reset(new GeometryTriangulator(obj)); +} + +CacheGeometryHandler::CacheGeometryHandler(const CacheGeometryHandler &handler) + : GeometryHandler(handler) { + m_triangulator = nullptr; + + if (handler.Obj != nullptr) { + Obj = handler.Obj; + m_triangulator.reset(new GeometryTriangulator(Obj)); + } else if (handler.ObjComp != nullptr) + ObjComp = handler.ObjComp; } boost::shared_ptr CacheGeometryHandler::clone() const { auto clone = boost::make_shared(*this); - if (this->Triangulator) - clone->Triangulator = new CacheGeometryGenerator(this->Obj); + if (this->m_triangulator) + clone->m_triangulator.reset(new GeometryTriangulator(this->Obj)); else - clone->Triangulator = nullptr; + clone->m_triangulator = nullptr; return clone; } CacheGeometryHandler::~CacheGeometryHandler() { - if (Triangulator != nullptr) - delete Triangulator; } GeometryHandler *CacheGeometryHandler::createInstance(IObjComponent *comp) { @@ -56,7 +66,7 @@ void CacheGeometryHandler::Triangulate() { // Check whether Object is triangulated otherwise triangulate PARALLEL_CRITICAL(Triangulate) if (Obj != nullptr && !boolTriangulated) { - Triangulator->Generate(); + m_triangulator->triangulate(); boolTriangulated = true; } } @@ -65,9 +75,7 @@ void CacheGeometryHandler::Render() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - m_renderer.renderTriangulated( - Triangulator->getNumberOfPoints(), Triangulator->getNumberOfTriangles(), - Triangulator->getTriangleVertices(), Triangulator->getTriangleFaces()); + m_renderer.renderTriangulated(*m_triangulator); } else if (ObjComp != nullptr) { m_renderer.render(ObjComp); } @@ -78,55 +86,57 @@ void CacheGeometryHandler::Initialize() { Obj->updateGeometryHandler(); if (!boolTriangulated) Triangulate(); - m_renderer.renderTriangulated( - Triangulator->getNumberOfPoints(), Triangulator->getNumberOfTriangles(), - Triangulator->getTriangleVertices(), Triangulator->getTriangleFaces()); + m_renderer.renderTriangulated(*m_triangulator); } else if (ObjComp != nullptr) { m_renderer.render(ObjComp); } } -int CacheGeometryHandler::NumberOfTriangles() { +size_t CacheGeometryHandler::numberOfTriangles() { if (Obj != nullptr) { Obj->updateGeometryHandler(); if (!boolTriangulated) Triangulate(); - return Triangulator->getNumberOfTriangles(); - } else { + return m_triangulator->numTriangleFaces(); + } + else { return 0; } } -int CacheGeometryHandler::NumberOfPoints() { +size_t CacheGeometryHandler::numberOfPoints() { if (Obj != nullptr) { Obj->updateGeometryHandler(); if (!boolTriangulated) Triangulate(); - return Triangulator->getNumberOfPoints(); - } else { + return m_triangulator->numTriangleVertices(); + } + else { return 0; } } -double *CacheGeometryHandler::getTriangleVertices() { +boost::optional &> +CacheGeometryHandler::getTriangleVertices() { if (Obj != nullptr) { Obj->updateGeometryHandler(); if (!boolTriangulated) Triangulate(); - return Triangulator->getTriangleVertices(); + return m_triangulator->getTriangleVertices(); } else { - return nullptr; + return boost::none; } } -int *CacheGeometryHandler::getTriangleFaces() { +boost::optional &> +CacheGeometryHandler::getTriangleFaces() { if (Obj != nullptr) { Obj->updateGeometryHandler(); if (!boolTriangulated) Triangulate(); - return Triangulator->getTriangleFaces(); + return m_triangulator->getTriangleFaces(); } else { - return nullptr; + return boost::none; } } @@ -137,9 +147,11 @@ Sets the geometry cache using the triangulation information provided @param pts :: a double array of the points @param faces :: an int array of the faces */ -void CacheGeometryHandler::setGeometryCache(int noPts, int noFaces, double *pts, - int *faces) { - Triangulator->setGeometryCache(noPts, noFaces, pts, faces); +void CacheGeometryHandler::setGeometryCache(size_t nPts, size_t nFaces, + std::vector &&pts, + std::vector &&faces) { + m_triangulator->setGeometryCache(nPts, nFaces, std::move(pts), + std::move(faces)); boolTriangulated = true; } } diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp new file mode 100644 index 000000000000..b1b982664868 --- /dev/null +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -0,0 +1,231 @@ +#include "MantidGeometry/Rendering/GeometryTriangulator.h" +#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Objects/Rules.h" +#include "MantidKernel/Logger.h" +#include "MantidKernel/WarningSuppressions.h" + +#ifdef ENABLE_OPENCASCADE +// Squash a warning coming out of an OpenCascade header +#ifdef __INTEL_COMPILER +#pragma warning disable 191 +#endif +// Opencascade defines _USE_MATH_DEFINES without checking whether it is already +// used. +// Undefine it here before we include the headers to avoid a warning. Older +// versions +// also define M_SQRT1_2 so do the same if it is already defined +#ifdef _MSC_VER +#undef _USE_MATH_DEFINES +#ifdef M_SQRT1_2 +#undef M_SQRT1_2 +#endif +#endif + +GCC_DIAG_OFF(conversion) +// clang-format off +GCC_DIAG_OFF(cast - qual) +// clang-format on +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +GCC_DIAG_ON(conversion) +// clang-format off +GCC_DIAG_ON(cast - qual) +// clang-format on + +#ifdef __INTEL_COMPILER +#pragma warning enable 191 +#endif + +#endif // ENABLE_OPENCASCADE + +namespace Mantid { +namespace Geometry { +namespace detail { +namespace { +/// static logger +Kernel::Logger g_log("GeometryTriangulator"); +} // namespace + +GeometryTriangulator::GeometryTriangulator(const Object *obj) + : m_isTriangulated(false) { + m_obj = obj; +#ifdef ENABLE_OPENCASCADE + m_objSurface = nullptr; +#endif +} + +GeometryTriangulator::~GeometryTriangulator() {} + +void GeometryTriangulator::triangulate() { +#ifdef ENABLE_OPENCASCADE + if (m_objSurface == nullptr) + OCAnalyzeObject(); +#endif + m_isTriangulated = true; +} + +#ifdef ENABLE_OPENCASCADE +/// Return OpenCascade surface. +TopoDS_Shape *GeometryTriangulator::getOCSurface() { + checkTriangulated(); + return m_objSurface; +} +#endif + +void GeometryTriangulator::checkTriangulated() { + if (m_obj != nullptr) { + if (!m_isTriangulated) { + triangulate(); + } + } +} +size_t GeometryTriangulator::numTriangleFaces() { + checkTriangulated(); + return m_nFaces; +} + +size_t GeometryTriangulator::numTriangleVertices() { + checkTriangulated(); + return m_nPoints; +} + +/// get a pointer to the 3x(NumberOfPoints) coordinates (x1,y1,z1,x2..) of +/// mesh +const std::vector &GeometryTriangulator::getTriangleVertices() { + checkTriangulated(); + return m_points; +} +/// get a pointer to the 3x(NumberOFaces) integers describing points forming +/// faces (p1,p2,p3)(p4,p5,p6). +const std::vector &GeometryTriangulator::getTriangleFaces() { + checkTriangulated(); + return m_faces; +} + +#ifdef ENABLE_OPENCASCADE +void GeometryTriangulator::OCAnalyzeObject() { + if (m_obj != nullptr) // If object exists + { + // Get the top rule tree in Obj + const Rule *top = m_obj->topRule(); + if (top == nullptr) { + m_objSurface = new TopoDS_Shape(); + return; + } + // Traverse through Rule + TopoDS_Shape Result = const_cast(top)->analyze(); + try { + m_objSurface = new TopoDS_Shape(Result); + BRepMesh_IncrementalMesh(Result, 0.001); + } catch (StdFail_NotDone &) { + g_log.error("Cannot build the geometry. Check the geometry definition"); + } + } + + setupPoints(); + setupFaces(); +} + +size_t GeometryTriangulator::numPoints() const { + size_t countVert = 0; + if (m_objSurface != nullptr) { + TopExp_Explorer Ex; + for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { + TopoDS_Face F = TopoDS::Face(Ex.Current()); + TopLoc_Location L; + Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); + countVert += facing->NbNodes(); + } + } + return countVert; +} + +size_t GeometryTriangulator::numFaces() const { + size_t countFace = 0; + if (m_objSurface != nullptr) { + TopExp_Explorer Ex; + for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { + TopoDS_Face F = TopoDS::Face(Ex.Current()); + TopLoc_Location L; + Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); + countFace += facing->NbTriangles(); + } + } + return countFace; +} + +void GeometryTriangulator::setupPoints() { + m_nPoints = numPoints(); + if (m_nPoints > 0) { + int index = 0; + m_points.resize(m_nPoints * 3); + TopExp_Explorer Ex; + for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { + TopoDS_Face F = TopoDS::Face(Ex.Current()); + TopLoc_Location L; + Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); + TColgp_Array1OfPnt tab(1, (facing->NbNodes())); + tab = facing->Nodes(); + for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) { + gp_Pnt pnt = tab.Value(i); + m_points[index * 3 + 0] = pnt.X(); + m_points[index * 3 + 1] = pnt.Y(); + m_points[index * 3 + 2] = pnt.Z(); + index++; + } + } + } +} + +void GeometryTriangulator::setupFaces() { + m_nFaces = numFaces(); + if (m_nFaces > 0) { + m_faces.resize(m_nFaces * 3); + TopExp_Explorer Ex; + int maxindex = 0; + int index = 0; + for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { + TopoDS_Face F = TopoDS::Face(Ex.Current()); + TopLoc_Location L; + Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); + TColgp_Array1OfPnt tab(1, (facing->NbNodes())); + tab = facing->Nodes(); + Poly_Array1OfTriangle tri(1, facing->NbTriangles()); + tri = facing->Triangles(); + for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { + Poly_Triangle trian = tri.Value(i); + Standard_Integer index1, index2, index3; + trian.Get(index1, index2, index3); + m_faces[index * 3 + 0] = maxindex + index1 - 1; + m_faces[index * 3 + 1] = maxindex + index2 - 1; + m_faces[index * 3 + 2] = maxindex + index3 - 1; + index++; + } + maxindex += facing->NbNodes(); + } + } +} +#endif + +void GeometryTriangulator::setGeometryCache(size_t nPoints, size_t nFaces, + std::vector &&points, + std::vector &&faces) { + m_nPoints = nPoints; + m_nFaces = nFaces; + m_points = std::move(points); + m_faces = std::move(faces); + m_isTriangulated = true; +} +} // namespace detail +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/OCGeometryGenerator.cpp b/Framework/Geometry/src/Rendering/OCGeometryGenerator.cpp deleted file mode 100644 index 49b701333b62..000000000000 --- a/Framework/Geometry/src/Rendering/OCGeometryGenerator.cpp +++ /dev/null @@ -1,215 +0,0 @@ -#include "MantidGeometry/Rendering/OCGeometryGenerator.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Surfaces/Quadratic.h" -#include "MantidGeometry/Surfaces/Sphere.h" -#include "MantidGeometry/Surfaces/Cylinder.h" -#include "MantidGeometry/Surfaces/Cone.h" -#include "MantidGeometry/Surfaces/Plane.h" -#include "MantidGeometry/Surfaces/Torus.h" -#include "MantidGeometry/Objects/Rules.h" -#include "MantidKernel/Logger.h" -#include "MantidKernel/Matrix.h" -#include "MantidKernel/Quat.h" -#include "MantidKernel/V3D.h" -#include "MantidKernel/WarningSuppressions.h" - -#include // Needed for g++4.4 on Mac with OpenCASCADE 6.3.0 -#include -#include - -// Squash a warning coming out of an OpenCascade header -#ifdef __INTEL_COMPILER -#pragma warning disable 191 -#endif -// Opencascade defines _USE_MATH_DEFINES without checking whether it is already -// used. -// Undefine it here before we include the headers to avoid a warning. Older -// versions -// also define M_SQRT1_2 so do the same if it is already defined -#ifdef _MSC_VER -#undef _USE_MATH_DEFINES -#ifdef M_SQRT1_2 -#undef M_SQRT1_2 -#endif -#endif - -GCC_DIAG_OFF(conversion) -// clang-format off -GCC_DIAG_OFF(cast-qual) -// clang-format on -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -GCC_DIAG_ON(conversion) -// clang-format off -GCC_DIAG_ON(cast-qual) -// clang-format on - -#ifdef __INTEL_COMPILER -#pragma warning enable 191 -#endif - -namespace Mantid { - -namespace Geometry { -namespace { -/// static logger -Kernel::Logger g_log("OCGeometryGenerator"); -} - -/** -* Constructor -* @param obj :: input object -*/ -OCGeometryGenerator::OCGeometryGenerator(const CSGObject *obj) : Obj(obj) { - ObjSurface = nullptr; -} - -/** -* Generate geometry, it uses OpenCascade to generate surface triangles. -*/ -void OCGeometryGenerator::Generate() { - if (ObjSurface == nullptr) { - AnalyzeObject(); - } -} - -/** -* Destroy the surface generated for the object -*/ -OCGeometryGenerator::~OCGeometryGenerator() { - if (ObjSurface != nullptr) { - delete ObjSurface; - } -} - -/** -* Analyzes the rule tree in object and creates a Topology Shape -*/ -void OCGeometryGenerator::AnalyzeObject() { - if (Obj != nullptr) // If object exists - { - // Get the top rule tree in Obj - const Rule *top = Obj->topRule(); - if (top == nullptr) { - ObjSurface = new TopoDS_Shape(); - return; - } - // Traverse through Rule - TopoDS_Shape Result = const_cast(top)->analyze(); - try { - ObjSurface = new TopoDS_Shape(Result); - BRepMesh_IncrementalMesh(Result, 0.001); - } catch (StdFail_NotDone &) { - g_log.error("Cannot build the geometry. Check the geometry definition"); - } - } -} - -/** -* Returns the shape generated. -*/ -TopoDS_Shape *OCGeometryGenerator::getObjectSurface() { return ObjSurface; } - -int OCGeometryGenerator::getNumberOfTriangles() { - int countFace = 0; - if (ObjSurface != nullptr) { - TopExp_Explorer Ex; - for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - countFace += facing->NbTriangles(); - } - } - return countFace; -} - -int OCGeometryGenerator::getNumberOfPoints() { - int countVert = 0; - if (ObjSurface != nullptr) { - TopExp_Explorer Ex; - for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - countVert += facing->NbNodes(); - } - } - return countVert; -} - -double *OCGeometryGenerator::getTriangleVertices() { - double *points = nullptr; - int nPts = this->getNumberOfPoints(); - if (nPts > 0) { - points = new double[static_cast(nPts) * 3]; - int index = 0; - TopExp_Explorer Ex; - for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - TColgp_Array1OfPnt tab(1, (facing->NbNodes())); - tab = facing->Nodes(); - for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) { - gp_Pnt pnt = tab.Value(i); - points[index * 3 + 0] = pnt.X(); - points[index * 3 + 1] = pnt.Y(); - points[index * 3 + 2] = pnt.Z(); - index++; - } - } - } - return points; -} - -int *OCGeometryGenerator::getTriangleFaces() { - int *faces = nullptr; - int nFaces = this->getNumberOfTriangles(); // was Points - if (nFaces > 0) { - faces = new int[static_cast(nFaces) * 3]; - TopExp_Explorer Ex; - int maxindex = 0; - int index = 0; - for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - TColgp_Array1OfPnt tab(1, (facing->NbNodes())); - tab = facing->Nodes(); - Poly_Array1OfTriangle tri(1, facing->NbTriangles()); - tri = facing->Triangles(); - for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { - Poly_Triangle trian = tri.Value(i); - Standard_Integer index1, index2, index3; - trian.Get(index1, index2, index3); - faces[index * 3 + 0] = maxindex + index1 - 1; - faces[index * 3 + 1] = maxindex + index2 - 1; - faces[index * 3 + 2] = maxindex + index3 - 1; - index++; - } - maxindex += facing->NbNodes(); - } - } - return faces; -} -} // NAMESPACE Geometry - -} // NAMESPACE Mantid diff --git a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp index b1b95ce04d4b..5de526d082d6 100644 --- a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp @@ -1,34 +1,45 @@ #include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Rendering/OCGeometryGenerator.h" +#include "MantidGeometry/Rendering/GeometryTriangulator.h" #include namespace Mantid { namespace Geometry { +using namespace detail; + OCGeometryHandler::OCGeometryHandler(IObjComponent *comp) : GeometryHandler(comp) { - Triangulator = nullptr; + m_triangulator = nullptr; } OCGeometryHandler::OCGeometryHandler(boost::shared_ptr obj) : GeometryHandler(obj) { - Triangulator = new OCGeometryGenerator(obj.get()); + m_triangulator.reset(new GeometryTriangulator(obj.get())); } OCGeometryHandler::OCGeometryHandler(CSGObject *obj) : GeometryHandler(obj) { - Triangulator = new OCGeometryGenerator(obj); + m_triangulator.reset(new GeometryTriangulator(obj)); +} + +OCGeometryHandler::OCGeometryHandler(const OCGeometryHandler &handler) + : GeometryHandler(handler) { + m_triangulator = nullptr; + + if (handler.Obj != nullptr) { + Obj = handler.Obj; + m_triangulator.reset(new GeometryTriangulator(Obj)); + } else if (handler.ObjComp != nullptr) + ObjComp = handler.ObjComp; } boost::shared_ptr OCGeometryHandler::clone() const { auto clone = boost::make_shared(*this); - if (this->Triangulator) - clone->Triangulator = new OCGeometryGenerator(this->Obj); + if (this->m_triangulator) + clone->m_triangulator.reset(new GeometryTriangulator(this->Obj)); return clone; } OCGeometryHandler::~OCGeometryHandler() { - if (Triangulator != nullptr) - delete Triangulator; } GeometryHandler *OCGeometryHandler::createInstance(IObjComponent *comp) { @@ -47,7 +58,7 @@ GeometryHandler *OCGeometryHandler::createInstance(CSGObject *obj) { void OCGeometryHandler::Triangulate() { // Check whether Object is triangulated otherwise triangulate if (Obj != nullptr && !boolTriangulated) { - Triangulator->Generate(); + m_triangulator->triangulate(); boolTriangulated = true; } } @@ -56,7 +67,7 @@ void OCGeometryHandler::Render() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - m_renderer.render(Triangulator->getObjectSurface()); + m_renderer.render(m_triangulator->getOCSurface()); } else if (ObjComp != nullptr) { m_renderer.render(ObjComp); } @@ -64,43 +75,44 @@ void OCGeometryHandler::Render() { void OCGeometryHandler::Initialize() { Render(); } -int OCGeometryHandler::NumberOfTriangles() { +size_t OCGeometryHandler::numberOfTriangles() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - return Triangulator->getNumberOfTriangles(); - } else { + return m_triangulator->numTriangleFaces(); + } + else { return 0; } } -int OCGeometryHandler::NumberOfPoints() { +size_t OCGeometryHandler::numberOfPoints() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - return Triangulator->getNumberOfPoints(); - } else { + return m_triangulator->numTriangleVertices(); + } + else { return 0; } } - -double *OCGeometryHandler::getTriangleVertices() { +boost::optional &> OCGeometryHandler::getTriangleVertices() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - return Triangulator->getTriangleVertices(); + return m_triangulator->getTriangleVertices(); } else { - return nullptr; + return boost::none; } } -int *OCGeometryHandler::getTriangleFaces() { +boost::optional &> OCGeometryHandler::getTriangleFaces() { if (Obj != nullptr) { if (!boolTriangulated) Triangulate(); - return Triangulator->getTriangleFaces(); + return m_triangulator->getTriangleFaces(); } else { - return nullptr; + return boost::none; } } } // namespace Geometry diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp new file mode 100644 index 000000000000..3ed31f227780 --- /dev/null +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -0,0 +1,441 @@ +#include "MantidGeometry/Rendering/Renderer.h" +#include "MantidGeometry/Instrument/ObjComponent.h" +#include "MantidGeometry/Instrument/RectangularDetector.h" +#include "MantidGeometry/Instrument/StructuredDetector.h" +#include "MantidGeometry/Rendering/GeometryTriangulator.h" +#include "MantidGeometry/Surfaces/Cone.h" +#include "MantidGeometry/Surfaces/Cylinder.h" +#include "MantidGeometry/Surfaces/Sphere.h" +#include "MantidKernel/Quat.h" +#include "MantidKernel/WarningSuppressions.h" + +// Squash a warning coming out of an OpenCascade header +#ifdef __INTEL_COMPILER +#pragma warning disable 191 +#endif +// Opencascade defines _USE_MATH_DEFINES without checking whether it is already +// used. +// Undefine it here before we include the headers to avoid a warning +#ifdef _MSC_VER +#undef _USE_MATH_DEFINES +#ifdef M_SQRT1_2 +#undef M_SQRT1_2 +#endif +#endif + +GCC_DIAG_OFF(conversion) +// clang-format off +GCC_DIAG_OFF(cast - qual) +// clang-format on +#include +#include +#include +#include +#include +#include +#include +#include +#include +GCC_DIAG_ON(conversion) +// clang-format off +GCC_DIAG_ON(cast - qual) +// clang-format on + +#ifdef __INTEL_COMPILER +#pragma warning enable 191 +#endif + +namespace Mantid { +namespace Geometry { +using Kernel::Quat; +using Kernel::V3D; + +namespace detail { +void Renderer::renderIObjComponent(IObjComponent *objComp, + RenderMode mode) const { + render(mode, objComp); +} + +void Renderer::renderTriangulated(detail::GeometryTriangulator &triangulator, + RenderMode mode) const { + render(mode, triangulator); +} + +void Renderer::renderOpenCascade(TopoDS_Shape *objSurf, RenderMode mode) const { + render(mode, objSurf); +} + +void Renderer::renderSphere(const Kernel::V3D ¢er, double radius, + RenderMode mode) const { + render(mode, center, radius); +} + +void Renderer::renderCuboid(const Kernel::V3D &Point1, + const Kernel::V3D &Point2, + const Kernel::V3D &Point3, + const Kernel::V3D &Point4, RenderMode mode) const { + render(mode, Point1, Point2, Point3, Point4); +} + +void Renderer::renderHexahedron(const std::vector &points, + RenderMode mode) const { + render(mode, points); +} + +void Renderer::renderCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, RenderMode mode) const { + render(mode, center, axis, radius, height); +} + +void Renderer::renderCylinder(const Kernel::V3D ¢er, + const Kernel::V3D &axis, double radius, + double height, bool segmented, + RenderMode mode) const { + render(mode, center, axis, radius, height, segmented); +} + +void Renderer::renderBitmap(const RectangularDetector *rectDet, + RenderMode mode) const { + render(mode, rectDet); +} + +void Renderer::renderStructured(const StructuredDetector *structDet, + RenderMode mode) const { + render(mode, structDet); +} + +// Render IObjectComponent +void Renderer::doRender(IObjComponent *ObjComp) const { + glPushMatrix(); + V3D pos = ObjComp->getPos(); + Quat rot = ObjComp->getRotation(); + double rotGL[16]; + rot.GLMatrix(&rotGL[0]); + glTranslated(pos[0], pos[1], pos[2]); + glMultMatrixd(rotGL); + V3D scaleFactor = ObjComp->getScaleFactor(); + glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); + ObjComp->drawObject(); + glPopMatrix(); +} + +// Render triangulated surface +void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { + const auto &faces = triangulator.getTriangleFaces(); + const auto &points = triangulator.getTriangleVertices(); + glBegin(GL_TRIANGLES); + V3D normal; + for (int i = 0; i < triangulator.numTriangleFaces(); i++) { + int index1 = faces[i * 3] * 3; + int index2 = faces[i * 3 + 1] * 3; + int index3 = faces[i * 3 + 2] * 3; + // Calculate normal and normalize + V3D v1(points[index1], points[index1 + 1], points[index1 + 2]); + V3D v2(points[index2], points[index2 + 1], points[index2 + 2]); + V3D v3(points[index3], points[index3 + 1], points[index3 + 2]); + normal = (v1 - v2).cross_prod(v2 - v3); + normal.normalize(); + glNormal3d(normal[0], normal[1], normal[2]); + glVertex3dv(&points[index1]); + glVertex3dv(&points[index2]); + glVertex3dv(&points[index3]); + } + glEnd(); +} + +// Render OpenCascade Shape +void Renderer::doRender(TopoDS_Shape *ObjSurf) const { + glBegin(GL_TRIANGLES); + if ((ObjSurf != nullptr) && !ObjSurf->IsNull()) { + TopExp_Explorer Ex; + for (Ex.Init(*ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) { + TopoDS_Face F = TopoDS::Face(Ex.Current()); + TopLoc_Location L; + Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); + TColgp_Array1OfPnt tab(1, (facing->NbNodes())); + tab = facing->Nodes(); + Poly_Array1OfTriangle tri(1, facing->NbTriangles()); + tri = facing->Triangles(); + for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { + Poly_Triangle trian = tri.Value(i); + Standard_Integer index1, index2, index3; + trian.Get(index1, index2, index3); + gp_Pnt point1 = tab.Value(index1); + gp_Pnt point2 = tab.Value(index2); + gp_Pnt point3 = tab.Value(index3); + gp_XYZ pt1 = tab.Value(index1).XYZ(); + gp_XYZ pt2 = tab.Value(index2).XYZ(); + gp_XYZ pt3 = tab.Value(index3).XYZ(); + + gp_XYZ v1 = pt2 - pt1; + gp_XYZ v2 = pt3 - pt2; + + gp_XYZ normal = v1 ^ v2; + normal.Normalize(); + glNormal3d(normal.X(), normal.Y(), normal.Z()); + glVertex3d(point1.X(), point1.Y(), point1.Z()); + glVertex3d(point2.X(), point2.Y(), point2.Z()); + glVertex3d(point3.X(), point3.Y(), point3.Z()); + } + } + } + glEnd(); +} + +// Render Sphere +void Renderer::doRender(const Kernel::V3D ¢er, double radius) const { + // create glu sphere + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + glPushMatrix(); + glTranslated(center[0], center[1], center[2]); + gluSphere(qobj, radius, Sphere::g_nslices, Sphere::g_nstacks); + glPopMatrix(); + gluDeleteQuadric(qobj); +} + +// Render Cuboid +void Renderer::doRender(const V3D &Point1, const V3D &Point2, const V3D &Point3, + const V3D &Point4) const { + V3D vec0 = Point1; + V3D vec1 = Point2 - Point1; + V3D vec2 = Point3 - Point1; + V3D vec3 = Point4 - Point1; + V3D vertex[8]; + vertex[0] = vec0; + vertex[1] = vec0 + vec3; + vertex[2] = vec0 + vec3 + vec1; + vertex[3] = vec0 + vec1; + vertex[4] = vec0 + vec2; + vertex[5] = vec0 + vec2 + vec3; + vertex[6] = vec0 + vec2 + vec3 + vec1; + vertex[7] = vec0 + vec1 + vec2; + + int faceindex[6][4] = { + {0, 1, 2, 3}, // top + {0, 3, 7, 4}, // left + {3, 2, 6, 7}, // back + {2, 1, 5, 6}, // right + {0, 4, 5, 1}, // front + {4, 7, 6, 5}, // bottom + }; + V3D normal; + // first face + glBegin(GL_QUADS); + for (auto &row : faceindex) { + normal = (vertex[row[0]] - vertex[row[1]]) + .cross_prod((vertex[row[0]] - vertex[row[2]])); + normal.normalize(); + glNormal3d(normal[0], normal[1], normal[2]); + for (const int ij : row) { + if (ij == 0) + glTexCoord2i(0, 0); + if (ij == 1) + glTexCoord2i(1, 0); + if (ij == 2) + glTexCoord2i(1, 1); + if (ij == 3) + glTexCoord2i(0, 1); + if (ij == 4) + glTexCoord2i(0, 0); + if (ij == 5) + glTexCoord2i(1, 0); + if (ij == 6) + glTexCoord2i(1, 1); + if (ij == 7) + glTexCoord2i(0, 1); + glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]); + } + } + glEnd(); +} + +// Render Hexahedron +void Renderer::doRender(const std::vector &points) const { + glBegin(GL_QUADS); + // bottom + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + // front + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + // right + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + // back + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + // left + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + // top + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + + glEnd(); +} + +// Render Cone +void Renderer::doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height) const { + glPushMatrix(); + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + glTranslated(center[0], center[1], center[2]); + GLdouble mat[16]; + V3D unit(0, 0, 1); + Quat rot(unit, axis); + rot.GLMatrix(&mat[0]); + glMultMatrixd(mat); + gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, + Geometry::Cone::g_nstacks); + glTranslated(0.0, 0.0, height); + gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); + glPopMatrix(); +} + +// Render Cylinder +void Renderer::doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height, bool segmented) const { + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + gluQuadricTexture(qobj, true); + glPushMatrix(); + glTranslated(center[0], center[1], center[2]); + GLdouble mat[16]; + V3D unit(0, 0, 1); + Quat rot(unit, axis); + rot.GLMatrix(&mat[0]); + glMultMatrixd(mat); + gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, + segmented ? 1 : Cylinder::g_nstacks); + gluQuadricTexture(qobj, false); + gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); + glTranslated(0.0, 0.0, height); + gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); + glPopMatrix(); +} + +// Render Bitmap for RectangularDetector +void Renderer::doRender(const RectangularDetector *rectDet) const { + // Because texture colours are combined with the geometry colour + // make sure the current colour is white + glColor3f(1.0f, 1.0f, 1.0f); + + // Nearest-neighbor scaling + GLint texParam = GL_NEAREST; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam); + + glEnable(GL_TEXTURE_2D); // enable texture mapping + + int texx, texy; + rectDet->getTextureSize(texx, texy); + double tex_frac_x = (1.0 * rectDet->xpixels()) / (texx); + double tex_frac_y = (1.0 * rectDet->ypixels()) / (texy); + + glBegin(GL_QUADS); + + glTexCoord2f(0.0, 0.0); + V3D pos; + pos = rectDet->getRelativePosAtXY(0, 0); + pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (-0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glTexCoord2f(static_cast(tex_frac_x), 0.0); + pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, 0); + pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (-0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glTexCoord2f(static_cast(tex_frac_x), + static_cast(tex_frac_y)); + pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, + rectDet->ypixels() - 1); + pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (+0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glTexCoord2f(0.0, static_cast(tex_frac_y)); + pos = rectDet->getRelativePosAtXY(0, rectDet->ypixels() - 1); + pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (+0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + + glEnd(); + if (glGetError() > 0) + std::cout << "OpenGL error in BitmapGeometryHandler::render \n"; + + glDisable( + GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. +} + +void Renderer::doRender(const StructuredDetector *structDet) const { + auto xVerts = structDet->getXValues(); + auto yVerts = structDet->getYValues(); + auto r = structDet->getR(); + auto g = structDet->getG(); + auto b = structDet->getB(); + + if (xVerts.size() != yVerts.size()) + return; + + auto w = structDet->xPixels() + 1; + auto h = structDet->yPixels() + 1; + + glBegin(GL_QUADS); + + for (size_t iy = 0; iy < h - 1; iy++) { + for (size_t ix = 0; ix < w - 1; ix++) { + + glColor3ub((GLubyte)r[(iy * (w - 1)) + ix], + (GLubyte)g[(iy * (w - 1)) + ix], + (GLubyte)b[(iy * (w - 1)) + ix]); + V3D pos; + pos = V3D(xVerts[(iy * w) + ix + w], yVerts[(iy * w) + ix + w], 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + pos = V3D(xVerts[(iy * w) + ix + w + 1], yVerts[(iy * w) + ix + w + 1], + 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + pos = V3D(xVerts[(iy * w) + ix + 1], yVerts[(iy * w) + ix + 1], 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + pos = V3D(xVerts[(iy * w) + ix], yVerts[(iy * w) + ix], 0.0); + glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), + static_cast(pos.Z())); + } + } + + glEnd(); + + if (glGetError() > 0) + std::cout << "OpenGL error in StructuredGeometryHandler::render \n"; + + glDisable( + GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. +} +} // namespace detail +} // namespace Geometry +} // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp index a509c8b577b9..9aa50d6d9a1c 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp @@ -69,8 +69,8 @@ void vtkGeometryCacheReader::readCacheForObject(IObject *obj) { } // Read the cache from the element int noOfTriangles = 0, noOfPoints = 0; - double *Points; - int *Faces; + std::vector Points; + std::vector Faces; std::stringstream buff; // Read number of points buff << pEle->getAttribute("NumberOfPoints"); @@ -83,15 +83,16 @@ void vtkGeometryCacheReader::readCacheForObject(IObject *obj) { // Read Points Element *pPts = pEle->getChildElement("Points")->getChildElement("DataArray"); - readPoints(pPts, &noOfPoints, &Points); + readPoints(pPts, noOfPoints, Points); // Read Triangles Element *pTris = pEle->getChildElement("Polys")->getChildElement("DataArray"); - readTriangles(pTris, &noOfTriangles, &Faces); + readTriangles(pTris, noOfTriangles, Faces); // First check whether Object can be written to the file boost::shared_ptr handle = obj->getGeometryHandler(); - handle->setGeometryCache(noOfPoints, noOfTriangles, Points, Faces); + handle->setGeometryCache(noOfPoints, noOfTriangles, std::move(Points), + std::move(Faces)); } /** @@ -112,14 +113,15 @@ vtkGeometryCacheReader::getElementByObjectName(std::string name) { * Read the points from the element */ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle, - int *noOfPoints, double **points) { + int noOfPoints, + std::vector &points) { if (pEle == nullptr) { - *noOfPoints = 0; + noOfPoints = 0; return; } // Allocate memory - *points = new double[(*noOfPoints) * 3]; - if (*points == nullptr) // Out of memory + points.resize(noOfPoints * 3); + if (points.size() != (noOfPoints * 3)) // Out of memory { g_log.error("Cannot allocate memory for triangle cache of Object "); return; @@ -127,25 +129,26 @@ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle, if (pEle->getAttribute("format") == "ascii") { // Read from Ascii std::stringstream buf; buf << pEle->innerText(); - for (int i = 0; i < (*noOfPoints) * 3; i++) { - buf >> (*points)[i]; + for (int i = 0; i < points.size(); i++) { + buf >> points[i]; } - } else { // Read from binary - } + } + // Read from binary otherwise } /** * Read triangle face indexs */ void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle, - int *noOfTriangles, int **faces) { + int noOfTriangles, + std::vector &faces) { if (pEle == nullptr) { - *noOfTriangles = 0; + noOfTriangles = 0; return; } // Allocate memory - *faces = new int[(*noOfTriangles) * 3]; - if (*faces == nullptr) // Out of memory + faces.resize(noOfTriangles * 3); + if (faces.size() != (noOfTriangles * 3)) // Out of memory { g_log.error("Cannot allocate memory for triangle cache of Object "); return; @@ -153,11 +156,11 @@ void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle, if (pEle->getAttribute("format") == "ascii") { // Read from Ascii std::stringstream buf; buf << pEle->innerText(); - for (int i = 0; i < (*noOfTriangles) * 3; i++) { - buf >> (*faces)[i]; + for (int i = 0; i < faces.size(); i++) { + buf >> faces[i]; } - } else { // Read from binary } + // Read from binary otherwise } } } diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp index 47a8719cffdf..8fdf921233a3 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp @@ -85,9 +85,9 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { // get the name of the Object int name = obj->getName(); // get number of point - int noPts = handle->NumberOfPoints(); + auto noPts = handle->numberOfPoints(); // get number of triangles - int noTris = handle->NumberOfTriangles(); + auto noTris = handle->numberOfTriangles(); // Add Piece AutoPtr pPiece = mDoc->createElement("Piece"); // Add attribute name @@ -110,9 +110,9 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { pPtsDataArray->setAttribute("format", "ascii"); buf.str(""); // get the triangles info - double *points = handle->getTriangleVertices(); + const auto &points = handle->getTriangleVertices().get(); int i; - for (i = 0; i < noPts * 3; i++) { + for (i = 0; i < points.size(); i++) { buf << points[i] << " "; } AutoPtr pPointText = mDoc->createTextNode(buf.str()); @@ -127,8 +127,8 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { pTrisDataArray->setAttribute("format", "ascii"); buf.str(""); - int *faces = handle->getTriangleFaces(); - for (i = 0; i < noTris * 3; i++) { + const auto &faces = handle->getTriangleFaces().get(); + for (i = 0; i < faces.size(); i++) { buf << faces[i] << " "; } AutoPtr pTrisDataText = mDoc->createTextNode(buf.str()); From 8c0deff40e57d1c787b9be6795df536243bf6a37 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 29 Nov 2017 12:26:06 +0000 Subject: [PATCH 015/364] remove shape handline from GluGeometryHandler in ShapeInfo re #21248 --- Framework/Geometry/CMakeLists.txt | 2 + .../inc/MantidGeometry/Objects/CSGObject.h | 1 + .../Rendering/GeometryTriangulator.h | 9 +- .../Rendering/GluGeometryHandler.h | 34 +- .../inc/MantidGeometry/Rendering/Renderer.h | 69 ++-- .../inc/MantidGeometry/Rendering/ShapeInfo.h | 91 +++++ Framework/Geometry/src/Objects/CSGObject.cpp | 44 +-- .../Geometry/src/Objects/ShapeFactory.cpp | 21 +- .../src/Rendering/BitmapGeometryHandler.cpp | 2 +- .../src/Rendering/CacheGeometryHandler.cpp | 4 +- .../src/Rendering/GeometryTriangulator.cpp | 8 +- .../src/Rendering/GluGeometryHandler.cpp | 100 +----- .../src/Rendering/OCGeometryHandler.cpp | 2 +- Framework/Geometry/src/Rendering/Renderer.cpp | 325 +++++++++--------- .../Geometry/src/Rendering/ShapeInfo.cpp | 67 ++++ .../Rendering/StructuredGeometryHandler.cpp | 2 +- Framework/Geometry/test/CSGObjectTest.h | 12 +- 17 files changed, 423 insertions(+), 370 deletions(-) create mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h create mode 100644 Framework/Geometry/src/Rendering/ShapeInfo.cpp diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index 729f043040a7..c3ec3cbba116 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -112,6 +112,7 @@ set ( SRC_FILES src/Rendering/CacheGeometryHandler.cpp src/Rendering/GeometryHandler.cpp src/Rendering/Renderer.cpp + src/Rendering/ShapeInfo.cpp src/Rendering/GluGeometryHandler.cpp src/Rendering/StructuredGeometryHandler.cpp src/Rendering/vtkGeometryCacheReader.cpp @@ -273,6 +274,7 @@ set ( INC_FILES inc/MantidGeometry/Rendering/CacheGeometryHandler.h inc/MantidGeometry/Rendering/GeometryHandler.h inc/MantidGeometry/Rendering/Renderer.h + inc/MantidGeometry/Rendering/ShapeInfo.h inc/MantidGeometry/Rendering/GluGeometryHandler.h inc/MantidGeometry/Rendering/OCGeometryHandler.h inc/MantidGeometry/Rendering/OpenGL_Headers.h diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index afffe49b9283..3f88ceb9782e 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -250,6 +250,7 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { /// Geometry Handle for rendering boost::shared_ptr m_handler; friend class CacheGeometryHandler; + friend class GeometryRenderer; /// Is geometry caching enabled? bool bGeometryCaching; /// a pointer to a class for reading from the geometry cache diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index 945d35d7c74d..74c8a7cc0718 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -63,9 +63,10 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { const std::vector &getTriangleFaces(); #ifdef ENABLE_OPENCASCADE private: - TopoDS_Shape *m_objSurface; ///< Storage for the output surface - /// Analyze the object - /// OpenCascade analysis of object surface + std::unique_ptr + m_objSurface; ///< Storage for the output surface + /// Analyze the object + /// OpenCascade analysis of object surface void OCAnalyzeObject(); size_t numPoints() const; size_t numFaces() const; @@ -74,7 +75,7 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { public: /// Return OpenCascade surface. - TopoDS_Shape *getOCSurface(); + const TopoDS_Shape &getOCSurface(); #endif }; } // namespace detail diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h index 04c8cf36264f..b4a24856e830 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h @@ -3,6 +3,7 @@ #include "MantidGeometry/DllConfig.h" #include "MantidGeometry/Rendering/GeometryHandler.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" namespace Mantid { namespace Kernel { @@ -45,27 +46,13 @@ class CSGObject; File change history is stored at: */ class MANTID_GEOMETRY_DLL GluGeometryHandler : public GeometryHandler { -public: - /// the type of the geometry eg CUBOID,CYLINDER,CONE,SPHERE - enum class GeometryType { - NOSHAPE = 0, - CUBOID, ///< CUBOID - HEXAHEDRON, ///< HEXAHEDRON - SPHERE, ///< SPHERE - CYLINDER, ///< CYLINDER - CONE, ///< CONE - SEGMENTED_CYLINDER ///< Cylinder with 1 or more segments (along the axis). - /// Sizes of segments are important. - }; - private: static Kernel::Logger &PLog; ///< The official logger /// Object/ObjComponent std::vector m_points; double radius; /// obj) override; GeometryHandler *createInstance(CSGObject *) override; /// sets the geometry handler for a cuboid - void setCuboid(const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &, - const Kernel::V3D &); - /// sets the geometry handler for a hexahedron - void setHexahedron(const Kernel::V3D &, const Kernel::V3D &, - const Kernel::V3D &, const Kernel::V3D &, - const Kernel::V3D &, const Kernel::V3D &, - const Kernel::V3D &, const Kernel::V3D &); - /// sets the geometry handler for a cone - void setSphere(const Kernel::V3D &, double); - /// sets the geometry handler for a cylinder - void setCylinder(const Kernel::V3D &, const Kernel::V3D &, double, double); - /// sets the geometry handler for a cone - void setCone(const Kernel::V3D &, const Kernel::V3D &, double, double); - /// sets the geometry handler for a segmented cylinder - void setSegmentedCylinder(const Kernel::V3D &, const Kernel::V3D &, double, - double); + void setShapeInfo(detail::ShapeInfo &&shapeInfo); void Triangulate() override; void Render() override; void Initialize() override; diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h index 86902702410b..3d2f37cefec2 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h @@ -45,6 +45,8 @@ class IObjComponent; Code Documentation is available at: */ namespace detail { +class ShapeInfo; + class MANTID_GEOMETRY_DLL Renderer { public: enum class RenderMode { Basic, Volumetric }; @@ -59,67 +61,44 @@ class MANTID_GEOMETRY_DLL Renderer { template void render(Args &&... args) const &; /// Render IObjComponent - void renderIObjComponent(IObjComponent *objComp, + void renderIObjComponent(const IObjComponent &objComp, RenderMode mode = RenderMode::Basic) const; /// Render Traingulated Surface void renderTriangulated(detail::GeometryTriangulator &triangulator, RenderMode mode = RenderMode::Basic) const; - /// Render OpenCascade Shape - void renderOpenCascade(TopoDS_Shape *objSurf, - RenderMode mode = RenderMode::Basic) const; + /// Renders a sphere, cuboid, hexahedron, cone or cylinder + void renderShape(const ShapeInfo &shapeInfo) const; + /// Renders a Bitmap (used for rendering RectangularDetector) + void renderBitmap(const RectangularDetector &rectDet, + RenderMode mode = RenderMode::Basic) const; + /// Renders structured geometry (used for rendering StructuredDetector) + void renderStructured(const StructuredDetector &structDet, + RenderMode mode = RenderMode::Basic) const; +private: + mutable RenderMode m_renderMode; /// Renders a sphere - void renderSphere(const Kernel::V3D ¢er, double radius, - RenderMode mode = RenderMode::Basic) const; + void doRenderSphere(const ShapeInfo &shapeInfo) const; /// Renders a cuboid - void renderCuboid(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4, - RenderMode mode = RenderMode::Basic) const; + void doRenderCuboid(const ShapeInfo &shapeInfo) const; /// Renders a Hexahedron from the input values - void renderHexahedron(const std::vector &points, - RenderMode mode = RenderMode::Basic) const; + void doRenderHexahedron(const ShapeInfo &shapeInfo) const; /// Renders a Cone from the input values - void renderCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, - RenderMode mode = RenderMode::Basic) const; + void doRenderCone(const ShapeInfo &shapeInfo) const; /// Renders a Cylinder/Segmented cylinder from the input values - void renderCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, bool segmented = false, - RenderMode mode = RenderMode::Basic) const; - /// Renders a Bitmap (used for rendering RectangularDetector) - void renderBitmap(const RectangularDetector *rectDet, - RenderMode mode = RenderMode::Basic) const; - /// Renders structured geometry (used for rendering StructuredDetector) - void renderStructured(const StructuredDetector *structDet, - RenderMode mode = RenderMode::Basic) const; - -private: - mutable RenderMode m_renderMode; + void doRenderCylinder(const ShapeInfo &shapeInfo) const; // general geometry /// Render IObjComponent - void doRender(IObjComponent *ObjComp) const; + void doRender(const IObjComponent &ObjComp) const; /// Render Traingulated Surface void doRender(GeometryTriangulator &triangulator) const; +#ifdef ENABLE_OPENCASCADE /// Render OpenCascade Shape - void doRender(TopoDS_Shape *ObjSurf) const; - - // shapes - /// Renders a sphere - void doRender(const Kernel::V3D ¢er, double radius) const; - /// Renders a cuboid - void doRender(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4) const; - /// Renders a Hexahedron from the input values - void doRender(const std::vector &points) const; - /// Renders a Cone from the input values - void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height) const; - /// Renders a Cylinder/Segmented cylinder from the input values - void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, bool segmented) const; + void doRender(const TopoDS_Shape &ObjSurf) const; +#endif /// Renders a Bitmap (used for rendering RectangularDetector) - void doRender(const RectangularDetector *rectDet) const; + void doRender(const RectangularDetector &rectDet) const; /// Renders structured geometry (used for rendering StructuredDetector) - void doRender(const StructuredDetector *structDet) const; + void doRender(const StructuredDetector &structDet) const; }; template diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h new file mode 100644 index 000000000000..06e8ee92806d --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h @@ -0,0 +1,91 @@ +#ifndef MANTID_GEOMETRY_SHAPEINFO_H_ +#define MANTID_GEOMETRY_SHAPEINFO_H_ + +#include "MantidGeometry/DllConfig.h" +#include + +namespace Mantid { +namespace Kernel { +class V3D; +} +namespace Geometry { +class RectangularDetector; +class StructuredDetector; +class IObjComponent; + +/** ShapeInfo : Stored Object related shape information for rendering. + +Copyright © 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +This file is part of Mantid. + +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +File change history is stored at: +Code Documentation is available at: +*/ +namespace detail { +class MANTID_GEOMETRY_DLL ShapeInfo { +public: + enum class GeometryShape { + NOSHAPE = 0, + CUBOID, ///< CUBOID + HEXAHEDRON, ///< HEXAHEDRON + SPHERE, ///< SPHERE + CYLINDER, ///< CYLINDER + CONE, ///< CONE + SEGMENTED_CYLINDER ///< Cylinder with 1 or more segments (along the axis). + /// Sizes of segments are important. + }; + +private: + std::vector m_points; + double m_radius; ///< Radius for the sphere, cone and cylinder + double m_height; ///< height for cone and cylinder; + GeometryShape m_shape; + +public: + ShapeInfo(); + ShapeInfo(const ShapeInfo &) = default; + const std::vector &points() const; + double radius() const; + double height() const; + GeometryShape shape() const; + + void getObjectGeometry(int &myshape, std::vector &points, + double &myradius, double &myheight) const; + /// sets the geometry handler for a cuboid + void setCuboid(const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &, + const Kernel::V3D &); + /// sets the geometry handler for a hexahedron + void setHexahedron(const Kernel::V3D &, const Kernel::V3D &, + const Kernel::V3D &, const Kernel::V3D &, + const Kernel::V3D &, const Kernel::V3D &, + const Kernel::V3D &, const Kernel::V3D &); + /// sets the geometry handler for a cone + void setSphere(const Kernel::V3D &, double); + /// sets the geometry handler for a cylinder + void setCylinder(const Kernel::V3D &, const Kernel::V3D &, double, double); + /// sets the geometry handler for a cone + void setCone(const Kernel::V3D &, const Kernel::V3D &, double, double); + /// sets the geometry handler for a segmented cylinder + void setSegmentedCylinder(const Kernel::V3D &, const Kernel::V3D &, double, + double); +}; +} // namespace detail +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_SHAPEINFO_H_ */ \ No newline at end of file diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index a03b8c05e153..3be854b59f7b 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -1015,21 +1015,21 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const { this->GetObjectGeom(type, geometry_vectors, radius, height); auto nTri = this->numberOfTriangles(); // Cylinders are by far the most frequently used - GluGeometryHandler::GeometryType gluType = - static_cast(type); + detail::ShapeInfo::GeometryShape gluType = + static_cast(type); switch (gluType) { - case GluGeometryHandler::GeometryType::CUBOID: + case detail::ShapeInfo::GeometryShape::CUBOID: return CuboidSolidAngle(observer, geometry_vectors); break; - case GluGeometryHandler::GeometryType::SPHERE: + case detail::ShapeInfo::GeometryShape::SPHERE: return SphereSolidAngle(observer, geometry_vectors, radius); break; - case GluGeometryHandler::GeometryType::CYLINDER: + case detail::ShapeInfo::GeometryShape::CYLINDER: return CylinderSolidAngle(observer, geometry_vectors[0], geometry_vectors[1], radius, height); break; - case GluGeometryHandler::GeometryType::CONE: + case detail::ShapeInfo::GeometryShape::CONE: return ConeSolidAngle(observer, geometry_vectors[0], geometry_vectors[1], radius, height); break; @@ -1101,16 +1101,16 @@ double CSGObject::triangleSolidAngle(const V3D &observer, int type; std::vector vectors; this->GetObjectGeom(type, vectors, radius, height); - GluGeometryHandler::GeometryType gluType = - static_cast(type); + detail::ShapeInfo::GeometryShape gluType = + static_cast(type); switch (gluType) { - case GluGeometryHandler::GeometryType::CUBOID: + case detail::ShapeInfo::GeometryShape::CUBOID: for (auto &vector : vectors) vector *= scaleFactor; return CuboidSolidAngle(observer, vectors); break; - case GluGeometryHandler::GeometryType::SPHERE: + case detail::ShapeInfo::GeometryShape::SPHERE: return SphereSolidAngle(observer, vectors, radius); break; default: @@ -1496,10 +1496,10 @@ double CSGObject::volume() const { double radius; std::vector vectors; this->GetObjectGeom(type, vectors, radius, height); - GluGeometryHandler::GeometryType gluType = - static_cast(type); + detail::ShapeInfo::GeometryShape gluType = + static_cast(type); switch (gluType) { - case GluGeometryHandler::GeometryType::CUBOID: { + case detail::ShapeInfo::GeometryShape::CUBOID: { // Here, the volume is calculated by the triangular method. // We use one of the vertices (vectors[0]) as the reference // point. @@ -1529,9 +1529,9 @@ double CSGObject::volume() const { volume += brt.scalar_prod(brb.cross_prod(blb)); return volume / 6; } - case GluGeometryHandler::GeometryType::SPHERE: + case detail::ShapeInfo::GeometryShape::SPHERE: return 4.0 / 3.0 * M_PI * radius * radius * radius; - case GluGeometryHandler::GeometryType::CYLINDER: + case detail::ShapeInfo::GeometryShape::CYLINDER: return M_PI * radius * radius * height; default: // Fall back to Monte Carlo method. @@ -1768,12 +1768,12 @@ void CSGObject::calcBoundingBoxByGeometry() { // Will only work for shapes handled by GluGeometryHandler m_handler->GetObjectGeom(type, vectors, radius, height); - GluGeometryHandler::GeometryType gluType = - static_cast(type); + detail::ShapeInfo::GeometryShape gluType = + static_cast(type); // Type of shape is given as a simple integer switch (gluType) { - case GluGeometryHandler::GeometryType::CUBOID: { + case detail::ShapeInfo::GeometryShape::CUBOID: { // Points as defined in IDF XML auto &lfb = vectors[0]; // Left-Front-Bottom auto &lft = vectors[1]; // Left-Front-Top @@ -1806,7 +1806,7 @@ void CSGObject::calcBoundingBoxByGeometry() { maxZ = std::max(maxZ, vector.Z()); } } break; - case GluGeometryHandler::GeometryType::HEXAHEDRON: { + case detail::ShapeInfo::GeometryShape::HEXAHEDRON: { // These will be replaced by more realistic values in the loop below minX = minY = minZ = std::numeric_limits::max(); maxX = maxY = maxZ = -std::numeric_limits::max(); @@ -1821,8 +1821,8 @@ void CSGObject::calcBoundingBoxByGeometry() { maxZ = std::max(maxZ, vector.Z()); } } break; - case GluGeometryHandler::GeometryType::CYLINDER: - case GluGeometryHandler::GeometryType::SEGMENTED_CYLINDER: { + case detail::ShapeInfo::GeometryShape::CYLINDER: + case detail::ShapeInfo::GeometryShape::SEGMENTED_CYLINDER: { // Center-point of base and normalized axis based on IDF XML auto &base = vectors[0]; auto &axis = vectors[1]; @@ -1845,7 +1845,7 @@ void CSGObject::calcBoundingBoxByGeometry() { maxZ = std::max(base.Z(), top.Z()) + rz; } break; - case GluGeometryHandler::GeometryType::CONE: { + case detail::ShapeInfo::GeometryShape::CONE: { auto &tip = vectors[0]; // Tip-point of cone auto &axis = vectors[1]; // Normalized axis auto base = tip + (axis * height); // Center of base diff --git a/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Framework/Geometry/src/Objects/ShapeFactory.cpp index 4b5fbfba4650..079340c724af 100644 --- a/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -6,6 +6,7 @@ #include "MantidGeometry/Objects/CSGObject.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidGeometry/Rendering/GluGeometryHandler.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Surfaces/Cone.h" #include "MantidGeometry/Surfaces/Cylinder.h" #include "MantidGeometry/Surfaces/Plane.h" @@ -1407,11 +1408,12 @@ ShapeFactory::createHexahedralShape(double xlb, double xlf, double xrf, shape->populate(prim); auto handler = boost::make_shared(shape); - + detail::ShapeInfo shapeInfo; shape->setGeometryHandler(handler); - handler->setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft, + shapeInfo.setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft, hex.rft, hex.rbt); + handler->setShapeInfo(std::move(shapeInfo)); shape->defineBoundingBox(std::max(xrb, xrf), yrf, ZDEPTH, std::min(xlf, xlb), ylb, 0); @@ -1424,14 +1426,15 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, boost::shared_ptr Obj) { auto geomHandler = boost::make_shared(Obj); + detail::ShapeInfo shapeInfo; Obj->setGeometryHandler(geomHandler); if (pElem->tagName() == "cuboid") { auto corners = parseCuboid(pElem); - geomHandler->setCuboid(corners.lfb, corners.lft, corners.lbb, corners.rfb); + shapeInfo.setCuboid(corners.lfb, corners.lft, corners.lbb, corners.rfb); } else if (pElem->tagName() == "hexahedron") { auto corners = parseHexahedron(pElem); - geomHandler->setHexahedron(corners.lbb, corners.lfb, corners.rfb, + shapeInfo.setHexahedron(corners.lbb, corners.lfb, corners.rfb, corners.rbb, corners.lbt, corners.lft, corners.rft, corners.rbt); } else if (pElem->tagName() == "sphere") { @@ -1440,7 +1443,7 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, V3D centre; if (pElemCentre) centre = parsePosition(pElemCentre); - geomHandler->setSphere(centre, std::stod(pElemRadius->getAttribute("val"))); + shapeInfo.setSphere(centre, std::stod(pElemRadius->getAttribute("val"))); } else if (pElem->tagName() == "cylinder") { Element *pElemCentre = getShapeElement(pElem, "centre-of-bottom-base"); Element *pElemAxis = getShapeElement(pElem, "axis"); @@ -1448,7 +1451,7 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, Element *pElemHeight = getShapeElement(pElem, "height"); V3D normVec = parsePosition(pElemAxis); normVec.normalize(); - geomHandler->setCylinder(parsePosition(pElemCentre), normVec, + shapeInfo.setCylinder(parsePosition(pElemCentre), normVec, std::stod(pElemRadius->getAttribute("val")), std::stod(pElemHeight->getAttribute("val"))); } else if (pElem->tagName() == "segmented-cylinder") { @@ -1458,7 +1461,7 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, Element *pElemHeight = getShapeElement(pElem, "height"); V3D normVec = parsePosition(pElemAxis); normVec.normalize(); - geomHandler->setSegmentedCylinder( + shapeInfo.setSegmentedCylinder( parsePosition(pElemCentre), normVec, std::stod(pElemRadius->getAttribute("val")), std::stod(pElemHeight->getAttribute("val"))); @@ -1473,8 +1476,10 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, double height = std::stod(pElemHeight->getAttribute("val")); double radius = height * tan(M_PI * std::stod(pElemAngle->getAttribute("val")) / 180.0); - geomHandler->setCone(parsePosition(pElemTipPoint), normVec, radius, height); + shapeInfo.setCone(parsePosition(pElemTipPoint), normVec, radius, height); } + + geomHandler->setShapeInfo(std::move(shapeInfo)); } } // namespace Geometry diff --git a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp index 16f4e64eb05c..2e9ec357927a 100644 --- a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp @@ -58,7 +58,7 @@ void BitmapGeometryHandler::Triangulate() { //---------------------------------------------------------------------------------------------- ///< Render Object or ObjComponent void BitmapGeometryHandler::Render() { - m_renderer.render(m_rectDet); + m_renderer.render(*m_rectDet); } //---------------------------------------------------------------------------------------------- diff --git a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp index 56b21884aecb..139f46e705a3 100644 --- a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp @@ -77,7 +77,7 @@ void CacheGeometryHandler::Render() { Triangulate(); m_renderer.renderTriangulated(*m_triangulator); } else if (ObjComp != nullptr) { - m_renderer.render(ObjComp); + m_renderer.render(*ObjComp); } } @@ -88,7 +88,7 @@ void CacheGeometryHandler::Initialize() { Triangulate(); m_renderer.renderTriangulated(*m_triangulator); } else if (ObjComp != nullptr) { - m_renderer.render(ObjComp); + m_renderer.render(*ObjComp); } } diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index b1b982664868..fc2a8fa2c144 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -76,9 +76,9 @@ void GeometryTriangulator::triangulate() { #ifdef ENABLE_OPENCASCADE /// Return OpenCascade surface. -TopoDS_Shape *GeometryTriangulator::getOCSurface() { +const TopoDS_Shape &GeometryTriangulator::getOCSurface() { checkTriangulated(); - return m_objSurface; + return *m_objSurface; } #endif @@ -119,13 +119,13 @@ void GeometryTriangulator::OCAnalyzeObject() { // Get the top rule tree in Obj const Rule *top = m_obj->topRule(); if (top == nullptr) { - m_objSurface = new TopoDS_Shape(); + m_objSurface.reset(new TopoDS_Shape()); return; } // Traverse through Rule TopoDS_Shape Result = const_cast(top)->analyze(); try { - m_objSurface = new TopoDS_Shape(Result); + m_objSurface.reset(new TopoDS_Shape(Result)); BRepMesh_IncrementalMesh(Result, 0.001); } catch (StdFail_NotDone &) { g_log.error("Cannot build the geometry. Check the geometry definition"); diff --git a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp index 4c2c8e1a93b5..61cae7445068 100644 --- a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp @@ -9,22 +9,20 @@ namespace Mantid { namespace Geometry { using Kernel::V3D; +using namespace detail; GluGeometryHandler::GluGeometryHandler(IObjComponent *comp) - : GeometryHandler(comp), radius(0.0), height(0.0), - type(GeometryType::NOSHAPE) {} + : GeometryHandler(comp), radius(0.0), height(0.0){} GluGeometryHandler::GluGeometryHandler(boost::shared_ptr obj) - : GeometryHandler(std::move(obj)), radius(0.0), height(0.0), - type(GeometryType::NOSHAPE) {} + : GeometryHandler(std::move(obj)), radius(0.0), height(0.0) {} GluGeometryHandler::GluGeometryHandler(CSGObject *obj) - : GeometryHandler(obj), radius(0.0), height(0.0), - type(GeometryType::NOSHAPE) {} + : GeometryHandler(obj), radius(0.0), height(0.0) {} GluGeometryHandler::GluGeometryHandler(const GluGeometryHandler &other) : GeometryHandler(other), m_points(other.m_points), radius(other.radius), - height(other.height), type(other.type) { + height(other.height), m_shapeInfo(other.m_shapeInfo) { } boost::shared_ptr GluGeometryHandler::clone() const { @@ -54,100 +52,24 @@ void GluGeometryHandler::Triangulate() { void GluGeometryHandler::Render() { if (Obj != nullptr) { - switch (type) { - case GeometryType::CUBOID: - m_renderer.renderCuboid(m_points[0], m_points[1], m_points[2], - m_points[3]); - break; - case GeometryType::HEXAHEDRON: - m_renderer.renderHexahedron( - std::vector{m_points[0], m_points[1], m_points[2], m_points[3], - m_points[4], m_points[5], m_points[6], m_points[7]}); - break; - case GeometryType::SPHERE: - m_renderer.renderSphere(m_points[0], radius); - break; - case GeometryType::CYLINDER: - m_renderer.renderCylinder(m_points[0], m_points[1], radius, height); - break; - case GeometryType::CONE: - m_renderer.renderCone(m_points[0], m_points[1], radius, height); - break; - case GeometryType::SEGMENTED_CYLINDER: - m_renderer.renderCylinder(m_points[0], m_points[1], radius, height, true); - break; - case GeometryType::NOSHAPE: - break; - } + m_renderer.renderShape(m_shapeInfo); } else if (ObjComp != nullptr) { - m_renderer.render(ObjComp); + m_renderer.render(*ObjComp); } } void GluGeometryHandler::GetObjectGeom(int &mytype, std::vector &vectors, double &myradius, double &myheight) { - mytype = 0; - if (Obj != nullptr) { - mytype = static_cast(type); - vectors = m_points; - switch (type) { - case GeometryType::CUBOID: - break; - case GeometryType::HEXAHEDRON: - break; - case GeometryType::SPHERE: - myradius = radius; - break; - default: - myradius = radius; - myheight = height; - break; - } - } + m_shapeInfo.getObjectGeometry(mytype, vectors, myradius, myheight); } void GluGeometryHandler::Initialize() { Render(); } -void GluGeometryHandler::setCuboid(const V3D &p1, const V3D &p2, const V3D &p3, - const V3D &p4) { - type = GeometryType::CUBOID; - m_points.assign({p1, p2, p3, p4}); -} - -void GluGeometryHandler::setHexahedron(const V3D &p1, const V3D &p2, - const V3D &p3, const V3D &p4, - const V3D &p5, const V3D &p6, - const V3D &p7, const V3D &p8) { - type = GeometryType::HEXAHEDRON; - m_points.assign({p1, p2, p3, p4, p5, p6, p7, p8}); +void GluGeometryHandler::setShapeInfo(detail::ShapeInfo &&shapeInfo) +{ + m_shapeInfo = std::move(shapeInfo); } -void GluGeometryHandler::setSphere(const V3D &c, double r) { - type = GeometryType::SPHERE; - m_points.assign({c}); - radius = r; -} -void GluGeometryHandler::setCylinder(const V3D &c, const V3D &a, double r, - double h) { - type = GeometryType::CYLINDER; - m_points.assign({c, a}); - radius = r; - height = h; -} -void GluGeometryHandler::setCone(const V3D &c, const V3D &a, double r, - double h) { - type = GeometryType::CONE; - m_points.assign({c, a}); - radius = r; - height = h; -} -void GluGeometryHandler::setSegmentedCylinder(const V3D &c, const V3D &a, - double r, double h) { - type = GeometryType::SEGMENTED_CYLINDER; - m_points.assign({c, a}); - radius = r; - height = h; -} } } diff --git a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp index 5de526d082d6..502989410f56 100644 --- a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp @@ -69,7 +69,7 @@ void OCGeometryHandler::Render() { Triangulate(); m_renderer.render(m_triangulator->getOCSurface()); } else if (ObjComp != nullptr) { - m_renderer.render(ObjComp); + m_renderer.render(*ObjComp); } } diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index 3ed31f227780..7d6f03dd3f69 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -3,6 +3,7 @@ #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Instrument/StructuredDetector.h" #include "MantidGeometry/Rendering/GeometryTriangulator.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Surfaces/Cone.h" #include "MantidGeometry/Surfaces/Cylinder.h" #include "MantidGeometry/Surfaces/Sphere.h" @@ -51,157 +52,76 @@ using Kernel::Quat; using Kernel::V3D; namespace detail { -void Renderer::renderIObjComponent(IObjComponent *objComp, +void Renderer::renderIObjComponent(const IObjComponent &objComp, RenderMode mode) const { render(mode, objComp); } void Renderer::renderTriangulated(detail::GeometryTriangulator &triangulator, RenderMode mode) const { +#ifdef ENABLE_OPENCASCADE + auto surface = triangulator.getOCSurface(); + if (!surface.IsNull()) + render(mode, surface); + else + render(mode, triangulator); +#else render(mode, triangulator); +#endif } -void Renderer::renderOpenCascade(TopoDS_Shape *objSurf, RenderMode mode) const { - render(mode, objSurf); -} - -void Renderer::renderSphere(const Kernel::V3D ¢er, double radius, - RenderMode mode) const { - render(mode, center, radius); -} - -void Renderer::renderCuboid(const Kernel::V3D &Point1, - const Kernel::V3D &Point2, - const Kernel::V3D &Point3, - const Kernel::V3D &Point4, RenderMode mode) const { - render(mode, Point1, Point2, Point3, Point4); -} - -void Renderer::renderHexahedron(const std::vector &points, - RenderMode mode) const { - render(mode, points); -} - -void Renderer::renderCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, RenderMode mode) const { - render(mode, center, axis, radius, height); -} - -void Renderer::renderCylinder(const Kernel::V3D ¢er, - const Kernel::V3D &axis, double radius, - double height, bool segmented, - RenderMode mode) const { - render(mode, center, axis, radius, height, segmented); +void Renderer::renderShape(const ShapeInfo &shapeInfo) const { + switch (shapeInfo.shape()) { + case ShapeInfo::GeometryShape::CUBOID: + doRenderCuboid(shapeInfo); + break; + case ShapeInfo::GeometryShape::SPHERE: + doRenderSphere(shapeInfo); + break; + case ShapeInfo::GeometryShape::HEXAHEDRON: + doRenderHexahedron(shapeInfo); + break; + case ShapeInfo::GeometryShape::CONE: + doRenderCone(shapeInfo); + break; + case ShapeInfo::GeometryShape::CYLINDER: + case ShapeInfo::GeometryShape::SEGMENTED_CYLINDER: + doRenderCylinder(shapeInfo); + break; + } } -void Renderer::renderBitmap(const RectangularDetector *rectDet, +void Renderer::renderBitmap(const RectangularDetector &rectDet, RenderMode mode) const { render(mode, rectDet); } -void Renderer::renderStructured(const StructuredDetector *structDet, +void Renderer::renderStructured(const StructuredDetector &structDet, RenderMode mode) const { render(mode, structDet); } -// Render IObjectComponent -void Renderer::doRender(IObjComponent *ObjComp) const { - glPushMatrix(); - V3D pos = ObjComp->getPos(); - Quat rot = ObjComp->getRotation(); - double rotGL[16]; - rot.GLMatrix(&rotGL[0]); - glTranslated(pos[0], pos[1], pos[2]); - glMultMatrixd(rotGL); - V3D scaleFactor = ObjComp->getScaleFactor(); - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - ObjComp->drawObject(); - glPopMatrix(); -} - -// Render triangulated surface -void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { - const auto &faces = triangulator.getTriangleFaces(); - const auto &points = triangulator.getTriangleVertices(); - glBegin(GL_TRIANGLES); - V3D normal; - for (int i = 0; i < triangulator.numTriangleFaces(); i++) { - int index1 = faces[i * 3] * 3; - int index2 = faces[i * 3 + 1] * 3; - int index3 = faces[i * 3 + 2] * 3; - // Calculate normal and normalize - V3D v1(points[index1], points[index1 + 1], points[index1 + 2]); - V3D v2(points[index2], points[index2 + 1], points[index2 + 2]); - V3D v3(points[index3], points[index3 + 1], points[index3 + 2]); - normal = (v1 - v2).cross_prod(v2 - v3); - normal.normalize(); - glNormal3d(normal[0], normal[1], normal[2]); - glVertex3dv(&points[index1]); - glVertex3dv(&points[index2]); - glVertex3dv(&points[index3]); - } - glEnd(); -} - -// Render OpenCascade Shape -void Renderer::doRender(TopoDS_Shape *ObjSurf) const { - glBegin(GL_TRIANGLES); - if ((ObjSurf != nullptr) && !ObjSurf->IsNull()) { - TopExp_Explorer Ex; - for (Ex.Init(*ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - TColgp_Array1OfPnt tab(1, (facing->NbNodes())); - tab = facing->Nodes(); - Poly_Array1OfTriangle tri(1, facing->NbTriangles()); - tri = facing->Triangles(); - for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { - Poly_Triangle trian = tri.Value(i); - Standard_Integer index1, index2, index3; - trian.Get(index1, index2, index3); - gp_Pnt point1 = tab.Value(index1); - gp_Pnt point2 = tab.Value(index2); - gp_Pnt point3 = tab.Value(index3); - gp_XYZ pt1 = tab.Value(index1).XYZ(); - gp_XYZ pt2 = tab.Value(index2).XYZ(); - gp_XYZ pt3 = tab.Value(index3).XYZ(); - - gp_XYZ v1 = pt2 - pt1; - gp_XYZ v2 = pt3 - pt2; - - gp_XYZ normal = v1 ^ v2; - normal.Normalize(); - glNormal3d(normal.X(), normal.Y(), normal.Z()); - glVertex3d(point1.X(), point1.Y(), point1.Z()); - glVertex3d(point2.X(), point2.Y(), point2.Z()); - glVertex3d(point3.X(), point3.Y(), point3.Z()); - } - } - } - glEnd(); -} - -// Render Sphere -void Renderer::doRender(const Kernel::V3D ¢er, double radius) const { +void Renderer::doRenderSphere(const ShapeInfo &shapeInfo) const +{ // create glu sphere GLUquadricObj *qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); gluQuadricNormals(qobj, GL_SMOOTH); glPushMatrix(); + auto center = shapeInfo.points()[0]; glTranslated(center[0], center[1], center[2]); - gluSphere(qobj, radius, Sphere::g_nslices, Sphere::g_nstacks); + gluSphere(qobj, shapeInfo.radius(), Sphere::g_nslices, Sphere::g_nstacks); glPopMatrix(); gluDeleteQuadric(qobj); } -// Render Cuboid -void Renderer::doRender(const V3D &Point1, const V3D &Point2, const V3D &Point3, - const V3D &Point4) const { - V3D vec0 = Point1; - V3D vec1 = Point2 - Point1; - V3D vec2 = Point3 - Point1; - V3D vec3 = Point4 - Point1; +void Renderer::doRenderCuboid(const ShapeInfo &shapeInfo) const +{ + const auto &points = shapeInfo.points(); + V3D vec0 = points[0]; + V3D vec1 = points[1] - points[0]; + V3D vec2 = points[2] - points[0]; + V3D vec3 = points[3] - points[0]; V3D vertex[8]; vertex[0] = vec0; vertex[1] = vec0 + vec3; @@ -213,19 +133,19 @@ void Renderer::doRender(const V3D &Point1, const V3D &Point2, const V3D &Point3, vertex[7] = vec0 + vec1 + vec2; int faceindex[6][4] = { - {0, 1, 2, 3}, // top - {0, 3, 7, 4}, // left - {3, 2, 6, 7}, // back - {2, 1, 5, 6}, // right - {0, 4, 5, 1}, // front - {4, 7, 6, 5}, // bottom + { 0, 1, 2, 3 }, // top + { 0, 3, 7, 4 }, // left + { 3, 2, 6, 7 }, // back + { 2, 1, 5, 6 }, // right + { 0, 4, 5, 1 }, // front + { 4, 7, 6, 5 }, // bottom }; V3D normal; // first face glBegin(GL_QUADS); for (auto &row : faceindex) { normal = (vertex[row[0]] - vertex[row[1]]) - .cross_prod((vertex[row[0]] - vertex[row[2]])); + .cross_prod((vertex[row[0]] - vertex[row[2]])); normal.normalize(); glNormal3d(normal[0], normal[1], normal[2]); for (const int ij : row) { @@ -251,9 +171,10 @@ void Renderer::doRender(const V3D &Point1, const V3D &Point2, const V3D &Point3, glEnd(); } -// Render Hexahedron -void Renderer::doRender(const std::vector &points) const { +void Renderer::doRenderHexahedron(const ShapeInfo &shapeInfo) const +{ glBegin(GL_QUADS); + const auto &points = shapeInfo.points(); // bottom glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); @@ -288,40 +209,46 @@ void Renderer::doRender(const std::vector &points) const { glEnd(); } -// Render Cone -void Renderer::doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height) const { +void Renderer::doRenderCone(const ShapeInfo &shapeInfo) const { glPushMatrix(); GLUquadricObj *qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); gluQuadricNormals(qobj, GL_SMOOTH); + auto center = shapeInfo.points()[0]; glTranslated(center[0], center[1], center[2]); GLdouble mat[16]; V3D unit(0, 0, 1); + auto axis = shapeInfo.points()[1]; Quat rot(unit, axis); rot.GLMatrix(&mat[0]); glMultMatrixd(mat); + auto radius = shapeInfo.radius(); + auto height = shapeInfo.height(); gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, - Geometry::Cone::g_nstacks); + Geometry::Cone::g_nstacks); glTranslated(0.0, 0.0, height); gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); glPopMatrix(); } -// Render Cylinder -void Renderer::doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, bool segmented) const { +void Renderer::doRenderCylinder(const ShapeInfo &shapeInfo) const { GLUquadricObj *qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); gluQuadricNormals(qobj, GL_SMOOTH); gluQuadricTexture(qobj, true); glPushMatrix(); + auto center = shapeInfo.points()[0]; glTranslated(center[0], center[1], center[2]); GLdouble mat[16]; V3D unit(0, 0, 1); + auto axis = shapeInfo.points()[1]; Quat rot(unit, axis); rot.GLMatrix(&mat[0]); glMultMatrixd(mat); + auto radius = shapeInfo.radius(); + auto height = shapeInfo.height(); + bool segmented = + shapeInfo.shape() == ShapeInfo::GeometryShape::SEGMENTED_CYLINDER; gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, segmented ? 1 : Cylinder::g_nstacks); gluQuadricTexture(qobj, false); @@ -331,8 +258,88 @@ void Renderer::doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, glPopMatrix(); } +// Render IObjectComponent +void Renderer::doRender(const IObjComponent &ObjComp) const { + glPushMatrix(); + V3D pos = ObjComp.getPos(); + Quat rot = ObjComp.getRotation(); + double rotGL[16]; + rot.GLMatrix(&rotGL[0]); + glTranslated(pos[0], pos[1], pos[2]); + glMultMatrixd(rotGL); + V3D scaleFactor = ObjComp.getScaleFactor(); + glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); + ObjComp.drawObject(); + glPopMatrix(); +} + +// Render triangulated surface +void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { + const auto &faces = triangulator.getTriangleFaces(); + const auto &points = triangulator.getTriangleVertices(); + glBegin(GL_TRIANGLES); + V3D normal; + for (int i = 0; i < triangulator.numTriangleFaces(); i++) { + int index1 = faces[i * 3] * 3; + int index2 = faces[i * 3 + 1] * 3; + int index3 = faces[i * 3 + 2] * 3; + // Calculate normal and normalize + V3D v1(points[index1], points[index1 + 1], points[index1 + 2]); + V3D v2(points[index2], points[index2 + 1], points[index2 + 2]); + V3D v3(points[index3], points[index3 + 1], points[index3 + 2]); + normal = (v1 - v2).cross_prod(v2 - v3); + normal.normalize(); + glNormal3d(normal[0], normal[1], normal[2]); + glVertex3dv(&points[index1]); + glVertex3dv(&points[index2]); + glVertex3dv(&points[index3]); + } + glEnd(); +} + +#ifdef ENABLE_OPENCASCADE +// Render OpenCascade Shape +void Renderer::doRender(const TopoDS_Shape &ObjSurf) const { + glBegin(GL_TRIANGLES); + if (ObjSurf.IsNull()) { + TopExp_Explorer Ex; + for (Ex.Init(ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) { + TopoDS_Face F = TopoDS::Face(Ex.Current()); + TopLoc_Location L; + Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); + TColgp_Array1OfPnt tab(1, (facing->NbNodes())); + tab = facing->Nodes(); + Poly_Array1OfTriangle tri(1, facing->NbTriangles()); + tri = facing->Triangles(); + for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { + Poly_Triangle trian = tri.Value(i); + Standard_Integer index1, index2, index3; + trian.Get(index1, index2, index3); + gp_Pnt point1 = tab.Value(index1); + gp_Pnt point2 = tab.Value(index2); + gp_Pnt point3 = tab.Value(index3); + gp_XYZ pt1 = tab.Value(index1).XYZ(); + gp_XYZ pt2 = tab.Value(index2).XYZ(); + gp_XYZ pt3 = tab.Value(index3).XYZ(); + + gp_XYZ v1 = pt2 - pt1; + gp_XYZ v2 = pt3 - pt2; + + gp_XYZ normal = v1 ^ v2; + normal.Normalize(); + glNormal3d(normal.X(), normal.Y(), normal.Z()); + glVertex3d(point1.X(), point1.Y(), point1.Z()); + glVertex3d(point2.X(), point2.Y(), point2.Z()); + glVertex3d(point3.X(), point3.Y(), point3.Z()); + } + } + } + glEnd(); +} +#endif + // Render Bitmap for RectangularDetector -void Renderer::doRender(const RectangularDetector *rectDet) const { +void Renderer::doRender(const RectangularDetector &rectDet) const { // Because texture colours are combined with the geometry colour // make sure the current colour is white glColor3f(1.0f, 1.0f, 1.0f); @@ -345,39 +352,39 @@ void Renderer::doRender(const RectangularDetector *rectDet) const { glEnable(GL_TEXTURE_2D); // enable texture mapping int texx, texy; - rectDet->getTextureSize(texx, texy); - double tex_frac_x = (1.0 * rectDet->xpixels()) / (texx); - double tex_frac_y = (1.0 * rectDet->ypixels()) / (texy); + rectDet.getTextureSize(texx, texy); + double tex_frac_x = (1.0 * rectDet.xpixels()) / (texx); + double tex_frac_y = (1.0 * rectDet.ypixels()) / (texy); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); V3D pos; - pos = rectDet->getRelativePosAtXY(0, 0); - pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (-0.5), + pos = rectDet.getRelativePosAtXY(0, 0); + pos += V3D(rectDet.xstep() * (-0.5), rectDet.ystep() * (-0.5), 0.0); // Adjust to account for the size of a pixel glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), static_cast(pos.Z())); glTexCoord2f(static_cast(tex_frac_x), 0.0); - pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, 0); - pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (-0.5), + pos = rectDet.getRelativePosAtXY(rectDet.xpixels() - 1, 0); + pos += V3D(rectDet.xstep() * (+0.5), rectDet.ystep() * (-0.5), 0.0); // Adjust to account for the size of a pixel glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), static_cast(pos.Z())); glTexCoord2f(static_cast(tex_frac_x), static_cast(tex_frac_y)); - pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, - rectDet->ypixels() - 1); - pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (+0.5), + pos = rectDet.getRelativePosAtXY(rectDet.xpixels() - 1, + rectDet.ypixels() - 1); + pos += V3D(rectDet.xstep() * (+0.5), rectDet.ystep() * (+0.5), 0.0); // Adjust to account for the size of a pixel glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), static_cast(pos.Z())); glTexCoord2f(0.0, static_cast(tex_frac_y)); - pos = rectDet->getRelativePosAtXY(0, rectDet->ypixels() - 1); - pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (+0.5), + pos = rectDet.getRelativePosAtXY(0, rectDet.ypixels() - 1); + pos += V3D(rectDet.xstep() * (-0.5), rectDet.ystep() * (+0.5), 0.0); // Adjust to account for the size of a pixel glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), static_cast(pos.Z())); @@ -390,18 +397,18 @@ void Renderer::doRender(const RectangularDetector *rectDet) const { GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. } -void Renderer::doRender(const StructuredDetector *structDet) const { - auto xVerts = structDet->getXValues(); - auto yVerts = structDet->getYValues(); - auto r = structDet->getR(); - auto g = structDet->getG(); - auto b = structDet->getB(); +void Renderer::doRender(const StructuredDetector &structDet) const { + auto xVerts = structDet.getXValues(); + auto yVerts = structDet.getYValues(); + auto r = structDet.getR(); + auto g = structDet.getG(); + auto b = structDet.getB(); if (xVerts.size() != yVerts.size()) return; - auto w = structDet->xPixels() + 1; - auto h = structDet->yPixels() + 1; + auto w = structDet.xPixels() + 1; + auto h = structDet.yPixels() + 1; glBegin(GL_QUADS); diff --git a/Framework/Geometry/src/Rendering/ShapeInfo.cpp b/Framework/Geometry/src/Rendering/ShapeInfo.cpp new file mode 100644 index 000000000000..c1642fe94aae --- /dev/null +++ b/Framework/Geometry/src/Rendering/ShapeInfo.cpp @@ -0,0 +1,67 @@ +#include "MantidGeometry/Rendering/ShapeInfo.h" + +namespace Mantid { +using Kernel::V3D; +namespace Geometry { +namespace detail { +ShapeInfo::ShapeInfo() + : m_points(), m_radius(0), m_height(0), + m_shape(ShapeInfo::GeometryShape::NOSHAPE) {} + +const std::vector &ShapeInfo::points() const { return m_points; } + +double ShapeInfo::radius() const { return m_radius; } + +double ShapeInfo::height() const { return m_height; } + +ShapeInfo::GeometryShape ShapeInfo::shape() const { return m_shape; } + +void ShapeInfo::getObjectGeometry(int &myshape, + std::vector &points, + double &myradius, double &myheight) const { + myshape = static_cast(m_shape); + points = m_points; + myradius = m_radius; + myheight = m_height; +} + +void ShapeInfo::setCuboid(const V3D &p1, const V3D &p2, const V3D &p3, + const V3D &p4) { + m_shape = GeometryShape::CUBOID; + m_points.assign({p1, p2, p3, p4}); +} + +void ShapeInfo::setHexahedron(const V3D &p1, const V3D &p2, const V3D &p3, + const V3D &p4, const V3D &p5, const V3D &p6, + const V3D &p7, const V3D &p8) { + m_shape = GeometryShape::HEXAHEDRON; + m_points.assign({p1, p2, p3, p4, p5, p6, p7, p8}); +} + +void ShapeInfo::setSphere(const V3D &c, double r) { + m_shape = GeometryShape::SPHERE; + m_points.assign({c}); + m_radius = r; +} +void ShapeInfo::setCylinder(const V3D &c, const V3D &a, double r, double h) { + m_shape = GeometryShape::CYLINDER; + m_points.assign({c, a}); + m_radius = r; + m_height = h; +} +void ShapeInfo::setCone(const V3D &c, const V3D &a, double r, double h) { + m_shape = GeometryShape::CONE; + m_points.assign({c, a}); + m_radius = r; + m_height = h; +} +void ShapeInfo::setSegmentedCylinder(const V3D &c, const V3D &a, double r, + double h) { + m_shape = GeometryShape::SEGMENTED_CYLINDER; + m_points.assign({c, a}); + m_radius = r; + m_height = h; +} +} // namespace detail +} // namespace Geometry +} // namespace Mantid \ No newline at end of file diff --git a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp b/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp index 67c14abdd765..24bf8158497f 100644 --- a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp @@ -54,7 +54,7 @@ void StructuredGeometryHandler::Triangulate() { //---------------------------------------------------------------------------------------------- ///< Draw pixels according to StructuredDetector vertices -void StructuredGeometryHandler::Render() { m_renderer.render(m_Det); } +void StructuredGeometryHandler::Render() { m_renderer.render(*m_Det); } //---------------------------------------------------------------------------------------------- ///< Prepare/Initialize Object/ObjComponent to be rendered diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h index b7e78634e74e..d70c589544e4 100644 --- a/Framework/Geometry/test/CSGObjectTest.h +++ b/Framework/Geometry/test/CSGObjectTest.h @@ -11,6 +11,7 @@ #include "MantidGeometry/Objects/Rules.h" #include "MantidGeometry/Objects/Track.h" #include "MantidGeometry/Rendering/GluGeometryHandler.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/make_unique.h" #include "MantidKernel/Material.h" @@ -783,7 +784,10 @@ class CSGObjectTest : public CxxTest::TestSuite { boost::shared_ptr h = boost::shared_ptr( new GluGeometryHandler(geom_obj.get())); - h->setCylinder(V3D(-0.0015, 0.0, 0.0), V3D(1., 0.0, 0.0), 0.005, 0.003); + detail::ShapeInfo shapeInfo; + shapeInfo.setCylinder(V3D(-0.0015, 0.0, 0.0), V3D(1., 0.0, 0.0), 0.005, + 0.003); + h->setShapeInfo(std::move(shapeInfo)); geom_obj->setGeometryHandler(h); double satol(1e-8); // tolerance for solid angle @@ -1429,8 +1433,10 @@ class CSGObjectTest : public CxxTest::TestSuite { // Explicitly setting the GluGeometryHanler hexahedron allows // for the correct bounding box calculation. auto handler = boost::make_shared(retVal); - handler->setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft, - hex.rft, hex.rbt); + detail::ShapeInfo shapeInfo; + shapeInfo.setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, + hex.lft, hex.rft, hex.rbt); + handler->setShapeInfo(std::move(shapeInfo)); retVal->setGeometryHandler(handler); retVal->setObject(68, ObjHex); From 2d0e27c22eed025c8c43ded7d0d44c66bc97696e Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 30 Nov 2017 15:35:33 +0000 Subject: [PATCH 016/364] Refactored geometry handling to single class re #21248 --- Framework/Geometry/CMakeLists.txt | 21 +- .../inc/MantidGeometry/Objects/CSGObject.h | 7 +- .../Rendering/BitmapGeometryHandler.h | 89 ---- .../Rendering/CacheGeometryHandler.h | 89 ---- .../Rendering/GeometryHandler.h | 138 +++--- .../Rendering/GeometryRenderer.h | 135 ------ .../Rendering/GeometryTriangulator.h | 5 +- .../Rendering/GluGeometryHandler.h | 79 ---- .../Rendering/OCGeometryHandler.h | 87 ---- .../inc/MantidGeometry/Rendering/Renderer.h | 12 +- .../inc/MantidGeometry/Rendering/ShapeInfo.h | 21 +- .../Rendering/StructuredGeometryHandler.h | 78 --- Framework/Geometry/src/IObjComponent.cpp | 8 +- .../src/Instrument/ObjCompAssembly.cpp | 6 +- .../Geometry/src/Instrument/ObjComponent.cpp | 4 +- .../src/Instrument/RectangularDetector.cpp | 13 +- .../src/Instrument/StructuredDetector.cpp | 9 +- Framework/Geometry/src/Objects/CSGObject.cpp | 46 +- .../Geometry/src/Objects/ShapeFactory.cpp | 6 +- .../src/Rendering/BitmapGeometryHandler.cpp | 70 --- .../src/Rendering/CacheGeometryHandler.cpp | 158 ------- .../src/Rendering/GeometryHandler.cpp | 132 ++++-- .../src/Rendering/GeometryRenderer.cpp | 445 ------------------ .../src/Rendering/GeometryTriangulator.cpp | 4 +- .../src/Rendering/GluGeometryHandler.cpp | 75 --- .../src/Rendering/OCGeometryHandler.cpp | 119 ----- Framework/Geometry/src/Rendering/Renderer.cpp | 52 +- .../Geometry/src/Rendering/ShapeInfo.cpp | 14 +- .../Rendering/StructuredGeometryHandler.cpp | 65 --- Framework/Geometry/test/CSGObjectTest.h | 46 +- Framework/Geometry/test/ObjCompAssemblyTest.h | 5 +- .../Geometry/test/ParObjCompAssemblyTest.h | 5 +- Framework/Geometry/test/ShapeInfoTest.h | 154 ++++++ 33 files changed, 445 insertions(+), 1752 deletions(-) delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h delete mode 100644 Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp delete mode 100644 Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp delete mode 100644 Framework/Geometry/src/Rendering/GeometryRenderer.cpp delete mode 100644 Framework/Geometry/src/Rendering/GluGeometryHandler.cpp delete mode 100644 Framework/Geometry/src/Rendering/OCGeometryHandler.cpp delete mode 100644 Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp create mode 100644 Framework/Geometry/test/ShapeInfoTest.h diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index c3ec3cbba116..6bbb7cfd3c2b 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -108,13 +108,9 @@ set ( SRC_FILES src/Objects/Rules.cpp src/Objects/ShapeFactory.cpp src/Objects/Track.cpp - src/Rendering/BitmapGeometryHandler.cpp - src/Rendering/CacheGeometryHandler.cpp src/Rendering/GeometryHandler.cpp src/Rendering/Renderer.cpp src/Rendering/ShapeInfo.cpp - src/Rendering/GluGeometryHandler.cpp - src/Rendering/StructuredGeometryHandler.cpp src/Rendering/vtkGeometryCacheReader.cpp src/Rendering/vtkGeometryCacheWriter.cpp src/Rendering/GeometryTriangulator.cpp @@ -131,14 +127,8 @@ set ( SRC_FILES src/Surfaces/Torus.cpp ) -set ( OPENCASCADE_SRC - src/Rendering/OCGeometryHandler.cpp -) - set ( SRC_UNITY_IGNORE_FILES src/Instrument/CompAssembly.cpp src/Instrument/ObjCompAssembly.cpp - src/Rendering/OCGeometryHandler.cpp - src/Rendering/OCGeometryRenderer.cpp ) set ( INC_FILES @@ -270,15 +260,10 @@ set ( INC_FILES inc/MantidGeometry/Objects/Rules.h inc/MantidGeometry/Objects/ShapeFactory.h inc/MantidGeometry/Objects/Track.h - inc/MantidGeometry/Rendering/BitmapGeometryHandler.h - inc/MantidGeometry/Rendering/CacheGeometryHandler.h inc/MantidGeometry/Rendering/GeometryHandler.h inc/MantidGeometry/Rendering/Renderer.h inc/MantidGeometry/Rendering/ShapeInfo.h - inc/MantidGeometry/Rendering/GluGeometryHandler.h - inc/MantidGeometry/Rendering/OCGeometryHandler.h inc/MantidGeometry/Rendering/OpenGL_Headers.h - inc/MantidGeometry/Rendering/StructuredGeometryHandler.h inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h inc/MantidGeometry/Rendering/vtkGeometryCacheWriter.h inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -403,6 +388,7 @@ set ( TEST_FILES SampleEnvironmentTest.h ScalarUtilsTest.h ShapeFactoryTest.h + ShapeInfoTest.h SpaceGroupFactoryTest.h SpaceGroupTest.h SphereTest.h @@ -439,11 +425,6 @@ if(UNITY_BUILD) enable_unity_build(Geometry SRC_FILES SRC_UNITY_IGNORE_FILES 10) endif(UNITY_BUILD) -# ===================== Open Cascade =================== -if (ENABLE_OPENCASCADE) - LIST (APPEND SRC_FILES ${OPENCASCADE_SRC} ) -endif () - # A few defines needed for OpenCascade on the Mac if ( APPLE ) add_definitions ( -DHAVE_IOSTREAM -DHAVE_LIMITS -DHAVE_IOMANIP ) diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index 3f88ceb9782e..1281c4ec5485 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -5,6 +5,7 @@ // Includes //---------------------------------------------------------------------- #include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Objects/IObject.h" #include "BoundingBox.h" @@ -23,7 +24,6 @@ class V3D; } namespace Geometry { -class CacheGeometryHandler; class CompGrp; class GeometryHandler; class Rule; @@ -188,7 +188,7 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { /// set vtkGeometryCache reader void setVtkGeometryCacheReader( boost::shared_ptr) override; - void GetObjectGeom(int &type, std::vector &vectors, + void GetObjectGeom(detail::ShapeInfo::GeometryShape &type, std::vector &vectors, double &myradius, double &myheight) const override; /// Getter for the shape xml std::string getShapeXML() const override; @@ -249,8 +249,7 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { int ObjNum; /// Geometry Handle for rendering boost::shared_ptr m_handler; - friend class CacheGeometryHandler; - friend class GeometryRenderer; + friend class GeometryHandler; /// Is geometry caching enabled? bool bGeometryCaching; /// a pointer to a class for reading from the geometry cache diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h deleted file mode 100644 index a0da6f818df2..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/BitmapGeometryHandler.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef BITMAPGEOMETRYHANDLER_H -#define BITMAPGEOMETRYHANDLER_H - -#ifndef Q_MOC_RUN -#include -#endif -#include "MantidGeometry/DllConfig.h" -#include "MantidKernel/Logger.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -namespace Mantid { - -namespace Geometry { -/** -\class BitmapGeometryHandler -\brief Handler for geometry objects that are rendered as bitmaps (e.g. -RectangularDetector), rather than primitives. -\author Janik Zikovsky -\date October 2010 -\version 1.0 - -This class supports drawing RectangularDetector - as a bitmap plotted by openGL -rather -than a million individual pixels rendered as cubes. -A texture will have been created by the RectangularDetectorActor (in MantidPlot) -and this is what will be mapped. - -Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge -National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -File change history is stored at: -*/ -class ObjComponent; -class CSGObject; -class MANTID_GEOMETRY_DLL BitmapGeometryHandler : public GeometryHandler { -private: - static Kernel::Logger &PLog; ///< The official logger - - boost::shared_ptr clone() const override; - - /// The RectangularDetector object being plotted. - RectangularDetector *m_rectDet; - -public: - BitmapGeometryHandler(RectangularDetector *comp); - BitmapGeometryHandler(); - // - // BitmapGeometryHandler(IObjComponent *comp); ///< - // Constructor - // BitmapGeometryHandler(boost::shared_ptr obj); - // ///) - override; ///< Create an instance of concrete geometry handler for Object - GeometryHandler *createInstance(CSGObject *) - override; ///< Create an instance of concrete geometry handler for Object - void Triangulate() override; ///< Triangulate the Object - void Render() override; ///< Render Object or ObjComponent - void Initialize() - override; ///< Prepare/Initialize Object/ObjComponent to be rendered - /// Returns true if the shape can be triangulated - bool canTriangulate() override { return false; } -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h deleted file mode 100644 index 49c9770f4334..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/CacheGeometryHandler.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef CACHE_GEOMETRYHANDLER_H -#define CACHE_GEOMETRYHANDLER_H - -#include "MantidGeometry/DllConfig.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" - -namespace Mantid { -namespace Kernel { -class V3D; -} - -namespace Geometry { -class GeometryHandler; -class CacheGeometryGenerator; -class IObjComponent; -class CSGObject; - -namespace detail { -class GeometryTriangulator; -} - -/** - \class CacheGeometryHandler - \brief Place holder for geometry triangulation and rendering with caching - triangles. - \author Srikanth Nagella - \date Jan 2009 - \version 1.0 - - This is an implementation class for handling geometry from cache, if the - cache doesn't exist then the - triangulation is done using another triangulation handler and store in cache. - - Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MANTID_GEOMETRY_DLL CacheGeometryHandler : public GeometryHandler { -private: - std::unique_ptr - m_triangulator; ///< Triangulates geometry - -public: - CacheGeometryHandler(IObjComponent *comp); ///< Constructor - CacheGeometryHandler(boost::shared_ptr obj); ///< Constructor - CacheGeometryHandler(CSGObject *obj); ///< Constructor - CacheGeometryHandler(const CacheGeometryHandler &handler); - boost::shared_ptr clone() const override; - ~CacheGeometryHandler() override; ///< Destructor - GeometryHandler *createInstance(IObjComponent *comp) override; - GeometryHandler *createInstance(boost::shared_ptr obj) override; - GeometryHandler *createInstance(CSGObject *obj) override; - - void Triangulate() override; - void Render() override; - void Initialize() override; - bool canTriangulate() override { return true; } - /// get the number of triangles - size_t numberOfTriangles() override; - /// get the number of points or vertices - size_t numberOfPoints() override; - boost::optional &> getTriangleVertices() override; - boost::optional &> getTriangleFaces() override; - /// Sets the geometry cache using the triangulation information provided - void setGeometryCache(size_t nPts, size_t nFaces, std::vector &&pts, - std::vector &&faces) override; -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index fb90fa5acacc..514f5d2fcc6f 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -2,12 +2,11 @@ #define GEOMETRYHANDLER_H #include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Rendering/Renderer.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidKernel/Logger.h" #include "MantidKernel/V3D.h" -#include -#include "MantidGeometry/Rendering/Renderer.h" #include -#include namespace Mantid { @@ -15,111 +14,86 @@ namespace Geometry { class IObjComponent; class ObjComponent; class CSGObject; -class GeometryRenderer; +namespace detail { +class Renderer; +} /** - \class GeometryHandler - \brief Place holder for geometry triangulation and rendering. - \author Srikanth Nagella - \date July 2008 - \version 1.0 +\class GeometryHandler +\brief Handles rendering of all object Geometry. +\author Lamar Moore +\date December 2017 - This is an abstract class for handling geometry primitives. +Handles the rendering of all geometry types in Mantid. - Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source +Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source - This file is part of Mantid. +This file is part of Mantid. - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . +You should have received a copy of the GNU General Public License +along with this program. If not, see . - File change history is stored at: +File change history is stored at: */ class MANTID_GEOMETRY_DLL GeometryHandler { private: static Kernel::Logger &PLog; ///< The official logger protected: - detail::Renderer m_renderer; - IObjComponent *ObjComp; ///< ObjComponent that uses this geometry handler - CSGObject *Obj; ///< Object that uses this geometry handler - bool boolTriangulated; ///< state of the geometry triangulation - bool - boolIsInitialized; ///< state of the geometry initialization for rendering + std::unique_ptr m_renderer = nullptr; + std::shared_ptr m_shapeInfo = nullptr; + std::unique_ptr m_triangulator = nullptr; + RectangularDetector *m_rectDet = nullptr; + StructuredDetector *m_structDet = nullptr; + IObjComponent *m_objComp = + nullptr; ///< ObjComponent that uses this geometry handler + CSGObject *m_obj = nullptr; ///< Object that uses this geometry handler public: - GeometryHandler(IObjComponent *comp); ///< Constructor - GeometryHandler(boost::shared_ptr obj); /// - clone() const = 0; ///< Virtual copy constructor - virtual ~GeometryHandler(); - virtual GeometryHandler *createInstance(IObjComponent *) = 0; ///< Create an - /// instance of - /// concrete - /// geometry - /// handler for - /// ObjComponent - virtual GeometryHandler *createInstance( - boost::shared_ptr) = 0; ///< Create an instance of - /// concrete geometry - /// handler for Object - virtual GeometryHandler * - createInstance(CSGObject *) = 0; ///< Create an instance - /// of concrete geometry - /// handler for Object - virtual void Triangulate() = 0; ///< Triangulate the Object - virtual void Render() = 0; ///< Render Object or ObjComponent - virtual void - Initialize() = 0; ///< Prepare/Initialize Object/ObjComponent to be rendered - /// Returns true if the shape can be triangulated - virtual bool canTriangulate() { return false; } + GeometryHandler(IObjComponent *comp); ///< Constructor + GeometryHandler(boost::shared_ptr obj); ///< Constructor + GeometryHandler(CSGObject *obj); ///< Constructor + GeometryHandler(RectangularDetector *comp); + GeometryHandler(StructuredDetector *comp); + GeometryHandler(const GeometryHandler &renderer); + boost::shared_ptr clone() const; + ~GeometryHandler(); + void render(); ///< Render Object or ObjComponent + void initialize(); ///< Prepare/Initialize Object/ObjComponent to be rendered + bool canTriangulate() const { return !(m_triangulator == nullptr); } /// get the number of triangles - virtual size_t numberOfTriangles() { return 0; } + size_t numberOfTriangles(); /// get the number of points or vertices - virtual size_t numberOfPoints() { return 0; } + size_t numberOfPoints(); + + bool hasShapeInfo() const { return !(m_shapeInfo == nullptr); } + const detail::ShapeInfo &shapeInfo() const { return *m_shapeInfo; } /// Extract the vertices of the triangles - virtual boost::optional &> getTriangleVertices() { - return boost::none; - } + boost::optional &> getTriangleVertices(); /// Extract the Faces of the triangles - virtual boost::optional &> getTriangleFaces() { - return boost::none; - } + boost::optional &> getTriangleFaces(); /// Sets the geometry cache using the triangulation information provided - virtual void setGeometryCache(size_t nPts, size_t nFaces, - std::vector &&pts, - std::vector &&faces) { - UNUSED_ARG(nPts); - UNUSED_ARG(nFaces); - UNUSED_ARG(pts); - UNUSED_ARG(faces); - }; + void setGeometryCache(size_t nPts, size_t nFaces, std::vector &&pts, + std::vector &&faces); /// return the actual type and points of one of the "standard" objects, /// cuboid/cone/cyl/sphere - virtual void GetObjectGeom(int &mytype, std::vector &vectors, - double &myradius, double &myheight) { - UNUSED_ARG(vectors); - UNUSED_ARG(myradius); - UNUSED_ARG(myheight); - // Flag that this is unknown at this point - mytype = -1; - }; + void GetObjectGeom(detail::ShapeInfo::GeometryShape &mytype, + std::vector &vectors, double &myradius, + double &myheight) const; + void setShapeInfo(detail::ShapeInfo &&shapeInfo); }; } // NAMESPACE Geometry - } // NAMESPACE Mantid #endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h deleted file mode 100644 index f7bc0a5facb7..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryRenderer.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef MANTID_GEOMETRY_GEOMETRYRENDERER_H_ -#define MANTID_GEOMETRY_GEOMETRYRENDERER_H_ - -#include "MantidGeometry/DllConfig.h" -#include "MantidGeometry/Rendering/OpenGL_Headers.h" - -class TopoDS_Shape; - -namespace Mantid { -namespace Kernel { -class V3D; -} -namespace Geometry { -class RectangularDetector; -class StructuredDetector; -class IObjComponent; - -/** GeometryRenderer : Handles rendering of geometry within mantid. - - Copyright © 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: -*/ -class MANTID_GEOMETRY_DLL GeometryRenderer { -public: - enum class RenderMode { Basic, Volumetric }; - GeometryRenderer() = default; - ~GeometryRenderer() = default; - - /// General method for rendering geometry - template - void render(RenderMode mode, Args &&... args) const &; - - /// Render Basic geometry without transparency (non-volumetric) - template void render(Args &&... args) const &; - - /// Render IObjComponent - void renderIObjComponent(IObjComponent *objComp, - RenderMode mode = RenderMode::Basic) const; - /// Render Traingulated Surface - void renderTriangulated(int noPts, int noFaces, double *points, int *faces, - RenderMode mode = RenderMode::Basic) const; - /// Render OpenCascade Shape - void renderOpenCascade(TopoDS_Shape *objSurf, - RenderMode mode = RenderMode::Basic) const; - /// Renders a sphere - void renderSphere(const Kernel::V3D ¢er, double radius, - RenderMode mode = RenderMode::Basic) const; - /// Renders a cuboid - void renderCuboid(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4, - RenderMode mode = RenderMode::Basic) const; - /// Renders a Hexahedron from the input values - void renderHexahedron(const std::vector &points, - RenderMode mode = RenderMode::Basic) const; - /// Renders a Cone from the input values - void renderCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, - RenderMode mode = RenderMode::Basic) const; - /// Renders a Cylinder/Segmented cylinder from the input values - void renderCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, bool segmented = false, - RenderMode mode = RenderMode::Basic) const; - /// Renders a Bitmap (used for rendering RectangularDetector) - void renderBitmap(const RectangularDetector *rectDet, - RenderMode mode = RenderMode::Basic) const; - /// Renders structured geometry (used for rendering StructuredDetector) - void renderStructured(const StructuredDetector *structDet, - RenderMode mode = RenderMode::Basic) const; - -private: - mutable RenderMode m_renderMode; - // general geometry - /// Render IObjComponent - void doRender(IObjComponent *ObjComp) const; - /// Render Traingulated Surface - void doRender(int noPts, int noFaces, double *points, int *faces) const; - /// Render OpenCascade Shape - void doRender(TopoDS_Shape *ObjSurf) const; - - // shapes - /// Renders a sphere - void doRender(const Kernel::V3D ¢er, double radius) const; - /// Renders a cuboid - void doRender(const Kernel::V3D &Point1, const Kernel::V3D &Point2, - const Kernel::V3D &Point3, const Kernel::V3D &Point4) const; - /// Renders a Hexahedron from the input values - void doRender(const std::vector &points) const; - /// Renders a Cone from the input values - void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height) const; - /// Renders a Cylinder/Segmented cylinder from the input values - void doRender(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height, bool segmented) const; - /// Renders a Bitmap (used for rendering RectangularDetector) - void doRender(const RectangularDetector *rectDet) const; - /// Renders structured geometry (used for rendering StructuredDetector) - void doRender(const StructuredDetector *structDet) const; -}; - -template -void GeometryRenderer::render(RenderMode mode, Args &&... args) const & { - // Wait for no OopenGL error - while (glGetError() != GL_NO_ERROR) - ; - m_renderMode = mode; - doRender(std::forward(args)...); -} - -template -void GeometryRenderer::render(Args &&... args) const & { - render(RenderMode::Basic, std::forward(args)...); -} - -} // namespace Geometry -} // namespace Mantid - -#endif /* MANTID_GEOMETRY_GEOMETRYRENDERER_H_ */ \ No newline at end of file diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index 74c8a7cc0718..951b3b0b6c45 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -2,6 +2,7 @@ #define MANTID_GEOMETRY_SURFACETRIANGULATOR_H_ #include "MantidGeometry/DllConfig.h" +#include #include class TopoDS_Shape; @@ -63,7 +64,7 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { const std::vector &getTriangleFaces(); #ifdef ENABLE_OPENCASCADE private: - std::unique_ptr + boost::shared_ptr m_objSurface; ///< Storage for the output surface /// Analyze the object /// OpenCascade analysis of object surface @@ -75,7 +76,7 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { public: /// Return OpenCascade surface. - const TopoDS_Shape &getOCSurface(); + boost::shared_ptr getOCSurface(); #endif }; } // namespace detail diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h deleted file mode 100644 index b4a24856e830..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GluGeometryHandler.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef GLU_GEOMETRYHANDLER_H -#define GLU_GEOMETRYHANDLER_H - -#include "MantidGeometry/DllConfig.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidGeometry/Rendering/ShapeInfo.h" - -namespace Mantid { -namespace Kernel { -class V3D; -} -namespace Geometry { -class GeometryHandler; -class IObjComponent; -class CSGObject; -/** - \class GluGeometryHandler - \brief Place holder for geometry triangulation and rendering with special - cases of cube, sphere, cone and cylinder. - \author Srikanth Nagella - \date December 2008 - \version 1.0 - - This is an implementation class for handling geometry without triangulating - and using opengl glu methods. - This class can render cube, sphere, cone and cylinder. - - Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MANTID_GEOMETRY_DLL GluGeometryHandler : public GeometryHandler { -private: - static Kernel::Logger &PLog; ///< The official logger - /// Object/ObjComponent - std::vector m_points; - double radius; /// obj); ///< Constructor - GluGeometryHandler(CSGObject *obj); ///< Constructor - boost::shared_ptr clone() const override; - ~GluGeometryHandler() override; ///< Destructor - GeometryHandler *createInstance(IObjComponent *comp) override; - GeometryHandler *createInstance(boost::shared_ptr obj) override; - GeometryHandler *createInstance(CSGObject *) override; - /// sets the geometry handler for a cuboid - void setShapeInfo(detail::ShapeInfo &&shapeInfo); - void Triangulate() override; - void Render() override; - void Initialize() override; - void GetObjectGeom(int &mytype, std::vector &vectors, - double &myradius, double &myheight) override; -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h deleted file mode 100644 index f638cf2939f6..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/OCGeometryHandler.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef OC_GEOMETRYHANDLER_H -#define OC_GEOMETRYHANDLER_H - -#include "MantidGeometry/DllConfig.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" - -namespace Mantid { - -namespace Geometry { -class GeometryHandler; -class IObjComponent; -class CSGObject; -namespace detail { -class GeometryTriangulator; -} -/** - \class OCGeometryHandler - \brief Place holder for OpenCascade library geometry triangulation and - rendering. - \author Srikanth Nagella - \date July 2008 - \version 1.0 - - This is an implementation class for handling geometry using - OpenCascade(www.opencascade.org). - Unlike the GluGeometryHandler, it can handle more complex shapes. - It uses OpenCascade to generate a mesh defining the surface of an Object - (shape). - This shape is saved along with the instrument definition as a .vtp file (for - speed-ups). - - Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MANTID_GEOMETRY_DLL OCGeometryHandler : public GeometryHandler { -private: - static Kernel::Logger &PLog; ///< The official logger - std::unique_ptr - m_triangulator; ///< Geometry generator to triangulate Object -public: - OCGeometryHandler(IObjComponent *comp); ///< Constructor - OCGeometryHandler(boost::shared_ptr obj); ///< Constructor - OCGeometryHandler(CSGObject *obj); ///< Constructor - OCGeometryHandler(const OCGeometryHandler &handler); - boost::shared_ptr - clone() const override; ///< Virtual copy constructor - ~OCGeometryHandler() override; ///< Destructor - GeometryHandler *createInstance(IObjComponent *comp) override; - GeometryHandler *createInstance(boost::shared_ptr obj) override; - GeometryHandler *createInstance(CSGObject *) override; - void Triangulate() override; - void Render() override; - void Initialize() override; - /// Returns true if the shape can be triangulated - bool canTriangulate() override { return true; } - /// get the number of triangles - size_t numberOfTriangles() override; - /// get the number of points or vertices - size_t numberOfPoints() override; - /// Extract the vertices of the triangles - boost::optional &> getTriangleVertices() override; - /// Extract the Faces of the triangles - boost::optional &> getTriangleFaces() override; -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h index 3d2f37cefec2..e6c3640caa65 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h @@ -16,10 +16,9 @@ class RectangularDetector; class StructuredDetector; class IObjComponent; - namespace detail - { - class GeometryTriangulator; - } +namespace detail { +class GeometryTriangulator; +} /** Renderer : Handles rendering details of geometry within mantid. @@ -70,10 +69,11 @@ class MANTID_GEOMETRY_DLL Renderer { void renderShape(const ShapeInfo &shapeInfo) const; /// Renders a Bitmap (used for rendering RectangularDetector) void renderBitmap(const RectangularDetector &rectDet, - RenderMode mode = RenderMode::Basic) const; + RenderMode mode = RenderMode::Basic) const; /// Renders structured geometry (used for rendering StructuredDetector) void renderStructured(const StructuredDetector &structDet, - RenderMode mode = RenderMode::Basic) const; + RenderMode mode = RenderMode::Basic) const; + private: mutable RenderMode m_renderMode; /// Renders a sphere diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h index 06e8ee92806d..c57df051e64b 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h @@ -64,8 +64,9 @@ class MANTID_GEOMETRY_DLL ShapeInfo { double height() const; GeometryShape shape() const; - void getObjectGeometry(int &myshape, std::vector &points, - double &myradius, double &myheight) const; + void getObjectGeometry(GeometryShape &myshape, + std::vector &points, double &myradius, + double &myheight) const; /// sets the geometry handler for a cuboid void setCuboid(const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &); @@ -74,15 +75,19 @@ class MANTID_GEOMETRY_DLL ShapeInfo { const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &, const Kernel::V3D &); - /// sets the geometry handler for a cone - void setSphere(const Kernel::V3D &, double); + /// sets the geometry handler for a sphere + void setSphere(const Kernel::V3D ¢er, double radius); /// sets the geometry handler for a cylinder - void setCylinder(const Kernel::V3D &, const Kernel::V3D &, double, double); + void setCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height); /// sets the geometry handler for a cone - void setCone(const Kernel::V3D &, const Kernel::V3D &, double, double); + void setCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height); /// sets the geometry handler for a segmented cylinder - void setSegmentedCylinder(const Kernel::V3D &, const Kernel::V3D &, double, - double); + void setSegmentedCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, + double radius, double height); + + bool operator==(const ShapeInfo &other); }; } // namespace detail } // namespace Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h deleted file mode 100644 index 98f366a542e0..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/StructuredGeometryHandler.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef STRUCTUREDGEOMETRYHANDLER_H -#define STRUCTUREDGEOMETRYHANDLER_H - -#ifndef Q_MOC_RUN -#include -#endif -#include "MantidGeometry/DllConfig.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/Instrument/StructuredDetector.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidKernel/Logger.h" - -namespace Mantid { -namespace Geometry { -/** -\class StructuredGeometryHandler -\brief Handler for StructuredDetector geometry objects -\author Lamar Moore -\date March 2016 -\version 1.0 - -This class supports drawing StructuredDetector. - -Copyright © 2008 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge -National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -File change history is stored at: -*/ -class ObjComponent; -class CSGObject; -class MANTID_GEOMETRY_DLL StructuredGeometryHandler : public GeometryHandler { -private: - static Kernel::Logger &PLog; ///< The official logger - - boost::shared_ptr clone() const override; - - /// The StructuredDetector object being drawn. - StructuredDetector *m_Det; - -public: - StructuredGeometryHandler(StructuredDetector *comp); - StructuredGeometryHandler(); - - StructuredGeometryHandler *createInstance( - IObjComponent *) override; ///< Create an instance of concrete geometry - /// handler for ObjComponent - StructuredGeometryHandler *createInstance(boost::shared_ptr) - override; ///< Create an instance of concrete geometry handler for Object - GeometryHandler *createInstance(CSGObject *) - override; ///< Create an instance of concrete geometry handler for Object - void Triangulate() override; ///< Triangulate the Object - void Render() override; ///< Render Object or ObjComponent - void Initialize() - override; ///< Prepare/Initialize Object/ObjComponent to be rendered - /// Returns true if the shape can be triangulated - bool canTriangulate() override { return false; } -}; - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid - -#endif // STRUCTUREDGEOMETRYHANDLER_H \ No newline at end of file diff --git a/Framework/Geometry/src/IObjComponent.cpp b/Framework/Geometry/src/IObjComponent.cpp index a922c367caf7..777957edcfa7 100644 --- a/Framework/Geometry/src/IObjComponent.cpp +++ b/Framework/Geometry/src/IObjComponent.cpp @@ -3,12 +3,12 @@ //---------------------------------------------------------------------- #include "MantidGeometry/IObjComponent.h" #include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidGeometry/Rendering/CacheGeometryHandler.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" namespace Mantid { namespace Geometry { -IObjComponent::IObjComponent() { handle = new CacheGeometryHandler(this); } +IObjComponent::IObjComponent() { handle = new GeometryHandler(this); } /** Constructor, specifying the GeometryHandler (renderer engine) * for this IObjComponent. @@ -42,7 +42,7 @@ void IObjComponent::setGeometryHandler(GeometryHandler *h) { IObjComponent::IObjComponent(const IObjComponent &origin) { // Handler contains a pointer to 'this' therefore needs regenerating // with new object - handle = origin.handle->createInstance(this); + handle = new GeometryHandler(this); } /** @@ -52,7 +52,7 @@ IObjComponent::IObjComponent(const IObjComponent &origin) { */ IObjComponent &IObjComponent::operator=(const IObjComponent &rhs) { if (&rhs != this) { - handle = rhs.handle->createInstance(this); + handle = new GeometryHandler(this); } return *this; } diff --git a/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp b/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp index c53c6a4713ff..388deee136f8 100644 --- a/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp +++ b/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp @@ -380,7 +380,7 @@ boost::shared_ptr ObjCompAssembly::createOutline() { // Get information about the shape and size of a detector std::string type; - int otype; + detail::ShapeInfo::GeometryShape otype; std::vector vectors; double radius, height; boost::shared_ptr obj = group.front()->shape(); @@ -389,9 +389,9 @@ boost::shared_ptr ObjCompAssembly::createOutline() { "Found ObjComponent without shape"); } obj->GetObjectGeom(otype, vectors, radius, height); - if (otype == 1) { + if (otype == detail::ShapeInfo::GeometryShape::CUBOID) { type = "box"; - } else if (otype == 4) { + } else if (otype == detail::ShapeInfo::GeometryShape::CYLINDER) { type = "cylinder"; } else { throw std::runtime_error( diff --git a/Framework/Geometry/src/Instrument/ObjComponent.cpp b/Framework/Geometry/src/Instrument/ObjComponent.cpp index e44028ef1e81..86b29bcdb153 100644 --- a/Framework/Geometry/src/Instrument/ObjComponent.cpp +++ b/Framework/Geometry/src/Instrument/ObjComponent.cpp @@ -313,7 +313,7 @@ void ObjComponent::draw() const { if (Handle() == nullptr) return; // Render the ObjComponent and then render the object - Handle()->Render(); + Handle()->render(); } /** @@ -334,7 +334,7 @@ void ObjComponent::initDraw() const { // Render the ObjComponent and then render the object if (shape() != nullptr) shape()->initDraw(); - Handle()->Initialize(); + Handle()->initialize(); } /** diff --git a/Framework/Geometry/src/Instrument/RectangularDetector.cpp b/Framework/Geometry/src/Instrument/RectangularDetector.cpp index 29744ae693e6..185483899941 100644 --- a/Framework/Geometry/src/Instrument/RectangularDetector.cpp +++ b/Framework/Geometry/src/Instrument/RectangularDetector.cpp @@ -7,13 +7,14 @@ #include "MantidGeometry/Objects/IObject.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidGeometry/Objects/Track.h" -#include "MantidGeometry/Rendering/BitmapGeometryHandler.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidKernel/Exception.h" #include "MantidKernel/Material.h" #include #include #include #include +#include #include "MantidGeometry/Instrument/RectangularDetectorPixel.h" namespace { @@ -45,7 +46,7 @@ RectangularDetector::RectangularDetector() m_minDetId(0), m_maxDetId(0) { init(); - setGeometryHandler(new BitmapGeometryHandler(this)); + setGeometryHandler(new GeometryHandler(this)); } /** Constructor for a parametrized RectangularDetector @@ -57,7 +58,7 @@ RectangularDetector::RectangularDetector(const RectangularDetector *base, : CompAssembly(base, map), IObjComponent(nullptr), m_rectBase(base), m_minDetId(0), m_maxDetId(0) { init(); - setGeometryHandler(new BitmapGeometryHandler(this)); + setGeometryHandler(new GeometryHandler(this)); } /** Valued constructor @@ -75,7 +76,7 @@ RectangularDetector::RectangularDetector(const std::string &n, m_minDetId(0), m_maxDetId(0) { init(); this->setName(n); - setGeometryHandler(new BitmapGeometryHandler(this)); + setGeometryHandler(new GeometryHandler(this)); } bool RectangularDetector::compareName(const std::string &proposedMatch) { @@ -673,7 +674,7 @@ void RectangularDetector::draw() const { if (Handle() == nullptr) return; // Render the ObjComponent and then render the object - Handle()->Render(); + Handle()->render(); } /** @@ -696,7 +697,7 @@ void RectangularDetector::initDraw() const { return; // Render the ObjComponent and then render the object // if(shape!=NULL) shape->initDraw(); - Handle()->Initialize(); + Handle()->initialize(); } //------------------------------------------------------------------------------------------------- diff --git a/Framework/Geometry/src/Instrument/StructuredDetector.cpp b/Framework/Geometry/src/Instrument/StructuredDetector.cpp index ecf96fc36e34..754b4aeb0879 100644 --- a/Framework/Geometry/src/Instrument/StructuredDetector.cpp +++ b/Framework/Geometry/src/Instrument/StructuredDetector.cpp @@ -5,8 +5,7 @@ #include "MantidGeometry/Objects/BoundingBox.h" #include "MantidGeometry/Objects/CSGObject.h" #include "MantidGeometry/Objects/ShapeFactory.h" -#include "MantidGeometry/Rendering/GluGeometryHandler.h" -#include "MantidGeometry/Rendering/StructuredGeometryHandler.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidKernel/Exception.h" #include "MantidKernel/Material.h" #include "MantidKernel/Matrix.h" @@ -71,7 +70,7 @@ void StructuredDetector::init() { m_idStepByRow = 0; m_idStep = 0; - setGeometryHandler(new StructuredGeometryHandler(this)); + setGeometryHandler(new GeometryHandler(this)); } /** Clone method @@ -552,7 +551,7 @@ void StructuredDetector::draw() const { if (Handle() == nullptr) return; // Render the ObjComponent and then render the object - Handle()->Render(); + Handle()->render(); } /** @@ -568,7 +567,7 @@ void StructuredDetector::initDraw() const { if (Handle() == nullptr) return; - Handle()->Initialize(); + Handle()->initialize(); } /// Returns the shape of the Object diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 3be854b59f7b..2f46cd252538 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -2,9 +2,8 @@ #include "MantidGeometry/Objects/Rules.h" #include "MantidGeometry/Objects/Track.h" -#include "MantidGeometry/Rendering/CacheGeometryHandler.h" #include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidGeometry/Rendering/GluGeometryHandler.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h" #include "MantidGeometry/Rendering/vtkGeometryCacheWriter.h" #include "MantidGeometry/Surfaces/Cone.h" @@ -60,7 +59,7 @@ CSGObject::CSGObject(const std::string &shapeXML) vtkCacheWriter(boost::shared_ptr()), m_shapeXML(shapeXML), m_id(), m_material() // empty by default { - m_handler = boost::make_shared(this); + handle = boost::make_shared(this); } /** @@ -1008,17 +1007,14 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const { // If the object is a simple shape use the special methods double height(0.0), radius(0.0); - int type(0); + detail::ShapeInfo::GeometryShape type; std::vector geometry_vectors; // Maximum of 4 vectors depending on the type geometry_vectors.reserve(4); this->GetObjectGeom(type, geometry_vectors, radius, height); auto nTri = this->numberOfTriangles(); // Cylinders are by far the most frequently used - detail::ShapeInfo::GeometryShape gluType = - static_cast(type); - - switch (gluType) { + switch (type) { case detail::ShapeInfo::GeometryShape::CUBOID: return CuboidSolidAngle(observer, geometry_vectors); break; @@ -1098,13 +1094,10 @@ double CSGObject::triangleSolidAngle(const V3D &observer, // if (nTri == 0) { double height = 0.0, radius(0.0); - int type; + detail::ShapeInfo::GeometryShape type; std::vector vectors; this->GetObjectGeom(type, vectors, radius, height); - detail::ShapeInfo::GeometryShape gluType = - static_cast(type); - - switch (gluType) { + switch (type) { case detail::ShapeInfo::GeometryShape::CUBOID: for (auto &vector : vectors) vector *= scaleFactor; @@ -1491,14 +1484,12 @@ double CSGObject::ConeSolidAngle(const V3D &observer, * @return The volume. */ double CSGObject::volume() const { - int type; + detail::ShapeInfo::GeometryShape type; double height; double radius; std::vector vectors; this->GetObjectGeom(type, vectors, radius, height); - detail::ShapeInfo::GeometryShape gluType = - static_cast(type); - switch (gluType) { + switch (type) { case detail::ShapeInfo::GeometryShape::CUBOID: { // Here, the volume is calculated by the triangular method. // We use one of the vertices (vectors[0]) as the reference @@ -1718,9 +1709,9 @@ void CSGObject::calcBoundingBoxByRule() { void CSGObject::calcBoundingBoxByVertices() { // Grab vertex information auto vertCount = this->numberOfVertices(); - const auto &vertArray = this->getTriangleVertices().get(); if (vertCount > 0) { + const auto &vertArray = this->getTriangleVertices().get(); // Unreasonable extents to be overwritten by loop constexpr double huge = 1e10; double minX, maxX, minY, maxY, minZ, maxZ; @@ -1761,18 +1752,15 @@ void CSGObject::calcBoundingBoxByGeometry() { double minX, maxX, minY, maxY, minZ, maxZ; // Shape geometry data - int type(0); + detail::ShapeInfo::GeometryShape type; std::vector vectors; double radius; double height; - // Will only work for shapes handled by GluGeometryHandler + // Will only work for shapes with ShapeInfo m_handler->GetObjectGeom(type, vectors, radius, height); - detail::ShapeInfo::GeometryShape gluType = - static_cast(type); - // Type of shape is given as a simple integer - switch (gluType) { + switch (type) { case detail::ShapeInfo::GeometryShape::CUBOID: { // Points as defined in IDF XML auto &lfb = vectors[0]; // Left-Front-Bottom @@ -2072,7 +2060,7 @@ void CSGObject::draw() const { if (m_handler == nullptr) return; // Render the Object - m_handler->Render(); + handle->render(); } /** @@ -2084,7 +2072,7 @@ void CSGObject::initDraw() const { if (m_handler == nullptr) return; // Render the Object - m_handler->Initialize(); + handle->initialize(); } /** * set vtkGeometryCache writer @@ -2176,9 +2164,9 @@ boost::optional &> CSGObject::getTriangleFaces() const { /** * get info on standard shapes */ -void CSGObject::GetObjectGeom(int &type, std::vector &vectors, - double &myradius, double &myheight) const { - type = 0; +void Object::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, std::vector &vectors, + double &myradius, double &myheight) const { + type = detail::ShapeInfo::GeometryShape::NOSHAPE; if (m_handler == nullptr) return; m_handler->GetObjectGeom(type, vectors, myradius, myheight); diff --git a/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Framework/Geometry/src/Objects/ShapeFactory.cpp index 079340c724af..29a977dbb7a9 100644 --- a/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -5,7 +5,7 @@ #include "MantidGeometry/Instrument/Container.h" #include "MantidGeometry/Objects/CSGObject.h" #include "MantidGeometry/Objects/ShapeFactory.h" -#include "MantidGeometry/Rendering/GluGeometryHandler.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Surfaces/Cone.h" #include "MantidGeometry/Surfaces/Cylinder.h" @@ -1407,7 +1407,7 @@ ShapeFactory::createHexahedralShape(double xlb, double xlf, double xrf, shape->setObject(21, algebra); shape->populate(prim); - auto handler = boost::make_shared(shape); + auto handler = boost::make_shared(shape); detail::ShapeInfo shapeInfo; shape->setGeometryHandler(handler); @@ -1425,7 +1425,7 @@ ShapeFactory::createHexahedralShape(double xlb, double xlf, double xrf, void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, boost::shared_ptr Obj) { - auto geomHandler = boost::make_shared(Obj); + auto geomHandler = boost::make_shared(Obj); detail::ShapeInfo shapeInfo; Obj->setGeometryHandler(geomHandler); diff --git a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp b/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp deleted file mode 100644 index 2e9ec357927a..000000000000 --- a/Framework/Geometry/src/Rendering/BitmapGeometryHandler.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "MantidGeometry/Rendering/BitmapGeometryHandler.h" -#include "MantidGeometry/Rendering/OpenGL_Headers.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -#include -#include - -#include - -namespace Mantid { -namespace Geometry { -using Kernel::V3D; - -/** - * @return A shared_ptr to a new copy of this object - */ -boost::shared_ptr BitmapGeometryHandler::clone() const { - return boost::make_shared(*this); -} - -/// Parameter constructor -BitmapGeometryHandler::BitmapGeometryHandler(RectangularDetector *comp) - : GeometryHandler(dynamic_cast(comp)) { - // Save the rectangular detector link for later. - m_rectDet = comp; -} - -BitmapGeometryHandler::BitmapGeometryHandler() - : GeometryHandler(static_cast(nullptr)), m_rectDet(nullptr) {} - -///< Create an instance of concrete geometry handler for ObjComponent -BitmapGeometryHandler * -BitmapGeometryHandler::createInstance(IObjComponent *comp) { - (void)comp; - return new BitmapGeometryHandler(); -} - -///< Create an instance of concrete geometry handler for Object -BitmapGeometryHandler * -BitmapGeometryHandler::createInstance(boost::shared_ptr obj) { - (void)obj; - return new BitmapGeometryHandler(); -} - -///< Create an instance of concrete geometry handler for Object -GeometryHandler *BitmapGeometryHandler::createInstance(CSGObject *obj) { - (void)obj; - return new BitmapGeometryHandler(); -} - -//---------------------------------------------------------------------------------------------- -/** Triangulate the Object - this function will not be used. - * - */ -void BitmapGeometryHandler::Triangulate() { - // std::cout << "BitmapGeometryHandler::Triangulate() called\n"; -} - -//---------------------------------------------------------------------------------------------- -///< Render Object or ObjComponent -void BitmapGeometryHandler::Render() { - m_renderer.render(*m_rectDet); -} - -//---------------------------------------------------------------------------------------------- -///< Prepare/Initialize Object/ObjComponent to be rendered -void BitmapGeometryHandler::Initialize() { - // std::cout << "BitmapGeometryHandler::Initialize() called\n"; -} -} -} diff --git a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp deleted file mode 100644 index 139f46e705a3..000000000000 --- a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidGeometry/Rendering/CacheGeometryHandler.h" -#include "MantidGeometry/Rendering/GeometryTriangulator.h" -#include "MantidKernel/MultiThreaded.h" - -#include - -namespace Mantid { -namespace Geometry { - -using namespace detail; -CacheGeometryHandler::CacheGeometryHandler(IObjComponent *comp) - : GeometryHandler(comp) { - m_triangulator = nullptr; -} - -CacheGeometryHandler::CacheGeometryHandler(boost::shared_ptr obj) - : GeometryHandler(obj) { - m_triangulator.reset(new GeometryTriangulator(obj.get())); -} - -CacheGeometryHandler::CacheGeometryHandler(CSGObject *obj) - : GeometryHandler(obj) { - m_triangulator.reset(new GeometryTriangulator(obj)); -} - -CacheGeometryHandler::CacheGeometryHandler(const CacheGeometryHandler &handler) - : GeometryHandler(handler) { - m_triangulator = nullptr; - - if (handler.Obj != nullptr) { - Obj = handler.Obj; - m_triangulator.reset(new GeometryTriangulator(Obj)); - } else if (handler.ObjComp != nullptr) - ObjComp = handler.ObjComp; -} - -boost::shared_ptr CacheGeometryHandler::clone() const { - auto clone = boost::make_shared(*this); - if (this->m_triangulator) - clone->m_triangulator.reset(new GeometryTriangulator(this->Obj)); - else - clone->m_triangulator = nullptr; - return clone; -} - -CacheGeometryHandler::~CacheGeometryHandler() { -} - -GeometryHandler *CacheGeometryHandler::createInstance(IObjComponent *comp) { - return new CacheGeometryHandler(comp); -} - -GeometryHandler * -CacheGeometryHandler::createInstance(boost::shared_ptr obj) { - return new CacheGeometryHandler(obj); -} - -GeometryHandler *CacheGeometryHandler::createInstance(CSGObject *obj) { - return new CacheGeometryHandler(obj); -} - -void CacheGeometryHandler::Triangulate() { - // Check whether Object is triangulated otherwise triangulate - PARALLEL_CRITICAL(Triangulate) - if (Obj != nullptr && !boolTriangulated) { - m_triangulator->triangulate(); - boolTriangulated = true; - } -} - -void CacheGeometryHandler::Render() { - if (Obj != nullptr) { - if (!boolTriangulated) - Triangulate(); - m_renderer.renderTriangulated(*m_triangulator); - } else if (ObjComp != nullptr) { - m_renderer.render(*ObjComp); - } -} - -void CacheGeometryHandler::Initialize() { - if (Obj != nullptr) { - Obj->updateGeometryHandler(); - if (!boolTriangulated) - Triangulate(); - m_renderer.renderTriangulated(*m_triangulator); - } else if (ObjComp != nullptr) { - m_renderer.render(*ObjComp); - } -} - -size_t CacheGeometryHandler::numberOfTriangles() { - if (Obj != nullptr) { - Obj->updateGeometryHandler(); - if (!boolTriangulated) - Triangulate(); - return m_triangulator->numTriangleFaces(); - } - else { - return 0; - } -} - -size_t CacheGeometryHandler::numberOfPoints() { - if (Obj != nullptr) { - Obj->updateGeometryHandler(); - if (!boolTriangulated) - Triangulate(); - return m_triangulator->numTriangleVertices(); - } - else { - return 0; - } -} - -boost::optional &> -CacheGeometryHandler::getTriangleVertices() { - if (Obj != nullptr) { - Obj->updateGeometryHandler(); - if (!boolTriangulated) - Triangulate(); - return m_triangulator->getTriangleVertices(); - } else { - return boost::none; - } -} - -boost::optional &> -CacheGeometryHandler::getTriangleFaces() { - if (Obj != nullptr) { - Obj->updateGeometryHandler(); - if (!boolTriangulated) - Triangulate(); - return m_triangulator->getTriangleFaces(); - } else { - return boost::none; - } -} - -/** -Sets the geometry cache using the triangulation information provided -@param noPts :: the number of points -@param noFaces :: the number of faces -@param pts :: a double array of the points -@param faces :: an int array of the faces -*/ -void CacheGeometryHandler::setGeometryCache(size_t nPts, size_t nFaces, - std::vector &&pts, - std::vector &&faces) { - m_triangulator->setGeometryCache(nPts, nFaces, std::move(pts), - std::move(faces)); - boolTriangulated = true; -} -} -} diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index e15226cc82c6..547eab09373e 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -1,42 +1,116 @@ #include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidKernel/make_unique.h" +#include "MantidGeometry/Instrument/RectangularDetector.h" +#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Rendering/GeometryTriangulator.h" +#include "MantidGeometry/Rendering/Renderer.h" +#include namespace Mantid { namespace Geometry { - -/** Constructor - * @param[in] comp - * This geometry handler will be ObjComponent's geometry handler - */ GeometryHandler::GeometryHandler(IObjComponent *comp) - : Obj() { - ObjComp = comp; - boolTriangulated = true; - boolIsInitialized = false; -} + : m_objComp(comp), m_renderer(new detail::Renderer()) {} -/** Constructor - * @param[in] obj - * This geometry handler will be Object's geometry handler - */ GeometryHandler::GeometryHandler(boost::shared_ptr obj) - : Obj(obj.get()) { - ObjComp = nullptr; - boolTriangulated = false; - boolIsInitialized = false; + : m_obj(obj.get()), + m_triangulator(new detail::GeometryTriangulator(obj.get())), + m_renderer(new detail::Renderer()) {} + +GeometryHandler::GeometryHandler(CSGObject *obj) + : m_obj(obj), m_triangulator(new detail::GeometryTriangulator(obj)), + m_renderer(new detail::Renderer()) {} + +GeometryHandler::GeometryHandler(RectangularDetector *comp) + : m_rectDet(comp), m_renderer(new detail::Renderer()) {} + +GeometryHandler::GeometryHandler(StructuredDetector *comp) + : m_structDet(comp), m_renderer(new detail::Renderer()) {} + +GeometryHandler::GeometryHandler(const GeometryHandler &renderer) + : m_renderer(new detail::Renderer()) { + if (renderer.m_obj) { + m_obj = renderer.m_obj; + if (renderer.m_triangulator) + m_triangulator.reset(new detail::GeometryTriangulator(m_obj)); + } + if (renderer.m_objComp) + m_objComp = renderer.m_objComp; + if (renderer.m_shapeInfo) + m_shapeInfo = renderer.m_shapeInfo; + if (renderer.m_structDet) + m_structDet = renderer.m_structDet; + if (renderer.m_rectDet) + m_rectDet = renderer.m_rectDet; } -/** Constructor - * @param[in] obj - * This geometry handler will be Object's geometry handler - */ -GeometryHandler::GeometryHandler(CSGObject *obj) : Obj(obj) { - ObjComp = nullptr; - boolTriangulated = false; - boolIsInitialized = false; +boost::shared_ptr GeometryHandler::clone() const { + return boost::make_shared(GeometryHandler(*this)); } +GeometryHandler::~GeometryHandler() {} -/// Destructor -GeometryHandler::~GeometryHandler() { ObjComp = nullptr; } +void GeometryHandler::render() { + if (m_rectDet) + m_renderer->renderBitmap(*m_rectDet); + else if (m_structDet) + m_renderer->renderStructured(*m_structDet); + else if (m_shapeInfo) + m_renderer->renderShape(*m_shapeInfo); + else if (m_objComp != nullptr) + m_renderer->renderIObjComponent(*m_objComp); + else if (canTriangulate()) + m_renderer->renderTriangulated(*m_triangulator); } + +void GeometryHandler::initialize() { + if (m_obj != nullptr) + m_obj->updateGeometryHandler(); + render(); +} + +size_t GeometryHandler::numberOfTriangles() { + if (canTriangulate()) + return m_triangulator->numTriangleFaces(); + return 0; +} + +size_t GeometryHandler::numberOfPoints() { + if (canTriangulate()) + return m_triangulator->numTriangleVertices(); + return 0; +} + +boost::optional &> +GeometryHandler::getTriangleVertices() { + if (canTriangulate()) + return m_triangulator->getTriangleVertices(); + return boost::none; +} + +boost::optional &> GeometryHandler::getTriangleFaces() { + if (canTriangulate()) + return m_triangulator->getTriangleFaces(); + return boost::none; +} + +void GeometryHandler::setGeometryCache(size_t nPts, size_t nFaces, + std::vector &&pts, + std::vector &&faces) { + if (canTriangulate()) { + m_triangulator->setGeometryCache(nPts, nFaces, std::move(pts), + std::move(faces)); + } +} + +void GeometryHandler::GetObjectGeom(detail::ShapeInfo::GeometryShape &mytype, + std::vector &vectors, + double &myradius, double &myheight) const { + mytype = detail::ShapeInfo::GeometryShape::NOSHAPE; + if (m_shapeInfo) + m_shapeInfo->getObjectGeometry(mytype, vectors, myradius, myheight); +} + +void GeometryHandler::setShapeInfo(detail::ShapeInfo &&shapeInfo) { + m_triangulator.reset(nullptr); + m_shapeInfo.reset(new detail::ShapeInfo(std::move(shapeInfo))); } +} // namespace Geometry +} // namespace Mantid \ No newline at end of file diff --git a/Framework/Geometry/src/Rendering/GeometryRenderer.cpp b/Framework/Geometry/src/Rendering/GeometryRenderer.cpp deleted file mode 100644 index 7a7f07edd137..000000000000 --- a/Framework/Geometry/src/Rendering/GeometryRenderer.cpp +++ /dev/null @@ -1,445 +0,0 @@ -#include "MantidGeometry/Rendering/GeometryRenderer.h" -#include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Instrument/StructuredDetector.h" -#include "MantidGeometry/Surfaces/Cone.h" -#include "MantidGeometry/Surfaces/Cylinder.h" -#include "MantidGeometry/Surfaces/Sphere.h" -#include "MantidKernel/Quat.h" -#include "MantidKernel/WarningSuppressions.h" - -// Squash a warning coming out of an OpenCascade header -#ifdef __INTEL_COMPILER -#pragma warning disable 191 -#endif -// Opencascade defines _USE_MATH_DEFINES without checking whether it is already -// used. -// Undefine it here before we include the headers to avoid a warning -#ifdef _MSC_VER -#undef _USE_MATH_DEFINES -#ifdef M_SQRT1_2 -#undef M_SQRT1_2 -#endif -#endif - -GCC_DIAG_OFF(conversion) -// clang-format off -GCC_DIAG_OFF(cast - qual) -// clang-format on -#include -#include -#include -#include -#include -#include -#include -#include -#include -GCC_DIAG_ON(conversion) -// clang-format off -GCC_DIAG_ON(cast - qual) -// clang-format on - -#ifdef __INTEL_COMPILER -#pragma warning enable 191 -#endif - -namespace Mantid { -namespace Geometry { -using Kernel::Quat; -using Kernel::V3D; - -void GeometryRenderer::renderIObjComponent(IObjComponent *objComp, - RenderMode mode) const { - render(mode, objComp); -} - -void GeometryRenderer::renderTriangulated(int noPts, int noFaces, - double *points, int *faces, - RenderMode mode) const { - render(mode, noPts, noFaces, points, faces); -} - -void GeometryRenderer::renderOpenCascade(TopoDS_Shape *objSurf, - RenderMode mode) const { - render(mode, objSurf); -} - -void GeometryRenderer::renderSphere(const Kernel::V3D ¢er, double radius, - RenderMode mode) const { - render(mode, center, radius); -} - -void GeometryRenderer::renderCuboid(const Kernel::V3D &Point1, - const Kernel::V3D &Point2, - const Kernel::V3D &Point3, - const Kernel::V3D &Point4, - RenderMode mode) const { - render(mode, Point1, Point2, Point3, Point4); -} - -void GeometryRenderer::renderHexahedron(const std::vector &points, - RenderMode mode) const { - render(mode, points); -} - -void GeometryRenderer::renderCone(const Kernel::V3D ¢er, - const Kernel::V3D &axis, double radius, - double height, RenderMode mode) const { - render(mode, center, axis, radius, height); -} - -void GeometryRenderer::renderCylinder(const Kernel::V3D ¢er, - const Kernel::V3D &axis, double radius, - double height, bool segmented, - RenderMode mode) const { - render(mode, center, axis, radius, height, segmented); -} - -void GeometryRenderer::renderBitmap(const RectangularDetector *rectDet, - RenderMode mode) const { - render(mode, rectDet); -} - -void GeometryRenderer::renderStructured(const StructuredDetector *structDet, - RenderMode mode) const { - render(mode, structDet); -} - -// Render IObjectComponent -void GeometryRenderer::doRender(IObjComponent *ObjComp) const { - glPushMatrix(); - V3D pos = ObjComp->getPos(); - Quat rot = ObjComp->getRotation(); - double rotGL[16]; - rot.GLMatrix(&rotGL[0]); - glTranslated(pos[0], pos[1], pos[2]); - glMultMatrixd(rotGL); - V3D scaleFactor = ObjComp->getScaleFactor(); - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - ObjComp->drawObject(); - glPopMatrix(); -} - -// Render triangulated surface -void GeometryRenderer::doRender(int noPts, int noFaces, double *points, - int *faces) const { - (void)noPts; // Avoid compiler warning - glBegin(GL_TRIANGLES); - V3D normal; - for (int i = 0; i < noFaces; i++) { - int index1 = faces[i * 3] * 3; - int index2 = faces[i * 3 + 1] * 3; - int index3 = faces[i * 3 + 2] * 3; - // Calculate normal and normalize - V3D v1(points[index1], points[index1 + 1], points[index1 + 2]); - V3D v2(points[index2], points[index2 + 1], points[index2 + 2]); - V3D v3(points[index3], points[index3 + 1], points[index3 + 2]); - normal = (v1 - v2).cross_prod(v2 - v3); - normal.normalize(); - glNormal3d(normal[0], normal[1], normal[2]); - glVertex3dv(points + index1); - glVertex3dv(points + index2); - glVertex3dv(points + index3); - } - glEnd(); -} - -// Render OpenCascade Shape -void GeometryRenderer::doRender(TopoDS_Shape *ObjSurf) const { - glBegin(GL_TRIANGLES); - if ((ObjSurf != nullptr) && !ObjSurf->IsNull()) { - TopExp_Explorer Ex; - for (Ex.Init(*ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) { - TopoDS_Face F = TopoDS::Face(Ex.Current()); - TopLoc_Location L; - Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - TColgp_Array1OfPnt tab(1, (facing->NbNodes())); - tab = facing->Nodes(); - Poly_Array1OfTriangle tri(1, facing->NbTriangles()); - tri = facing->Triangles(); - for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) { - Poly_Triangle trian = tri.Value(i); - Standard_Integer index1, index2, index3; - trian.Get(index1, index2, index3); - gp_Pnt point1 = tab.Value(index1); - gp_Pnt point2 = tab.Value(index2); - gp_Pnt point3 = tab.Value(index3); - gp_XYZ pt1 = tab.Value(index1).XYZ(); - gp_XYZ pt2 = tab.Value(index2).XYZ(); - gp_XYZ pt3 = tab.Value(index3).XYZ(); - - gp_XYZ v1 = pt2 - pt1; - gp_XYZ v2 = pt3 - pt2; - - gp_XYZ normal = v1 ^ v2; - normal.Normalize(); - glNormal3d(normal.X(), normal.Y(), normal.Z()); - glVertex3d(point1.X(), point1.Y(), point1.Z()); - glVertex3d(point2.X(), point2.Y(), point2.Z()); - glVertex3d(point3.X(), point3.Y(), point3.Z()); - } - } - } - glEnd(); -} - -// Render Sphere -void GeometryRenderer::doRender(const Kernel::V3D ¢er, - double radius) const { - // create glu sphere - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - glPushMatrix(); - glTranslated(center[0], center[1], center[2]); - gluSphere(qobj, radius, Sphere::g_nslices, Sphere::g_nstacks); - glPopMatrix(); - gluDeleteQuadric(qobj); -} - -// Render Cuboid -void GeometryRenderer::doRender(const V3D &Point1, const V3D &Point2, - const V3D &Point3, const V3D &Point4) const { - V3D vec0 = Point1; - V3D vec1 = Point2 - Point1; - V3D vec2 = Point3 - Point1; - V3D vec3 = Point4 - Point1; - V3D vertex[8]; - vertex[0] = vec0; - vertex[1] = vec0 + vec3; - vertex[2] = vec0 + vec3 + vec1; - vertex[3] = vec0 + vec1; - vertex[4] = vec0 + vec2; - vertex[5] = vec0 + vec2 + vec3; - vertex[6] = vec0 + vec2 + vec3 + vec1; - vertex[7] = vec0 + vec1 + vec2; - - int faceindex[6][4] = { - {0, 1, 2, 3}, // top - {0, 3, 7, 4}, // left - {3, 2, 6, 7}, // back - {2, 1, 5, 6}, // right - {0, 4, 5, 1}, // front - {4, 7, 6, 5}, // bottom - }; - V3D normal; - // first face - glBegin(GL_QUADS); - for (auto &row : faceindex) { - normal = (vertex[row[0]] - vertex[row[1]]) - .cross_prod((vertex[row[0]] - vertex[row[2]])); - normal.normalize(); - glNormal3d(normal[0], normal[1], normal[2]); - for (const int ij : row) { - if (ij == 0) - glTexCoord2i(0, 0); - if (ij == 1) - glTexCoord2i(1, 0); - if (ij == 2) - glTexCoord2i(1, 1); - if (ij == 3) - glTexCoord2i(0, 1); - if (ij == 4) - glTexCoord2i(0, 0); - if (ij == 5) - glTexCoord2i(1, 0); - if (ij == 6) - glTexCoord2i(1, 1); - if (ij == 7) - glTexCoord2i(0, 1); - glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]); - } - } - glEnd(); -} - -// Render Hexahedron -void GeometryRenderer::doRender(const std::vector &points) const { - glBegin(GL_QUADS); - // bottom - glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); - glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); - glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); - glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); - // front - glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); - glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); - glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); - glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); - // right - glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); - glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); - glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); - glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); - // back - glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); - glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); - glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); - glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); - // left - glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); - glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); - glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); - glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); - // top - glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); - glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); - glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); - glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); - - glEnd(); -} - -// Render Cone -void GeometryRenderer::doRender(const Kernel::V3D ¢er, - const Kernel::V3D &axis, double radius, - double height) const { - glPushMatrix(); - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - glTranslated(center[0], center[1], center[2]); - GLdouble mat[16]; - V3D unit(0, 0, 1); - Quat rot(unit, axis); - rot.GLMatrix(&mat[0]); - glMultMatrixd(mat); - gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, - Geometry::Cone::g_nstacks); - glTranslated(0.0, 0.0, height); - gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); - glPopMatrix(); -} - -// Render Cylinder -void GeometryRenderer::doRender(const Kernel::V3D ¢er, - const Kernel::V3D &axis, double radius, - double height, bool segmented) const { - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - gluQuadricTexture(qobj, true); - glPushMatrix(); - glTranslated(center[0], center[1], center[2]); - GLdouble mat[16]; - V3D unit(0, 0, 1); - Quat rot(unit, axis); - rot.GLMatrix(&mat[0]); - glMultMatrixd(mat); - gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, - segmented ? 1 : Cylinder::g_nstacks); - gluQuadricTexture(qobj, false); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glTranslated(0.0, 0.0, height); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glPopMatrix(); -} - -// Render Bitmap for RectangularDetector -void GeometryRenderer::doRender(const RectangularDetector *rectDet) const { - // Because texture colours are combined with the geometry colour - // make sure the current colour is white - glColor3f(1.0f, 1.0f, 1.0f); - - // Nearest-neighbor scaling - GLint texParam = GL_NEAREST; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam); - - glEnable(GL_TEXTURE_2D); // enable texture mapping - - int texx, texy; - rectDet->getTextureSize(texx, texy); - double tex_frac_x = (1.0 * rectDet->xpixels()) / (texx); - double tex_frac_y = (1.0 * rectDet->ypixels()) / (texy); - - glBegin(GL_QUADS); - - glTexCoord2f(0.0, 0.0); - V3D pos; - pos = rectDet->getRelativePosAtXY(0, 0); - pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (-0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glTexCoord2f(static_cast(tex_frac_x), 0.0); - pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, 0); - pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (-0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glTexCoord2f(static_cast(tex_frac_x), - static_cast(tex_frac_y)); - pos = rectDet->getRelativePosAtXY(rectDet->xpixels() - 1, - rectDet->ypixels() - 1); - pos += V3D(rectDet->xstep() * (+0.5), rectDet->ystep() * (+0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glTexCoord2f(0.0, static_cast(tex_frac_y)); - pos = rectDet->getRelativePosAtXY(0, rectDet->ypixels() - 1); - pos += V3D(rectDet->xstep() * (-0.5), rectDet->ystep() * (+0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - - glEnd(); - if (glGetError() > 0) - std::cout << "OpenGL error in BitmapGeometryHandler::render \n"; - - glDisable( - GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. -} - -void GeometryRenderer::doRender(const StructuredDetector *structDet) const { - auto xVerts = structDet->getXValues(); - auto yVerts = structDet->getYValues(); - auto r = structDet->getR(); - auto g = structDet->getG(); - auto b = structDet->getB(); - - if (xVerts.size() != yVerts.size()) - return; - - auto w = structDet->xPixels() + 1; - auto h = structDet->yPixels() + 1; - - glBegin(GL_QUADS); - - for (size_t iy = 0; iy < h - 1; iy++) { - for (size_t ix = 0; ix < w - 1; ix++) { - - glColor3ub((GLubyte)r[(iy * (w - 1)) + ix], - (GLubyte)g[(iy * (w - 1)) + ix], - (GLubyte)b[(iy * (w - 1)) + ix]); - V3D pos; - pos = V3D(xVerts[(iy * w) + ix + w], yVerts[(iy * w) + ix + w], 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix + w + 1], yVerts[(iy * w) + ix + w + 1], - 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix + 1], yVerts[(iy * w) + ix + 1], 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix], yVerts[(iy * w) + ix], 0.0); - glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), - static_cast(pos.Z())); - } - } - - glEnd(); - - if (glGetError() > 0) - std::cout << "OpenGL error in StructuredGeometryHandler::render \n"; - - glDisable( - GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. -} -} // namespace Geometry -} // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index fc2a8fa2c144..3545750ad710 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -76,9 +76,9 @@ void GeometryTriangulator::triangulate() { #ifdef ENABLE_OPENCASCADE /// Return OpenCascade surface. -const TopoDS_Shape &GeometryTriangulator::getOCSurface() { +boost::shared_ptr GeometryTriangulator::getOCSurface() { checkTriangulated(); - return *m_objSurface; + return m_objSurface; } #endif diff --git a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp deleted file mode 100644 index 61cae7445068..000000000000 --- a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "MantidGeometry/Rendering/GluGeometryHandler.h" -#include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" -#include "MantidKernel/make_unique.h" - -#include - -namespace Mantid { -namespace Geometry { -using Kernel::V3D; -using namespace detail; - -GluGeometryHandler::GluGeometryHandler(IObjComponent *comp) - : GeometryHandler(comp), radius(0.0), height(0.0){} - -GluGeometryHandler::GluGeometryHandler(boost::shared_ptr obj) - : GeometryHandler(std::move(obj)), radius(0.0), height(0.0) {} - -GluGeometryHandler::GluGeometryHandler(CSGObject *obj) - : GeometryHandler(obj), radius(0.0), height(0.0) {} - -GluGeometryHandler::GluGeometryHandler(const GluGeometryHandler &other) - : GeometryHandler(other), m_points(other.m_points), radius(other.radius), - height(other.height), m_shapeInfo(other.m_shapeInfo) { -} - -boost::shared_ptr GluGeometryHandler::clone() const { - return boost::make_shared(*this); -} - -GluGeometryHandler::~GluGeometryHandler() = default; - -GeometryHandler *GluGeometryHandler::createInstance(IObjComponent *comp) { - return new GluGeometryHandler(comp); -} - -GeometryHandler * -GluGeometryHandler::createInstance(boost::shared_ptr obj) { - return new GluGeometryHandler(obj); -} - -GeometryHandler *GluGeometryHandler::createInstance(CSGObject *obj) { - return new GluGeometryHandler(obj); -} - -void GluGeometryHandler::Triangulate() { - // Check whether Object is triangulated otherwise triangulate - // Doesn't have to do anything because we are not going to triangulate - // anything -} - -void GluGeometryHandler::Render() { - if (Obj != nullptr) { - m_renderer.renderShape(m_shapeInfo); - } else if (ObjComp != nullptr) { - m_renderer.render(*ObjComp); - } -} - -void GluGeometryHandler::GetObjectGeom(int &mytype, - std::vector &vectors, - double &myradius, double &myheight) { - m_shapeInfo.getObjectGeometry(mytype, vectors, myradius, myheight); -} - -void GluGeometryHandler::Initialize() { Render(); } - -void GluGeometryHandler::setShapeInfo(detail::ShapeInfo &&shapeInfo) -{ - m_shapeInfo = std::move(shapeInfo); -} - -} -} diff --git a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp b/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp deleted file mode 100644 index 502989410f56..000000000000 --- a/Framework/Geometry/src/Rendering/OCGeometryHandler.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Rendering/GeometryTriangulator.h" - -#include - -namespace Mantid { -namespace Geometry { -using namespace detail; - -OCGeometryHandler::OCGeometryHandler(IObjComponent *comp) - : GeometryHandler(comp) { - m_triangulator = nullptr; -} - -OCGeometryHandler::OCGeometryHandler(boost::shared_ptr obj) - : GeometryHandler(obj) { - m_triangulator.reset(new GeometryTriangulator(obj.get())); -} - -OCGeometryHandler::OCGeometryHandler(CSGObject *obj) : GeometryHandler(obj) { - m_triangulator.reset(new GeometryTriangulator(obj)); -} - -OCGeometryHandler::OCGeometryHandler(const OCGeometryHandler &handler) - : GeometryHandler(handler) { - m_triangulator = nullptr; - - if (handler.Obj != nullptr) { - Obj = handler.Obj; - m_triangulator.reset(new GeometryTriangulator(Obj)); - } else if (handler.ObjComp != nullptr) - ObjComp = handler.ObjComp; -} - -boost::shared_ptr OCGeometryHandler::clone() const { - auto clone = boost::make_shared(*this); - if (this->m_triangulator) - clone->m_triangulator.reset(new GeometryTriangulator(this->Obj)); - return clone; -} - -OCGeometryHandler::~OCGeometryHandler() { -} - -GeometryHandler *OCGeometryHandler::createInstance(IObjComponent *comp) { - return new OCGeometryHandler(comp); -} - -GeometryHandler * -OCGeometryHandler::createInstance(boost::shared_ptr obj) { - return new OCGeometryHandler(obj); -} - -GeometryHandler *OCGeometryHandler::createInstance(CSGObject *obj) { - return new OCGeometryHandler(obj); -} - -void OCGeometryHandler::Triangulate() { - // Check whether Object is triangulated otherwise triangulate - if (Obj != nullptr && !boolTriangulated) { - m_triangulator->triangulate(); - boolTriangulated = true; - } -} - -void OCGeometryHandler::Render() { - if (Obj != nullptr) { - if (!boolTriangulated) - Triangulate(); - m_renderer.render(m_triangulator->getOCSurface()); - } else if (ObjComp != nullptr) { - m_renderer.render(*ObjComp); - } -} - -void OCGeometryHandler::Initialize() { Render(); } - -size_t OCGeometryHandler::numberOfTriangles() { - if (Obj != nullptr) { - if (!boolTriangulated) - Triangulate(); - return m_triangulator->numTriangleFaces(); - } - else { - return 0; - } -} - -size_t OCGeometryHandler::numberOfPoints() { - if (Obj != nullptr) { - if (!boolTriangulated) - Triangulate(); - return m_triangulator->numTriangleVertices(); - } - else { - return 0; - } -} -boost::optional &> OCGeometryHandler::getTriangleVertices() { - if (Obj != nullptr) { - if (!boolTriangulated) - Triangulate(); - return m_triangulator->getTriangleVertices(); - } else { - return boost::none; - } -} - -boost::optional &> OCGeometryHandler::getTriangleFaces() { - if (Obj != nullptr) { - if (!boolTriangulated) - Triangulate(); - return m_triangulator->getTriangleFaces(); - } else { - return boost::none; - } -} -} // namespace Geometry -} // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index 7d6f03dd3f69..a4ef60a529a6 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -61,8 +61,8 @@ void Renderer::renderTriangulated(detail::GeometryTriangulator &triangulator, RenderMode mode) const { #ifdef ENABLE_OPENCASCADE auto surface = triangulator.getOCSurface(); - if (!surface.IsNull()) - render(mode, surface); + if (surface && !surface->IsNull()) + render(mode, *surface); else render(mode, triangulator); #else @@ -101,8 +101,7 @@ void Renderer::renderStructured(const StructuredDetector &structDet, render(mode, structDet); } -void Renderer::doRenderSphere(const ShapeInfo &shapeInfo) const -{ +void Renderer::doRenderSphere(const ShapeInfo &shapeInfo) const { // create glu sphere GLUquadricObj *qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_FILL); @@ -115,8 +114,7 @@ void Renderer::doRenderSphere(const ShapeInfo &shapeInfo) const gluDeleteQuadric(qobj); } -void Renderer::doRenderCuboid(const ShapeInfo &shapeInfo) const -{ +void Renderer::doRenderCuboid(const ShapeInfo &shapeInfo) const { const auto &points = shapeInfo.points(); V3D vec0 = points[0]; V3D vec1 = points[1] - points[0]; @@ -133,19 +131,19 @@ void Renderer::doRenderCuboid(const ShapeInfo &shapeInfo) const vertex[7] = vec0 + vec1 + vec2; int faceindex[6][4] = { - { 0, 1, 2, 3 }, // top - { 0, 3, 7, 4 }, // left - { 3, 2, 6, 7 }, // back - { 2, 1, 5, 6 }, // right - { 0, 4, 5, 1 }, // front - { 4, 7, 6, 5 }, // bottom + {0, 1, 2, 3}, // top + {0, 3, 7, 4}, // left + {3, 2, 6, 7}, // back + {2, 1, 5, 6}, // right + {0, 4, 5, 1}, // front + {4, 7, 6, 5}, // bottom }; V3D normal; // first face glBegin(GL_QUADS); for (auto &row : faceindex) { normal = (vertex[row[0]] - vertex[row[1]]) - .cross_prod((vertex[row[0]] - vertex[row[2]])); + .cross_prod((vertex[row[0]] - vertex[row[2]])); normal.normalize(); glNormal3d(normal[0], normal[1], normal[2]); for (const int ij : row) { @@ -171,8 +169,7 @@ void Renderer::doRenderCuboid(const ShapeInfo &shapeInfo) const glEnd(); } -void Renderer::doRenderHexahedron(const ShapeInfo &shapeInfo) const -{ +void Renderer::doRenderHexahedron(const ShapeInfo &shapeInfo) const { glBegin(GL_QUADS); const auto &points = shapeInfo.points(); // bottom @@ -225,7 +222,7 @@ void Renderer::doRenderCone(const ShapeInfo &shapeInfo) const { auto radius = shapeInfo.radius(); auto height = shapeInfo.height(); gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, - Geometry::Cone::g_nstacks); + Geometry::Cone::g_nstacks); glTranslated(0.0, 0.0, height); gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); glPopMatrix(); @@ -375,8 +372,8 @@ void Renderer::doRender(const RectangularDetector &rectDet) const { glTexCoord2f(static_cast(tex_frac_x), static_cast(tex_frac_y)); - pos = rectDet.getRelativePosAtXY(rectDet.xpixels() - 1, - rectDet.ypixels() - 1); + pos = + rectDet.getRelativePosAtXY(rectDet.xpixels() - 1, rectDet.ypixels() - 1); pos += V3D(rectDet.xstep() * (+0.5), rectDet.ystep() * (+0.5), 0.0); // Adjust to account for the size of a pixel glVertex3f(static_cast(pos.X()), static_cast(pos.Y()), @@ -391,18 +388,19 @@ void Renderer::doRender(const RectangularDetector &rectDet) const { glEnd(); if (glGetError() > 0) - std::cout << "OpenGL error in BitmapGeometryHandler::render \n"; + std::cout + << "OpenGL error in Renderer::doRender(const RectangularDetector &) \n"; glDisable( GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. } void Renderer::doRender(const StructuredDetector &structDet) const { - auto xVerts = structDet.getXValues(); - auto yVerts = structDet.getYValues(); - auto r = structDet.getR(); - auto g = structDet.getG(); - auto b = structDet.getB(); + const auto &xVerts = structDet.getXValues(); + const auto &yVerts = structDet.getYValues(); + const auto &r = structDet.getR(); + const auto &g = structDet.getG(); + const auto &b = structDet.getB(); if (xVerts.size() != yVerts.size()) return; @@ -438,10 +436,8 @@ void Renderer::doRender(const StructuredDetector &structDet) const { glEnd(); if (glGetError() > 0) - std::cout << "OpenGL error in StructuredGeometryHandler::render \n"; - - glDisable( - GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. + std::cout + << "OpenGL error in Renderer::doRender(const StructuredDetector &) \n"; } } // namespace detail } // namespace Geometry diff --git a/Framework/Geometry/src/Rendering/ShapeInfo.cpp b/Framework/Geometry/src/Rendering/ShapeInfo.cpp index c1642fe94aae..d9b625580622 100644 --- a/Framework/Geometry/src/Rendering/ShapeInfo.cpp +++ b/Framework/Geometry/src/Rendering/ShapeInfo.cpp @@ -16,10 +16,10 @@ double ShapeInfo::height() const { return m_height; } ShapeInfo::GeometryShape ShapeInfo::shape() const { return m_shape; } -void ShapeInfo::getObjectGeometry(int &myshape, +void ShapeInfo::getObjectGeometry(ShapeInfo::GeometryShape &myshape, std::vector &points, double &myradius, double &myheight) const { - myshape = static_cast(m_shape); + myshape = m_shape; points = m_points; myradius = m_radius; myheight = m_height; @@ -29,6 +29,8 @@ void ShapeInfo::setCuboid(const V3D &p1, const V3D &p2, const V3D &p3, const V3D &p4) { m_shape = GeometryShape::CUBOID; m_points.assign({p1, p2, p3, p4}); + m_radius = 0; + m_height = 0; } void ShapeInfo::setHexahedron(const V3D &p1, const V3D &p2, const V3D &p3, @@ -36,12 +38,15 @@ void ShapeInfo::setHexahedron(const V3D &p1, const V3D &p2, const V3D &p3, const V3D &p7, const V3D &p8) { m_shape = GeometryShape::HEXAHEDRON; m_points.assign({p1, p2, p3, p4, p5, p6, p7, p8}); + m_radius = 0; + m_height = 0; } void ShapeInfo::setSphere(const V3D &c, double r) { m_shape = GeometryShape::SPHERE; m_points.assign({c}); m_radius = r; + m_height = 0; } void ShapeInfo::setCylinder(const V3D &c, const V3D &a, double r, double h) { m_shape = GeometryShape::CYLINDER; @@ -62,6 +67,11 @@ void ShapeInfo::setSegmentedCylinder(const V3D &c, const V3D &a, double r, m_radius = r; m_height = h; } + +bool ShapeInfo::operator==(const ShapeInfo &other) { + return m_shape == other.m_shape && m_height == other.m_height && + m_radius == other.m_radius && m_points == other.m_points; +} } // namespace detail } // namespace Geometry } // namespace Mantid \ No newline at end of file diff --git a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp b/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp deleted file mode 100644 index 24bf8158497f..000000000000 --- a/Framework/Geometry/src/Rendering/StructuredGeometryHandler.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "MantidGeometry/Instrument/StructuredDetector.h" -#include "MantidGeometry/Rendering/OpenGL_Headers.h" -#include "MantidGeometry/Rendering/StructuredGeometryHandler.h" -#include -#include - -#include - -namespace Mantid { -namespace Geometry { -using Kernel::V3D; - -/** - * @return A shared_ptr to a new copy of this object - */ -boost::shared_ptr StructuredGeometryHandler::clone() const { - return boost::make_shared(*this); -} - -/// Parameter constructor -StructuredGeometryHandler::StructuredGeometryHandler(StructuredDetector *comp) - : GeometryHandler(dynamic_cast(comp)) { - // Save the structured detector link for later. - m_Det = comp; -} - -StructuredGeometryHandler::StructuredGeometryHandler() - : GeometryHandler(static_cast(nullptr)), m_Det(nullptr) {} - -///< Create an instance of concrete geometry handler for ObjComponent -StructuredGeometryHandler * -StructuredGeometryHandler::createInstance(IObjComponent *) { - return new StructuredGeometryHandler(); -} - -///< Create an instance of concrete geometry handler for Object -StructuredGeometryHandler * - StructuredGeometryHandler::createInstance(boost::shared_ptr) { - return new StructuredGeometryHandler(); -} - -///< Create an instance of concrete geometry handler for Object -GeometryHandler *StructuredGeometryHandler::createInstance(CSGObject *) { - return new StructuredGeometryHandler(); -} - -//---------------------------------------------------------------------------------------------- -/** Triangulate the Object - this function will not be used. - * - */ -void StructuredGeometryHandler::Triangulate() { - // do nothing -} - -//---------------------------------------------------------------------------------------------- -///< Draw pixels according to StructuredDetector vertices -void StructuredGeometryHandler::Render() { m_renderer.render(*m_Det); } - -//---------------------------------------------------------------------------------------------- -///< Prepare/Initialize Object/ObjComponent to be rendered -void StructuredGeometryHandler::Initialize() { - // do nothing -} -} -} diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h index d70c589544e4..25006911a20b 100644 --- a/Framework/Geometry/test/CSGObjectTest.h +++ b/Framework/Geometry/test/CSGObjectTest.h @@ -10,7 +10,7 @@ #include "MantidGeometry/Surfaces/SurfaceFactory.h" #include "MantidGeometry/Objects/Rules.h" #include "MantidGeometry/Objects/Track.h" -#include "MantidGeometry/Rendering/GluGeometryHandler.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/make_unique.h" @@ -36,6 +36,7 @@ using namespace Mantid; using namespace Geometry; using Mantid::Kernel::V3D; +using detail::ShapeInfo; namespace { // ----------------------------------------------------------------------------- @@ -84,23 +85,22 @@ class CSGObjectTest : public CxxTest::TestSuite { auto original_ptr = ComponentCreationHelper::createSphere(1.0); auto &original = dynamic_cast(*original_ptr); original.setID("sp-1"); - int objType(-1); + ShapeInfo::GeometryShape objType; double radius(-1.0), height(-1.0); std::vector pts; - original.GetObjectGeom(objType, pts, radius, height); - TS_ASSERT_EQUALS(3, objType); - TS_ASSERT(boost::dynamic_pointer_cast( - original.getGeometryHandler())); + auto handler = original->getGeometryHandler(); + TS_ASSERT(handler->hasShapeInfo()); + original->GetObjectGeom(objType, pts, radius, height); + TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType); CSGObject copy(original); - // The copy should be a primitive object with a GluGeometryHandler - objType = -1; + // The copy should be a primitive object with a GeometryHandler copy.GetObjectGeom(objType, pts, radius, height); TS_ASSERT_EQUALS("sp-1", copy.id()); - TS_ASSERT_EQUALS(3, objType); - TS_ASSERT(boost::dynamic_pointer_cast( - copy.getGeometryHandler())); + auto handlerCopy = copy.getGeometryHandler(); + TS_ASSERT(handlerCopy->hasShapeInfo()); + TS_ASSERT_EQUALS(handler->shapeInfo(), handlerCopy->shapeInfo()); TS_ASSERT_EQUALS(copy.getName(), original.getName()); // Check the string representation is the same TS_ASSERT_EQUALS(copy.str(), original.str()); @@ -111,24 +111,24 @@ class CSGObjectTest : public CxxTest::TestSuite { auto original_ptr = ComponentCreationHelper::createSphere(1.0); auto &original = dynamic_cast(*original_ptr); original.setID("sp-1"); - int objType(-1); + ShapeInfo::GeometryShape objType; double radius(-1.0), height(-1.0); std::vector pts; - original.GetObjectGeom(objType, pts, radius, height); - TS_ASSERT_EQUALS(3, objType); - TS_ASSERT(boost::dynamic_pointer_cast( - original.getGeometryHandler())); + auto handler = original->getGeometryHandler(); + TS_ASSERT(handler->hasShapeInfo()); + original->GetObjectGeom(objType, pts, radius, height); + TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType); CSGObject lhs; // initialize lhs = original; // assign // The copy should be a primitive object with a GluGeometryHandler - objType = -1; lhs.GetObjectGeom(objType, pts, radius, height); TS_ASSERT_EQUALS("sp-1", lhs.id()); - TS_ASSERT_EQUALS(3, objType); - TS_ASSERT(boost::dynamic_pointer_cast( - lhs.getGeometryHandler())); + TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType); + auto handlerCopy = lhs.getGeometryHandler(); + TS_ASSERT(handlerCopy->hasShapeInfo()); + TS_ASSERT_EQUALS(handlerCopy->shapeInfo(), handler->shapeInfo()); } void testCreateUnitCube() { @@ -781,9 +781,7 @@ class CSGObjectTest : public CxxTest::TestSuite { { boost::shared_ptr geom_obj = createSmallCappedCylinder(); // Want to test triangulation so setup a geometry handler - boost::shared_ptr h = - boost::shared_ptr( - new GluGeometryHandler(geom_obj.get())); + auto h = boost::make_shared(geom_obj); detail::ShapeInfo shapeInfo; shapeInfo.setCylinder(V3D(-0.0015, 0.0, 0.0), V3D(1., 0.0, 0.0), 0.005, 0.003); @@ -1432,7 +1430,7 @@ class CSGObjectTest : public CxxTest::TestSuite { // Explicitly setting the GluGeometryHanler hexahedron allows // for the correct bounding box calculation. - auto handler = boost::make_shared(retVal); + auto handler = boost::make_shared(retVal); detail::ShapeInfo shapeInfo; shapeInfo.setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft, hex.rft, hex.rbt); diff --git a/Framework/Geometry/test/ObjCompAssemblyTest.h b/Framework/Geometry/test/ObjCompAssemblyTest.h index 4956b67a238a..30fda2960985 100644 --- a/Framework/Geometry/test/ObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ObjCompAssemblyTest.h @@ -359,12 +359,13 @@ class ObjCompAssemblyTest : public CxxTest::TestSuite { boost::shared_ptr shape = bank.createOutline(); TS_ASSERT(shape); - int otype; + detail::ShapeInfo::GeometryShape otype; std::vector vectors; double radius, height; shape->GetObjectGeom(otype, vectors, radius, height); - TS_ASSERT_EQUALS(otype, 6); + TS_ASSERT_EQUALS(otype, + detail::ShapeInfo::GeometryShape::SEGMENTED_CYLINDER); TS_ASSERT_EQUALS(radius, 0.1); TS_ASSERT_EQUALS(height, 0.6); } diff --git a/Framework/Geometry/test/ParObjCompAssemblyTest.h b/Framework/Geometry/test/ParObjCompAssemblyTest.h index 7710e6233bbc..96af56c03f28 100644 --- a/Framework/Geometry/test/ParObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ParObjCompAssemblyTest.h @@ -135,12 +135,13 @@ class ParObjCompAssemblyTest : public CxxTest::TestSuite { boost::shared_ptr shape = bank.createOutline(); TS_ASSERT(shape); - int otype; + detail::ShapeInfo::GeometryShape otype; std::vector vectors; double radius, height; shape->GetObjectGeom(otype, vectors, radius, height); - TS_ASSERT_EQUALS(otype, 6); + TS_ASSERT_EQUALS(otype, + detail::ShapeInfo::GeometryShape::SEGMENTED_CYLINDER); TS_ASSERT_EQUALS(radius, 0.1); TS_ASSERT_EQUALS(height, 0.6); diff --git a/Framework/Geometry/test/ShapeInfoTest.h b/Framework/Geometry/test/ShapeInfoTest.h new file mode 100644 index 000000000000..610371b221d3 --- /dev/null +++ b/Framework/Geometry/test/ShapeInfoTest.h @@ -0,0 +1,154 @@ +#include "MantidGeometry/Rendering/ShapeInfo.h" +#include "MantidKernel/V3D.h" +#include + +using Mantid::Kernel::V3D; +using namespace Mantid::Geometry::detail; + +class ShapeInfoTest : public CxxTest::TestSuite { +private: + ShapeInfo m_shapeInfo; + +public: + void testConstructEmptyInitiazesEverythingZero() { + TS_ASSERT(m_shapeInfo.points().size() == 0); + TS_ASSERT(m_shapeInfo.height() == 0); + TS_ASSERT(m_shapeInfo.radius() == 0); + TS_ASSERT(m_shapeInfo.shape() == ShapeInfo::GeometryShape::NOSHAPE); + } + + void testSetSphere() { + V3D center(0, 0, 0); + double radius = 10; + m_shapeInfo.setSphere(center, radius); + + TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::SPHERE); + TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius); + TS_ASSERT_EQUALS(m_shapeInfo.height(), 0); + TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 1); + TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center); + } + + void testSetCuboid() { + V3D p1(0, 0, 0); + V3D p2(0, 0, 1); + V3D p3(0, 1, 0); + V3D p4(0, 1, 1); + + m_shapeInfo.setCuboid(p1, p2, p3, p4); + + TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::CUBOID); + TS_ASSERT_EQUALS(m_shapeInfo.radius(), 0); + TS_ASSERT_EQUALS(m_shapeInfo.height(), 0); + TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 4); + TS_ASSERT_EQUALS(m_shapeInfo.points(), (std::vector{p1, p2, p3, p4})); + } + + void testSetHexahedron() { + V3D p1(0, 0, 0); + V3D p2(0, 0, 1); + V3D p3(0, 1, 0); + V3D p4(0, 1, 1); + V3D p5(1, 0, 0); + V3D p6(1, 0, 1); + V3D p7(1, 1, 0); + V3D p8(1, 1, 1); + + m_shapeInfo.setHexahedron(p1, p2, p3, p4, p5, p6, p7, p8); + + TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::HEXAHEDRON); + TS_ASSERT_EQUALS(m_shapeInfo.radius(), 0); + TS_ASSERT_EQUALS(m_shapeInfo.height(), 0); + TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 8); + TS_ASSERT_EQUALS(m_shapeInfo.points(), + (std::vector{p1, p2, p3, p4, p5, p6, p7, p8})); + } + + void testSetCone() { + V3D center(0, 0, 0); + V3D axis(1, 0, 0); + double radius = 10; + double height = 5; + m_shapeInfo.setCone(center, axis, radius, height); + + TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::CONE); + TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius); + TS_ASSERT_EQUALS(m_shapeInfo.height(), height); + TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 2); + TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center); + TS_ASSERT_EQUALS(m_shapeInfo.points()[1], axis); + } + + void testSetCylinder() { + V3D center(0, 0, 0); + V3D axis(1, 0, 0); + double radius = 10; + double height = 5; + m_shapeInfo.setCylinder(center, axis, radius, height); + + TS_ASSERT_EQUALS(m_shapeInfo.shape(), ShapeInfo::GeometryShape::CYLINDER); + TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius); + TS_ASSERT_EQUALS(m_shapeInfo.height(), height); + TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 2); + TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center); + TS_ASSERT_EQUALS(m_shapeInfo.points()[1], axis); + } + + void testSetSegmentedSphere() { + V3D center(0, 0, 0); + V3D axis(1, 0, 0); + double radius = 10; + double height = 5; + m_shapeInfo.setSegmentedCylinder(center, axis, radius, height); + + TS_ASSERT_EQUALS(m_shapeInfo.shape(), + ShapeInfo::GeometryShape::SEGMENTED_CYLINDER); + TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius); + TS_ASSERT_EQUALS(m_shapeInfo.height(), height); + TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 2); + TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center); + TS_ASSERT_EQUALS(m_shapeInfo.points()[1], axis); + } + + void testGetObjectGeometry() { + V3D center(0, 0, 0); + double radius = 10; + m_shapeInfo.setSphere(center, radius); + + ShapeInfo::GeometryShape tshape; + std::vector tpoints; + double theight; + double tradius; + + m_shapeInfo.getObjectGeometry(tshape, tpoints, tradius, theight); + TS_ASSERT_EQUALS(tradius, radius); + TS_ASSERT(theight == 0); + TS_ASSERT(tpoints.size() == 1); + TS_ASSERT_EQUALS(tpoints[0], center); + TS_ASSERT_EQUALS(tshape, ShapeInfo::GeometryShape::SPHERE); + } + + void testCopyConstructor() { + V3D center(0, 2, 1); + double radius = 10; + m_shapeInfo.setSphere(center, radius); + + ShapeInfo shapeInfoCopy(m_shapeInfo); + + TS_ASSERT_EQUALS(m_shapeInfo.shape(), shapeInfoCopy.shape()); + TS_ASSERT_EQUALS(m_shapeInfo.radius(), shapeInfoCopy.radius()); + TS_ASSERT_EQUALS(m_shapeInfo.height(), shapeInfoCopy.height()); + TS_ASSERT_EQUALS(m_shapeInfo.points(), shapeInfoCopy.points()); + } + + void testEquality() { + V3D center(0, 2, 1); + double radius = 10; + m_shapeInfo.setSphere(center, radius); + ShapeInfo shapeInfo2, shapeInfo3; + shapeInfo2.setSphere(center, radius); + shapeInfo3.setCuboid(V3D(), V3D(), V3D(), V3D()); + TS_ASSERT_EQUALS(shapeInfo2, m_shapeInfo); + TS_ASSERT_DIFFERS(shapeInfo3, m_shapeInfo); + } +}; \ No newline at end of file From d305bac961d2ab0b2f01291aef985cc78e2408dc Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 1 Dec 2017 07:38:30 +0000 Subject: [PATCH 017/364] Small opencascade fix re #21248 --- Framework/Geometry/CMakeLists.txt | 10 +++++----- Framework/Geometry/src/Rendering/Renderer.cpp | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index 6bbb7cfd3c2b..5316f12f8a8c 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -109,8 +109,8 @@ set ( SRC_FILES src/Objects/ShapeFactory.cpp src/Objects/Track.cpp src/Rendering/GeometryHandler.cpp - src/Rendering/Renderer.cpp - src/Rendering/ShapeInfo.cpp + src/Rendering/Renderer.cpp + src/Rendering/ShapeInfo.cpp src/Rendering/vtkGeometryCacheReader.cpp src/Rendering/vtkGeometryCacheWriter.cpp src/Rendering/GeometryTriangulator.cpp @@ -261,8 +261,8 @@ set ( INC_FILES inc/MantidGeometry/Objects/ShapeFactory.h inc/MantidGeometry/Objects/Track.h inc/MantidGeometry/Rendering/GeometryHandler.h - inc/MantidGeometry/Rendering/Renderer.h - inc/MantidGeometry/Rendering/ShapeInfo.h + inc/MantidGeometry/Rendering/Renderer.h + inc/MantidGeometry/Rendering/ShapeInfo.h inc/MantidGeometry/Rendering/OpenGL_Headers.h inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h inc/MantidGeometry/Rendering/vtkGeometryCacheWriter.h @@ -388,7 +388,7 @@ set ( TEST_FILES SampleEnvironmentTest.h ScalarUtilsTest.h ShapeFactoryTest.h - ShapeInfoTest.h + ShapeInfoTest.h SpaceGroupFactoryTest.h SpaceGroupTest.h SphereTest.h diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index a4ef60a529a6..348039e8397f 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -10,6 +10,7 @@ #include "MantidKernel/Quat.h" #include "MantidKernel/WarningSuppressions.h" +#ifdef ENABLE_OPENCASCADE // Squash a warning coming out of an OpenCascade header #ifdef __INTEL_COMPILER #pragma warning disable 191 @@ -45,6 +46,7 @@ GCC_DIAG_ON(cast - qual) #ifdef __INTEL_COMPILER #pragma warning enable 191 #endif +#endif namespace Mantid { namespace Geometry { From aeec5ab8a88f1b8a80452868b6706fb7cfa176b0 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 1 Dec 2017 07:53:36 +0000 Subject: [PATCH 018/364] Clang format #21248 --- .../inc/MantidGeometry/Objects/CSGObject.h | 9 +++---- Framework/Geometry/src/Objects/CSGObject.cpp | 24 +++++++------------ .../Geometry/src/Objects/ShapeFactory.cpp | 18 +++++++------- .../src/Rendering/vtkGeometryCacheReader.cpp | 2 +- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index 1281c4ec5485..23eba4a44c35 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -188,8 +188,9 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { /// set vtkGeometryCache reader void setVtkGeometryCacheReader( boost::shared_ptr) override; - void GetObjectGeom(detail::ShapeInfo::GeometryShape &type, std::vector &vectors, - double &myradius, double &myheight) const override; + void GetObjectGeom(detail::ShapeInfo::GeometryShape &type, + std::vector &vectors, double &myradius, + double &myheight) const; /// Getter for the shape xml std::string getShapeXML() const override; @@ -260,8 +261,8 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { size_t numberOfTriangles() const; size_t numberOfVertices() const; /// for solid angle from triangulation - boost::optional &>getTriangleFaces() const; - boost::optional &>getTriangleVertices() const; + boost::optional &> getTriangleFaces() const; + boost::optional &> getTriangleVertices() const; /// original shape xml used to generate this object. std::string m_shapeXML; /// Optional string identifier diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 2f46cd252538..ce33b073e4f8 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -2125,28 +2125,21 @@ void CSGObject::updateGeometryHandler() { // Initialize Draw Object -/** -* get number of triangles -* @return the number of triangles -*/ -int CSGObject::NumberOfTriangles() const { - if (m_handler == nullptr) +size_t CSGObject::numberOfTriangles() const { + if (handle == nullptr) return 0; return m_handler->NumberOfTriangles(); } - -/** -* get number of points -*/ -int CSGObject::NumberOfPoints() const { - if (m_handler == nullptr) +size_t CSGObject::numberOfVertices() const { + if (handle == nullptr) return 0; return m_handler->NumberOfPoints(); } /** * get vertices */ -boost::optional &>CSGObject::getTriangleVertices() const { +boost::optional &> +CSGObject::getTriangleVertices() const { if (handle == nullptr) return boost::none; return m_handler->getTriangleVertices(); @@ -2164,8 +2157,9 @@ boost::optional &> CSGObject::getTriangleFaces() const { /** * get info on standard shapes */ -void Object::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, std::vector &vectors, - double &myradius, double &myheight) const { +void Object::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, + std::vector &vectors, double &myradius, + double &myheight) const { type = detail::ShapeInfo::GeometryShape::NOSHAPE; if (m_handler == nullptr) return; diff --git a/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Framework/Geometry/src/Objects/ShapeFactory.cpp index 29a977dbb7a9..e5cccd858ca6 100644 --- a/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -1412,7 +1412,7 @@ ShapeFactory::createHexahedralShape(double xlb, double xlf, double xrf, shape->setGeometryHandler(handler); shapeInfo.setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft, - hex.rft, hex.rbt); + hex.rft, hex.rbt); handler->setShapeInfo(std::move(shapeInfo)); shape->defineBoundingBox(std::max(xrb, xrf), yrf, ZDEPTH, std::min(xlf, xlb), @@ -1434,9 +1434,8 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, shapeInfo.setCuboid(corners.lfb, corners.lft, corners.lbb, corners.rfb); } else if (pElem->tagName() == "hexahedron") { auto corners = parseHexahedron(pElem); - shapeInfo.setHexahedron(corners.lbb, corners.lfb, corners.rfb, - corners.rbb, corners.lbt, corners.lft, - corners.rft, corners.rbt); + shapeInfo.setHexahedron(corners.lbb, corners.lfb, corners.rfb, corners.rbb, + corners.lbt, corners.lft, corners.rft, corners.rbt); } else if (pElem->tagName() == "sphere") { Element *pElemCentre = getOptionalShapeElement(pElem, "centre"); Element *pElemRadius = getShapeElement(pElem, "radius"); @@ -1452,8 +1451,8 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, V3D normVec = parsePosition(pElemAxis); normVec.normalize(); shapeInfo.setCylinder(parsePosition(pElemCentre), normVec, - std::stod(pElemRadius->getAttribute("val")), - std::stod(pElemHeight->getAttribute("val"))); + std::stod(pElemRadius->getAttribute("val")), + std::stod(pElemHeight->getAttribute("val"))); } else if (pElem->tagName() == "segmented-cylinder") { Element *pElemCentre = getShapeElement(pElem, "centre-of-bottom-base"); Element *pElemAxis = getShapeElement(pElem, "axis"); @@ -1461,10 +1460,9 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, Element *pElemHeight = getShapeElement(pElem, "height"); V3D normVec = parsePosition(pElemAxis); normVec.normalize(); - shapeInfo.setSegmentedCylinder( - parsePosition(pElemCentre), normVec, - std::stod(pElemRadius->getAttribute("val")), - std::stod(pElemHeight->getAttribute("val"))); + shapeInfo.setSegmentedCylinder(parsePosition(pElemCentre), normVec, + std::stod(pElemRadius->getAttribute("val")), + std::stod(pElemHeight->getAttribute("val"))); } else if (pElem->tagName() == "cone") { Element *pElemTipPoint = getShapeElement(pElem, "tip-point"); Element *pElemAxis = getShapeElement(pElem, "axis"); diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp index 9aa50d6d9a1c..046151fb576f 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp @@ -132,7 +132,7 @@ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle, for (int i = 0; i < points.size(); i++) { buf >> points[i]; } - } + } // Read from binary otherwise } From b5a870a20265280f85d7e35f84425aa41092272c Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 1 Dec 2017 08:08:56 +0000 Subject: [PATCH 019/364] boost::optional fix #21248 --- .../Rendering/GeometryHandler.h | 11 +++++---- .../src/Rendering/GeometryHandler.cpp | 24 +++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 514f5d2fcc6f..fd7be039c8c9 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -2,10 +2,10 @@ #define GEOMETRYHANDLER_H #include "MantidGeometry/DllConfig.h" -#include "MantidGeometry/Rendering/Renderer.h" #include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidKernel/Logger.h" #include "MantidKernel/V3D.h" +#include #include namespace Mantid { @@ -16,6 +16,7 @@ class ObjComponent; class CSGObject; namespace detail { class Renderer; +class GeometryTriangulator; } /** @@ -51,9 +52,9 @@ class MANTID_GEOMETRY_DLL GeometryHandler { static Kernel::Logger &PLog; ///< The official logger protected: - std::unique_ptr m_renderer = nullptr; - std::shared_ptr m_shapeInfo = nullptr; - std::unique_ptr m_triangulator = nullptr; + std::unique_ptr m_renderer; + std::shared_ptr m_shapeInfo; + std::unique_ptr m_triangulator; RectangularDetector *m_rectDet = nullptr; StructuredDetector *m_structDet = nullptr; IObjComponent *m_objComp = @@ -65,7 +66,7 @@ class MANTID_GEOMETRY_DLL GeometryHandler { GeometryHandler(CSGObject *obj); ///< Constructor GeometryHandler(RectangularDetector *comp); GeometryHandler(StructuredDetector *comp); - GeometryHandler(const GeometryHandler &renderer); + GeometryHandler(const GeometryHandler &handler); boost::shared_ptr clone() const; ~GeometryHandler(); void render(); ///< Render Object or ObjComponent diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 547eab09373e..e636a3e83a98 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -25,21 +25,21 @@ GeometryHandler::GeometryHandler(RectangularDetector *comp) GeometryHandler::GeometryHandler(StructuredDetector *comp) : m_structDet(comp), m_renderer(new detail::Renderer()) {} -GeometryHandler::GeometryHandler(const GeometryHandler &renderer) +GeometryHandler::GeometryHandler(const GeometryHandler &handler) : m_renderer(new detail::Renderer()) { - if (renderer.m_obj) { - m_obj = renderer.m_obj; - if (renderer.m_triangulator) + if (handler.m_obj) { + m_obj = handler.m_obj; + if (handler.m_triangulator) m_triangulator.reset(new detail::GeometryTriangulator(m_obj)); } - if (renderer.m_objComp) - m_objComp = renderer.m_objComp; - if (renderer.m_shapeInfo) - m_shapeInfo = renderer.m_shapeInfo; - if (renderer.m_structDet) - m_structDet = renderer.m_structDet; - if (renderer.m_rectDet) - m_rectDet = renderer.m_rectDet; + if (handler.m_objComp) + m_objComp = handler.m_objComp; + if (handler.m_shapeInfo) + m_shapeInfo = handler.m_shapeInfo; + if (handler.m_structDet) + m_structDet = handler.m_structDet; + if (handler.m_rectDet) + m_rectDet = handler.m_rectDet; } boost::shared_ptr GeometryHandler::clone() const { From f2d73d7a796ee24aee9d3e0d5431d0bb99682af6 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 1 Dec 2017 09:28:15 +0000 Subject: [PATCH 020/364] unix platform fixes #21248 --- .../Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h | 2 ++ Framework/Geometry/src/Objects/CSGObject.cpp | 6 +++--- Framework/Geometry/src/Rendering/Renderer.cpp | 4 +++- Framework/Geometry/src/Rendering/ShapeInfo.cpp | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index fd7be039c8c9..2b514633dc11 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -5,7 +5,9 @@ #include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidKernel/Logger.h" #include "MantidKernel/V3D.h" +#include #include +#include #include namespace Mantid { diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index ce33b073e4f8..6cc5f8a58487 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -1037,7 +1037,7 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const { const auto &vertices = this->getTriangleVertices().get(); const auto &faces = this->getTriangleFaces().get(); double sangle(0.0), sneg(0.0); - for (int i = 0; i < nTri; i++) { + for (size_t i = 0; i < nTri; i++) { int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2]; V3D vp1 = V3D(vertices[3 * p1], vertices[3 * p1 + 1], vertices[3 * p1 + 2]); @@ -1118,7 +1118,7 @@ double CSGObject::triangleSolidAngle(const V3D &observer, const auto &vertices = this->getTriangleVertices().get(); const auto &faces = this->getTriangleFaces().get(); double sangle(0.0), sneg(0.0); - for (int i = 0; i < nTri; i++) { + for (size_t i = 0; i < nTri; i++) { int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2]; // would be more efficient to pre-multiply the vertices (copy of) by these // factors beforehand @@ -1719,7 +1719,7 @@ void CSGObject::calcBoundingBoxByVertices() { maxX = maxY = maxZ = -huge; // Loop over all vertices and determine minima and maxima on each axis - for (int i = 0; i < vertCount; ++i) { + for (size_t i = 0; i < vertCount; ++i) { auto vx = vertArray[3 * i + 0]; auto vy = vertArray[3 * i + 1]; auto vz = vertArray[3 * i + 2]; diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index 348039e8397f..f2f851f5d7a8 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -90,6 +90,8 @@ void Renderer::renderShape(const ShapeInfo &shapeInfo) const { case ShapeInfo::GeometryShape::SEGMENTED_CYLINDER: doRenderCylinder(shapeInfo); break; + default: + return; } } @@ -278,7 +280,7 @@ void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { const auto &points = triangulator.getTriangleVertices(); glBegin(GL_TRIANGLES); V3D normal; - for (int i = 0; i < triangulator.numTriangleFaces(); i++) { + for (size_t i = 0; i < triangulator.numTriangleFaces(); i++) { int index1 = faces[i * 3] * 3; int index2 = faces[i * 3 + 1] * 3; int index3 = faces[i * 3 + 2] * 3; diff --git a/Framework/Geometry/src/Rendering/ShapeInfo.cpp b/Framework/Geometry/src/Rendering/ShapeInfo.cpp index d9b625580622..099263b81a75 100644 --- a/Framework/Geometry/src/Rendering/ShapeInfo.cpp +++ b/Framework/Geometry/src/Rendering/ShapeInfo.cpp @@ -1,4 +1,5 @@ #include "MantidGeometry/Rendering/ShapeInfo.h" +#include "MantidKernel/V3D.h" namespace Mantid { using Kernel::V3D; From 19d957e5b55efc8991863cb788f959cdebf34ef3 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 1 Dec 2017 11:43:08 +0000 Subject: [PATCH 021/364] address llvm warnings #21248 --- .../inc/MantidGeometry/IObjComponent.h | 5 ----- .../Rendering/GeometryHandler.h | 5 +++-- Framework/Geometry/src/IObjComponent.cpp | 22 ------------------- .../src/Rendering/GeometryHandler.cpp | 18 +++++++-------- .../src/Rendering/GeometryTriangulator.cpp | 8 +++---- Framework/Geometry/src/Rendering/Renderer.cpp | 4 ++-- .../src/Rendering/vtkGeometryCacheReader.cpp | 8 +++---- .../src/Rendering/vtkGeometryCacheWriter.cpp | 2 +- 8 files changed, 23 insertions(+), 49 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h index 8cafbd21fb18..2115040ff9f1 100644 --- a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h +++ b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h @@ -104,11 +104,6 @@ class MANTID_GEOMETRY_DLL IObjComponent : public virtual IComponent { GeometryHandler *Handle() const { return handle; } protected: - /// Protected copy constructor - IObjComponent(const IObjComponent &); - /// Assignment operator - IObjComponent &operator=(const IObjComponent &); - /// Reset the current geometry handler void setGeometryHandler(GeometryHandler *h); diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 2b514633dc11..986b18bd77a9 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -71,8 +71,9 @@ class MANTID_GEOMETRY_DLL GeometryHandler { GeometryHandler(const GeometryHandler &handler); boost::shared_ptr clone() const; ~GeometryHandler(); - void render(); ///< Render Object or ObjComponent - void initialize(); ///< Prepare/Initialize Object/ObjComponent to be rendered + void render() const; ///< Render Object or ObjComponent + void + initialize() const; ///< Prepare/Initialize Object/ObjComponent to be rendered bool canTriangulate() const { return !(m_triangulator == nullptr); } /// get the number of triangles size_t numberOfTriangles(); diff --git a/Framework/Geometry/src/IObjComponent.cpp b/Framework/Geometry/src/IObjComponent.cpp index 777957edcfa7..587e3dc07184 100644 --- a/Framework/Geometry/src/IObjComponent.cpp +++ b/Framework/Geometry/src/IObjComponent.cpp @@ -35,27 +35,5 @@ void IObjComponent::setGeometryHandler(GeometryHandler *h) { this->handle = h; } -/** - * Copy constructor - * @param origin :: The object to initialize this with - */ -IObjComponent::IObjComponent(const IObjComponent &origin) { - // Handler contains a pointer to 'this' therefore needs regenerating - // with new object - handle = new GeometryHandler(this); -} - -/** - * Assignment operator - * @param rhs The rvalue to copy into this object - * @returns A reference to this object - */ -IObjComponent &IObjComponent::operator=(const IObjComponent &rhs) { - if (&rhs != this) { - handle = new GeometryHandler(this); - } - return *this; -} - } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index e636a3e83a98..3dc8dddc6966 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -8,22 +8,22 @@ namespace Mantid { namespace Geometry { GeometryHandler::GeometryHandler(IObjComponent *comp) - : m_objComp(comp), m_renderer(new detail::Renderer()) {} + : m_renderer(new detail::Renderer()), m_objComp(comp) {} GeometryHandler::GeometryHandler(boost::shared_ptr obj) - : m_obj(obj.get()), + : m_renderer(new detail::Renderer()), m_triangulator(new detail::GeometryTriangulator(obj.get())), - m_renderer(new detail::Renderer()) {} + m_obj(obj.get()) {} GeometryHandler::GeometryHandler(CSGObject *obj) - : m_obj(obj), m_triangulator(new detail::GeometryTriangulator(obj)), - m_renderer(new detail::Renderer()) {} + : m_renderer(new detail::Renderer()), + m_triangulator(new detail::GeometryTriangulator(obj)), m_obj(obj) {} GeometryHandler::GeometryHandler(RectangularDetector *comp) - : m_rectDet(comp), m_renderer(new detail::Renderer()) {} + : m_renderer(new detail::Renderer()), m_rectDet(comp) {} GeometryHandler::GeometryHandler(StructuredDetector *comp) - : m_structDet(comp), m_renderer(new detail::Renderer()) {} + : m_renderer(new detail::Renderer()), m_structDet(comp) {} GeometryHandler::GeometryHandler(const GeometryHandler &handler) : m_renderer(new detail::Renderer()) { @@ -47,7 +47,7 @@ boost::shared_ptr GeometryHandler::clone() const { } GeometryHandler::~GeometryHandler() {} -void GeometryHandler::render() { +void GeometryHandler::render() const { if (m_rectDet) m_renderer->renderBitmap(*m_rectDet); else if (m_structDet) @@ -60,7 +60,7 @@ void GeometryHandler::render() { m_renderer->renderTriangulated(*m_triangulator); } -void GeometryHandler::initialize() { +void GeometryHandler::initialize() const { if (m_obj != nullptr) m_obj->updateGeometryHandler(); render(); diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index 3545750ad710..ff04f08b74ba 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -23,7 +23,7 @@ GCC_DIAG_OFF(conversion) // clang-format off -GCC_DIAG_OFF(cast - qual) +GCC_DIAG_OFF(cast-qual) // clang-format on #include #include @@ -39,7 +39,7 @@ GCC_DIAG_OFF(cast - qual) #include GCC_DIAG_ON(conversion) // clang-format off -GCC_DIAG_ON(cast - qual) +GCC_DIAG_ON(cast-qual) // clang-format on #ifdef __INTEL_COMPILER @@ -144,7 +144,7 @@ size_t GeometryTriangulator::numPoints() const { TopoDS_Face F = TopoDS::Face(Ex.Current()); TopLoc_Location L; Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - countVert += facing->NbNodes(); + countVert += static_cast(facing->NbNodes()); } } return countVert; @@ -158,7 +158,7 @@ size_t GeometryTriangulator::numFaces() const { TopoDS_Face F = TopoDS::Face(Ex.Current()); TopLoc_Location L; Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); - countFace += facing->NbTriangles(); + countFace += static_cast(facing->NbTriangles()); } } return countFace; diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index f2f851f5d7a8..5c9e70cbc0e2 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -27,7 +27,7 @@ GCC_DIAG_OFF(conversion) // clang-format off -GCC_DIAG_OFF(cast - qual) +GCC_DIAG_OFF(cast-qual) // clang-format on #include #include @@ -40,7 +40,7 @@ GCC_DIAG_OFF(cast - qual) #include GCC_DIAG_ON(conversion) // clang-format off -GCC_DIAG_ON(cast - qual) +GCC_DIAG_ON(cast-qual) // clang-format on #ifdef __INTEL_COMPILER diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp index 046151fb576f..9db17f667543 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp @@ -121,7 +121,7 @@ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle, } // Allocate memory points.resize(noOfPoints * 3); - if (points.size() != (noOfPoints * 3)) // Out of memory + if (points.size() != static_cast(noOfPoints * 3)) // Out of memory { g_log.error("Cannot allocate memory for triangle cache of Object "); return; @@ -129,7 +129,7 @@ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle, if (pEle->getAttribute("format") == "ascii") { // Read from Ascii std::stringstream buf; buf << pEle->innerText(); - for (int i = 0; i < points.size(); i++) { + for (size_t i = 0; i < points.size(); i++) { buf >> points[i]; } } @@ -148,7 +148,7 @@ void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle, } // Allocate memory faces.resize(noOfTriangles * 3); - if (faces.size() != (noOfTriangles * 3)) // Out of memory + if (faces.size() != static_cast(noOfTriangles * 3)) // Out of memory { g_log.error("Cannot allocate memory for triangle cache of Object "); return; @@ -156,7 +156,7 @@ void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle, if (pEle->getAttribute("format") == "ascii") { // Read from Ascii std::stringstream buf; buf << pEle->innerText(); - for (int i = 0; i < faces.size(); i++) { + for (size_t i = 0; i < faces.size(); i++) { buf >> faces[i]; } } diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp index 8fdf921233a3..b4712493d435 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp @@ -111,7 +111,7 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { buf.str(""); // get the triangles info const auto &points = handle->getTriangleVertices().get(); - int i; + size_t i; for (i = 0; i < points.size(); i++) { buf << points[i] << " "; } From bfeb3a763ee7de92375464a921bb86e8174b15ae Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 1 Dec 2017 11:47:04 +0000 Subject: [PATCH 022/364] clang format #21248 --- .../Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 986b18bd77a9..60f2df0f4d52 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -71,7 +71,7 @@ class MANTID_GEOMETRY_DLL GeometryHandler { GeometryHandler(const GeometryHandler &handler); boost::shared_ptr clone() const; ~GeometryHandler(); - void render() const; ///< Render Object or ObjComponent + void render() const; ///< Render Object or ObjComponent void initialize() const; ///< Prepare/Initialize Object/ObjComponent to be rendered bool canTriangulate() const { return !(m_triangulator == nullptr); } From 0448b9f7386ff88777b7b4781c260105f1f183a3 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 1 Dec 2017 13:17:33 +0000 Subject: [PATCH 023/364] replace IObjComponent copy constructors #21248 --- .../inc/MantidGeometry/IObjComponent.h | 5 +++++ Framework/Geometry/src/IObjComponent.cpp | 20 +++++++++++++++++++ .../src/Rendering/GeometryHandler.cpp | 3 ++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h index 2115040ff9f1..8cafbd21fb18 100644 --- a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h +++ b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h @@ -104,6 +104,11 @@ class MANTID_GEOMETRY_DLL IObjComponent : public virtual IComponent { GeometryHandler *Handle() const { return handle; } protected: + /// Protected copy constructor + IObjComponent(const IObjComponent &); + /// Assignment operator + IObjComponent &operator=(const IObjComponent &); + /// Reset the current geometry handler void setGeometryHandler(GeometryHandler *h); diff --git a/Framework/Geometry/src/IObjComponent.cpp b/Framework/Geometry/src/IObjComponent.cpp index 587e3dc07184..8ea7b46480f7 100644 --- a/Framework/Geometry/src/IObjComponent.cpp +++ b/Framework/Geometry/src/IObjComponent.cpp @@ -35,5 +35,25 @@ void IObjComponent::setGeometryHandler(GeometryHandler *h) { this->handle = h; } +/** + * Copy constructor + */ +IObjComponent::IObjComponent(const IObjComponent &) { + // Copy constructor just creates new handle. Copies nothing. + handle = new GeometryHandler(this); +} + +/** + * Assignment operator + * @param rhs The rvalue to copy into this object + * @returns A reference to this object + */ +IObjComponent &IObjComponent::operator=(const IObjComponent &rhs) { + if (&rhs != this) { + // Assignment operator copies nothing. Just creates new handle. + handle = new GeometryHandler(this); + } + return *this; +} } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 3dc8dddc6966..50aa30d00766 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -43,8 +43,9 @@ GeometryHandler::GeometryHandler(const GeometryHandler &handler) } boost::shared_ptr GeometryHandler::clone() const { - return boost::make_shared(GeometryHandler(*this)); + return boost::make_shared(*this); } + GeometryHandler::~GeometryHandler() {} void GeometryHandler::render() const { From d8ef2d6cefd4d1c44de2bf473784d768075a5460 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 4 Dec 2017 09:27:02 +0000 Subject: [PATCH 024/364] Fix geometry cache writing issue #21248 --- .../src/Rendering/GeometryTriangulator.cpp | 20 ++++++++++--------- Framework/Geometry/src/Rendering/Renderer.cpp | 5 +++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index ff04f08b74ba..373be18bc5af 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -3,6 +3,7 @@ #include "MantidGeometry/Objects/Rules.h" #include "MantidKernel/Logger.h" #include "MantidKernel/WarningSuppressions.h" +#include #ifdef ENABLE_OPENCASCADE // Squash a warning coming out of an OpenCascade header @@ -57,7 +58,7 @@ Kernel::Logger g_log("GeometryTriangulator"); } // namespace GeometryTriangulator::GeometryTriangulator(const Object *obj) - : m_isTriangulated(false) { + : m_isTriangulated(false), m_nFaces(0), m_nPoints(0) { m_obj = obj; #ifdef ENABLE_OPENCASCADE m_objSurface = nullptr; @@ -121,14 +122,15 @@ void GeometryTriangulator::OCAnalyzeObject() { if (top == nullptr) { m_objSurface.reset(new TopoDS_Shape()); return; - } - // Traverse through Rule - TopoDS_Shape Result = const_cast(top)->analyze(); - try { - m_objSurface.reset(new TopoDS_Shape(Result)); - BRepMesh_IncrementalMesh(Result, 0.001); - } catch (StdFail_NotDone &) { - g_log.error("Cannot build the geometry. Check the geometry definition"); + } else { + // Traverse through Rule + TopoDS_Shape Result = const_cast(top)->analyze(); + try { + m_objSurface.reset(new TopoDS_Shape(Result)); + BRepMesh_IncrementalMesh(Result, 0.001); + } catch (StdFail_NotDone &) { + g_log.error("Cannot build the geometry. Check the geometry definition"); + } } } diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index 5c9e70cbc0e2..74b7aceaa040 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -1,5 +1,5 @@ #include "MantidGeometry/Rendering/Renderer.h" -#include "MantidGeometry/Instrument/ObjComponent.h" +#include "MantidGeometry/IObjComponent.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Instrument/StructuredDetector.h" #include "MantidGeometry/Rendering/GeometryTriangulator.h" @@ -9,6 +9,7 @@ #include "MantidGeometry/Surfaces/Sphere.h" #include "MantidKernel/Quat.h" #include "MantidKernel/WarningSuppressions.h" +#include #ifdef ENABLE_OPENCASCADE // Squash a warning coming out of an OpenCascade header @@ -302,7 +303,7 @@ void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { // Render OpenCascade Shape void Renderer::doRender(const TopoDS_Shape &ObjSurf) const { glBegin(GL_TRIANGLES); - if (ObjSurf.IsNull()) { + if (!ObjSurf.IsNull()) { TopExp_Explorer Ex; for (Ex.Init(ObjSurf, TopAbs_FACE); Ex.More(); Ex.Next()) { TopoDS_Face F = TopoDS::Face(Ex.Current()); From 328d8e50b30a27761c1a49e11f6d6f32964bce44 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 4 Dec 2017 13:01:28 +0000 Subject: [PATCH 025/364] osx implicit conversion issue #21248 --- Framework/Geometry/src/Rendering/GeometryTriangulator.cpp | 4 ++-- Framework/Geometry/src/Rendering/Renderer.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index 373be18bc5af..2df4e4da3438 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -169,7 +169,7 @@ size_t GeometryTriangulator::numFaces() const { void GeometryTriangulator::setupPoints() { m_nPoints = numPoints(); if (m_nPoints > 0) { - int index = 0; + size_t index = 0; m_points.resize(m_nPoints * 3); TopExp_Explorer Ex; for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { @@ -195,7 +195,7 @@ void GeometryTriangulator::setupFaces() { m_faces.resize(m_nFaces * 3); TopExp_Explorer Ex; int maxindex = 0; - int index = 0; + size_t index = 0; for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) { TopoDS_Face F = TopoDS::Face(Ex.Current()); TopLoc_Location L; diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index 74b7aceaa040..24d3955e87f3 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -282,9 +282,9 @@ void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { glBegin(GL_TRIANGLES); V3D normal; for (size_t i = 0; i < triangulator.numTriangleFaces(); i++) { - int index1 = faces[i * 3] * 3; - int index2 = faces[i * 3 + 1] * 3; - int index3 = faces[i * 3 + 2] * 3; + auto index2 = static_cast(faces[i * 3 + 1] * 3); + auto index3 = static_cast(faces[i * 3 + 2] * 3); + auto index1 = static_cast(faces[i * 3] * 3); // Calculate normal and normalize V3D v1(points[index1], points[index1 + 1], points[index1 + 2]); V3D v2(points[index2], points[index2 + 1], points[index2 + 2]); From 02d75875460c8b9a0ec5b462831c692aa70a338c Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 5 Dec 2017 10:38:26 +0000 Subject: [PATCH 026/364] remove segmented-cylinder #21248 --- .../inc/MantidGeometry/Rendering/ShapeInfo.h | 5 --- .../src/Instrument/ObjCompAssembly.cpp | 4 +- Framework/Geometry/src/Objects/CSGObject.cpp | 3 +- .../Geometry/src/Objects/ShapeFactory.cpp | 10 ----- Framework/Geometry/src/Rendering/Renderer.cpp | 5 +-- .../Geometry/src/Rendering/ShapeInfo.cpp | 9 +--- Framework/Geometry/test/ObjCompAssemblyTest.h | 37 --------------- .../Geometry/test/ParObjCompAssemblyTest.h | 45 ------------------- Framework/Geometry/test/ShapeInfoTest.h | 16 ------- 9 files changed, 6 insertions(+), 128 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h index c57df051e64b..5e352143c846 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h @@ -46,8 +46,6 @@ class MANTID_GEOMETRY_DLL ShapeInfo { SPHERE, ///< SPHERE CYLINDER, ///< CYLINDER CONE, ///< CONE - SEGMENTED_CYLINDER ///< Cylinder with 1 or more segments (along the axis). - /// Sizes of segments are important. }; private: @@ -83,9 +81,6 @@ class MANTID_GEOMETRY_DLL ShapeInfo { /// sets the geometry handler for a cone void setCone(const Kernel::V3D ¢er, const Kernel::V3D &axis, double radius, double height); - /// sets the geometry handler for a segmented cylinder - void setSegmentedCylinder(const Kernel::V3D ¢er, const Kernel::V3D &axis, - double radius, double height); bool operator==(const ShapeInfo &other); }; diff --git a/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp b/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp index 388deee136f8..3f4deaf8030b 100644 --- a/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp +++ b/Framework/Geometry/src/Instrument/ObjCompAssembly.cpp @@ -583,7 +583,7 @@ boost::shared_ptr ObjCompAssembly::createOutline() { // inverse the vz axis vz = vz * (-1); } - obj_str << ""; + obj_str << ""; obj_str << " ObjCompAssembly::createOutline() { << vz.Z() << "\" /> "; obj_str << ""; obj_str << ""; - obj_str << ""; + obj_str << ""; } if (!obj_str.str().empty()) { diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 6cc5f8a58487..4dfd120daf5a 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -1809,8 +1809,7 @@ void CSGObject::calcBoundingBoxByGeometry() { maxZ = std::max(maxZ, vector.Z()); } } break; - case detail::ShapeInfo::GeometryShape::CYLINDER: - case detail::ShapeInfo::GeometryShape::SEGMENTED_CYLINDER: { + case detail::ShapeInfo::GeometryShape::CYLINDER: { // Center-point of base and normalized axis based on IDF XML auto &base = vectors[0]; auto &axis = vectors[1]; diff --git a/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Framework/Geometry/src/Objects/ShapeFactory.cpp index e5cccd858ca6..8cb0466d41c3 100644 --- a/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -1453,16 +1453,6 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem, shapeInfo.setCylinder(parsePosition(pElemCentre), normVec, std::stod(pElemRadius->getAttribute("val")), std::stod(pElemHeight->getAttribute("val"))); - } else if (pElem->tagName() == "segmented-cylinder") { - Element *pElemCentre = getShapeElement(pElem, "centre-of-bottom-base"); - Element *pElemAxis = getShapeElement(pElem, "axis"); - Element *pElemRadius = getShapeElement(pElem, "radius"); - Element *pElemHeight = getShapeElement(pElem, "height"); - V3D normVec = parsePosition(pElemAxis); - normVec.normalize(); - shapeInfo.setSegmentedCylinder(parsePosition(pElemCentre), normVec, - std::stod(pElemRadius->getAttribute("val")), - std::stod(pElemHeight->getAttribute("val"))); } else if (pElem->tagName() == "cone") { Element *pElemTipPoint = getShapeElement(pElem, "tip-point"); Element *pElemAxis = getShapeElement(pElem, "axis"); diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index 24d3955e87f3..2d023c4083fd 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -88,7 +88,6 @@ void Renderer::renderShape(const ShapeInfo &shapeInfo) const { doRenderCone(shapeInfo); break; case ShapeInfo::GeometryShape::CYLINDER: - case ShapeInfo::GeometryShape::SEGMENTED_CYLINDER: doRenderCylinder(shapeInfo); break; default: @@ -249,10 +248,8 @@ void Renderer::doRenderCylinder(const ShapeInfo &shapeInfo) const { glMultMatrixd(mat); auto radius = shapeInfo.radius(); auto height = shapeInfo.height(); - bool segmented = - shapeInfo.shape() == ShapeInfo::GeometryShape::SEGMENTED_CYLINDER; gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, - segmented ? 1 : Cylinder::g_nstacks); + Cylinder::g_nstacks); gluQuadricTexture(qobj, false); gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); glTranslated(0.0, 0.0, height); diff --git a/Framework/Geometry/src/Rendering/ShapeInfo.cpp b/Framework/Geometry/src/Rendering/ShapeInfo.cpp index 099263b81a75..3d595d3fecc6 100644 --- a/Framework/Geometry/src/Rendering/ShapeInfo.cpp +++ b/Framework/Geometry/src/Rendering/ShapeInfo.cpp @@ -49,25 +49,20 @@ void ShapeInfo::setSphere(const V3D &c, double r) { m_radius = r; m_height = 0; } + void ShapeInfo::setCylinder(const V3D &c, const V3D &a, double r, double h) { m_shape = GeometryShape::CYLINDER; m_points.assign({c, a}); m_radius = r; m_height = h; } + void ShapeInfo::setCone(const V3D &c, const V3D &a, double r, double h) { m_shape = GeometryShape::CONE; m_points.assign({c, a}); m_radius = r; m_height = h; } -void ShapeInfo::setSegmentedCylinder(const V3D &c, const V3D &a, double r, - double h) { - m_shape = GeometryShape::SEGMENTED_CYLINDER; - m_points.assign({c, a}); - m_radius = r; - m_height = h; -} bool ShapeInfo::operator==(const ShapeInfo &other) { return m_shape == other.m_shape && m_height == other.m_height && diff --git a/Framework/Geometry/test/ObjCompAssemblyTest.h b/Framework/Geometry/test/ObjCompAssemblyTest.h index 30fda2960985..58924a84defb 100644 --- a/Framework/Geometry/test/ObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ObjCompAssemblyTest.h @@ -333,43 +333,6 @@ class ObjCompAssemblyTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(comp.type(), "ObjCompAssembly"); } - void testCreateOutlineCylinder() { - std::stringstream obj_str; - obj_str << ""; - obj_str << ""; - obj_str << " "; - obj_str << ""; - obj_str << ""; - obj_str << ""; - auto s = Mantid::Geometry::ShapeFactory().createShape(obj_str.str()); - - ObjCompAssembly bank("BankName"); - Component *det1 = new ObjComponent("Det1Name", s); - det1->setPos(V3D(0, -0.1, 0)); - Component *det2 = new ObjComponent("Det2Name", s); - det2->setPos(V3D(0, 0.1, 0)); - Component *det3 = new ObjComponent("Det3Name", s); - det3->setPos(V3D(0, 0.3, 0)); - - bank.add(det1); - bank.add(det2); - bank.add(det3); - - boost::shared_ptr shape = bank.createOutline(); - TS_ASSERT(shape); - - detail::ShapeInfo::GeometryShape otype; - std::vector vectors; - double radius, height; - shape->GetObjectGeom(otype, vectors, radius, height); - - TS_ASSERT_EQUALS(otype, - detail::ShapeInfo::GeometryShape::SEGMENTED_CYLINDER); - TS_ASSERT_EQUALS(radius, 0.1); - TS_ASSERT_EQUALS(height, 0.6); - } - void test_fail_CreateOutline_for_wrong_component_type() { std::stringstream obj_str; obj_str << ""; diff --git a/Framework/Geometry/test/ParObjCompAssemblyTest.h b/Framework/Geometry/test/ParObjCompAssemblyTest.h index 96af56c03f28..93fc41549ee9 100644 --- a/Framework/Geometry/test/ParObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ParObjCompAssemblyTest.h @@ -108,51 +108,6 @@ class ParObjCompAssemblyTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(pcomp.type(), "ObjCompAssembly"); } - void testCreateOutlineCylinder() { - std::stringstream obj_str; - obj_str << ""; - obj_str << ""; - obj_str << " "; - obj_str << ""; - obj_str << ""; - obj_str << ""; - boost::shared_ptr s = - Mantid::Geometry::ShapeFactory().createShape(obj_str.str()); - - ObjCompAssembly bank("BankName"); - Component *det1 = new ObjComponent("Det1Name", s); - det1->setPos(V3D(0, -0.1, 0)); - Component *det2 = new ObjComponent("Det2Name", s); - det2->setPos(V3D(0, 0.1, 0)); - Component *det3 = new ObjComponent("Det3Name", s); - det3->setPos(V3D(0, 0.3, 0)); - - bank.add(det1); - bank.add(det2); - bank.add(det3); - - boost::shared_ptr shape = bank.createOutline(); - TS_ASSERT(shape); - - detail::ShapeInfo::GeometryShape otype; - std::vector vectors; - double radius, height; - shape->GetObjectGeom(otype, vectors, radius, height); - - TS_ASSERT_EQUALS(otype, - detail::ShapeInfo::GeometryShape::SEGMENTED_CYLINDER); - TS_ASSERT_EQUALS(radius, 0.1); - TS_ASSERT_EQUALS(height, 0.6); - - ParameterMap_sptr pmap(new ParameterMap()); - boost::shared_ptr pcomp( - new ObjCompAssembly(&bank, pmap.get())); - boost::shared_ptr ic = - boost::dynamic_pointer_cast(pcomp); - boost::shared_ptr ica = - boost::dynamic_pointer_cast(ic); - } }; #endif diff --git a/Framework/Geometry/test/ShapeInfoTest.h b/Framework/Geometry/test/ShapeInfoTest.h index 610371b221d3..34f7029c25a4 100644 --- a/Framework/Geometry/test/ShapeInfoTest.h +++ b/Framework/Geometry/test/ShapeInfoTest.h @@ -94,22 +94,6 @@ class ShapeInfoTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(m_shapeInfo.points()[1], axis); } - void testSetSegmentedSphere() { - V3D center(0, 0, 0); - V3D axis(1, 0, 0); - double radius = 10; - double height = 5; - m_shapeInfo.setSegmentedCylinder(center, axis, radius, height); - - TS_ASSERT_EQUALS(m_shapeInfo.shape(), - ShapeInfo::GeometryShape::SEGMENTED_CYLINDER); - TS_ASSERT_EQUALS(m_shapeInfo.radius(), radius); - TS_ASSERT_EQUALS(m_shapeInfo.height(), height); - TS_ASSERT_EQUALS(m_shapeInfo.points().size(), 2); - TS_ASSERT_EQUALS(m_shapeInfo.points()[0], center); - TS_ASSERT_EQUALS(m_shapeInfo.points()[1], axis); - } - void testGetObjectGeometry() { V3D center(0, 0, 0); double radius = 10; From ad9ec1259374e0f9f03f8336d6765ed2b7c77bc3 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 5 Dec 2017 10:54:06 +0000 Subject: [PATCH 027/364] clang-format #21248 --- .../Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h | 10 +++++----- Framework/Geometry/test/ParObjCompAssemblyTest.h | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h index 5e352143c846..1a630e1bfecb 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h @@ -41,11 +41,11 @@ class MANTID_GEOMETRY_DLL ShapeInfo { public: enum class GeometryShape { NOSHAPE = 0, - CUBOID, ///< CUBOID - HEXAHEDRON, ///< HEXAHEDRON - SPHERE, ///< SPHERE - CYLINDER, ///< CYLINDER - CONE, ///< CONE + CUBOID, ///< CUBOID + HEXAHEDRON, ///< HEXAHEDRON + SPHERE, ///< SPHERE + CYLINDER, ///< CYLINDER + CONE, ///< CONE }; private: diff --git a/Framework/Geometry/test/ParObjCompAssemblyTest.h b/Framework/Geometry/test/ParObjCompAssemblyTest.h index 93fc41549ee9..3085c2b6f2e7 100644 --- a/Framework/Geometry/test/ParObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ParObjCompAssemblyTest.h @@ -107,7 +107,6 @@ class ParObjCompAssemblyTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(pcomp.type(), "ObjCompAssembly"); } - }; #endif From 3ccba3388ce250b9ae73b41c339a3afc566e8913 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 8 Dec 2017 07:19:30 +0000 Subject: [PATCH 028/364] Basic geometry rendering minus unwrapped #21339 --- .../MantidGeometry/Instrument/ComponentInfo.h | 2 +- .../Geometry/src/Instrument/ComponentInfo.cpp | 2 +- MantidPlot/src/Mantid/MantidUI.cpp | 6 + .../MantidQtWidgets/InstrumentView/GLColor.h | 2 +- .../InstrumentView/InstrumentActor.h | 37 +- .../InstrumentWidgetRenderTab.h | 2 + .../InstrumentView/PanelsSurface.h | 5 +- qt/widgets/instrumentview/src/GLColor.cpp | 4 +- .../instrumentview/src/InstrumentActor.cpp | 653 +++++++++++------- .../src/InstrumentWidgetRenderTab.cpp | 19 +- .../instrumentview/src/PanelsSurface.cpp | 153 +++- 11 files changed, 598 insertions(+), 287 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index 81ea8c9367e2..e1d80f18e481 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -131,7 +131,7 @@ class MANTID_GEOMETRY_DLL ComponentInfo { const std::string &name(const size_t componentIndex) const; void setScaleFactor(const size_t componentIndex, const Kernel::V3D &scaleFactor); - size_t root(); + size_t root() const; const IComponent *componentID(const size_t componentIndex) const { return m_componentIds->operator[](componentIndex); diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index e5692787af46..69a76c1d4b19 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -193,7 +193,7 @@ size_t ComponentInfo::sample() const { return m_componentInfo->sample(); } double ComponentInfo::l1() const { return m_componentInfo->l1(); } -size_t ComponentInfo::root() { return m_componentInfo->root(); } +size_t ComponentInfo::root() const { return m_componentInfo->root(); } void ComponentInfo::setPosition(const size_t componentIndex, const Kernel::V3D &newPosition) { diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index 1d5dfe006447..77e3f6fc77dd 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -97,6 +97,7 @@ #include "MantidQtWidgets/SpectrumViewer/SpectrumView.h" #include +#include using namespace std; @@ -2171,9 +2172,14 @@ void MantidUI::showMantidInstrument() { } void MantidUI::showMantidInstrumentSelected() { + auto start = std::chrono::system_clock::now(); QString wsName = getSelectedWorkspaceName(); if (!wsName.isEmpty()) showMantidInstrument(wsName); + auto end = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = end - start; + g_log.information() << "Show instrument lasted: " << elapsed_seconds.count() + << " seconds." << std::endl; } void MantidUI::mantidMenuAboutToShow() { diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h index 5cda5822dd6a..6ea19cc70dbc 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLColor.h @@ -41,7 +41,7 @@ class GLColor { public: /// Default Constructor GLColor(float red = 0, float green = 0, float blue = 0, float alpha = 1.0f); - GLColor(int r, int g, int b); + GLColor(int r, int g, int b, int a = 255); /// Destructor virtual ~GLColor(); diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index a68f04d17423..f400e4685d26 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -8,13 +8,11 @@ #include "GLColor.h" #include "MantidAPI/MatrixWorkspace_fwd.h" #include "MantidAPI/SpectraDetectorTypes.h" -#include "MantidGeometry/IObjComponent.h" #include "MantidQtWidgets/LegacyQwt/MantidColorMap.h" #include "MaskBinsData.h" #include "SampleActor.h" #include -#include #include //------------------------------------------------------------------ @@ -29,6 +27,8 @@ namespace Geometry { class IObjComponent; class Instrument; class IDetector; +class ComponentInfo; +class DetectorInfo; } } @@ -62,9 +62,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { void draw(bool picking = false) const override; /// Return the bounding box in 3D void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override { - m_scene.getBoundingBox(minBound, maxBound); - } + Mantid::Kernel::V3D &maxBound) const override; /// Run visitors callback on each component bool accept(GLActorVisitor &visitor, VisitorAcceptRule rule = VisitAll) override; @@ -79,6 +77,8 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { boost::shared_ptr getInstrument() const; /// Get the associated data workspace boost::shared_ptr getWorkspace() const; + const Mantid::Geometry::ComponentInfo &getComponentInfo() const; + const Mantid::Geometry::DetectorInfo &getDetectorInfo() const; /// Get the mask displayed but not yet applied as a MatrxWorkspace boost::shared_ptr getMaskMatrixWorkspace() const; @@ -114,6 +114,8 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { /// Get colormap scale autoscaling status. bool autoscaling() const { return m_autoscaling; } + void showVolumeRender(bool on); + /// Set the integration range. void setIntegrationRange(const double &xmin, const double &xmax); /// Get the minimum data value on the color map scale. @@ -137,7 +139,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { bool wholeRange() const; /// Get the number of detectors in the instrument. - size_t ndetectors() const { return m_detIDs.size(); } + size_t ndetectors() const;// { return m_detIDs.size(); } /// Get a reference to a detector by a pick ID converted form a color in /// the pick image. const Mantid::Geometry::IDetector &getDetectorByPickID(size_t pickID) const; @@ -152,9 +154,9 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { void cacheDetPos() const; /// Get position of a detector by a pick ID converted form a color in the pick /// image. - const Mantid::Kernel::V3D &getDetPos(size_t pickID) const; + const Mantid::Kernel::V3D getDetPos(size_t pickID) const; /// Get a vector of IDs of all detectors in the instrument. - const std::vector &getAllDetIDs() const { return m_detIDs; } + const std::vector &getAllDetIDs() const; /// Get displayed color of a detector by its detector ID. GLColor getColor(Mantid::detid_t id) const; /// Get the workspace index of a detector by its detector ID. @@ -172,7 +174,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { void updateColors(); /// Invalidate the OpenGL display lists to force full re-drawing of the /// instrument and creation of new lists. - void invalidateDisplayLists() const { m_scene.invalidateDisplayList(); } + void invalidateDisplayLists() const; //{ m_scene.invalidateDisplayList(); } /// Toggle display of the guide and other non-detector instrument components void showGuides(bool); /// Get the guide visibility status @@ -204,6 +206,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { void colorMapChanged(); private: + void doDraw(bool picking) const; void setUpWorkspace( boost::shared_ptr sharedWorkspace, double scaleMin, double scaleMax); @@ -225,7 +228,8 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { size_t pushBackDetid(Mantid::detid_t) const; void pushBackNonDetid(ObjComponentActor *actor, Mantid::Geometry::ComponentID compID) const; - void setupPickColors(); + void setupColors();//TODO: Rename to setupPickColors + void setupPickColors();//TODO: Remove boost::shared_ptr getMaskWorkspaceIfExists() const; @@ -258,6 +262,8 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { bool m_autoscaling; /// Flag to show the guide and other components. Loaded and saved in settings. bool m_showGuides; + /// Flag to enable intensity based transparency. + bool m_volumeRender; /// Color map scale type: linear or log GraphOptions::ScaleType m_scaleType; @@ -281,16 +287,23 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { /// Position to refer to when detector not found const Mantid::Kernel::V3D m_defaultPos; - /// Colors in order of workspace indexes + /// Colors in order of component info mutable std::vector m_colors; /// Colour of a masked detector GLColor m_maskedColor; /// Colour of a "failed" detector GLColor m_failedColor; /// The collection of actors for the instrument components - GLActorCollection m_scene; + //GLActorCollection m_scene; static double m_tolerance; + + std::vector m_pickColors; + std::vector m_isCompVisible; + + //Two display lists for normal rendering and picking + mutable GLuint m_displayListId[2]; + mutable bool m_useDisplayList[2]; friend class ObjComponentActor; friend class ObjCompAssemblyActor; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h index 9b2f1debf9ef..7d55f262f0e5 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h @@ -57,6 +57,7 @@ public slots: void setMaxValue(double value, bool apply = true); void setRange(double minValue, double maxValue, bool apply = true); void showAxes(bool on); + void showVolumeRender(bool on); void displayDetectorsOnly(bool yes); void enableGL(bool on); void setColorMapAutoscaling(bool); @@ -113,6 +114,7 @@ private slots: QAction *m_displayDetectorsOnly; QAction *m_wireframe; QAction *m_lighting; + QAction *m_volumeRender; QAction *m_GLView; ///< toggle between OpenGL and simple view QAction *m_UCorrection; QActionGroup *m_precisionActionGroup; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h index b397935ac3cd..4407a5677b7b 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h @@ -59,10 +59,6 @@ class PanelsSurface : public UnwrappedSurface { // Setup the projection axes void setupAxes(); - // Setup the projection axes - void setupBasisAxes(const Mantid::Kernel::V3D &zaxis, - Mantid::Kernel::V3D &xaxis, - Mantid::Kernel::V3D &yaxis) const; // Find all flat banks of detectors. void findFlatBanks(); // Add a flat bank @@ -82,6 +78,7 @@ class PanelsSurface : public UnwrappedSurface { // Add a structured detector void addStructuredDetector(Mantid::Geometry::ComponentID bankId); // Calculate bank rotation + void constructFromComponentInfo(); Mantid::Kernel::Quat calcBankRotation(const Mantid::Kernel::V3D &detPos, Mantid::Kernel::V3D normal) const; // Add a detector from an assembly diff --git a/qt/widgets/instrumentview/src/GLColor.cpp b/qt/widgets/instrumentview/src/GLColor.cpp index 37b30138a1ae..7a31a62fa863 100644 --- a/qt/widgets/instrumentview/src/GLColor.cpp +++ b/qt/widgets/instrumentview/src/GLColor.cpp @@ -24,11 +24,11 @@ GLColor::GLColor(float red, float green, float blue, float alpha) { m_rgba[3] = (unsigned char)(alpha * 255); } -GLColor::GLColor(int r, int g, int b) { +GLColor::GLColor(int r, int g, int b, int a) { m_rgba[0] = (unsigned char)r; m_rgba[1] = (unsigned char)g; m_rgba[2] = (unsigned char)b; - m_rgba[3] = 255; + m_rgba[3] = (unsigned char)a; } /** diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 633e33f7c1ce..8f4cb7fa77d3 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -7,6 +7,7 @@ #include "MantidQtWidgets/InstrumentView/ObjComponentActor.h" #include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h" #include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h" +#include "MantidQtWidgets/InstrumentView/OpenGLError.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/CommonBinsValidator.h" @@ -15,9 +16,11 @@ #include "MantidAPI/IMaskWorkspace.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/SpectrumInfo.h" +#include "MantidTypes/SpectrumDefinition.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidGeometry/Instrument.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidKernel/ConfigService.h" @@ -49,34 +52,45 @@ struct Sqrt { double InstrumentActor::m_tolerance = 0.00001; /** -* Constructor. Creates a tree of GLActors. Each actor is responsible for -* displaying insrument components in 3D. -* Some of the components have "pick ID" assigned to them. Pick IDs can be -* uniquely converted to a RGB colour value -* which in turn can be used for picking the component from the screen. -* @param wsName :: Workspace name -* @param autoscaling :: True to start with autoscaling option on. If on the min -* and max of -* the colormap scale are defined by the min and max of the data. -* @param scaleMin :: Minimum value of the colormap scale. Used to assign -* detector colours. Ignored if autoscaling == true. -* @param scaleMax :: Maximum value of the colormap scale. Used to assign -* detector colours. Ignored if autoscaling == true. -*/ + * Constructor. Creates a tree of GLActors. Each actor is responsible for + * displaying insrument components in 3D. + * Some of the components have "pick ID" assigned to them. Pick IDs can be + * uniquely converted to a RGB colour value + * which in turn can be used for picking the component from the screen. + * @param wsName :: Workspace name + * @param autoscaling :: True to start with autoscaling option on. If on the min + * and max of + * the colormap scale are defined by the min and max of the data. + * @param scaleMin :: Minimum value of the colormap scale. Used to assign + * detector colours. Ignored if autoscaling == true. + * @param scaleMax :: Maximum value of the colormap scale. Used to assign + * detector colours. Ignored if autoscaling == true. + */ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, double scaleMin, double scaleMax) : m_workspace(AnalysisDataService::Instance().retrieveWS( wsName.toStdString())), - m_ragged(true), m_autoscaling(autoscaling), m_defaultPos(), - m_maskedColor(100, 100, 100), m_failedColor(200, 200, 200) { + m_ragged(true), m_autoscaling(autoscaling), m_volumeRender(false), + m_defaultPos(), m_maskedColor(100, 100, 100), + m_failedColor(200, 200, 200) { // settings loadSettings(); auto sharedWorkspace = m_workspace.lock(); + if (!sharedWorkspace) throw std::logic_error( "InstrumentActor passed a workspace that isn't a MatrixWorkspace"); + const auto &componentInfo = sharedWorkspace->componentInfo(); + const auto &detectorInfo = sharedWorkspace->detectorInfo(); + + m_isCompVisible.assign(componentInfo.size(), true); + m_pickColors.resize(componentInfo.size()); + + for (size_t i = 0; i < componentInfo.size(); ++i) + m_pickColors[i] = makePickColor(i); + // set up the color map if (!m_currentColorMapFilename.isEmpty()) { loadColorMap(m_currentColorMapFilename, false); @@ -90,8 +104,9 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, // If the instrument is empty, maybe only having the sample and source const int nelements = instrument->nelements(); - if ((nelements == 0) || (nelements == 1 && (instrument->getSource() || - instrument->getSample())) || + if ((nelements == 0) || + (nelements == 1 && + (instrument->getSource() || instrument->getSample())) || (nelements == 2 && instrument->getSource() && instrument->getSample())) { QMessageBox::warning(nullptr, "MantidPlot - Warning", "This instrument appears to contain no detectors", @@ -100,28 +115,42 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, // this adds actors for all instrument components to the scene and fills in // m_detIDs - m_scene.addActor(new CompAssemblyActor(*this, instrument->getComponentID())); - setupPickColors(); + // m_scene.addActor(new CompAssemblyActor(*this, + // instrument->getComponentID())); setupPickColors(); if (!m_showGuides) { // hide guide and other components showGuides(m_showGuides); } + + m_displayListId[0] = 0; + m_displayListId[1] = 0; + m_useDisplayList[0] = false; + m_useDisplayList[1] = false; } /** -* Destructor -*/ -InstrumentActor::~InstrumentActor() { saveSettings(); } + * Destructor + */ +InstrumentActor::~InstrumentActor() +{ + for (size_t i = 0; i < 2; ++i) { + if (m_displayListId[i] != 0) { + glDeleteLists(m_displayListId[i], 1); + } + } + + saveSettings(); +} /** -* Set up the workspace: calculate the value ranges, set the colours. -* @param sharedWorkspace :: A shared pointer to the workspace. -* @param scaleMin :: Minimum limit on the color map axis. If autoscale this -* value is ignored. -* @param scaleMax :: Maximum limit on the color map axis. If autoscale this -* value is ignored. -*/ + * Set up the workspace: calculate the value ranges, set the colours. + * @param sharedWorkspace :: A shared pointer to the workspace. + * @param scaleMin :: Minimum limit on the color map axis. If autoscale this + * value is ignored. + * @param scaleMax :: Maximum limit on the color map axis. If autoscale this + * value is ignored. + */ void InstrumentActor::setUpWorkspace( boost::shared_ptr sharedWorkspace, double scaleMin, double scaleMax) { @@ -171,13 +200,13 @@ void InstrumentActor::setUpWorkspace( } /** Used to set visibility of an actor corresponding to a particular component -* When selecting a component in the InstrumentTreeWidget -* -* @param visitor :: Visitor to be accepted bu this actor. -* @param rule :: A rule defining visitor acceptance by assembly actors. -*/ + * When selecting a component in the InstrumentTreeWidget + * + * @param visitor :: Visitor to be accepted bu this actor. + * @param rule :: A rule defining visitor acceptance by assembly actors. + */ bool InstrumentActor::accept(GLActorVisitor &visitor, VisitorAcceptRule rule) { - bool ok = m_scene.accept(visitor, rule); + bool ok = true; // m_scene.accept(visitor, rule); visitor.visit(this); invalidateDisplayLists(); return ok; @@ -185,25 +214,25 @@ bool InstrumentActor::accept(GLActorVisitor &visitor, VisitorAcceptRule rule) { bool InstrumentActor::accept(GLActorConstVisitor &visitor, GLActor::VisitorAcceptRule rule) const { - bool ok = m_scene.accept(visitor, rule); + bool ok = true; // m_scene.accept(visitor, rule); visitor.visit(this); return ok; } void InstrumentActor::setChildVisibility(bool on) { - m_scene.setChildVisibility(on); - auto guidesVisitor = SetVisibleNonDetectorVisitor(m_showGuides); - m_scene.accept(guidesVisitor); + // m_scene.setChildVisibility(on); + // auto guidesVisitor = SetVisibleNonDetectorVisitor(m_showGuides); + // m_scene.accept(guidesVisitor); } bool InstrumentActor::hasChildVisible() const { - return m_scene.hasChildVisible(); + return true; // m_scene.hasChildVisible(); } /** Returns the workspace relating to this instrument view. -* !!!! DON'T USE THIS TO GET HOLD OF THE INSTRUMENT !!!! -* !!!! USE InstrumentActor::getInstrument() BELOW !!!! -*/ + * !!!! DON'T USE THIS TO GET HOLD OF THE INSTRUMENT !!!! + * !!!! USE InstrumentActor::getInstrument() BELOW !!!! + */ MatrixWorkspace_const_sptr InstrumentActor::getWorkspace() const { auto sharedWorkspace = m_workspace.lock(); @@ -214,9 +243,17 @@ MatrixWorkspace_const_sptr InstrumentActor::getWorkspace() const { return sharedWorkspace; } +void InstrumentActor::getBoundingBox(Mantid::Kernel::V3D &minBound, + Mantid::Kernel::V3D &maxBound) const { + const auto &componentInfo = getComponentInfo(); + auto bb = componentInfo.boundingBox(componentInfo.root()); + minBound = bb.minPoint(); + maxBound = bb.maxPoint(); +} + /** Returns the mask workspace relating to this instrument view as a * MatrixWorkspace -*/ + */ MatrixWorkspace_sptr InstrumentActor::getMaskMatrixWorkspace() const { if (!m_maskWorkspace) { initMaskHelper(); @@ -225,7 +262,7 @@ MatrixWorkspace_sptr InstrumentActor::getMaskMatrixWorkspace() const { } /** set the mask workspace -*/ + */ void InstrumentActor::setMaskMatrixWorkspace( MatrixWorkspace_sptr wsMask) const { m_maskWorkspace = wsMask; @@ -252,10 +289,10 @@ void InstrumentActor::invertMaskWorkspace() const { } /** -* Returns the mask workspace relating to this instrument view as a -* IMaskWorkspace. -* Guarantees to return a valid pointer -*/ + * Returns the mask workspace relating to this instrument view as a + * IMaskWorkspace. + * Guarantees to return a valid pointer + */ IMaskWorkspace_sptr InstrumentActor::getMaskWorkspace() const { if (!m_maskWorkspace) { initMaskHelper(); @@ -264,10 +301,10 @@ IMaskWorkspace_sptr InstrumentActor::getMaskWorkspace() const { } /** -* Returns the mask workspace relating to this instrument view as a -* IMaskWorkspace -* if it exists or empty pointer if it doesn't. -*/ + * Returns the mask workspace relating to this instrument view as a + * IMaskWorkspace + * if it exists or empty pointer if it doesn't. + */ IMaskWorkspace_sptr InstrumentActor::getMaskWorkspaceIfExists() const { if (!m_maskWorkspace) return IMaskWorkspace_sptr(); @@ -275,8 +312,8 @@ IMaskWorkspace_sptr InstrumentActor::getMaskWorkspaceIfExists() const { } /** -* Apply mask stored in the helper mask workspace to the data workspace. -*/ + * Apply mask stored in the helper mask workspace to the data workspace. + */ void InstrumentActor::applyMaskWorkspace() { auto wsName = getWorkspace()->getName(); if (m_maskWorkspace) { @@ -304,8 +341,8 @@ void InstrumentActor::applyMaskWorkspace() { } /** -* Removes the mask workspace. -*/ + * Removes the mask workspace. + */ void InstrumentActor::clearMasks() { bool needColorRecalc = false; if (m_maskWorkspace) { @@ -357,30 +394,32 @@ const MantidColorMap &InstrumentActor::getColorMap() const { /// Get a detector reference given a pick ID. const Mantid::Geometry::IDetector & InstrumentActor::getDetectorByPickID(size_t pickID) const { - return getDetectorByDetID(m_detIDs.at(pickID)); + const auto &detectorInfo = getDetectorInfo(); + return detectorInfo.detector(pickID); } /// Get a reference to a detector by a detector ID. const Mantid::Geometry::IDetector & InstrumentActor::getDetectorByDetID(Mantid::detid_t detID) const { - const auto &detectorInfo = getWorkspace()->detectorInfo(); + const auto &detectorInfo = getDetectorInfo(); auto detectorIndex = detectorInfo.indexOf(detID); return detectorInfo.detector(detectorIndex); } Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const { - if (pickID < m_detIDs.size()) { - return m_detIDs[pickID]; + const auto &detInfo = getDetectorInfo(); + if (pickID < detInfo.size()) { + return detInfo.detectorIDs()[pickID]; } return -1; } /** -* Get a component id of a picked component. -*/ + * Get a component id of a picked component. + */ Mantid::Geometry::ComponentID InstrumentActor::getComponentID(size_t pickID) const { - size_t ndet = m_detIDs.size(); + /*size_t ndet = m_detIDs.size(); auto compID = Mantid::Geometry::ComponentID(); if (pickID < ndet) { auto &det = getDetectorByPickID(m_detIDs[pickID]); @@ -388,15 +427,17 @@ InstrumentActor::getComponentID(size_t pickID) const { } else if (pickID < ndet + m_nonDetIDs.size()) { compID = m_nonDetIDs[pickID - ndet]; } - return compID; + return compID;*/ + const auto &componentInfo = getComponentInfo(); + return componentInfo.componentID(pickID)->getComponentID(); } /** Retrieve the workspace index corresponding to a particular detector -* @param id The detector id -* @returns The workspace index containing data for this detector -* @throws Exception::NotFoundError If the detector is not represented in the -* workspace -*/ + * @param id The detector id + * @returns The workspace index containing data for this detector + * @throws Exception::NotFoundError If the detector is not represented in the + * workspace + */ size_t InstrumentActor::getWorkspaceIndex(Mantid::detid_t id) const { auto mapEntry = m_detid2index_map.find(id); if (mapEntry == m_detid2index_map.end()) { @@ -407,13 +448,13 @@ size_t InstrumentActor::getWorkspaceIndex(Mantid::detid_t id) const { } /** -* Set an interval in the data workspace x-vector's units in which the data are -* to be -* integrated to calculate the detector colours. -* -* @param xmin :: The lower bound. -* @param xmax :: The upper bound. -*/ + * Set an interval in the data workspace x-vector's units in which the data are + * to be + * integrated to calculate the detector colours. + * + * @param xmin :: The lower bound. + * @param xmax :: The upper bound. + */ void InstrumentActor::setIntegrationRange(const double &xmin, const double &xmax) { setDataIntegrationRange(xmin, xmax); @@ -421,9 +462,10 @@ void InstrumentActor::setIntegrationRange(const double &xmin, } /** Gives the total signal in the spectrum relating to the given detector -* @param id The detector id -* @return The signal, or -1 if the detector is not represented in the workspace -*/ + * @param id The detector id + * @return The signal, or -1 if the detector is not represented in the + * workspace + */ double InstrumentActor::getIntegratedCounts(Mantid::detid_t id) const { try { size_t i = getWorkspaceIndex(id); @@ -435,19 +477,19 @@ double InstrumentActor::getIntegratedCounts(Mantid::detid_t id) const { } /** -* Sum counts in detectors for purposes of rough plotting against the units on -* the x-axis. -* Checks (approximately) if the workspace is ragged or not and uses the -* appropriate summation -* method. -* -* @param dets :: A list of detector IDs to sum. -* @param x :: (output) Time of flight values (or whatever values the x axis has) -* to plot against. -* @param y :: (output) The sums of the counts for each bin. -* @param size :: (optional input) Size of the output vectors. If not given it -* will be determined automatically. -*/ + * Sum counts in detectors for purposes of rough plotting against the units on + * the x-axis. + * Checks (approximately) if the workspace is ragged or not and uses the + * appropriate summation + * method. + * + * @param dets :: A list of detector IDs to sum. + * @param x :: (output) Time of flight values (or whatever values the x axis + * has) to plot against. + * @param y :: (output) The sums of the counts for each bin. + * @param size :: (optional input) Size of the output vectors. If not given it + * will be determined automatically. + */ void InstrumentActor::sumDetectors(QList &dets, std::vector &x, std::vector &y, size_t size) const { Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); @@ -465,15 +507,15 @@ void InstrumentActor::sumDetectors(QList &dets, std::vector &x, } /** -* Sum counts in detectors for purposes of rough plotting against the units on -* the x-axis. -* Assumes that all spectra share the x vector. -* -* @param dets :: A list of detector IDs to sum. -* @param x :: (output) Time of flight values (or whatever values the x axis has) -* to plot against. -* @param y :: (output) The sums of the counts for each bin. -*/ + * Sum counts in detectors for purposes of rough plotting against the units on + * the x-axis. + * Assumes that all spectra share the x vector. + * + * @param dets :: A list of detector IDs to sum. + * @param x :: (output) Time of flight values (or whatever values the x axis + * has) to plot against. + * @param y :: (output) The sums of the counts for each bin. + */ void InstrumentActor::sumDetectorsUniform(QList &dets, std::vector &x, std::vector &y) const { @@ -518,16 +560,16 @@ void InstrumentActor::sumDetectorsUniform(QList &dets, } /** -* Sum counts in detectors for purposes of rough plotting against the units on -* the x-axis. -* Assumes that all spectra have different x vectors. -* -* @param dets :: A list of detector IDs to sum. -* @param x :: (output) Time of flight values (or whatever values the x axis has) -* to plot against. -* @param y :: (output) The sums of the counts for each bin. -* @param size :: (input) Size of the output vectors. -*/ + * Sum counts in detectors for purposes of rough plotting against the units on + * the x-axis. + * Assumes that all spectra have different x vectors. + * + * @param dets :: A list of detector IDs to sum. + * @param x :: (output) Time of flight values (or whatever values the x axis + * has) to plot against. + * @param y :: (output) The sums of the counts for each bin. + * @param size :: (input) Size of the output vectors. + */ void InstrumentActor::sumDetectorsRagged(QList &dets, std::vector &x, std::vector &y, @@ -615,50 +657,77 @@ void InstrumentActor::sumDetectorsRagged(QList &dets, } /** -* Recalculate the detector colors based on the integrated values in -* m_specIntegrs and -* the masking information in .... -*/ + * Recalculate the detector colors based on the integrated values in + * m_specIntegrs and + * the masking information in .... + */ void InstrumentActor::resetColors() { QwtDoubleInterval qwtInterval(m_DataMinScaleValue, m_DataMaxScaleValue); - m_colors.resize(m_specIntegrs.size()); - auto sharedWorkspace = getWorkspace(); + const auto &componentInfo = sharedWorkspace->componentInfo(); + const auto &detectorInfo = sharedWorkspace->detectorInfo(); const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); - - IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists(); - - for (int iwi = 0; iwi < int(m_specIntegrs.size()); iwi++) { - size_t wi = size_t(iwi); - double integratedValue = m_specIntegrs[wi]; - try { - // Find if the detector is masked - const auto &dets = sharedWorkspace->getSpectrum(wi).getDetectorIDs(); - bool masked = false; - - if (mask) { - masked = mask->isMasked(dets); - } else { - masked = spectrumInfo.hasDetectors(wi) && spectrumInfo.isMasked(wi); - } - - if (masked) { - m_colors[wi] = m_maskedColor; + auto color = m_colorMap.rgb(qwtInterval, 0); + m_colors.assign(componentInfo.size(), + GLColor(qRed(color), qGreen(color), qBlue(color), 1)); + + for (size_t wi = 0; wi < m_specIntegrs.size(); ++wi) { + const auto &specDef = spectrumInfo.spectrumDefinition(wi); + for (const auto &det : specDef) { + auto detIndex = det.first; + if (detectorInfo.isMasked(detIndex)) { + m_colors[detIndex] = m_maskedColor; } else { - QRgb color = m_colorMap.rgb(qwtInterval, integratedValue); - m_colors[wi] = GLColor(qRed(color), qGreen(color), qBlue(color)); + auto integratedValue = m_specIntegrs[wi]; + color = m_colorMap.rgb(qwtInterval, integratedValue); + m_colors[detIndex] = GLColor( + qRed(color), qGreen(color), qBlue(color), + static_cast(255 * (integratedValue / m_DataMaxScaleValue))); } - } catch (NotFoundError &) { - m_colors[wi] = m_failedColor; - continue; } } - if (m_scene.getNumberOfActors() > 0) { + // QwtDoubleInterval qwtInterval(m_DataMinScaleValue, m_DataMaxScaleValue); + // m_colors.resize(m_specIntegrs.size()); + + // auto sharedWorkspace = getWorkspace(); + // const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); + + // IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists(); + + // for (int iwi = 0; iwi < int(m_specIntegrs.size()); iwi++) { + // size_t wi = size_t(iwi); + // double integratedValue = m_specIntegrs[wi]; + // try { + // // Find if the detector is masked + // const auto &dets = sharedWorkspace->getSpectrum(wi).getDetectorIDs(); + // bool masked = false; + + // if (mask) { + // masked = mask->isMasked(dets); + // } else { + // masked = spectrumInfo.hasDetectors(wi) && spectrumInfo.isMasked(wi); + // } + + // if (masked) { + // m_colors[wi] = m_maskedColor; + // } else { + // QRgb color = m_colorMap.rgb(qwtInterval, integratedValue); + // m_colors[wi] = GLColor(qRed(color), qGreen(color), qBlue(color)); + // } + // } catch (NotFoundError &) { + // m_colors[wi] = m_failedColor; + // continue; + // } + //} + + setupColors(); + invalidateDisplayLists(); + /*if (m_scene.getNumberOfActors() > 0) { if (auto actor = dynamic_cast(m_scene.getActor(0))) { actor->setColors(); invalidateDisplayLists(); } - } + }*/ emit colorMapChanged(); } @@ -668,8 +737,8 @@ void InstrumentActor::updateColors() { } /** -* @param on :: True or false for on or off. -*/ + * @param on :: True or false for on or off. + */ void InstrumentActor::showGuides(bool on) { auto visitor = SetVisibleNonDetectorVisitor(on); this->accept(visitor); @@ -678,7 +747,7 @@ void InstrumentActor::showGuides(bool on) { GLColor InstrumentActor::getColor(Mantid::detid_t id) const { try { - size_t i = getWorkspaceIndex(id); + size_t i = getDetectorInfo().indexOf(id); return m_colors.at(i); } catch (NotFoundError &) { // Return the first color if the detector is not represented in the @@ -687,12 +756,77 @@ GLColor InstrumentActor::getColor(Mantid::detid_t id) const { } } -void InstrumentActor::draw(bool picking) const { m_scene.draw(picking); } +void InstrumentActor::draw(bool picking) const { + if (std::none_of(m_isCompVisible.cbegin(), m_isCompVisible.cend(), + [](bool visible) { return visible; })) + return; + OpenGLError::check("InstrumentActor::draw(0)"); + size_t i = picking ? 1 : 0; + if (m_useDisplayList[i]) { + glCallList(m_displayListId[i]); + } else { + m_displayListId[i] = glGenLists(1); + m_useDisplayList[i] = true; + glNewList(m_displayListId[i], + GL_COMPILE); // Construct display list for object representation + doDraw(picking); + glEndList(); + if (glGetError() == GL_OUT_OF_MEMORY) // Throw an exception + throw Mantid::Kernel::Exception::OpenGLError( + "OpenGL: Out of video memory"); + glCallList(m_displayListId[i]); + } + OpenGLError::check("InstrumentActor::draw()"); +} + +void InstrumentActor::doDraw(bool picking) const { + const auto &componentInfo = getComponentInfo(); + for (size_t i = 0; i < componentInfo.size(); ++i) { + if (!componentInfo.isDetector(i) && !m_showGuides) + continue; + + if (componentInfo.hasShape(i)) { + if (m_isCompVisible[i]) { + if (picking) + m_pickColors[i].paint(); + else + m_colors[i].paint(); + glPushMatrix(); + //Translate + auto pos = componentInfo.position(i); + if(!pos.nullVector()) + glTranslated(pos[0], pos[1], pos[2]); + + //Rotate + auto rot = componentInfo.rotation(i); + if (!rot.isNull()) { + double deg, ax0, ax1, ax2; + rot.getAngleAxis(deg, ax0, ax1, ax2); + glRotated(deg, ax0, ax1, ax2); + } + + //Scale + auto scale = componentInfo.scaleFactor(i); + if(scale != Kernel::V3D(1, 1, 1)) + glScaled(scale[0], scale[1], scale[2]); + + if (m_volumeRender) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + componentInfo.shape(i).draw(); + glPopMatrix(); + } + } + } + // m_scene.draw(picking); +} /** -* @param fname :: A color map file name. -* @param reset_colors :: An option to reset the detector colors. -*/ + * @param fname :: A color map file name. + * @param reset_colors :: An option to reset the detector colors. + */ void InstrumentActor::loadColorMap(const QString &fname, bool reset_colors) { m_colorMap.loadMap(fname); m_currentColorMapFilename = fname; @@ -703,72 +837,89 @@ void InstrumentActor::loadColorMap(const QString &fname, bool reset_colors) { //------------------------------------------------------------------------------ /** Add a detector ID to the pick list (m_detIDs) -* The order of detids define the pickIDs for detectors. -* -* @param id :: detector ID to add. -* @return pick ID of the added detector -*/ + * The order of detids define the pickIDs for detectors. + * + * @param id :: detector ID to add. + * @return pick ID of the added detector + */ size_t InstrumentActor::pushBackDetid(Mantid::detid_t id) const { - m_detIDs.push_back(id); - return m_detIDs.size() - 1; + // m_detIDs.push_back(id); + return 0;//m_detIDs.size() - 1; } //------------------------------------------------------------------------------ /** Add a non-detector component ID to the pick list (m_nonDetIDs) -* -* @param actor :: ObjComponentActor for the component added. -* @param compID :: component ID to add. -*/ + * + * @param actor :: ObjComponentActor for the component added. + * @param compID :: component ID to add. + */ void InstrumentActor::pushBackNonDetid( ObjComponentActor *actor, Mantid::Geometry::ComponentID compID) const { - m_nonDetActorsTemp.push_back(actor); - m_nonDetIDs.push_back(compID); + //m_nonDetActorsTemp.push_back(actor); + //m_nonDetIDs.push_back(compID); +} + +void InstrumentActor::setupColors() { + const auto &componentInfo = getComponentInfo(); + m_pickColors.resize(componentInfo.size()); + + for (size_t i = 0; i < componentInfo.size(); ++i) { + m_pickColors[i] = makePickColor(i); + } } //------------------------------------------------------------------------------ /** -* Set pick colors to non-detectors strored by calls to pushBackNonDetid(). -*/ + * Set pick colors to non-detectors strored by calls to pushBackNonDetid(). + */ void InstrumentActor::setupPickColors() { - assert(m_nonDetActorsTemp.size() == m_nonDetIDs.size()); + /*assert(m_nonDetActorsTemp.size() == m_nonDetIDs.size()); + const auto &componentInfo = getComponentInfo(); auto nDets = m_detIDs.size(); for (size_t i = 0; i < m_nonDetActorsTemp.size(); ++i) { m_nonDetActorsTemp[i]->setPickColor(makePickColor(nDets + i)); } - m_nonDetActorsTemp.clear(); + m_nonDetActorsTemp.clear();*/ } //------------------------------------------------------------------------------ /** If needed, cache the detector positions for all detectors. -* Call this BEFORE getDetPos(). -* Does nothing if the positions have already been cached. -*/ + * Call this BEFORE getDetPos(). + * Does nothing if the positions have already been cached. + */ void InstrumentActor::cacheDetPos() const { - if (m_detPos.size() != m_detIDs.size()) { + /*if (m_detPos.size() != m_detIDs.size()) { m_detPos.clear(); for (size_t pickID = 0; pickID < m_detIDs.size(); pickID++) { auto &det = this->getDetectorByPickID(pickID); m_detPos.push_back(det.getPos()); } - } + }*/ } //------------------------------------------------------------------------------ /** Get the cached detector position -* -* @param pickID :: pick Index maching the getDetector() calls; -* @return the real-space position of the detector -*/ -const Mantid::Kernel::V3D &InstrumentActor::getDetPos(size_t pickID) const { - if (pickID < m_detPos.size()) { - return m_detPos.at(pickID); + * + * @param pickID :: pick Index maching the getDetector() calls; + * @return the real-space position of the detector + */ +const Mantid::Kernel::V3D InstrumentActor::getDetPos(size_t pickID) const { + const auto &detInfo = getDetectorInfo(); + if (pickID < detInfo.size()) { + return detInfo.position(pickID); } return m_defaultPos; } +const std::vector &InstrumentActor::getAllDetIDs() const +{ + const auto &detInfo = getDetectorInfo(); + return detInfo.detectorIDs(); +} + /** -* @param type :: 0 - linear, 1 - log10. -*/ + * @param type :: 0 - linear, 1 - log10. + */ void InstrumentActor::changeScaleType(int type) { m_colorMap.changeScaleType(static_cast(type)); resetColors(); @@ -830,14 +981,16 @@ bool InstrumentActor::wholeRange() const { m_BinMaxValue == m_WkspBinMaxValue; } +size_t InstrumentActor::ndetectors() const { return getDetectorInfo().size(); } + /** -* Set autoscaling of the y axis. If autoscaling is on the minValue() and -* maxValue() -* return the actual min and max values in the data. If autoscaling is off -* minValue() and maxValue() are fixed and do not change after changing the x -* integration range. -* @param on :: On or Off. -*/ + * Set autoscaling of the y axis. If autoscaling is on the minValue() and + * maxValue() + * return the actual min and max values in the data. If autoscaling is off + * minValue() and maxValue() are fixed and do not change after changing the x + * integration range. + * @param on :: On or Off. + */ void InstrumentActor::setAutoscaling(bool on) { m_autoscaling = on; if (on) { @@ -848,10 +1001,15 @@ void InstrumentActor::setAutoscaling(bool on) { } } +void InstrumentActor::showVolumeRender(bool on) { + m_volumeRender = on; + resetColors(); +} + /** -* Extracts the current applied mask to the main workspace -* @returns the current applied mask to the main workspace -*/ + * Extracts the current applied mask to the main workspace + * @returns the current applied mask to the main workspace + */ Mantid::API::MatrixWorkspace_sptr InstrumentActor::extractCurrentMask() const { const std::string maskName = "__InstrumentActor_MaskWorkspace"; Mantid::API::IAlgorithm *alg = @@ -869,8 +1027,8 @@ Mantid::API::MatrixWorkspace_sptr InstrumentActor::extractCurrentMask() const { } /** -* Initialize the helper mask workspace with the mask from the data workspace. -*/ + * Initialize the helper mask workspace with the mask from the data workspace. + */ void InstrumentActor::initMaskHelper() const { if (m_maskWorkspace) return; @@ -885,30 +1043,30 @@ void InstrumentActor::initMaskHelper() const { } /** -* Checks if the actor has a mask workspace attached. -*/ + * Checks if the actor has a mask workspace attached. + */ bool InstrumentActor::hasMaskWorkspace() const { return m_maskWorkspace != nullptr; } /** -* Find a rotation from one orthonormal basis set (Xfrom,Yfrom,Zfrom) to -* another orthonormal basis set (Xto,Yto,Zto). Both sets must be right-handed -* (or same-handed, I didn't check). The method doesn't check the sets for -* orthogonality -* or normality. The result is a rotation quaternion such that: -* R.rotate(Xfrom) == Xto -* R.rotate(Yfrom) == Yto -* R.rotate(Zfrom) == Zto -* @param Xfrom :: The X axis of the original basis set -* @param Yfrom :: The Y axis of the original basis set -* @param Zfrom :: The Z axis of the original basis set -* @param Xto :: The X axis of the final basis set -* @param Yto :: The Y axis of the final basis set -* @param Zto :: The Z axis of the final basis set -* @param R :: The output rotation as a quaternion -* @param out :: Debug printout flag -*/ + * Find a rotation from one orthonormal basis set (Xfrom,Yfrom,Zfrom) to + * another orthonormal basis set (Xto,Yto,Zto). Both sets must be right-handed + * (or same-handed, I didn't check). The method doesn't check the sets for + * orthogonality + * or normality. The result is a rotation quaternion such that: + * R.rotate(Xfrom) == Xto + * R.rotate(Yfrom) == Yto + * R.rotate(Zfrom) == Zto + * @param Xfrom :: The X axis of the original basis set + * @param Yfrom :: The Y axis of the original basis set + * @param Zfrom :: The Z axis of the original basis set + * @param Xto :: The X axis of the final basis set + * @param Yto :: The Y axis of the final basis set + * @param Zto :: The Z axis of the final basis set + * @param R :: The output rotation as a quaternion + * @param out :: Debug printout flag + */ void InstrumentActor::BasisRotation(const Mantid::Kernel::V3D &Xfrom, const Mantid::Kernel::V3D &Yfrom, const Mantid::Kernel::V3D &Zfrom, @@ -994,15 +1152,15 @@ void InstrumentActor::BasisRotation(const Mantid::Kernel::V3D &Xfrom, } /** -* Calculate a rotation to look in a particular direction. -* -* @param eye :: A direction to look in -* @param up :: A vector showing the 'up' direction after the rotation. It -* doesn't have to be normal to eye -* just non-collinear. If up is collinear to eye the actual 'up' direction is -* undefined. -* @param R :: The result rotation. -*/ + * Calculate a rotation to look in a particular direction. + * + * @param eye :: A direction to look in + * @param up :: A vector showing the 'up' direction after the rotation. It + * doesn't have to be normal to eye + * just non-collinear. If up is collinear to eye the actual 'up' direction is + * undefined. + * @param R :: The result rotation. + */ void InstrumentActor::rotateToLookAt(const Mantid::Kernel::V3D &eye, const Mantid::Kernel::V3D &up, Mantid::Kernel::Quat &R) { @@ -1039,11 +1197,11 @@ void InstrumentActor::rotateToLookAt(const Mantid::Kernel::V3D &eye, } /** -* Find the offsets in the spectrum's x vector of the bounds of integration. -* @param wi :: The works[ace index of the spectrum. -* @param imin :: Index of the lower bound: x_min == x(wi)[imin] -* @param imax :: Index of the upper bound: x_max == x(wi)[imax] -*/ + * Find the offsets in the spectrum's x vector of the bounds of integration. + * @param wi :: The works[ace index of the spectrum. + * @param imin :: Index of the lower bound: x_min == x(wi)[imin] + * @param imax :: Index of the upper bound: x_max == x(wi)[imax] + */ void InstrumentActor::getBinMinMaxIndex(size_t wi, size_t &imin, size_t &imax) const { Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); @@ -1078,8 +1236,8 @@ void InstrumentActor::getBinMinMaxIndex(size_t wi, size_t &imin, } /** -* Set the minimum and the maximum data values on the color map scale. -*/ + * Set the minimum and the maximum data values on the color map scale. + */ void InstrumentActor::setDataMinMaxRange(double vmin, double vmax) { if (vmin < m_DataMinValue) { vmin = m_DataMinValue; @@ -1131,7 +1289,7 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, // Now we need to convert to a vector where each entry is the sum for the // detector ID at that spot (in integrated_values). - for (size_t i = 0; i < m_specIntegrs.size(); i++) { + for (size_t i = 0; i < m_specIntegrs.size(); ++i) { // skip the monitors if (std::find(monitorIndices.begin(), monitorIndices.end(), i) != monitorIndices.end()) { @@ -1245,11 +1403,11 @@ bool SetVisibleComponentVisitor::visit(StructuredDetectorActor *actor) { //-------------------------------------------------------------------------// /** -* Visits an actor and if it is a "non-detector" sets its visibility. -* -* @param actor :: A visited actor. -* @return always false to traverse all the instrument tree. -*/ + * Visits an actor and if it is a "non-detector" sets its visibility. + * + * @param actor :: A visited actor. + * @return always false to traverse all the instrument tree. + */ bool SetVisibleNonDetectorVisitor::visit(GLActor *actor) { ComponentActor *comp = dynamic_cast(actor); if (comp && comp->isNonDetector()) { @@ -1304,5 +1462,24 @@ void InstrumentActor::loadFromProject(const std::string &lines) { } } -} // MantidWidgets -} // MantidQt +const Mantid::Geometry::ComponentInfo & +InstrumentActor::getComponentInfo() const { + return getWorkspace()->componentInfo(); +} + +const Mantid::Geometry::DetectorInfo &InstrumentActor::getDetectorInfo() const { + return getWorkspace()->detectorInfo(); +} + +void InstrumentActor::invalidateDisplayLists() const { + for (size_t i = 0; i < 2; ++i) { + if (m_displayListId[i] != 0) { + glDeleteLists(m_displayListId[i], 1); + m_displayListId[i] = 0; + m_useDisplayList[i] = false; + } + } +} + +} // namespace MantidWidgets +} // namespace MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp index 6b33c5fe23b4..698b7b753c45 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp @@ -141,6 +141,10 @@ InstrumentWidgetRenderTab::InstrumentWidgetRenderTab( m_displayAxes->setCheckable(true); m_displayAxes->setChecked(true); connect(m_displayAxes, SIGNAL(toggled(bool)), this, SLOT(showAxes(bool))); + m_volumeRender = new QAction("VolumeRender", this); + m_volumeRender->setCheckable(true); + m_volumeRender->setChecked(false); + connect(m_volumeRender, SIGNAL(toggled(bool)), this, SLOT(showVolumeRender(bool))); m_displayDetectorsOnly = new QAction("Display Detectors Only", this); m_displayDetectorsOnly->setCheckable(true); m_displayDetectorsOnly->setChecked(true); @@ -173,6 +177,7 @@ InstrumentWidgetRenderTab::InstrumentWidgetRenderTab( displaySettingsMenu->addSeparator(); displaySettingsMenu->addAction(m_displayAxes); displaySettingsMenu->addAction(m_displayDetectorsOnly); + displaySettingsMenu->addAction(m_volumeRender); displaySettingsMenu->addAction(m_wireframe); displaySettingsMenu->addAction(m_lighting); displaySettingsMenu->addAction(m_GLView); @@ -443,6 +448,14 @@ void InstrumentWidgetRenderTab::showAxes(bool on) { m_displayAxes->blockSignals(false); } +void InstrumentWidgetRenderTab::showVolumeRender(bool on) +{ + m_instrWidget->getInstrumentActor().showVolumeRender(on); + m_volumeRender->blockSignals(true); + m_volumeRender->setChecked(on); + m_volumeRender->blockSignals(false); +} + /** * Toggle display of guide and other non-detector components. * @@ -735,6 +748,7 @@ MantidQt::MantidWidgets::InstrumentWidgetRenderTab::saveToProject() const { tab.writeLine("AxesView") << mAxisCombo->currentIndex(); tab.writeLine("AutoScaling") << m_autoscaling->isChecked(); tab.writeLine("DisplayAxes") << m_displayAxes->isChecked(); + tab.writeLine("VolumeRender") << m_volumeRender->isChecked(); tab.writeLine("FlipView") << m_flipCheckBox->isChecked(); tab.writeLine("DisplayDetectorsOnly") << m_displayDetectorsOnly->isChecked(); tab.writeLine("DisplayWireframe") << m_wireframe->isChecked(); @@ -772,7 +786,7 @@ void InstrumentWidgetRenderTab::loadFromProject(const std::string &lines) { tsv >> tabLines; API::TSVSerialiser tab(tabLines); - bool autoScaling, displayAxes, flipView, displayDetectorsOnly, + bool autoScaling, displayAxes, volumeRender, flipView, displayDetectorsOnly, displayWireframe, displayLighting, useOpenGL, useUCorrection; int axesView; @@ -782,6 +796,8 @@ void InstrumentWidgetRenderTab::loadFromProject(const std::string &lines) { tab >> autoScaling; tab.selectLine("DisplayAxes"); tab >> displayAxes; + tab.selectLine("VolumeRender"); + tab >> volumeRender; tab.selectLine("FlipView"); tab >> flipView; tab.selectLine("DisplayDetectorsOnly"); @@ -798,6 +814,7 @@ void InstrumentWidgetRenderTab::loadFromProject(const std::string &lines) { mAxisCombo->setCurrentIndex(axesView); m_autoscaling->setChecked(autoScaling); m_displayAxes->setChecked(displayAxes); + m_volumeRender->setChecked(volumeRender); m_flipCheckBox->setChecked(flipView); m_displayDetectorsOnly->setChecked(displayDetectorsOnly); m_wireframe->setChecked(displayWireframe); diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 345257f1be1b..2ba9a61ba75c 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -7,6 +7,7 @@ #include "MantidAPI/MatrixWorkspace.h" #include "MantidGeometry/Instrument/DetectorInfo.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidGeometry/Instrument/ObjCompAssembly.h" #include "MantidKernel/Logger.h" #include "MantidKernel/Tolerance.h" @@ -20,10 +21,113 @@ using namespace Mantid::Geometry; namespace { + /// static logger Mantid::Kernel::Logger g_log("PanelsSurface"); + +/** + * Given the z axis, define the x and y ones. + * @param zaxis :: A given vector in 3d space to become the z axis of a + * coordinate system. + * @param xaxis :: An output arbitrary vector perpendicular to zaxis. + * @param yaxis :: An output arbitrary vector perpendicular to both zaxis and + * xaxis. + */ +void setupBasisAxes(const Mantid::Kernel::V3D &zaxis, + Mantid::Kernel::V3D &xaxis, Mantid::Kernel::V3D &yaxis) { + double R, theta, phi; + zaxis.getSpherical(R, theta, phi); + if (theta <= 45.0) { + xaxis = Mantid::Kernel::V3D(1, 0, 0); + } else if (phi <= 45.0) { + xaxis = Mantid::Kernel::V3D(0, 1, 0); + } else { + xaxis = Mantid::Kernel::V3D(0, 0, 1); + } + yaxis = zaxis.cross_prod(xaxis); + yaxis.normalize(); + xaxis = yaxis.cross_prod(zaxis); } +Mantid::Kernel::V3D +calculateStructuredNormal(const Mantid::Geometry::ComponentInfo &componentInfo, + size_t bankRoot) { + // Find norm using Bounding Box coords + auto boundingBox = componentInfo.boundingBox(bankRoot); + auto minPoint = boundingBox.minPoint(); + auto maxPoint = boundingBox.maxPoint(); + + auto p0 = Mantid::Kernel::V3D(minPoint.X(), minPoint.Y(), 0); + auto p1 = Mantid::Kernel::V3D(maxPoint.X(), maxPoint.Y(), 0); + auto p2 = Mantid::Kernel::V3D(minPoint.X(), maxPoint.Y(), 0); + auto p3 = Mantid::Kernel::V3D(maxPoint.X(), minPoint.Y(), 0); + + Mantid::Kernel::V3D xaxis = p1 - p0; + Mantid::Kernel::V3D yaxis = p3 - p0; + Mantid::Kernel::V3D normal = xaxis.cross_prod(yaxis); + normal.normalize(); + return normal; +} + +std::pair, Mantid::Kernel::V3D> +searchFlatPanels(const ComponentInfo &componentInfo, + const DetectorInfo &detectorInfo, size_t rootIndex, + const std::vector &children, + std::vector &visited) { + Mantid::Kernel::V3D normal; + bool structuredNormalFound = false; + if (componentInfo.isStructuredBank(rootIndex)) { + normal = calculateStructuredNormal(componentInfo, rootIndex); + structuredNormalFound = true; + } + + QList detectors; + Mantid::Kernel::V3D pos0; + Mantid::Kernel::V3D x, y; + bool normalFound = false; + + for (auto child : children) { + if (visited[child]) + continue; + visited[child] = true; + + if (detectorInfo.isMonitor(child)) + continue; + if (!structuredNormalFound) { + Mantid::Kernel::V3D pos = detectorInfo.position(child); + if (child == children[0]) + pos0 = pos; + else if (child == children[1]) { + // at first set the normal to an argbitrary vector orthogonal to + // the line between the first two detectors + y = pos - pos0; + y.normalize(); + setupBasisAxes(y, normal, x); + } else if (fabs(normal.scalar_prod(pos - pos0)) > + Mantid::Kernel::Tolerance) { + if (!normalFound) { + // when first non-colinear detector is found set the normal + x = pos - pos0; + x.normalize(); + normal = x.cross_prod(y); + normal.normalize(); + x = y.cross_prod(normal); + normalFound = true; + } else { + // TODO: Replace somehow with componentInfo name method. + /*g_log.warning() << "Assembly " << componentInfo->name(rootIndex) + << " isn't flat.\n";*/ + break; + } + } + } + detectors << componentInfo.componentID(child)->getComponentID(); + } + return std::make_pair(detectors, normal); +} + +} // namespace + namespace MantidQt { namespace MantidWidgets { @@ -72,9 +176,10 @@ void PanelsSurface::init() { // Pre-calculate all the detector positions (serial because // I suspect the IComponent->getPos() method to not be properly thread safe) - m_instrActor->cacheDetPos(); + //m_instrActor->cacheDetPos(); - findFlatBanks(); + //findFlatBanks(); + constructFromComponentInfo(); spreadBanks(); RectF surfaceRect; @@ -119,31 +224,6 @@ void PanelsSurface::setupAxes() { m_origin.ry() = m_yaxis.scalar_prod(m_pos); } -/** -* Given the z axis, define the x and y ones. -* @param zaxis :: A given vector in 3d space to become the z axis of a -* coordinate system. -* @param xaxis :: An output arbitrary vector perpendicular to zaxis. -* @param yaxis :: An output arbitrary vector perpendicular to both zaxis and -* xaxis. -*/ -void PanelsSurface::setupBasisAxes(const Mantid::Kernel::V3D &zaxis, - Mantid::Kernel::V3D &xaxis, - Mantid::Kernel::V3D &yaxis) const { - double R, theta, phi; - zaxis.getSpherical(R, theta, phi); - if (theta <= 45.0) { - xaxis = Mantid::Kernel::V3D(1, 0, 0); - } else if (phi <= 45.0) { - xaxis = Mantid::Kernel::V3D(0, 1, 0); - } else { - xaxis = Mantid::Kernel::V3D(0, 0, 1); - } - yaxis = zaxis.cross_prod(xaxis); - yaxis.normalize(); - xaxis = yaxis.cross_prod(zaxis); -} - //-----------------------------------------------------------------------------------------------// class FlatBankFinder : public GLActorConstVisitor { @@ -462,6 +542,25 @@ void PanelsSurface::addCompAssembly(ComponentID bankId) { } } +void PanelsSurface::constructFromComponentInfo() { + const auto componentInfo = m_instrActor->getComponentInfo(); + std::vector visited(componentInfo.size(), false); + const auto &detectorInfo = m_instrActor->getDetectorInfo(); + + for (size_t i = 0; i < componentInfo.size(); ++i) { + auto children = componentInfo.detectorsInSubtree(i); + + if (children.size() > 1) { + auto res = searchFlatPanels(componentInfo, detectorInfo, i, children, visited); + auto detectors = res.first; + auto normal = res.second; + if (!detectors.isEmpty()) + addFlatBankOfDetectors(componentInfo.componentID(i)->getComponentID(), + normal, detectors); + } + } +} + /** * Add a rectangular detector which is flat. * @param bankId :: Component id of a rectangular detector. From 87aa844306568c4865b4f32c84aacbb8f4ab70aa Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 14 Dec 2017 12:56:23 +0000 Subject: [PATCH 029/364] Updates to unwrapped views #21339 --- .../MantidGeometry/Instrument/ComponentInfo.h | 21 +- .../Geometry/src/Instrument/ComponentInfo.cpp | 31 +- qt/widgets/instrumentview/CMakeLists.txt | 2 + .../InstrumentView/PanelsSurface.h | 36 +- .../InstrumentView/UnwrappedDetector.h | 57 ++ .../InstrumentView/UnwrappedSurface.h | 33 +- .../instrumentview/src/InstrumentActor.cpp | 14 +- .../instrumentview/src/PanelsSurface.cpp | 617 ++++-------------- .../instrumentview/src/RotationSurface.cpp | 1 + .../instrumentview/src/UnwrappedCylinder.cpp | 1 + .../instrumentview/src/UnwrappedDetector.cpp | 70 ++ .../instrumentview/src/UnwrappedSphere.cpp | 1 + .../instrumentview/src/UnwrappedSurface.cpp | 52 +- 13 files changed, 330 insertions(+), 606 deletions(-) create mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h create mode 100644 qt/widgets/instrumentview/src/UnwrappedDetector.cpp diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index e1d80f18e481..938900ca147d 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -87,12 +87,22 @@ class MANTID_GEOMETRY_DLL ComponentInfo { const std::map &detectorExclusions) const; public: + typedef struct { + size_t topLeft; + size_t bottomLeft; + size_t bottomRight; + size_t topRight; + size_t nX; + size_t nY; + } StructuredPanel; + ComponentInfo( std::unique_ptr componentInfo, boost::shared_ptr> componentIds, - boost::shared_ptr> componentIdToIndexMap, + boost::shared_ptr< + const std::unordered_map> + componentIdToIndexMap, boost::shared_ptr>> shapes); ~ComponentInfo(); @@ -102,6 +112,7 @@ class MANTID_GEOMETRY_DLL ComponentInfo { std::vector detectorsInSubtree(size_t componentIndex) const; std::vector componentsInSubtree(size_t componentIndex) const; size_t size() const; + StructuredPanel structuredPanel(const size_t componentIndex) const; size_t indexOf(Geometry::IComponent *id) const; size_t indexOfAny(const std::string &name) const; bool isDetector(const size_t componentIndex) const; @@ -137,12 +148,16 @@ class MANTID_GEOMETRY_DLL ComponentInfo { return m_componentIds->operator[](componentIndex); } bool hasValidShape(const size_t componentIndex) const; - const Geometry::IObject &shape(const size_t componentIndex) const; + + boost::shared_ptr + shape(const size_t componentIndex) const; + double solidAngle(const size_t componentIndex, const Kernel::V3D &observer) const; BoundingBox boundingBox(const size_t componentIndex, const BoundingBox *reference = nullptr) const; Beamline::ComponentType componentType(const size_t componentIndex) const; + bool isRectangularBank(const size_t componentIndex) const; void setScanInterval(const std::pair &interval); void merge(const ComponentInfo &other); size_t scanSize() const; diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index 69a76c1d4b19..cbbe2e3a5715 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -109,6 +109,26 @@ ComponentInfo::componentsInSubtree(size_t componentIndex) const { size_t ComponentInfo::size() const { return m_componentInfo->size(); } +ComponentInfo::StructuredPanel +ComponentInfo::structuredPanel(const size_t componentIndex) const { + StructuredPanel corners; + auto innerRangeComp = + m_componentInfo->componentRangeInSubtree(componentIndex); + // nSubComponents, subtract off self hence -1. nSubComponents = number of + // horizontal columns. + corners.nX = innerRangeComp.end() - innerRangeComp.begin() - 1; + auto innerRangeDet = m_componentInfo->detectorRangeInSubtree(componentIndex); + auto nSubDetectors = + std::distance(innerRangeDet.begin(), innerRangeDet.end()); + corners.nY = nSubDetectors / corners.nX; + + corners.bottomLeft = *innerRangeDet.begin(); + corners.topRight = corners.bottomLeft + nSubDetectors - 1; + corners.topLeft = corners.bottomLeft + (corners.nY - 1); + corners.bottomRight = corners.topRight - (corners.nY - 1); + return corners; +} + size_t ComponentInfo::indexOf(Geometry::IComponent *id) const { return m_compIDToIndex->at(id); } @@ -206,8 +226,9 @@ void ComponentInfo::setRotation(const size_t componentIndex, Kernel::toQuaterniond(newRotation)); } -const IObject &ComponentInfo::shape(const size_t componentIndex) const { - return *(*m_shapes)[componentIndex]; +boost::shared_ptr +ComponentInfo::shape(const size_t componentIndex) const { + return (*m_shapes)[componentIndex]; } Kernel::V3D ComponentInfo::scaleFactor(const size_t componentIndex) const { @@ -234,11 +255,11 @@ double ComponentInfo::solidAngle(const size_t componentIndex, toShapeFrame(observer, *m_componentInfo, componentIndex); const Kernel::V3D scaleFactor = this->scaleFactor(componentIndex); if ((scaleFactor - Kernel::V3D(1.0, 1.0, 1.0)).norm() < 1e-12) - return shape(componentIndex).solidAngle(relativeObserver); + return shape(componentIndex)->solidAngle(relativeObserver); else { // This function will scale the object shape when calculating the solid // angle. - return shape(componentIndex).solidAngle(relativeObserver, scaleFactor); + return shape(componentIndex)->solidAngle(relativeObserver, scaleFactor); } } @@ -374,7 +395,7 @@ ComponentInfo::componentBoundingBox(const size_t index, return BoundingBox(); // Return null bounding box } const auto &s = this->shape(index); - BoundingBox absoluteBB = s.getBoundingBox(); + BoundingBox absoluteBB = s->getBoundingBox(); // modify in place for speed const Eigen::Vector3d scaleFactor = m_componentInfo->scaleFactor(index); diff --git a/qt/widgets/instrumentview/CMakeLists.txt b/qt/widgets/instrumentview/CMakeLists.txt index 80a0417f190f..444bd0aff720 100644 --- a/qt/widgets/instrumentview/CMakeLists.txt +++ b/qt/widgets/instrumentview/CMakeLists.txt @@ -41,6 +41,7 @@ set ( SRC_FILES src/StructuredDetectorActor.cpp src/UCorrectionDialog.cpp src/UnwrappedCylinder.cpp + src/UnwrappedDetector.cpp src/UnwrappedSphere.cpp src/UnwrappedSurface.cpp src/Viewport.cpp @@ -116,6 +117,7 @@ set ( INC_FILES inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h inc/MantidQtWidgets/InstrumentView/UCorrectionDialog.h inc/MantidQtWidgets/InstrumentView/UnwrappedCylinder.h + inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h inc/MantidQtWidgets/InstrumentView/UnwrappedSphere.h inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h inc/MantidQtWidgets/InstrumentView/Viewport.h diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h index 4407a5677b7b..595dc48ae722 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h @@ -4,6 +4,7 @@ #include "UnwrappedSurface.h" #include +#include namespace MantidQt { namespace MantidWidgets { @@ -53,38 +54,30 @@ class PanelsSurface : public UnwrappedSurface { double &) const override; protected: + boost::optional, Mantid::Kernel::V3D>> + findFlatPanels(size_t rootIndex, const std::vector &children, + std::vector &visited); + + void processStructured(const std::vector &children, size_t rootIndex); + + std::pair, Mantid::Kernel::V3D> + processUnstructured(const std::vector &children, size_t rootIndex, + std::vector &visited); + void rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat &R) const override; - // void drawCustom(QPainter *painter) const; - // Setup the projection axes void setupAxes(); - // Find all flat banks of detectors. - void findFlatBanks(); - // Add a flat bank - void addFlatBank(Mantid::Geometry::ComponentID bankId, - const Mantid::Kernel::V3D &normal, - QList objCompAssemblies); // Add a flat bank void addFlatBankOfDetectors(Mantid::Geometry::ComponentID bankId, const Mantid::Kernel::V3D &normal, - QList detectors); - // Add a component assembly containing a flat array of ObjCompAssemblies - void addObjCompAssemblies(Mantid::Geometry::ComponentID bankId); - // Add a component assembly - void addCompAssembly(Mantid::Geometry::ComponentID bankId); - // Add a rectangular detector - void addRectangularDetector(Mantid::Geometry::ComponentID bankId); - // Add a structured detector - void addStructuredDetector(Mantid::Geometry::ComponentID bankId); - // Calculate bank rotation + const std::vector &detectors); void constructFromComponentInfo(); Mantid::Kernel::Quat calcBankRotation(const Mantid::Kernel::V3D &detPos, Mantid::Kernel::V3D normal) const; // Add a detector from an assembly - void addDetector(const Mantid::Geometry::IDetector &det, - const Mantid::Kernel::V3D &refPos, int index, - Mantid::Kernel::Quat &rotation); + void addDetector(size_t detIndex, const Mantid::Kernel::V3D &refPos, + int index, Mantid::Kernel::Quat &rotation); // Spread the banks over the projection plane void spreadBanks(); // Find index of the largest bank @@ -108,7 +101,6 @@ class PanelsSurface : public UnwrappedSurface { /// Maps detector ids to indices of FlatBankInfos in m_flatBanks QMap m_detector2bankMap; - friend class FlatBankFinder; friend struct FlatBankInfo; }; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h new file mode 100644 index 000000000000..fa0cbbb1ea3c --- /dev/null +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h @@ -0,0 +1,57 @@ +#ifndef UNWRAPPEDDETECTOR_H +#define UNWRAPPEDDETECTOR_H + +#include "MantidGeometry/IDTypes.h" +#include "MantidKernel/Quat.h" +#include "MantidKernel/V3D.h" +#include + +namespace Mantid { +namespace Geometry { +class IDetector; +class Object; +} // namespace Geometry +} // namespace Mantid + +namespace MantidQt { +namespace MantidWidgets { + +/** +\class UnwrappedDetector +\brief Class helper for drawing detectors on unwraped surfaces +\date 15 Nov 2010 +\author Roman Tolchenov, Tessella plc + +This class keeps information used to draw a detector on an unwrapped surface. + +*/ +class UnwrappedDetector { +public: + UnwrappedDetector(); + UnwrappedDetector(const unsigned char *c, + const Mantid::Geometry::IDetector &det); + UnwrappedDetector(unsigned char r, unsigned char g, unsigned char b, + Mantid::detid_t detID, const Mantid::Kernel::V3D &pos, + const Mantid::Kernel::Quat &rot, + const Mantid::Kernel::V3D &scaleFactor, + boost::shared_ptr shape); + UnwrappedDetector(const UnwrappedDetector &other); + UnwrappedDetector &operator=(const UnwrappedDetector &other); + bool isValid() const; + unsigned char color[3]; ///< red, green, blue colour components (0 - 255) + double u; ///< horizontal "unwrapped" coordinate + double v; ///< vertical "unwrapped" coordinate + double width; ///< detector width in units of u + double height; ///< detector height in units of v + double uscale; ///< scaling factor in u direction + double vscale; ///< scaling factor in v direction + Mantid::detid_t detID; ///< Detector ID + Mantid::Kernel::V3D position; ///< Detector position + Mantid::Kernel::Quat rotation; ///< Detector orientation + boost::shared_ptr + shape; ///< Shape of the detector + Mantid::Kernel::V3D scaleFactor; ///< Detector's scale factor +}; +} // namespace MantidWidgets +} // namespace MantidQt +#endif \ No newline at end of file diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h index 3dab3355bba4..b384470f19ba 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h @@ -31,38 +31,7 @@ class GL3DWidget; namespace MantidQt { namespace MantidWidgets { - -/** -\class UnwrappedDetector -\brief Class helper for drawing detectors on unwraped surfaces -\date 15 Nov 2010 -\author Roman Tolchenov, Tessella plc - -This class keeps information used to draw a detector on an unwrapped surface. - -*/ -class UnwrappedDetector { -public: - UnwrappedDetector(); - UnwrappedDetector(const unsigned char *c, - const Mantid::Geometry::IDetector &det); - UnwrappedDetector(const UnwrappedDetector &other); - UnwrappedDetector &operator=(const UnwrappedDetector &other); - bool isValid() const; - unsigned char color[3]; ///< red, green, blue colour components (0 - 255) - double u; ///< horizontal "unwrapped" coordinate - double v; ///< vertical "unwrapped" coordinate - double width; ///< detector width in units of u - double height; ///< detector height in units of v - double uscale; ///< scaling factor in u direction - double vscale; ///< scaling factor in v direction - Mantid::detid_t detID; ///< Detector ID - Mantid::Kernel::V3D position; ///< Detector position - Mantid::Kernel::Quat rotation; ///< Detector orientation - boost::shared_ptr - shape; ///< Shape of the detector - Mantid::Kernel::V3D scaleFactor; ///< Detector's scale factor -}; +class UnwrappedDetector; /** * @class UnwrappedSurface diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 8f4cb7fa77d3..a1c0cde6d2f4 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -419,17 +419,11 @@ Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const { */ Mantid::Geometry::ComponentID InstrumentActor::getComponentID(size_t pickID) const { - /*size_t ndet = m_detIDs.size(); auto compID = Mantid::Geometry::ComponentID(); - if (pickID < ndet) { - auto &det = getDetectorByPickID(m_detIDs[pickID]); - compID = det.getComponentID(); - } else if (pickID < ndet + m_nonDetIDs.size()) { - compID = m_nonDetIDs[pickID - ndet]; - } - return compID;*/ const auto &componentInfo = getComponentInfo(); - return componentInfo.componentID(pickID)->getComponentID(); + if (pickID < componentInfo.size()) + compID = componentInfo.componentID(pickID)->getComponentID(); + return compID; } /** Retrieve the workspace index corresponding to a particular detector @@ -816,7 +810,7 @@ void InstrumentActor::doDraw(bool picking) const { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - componentInfo.shape(i).draw(); + componentInfo.shape(i)->draw(); glPopMatrix(); } } diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 2ba9a61ba75c..c42c5a3d0124 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -2,6 +2,7 @@ #include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" #include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h" #include "MantidQtWidgets/InstrumentView/PanelsSurface.h" +#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" #include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h" #include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h" @@ -49,83 +50,25 @@ void setupBasisAxes(const Mantid::Kernel::V3D &zaxis, xaxis = yaxis.cross_prod(zaxis); } +std::vector +retrievePanelCorners(const Mantid::Geometry::ComponentInfo &componentInfo, + size_t rootIndex) { + auto panel = componentInfo.structuredPanel(rootIndex); + return {componentInfo.position(panel.bottomLeft), + componentInfo.position(panel.bottomRight), + componentInfo.position(panel.topRight), + componentInfo.position(panel.topLeft)}; +} + Mantid::Kernel::V3D -calculateStructuredNormal(const Mantid::Geometry::ComponentInfo &componentInfo, - size_t bankRoot) { - // Find norm using Bounding Box coords - auto boundingBox = componentInfo.boundingBox(bankRoot); - auto minPoint = boundingBox.minPoint(); - auto maxPoint = boundingBox.maxPoint(); - - auto p0 = Mantid::Kernel::V3D(minPoint.X(), minPoint.Y(), 0); - auto p1 = Mantid::Kernel::V3D(maxPoint.X(), maxPoint.Y(), 0); - auto p2 = Mantid::Kernel::V3D(minPoint.X(), maxPoint.Y(), 0); - auto p3 = Mantid::Kernel::V3D(maxPoint.X(), minPoint.Y(), 0); - - Mantid::Kernel::V3D xaxis = p1 - p0; - Mantid::Kernel::V3D yaxis = p3 - p0; - Mantid::Kernel::V3D normal = xaxis.cross_prod(yaxis); +calculatePanelNormal(const std::vector &panelCorners) { + // find the normal + auto xaxis = panelCorners[1] - panelCorners[0]; + auto yaxis = panelCorners[3] - panelCorners[0]; + auto normal = xaxis.cross_prod(yaxis); normal.normalize(); return normal; } - -std::pair, Mantid::Kernel::V3D> -searchFlatPanels(const ComponentInfo &componentInfo, - const DetectorInfo &detectorInfo, size_t rootIndex, - const std::vector &children, - std::vector &visited) { - Mantid::Kernel::V3D normal; - bool structuredNormalFound = false; - if (componentInfo.isStructuredBank(rootIndex)) { - normal = calculateStructuredNormal(componentInfo, rootIndex); - structuredNormalFound = true; - } - - QList detectors; - Mantid::Kernel::V3D pos0; - Mantid::Kernel::V3D x, y; - bool normalFound = false; - - for (auto child : children) { - if (visited[child]) - continue; - visited[child] = true; - - if (detectorInfo.isMonitor(child)) - continue; - if (!structuredNormalFound) { - Mantid::Kernel::V3D pos = detectorInfo.position(child); - if (child == children[0]) - pos0 = pos; - else if (child == children[1]) { - // at first set the normal to an argbitrary vector orthogonal to - // the line between the first two detectors - y = pos - pos0; - y.normalize(); - setupBasisAxes(y, normal, x); - } else if (fabs(normal.scalar_prod(pos - pos0)) > - Mantid::Kernel::Tolerance) { - if (!normalFound) { - // when first non-colinear detector is found set the normal - x = pos - pos0; - x.normalize(); - normal = x.cross_prod(y); - normal.normalize(); - x = y.cross_prod(normal); - normalFound = true; - } else { - // TODO: Replace somehow with componentInfo name method. - /*g_log.warning() << "Assembly " << componentInfo->name(rootIndex) - << " isn't flat.\n";*/ - break; - } - } - } - detectors << componentInfo.componentID(child)->getComponentID(); - } - return std::make_pair(detectors, normal); -} - } // namespace namespace MantidQt { @@ -174,11 +117,6 @@ void PanelsSurface::init() { if (ndet == 0) return; - // Pre-calculate all the detector positions (serial because - // I suspect the IComponent->getPos() method to not be properly thread safe) - //m_instrActor->cacheDetPos(); - - //findFlatBanks(); constructFromComponentInfo(); spreadBanks(); @@ -226,57 +164,15 @@ void PanelsSurface::setupAxes() { //-----------------------------------------------------------------------------------------------// -class FlatBankFinder : public GLActorConstVisitor { - PanelsSurface &m_surface; - -public: - explicit FlatBankFinder(PanelsSurface &surface) : m_surface(surface) {} - - bool visit(const GLActor *) override { return false; } - bool visit(const GLActorCollection *) override { return false; } - bool visit(const ComponentActor *) override { return false; } - bool visit(const InstrumentActor *) override { return false; } - bool visit(const ObjCompAssemblyActor *) override { return false; } - - bool visit(const CompAssemblyActor *actor) override { - m_surface.addObjCompAssemblies(actor->getComponent()->getComponentID()); - return false; - } - - bool visit(const RectangularDetectorActor *actor) override { - m_surface.addRectangularDetector(actor->getComponent()->getComponentID()); - return false; - } - - bool visit(const StructuredDetectorActor *actor) override { - m_surface.addStructuredDetector(actor->getComponent()->getComponentID()); - return false; - } -}; - -/** -* Traverse the instrument tree and find the banks which detectors lie in the -* same plane. -* -*/ -void PanelsSurface::findFlatBanks() { - clearBanks(); - FlatBankFinder finder(*this); - m_instrActor->accept(finder); -} - -//-----------------------------------------------------------------------------------------------// - /** -* Add a flat bank from an assembly of ObjCompAssemblies. +* Add a flat bank from an assembly of detectors. * @param bankId :: Component ID of the bank. * @param normal :: Normal vector to the bank's plane. -* @param objCompAssemblies :: List of component IDs. Each component must cast to -* ObjCompAssembly. +* @param detectors :: List of detectorIndices. */ -void PanelsSurface::addFlatBank(ComponentID bankId, - const Mantid::Kernel::V3D &normal, - QList objCompAssemblies) { +void PanelsSurface::addFlatBankOfDetectors( + ComponentID bankId, const Mantid::Kernel::V3D &normal, + const std::vector &detectors) { int index = m_flatBanks.size(); // save bank info FlatBankInfo *info = new FlatBankInfo(this); @@ -284,231 +180,94 @@ void PanelsSurface::addFlatBank(ComponentID bankId, info->id = bankId; // record the first detector index of the bank info->startDetectorIndex = m_unwrappedDetectors.size(); - bool doneRotation = false; + int nelem = detectors.size(); + m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); + // keep reference position on the bank's plane - Mantid::Kernel::V3D pos0; - QPointF p0, p1; - Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument(); - // loop over the assemblies and process the detectors - foreach (ComponentID id, objCompAssemblies) { - Mantid::Geometry::ICompAssembly_const_sptr assembly = - boost::dynamic_pointer_cast( - instr->getComponentByID(id)); - assert(assembly); - int nelem = assembly->nelements(); - m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); - for (int i = 0; i < nelem; ++i) { - // setup detector info - auto det = boost::dynamic_pointer_cast( - assembly->getChild(i)); - if (!doneRotation) { - pos0 = det->getPos(); - // find the rotation to put the bank on the plane - info->rotation = calcBankRotation(pos0, normal); - Mantid::Kernel::V3D pos1 = assembly->getChild(nelem - 1)->getPos(); - pos1 -= pos0; - info->rotation.rotate(pos1); - pos1 += pos0; - // start forming the outline polygon - p0.rx() = m_xaxis.scalar_prod(pos0); - p0.ry() = m_yaxis.scalar_prod(pos0); - p1.rx() = m_xaxis.scalar_prod(pos1); - p1.ry() = m_yaxis.scalar_prod(pos1); - QVector vert; - vert << p1 << p0; - info->polygon = QPolygonF(vert); - doneRotation = true; - } - // add the detector - addDetector(*det, pos0, index, info->rotation); - } + const auto &detectorInfo = m_instrActor->getDetectorInfo(); + auto pos0 = detectorInfo.position(detectors[0]); + auto pos1 = detectorInfo.position(detectors[1]) - pos0; + + info->rotation = calcBankRotation(pos0, normal); + info->rotation.rotate(pos1); + pos1 += pos0; + QPointF p0(m_xaxis.scalar_prod(pos0), m_yaxis.scalar_prod(pos0)); + QPointF p1(m_xaxis.scalar_prod(pos1), m_yaxis.scalar_prod(pos1)); + QVector vert; + vert << p1 << p0; + info->polygon = QPolygonF(vert); + + for (auto detector : detectors) { + addDetector(detector, pos0, index, info->rotation); // update the outline polygon - UnwrappedDetector &udet0 = *(m_unwrappedDetectors.end() - nelem); - UnwrappedDetector &udet1 = m_unwrappedDetectors.back(); - // get the tube end points - QPointF p3 = QPointF(udet0.u, udet0.v); - QPointF p4 = QPointF(udet1.u, udet1.v); - QVector vert; - // add a quadrilateral formed by end points of two nearest tubes - // assumption is made here that any two adjacent tubes in an assembly's - // children's list - // are close to each other - vert << p0 << p1 << p4 << p3; + UnwrappedDetector &udet = *(m_unwrappedDetectors.end() - 1); + auto p2 = QPointF(udet.u, udet.v); + vert.clear(); + vert << p0 << p1 << p2; info->polygon = info->polygon.united(QPolygonF(vert)); - p0 = p3; - p1 = p4; } // record the end detector index of the bank info->endDetectorIndex = m_unwrappedDetectors.size(); } -/** -* Add a flat bank from an assembly of detectors. -* @param bankId :: Component ID of the bank. -* @param normal :: Normal vector to the bank's plane. -* @param detectors :: List of component IDs. Each component must cast to -* Detector. -*/ -void PanelsSurface::addFlatBankOfDetectors(ComponentID bankId, - const Mantid::Kernel::V3D &normal, - QList detectors) { +void PanelsSurface::processStructured(const std::vector &children, + size_t rootIndex) { int index = m_flatBanks.size(); + const auto &componentInfo = m_instrActor->getComponentInfo(); + auto corners = retrievePanelCorners(componentInfo, rootIndex); + auto normal = calculatePanelNormal(corners); // save bank info FlatBankInfo *info = new FlatBankInfo(this); m_flatBanks << info; - info->id = bankId; + // set bank ID + info->id = componentInfo.componentID(rootIndex)->getComponentID(); + // find the rotation to put the bank on the plane + info->rotation = calcBankRotation(corners[0], normal); // record the first detector index of the bank info->startDetectorIndex = m_unwrappedDetectors.size(); - int nelem = detectors.size(); - m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); - - // keep reference position on the bank's plane - Mantid::Kernel::V3D pos0, pos1; - QPointF p0, p1; - Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument(); - // loop over the detectors - for (int i = 0; i < detectors.size(); ++i) { - ComponentID id = detectors[i]; - auto det = boost::dynamic_pointer_cast( - instr->getComponentByID(id)); - - if (i == 0) { - pos0 = det->getPos(); - } else if (i == 1) { - // find the rotation to put the bank on the plane - info->rotation = calcBankRotation(pos0, normal); - pos1 = det->getPos(); - pos1 -= pos0; - info->rotation.rotate(pos1); - pos1 += pos0; - // start forming the outline polygon - p0.rx() = m_xaxis.scalar_prod(pos0); - p0.ry() = m_yaxis.scalar_prod(pos0); - p1.rx() = m_xaxis.scalar_prod(pos1); - p1.ry() = m_yaxis.scalar_prod(pos1); - QVector vert; - vert << p1 << p0; - info->polygon = QPolygonF(vert); - } - // add the detector - addDetector(*det, pos0, index, info->rotation); - // update the outline polygon - UnwrappedDetector &udet = *(m_unwrappedDetectors.end() - 1); - QPointF p2 = QPointF(udet.u, udet.v); - QVector vert; - vert << p0 << p1 << p2; - info->polygon = info->polygon.united(QPolygonF(vert)); + // set the outline + QVector verts; + for (auto &corner : corners) { + auto pos = corner - corners[0]; + info->rotation.rotate(pos); + pos += corners[0]; + verts << QPointF(pos.X(), pos.Y()); } - // record the end detector index of the bank - info->endDetectorIndex = m_unwrappedDetectors.size(); -} + info->polygon = QPolygonF(verts); -/** -* Add a component assembly containing a flat array of ObjCompAssemblies. -* @param bankId :: Component id of an assembly. -*/ -void PanelsSurface::addObjCompAssemblies(ComponentID bankId) { - Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument(); - boost::shared_ptr assembly = - boost::dynamic_pointer_cast( - instr->getComponentByID(bankId)); - - size_t nelem = static_cast(assembly->nelements()); - // assemblies with one element cannot be flat (but its element can be) - if (nelem == 1) { - return; - } + auto nelem = children.size(); + m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); - QList objCompAssemblies; - // normal to the plane, undefined at first - Mantid::Kernel::V3D normal(0, 0, 0); - Mantid::Kernel::V3D x, y, pos; - for (size_t i = 0; i < nelem; ++i) { - auto elem = assembly->getChild((int)i); - ObjCompAssembly *objCompAssembly = - dynamic_cast(elem.get()); - if (!objCompAssembly) { - CompAssembly *compAssembly = dynamic_cast(elem.get()); - if (!compAssembly || compAssembly->nelements() != 1) { - // m_surface.g_log.warning() << "Not a CompAssembly\n"; - addCompAssembly(bankId); - return; - } - elem = compAssembly->getChild(0); - objCompAssembly = dynamic_cast(elem.get()); - if (!objCompAssembly) { - // m_surface.g_log.warning() << "Not a ObjCompAssembly\n"; - return; - } - } - if (i == 0) { - pos = objCompAssembly->getChild(0)->getPos(); - x = objCompAssembly->getChild(1)->getPos() - pos; - x.normalize(); - } else if (i == 1) { - y = objCompAssembly->getChild(0)->getPos() - pos; - y.normalize(); - normal = x.cross_prod(y); - if (normal.nullVector()) { - y = objCompAssembly->getChild(1)->getPos() - - objCompAssembly->getChild(0)->getPos(); - y.normalize(); - normal = x.cross_prod(y); - } - if (normal.nullVector()) { - g_log.warning() << "Colinear ObjCompAssemblies\n"; - return; - } - normal.normalize(); - } else { - Mantid::Kernel::V3D vector = objCompAssembly->getChild(0)->getPos() - - objCompAssembly->getChild(1)->getPos(); - vector.normalize(); - if (fabs(vector.scalar_prod(normal)) > Mantid::Kernel::Tolerance) { - g_log.warning() << "Assembly " << assembly->getName() - << " isn't flat.\n"; - return; - } - } - objCompAssemblies << objCompAssembly->getComponentID(); - } - if (!objCompAssemblies.isEmpty()) { - addFlatBank(assembly->getComponentID(), normal, objCompAssemblies); - } + for (auto child : children) + addDetector(child, corners[0], index, info->rotation); + // record the end detector index of the bank + info->endDetectorIndex = m_unwrappedDetectors.size(); } -/** -* Add an assembly if its detectors are in the same plane. -* @param bankId :: Component id of an assembly. -*/ -void PanelsSurface::addCompAssembly(ComponentID bankId) { - Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument(); - boost::shared_ptr assembly = - boost::dynamic_pointer_cast( - instr->getComponentByID(bankId)); - - size_t nelem = static_cast(assembly->nelements()); - // normal to the plane, undefined at first - Mantid::Kernel::V3D normal, x, y; +std::pair, Mantid::Kernel::V3D> +PanelsSurface::processUnstructured(const std::vector &children, + size_t rootIndex, + std::vector &visited) { + Mantid::Kernel::V3D normal; + const auto &detectorInfo = m_instrActor->getDetectorInfo(); Mantid::Kernel::V3D pos0; + Mantid::Kernel::V3D x, y; bool normalFound = false; - QList detectors; - const auto &detectorInfo = m_instrActor->getWorkspace()->detectorInfo(); - for (size_t i = 0; i < nelem; ++i) { - auto elem = assembly->getChild((int)i); - Mantid::Geometry::IDetector_const_sptr det = - boost::dynamic_pointer_cast(elem); - if (!det) { - return; - } - size_t detIndex = detectorInfo.indexOf(det->getID()); - if (detectorInfo.isMonitor(detIndex)) + const auto &componentInfo = m_instrActor->getComponentInfo(); + std::vector detectors; + detectors.reserve(children.size()); + for (auto child : children) { + if (visited[child]) + continue; + visited[child] = true; + + if (detectorInfo.isMonitor(child)) continue; - Mantid::Kernel::V3D pos = detectorInfo.position(detIndex); - if (i == 0) { + auto pos = detectorInfo.position(child); + if (child == children[0]) pos0 = pos; - } else if (i == 1) { + else if (child == children[1]) { // at first set the normal to an argbitrary vector orthogonal to // the line between the first two detectors y = pos - pos0; @@ -525,178 +284,64 @@ void PanelsSurface::addCompAssembly(ComponentID bankId) { x = y.cross_prod(normal); normalFound = true; } else { - g_log.warning() << "Assembly " << assembly->getName() - << " isn't flat.\n"; - return; + // TODO: Replace somehow with componentInfo name method. + /*g_log.warning() << "Assembly " << componentInfo->name(rootIndex) + << " isn't flat.\n";*/ + break; } } - detectors << det->getComponentID(); + detectors.push_back(child); } + return std::make_pair(detectors, normal); +} - // normalFound doesn't have to be true at this point - // if it is false then the normal was found by the first guess +boost::optional, Mantid::Kernel::V3D>> +PanelsSurface::findFlatPanels(size_t rootIndex, + const std::vector &children, + std::vector &visited) { + const auto &componentInfo = m_instrActor->getComponentInfo(); + auto parentIndex = componentInfo.parent(rootIndex); - // add the detectors - if (!detectors.isEmpty()) { - addFlatBankOfDetectors(bankId, normal, detectors); + if (componentInfo.isStructuredBank(parentIndex)) { + /* Do nothing until the root index of the structured bank. */ + return boost::none; } + + if (componentInfo.isStructuredBank(rootIndex)) { + processStructured(children, rootIndex); + for (auto child : children) + visited[child] = true; + return boost::none; + } + + return processUnstructured(children, rootIndex, visited); } void PanelsSurface::constructFromComponentInfo() { const auto componentInfo = m_instrActor->getComponentInfo(); std::vector visited(componentInfo.size(), false); - const auto &detectorInfo = m_instrActor->getDetectorInfo(); - for (size_t i = 0; i < componentInfo.size(); ++i) { + for (size_t i = 0; i < componentInfo.size()-1; ++i) { auto children = componentInfo.detectorsInSubtree(i); if (children.size() > 1) { - auto res = searchFlatPanels(componentInfo, detectorInfo, i, children, visited); - auto detectors = res.first; - auto normal = res.second; - if (!detectors.isEmpty()) - addFlatBankOfDetectors(componentInfo.componentID(i)->getComponentID(), - normal, detectors); + auto res = findFlatPanels(i, children, visited); + if (res != boost::none) { + std::vector detectors; + Mantid::Kernel::V3D normal; + std::tie(detectors, normal) = res.get(); + if (!detectors.empty()) + addFlatBankOfDetectors(componentInfo.componentID(i)->getComponentID(), + normal, detectors); + } + } else if (children.size() > 0 && + componentInfo.parent(children[0]) == componentInfo.root()) { + auto child = children[0]; + visited[child] = true; } } } -/** -* Add a rectangular detector which is flat. -* @param bankId :: Component id of a rectangular detector. -*/ -void PanelsSurface::addRectangularDetector(ComponentID bankId) { - Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument(); - Mantid::Geometry::RectangularDetector_const_sptr rectDetector = - boost::dynamic_pointer_cast( - instr->getComponentByID(bankId)); - - int nx = rectDetector->xpixels(); - int ny = rectDetector->ypixels(); - Mantid::Kernel::V3D pos0 = rectDetector->getAtXY(0, 0)->getPos(); - Mantid::Kernel::V3D pos1 = rectDetector->getAtXY(nx - 1, 0)->getPos(); - Mantid::Kernel::V3D pos2 = rectDetector->getAtXY(nx - 1, ny - 1)->getPos(); - Mantid::Kernel::V3D pos3 = rectDetector->getAtXY(0, ny - 1)->getPos(); - - // find the normal - Mantid::Kernel::V3D xaxis = pos1 - pos0; - Mantid::Kernel::V3D yaxis = pos3 - pos0; - Mantid::Kernel::V3D normal = xaxis.cross_prod(yaxis); - normal.normalize(); - - int index = m_flatBanks.size(); - // save bank info - FlatBankInfo *info = new FlatBankInfo(this); - m_flatBanks << info; - info->id = bankId; - // find the rotation to put the bank on the plane - info->rotation = calcBankRotation(pos0, normal); - // record the first detector index of the bank - info->startDetectorIndex = m_unwrappedDetectors.size(); - // set the outline - QVector verts; - Mantid::Kernel::V3D pos = pos0; - verts << QPointF(pos.X(), pos.Y()); - - pos = pos1 - pos0; - info->rotation.rotate(pos); - pos += pos0; - verts << QPointF(pos.X(), pos.Y()); - - pos = pos2 - pos0; - info->rotation.rotate(pos); - pos += pos0; - verts << QPointF(pos.X(), pos.Y()); - - pos = pos3 - pos0; - info->rotation.rotate(pos); - pos += pos0; - verts << QPointF(pos.X(), pos.Y()); - - info->polygon = QPolygonF(verts); - - int nelem = rectDetector->nelements(); - m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); - - for (int i = 0; i < nx; ++i) - for (int j = 0; j < ny; ++j) { - Mantid::Geometry::IDetector_const_sptr det = rectDetector->getAtXY(i, j); - addDetector(*det, pos0, index, info->rotation); - } - - // record the end detector index of the bank - info->endDetectorIndex = m_unwrappedDetectors.size(); -} - -/** -* Add a structured detector which is flat. -* @param bankId :: Component id of a structured detector. -*/ -void PanelsSurface::addStructuredDetector( - Mantid::Geometry::ComponentID bankId) { - Mantid::Geometry::Instrument_const_sptr instr = m_instrActor->getInstrument(); - Mantid::Geometry::StructuredDetector_const_sptr structDetector = - boost::dynamic_pointer_cast( - instr->getComponentByID(bankId)); - - auto nx = structDetector->xPixels(); - auto ny = structDetector->yPixels(); - Mantid::Kernel::V3D pos0 = structDetector->getAtXY(0, 0)->getPos(); - Mantid::Kernel::V3D pos1 = structDetector->getAtXY(nx - 1, 0)->getPos(); - Mantid::Kernel::V3D pos2 = structDetector->getAtXY(nx - 1, ny - 1)->getPos(); - Mantid::Kernel::V3D pos3 = structDetector->getAtXY(0, ny - 1)->getPos(); - - // find the normal - Mantid::Kernel::V3D xaxis = pos1 - pos0; - Mantid::Kernel::V3D yaxis = pos3 - pos0; - Mantid::Kernel::V3D normal = xaxis.cross_prod(yaxis); - normal.normalize(); - - int index = m_flatBanks.size(); - // save bank info - FlatBankInfo *info = new FlatBankInfo(this); - m_flatBanks << info; - info->id = bankId; - // find the rotation to put the bank on the plane - info->rotation = calcBankRotation(pos0, normal); - // record the first detector index of the bank - info->startDetectorIndex = m_unwrappedDetectors.size(); - // set the outline - QVector verts; - Mantid::Kernel::V3D pos = pos0; - verts << QPointF(pos.X(), pos.Y()); - - pos = pos1 - pos0; - info->rotation.rotate(pos); - pos += pos0; - verts << QPointF(pos.X(), pos.Y()); - - pos = pos2 - pos0; - info->rotation.rotate(pos); - pos += pos0; - verts << QPointF(pos.X(), pos.Y()); - - pos = pos3 - pos0; - info->rotation.rotate(pos); - pos += pos0; - verts << QPointF(pos.X(), pos.Y()); - - info->polygon = QPolygonF(verts); - - int nelem = structDetector->nelements(); - m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); - - for (size_t i = 0; i < nx; ++i) - for (size_t j = 0; j < ny; ++j) { - Mantid::Geometry::IDetector_const_sptr det = - structDetector->getAtXY(i, j); - addDetector(*det, pos0, index, info->rotation); - } - - // record the end detector index of the bank - info->endDetectorIndex = m_unwrappedDetectors.size(); -} - /** * Calculate the rotation needed to place a bank on the projection plane. * @@ -723,17 +368,21 @@ PanelsSurface::calcBankRotation(const Mantid::Kernel::V3D &detPos, return Mantid::Kernel::Quat(normal, m_zaxis); } -void PanelsSurface::addDetector(const Mantid::Geometry::IDetector &det, +void PanelsSurface::addDetector(size_t detIndex, const Mantid::Kernel::V3D &refPos, int index, Mantid::Kernel::Quat &rotation) { - // setup detector info - Mantid::Kernel::V3D pos = det.getPos(); - Mantid::detid_t detid = det.getID(); + const auto &detectorInfo = m_instrActor->getDetectorInfo(); + const auto &componentInfo = m_instrActor->getComponentInfo(); + + Mantid::Kernel::V3D pos = detectorInfo.position(detIndex); + Mantid::detid_t detid = detectorInfo.detectorIDs()[detIndex]; m_detector2bankMap[detid] = index; // get the colour unsigned char color[3]; m_instrActor->getColor(detid).getUB3(&color[0]); - UnwrappedDetector udet(color, det); + UnwrappedDetector udet( + color[0], color[1], color[2], detid, pos, detectorInfo.rotation(detIndex), + componentInfo.scaleFactor(detIndex), componentInfo.shape(detIndex)); // apply bank's rotation pos -= refPos; rotation.rotate(pos); diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 0f3bea59cdd2..268db12e4489 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -1,4 +1,5 @@ #include "MantidQtWidgets/InstrumentView/RotationSurface.h" +#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" #include "MantidKernel/Logger.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidGeometry/Instrument/DetectorInfo.h" diff --git a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp index ce2f3e4277af..a71d13a2b2fd 100644 --- a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp @@ -1,4 +1,5 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedCylinder.h" +#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" #include "MantidGeometry/IDetector.h" diff --git a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp new file mode 100644 index 000000000000..e06e1bf7c557 --- /dev/null +++ b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp @@ -0,0 +1,70 @@ +#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" +#include "MantidGeometry/IDetector.h" +#include "MantidGeometry/Objects/Object.h" + +using namespace Mantid::Geometry; + +namespace MantidQt { +namespace MantidWidgets { + +UnwrappedDetector::UnwrappedDetector() + : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(0) { + color[0] = 0; + color[1] = 0; + color[2] = 0; +} + +UnwrappedDetector::UnwrappedDetector(const unsigned char *c, + const IDetector &det) + : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(det.getID()), + position(det.getPos()), rotation(det.getRotation()), shape(det.shape()), + scaleFactor(det.getScaleFactor()) { + color[0] = *c; + color[1] = *(c + 1); + color[2] = *(c + 2); +} + +UnwrappedDetector::UnwrappedDetector(unsigned char r, unsigned char g, + unsigned char b, Mantid::detid_t detID, + const Mantid::Kernel::V3D &pos, + const Mantid::Kernel::Quat &rot, + const Mantid::Kernel::V3D &scaleFactor, + boost::shared_ptr shape) + : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(detID), + position(pos), rotation(rot), scaleFactor(scaleFactor) { + color[0] = r; + color[1] = g; + color[2] = b; + + this->shape = shape; +} + +/** Copy constructor */ +UnwrappedDetector::UnwrappedDetector(const UnwrappedDetector &other) { + this->operator=(other); +} + +/** Assignment operator */ +UnwrappedDetector &UnwrappedDetector:: +operator=(const UnwrappedDetector &other) { + color[0] = other.color[0]; + color[1] = other.color[1]; + color[2] = other.color[2]; + u = other.u; + v = other.v; + width = other.width; + height = other.height; + uscale = other.uscale; + vscale = other.vscale; + detID = other.detID; + position = other.position; + rotation = other.rotation; + shape = other.shape; + scaleFactor = other.scaleFactor; + return *this; +} + +/** Check if the object is valid*/ +bool UnwrappedDetector::isValid() const { return static_cast(shape); } +} // namespace MantidWidgets +} // namespace MantidQt \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp index 71ad108ce3c7..d5f5d53e5640 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp @@ -1,4 +1,5 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedSphere.h" +#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" #include "MantidGeometry/IDetector.h" #include diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 5bf94a32d8d1..1eeb59a8927c 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -1,4 +1,5 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedSurface.h" +#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" #include "MantidQtWidgets/InstrumentView/GLColor.h" #include "MantidQtWidgets/InstrumentView/MantidGLWidget.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" @@ -6,73 +7,24 @@ #include "MantidAPI/IPeaksWorkspace.h" #include "MantidGeometry/IDetector.h" +#include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Objects/CSGObject.h" #include "MantidQtWidgets/Common/InputController.h" -#include -#include #include #include #include -#include #include #include #include #include -#include "MantidKernel/Exception.h" using namespace Mantid::Geometry; namespace MantidQt { namespace MantidWidgets { - -UnwrappedDetector::UnwrappedDetector() - : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(0) { - color[0] = 0; - color[1] = 0; - color[2] = 0; -} - -UnwrappedDetector::UnwrappedDetector(const unsigned char *c, - const IDetector &det) - : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(det.getID()), - position(det.getPos()), rotation(det.getRotation()), shape(det.shape()), - scaleFactor(det.getScaleFactor()) { - color[0] = *c; - color[1] = *(c + 1); - color[2] = *(c + 2); -} - -/** Copy constructor */ -UnwrappedDetector::UnwrappedDetector(const UnwrappedDetector &other) { - this->operator=(other); -} - -/** Assignment operator */ -UnwrappedDetector &UnwrappedDetector:: -operator=(const UnwrappedDetector &other) { - color[0] = other.color[0]; - color[1] = other.color[1]; - color[2] = other.color[2]; - u = other.u; - v = other.v; - width = other.width; - height = other.height; - uscale = other.uscale; - vscale = other.vscale; - detID = other.detID; - position = other.position; - rotation = other.rotation; - shape = other.shape; - scaleFactor = other.scaleFactor; - return *this; -} - -/** Check if the object is valid*/ -bool UnwrappedDetector::isValid() const { return static_cast(shape); } - /** * Constructor. * @param rootActor :: The instrument actor. From 27b25b3677cfe1aa18eb390f6893ad1d32ebe4f0 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 2 Jan 2018 11:20:45 +0000 Subject: [PATCH 030/364] modifications to UnwrappedDetector interface re #21339 --- .../Geometry/test/InstrumentVisitorTest.h | 6 ++-- .../InstrumentView/InstrumentActor.h | 2 ++ .../InstrumentView/UnwrappedDetector.h | 16 +++++----- .../instrumentview/src/InstrumentActor.cpp | 7 +++++ .../instrumentview/src/PanelsSurface.cpp | 18 +++++------ .../instrumentview/src/RotationSurface.cpp | 26 ++++++++-------- .../instrumentview/src/UnwrappedDetector.cpp | 30 ++++--------------- .../instrumentview/src/UnwrappedSurface.cpp | 16 +++++----- 8 files changed, 53 insertions(+), 68 deletions(-) diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index 3a656cf489f6..5d549a821dc8 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -372,15 +372,15 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { // Instrument const auto &instrumentShape = componentInfo->shape(componentInfo->root()); TSM_ASSERT("CompAssemblies should have no shape", - !instrumentShape.hasValidShape()); + !instrumentShape->hasValidShape()); // Bank 1 const auto &subAssemblyShape = componentInfo->shape(componentInfo->root() - 3); TSM_ASSERT("CompAssemblies should have no shape", - !subAssemblyShape.hasValidShape()); + !subAssemblyShape->hasValidShape()); const auto &detectorShape = componentInfo->shape(0 /*Is a detector index!*/); - TSM_ASSERT("Detectors should have a shape", detectorShape.hasValidShape()); + TSM_ASSERT("Detectors should have a shape", detectorShape->hasValidShape()); // Check shapes are re-used as expected TSM_ASSERT_EQUALS("Shape object should be reused", &instrumentShape, diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index f400e4685d26..4edb931f4071 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -159,6 +159,8 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { const std::vector &getAllDetIDs() const; /// Get displayed color of a detector by its detector ID. GLColor getColor(Mantid::detid_t id) const; + /// Get displayed color of a detector by its index. + GLColor getColor(size_t index) const; /// Get the workspace index of a detector by its detector ID. size_t getWorkspaceIndex(Mantid::detid_t id) const; /// Get the integrated counts of a detector by its detector ID. diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h index fa0cbbb1ea3c..e87bc06f0a55 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h @@ -5,17 +5,17 @@ #include "MantidKernel/Quat.h" #include "MantidKernel/V3D.h" #include +#include "MantidQtWidgets/InstrumentView/GLColor.h" namespace Mantid { namespace Geometry { class IDetector; -class Object; +class IObject; } // namespace Geometry } // namespace Mantid namespace MantidQt { namespace MantidWidgets { - /** \class UnwrappedDetector \brief Class helper for drawing detectors on unwraped surfaces @@ -28,17 +28,15 @@ This class keeps information used to draw a detector on an unwrapped surface. class UnwrappedDetector { public: UnwrappedDetector(); - UnwrappedDetector(const unsigned char *c, - const Mantid::Geometry::IDetector &det); - UnwrappedDetector(unsigned char r, unsigned char g, unsigned char b, - Mantid::detid_t detID, const Mantid::Kernel::V3D &pos, + UnwrappedDetector(GLColor color, Mantid::detid_t detID, + const Mantid::Kernel::V3D &pos, const Mantid::Kernel::Quat &rot, const Mantid::Kernel::V3D &scaleFactor, - boost::shared_ptr shape); + boost::shared_ptr shape); UnwrappedDetector(const UnwrappedDetector &other); UnwrappedDetector &operator=(const UnwrappedDetector &other); bool isValid() const; - unsigned char color[3]; ///< red, green, blue colour components (0 - 255) + GLColor color; ///< red, green, blue colour components (0 - 255) double u; ///< horizontal "unwrapped" coordinate double v; ///< vertical "unwrapped" coordinate double width; ///< detector width in units of u @@ -48,7 +46,7 @@ class UnwrappedDetector { Mantid::detid_t detID; ///< Detector ID Mantid::Kernel::V3D position; ///< Detector position Mantid::Kernel::Quat rotation; ///< Detector orientation - boost::shared_ptr + boost::shared_ptr shape; ///< Shape of the detector Mantid::Kernel::V3D scaleFactor; ///< Detector's scale factor }; diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index a1c0cde6d2f4..a50c70bf9394 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -750,6 +750,13 @@ GLColor InstrumentActor::getColor(Mantid::detid_t id) const { } } +GLColor InstrumentActor::getColor(size_t index) const { + if (index <= m_colors.size() - 1) + return m_colors.at(index); + + return m_colors.front(); +} + void InstrumentActor::draw(bool picking) const { if (std::none_of(m_isCompVisible.cbegin(), m_isCompVisible.cend(), [](bool visible) { return visible; })) diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index c42c5a3d0124..6f41c8e1e6ae 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -180,7 +180,7 @@ void PanelsSurface::addFlatBankOfDetectors( info->id = bankId; // record the first detector index of the bank info->startDetectorIndex = m_unwrappedDetectors.size(); - int nelem = detectors.size(); + auto nelem = detectors.size(); m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); // keep reference position on the bank's plane @@ -284,9 +284,8 @@ PanelsSurface::processUnstructured(const std::vector &children, x = y.cross_prod(normal); normalFound = true; } else { - // TODO: Replace somehow with componentInfo name method. - /*g_log.warning() << "Assembly " << componentInfo->name(rootIndex) - << " isn't flat.\n";*/ + g_log.warning() << "Assembly " << componentInfo.name(rootIndex) + << " isn't flat.\n"; break; } } @@ -318,7 +317,7 @@ PanelsSurface::findFlatPanels(size_t rootIndex, } void PanelsSurface::constructFromComponentInfo() { - const auto componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->getComponentInfo(); std::vector visited(componentInfo.size(), false); for (size_t i = 0; i < componentInfo.size()-1; ++i) { @@ -378,11 +377,10 @@ void PanelsSurface::addDetector(size_t detIndex, Mantid::detid_t detid = detectorInfo.detectorIDs()[detIndex]; m_detector2bankMap[detid] = index; // get the colour - unsigned char color[3]; - m_instrActor->getColor(detid).getUB3(&color[0]); - UnwrappedDetector udet( - color[0], color[1], color[2], detid, pos, detectorInfo.rotation(detIndex), - componentInfo.scaleFactor(detIndex), componentInfo.shape(detIndex)); + UnwrappedDetector udet(m_instrActor->getColor(detIndex), detid, pos, + detectorInfo.rotation(detIndex), + componentInfo.scaleFactor(detIndex), + componentInfo.shape(detIndex)); // apply bank's rotation pos -= refPos; rotation.rotate(pos); diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 268db12e4489..582d2d7ef12b 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -3,6 +3,7 @@ #include "MantidKernel/Logger.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidGeometry/Instrument/DetectorInfo.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include #include @@ -79,8 +80,8 @@ void RotationSurface::init() { m_u_min = -DBL_MAX; m_u_max = DBL_MAX; - const auto &detectorInfo = m_instrActor->getWorkspace()->detectorInfo(); - + const auto &detectorInfo = m_instrActor->getDetectorInfo(); + const auto &componentInfo = m_instrActor->getComponentInfo(); // Set if one of the threads in the following loop // throws an exception bool exceptionThrown = false; @@ -93,13 +94,8 @@ void RotationSurface::init() { try { size_t i = size_t(ii); - unsigned char color[3]; - Mantid::detid_t id = m_instrActor->getDetID(i); - + auto id = m_instrActor->getDetID(i); try { - auto &det = - m_instrActor->getDetectorByDetID(id); - if (detectorInfo.isMonitor( detectorInfo.indexOf(id)) || (id < 0)) { @@ -109,19 +105,23 @@ void RotationSurface::init() { m_unwrappedDetectors[i] = UnwrappedDetector(); } else { // A real detector. - m_instrActor->getColor(id).getUB3(&color[0]); - // Position, relative to origin // Mantid::Kernel::V3D pos = det->getPos() - // m_pos; - Mantid::Kernel::V3D pos = + Mantid::Kernel::V3D rpos = m_instrActor->getDetPos(i) - m_pos; + auto pos = detectorInfo.position(i); + auto rot = detectorInfo.rotation(i); + auto scaleFactor = componentInfo.scaleFactor(i); + auto shape = componentInfo.shape(i); // Create the unwrapped shape - UnwrappedDetector udet(&color[0], det); + UnwrappedDetector udet( + m_instrActor->getColor(i), id, pos, rot, + scaleFactor, shape); // Calculate its position/size in UV // coordinates - this->calcUV(udet, pos); + this->calcUV(udet, rpos); m_unwrappedDetectors[i] = udet; } // is a real detector diff --git a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp index e06e1bf7c557..7b84bc7ed2f4 100644 --- a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp @@ -1,6 +1,6 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" #include "MantidGeometry/IDetector.h" -#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Objects/CSGObject.h" using namespace Mantid::Geometry; @@ -9,33 +9,17 @@ namespace MantidWidgets { UnwrappedDetector::UnwrappedDetector() : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(0) { - color[0] = 0; - color[1] = 0; - color[2] = 0; + color = GLColor(0, 0, 0); } -UnwrappedDetector::UnwrappedDetector(const unsigned char *c, - const IDetector &det) - : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(det.getID()), - position(det.getPos()), rotation(det.getRotation()), shape(det.shape()), - scaleFactor(det.getScaleFactor()) { - color[0] = *c; - color[1] = *(c + 1); - color[2] = *(c + 2); -} - -UnwrappedDetector::UnwrappedDetector(unsigned char r, unsigned char g, - unsigned char b, Mantid::detid_t detID, +UnwrappedDetector::UnwrappedDetector(GLColor color, Mantid::detid_t detID, const Mantid::Kernel::V3D &pos, const Mantid::Kernel::Quat &rot, const Mantid::Kernel::V3D &scaleFactor, - boost::shared_ptr shape) + boost::shared_ptr shape) : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(detID), position(pos), rotation(rot), scaleFactor(scaleFactor) { - color[0] = r; - color[1] = g; - color[2] = b; - + this->color = color; this->shape = shape; } @@ -47,9 +31,7 @@ UnwrappedDetector::UnwrappedDetector(const UnwrappedDetector &other) { /** Assignment operator */ UnwrappedDetector &UnwrappedDetector:: operator=(const UnwrappedDetector &other) { - color[0] = other.color[0]; - color[1] = other.color[1]; - color[2] = other.color[2]; + color = other.color; u = other.u; v = other.v; width = other.width; diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 1eeb59a8927c..4c2477f89e75 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -239,12 +239,14 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { */ void UnwrappedSurface::setColor(int index, bool picking) const { if (picking) { - GLColor c = GLActor::makePickColor(index); + auto c = GLActor::makePickColor(index); unsigned char r, g, b; c.get(r, g, b); glColor3ub(r, g, b); } else { - glColor3ubv(&m_unwrappedDetectors[index].color[0]); + unsigned char col[3]; + m_unwrappedDetectors[index].color.getUB3(&col[0]); + glColor3ub(col[0], col[1], col[2]); } } @@ -389,11 +391,7 @@ void UnwrappedSurface::getMaskedDetectors(QList &dets) const { void UnwrappedSurface::changeColorMap() { for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { UnwrappedDetector &udet = m_unwrappedDetectors[i]; - unsigned char color[3]; - m_instrActor->getColor(udet.detID).getUB3(&color[0]); - udet.color[0] = color[0]; - udet.color[1] = color[1]; - udet.color[2] = color[2]; + udet.color = m_instrActor->getColor(udet.detID); } } @@ -522,8 +520,8 @@ void UnwrappedSurface::drawSimpleToImage(QImage *image, bool picking) const { c.get(r, g, b); color = QColor(r, g, b); } else { - auto c = &m_unwrappedDetectors[index].color[0]; - color = QColor(c[0], c[1], c[2]); + auto c = m_unwrappedDetectors[index].color; + color = QColor(c.red(), c.green(), c.blue()); } paint.fillRect(u - iw / 2, v - ih / 2, iw, ih, color); From 30513af52edfbd8532e938ea6324e7ab4f71d039 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 2 Jan 2018 11:35:29 +0000 Subject: [PATCH 031/364] Get color only by det index re #21339 --- .../MantidQtWidgets/InstrumentView/InstrumentActor.h | 2 -- .../InstrumentView/UnwrappedDetector.h | 3 ++- qt/widgets/instrumentview/src/InstrumentActor.cpp | 11 ----------- qt/widgets/instrumentview/src/PanelsSurface.cpp | 2 +- qt/widgets/instrumentview/src/RotationSurface.cpp | 4 ++-- qt/widgets/instrumentview/src/UnwrappedDetector.cpp | 8 ++++++-- qt/widgets/instrumentview/src/UnwrappedSurface.cpp | 2 +- 7 files changed, 12 insertions(+), 20 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 4edb931f4071..75f15b37f122 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -157,8 +157,6 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { const Mantid::Kernel::V3D getDetPos(size_t pickID) const; /// Get a vector of IDs of all detectors in the instrument. const std::vector &getAllDetIDs() const; - /// Get displayed color of a detector by its detector ID. - GLColor getColor(Mantid::detid_t id) const; /// Get displayed color of a detector by its index. GLColor getColor(size_t index) const; /// Get the workspace index of a detector by its detector ID. diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h index e87bc06f0a55..fe946b43aeea 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h @@ -28,7 +28,7 @@ This class keeps information used to draw a detector on an unwrapped surface. class UnwrappedDetector { public: UnwrappedDetector(); - UnwrappedDetector(GLColor color, Mantid::detid_t detID, + UnwrappedDetector(GLColor color, Mantid::detid_t detID, size_t detIndex, const Mantid::Kernel::V3D &pos, const Mantid::Kernel::Quat &rot, const Mantid::Kernel::V3D &scaleFactor, @@ -44,6 +44,7 @@ class UnwrappedDetector { double uscale; ///< scaling factor in u direction double vscale; ///< scaling factor in v direction Mantid::detid_t detID; ///< Detector ID + size_t detIndex; ///< Detector Index in ComponentInfo/DetectorInfo. Mantid::Kernel::V3D position; ///< Detector position Mantid::Kernel::Quat rotation; ///< Detector orientation boost::shared_ptr diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index a50c70bf9394..925748aa1bfd 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -739,17 +739,6 @@ void InstrumentActor::showGuides(bool on) { m_showGuides = on; } -GLColor InstrumentActor::getColor(Mantid::detid_t id) const { - try { - size_t i = getDetectorInfo().indexOf(id); - return m_colors.at(i); - } catch (NotFoundError &) { - // Return the first color if the detector is not represented in the - // workspace - return m_colors.front(); - } -} - GLColor InstrumentActor::getColor(size_t index) const { if (index <= m_colors.size() - 1) return m_colors.at(index); diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 6f41c8e1e6ae..18a1fade7873 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -377,7 +377,7 @@ void PanelsSurface::addDetector(size_t detIndex, Mantid::detid_t detid = detectorInfo.detectorIDs()[detIndex]; m_detector2bankMap[detid] = index; // get the colour - UnwrappedDetector udet(m_instrActor->getColor(detIndex), detid, pos, + UnwrappedDetector udet(m_instrActor->getColor(detIndex), detid, detIndex, pos, detectorInfo.rotation(detIndex), componentInfo.scaleFactor(detIndex), componentInfo.shape(detIndex)); diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 582d2d7ef12b..3cf5b3bfc487 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -117,8 +117,8 @@ void RotationSurface::init() { auto shape = componentInfo.shape(i); // Create the unwrapped shape UnwrappedDetector udet( - m_instrActor->getColor(i), id, pos, rot, - scaleFactor, shape); + m_instrActor->getColor(i), id, i, pos, + rot, scaleFactor, shape); // Calculate its position/size in UV // coordinates this->calcUV(udet, rpos); diff --git a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp index 7b84bc7ed2f4..90c094a37353 100644 --- a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp @@ -8,17 +8,20 @@ namespace MantidQt { namespace MantidWidgets { UnwrappedDetector::UnwrappedDetector() - : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(0) { + : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(0), + detIndex(0) { color = GLColor(0, 0, 0); } UnwrappedDetector::UnwrappedDetector(GLColor color, Mantid::detid_t detID, + size_t detIndex, const Mantid::Kernel::V3D &pos, const Mantid::Kernel::Quat &rot, const Mantid::Kernel::V3D &scaleFactor, boost::shared_ptr shape) : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(detID), - position(pos), rotation(rot), scaleFactor(scaleFactor) { + detIndex(detIndex), position(pos), rotation(rot), + scaleFactor(scaleFactor) { this->color = color; this->shape = shape; } @@ -39,6 +42,7 @@ operator=(const UnwrappedDetector &other) { uscale = other.uscale; vscale = other.vscale; detID = other.detID; + detIndex = other.detIndex; position = other.position; rotation = other.rotation; shape = other.shape; diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 4c2477f89e75..9c04e841acc2 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -391,7 +391,7 @@ void UnwrappedSurface::getMaskedDetectors(QList &dets) const { void UnwrappedSurface::changeColorMap() { for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { UnwrappedDetector &udet = m_unwrappedDetectors[i]; - udet.color = m_instrActor->getColor(udet.detID); + udet.color = m_instrActor->getColor(udet.detIndex); } } From f3dad46cbc6a75c3462672a95e44e36106efd3e5 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 3 Jan 2018 09:26:34 +0000 Subject: [PATCH 032/364] mask tab fix and remove references to actors re #21339 --- qt/widgets/instrumentview/CMakeLists.txt | 18 --- .../InstrumentView/GLActorVisitor.h | 19 --- .../InstrumentView/InstrumentActor.h | 63 +------- .../instrumentview/src/GLActorVisitor.cpp | 60 -------- .../instrumentview/src/InstrumentActor.cpp | 134 ++++-------------- .../src/InstrumentTreeWidget.cpp | 3 +- 6 files changed, 31 insertions(+), 266 deletions(-) diff --git a/qt/widgets/instrumentview/CMakeLists.txt b/qt/widgets/instrumentview/CMakeLists.txt index 444bd0aff720..0e5b79584cb5 100644 --- a/qt/widgets/instrumentview/CMakeLists.txt +++ b/qt/widgets/instrumentview/CMakeLists.txt @@ -2,15 +2,11 @@ set ( SRC_FILES src/BinDialog.cpp src/CollapsiblePanel.cpp src/ColorMapWidget.cpp - src/CompAssemblyActor.cpp - src/ComponentActor.cpp src/DetXMLFile.cpp src/GLActor.cpp - src/GLActorCollection.cpp src/GLActorVisitor.cpp src/GLColor.cpp src/GLObject.cpp - src/ICompAssemblyActor.cpp src/InstrumentActor.cpp src/InstrumentTreeModel.cpp src/InstrumentTreeWidget.cpp @@ -22,8 +18,6 @@ set ( SRC_FILES src/InstrumentWidgetTreeTab.cpp src/MantidGLWidget.cpp src/MaskBinsData.cpp - src/ObjCompAssemblyActor.cpp - src/ObjComponentActor.cpp src/OneCurvePlot.cpp src/OpenGLError.cpp src/PanelsSurface.cpp @@ -32,13 +26,10 @@ set ( SRC_FILES src/Projection3D.cpp src/ProjectionSurface.cpp src/RectF.cpp - src/RectangularDetectorActor.cpp src/RotationSurface.cpp - src/SampleActor.cpp src/Shape2D.cpp src/Shape2DCollection.cpp src/SimpleWidget.cpp - src/StructuredDetectorActor.cpp src/UCorrectionDialog.cpp src/UnwrappedCylinder.cpp src/UnwrappedDetector.cpp @@ -76,16 +67,12 @@ set ( INC_FILES inc/MantidQtWidgets/InstrumentView/BinDialog.h inc/MantidQtWidgets/InstrumentView/CollapsiblePanel.h inc/MantidQtWidgets/InstrumentView/ColorMapWidget.h - inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h - inc/MantidQtWidgets/InstrumentView/ComponentActor.h inc/MantidQtWidgets/InstrumentView/DetXMLFile.h inc/MantidQtWidgets/InstrumentView/DllOption.h inc/MantidQtWidgets/InstrumentView/GLActor.h - inc/MantidQtWidgets/InstrumentView/GLActorCollection.h inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h inc/MantidQtWidgets/InstrumentView/GLColor.h inc/MantidQtWidgets/InstrumentView/GLObject.h - inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h inc/MantidQtWidgets/InstrumentView/InstrumentActor.h inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h @@ -98,8 +85,6 @@ set ( INC_FILES inc/MantidQtWidgets/InstrumentView/InstrumentWidgetTypes.h inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h inc/MantidQtWidgets/InstrumentView/MaskBinsData.h - inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h - inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h inc/MantidQtWidgets/InstrumentView/OneCurvePlot.h inc/MantidQtWidgets/InstrumentView/OpenGLError.h inc/MantidQtWidgets/InstrumentView/PanelsSurface.h @@ -108,13 +93,10 @@ set ( INC_FILES inc/MantidQtWidgets/InstrumentView/Projection3D.h inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h inc/MantidQtWidgets/InstrumentView/RectF.h - inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h inc/MantidQtWidgets/InstrumentView/RotationSurface.h - inc/MantidQtWidgets/InstrumentView/SampleActor.h inc/MantidQtWidgets/InstrumentView/Shape2D.h inc/MantidQtWidgets/InstrumentView/Shape2DCollection.h inc/MantidQtWidgets/InstrumentView/SimpleWidget.h - inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h inc/MantidQtWidgets/InstrumentView/UCorrectionDialog.h inc/MantidQtWidgets/InstrumentView/UnwrappedCylinder.h inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h index 401783ed5355..de82eb56f2be 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h @@ -4,12 +4,6 @@ namespace MantidQt { namespace MantidWidgets { class GLActor; -class GLActorCollection; -class ComponentActor; -class CompAssemblyActor; -class ObjCompAssemblyActor; -class RectangularDetectorActor; -class StructuredDetectorActor; class InstrumentActor; /** @@ -21,13 +15,7 @@ class GLActorVisitor { virtual ~GLActorVisitor() {} /// Abstract method that must be implemented in sub-classes virtual bool visit(GLActor *) = 0; - virtual bool visit(GLActorCollection *); - virtual bool visit(CompAssemblyActor *); - virtual bool visit(ObjCompAssemblyActor *); - virtual bool visit(ComponentActor *); virtual bool visit(InstrumentActor *); - virtual bool visit(RectangularDetectorActor *); - virtual bool visit(StructuredDetectorActor *); }; /** @@ -39,13 +27,7 @@ class GLActorConstVisitor { virtual ~GLActorConstVisitor() {} /// Abstract method that must be implemented in sub-classes virtual bool visit(const GLActor *) = 0; - virtual bool visit(const GLActorCollection *); - virtual bool visit(const CompAssemblyActor *); - virtual bool visit(const ObjCompAssemblyActor *); - virtual bool visit(const ComponentActor *); virtual bool visit(const InstrumentActor *); - virtual bool visit(const RectangularDetectorActor *); - virtual bool visit(const StructuredDetectorActor *); }; /* @@ -66,7 +48,6 @@ class SetAllVisibleVisitor : public SetVisibilityVisitor { explicit SetAllVisibleVisitor(bool showNonDet) : m_showNonDet(showNonDet) {} using GLActorVisitor::visit; bool visit(GLActor *) override; - bool visit(ComponentActor *actor) override; private: bool m_showNonDet; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 75f15b37f122..1f1a7e0cb640 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -3,7 +3,6 @@ #include "DllOption.h" #include "GLActor.h" -#include "GLActorCollection.h" #include "GLActorVisitor.h" #include "GLColor.h" #include "MantidAPI/MatrixWorkspace_fwd.h" @@ -34,7 +33,6 @@ class DetectorInfo; namespace MantidQt { namespace MantidWidgets { -class ObjComponentActor; /** \class InstrumentActor @@ -69,6 +67,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { /// Run visitors callback on each component (const version) bool accept(GLActorConstVisitor &visitor, VisitorAcceptRule rule = VisitAll) const override; + void setComponentVisible(Mantid::Geometry::ComponentID component); /// Toggle the visibility of the child actors (if exist). void setChildVisibility(bool) override; /// Check if any child is visible @@ -304,66 +303,6 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { //Two display lists for normal rendering and picking mutable GLuint m_displayListId[2]; mutable bool m_useDisplayList[2]; - - friend class ObjComponentActor; - friend class ObjCompAssemblyActor; - friend class RectangularDetectorActor; - friend class StructuredDetectorActor; -}; - -/** -* Sets visibility of an actor with a particular ComponentID -* and makes all other components invisible. -*/ -class SetVisibleComponentVisitor : public SetVisibilityVisitor { -public: - explicit SetVisibleComponentVisitor(const Mantid::Geometry::ComponentID id) - : m_id(id) {} - bool visit(GLActor *) override; - bool visit(GLActorCollection *) override; - bool visit(ComponentActor *actor) override; - bool visit(CompAssemblyActor *actor) override; - bool visit(ObjCompAssemblyActor *actor) override; - bool visit(InstrumentActor *actor) override; - bool visit(RectangularDetectorActor *actor) override; - bool visit(StructuredDetectorActor *actor) override; - Mantid::Geometry::ComponentID getID() const { return m_id; } - -private: - Mantid::Geometry::ComponentID m_id; -}; - -/** -* Set visibility of all actors of non-detector components. -* Pass true to constructor to set them visible and false to make them invisible. -*/ -class SetVisibleNonDetectorVisitor : public SetVisibilityVisitor { -public: - /// Constructor - /// @param on :: If true then all non-detectors will be made visible or - /// invisible if false. - explicit SetVisibleNonDetectorVisitor(bool on) : m_on(on) {} - using GLActorVisitor::visit; - bool visit(GLActor *) override; - -private: - bool m_on; -}; - -/** -* Finds an actor with a particular ComponentID -*/ -class FindComponentVisitor : public GLActorVisitor { -public: - explicit FindComponentVisitor(const Mantid::Geometry::ComponentID id) - : m_id(id), m_actor(nullptr) {} - using GLActorVisitor::visit; - bool visit(GLActor *) override; - ComponentActor *getActor() const { return m_actor; } - -private: - Mantid::Geometry::ComponentID m_id; - mutable ComponentActor *m_actor; }; } // MantidWidgets diff --git a/qt/widgets/instrumentview/src/GLActorVisitor.cpp b/qt/widgets/instrumentview/src/GLActorVisitor.cpp index 176bd6992502..1fa156dcf8c1 100644 --- a/qt/widgets/instrumentview/src/GLActorVisitor.cpp +++ b/qt/widgets/instrumentview/src/GLActorVisitor.cpp @@ -1,82 +1,22 @@ #include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" #include "MantidQtWidgets/InstrumentView/GLActor.h" -#include "MantidQtWidgets/InstrumentView/GLActorCollection.h" -#include "MantidQtWidgets/InstrumentView/ComponentActor.h" -#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h" -#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h" #include "MantidQtWidgets/InstrumentView/InstrumentActor.h" -#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h" -#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h" namespace MantidQt { namespace MantidWidgets { // Default visit implementations just call visit(GLActor*) -bool GLActorVisitor::visit(GLActorCollection *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorVisitor::visit(CompAssemblyActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorVisitor::visit(ObjCompAssemblyActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorVisitor::visit(ComponentActor *actor) { - return this->visit(static_cast(actor)); -} - bool GLActorVisitor::visit(InstrumentActor *actor) { return this->visit(static_cast(actor)); } -bool GLActorVisitor::visit(RectangularDetectorActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorVisitor::visit(StructuredDetectorActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorConstVisitor::visit(const GLActorCollection *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorConstVisitor::visit(const CompAssemblyActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorConstVisitor::visit(const ObjCompAssemblyActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorConstVisitor::visit(const ComponentActor *actor) { - return this->visit(static_cast(actor)); -} - bool GLActorConstVisitor::visit(const InstrumentActor *actor) { return this->visit(static_cast(actor)); } -bool GLActorConstVisitor::visit(const RectangularDetectorActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorConstVisitor::visit(const StructuredDetectorActor *actor) { - return this->visit(static_cast(actor)); -} - bool SetAllVisibleVisitor::visit(GLActor *actor) { actor->setVisibility(true); return true; } - -bool SetAllVisibleVisitor::visit(ComponentActor *actor) { - bool on = (!actor->isNonDetector()) || m_showNonDet; - actor->setVisibility(on); - return true; -} } // MantidWidgets } // MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 925748aa1bfd..b95107d9cfc4 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -1,12 +1,6 @@ #include "MantidQtWidgets/InstrumentView/InstrumentActor.h" #include "MantidQtWidgets/Common/TSVSerialiser.h" -#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h" -#include "MantidQtWidgets/InstrumentView/ComponentActor.h" #include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" -#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h" -#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h" -#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h" -#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" #include "MantidAPI/AnalysisDataService.h" @@ -219,14 +213,27 @@ bool InstrumentActor::accept(GLActorConstVisitor &visitor, return ok; } +void InstrumentActor::setComponentVisible( + Mantid::Geometry::ComponentID component) { + setChildVisibility(false); + const auto &componentInfo = getComponentInfo(); + auto index = componentInfo.indexOf(component); + + auto children = componentInfo.componentsInSubtree(index); + m_isCompVisible[index] = true; + for (auto child : children) + m_isCompVisible[child] = true; + + invalidateDisplayLists(); +} + void InstrumentActor::setChildVisibility(bool on) { - // m_scene.setChildVisibility(on); - // auto guidesVisitor = SetVisibleNonDetectorVisitor(m_showGuides); - // m_scene.accept(guidesVisitor); + std::fill(m_isCompVisible.begin(), m_isCompVisible.end(), on); } bool InstrumentActor::hasChildVisible() const { - return true; // m_scene.hasChildVisible(); + return std::any_of(m_isCompVisible.begin(), m_isCompVisible.end(), + [](bool visible) { return visible; }); } /** Returns the workspace relating to this instrument view. @@ -665,11 +672,21 @@ void InstrumentActor::resetColors() { m_colors.assign(componentInfo.size(), GLColor(qRed(color), qGreen(color), qBlue(color), 1)); + IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists(); + const auto &detectorIDs = detectorInfo.detectorIDs(); for (size_t wi = 0; wi < m_specIntegrs.size(); ++wi) { const auto &specDef = spectrumInfo.spectrumDefinition(wi); + bool masked = false; + for (const auto &det : specDef) { auto detIndex = det.first; - if (detectorInfo.isMasked(detIndex)) { + + if (mask) + masked = mask->isMasked(detectorIDs[detIndex]); + else + masked = spectrumInfo.hasDetectors(wi) && spectrumInfo.isMasked(wi); + + if (detectorInfo.isMasked(detIndex) || masked) { m_colors[detIndex] = m_maskedColor; } else { auto integratedValue = m_specIntegrs[wi]; @@ -733,11 +750,7 @@ void InstrumentActor::updateColors() { /** * @param on :: True or false for on or off. */ -void InstrumentActor::showGuides(bool on) { - auto visitor = SetVisibleNonDetectorVisitor(on); - this->accept(visitor); - m_showGuides = on; -} +void InstrumentActor::showGuides(bool on) { m_showGuides = on; } GLColor InstrumentActor::getColor(size_t index) const { if (index <= m_colors.size() - 1) @@ -1329,95 +1342,6 @@ void InstrumentActor::addMaskBinsData(const QList &detIDs) { /// Show if bin masks have been defined. bool InstrumentActor::hasBinMask() const { return !m_maskBinsData.isEmpty(); } -//-------------------------------------------------------------------------// -bool SetVisibleComponentVisitor::visit(GLActor *actor) { - actor->setVisibility(false); - return false; -} - -bool SetVisibleComponentVisitor::visit(GLActorCollection *actor) { - bool visible = actor->hasChildVisible(); - actor->setVisibility(visible); - return visible; -} - -bool SetVisibleComponentVisitor::visit(ComponentActor *actor) { - bool on = actor->getComponent()->getComponentID() == m_id; - actor->setVisibility(on); - return on; -} - -bool SetVisibleComponentVisitor::visit(CompAssemblyActor *actor) { - bool visible = false; - if (actor->getComponent()->getComponentID() == m_id) { - visible = true; - actor->setChildVisibility(true); - } else { - visible = actor->hasChildVisible(); - actor->setVisibility(visible); - } - return visible; -} - -bool SetVisibleComponentVisitor::visit(ObjCompAssemblyActor *actor) { - bool on = actor->getComponent()->getComponentID() == m_id; - actor->setVisibility(on); - return on; -} - -bool SetVisibleComponentVisitor::visit(InstrumentActor *actor) { - bool visible = false; - if (actor->getInstrument()->getComponentID() == m_id) { - visible = true; - actor->setChildVisibility(true); - } else { - visible = actor->hasChildVisible(); - actor->setVisibility(visible); - } - return visible; -} - -bool SetVisibleComponentVisitor::visit(RectangularDetectorActor *actor) { - bool on = actor->getComponent()->getComponentID() == m_id || - actor->isChildDetector(m_id); - actor->setVisibility(on); - return on; -} - -bool SetVisibleComponentVisitor::visit(StructuredDetectorActor *actor) { - bool on = actor->getComponent()->getComponentID() == m_id || - actor->isChildDetector(m_id); - actor->setVisibility(on); - return on; -} - -//-------------------------------------------------------------------------// -/** - * Visits an actor and if it is a "non-detector" sets its visibility. - * - * @param actor :: A visited actor. - * @return always false to traverse all the instrument tree. - */ -bool SetVisibleNonDetectorVisitor::visit(GLActor *actor) { - ComponentActor *comp = dynamic_cast(actor); - if (comp && comp->isNonDetector()) { - actor->setVisibility(m_on); - } - return false; -} - -//-------------------------------------------------------------------------// -bool FindComponentVisitor::visit(GLActor *actor) { - ComponentActor *comp = dynamic_cast(actor); - if (comp) { - if (comp->getComponent()->getComponentID() == m_id) { - m_actor = comp; - return true; - } - } - return false; -} - /** * Save the state of the instrument actor to a project file. * @return string representing the current state of the instrumet actor. diff --git a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp index 7c544f93935c..1a88d77b3cec 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp @@ -123,8 +123,7 @@ void InstrumentTreeWidget::sendComponentSelectedSignal( const QModelIndex index) { Mantid::Geometry::ComponentID id = static_cast(index.internalPointer()); - auto visitor = SetVisibleComponentVisitor(id); - m_instrWidget->getInstrumentActor().accept(visitor); + m_instrWidget->getInstrumentActor().setComponentVisible(id); emit componentSelected(id); } From 888c39a63490e7552b474409412aa5eb43be08c6 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 3 Jan 2018 10:43:19 +0000 Subject: [PATCH 033/364] Remove all actor code and base classes re #21339 --- qt/widgets/instrumentview/CMakeLists.txt | 4 - .../InstrumentView/CompAssemblyActor.h | 90 ----- .../InstrumentView/ComponentActor.h | 82 ----- .../MantidQtWidgets/InstrumentView/GLActor.h | 118 ------- .../InstrumentView/GLActorCollection.h | 74 ---- .../InstrumentView/GLActorVisitor.h | 58 --- .../InstrumentView/ICompAssemblyActor.h | 77 ---- .../InstrumentView/InstrumentActor.h | 38 +- .../InstrumentView/ObjCompAssemblyActor.h | 93 ----- .../InstrumentView/ObjComponentActor.h | 78 ---- .../InstrumentView/RectangularDetectorActor.h | 114 ------ .../InstrumentView/SampleActor.h | 79 ----- .../InstrumentView/StructuredDetectorActor.h | 100 ------ .../instrumentview/src/CompAssemblyActor.cpp | 271 -------------- .../instrumentview/src/ComponentActor.cpp | 76 ---- qt/widgets/instrumentview/src/GLActor.cpp | 56 --- .../instrumentview/src/GLActorCollection.cpp | 178 ---------- .../instrumentview/src/GLActorVisitor.cpp | 22 -- qt/widgets/instrumentview/src/GLObject.cpp | 1 - .../instrumentview/src/ICompAssemblyActor.cpp | 36 -- .../instrumentview/src/InstrumentActor.cpp | 101 ++---- .../src/InstrumentWidgetRenderTab.cpp | 4 +- .../src/ObjCompAssemblyActor.cpp | 195 ---------- .../instrumentview/src/ObjComponentActor.cpp | 127 ------- .../instrumentview/src/PanelsSurface.cpp | 6 - .../instrumentview/src/Projection3D.cpp | 1 - .../instrumentview/src/ProjectionSurface.cpp | 2 +- .../src/RectangularDetectorActor.cpp | 332 ------------------ qt/widgets/instrumentview/src/SampleActor.cpp | 51 --- .../src/StructuredDetectorActor.cpp | 193 ---------- .../instrumentview/src/UnwrappedSurface.cpp | 4 +- 31 files changed, 52 insertions(+), 2609 deletions(-) delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ComponentActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorCollection.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/SampleActor.h delete mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h delete mode 100644 qt/widgets/instrumentview/src/CompAssemblyActor.cpp delete mode 100644 qt/widgets/instrumentview/src/ComponentActor.cpp delete mode 100644 qt/widgets/instrumentview/src/GLActor.cpp delete mode 100644 qt/widgets/instrumentview/src/GLActorCollection.cpp delete mode 100644 qt/widgets/instrumentview/src/GLActorVisitor.cpp delete mode 100644 qt/widgets/instrumentview/src/ICompAssemblyActor.cpp delete mode 100644 qt/widgets/instrumentview/src/ObjCompAssemblyActor.cpp delete mode 100644 qt/widgets/instrumentview/src/ObjComponentActor.cpp delete mode 100644 qt/widgets/instrumentview/src/RectangularDetectorActor.cpp delete mode 100644 qt/widgets/instrumentview/src/SampleActor.cpp delete mode 100644 qt/widgets/instrumentview/src/StructuredDetectorActor.cpp diff --git a/qt/widgets/instrumentview/CMakeLists.txt b/qt/widgets/instrumentview/CMakeLists.txt index 0e5b79584cb5..8032364c1ac0 100644 --- a/qt/widgets/instrumentview/CMakeLists.txt +++ b/qt/widgets/instrumentview/CMakeLists.txt @@ -3,8 +3,6 @@ set ( SRC_FILES src/CollapsiblePanel.cpp src/ColorMapWidget.cpp src/DetXMLFile.cpp - src/GLActor.cpp - src/GLActorVisitor.cpp src/GLColor.cpp src/GLObject.cpp src/InstrumentActor.cpp @@ -69,8 +67,6 @@ set ( INC_FILES inc/MantidQtWidgets/InstrumentView/ColorMapWidget.h inc/MantidQtWidgets/InstrumentView/DetXMLFile.h inc/MantidQtWidgets/InstrumentView/DllOption.h - inc/MantidQtWidgets/InstrumentView/GLActor.h - inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h inc/MantidQtWidgets/InstrumentView/GLColor.h inc/MantidQtWidgets/InstrumentView/GLObject.h inc/MantidQtWidgets/InstrumentView/InstrumentActor.h diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h deleted file mode 100644 index 9116c22d17a9..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/CompAssemblyActor.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef COMPASSEMBLY_ACTOR__H_ -#define COMPASSEMBLY_ACTOR__H_ - -#include "ICompAssemblyActor.h" -#include "GLActor.h" - -#include "MantidGeometry/IComponent.h" -#include "MantidKernel/V3D.h" -/** - \class CompAssemblyActor - \brief This class wraps the ICompAssembly into Actor. - \author Srikanth Nagella - \date March 2009 - \version 1.0 - - This class has the implementation for calling the children of ICompAssembly's - IObjComponent to render themselves - and call the ICompAssemblys. This maintains the count of the children for easy - lookup. - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -namespace Mantid { -namespace Kernel { -class V3D; -} -namespace Geometry { -class ICompAssembly; -class CSGObject; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class InstrumentActor; - -class ObjComponentActor; - -class CompAssemblyActor : public ICompAssemblyActor { -public: - CompAssemblyActor( - const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID); ///< Constructor - ~CompAssemblyActor() override; - std::string type() const override { - return "CompAssemblyActor"; - } ///< Type of the GL object - void draw(bool picking = false) const override; ///< Method that defines - /// ObjComponent geometry. Calls - /// ObjComponent draw method - void setChildVisibility(bool) override; - bool hasChildVisible() const override; - bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll) override; - bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const override; - void setColors() override; - -protected: - mutable std::vector - mChildObjCompActors; ///< List of ObjComponent Actors - mutable std::vector - mChildCompAssemActors; ///< List of CompAssembly Actors -private: - void AppendBoundingBox(const Mantid::Kernel::V3D &minBound, - const Mantid::Kernel::V3D &maxBound); -}; - -} // MantidWidgets -} // MantidQt - -#endif /*GLTRIANGLE_H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ComponentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ComponentActor.h deleted file mode 100644 index ce4a12ef49c4..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ComponentActor.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef COMPONENT_ACTOR_H_ -#define COMPONENT_ACTOR_H_ -#include "GLActor.h" -#include "GLColor.h" - -#include "MantidGeometry/IComponent.h" - -/** - \class ObjComponentActor - \brief ObjComponentActor is an actor class for rendering ObjComponents. - \author Srikanth Nagella - \date March 2009 - \version 1.0 - - This class has the implementation for rendering ObjComponents in OpenGL and - it inherits from the GLActor - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -namespace Mantid { -namespace Geometry { -class IObjComponent; -class IDetector; -class ObjCompAssembly; -class CompAssembly; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class InstrumentActor; - -class ComponentActor : public GLActor { -public: - ComponentActor( - const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID); ///< Default Constructor - virtual std::string type() const { - return "ComponentActor"; - } ///< Type of the GL object - bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll) override; - bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const override; - boost::shared_ptr getComponent() const; - boost::shared_ptr - getObjComponent() const; - boost::shared_ptr getDetector() const; - boost::shared_ptr - getObjCompAssembly() const; - boost::shared_ptr - getCompAssembly() const; - virtual void setColors() {} - /// Check if the component is a non-detector. - bool isNonDetector() const; - -protected: - const InstrumentActor &m_instrActor; - Mantid::Geometry::ComponentID m_id; ///< Component ID -}; -} // MantidWidgets -} // MantidQt - -#endif /*COMPONENT_ACTOR_H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActor.h deleted file mode 100644 index 35d61fe78e9e..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActor.h +++ /dev/null @@ -1,118 +0,0 @@ -/**________________________________________________ -* Library : NTK -* Name : GLActor.h -* Author : L.C.Chapon -* Date : 8 Nov 2006 -* Description : Base class for all objects in a 3D Scene. -* Methods are provide to position and -* rotate the objects. The objects can also -* be set as active or not. Actors maintian safe pointer -* to a GLObject. -*________________________________________________ -*/ -#ifndef GLACTOR_H_ -#define GLACTOR_H_ -#include "MantidKernel/V3D.h" -#include "GLObject.h" -#include "GLColor.h" -#include - -#include - -#include -#include -#include - -namespace Mantid { -namespace Geometry { -class IDetector; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class GLActorVisitor; -class GLActorConstVisitor; - -/** -\class GLActor -\brief An actor class that holds geometry objects with its position. -\author Chapon Laurent & Srikanth Nagella -\date August 2008 -\version 1.0 - -Base class for all objects in a 3D Scene. Methods are provided to position and -rotate the objects. -The objects can also be set as active or not. Actors maintain safe pointer to a -GLObject. - -Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge -National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -File change history is stored at: -*/ -enum class GLActorVisiblity : char { VISIBLE, HIDDEN, ALWAYS_HIDDEN }; - -class GLActor : public QObject { -public: - /// Rules for visitor propagation. If vistor's visit(...) method returns true - /// the propagation can be continued (VisitAll) or abandoned (Finish) - enum VisitorAcceptRule { VisitAll, Finish }; - GLActor() : m_visible(GLActorVisiblity::VISIBLE) {} - ///< Virtual destructor - ~GLActor() override; - /// Toggle the visibility of the actor. - virtual void setVisibility(bool on); - /// Toggle the visibility of the child actors (if exist). - virtual void setChildVisibility(bool on) { setVisibility(on); } - /// Sets the current component to always hide - void setAlwaysHidden() { m_visible = GLActorVisiblity::ALWAYS_HIDDEN; } - /// Check if any child is visible - virtual bool hasChildVisible() const { return true; } - /// Get the visibility status. - bool isVisible() const { return m_visible == GLActorVisiblity::VISIBLE; } - /// Draw the actor in 3D. - virtual void draw(bool picking = false) const = 0; - /// Get the 3D bounding box of the actor - virtual void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const = 0; - /// Accept a visitor - virtual bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll); - /// Accept a const visitor - virtual bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const; - /// Convert a "pick ID" to a colour to put into the pick image. - static GLColor makePickColor(size_t pickID); - /// Decode a pick colour and return corresponding "pick ID" - static size_t decodePickColor(const QRgb &c); - /// Decode a pick colour and return corresponding "pick ID" - static size_t decodePickColor(unsigned char r, unsigned char g, - unsigned char b); - /// Get colour of a component which doesn't have any counts associated with - /// it. - static GLColor defaultDetectorColor(); - -protected: - GLActorVisiblity m_visible; ///< Flag whether the actor is visible or not -}; - -} // MantidWidgets -} // MantidQt - -#endif /*GLACTOR_H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorCollection.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorCollection.h deleted file mode 100644 index 78c2d909ac67..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorCollection.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef GLACTORCOLLECTION_H_ -#define GLACTORCOLLECTION_H_ -#include "GLActor.h" - -#include "MantidKernel/V3D.h" - -#include - -namespace MantidQt { -namespace MantidWidgets { -/** -\class GLActorCollection -\brief An actor class collection -\author Chapon Laurent & Srikanth Nagella -\date August 2008 -\version 1.0 - - -GLActorCollection has the list of GLActor. - -Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge -National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -File change history is stored at: -*/ - -class GLActorCollection : public GLActor { -public: - GLActorCollection(); ///< Default Constructor - ~GLActorCollection() override; ///< Destructor - void setChildVisibility(bool) override; - bool hasChildVisible() const override; - void draw(bool picking = false) const override; - void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override; - bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll) override; - bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const override; - - void addActor(GLActor *); - void removeActor(GLActor *); - int getNumberOfActors(); - GLActor *getActor(int index); - void invalidateDisplayList() const; - -private: - void drawGL(bool picking = false) const; - mutable std::vector - mActorsList; ///< Vector of GLActors for fast access. - Mantid::Kernel::V3D m_minBound; - Mantid::Kernel::V3D m_maxBound; - mutable GLuint m_displayListId[2]; - mutable bool m_useDisplayList[2]; -}; -} // MantidWidgets -} // MantidQt - -#endif /*GLACTORCOLLECTION_H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h deleted file mode 100644 index de82eb56f2be..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/GLActorVisitor.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef GLACTORVISITOR_H -#define GLACTORVISITOR_H - -namespace MantidQt { -namespace MantidWidgets { -class GLActor; -class InstrumentActor; - -/** -* A base class for an actor visitor. -*/ -class GLActorVisitor { -public: - /// Virtual destructor. - virtual ~GLActorVisitor() {} - /// Abstract method that must be implemented in sub-classes - virtual bool visit(GLActor *) = 0; - virtual bool visit(InstrumentActor *); -}; - -/** -* A base class for an actor visitor (const version). -*/ -class GLActorConstVisitor { -public: - /// Virtual destructor. - virtual ~GLActorConstVisitor() {} - /// Abstract method that must be implemented in sub-classes - virtual bool visit(const GLActor *) = 0; - virtual bool visit(const InstrumentActor *); -}; - -/* -* The visit() method implemented by sub-classes must return true if an actor -* is set visible and false otherwise. This is requered by -*GLActorCollection::accept() -* method to determine whether the collection itself is visible or not. -* -* All visitors changing visibility should be sub-classed from this base class. -*/ -class SetVisibilityVisitor : public GLActorVisitor {}; - -/** -* Set all actors visible. -*/ -class SetAllVisibleVisitor : public SetVisibilityVisitor { -public: - explicit SetAllVisibleVisitor(bool showNonDet) : m_showNonDet(showNonDet) {} - using GLActorVisitor::visit; - bool visit(GLActor *) override; - -private: - bool m_showNonDet; -}; -} // MantidWidgets -} // MantidQt - -#endif // GLACTORVISITOR_H diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h deleted file mode 100644 index 21cbebe5e546..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ICompAssemblyActor.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef ICOMPASSEMBLY_ACTOR__H_ -#define ICOMPASSEMBLY_ACTOR__H_ -#include "ComponentActor.h" -#include "MantidGeometry/IComponent.h" -#include "MantidKernel/V3D.h" - -#include - -#include - -/** - \class ICompAssemblyActor - \brief This class wraps the ICompAssembly into Actor. - \author Srikanth Nagella - \date March 2009 - \version 1.0 - - This class has the interface Comp assembly actors. - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -namespace Mantid { -namespace Kernel { -class V3D; -} - -namespace Geometry { -class ICompAssembly; -class CSGObject; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class InstrumentActor; -class ObjComponentActor; - -class ICompAssemblyActor : public ComponentActor { -public: - ICompAssemblyActor( - const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID); ///< Constructor - void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override; - - std::string type() const override { - return "ICompAssemblyActor"; - } ///< Type of the GL object - size_t getNumberOfDetectors() const { return mNumberOfDetectors; } - -protected: - size_t mNumberOfDetectors; - Mantid::Kernel::V3D minBoundBox; - Mantid::Kernel::V3D maxBoundBox; -}; -} // MantidWidgets -} // MantidQt - -#endif /*GLTRIANGLE_H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 1f1a7e0cb640..f0fb73e30e30 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -2,15 +2,13 @@ #define INSTRUMENTACTOR_H_ #include "DllOption.h" -#include "GLActor.h" -#include "GLActorVisitor.h" +#include "MantidGeometry/Rendering/OpenGL_Headers.h" #include "GLColor.h" #include "MantidAPI/MatrixWorkspace_fwd.h" #include "MantidAPI/SpectraDetectorTypes.h" #include "MantidQtWidgets/LegacyQwt/MantidColorMap.h" #include "MaskBinsData.h" -#include "SampleActor.h" - +#include "MantidGeometry/IComponent.h" #include #include @@ -46,32 +44,27 @@ interface for picked ObjComponent and other operation for selective rendering of the instrument */ -class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { +class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor: public QObject { Q_OBJECT public: /// Constructor InstrumentActor(const QString &wsName, bool autoscaling = true, double scaleMin = 0.0, double scaleMax = 0.0); ///< Destructor - ~InstrumentActor() override; + ~InstrumentActor(); ///< Type of the GL object virtual std::string type() const { return "InstrumentActor"; } /// Draw the instrument in 3D - void draw(bool picking = false) const override; + void draw(bool picking = false) const; /// Return the bounding box in 3D void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override; - /// Run visitors callback on each component - bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll) override; - /// Run visitors callback on each component (const version) - bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const override; + Mantid::Kernel::V3D &maxBound) const; + /// Set a component (and all its children) visible. void setComponentVisible(Mantid::Geometry::ComponentID component); /// Toggle the visibility of the child actors (if exist). - void setChildVisibility(bool) override; + void setChildVisibility(bool); /// Check if any child is visible - bool hasChildVisible() const override; + bool hasChildVisible() const; /// Get the underlying instrument boost::shared_ptr getInstrument() const; /// Get the associated data workspace @@ -191,6 +184,10 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { const Mantid::Kernel::V3D &up, Mantid::Kernel::Quat &R); + /// Convert a "pick ID" to a colour to put into the pick image. + static GLColor makePickColor(size_t pickID); + /// Decode a pick colour and return corresponding "pick ID" + static size_t decodePickColor(const QRgb &c); /* Masking */ void initMaskHelper() const; @@ -224,11 +221,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { void sumDetectorsRagged(QList &dets, std::vector &x, std::vector &y, size_t size) const; - size_t pushBackDetid(Mantid::detid_t) const; - void pushBackNonDetid(ObjComponentActor *actor, - Mantid::Geometry::ComponentID compID) const; - void setupColors();//TODO: Rename to setupPickColors - void setupPickColors();//TODO: Remove + void setupPickColors(); boost::shared_ptr getMaskWorkspaceIfExists() const; @@ -276,9 +269,6 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public GLActor { /// pickID of the component /// is m_detIDs.size() + i. mutable std::vector m_nonDetIDs; - /// Temporary stores addresses of actors for non-detector components until - /// initialisation completes - mutable std::vector m_nonDetActorsTemp; /// All detector positions, in order of pickIDs, populated by Obj..Actor /// constructors diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h deleted file mode 100644 index 8cde9c9a31af..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef OBJCOMPASSEMBLY_ACTOR__H_ -#define OBJCOMPASSEMBLY_ACTOR__H_ -#include "ICompAssemblyActor.h" - -#include "MantidGeometry/IComponent.h" -#include "MantidGeometry/IDetector.h" -#include "MantidKernel/V3D.h" - -class TexObject; -namespace Mantid { -namespace Geometry { -class ObjCompAssembly; -} -} - -namespace MantidQt { -namespace MantidWidgets { -/** -\class ObjCompAssemblyActor -\brief This class wraps the ICompAssembly into Actor. -\author Srikanth Nagella -\date March 2009 -\version 1.0 - -This class has the implementation for calling the children of ICompAssembly's -IObjComponent to render themselves -and call the ICompAssemblys. This maintains the count of the children for easy -lookup. - -Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge -National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -File change history is stored at: -*/ -class ObjCompAssemblyActor : public ICompAssemblyActor { -public: - /// Constructor - ObjCompAssemblyActor(const InstrumentActor &instrActor, - Mantid::Geometry::ComponentID compID); - ~ObjCompAssemblyActor() override; ///< Destructor - std::string type() const override { - return "ObjCompAssemblyActor"; - } ///< Type of the GL object - void draw(bool picking = false) const override; ///< Method that defines - /// ObjComponent geometry. Calls - /// ObjComponent draw method - // virtual void getBoundingBox(Mantid::Kernel::V3D& - // minBound,Mantid::Kernel::V3D& maxBound)const; - void setColors() override; - bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll) override; - bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const override; - -private: - void setDetectorColor(unsigned char *data, size_t i, - GLColor c) const; ///< set colour to a detector - void setDataColors() const; - void setPickColors() const; - void generateTexture(unsigned char *data, unsigned int &id) const; - /// Swap between drawing counts and drawing detector code colours - void swap(); - const unsigned char *getColor(int i) const; - - std::vector m_detIDs; ///< List of Component IDs - mutable unsigned int m_idData; ///< OpenGL texture id - mutable unsigned int m_idPick; ///< OpenGL texture id - int m_n; ///< texture size in one dimension, the other dimension is 1 - unsigned char *m_data; ///< texture colour data - unsigned char *m_pick_data; ///< texture with detector code colours - mutable bool - m_texturesGenerated; ///< true if the textures have been generated -}; - -} // MantidWidgets -} // MantidQt - -#endif /*OBJCOMPASSEMBLY_ACTOR__H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h deleted file mode 100644 index 6ffe582de33f..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ObjComponentActor.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef OBJCOMPONENT_ACTOR_H_ -#define OBJCOMPONENT_ACTOR_H_ -#include "ComponentActor.h" -#include "GLColor.h" -/** - \class ObjComponentActor - \brief ObjComponentActor is an actor class for rendering ObjComponents. - \author Srikanth Nagella - \date March 2009 - \version 1.0 - - This class has the implementation for rendering ObjComponents in OpenGL and - it inherits from the GLActor - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -namespace Mantid { -namespace Kernel { -class V3D; -} - -namespace Geometry { -class IObjComponent; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class InstrumentActor; - -class ObjComponentActor : public ComponentActor { -public: - ObjComponentActor( - const InstrumentActor &instrActor, - Mantid::Geometry::ComponentID compID); ///< Default Constructor - ~ObjComponentActor() override; ///< Destructor - std::string type() const override { - return "ObjComponentActor"; - } ///< Type of the GL object - void draw(bool picking = false) const override; ///< Method that defines - /// ObjComponent geometry. Calls - /// ObjComponent draw method - void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override; - void setColors() override; - - void setColor(const GLColor &c) { m_dataColor = c; } - -private: - void setPickColor(const GLColor &c) { m_pickColor = c; } - - GLColor m_dataColor; - GLColor m_pickColor; - - friend class InstrumentActor; -}; -} // MantidWidgets -} // MantidQt - -#endif /*OBJCOMPONENT_ACTOR_H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h deleted file mode 100644 index 887dcf9a2bb4..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/RectangularDetectorActor.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef RECTANGULAR_DETECTOR_ACTOR__H_ -#define RECTANGULAR_DETECTOR_ACTOR__H_ -#include "GLActor.h" -#include "ObjComponentActor.h" -#include "ICompAssemblyActor.h" -#include "MantidGeometry/IComponent.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidKernel/V3D.h" -/** - \class RectangularDetectorActor - \brief This class wraps a RectangularDetector into Actor. - \author Janik Zikovsky - \date October 7 2010 - \version 1.0 - - This class is used to render a RectangularDetector as a bitmap and plot it. - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -namespace Mantid { -namespace Kernel { -class V3D; -} -namespace Geometry { -class ICompAssembly; -class CSGObject; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class ObjComponentActor; - -class RectangularDetectorActor : public ICompAssemblyActor { -public: - /// Constructor - RectangularDetectorActor(const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID); - /// Destructor - ~RectangularDetectorActor() override; - -private: - void AppendBoundingBox(const Mantid::Kernel::V3D &minBound, - const Mantid::Kernel::V3D &maxBound); - -protected: - /// The rectangular detector - boost::shared_ptr mDet; - - void init() const; - void redraw(); - int findDetectorIDUsingColor(int rgb); - virtual void initChilds(bool) {} - -public: - std::string type() const override { - return "RectangularDetectorActor"; - } ///< Type of the GL object - - void draw(bool picking = false) const override; ///< Method that - /// defines - /// ObjComponent - /// geometry. Calls - /// ObjComponent - /// draw method - void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override; - bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll) override; - bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const override; - bool isChildDetector(const Mantid::Geometry::ComponentID &id) const; - void setColors() override; - - int genTexture(char *&image_data, std::vector &list, - bool useDetectorIDs); - void uploadTexture(char *&image_data) const; - -private: - /// Texture ID that holds the texture. - mutable unsigned int mTextureID; - - /// Pointer to the array holding the texture color data - mutable char *image_data; - - /// Pointer to the array holding the color data for picking the scene - mutable char *pick_data; - - /// pick ids - std::vector m_pickIDs; -}; - -} // MantidWidgets -} // MantidQt - -#endif /*RECTANGULAR_DETECTOR_ACTOR__H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/SampleActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/SampleActor.h deleted file mode 100644 index cb46c0c637f3..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/SampleActor.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef SMAPLE_ACTOR_H_ -#define SMAPLE_ACTOR_H_ -#include "GLActor.h" -#include "GLColor.h" -#include "ObjComponentActor.h" - -#include - -/** - \class SampleActor - \brief SampleActor is an actor class for rendering Samples. - \author Roman Tolchenov - \date 04/07/2011 - \version 1.0 - - This class has the implementation for rendering SampleActor in OpenGL and it - inherits from the GLActor - - Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -namespace Mantid { -namespace API { -class Sample; -} -namespace Geometry { -class IObjComponent; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class InstrumentActor; - -class SampleActor : public GLActor { -public: - SampleActor(const InstrumentActor &instrActor, - const Mantid::API::Sample &sample, - const ObjComponentActor *samplePosActor); ///< Constructor - virtual std::string type() const { - return "SampleActor"; - } ///< Type of the GL object - void draw(bool picking) const override; - void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override; - void setColor(const GLColor &c) { m_color = c; } - const ObjComponentActor *getSamplePosActor() const { - return m_samplePosActor; - } - -protected: - const InstrumentActor &m_instrActor; - const Mantid::API::Sample &m_sample; - const ObjComponentActor *m_samplePosActor; - boost::shared_ptr m_samplePos; - GLColor m_color; -}; - -} // MantidWidgets -} // MantidQt - -#endif /*SMAPLE_ACTOR_H_*/ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h deleted file mode 100644 index 07e72cb3e303..000000000000 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/StructuredDetectorActor.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef STRUCTUREDDETECTORACTOR -#define STRUCTUREDDETECTORACTOR -#include "GLActor.h" -#include "ICompAssemblyActor.h" -#include "MantidGeometry/IComponent.h" -#include "MantidGeometry/Instrument/StructuredDetector.h" -#include "MantidKernel/V3D.h" -#include "ObjComponentActor.h" -/** -\class StructuredDetectorActor -\brief This class wraps a StructuredDetector into Actor. -\author Lamar Moore -\date March 9 2016 -\version 1.0 - -This class is used to render a StructuredDetector as a bitmap and plot it. - -Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge -National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -File change history is stored at: -*/ -namespace Mantid { -namespace Kernel { -class V3D; -} -namespace Geometry { -class ICompAssembly; -class CSGObject; -} -} - -namespace MantidQt { -namespace MantidWidgets { -class ObjComponentActor; - -class StructuredDetectorActor : public ICompAssemblyActor { -public: - /// Constructor - StructuredDetectorActor(const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID); - /// Destructor - ~StructuredDetectorActor() override; - -private: - void AppendBoundingBox(const Mantid::Kernel::V3D &minBound, - const Mantid::Kernel::V3D &maxBound); - -protected: - /// The structured detector - boost::shared_ptr m_det; - std::vector m_clist; - std::vector m_pickIds; - std::vector m_pickColors; - - void init() const; - void redraw(); - int findDetectorIDUsingColor(int rgb); - virtual void initChilds(bool) {} - -public: - std::string type() const override { - return "StructuredDetectorActor"; - } ///< Type of the GL object - - void draw(bool picking = false) const override; ///< Method that - /// defines - /// ObjComponent - /// geometry. Calls - /// ObjComponent - /// draw method - void getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const override; - bool accept(GLActorVisitor &visitor, - VisitorAcceptRule rule = VisitAll) override; - bool accept(GLActorConstVisitor &visitor, - VisitorAcceptRule rule = VisitAll) const override; - bool isChildDetector(const Mantid::Geometry::ComponentID &id) const; - void setColors() override; -}; - -} // MantidWidgets -} // MantidQt - -#endif // STRUCTUREDDETECTORACTOR \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/CompAssemblyActor.cpp b/qt/widgets/instrumentview/src/CompAssemblyActor.cpp deleted file mode 100644 index e60b56793406..000000000000 --- a/qt/widgets/instrumentview/src/CompAssemblyActor.cpp +++ /dev/null @@ -1,271 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h" -#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h" -#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h" -#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h" -#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h" -#include "MantidQtWidgets/InstrumentView/OpenGLError.h" -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" - -#include "MantidGeometry/Instrument.h" -#include "MantidKernel/V3D.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/ICompAssembly.h" -#include "MantidGeometry/Instrument/ObjCompAssembly.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/IDetector.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Instrument/StructuredDetector.h" -#include "MantidKernel/Exception.h" - -#include - -using Mantid::Geometry::IComponent; -using Mantid::Geometry::IObjComponent; -using Mantid::Geometry::ICompAssembly; -using Mantid::Geometry::ObjCompAssembly; -using Mantid::Geometry::ComponentID; -using Mantid::Geometry::RectangularDetector; -using Mantid::Geometry::StructuredDetector; - -namespace MantidQt { -namespace MantidWidgets { - -/** -* This is a constructor for CompAssembly Actor -* @param instrActor :: the current instrument actor -* @param compID :: the current component ID -*/ -CompAssemblyActor::CompAssemblyActor( - const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID) - : ICompAssemblyActor(instrActor, compID) { - boost::shared_ptr CompPtr = getComponent(); - - // bounding box of the overall instrument - Mantid::Kernel::V3D minBound; - Mantid::Kernel::V3D maxBound; - // Iterate through CompAssembly children - boost::shared_ptr CompAssemPtr = - boost::dynamic_pointer_cast(CompPtr); - if (CompAssemPtr != boost::shared_ptr()) { - int nChild = CompAssemPtr->nelements(); - for (int i = 0; i < nChild; i++) { - boost::shared_ptr ChildCompPtr = (*CompAssemPtr)[i]; - boost::shared_ptr ChildCAPtr = - boost::dynamic_pointer_cast(ChildCompPtr); - - // If the child is a CompAssembly then create a CompAssemblyActor for the - // child - if (ChildCAPtr) { - boost::shared_ptr ChildOCAPtr = - boost::dynamic_pointer_cast(ChildCompPtr); - boost::shared_ptr ChildRDPtr = - boost::dynamic_pointer_cast(ChildCompPtr); - boost::shared_ptr ChildSDPtr = - boost::dynamic_pointer_cast(ChildCompPtr); - - if (ChildSDPtr) { - StructuredDetectorActor *iActor = new StructuredDetectorActor( - instrActor, ChildSDPtr->getComponentID()); - iActor->getBoundingBox(minBound, maxBound); - AppendBoundingBox(minBound, maxBound); - mNumberOfDetectors += iActor->getNumberOfDetectors(); - mChildCompAssemActors.push_back(iActor); - } else if (ChildRDPtr) { - // If the child is a RectangularDetector, then create a - // RectangularDetectorActor for it. - RectangularDetectorActor *iActor = new RectangularDetectorActor( - instrActor, ChildCAPtr->getComponentID()); - iActor->getBoundingBox(minBound, maxBound); - AppendBoundingBox(minBound, maxBound); - mNumberOfDetectors += iActor->getNumberOfDetectors(); - mChildCompAssemActors.push_back(iActor); - } else if (ChildOCAPtr) { - ObjCompAssemblyActor *iActor = new ObjCompAssemblyActor( - instrActor, ChildCAPtr->getComponentID()); - iActor->getBoundingBox(minBound, maxBound); - AppendBoundingBox(minBound, maxBound); - mNumberOfDetectors += iActor->getNumberOfDetectors(); - mChildCompAssemActors.push_back(iActor); - } else { - CompAssemblyActor *iActor = - new CompAssemblyActor(instrActor, ChildCAPtr->getComponentID()); - iActor->getBoundingBox(minBound, maxBound); - AppendBoundingBox(minBound, maxBound); - mNumberOfDetectors += iActor->getNumberOfDetectors(); - mChildCompAssemActors.push_back(iActor); - } - } else // it has to be a ObjComponent child, create a ObjComponentActor - // for the child use the same display list attribute - { - boost::shared_ptr ChildObjPtr = - boost::dynamic_pointer_cast( - ChildCompPtr); - ObjComponentActor *iActor = - new ObjComponentActor(instrActor, ChildCompPtr->getComponentID()); - iActor->getBoundingBox(minBound, maxBound); - AppendBoundingBox(minBound, maxBound); - mChildObjCompActors.push_back(iActor); - mNumberOfDetectors++; - } - } - } -} - -/** -* Destructor which removes the actors created by this object -*/ -CompAssemblyActor::~CompAssemblyActor() { - // Remove all the child CompAssembly Actors - for (std::vector::iterator iAssem = - mChildCompAssemActors.begin(); - iAssem != mChildCompAssemActors.end(); ++iAssem) - delete (*iAssem); - mChildCompAssemActors.clear(); - // Remove all the child ObjComponent Actors - for (std::vector::iterator iObjComp = - mChildObjCompActors.begin(); - iObjComp != mChildObjCompActors.end(); ++iObjComp) - delete (*iObjComp); - mChildObjCompActors.clear(); -} - -/** -* This function is concrete implementation that renders the Child ObjComponents -* and Child CompAssembly's -*/ -void CompAssemblyActor::draw(bool picking) const { - OpenGLError::check("CompAssemblyActor::draw(0)"); - // Only draw the CompAssembly Children only if they are visible - if (isVisible()) { - // Iterate through the ObjCompActor children and draw them - for (std::vector::iterator itrObjComp = - mChildObjCompActors.begin(); - itrObjComp != mChildObjCompActors.end(); ++itrObjComp) { - // Only draw the ObjCompActor if its visible - if ((*itrObjComp)->isVisible()) { - // std::cout << (*itrObjComp)->getName() << " is gonna draw. From - // define()\n"; - (*itrObjComp)->draw(picking); - OpenGLError::check("draw " + (*itrObjComp)->getComponent()->getName()); - } else { - // std::cout << (*itrObjComp)->getName() << " is not visible\n"; - } - } - // Iterate through the CompAssemblyActor children and draw them - for (std::vector::iterator itrObjAssem = - mChildCompAssemActors.begin(); - itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) { - if ((*itrObjAssem)->isVisible()) { - // std::cout << (*itrObjAssem)->getName() << " is gonna draw. From - // define()\n"; - (*itrObjAssem)->draw(picking); - } - } - } else { - // std::cout << this->getName() << " is not visible\n"; - } - OpenGLError::check("CompAssemblyActor::draw()"); -} - -bool CompAssemblyActor::accept(GLActorVisitor &visitor, - VisitorAcceptRule rule) { - for (std::vector::iterator itrObjComp = - mChildObjCompActors.begin(); - itrObjComp != mChildObjCompActors.end(); ++itrObjComp) { - if ((**itrObjComp).accept(visitor, rule) && rule == Finish) - return true; - } - for (std::vector::iterator itrObjAssem = - mChildCompAssemActors.begin(); - itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) { - if ((**itrObjAssem).accept(visitor, rule) && rule == Finish) - return true; - } - return visitor.visit(this); -} - -bool CompAssemblyActor::accept(GLActorConstVisitor &visitor, - GLActor::VisitorAcceptRule rule) const { - for (std::vector::iterator itrObjComp = - mChildObjCompActors.begin(); - itrObjComp != mChildObjCompActors.end(); ++itrObjComp) { - if ((**itrObjComp).accept(visitor, rule) && rule == Finish) - return true; - } - for (std::vector::iterator itrObjAssem = - mChildCompAssemActors.begin(); - itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) { - if ((**itrObjAssem).accept(visitor, rule) && rule == Finish) - return true; - } - return visitor.visit(this); -} - -//------------------------------------------------------------------------------------------------ -/** -* Append the bounding box CompAssembly bounding box -* @param minBound :: min point of the bounding box -* @param maxBound :: max point of the bounding box -*/ -void CompAssemblyActor::AppendBoundingBox(const Mantid::Kernel::V3D &minBound, - const Mantid::Kernel::V3D &maxBound) { - if (minBoundBox[0] > minBound[0]) - minBoundBox[0] = minBound[0]; - if (minBoundBox[1] > minBound[1]) - minBoundBox[1] = minBound[1]; - if (minBoundBox[2] > minBound[2]) - minBoundBox[2] = minBound[2]; - if (maxBoundBox[0] < maxBound[0]) - maxBoundBox[0] = maxBound[0]; - if (maxBoundBox[1] < maxBound[1]) - maxBoundBox[1] = maxBound[1]; - if (maxBoundBox[2] < maxBound[2]) - maxBoundBox[2] = maxBound[2]; -} - -void CompAssemblyActor::setColors() { - for (std::vector::iterator iAssem = - mChildCompAssemActors.begin(); - iAssem != mChildCompAssemActors.end(); ++iAssem) { - (**iAssem).setColors(); - } - for (std::vector::iterator iObjComp = - mChildObjCompActors.begin(); - iObjComp != mChildObjCompActors.end(); ++iObjComp) { - (**iObjComp).setColors(); - } -} - -void CompAssemblyActor::setChildVisibility(bool on) { - GLActor::setVisibility(on); - for (std::vector::iterator itrObjComp = - mChildObjCompActors.begin(); - itrObjComp != mChildObjCompActors.end(); ++itrObjComp) { - (**itrObjComp).setVisibility(on); - } - for (std::vector::iterator itrObjAssem = - mChildCompAssemActors.begin(); - itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) { - (**itrObjAssem).setChildVisibility(on); - } -} - -bool CompAssemblyActor::hasChildVisible() const { - for (std::vector::iterator itrObjComp = - mChildObjCompActors.begin(); - itrObjComp != mChildObjCompActors.end(); ++itrObjComp) { - if ((**itrObjComp).isVisible()) - return true; - } - for (std::vector::iterator itrObjAssem = - mChildCompAssemActors.begin(); - itrObjAssem != mChildCompAssemActors.end(); ++itrObjAssem) { - if ((**itrObjAssem).hasChildVisible()) - return true; - } - return false; -} - -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/ComponentActor.cpp b/qt/widgets/instrumentview/src/ComponentActor.cpp deleted file mode 100644 index 36a0b1108b96..000000000000 --- a/qt/widgets/instrumentview/src/ComponentActor.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/ComponentActor.h" -#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" - -#include "MantidGeometry/Instrument.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/Instrument/ObjCompAssembly.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Instrument/StructuredDetector.h" -#include "MantidGeometry/Instrument/CompAssembly.h" - -using namespace Mantid; -using namespace Geometry; - -namespace MantidQt { -namespace MantidWidgets { -ComponentActor::ComponentActor(const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID) - : GLActor(), m_instrActor(instrActor), m_id(compID) {} - -bool ComponentActor::accept(GLActorVisitor &visitor, - GLActor::VisitorAcceptRule) { - return visitor.visit(this); -} - -bool ComponentActor::accept(GLActorConstVisitor &visitor, - GLActor::VisitorAcceptRule) const { - return visitor.visit(this); -} - -boost::shared_ptr -ComponentActor::getComponent() const { - return m_instrActor.getInstrument()->getComponentByID(m_id); -} - -boost::shared_ptr -ComponentActor::getObjComponent() const { - return boost::dynamic_pointer_cast( - getComponent()); -} - -boost::shared_ptr -ComponentActor::getDetector() const { - return boost::dynamic_pointer_cast( - getComponent()); -} - -boost::shared_ptr -ComponentActor::getObjCompAssembly() const { - return boost::dynamic_pointer_cast( - getComponent()); -} - -boost::shared_ptr -ComponentActor::getCompAssembly() const { - return boost::dynamic_pointer_cast( - getComponent()); -} - -/** -* A component is a non-detector if it's an ObjComponent (has a shape) and not an -ObjCompAssembly -* (a single object) and not a RectangularDetector (which is an assembly) or a -StructuredDetector -(which is an assembly). -*/ -bool ComponentActor::isNonDetector() const { - auto obj = getObjComponent(); - return obj && !getObjCompAssembly() && !getDetector() && - !boost::dynamic_pointer_cast< - const Mantid::Geometry::RectangularDetector>(obj) && - !boost::dynamic_pointer_cast< - const Mantid::Geometry::StructuredDetector>(obj); -} - -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/GLActor.cpp b/qt/widgets/instrumentview/src/GLActor.cpp deleted file mode 100644 index 452855bcafe0..000000000000 --- a/qt/widgets/instrumentview/src/GLActor.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/GLActor.h" -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" - -namespace MantidQt { -namespace MantidWidgets { -GLActor::~GLActor() {} - -void GLActor::setVisibility(bool on) { - if (m_visible == GLActorVisiblity::ALWAYS_HIDDEN) { - // If we are always hidden do not change the visibility - return; - } - if (on) { - m_visible = GLActorVisiblity::VISIBLE; - } else { - m_visible = GLActorVisiblity::HIDDEN; - } -} - -bool GLActor::accept(GLActorVisitor &visitor, VisitorAcceptRule) { - return visitor.visit(this); -} - -bool GLActor::accept(GLActorConstVisitor &visitor, - GLActor::VisitorAcceptRule) const { - return visitor.visit(this); -} - -GLColor GLActor::makePickColor(size_t pickID) { - pickID += 1; - unsigned char r, g, b; - r = (unsigned char)(pickID / 65536); - g = (unsigned char)((pickID % 65536) / 256); - b = (unsigned char)((pickID % 65536) % 256); - return GLColor(r, g, b); -} - -size_t GLActor::decodePickColor(const QRgb &c) { - return decodePickColor((unsigned char)qRed(c), (unsigned char)qGreen(c), - (unsigned char)qBlue(c)); -} - -size_t GLActor::decodePickColor(unsigned char r, unsigned char g, - unsigned char b) { - unsigned int index = r; - index *= 256; - index += g; - index *= 256; - index += b - 1; - return index; -} - -GLColor GLActor::defaultDetectorColor() { return GLColor(200, 200, 200); } - -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/GLActorCollection.cpp b/qt/widgets/instrumentview/src/GLActorCollection.cpp deleted file mode 100644 index 4e092285e6ed..000000000000 --- a/qt/widgets/instrumentview/src/GLActorCollection.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/GLActorCollection.h" -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" -#include "MantidQtWidgets/InstrumentView/OpenGLError.h" - -#include "MantidKernel/Exception.h" - -#include -#include -#include -#include - -namespace MantidQt { -namespace MantidWidgets { -GLActorCollection::GLActorCollection() - : GLActor(), m_minBound(DBL_MAX, DBL_MAX, DBL_MAX), - m_maxBound(-DBL_MAX, -DBL_MAX, -DBL_MAX) { - m_displayListId[0] = 0; - m_displayListId[1] = 0; - m_useDisplayList[0] = false; - m_useDisplayList[1] = false; -} - -GLActorCollection::~GLActorCollection() { - for (std::vector::iterator i = mActorsList.begin(); - i != mActorsList.end(); ++i) { - delete (*i); - } - mActorsList.clear(); - for (size_t i = 0; i < 2; ++i) { - if (m_displayListId[i] != 0) { - glDeleteLists(m_displayListId[i], 1); - } - } -} - -/** -* This method does the drawing by calling the list of actors to draw themselfs -*/ -void GLActorCollection::draw(bool picking) const { - if (!isVisible()) - return; - OpenGLError::check("GLActorCollection::draw(0)"); - size_t i = picking ? 1 : 0; - if (m_useDisplayList[i]) { - glCallList(m_displayListId[i]); - } else if (m_displayListId[i] == 0) { - m_displayListId[i] = glGenLists(1); - // child actors can also create display lists, so delay - // until all the children have finished making theirs - drawGL(picking); - } else { - m_useDisplayList[i] = true; - glNewList(m_displayListId[i], - GL_COMPILE); // Construct display list for object representation - drawGL(picking); - glEndList(); - if (glGetError() == GL_OUT_OF_MEMORY) // Throw an exception - throw Mantid::Kernel::Exception::OpenGLError( - "OpenGL: Out of video memory"); - glCallList(m_displayListId[i]); - } - OpenGLError::check("GLActorCollection::draw()"); -} - -void GLActorCollection::drawGL(bool picking) const { - for (std::vector::const_iterator it = mActorsList.begin(); - it != mActorsList.end(); ++it) { - (**it).draw(picking); - } -} - -bool GLActorCollection::accept(GLActorVisitor &visitor, - VisitorAcceptRule rule) { - for (std::vector::const_iterator it = mActorsList.begin(); - it != mActorsList.end(); ++it) { - if ((**it).accept(visitor, rule) && rule == Finish) - return true; - } - return visitor.visit(this); -} - -bool GLActorCollection::accept(GLActorConstVisitor &visitor, - GLActor::VisitorAcceptRule rule) const { - for (std::vector::const_iterator it = mActorsList.begin(); - it != mActorsList.end(); ++it) { - if ((**it).accept(visitor, rule) && rule == Finish) - return true; - } - return visitor.visit(this); -} - -/** -* This method addes a new actor to the collection. -* @param a :: input actor to be added to the list -*/ -void GLActorCollection::addActor(GLActor *a) { - if (!a) { - return; - } - mActorsList.push_back(a); - Mantid::Kernel::V3D minBound; - Mantid::Kernel::V3D maxBound; - a->getBoundingBox(minBound, maxBound); - if (m_minBound[0] > minBound[0]) - m_minBound[0] = minBound[0]; - if (m_minBound[1] > minBound[1]) - m_minBound[1] = minBound[1]; - if (m_minBound[2] > minBound[2]) - m_minBound[2] = minBound[2]; - if (m_maxBound[0] < maxBound[0]) - m_maxBound[0] = maxBound[0]; - if (m_maxBound[1] < maxBound[1]) - m_maxBound[1] = maxBound[1]; - if (m_maxBound[2] < maxBound[2]) - m_maxBound[2] = maxBound[2]; -} - -/** -* Remove the input actor from the collection -* @param :: input actor to be removed from the list -*/ -void GLActorCollection::removeActor(GLActor *) { - throw std::runtime_error("Removing actor not implemented"); -} - -/** -* This method returns the number of actors in the collection -* @return integer value of number of actors in collection -*/ -int GLActorCollection::getNumberOfActors() { - return static_cast(mActorsList.size()); -} - -/** -* This method returns the actor at the given index -* @param index :: is the index in actor collection to be returned -* @return a pointer to the actor at a given index -*/ -GLActor *GLActorCollection::getActor(int index) { - if (index < 0 || index > static_cast(mActorsList.size())) - return nullptr; - return mActorsList.at(index); -} - -void GLActorCollection::getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const { - minBound = m_minBound; - maxBound = m_maxBound; -} - -void GLActorCollection::invalidateDisplayList() const { - for (size_t i = 0; i < 2; ++i) { - if (m_displayListId[i] != 0) { - glDeleteLists(m_displayListId[i], 1); - m_displayListId[i] = 0; - m_useDisplayList[i] = false; - } - } -} - -void GLActorCollection::setChildVisibility(bool on) { - GLActor::setVisibility(on); - for (std::vector::const_iterator it = mActorsList.begin(); - it != mActorsList.end(); ++it) { - (**it).setChildVisibility(on); - } -} - -bool GLActorCollection::hasChildVisible() const { - for (std::vector::const_iterator it = mActorsList.begin(); - it != mActorsList.end(); ++it) { - if ((**it).hasChildVisible()) - return true; - } - return false; -} -} -} diff --git a/qt/widgets/instrumentview/src/GLActorVisitor.cpp b/qt/widgets/instrumentview/src/GLActorVisitor.cpp deleted file mode 100644 index 1fa156dcf8c1..000000000000 --- a/qt/widgets/instrumentview/src/GLActorVisitor.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" -#include "MantidQtWidgets/InstrumentView/GLActor.h" -#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" - -namespace MantidQt { -namespace MantidWidgets { -// Default visit implementations just call visit(GLActor*) - -bool GLActorVisitor::visit(InstrumentActor *actor) { - return this->visit(static_cast(actor)); -} - -bool GLActorConstVisitor::visit(const InstrumentActor *actor) { - return this->visit(static_cast(actor)); -} - -bool SetAllVisibleVisitor::visit(GLActor *actor) { - actor->setVisibility(true); - return true; -} -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/GLObject.cpp b/qt/widgets/instrumentview/src/GLObject.cpp index a4eb4a7838bf..c071256d7737 100644 --- a/qt/widgets/instrumentview/src/GLObject.cpp +++ b/qt/widgets/instrumentview/src/GLObject.cpp @@ -2,7 +2,6 @@ #include #endif #include "MantidQtWidgets/InstrumentView/GLObject.h" -#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h" #include "MantidKernel/Exception.h" #include "MantidKernel/System.h" diff --git a/qt/widgets/instrumentview/src/ICompAssemblyActor.cpp b/qt/widgets/instrumentview/src/ICompAssemblyActor.cpp deleted file mode 100644 index 6c8d90c69eb0..000000000000 --- a/qt/widgets/instrumentview/src/ICompAssemblyActor.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/ICompAssemblyActor.h" -#include - -#include "MantidKernel/V3D.h" -#include "MantidGeometry/IComponent.h" - -using namespace Mantid; -using namespace Geometry; - -namespace MantidQt { -namespace MantidWidgets { -/** -* This is a constructor for CompAssembly Actor -* @param instrActor :: the instrument actor -* @param compID :: the component ID -*/ -ICompAssemblyActor::ICompAssemblyActor( - const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID) - : ComponentActor(instrActor, compID), mNumberOfDetectors(0), - minBoundBox(DBL_MAX, DBL_MAX, DBL_MAX), - maxBoundBox(-DBL_MAX, -DBL_MAX, -DBL_MAX) {} - -//------------------------------------------------------------------------------------------------ -/** -* Return the bounding box -* @param minBound :: min point of the bounding box -* @param maxBound :: max point of the bounding box -*/ -void ICompAssemblyActor::getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const { - minBound = minBoundBox; - maxBound = maxBoundBox; -} -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index b95107d9cfc4..8163419d3e31 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -1,6 +1,5 @@ #include "MantidQtWidgets/InstrumentView/InstrumentActor.h" #include "MantidQtWidgets/Common/TSVSerialiser.h" -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" #include "MantidAPI/AnalysisDataService.h" @@ -37,6 +36,18 @@ using namespace Mantid; namespace MantidQt { namespace MantidWidgets { +namespace { +size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) { + unsigned int index = r; + index *= 256; + index += g; + index *= 256; + index += b - 1; + return index; +} + +GLColor defaultDetectorColor() { return GLColor(200, 200, 200); } +} // namespace /// to be used in std::transform struct Sqrt { @@ -193,26 +204,6 @@ void InstrumentActor::setUpWorkspace( m_detid2index_map = sharedWorkspace->getDetectorIDToWorkspaceIndexMap(); } -/** Used to set visibility of an actor corresponding to a particular component - * When selecting a component in the InstrumentTreeWidget - * - * @param visitor :: Visitor to be accepted bu this actor. - * @param rule :: A rule defining visitor acceptance by assembly actors. - */ -bool InstrumentActor::accept(GLActorVisitor &visitor, VisitorAcceptRule rule) { - bool ok = true; // m_scene.accept(visitor, rule); - visitor.visit(this); - invalidateDisplayLists(); - return ok; -} - -bool InstrumentActor::accept(GLActorConstVisitor &visitor, - GLActor::VisitorAcceptRule rule) const { - bool ok = true; // m_scene.accept(visitor, rule); - visitor.visit(this); - return ok; -} - void InstrumentActor::setComponentVisible( Mantid::Geometry::ComponentID component) { setChildVisibility(false); @@ -731,14 +722,8 @@ void InstrumentActor::resetColors() { // } //} - setupColors(); + setupPickColors(); invalidateDisplayLists(); - /*if (m_scene.getNumberOfActors() > 0) { - if (auto actor = dynamic_cast(m_scene.getActor(0))) { - actor->setColors(); - invalidateDisplayLists(); - } - }*/ emit colorMapChanged(); } @@ -750,7 +735,11 @@ void InstrumentActor::updateColors() { /** * @param on :: True or false for on or off. */ -void InstrumentActor::showGuides(bool on) { m_showGuides = on; } +void InstrumentActor::showGuides(bool on) +{ + m_showGuides = on; + invalidateDisplayLists(); +} GLColor InstrumentActor::getColor(size_t index) const { if (index <= m_colors.size() - 1) @@ -839,30 +828,7 @@ void InstrumentActor::loadColorMap(const QString &fname, bool reset_colors) { } //------------------------------------------------------------------------------ -/** Add a detector ID to the pick list (m_detIDs) - * The order of detids define the pickIDs for detectors. - * - * @param id :: detector ID to add. - * @return pick ID of the added detector - */ -size_t InstrumentActor::pushBackDetid(Mantid::detid_t id) const { - // m_detIDs.push_back(id); - return 0;//m_detIDs.size() - 1; -} - -//------------------------------------------------------------------------------ -/** Add a non-detector component ID to the pick list (m_nonDetIDs) - * - * @param actor :: ObjComponentActor for the component added. - * @param compID :: component ID to add. - */ -void InstrumentActor::pushBackNonDetid( - ObjComponentActor *actor, Mantid::Geometry::ComponentID compID) const { - //m_nonDetActorsTemp.push_back(actor); - //m_nonDetIDs.push_back(compID); -} - -void InstrumentActor::setupColors() { +void InstrumentActor::setupPickColors() { const auto &componentInfo = getComponentInfo(); m_pickColors.resize(componentInfo.size()); @@ -871,20 +837,6 @@ void InstrumentActor::setupColors() { } } -//------------------------------------------------------------------------------ -/** - * Set pick colors to non-detectors strored by calls to pushBackNonDetid(). - */ -void InstrumentActor::setupPickColors() { - /*assert(m_nonDetActorsTemp.size() == m_nonDetIDs.size()); - const auto &componentInfo = getComponentInfo(); - auto nDets = m_detIDs.size(); - for (size_t i = 0; i < m_nonDetActorsTemp.size(); ++i) { - m_nonDetActorsTemp[i]->setPickColor(makePickColor(nDets + i)); - } - m_nonDetActorsTemp.clear();*/ -} - //------------------------------------------------------------------------------ /** If needed, cache the detector positions for all detectors. * Call this BEFORE getDetPos(). @@ -1395,5 +1347,20 @@ void InstrumentActor::invalidateDisplayLists() const { } } +GLColor InstrumentActor::makePickColor(size_t pickID) { + pickID += 1; + unsigned char r, g, b; + r = static_cast(pickID / 65536); + g = static_cast((pickID % 65536) / 256); + b = static_cast((pickID % 65536) % 256); + return GLColor(r, g, b); +} + +size_t InstrumentActor::decodePickColor(const QRgb &c) { + return decodePickColorRGB(static_cast(qRed(c)), + static_cast(qGreen(c)), + static_cast(qBlue(c))); +} + } // namespace MantidWidgets } // namespace MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp index 698b7b753c45..7c77daa35e33 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp @@ -487,9 +487,7 @@ void InstrumentWidgetRenderTab::showEvent(QShowEvent *) { if (surface) { surface->setInteractionMode(ProjectionSurface::MoveMode); } - auto &actor = m_instrWidget->getInstrumentActor(); - auto visitor = SetAllVisibleVisitor(actor.areGuidesShown()); - actor.accept(visitor); + getSurface()->updateView(); getSurface()->requestRedraw(); } diff --git a/qt/widgets/instrumentview/src/ObjCompAssemblyActor.cpp b/qt/widgets/instrumentview/src/ObjCompAssemblyActor.cpp deleted file mode 100644 index 3c5da76700f8..000000000000 --- a/qt/widgets/instrumentview/src/ObjCompAssemblyActor.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h" -#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h" -#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" -#include "MantidQtWidgets/InstrumentView/OpenGLError.h" - -#include "MantidKernel/V3D.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/ICompAssembly.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/IDetector.h" -#include "MantidGeometry/Instrument/ObjCompAssembly.h" -#include "MantidKernel/Exception.h" -#include -using namespace Mantid; -using namespace Geometry; - -namespace MantidQt { -namespace MantidWidgets { - -ObjCompAssemblyActor::ObjCompAssemblyActor(const InstrumentActor &instrActor, - Mantid::Geometry::ComponentID compID) - : ICompAssemblyActor(instrActor, compID), m_idData(0), m_idPick(0), - m_n(getObjCompAssembly()->nelements()), m_pick_data(), - m_texturesGenerated(false) { - - ObjCompAssembly_const_sptr objAss = getObjCompAssembly(); - mNumberOfDetectors = objAss->nelements(); - assert(static_cast(m_n) == mNumberOfDetectors); - m_data = new unsigned char[m_n * 3]; - m_pick_data = new unsigned char[m_n * 3]; - for (size_t i = 0; i < getNumberOfDetectors(); ++i) { - IDetector_const_sptr det = boost::dynamic_pointer_cast( - objAss->getChild(static_cast(i))); - assert(det); - detid_t id = det->getID(); - m_detIDs.push_back(id); - size_t pickID = instrActor.pushBackDetid(id); - setDetectorColor(m_pick_data, i, GLActor::makePickColor(pickID)); - } - Mantid::Geometry::BoundingBox boundBox; - objAss->getBoundingBox(boundBox); - minBoundBox[0] = boundBox.xMin(); - minBoundBox[1] = boundBox.yMin(); - minBoundBox[2] = boundBox.zMin(); - maxBoundBox[0] = boundBox.xMax(); - maxBoundBox[1] = boundBox.yMax(); - maxBoundBox[2] = boundBox.zMax(); -} - -/** -* Destructor which removes the actors created by this object -*/ -ObjCompAssemblyActor::~ObjCompAssemblyActor() { - if (m_data) { - delete[] m_data; - delete[] m_pick_data; - } - if (m_texturesGenerated) { - glDeleteTextures(1, &m_idData); - glDeleteTextures(1, &m_idPick); - } -} - -/** -* This function is concrete implementation that renders the Child ObjComponents -* and Child CompAssembly's -*/ -void ObjCompAssemblyActor::draw(bool picking) const { - OpenGLError::check("ObjCompAssemblyActor::draw(0)"); - - if (!m_texturesGenerated) { - setDataColors(); - setPickColors(); - m_texturesGenerated = true; - } - - ObjCompAssembly_const_sptr objAss = getObjCompAssembly(); - glPushMatrix(); - - unsigned int texID = picking ? m_idPick : m_idData; - // Because texture colours are combined with the geometry colour - // make sure the current colour is white - glColor3f(1.0f, 1.0f, 1.0f); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texID); - objAss->draw(); - glBindTexture(GL_TEXTURE_2D, 0); - OpenGLError::check("ObjCompAssemblyActor::draw()"); - - glPopMatrix(); -} - -void ObjCompAssemblyActor::generateTexture(unsigned char *data, - unsigned int &id) const { - if (id > 0) { - glDeleteTextures(1, &id); - OpenGLError::check("TexObject::generateTexture()[delete texture] "); - } - - int width = 1; - int height = m_n; - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glGenTextures(1, &id); // Create The Texture - OpenGLError::check("TexObject::generateTexture()[generate] "); - glBindTexture(GL_TEXTURE_2D, id); - OpenGLError::check("TexObject::generateTexture()[bind] "); - - GLint texParam = GL_NEAREST; - glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, - data); - OpenGLError::check("TexObject::generateTexture()[set data] "); - /* If the above call to glTexImage2D has generated an error, it is likely as a - * result - * of outline="yes" being set in the IDF. If this is enabled then the texture - * above - * is generated with a width being equal to the number of points that make up - * the - * outline. However, some OpenGL implementations only support textures with a - * 2^n size. - * On the machines tested (Ubuntu 14.04, Windows 7, and RHEL6), this was not an - * issue, - * but we can't guarantee that a user wont try this on a system that doesn't - * support - * non power of 2 textures. In that case, the best thing to do would be to - * create a - * texture with a width of the next 2^n up, and adjust the texture coordinates - * accordingly. However, this is not a trivial change to make, and as far as we - * can tell - * no one has ever run into this issue, so it's being left for now. If this - * does prove - * problematic in the future, hopefully this note will save you some time - * figuring out - * the problem. - */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam); - OpenGLError::check("TexObject::generateTexture()[parameters] "); -} - -/** -* Set colour to a detector. -* @param data :: pointer to color array -* @param i :: Index of the detector in ObjCompAssembly -* @param c :: The colour -*/ -void ObjCompAssemblyActor::setDetectorColor(unsigned char *data, size_t i, - GLColor c) const { - size_t pos = 3 * i; - float r, g, b, a; - c.get(r, g, b, a); - data[pos] = (unsigned char)(r * 255); - data[pos + 1] = (unsigned char)(g * 255); - data[pos + 2] = (unsigned char)(b * 255); -} - -void ObjCompAssemblyActor::swap() { - if (!m_pick_data) { - m_pick_data = new unsigned char[m_n * 3]; - } - unsigned char *tmp = m_data; - m_data = m_pick_data; - m_pick_data = tmp; -} - -const unsigned char *ObjCompAssemblyActor::getColor(int i) const { - return &m_data[3 * i]; -} - -void ObjCompAssemblyActor::setColors() { setDataColors(); } - -void ObjCompAssemblyActor::setDataColors() const { - for (size_t i = 0; i < size_t(m_n); ++i) { - GLColor c = m_instrActor.getColor(m_detIDs[i]); - setDetectorColor(m_data, i, c); - } - generateTexture(m_data, m_idData); -} - -void ObjCompAssemblyActor::setPickColors() const { - generateTexture(m_pick_data, m_idPick); -} - -bool ObjCompAssemblyActor::accept(GLActorVisitor &visitor, - GLActor::VisitorAcceptRule) { - return visitor.visit(this); -} - -bool ObjCompAssemblyActor::accept(GLActorConstVisitor &visitor, - GLActor::VisitorAcceptRule) const { - return visitor.visit(this); -} - -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/ObjComponentActor.cpp b/qt/widgets/instrumentview/src/ObjComponentActor.cpp deleted file mode 100644 index dd1c140ffc9f..000000000000 --- a/qt/widgets/instrumentview/src/ObjComponentActor.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h" -#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" -#include "MantidQtWidgets/InstrumentView/OpenGLError.h" - -#include "MantidKernel/V3D.h" -#include "MantidKernel/Quat.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/IComponent.h" -#include "MantidKernel/Exception.h" -#include "MantidGeometry/IDetector.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Objects/BoundingBox.h" - -using namespace Mantid; -using namespace Geometry; - -namespace { -// Anonymous namespace - -/** - * Returns if the current component is finite or - * has 'infinite' length based on all axis found - * within the bounding box - * - * @param compID:: The component to check - * @return :: True if the component has finite size else False - */ -bool isComponentFinite(const Mantid::Geometry::ComponentID &compID) { - Geometry::BoundingBox boundedBox; - compID->getBoundingBox(boundedBox); - const auto width = boundedBox.width(); - const double x = width[0]; - const double y = width[1]; - const double z = width[2]; - - // Currently an 'infinite' component will have length 1000 - // on one of its axis. Check all to make sure it is not greater - // than 1000 units in length. - const double maximumSize = 999; - if (x > maximumSize || y > maximumSize || z > maximumSize) { - return false; - } else { - return true; - } -} -} - -namespace MantidQt { -namespace MantidWidgets { - -ObjComponentActor::ObjComponentActor(const InstrumentActor &instrActor, - Mantid::Geometry::ComponentID compID) - : ComponentActor(instrActor, compID) { - // set the displayed colour - setColors(); - - if (!isComponentFinite(compID)) { - // If the component does not have finite length we set it always - // hidden so scale is not messed up and it is not displayed. - setAlwaysHidden(); - } - - // register the component with InstrumentActor and set the pick colour - IDetector_const_sptr det = getDetector(); - if (det) { - size_t pickID = instrActor.pushBackDetid(det->getID()); - m_pickColor = makePickColor(pickID); - } else { - instrActor.pushBackNonDetid(this, compID); - } -} - -ObjComponentActor::~ObjComponentActor() {} - -//------------------------------------------------------------------------------------------------- -/** -* Concrete implementation of rendering ObjComponent. -*/ -void ObjComponentActor::draw(bool picking) const { - OpenGLError::check("ObjComponentActor::draw(0)"); - glPushMatrix(); - if (picking) { - m_pickColor.paint(); - } else { - m_dataColor.paint(); - } - getObjComponent()->draw(); - glPopMatrix(); - OpenGLError::check("ObjComponentActor::draw()"); -} - -/** -* Set displayed component colour. If it's a detector the colour maps to the -* integrated counts in it. -*/ -void ObjComponentActor::setColors() { - IDetector_const_sptr det = getDetector(); - if (det) { - setColor(m_instrActor.getColor(det->getID())); - } else { - setColor(defaultDetectorColor()); - } -} - -/** -* Return the bounding box of visible components. -* If this is not visible an empty V3D object will -* be returned. -* @param minBound :: min point of the bounding box -* @param maxBound :: max point of the bounding box -*/ -void ObjComponentActor::getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const { - if (!isVisible()) { - // If this is not visible we should not consider this component - minBound = Kernel::V3D(); - maxBound = Kernel::V3D(); - } else { - Mantid::Geometry::BoundingBox boundBox; - getComponent()->getBoundingBox(boundBox); - minBound = boundBox.minPoint(); - maxBound = boundBox.maxPoint(); - } -} - -} // MantidWidgets -} // MantidQt \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 18a1fade7873..2379694fe897 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -1,15 +1,9 @@ -#include "MantidQtWidgets/InstrumentView/CompAssemblyActor.h" -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" -#include "MantidQtWidgets/InstrumentView/ObjCompAssemblyActor.h" #include "MantidQtWidgets/InstrumentView/PanelsSurface.h" #include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" -#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h" -#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidGeometry/Instrument/ComponentInfo.h" -#include "MantidGeometry/Instrument/ObjCompAssembly.h" #include "MantidKernel/Logger.h" #include "MantidKernel/Tolerance.h" #include "MantidKernel/V3D.h" diff --git a/qt/widgets/instrumentview/src/Projection3D.cpp b/qt/widgets/instrumentview/src/Projection3D.cpp index 14d17c86f993..37e4308bc27c 100644 --- a/qt/widgets/instrumentview/src/Projection3D.cpp +++ b/qt/widgets/instrumentview/src/Projection3D.cpp @@ -2,7 +2,6 @@ #include #endif #include "MantidQtWidgets/InstrumentView/Projection3D.h" -#include "MantidQtWidgets/InstrumentView/GLActor.h" #include "MantidQtWidgets/InstrumentView/GLColor.h" #include "MantidQtWidgets/InstrumentView/UnwrappedCylinder.h" #include "MantidQtWidgets/InstrumentView/UnwrappedSphere.h" diff --git a/qt/widgets/instrumentview/src/ProjectionSurface.cpp b/qt/widgets/instrumentview/src/ProjectionSurface.cpp index c8991e796c30..6d64e7900297 100644 --- a/qt/widgets/instrumentview/src/ProjectionSurface.cpp +++ b/qt/widgets/instrumentview/src/ProjectionSurface.cpp @@ -500,7 +500,7 @@ size_t ProjectionSurface::getPickID(int x, int y) const { if (!m_pickImage || !m_pickImage->valid(x, y)) return -1; QRgb pixel = m_pickImage->pixel(x, y); - return GLActor::decodePickColor(pixel); + return InstrumentActor::decodePickColor(pixel); } /** diff --git a/qt/widgets/instrumentview/src/RectangularDetectorActor.cpp b/qt/widgets/instrumentview/src/RectangularDetectorActor.cpp deleted file mode 100644 index 3f4bc833162d..000000000000 --- a/qt/widgets/instrumentview/src/RectangularDetectorActor.cpp +++ /dev/null @@ -1,332 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/RectangularDetectorActor.h" -#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h" -#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" - -#include "MantidKernel/V3D.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Objects/BoundingBox.h" -#include "MantidGeometry/ICompAssembly.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/IDetector.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Instrument.h" -#include "MantidKernel/Exception.h" -#include -#include "MantidGeometry/IComponent.h" -using namespace Mantid; -using namespace Geometry; -using Mantid::Kernel::V3D; -using Mantid::Kernel::Quat; - -namespace MantidQt { -namespace MantidWidgets { - -static const bool VERBOSE = false; - -/** -* Constructor. -* -* @param instrActor :: the instrument actor -* @param compID :: the component ID -*/ -RectangularDetectorActor::RectangularDetectorActor( - const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID) - : ICompAssemblyActor(instrActor, compID), mTextureID(0), - image_data(nullptr), pick_data(nullptr) { - mNumberOfDetectors = 0; - mDet = boost::dynamic_pointer_cast(getComponent()); - - if (!mDet) - return; - - BoundingBox compBox; - mDet->getBoundingBox(compBox); - mNumberOfDetectors = mDet->xpixels() * mDet->ypixels(); - this->AppendBoundingBox(compBox.minPoint(), compBox.maxPoint()); - - std::vector clist; - for (int y = 0; y < mDet->ypixels(); y++) { - for (int x = 0; x < mDet->xpixels(); x++) { - // Getting the detector is slow. Get the ID directly - detid_t id = mDet->getDetectorIDAtXY(x, y); - size_t pickID = instrActor.pushBackDetid(id); - m_pickIDs.push_back(pickID); - clist.push_back(instrActor.getColor(id)); - } - } - - genTexture(image_data, clist, false); - genTexture(pick_data, clist, true); - uploadTexture(image_data); -} - -//------------------------------------------------------------------------------------------------- -/** -* Destructor which removes the actors created by this object -*/ -RectangularDetectorActor::~RectangularDetectorActor() { - delete[] image_data; - delete[] pick_data; -} - -//------------------------------------------------------------------------------------------------- -/** -* This function is concrete implementation that renders the Child ObjComponents -* and Child CompAssembly's -*/ -void RectangularDetectorActor::draw(bool picking) const { - if (VERBOSE) - std::cout << "RectangularDetectorActor::define() called for " - << mDet->getName() << "\n"; - - glPushMatrix(); - // Translation first - V3D pos = mDet->getPos(); - if (!(pos.nullVector())) { - glTranslated(pos[0], pos[1], pos[2]); - } - // Rotation - Quat rot = mDet->getRotation(); - if (!(rot.isNull())) { - double deg, ax0, ax1, ax2; - rot.getAngleAxis(deg, ax0, ax1, ax2); - glRotated(deg, ax0, ax1, ax2); - } - // Scale - V3D scaleFactor = mDet->getScaleFactor(); - if (!(scaleFactor == V3D(1, 1, 1))) { - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - } - - // glBindTexture(GL_TEXTURE_2D, mTextureID); - if (picking) { - this->uploadTexture(pick_data); - } else { - this->uploadTexture(image_data); - } - // RectangularDetector will use. - mDet->draw(); - glBindTexture(GL_TEXTURE_2D, 0); - - glPopMatrix(); -} - -//------------------------------------------------------------------------------------------------ -/** -* Accept a visitor. This sets the matching component's visibility to True. -* It looks if the given component is a child (pixel) of the parent rectangular -* detector, and sets the visibility of the whole panel to true if so. -* -* @param visitor :: A visitor. -* @param rule :: A rule defining visitor acceptance by assembly actors. Unused. -* -*/ -bool RectangularDetectorActor::accept(GLActorVisitor &visitor, - VisitorAcceptRule) { - return visitor.visit(this); -} - -bool RectangularDetectorActor::accept(GLActorConstVisitor &visitor, - GLActor::VisitorAcceptRule) const { - return visitor.visit(this); -} - -bool RectangularDetectorActor::isChildDetector(const ComponentID &id) const { - // ID of the parent RectangularDetector - Mantid::Geometry::ComponentID thisID = this->m_id; - - // Get the component object - IComponent_const_sptr comp = - m_instrActor.getInstrument()->getComponentByID(id); - if (comp) { - // Get the parent (e.g. the column) - IComponent_const_sptr parent1 = comp->getParent(); - if (parent1) { - if (parent1->getComponentID() == thisID) { - return true; - } - // Go to grandparent - IComponent_const_sptr parent2 = parent1->getParent(); - if (parent2) { - if (parent2->getComponentID() == thisID) { - return true; - } - } // valid grandparent - } // valid parent - } // valid component - return false; -} - -//------------------------------------------------------------------------------------------------ -/** -* Generate a texture for the RectangularDetector -* -* @param image_data :: pointer to where the image data will be filled in. -* @param list :: Color list iterator. Only used if useDetectorIDs is false. -* @param useDetectorIDs :: set to true to make a fake texture using the detector -*IDs. If false, the iterator is used. -* -*/ -int RectangularDetectorActor::genTexture(char *&image_data, - std::vector &list, - bool useDetectorIDs) { - int num = mDet->xpixels() * mDet->ypixels(); - - // The texture size must be 2^n power. - int text_x_size, text_y_size; - mDet->getTextureSize(text_x_size, text_y_size); - - // std::cerr << "Texture size: " << text_x_size << ',' << text_y_size - // <<'\n'; - - //------ Create the image data buffer ------- - if (!image_data) { - // Delete the old memory - delete[] image_data; - image_data = new char[3 * text_x_size * text_y_size]; - } - // Pointer to where we are in it. - char *image_data_ptr = image_data; - - // Fill with 0 (black) everywhere - std::fill(image_data, image_data + 3 * text_x_size * text_y_size, 0); - - // For using color IDs - int rgb = 0; - std::vector::iterator list_it = list.begin(); - - for (int y = 0; y < mDet->ypixels(); y++) { - for (int x = 0; x < mDet->xpixels(); x++) { - // Use black as the default color (for going off the edges) - unsigned char r, g, b; - - if (useDetectorIDs) { - GLColor c = GLActor::makePickColor(m_pickIDs[rgb]); - c.get(r, g, b); - rgb++; - } else { - // Get the current color - list_it->get(r, g, b); - // Go to the next color - ++list_it; - } - - // //TEMP: way to show the colors - // r=x; - // g=y; - // b=x; - - // Save the color data to the buffer - *image_data_ptr = r; - image_data_ptr++; - *image_data_ptr = g; - image_data_ptr++; - *image_data_ptr = b; - image_data_ptr++; - } - - // Skip any padding in x. 3 bytes per pixel - image_data_ptr += 3 * (text_x_size - mDet->xpixels()); - } - - if (VERBOSE) - std::cout << "RectangularDetectorActor::genTexture() called for " - << mDet->getName() << " with " << num << " entries set\n"; - - return num; -} - -//------------------------------------------------------------------------------------------------ -/** Upload the texture to the video card. */ -void RectangularDetectorActor::uploadTexture(char *&image_data) const { - if (!image_data) - throw std::runtime_error( - "Empty pointer passed to RectangularDetectorActor::uploadTexture()!"); - - // The texture size must be 2^n power. - int text_x_size, text_y_size; - mDet->getTextureSize(text_x_size, text_y_size); - - // Set up before uploading a texture - if (mTextureID > 0) - glDeleteTextures(1, &mTextureID); - glGenTextures(1, &mTextureID); // Create The Texture - if (VERBOSE) - std::cout << mDet->getName() << " is drawing with texture id " << mTextureID - << "\n"; - // mDet->setTextureID(mTextureID); - - glBindTexture(GL_TEXTURE_2D, mTextureID); - - if (glGetError() > 0) - std::cout << "OpenGL error in glBindTexture \n"; - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, - GL_MODULATE); // This one allows lighting effects - // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //This one - // doesn't - - // Upload the texture to video card - if (glGetError() > 0) - std::cout << "OpenGL error BEFORE glTexImage2D \n"; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, text_x_size, text_y_size, 0, GL_RGB, - GL_UNSIGNED_BYTE, image_data); - if (glGetError() > 0) - std::cout << "OpenGL error in glTexImage2D \n"; -} - -//------------------------------------------------------------------------------------------------- -/** -* Return the bounding box, from the one calculated in the cache previously. -* @param minBound :: min point of the bounding box -* @param maxBound :: max point of the bounding box -*/ -void RectangularDetectorActor::getBoundingBox( - Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound) const { - minBound = minBoundBox; - maxBound = maxBoundBox; -} - -/** -* Append the bounding box CompAssembly bounding box -* @param minBound :: min point of the bounding box -* @param maxBound :: max point of the bounding box -*/ -void RectangularDetectorActor::AppendBoundingBox( - const Mantid::Kernel::V3D &minBound, const Mantid::Kernel::V3D &maxBound) { - if (minBoundBox[0] > minBound[0]) - minBoundBox[0] = minBound[0]; - if (minBoundBox[1] > minBound[1]) - minBoundBox[1] = minBound[1]; - if (minBoundBox[2] > minBound[2]) - minBoundBox[2] = minBound[2]; - if (maxBoundBox[0] < maxBound[0]) - maxBoundBox[0] = maxBound[0]; - if (maxBoundBox[1] < maxBound[1]) - maxBoundBox[1] = maxBound[1]; - if (maxBoundBox[2] < maxBound[2]) - maxBoundBox[2] = maxBound[2]; -} - -void RectangularDetectorActor::setColors() { - std::vector clist; - for (int y = 0; y < mDet->ypixels(); y++) { - for (int x = 0; x < mDet->xpixels(); x++) { - detid_t id = mDet->getDetectorIDAtXY(x, y); - clist.push_back(m_instrActor.getColor(id)); - } - } - genTexture(image_data, clist, false); - uploadTexture(image_data); -} -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/SampleActor.cpp b/qt/widgets/instrumentview/src/SampleActor.cpp deleted file mode 100644 index a2fc83fe23be..000000000000 --- a/qt/widgets/instrumentview/src/SampleActor.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/SampleActor.h" -#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" -#include "MantidQtWidgets/InstrumentView/OpenGLError.h" - -#include "MantidAPI/Sample.h" -#include "MantidGeometry/IObjComponent.h" - -using namespace Mantid; -using namespace Geometry; - -namespace MantidQt { -namespace MantidWidgets { - -SampleActor::SampleActor(const InstrumentActor &instrActor, - const Mantid::API::Sample &sample, - const ObjComponentActor *samplePosActor) - : GLActor(), m_instrActor(instrActor), m_sample(sample), - m_samplePosActor(samplePosActor), - m_samplePos(samplePosActor->getObjComponent()), m_color(255, 255, 255) {} - -/** -* Implementation of rendering Sample. -*/ -void SampleActor::draw(bool picking) const { - if (!picking && isVisible()) { - OpenGLError::check("SampleActor::draw()"); - glPushAttrib(GL_ENABLE_BIT); - GLboolean hasLight0; - glGetBooleanv(GL_LIGHT0, &hasLight0); - if (hasLight0) { - glEnable(GL_LIGHTING); - } - glPushMatrix(); - m_color.paint(); - Mantid::Kernel::V3D pos = m_samplePos->getPos(); - glTranslated(pos.X(), pos.Y(), pos.Z()); - m_sample.getShape().draw(); - glPopMatrix(); - glPopAttrib(); - OpenGLError::check("SampleActor::draw()"); - } -} - -void SampleActor::getBoundingBox(Mantid::Kernel::V3D &minBound, - Mantid::Kernel::V3D &maxBound) const { - Mantid::Geometry::BoundingBox boundBox = m_sample.getShape().getBoundingBox(); - minBound = boundBox.minPoint(); - maxBound = boundBox.maxPoint(); -} -} // MantidWidgets -} // MantidQt diff --git a/qt/widgets/instrumentview/src/StructuredDetectorActor.cpp b/qt/widgets/instrumentview/src/StructuredDetectorActor.cpp deleted file mode 100644 index 5e539f666986..000000000000 --- a/qt/widgets/instrumentview/src/StructuredDetectorActor.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" -#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" -#include "MantidQtWidgets/InstrumentView/ObjComponentActor.h" -#include "MantidQtWidgets/InstrumentView/StructuredDetectorActor.h" - -#include "MantidGeometry/ICompAssembly.h" -#include "MantidGeometry/IComponent.h" -#include "MantidGeometry/IDetector.h" -#include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/Instrument.h" -#include "MantidGeometry/Instrument/StructuredDetector.h" -#include "MantidGeometry/Objects/BoundingBox.h" -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidKernel/Exception.h" -#include "MantidKernel/V3D.h" -#include -using namespace Mantid; -using namespace Geometry; -using Mantid::Kernel::V3D; -using Mantid::Kernel::Quat; - -namespace MantidQt { -namespace MantidWidgets { - -/** -* Constructor. -* -* @param instrActor :: the instrument actor -* @param compID :: the component ID -*/ -StructuredDetectorActor::StructuredDetectorActor( - const InstrumentActor &instrActor, - const Mantid::Geometry::ComponentID &compID) - : ICompAssemblyActor(instrActor, compID) { - - mNumberOfDetectors = 0; - m_det = boost::dynamic_pointer_cast(getComponent()); - - if (!m_det) - return; - - BoundingBox compBox; - m_det->getBoundingBox(compBox); - mNumberOfDetectors = m_det->xPixels() * m_det->yPixels(); - this->AppendBoundingBox(compBox.minPoint(), compBox.maxPoint()); - - for (size_t y = 0; y < m_det->yPixels(); y++) { - for (size_t x = 0; x < m_det->xPixels(); x++) { - // Getting the detector is slow. Get the ID directly - detid_t id = m_det->getDetectorIDAtXY(x, y); - size_t pickID = instrActor.pushBackDetid(id); - m_pickIds.push_back(pickID); - m_pickColors.push_back(GLActor::makePickColor(pickID)); - m_clist.push_back(instrActor.getColor(id)); - } - } -} - -/** -* Destructor which removes the actors created by this object -*/ -StructuredDetectorActor::~StructuredDetectorActor() {} - -void StructuredDetectorActor::draw(bool picking) const { - glPushMatrix(); - // Translation first - V3D pos = m_det->getPos(); - if (!(pos.nullVector())) { - glTranslated(pos[0], pos[1], pos[2]); - } - // Rotation - Quat rot = m_det->getRotation(); - if (!(rot.isNull())) { - double deg, ax0, ax1, ax2; - rot.getAngleAxis(deg, ax0, ax1, ax2); - glRotated(deg, ax0, ax1, ax2); - } - // Scale - V3D scaleFactor = m_det->getScaleFactor(); - if (!(scaleFactor == V3D(1, 1, 1))) { - glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - } - - // StructuredDetector will use. - std::vector r, g, b; - - if (picking) { - for (std::vector::const_iterator i = m_pickColors.cbegin(); - i != m_pickColors.cend(); ++i) { - r.push_back((*i).red()); - g.push_back((*i).green()); - b.push_back((*i).blue()); - } - } else { - for (std::vector::const_iterator i = m_clist.cbegin(); - i != m_clist.cend(); ++i) { - r.push_back((*i).red()); - g.push_back((*i).green()); - b.push_back((*i).blue()); - } - } - - m_det->setColors(r, g, b); - m_det->draw(); - - glPopMatrix(); -} - -/** -* Accept a visitor. This sets the matching component's visibility to True. -* It looks if the given component is a child (pixel) of the parent rectangular -* detector, and sets the visibility of the whole panel to true if so. -* -* @param visitor :: A visitor. -* @param rule :: A rule defining visitor acceptance by assembly actors. Unused. -* -*/ -bool StructuredDetectorActor::accept(GLActorVisitor &visitor, - VisitorAcceptRule) { - return visitor.visit(this); -} - -bool StructuredDetectorActor::accept(GLActorConstVisitor &visitor, - VisitorAcceptRule) const { - return visitor.visit(this); -} - -bool StructuredDetectorActor::isChildDetector( - const Mantid::Geometry::ComponentID &id) const { - // ID of the parent RectangularDetector - Mantid::Geometry::ComponentID thisID = this->m_id; - - // Get the component object - IComponent_const_sptr comp = - m_instrActor.getInstrument()->getComponentByID(id); - if (comp) { - // Get the parent (e.g. the column) - IComponent_const_sptr parent1 = comp->getParent(); - if (parent1) { - if (parent1->getComponentID() == thisID) { - return true; - } - // Go to grandparent - IComponent_const_sptr parent2 = parent1->getParent(); - if (parent2) { - if (parent2->getComponentID() == thisID) { - return true; - } - } // valid grandparent - } // valid parent - } // valid component - return false; -} - -//------------------------------------------------------------------------------------------------- -/** -* Return the bounding box, from the one calculated in the cache previously. -* @param minBound :: min point of the bounding box -* @param maxBound :: max point of the bounding box -*/ -void StructuredDetectorActor::getBoundingBox( - Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound) const { - minBound = minBoundBox; - maxBound = maxBoundBox; -} - -/** -* Append the bounding box CompAssembly bounding box -* @param minBound :: min point of the bounding box -* @param maxBound :: max point of the bounding box -*/ -void StructuredDetectorActor::AppendBoundingBox( - const Mantid::Kernel::V3D &minBound, const Mantid::Kernel::V3D &maxBound) { - if (minBoundBox[0] > minBound[0]) - minBoundBox[0] = minBound[0]; - if (minBoundBox[1] > minBound[1]) - minBoundBox[1] = minBound[1]; - if (minBoundBox[2] > minBound[2]) - minBoundBox[2] = minBound[2]; - if (maxBoundBox[0] < maxBound[0]) - maxBoundBox[0] = maxBound[0]; - if (maxBoundBox[1] < maxBound[1]) - maxBoundBox[1] = maxBound[1]; - if (maxBoundBox[2] < maxBound[2]) - maxBoundBox[2] = maxBound[2]; -} - -void StructuredDetectorActor::setColors() { - // do nothing -} - -} // namespace MantidWidgets -} // namespace MantidQt \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 9c04e841acc2..3309cf05637a 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -239,7 +239,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { */ void UnwrappedSurface::setColor(int index, bool picking) const { if (picking) { - auto c = GLActor::makePickColor(index); + auto c = InstrumentActor::makePickColor(index); unsigned char r, g, b; c.get(r, g, b); glColor3ub(r, g, b); @@ -515,7 +515,7 @@ void UnwrappedSurface::drawSimpleToImage(QImage *image, bool picking) const { QColor color; int index = int(i); if (picking) { - GLColor c = GLActor::makePickColor(index); + GLColor c = InstrumentActor::makePickColor(index); unsigned char r, g, b; c.get(r, g, b); color = QColor(r, g, b); From 8036a073ba3178ebadef34fd42ac66b2094285e3 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 8 Jan 2018 11:59:52 +0000 Subject: [PATCH 034/364] fix instrument tree model 21339 --- .../inc/MantidBeamline/ComponentInfo.h | 10 +- Framework/Beamline/src/ComponentInfo.cpp | 25 +++ Framework/Beamline/test/ComponentInfoTest.h | 101 +++++++-- .../MantidGeometry/Instrument/ComponentInfo.h | 1 + .../MantidGeometry/Instrument/DetectorInfo.h | 2 + .../Instrument/InstrumentVisitor.h | 3 + .../Geometry/src/Instrument/ComponentInfo.cpp | 5 + .../Geometry/src/Instrument/DetectorInfo.cpp | 12 ++ .../src/Instrument/InstrumentVisitor.cpp | 10 +- Framework/Geometry/test/ComponentInfoTest.h | 13 +- .../Geometry/test/InstrumentVisitorTest.h | 64 +++++- .../InstrumentView/InstrumentActor.h | 21 +- .../InstrumentView/InstrumentTreeModel.h | 3 +- .../InstrumentView/InstrumentTreeWidget.h | 2 +- .../InstrumentView/InstrumentWidget.h | 2 +- .../InstrumentView/InstrumentWidgetPickTab.h | 1 - .../InstrumentView/MantidGLWidget.h | 2 +- .../InstrumentView/Projection3D.h | 2 +- .../InstrumentView/ProjectionSurface.h | 4 +- .../InstrumentView/UnwrappedSurface.h | 11 +- .../instrumentview/src/InstrumentActor.cpp | 193 +++++++++--------- .../src/InstrumentTreeModel.cpp | 159 +++++++-------- .../src/InstrumentTreeWidget.cpp | 85 ++------ .../instrumentview/src/InstrumentWidget.cpp | 21 +- .../src/InstrumentWidgetPickTab.cpp | 179 ++++++---------- .../src/InstrumentWidgetRenderTab.cpp | 2 +- .../src/InstrumentWidgetTreeTab.cpp | 7 +- .../instrumentview/src/MantidGLWidget.cpp | 4 +- .../instrumentview/src/PanelsSurface.cpp | 1 - .../instrumentview/src/Projection3D.cpp | 22 +- .../instrumentview/src/ProjectionSurface.cpp | 6 +- .../instrumentview/src/RotationSurface.cpp | 7 - .../instrumentview/src/UnwrappedSurface.cpp | 105 +++------- 33 files changed, 522 insertions(+), 563 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index edc8082ed89b..c5c0d5c83695 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -52,6 +52,7 @@ class MANTID_BEAMLINE_DLL ComponentInfo { boost::shared_ptr>> m_componentRanges; boost::shared_ptr> m_parentIndices; + boost::shared_ptr>> m_instrumentTree; Mantid::Kernel::cow_ptr> m_positions; Mantid::Kernel::cow_ptr>> @@ -98,13 +99,11 @@ class MANTID_BEAMLINE_DLL ComponentInfo { boost::shared_ptr>> componentRanges, boost::shared_ptr> parentIndices, + boost::shared_ptr>> instrumentTree, boost::shared_ptr> positions, - boost::shared_ptr>> - rotations, + boost::shared_ptr> rotations, boost::shared_ptr> scaleFactors, - boost::shared_ptr> componentType, - boost::shared_ptr> names, + boost::shared_ptr> componentType, boost::shared_ptr> names, int64_t sourceIndex, int64_t sampleIndex); /// Copy assignment not permitted because of the way DetectorInfo stored ComponentInfo &operator=(const ComponentInfo &other) = delete; @@ -112,6 +111,7 @@ class MANTID_BEAMLINE_DLL ComponentInfo { std::unique_ptr cloneWithoutDetectorInfo() const; std::vector detectorsInSubtree(const size_t componentIndex) const; std::vector componentsInSubtree(const size_t componentIndex) const; + const std::vector &children(const size_t componentIndex) const; size_t size() const; bool isDetector(const size_t componentIndex) const { return componentIndex < m_assemblySortedDetectorIndices->size(); diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 2e53c46e4701..a729b691a3bf 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -38,6 +38,7 @@ ComponentInfo::ComponentInfo( boost::shared_ptr>> componentRanges, boost::shared_ptr> parentIndices, + boost::shared_ptr>> instrumentTree, boost::shared_ptr> positions, boost::shared_ptr>> @@ -52,6 +53,7 @@ ComponentInfo::ComponentInfo( m_detectorRanges(std::move(detectorRanges)), m_componentRanges(std::move(componentRanges)), m_parentIndices(std::move(parentIndices)), + m_instrumentTree(std::move(instrumentTree)), m_positions(std::move(positions)), m_rotations(std::move(rotations)), m_scaleFactors(std::move(scaleFactors)), m_componentType(std::move(componentType)), m_names(std::move(names)), @@ -92,6 +94,16 @@ ComponentInfo::ComponentInfo( throw std::invalid_argument("ComponentInfo should be provided same number " "of names as number of components"); } + + size_t treeSize = 1; // initialize with root + for (const auto &assem : *m_instrumentTree) + treeSize += assem.size(); + + if (treeSize != m_size) { + throw std::invalid_argument("ComponentInfo should be provided an " + "instrument tree which contains same number " + "components"); + } } std::unique_ptr ComponentInfo::cloneWithoutDetectorInfo() const { @@ -140,6 +152,19 @@ ComponentInfo::componentsInSubtree(const size_t componentIndex) const { return indices; } +const std::vector & +ComponentInfo::children(const size_t componentIndex) const { + static std::vector emptyVec; + auto dets = detectorRangeInSubtree(root()); + auto numDets = static_cast(std::distance(dets.begin(), dets.end())); + auto index = componentIndex - numDets; + + if (index < m_instrumentTree->size()) + return (*m_instrumentTree)[index]; + + return emptyVec; +} + size_t ComponentInfo::size() const { return m_size; } Eigen::Vector3d ComponentInfo::position(const size_t componentIndex) const { diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 4af0a9d5fdbc..0bd658dbb967 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -66,6 +66,11 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) { auto isRectangularBank = boost::make_shared>(1, ComponentType::Generic); + std::vector children(detPositions.size()); + std::iota(children.begin(), children.end(), 0); + auto instrumentTree = + boost::make_shared>>(1, children); + auto componentInfo = boost::make_shared( bankSortedDetectorIndices, boost::make_shared>>( @@ -73,8 +78,8 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, positions, rotations, scaleFactors, isRectangularBank, - names, -1, -1); + parentIndices, instrumentTree, positions, rotations, scaleFactors, + isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -141,6 +146,8 @@ makeTreeExampleAndReturnGeometricArguments() { // Rectangular bank flag auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); + auto instrumentTree = boost::make_shared>>( + 2, std::vector(2)); auto compInfo = boost::make_shared( bankSortedDetectorIndices, @@ -149,7 +156,7 @@ makeTreeExampleAndReturnGeometricArguments() { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, compPositions, compRotations, scaleFactors, + parentIndices, instrumentTree, compPositions, compRotations, scaleFactors, isRectangularBank, names, -1, -1); compInfo->setDetectorInfo(detectorInfo.get()); @@ -207,6 +214,9 @@ makeTreeExample() { // Rectangular bank flag auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); + + auto instrumentTree = boost::make_shared>>( + 2, std::vector(2)); auto componentInfo = boost::make_shared( bankSortedDetectorIndices, @@ -215,7 +225,7 @@ makeTreeExample() { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, positions, rotations, scaleFactors, isRectangularBank, + parentIndices, instrumentTree, positions, rotations, scaleFactors, isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -273,12 +283,13 @@ class ComponentInfoTest : public CxxTest::TestSuite { boost::make_shared>( std::vector{0, 1, 2}); auto bankSortedComponentIndices = - boost::make_shared>(std::vector{}); + boost::make_shared>(std::vector(1)); auto parentIndices = boost::make_shared>( - std::vector{9, 9, 9}); // These indices are invalid, but that's + std::vector{9, 9, 9, 9}); // These indices are invalid, but that's // ok as not being tested here auto detectorRanges = - boost::make_shared>>(); + boost::make_shared>>( + 1, std::pair{0, 2}); auto componentRanges = boost::make_shared>>( std::vector>{}); @@ -287,10 +298,13 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto scaleFactors = boost::make_shared(3); auto names = boost::make_shared(3); auto isRectangularBank = boost::make_shared>(); - ComponentInfo componentInfo(bankSortedDetectorIndices, detectorRanges, - bankSortedComponentIndices, componentRanges, - parentIndices, positions, rotations, - scaleFactors, isRectangularBank, names, -1, -1); + auto instrumentTree = boost::make_shared>>( + 1, std::vector(3)); + + ComponentInfo componentInfo( + bankSortedDetectorIndices, detectorRanges, bankSortedComponentIndices, + componentRanges, parentIndices, instrumentTree, positions, rotations, + scaleFactors, isRectangularBank, names, -1, -1); DetectorInfo detectorInfo; // Detector info size 0 TS_ASSERT_THROWS(componentInfo.setDetectorInfo(&detectorInfo), @@ -325,11 +339,14 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto names = boost::make_shared(); auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); + auto instrumentTree = boost::make_shared< + std::vector>>(); // invalid but not being tested + TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, bankSortedComponentIndices, componentRanges, - parentIndices, positions, rotations, - scaleFactors, isRectangularBank, names, -1, - -1), + parentIndices, instrumentTree, positions, + rotations, scaleFactors, isRectangularBank, + names, -1, -1), std::invalid_argument &); } @@ -365,12 +382,58 @@ class ComponentInfoTest : public CxxTest::TestSuite { std::vector>{{0, 0}}); auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); + auto instrumentTree = boost::make_shared< + std::vector>>(); // invalid but not being tested - TS_ASSERT_THROWS( - ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, - componentRanges, parentIndices, positions, rotations, - scaleFactors, isRectangularBank, names, -1, -1), - std::invalid_argument &); + TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, + componentsInSubtree, componentRanges, + parentIndices, instrumentTree, positions, + rotations, scaleFactors, isRectangularBank, + names, -1, -1), + std::invalid_argument &); + } + + void test_throw_if_instrument_tree_not_same_size_as_number_of_components() { + /* + * Positions are rotations are only currently stored for non-detector + * components + * We should have as many detectorRanges as we have non-detector components + * too. + * All vectors should be the same size. + */ + auto detectorsInSubtree = + boost::make_shared>(); // No detector indices + // in this example! + + auto componentsInSubtree = + boost::make_shared>(std::vector{0}); + + auto detectorRanges = + boost::make_shared>>( + 1, std::pair(0, 0)); + + auto parentIndices = boost::make_shared>( + std::vector{9, 9, 9}); // These indices are invalid, but that's + // ok as not being tested here + auto positions = boost::make_shared(1); + auto rotations = boost::make_shared(1); + + auto scaleFactors = boost::make_shared(1); + auto names = boost::make_shared(1); + // Only one component. So single empty component range. + auto componentRanges = + boost::make_shared>>( + std::vector>{ {0, 0}}); + auto isRectangularBank = boost::make_shared>(1, false); + auto instrumentTree = boost::make_shared>>( + 1, std::vector{1, 2}); // invalid + + TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, + componentsInSubtree, componentRanges, + parentIndices, instrumentTree, positions, + rotations, scaleFactors, isRectangularBank, + names, -1, -1), + std::invalid_argument &); } void test_read_positions_rotations() { diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index 938900ca147d..a476623b1bc1 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -111,6 +111,7 @@ class MANTID_GEOMETRY_DLL ComponentInfo { std::unique_ptr cloneWithoutDetectorInfo() const; std::vector detectorsInSubtree(size_t componentIndex) const; std::vector componentsInSubtree(size_t componentIndex) const; + const std::vector &children(size_t componentIndex) const; size_t size() const; StructuredPanel structuredPanel(const size_t componentIndex) const; size_t indexOf(Geometry::IComponent *id) const; diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h index 18924dc6f9c4..f8cfc21eff72 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h @@ -90,6 +90,8 @@ class MANTID_GEOMETRY_DLL DetectorInfo { double twoTheta(const std::pair &index) const; double signedTwoTheta(const size_t index) const; double signedTwoTheta(const std::pair &index) const; + double getPhi(const size_t index) const; + double getPhiOffset(const size_t index, const double offset) const; Kernel::V3D position(const size_t index) const; Kernel::V3D position(const std::pair &index) const; Kernel::Quat rotation(const size_t index) const; diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h index ac77820aad5f..22d8ca0fbabf 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h @@ -78,6 +78,9 @@ class MANTID_GEOMETRY_DLL InstrumentVisitor /// Index of the parent component boost::shared_ptr> m_parentComponentIndices; + /// Stores instrument tree structure by storing children of all Components + boost::shared_ptr>> m_instrumentTree; + /// Only Assemblies and other NON-detectors yield detector ranges boost::shared_ptr>> m_detectorRanges; diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index cbbe2e3a5715..ed0177069633 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -107,6 +107,11 @@ ComponentInfo::componentsInSubtree(size_t componentIndex) const { return m_componentInfo->componentsInSubtree(componentIndex); } +const std::vector & +ComponentInfo::children(size_t componentIndex) const { + return m_componentInfo->children(componentIndex); +} + size_t ComponentInfo::size() const { return m_componentInfo->size(); } ComponentInfo::StructuredPanel diff --git a/Framework/Geometry/src/Instrument/DetectorInfo.cpp b/Framework/Geometry/src/Instrument/DetectorInfo.cpp index d2b98326e484..a31bf27e3a88 100644 --- a/Framework/Geometry/src/Instrument/DetectorInfo.cpp +++ b/Framework/Geometry/src/Instrument/DetectorInfo.cpp @@ -231,6 +231,18 @@ DetectorInfo::signedTwoTheta(const std::pair &index) const { return angle; } +double DetectorInfo::getPhi(const size_t index) const { + const Kernel::V3D pos = position(index); + return std::atan2(pos[1], pos[0]); +} + +/// Calculate the phi angle between detector and beam, and then offset. +double DetectorInfo::getPhiOffset(const size_t index, + const double offset) const { + double avgPos = getPhi(index); + return avgPos < 0 ? -(offset + avgPos) : offset - avgPos; +} + /// Returns the position of the detector with given index. Kernel::V3D DetectorInfo::position(const size_t index) const { return Kernel::toV3D(m_detectorInfo->position(index)); diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index daa04a826846..ae12b653c3d4 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -71,12 +71,14 @@ InstrumentVisitor::InstrumentVisitor( boost::make_shared>()), m_parentComponentIndices(boost::make_shared>( m_orderedDetectorIds->size(), 0)), + m_instrumentTree(boost::make_shared>>()), m_detectorRanges( boost::make_shared>>()), m_componentRanges( boost::make_shared>>()), - m_componentIdToIndexMap(boost::make_shared< - std::unordered_map>()), + m_componentIdToIndexMap( + boost::make_shared< + std::unordered_map>()), m_detectorIdToIndexMap(makeDetIdToIndexMap(*m_orderedDetectorIds)), m_positions(boost::make_shared>()), m_detectorPositions(boost::make_shared>( @@ -178,6 +180,7 @@ InstrumentVisitor::registerComponentAssembly(const ICompAssembly &assembly) { for (const auto &child : children) { (*m_parentComponentIndices)[child] = componentIndex; } + m_instrumentTree->emplace_back(std::move(children)); return componentIndex; } @@ -205,6 +208,7 @@ InstrumentVisitor::registerGenericComponent(const IComponent &component) { // Unless this is the root component this parent is not correct and will be // updated later in the register call of the parent. m_parentComponentIndices->push_back(componentIndex); + m_instrumentTree->emplace_back(std::vector()); return componentIndex; } @@ -335,7 +339,7 @@ InstrumentVisitor::componentInfo() const { return Kernel::make_unique( m_assemblySortedDetectorIndices, m_detectorRanges, m_assemblySortedComponentIndices, m_componentRanges, - m_parentComponentIndices, m_positions, m_rotations, m_scaleFactors, + m_parentComponentIndices, m_instrumentTree, m_positions, m_rotations, m_scaleFactors, m_componentType, m_names, m_sourceIndex, m_sampleIndex); } diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index f4282e4ef0fc..feb7873780a0 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -109,10 +109,11 @@ std::unique_ptr makeSingleBeamlineComponentInfo( using Mantid::Beamline::ComponentType; auto isStructuredBank = boost::make_shared>(1, ComponentType::Generic); + auto instrumentTree = boost::make_shared>>(1); return Kernel::make_unique( detectorIndices, detectorRanges, componentIndices, componentRanges, - parentIndices, positions, rotations, scaleFactors, isStructuredBank, - names, -1, -1); + parentIndices, instrumentTree, positions, rotations, scaleFactors, + isStructuredBank, names, -1, -1); } } // namespace @@ -156,10 +157,12 @@ class ComponentInfoTest : public CxxTest::TestSuite { using Mantid::Beamline::ComponentType; auto isRectBank = boost::make_shared>( 2, ComponentType::Generic); + auto instrumentTree = boost::make_shared>>( + 1, std::vector(1)); auto internalInfo = Kernel::make_unique( detectorIndices, detectorRanges, componentIndices, componentRanges, - parentIndices, positions, rotations, scaleFactors, isRectBank, names, - -1, -1); + parentIndices, instrumentTree, positions, rotations, scaleFactors, + isRectBank, names, -1, -1); Mantid::Geometry::ObjComponent comp1("component1"); Mantid::Geometry::ObjComponent comp2("component2"); @@ -199,7 +202,7 @@ class ComponentInfoTest : public CxxTest::TestSuite { // Compare sizes TS_ASSERT_EQUALS(b->size(), a.size()); // Shapes are the same - TS_ASSERT_EQUALS(&b->shape(0), &a.shape(0)); + TS_ASSERT_EQUALS(b->shape(0).get(), a.shape(0).get()); // IDs are the same TS_ASSERT_EQUALS(b->indexOf(&comp1), a.indexOf(&comp1)); TS_ASSERT(!b->hasDetectorInfo()); diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index 5d549a821dc8..bd087bba6b8e 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -244,8 +244,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { void test_visitor_component_ranges_check() { // Create a very basic instrument to visit auto visitee = createMinimalInstrument(V3D(0, 0, 0) /*source pos*/, - V3D(10, 0, 0) /*sample pos*/ - , + V3D(10, 0, 0) /*sample pos*/, V3D(11, 0, 0) /*detector position*/); InstrumentVisitor visitor(makeParameterized(visitee)); @@ -383,10 +382,10 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { TSM_ASSERT("Detectors should have a shape", detectorShape->hasValidShape()); // Check shapes are re-used as expected - TSM_ASSERT_EQUALS("Shape object should be reused", &instrumentShape, - &subAssemblyShape); - TSM_ASSERT_EQUALS("Shape object should be reused", &detectorShape, - &componentInfo->shape(1 /*another detector*/)); + TSM_ASSERT_EQUALS("Shape object should be reused", instrumentShape.get(), + subAssemblyShape.get()); + TSM_ASSERT_EQUALS("Shape object should be reused", detectorShape.get(), + componentInfo->shape(1 /*another detector*/).get()); } void test_names() { @@ -441,6 +440,59 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(detScaling, compInfo->scaleFactor(0)); TS_ASSERT_EQUALS(instrScaling, compInfo->scaleFactor(compInfo->root())); } + + void test_instrumentTreeWithMinimalInstrument() + { + /** This should produce the following instrument tree + * 3 + * / | \ + *0 1 2 + */ + auto instrument = + createMinimalInstrument(V3D(0, 0, 0), V3D(0, 0, 1), V3D(0, 0, 10)); + auto visitor = InstrumentVisitor(instrument); + + visitor.walkInstrument(); + + auto componentInfo = visitor.componentInfo(); + auto root = componentInfo->root(); + TS_ASSERT_EQUALS(componentInfo->children(0).size(), 0); + TS_ASSERT_EQUALS(componentInfo->children(1).size(), 0); + TS_ASSERT_EQUALS(componentInfo->children(2).size(), 0); + TS_ASSERT_EQUALS(componentInfo->children(root).size(), 3); + } + + void test_instrumentTreeWithComplexInstrument() + { + /** This should produce the following instrument tree + * 16 + * / / \ \ + * 14 15 10 13 + * / \ / \ + * 8 9 11 12 + * / \ / \ / \ / \ + * 0 1 2 3 4 5 6 7 + */ + auto instrument = createTestInstrumentRectangular2(2, 2); + auto visitor = InstrumentVisitor(instrument); + + visitor.walkInstrument(); + + auto componentInfo = visitor.componentInfo(); + auto root = componentInfo->root(); + for (int i = 0; i < 8; i++) + TS_ASSERT_EQUALS(componentInfo->children(i).size(), 0); + + TS_ASSERT_EQUALS(componentInfo->children(root).size(), 4); + TS_ASSERT_EQUALS(componentInfo->children(8).size(), 2); + TS_ASSERT_EQUALS(componentInfo->children(9).size(), 2); + TS_ASSERT_EQUALS(componentInfo->children(11).size(), 2); + TS_ASSERT_EQUALS(componentInfo->children(12).size(), 2); + TS_ASSERT_EQUALS(componentInfo->children(10).size(), 2); + TS_ASSERT_EQUALS(componentInfo->children(13).size(), 2); + TS_ASSERT_EQUALS(componentInfo->children(14).size(), 0); + TS_ASSERT_EQUALS(componentInfo->children(15).size(), 0); + } }; class InstrumentVisitorTestPerformance : public CxxTest::TestSuite { diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index f0fb73e30e30..b87dd4283526 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -52,20 +52,19 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor: public QObject { double scaleMin = 0.0, double scaleMax = 0.0); ///< Destructor ~InstrumentActor(); - ///< Type of the GL object - virtual std::string type() const { return "InstrumentActor"; } /// Draw the instrument in 3D void draw(bool picking = false) const; /// Return the bounding box in 3D void getBoundingBox(Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound) const; /// Set a component (and all its children) visible. - void setComponentVisible(Mantid::Geometry::ComponentID component); + void setComponentVisible(size_t componentIndex); /// Toggle the visibility of the child actors (if exist). void setChildVisibility(bool); /// Check if any child is visible bool hasChildVisible() const; /// Get the underlying instrument + std::vector getMonitors() const; boost::shared_ptr getInstrument() const; /// Get the associated data workspace boost::shared_ptr getWorkspace() const; @@ -132,18 +131,12 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor: public QObject { /// Get the number of detectors in the instrument. size_t ndetectors() const;// { return m_detIDs.size(); } - /// Get a reference to a detector by a pick ID converted form a color in - /// the pick image. - const Mantid::Geometry::IDetector &getDetectorByPickID(size_t pickID) const; - /// Get a reference to a detector by a detector ID. - const Mantid::Geometry::IDetector & - getDetectorByDetID(Mantid::detid_t detID) const; + /// Get a detector index by a detector ID. + size_t getDetectorByDetID(Mantid::detid_t detID) const; /// Get a detector ID by a pick ID converted form a color in the pick image. Mantid::detid_t getDetID(size_t pickID) const; /// Get a component ID for a non-detector. Mantid::Geometry::ComponentID getComponentID(size_t pickID) const; - /// Cache detector positions. - void cacheDetPos() const; /// Get position of a detector by a pick ID converted form a color in the pick /// image. const Mantid::Kernel::V3D getDetPos(size_t pickID) const; @@ -193,6 +186,12 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor: public QObject { void initMaskHelper() const; bool hasMaskWorkspace() const; bool hasBinMask() const; + QString getParameterInfo(size_t index) const; + std::string getDefaultAxis() const; + std::string getDefaultView() const; + std::string getInstrumentName() const; + std::vector getStringParameter(const std::string &name, + bool recursive = true) const; /// Load the state of the actor from a Mantid project file. void loadFromProject(const std::string &lines); /// Save the state of the actor to a Mantid project file. diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h index a53cd4cac13f..d714c99efd73 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h @@ -33,10 +33,11 @@ class InstrumentTreeModel : public QAbstractItemModel { QModelIndex parent(const QModelIndex &index) const override; int rowCount(const QModelIndex &paren = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; - + static size_t extractIndex(const QModelIndex &index); private: /// instrument widget to which the model corresponds const InstrumentWidget *m_instrWidget; + mutable std::vector m_componentIndices; }; } // MantidWidgets } // MantidQt diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h index 7cd33fc0129c..1e22e4bbd533 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h @@ -36,7 +36,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentTreeWidget public slots: void sendComponentSelectedSignal(const QModelIndex); signals: - void componentSelected(const Mantid::Geometry::ComponentID); + void componentSelected(size_t); private: InstrumentWidget *m_instrWidget; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h index eefd8644c4bf..2260a08c1e45 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h @@ -172,7 +172,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentWidget public slots: void tabChanged(int); - void componentSelected(Mantid::Geometry::ComponentID id); + void componentSelected(size_t componentIndex); void executeAlgorithm(const QString &, const QString &); void executeAlgorithm(Mantid::API::IAlgorithm_sptr); diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h index ff9ac33ad397..371b4a9f9566 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h @@ -205,7 +205,6 @@ public slots: QString displayPeakInfo(Mantid::Geometry::IPeak *peak); QString displayPeakAngles(const std::pair &peaks); - QString getParameterInfo(const Mantid::Geometry::IComponent &comp); QString getPeakOverlayInfo(); InstrumentWidgetPickTab *m_tab; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h index 6407cc16b80d..0a06893e4a2d 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MantidGLWidget.h @@ -34,7 +34,7 @@ public slots: void enableLighting(bool); void updateView(bool picking = true); void updateDetectors(); - void componentSelected(Mantid::Geometry::ComponentID id); + void componentSelected(size_t componentIndex); protected: void initializeGL() override; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h index 5d9f901a5d58..9e44430cef90 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h @@ -39,7 +39,7 @@ class Projection3D : public ProjectionSurface { void set3DAxesState(bool on); void setWireframe(bool on); - void componentSelected(Mantid::Geometry::ComponentID = nullptr) override; + void componentSelected(size_t componentIndex) override; void getSelectedDetectors(QList &dets) override; void getMaskedDetectors(QList &dets) const override; void resize(int, int) override; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h index 2d38ea074650..b3562edd963b 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h @@ -109,9 +109,9 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW ProjectionSurface : public QObject { virtual bool hasSelection() const; virtual int getDetectorID(int x, int y) const; - virtual const Mantid::Geometry::IDetector &getDetector(int x, int y) const; + virtual size_t getDetector(int x, int y) const; /// NULL deselects components and selects the whole instrument - virtual void componentSelected(Mantid::Geometry::ComponentID = nullptr) = 0; + virtual void componentSelected(size_t componentIndex) = 0; /// fill in a list of detector ids which were selected by the selction tool virtual void getSelectedDetectors(QList &dets) = 0; /// fill in a list of detector ids which were masked by the mask shapes diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h index b384470f19ba..b0b1f1c423e9 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h @@ -3,7 +3,6 @@ #include "MantidKernel/V3D.h" #include "MantidKernel/Quat.h" -#include "MantidGeometry/IComponent.h" #include "MantidGeometry/Objects/IObject.h" #include "InstrumentActor.h" #include "ProjectionSurface.h" @@ -61,7 +60,7 @@ class UnwrappedSurface : public ProjectionSurface { /** @name Implemented public virtual methods */ //@{ - void componentSelected(Mantid::Geometry::ComponentID = nullptr) override; + void componentSelected(size_t componentIndex) override; void getSelectedDetectors(QList &dets) override; void getMaskedDetectors(QList &dets) const override; void setPeaksWorkspace(boost::shared_ptr pws); @@ -98,6 +97,7 @@ class UnwrappedSurface : public ProjectionSurface { bool isFlippedView() const { return m_flippedView; } /// Zoom into an area of the screen void zoom(const QRectF &area); + void zoom(const Mantid::Geometry::BoundingBox &area); //@} /// Load settings for the unwrapped surface from a project file virtual void loadFromProject(const std::string &lines) override; @@ -122,6 +122,7 @@ protected slots: void drawSurface(MantidGLWidget *widget, bool picking = false) const override; void drawSimpleToImage(QImage *image, bool picking = false) const override; void changeColorMap() override; + void doZoom(const QRectF &area); //@} /** @name New protected virtual methods */ @@ -149,9 +150,6 @@ protected slots: /** @name Protected methods */ //@{ void setColor(int index, bool picking) const; - void calcAssemblies(const Mantid::Geometry::IComponent *comp, - const QRectF &compRect); - void cacheAllAssemblies(); void createPeakShapes(const QRect &viewport) const; //@} @@ -165,9 +163,6 @@ protected slots: /// Info needed to draw detectors onto unwrapped image std::vector m_unwrappedDetectors; - /// Bounding rectangles of detector assemblies - QMap m_assemblies; - bool m_flippedView; ///< if false the image is seen from the sample. if true /// the view is looking towards the sample. mutable bool m_startPeakShapes; ///< set to true to start creating diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 8163419d3e31..9f937020d7ff 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -49,11 +49,6 @@ size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) { GLColor defaultDetectorColor() { return GLColor(200, 200, 200); } } // namespace -/// to be used in std::transform -struct Sqrt { - double operator()(double x) { return sqrt(x); } -}; - double InstrumentActor::m_tolerance = 0.00001; /** @@ -88,13 +83,9 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, "InstrumentActor passed a workspace that isn't a MatrixWorkspace"); const auto &componentInfo = sharedWorkspace->componentInfo(); - const auto &detectorInfo = sharedWorkspace->detectorInfo(); m_isCompVisible.assign(componentInfo.size(), true); - m_pickColors.resize(componentInfo.size()); - - for (size_t i = 0; i < componentInfo.size(); ++i) - m_pickColors[i] = makePickColor(i); + setupPickColors(); // set up the color map if (!m_currentColorMapFilename.isEmpty()) { @@ -105,24 +96,18 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, // set up data ranges and colours setUpWorkspace(sharedWorkspace, scaleMin, scaleMax); - Instrument_const_sptr instrument = getInstrument(); - // If the instrument is empty, maybe only having the sample and source - const int nelements = instrument->nelements(); + auto nelements = componentInfo.size(); if ((nelements == 0) || (nelements == 1 && - (instrument->getSource() || instrument->getSample())) || - (nelements == 2 && instrument->getSource() && instrument->getSample())) { + (componentInfo.hasSource() || componentInfo.hasSample())) || + (nelements == 2 && componentInfo.hasSource() && + componentInfo.hasSample())) { QMessageBox::warning(nullptr, "MantidPlot - Warning", "This instrument appears to contain no detectors", "OK"); } - // this adds actors for all instrument components to the scene and fills in - // m_detIDs - // m_scene.addActor(new CompAssemblyActor(*this, - // instrument->getComponentID())); setupPickColors(); - if (!m_showGuides) { // hide guide and other components showGuides(m_showGuides); @@ -204,14 +189,11 @@ void InstrumentActor::setUpWorkspace( m_detid2index_map = sharedWorkspace->getDetectorIDToWorkspaceIndexMap(); } -void InstrumentActor::setComponentVisible( - Mantid::Geometry::ComponentID component) { +void InstrumentActor::setComponentVisible(size_t componentIndex) { setChildVisibility(false); const auto &componentInfo = getComponentInfo(); - auto index = componentInfo.indexOf(component); - - auto children = componentInfo.componentsInSubtree(index); - m_isCompVisible[index] = true; + auto children = componentInfo.componentsInSubtree(componentIndex); + m_isCompVisible[componentIndex] = true; for (auto child : children) m_isCompVisible[child] = true; @@ -358,6 +340,18 @@ void InstrumentActor::clearMasks() { } } +std::vector InstrumentActor::getMonitors() const { + const auto &detectorInfo = getDetectorInfo(); + std::vector monitors; + + for (size_t i = 0; i < detectorInfo.size(); i++) { + if (detectorInfo.isMonitor(i)) + monitors.push_back(i); + } + + return monitors; +} + Instrument_const_sptr InstrumentActor::getInstrument() const { Instrument_const_sptr retval; @@ -389,19 +383,9 @@ const MantidColorMap &InstrumentActor::getColorMap() const { return m_colorMap; } -/// Get a detector reference given a pick ID. -const Mantid::Geometry::IDetector & -InstrumentActor::getDetectorByPickID(size_t pickID) const { - const auto &detectorInfo = getDetectorInfo(); - return detectorInfo.detector(pickID); -} - -/// Get a reference to a detector by a detector ID. -const Mantid::Geometry::IDetector & -InstrumentActor::getDetectorByDetID(Mantid::detid_t detID) const { +size_t InstrumentActor::getDetectorByDetID(Mantid::detid_t detID) const { const auto &detectorInfo = getDetectorInfo(); - auto detectorIndex = detectorInfo.indexOf(detID); - return detectorInfo.detector(detectorIndex); + return detectorInfo.indexOf(detID); } Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const { @@ -688,40 +672,6 @@ void InstrumentActor::resetColors() { } } } - // QwtDoubleInterval qwtInterval(m_DataMinScaleValue, m_DataMaxScaleValue); - // m_colors.resize(m_specIntegrs.size()); - - // auto sharedWorkspace = getWorkspace(); - // const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); - - // IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists(); - - // for (int iwi = 0; iwi < int(m_specIntegrs.size()); iwi++) { - // size_t wi = size_t(iwi); - // double integratedValue = m_specIntegrs[wi]; - // try { - // // Find if the detector is masked - // const auto &dets = sharedWorkspace->getSpectrum(wi).getDetectorIDs(); - // bool masked = false; - - // if (mask) { - // masked = mask->isMasked(dets); - // } else { - // masked = spectrumInfo.hasDetectors(wi) && spectrumInfo.isMasked(wi); - // } - - // if (masked) { - // m_colors[wi] = m_maskedColor; - // } else { - // QRgb color = m_colorMap.rgb(qwtInterval, integratedValue); - // m_colors[wi] = GLColor(qRed(color), qGreen(color), qBlue(color)); - // } - // } catch (NotFoundError &) { - // m_colors[wi] = m_failedColor; - // continue; - // } - //} - setupPickColors(); invalidateDisplayLists(); emit colorMapChanged(); @@ -838,22 +788,7 @@ void InstrumentActor::setupPickColors() { } //------------------------------------------------------------------------------ -/** If needed, cache the detector positions for all detectors. - * Call this BEFORE getDetPos(). - * Does nothing if the positions have already been cached. - */ -void InstrumentActor::cacheDetPos() const { - /*if (m_detPos.size() != m_detIDs.size()) { - m_detPos.clear(); - for (size_t pickID = 0; pickID < m_detIDs.size(); pickID++) { - auto &det = this->getDetectorByPickID(pickID); - m_detPos.push_back(det.getPos()); - } - }*/ -} - -//------------------------------------------------------------------------------ -/** Get the cached detector position +/** Get the detector position * * @param pickID :: pick Index maching the getDetector() calls; * @return the real-space position of the detector @@ -1218,14 +1153,7 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, auto workspace = getWorkspace(); calculateIntegratedSpectra(*workspace); - - // get the workspace indices of monitors in order to exclude them from finding - // of the max value - auto monitorIDs = getInstrument()->getMonitors(); - // clang-format off - // because it indents this line half way across the page (?) - auto monitorIndices = workspace->getIndicesFromDetectorIDs(monitorIDs); - // clang-format on + auto monitorIndices = getMonitors(); // check that there is at least 1 non-monitor spectrum if (monitorIndices.size() == m_specIntegrs.size()) { @@ -1294,6 +1222,79 @@ void InstrumentActor::addMaskBinsData(const QList &detIDs) { /// Show if bin masks have been defined. bool InstrumentActor::hasBinMask() const { return !m_maskBinsData.isEmpty(); } +QString InstrumentActor::getParameterInfo(size_t index) const { + auto instr = getInstrument(); + const auto &componentInfo = getComponentInfo(); + + auto compID = componentInfo.componentID(index); + auto comp = instr->getComponentByID(compID); + + QString text = ""; + std::map> + mapCmptToNameVector; + + auto paramNames = comp->getParameterNamesByComponent(); + for (auto itParamName = paramNames.begin(); itParamName != paramNames.end(); + ++itParamName) { + // build the data structure I need Map comp id -> vector of names + std::string paramName = itParamName->first; + Mantid::Geometry::ComponentID paramCompId = itParamName->second; + // attempt to insert this will fail silently if the key already exists + if (mapCmptToNameVector.find(paramCompId) == mapCmptToNameVector.end()) { + mapCmptToNameVector.emplace(paramCompId, std::vector()); + } + // get the vector out and add the name + mapCmptToNameVector[paramCompId].push_back(paramName); + } + + // walk out from the selected component + const Mantid::Geometry::IComponent *paramComp = comp.get(); + boost::shared_ptr parentComp; + while (paramComp) { + auto id = paramComp->getComponentID(); + auto &compParamNames = mapCmptToNameVector[id]; + if (compParamNames.size() > 0) { + text += QString::fromStdString( + "\nParameters from: " + paramComp->getName() + "\n"); + std::sort(compParamNames.begin(), compParamNames.end(), + Mantid::Kernel::CaseInsensitiveStringComparator()); + for (auto itParamName = compParamNames.begin(); + itParamName != compParamNames.end(); ++itParamName) { + std::string paramName = *itParamName; + // no need to search recursively as we are asking from the matching + // component + std::string paramValue = + paramComp->getParameterAsString(paramName, false); + if (paramValue != "") { + text += QString::fromStdString(paramName + ": " + paramValue + "\n"); + } + } + } + parentComp = paramComp->getParent(); + paramComp = parentComp.get(); + } + + return text; +} + +std::string InstrumentActor::getDefaultAxis() const { + return getInstrument()->getDefaultAxis(); +} + +std::string InstrumentActor::getDefaultView() const { + return getInstrument()->getDefaultView(); +} + +std::string InstrumentActor::getInstrumentName() const { + const auto &componentInfo = getComponentInfo(); + return componentInfo.name(componentInfo.root()); +} + +std::vector +InstrumentActor::getStringParameter(const std::string &name, + bool recursive) const { + return getInstrument()->getStringParameter(name, recursive); +} /** * Save the state of the instrument actor to a project file. * @return string representing the current state of the instrumet actor. diff --git a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp index 73c8037b4b1e..c21af36e8bab 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp @@ -5,6 +5,7 @@ #endif #include "MantidKernel/Exception.h" #include "MantidGeometry/ICompAssembly.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidGeometry/Instrument.h" #include "MantidAPI/MatrixWorkspace.h" @@ -14,13 +15,17 @@ using Mantid::Geometry::IObjComponent; namespace MantidQt { namespace MantidWidgets { - /** -* Constructor for tree model to display instrument tree -*/ + * Constructor for tree model to display instrument tree + */ InstrumentTreeModel::InstrumentTreeModel(const InstrumentWidget *instrWidget, QObject *parent) - : QAbstractItemModel(parent), m_instrWidget(instrWidget) {} + : QAbstractItemModel(parent), m_instrWidget(instrWidget) { + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + m_componentIndices.resize(componentInfo.size()); + std::iota(m_componentIndices.begin(), m_componentIndices.end(), 0); +} /** * Destructor for instrument display tree @@ -36,20 +41,17 @@ InstrumentTreeModel::~InstrumentTreeModel() {} int InstrumentTreeModel::columnCount(const QModelIndex &parent) const { try { if (parent.isValid()) { - auto instr = m_instrWidget->getInstrumentActor().getInstrument(); - boost::shared_ptr comp = instr->getComponentByID( - static_cast(parent.internalPointer())); - boost::shared_ptr objcomp = - boost::dynamic_pointer_cast(comp); - if (objcomp) + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + auto index = extractIndex(parent); + if (componentInfo.children(index).size() > 0) return 1; - return 0; } else return 1; } catch (...) { - // std::cout<<"Exception :: columnCount"<<'\n'; - return 0; + // do nothing } + return 0; } /** @@ -61,21 +63,19 @@ QVariant InstrumentTreeModel::data(const QModelIndex &index, int role) const { if (role != Qt::DisplayRole) return QVariant(); - auto instr = m_instrWidget->getInstrumentActor().getInstrument(); + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); if (!index.isValid()) // not valid has to return the root node - return QString(instr->getName().c_str()); + return QString::fromStdString(componentInfo.name(componentInfo.root())); - boost::shared_ptr ins = instr->getComponentByID( - static_cast(index.internalPointer())); - if (ins) { - return QString(ins->getName().c_str()); - } - return QString("Error"); + auto compIndex = extractIndex(index); + return QString::fromStdString(componentInfo.name(compIndex)); } catch (...) { - // std::cout<<" Exception: in data"<<'\n'; - return 0; + // Ignore Exceptions } + + return 0; } /** @@ -104,34 +104,27 @@ QVariant InstrumentTreeModel::headerData(int section, */ QModelIndex InstrumentTreeModel::index(int row, int column, const QModelIndex &parent) const { - // std::cout<<"Index +++++++++ row"< parentItem; - auto instr = m_instrWidget->getInstrumentActor().getInstrument(); - if (!parent.isValid()) // invalid parent, has to be the root node i.e - // instrument - return createIndex(row, column, instr->getComponentID()); - - boost::shared_ptr comp = instr->getComponentByID( - static_cast(parent.internalPointer())); - parentItem = boost::dynamic_pointer_cast(comp); - if (!parentItem) { - boost::shared_ptr objcomp = - boost::dynamic_pointer_cast(comp); - if (objcomp) - return QModelIndex(); - // Not an instrument so check for Component Assembly - parentItem = boost::dynamic_pointer_cast(instr); + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + if (!parent.isValid()) { // invalid parent, has to be the root node i.e + // instrument + return createIndex(row, column, + &m_componentIndices[componentInfo.root()]); + } + auto index = extractIndex(parent); + const auto &children = componentInfo.children(index); + + if (index == componentInfo.source() || index == componentInfo.sample()) { + return QModelIndex(); } // If component assembly pick the Component at the row index. if row index // is higher than number // of components in assembly return empty model index - if (parentItem->nelements() < row) { + if (children.size() <= row) { return QModelIndex(); } else { - return createIndex(row, column, - (void *)((*parentItem)[row]->getComponentID())); + return createIndex(row, column, &m_componentIndices[children[row]]); } } catch (...) { std::cout << "InstrumentTreeModel::index(" << row << "," << column @@ -144,37 +137,35 @@ QModelIndex InstrumentTreeModel::index(int row, int column, * Returns the parent model index. */ QModelIndex InstrumentTreeModel::parent(const QModelIndex &index) const { - // std::cout<<"parent +++++++++ row"<getInstrumentActor().getInstrument(); + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + auto compIndex = extractIndex(index); - if (instr->getComponentID() == - static_cast(index.internalPointer())) + if (compIndex == componentInfo.root()) return QModelIndex(); - boost::shared_ptr child = instr->getComponentByID( - static_cast(index.internalPointer())); - if (child->getParent()->getComponentID() == instr->getComponentID()) - return createIndex(0, 0, instr->getComponentID()); - boost::shared_ptr parent = - instr->getComponentByID(child->getParent()->getComponentID()); - boost::shared_ptr greatParent = - instr->getComponentByID(parent->getParent()->getComponentID()); - boost::shared_ptr greatParentAssembly = - boost::dynamic_pointer_cast(greatParent); - int iindex = 0; - for (int i = 0; i < greatParentAssembly->nelements(); i++) - if ((*greatParentAssembly)[i]->getComponentID() == - parent->getComponentID()) - iindex = i; - return createIndex(iindex, 0, (void *)parent->getComponentID()); + auto parent = componentInfo.parent(compIndex); + if (parent == componentInfo.root()) + return createIndex(0, 0, &m_componentIndices[componentInfo.root()]); + + auto grandParent = componentInfo.parent(parent); + const auto &grandParentElems = componentInfo.children(grandParent); + + int row = 0; + for (auto child : grandParentElems) { + if (child == parent) + break; + row++; + } + + return createIndex(row, 0, &m_componentIndices[parent]); } catch (...) { - // std::cout<<"Exception: in parent"<<'\n'; + // do nothing } return QModelIndex(); } @@ -184,37 +175,27 @@ QModelIndex InstrumentTreeModel::parent(const QModelIndex &index) const { * ObjComponent row count will be 0. */ int InstrumentTreeModel::rowCount(const QModelIndex &parent) const { - // std::cout<<"rowCount +++++++++ row"<(m_instrument)->nelements(); + return 1; } else { - auto instr = m_instrWidget->getInstrumentActor().getInstrument(); - if (instr->getComponentID() == static_cast( - parent.internalPointer())) { - return instr->nelements(); - } - boost::shared_ptr comp = - instr->getComponentByID(static_cast( - parent - .internalPointer())); // static_cast(parent.internalPointer()); - boost::shared_ptr assembly = - boost::dynamic_pointer_cast(comp); - if (assembly) { - return assembly->nelements(); - } - boost::shared_ptr objcomp = - boost::dynamic_pointer_cast(comp); - if (objcomp) - return 0; + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + auto index = extractIndex(parent); + const auto &children = componentInfo.children(index); + if (children.size() > 1) + return static_cast(children.size()); } } catch (...) { - // std::cout<<"Exception: in rowCount"<<'\n'; + // do nothing } return 0; } + +size_t InstrumentTreeModel::extractIndex(const QModelIndex &index) { + auto indexPtr = static_cast(index.internalPointer()); + return *indexPtr; +} } // MantidWidgets } // MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp index 1a88d77b3cec..60250559ade7 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp @@ -6,9 +6,9 @@ #include "MantidKernel/Exception.h" #include "MantidGeometry/ICompAssembly.h" #include "MantidGeometry/Instrument.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/Sample.h" -#include "MantidQtWidgets/InstrumentView/GLActor.h" #include #include #include @@ -35,73 +35,17 @@ void InstrumentTreeWidget::getSelectedBoundingBox(const QModelIndex &index, double &xmax, double &ymax, double &zmax, double &xmin, double &ymin, double &zmin) { - Mantid::Geometry::Instrument_const_sptr instrument = - m_instrWidget->getInstrumentActor().getInstrument(); - // Check whether its instrument - boost::shared_ptr selectedComponent; - if (instrument->getComponentID() == - static_cast(index.internalPointer())) - selectedComponent = - boost::dynamic_pointer_cast( - instrument); - else - selectedComponent = instrument->getComponentByID( - static_cast(index.internalPointer())); + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + auto compIndex = InstrumentTreeModel::extractIndex(index); + auto bb = componentInfo.boundingBox(compIndex); - // get the bounding box for the component - xmax = ymax = zmax = -DBL_MAX; - xmin = ymin = zmin = DBL_MAX; - Mantid::Geometry::BoundingBox boundBox; - std::queue> CompList; - CompList.push(selectedComponent); - while (!CompList.empty()) { - boost::shared_ptr tmp = - CompList.front(); - CompList.pop(); - boost::shared_ptr tmpObj = - boost::dynamic_pointer_cast(tmp); - if (tmpObj) { - try { - // std::cerr << int(tmpObj->getComponentID()) << ' ' << - // int(instrument->getSample()->getComponentID()) << '\n'; - if (tmpObj->getComponentID() == - instrument->getSample()->getComponentID()) { - boundBox = m_instrWidget->getInstrumentActor() - .getWorkspace() - ->sample() - .getShape() - .getBoundingBox(); - boundBox.moveBy(tmpObj->getPos()); - } else { - tmpObj->getBoundingBox(boundBox); - } - double txmax(boundBox.xMax()), tymax(boundBox.yMax()), - tzmax(boundBox.zMax()), txmin(boundBox.xMin()), - tymin(boundBox.yMin()), tzmin(boundBox.zMin()); - if (txmax > xmax) - xmax = txmax; - if (tymax > ymax) - ymax = tymax; - if (tzmax > zmax) - zmax = tzmax; - if (txmin < xmin) - xmin = txmin; - if (tymin < ymin) - ymin = tymin; - if (tzmin < zmin) - zmin = tzmin; - } catch (Mantid::Kernel::Exception::NullPointerException &) { - } - } else if (boost::dynamic_pointer_cast< - const Mantid::Geometry::ICompAssembly>(tmp)) { - boost::shared_ptr tmpAssem = - boost::dynamic_pointer_cast( - tmp); - for (int idx = 0; idx < tmpAssem->nelements(); idx++) { - CompList.push((*tmpAssem)[idx]); - } - } - } + xmax = bb.xMax(); + ymax = bb.yMax(); + zmax = bb.zMax(); + xmin = bb.xMin(); + ymin = bb.yMin(); + zmin = bb.zMin(); } QModelIndex @@ -121,10 +65,9 @@ InstrumentTreeWidget::findComponentByName(const QString &name) const { void InstrumentTreeWidget::sendComponentSelectedSignal( const QModelIndex index) { - Mantid::Geometry::ComponentID id = - static_cast(index.internalPointer()); - m_instrWidget->getInstrumentActor().setComponentVisible(id); - emit componentSelected(id); + auto selectedIndex = InstrumentTreeModel::extractIndex(index); + m_instrWidget->getInstrumentActor().setComponentVisible(selectedIndex); + emit componentSelected(selectedIndex); } /** Get a list of components that have been expanded diff --git a/qt/widgets/instrumentview/src/InstrumentWidget.cpp b/qt/widgets/instrumentview/src/InstrumentWidget.cpp index a7f95ce00e73..e7afb960028e 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidget.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidget.cpp @@ -7,6 +7,7 @@ #include "MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h" #include "MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h" #include "MantidQtWidgets/InstrumentView/InstrumentWidgetTreeTab.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidAPI/Axis.h" #include "MantidAPI/IMaskWorkspace.h" @@ -259,8 +260,8 @@ void InstrumentWidget::init(bool resetGeometry, bool autoscaling, if (resetGeometry || !surface) { if (setDefaultView) { // set the view type to the instrument's default view - QString defaultView = QString::fromStdString( - m_instrumentActor->getInstrument()->getDefaultView()); + QString defaultView = + QString::fromStdString(m_instrumentActor->getDefaultView()); if (defaultView == "3D" && Mantid::Kernel::ConfigService::Instance().getString( "MantidOptions.InstrumentView.UseOpenGL") != "On") { @@ -400,13 +401,11 @@ void InstrumentWidget::setSurfaceType(int type) { // If anything throws during surface creation, store error message here QString errorMessage; try { - Mantid::Geometry::Instrument_const_sptr instr = - m_instrumentActor->getInstrument(); - Mantid::Geometry::IComponent_const_sptr sample = instr->getSample(); - if (!sample) { + const auto &componentInfo = m_instrumentActor->getComponentInfo(); + if (!componentInfo.hasSample()) { throw InstrumentHasNoSampleError(); } - Mantid::Kernel::V3D sample_pos = sample->getPos(); + auto sample_pos = componentInfo.samplePosition(); auto axis = getSurfaceAxis(surfaceType); // create the surface @@ -824,11 +823,10 @@ void InstrumentWidget::setBinRange(double xmin, double xmax) { * is visible the rest of the instrument is hidden. * @param id :: The component id. */ -void InstrumentWidget::componentSelected(ComponentID id) { +void InstrumentWidget::componentSelected(size_t componentIndex) { auto surface = getSurface(); if (surface) { - surface->componentSelected(id); - // surface->updateView(); + surface->componentSelected(componentIndex); updateInstrumentView(); } } @@ -1215,8 +1213,7 @@ QString InstrumentWidget::getSettingsGroupName() const { */ QString InstrumentWidget::getInstrumentSettingsGroupName() const { return QString::fromAscii(InstrumentWidgetSettingsGroup) + "/" + - QString::fromStdString( - getInstrumentActor().getInstrument()->getName()); + QString::fromStdString(getInstrumentActor().getInstrumentName()); } bool InstrumentWidget::hasWorkspace(const std::string &wsName) const { diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 496923915c00..0715c45392c0 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -18,6 +18,8 @@ #include "MantidAPI/Sample.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidGeometry/Crystal/OrientedLattice.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" +#include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidKernel/V3D.h" #include "qwt_scale_widget.h" @@ -850,9 +852,11 @@ QString ComponentInfoController::displayDetectorInfo(Mantid::detid_t detid) { if (detid >= 0) { // collect info about selected detector and add it to text const auto &actor = m_instrWidget->getInstrumentActor(); - auto &det = actor.getDetectorByDetID(detid); + const auto &componentInfo = actor.getComponentInfo(); + auto det = actor.getDetectorByDetID(detid); - text = "Selected detector: " + QString::fromStdString(det.getName()) + "\n"; + text = "Selected detector: " + + QString::fromStdString(componentInfo.name(det)) + "\n"; text += "Detector ID: " + QString::number(detid) + '\n'; QString wsIndex; try { @@ -862,33 +866,30 @@ QString ComponentInfoController::displayDetectorInfo(Mantid::detid_t detid) { wsIndex = "None"; } text += "Workspace index: " + wsIndex + '\n'; - Mantid::Kernel::V3D pos = det.getPos(); + Mantid::Kernel::V3D pos = componentInfo.position(det); text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) + "," + QString::number(pos.Z()) + '\n'; double r, t, p; pos.getSpherical(r, t, p); text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," + QString::number(p) + '\n'; - Mantid::Geometry::ICompAssembly_const_sptr parent = - boost::dynamic_pointer_cast( - det.getParent()); - if (parent) { + if (componentInfo.hasParent(det)) { QString textpath; - while (parent) { - textpath = "/" + QString::fromStdString(parent->getName()) + textpath; - parent = - boost::dynamic_pointer_cast( - parent->getParent()); + auto parent = det; + while (componentInfo.hasParent(parent)) { + parent = componentInfo.parent(parent); + textpath = + "/" + QString::fromStdString(componentInfo.name(parent)) + textpath; } text += "Component path:" + textpath + "/" + - QString::fromStdString(det.getName()) + '\n'; + QString::fromStdString(componentInfo.name(det)) + '\n'; } const double integrated = actor.getIntegratedCounts(detid); const QString counts = integrated == -1.0 ? "N/A" : QString::number(integrated); text += "Counts: " + counts + '\n'; // display info about peak overlays - text += getParameterInfo(det); + text += actor.getParameterInfo(det); } return text; } @@ -900,19 +901,19 @@ QString ComponentInfoController::displayDetectorInfo(Mantid::detid_t detid) { */ QString ComponentInfoController::displayNonDetectorInfo( Mantid::Geometry::ComponentID compID) { - auto component = - m_instrWidget->getInstrumentActor().getInstrument()->getComponentByID( - compID); + const auto &actor = m_instrWidget->getInstrumentActor(); + const auto &componentInfo = actor.getComponentInfo(); + auto component = componentInfo.indexOf(compID); QString text = "Selected component: "; - text += QString::fromStdString(component->getName()) + '\n'; - Mantid::Kernel::V3D pos = component->getPos(); + text += QString::fromStdString(componentInfo.name(component)) + '\n'; + Mantid::Kernel::V3D pos = componentInfo.position(component); text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) + "," + QString::number(pos.Z()) + '\n'; double r, t, p; pos.getSpherical(r, t, p); text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," + QString::number(p) + '\n'; - text += getParameterInfo(*component); + text += actor.getParameterInfo(component); return text; } @@ -1040,59 +1041,6 @@ void ComponentInfoController::displayAlignPeaksInfo( m_selectionInfoDisplay->setText(QString::fromStdString(text.str())); } -/** -* Form a string for output from the components instrument parameters -*/ -QString ComponentInfoController::getParameterInfo( - const Mantid::Geometry::IComponent &comp) { - QString text = ""; - std::map> - mapCmptToNameVector; - - auto paramNames = comp.getParameterNamesByComponent(); - for (auto itParamName = paramNames.begin(); itParamName != paramNames.end(); - ++itParamName) { - // build the data structure I need Map comp id -> vector of names - std::string paramName = itParamName->first; - Mantid::Geometry::ComponentID paramCompId = itParamName->second; - // attempt to insert this will fail silently if the key already exists - if (mapCmptToNameVector.find(paramCompId) == mapCmptToNameVector.end()) { - mapCmptToNameVector.emplace(paramCompId, std::vector()); - } - // get the vector out and add the name - mapCmptToNameVector[paramCompId].push_back(paramName); - } - - // walk out from the selected component - const Mantid::Geometry::IComponent *paramComp = ∁ - boost::shared_ptr parentComp; - while (paramComp) { - auto id = paramComp->getComponentID(); - auto &compParamNames = mapCmptToNameVector[id]; - if (compParamNames.size() > 0) { - text += QString::fromStdString("\nParameters from: " + - paramComp->getName() + "\n"); - std::sort(compParamNames.begin(), compParamNames.end(), - Mantid::Kernel::CaseInsensitiveStringComparator()); - for (auto itParamName = compParamNames.begin(); - itParamName != compParamNames.end(); ++itParamName) { - std::string paramName = *itParamName; - // no need to search recursively as we are asking from the matching - // component - std::string paramValue = - paramComp->getParameterAsString(paramName, false); - if (paramValue != "") { - text += QString::fromStdString(paramName + ": " + paramValue + "\n"); - } - } - } - parentComp = paramComp->getParent(); - paramComp = parentComp.get(); - } - - return text; -} - /** * Return non-detector info to be displayed in the selection info display. */ @@ -1243,13 +1191,11 @@ void DetectorPlotController::plotSingle(int detid) { */ void DetectorPlotController::plotTube(int detid) { const auto &actor = m_instrWidget->getInstrumentActor(); - auto &det = actor.getDetectorByDetID(detid); - boost::shared_ptr parent = - det.getParent(); - Mantid::Geometry::ICompAssembly_const_sptr ass = - boost::dynamic_pointer_cast( - parent); - if (parent && ass) { + const auto &componentInfo = actor.getComponentInfo(); + auto det = actor.getDetectorByDetID(detid); + + if (componentInfo.hasParent(det) && + componentInfo.detectorsInSubtree(det).size() > 0) { if (m_plotType == TubeSum) // plot sums over detectors vs time bins { plotTubeSums(detid); @@ -1278,9 +1224,10 @@ void DetectorPlotController::plotTubeSums(int detid) { return; } const auto &actor = m_instrWidget->getInstrumentActor(); - auto &det = actor.getDetectorByDetID(detid); - auto parent = det.getParent(); - QString label = QString::fromStdString(parent->getName()) + " (" + + const auto &componentInfo = actor.getComponentInfo(); + auto det = actor.getDetectorByDetID(detid); + auto parent = componentInfo.parent(det); + QString label = QString::fromStdString(componentInfo.name(parent)) + " (" + QString::number(detid) + ") Sum"; m_plot->setData(&x[0], &y[0], static_cast(y.size()), actor.getWorkspace()->getAxis(0)->unit()->unitID()); @@ -1300,7 +1247,9 @@ void DetectorPlotController::plotTubeSums(int detid) { * with this id. */ void DetectorPlotController::plotTubeIntegrals(int detid) { - auto &det = m_instrWidget->getInstrumentActor().getDetectorByDetID(detid); + auto det = m_instrWidget->getInstrumentActor().getDetectorByDetID(detid); + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); std::vector x, y; prepareDataForIntegralsPlot(detid, x, y); if (x.empty() || y.empty()) { @@ -1314,10 +1263,10 @@ void DetectorPlotController::plotTubeIntegrals(int detid) { } m_plot->setData(&x[0], &y[0], static_cast(y.size()), xAxisCaption.toStdString()); - auto parent = det.getParent(); + auto parent = componentInfo.parent(det); // curve label: "tube_name (detid) Integrals" // detid is included to distiguish tubes with the same name - QString label = QString::fromStdString(parent->getName()) + " (" + + QString label = QString::fromStdString(componentInfo.name(parent)) + " (" + QString::number(detid) + ") Integrals/" + getTubeXUnitsName(); m_plot->setLabel(label); } @@ -1371,10 +1320,11 @@ void DetectorPlotController::prepareDataForSumsPlot(int detid, std::vector *err) { const auto &actor = m_instrWidget->getInstrumentActor(); auto ws = actor.getWorkspace(); - auto &det = actor.getDetectorByDetID(detid); - auto parent = det.getParent(); - auto ass = boost::dynamic_pointer_cast( - parent); + const auto &componentInfo = actor.getComponentInfo(); + auto detector = actor.getDetectorByDetID(detid); + auto parent = componentInfo.parent(detector); + auto ass = componentInfo.detectorsInSubtree(parent); + size_t wi; try { wi = actor.getWorkspaceIndex(detid); @@ -1390,13 +1340,11 @@ void DetectorPlotController::prepareDataForSumsPlot(int detid, if (err) err->resize(x.size(), 0); - const int n = ass->nelements(); - for (int i = 0; i < n; ++i) { - Mantid::Geometry::IDetector_sptr idet = - boost::dynamic_pointer_cast((*ass)[i]); - if (idet) { + const auto &detectorInfo = actor.getDetectorInfo(); + for (auto det: ass) { + if (componentInfo.isDetector(det)) { try { - size_t index = actor.getWorkspaceIndex(idet->getID()); + size_t index = actor.getWorkspaceIndex(detectorInfo.detectorIDs()[det]); const auto &Y = ws->y(index); std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(), std::plus()); @@ -1448,19 +1396,18 @@ void DetectorPlotController::prepareDataForIntegralsPlot( return; const auto &actor = m_instrWidget->getInstrumentActor(); + const auto &componentInfo = actor.getComponentInfo(); Mantid::API::MatrixWorkspace_const_sptr ws = actor.getWorkspace(); // Does the instrument definition specify that psi should be offset. - std::vector parameters = - ws->getInstrument()->getStringParameter("offset-phi"); + std::vector parameters = actor.getStringParameter("offset-phi"); const bool bOffsetPsi = (!parameters.empty()) && std::find(parameters.begin(), parameters.end(), "Always") != parameters.end(); - auto &det = actor.getDetectorByDetID(detid); - auto parent = det.getParent(); - auto ass = boost::dynamic_pointer_cast( - parent); + auto det = actor.getDetectorByDetID(detid); + auto parent = componentInfo.parent(det); + auto ass = componentInfo.detectorsInSubtree(parent); size_t wi; try { wi = actor.getWorkspaceIndex(detid); @@ -1471,9 +1418,9 @@ void DetectorPlotController::prepareDataForIntegralsPlot( size_t imin, imax; actor.getBinMinMaxIndex(wi, imin, imax); - Mantid::Kernel::V3D samplePos = actor.getInstrument()->getSample()->getPos(); + auto samplePos = actor.getComponentInfo().samplePosition(); - const int n = ass->nelements(); + auto n = ass.size(); if (n == 0) { // don't think it's ever possible but... throw std::runtime_error("PickTab miniplot: empty instrument assembly"); @@ -1485,32 +1432,32 @@ void DetectorPlotController::prepareDataForIntegralsPlot( // collect and sort xy pairs in xymap std::map xymap, errmap; // get the first detector in the tube for lenth calculation - Mantid::Geometry::IDetector_sptr idet0 = - boost::dynamic_pointer_cast((*ass)[0]); - if (!idet0) { + if (!componentInfo.isDetector(ass[0])) { // it's not an assembly of detectors, // could be a mixture of monitors and other components PREPAREDATAFORINTEGRALSPLOT_RETURN_FAILED } - Mantid::Kernel::V3D normal = (*ass)[1]->getPos() - idet0->getPos(); + + auto normal = componentInfo.position(ass[1]) - componentInfo.position(ass[0]); normal.normalize(); - for (int i = 0; i < n; ++i) { - Mantid::Geometry::IDetector_sptr idet = - boost::dynamic_pointer_cast((*ass)[i]); - if (idet) { + const auto &detectorInfo = actor.getDetectorInfo(); + for (auto det: ass) { + if (componentInfo.isDetector(det)) { try { - const int id = idet->getID(); + auto id = detectorInfo.detectorIDs()[det]; // get the x-value for detector idet double xvalue = 0; switch (m_tubeXUnits) { case LENGTH: - xvalue = idet->getDistance(*idet0); + xvalue = detectorInfo.position(det).distance( + detectorInfo.position(ass[0])); break; case PHI: - xvalue = bOffsetPsi ? idet->getPhiOffset(M_PI) : idet->getPhi(); + xvalue = bOffsetPsi ? detectorInfo.getPhiOffset(det, M_PI) + : detectorInfo.getPhi(det); break; case OUT_OF_PLANE_ANGLE: { - Mantid::Kernel::V3D pos = idet->getPos(); + auto pos = detectorInfo.position(det); xvalue = getOutOfPlaneAngle(pos, samplePos, normal); break; } diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp index 7c77daa35e33..9da9f43d00a8 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp @@ -292,7 +292,7 @@ void InstrumentWidgetRenderTab::enable3DSurface(bool on) { */ void InstrumentWidgetRenderTab::initSurface() { setAxis(QString::fromStdString( - m_instrWidget->getInstrumentActor().getInstrument()->getDefaultAxis())); + m_instrWidget->getInstrumentActor().getDefaultAxis())); auto surface = getSurface(); // 3D axes switch needs to be shown for the 3D surface diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp index c703547ff0b7..a1c43a6ae19a 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetTreeTab.cpp @@ -1,6 +1,5 @@ #include "MantidQtWidgets/InstrumentView/InstrumentWidgetTreeTab.h" #include "MantidQtWidgets/Common/TSVSerialiser.h" -#include "MantidQtWidgets/InstrumentView/GLActorVisitor.h" #include "MantidQtWidgets/InstrumentView/InstrumentActor.h" #include "MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h" #include "MantidQtWidgets/InstrumentView/InstrumentWidget.h" @@ -18,10 +17,8 @@ InstrumentWidgetTreeTab::InstrumentWidgetTreeTab(InstrumentWidget *instrWidget) // Tree Controls m_instrumentTree = new InstrumentTreeWidget(nullptr); layout->addWidget(m_instrumentTree); - connect(m_instrumentTree, - SIGNAL(componentSelected(Mantid::Geometry::ComponentID)), - m_instrWidget, - SLOT(componentSelected(Mantid::Geometry::ComponentID))); + connect(m_instrumentTree, SIGNAL(componentSelected(size_t)), m_instrWidget, + SLOT(componentSelected(size_t))); connect(m_instrWidget, SIGNAL(requestSelectComponent(QString)), this, SLOT(selectComponentByName(QString))); } diff --git a/qt/widgets/instrumentview/src/MantidGLWidget.cpp b/qt/widgets/instrumentview/src/MantidGLWidget.cpp index a4ecdee8ce25..2c9a39339847 100644 --- a/qt/widgets/instrumentview/src/MantidGLWidget.cpp +++ b/qt/widgets/instrumentview/src/MantidGLWidget.cpp @@ -283,9 +283,9 @@ void MantidGLWidget::draw() { OpenGLError::check("MantidGLWidget::drawUnwrapped()"); } -void MantidGLWidget::componentSelected(Mantid::Geometry::ComponentID id) { +void MantidGLWidget::componentSelected(size_t componentIndex) { if (m_surface) { - m_surface->componentSelected(id); + m_surface->componentSelected(componentIndex); m_surface->updateView(); update(); } diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 2379694fe897..186084e80865 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -105,7 +105,6 @@ PanelsSurface::~PanelsSurface() { clearBanks(); } */ void PanelsSurface::init() { m_unwrappedDetectors.clear(); - m_assemblies.clear(); size_t ndet = m_instrActor->ndetectors(); if (ndet == 0) diff --git a/qt/widgets/instrumentview/src/Projection3D.cpp b/qt/widgets/instrumentview/src/Projection3D.cpp index 37e4308bc27c..2b57569753ce 100644 --- a/qt/widgets/instrumentview/src/Projection3D.cpp +++ b/qt/widgets/instrumentview/src/Projection3D.cpp @@ -7,7 +7,7 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedSphere.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" -#include "MantidGeometry/Instrument.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidGeometry/Objects/CSGObject.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidQtWidgets/Common/InputController.h" @@ -41,9 +41,6 @@ Projection3D::Projection3D(const InstrumentActor *rootActor, int winWidth, int winHeight) : ProjectionSurface(rootActor), m_drawAxes(true), m_wireframe(false), m_viewport(0, 0) { - - Instrument_const_sptr instr = rootActor->getInstrument(); - m_viewport.resize(winWidth, winHeight); V3D minBounds, maxBounds; m_instrActor->getBoundingBox(minBounds, maxBounds); @@ -217,9 +214,6 @@ void Projection3D::getSelectedDetectors(QList &dets) { double yTop = ymin + (ymax - ymin) * (h - rect.top()) / h; size_t ndet = m_instrActor->ndetectors(); - // Cache all the detector positions if needed. This is slow, but just once. - m_instrActor->cacheDetPos(); - for (size_t i = 0; i < ndet; ++i) { detid_t detId = m_instrActor->getDetID(i); V3D pos = m_instrActor->getDetPos(i); @@ -238,9 +232,6 @@ void Projection3D::getSelectedDetectors(QList &dets) { * @param dets :: returns a list of detector IDs to mask. */ void Projection3D::getMaskedDetectors(QList &dets) const { - // Cache all the detector positions if needed. This is slow, but just once. - m_instrActor->cacheDetPos(); - // find the layer of visible detectors QList pixels = m_maskShapes.getMaskedPixels(); double zmin = 1.0; @@ -288,19 +279,18 @@ void Projection3D::getMaskedDetectors(QList &dets) const { * Orient the viewport to look at a selected component. * @param id :: The ID of a selected component. */ -void Projection3D::componentSelected(Mantid::Geometry::ComponentID id) { +void Projection3D::componentSelected(size_t componentIndex) { - Instrument_const_sptr instr = m_instrActor->getInstrument(); + const auto &componentInfo = m_instrActor->getComponentInfo(); - if (id == NULL || id == instr->getComponentID()) { + if (componentIndex == componentInfo.root()) { m_viewport.reset(); return; } - IComponent_const_sptr comp = instr->getComponentByID(id); - V3D pos = comp->getPos(); + auto pos = componentInfo.position(componentIndex); - V3D compDir = comp->getPos() - instr->getSample()->getPos(); + auto compDir = pos - componentInfo.samplePosition(); compDir.normalize(); V3D up(0, 0, 1); V3D x = up.cross_prod(compDir); diff --git a/qt/widgets/instrumentview/src/ProjectionSurface.cpp b/qt/widgets/instrumentview/src/ProjectionSurface.cpp index 6d64e7900297..3fd01e2430ef 100644 --- a/qt/widgets/instrumentview/src/ProjectionSurface.cpp +++ b/qt/widgets/instrumentview/src/ProjectionSurface.cpp @@ -441,10 +441,8 @@ int ProjectionSurface::getDetectorID(int x, int y) const { } //------------------------------------------------------------------------------ -const Mantid::Geometry::IDetector &ProjectionSurface::getDetector(int x, - int y) const { - size_t pickID = getPickID(x, y); - return m_instrActor->getDetectorByPickID(pickID); +size_t ProjectionSurface::getDetector(int x, int y) const { + return getPickID(x, y); } /** diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 3cf5b3bfc487..61d9f8595240 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -31,7 +31,6 @@ RotationSurface::RotationSurface(const InstrumentActor *rootActor, void RotationSurface::init() { // the actor calls this->callback for each detector m_unwrappedDetectors.clear(); - m_assemblies.clear(); // if u-correction is applied manually then m_u_min and m_u_max // have valid values and have to be saved @@ -43,12 +42,6 @@ void RotationSurface::init() { if (ndet == 0) return; - // Pre-calculate all the detector positions (serial because - // I suspect the IComponent->getPos() method to not be properly thread safe) - m_instrActor->cacheDetPos(); - - Instrument_const_sptr inst = m_instrActor->getInstrument(); - // First detector defines the surface's x axis if (m_xaxis.nullVector()) { Mantid::Kernel::V3D pos = m_instrActor->getDetPos(0) - m_pos; diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 3309cf05637a..98a514842b92 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -8,7 +8,7 @@ #include "MantidAPI/IPeaksWorkspace.h" #include "MantidGeometry/IDetector.h" #include "MantidGeometry/Instrument/DetectorInfo.h" -#include "MantidGeometry/Instrument.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidGeometry/Objects/CSGObject.h" #include "MantidQtWidgets/Common/InputController.h" @@ -55,52 +55,6 @@ QString UnwrappedSurface::getDimInfo() const { .arg(m_viewRect.y1()); } -//------------------------------------------------------------------------------ -/** Calculate the rectangular region in uv coordinates occupied by an assembly. -* -* @param comp :: A member of the assembly. The total area of the assembly is a -*sum of areas of its members -* @param compRect :: A rect. area occupied by comp in uv space -*/ -void UnwrappedSurface::calcAssemblies(const Mantid::Geometry::IComponent *comp, - const QRectF &compRect) { - // We don't need the parametrized version = use the bare parent for speed - const Mantid::Geometry::IComponent *parent = comp->getBareParent(); - if (parent) { - QRectF &r = m_assemblies[parent->getComponentID()]; - r |= compRect; - calcAssemblies(parent, r); - } -} - -//------------------------------------------------------------------------------ -/** If needed, recalculate the cached bounding rectangles of all assemblies. */ -void UnwrappedSurface::cacheAllAssemblies() { - if (!m_assemblies.empty()) - return; - - for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { - const UnwrappedDetector &udet = m_unwrappedDetectors[i]; - if (!udet.isValid()) - continue; - // Get the BARE parent (not parametrized) to speed things up. - auto &detector = m_instrActor->getDetectorByDetID(udet.detID); - const Mantid::Geometry::IComponent *bareDet = detector.getComponentID(); - const Mantid::Geometry::IComponent *parent = bareDet->getBareParent(); - if (parent) { - QRectF detRect; - detRect.setLeft(udet.u - udet.width); - detRect.setRight(udet.u + udet.width); - detRect.setBottom(udet.v - udet.height); - detRect.setTop(udet.v + udet.height); - Mantid::Geometry::ComponentID id = parent->getComponentID(); - QRectF &r = m_assemblies[id]; - r |= detRect; - calcAssemblies(parent, r); - } - } -} - //------------------------------------------------------------------------------ /** * Draw the unwrapped instrument onto the screen @@ -268,30 +222,19 @@ bool hasParent(boost::shared_ptr comp, * * @param id :: ComponentID to zoom to. */ -void UnwrappedSurface::componentSelected(Mantid::Geometry::ComponentID id) { - boost::shared_ptr instr = - m_instrActor->getInstrument(); - if (id == nullptr) { - id = instr->getComponentID(); - } - boost::shared_ptr comp = - instr->getComponentByID(id); - boost::shared_ptr ass = - boost::dynamic_pointer_cast(comp); - boost::shared_ptr det = - boost::dynamic_pointer_cast(comp); - if (det) { - int detID = det->getID(); - - std::vector::const_iterator it; - for (it = m_unwrappedDetectors.begin(); it != m_unwrappedDetectors.end(); - ++it) { - const UnwrappedDetector &udet = *it; +void UnwrappedSurface::componentSelected(size_t componentIndex) { + const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &detectorInfo = m_instrActor->getDetectorInfo(); + if (componentInfo.isDetector(componentIndex)) { + int detID = detectorInfo.detectorIDs()[componentIndex]; + for (auto it = m_unwrappedDetectors.cbegin(); + it != m_unwrappedDetectors.cend(); ++it) { + const auto &udet = *it; if (udet.detID == detID) { - double w = udet.width; + auto w = udet.width; if (w > m_width_max) w = m_width_max; - double h = udet.height; + auto h = udet.height; if (h > m_height_max) h = m_height_max; QRectF area(udet.u - w, udet.v - h, w * 2, h * 2); @@ -300,16 +243,9 @@ void UnwrappedSurface::componentSelected(Mantid::Geometry::ComponentID id) { } } } - if (ass) { - this->cacheAllAssemblies(); - QMap::iterator assRect = - m_assemblies.find(ass->getComponentID()); - if (assRect != m_assemblies.end()) - zoom(*assRect); - else { - // std::cout << "Assembly not found \n"; - } - } + + if (componentInfo.detectorsInSubtree(componentIndex).size() > 0) + zoom(componentInfo.boundingBox(componentIndex)); } void UnwrappedSurface::getSelectedDetectors(QList &dets) { @@ -541,6 +477,19 @@ void UnwrappedSurface::drawSimpleToImage(QImage *image, bool picking) const { * Zooms to the specified area. The previous zoom stack is cleared. */ void UnwrappedSurface::zoom(const QRectF &area) { + doZoom(area); +} + +void UnwrappedSurface::zoom(const Mantid::Geometry::BoundingBox &area) { + double left = area.xMin(); + double top = area.yMin(); + double width = abs(area.xMax() - area.xMin()); + double height = abs(area.yMax() - area.yMin()); + + doZoom(QRectF(left, top, width, height)); +} + +void UnwrappedSurface::doZoom(const QRectF &area) { if (!m_zoomStack.isEmpty()) { m_viewRect = m_zoomStack.first(); m_zoomStack.clear(); From be3c1786eee943facb34154aae849eb36fd86085 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 9 Jan 2018 11:10:15 +0000 Subject: [PATCH 035/364] Update unwrapped detector and fix display issues re #21339 --- .../MantidGeometry/Instrument/ComponentInfo.h | 5 +- .../Geometry/src/Instrument/ComponentInfo.cpp | 11 ++- Framework/Geometry/test/ComponentInfoTest.h | 2 +- .../Geometry/test/InstrumentVisitorTest.h | 14 +-- .../InstrumentView/PanelsSurface.h | 7 +- .../InstrumentView/UnwrappedDetector.h | 13 +-- .../InstrumentView/UnwrappedSurface.h | 4 +- .../instrumentview/src/InstrumentActor.cpp | 2 +- .../instrumentview/src/PanelsSurface.cpp | 46 ++++------ .../instrumentview/src/RotationSurface.cpp | 35 +++----- .../instrumentview/src/UnwrappedCylinder.cpp | 7 +- .../instrumentview/src/UnwrappedDetector.cpp | 25 ++---- .../instrumentview/src/UnwrappedSphere.cpp | 7 +- .../instrumentview/src/UnwrappedSurface.cpp | 87 +++++++++---------- 14 files changed, 98 insertions(+), 167 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index a476623b1bc1..bd60a4f915d3 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -149,9 +149,8 @@ class MANTID_GEOMETRY_DLL ComponentInfo { return m_componentIds->operator[](componentIndex); } bool hasValidShape(const size_t componentIndex) const; - - boost::shared_ptr - shape(const size_t componentIndex) const; + + const Geometry::IObject &shape(const size_t componentIndex) const; double solidAngle(const size_t componentIndex, const Kernel::V3D &observer) const; diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index ed0177069633..6a5ee8909878 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -231,9 +231,8 @@ void ComponentInfo::setRotation(const size_t componentIndex, Kernel::toQuaterniond(newRotation)); } -boost::shared_ptr -ComponentInfo::shape(const size_t componentIndex) const { - return (*m_shapes)[componentIndex]; +const IObject &ComponentInfo::shape(const size_t componentIndex) const { + return *(*m_shapes)[componentIndex]; } Kernel::V3D ComponentInfo::scaleFactor(const size_t componentIndex) const { @@ -260,11 +259,11 @@ double ComponentInfo::solidAngle(const size_t componentIndex, toShapeFrame(observer, *m_componentInfo, componentIndex); const Kernel::V3D scaleFactor = this->scaleFactor(componentIndex); if ((scaleFactor - Kernel::V3D(1.0, 1.0, 1.0)).norm() < 1e-12) - return shape(componentIndex)->solidAngle(relativeObserver); + return shape(componentIndex).solidAngle(relativeObserver); else { // This function will scale the object shape when calculating the solid // angle. - return shape(componentIndex)->solidAngle(relativeObserver, scaleFactor); + return shape(componentIndex).solidAngle(relativeObserver, scaleFactor); } } @@ -400,7 +399,7 @@ ComponentInfo::componentBoundingBox(const size_t index, return BoundingBox(); // Return null bounding box } const auto &s = this->shape(index); - BoundingBox absoluteBB = s->getBoundingBox(); + BoundingBox absoluteBB = s.getBoundingBox(); // modify in place for speed const Eigen::Vector3d scaleFactor = m_componentInfo->scaleFactor(index); diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index feb7873780a0..f3530b6cf6a2 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -202,7 +202,7 @@ class ComponentInfoTest : public CxxTest::TestSuite { // Compare sizes TS_ASSERT_EQUALS(b->size(), a.size()); // Shapes are the same - TS_ASSERT_EQUALS(b->shape(0).get(), a.shape(0).get()); + TS_ASSERT_EQUALS(&b->shape(0), &a.shape(0)); // IDs are the same TS_ASSERT_EQUALS(b->indexOf(&comp1), a.indexOf(&comp1)); TS_ASSERT(!b->hasDetectorInfo()); diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index bd087bba6b8e..90800ead8f49 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -371,21 +371,21 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { // Instrument const auto &instrumentShape = componentInfo->shape(componentInfo->root()); TSM_ASSERT("CompAssemblies should have no shape", - !instrumentShape->hasValidShape()); + !instrumentShape.hasValidShape()); // Bank 1 const auto &subAssemblyShape = componentInfo->shape(componentInfo->root() - 3); TSM_ASSERT("CompAssemblies should have no shape", - !subAssemblyShape->hasValidShape()); + !subAssemblyShape.hasValidShape()); const auto &detectorShape = componentInfo->shape(0 /*Is a detector index!*/); - TSM_ASSERT("Detectors should have a shape", detectorShape->hasValidShape()); + TSM_ASSERT("Detectors should have a shape", detectorShape.hasValidShape()); // Check shapes are re-used as expected - TSM_ASSERT_EQUALS("Shape object should be reused", instrumentShape.get(), - subAssemblyShape.get()); - TSM_ASSERT_EQUALS("Shape object should be reused", detectorShape.get(), - componentInfo->shape(1 /*another detector*/).get()); + TSM_ASSERT_EQUALS("Shape object should be reused", &instrumentShape, + &subAssemblyShape); + TSM_ASSERT_EQUALS("Shape object should be reused", &detectorShape, + &componentInfo->shape(1 /*another detector*/)); } void test_names() { diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h index 595dc48ae722..2bafb29666d5 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h @@ -12,8 +12,6 @@ class PanelsSurface; struct FlatBankInfo { explicit FlatBankInfo(PanelsSurface *s); - /// Component id of the bank - Mantid::Geometry::ComponentID id; /// Bank's rotation Mantid::Kernel::Quat rotation; /// Starting index of bank's detectors in m_unwrappedDetectors vector @@ -69,8 +67,7 @@ class PanelsSurface : public UnwrappedSurface { // Setup the projection axes void setupAxes(); // Add a flat bank - void addFlatBankOfDetectors(Mantid::Geometry::ComponentID bankId, - const Mantid::Kernel::V3D &normal, + void addFlatBankOfDetectors(const Mantid::Kernel::V3D &normal, const std::vector &detectors); void constructFromComponentInfo(); Mantid::Kernel::Quat calcBankRotation(const Mantid::Kernel::V3D &detPos, @@ -99,7 +96,7 @@ class PanelsSurface : public UnwrappedSurface { /// Keep info of the flat banks QList m_flatBanks; /// Maps detector ids to indices of FlatBankInfos in m_flatBanks - QMap m_detector2bankMap; + QMap m_detector2bankMap; friend struct FlatBankInfo; }; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h index fe946b43aeea..0ef007192897 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h @@ -28,14 +28,9 @@ This class keeps information used to draw a detector on an unwrapped surface. class UnwrappedDetector { public: UnwrappedDetector(); - UnwrappedDetector(GLColor color, Mantid::detid_t detID, size_t detIndex, - const Mantid::Kernel::V3D &pos, - const Mantid::Kernel::Quat &rot, - const Mantid::Kernel::V3D &scaleFactor, - boost::shared_ptr shape); + UnwrappedDetector(GLColor color, size_t detIndex); UnwrappedDetector(const UnwrappedDetector &other); UnwrappedDetector &operator=(const UnwrappedDetector &other); - bool isValid() const; GLColor color; ///< red, green, blue colour components (0 - 255) double u; ///< horizontal "unwrapped" coordinate double v; ///< vertical "unwrapped" coordinate @@ -43,13 +38,7 @@ class UnwrappedDetector { double height; ///< detector height in units of v double uscale; ///< scaling factor in u direction double vscale; ///< scaling factor in v direction - Mantid::detid_t detID; ///< Detector ID size_t detIndex; ///< Detector Index in ComponentInfo/DetectorInfo. - Mantid::Kernel::V3D position; ///< Detector position - Mantid::Kernel::Quat rotation; ///< Detector orientation - boost::shared_ptr - shape; ///< Shape of the detector - Mantid::Kernel::V3D scaleFactor; ///< Detector's scale factor }; } // namespace MantidWidgets } // namespace MantidQt diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h index b0b1f1c423e9..a26bd3626104 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h @@ -97,7 +97,6 @@ class UnwrappedSurface : public ProjectionSurface { bool isFlippedView() const { return m_flippedView; } /// Zoom into an area of the screen void zoom(const QRectF &area); - void zoom(const Mantid::Geometry::BoundingBox &area); //@} /// Load settings for the unwrapped surface from a project file virtual void loadFromProject(const std::string &lines) override; @@ -122,7 +121,6 @@ protected slots: void drawSurface(MantidGLWidget *widget, bool picking = false) const override; void drawSimpleToImage(QImage *image, bool picking = false) const override; void changeColorMap() override; - void doZoom(const QRectF &area); //@} /** @name New protected virtual methods */ @@ -149,7 +147,7 @@ protected slots: /** @name Protected methods */ //@{ - void setColor(int index, bool picking) const; + void setColor(size_t index, bool picking) const; void createPeakShapes(const QRect &viewport) const; //@} diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 9f937020d7ff..1d1932f8e0a9 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -758,7 +758,7 @@ void InstrumentActor::doDraw(bool picking) const { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - componentInfo.shape(i)->draw(); + componentInfo.shape(i).draw(); glPopMatrix(); } } diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 186084e80865..d06c152420a4 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -72,7 +72,7 @@ namespace MantidWidgets { * @param s The surface of the panel */ FlatBankInfo::FlatBankInfo(PanelsSurface *s) - : id(nullptr), rotation(), startDetectorIndex(0), endDetectorIndex(0), + : rotation(), startDetectorIndex(0), endDetectorIndex(0), polygon(), surface(s) {} /** @@ -83,7 +83,7 @@ void FlatBankInfo::translate(const QPointF &shift) { double du = shift.x(); double dv = shift.y(); polygon.translate(shift); - for (size_t i = startDetectorIndex; i < endDetectorIndex; ++i) { + for (size_t i = startDetectorIndex; i <= endDetectorIndex; ++i) { UnwrappedDetector &udet = surface->m_unwrappedDetectors[i]; udet.u += du; udet.v += dv; @@ -107,6 +107,7 @@ void PanelsSurface::init() { m_unwrappedDetectors.clear(); size_t ndet = m_instrActor->ndetectors(); + m_unwrappedDetectors.resize(ndet); if (ndet == 0) return; @@ -141,9 +142,10 @@ void PanelsSurface::project(const Mantid::Kernel::V3D &, double &, double &, void PanelsSurface::rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat &R) const { - int index = m_detector2bankMap[udet.detID]; + const auto &detectorInfo = m_instrActor->getDetectorInfo(); + int index = m_detector2bankMap[udet.detIndex]; FlatBankInfo &info = *m_flatBanks[index]; - R = info.rotation * udet.rotation; + R = info.rotation * detectorInfo.rotation(udet.detIndex); } /** @@ -164,17 +166,14 @@ void PanelsSurface::setupAxes() { * @param detectors :: List of detectorIndices. */ void PanelsSurface::addFlatBankOfDetectors( - ComponentID bankId, const Mantid::Kernel::V3D &normal, - const std::vector &detectors) { + const Mantid::Kernel::V3D &normal, const std::vector &detectors) { int index = m_flatBanks.size(); // save bank info FlatBankInfo *info = new FlatBankInfo(this); m_flatBanks << info; - info->id = bankId; // record the first detector index of the bank - info->startDetectorIndex = m_unwrappedDetectors.size(); - auto nelem = detectors.size(); - m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); + info->startDetectorIndex = detectors.front(); + info->endDetectorIndex = detectors.back(); // keep reference position on the bank's plane const auto &detectorInfo = m_instrActor->getDetectorInfo(); @@ -193,14 +192,12 @@ void PanelsSurface::addFlatBankOfDetectors( for (auto detector : detectors) { addDetector(detector, pos0, index, info->rotation); // update the outline polygon - UnwrappedDetector &udet = *(m_unwrappedDetectors.end() - 1); + UnwrappedDetector &udet = m_unwrappedDetectors[detector]; auto p2 = QPointF(udet.u, udet.v); vert.clear(); vert << p0 << p1 << p2; info->polygon = info->polygon.united(QPolygonF(vert)); } - // record the end detector index of the bank - info->endDetectorIndex = m_unwrappedDetectors.size(); } void PanelsSurface::processStructured(const std::vector &children, @@ -212,12 +209,11 @@ void PanelsSurface::processStructured(const std::vector &children, // save bank info FlatBankInfo *info = new FlatBankInfo(this); m_flatBanks << info; - // set bank ID - info->id = componentInfo.componentID(rootIndex)->getComponentID(); // find the rotation to put the bank on the plane info->rotation = calcBankRotation(corners[0], normal); // record the first detector index of the bank - info->startDetectorIndex = m_unwrappedDetectors.size(); + info->startDetectorIndex = children.front(); + info->endDetectorIndex = children.back(); // set the outline QVector verts; for (auto &corner : corners) { @@ -229,13 +225,8 @@ void PanelsSurface::processStructured(const std::vector &children, info->polygon = QPolygonF(verts); - auto nelem = children.size(); - m_unwrappedDetectors.reserve(m_unwrappedDetectors.size() + nelem); - for (auto child : children) addDetector(child, corners[0], index, info->rotation); - // record the end detector index of the bank - info->endDetectorIndex = m_unwrappedDetectors.size(); } std::pair, Mantid::Kernel::V3D> @@ -323,8 +314,7 @@ void PanelsSurface::constructFromComponentInfo() { Mantid::Kernel::V3D normal; std::tie(detectors, normal) = res.get(); if (!detectors.empty()) - addFlatBankOfDetectors(componentInfo.componentID(i)->getComponentID(), - normal, detectors); + addFlatBankOfDetectors(normal, detectors); } } else if (children.size() > 0 && componentInfo.parent(children[0]) == componentInfo.root()) { @@ -367,13 +357,9 @@ void PanelsSurface::addDetector(size_t detIndex, const auto &componentInfo = m_instrActor->getComponentInfo(); Mantid::Kernel::V3D pos = detectorInfo.position(detIndex); - Mantid::detid_t detid = detectorInfo.detectorIDs()[detIndex]; - m_detector2bankMap[detid] = index; + m_detector2bankMap[detIndex] = index; // get the colour - UnwrappedDetector udet(m_instrActor->getColor(detIndex), detid, detIndex, pos, - detectorInfo.rotation(detIndex), - componentInfo.scaleFactor(detIndex), - componentInfo.shape(detIndex)); + UnwrappedDetector udet(m_instrActor->getColor(detIndex), detIndex); // apply bank's rotation pos -= refPos; rotation.rotate(pos); @@ -382,7 +368,7 @@ void PanelsSurface::addDetector(size_t detIndex, udet.v = m_yaxis.scalar_prod(pos); udet.uscale = udet.vscale = 1.0; this->calcSize(udet); - m_unwrappedDetectors.push_back(udet); + m_unwrappedDetectors[detIndex] = udet; } /** diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 61d9f8595240..e920c9acc202 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -86,32 +86,20 @@ void RotationSurface::init() { if (!exceptionThrown) try { size_t i = size_t(ii); - - auto id = m_instrActor->getDetID(i); try { - if (detectorInfo.isMonitor( - detectorInfo.indexOf(id)) || - (id < 0)) { - // Not a detector or a monitor - // Make some blank, empty thing that won't - // draw + if (detectorInfo.isMonitor(i)) { m_unwrappedDetectors[i] = UnwrappedDetector(); } else { // A real detector. // Position, relative to origin - // Mantid::Kernel::V3D pos = det->getPos() - - // m_pos; - Mantid::Kernel::V3D rpos = - m_instrActor->getDetPos(i) - m_pos; + auto rpos = detectorInfo.position(i) - m_pos; auto pos = detectorInfo.position(i); auto rot = detectorInfo.rotation(i); auto scaleFactor = componentInfo.scaleFactor(i); - auto shape = componentInfo.shape(i); // Create the unwrapped shape UnwrappedDetector udet( - m_instrActor->getColor(i), id, i, pos, - rot, scaleFactor, shape); + m_instrActor->getColor(i), i); // Calculate its position/size in UV // coordinates this->calcUV(udet, rpos); @@ -203,7 +191,7 @@ void RotationSurface::findUVBounds() { m_v_max = -DBL_MAX; for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { const UnwrappedDetector &udet = m_unwrappedDetectors[i]; - if (!udet.isValid()) + if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) continue; if (udet.u < m_u_min) m_u_min = udet.u; @@ -233,12 +221,10 @@ void RotationSurface::findAndCorrectUGap() { return; } - std::vector::const_iterator ud = - m_unwrappedDetectors.begin(); - for (; ud != m_unwrappedDetectors.end(); ++ud) { - if (!ud->isValid()) + for (const auto &udet: m_unwrappedDetectors) { + if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) continue; - double u = ud->u; + double u = udet.u; int i = int((u - m_u_min) / bin_width); ubins[i] = true; } @@ -272,11 +258,10 @@ void RotationSurface::findAndCorrectUGap() { m_u_max += period; } - std::vector::iterator ud = m_unwrappedDetectors.begin(); - for (; ud != m_unwrappedDetectors.end(); ++ud) { - if (!ud->isValid()) + for (auto &udet: m_unwrappedDetectors) { + if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) continue; - double &u = ud->u; + double &u = udet.u; u = applyUCorrection(u); } } diff --git a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp index a71d13a2b2fd..8d697506b4f7 100644 --- a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp @@ -1,7 +1,7 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedCylinder.h" #include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" -#include "MantidGeometry/IDetector.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" namespace MantidQt { namespace MantidWidgets { @@ -39,10 +39,11 @@ void UnwrappedCylinder::rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat &R) const { // direction in which to look Mantid::Kernel::V3D eye; + const auto &componentInfo = m_instrActor->getComponentInfo(); // rotation from the global axes to those where // the z axis points to the detector Mantid::Kernel::Quat R1; - eye = m_pos - udet.position; + eye = m_pos - componentInfo.position(udet.detIndex); if (!eye.nullVector()) { // eye must point towards the detector and be perpendicular to the // cylinder's axis @@ -55,7 +56,7 @@ void UnwrappedCylinder::rotate(const UnwrappedDetector &udet, } } // add detector's own rotation - R = R1 * udet.rotation; + R = R1 * componentInfo.rotation(udet.detIndex); } } // MantidWidgets diff --git a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp index 90c094a37353..1f9ea142d499 100644 --- a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp @@ -8,22 +8,15 @@ namespace MantidQt { namespace MantidWidgets { UnwrappedDetector::UnwrappedDetector() - : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(0), - detIndex(0) { + : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detIndex(0) { color = GLColor(0, 0, 0); } -UnwrappedDetector::UnwrappedDetector(GLColor color, Mantid::detid_t detID, - size_t detIndex, - const Mantid::Kernel::V3D &pos, - const Mantid::Kernel::Quat &rot, - const Mantid::Kernel::V3D &scaleFactor, - boost::shared_ptr shape) - : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detID(detID), - detIndex(detIndex), position(pos), rotation(rot), - scaleFactor(scaleFactor) { +UnwrappedDetector::UnwrappedDetector(GLColor color, + size_t detIndex) + : u(0), v(0), width(0), height(0), uscale(0), vscale(0), + detIndex(detIndex){ this->color = color; - this->shape = shape; } /** Copy constructor */ @@ -41,16 +34,8 @@ operator=(const UnwrappedDetector &other) { height = other.height; uscale = other.uscale; vscale = other.vscale; - detID = other.detID; detIndex = other.detIndex; - position = other.position; - rotation = other.rotation; - shape = other.shape; - scaleFactor = other.scaleFactor; return *this; } - -/** Check if the object is valid*/ -bool UnwrappedDetector::isValid() const { return static_cast(shape); } } // namespace MantidWidgets } // namespace MantidQt \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp index d5f5d53e5640..61095fea1f06 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp @@ -1,6 +1,6 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedSphere.h" #include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" -#include "MantidGeometry/IDetector.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" #include namespace MantidQt { @@ -44,12 +44,13 @@ void UnwrappedSphere::rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat R1; // direction in which to look: from sample to detector Mantid::Kernel::V3D eye; - eye = m_pos - udet.position; + const auto &componentInfo = m_instrActor->getComponentInfo(); + eye = m_pos - componentInfo.position(udet.detIndex); if (!eye.nullVector()) { InstrumentActor::rotateToLookAt(eye, m_zaxis, R1); } // add detector's own rotation - R = R1 * udet.rotation; + R = R1 * componentInfo.rotation(udet.detIndex); } } // MantidWidgets diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 98a514842b92..84229d3409de 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -25,10 +25,23 @@ using namespace Mantid::Geometry; namespace MantidQt { namespace MantidWidgets { +namespace { + +QRectF getArea(const UnwrappedDetector &udet, double maxWidth, + double maxHeight) { + auto w = udet.width; + if (w > maxWidth) + w = maxWidth; + auto h = udet.height; + if (h > maxHeight) + h = maxHeight; + return QRectF(udet.u - w, udet.v - h, w * 2, h * 2); +} +} // namespace /** -* Constructor. -* @param rootActor :: The instrument actor. -*/ + * Constructor. + * @param rootActor :: The instrument actor. + */ UnwrappedSurface::UnwrappedSurface(const InstrumentActor *rootActor) : ProjectionSurface(rootActor), m_u_min(DBL_MAX), m_u_max(-DBL_MAX), m_v_min(DBL_MAX), m_v_max(-DBL_MAX), m_height_max(0), m_width_max(0), @@ -126,10 +139,9 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { glShadeModel(GL_FLAT); } - for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { - const UnwrappedDetector &udet = m_unwrappedDetectors[i]; - - if (!udet.isValid()) + const auto &componentInfo = m_instrActor->getComponentInfo(); + for (const auto &udet: m_unwrappedDetectors) { + if (!componentInfo.hasShape(udet.detIndex)) continue; int iw = int(udet.width / dw); @@ -143,7 +155,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { continue; // apply the detector's colour - setColor(int(i), picking); + setColor(udet.detIndex, picking); // if the detector is too small to see its shape draw a rectangle if (iw < 6 || ih < 6) { @@ -167,10 +179,11 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { rot.getAngleAxis(deg, ax0, ax1, ax2); glRotated(deg, ax0, ax1, ax2); - Mantid::Kernel::V3D scaleFactor = udet.scaleFactor; + Mantid::Kernel::V3D scaleFactor = + componentInfo.scaleFactor(udet.detIndex); glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - udet.shape->draw(); + m_instrActor->getComponentInfo().shape(udet.detIndex).draw(); glPopMatrix(); } @@ -191,7 +204,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { * @param picking :: True if detector is being drawn in the picking mode. * In this case index is transformed into color */ -void UnwrappedSurface::setColor(int index, bool picking) const { +void UnwrappedSurface::setColor(size_t index, bool picking) const { if (picking) { auto c = InstrumentActor::makePickColor(index); unsigned char r, g, b; @@ -224,28 +237,16 @@ bool hasParent(boost::shared_ptr comp, */ void UnwrappedSurface::componentSelected(size_t componentIndex) { const auto &componentInfo = m_instrActor->getComponentInfo(); - const auto &detectorInfo = m_instrActor->getDetectorInfo(); if (componentInfo.isDetector(componentIndex)) { - int detID = detectorInfo.detectorIDs()[componentIndex]; - for (auto it = m_unwrappedDetectors.cbegin(); - it != m_unwrappedDetectors.cend(); ++it) { - const auto &udet = *it; - if (udet.detID == detID) { - auto w = udet.width; - if (w > m_width_max) - w = m_width_max; - auto h = udet.height; - if (h > m_height_max) - h = m_height_max; - QRectF area(udet.u - w, udet.v - h, w * 2, h * 2); - zoom(area); - break; - } - } + const auto &udet = m_unwrappedDetectors[componentIndex]; + zoom(getArea(udet, m_width_max, m_height_max)); + } else { + auto detectors = componentInfo.detectorsInSubtree(componentIndex); + QRectF area; + for (auto det : detectors) + area |= getArea(m_unwrappedDetectors[det], m_width_max, m_height_max); + zoom(area); } - - if (componentInfo.detectorsInSubtree(componentIndex).size() > 0) - zoom(componentInfo.boundingBox(componentIndex)); } void UnwrappedSurface::getSelectedDetectors(QList &dets) { @@ -302,12 +303,13 @@ void UnwrappedSurface::getSelectedDetectors(QList &dets) { break; } + const auto &detectorInfo = m_instrActor->getDetectorInfo(); // select detectors with u,v within the allowed boundaries for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { UnwrappedDetector &udet = m_unwrappedDetectors[i]; if (udet.u >= uleft && udet.u <= uright && udet.v >= vbottom && udet.v <= vtop) { - dets.push_back(udet.detID); + dets.push_back(detectorInfo.detectorIDs()[udet.detIndex]); } } } @@ -316,10 +318,11 @@ void UnwrappedSurface::getMaskedDetectors(QList &dets) const { dets.clear(); if (m_maskShapes.isEmpty()) return; + const auto &detectorInfo = m_instrActor->getDetectorInfo(); for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { const UnwrappedDetector &udet = m_unwrappedDetectors[i]; if (m_maskShapes.isMasked(udet.u, udet.v)) { - dets.append(udet.detID); + dets.append(detectorInfo.detectorIDs()[udet.detIndex]); } } } @@ -477,19 +480,6 @@ void UnwrappedSurface::drawSimpleToImage(QImage *image, bool picking) const { * Zooms to the specified area. The previous zoom stack is cleared. */ void UnwrappedSurface::zoom(const QRectF &area) { - doZoom(area); -} - -void UnwrappedSurface::zoom(const Mantid::Geometry::BoundingBox &area) { - double left = area.xMin(); - double top = area.yMin(); - double width = abs(area.xMax() - area.xMin()); - double height = abs(area.yMax() - area.yMin()); - - doZoom(QRectF(left, top, width, height)); -} - -void UnwrappedSurface::doZoom(const QRectF &area) { if (!m_zoomStack.isEmpty()) { m_viewRect = m_zoomStack.first(); m_zoomStack.clear(); @@ -600,8 +590,9 @@ void UnwrappedSurface::calcSize(UnwrappedDetector &udet) { Mantid::Kernel::Quat R; this->rotate(udet, R); - Mantid::Geometry::BoundingBox bbox = udet.shape->getBoundingBox(); - Mantid::Kernel::V3D scale = udet.scaleFactor; + const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &bbox = componentInfo.shape(udet.detIndex).getBoundingBox(); + auto scale = componentInfo.scaleFactor(udet.detIndex); // sizes of the detector along each 3D axis Mantid::Kernel::V3D size = bbox.maxPoint() - bbox.minPoint(); From d9e18d1a7543b6467f155718508b29d71280416b Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 10 Jan 2018 10:25:19 +0000 Subject: [PATCH 036/364] fix merge issues --- CMakeLists.txt | 3 ++- Framework/Beamline/inc/MantidBeamline/ComponentInfo.h | 3 ++- Framework/Beamline/test/ComponentInfoTest.h | 7 ++++--- .../inc/MantidGeometry/Instrument/ComponentInfo.h | 1 - qt/widgets/instrumentview/src/PanelsSurface.cpp | 9 ++++++--- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6813d520d89e..b81a60aa0dea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,11 +153,12 @@ include_directories ( Framework/Kernel/inc ) include_directories ( Framework/HistogramData/inc ) include_directories ( Framework/Indexing/inc ) include_directories ( Framework/Parallel/inc ) +include_directories ( Framework/Beamline/inc ) include_directories ( Framework/Geometry/inc ) include_directories ( Framework/API/inc ) include_directories ( Framework/Types/inc ) -set ( CORE_MANTIDLIBS Kernel HistogramData Indexing Geometry API Types ) +set ( CORE_MANTIDLIBS Kernel HistogramData Indexing Beamline Geometry API Types ) if ( ENABLE_MANTIDPLOT AND MAKE_VATES ) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index c5c0d5c83695..f0946bba6776 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -103,7 +103,8 @@ class MANTID_BEAMLINE_DLL ComponentInfo { boost::shared_ptr> positions, boost::shared_ptr> rotations, boost::shared_ptr> scaleFactors, - boost::shared_ptr> componentType, boost::shared_ptr> names, + boost::shared_ptr> componentType, + boost::shared_ptr> names, int64_t sourceIndex, int64_t sampleIndex); /// Copy assignment not permitted because of the way DetectorInfo stored ComponentInfo &operator=(const ComponentInfo &other) = delete; diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 0bd658dbb967..749c99dd80c6 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -424,20 +424,21 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto componentRanges = boost::make_shared>>( std::vector>{ {0, 0}}); - auto isRectangularBank = boost::make_shared>(1, false); + auto componentTypes = + boost::make_shared>( + 1, Mantid::Beamline::ComponentType::Generic); auto instrumentTree = boost::make_shared>>( 1, std::vector{1, 2}); // invalid TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, componentRanges, parentIndices, instrumentTree, positions, - rotations, scaleFactors, isRectangularBank, + rotations, scaleFactors, componentTypes, names, -1, -1), std::invalid_argument &); } void test_read_positions_rotations() { - auto allOutputs = makeTreeExampleAndReturnGeometricArguments(); // Resulting ComponentInfo diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index bd60a4f915d3..6ab11126371c 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -157,7 +157,6 @@ class MANTID_GEOMETRY_DLL ComponentInfo { BoundingBox boundingBox(const size_t componentIndex, const BoundingBox *reference = nullptr) const; Beamline::ComponentType componentType(const size_t componentIndex) const; - bool isRectangularBank(const size_t componentIndex) const; void setScanInterval(const std::pair &interval); void merge(const ComponentInfo &other); size_t scanSize() const; diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index d06c152420a4..dcb9ef1f3bc4 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -284,13 +284,16 @@ PanelsSurface::findFlatPanels(size_t rootIndex, std::vector &visited) { const auto &componentInfo = m_instrActor->getComponentInfo(); auto parentIndex = componentInfo.parent(rootIndex); - - if (componentInfo.isStructuredBank(parentIndex)) { + auto componentType = componentInfo.componentType(parentIndex); + if (componentType == Mantid::Beamline::ComponentType::Rectangular || + componentType == Mantid::Beamline::ComponentType::Structured) { /* Do nothing until the root index of the structured bank. */ return boost::none; } - if (componentInfo.isStructuredBank(rootIndex)) { + componentType = componentInfo.componentType(rootIndex); + if (componentType == Mantid::Beamline::ComponentType::Rectangular || + componentType == Mantid::Beamline::ComponentType::Structured) { processStructured(children, rootIndex); for (auto child : children) visited[child] = true; From 30d8884afa831c2010ef867f5309783baf4d0937 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 10 Jan 2018 11:13:04 +0000 Subject: [PATCH 037/364] cleanup around GeometryHandler #21339 --- Framework/Beamline/test/ComponentInfoTest.h | 44 +++++++++---------- .../MantidGeometry/Instrument/ComponentInfo.h | 5 +-- .../inc/MantidGeometry/Objects/CSGObject.h | 4 +- .../Rendering/GeometryHandler.h | 8 ++-- .../Rendering/GeometryTriangulator.h | 2 +- .../src/Instrument/InstrumentVisitor.cpp | 9 ++-- Framework/Geometry/src/Objects/CSGObject.cpp | 27 +++++------- .../src/Rendering/GeometryHandler.cpp | 11 ++--- .../Geometry/test/InstrumentVisitorTest.h | 6 +-- .../InstrumentView/InstrumentActor.h | 10 ++--- .../InstrumentView/InstrumentTreeModel.h | 1 + .../InstrumentView/PanelsSurface.h | 2 +- .../InstrumentView/UnwrappedDetector.h | 14 +++--- .../instrumentview/src/InstrumentActor.cpp | 34 +++++++------- .../src/InstrumentWidgetPickTab.cpp | 8 ++-- .../src/InstrumentWidgetRenderTab.cpp | 6 +-- .../instrumentview/src/PanelsSurface.cpp | 10 ++--- .../instrumentview/src/RotationSurface.cpp | 7 +-- .../instrumentview/src/UnwrappedDetector.cpp | 5 +-- .../instrumentview/src/UnwrappedSurface.cpp | 10 ++--- 20 files changed, 106 insertions(+), 117 deletions(-) diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 749c99dd80c6..4243358fd223 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -214,9 +214,9 @@ makeTreeExample() { // Rectangular bank flag auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); - + auto instrumentTree = boost::make_shared>>( - 2, std::vector(2)); + 2, std::vector(2)); auto componentInfo = boost::make_shared( bankSortedDetectorIndices, @@ -225,8 +225,8 @@ makeTreeExample() { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, instrumentTree, positions, rotations, scaleFactors, isRectangularBank, - names, -1, -1); + parentIndices, instrumentTree, positions, rotations, scaleFactors, + isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -284,9 +284,10 @@ class ComponentInfoTest : public CxxTest::TestSuite { std::vector{0, 1, 2}); auto bankSortedComponentIndices = boost::make_shared>(std::vector(1)); - auto parentIndices = boost::make_shared>( - std::vector{9, 9, 9, 9}); // These indices are invalid, but that's - // ok as not being tested here + auto parentIndices = + boost::make_shared>(std::vector{ + 9, 9, 9, 9}); // These indices are invalid, but that's + // ok as not being tested here auto detectorRanges = boost::make_shared>>( 1, std::pair{0, 2}); @@ -340,7 +341,7 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); auto instrumentTree = boost::make_shared< - std::vector>>(); // invalid but not being tested + std::vector>>(); // invalid but not being tested TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, bankSortedComponentIndices, componentRanges, @@ -383,7 +384,7 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); auto instrumentTree = boost::make_shared< - std::vector>>(); // invalid but not being tested + std::vector>>(); // invalid but not being tested TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, componentRanges, @@ -402,19 +403,19 @@ class ComponentInfoTest : public CxxTest::TestSuite { * All vectors should be the same size. */ auto detectorsInSubtree = - boost::make_shared>(); // No detector indices - // in this example! + boost::make_shared>(); // No detector indices + // in this example! auto componentsInSubtree = - boost::make_shared>(std::vector{0}); + boost::make_shared>(std::vector{0}); auto detectorRanges = boost::make_shared>>( 1, std::pair(0, 0)); auto parentIndices = boost::make_shared>( - std::vector{9, 9, 9}); // These indices are invalid, but that's - // ok as not being tested here + std::vector{9, 9, 9}); // These indices are invalid, but that's + // ok as not being tested here auto positions = boost::make_shared(1); auto rotations = boost::make_shared(1); @@ -422,20 +423,19 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto names = boost::make_shared(1); // Only one component. So single empty component range. auto componentRanges = - boost::make_shared>>( - std::vector>{ {0, 0}}); + boost::make_shared>>( + std::vector>{{0, 0}}); auto componentTypes = boost::make_shared>( 1, Mantid::Beamline::ComponentType::Generic); auto instrumentTree = boost::make_shared>>( 1, std::vector{1, 2}); // invalid - TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, - componentsInSubtree, componentRanges, - parentIndices, instrumentTree, positions, - rotations, scaleFactors, componentTypes, - names, -1, -1), - std::invalid_argument &); + TS_ASSERT_THROWS( + ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, + componentRanges, parentIndices, instrumentTree, positions, + rotations, scaleFactors, componentTypes, names, -1, -1), + std::invalid_argument &); } void test_read_positions_rotations() { diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index 6ab11126371c..8e9f11f921d6 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -100,9 +100,8 @@ class MANTID_GEOMETRY_DLL ComponentInfo { std::unique_ptr componentInfo, boost::shared_ptr> componentIds, - boost::shared_ptr< - const std::unordered_map> - componentIdToIndexMap, + boost::shared_ptr> componentIdToIndexMap, boost::shared_ptr>> shapes); ~ComponentInfo(); diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index 23eba4a44c35..809a9fe1b92a 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -261,8 +261,8 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { size_t numberOfTriangles() const; size_t numberOfVertices() const; /// for solid angle from triangulation - boost::optional &> getTriangleFaces() const; - boost::optional &> getTriangleVertices() const; + const std::vector &getTriangleFaces() const; + const std::vector &getTriangleVertices() const; /// original shape xml used to generate this object. std::string m_shapeXML; /// Optional string identifier diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 60f2df0f4d52..6ef8fe5d2d2f 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -60,10 +60,10 @@ class MANTID_GEOMETRY_DLL GeometryHandler { RectangularDetector *m_rectDet = nullptr; StructuredDetector *m_structDet = nullptr; IObjComponent *m_objComp = - nullptr; ///< ObjComponent that uses this geometry handler + nullptr; ///< ObjComponent that uses this geometry handler CSGObject *m_obj = nullptr; ///< Object that uses this geometry handler public: - GeometryHandler(IObjComponent *comp); ///< Constructor + GeometryHandler(IObjComponent *comp); ///< Constructor GeometryHandler(boost::shared_ptr obj); ///< Constructor GeometryHandler(CSGObject *obj); ///< Constructor GeometryHandler(RectangularDetector *comp); @@ -83,9 +83,9 @@ class MANTID_GEOMETRY_DLL GeometryHandler { bool hasShapeInfo() const { return !(m_shapeInfo == nullptr); } const detail::ShapeInfo &shapeInfo() const { return *m_shapeInfo; } /// Extract the vertices of the triangles - boost::optional &> getTriangleVertices(); + const std::vector & getTriangleVertices(); /// Extract the Faces of the triangles - boost::optional &> getTriangleFaces(); + const std::vector &getTriangleFaces(); /// Sets the geometry cache using the triangulation information provided void setGeometryCache(size_t nPts, size_t nFaces, std::vector &&pts, std::vector &&faces); diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index 951b3b0b6c45..91a7ffae1336 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -43,7 +43,7 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { size_t m_nPoints; std::vector m_points; ///< double array or points std::vector m_faces; ///< Integer array of faces - const Object *m_obj; ///< Input Object + const CSGObject *m_obj; ///< Input Object void checkTriangulated(); public: diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index ae12b653c3d4..7819c0529673 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -76,9 +76,8 @@ InstrumentVisitor::InstrumentVisitor( boost::make_shared>>()), m_componentRanges( boost::make_shared>>()), - m_componentIdToIndexMap( - boost::make_shared< - std::unordered_map>()), + m_componentIdToIndexMap(boost::make_shared< + std::unordered_map>()), m_detectorIdToIndexMap(makeDetIdToIndexMap(*m_orderedDetectorIds)), m_positions(boost::make_shared>()), m_detectorPositions(boost::make_shared>( @@ -339,8 +338,8 @@ InstrumentVisitor::componentInfo() const { return Kernel::make_unique( m_assemblySortedDetectorIndices, m_detectorRanges, m_assemblySortedComponentIndices, m_componentRanges, - m_parentComponentIndices, m_instrumentTree, m_positions, m_rotations, m_scaleFactors, - m_componentType, m_names, m_sourceIndex, m_sampleIndex); + m_parentComponentIndices, m_instrumentTree, m_positions, m_rotations, + m_scaleFactors, m_componentType, m_names, m_sourceIndex, m_sampleIndex); } std::unique_ptr diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 4dfd120daf5a..f9b9b31492af 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -1034,8 +1034,8 @@ double CSGObject::triangleSolidAngle(const V3D &observer) const { { return rayTraceSolidAngle(observer); } else { // Compute a generic shape that has been triangulated - const auto &vertices = this->getTriangleVertices().get(); - const auto &faces = this->getTriangleFaces().get(); + const auto &vertices = this->getTriangleVertices(); + const auto &faces = this->getTriangleFaces(); double sangle(0.0), sneg(0.0); for (size_t i = 0; i < nTri; i++) { int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2]; @@ -1115,8 +1115,8 @@ double CSGObject::triangleSolidAngle(const V3D &observer, // return rayTraceSolidAngle(observer); // so is this } - const auto &vertices = this->getTriangleVertices().get(); - const auto &faces = this->getTriangleFaces().get(); + const auto &vertices = this->getTriangleVertices(); + const auto &faces = this->getTriangleFaces(); double sangle(0.0), sneg(0.0); for (size_t i = 0; i < nTri; i++) { int p1 = faces[i * 3], p2 = faces[i * 3 + 1], p3 = faces[i * 3 + 2]; @@ -1711,7 +1711,7 @@ void CSGObject::calcBoundingBoxByVertices() { auto vertCount = this->numberOfVertices(); if (vertCount > 0) { - const auto &vertArray = this->getTriangleVertices().get(); + const auto &vertArray = this->getTriangleVertices(); // Unreasonable extents to be overwritten by loop constexpr double huge = 1e10; double minX, maxX, minY, maxY, minZ, maxZ; @@ -2137,19 +2137,14 @@ size_t CSGObject::numberOfVertices() const { /** * get vertices */ -boost::optional &> -CSGObject::getTriangleVertices() const { - if (handle == nullptr) - return boost::none; +const std::vector &CSGObject::getTriangleVertices() const { return m_handler->getTriangleVertices(); } /** -* get faces -*/ -boost::optional &> CSGObject::getTriangleFaces() const { - if (handle == nullptr) - return boost::none; + * get faces + */ +const std::vector &CSGObject::getTriangleFaces() const { return m_handler->getTriangleFaces(); } @@ -2157,8 +2152,8 @@ boost::optional &> CSGObject::getTriangleFaces() const { * get info on standard shapes */ void Object::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, - std::vector &vectors, double &myradius, - double &myheight) const { + std::vector &vectors, + double &myradius, double &myheight) const { type = detail::ShapeInfo::GeometryShape::NOSHAPE; if (m_handler == nullptr) return; diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 50aa30d00766..116cfdcfffb2 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -79,17 +79,18 @@ size_t GeometryHandler::numberOfPoints() { return 0; } -boost::optional &> -GeometryHandler::getTriangleVertices() { +const std::vector &GeometryHandler::getTriangleVertices() { + static std::vector empty; if (canTriangulate()) return m_triangulator->getTriangleVertices(); - return boost::none; + return empty; } -boost::optional &> GeometryHandler::getTriangleFaces() { +const std::vector &GeometryHandler::getTriangleFaces() { + static std::vector empty; if (canTriangulate()) return m_triangulator->getTriangleFaces(); - return boost::none; + return empty; } void GeometryHandler::setGeometryCache(size_t nPts, size_t nFaces, diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index 90800ead8f49..dbd6ecf5eec6 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -441,8 +441,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(instrScaling, compInfo->scaleFactor(compInfo->root())); } - void test_instrumentTreeWithMinimalInstrument() - { + void test_instrumentTreeWithMinimalInstrument() { /** This should produce the following instrument tree * 3 * / | \ @@ -462,8 +461,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(componentInfo->children(root).size(), 3); } - void test_instrumentTreeWithComplexInstrument() - { + void test_instrumentTreeWithComplexInstrument() { /** This should produce the following instrument tree * 16 * / / \ \ diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index b87dd4283526..3a1194ef949a 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -44,7 +44,7 @@ interface for picked ObjComponent and other operation for selective rendering of the instrument */ -class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor: public QObject { +class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { Q_OBJECT public: /// Constructor @@ -130,7 +130,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor: public QObject { bool wholeRange() const; /// Get the number of detectors in the instrument. - size_t ndetectors() const;// { return m_detIDs.size(); } + size_t ndetectors() const; // { return m_detIDs.size(); } /// Get a detector index by a detector ID. size_t getDetectorByDetID(Mantid::detid_t detID) const; /// Get a detector ID by a pick ID converted form a color in the pick image. @@ -282,14 +282,14 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor: public QObject { /// Colour of a "failed" detector GLColor m_failedColor; /// The collection of actors for the instrument components - //GLActorCollection m_scene; + // GLActorCollection m_scene; static double m_tolerance; - + std::vector m_pickColors; std::vector m_isCompVisible; - //Two display lists for normal rendering and picking + // Two display lists for normal rendering and picking mutable GLuint m_displayListId[2]; mutable bool m_useDisplayList[2]; }; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h index d714c99efd73..86d54b58d767 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h @@ -34,6 +34,7 @@ class InstrumentTreeModel : public QAbstractItemModel { int rowCount(const QModelIndex &paren = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; static size_t extractIndex(const QModelIndex &index); + private: /// instrument widget to which the model corresponds const InstrumentWidget *m_instrWidget; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h index 2bafb29666d5..56542a27e0f0 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h @@ -54,7 +54,7 @@ class PanelsSurface : public UnwrappedSurface { protected: boost::optional, Mantid::Kernel::V3D>> findFlatPanels(size_t rootIndex, const std::vector &children, - std::vector &visited); + std::vector &visited); void processStructured(const std::vector &children, size_t rootIndex); diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h index 0ef007192897..d2c14e63edba 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h @@ -31,13 +31,13 @@ class UnwrappedDetector { UnwrappedDetector(GLColor color, size_t detIndex); UnwrappedDetector(const UnwrappedDetector &other); UnwrappedDetector &operator=(const UnwrappedDetector &other); - GLColor color; ///< red, green, blue colour components (0 - 255) - double u; ///< horizontal "unwrapped" coordinate - double v; ///< vertical "unwrapped" coordinate - double width; ///< detector width in units of u - double height; ///< detector height in units of v - double uscale; ///< scaling factor in u direction - double vscale; ///< scaling factor in v direction + GLColor color; ///< red, green, blue colour components (0 - 255) + double u; ///< horizontal "unwrapped" coordinate + double v; ///< vertical "unwrapped" coordinate + double width; ///< detector width in units of u + double height; ///< detector height in units of v + double uscale; ///< scaling factor in u direction + double vscale; ///< scaling factor in v direction size_t detIndex; ///< Detector Index in ComponentInfo/DetectorInfo. }; } // namespace MantidWidgets diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 1d1932f8e0a9..71b2ae715ef1 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -98,9 +98,8 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, // If the instrument is empty, maybe only having the sample and source auto nelements = componentInfo.size(); - if ((nelements == 0) || - (nelements == 1 && - (componentInfo.hasSource() || componentInfo.hasSample())) || + if ((nelements == 0) || (nelements == 1 && (componentInfo.hasSource() || + componentInfo.hasSample())) || (nelements == 2 && componentInfo.hasSource() && componentInfo.hasSample())) { QMessageBox::warning(nullptr, "MantidPlot - Warning", @@ -122,8 +121,7 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, /** * Destructor */ -InstrumentActor::~InstrumentActor() -{ +InstrumentActor::~InstrumentActor() { for (size_t i = 0; i < 2; ++i) { if (m_displayListId[i] != 0) { glDeleteLists(m_displayListId[i], 1); @@ -685,8 +683,7 @@ void InstrumentActor::updateColors() { /** * @param on :: True or false for on or off. */ -void InstrumentActor::showGuides(bool on) -{ +void InstrumentActor::showGuides(bool on) { m_showGuides = on; invalidateDisplayLists(); } @@ -735,12 +732,12 @@ void InstrumentActor::doDraw(bool picking) const { else m_colors[i].paint(); glPushMatrix(); - //Translate + // Translate auto pos = componentInfo.position(i); - if(!pos.nullVector()) + if (!pos.nullVector()) glTranslated(pos[0], pos[1], pos[2]); - - //Rotate + + // Rotate auto rot = componentInfo.rotation(i); if (!rot.isNull()) { double deg, ax0, ax1, ax2; @@ -748,16 +745,16 @@ void InstrumentActor::doDraw(bool picking) const { glRotated(deg, ax0, ax1, ax2); } - //Scale + // Scale auto scale = componentInfo.scaleFactor(i); - if(scale != Kernel::V3D(1, 1, 1)) + if (scale != Kernel::V3D(1, 1, 1)) glScaled(scale[0], scale[1], scale[2]); - + if (m_volumeRender) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - + componentInfo.shape(i).draw(); glPopMatrix(); } @@ -801,8 +798,7 @@ const Mantid::Kernel::V3D InstrumentActor::getDetPos(size_t pickID) const { return m_defaultPos; } -const std::vector &InstrumentActor::getAllDetIDs() const -{ +const std::vector &InstrumentActor::getAllDetIDs() const { const auto &detInfo = getDetectorInfo(); return detInfo.detectorIDs(); } @@ -1254,8 +1250,8 @@ QString InstrumentActor::getParameterInfo(size_t index) const { auto id = paramComp->getComponentID(); auto &compParamNames = mapCmptToNameVector[id]; if (compParamNames.size() > 0) { - text += QString::fromStdString( - "\nParameters from: " + paramComp->getName() + "\n"); + text += QString::fromStdString("\nParameters from: " + + paramComp->getName() + "\n"); std::sort(compParamNames.begin(), compParamNames.end(), Mantid::Kernel::CaseInsensitiveStringComparator()); for (auto itParamName = compParamNames.begin(); diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 0715c45392c0..7660f2c2f18d 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -1341,7 +1341,7 @@ void DetectorPlotController::prepareDataForSumsPlot(int detid, err->resize(x.size(), 0); const auto &detectorInfo = actor.getDetectorInfo(); - for (auto det: ass) { + for (auto det : ass) { if (componentInfo.isDetector(det)) { try { size_t index = actor.getWorkspaceIndex(detectorInfo.detectorIDs()[det]); @@ -1441,7 +1441,7 @@ void DetectorPlotController::prepareDataForIntegralsPlot( auto normal = componentInfo.position(ass[1]) - componentInfo.position(ass[0]); normal.normalize(); const auto &detectorInfo = actor.getDetectorInfo(); - for (auto det: ass) { + for (auto det : ass) { if (componentInfo.isDetector(det)) { try { auto id = detectorInfo.detectorIDs()[det]; @@ -1449,8 +1449,8 @@ void DetectorPlotController::prepareDataForIntegralsPlot( double xvalue = 0; switch (m_tubeXUnits) { case LENGTH: - xvalue = detectorInfo.position(det).distance( - detectorInfo.position(ass[0])); + xvalue = detectorInfo.position(det) + .distance(detectorInfo.position(ass[0])); break; case PHI: xvalue = bOffsetPsi ? detectorInfo.getPhiOffset(det, M_PI) diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp index 9da9f43d00a8..606959305209 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp @@ -144,7 +144,8 @@ InstrumentWidgetRenderTab::InstrumentWidgetRenderTab( m_volumeRender = new QAction("VolumeRender", this); m_volumeRender->setCheckable(true); m_volumeRender->setChecked(false); - connect(m_volumeRender, SIGNAL(toggled(bool)), this, SLOT(showVolumeRender(bool))); + connect(m_volumeRender, SIGNAL(toggled(bool)), this, + SLOT(showVolumeRender(bool))); m_displayDetectorsOnly = new QAction("Display Detectors Only", this); m_displayDetectorsOnly->setCheckable(true); m_displayDetectorsOnly->setChecked(true); @@ -448,8 +449,7 @@ void InstrumentWidgetRenderTab::showAxes(bool on) { m_displayAxes->blockSignals(false); } -void InstrumentWidgetRenderTab::showVolumeRender(bool on) -{ +void InstrumentWidgetRenderTab::showVolumeRender(bool on) { m_instrWidget->getInstrumentActor().showVolumeRender(on); m_volumeRender->blockSignals(true); m_volumeRender->setChecked(on); diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index dcb9ef1f3bc4..e530286e082a 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -72,8 +72,8 @@ namespace MantidWidgets { * @param s The surface of the panel */ FlatBankInfo::FlatBankInfo(PanelsSurface *s) - : rotation(), startDetectorIndex(0), endDetectorIndex(0), - polygon(), surface(s) {} + : rotation(), startDetectorIndex(0), endDetectorIndex(0), polygon(), + surface(s) {} /** * Translate the bank by a vector. @@ -163,7 +163,7 @@ void PanelsSurface::setupAxes() { * Add a flat bank from an assembly of detectors. * @param bankId :: Component ID of the bank. * @param normal :: Normal vector to the bank's plane. -* @param detectors :: List of detectorIndices. +* @param detectors :: List of detectorIndices. */ void PanelsSurface::addFlatBankOfDetectors( const Mantid::Kernel::V3D &normal, const std::vector &detectors) { @@ -307,9 +307,9 @@ void PanelsSurface::constructFromComponentInfo() { const auto &componentInfo = m_instrActor->getComponentInfo(); std::vector visited(componentInfo.size(), false); - for (size_t i = 0; i < componentInfo.size()-1; ++i) { + for (size_t i = 0; i < componentInfo.size() - 1; ++i) { auto children = componentInfo.detectorsInSubtree(i); - + if (children.size() > 1) { auto res = findFlatPanels(i, children, visited); if (res != boost::none) { diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index e920c9acc202..aa6b2e96e858 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -96,7 +96,8 @@ void RotationSurface::init() { auto pos = detectorInfo.position(i); auto rot = detectorInfo.rotation(i); - auto scaleFactor = componentInfo.scaleFactor(i); + auto scaleFactor = + componentInfo.scaleFactor(i); // Create the unwrapped shape UnwrappedDetector udet( m_instrActor->getColor(i), i); @@ -221,7 +222,7 @@ void RotationSurface::findAndCorrectUGap() { return; } - for (const auto &udet: m_unwrappedDetectors) { + for (const auto &udet : m_unwrappedDetectors) { if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) continue; double u = udet.u; @@ -258,7 +259,7 @@ void RotationSurface::findAndCorrectUGap() { m_u_max += period; } - for (auto &udet: m_unwrappedDetectors) { + for (auto &udet : m_unwrappedDetectors) { if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) continue; double &u = udet.u; diff --git a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp index 1f9ea142d499..44db7b3761ec 100644 --- a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp @@ -12,10 +12,9 @@ UnwrappedDetector::UnwrappedDetector() color = GLColor(0, 0, 0); } -UnwrappedDetector::UnwrappedDetector(GLColor color, - size_t detIndex) +UnwrappedDetector::UnwrappedDetector(GLColor color, size_t detIndex) : u(0), v(0), width(0), height(0), uscale(0), vscale(0), - detIndex(detIndex){ + detIndex(detIndex) { this->color = color; } diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 84229d3409de..86f114e1843c 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -38,10 +38,10 @@ QRectF getArea(const UnwrappedDetector &udet, double maxWidth, return QRectF(udet.u - w, udet.v - h, w * 2, h * 2); } } // namespace -/** - * Constructor. - * @param rootActor :: The instrument actor. - */ + /** + * Constructor. + * @param rootActor :: The instrument actor. + */ UnwrappedSurface::UnwrappedSurface(const InstrumentActor *rootActor) : ProjectionSurface(rootActor), m_u_min(DBL_MAX), m_u_max(-DBL_MAX), m_v_min(DBL_MAX), m_v_max(-DBL_MAX), m_height_max(0), m_width_max(0), @@ -140,7 +140,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { } const auto &componentInfo = m_instrActor->getComponentInfo(); - for (const auto &udet: m_unwrappedDetectors) { + for (const auto &udet : m_unwrappedDetectors) { if (!componentInfo.hasShape(udet.detIndex)) continue; From e3fecc939cd280c3115d8b5f5494ce18d74dd86f Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 10 Jan 2018 11:18:53 +0000 Subject: [PATCH 038/364] clang format #21339 --- .../Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 6ef8fe5d2d2f..4a576795a6fd 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -83,7 +83,7 @@ class MANTID_GEOMETRY_DLL GeometryHandler { bool hasShapeInfo() const { return !(m_shapeInfo == nullptr); } const detail::ShapeInfo &shapeInfo() const { return *m_shapeInfo; } /// Extract the vertices of the triangles - const std::vector & getTriangleVertices(); + const std::vector &getTriangleVertices(); /// Extract the Faces of the triangles const std::vector &getTriangleFaces(); /// Sets the geometry cache using the triangulation information provided From 0280ba84982fbde8a4e93797103ef4fdbebfef93 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 10 Jan 2018 12:28:11 +0000 Subject: [PATCH 039/364] remove unused variable #21339 --- qt/widgets/instrumentview/src/PanelsSurface.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index e530286e082a..27192c9cf1f4 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -357,7 +357,6 @@ void PanelsSurface::addDetector(size_t detIndex, const Mantid::Kernel::V3D &refPos, int index, Mantid::Kernel::Quat &rotation) { const auto &detectorInfo = m_instrActor->getDetectorInfo(); - const auto &componentInfo = m_instrActor->getComponentInfo(); Mantid::Kernel::V3D pos = detectorInfo.position(detIndex); m_detector2bankMap[detIndex] = index; From 17b9de06c5c4a28174af4bd1a7075389bcb20d2f Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 10 Jan 2018 13:08:56 +0000 Subject: [PATCH 040/364] Cache writer fix after removing boost::optional #21339 --- Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp index b4712493d435..99f82f472824 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp @@ -110,7 +110,7 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { pPtsDataArray->setAttribute("format", "ascii"); buf.str(""); // get the triangles info - const auto &points = handle->getTriangleVertices().get(); + const auto &points = handle->getTriangleVertices(); size_t i; for (i = 0; i < points.size(); i++) { buf << points[i] << " "; @@ -127,7 +127,7 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { pTrisDataArray->setAttribute("format", "ascii"); buf.str(""); - const auto &faces = handle->getTriangleFaces().get(); + const auto &faces = handle->getTriangleFaces(); for (i = 0; i < faces.size(); i++) { buf << faces[i] << " "; } From ed8f030235251300c948a1543be2cf2438779b8b Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 11 Jan 2018 10:50:38 +0000 Subject: [PATCH 041/364] review changes and fix unit tests #21339 --- .../inc/MantidBeamline/ComponentInfo.h | 39 +++-- Framework/Beamline/src/ComponentInfo.cpp | 28 +-- Framework/Beamline/test/ComponentInfoTest.h | 83 ++++----- .../MantidGeometry/Instrument/DetectorInfo.h | 2 - .../Instrument/InstrumentVisitor.h | 3 +- .../Geometry/src/Instrument/ComponentInfo.cpp | 27 +-- .../Geometry/src/Instrument/DetectorInfo.cpp | 12 -- .../src/Instrument/InstrumentVisitor.cpp | 17 +- Framework/Geometry/test/ComponentInfoTest.h | 43 ++++- .../Geometry/test/InstrumentVisitorTest.h | 4 +- Framework/Geometry/test/ObjCompAssemblyTest.h | 36 ++++ .../Geometry/test/ParObjCompAssemblyTest.h | 45 +++++ .../instrumentview/src/InstrumentActor.cpp | 11 +- .../src/InstrumentTreeModel.cpp | 162 +++++++----------- .../src/InstrumentWidgetPickTab.cpp | 24 ++- 15 files changed, 309 insertions(+), 227 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index f0946bba6776..95b6185070b1 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -52,7 +52,8 @@ class MANTID_BEAMLINE_DLL ComponentInfo { boost::shared_ptr>> m_componentRanges; boost::shared_ptr> m_parentIndices; - boost::shared_ptr>> m_instrumentTree; + boost::shared_ptr>> + m_assemblyImmediateChildren; Mantid::Kernel::cow_ptr> m_positions; Mantid::Kernel::cow_ptr>> @@ -89,28 +90,28 @@ class MANTID_BEAMLINE_DLL ComponentInfo { public: ComponentInfo(); - ComponentInfo( - boost::shared_ptr> - assemblySortedDetectorIndices, - boost::shared_ptr>> - detectorRanges, - boost::shared_ptr> - assemblySortedComponentIndices, - boost::shared_ptr>> - componentRanges, - boost::shared_ptr> parentIndices, - boost::shared_ptr>> instrumentTree, - boost::shared_ptr> positions, - boost::shared_ptr> rotations, - boost::shared_ptr> scaleFactors, - boost::shared_ptr> componentType, - boost::shared_ptr> names, - int64_t sourceIndex, int64_t sampleIndex); + ComponentInfo(boost::shared_ptr> + assemblySortedDetectorIndices, + boost::shared_ptr>> + detectorRanges, + boost::shared_ptr> + assemblySortedComponentIndices, + boost::shared_ptr>> + componentRanges, + boost::shared_ptr> parentIndices, + boost::shared_ptr>> + assemblyImmediateChildren, + boost::shared_ptr> positions, + boost::shared_ptr> rotations, + boost::shared_ptr> scaleFactors, + boost::shared_ptr> componentType, + boost::shared_ptr> names, + int64_t sourceIndex, int64_t sampleIndex); /// Copy assignment not permitted because of the way DetectorInfo stored ComponentInfo &operator=(const ComponentInfo &other) = delete; /// Clone method std::unique_ptr cloneWithoutDetectorInfo() const; - std::vector detectorsInSubtree(const size_t componentIndex) const; + std::vector detectorsInFullSubtree(const size_t componentIndex) const; std::vector componentsInSubtree(const size_t componentIndex) const; const std::vector &children(const size_t componentIndex) const; size_t size() const; diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index a729b691a3bf..9b3424ed6b14 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -38,7 +38,8 @@ ComponentInfo::ComponentInfo( boost::shared_ptr>> componentRanges, boost::shared_ptr> parentIndices, - boost::shared_ptr>> instrumentTree, + boost::shared_ptr>> + assemblyImmediateChildren, boost::shared_ptr> positions, boost::shared_ptr>> @@ -53,7 +54,7 @@ ComponentInfo::ComponentInfo( m_detectorRanges(std::move(detectorRanges)), m_componentRanges(std::move(componentRanges)), m_parentIndices(std::move(parentIndices)), - m_instrumentTree(std::move(instrumentTree)), + m_assemblyImmediateChildren(std::move(assemblyImmediateChildren)), m_positions(std::move(positions)), m_rotations(std::move(rotations)), m_scaleFactors(std::move(scaleFactors)), m_componentType(std::move(componentType)), m_names(std::move(names)), @@ -95,11 +96,11 @@ ComponentInfo::ComponentInfo( "of names as number of components"); } - size_t treeSize = 1; // initialize with root - for (const auto &assem : *m_instrumentTree) - treeSize += assem.size(); + size_t assemTotalSize = 1; // initialize with root + for (const auto &assem : *m_assemblyImmediateChildren) + assemTotalSize += assem.size(); - if (treeSize != m_size) { + if (assemTotalSize != m_size) { throw std::invalid_argument("ComponentInfo should be provided an " "instrument tree which contains same number " "components"); @@ -113,7 +114,7 @@ std::unique_ptr ComponentInfo::cloneWithoutDetectorInfo() const { } std::vector -ComponentInfo::detectorsInSubtree(const size_t componentIndex) const { +ComponentInfo::detectorsInFullSubtree(const size_t componentIndex) const { if (isDetector(componentIndex)) { /* This is a single detector. Just return the corresponding index. * detectorIndex == componentIndex @@ -155,12 +156,13 @@ ComponentInfo::componentsInSubtree(const size_t componentIndex) const { const std::vector & ComponentInfo::children(const size_t componentIndex) const { static std::vector emptyVec; - auto dets = detectorRangeInSubtree(root()); - auto numDets = static_cast(std::distance(dets.begin(), dets.end())); - auto index = componentIndex - numDets; - if (index < m_instrumentTree->size()) - return (*m_instrumentTree)[index]; + if (!isDetector(componentIndex)) { + auto numDets = m_assemblySortedDetectorIndices->size(); + auto index = componentIndex - numDets; + + return (*m_assemblyImmediateChildren)[index]; + } return emptyVec; } @@ -326,7 +328,7 @@ void ComponentInfo::setPosition(const size_t componentIndex, if (isDetector(componentIndex)) return m_detectorInfo->setPosition(componentIndex, newPosition); - // Optimization: Not using detectorsInSubtree and componentsInSubtree to avoid + // Optimization: Not using detectorsInFullSubtree and componentsInSubtree to avoid // memory allocations. // Optimization: Split loop over detectors and other components. const auto detectorRange = detectorRangeInSubtree(componentIndex); diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 4243358fd223..b43fcc572299 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -68,7 +68,7 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) { std::vector children(detPositions.size()); std::iota(children.begin(), children.end(), 0); - auto instrumentTree = + auto assemblyImmediateChildren = boost::make_shared>>(1, children); auto componentInfo = boost::make_shared( @@ -78,8 +78,8 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, instrumentTree, positions, rotations, scaleFactors, - isRectangularBank, names, -1, -1); + parentIndices, assemblyImmediateChildren, positions, rotations, + scaleFactors, isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -146,8 +146,9 @@ makeTreeExampleAndReturnGeometricArguments() { // Rectangular bank flag auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); - auto instrumentTree = boost::make_shared>>( - 2, std::vector(2)); + auto assemblyImmediateChildren = + boost::make_shared>>( + 2, std::vector(2)); auto compInfo = boost::make_shared( bankSortedDetectorIndices, @@ -156,8 +157,8 @@ makeTreeExampleAndReturnGeometricArguments() { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, instrumentTree, compPositions, compRotations, scaleFactors, - isRectangularBank, names, -1, -1); + parentIndices, assemblyImmediateChildren, compPositions, compRotations, + scaleFactors, isRectangularBank, names, -1, -1); compInfo->setDetectorInfo(detectorInfo.get()); @@ -215,8 +216,9 @@ makeTreeExample() { auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); - auto instrumentTree = boost::make_shared>>( - 2, std::vector(2)); + auto assemblyImmediateChildren = + boost::make_shared>>( + 2, std::vector(2)); auto componentInfo = boost::make_shared( bankSortedDetectorIndices, @@ -225,8 +227,8 @@ makeTreeExample() { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, instrumentTree, positions, rotations, scaleFactors, - isRectangularBank, names, -1, -1); + parentIndices, assemblyImmediateChildren, positions, rotations, + scaleFactors, isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -294,18 +296,19 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto componentRanges = boost::make_shared>>( std::vector>{}); - auto positions = boost::make_shared(); - auto rotations = boost::make_shared(); - auto scaleFactors = boost::make_shared(3); - auto names = boost::make_shared(3); - auto isRectangularBank = boost::make_shared>(); - auto instrumentTree = boost::make_shared>>( - 1, std::vector(3)); + auto positions = boost::make_shared(1); + auto rotations = boost::make_shared(1); + auto scaleFactors = boost::make_shared(4); + auto names = boost::make_shared(4); + auto isRectangularBank = boost::make_shared>(1); + auto assemblyImmediateChildren = + boost::make_shared>>( + 1, std::vector(3)); ComponentInfo componentInfo( bankSortedDetectorIndices, detectorRanges, bankSortedComponentIndices, - componentRanges, parentIndices, instrumentTree, positions, rotations, - scaleFactors, isRectangularBank, names, -1, -1); + componentRanges, parentIndices, assemblyImmediateChildren, positions, + rotations, scaleFactors, isRectangularBank, names, -1, -1); DetectorInfo detectorInfo; // Detector info size 0 TS_ASSERT_THROWS(componentInfo.setDetectorInfo(&detectorInfo), @@ -340,14 +343,14 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto names = boost::make_shared(); auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); - auto instrumentTree = boost::make_shared< + auto assemblyImmediateChildren = boost::make_shared< std::vector>>(); // invalid but not being tested TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, bankSortedComponentIndices, componentRanges, - parentIndices, instrumentTree, positions, - rotations, scaleFactors, isRectangularBank, - names, -1, -1), + parentIndices, assemblyImmediateChildren, + positions, rotations, scaleFactors, + isRectangularBank, names, -1, -1), std::invalid_argument &); } @@ -383,12 +386,12 @@ class ComponentInfoTest : public CxxTest::TestSuite { std::vector>{{0, 0}}); auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); - auto instrumentTree = boost::make_shared< + auto assemblyImmediateChildren = boost::make_shared< std::vector>>(); // invalid but not being tested TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, componentRanges, - parentIndices, instrumentTree, positions, + parentIndices, assemblyImmediateChildren, positions, rotations, scaleFactors, isRectangularBank, names, -1, -1), std::invalid_argument &); @@ -428,14 +431,16 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto componentTypes = boost::make_shared>( 1, Mantid::Beamline::ComponentType::Generic); - auto instrumentTree = boost::make_shared>>( - 1, std::vector{1, 2}); // invalid - - TS_ASSERT_THROWS( - ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, - componentRanges, parentIndices, instrumentTree, positions, - rotations, scaleFactors, componentTypes, names, -1, -1), - std::invalid_argument &); + auto assemblyImmediateChildren = + boost::make_shared>>( + 1, std::vector{1, 2}); // invalid + + TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, + componentsInSubtree, componentRanges, + parentIndices, assemblyImmediateChildren, + positions, rotations, scaleFactors, + componentTypes, names, -1, -1), + std::invalid_argument &); } void test_read_positions_rotations() { @@ -628,15 +633,15 @@ class ComponentInfoTest : public CxxTest::TestSuite { /* Note that detectors are always the first n component indexes! */ - TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(0), std::vector{0}); - TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(1), std::vector{1}); - TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(2), std::vector{2}); + TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(0), std::vector{0}); + TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(1), std::vector{1}); + TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(2), std::vector{2}); // Now we have non-detector components - TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(4 /*component index of root*/), + TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(4 /*component index of root*/), std::vector({0, 2, 1})); TS_ASSERT_EQUALS( - compInfo.detectorsInSubtree(3 /*component index of sub-assembly*/), + compInfo.detectorsInFullSubtree(3 /*component index of sub-assembly*/), std::vector({0, 2})); } diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h index f8cfc21eff72..18924dc6f9c4 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorInfo.h @@ -90,8 +90,6 @@ class MANTID_GEOMETRY_DLL DetectorInfo { double twoTheta(const std::pair &index) const; double signedTwoTheta(const size_t index) const; double signedTwoTheta(const std::pair &index) const; - double getPhi(const size_t index) const; - double getPhiOffset(const size_t index, const double offset) const; Kernel::V3D position(const size_t index) const; Kernel::V3D position(const std::pair &index) const; Kernel::Quat rotation(const size_t index) const; diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h index 22d8ca0fbabf..2b2259b1fbc7 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h @@ -79,7 +79,8 @@ class MANTID_GEOMETRY_DLL InstrumentVisitor boost::shared_ptr> m_parentComponentIndices; /// Stores instrument tree structure by storing children of all Components - boost::shared_ptr>> m_instrumentTree; + boost::shared_ptr>> + m_assemblyImmediateChildren; /// Only Assemblies and other NON-detectors yield detector ranges boost::shared_ptr>> m_detectorRanges; diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index 6a5ee8909878..f47b099ab99b 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -99,7 +99,7 @@ ComponentInfo::~ComponentInfo() = default; std::vector ComponentInfo::detectorsInSubtree(size_t componentIndex) const { - return m_componentInfo->detectorsInSubtree(componentIndex); + return m_componentInfo->detectorsInFullSubtree(componentIndex); } std::vector @@ -293,27 +293,18 @@ void ComponentInfo::growBoundingBoxAsRectuangularBank( Geometry::BoundingBox &mutableBB, std::map &mutableDetExclusions, IteratorT &mutableIterator) const { - const auto innerRangeComp = m_componentInfo->componentRangeInSubtree(index); - const auto innerRangeDet = m_componentInfo->detectorRangeInSubtree(index); - // subtract 1 because component ranges includes self - auto nSubComponents = innerRangeComp.end() - innerRangeComp.begin() - 1; - auto nSubDetectors = - std::distance(innerRangeDet.begin(), innerRangeDet.end()); - auto nY = nSubDetectors / nSubComponents; - size_t bottomLeft = *innerRangeDet.begin(); - size_t topRight = bottomLeft + nSubDetectors - 1; - size_t topLeft = bottomLeft + (nY - 1); - size_t bottomRight = topRight - (nY - 1); - - mutableBB.grow(componentBoundingBox(bottomLeft, reference)); - mutableBB.grow(componentBoundingBox(topRight, reference)); - mutableBB.grow(componentBoundingBox(topLeft, reference)); - mutableBB.grow(componentBoundingBox(bottomRight, reference)); + + auto panel = structuredPanel(index); + mutableBB.grow(componentBoundingBox(panel.bottomLeft, reference)); + mutableBB.grow(componentBoundingBox(panel.topRight, reference)); + mutableBB.grow(componentBoundingBox(panel.topLeft, reference)); + mutableBB.grow(componentBoundingBox(panel.bottomRight, reference)); // Get bounding box for rectangular bank. // Record detector ranges to skip - mutableDetExclusions.insert(std::make_pair(bottomLeft, topRight)); + mutableDetExclusions.insert(std::make_pair(panel.bottomLeft, panel.topRight)); // Skip all sub components. + const auto innerRangeComp = m_componentInfo->componentRangeInSubtree(index); mutableIterator = innerRangeComp.rend(); } diff --git a/Framework/Geometry/src/Instrument/DetectorInfo.cpp b/Framework/Geometry/src/Instrument/DetectorInfo.cpp index a31bf27e3a88..d2b98326e484 100644 --- a/Framework/Geometry/src/Instrument/DetectorInfo.cpp +++ b/Framework/Geometry/src/Instrument/DetectorInfo.cpp @@ -231,18 +231,6 @@ DetectorInfo::signedTwoTheta(const std::pair &index) const { return angle; } -double DetectorInfo::getPhi(const size_t index) const { - const Kernel::V3D pos = position(index); - return std::atan2(pos[1], pos[0]); -} - -/// Calculate the phi angle between detector and beam, and then offset. -double DetectorInfo::getPhiOffset(const size_t index, - const double offset) const { - double avgPos = getPhi(index); - return avgPos < 0 ? -(offset + avgPos) : offset - avgPos; -} - /// Returns the position of the detector with given index. Kernel::V3D DetectorInfo::position(const size_t index) const { return Kernel::toV3D(m_detectorInfo->position(index)); diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index 7819c0529673..a26768d13de0 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -71,13 +71,15 @@ InstrumentVisitor::InstrumentVisitor( boost::make_shared>()), m_parentComponentIndices(boost::make_shared>( m_orderedDetectorIds->size(), 0)), - m_instrumentTree(boost::make_shared>>()), + m_assemblyImmediateChildren( + boost::make_shared>>()), m_detectorRanges( boost::make_shared>>()), m_componentRanges( boost::make_shared>>()), - m_componentIdToIndexMap(boost::make_shared< - std::unordered_map>()), + m_componentIdToIndexMap( + boost::make_shared< + std::unordered_map>()), m_detectorIdToIndexMap(makeDetIdToIndexMap(*m_orderedDetectorIds)), m_positions(boost::make_shared>()), m_detectorPositions(boost::make_shared>( @@ -179,7 +181,7 @@ InstrumentVisitor::registerComponentAssembly(const ICompAssembly &assembly) { for (const auto &child : children) { (*m_parentComponentIndices)[child] = componentIndex; } - m_instrumentTree->emplace_back(std::move(children)); + m_assemblyImmediateChildren->emplace_back(std::move(children)); return componentIndex; } @@ -207,7 +209,7 @@ InstrumentVisitor::registerGenericComponent(const IComponent &component) { // Unless this is the root component this parent is not correct and will be // updated later in the register call of the parent. m_parentComponentIndices->push_back(componentIndex); - m_instrumentTree->emplace_back(std::vector()); + m_assemblyImmediateChildren->emplace_back(std::vector()); return componentIndex; } @@ -338,8 +340,9 @@ InstrumentVisitor::componentInfo() const { return Kernel::make_unique( m_assemblySortedDetectorIndices, m_detectorRanges, m_assemblySortedComponentIndices, m_componentRanges, - m_parentComponentIndices, m_instrumentTree, m_positions, m_rotations, - m_scaleFactors, m_componentType, m_names, m_sourceIndex, m_sampleIndex); + m_parentComponentIndices, m_assemblyImmediateChildren, m_positions, + m_rotations, m_scaleFactors, m_componentType, m_names, m_sourceIndex, + m_sampleIndex); } std::unique_ptr diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index f3530b6cf6a2..86944db9730b 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -109,11 +109,12 @@ std::unique_ptr makeSingleBeamlineComponentInfo( using Mantid::Beamline::ComponentType; auto isStructuredBank = boost::make_shared>(1, ComponentType::Generic); - auto instrumentTree = boost::make_shared>>(1); + auto assemblyImmediateChildren = + boost::make_shared>>(1); return Kernel::make_unique( detectorIndices, detectorRanges, componentIndices, componentRanges, - parentIndices, instrumentTree, positions, rotations, scaleFactors, - isStructuredBank, names, -1, -1); + parentIndices, assemblyImmediateChildren, positions, rotations, + scaleFactors, isStructuredBank, names, -1, -1); } } // namespace @@ -157,12 +158,13 @@ class ComponentInfoTest : public CxxTest::TestSuite { using Mantid::Beamline::ComponentType; auto isRectBank = boost::make_shared>( 2, ComponentType::Generic); - auto instrumentTree = boost::make_shared>>( - 1, std::vector(1)); + auto assemblyImmediateChildren = + boost::make_shared>>( + 1, std::vector(1)); auto internalInfo = Kernel::make_unique( detectorIndices, detectorRanges, componentIndices, componentRanges, - parentIndices, instrumentTree, positions, rotations, scaleFactors, - isRectBank, names, -1, -1); + parentIndices, assemblyImmediateChildren, positions, rotations, + scaleFactors, isRectBank, names, -1, -1); Mantid::Geometry::ObjComponent comp1("component1"); Mantid::Geometry::ObjComponent comp2("component2"); @@ -650,6 +652,33 @@ class ComponentInfoTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(infoScan1->position({0 /*detector index*/, 1}), detectorPos); } + + void test_StructuredPanel_for_single_rectangular_bank() { + auto instrument = + ComponentCreationHelper::createTestInstrumentRectangular2(1, 4); + auto wrappers = InstrumentVisitor::makeWrappers(*instrument); + const auto &componentInfo = std::get<0>(wrappers); + + // find structured panel + size_t structuredIndex = 0; + for (size_t i = componentInfo->root(); i >= 0; --i) { + if (componentInfo->componentType(i) == + Mantid::Beamline::ComponentType::Structured || + componentInfo->componentType(i) == + Mantid::Beamline::ComponentType::Rectangular) { + structuredIndex = i; + break; + } + } + + auto panel = componentInfo->structuredPanel(structuredIndex); + TS_ASSERT_EQUALS(panel.nX, 4); + TS_ASSERT_EQUALS(panel.nY, 4); + TS_ASSERT_EQUALS(panel.bottomLeft, 0); + TS_ASSERT_EQUALS(panel.bottomRight, 12); + TS_ASSERT_EQUALS(panel.topLeft, 3); + TS_ASSERT_EQUALS(panel.topRight, 15); + } }; #endif /* MANTID_GEOMETRY_COMPONENTINFOTEST_H_ */ diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index dbd6ecf5eec6..f5d948ce8952 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -165,7 +165,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { TSM_ASSERT_EQUALS("Detector has parent of instrument", compInfo->parent(detectorIndex), instrumentIndex); TSM_ASSERT_EQUALS("Instrument has single detector", - compInfo->detectorsInSubtree(instrumentIndex), + compInfo->detectorsInFullSubtree(instrumentIndex), std::vector{detectorIndex}); } @@ -238,7 +238,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { compInfo->setDetectorInfo(detInfo.get()); detInfo->setComponentInfo(compInfo.get()); - TS_ASSERT_EQUALS(compInfo->detectorsInSubtree(3), std::vector{0}); + TS_ASSERT_EQUALS(compInfo->detectorsInFullSubtree(3), std::vector{0}); } void test_visitor_component_ranges_check() { diff --git a/Framework/Geometry/test/ObjCompAssemblyTest.h b/Framework/Geometry/test/ObjCompAssemblyTest.h index 58924a84defb..487792279662 100644 --- a/Framework/Geometry/test/ObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ObjCompAssemblyTest.h @@ -333,6 +333,42 @@ class ObjCompAssemblyTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(comp.type(), "ObjCompAssembly"); } + void testCreateOutlineCylinder() { + std::stringstream obj_str; + obj_str << ""; + obj_str << ""; + obj_str << " "; + obj_str << ""; + obj_str << ""; + obj_str << ""; + auto s = Mantid::Geometry::ShapeFactory().createShape(obj_str.str()); + + ObjCompAssembly bank("BankName"); + Component *det1 = new ObjComponent("Det1Name", s); + det1->setPos(V3D(0, -0.1, 0)); + Component *det2 = new ObjComponent("Det2Name", s); + det2->setPos(V3D(0, 0.1, 0)); + Component *det3 = new ObjComponent("Det3Name", s); + det3->setPos(V3D(0, 0.3, 0)); + + bank.add(det1); + bank.add(det2); + bank.add(det3); + + boost::shared_ptr shape = bank.createOutline(); + TS_ASSERT(shape); + + detail::ShapeInfo::GeometryShape otype; + std::vector vectors; + double radius, height; + shape->GetObjectGeom(otype, vectors, radius, height); + + TS_ASSERT_EQUALS(otype, detail::ShapeInfo::GeometryShape::CYLINDER); + TS_ASSERT_EQUALS(radius, 0.1); + TS_ASSERT_EQUALS(height, 0.6); + } + void test_fail_CreateOutline_for_wrong_component_type() { std::stringstream obj_str; obj_str << ""; diff --git a/Framework/Geometry/test/ParObjCompAssemblyTest.h b/Framework/Geometry/test/ParObjCompAssemblyTest.h index 3085c2b6f2e7..88bbfba57da0 100644 --- a/Framework/Geometry/test/ParObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ParObjCompAssemblyTest.h @@ -107,6 +107,51 @@ class ParObjCompAssemblyTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(pcomp.type(), "ObjCompAssembly"); } + + void testCreateOutlineCylinder() { + std::stringstream obj_str; + obj_str << ""; + obj_str << ""; + obj_str << " "; + obj_str << ""; + obj_str << ""; + obj_str << ""; + boost::shared_ptr s = + Mantid::Geometry::ShapeFactory().createShape(obj_str.str()); + + ObjCompAssembly bank("BankName"); + Component *det1 = new ObjComponent("Det1Name", s); + det1->setPos(V3D(0, -0.1, 0)); + Component *det2 = new ObjComponent("Det2Name", s); + det2->setPos(V3D(0, 0.1, 0)); + Component *det3 = new ObjComponent("Det3Name", s); + det3->setPos(V3D(0, 0.3, 0)); + + bank.add(det1); + bank.add(det2); + bank.add(det3); + + boost::shared_ptr shape = bank.createOutline(); + TS_ASSERT(shape); + + detail::ShapeInfo::GeometryShape otype; + std::vector vectors; + double radius, height; + shape->GetObjectGeom(otype, vectors, radius, height); + + TS_ASSERT_EQUALS(otype, detail::ShapeInfo::GeometryShape::CYLINDER); + TS_ASSERT_EQUALS(radius, 0.1); + TS_ASSERT_EQUALS(height, 0.6); + + ParameterMap_sptr pmap(new ParameterMap()); + boost::shared_ptr pcomp( + new ObjCompAssembly(&bank, pmap.get())); + boost::shared_ptr ic = + boost::dynamic_pointer_cast(pcomp); + boost::shared_ptr ica = + boost::dynamic_pointer_cast(ic); + } }; #endif diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 71b2ae715ef1..9a0b9bd2ce34 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -656,8 +656,6 @@ void InstrumentActor::resetColors() { if (mask) masked = mask->isMasked(detectorIDs[detIndex]); - else - masked = spectrumInfo.hasDetectors(wi) && spectrumInfo.isMasked(wi); if (detectorInfo.isMasked(detIndex) || masked) { m_colors[detIndex] = m_maskedColor; @@ -1149,7 +1147,14 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, auto workspace = getWorkspace(); calculateIntegratedSpectra(*workspace); - auto monitorIndices = getMonitors(); + auto monitors = getMonitors(); + const auto &detectorIDs = getDetectorInfo().detectorIDs(); + std::vector monitorIDs; + monitorIDs.reserve(monitors.size()); + for (auto mon : monitors) + monitorIDs.push_back(detectorIDs[mon]); + + auto monitorIndices = workspace->getIndicesFromDetectorIDs(monitorIDs); // check that there is at least 1 non-monitor spectrum if (monitorIndices.size() == m_specIntegrs.size()) { diff --git a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp index c21af36e8bab..1d9e3ef2639f 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp @@ -39,18 +39,15 @@ InstrumentTreeModel::~InstrumentTreeModel() {} * Returns 0 for the ObjComponent = I'm an end point. */ int InstrumentTreeModel::columnCount(const QModelIndex &parent) const { - try { - if (parent.isValid()) { - const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); - auto index = extractIndex(parent); - if (componentInfo.children(index).size() > 0) - return 1; - } else - return 1; - } catch (...) { - // do nothing - } + if (!parent.isValid()) + return 1; + + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + auto index = extractIndex(parent); + if (componentInfo.children(index).size() > 0) + return 1; + return 0; } @@ -59,23 +56,17 @@ int InstrumentTreeModel::columnCount(const QModelIndex &parent) const { * string will be instrument name */ QVariant InstrumentTreeModel::data(const QModelIndex &index, int role) const { - try { - if (role != Qt::DisplayRole) - return QVariant(); - - const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + if (role != Qt::DisplayRole) + return QVariant(); - if (!index.isValid()) // not valid has to return the root node - return QString::fromStdString(componentInfo.name(componentInfo.root())); + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); - auto compIndex = extractIndex(index); - return QString::fromStdString(componentInfo.name(compIndex)); - } catch (...) { - // Ignore Exceptions - } + if (!index.isValid()) // not valid has to return the root node + return QString::fromStdString(componentInfo.name(componentInfo.root())); - return 0; + auto compIndex = extractIndex(index); + return QString::fromStdString(componentInfo.name(compIndex)); } /** @@ -104,70 +95,52 @@ QVariant InstrumentTreeModel::headerData(int section, */ QModelIndex InstrumentTreeModel::index(int row, int column, const QModelIndex &parent) const { - try { - const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); - if (!parent.isValid()) { // invalid parent, has to be the root node i.e - // instrument - return createIndex(row, column, - &m_componentIndices[componentInfo.root()]); - } - auto index = extractIndex(parent); - const auto &children = componentInfo.children(index); - - if (index == componentInfo.source() || index == componentInfo.sample()) { - return QModelIndex(); - } - // If component assembly pick the Component at the row index. if row index - // is higher than number - // of components in assembly return empty model index - if (children.size() <= row) { - return QModelIndex(); - } else { - return createIndex(row, column, &m_componentIndices[children[row]]); - } - } catch (...) { - std::cout << "InstrumentTreeModel::index(" << row << "," << column - << ") threw an exception.\n"; + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + if (!parent.isValid()) { // invalid parent, has to be the root node i.e + // instrument + return createIndex(row, column, &m_componentIndices[componentInfo.root()]); } - return QModelIndex(); + auto index = extractIndex(parent); + const auto &children = componentInfo.children(index); + + if (index == componentInfo.source() || index == componentInfo.sample() || + children.size() <= row) + return QModelIndex(); + + return createIndex(row, column, &m_componentIndices[children[row]]); } /** * Returns the parent model index. */ QModelIndex InstrumentTreeModel::parent(const QModelIndex &index) const { - try { - if (!index.isValid()) // the index corresponds to root so there is no parent - // for root return empty. - return QModelIndex(); - - const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); - auto compIndex = extractIndex(index); - - if (compIndex == componentInfo.root()) - return QModelIndex(); - - auto parent = componentInfo.parent(compIndex); - if (parent == componentInfo.root()) - return createIndex(0, 0, &m_componentIndices[componentInfo.root()]); - - auto grandParent = componentInfo.parent(parent); - const auto &grandParentElems = componentInfo.children(grandParent); - - int row = 0; - for (auto child : grandParentElems) { - if (child == parent) - break; - row++; - } - - return createIndex(row, 0, &m_componentIndices[parent]); - } catch (...) { - // do nothing + if (!index.isValid()) // the index corresponds to root so there is no parent + // for root return empty. + return QModelIndex(); + + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + auto compIndex = extractIndex(index); + + if (compIndex == componentInfo.root()) + return QModelIndex(); + + auto parent = componentInfo.parent(compIndex); + if (parent == componentInfo.root()) + return createIndex(0, 0, &m_componentIndices[componentInfo.root()]); + + auto grandParent = componentInfo.parent(parent); + const auto &grandParentElems = componentInfo.children(grandParent); + + int row = 0; + for (auto child : grandParentElems) { + if (child == parent) + break; + row++; } - return QModelIndex(); + + return createIndex(row, 0, &m_componentIndices[parent]); } /** @@ -175,21 +148,16 @@ QModelIndex InstrumentTreeModel::parent(const QModelIndex &index) const { * ObjComponent row count will be 0. */ int InstrumentTreeModel::rowCount(const QModelIndex &parent) const { - try { - if (!parent.isValid()) // Root node row count is one. - { - return 1; - } else { - const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); - auto index = extractIndex(parent); - const auto &children = componentInfo.children(index); - if (children.size() > 1) - return static_cast(children.size()); - } - } catch (...) { - // do nothing - } + if (!parent.isValid()) // Root node row count is one. + return 1; + + const auto &componentInfo = + m_instrWidget->getInstrumentActor().getComponentInfo(); + auto index = extractIndex(parent); + const auto &children = componentInfo.children(index); + if (children.size() > 1) + return static_cast(children.size()); + return 0; } diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 7660f2c2f18d..5850b50328be 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -53,10 +53,22 @@ namespace MantidWidgets { using namespace boost::math; -/// to be used in std::transform +namespace { +double getPhi(const Mantid::Kernel::V3D &pos) { + return std::atan2(pos[1], pos[0]); +} + +double getPhiOffset(const Mantid::Kernel::V3D &pos, const double offset) { + double avgPos = getPhi(pos); + return avgPos < 0 ? -(offset + avgPos) : offset - avgPos; +} +} // namespace + + /// to be used in std::transform struct Sqrt { double operator()(double x) { return sqrt(x); } -}; + }; + /** * Constructor. @@ -1447,17 +1459,15 @@ void DetectorPlotController::prepareDataForIntegralsPlot( auto id = detectorInfo.detectorIDs()[det]; // get the x-value for detector idet double xvalue = 0; + auto pos = detectorInfo.position(det); switch (m_tubeXUnits) { case LENGTH: - xvalue = detectorInfo.position(det) - .distance(detectorInfo.position(ass[0])); + xvalue = pos.distance(detectorInfo.position(ass[0])); break; case PHI: - xvalue = bOffsetPsi ? detectorInfo.getPhiOffset(det, M_PI) - : detectorInfo.getPhi(det); + xvalue = bOffsetPsi ? getPhiOffset(pos, M_PI) : getPhi(pos); break; case OUT_OF_PLANE_ANGLE: { - auto pos = detectorInfo.position(det); xvalue = getOutOfPlaneAngle(pos, samplePos, normal); break; } From 48b489e8939471682a5017aeceb06f3eb0a33508 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 11 Jan 2018 12:20:52 +0000 Subject: [PATCH 042/364] clang-format #21339 --- Framework/Beamline/src/ComponentInfo.cpp | 3 ++- Framework/Beamline/test/ComponentInfoTest.h | 20 +++++++++++-------- .../Geometry/src/Instrument/ComponentInfo.cpp | 2 +- .../src/Instrument/InstrumentVisitor.cpp | 5 ++--- .../Geometry/test/InstrumentVisitorTest.h | 3 ++- .../src/InstrumentWidgetPickTab.cpp | 5 ++--- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 9b3424ed6b14..30eefab50a01 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -328,7 +328,8 @@ void ComponentInfo::setPosition(const size_t componentIndex, if (isDetector(componentIndex)) return m_detectorInfo->setPosition(componentIndex, newPosition); - // Optimization: Not using detectorsInFullSubtree and componentsInSubtree to avoid + // Optimization: Not using detectorsInFullSubtree and componentsInSubtree to + // avoid // memory allocations. // Optimization: Split loop over detectors and other components. const auto detectorRange = detectorRangeInSubtree(componentIndex); diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index b43fcc572299..98178ab9af5b 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -391,9 +391,9 @@ class ComponentInfoTest : public CxxTest::TestSuite { TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, componentRanges, - parentIndices, assemblyImmediateChildren, positions, - rotations, scaleFactors, isRectangularBank, - names, -1, -1), + parentIndices, assemblyImmediateChildren, + positions, rotations, scaleFactors, + isRectangularBank, names, -1, -1), std::invalid_argument &); } @@ -633,13 +633,17 @@ class ComponentInfoTest : public CxxTest::TestSuite { /* Note that detectors are always the first n component indexes! */ - TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(0), std::vector{0}); - TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(1), std::vector{1}); - TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(2), std::vector{2}); + TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(0), + std::vector{0}); + TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(1), + std::vector{1}); + TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(2), + std::vector{2}); // Now we have non-detector components - TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(4 /*component index of root*/), - std::vector({0, 2, 1})); + TS_ASSERT_EQUALS( + compInfo.detectorsInFullSubtree(4 /*component index of root*/), + std::vector({0, 2, 1})); TS_ASSERT_EQUALS( compInfo.detectorsInFullSubtree(3 /*component index of sub-assembly*/), std::vector({0, 2})); diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index f47b099ab99b..81e3aa2b2437 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -293,7 +293,7 @@ void ComponentInfo::growBoundingBoxAsRectuangularBank( Geometry::BoundingBox &mutableBB, std::map &mutableDetExclusions, IteratorT &mutableIterator) const { - + auto panel = structuredPanel(index); mutableBB.grow(componentBoundingBox(panel.bottomLeft, reference)); mutableBB.grow(componentBoundingBox(panel.topRight, reference)); diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index a26768d13de0..42a4f41a858b 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -77,9 +77,8 @@ InstrumentVisitor::InstrumentVisitor( boost::make_shared>>()), m_componentRanges( boost::make_shared>>()), - m_componentIdToIndexMap( - boost::make_shared< - std::unordered_map>()), + m_componentIdToIndexMap(boost::make_shared< + std::unordered_map>()), m_detectorIdToIndexMap(makeDetIdToIndexMap(*m_orderedDetectorIds)), m_positions(boost::make_shared>()), m_detectorPositions(boost::make_shared>( diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index f5d948ce8952..8dff9f163b69 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -238,7 +238,8 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { compInfo->setDetectorInfo(detInfo.get()); detInfo->setComponentInfo(compInfo.get()); - TS_ASSERT_EQUALS(compInfo->detectorsInFullSubtree(3), std::vector{0}); + TS_ASSERT_EQUALS(compInfo->detectorsInFullSubtree(3), + std::vector{0}); } void test_visitor_component_ranges_check() { diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 5850b50328be..9fd18add84b9 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -64,11 +64,10 @@ double getPhiOffset(const Mantid::Kernel::V3D &pos, const double offset) { } } // namespace - /// to be used in std::transform +/// to be used in std::transform struct Sqrt { double operator()(double x) { return sqrt(x); } - }; - +}; /** * Constructor. From 1d9f8f92c5cd0fac97fd02242baca1451bf094cd Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 11 Jan 2018 12:42:27 +0000 Subject: [PATCH 043/364] Fix forward declaration issue in UnwrappedSurface #21339 --- .../inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h | 3 +-- qt/widgets/instrumentview/src/UnwrappedSurface.cpp | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h index a26bd3626104..104edb209be2 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h @@ -6,6 +6,7 @@ #include "MantidGeometry/Objects/IObject.h" #include "InstrumentActor.h" #include "ProjectionSurface.h" +#include "UnwrappedDetector.h" #include #include @@ -30,8 +31,6 @@ class GL3DWidget; namespace MantidQt { namespace MantidWidgets { -class UnwrappedDetector; - /** * @class UnwrappedSurface * @brief Performs projection of an instrument onto a 2D surface and unwrapping diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 86f114e1843c..f2f767836852 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -1,5 +1,4 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedSurface.h" -#include "MantidQtWidgets/InstrumentView/UnwrappedDetector.h" #include "MantidQtWidgets/InstrumentView/GLColor.h" #include "MantidQtWidgets/InstrumentView/MantidGLWidget.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" From 42624048a9dd5248d3524dc0f20f8a10ec2ba555 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 11 Jan 2018 15:17:27 +0000 Subject: [PATCH 044/364] fix clang warnings #21339 --- Framework/Geometry/test/ComponentInfoTest.h | 2 +- qt/widgets/instrumentview/src/InstrumentTreeModel.cpp | 2 +- qt/widgets/instrumentview/src/RotationSurface.cpp | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index 86944db9730b..897ee5c52d8a 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -661,7 +661,7 @@ class ComponentInfoTest : public CxxTest::TestSuite { // find structured panel size_t structuredIndex = 0; - for (size_t i = componentInfo->root(); i >= 0; --i) { + for (size_t i = componentInfo->root(); i > 0; --i) { if (componentInfo->componentType(i) == Mantid::Beamline::ComponentType::Structured || componentInfo->componentType(i) == diff --git a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp index 1d9e3ef2639f..61d597380d2c 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp @@ -105,7 +105,7 @@ QModelIndex InstrumentTreeModel::index(int row, int column, const auto &children = componentInfo.children(index); if (index == componentInfo.source() || index == componentInfo.sample() || - children.size() <= row) + static_cast(children.size()) <= row) return QModelIndex(); return createIndex(row, column, &m_componentIndices[children[row]]); diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index aa6b2e96e858..771c0a8c9a4d 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -93,11 +93,6 @@ void RotationSurface::init() { // A real detector. // Position, relative to origin auto rpos = detectorInfo.position(i) - m_pos; - - auto pos = detectorInfo.position(i); - auto rot = detectorInfo.rotation(i); - auto scaleFactor = - componentInfo.scaleFactor(i); // Create the unwrapped shape UnwrappedDetector udet( m_instrActor->getColor(i), i); From 0fd54b35139ac61fa7adbb7d50b389024a21e9a0 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 16 Jan 2018 10:23:32 +0000 Subject: [PATCH 045/364] review changes #21339 --- .../inc/MantidBeamline/ComponentInfo.h | 6 +- Framework/Beamline/src/ComponentInfo.cpp | 11 ++- Framework/Beamline/test/ComponentInfoTest.h | 72 +++++++++---------- .../MantidGeometry/Instrument/ComponentInfo.h | 4 +- .../Instrument/InstrumentVisitor.h | 3 +- .../Rendering/GeometryHandler.h | 8 +-- .../src/Instrument/InstrumentVisitor.cpp | 17 +++-- Framework/Geometry/src/Objects/CSGObject.cpp | 6 ++ .../src/Rendering/GeometryHandler.cpp | 8 +-- Framework/Geometry/test/ComponentInfoTest.h | 16 ++--- MantidPlot/src/Mantid/MantidUI.cpp | 3 +- .../instrumentview/src/InstrumentActor.cpp | 7 +- .../src/InstrumentTreeModel.cpp | 2 +- .../instrumentview/src/RotationSurface.cpp | 7 +- .../instrumentview/src/UnwrappedSurface.cpp | 13 +++- 15 files changed, 93 insertions(+), 90 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index 95b6185070b1..382346280f1f 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -52,8 +52,7 @@ class MANTID_BEAMLINE_DLL ComponentInfo { boost::shared_ptr>> m_componentRanges; boost::shared_ptr> m_parentIndices; - boost::shared_ptr>> - m_assemblyImmediateChildren; + boost::shared_ptr>> m_children; Mantid::Kernel::cow_ptr> m_positions; Mantid::Kernel::cow_ptr>> @@ -99,8 +98,7 @@ class MANTID_BEAMLINE_DLL ComponentInfo { boost::shared_ptr>> componentRanges, boost::shared_ptr> parentIndices, - boost::shared_ptr>> - assemblyImmediateChildren, + boost::shared_ptr>> children, boost::shared_ptr> positions, boost::shared_ptr> rotations, boost::shared_ptr> scaleFactors, diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 30eefab50a01..07c15525069e 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -38,8 +38,7 @@ ComponentInfo::ComponentInfo( boost::shared_ptr>> componentRanges, boost::shared_ptr> parentIndices, - boost::shared_ptr>> - assemblyImmediateChildren, + boost::shared_ptr>> children, boost::shared_ptr> positions, boost::shared_ptr>> @@ -54,8 +53,8 @@ ComponentInfo::ComponentInfo( m_detectorRanges(std::move(detectorRanges)), m_componentRanges(std::move(componentRanges)), m_parentIndices(std::move(parentIndices)), - m_assemblyImmediateChildren(std::move(assemblyImmediateChildren)), - m_positions(std::move(positions)), m_rotations(std::move(rotations)), + m_children(std::move(children)), m_positions(std::move(positions)), + m_rotations(std::move(rotations)), m_scaleFactors(std::move(scaleFactors)), m_componentType(std::move(componentType)), m_names(std::move(names)), m_size(m_assemblySortedDetectorIndices->size() + @@ -97,7 +96,7 @@ ComponentInfo::ComponentInfo( } size_t assemTotalSize = 1; // initialize with root - for (const auto &assem : *m_assemblyImmediateChildren) + for (const auto &assem : *m_children) assemTotalSize += assem.size(); if (assemTotalSize != m_size) { @@ -161,7 +160,7 @@ ComponentInfo::children(const size_t componentIndex) const { auto numDets = m_assemblySortedDetectorIndices->size(); auto index = componentIndex - numDets; - return (*m_assemblyImmediateChildren)[index]; + return (*m_children)[index]; } return emptyVec; diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 98178ab9af5b..a4bf77a0801f 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -66,10 +66,10 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) { auto isRectangularBank = boost::make_shared>(1, ComponentType::Generic); - std::vector children(detPositions.size()); - std::iota(children.begin(), children.end(), 0); - auto assemblyImmediateChildren = - boost::make_shared>>(1, children); + std::vector branch(detPositions.size()); + std::iota(branch.begin(), branch.end(), 0); + auto children = + boost::make_shared>>(1, branch); auto componentInfo = boost::make_shared( bankSortedDetectorIndices, @@ -78,7 +78,7 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, assemblyImmediateChildren, positions, rotations, + parentIndices, children, positions, rotations, scaleFactors, isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -146,7 +146,7 @@ makeTreeExampleAndReturnGeometricArguments() { // Rectangular bank flag auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); - auto assemblyImmediateChildren = + auto children = boost::make_shared>>( 2, std::vector(2)); @@ -157,8 +157,8 @@ makeTreeExampleAndReturnGeometricArguments() { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, assemblyImmediateChildren, compPositions, compRotations, - scaleFactors, isRectangularBank, names, -1, -1); + parentIndices, children, compPositions, compRotations, scaleFactors, + isRectangularBank, names, -1, -1); compInfo->setDetectorInfo(detectorInfo.get()); @@ -216,9 +216,8 @@ makeTreeExample() { auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); - auto assemblyImmediateChildren = - boost::make_shared>>( - 2, std::vector(2)); + auto children = boost::make_shared>>( + 2, std::vector(2)); auto componentInfo = boost::make_shared( bankSortedDetectorIndices, @@ -227,8 +226,8 @@ makeTreeExample() { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, assemblyImmediateChildren, positions, rotations, - scaleFactors, isRectangularBank, names, -1, -1); + parentIndices, children, positions, rotations, scaleFactors, + isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -301,14 +300,13 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto scaleFactors = boost::make_shared(4); auto names = boost::make_shared(4); auto isRectangularBank = boost::make_shared>(1); - auto assemblyImmediateChildren = - boost::make_shared>>( - 1, std::vector(3)); + auto children = boost::make_shared>>( + 1, std::vector(3)); - ComponentInfo componentInfo( - bankSortedDetectorIndices, detectorRanges, bankSortedComponentIndices, - componentRanges, parentIndices, assemblyImmediateChildren, positions, - rotations, scaleFactors, isRectangularBank, names, -1, -1); + ComponentInfo componentInfo(bankSortedDetectorIndices, detectorRanges, + bankSortedComponentIndices, componentRanges, + parentIndices, children, positions, rotations, + scaleFactors, isRectangularBank, names, -1, -1); DetectorInfo detectorInfo; // Detector info size 0 TS_ASSERT_THROWS(componentInfo.setDetectorInfo(&detectorInfo), @@ -343,14 +341,14 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto names = boost::make_shared(); auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); - auto assemblyImmediateChildren = boost::make_shared< + auto children = boost::make_shared< std::vector>>(); // invalid but not being tested TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, bankSortedComponentIndices, componentRanges, - parentIndices, assemblyImmediateChildren, - positions, rotations, scaleFactors, - isRectangularBank, names, -1, -1), + parentIndices, children, positions, + rotations, scaleFactors, isRectangularBank, + names, -1, -1), std::invalid_argument &); } @@ -386,14 +384,14 @@ class ComponentInfoTest : public CxxTest::TestSuite { std::vector>{{0, 0}}); auto isRectangularBank = boost::make_shared>( 2, ComponentType::Generic); - auto assemblyImmediateChildren = boost::make_shared< + auto children = boost::make_shared< std::vector>>(); // invalid but not being tested TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, componentRanges, - parentIndices, assemblyImmediateChildren, - positions, rotations, scaleFactors, - isRectangularBank, names, -1, -1), + parentIndices, children, positions, + rotations, scaleFactors, isRectangularBank, + names, -1, -1), std::invalid_argument &); } @@ -431,16 +429,14 @@ class ComponentInfoTest : public CxxTest::TestSuite { auto componentTypes = boost::make_shared>( 1, Mantid::Beamline::ComponentType::Generic); - auto assemblyImmediateChildren = - boost::make_shared>>( - 1, std::vector{1, 2}); // invalid - - TS_ASSERT_THROWS(ComponentInfo(detectorsInSubtree, detectorRanges, - componentsInSubtree, componentRanges, - parentIndices, assemblyImmediateChildren, - positions, rotations, scaleFactors, - componentTypes, names, -1, -1), - std::invalid_argument &); + auto children = boost::make_shared>>( + 1, std::vector{1, 2}); // invalid + + TS_ASSERT_THROWS( + ComponentInfo(detectorsInSubtree, detectorRanges, componentsInSubtree, + componentRanges, parentIndices, children, positions, + rotations, scaleFactors, componentTypes, names, -1, -1), + std::invalid_argument &); } void test_read_positions_rotations() { diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index 8e9f11f921d6..a19b8518f21c 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -87,14 +87,14 @@ class MANTID_GEOMETRY_DLL ComponentInfo { const std::map &detectorExclusions) const; public: - typedef struct { + struct StructuredPanel { size_t topLeft; size_t bottomLeft; size_t bottomRight; size_t topRight; size_t nX; size_t nY; - } StructuredPanel; + }; ComponentInfo( std::unique_ptr componentInfo, diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h index 2b2259b1fbc7..f228a8b30797 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h @@ -79,8 +79,7 @@ class MANTID_GEOMETRY_DLL InstrumentVisitor boost::shared_ptr> m_parentComponentIndices; /// Stores instrument tree structure by storing children of all Components - boost::shared_ptr>> - m_assemblyImmediateChildren; + boost::shared_ptr>> m_children; /// Only Assemblies and other NON-detectors yield detector ranges boost::shared_ptr>> m_detectorRanges; diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 4a576795a6fd..e0ae299248ab 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -76,16 +76,16 @@ class MANTID_GEOMETRY_DLL GeometryHandler { initialize() const; ///< Prepare/Initialize Object/ObjComponent to be rendered bool canTriangulate() const { return !(m_triangulator == nullptr); } /// get the number of triangles - size_t numberOfTriangles(); + size_t numberOfTriangles() const; /// get the number of points or vertices - size_t numberOfPoints(); + size_t numberOfPoints() const; bool hasShapeInfo() const { return !(m_shapeInfo == nullptr); } const detail::ShapeInfo &shapeInfo() const { return *m_shapeInfo; } /// Extract the vertices of the triangles - const std::vector &getTriangleVertices(); + const std::vector &getTriangleVertices() const; /// Extract the Faces of the triangles - const std::vector &getTriangleFaces(); + const std::vector &getTriangleFaces() const; /// Sets the geometry cache using the triangulation information provided void setGeometryCache(size_t nPts, size_t nFaces, std::vector &&pts, std::vector &&faces); diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index 42a4f41a858b..f3f11e9a30b9 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -71,14 +71,14 @@ InstrumentVisitor::InstrumentVisitor( boost::make_shared>()), m_parentComponentIndices(boost::make_shared>( m_orderedDetectorIds->size(), 0)), - m_assemblyImmediateChildren( - boost::make_shared>>()), + m_children(boost::make_shared>>()), m_detectorRanges( boost::make_shared>>()), m_componentRanges( boost::make_shared>>()), - m_componentIdToIndexMap(boost::make_shared< - std::unordered_map>()), + m_componentIdToIndexMap( + boost::make_shared< + std::unordered_map>()), m_detectorIdToIndexMap(makeDetIdToIndexMap(*m_orderedDetectorIds)), m_positions(boost::make_shared>()), m_detectorPositions(boost::make_shared>( @@ -180,7 +180,7 @@ InstrumentVisitor::registerComponentAssembly(const ICompAssembly &assembly) { for (const auto &child : children) { (*m_parentComponentIndices)[child] = componentIndex; } - m_assemblyImmediateChildren->emplace_back(std::move(children)); + m_children->emplace_back(std::move(children)); return componentIndex; } @@ -208,7 +208,7 @@ InstrumentVisitor::registerGenericComponent(const IComponent &component) { // Unless this is the root component this parent is not correct and will be // updated later in the register call of the parent. m_parentComponentIndices->push_back(componentIndex); - m_assemblyImmediateChildren->emplace_back(std::vector()); + m_children->emplace_back(std::vector()); return componentIndex; } @@ -339,9 +339,8 @@ InstrumentVisitor::componentInfo() const { return Kernel::make_unique( m_assemblySortedDetectorIndices, m_detectorRanges, m_assemblySortedComponentIndices, m_componentRanges, - m_parentComponentIndices, m_assemblyImmediateChildren, m_positions, - m_rotations, m_scaleFactors, m_componentType, m_names, m_sourceIndex, - m_sampleIndex); + m_parentComponentIndices, m_children, m_positions, m_rotations, + m_scaleFactors, m_componentType, m_names, m_sourceIndex, m_sampleIndex); } std::unique_ptr diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index f9b9b31492af..05e982861d69 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -2138,6 +2138,9 @@ size_t CSGObject::numberOfVertices() const { * get vertices */ const std::vector &CSGObject::getTriangleVertices() const { + static std::vector empty; + if (m_handler == nullptr) + return empty; return m_handler->getTriangleVertices(); } @@ -2145,6 +2148,9 @@ const std::vector &CSGObject::getTriangleVertices() const { * get faces */ const std::vector &CSGObject::getTriangleFaces() const { + static std::vector empty; + if (m_handler == nullptr) + return empty; return m_handler->getTriangleFaces(); } diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 116cfdcfffb2..2f8c96048776 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -67,26 +67,26 @@ void GeometryHandler::initialize() const { render(); } -size_t GeometryHandler::numberOfTriangles() { +size_t GeometryHandler::numberOfTriangles() const { if (canTriangulate()) return m_triangulator->numTriangleFaces(); return 0; } -size_t GeometryHandler::numberOfPoints() { +size_t GeometryHandler::numberOfPoints() const { if (canTriangulate()) return m_triangulator->numTriangleVertices(); return 0; } -const std::vector &GeometryHandler::getTriangleVertices() { +const std::vector &GeometryHandler::getTriangleVertices() const { static std::vector empty; if (canTriangulate()) return m_triangulator->getTriangleVertices(); return empty; } -const std::vector &GeometryHandler::getTriangleFaces() { +const std::vector &GeometryHandler::getTriangleFaces() const { static std::vector empty; if (canTriangulate()) return m_triangulator->getTriangleFaces(); diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index 897ee5c52d8a..40a61854a652 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -109,12 +109,11 @@ std::unique_ptr makeSingleBeamlineComponentInfo( using Mantid::Beamline::ComponentType; auto isStructuredBank = boost::make_shared>(1, ComponentType::Generic); - auto assemblyImmediateChildren = - boost::make_shared>>(1); + auto children = boost::make_shared>>(1); return Kernel::make_unique( detectorIndices, detectorRanges, componentIndices, componentRanges, - parentIndices, assemblyImmediateChildren, positions, rotations, - scaleFactors, isStructuredBank, names, -1, -1); + parentIndices, children, positions, rotations, scaleFactors, + isStructuredBank, names, -1, -1); } } // namespace @@ -158,13 +157,12 @@ class ComponentInfoTest : public CxxTest::TestSuite { using Mantid::Beamline::ComponentType; auto isRectBank = boost::make_shared>( 2, ComponentType::Generic); - auto assemblyImmediateChildren = - boost::make_shared>>( - 1, std::vector(1)); + auto children = boost::make_shared>>( + 1, std::vector(1)); auto internalInfo = Kernel::make_unique( detectorIndices, detectorRanges, componentIndices, componentRanges, - parentIndices, assemblyImmediateChildren, positions, rotations, - scaleFactors, isRectBank, names, -1, -1); + parentIndices, children, positions, rotations, scaleFactors, isRectBank, + names, -1, -1); Mantid::Geometry::ObjComponent comp1("component1"); Mantid::Geometry::ObjComponent comp2("component2"); diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index 77e3f6fc77dd..95b236d0ad4d 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -2179,9 +2179,10 @@ void MantidUI::showMantidInstrumentSelected() { auto end = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = end - start; g_log.information() << "Show instrument lasted: " << elapsed_seconds.count() - << " seconds." << std::endl; + << " seconds." << std::endl; } + void MantidUI::mantidMenuAboutToShow() { mantidMenu->clear(); // Ticket #672 Mantid Menu Improvements diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 9a0b9bd2ce34..677925b48f9d 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -720,10 +720,12 @@ void InstrumentActor::draw(bool picking) const { void InstrumentActor::doDraw(bool picking) const { const auto &componentInfo = getComponentInfo(); for (size_t i = 0; i < componentInfo.size(); ++i) { - if (!componentInfo.isDetector(i) && !m_showGuides) + if ((!componentInfo.isDetector(i) && !m_showGuides) || + componentInfo.componentType(i) == + Beamline::ComponentType::OutlineComposite) continue; - if (componentInfo.hasShape(i)) { + if (componentInfo.hasValidShape(i)) { if (m_isCompVisible[i]) { if (picking) m_pickColors[i].paint(); @@ -758,7 +760,6 @@ void InstrumentActor::doDraw(bool picking) const { } } } - // m_scene.draw(picking); } /** * @param fname :: A color map file name. diff --git a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp index 61d597380d2c..973a8f1d656d 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp @@ -155,7 +155,7 @@ int InstrumentTreeModel::rowCount(const QModelIndex &parent) const { m_instrWidget->getInstrumentActor().getComponentInfo(); auto index = extractIndex(parent); const auto &children = componentInfo.children(index); - if (children.size() > 1) + if (children.size() > 0) return static_cast(children.size()); return 0; diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 771c0a8c9a4d..0b713b7e5ca5 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -74,7 +74,6 @@ void RotationSurface::init() { m_u_max = DBL_MAX; const auto &detectorInfo = m_instrActor->getDetectorInfo(); - const auto &componentInfo = m_instrActor->getComponentInfo(); // Set if one of the threads in the following loop // throws an exception bool exceptionThrown = false; @@ -187,7 +186,7 @@ void RotationSurface::findUVBounds() { m_v_max = -DBL_MAX; for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { const UnwrappedDetector &udet = m_unwrappedDetectors[i]; - if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) + if (!m_instrActor->getComponentInfo().hasValidShape(udet.detIndex)) continue; if (udet.u < m_u_min) m_u_min = udet.u; @@ -218,7 +217,7 @@ void RotationSurface::findAndCorrectUGap() { } for (const auto &udet : m_unwrappedDetectors) { - if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) + if (!m_instrActor->getComponentInfo().hasValidShape(udet.detIndex)) continue; double u = udet.u; int i = int((u - m_u_min) / bin_width); @@ -255,7 +254,7 @@ void RotationSurface::findAndCorrectUGap() { } for (auto &udet : m_unwrappedDetectors) { - if (!m_instrActor->getComponentInfo().hasShape(udet.detIndex)) + if (!m_instrActor->getComponentInfo().hasValidShape(udet.detIndex)) continue; double &u = udet.u; u = applyUCorrection(u); diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index f2f767836852..0582419917d9 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -140,7 +140,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { const auto &componentInfo = m_instrActor->getComponentInfo(); for (const auto &udet : m_unwrappedDetectors) { - if (!componentInfo.hasShape(udet.detIndex)) + if (!componentInfo.hasValidShape(udet.detIndex)) continue; int iw = int(udet.width / dw); @@ -242,8 +242,15 @@ void UnwrappedSurface::componentSelected(size_t componentIndex) { } else { auto detectors = componentInfo.detectorsInSubtree(componentIndex); QRectF area; - for (auto det : detectors) - area |= getArea(m_unwrappedDetectors[det], m_width_max, m_height_max); + for (auto det : detectors) { + QRectF detRect; + const auto &udet = m_unwrappedDetectors[det]; + detRect.setLeft(udet.u - udet.width); + detRect.setRight(udet.u + udet.width); + detRect.setBottom(udet.v - udet.height); + detRect.setTop(udet.v + udet.height); + area |= detRect; + } zoom(area); } } From 0bdf9d08d045d2e0533a9603972b77852fd045b1 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 16 Jan 2018 10:27:46 +0000 Subject: [PATCH 046/364] remove profiling code and clang format #21339 --- Framework/Beamline/test/ComponentInfoTest.h | 9 ++++----- Framework/Geometry/src/Instrument/InstrumentVisitor.cpp | 5 ++--- MantidPlot/src/Mantid/MantidUI.cpp | 7 ------- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index a4bf77a0801f..425beea119f4 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -78,8 +78,8 @@ makeFlatTree(PosVec detPositions, RotVec detRotations) { bankSortedComponentIndices, boost::make_shared>>( componentRanges), - parentIndices, children, positions, rotations, - scaleFactors, isRectangularBank, names, -1, -1); + parentIndices, children, positions, rotations, scaleFactors, + isRectangularBank, names, -1, -1); componentInfo->setDetectorInfo(detectorInfo.get()); @@ -146,9 +146,8 @@ makeTreeExampleAndReturnGeometricArguments() { // Rectangular bank flag auto isRectangularBank = boost::make_shared>(2, ComponentType::Generic); - auto children = - boost::make_shared>>( - 2, std::vector(2)); + auto children = boost::make_shared>>( + 2, std::vector(2)); auto compInfo = boost::make_shared( bankSortedDetectorIndices, diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index f3f11e9a30b9..308dae8122ea 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -76,9 +76,8 @@ InstrumentVisitor::InstrumentVisitor( boost::make_shared>>()), m_componentRanges( boost::make_shared>>()), - m_componentIdToIndexMap( - boost::make_shared< - std::unordered_map>()), + m_componentIdToIndexMap(boost::make_shared< + std::unordered_map>()), m_detectorIdToIndexMap(makeDetIdToIndexMap(*m_orderedDetectorIds)), m_positions(boost::make_shared>()), m_detectorPositions(boost::make_shared>( diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index 95b236d0ad4d..1d5dfe006447 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -97,7 +97,6 @@ #include "MantidQtWidgets/SpectrumViewer/SpectrumView.h" #include -#include using namespace std; @@ -2172,17 +2171,11 @@ void MantidUI::showMantidInstrument() { } void MantidUI::showMantidInstrumentSelected() { - auto start = std::chrono::system_clock::now(); QString wsName = getSelectedWorkspaceName(); if (!wsName.isEmpty()) showMantidInstrument(wsName); - auto end = std::chrono::system_clock::now(); - std::chrono::duration elapsed_seconds = end - start; - g_log.information() << "Show instrument lasted: " << elapsed_seconds.count() - << " seconds." << std::endl; } - void MantidUI::mantidMenuAboutToShow() { mantidMenu->clear(); // Ticket #672 Mantid Menu Improvements From 6f18fe750ff0e14334d54d72a1b0be6f8aed04e5 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 07:14:18 +0000 Subject: [PATCH 047/364] minor speed improvement re #21339 --- .../InstrumentView/InstrumentActor.h | 25 +-- .../InstrumentView/InstrumentWidgetPickTab.h | 18 +- .../InstrumentView/MaskBinsData.h | 4 +- .../InstrumentView/Projection3D.h | 4 +- .../InstrumentView/ProjectionSurface.h | 4 +- .../InstrumentView/UnwrappedSurface.h | 4 +- .../instrumentview/src/InstrumentActor.cpp | 114 +++++------ .../src/InstrumentWidgetMaskTab.cpp | 45 +++-- .../src/InstrumentWidgetPickTab.cpp | 187 ++++++++---------- .../instrumentview/src/MaskBinsData.cpp | 10 +- .../instrumentview/src/Projection3D.cpp | 14 +- .../instrumentview/src/UnwrappedSurface.cpp | 10 +- 12 files changed, 194 insertions(+), 245 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 3a1194ef949a..84a323c37b8e 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -82,7 +82,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { /// Apply the mask in the attached mask workspace to the data. void applyMaskWorkspace(); /// Add a range of bins for masking - void addMaskBinsData(const QList &detIDs); + void addMaskBinsData(const std::vector &indices); /// Remove the attached mask workspace without applying the mask. /// Remove the bin masking data. void clearMasks(); @@ -135,6 +135,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { size_t getDetectorByDetID(Mantid::detid_t detID) const; /// Get a detector ID by a pick ID converted form a color in the pick image. Mantid::detid_t getDetID(size_t pickID) const; + QList getDetIDs(const std::vector &dets) const; /// Get a component ID for a non-detector. Mantid::Geometry::ComponentID getComponentID(size_t pickID) const; /// Get position of a detector by a pick ID converted form a color in the pick @@ -144,12 +145,12 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { const std::vector &getAllDetIDs() const; /// Get displayed color of a detector by its index. GLColor getColor(size_t index) const; - /// Get the workspace index of a detector by its detector ID. - size_t getWorkspaceIndex(Mantid::detid_t id) const; - /// Get the integrated counts of a detector by its detector ID. - double getIntegratedCounts(Mantid::detid_t id) const; + /// Get the workspace index of a detector by its detector Index. + size_t getWorkspaceIndex(size_t index) const; + /// Get the integrated counts of a detector by its detector Index. + double getIntegratedCounts(size_t index) const; /// Sum the counts in detectors - void sumDetectors(QList &dets, std::vector &x, + void sumDetectors(const std::vector &dets, std::vector &x, std::vector &y, size_t size = 0) const; /// Calc indexes for min and max bin values void getBinMinMaxIndex(size_t wi, size_t &imin, size_t &imax) const; @@ -214,10 +215,10 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { calculateIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace); /// Sum the counts in detectors if the workspace has equal bins for all /// spectra - void sumDetectorsUniform(QList &dets, std::vector &x, + void sumDetectorsUniform(const std::vector &dets, std::vector &x, std::vector &y) const; /// Sum the counts in detectors if the workspace is ragged - void sumDetectorsRagged(QList &dets, std::vector &x, + void sumDetectorsRagged(const std::vector &dets, std::vector &x, std::vector &y, size_t size) const; void setupPickColors(); @@ -257,10 +258,6 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { bool m_volumeRender; /// Color map scale type: linear or log GraphOptions::ScaleType m_scaleType; - - /// The workspace's detector ID to workspace index map - Mantid::detid2index_map m_detid2index_map; - /// All det ids in the instrument in order of pickIDs, populated by Obj..Actor /// constructors mutable std::vector m_detIDs; @@ -281,14 +278,12 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { GLColor m_maskedColor; /// Colour of a "failed" detector GLColor m_failedColor; - /// The collection of actors for the instrument components - // GLActorCollection m_scene; static double m_tolerance; std::vector m_pickColors; std::vector m_isCompVisible; - + std::vector m_detIndex2WsIndex; // Two display lists for normal rendering and picking mutable GLuint m_displayListId[2]; mutable bool m_useDisplayList[2]; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h index 371b4a9f9566..93a5df79fa5e 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h @@ -200,7 +200,7 @@ public slots: void clear(); private: - QString displayDetectorInfo(Mantid::detid_t detid); + QString displayDetectorInfo(size_t index); QString displayNonDetectorInfo(Mantid::Geometry::ComponentID compID); QString displayPeakInfo(Mantid::Geometry::IPeak *peak); QString displayPeakAngles(const std::pair detIDs); + void setPlotData(const std::vector &detIndices); void updatePlot(); void clear(); void savePlotToWorkspace(); @@ -255,17 +255,17 @@ private slots: void addPeak(double x, double y); private: - void plotSingle(int detid); - void plotTube(int detid); - void plotTubeSums(int detid); - void plotTubeIntegrals(int detid); - void prepareDataForSinglePlot(int detid, std::vector &x, + void plotSingle(size_t detindex); + void plotTube(size_t detindex); + void plotTubeSums(size_t detindex); + void plotTubeIntegrals(size_t detindex); + void prepareDataForSinglePlot(size_t detindex, std::vector &x, std::vector &y, std::vector *err = nullptr); - void prepareDataForSumsPlot(int detid, std::vector &x, + void prepareDataForSumsPlot(size_t detindex, std::vector &x, std::vector &y, std::vector *err = nullptr); - void prepareDataForIntegralsPlot(int detid, std::vector &x, + void prepareDataForIntegralsPlot(size_t detindex, std::vector &x, std::vector &y, std::vector *err = nullptr); static double getOutOfPlaneAngle(const Mantid::Kernel::V3D &pos, diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h index f50f2554b98f..2ffd97d42783 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/MaskBinsData.h @@ -36,7 +36,7 @@ File change history is stored at: */ class MaskBinsData { public: - void addXRange(double start, double end, const QList &indices); + void addXRange(double start, double end, const std::vector &indices); void mask(const std::string &wsName) const; bool isEmpty() const; void subtractIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace, @@ -53,7 +53,7 @@ class MaskBinsData { BinMask(double s = 0.0, double e = 0.0) : start(s), end(e) {} double start; double end; - QList spectra; + std::vector spectra; }; QList m_masks; }; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h index 9e44430cef90..73d7bab257c8 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h @@ -40,8 +40,8 @@ class Projection3D : public ProjectionSurface { void setWireframe(bool on); void componentSelected(size_t componentIndex) override; - void getSelectedDetectors(QList &dets) override; - void getMaskedDetectors(QList &dets) const override; + void getSelectedDetectors(std::vector &dets) override; + void getMaskedDetectors(std::vector &dets) const override; void resize(int, int) override; QString getInfoText() const override; /// Load settings for the 3D projection from a project file diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h index b3562edd963b..68dbaaa0d011 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h @@ -113,9 +113,9 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW ProjectionSurface : public QObject { /// NULL deselects components and selects the whole instrument virtual void componentSelected(size_t componentIndex) = 0; /// fill in a list of detector ids which were selected by the selction tool - virtual void getSelectedDetectors(QList &dets) = 0; + virtual void getSelectedDetectors(std::vector &dets) = 0; /// fill in a list of detector ids which were masked by the mask shapes - virtual void getMaskedDetectors(QList &dets) const = 0; + virtual void getMaskedDetectors(std::vector &dets) const = 0; virtual QString getInfoText() const; /// Change the interaction mode diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h index 104edb209be2..3f473ce4f235 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h @@ -60,8 +60,8 @@ class UnwrappedSurface : public ProjectionSurface { /** @name Implemented public virtual methods */ //@{ void componentSelected(size_t componentIndex) override; - void getSelectedDetectors(QList &dets) override; - void getMaskedDetectors(QList &dets) const override; + void getSelectedDetectors(std::vector &dets) override; + void getMaskedDetectors(std::vector &dets) const override; void setPeaksWorkspace(boost::shared_ptr pws); QString getInfoText() const override; RectF getSurfaceBounds() const override; diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 677925b48f9d..b158d410af2e 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -45,8 +45,6 @@ size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) { index += b - 1; return index; } - -GLColor defaultDetectorColor() { return GLColor(200, 200, 200); } } // namespace double InstrumentActor::m_tolerance = 0.00001; @@ -142,6 +140,7 @@ InstrumentActor::~InstrumentActor() { void InstrumentActor::setUpWorkspace( boost::shared_ptr sharedWorkspace, double scaleMin, double scaleMax) { + const size_t nHist = sharedWorkspace->getNumberHistograms(); m_WkspBinMinValue = DBL_MAX; m_WkspBinMaxValue = -DBL_MAX; @@ -168,6 +167,14 @@ void InstrumentActor::setUpWorkspace( } } + const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); + m_detIndex2WsIndex.resize(sharedWorkspace->componentInfo().size()); + for (size_t wi = 0; wi < spectrumInfo.size(); wi++) { + const auto &specDef = spectrumInfo.spectrumDefinition(wi); + for (auto info : specDef) + m_detIndex2WsIndex[info.first] = wi; + } + // set some values as the variables will be used m_DataPositiveMinValue = DBL_MAX; m_DataMinValue = -DBL_MAX; @@ -182,9 +189,6 @@ void InstrumentActor::setUpWorkspace( // set the ragged flag using a workspace validator auto wsValidator = Mantid::API::CommonBinsValidator(); m_ragged = !wsValidator.isValid(sharedWorkspace).empty(); - - /// Keep the pointer to the detid2index map - m_detid2index_map = sharedWorkspace->getDetectorIDToWorkspaceIndexMap(); } void InstrumentActor::setComponentVisible(size_t componentIndex) { @@ -394,6 +398,14 @@ Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const { return -1; } +QList +InstrumentActor::getDetIDs(const std::vector &dets) const { + QList detIDs; + for (auto det : dets) + detIDs.append(getDetID(det)); + return detIDs; +} + /** * Get a component id of a picked component. */ @@ -412,13 +424,8 @@ InstrumentActor::getComponentID(size_t pickID) const { * @throws Exception::NotFoundError If the detector is not represented in the * workspace */ -size_t InstrumentActor::getWorkspaceIndex(Mantid::detid_t id) const { - auto mapEntry = m_detid2index_map.find(id); - if (mapEntry == m_detid2index_map.end()) { - throw Kernel::Exception::NotFoundError("Detector ID not in workspace", id); - } - - return mapEntry->second; +size_t InstrumentActor::getWorkspaceIndex(size_t index) const { + return m_detIndex2WsIndex[index]; } /** @@ -436,18 +443,12 @@ void InstrumentActor::setIntegrationRange(const double &xmin, } /** Gives the total signal in the spectrum relating to the given detector - * @param id The detector id - * @return The signal, or -1 if the detector is not represented in the - * workspace + * @param index The detector index + * @return The signal */ -double InstrumentActor::getIntegratedCounts(Mantid::detid_t id) const { - try { - size_t i = getWorkspaceIndex(id); +double InstrumentActor::getIntegratedCounts(size_t index) const { + size_t i = getWorkspaceIndex(index); return m_specIntegrs.at(i); - } catch (NotFoundError &) { - // If the detector is not represented in the workspace - return -1.0; - } } /** @@ -457,14 +458,14 @@ double InstrumentActor::getIntegratedCounts(Mantid::detid_t id) const { * appropriate summation * method. * - * @param dets :: A list of detector IDs to sum. + * @param dets :: A list of detector Indices to sum. * @param x :: (output) Time of flight values (or whatever values the x axis * has) to plot against. * @param y :: (output) The sums of the counts for each bin. * @param size :: (optional input) Size of the output vectors. If not given it * will be determined automatically. */ -void InstrumentActor::sumDetectors(QList &dets, std::vector &x, +void InstrumentActor::sumDetectors(const std::vector &dets, std::vector &x, std::vector &y, size_t size) const { Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); if (size > ws->blocksize() || size == 0) { @@ -485,26 +486,16 @@ void InstrumentActor::sumDetectors(QList &dets, std::vector &x, * the x-axis. * Assumes that all spectra share the x vector. * - * @param dets :: A list of detector IDs to sum. + * @param dets :: A list of detector Indices to sum. * @param x :: (output) Time of flight values (or whatever values the x axis * has) to plot against. * @param y :: (output) The sums of the counts for each bin. */ -void InstrumentActor::sumDetectorsUniform(QList &dets, +void InstrumentActor::sumDetectorsUniform(const std::vector &dets, std::vector &x, std::vector &y) const { - size_t wi; - bool isDataEmpty = dets.isEmpty(); - - if (!isDataEmpty) { - try { - wi = getWorkspaceIndex(dets[0]); - } catch (Mantid::Kernel::Exception::NotFoundError &) { - isDataEmpty = - true; // Detector doesn't have a workspace index relating to it - } - } + bool isDataEmpty = dets.empty(); if (isDataEmpty) { x.clear(); @@ -514,6 +505,7 @@ void InstrumentActor::sumDetectorsUniform(QList &dets, // find the bins inside the integration range size_t imin, imax; + auto wi = getWorkspaceIndex(dets[0]); getBinMinMaxIndex(wi, imin, imax); Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); @@ -521,15 +513,11 @@ void InstrumentActor::sumDetectorsUniform(QList &dets, x.assign(XPoints.begin() + imin, XPoints.begin() + imax); y.resize(x.size(), 0); // sum the spectra - foreach (int id, dets) { - try { - size_t index = getWorkspaceIndex(id); - const auto &Y = ws->y(index); - std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(), - std::plus()); - } catch (Mantid::Kernel::Exception::NotFoundError &) { - continue; // Detector doesn't have a workspace index relating to it - } + for (auto det : dets) { + auto index = getWorkspaceIndex(det); + const auto &Y = ws->y(index); + std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(), + std::plus()); } } @@ -544,11 +532,11 @@ void InstrumentActor::sumDetectorsUniform(QList &dets, * @param y :: (output) The sums of the counts for each bin. * @param size :: (input) Size of the output vectors. */ -void InstrumentActor::sumDetectorsRagged(QList &dets, +void InstrumentActor::sumDetectorsRagged(const std::vector &dets, std::vector &x, std::vector &y, size_t size) const { - if (dets.isEmpty() || size == 0) { + if (dets.empty() || size == 0) { x.clear(); y.clear(); return; @@ -565,9 +553,9 @@ void InstrumentActor::sumDetectorsRagged(QList &dets, size_t nSpec = 0; // number of actual spectra to add // fill in the temp workspace with the data from the detectors - foreach (int id, dets) { + for(auto det: dets) { try { - size_t index = getWorkspaceIndex(id); + size_t index = getWorkspaceIndex(det); dws->setHistogram(nSpec, ws->histogram(index)); double xmin = dws->x(nSpec).front(); double xmax = dws->x(nSpec).back(); @@ -1149,13 +1137,11 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, auto workspace = getWorkspace(); calculateIntegratedSpectra(*workspace); auto monitors = getMonitors(); - const auto &detectorIDs = getDetectorInfo().detectorIDs(); - std::vector monitorIDs; - monitorIDs.reserve(monitors.size()); - for (auto mon : monitors) - monitorIDs.push_back(detectorIDs[mon]); + std::vector monitorIndices; - auto monitorIndices = workspace->getIndicesFromDetectorIDs(monitorIDs); + monitorIndices.reserve(monitors.size()); + for (auto monitor : monitors) + monitorIndices.push_back(getWorkspaceIndex(monitor)); // check that there is at least 1 non-monitor spectrum if (monitorIndices.size() == m_specIntegrs.size()) { @@ -1187,7 +1173,6 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, "or NaN).\n" "Please run ReplaceSpecialValues algorithm for correction."); } - // integrated_values[i] = sum; if (sum < m_DataMinValue) { m_DataMinValue = sum; } @@ -1207,14 +1192,13 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, } /// Add a range of bins for masking -void InstrumentActor::addMaskBinsData(const QList &detIDs) { - QList indices; - foreach (int id, detIDs) { - auto index = m_detid2index_map[id]; - indices.append(static_cast(index)); - } - if (!indices.isEmpty()) { - m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, indices); +void InstrumentActor::addMaskBinsData(const std::vector &indices) { + std::vector wsIndices; + wsIndices.reserve(indices.size()); + for (auto det: indices) + wsIndices.push_back(getWorkspaceIndex(det)); + if (!indices.empty()) { + m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, wsIndices); auto workspace = getWorkspace(); calculateIntegratedSpectra(*workspace); resetColors(); diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp index 75bc66eb95cd..52840b486e78 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp @@ -729,9 +729,10 @@ void InstrumentWidgetMaskTab::saveMaskToTable() { */ void InstrumentWidgetMaskTab::extractDetsToWorkspace() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QList dets; + std::vector dets; m_instrWidget->getSurface()->getMaskedDetectors(dets); - DetXMLFile mapFile(dets); + const auto &actor = m_instrWidget->getInstrumentActor(); + DetXMLFile mapFile(actor.getDetIDs(dets)); std::string fname = mapFile(); if (!fname.empty()) { std::string workspaceName = m_instrWidget->getWorkspaceName().toStdString(); @@ -751,9 +752,10 @@ void InstrumentWidgetMaskTab::extractDetsToWorkspace() { */ void InstrumentWidgetMaskTab::sumDetsToWorkspace() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - QList dets; + std::vector dets; m_instrWidget->getSurface()->getMaskedDetectors(dets); - DetXMLFile mapFile(dets, DetXMLFile::Sum); + DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getDetIDs(dets), + DetXMLFile::Sum); std::string fname = mapFile(); if (!fname.empty()) { @@ -773,9 +775,10 @@ void InstrumentWidgetMaskTab::saveIncludeGroupToFile() { QString fname = m_instrWidget->getSaveFileName("Save grouping file", "XML files (*.xml);;All (*)"); if (!fname.isEmpty()) { - QList dets; + std::vector dets; m_instrWidget->getSurface()->getMaskedDetectors(dets); - DetXMLFile mapFile(dets, DetXMLFile::Sum, fname); + DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getDetIDs(dets), + DetXMLFile::Sum, fname); } } @@ -783,10 +786,10 @@ void InstrumentWidgetMaskTab::saveExcludeGroupToFile() { QString fname = m_instrWidget->getSaveFileName("Save grouping file", "XML files (*.xml);;All (*)"); if (!fname.isEmpty()) { - QList dets; + std::vector dets; m_instrWidget->getSurface()->getMaskedDetectors(dets); - DetXMLFile mapFile(m_instrWidget->getInstrumentActor().getAllDetIDs(), dets, - fname); + const auto &actor = m_instrWidget->getInstrumentActor(); + DetXMLFile mapFile(actor.getAllDetIDs(), actor.getDetIDs(dets), fname); } } @@ -1109,11 +1112,12 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) { m_instrWidget->updateInstrumentView(); // to refresh the pick image Mantid::API::IMaskWorkspace_sptr wsFresh; - QList dets; + const auto &actor = m_instrWidget->getInstrumentActor(); + std::vector dets; // get detectors covered by the shapes m_instrWidget->getSurface()->getMaskedDetectors(dets); - if (!dets.isEmpty()) { - auto wsMask = m_instrWidget->getInstrumentActor().getMaskWorkspace(); + if (!dets.empty()) { + auto wsMask = actor.getMaskWorkspace(); // have to cast up to the MaskWorkspace to get access to clone() std::set detList; @@ -1122,21 +1126,22 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) { // but not if the mask is fresh and empty if (wsMask->getNumberMasked() > 0) { wsFresh = boost::dynamic_pointer_cast( - m_instrWidget->getInstrumentActor().extractCurrentMask()); - m_instrWidget->getInstrumentActor().invertMaskWorkspace(); + actor.extractCurrentMask()); + actor.invertMaskWorkspace(); } } - foreach (int id, dets) { detList.insert(id); } + for (auto det : dets) + detList.insert(actor.getDetID(det)); if (!detList.empty()) { // try to mask each detector separately and ignore any failure - for (auto det = detList.begin(); det != detList.end(); ++det) { + for (auto det: detList) { try { if (isROI && wsFresh) { - if (wsMask->isMasked(*det)) - wsFresh->setMasked(*det); + if (wsMask->isMasked(det)) + wsFresh->setMasked(det); } else { - wsMask->setMasked(*det); + wsMask->setMasked(det); } } catch (...) { } @@ -1160,7 +1165,7 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) { } void InstrumentWidgetMaskTab::storeBinMask() { - QList dets; + std::vector dets; // get detectors covered by the shapes m_instrWidget->getSurface()->getMaskedDetectors(dets); // mask some bins diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 9fd18add84b9..94941dfb78d7 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -742,7 +742,7 @@ void InstrumentWidgetPickTab::updatePlotMultipleDetectors() { return; ProjectionSurface &surface = *getSurface(); if (surface.hasMasks()) { - QList dets; + std::vector dets; surface.getMaskedDetectors(dets); m_plotController->setPlotData(dets); } else { @@ -830,10 +830,10 @@ void ComponentInfoController::displayInfo(size_t pickID) { } const auto &actor = m_instrWidget->getInstrumentActor(); + const auto &componentInfo = actor.getComponentInfo(); QString text = ""; - int detid = actor.getDetID(pickID); - if (detid >= 0) { - text += displayDetectorInfo(detid); + if (componentInfo.isDetector(pickID)) { + text += displayDetectorInfo(pickID); } else if (auto componentID = actor.getComponentID(pickID)) { text += displayNonDetectorInfo(componentID); } else { @@ -851,56 +851,51 @@ void ComponentInfoController::displayInfo(size_t pickID) { /** * Return string with info on a detector. -* @param detid :: A detector ID. +* @param index :: A detector Index. */ -QString ComponentInfoController::displayDetectorInfo(Mantid::detid_t detid) { +QString ComponentInfoController::displayDetectorInfo(size_t index) { if (m_instrWidgetBlocked) { clear(); return ""; } QString text; - if (detid >= 0) { + // collect info about selected detector and add it to text const auto &actor = m_instrWidget->getInstrumentActor(); const auto &componentInfo = actor.getComponentInfo(); - auto det = actor.getDetectorByDetID(detid); + auto detid = actor.getDetID(index); text = "Selected detector: " + - QString::fromStdString(componentInfo.name(det)) + "\n"; + QString::fromStdString(componentInfo.name(index)) + "\n"; text += "Detector ID: " + QString::number(detid) + '\n'; QString wsIndex; - try { - wsIndex = QString::number(actor.getWorkspaceIndex(detid)); - } catch (Mantid::Kernel::Exception::NotFoundError &) { - // Detector doesn't have a workspace index relating to it - wsIndex = "None"; - } + wsIndex = QString::number(actor.getWorkspaceIndex(index)); text += "Workspace index: " + wsIndex + '\n'; - Mantid::Kernel::V3D pos = componentInfo.position(det); + Mantid::Kernel::V3D pos = componentInfo.position(index); text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) + "," + QString::number(pos.Z()) + '\n'; double r, t, p; pos.getSpherical(r, t, p); text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," + QString::number(p) + '\n'; - if (componentInfo.hasParent(det)) { + if (componentInfo.hasParent(index)) { QString textpath; - auto parent = det; + auto parent = index; while (componentInfo.hasParent(parent)) { parent = componentInfo.parent(parent); textpath = "/" + QString::fromStdString(componentInfo.name(parent)) + textpath; } text += "Component path:" + textpath + "/" + - QString::fromStdString(componentInfo.name(det)) + '\n'; - } - const double integrated = actor.getIntegratedCounts(detid); + QString::fromStdString(componentInfo.name(index)) + '\n'; + + const double integrated = actor.getIntegratedCounts(index); const QString counts = integrated == -1.0 ? "N/A" : QString::number(integrated); text += "Counts: " + counts + '\n'; // display info about peak overlays - text += actor.getParameterInfo(det); + text += actor.getParameterInfo(index); } return text; } @@ -1099,19 +1094,19 @@ void DetectorPlotController::setPlotData(size_t pickID) { m_plotType = Single; } - const int detid = m_instrWidget->getInstrumentActor().getDetID(pickID); - if (!m_enabled) { m_plot->clearCurve(); return; } - if (detid >= 0) { + const auto &actor = m_instrWidget->getInstrumentActor(); + const auto &componentInfo = actor.getComponentInfo(); + if (componentInfo.isDetector(pickID)) { if (m_plotType == Single) { - m_currentDetID = detid; - plotSingle(detid); + m_currentDetID = actor.getDetID(pickID); + plotSingle(pickID); } else if (m_plotType == TubeSum || m_plotType == TubeIntegral) { - plotTube(detid); + plotTube(pickID); } else { throw std::logic_error("setPlotData: Unexpected plot type."); } @@ -1122,15 +1117,16 @@ void DetectorPlotController::setPlotData(size_t pickID) { /** * Set curev data from multiple detectors: sum their spectra. -* @param detIDs :: A list of detector IDs. +* @param detIndices :: A list of detector Indices. */ -void DetectorPlotController::setPlotData(QList detIDs) { +void DetectorPlotController::setPlotData( + const std::vector &detIndices) { setPlotType(DetectorSum); clear(); std::vector x, y; QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); const auto &actor = m_instrWidget->getInstrumentActor(); - actor.sumDetectors(detIDs, x, y, static_cast(m_plot->width())); + actor.sumDetectors(detIndices, x, y, static_cast(m_plot->width())); QApplication::restoreOverrideCursor(); if (!x.empty()) { m_plot->setData(&x[0], &y[0], static_cast(y.size()), @@ -1157,23 +1153,20 @@ void DetectorPlotController::clear() { /** * Plot data for a detector. -* @param detid :: ID of the detector to be plotted. +* @param detindex :: Index of the detector to be plotted. */ -void DetectorPlotController::plotSingle(int detid) { - +void DetectorPlotController::plotSingle(size_t detindex) { clear(); std::vector x, y; - prepareDataForSinglePlot(detid, x, y); + prepareDataForSinglePlot(detindex, x, y); if (x.empty() || y.empty()) return; + const auto &actor = m_instrWidget->getInstrumentActor(); // set the data m_plot->setData(&x[0], &y[0], static_cast(y.size()), - m_instrWidget->getInstrumentActor() - .getWorkspace() - ->getAxis(0) - ->unit() - ->unitID()); + actor.getWorkspace()->getAxis(0)->unit()->unitID()); + auto detid = actor.getDetID(detindex); m_plot->setLabel("Detector " + QString::number(detid)); // find any markers @@ -1196,25 +1189,24 @@ void DetectorPlotController::plotSingle(int detid) { * LENGTH * PHI * The units can be set with setTubeXUnits(...) method. -* @param detid :: A detector id. The miniplot will display data for a component +* @param detindex :: A detector index. The miniplot will display data for a component * containing the detector * with this id. */ -void DetectorPlotController::plotTube(int detid) { +void DetectorPlotController::plotTube(size_t detindex) { const auto &actor = m_instrWidget->getInstrumentActor(); const auto &componentInfo = actor.getComponentInfo(); - auto det = actor.getDetectorByDetID(detid); - if (componentInfo.hasParent(det) && - componentInfo.detectorsInSubtree(det).size() > 0) { + if (componentInfo.hasParent(detindex) && + componentInfo.detectorsInSubtree(detindex).size() > 0) { if (m_plotType == TubeSum) // plot sums over detectors vs time bins { - plotTubeSums(detid); + plotTubeSums(detindex); } else // plot detector integrals vs detID or a function of detector // position in the tube { assert(m_plotType == TubeIntegral); - plotTubeIntegrals(detid); + plotTubeIntegrals(detindex); } } else { m_plot->clearCurve(); @@ -1223,21 +1215,21 @@ void DetectorPlotController::plotTube(int detid) { /** * Plot the accumulated data in a tube against time of flight. -* @param detid :: A detector id. The miniplot will display data for a component +* @param detindex :: A detector id. The miniplot will display data for a component * containing the detector * with this id. */ -void DetectorPlotController::plotTubeSums(int detid) { +void DetectorPlotController::plotTubeSums(size_t detindex) { std::vector x, y; - prepareDataForSumsPlot(detid, x, y); + prepareDataForSumsPlot(detindex, x, y); if (x.empty() || y.empty()) { clear(); return; } const auto &actor = m_instrWidget->getInstrumentActor(); const auto &componentInfo = actor.getComponentInfo(); - auto det = actor.getDetectorByDetID(detid); - auto parent = componentInfo.parent(det); + auto parent = componentInfo.parent(detindex); + auto detid = actor.getDetID(detindex); QString label = QString::fromStdString(componentInfo.name(parent)) + " (" + QString::number(detid) + ") Sum"; m_plot->setData(&x[0], &y[0], static_cast(y.size()), @@ -1253,16 +1245,15 @@ void DetectorPlotController::plotTubeSums(int detid) { * LENGTH * PHI * The units can be set with setTubeXUnits(...) method. -* @param detid :: A detector id. The miniplot will display data for a component +* @param detindex :: A detector index. The miniplot will display data for a component * containing the detector * with this id. */ -void DetectorPlotController::plotTubeIntegrals(int detid) { - auto det = m_instrWidget->getInstrumentActor().getDetectorByDetID(detid); - const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); +void DetectorPlotController::plotTubeIntegrals(size_t detindex) { + const auto &actor = m_instrWidget->getInstrumentActor(); + const auto &componentInfo =actor.getComponentInfo(); std::vector x, y; - prepareDataForIntegralsPlot(detid, x, y); + prepareDataForIntegralsPlot(detindex, x, y); if (x.empty() || y.empty()) { clear(); return; @@ -1274,32 +1265,28 @@ void DetectorPlotController::plotTubeIntegrals(int detid) { } m_plot->setData(&x[0], &y[0], static_cast(y.size()), xAxisCaption.toStdString()); - auto parent = componentInfo.parent(det); + auto parent = componentInfo.parent(detindex); // curve label: "tube_name (detid) Integrals" // detid is included to distiguish tubes with the same name QString label = QString::fromStdString(componentInfo.name(parent)) + " (" + - QString::number(detid) + ") Integrals/" + getTubeXUnitsName(); + QString::number(actor.getDetID(detindex)) + ") Integrals/" + + getTubeXUnitsName(); m_plot->setLabel(label); } /** * Prepare data for plotting a spectrum of a single detector. -* @param detid :: ID of the detector to be plotted. +* @param detindex :: Index of the detector to be plotted. * @param x :: Vector of x coordinates (output) * @param y :: Vector of y coordinates (output) * @param err :: Optional pointer to a vector of errors (output) */ void DetectorPlotController::prepareDataForSinglePlot( - int detid, std::vector &x, std::vector &y, + size_t detindex, std::vector &x, std::vector &y, std::vector *err) { const auto &actor = m_instrWidget->getInstrumentActor(); Mantid::API::MatrixWorkspace_const_sptr ws = actor.getWorkspace(); - size_t wi; - try { - wi = actor.getWorkspaceIndex(detid); - } catch (Mantid::Kernel::Exception::NotFoundError &) { - return; // Detector doesn't have a workspace index relating to it - } + auto wi = actor.getWorkspaceIndex(detindex); // get the data const auto &XPoints = ws->points(wi); const auto &Y = ws->y(wi); @@ -1318,30 +1305,24 @@ void DetectorPlotController::prepareDataForSinglePlot( /** * Prepare data for plotting accumulated data in a tube against time of flight. -* @param detid :: A detector id. The miniplot will display data for a component -* containing the detector -* with this id. +* @param detindex :: A detector index. The miniplot will display data for a component +* containing the detector with this index. * @param x :: Vector of x coordinates (output) * @param y :: Vector of y coordinates (output) * @param err :: Optional pointer to a vector of errors (output) */ -void DetectorPlotController::prepareDataForSumsPlot(int detid, +void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, std::vector &x, std::vector &y, std::vector *err) { const auto &actor = m_instrWidget->getInstrumentActor(); auto ws = actor.getWorkspace(); const auto &componentInfo = actor.getComponentInfo(); - auto detector = actor.getDetectorByDetID(detid); - auto parent = componentInfo.parent(detector); + auto detid = actor.getDetID(detindex); + auto parent = componentInfo.parent(detindex); auto ass = componentInfo.detectorsInSubtree(parent); - size_t wi; - try { - wi = actor.getWorkspaceIndex(detid); - } catch (Mantid::Kernel::Exception::NotFoundError &) { - return; // Detector doesn't have a workspace index relating to it - } + auto wi = actor.getWorkspaceIndex(detindex); size_t imin, imax; actor.getBinMinMaxIndex(wi, imin, imax); @@ -1354,22 +1335,18 @@ void DetectorPlotController::prepareDataForSumsPlot(int detid, const auto &detectorInfo = actor.getDetectorInfo(); for (auto det : ass) { if (componentInfo.isDetector(det)) { - try { - size_t index = actor.getWorkspaceIndex(detectorInfo.detectorIDs()[det]); - const auto &Y = ws->y(index); - std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(), + auto index = actor.getWorkspaceIndex(det); + const auto &Y = ws->y(index); + std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(), + std::plus()); + if (err) { + const auto &E = ws->e(index); + std::vector tmp; + tmp.assign(E.begin() + imin, E.begin() + imax); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), tmp.begin(), + std::multiplies()); + std::transform(err->begin(), err->end(), tmp.begin(), err->begin(), std::plus()); - if (err) { - const auto &E = ws->e(index); - std::vector tmp; - tmp.assign(E.begin() + imin, E.begin() + imax); - std::transform(tmp.begin(), tmp.end(), tmp.begin(), tmp.begin(), - std::multiplies()); - std::transform(err->begin(), err->end(), tmp.begin(), err->begin(), - std::plus()); - } - } catch (Mantid::Kernel::Exception::NotFoundError &) { - continue; // Detector doesn't have a workspace index relating to it } } } @@ -1389,14 +1366,13 @@ void DetectorPlotController::prepareDataForSumsPlot(int detid, * OUT_OF_PLANE_ANGLE * The units can be set with setTubeXUnits(...) method. * @param detid :: A detector id. The miniplot will display data for a component -* containing the detector -* with this id. +* containing the detector with this index. * @param x :: Vector of x coordinates (output) * @param y :: Vector of y coordinates (output) * @param err :: Optional pointer to a vector of errors (output) */ void DetectorPlotController::prepareDataForIntegralsPlot( - int detid, std::vector &x, std::vector &y, + size_t detindex, std::vector &x, std::vector &y, std::vector *err) { #define PREPAREDATAFORINTEGRALSPLOT_RETURN_FAILED \ @@ -1415,16 +1391,9 @@ void DetectorPlotController::prepareDataForIntegralsPlot( const bool bOffsetPsi = (!parameters.empty()) && std::find(parameters.begin(), parameters.end(), "Always") != parameters.end(); - - auto det = actor.getDetectorByDetID(detid); - auto parent = componentInfo.parent(det); + auto parent = componentInfo.parent(detindex); auto ass = componentInfo.detectorsInSubtree(parent); - size_t wi; - try { - wi = actor.getWorkspaceIndex(detid); - } catch (Mantid::Kernel::Exception::NotFoundError &) { - return; // Detector doesn't have a workspace index relating to it - } + auto wi = actor.getWorkspaceIndex(detindex); // imin and imax give the bin integration range size_t imin, imax; actor.getBinMinMaxIndex(wi, imin, imax); @@ -1473,7 +1442,7 @@ void DetectorPlotController::prepareDataForIntegralsPlot( default: xvalue = static_cast(id); } - size_t index = actor.getWorkspaceIndex(id); + auto index = actor.getWorkspaceIndex(det); // get the y-value for detector idet const auto &Y = ws->y(index); double sum = std::accumulate(Y.begin() + imin, Y.begin() + imax, 0); @@ -1546,7 +1515,7 @@ void DetectorPlotController::savePlotToWorkspace() { if (X.empty()) { // label doesn't have any info on how to reproduce the curve: // only the current curve can be saved - QList dets; + std::vector dets; m_tab->getSurface()->getMaskedDetectors(dets); actor.sumDetectors(dets, x, y); unitX = parentWorkspace->getAxis(0)->unit()->unitID(); diff --git a/qt/widgets/instrumentview/src/MaskBinsData.cpp b/qt/widgets/instrumentview/src/MaskBinsData.cpp index 5369b49164e2..216e3b8e299b 100644 --- a/qt/widgets/instrumentview/src/MaskBinsData.cpp +++ b/qt/widgets/instrumentview/src/MaskBinsData.cpp @@ -10,7 +10,7 @@ namespace MantidWidgets { /// Add a range of x values for bin masking. void MaskBinsData::addXRange(double start, double end, - const QList &indices) { + const std::vector &indices) { BinMask range(start, end); range.spectra = indices; m_masks.append(range); @@ -69,12 +69,12 @@ void MaskBinsData::loadFromProject(const std::string &lines) { double start, end; mask >> start >> end; - QList spectra; + std::vector spectra; const size_t numSpectra = mask.values("Spectra").size(); for (size_t i = 0; i < numSpectra; ++i) { - int spectrum; + size_t spectrum; mask >> spectrum; - spectra.append(spectrum); + spectra.push_back(spectrum); } addXRange(start, end, spectra); @@ -90,7 +90,7 @@ std::string MaskBinsData::saveToProject() const { API::TSVSerialiser mask; mask.writeLine("Range") << binMask.start << binMask.end; mask.writeLine("Spectra"); - for (const int spectrum : binMask.spectra) { + for (auto spectrum : binMask.spectra) { mask << spectrum; } tsv.writeSection("Mask", mask.outputLines()); diff --git a/qt/widgets/instrumentview/src/Projection3D.cpp b/qt/widgets/instrumentview/src/Projection3D.cpp index 2b57569753ce..ffabd695cba4 100644 --- a/qt/widgets/instrumentview/src/Projection3D.cpp +++ b/qt/widgets/instrumentview/src/Projection3D.cpp @@ -196,9 +196,9 @@ void Projection3D::setWireframe(bool on) { m_wireframe = on; } /** This seems to be called when the user has selected a rectangle * using the mouse. * -* @param dets :: returns a list of detector IDs selected. +* @param dets :: returns a list of detector Indices selected. */ -void Projection3D::getSelectedDetectors(QList &dets) { +void Projection3D::getSelectedDetectors(std::vector &dets) { dets.clear(); if (!hasSelection()) return; @@ -215,12 +215,11 @@ void Projection3D::getSelectedDetectors(QList &dets) { size_t ndet = m_instrActor->ndetectors(); for (size_t i = 0; i < ndet; ++i) { - detid_t detId = m_instrActor->getDetID(i); V3D pos = m_instrActor->getDetPos(i); m_viewport.transform(pos); if (pos.X() >= xLeft && pos.X() <= xRight && pos.Y() >= yBottom && pos.Y() <= yTop) { - dets.push_back(detId); + dets.push_back(i); } } } @@ -229,9 +228,9 @@ void Projection3D::getSelectedDetectors(QList &dets) { /** Select detectors to mask, using the mouse. * From the Instrument Window's mask tab. * -* @param dets :: returns a list of detector IDs to mask. +* @param dets :: returns a list of detector Indices to mask. */ -void Projection3D::getMaskedDetectors(QList &dets) const { +void Projection3D::getMaskedDetectors(std::vector &dets) const { // find the layer of visible detectors QList pixels = m_maskShapes.getMaskedPixels(); double zmin = 1.0; @@ -264,13 +263,12 @@ void Projection3D::getMaskedDetectors(QList &dets) const { // Find the cached ID and position. This is much faster than getting the // detector. V3D pos = m_instrActor->getDetPos(i); - detid_t id = m_instrActor->getDetID(i); // project pos onto the screen plane m_viewport.transform(pos); if (pos.Z() < zmin || pos.Z() > zmax) continue; if (m_maskShapes.isMasked(pos.X(), pos.Y())) { - dets.push_back(int(id)); + dets.push_back(i); } } } diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 0582419917d9..e48a79721a3a 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -255,7 +255,7 @@ void UnwrappedSurface::componentSelected(size_t componentIndex) { } } -void UnwrappedSurface::getSelectedDetectors(QList &dets) { +void UnwrappedSurface::getSelectedDetectors(std::vector &dets) { if (m_selectRect.isNull()) { return; } @@ -309,26 +309,24 @@ void UnwrappedSurface::getSelectedDetectors(QList &dets) { break; } - const auto &detectorInfo = m_instrActor->getDetectorInfo(); // select detectors with u,v within the allowed boundaries for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { UnwrappedDetector &udet = m_unwrappedDetectors[i]; if (udet.u >= uleft && udet.u <= uright && udet.v >= vbottom && udet.v <= vtop) { - dets.push_back(detectorInfo.detectorIDs()[udet.detIndex]); + dets.push_back(udet.detIndex); } } } -void UnwrappedSurface::getMaskedDetectors(QList &dets) const { +void UnwrappedSurface::getMaskedDetectors(std::vector &dets) const { dets.clear(); if (m_maskShapes.isEmpty()) return; - const auto &detectorInfo = m_instrActor->getDetectorInfo(); for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { const UnwrappedDetector &udet = m_unwrappedDetectors[i]; if (m_maskShapes.isMasked(udet.u, udet.v)) { - dets.append(detectorInfo.detectorIDs()[udet.detIndex]); + dets.push_back(udet.detIndex); } } } From 6713380bbcf38de8eb792cb8ba503e55252a7d26 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 10:40:38 +0000 Subject: [PATCH 048/364] Fix detector color issue #21339 --- .../InstrumentView/InstrumentActor.h | 23 ++--- .../instrumentview/src/InstrumentActor.cpp | 93 +++++++++++-------- .../src/InstrumentWidgetMaskTab.cpp | 4 +- .../src/InstrumentWidgetPickTab.cpp | 74 ++++++++------- 4 files changed, 104 insertions(+), 90 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 84a323c37b8e..01652a1178f1 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -215,11 +215,13 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { calculateIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace); /// Sum the counts in detectors if the workspace has equal bins for all /// spectra - void sumDetectorsUniform(const std::vector &dets, std::vector &x, + void sumDetectorsUniform(const std::vector &dets, + std::vector &x, std::vector &y) const; /// Sum the counts in detectors if the workspace is ragged - void sumDetectorsRagged(const std::vector &dets, std::vector &x, - std::vector &y, size_t size) const; + void sumDetectorsRagged(const std::vector &dets, + std::vector &x, std::vector &y, + size_t size) const; void setupPickColors(); @@ -258,22 +260,13 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { bool m_volumeRender; /// Color map scale type: linear or log GraphOptions::ScaleType m_scaleType; - /// All det ids in the instrument in order of pickIDs, populated by Obj..Actor - /// constructors - mutable std::vector m_detIDs; - /// All non-detector component IDs in order of pickIDs. For any index i a - /// pickID of the component - /// is m_detIDs.size() + i. - mutable std::vector m_nonDetIDs; - - /// All detector positions, in order of pickIDs, populated by Obj..Actor - /// constructors - mutable std::vector m_detPos; /// Position to refer to when detector not found const Mantid::Kernel::V3D m_defaultPos; /// Colors in order of component info - mutable std::vector m_colors; + std::vector m_colors; + std::vector m_monitors; + std::vector m_components; /// Colour of a masked detector GLColor m_maskedColor; /// Colour of a "failed" detector diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index b158d410af2e..ad8f6380cb0c 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -45,6 +45,8 @@ size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) { index += b - 1; return index; } + +GLColor defaultDetectorColor() { return GLColor(200, 200, 200, 1); } } // namespace double InstrumentActor::m_tolerance = 0.00001; @@ -81,6 +83,13 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, "InstrumentActor passed a workspace that isn't a MatrixWorkspace"); const auto &componentInfo = sharedWorkspace->componentInfo(); + const auto &detectorInfo = sharedWorkspace->detectorInfo(); + for (size_t i = 0; i < componentInfo.size(); ++i) { + if (!componentInfo.isDetector(i)) + m_components.push_back(i); + else if (detectorInfo.isMonitor(i)) + m_monitors.push_back(i); + } m_isCompVisible.assign(componentInfo.size(), true); setupPickColors(); @@ -343,15 +352,7 @@ void InstrumentActor::clearMasks() { } std::vector InstrumentActor::getMonitors() const { - const auto &detectorInfo = getDetectorInfo(); - std::vector monitors; - - for (size_t i = 0; i < detectorInfo.size(); i++) { - if (detectorInfo.isMonitor(i)) - monitors.push_back(i); - } - - return monitors; + return m_monitors; } Instrument_const_sptr InstrumentActor::getInstrument() const { @@ -647,15 +648,22 @@ void InstrumentActor::resetColors() { if (detectorInfo.isMasked(detIndex) || masked) { m_colors[detIndex] = m_maskedColor; + continue; } else { auto integratedValue = m_specIntegrs[wi]; - color = m_colorMap.rgb(qwtInterval, integratedValue); + auto color = m_colorMap.rgb(qwtInterval, integratedValue); m_colors[detIndex] = GLColor( qRed(color), qGreen(color), qBlue(color), static_cast(255 * (integratedValue / m_DataMaxScaleValue))); + continue; } + continue; } } + + for (auto comp : m_components) + m_colors[comp] = defaultDetectorColor(); + setupPickColors(); invalidateDisplayLists(); emit colorMapChanged(); @@ -1136,12 +1144,11 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, auto workspace = getWorkspace(); calculateIntegratedSpectra(*workspace); - auto monitors = getMonitors(); std::vector monitorIndices; - monitorIndices.reserve(monitors.size()); - for (auto monitor : monitors) - monitorIndices.push_back(getWorkspaceIndex(monitor)); + monitorIndices.reserve(m_monitors.size()); + for (auto monitor : m_monitors) + monitorIndices.push_back(getWorkspaceIndex(monitor)); // check that there is at least 1 non-monitor spectrum if (monitorIndices.size() == m_specIntegrs.size()) { @@ -1158,30 +1165,40 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, m_DataMinValue = DBL_MAX; m_DataMaxValue = -DBL_MAX; - // Now we need to convert to a vector where each entry is the sum for the - // detector ID at that spot (in integrated_values). - for (size_t i = 0; i < m_specIntegrs.size(); ++i) { - // skip the monitors - if (std::find(monitorIndices.begin(), monitorIndices.end(), i) != - monitorIndices.end()) { - continue; - } - double sum = m_specIntegrs[i]; - if (!std::isfinite(sum)) { - throw std::runtime_error( - "The workspace contains values that cannot be displayed (infinite " - "or NaN).\n" - "Please run ReplaceSpecialValues algorithm for correction."); - } - if (sum < m_DataMinValue) { - m_DataMinValue = sum; - } - if (sum > m_DataMaxValue) { - m_DataMaxValue = sum; - } - if (sum > 0 && sum < m_DataPositiveMinValue) { - m_DataPositiveMinValue = sum; - } + if (std::any_of(m_specIntegrs.begin(), m_specIntegrs.end(), + [](double val) { return !std::isfinite(val); })) + throw std::runtime_error( + "The workspace contains values that cannot be displayed (infinite " + "or NaN).\n" + "Please run ReplaceSpecialValues algorithm for correction."); + + std::vector copy; + copy.reserve(m_specIntegrs.size()); + size_t i = 0; + const auto &spectrumInfo = workspace->spectrumInfo(); + + //Ignore monitors indices if multiple detectors aren't grouped. + std::remove_copy_if( + m_specIntegrs.cbegin(), m_specIntegrs.cend(), std::back_inserter(copy), + [&spectrumInfo, &monitorIndices, &i](double val) { + auto ret = spectrumInfo.spectrumDefinition(i).size() == 0 && + std::find(monitorIndices.begin(), monitorIndices.end(), + i) != monitorIndices.end(); + ++i; + return ret; + }); + + copy.shrink_to_fit(); + + auto res = std::minmax_element(copy.cbegin(), copy.cend()); + m_DataMinValue = *res.first; + m_DataMaxValue = *res.second; + if (m_DataMinValue > 0) + m_DataPositiveMinValue = m_DataMinValue; + else { + auto lb = std::lower_bound(copy.cbegin(), copy.cend(), 0); + if (lb != copy.cend()) + m_DataPositiveMinValue = *lb; } } diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp index 52840b486e78..a70b38899dd4 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetMaskTab.cpp @@ -1130,12 +1130,12 @@ void InstrumentWidgetMaskTab::storeDetectorMask(bool isROI) { actor.invertMaskWorkspace(); } } - for (auto det : dets) + for (auto det : dets) detList.insert(actor.getDetID(det)); if (!detList.empty()) { // try to mask each detector separately and ignore any failure - for (auto det: detList) { + for (auto det : detList) { try { if (isROI && wsFresh) { if (wsMask->isMasked(det)) diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 94941dfb78d7..071aa052538b 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -860,36 +860,36 @@ QString ComponentInfoController::displayDetectorInfo(size_t index) { } QString text; - - // collect info about selected detector and add it to text - const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); - auto detid = actor.getDetID(index); - - text = "Selected detector: " + - QString::fromStdString(componentInfo.name(index)) + "\n"; - text += "Detector ID: " + QString::number(detid) + '\n'; - QString wsIndex; - wsIndex = QString::number(actor.getWorkspaceIndex(index)); - text += "Workspace index: " + wsIndex + '\n'; - Mantid::Kernel::V3D pos = componentInfo.position(index); - text += "xyz: " + QString::number(pos.X()) + "," + - QString::number(pos.Y()) + "," + QString::number(pos.Z()) + '\n'; - double r, t, p; - pos.getSpherical(r, t, p); - text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," + - QString::number(p) + '\n'; - if (componentInfo.hasParent(index)) { - QString textpath; - auto parent = index; - while (componentInfo.hasParent(parent)) { - parent = componentInfo.parent(parent); - textpath = - "/" + QString::fromStdString(componentInfo.name(parent)) + textpath; - } - text += "Component path:" + textpath + "/" + - QString::fromStdString(componentInfo.name(index)) + '\n'; - + + // collect info about selected detector and add it to text + const auto &actor = m_instrWidget->getInstrumentActor(); + const auto &componentInfo = actor.getComponentInfo(); + auto detid = actor.getDetID(index); + + text = "Selected detector: " + + QString::fromStdString(componentInfo.name(index)) + "\n"; + text += "Detector ID: " + QString::number(detid) + '\n'; + QString wsIndex; + wsIndex = QString::number(actor.getWorkspaceIndex(index)); + text += "Workspace index: " + wsIndex + '\n'; + Mantid::Kernel::V3D pos = componentInfo.position(index); + text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) + + "," + QString::number(pos.Z()) + '\n'; + double r, t, p; + pos.getSpherical(r, t, p); + text += "rtp: " + QString::number(r) + "," + QString::number(t) + "," + + QString::number(p) + '\n'; + if (componentInfo.hasParent(index)) { + QString textpath; + auto parent = index; + while (componentInfo.hasParent(parent)) { + parent = componentInfo.parent(parent); + textpath = + "/" + QString::fromStdString(componentInfo.name(parent)) + textpath; + } + text += "Component path:" + textpath + "/" + + QString::fromStdString(componentInfo.name(index)) + '\n'; + const double integrated = actor.getIntegratedCounts(index); const QString counts = integrated == -1.0 ? "N/A" : QString::number(integrated); @@ -1189,7 +1189,8 @@ void DetectorPlotController::plotSingle(size_t detindex) { * LENGTH * PHI * The units can be set with setTubeXUnits(...) method. -* @param detindex :: A detector index. The miniplot will display data for a component +* @param detindex :: A detector index. The miniplot will display data for a +* component * containing the detector * with this id. */ @@ -1215,7 +1216,8 @@ void DetectorPlotController::plotTube(size_t detindex) { /** * Plot the accumulated data in a tube against time of flight. -* @param detindex :: A detector id. The miniplot will display data for a component +* @param detindex :: A detector id. The miniplot will display data for a +* component * containing the detector * with this id. */ @@ -1245,13 +1247,14 @@ void DetectorPlotController::plotTubeSums(size_t detindex) { * LENGTH * PHI * The units can be set with setTubeXUnits(...) method. -* @param detindex :: A detector index. The miniplot will display data for a component +* @param detindex :: A detector index. The miniplot will display data for a +* component * containing the detector * with this id. */ void DetectorPlotController::plotTubeIntegrals(size_t detindex) { const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo =actor.getComponentInfo(); + const auto &componentInfo = actor.getComponentInfo(); std::vector x, y; prepareDataForIntegralsPlot(detindex, x, y); if (x.empty() || y.empty()) { @@ -1305,7 +1308,8 @@ void DetectorPlotController::prepareDataForSinglePlot( /** * Prepare data for plotting accumulated data in a tube against time of flight. -* @param detindex :: A detector index. The miniplot will display data for a component +* @param detindex :: A detector index. The miniplot will display data for a +* component * containing the detector with this index. * @param x :: Vector of x coordinates (output) * @param y :: Vector of y coordinates (output) From 1546a42cf72f34bce1641315b4d753239fe8b334 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 10:49:58 +0000 Subject: [PATCH 049/364] clang-format #21339 --- .../instrumentview/src/InstrumentActor.cpp | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index ad8f6380cb0c..24130c188f27 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -179,9 +179,9 @@ void InstrumentActor::setUpWorkspace( const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); m_detIndex2WsIndex.resize(sharedWorkspace->componentInfo().size()); for (size_t wi = 0; wi < spectrumInfo.size(); wi++) { - const auto &specDef = spectrumInfo.spectrumDefinition(wi); - for (auto info : specDef) - m_detIndex2WsIndex[info.first] = wi; + const auto &specDef = spectrumInfo.spectrumDefinition(wi); + for (auto info : specDef) + m_detIndex2WsIndex[info.first] = wi; } // set some values as the variables will be used @@ -351,9 +351,7 @@ void InstrumentActor::clearMasks() { } } -std::vector InstrumentActor::getMonitors() const { - return m_monitors; -} +std::vector InstrumentActor::getMonitors() const { return m_monitors; } Instrument_const_sptr InstrumentActor::getInstrument() const { Instrument_const_sptr retval; @@ -448,8 +446,8 @@ void InstrumentActor::setIntegrationRange(const double &xmin, * @return The signal */ double InstrumentActor::getIntegratedCounts(size_t index) const { - size_t i = getWorkspaceIndex(index); - return m_specIntegrs.at(i); + size_t i = getWorkspaceIndex(index); + return m_specIntegrs.at(i); } /** @@ -466,7 +464,8 @@ double InstrumentActor::getIntegratedCounts(size_t index) const { * @param size :: (optional input) Size of the output vectors. If not given it * will be determined automatically. */ -void InstrumentActor::sumDetectors(const std::vector &dets, std::vector &x, +void InstrumentActor::sumDetectors(const std::vector &dets, + std::vector &x, std::vector &y, size_t size) const { Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); if (size > ws->blocksize() || size == 0) { @@ -554,7 +553,7 @@ void InstrumentActor::sumDetectorsRagged(const std::vector &dets, size_t nSpec = 0; // number of actual spectra to add // fill in the temp workspace with the data from the detectors - for(auto det: dets) { + for (auto det : dets) { try { size_t index = getWorkspaceIndex(det); dws->setHistogram(nSpec, ws->histogram(index)); @@ -661,9 +660,9 @@ void InstrumentActor::resetColors() { } } - for (auto comp : m_components) + for (auto comp : m_components) m_colors[comp] = defaultDetectorColor(); - + setupPickColors(); invalidateDisplayLists(); emit colorMapChanged(); @@ -1177,7 +1176,7 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, size_t i = 0; const auto &spectrumInfo = workspace->spectrumInfo(); - //Ignore monitors indices if multiple detectors aren't grouped. + // Ignore monitors indices if multiple detectors aren't grouped. std::remove_copy_if( m_specIntegrs.cbegin(), m_specIntegrs.cend(), std::back_inserter(copy), [&spectrumInfo, &monitorIndices, &i](double val) { @@ -1187,7 +1186,7 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, ++i; return ret; }); - + copy.shrink_to_fit(); auto res = std::minmax_element(copy.cbegin(), copy.cend()); @@ -1212,7 +1211,7 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, void InstrumentActor::addMaskBinsData(const std::vector &indices) { std::vector wsIndices; wsIndices.reserve(indices.size()); - for (auto det: indices) + for (auto det : indices) wsIndices.push_back(getWorkspaceIndex(det)); if (!indices.empty()) { m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, wsIndices); From 1a6e576b8ecaf96e2d84c3b7768083a6332202e9 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 11:39:01 +0000 Subject: [PATCH 050/364] fix monitor skipping #21339 --- .../instrumentview/src/InstrumentActor.cpp | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 24130c188f27..912b65227e00 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -1171,33 +1171,23 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, "or NaN).\n" "Please run ReplaceSpecialValues algorithm for correction."); - std::vector copy; - copy.reserve(m_specIntegrs.size()); - size_t i = 0; const auto &spectrumInfo = workspace->spectrumInfo(); - // Ignore monitors indices if multiple detectors aren't grouped. - std::remove_copy_if( - m_specIntegrs.cbegin(), m_specIntegrs.cend(), std::back_inserter(copy), - [&spectrumInfo, &monitorIndices, &i](double val) { - auto ret = spectrumInfo.spectrumDefinition(i).size() == 0 && - std::find(monitorIndices.begin(), monitorIndices.end(), - i) != monitorIndices.end(); - ++i; - return ret; - }); - - copy.shrink_to_fit(); - - auto res = std::minmax_element(copy.cbegin(), copy.cend()); - m_DataMinValue = *res.first; - m_DataMaxValue = *res.second; - if (m_DataMinValue > 0) - m_DataPositiveMinValue = m_DataMinValue; - else { - auto lb = std::lower_bound(copy.cbegin(), copy.cend(), 0); - if (lb != copy.cend()) - m_DataPositiveMinValue = *lb; + // Ignore monitors if multiple detectors aren't grouped. + for (size_t i = 0; i < m_specIntegrs.size(); i++) { + if (spectrumInfo.spectrumDefinition(i).size() == 1 && + std::find(monitorIndices.begin(), monitorIndices.end(), i) != + monitorIndices.end()) + continue; + + auto sum = m_specIntegrs[i]; + + if (sum < m_DataMinValue) + m_DataMinValue = sum; + if (sum > m_DataMaxValue) + m_DataMaxValue = sum; + if (sum > 0 && sum < m_DataPositiveMinValue) + m_DataPositiveMinValue = sum; } } From 645e21663eace2a6bf5c1a5444c1cbafc0839c87 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 11:44:31 +0000 Subject: [PATCH 051/364] revert to name detectorsInSubtree #21339 --- Framework/Beamline/inc/MantidBeamline/ComponentInfo.h | 2 +- Framework/Beamline/src/ComponentInfo.cpp | 4 ++-- Framework/Geometry/src/Instrument/ComponentInfo.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index 382346280f1f..9618c3b5b3da 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -109,7 +109,7 @@ class MANTID_BEAMLINE_DLL ComponentInfo { ComponentInfo &operator=(const ComponentInfo &other) = delete; /// Clone method std::unique_ptr cloneWithoutDetectorInfo() const; - std::vector detectorsInFullSubtree(const size_t componentIndex) const; + std::vector detectorsInSubtree(const size_t componentIndex) const; std::vector componentsInSubtree(const size_t componentIndex) const; const std::vector &children(const size_t componentIndex) const; size_t size() const; diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 07c15525069e..447646dad3d2 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -113,7 +113,7 @@ std::unique_ptr ComponentInfo::cloneWithoutDetectorInfo() const { } std::vector -ComponentInfo::detectorsInFullSubtree(const size_t componentIndex) const { +ComponentInfo::detectorsInSubtree(const size_t componentIndex) const { if (isDetector(componentIndex)) { /* This is a single detector. Just return the corresponding index. * detectorIndex == componentIndex @@ -327,7 +327,7 @@ void ComponentInfo::setPosition(const size_t componentIndex, if (isDetector(componentIndex)) return m_detectorInfo->setPosition(componentIndex, newPosition); - // Optimization: Not using detectorsInFullSubtree and componentsInSubtree to + // Optimization: Not using detectorsInSubtree and componentsInSubtree to // avoid // memory allocations. // Optimization: Split loop over detectors and other components. diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index 81e3aa2b2437..fbf9f7858fc9 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -99,7 +99,7 @@ ComponentInfo::~ComponentInfo() = default; std::vector ComponentInfo::detectorsInSubtree(size_t componentIndex) const { - return m_componentInfo->detectorsInFullSubtree(componentIndex); + return m_componentInfo->detectorsInSubtree(componentIndex); } std::vector From 3137289df2e5287a9e05c5081d3cfbc76d3a705b Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 13:15:44 +0000 Subject: [PATCH 052/364] revert to name detectorsInSubtree in tests #21339 --- Framework/Beamline/test/ComponentInfoTest.h | 10 +++++----- Framework/Geometry/test/InstrumentVisitorTest.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 425beea119f4..f76181a495f2 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -628,19 +628,19 @@ class ComponentInfoTest : public CxxTest::TestSuite { /* Note that detectors are always the first n component indexes! */ - TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(0), + TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(0), std::vector{0}); - TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(1), + TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(1), std::vector{1}); - TS_ASSERT_EQUALS(compInfo.detectorsInFullSubtree(2), + TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(2), std::vector{2}); // Now we have non-detector components TS_ASSERT_EQUALS( - compInfo.detectorsInFullSubtree(4 /*component index of root*/), + compInfo.detectorsInSubtree(4 /*component index of root*/), std::vector({0, 2, 1})); TS_ASSERT_EQUALS( - compInfo.detectorsInFullSubtree(3 /*component index of sub-assembly*/), + compInfo.detectorsInSubtree(3 /*component index of sub-assembly*/), std::vector({0, 2})); } diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index 8dff9f163b69..345f1693ea72 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -165,7 +165,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { TSM_ASSERT_EQUALS("Detector has parent of instrument", compInfo->parent(detectorIndex), instrumentIndex); TSM_ASSERT_EQUALS("Instrument has single detector", - compInfo->detectorsInFullSubtree(instrumentIndex), + compInfo->detectorsInSubtree(instrumentIndex), std::vector{detectorIndex}); } @@ -238,7 +238,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { compInfo->setDetectorInfo(detInfo.get()); detInfo->setComponentInfo(compInfo.get()); - TS_ASSERT_EQUALS(compInfo->detectorsInFullSubtree(3), + TS_ASSERT_EQUALS(compInfo->detectorsInSubtree(3), std::vector{0}); } From 3707c37aa37d7b562b966148991ff5278840d4aa Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 13:17:38 +0000 Subject: [PATCH 053/364] clang-format #21339 --- Framework/Beamline/test/ComponentInfoTest.h | 14 +++++--------- Framework/Geometry/test/InstrumentVisitorTest.h | 3 +-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index f76181a495f2..dcd6c92dc07b 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -628,17 +628,13 @@ class ComponentInfoTest : public CxxTest::TestSuite { /* Note that detectors are always the first n component indexes! */ - TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(0), - std::vector{0}); - TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(1), - std::vector{1}); - TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(2), - std::vector{2}); + TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(0), std::vector{0}); + TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(1), std::vector{1}); + TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(2), std::vector{2}); // Now we have non-detector components - TS_ASSERT_EQUALS( - compInfo.detectorsInSubtree(4 /*component index of root*/), - std::vector({0, 2, 1})); + TS_ASSERT_EQUALS(compInfo.detectorsInSubtree(4 /*component index of root*/), + std::vector({0, 2, 1})); TS_ASSERT_EQUALS( compInfo.detectorsInSubtree(3 /*component index of sub-assembly*/), std::vector({0, 2})); diff --git a/Framework/Geometry/test/InstrumentVisitorTest.h b/Framework/Geometry/test/InstrumentVisitorTest.h index 345f1693ea72..dbd6ecf5eec6 100644 --- a/Framework/Geometry/test/InstrumentVisitorTest.h +++ b/Framework/Geometry/test/InstrumentVisitorTest.h @@ -238,8 +238,7 @@ class InstrumentVisitorTest : public CxxTest::TestSuite { compInfo->setDetectorInfo(detInfo.get()); detInfo->setComponentInfo(compInfo.get()); - TS_ASSERT_EQUALS(compInfo->detectorsInSubtree(3), - std::vector{0}); + TS_ASSERT_EQUALS(compInfo->detectorsInSubtree(3), std::vector{0}); } void test_visitor_component_ranges_check() { From 42102e7a95f384787103eaa15439d44034b6c124 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 18 Jan 2018 15:56:28 +0000 Subject: [PATCH 054/364] Fix workspace setup in InstrumentActor #21399 --- qt/widgets/instrumentview/src/InstrumentActor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 912b65227e00..510905110525 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -1143,11 +1143,10 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, auto workspace = getWorkspace(); calculateIntegratedSpectra(*workspace); - std::vector monitorIndices; + std::set monitorIndices; - monitorIndices.reserve(m_monitors.size()); for (auto monitor : m_monitors) - monitorIndices.push_back(getWorkspaceIndex(monitor)); + monitorIndices.emplace(getWorkspaceIndex(monitor)); // check that there is at least 1 non-monitor spectrum if (monitorIndices.size() == m_specIntegrs.size()) { @@ -1175,7 +1174,8 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, // Ignore monitors if multiple detectors aren't grouped. for (size_t i = 0; i < m_specIntegrs.size(); i++) { - if (spectrumInfo.spectrumDefinition(i).size() == 1 && + const auto &spectrumDefinition = spectrumInfo.spectrumDefinition(i); + if (spectrumDefinition.size() == 1 && std::find(monitorIndices.begin(), monitorIndices.end(), i) != monitorIndices.end()) continue; From bb0a5760b19d2077d2896adec82bbfb7121f4fda Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 22 Jan 2018 07:45:06 +0000 Subject: [PATCH 055/364] fix unused variable #21339 --- qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 071aa052538b..23282e365987 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -1322,7 +1322,6 @@ void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, const auto &actor = m_instrWidget->getInstrumentActor(); auto ws = actor.getWorkspace(); const auto &componentInfo = actor.getComponentInfo(); - auto detid = actor.getDetID(detindex); auto parent = componentInfo.parent(detindex); auto ass = componentInfo.detectorsInSubtree(parent); @@ -1336,7 +1335,6 @@ void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, if (err) err->resize(x.size(), 0); - const auto &detectorInfo = actor.getDetectorInfo(); for (auto det : ass) { if (componentInfo.isDetector(det)) { auto index = actor.getWorkspaceIndex(det); From a54733b317fe2eb69e5d5ddb5b7d76820fcae12f Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 22 Jan 2018 08:45:38 +0000 Subject: [PATCH 056/364] implicit conversion fix #21339 --- qt/widgets/instrumentview/src/MaskBinsData.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qt/widgets/instrumentview/src/MaskBinsData.cpp b/qt/widgets/instrumentview/src/MaskBinsData.cpp index 216e3b8e299b..4b57de8e82fa 100644 --- a/qt/widgets/instrumentview/src/MaskBinsData.cpp +++ b/qt/widgets/instrumentview/src/MaskBinsData.cpp @@ -21,7 +21,10 @@ void MaskBinsData::addXRange(double start, double end, void MaskBinsData::mask(const std::string &wsName) const { for (auto mask = m_masks.begin(); mask != m_masks.end(); ++mask) { auto &spectra = mask->spectra; - std::vector spectraList(spectra.begin(), spectra.end()); + std::vector spectraList(spectra.size()); + std::transform( + spectra.cbegin(), spectra.cend(), spectraList.begin(), + [](const size_t spec) -> int { return static_cast(spec); }); auto alg = Mantid::API::AlgorithmManager::Instance().create("MaskBins", -1); alg->setPropertyValue("InputWorkspace", wsName); alg->setPropertyValue("OutputWorkspace", wsName); From 4eb733ebae16c4d047690e67e1ad4a81130cc093 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 22 Jan 2018 08:59:51 +0000 Subject: [PATCH 057/364] clang-format #21339 --- qt/widgets/instrumentview/src/MaskBinsData.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qt/widgets/instrumentview/src/MaskBinsData.cpp b/qt/widgets/instrumentview/src/MaskBinsData.cpp index 4b57de8e82fa..5c49f576ed9c 100644 --- a/qt/widgets/instrumentview/src/MaskBinsData.cpp +++ b/qt/widgets/instrumentview/src/MaskBinsData.cpp @@ -22,9 +22,9 @@ void MaskBinsData::mask(const std::string &wsName) const { for (auto mask = m_masks.begin(); mask != m_masks.end(); ++mask) { auto &spectra = mask->spectra; std::vector spectraList(spectra.size()); - std::transform( - spectra.cbegin(), spectra.cend(), spectraList.begin(), - [](const size_t spec) -> int { return static_cast(spec); }); + std::transform(spectra.cbegin(), spectra.cend(), spectraList.begin(), + [](const size_t spec) + -> int { return static_cast(spec); }); auto alg = Mantid::API::AlgorithmManager::Instance().create("MaskBins", -1); alg->setPropertyValue("InputWorkspace", wsName); alg->setPropertyValue("OutputWorkspace", wsName); From dd435a494136de2bb12ead0e644d80585569fd38 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 23 Jan 2018 07:32:37 +0000 Subject: [PATCH 058/364] Fix detector info display re #21339 --- .../InstrumentView/InstrumentActor.h | 2 + .../instrumentview/src/InstrumentActor.cpp | 60 ++++++++----- .../src/InstrumentWidgetPickTab.cpp | 85 ++++++++++--------- 3 files changed, 87 insertions(+), 60 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 01652a1178f1..63469849e92d 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -47,6 +47,8 @@ operation for selective rendering of the instrument class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { Q_OBJECT public: + /// Invalid workspace index in detector index to workspace index lookup + static const size_t INVALID_INDEX = std::numeric_limits::max(); /// Constructor InstrumentActor(const QString &wsName, bool autoscaling = true, double scaleMin = 0.0, double scaleMax = 0.0); diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 510905110525..1c26b3b1f7f7 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -177,7 +177,8 @@ void InstrumentActor::setUpWorkspace( } const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); - m_detIndex2WsIndex.resize(sharedWorkspace->componentInfo().size()); + m_detIndex2WsIndex.resize(sharedWorkspace->componentInfo().size(), + INVALID_INDEX); for (size_t wi = 0; wi < spectrumInfo.size(); wi++) { const auto &specDef = spectrumInfo.spectrumDefinition(wi); for (auto info : specDef) @@ -418,7 +419,7 @@ InstrumentActor::getComponentID(size_t pickID) const { } /** Retrieve the workspace index corresponding to a particular detector - * @param id The detector id + * @param index The detector index * @returns The workspace index containing data for this detector * @throws Exception::NotFoundError If the detector is not represented in the * workspace @@ -446,7 +447,9 @@ void InstrumentActor::setIntegrationRange(const double &xmin, * @return The signal */ double InstrumentActor::getIntegratedCounts(size_t index) const { - size_t i = getWorkspaceIndex(index); + auto i = getWorkspaceIndex(index); + if (i == INVALID_INDEX) + return -1.0; return m_specIntegrs.at(i); } @@ -497,6 +500,11 @@ void InstrumentActor::sumDetectorsUniform(const std::vector &dets, bool isDataEmpty = dets.empty(); + auto wi = getWorkspaceIndex(dets[0]); + + if (wi == INVALID_INDEX) + isDataEmpty = true; + if (isDataEmpty) { x.clear(); y.clear(); @@ -505,7 +513,8 @@ void InstrumentActor::sumDetectorsUniform(const std::vector &dets, // find the bins inside the integration range size_t imin, imax; - auto wi = getWorkspaceIndex(dets[0]); + + getBinMinMaxIndex(wi, imin, imax); Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); @@ -515,6 +524,8 @@ void InstrumentActor::sumDetectorsUniform(const std::vector &dets, // sum the spectra for (auto det : dets) { auto index = getWorkspaceIndex(det); + if (index == INVALID_INDEX) + continue; const auto &Y = ws->y(index); std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(), std::plus()); @@ -554,19 +565,17 @@ void InstrumentActor::sumDetectorsRagged(const std::vector &dets, size_t nSpec = 0; // number of actual spectra to add // fill in the temp workspace with the data from the detectors for (auto det : dets) { - try { - size_t index = getWorkspaceIndex(det); - dws->setHistogram(nSpec, ws->histogram(index)); - double xmin = dws->x(nSpec).front(); - double xmax = dws->x(nSpec).back(); - if (xmin < xStart) - xStart = xmin; - if (xmax > xEnd) - xEnd = xmax; - ++nSpec; - } catch (Mantid::Kernel::Exception::NotFoundError &) { - continue; // Detector doesn't have a workspace index relating to it - } + auto index = getWorkspaceIndex(det); + if (index == INVALID_INDEX) + continue; + dws->setHistogram(nSpec, ws->histogram(index)); + double xmin = dws->x(nSpec).front(); + double xmax = dws->x(nSpec).back(); + if (xmin < xStart) + xStart = xmin; + if (xmax > xEnd) + xEnd = xmax; + ++nSpec; } if (nSpec == 0) { @@ -1145,9 +1154,12 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, calculateIntegratedSpectra(*workspace); std::set monitorIndices; - for (auto monitor : m_monitors) - monitorIndices.emplace(getWorkspaceIndex(monitor)); - + for (auto monitor : m_monitors) { + auto index = getWorkspaceIndex(monitor); + if (index == INVALID_INDEX) + continue; + monitorIndices.emplace(index); + } // check that there is at least 1 non-monitor spectrum if (monitorIndices.size() == m_specIntegrs.size()) { // there are only monitors - cannot skip them @@ -1201,8 +1213,12 @@ void InstrumentActor::setDataIntegrationRange(const double &xmin, void InstrumentActor::addMaskBinsData(const std::vector &indices) { std::vector wsIndices; wsIndices.reserve(indices.size()); - for (auto det : indices) - wsIndices.push_back(getWorkspaceIndex(det)); + for (auto det : indices) { + auto index = getWorkspaceIndex(det); + if (index == INVALID_INDEX) + continue; + wsIndices.push_back(index); + } if (!indices.empty()) { m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, wsIndices); auto workspace = getWorkspace(); diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 23282e365987..fa9cbe008acf 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -870,7 +870,8 @@ QString ComponentInfoController::displayDetectorInfo(size_t index) { QString::fromStdString(componentInfo.name(index)) + "\n"; text += "Detector ID: " + QString::number(detid) + '\n'; QString wsIndex; - wsIndex = QString::number(actor.getWorkspaceIndex(index)); + auto ws = actor.getWorkspaceIndex(index); + wsIndex = ws == InstrumentActor::INVALID_INDEX ? "None" : QString::number(ws); text += "Workspace index: " + wsIndex + '\n'; Mantid::Kernel::V3D pos = componentInfo.position(index); text += "xyz: " + QString::number(pos.X()) + "," + QString::number(pos.Y()) + @@ -1290,6 +1291,8 @@ void DetectorPlotController::prepareDataForSinglePlot( const auto &actor = m_instrWidget->getInstrumentActor(); Mantid::API::MatrixWorkspace_const_sptr ws = actor.getWorkspace(); auto wi = actor.getWorkspaceIndex(detindex); + if (wi == InstrumentActor::INVALID_INDEX) + return; // get the data const auto &XPoints = ws->points(wi); const auto &Y = ws->y(wi); @@ -1326,6 +1329,10 @@ void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, auto ass = componentInfo.detectorsInSubtree(parent); auto wi = actor.getWorkspaceIndex(detindex); + + if (wi == InstrumentActor::INVALID_INDEX) + return; + size_t imin, imax; actor.getBinMinMaxIndex(wi, imin, imax); @@ -1338,6 +1345,8 @@ void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, for (auto det : ass) { if (componentInfo.isDetector(det)) { auto index = actor.getWorkspaceIndex(det); + if (index == InstrumentActor::INVALID_INDEX) + continue; const auto &Y = ws->y(index); std::transform(y.begin(), y.end(), Y.begin() + imin, y.begin(), std::plus()); @@ -1396,6 +1405,8 @@ void DetectorPlotController::prepareDataForIntegralsPlot( auto parent = componentInfo.parent(detindex); auto ass = componentInfo.detectorsInSubtree(parent); auto wi = actor.getWorkspaceIndex(detindex); + if (wi == InstrumentActor::INVALID_INDEX) + return; // imin and imax give the bin integration range size_t imin, imax; actor.getBinMinMaxIndex(wi, imin, imax); @@ -1425,43 +1436,41 @@ void DetectorPlotController::prepareDataForIntegralsPlot( const auto &detectorInfo = actor.getDetectorInfo(); for (auto det : ass) { if (componentInfo.isDetector(det)) { - try { - auto id = detectorInfo.detectorIDs()[det]; - // get the x-value for detector idet - double xvalue = 0; - auto pos = detectorInfo.position(det); - switch (m_tubeXUnits) { - case LENGTH: - xvalue = pos.distance(detectorInfo.position(ass[0])); - break; - case PHI: - xvalue = bOffsetPsi ? getPhiOffset(pos, M_PI) : getPhi(pos); - break; - case OUT_OF_PLANE_ANGLE: { - xvalue = getOutOfPlaneAngle(pos, samplePos, normal); - break; - } - default: - xvalue = static_cast(id); - } - auto index = actor.getWorkspaceIndex(det); - // get the y-value for detector idet - const auto &Y = ws->y(index); - double sum = std::accumulate(Y.begin() + imin, Y.begin() + imax, 0); - xymap[xvalue] = sum; - if (err) { - const auto &E = ws->e(index); - std::vector tmp(imax - imin); - // take squares of the errors - std::transform(E.begin() + imin, E.begin() + imax, E.begin() + imin, - tmp.begin(), std::multiplies()); - // sum them - double sum = std::accumulate(tmp.begin(), tmp.end(), 0); - // take sqrt - errmap[xvalue] = sqrt(sum); - } - } catch (Mantid::Kernel::Exception::NotFoundError &) { - continue; // Detector doesn't have a workspace index relating to it + auto id = detectorInfo.detectorIDs()[det]; + // get the x-value for detector idet + double xvalue = 0; + auto pos = detectorInfo.position(det); + switch (m_tubeXUnits) { + case LENGTH: + xvalue = pos.distance(detectorInfo.position(ass[0])); + break; + case PHI: + xvalue = bOffsetPsi ? getPhiOffset(pos, M_PI) : getPhi(pos); + break; + case OUT_OF_PLANE_ANGLE: { + xvalue = getOutOfPlaneAngle(pos, samplePos, normal); + break; + } + default: + xvalue = static_cast(id); + } + auto index = actor.getWorkspaceIndex(det); + if (index == InstrumentActor::INVALID_INDEX) + continue; + // get the y-value for detector idet + const auto &Y = ws->y(index); + double sum = std::accumulate(Y.begin() + imin, Y.begin() + imax, 0); + xymap[xvalue] = sum; + if (err) { + const auto &E = ws->e(index); + std::vector tmp(imax - imin); + // take squares of the errors + std::transform(E.begin() + imin, E.begin() + imax, E.begin() + imin, + tmp.begin(), std::multiplies()); + // sum them + double sum = std::accumulate(tmp.begin(), tmp.end(), 0); + // take sqrt + errmap[xvalue] = sqrt(sum); } } } From d44c221712afe4a5e5b4e25e1123d7a1afe8d989 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 23 Jan 2018 07:44:58 +0000 Subject: [PATCH 059/364] clang-format #21339 --- qt/widgets/instrumentview/src/InstrumentActor.cpp | 1 - qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 1c26b3b1f7f7..7afb8a70034f 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -514,7 +514,6 @@ void InstrumentActor::sumDetectorsUniform(const std::vector &dets, // find the bins inside the integration range size_t imin, imax; - getBinMinMaxIndex(wi, imin, imax); Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace(); diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index fa9cbe008acf..dc0e41ea518f 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -1329,10 +1329,10 @@ void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, auto ass = componentInfo.detectorsInSubtree(parent); auto wi = actor.getWorkspaceIndex(detindex); - + if (wi == InstrumentActor::INVALID_INDEX) return; - + size_t imin, imax; actor.getBinMinMaxIndex(wi, imin, imax); From 66ffdb82b98e1a7e75828264956dcf6cf03f8543 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 24 Jan 2018 15:39:20 +0000 Subject: [PATCH 060/364] review changes #21339 --- .../inc/MantidBeamline/ComponentInfo.h | 1 + Framework/Beamline/src/ComponentInfo.cpp | 25 ++- .../MantidGeometry/Instrument/ComponentInfo.h | 6 +- .../Geometry/src/Instrument/ComponentInfo.cpp | 18 +- .../src/Instrument/InstrumentVisitor.cpp | 1 + Framework/Geometry/src/Objects/CSGObject.cpp | 4 +- Framework/Geometry/test/ComponentInfoTest.h | 6 +- .../InstrumentView/InstrumentActor.h | 14 +- .../InstrumentWidgetRenderTab.h | 2 - .../InstrumentView/Projection3D.h | 4 +- .../InstrumentView/ProjectionSurface.h | 9 +- .../InstrumentView/UnwrappedSurface.h | 4 +- .../instrumentview/src/InstrumentActor.cpp | 207 +++++++++--------- .../src/InstrumentTreeModel.cpp | 12 +- .../src/InstrumentWidgetPickTab.cpp | 14 +- .../src/InstrumentWidgetRenderTab.cpp | 19 +- .../instrumentview/src/PanelsSurface.cpp | 2 +- .../instrumentview/src/Projection3D.cpp | 14 +- .../instrumentview/src/UnwrappedSurface.cpp | 11 +- 19 files changed, 191 insertions(+), 182 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index 9618c3b5b3da..f0903aa40d6e 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -113,6 +113,7 @@ class MANTID_BEAMLINE_DLL ComponentInfo { std::vector componentsInSubtree(const size_t componentIndex) const; const std::vector &children(const size_t componentIndex) const; size_t size() const; + size_t numberOfDetectorsInSubtree(const size_t componentIndex) const; bool isDetector(const size_t componentIndex) const { return componentIndex < m_assemblySortedDetectorIndices->size(); } diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 447646dad3d2..6baef33046eb 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -95,9 +95,12 @@ ComponentInfo::ComponentInfo( "of names as number of components"); } - size_t assemTotalSize = 1; // initialize with root - for (const auto &assem : *m_children) - assemTotalSize += assem.size(); + // Calculate total size of all assemblies + auto assemTotalSize = std::accumulate( + m_children->begin(), m_children->end(), static_cast(1), + [](size_t size, const std::vector &assem) { + return size += assem.size(); + }); if (assemTotalSize != m_size) { throw std::invalid_argument("ComponentInfo should be provided an " @@ -154,20 +157,22 @@ ComponentInfo::componentsInSubtree(const size_t componentIndex) const { const std::vector & ComponentInfo::children(const size_t componentIndex) const { - static std::vector emptyVec; + static const std::vector emptyVec; - if (!isDetector(componentIndex)) { - auto numDets = m_assemblySortedDetectorIndices->size(); - auto index = componentIndex - numDets; - - return (*m_children)[index]; - } + if (!isDetector(componentIndex)) + return (*m_children)[compOffsetIndex(componentIndex)]; return emptyVec; } size_t ComponentInfo::size() const { return m_size; } +size_t +ComponentInfo::numberOfDetectorsInSubtree(const size_t componentIndex) const { + auto range = detectorRangeInSubtree(componentIndex); + return std::distance(range.begin(), range.end()); +} + Eigen::Vector3d ComponentInfo::position(const size_t componentIndex) const { checkNoTimeDependence(); if (isDetector(componentIndex)) { diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index a19b8518f21c..b7d8a6c554e0 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -87,7 +87,7 @@ class MANTID_GEOMETRY_DLL ComponentInfo { const std::map &detectorExclusions) const; public: - struct StructuredPanel { + struct QuadrilateralComponent { size_t topLeft; size_t bottomLeft; size_t bottomRight; @@ -112,7 +112,9 @@ class MANTID_GEOMETRY_DLL ComponentInfo { std::vector componentsInSubtree(size_t componentIndex) const; const std::vector &children(size_t componentIndex) const; size_t size() const; - StructuredPanel structuredPanel(const size_t componentIndex) const; + size_t numberOfDetectorsInSubtree(size_t componentIndex) const; + QuadrilateralComponent + quadrilateralComponent(const size_t componentIndex) const; size_t indexOf(Geometry::IComponent *id) const; size_t indexOfAny(const std::string &name) const; bool isDetector(const size_t componentIndex) const; diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index fbf9f7858fc9..2218752a18de 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -114,9 +114,19 @@ ComponentInfo::children(size_t componentIndex) const { size_t ComponentInfo::size() const { return m_componentInfo->size(); } -ComponentInfo::StructuredPanel -ComponentInfo::structuredPanel(const size_t componentIndex) const { - StructuredPanel corners; +size_t ComponentInfo::numberOfDetectorsInSubtree(size_t componentIndex) const { + return m_componentInfo->numberOfDetectorsInSubtree(componentIndex); +} + +ComponentInfo::QuadrilateralComponent +ComponentInfo::quadrilateralComponent(const size_t componentIndex) const { + auto type = componentType(componentIndex); + if (!(type == Beamline::ComponentType::Structured || + type == Beamline::ComponentType::Rectangular)) + throw std::runtime_error("ComponentType is not Structured or Rectangular " + "in ComponentInfo::quadrilateralComponent."); + + QuadrilateralComponent corners; auto innerRangeComp = m_componentInfo->componentRangeInSubtree(componentIndex); // nSubComponents, subtract off self hence -1. nSubComponents = number of @@ -294,7 +304,7 @@ void ComponentInfo::growBoundingBoxAsRectuangularBank( std::map &mutableDetExclusions, IteratorT &mutableIterator) const { - auto panel = structuredPanel(index); + auto panel = quadrilateralComponent(index); mutableBB.grow(componentBoundingBox(panel.bottomLeft, reference)); mutableBB.grow(componentBoundingBox(panel.topRight, reference)); mutableBB.grow(componentBoundingBox(panel.topLeft, reference)); diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index 308dae8122ea..48475106c4da 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -207,6 +207,7 @@ InstrumentVisitor::registerGenericComponent(const IComponent &component) { // Unless this is the root component this parent is not correct and will be // updated later in the register call of the parent. m_parentComponentIndices->push_back(componentIndex); + // Generic components are not assemblies and do not therefore have children. m_children->emplace_back(std::vector()); return componentIndex; } diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 05e982861d69..9b85ec5e74f9 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -2138,7 +2138,7 @@ size_t CSGObject::numberOfVertices() const { * get vertices */ const std::vector &CSGObject::getTriangleVertices() const { - static std::vector empty; + static const std::vector empty; if (m_handler == nullptr) return empty; return m_handler->getTriangleVertices(); @@ -2148,7 +2148,7 @@ const std::vector &CSGObject::getTriangleVertices() const { * get faces */ const std::vector &CSGObject::getTriangleFaces() const { - static std::vector empty; + static const std::vector empty; if (m_handler == nullptr) return empty; return m_handler->getTriangleFaces(); diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index 40a61854a652..de437e3d77a6 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -107,13 +107,13 @@ std::unique_ptr makeSingleBeamlineComponentInfo( boost::make_shared>(1, scaleFactor); auto names = boost::make_shared>(1); using Mantid::Beamline::ComponentType; - auto isStructuredBank = + auto componentType = boost::make_shared>(1, ComponentType::Generic); auto children = boost::make_shared>>(1); return Kernel::make_unique( detectorIndices, detectorRanges, componentIndices, componentRanges, parentIndices, children, positions, rotations, scaleFactors, - isStructuredBank, names, -1, -1); + componentType, names, -1, -1); } } // namespace @@ -669,7 +669,7 @@ class ComponentInfoTest : public CxxTest::TestSuite { } } - auto panel = componentInfo->structuredPanel(structuredIndex); + auto panel = componentInfo->quadrilateralComponent(structuredIndex); TS_ASSERT_EQUALS(panel.nX, 4); TS_ASSERT_EQUALS(panel.nY, 4); TS_ASSERT_EQUALS(panel.bottomLeft, 0); diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 63469849e92d..6ba1ad4ab82d 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -70,8 +70,8 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { boost::shared_ptr getInstrument() const; /// Get the associated data workspace boost::shared_ptr getWorkspace() const; - const Mantid::Geometry::ComponentInfo &getComponentInfo() const; - const Mantid::Geometry::DetectorInfo &getDetectorInfo() const; + const Mantid::Geometry::ComponentInfo &componentInfo() const; + const Mantid::Geometry::DetectorInfo &detectorInfo() const; /// Get the mask displayed but not yet applied as a MatrxWorkspace boost::shared_ptr getMaskMatrixWorkspace() const; @@ -107,8 +107,6 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { /// Get colormap scale autoscaling status. bool autoscaling() const { return m_autoscaling; } - void showVolumeRender(bool on); - /// Set the integration range. void setIntegrationRange(const double &xmin, const double &xmax); /// Get the minimum data value on the color map scale. @@ -208,6 +206,9 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { void setUpWorkspace( boost::shared_ptr sharedWorkspace, double scaleMin, double scaleMax); + void setupPhysicalInstrument(); + const Mantid::Geometry::ComponentInfo &getComponentInfo() const; + const Mantid::Geometry::DetectorInfo &getDetectorInfo() const; void resetColors(); void loadSettings(); void saveSettings(); @@ -258,8 +259,6 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { bool m_autoscaling; /// Flag to show the guide and other components. Loaded and saved in settings. bool m_showGuides; - /// Flag to enable intensity based transparency. - bool m_volumeRender; /// Color map scale type: linear or log GraphOptions::ScaleType m_scaleType; /// Position to refer to when detector not found @@ -282,6 +281,9 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { // Two display lists for normal rendering and picking mutable GLuint m_displayListId[2]; mutable bool m_useDisplayList[2]; + bool m_isPhysicalInstrument; + std::unique_ptr m_physicalComponentInfo; + std::unique_ptr m_physicalDetectorInfo; }; } // MantidWidgets diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h index 7d55f262f0e5..9b2f1debf9ef 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h @@ -57,7 +57,6 @@ public slots: void setMaxValue(double value, bool apply = true); void setRange(double minValue, double maxValue, bool apply = true); void showAxes(bool on); - void showVolumeRender(bool on); void displayDetectorsOnly(bool yes); void enableGL(bool on); void setColorMapAutoscaling(bool); @@ -114,7 +113,6 @@ private slots: QAction *m_displayDetectorsOnly; QAction *m_wireframe; QAction *m_lighting; - QAction *m_volumeRender; QAction *m_GLView; ///< toggle between OpenGL and simple view QAction *m_UCorrection; QActionGroup *m_precisionActionGroup; diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h index 73d7bab257c8..045a6b751c21 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/Projection3D.h @@ -40,8 +40,8 @@ class Projection3D : public ProjectionSurface { void setWireframe(bool on); void componentSelected(size_t componentIndex) override; - void getSelectedDetectors(std::vector &dets) override; - void getMaskedDetectors(std::vector &dets) const override; + void getSelectedDetectors(std::vector &detIndices) override; + void getMaskedDetectors(std::vector &detIndices) const override; void resize(int, int) override; QString getInfoText() const override; /// Load settings for the 3D projection from a project file diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h index 68dbaaa0d011..8d132d39df1e 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h @@ -112,10 +112,11 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW ProjectionSurface : public QObject { virtual size_t getDetector(int x, int y) const; /// NULL deselects components and selects the whole instrument virtual void componentSelected(size_t componentIndex) = 0; - /// fill in a list of detector ids which were selected by the selction tool - virtual void getSelectedDetectors(std::vector &dets) = 0; - /// fill in a list of detector ids which were masked by the mask shapes - virtual void getMaskedDetectors(std::vector &dets) const = 0; + /// fill in a list of detector indices which were selected by the selction + /// tool + virtual void getSelectedDetectors(std::vector &detIndices) = 0; + /// fill in a list of detector indices which were masked by the mask shapes + virtual void getMaskedDetectors(std::vector &detIndices) const = 0; virtual QString getInfoText() const; /// Change the interaction mode diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h index 3f473ce4f235..82549f3f16ee 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedSurface.h @@ -60,8 +60,8 @@ class UnwrappedSurface : public ProjectionSurface { /** @name Implemented public virtual methods */ //@{ void componentSelected(size_t componentIndex) override; - void getSelectedDetectors(std::vector &dets) override; - void getMaskedDetectors(std::vector &dets) const override; + void getSelectedDetectors(std::vector &detIndices) override; + void getMaskedDetectors(std::vector &detIndices) const override; void setPeaksWorkspace(boost::shared_ptr pws); QString getInfoText() const override; RectF getSurfaceBounds() const override; diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 7afb8a70034f..6d9d3cb025f2 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -15,6 +15,7 @@ #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/ComponentInfo.h" #include "MantidGeometry/Instrument/DetectorInfo.h" +#include "MantidGeometry/Instrument/InstrumentVisitor.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/Exception.h" @@ -47,6 +48,14 @@ size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) { } GLColor defaultDetectorColor() { return GLColor(200, 200, 200, 1); } + +bool isPhysicalView() { + std::string view = Mantid::Kernel::ConfigService::Instance().getString( + "instrument.view.geometry"); + + return boost::iequals("Default", view) || boost::iequals("Physical", view); +} + } // namespace double InstrumentActor::m_tolerance = 0.00001; @@ -70,9 +79,9 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, double scaleMin, double scaleMax) : m_workspace(AnalysisDataService::Instance().retrieveWS( wsName.toStdString())), - m_ragged(true), m_autoscaling(autoscaling), m_volumeRender(false), - m_defaultPos(), m_maskedColor(100, 100, 100), - m_failedColor(200, 200, 200) { + m_ragged(true), m_autoscaling(autoscaling), m_defaultPos(), + m_maskedColor(100, 100, 100), m_failedColor(200, 200, 200), + m_isPhysicalInstrument(false) { // settings loadSettings(); @@ -81,17 +90,16 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, if (!sharedWorkspace) throw std::logic_error( "InstrumentActor passed a workspace that isn't a MatrixWorkspace"); + setupPhysicalInstrument(); - const auto &componentInfo = sharedWorkspace->componentInfo(); - const auto &detectorInfo = sharedWorkspace->detectorInfo(); - for (size_t i = 0; i < componentInfo.size(); ++i) { - if (!componentInfo.isDetector(i)) + for (size_t i = 0; i < componentInfo().size(); ++i) { + if (!componentInfo().isDetector(i)) m_components.push_back(i); - else if (detectorInfo.isMonitor(i)) + else if (detectorInfo().isMonitor(i)) m_monitors.push_back(i); } - m_isCompVisible.assign(componentInfo.size(), true); + m_isCompVisible.assign(componentInfo().size(), true); setupPickColors(); // set up the color map @@ -104,11 +112,7 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, setUpWorkspace(sharedWorkspace, scaleMin, scaleMax); // If the instrument is empty, maybe only having the sample and source - auto nelements = componentInfo.size(); - if ((nelements == 0) || (nelements == 1 && (componentInfo.hasSource() || - componentInfo.hasSample())) || - (nelements == 2 && componentInfo.hasSource() && - componentInfo.hasSample())) { + if (detectorInfo().size() == 0) { QMessageBox::warning(nullptr, "MantidPlot - Warning", "This instrument appears to contain no detectors", "OK"); @@ -177,8 +181,7 @@ void InstrumentActor::setUpWorkspace( } const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); - m_detIndex2WsIndex.resize(sharedWorkspace->componentInfo().size(), - INVALID_INDEX); + m_detIndex2WsIndex.resize(componentInfo().size(), INVALID_INDEX); for (size_t wi = 0; wi < spectrumInfo.size(); wi++) { const auto &specDef = spectrumInfo.spectrumDefinition(wi); for (auto info : specDef) @@ -201,10 +204,25 @@ void InstrumentActor::setUpWorkspace( m_ragged = !wsValidator.isValid(sharedWorkspace).empty(); } +void InstrumentActor::setupPhysicalInstrument() { + auto sharedWorkspace = getWorkspace(); + Mantid::Kernel::ReadLock _lock(*sharedWorkspace); + + if (isPhysicalView()) { + auto instr = sharedWorkspace->getInstrument()->getPhysicalInstrument(); + if (instr) { + m_isPhysicalInstrument = true; + auto infos = InstrumentVisitor::makeWrappers(*instr); + m_physicalComponentInfo = std::move(infos.first); + m_physicalDetectorInfo = std::move(infos.second); + } + } +} + void InstrumentActor::setComponentVisible(size_t componentIndex) { setChildVisibility(false); - const auto &componentInfo = getComponentInfo(); - auto children = componentInfo.componentsInSubtree(componentIndex); + const auto &compInfo = componentInfo(); + auto children = compInfo.componentsInSubtree(componentIndex); m_isCompVisible[componentIndex] = true; for (auto child : children) m_isCompVisible[child] = true; @@ -237,8 +255,8 @@ MatrixWorkspace_const_sptr InstrumentActor::getWorkspace() const { void InstrumentActor::getBoundingBox(Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound) const { - const auto &componentInfo = getComponentInfo(); - auto bb = componentInfo.boundingBox(componentInfo.root()); + const auto &compInfo = componentInfo(); + auto bb = compInfo.boundingBox(compInfo.root()); minBound = bb.minPoint(); maxBound = bb.maxPoint(); } @@ -355,30 +373,18 @@ void InstrumentActor::clearMasks() { std::vector InstrumentActor::getMonitors() const { return m_monitors; } Instrument_const_sptr InstrumentActor::getInstrument() const { - Instrument_const_sptr retval; - - // Look to see if we have set the property in the properties file - // to define our 'default' view - std::string view = Mantid::Kernel::ConfigService::Instance().getString( - "instrument.view.geometry"); - auto sharedWorkspace = getWorkspace(); Mantid::Kernel::ReadLock _lock(*sharedWorkspace); - if (boost::iequals("Default", view) || boost::iequals("Physical", view)) { + if (isPhysicalView()) { // First see if there is a 'physical' instrument available. Use it if there // is. - retval = sharedWorkspace->getInstrument()->getPhysicalInstrument(); - } else if (boost::iequals("Neutronic", view)) { - retval = sharedWorkspace->getInstrument(); + auto instr = sharedWorkspace->getInstrument()->getPhysicalInstrument(); + if (instr) + return instr; } - if (!retval) { - // Otherwise get hold of the 'main' instrument and use that - retval = sharedWorkspace->getInstrument(); - } - - return retval; + return sharedWorkspace->getInstrument(); } const MantidColorMap &InstrumentActor::getColorMap() const { @@ -386,12 +392,12 @@ const MantidColorMap &InstrumentActor::getColorMap() const { } size_t InstrumentActor::getDetectorByDetID(Mantid::detid_t detID) const { - const auto &detectorInfo = getDetectorInfo(); - return detectorInfo.indexOf(detID); + const auto &detInfo = detectorInfo(); + return detInfo.indexOf(detID); } Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const { - const auto &detInfo = getDetectorInfo(); + const auto &detInfo = detectorInfo(); if (pickID < detInfo.size()) { return detInfo.detectorIDs()[pickID]; } @@ -401,6 +407,7 @@ Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const { QList InstrumentActor::getDetIDs(const std::vector &dets) const { QList detIDs; + detIDs.reserve(dets.size()); for (auto det : dets) detIDs.append(getDetID(det)); return detIDs; @@ -412,9 +419,9 @@ InstrumentActor::getDetIDs(const std::vector &dets) const { Mantid::Geometry::ComponentID InstrumentActor::getComponentID(size_t pickID) const { auto compID = Mantid::Geometry::ComponentID(); - const auto &componentInfo = getComponentInfo(); - if (pickID < componentInfo.size()) - compID = componentInfo.componentID(pickID)->getComponentID(); + const auto &compInfo = componentInfo(); + if (pickID < compInfo.size()) + compID = compInfo.componentID(pickID)->getComponentID(); return compID; } @@ -634,37 +641,32 @@ void InstrumentActor::sumDetectorsRagged(const std::vector &dets, void InstrumentActor::resetColors() { QwtDoubleInterval qwtInterval(m_DataMinScaleValue, m_DataMaxScaleValue); auto sharedWorkspace = getWorkspace(); - const auto &componentInfo = sharedWorkspace->componentInfo(); - const auto &detectorInfo = sharedWorkspace->detectorInfo(); + const auto &compInfo = componentInfo(); + const auto &detInfo = detectorInfo(); const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); auto color = m_colorMap.rgb(qwtInterval, 0); - m_colors.assign(componentInfo.size(), + m_colors.assign(compInfo.size(), GLColor(qRed(color), qGreen(color), qBlue(color), 1)); + auto invalidColor = GLColor(100, 100, 100, 1); IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists(); - const auto &detectorIDs = detectorInfo.detectorIDs(); - for (size_t wi = 0; wi < m_specIntegrs.size(); ++wi) { - const auto &specDef = spectrumInfo.spectrumDefinition(wi); - bool masked = false; - - for (const auto &det : specDef) { - auto detIndex = det.first; - - if (mask) - masked = mask->isMasked(detectorIDs[detIndex]); - - if (detectorInfo.isMasked(detIndex) || masked) { - m_colors[detIndex] = m_maskedColor; - continue; - } else { - auto integratedValue = m_specIntegrs[wi]; + const auto &detectorIDs = detInfo.detectorIDs(); + for (size_t det = 0; det < detInfo.size(); ++det) { + auto masked = false; + + if (mask) + masked = mask->isMasked(detectorIDs[det]); + if (detInfo.isMasked(det) || masked) + m_colors[det] = m_maskedColor; + else { + auto integratedValue = getIntegratedCounts(det); + if (integratedValue > -1) { auto color = m_colorMap.rgb(qwtInterval, integratedValue); - m_colors[detIndex] = GLColor( + m_colors[det] = GLColor( qRed(color), qGreen(color), qBlue(color), static_cast(255 * (integratedValue / m_DataMaxScaleValue))); - continue; - } - continue; + } else + m_colors[det] = invalidColor; } } @@ -721,14 +723,13 @@ void InstrumentActor::draw(bool picking) const { } void InstrumentActor::doDraw(bool picking) const { - const auto &componentInfo = getComponentInfo(); - for (size_t i = 0; i < componentInfo.size(); ++i) { - if ((!componentInfo.isDetector(i) && !m_showGuides) || - componentInfo.componentType(i) == - Beamline::ComponentType::OutlineComposite) + const auto &compInfo = componentInfo(); + for (size_t i = 0; i < compInfo.size(); ++i) { + if ((!compInfo.isDetector(i) && !m_showGuides) || + compInfo.componentType(i) == Beamline::ComponentType::OutlineComposite) continue; - if (componentInfo.hasValidShape(i)) { + if (compInfo.hasValidShape(i)) { if (m_isCompVisible[i]) { if (picking) m_pickColors[i].paint(); @@ -736,12 +737,12 @@ void InstrumentActor::doDraw(bool picking) const { m_colors[i].paint(); glPushMatrix(); // Translate - auto pos = componentInfo.position(i); + auto pos = compInfo.position(i); if (!pos.nullVector()) glTranslated(pos[0], pos[1], pos[2]); // Rotate - auto rot = componentInfo.rotation(i); + auto rot = compInfo.rotation(i); if (!rot.isNull()) { double deg, ax0, ax1, ax2; rot.getAngleAxis(deg, ax0, ax1, ax2); @@ -749,16 +750,11 @@ void InstrumentActor::doDraw(bool picking) const { } // Scale - auto scale = componentInfo.scaleFactor(i); + auto scale = compInfo.scaleFactor(i); if (scale != Kernel::V3D(1, 1, 1)) glScaled(scale[0], scale[1], scale[2]); - if (m_volumeRender) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - componentInfo.shape(i).draw(); + compInfo.shape(i).draw(); glPopMatrix(); } } @@ -778,10 +774,10 @@ void InstrumentActor::loadColorMap(const QString &fname, bool reset_colors) { //------------------------------------------------------------------------------ void InstrumentActor::setupPickColors() { - const auto &componentInfo = getComponentInfo(); - m_pickColors.resize(componentInfo.size()); + const auto &compInfo = componentInfo(); + m_pickColors.resize(compInfo.size()); - for (size_t i = 0; i < componentInfo.size(); ++i) { + for (size_t i = 0; i < compInfo.size(); ++i) { m_pickColors[i] = makePickColor(i); } } @@ -793,7 +789,7 @@ void InstrumentActor::setupPickColors() { * @return the real-space position of the detector */ const Mantid::Kernel::V3D InstrumentActor::getDetPos(size_t pickID) const { - const auto &detInfo = getDetectorInfo(); + const auto &detInfo = detectorInfo(); if (pickID < detInfo.size()) { return detInfo.position(pickID); } @@ -801,7 +797,7 @@ const Mantid::Kernel::V3D InstrumentActor::getDetPos(size_t pickID) const { } const std::vector &InstrumentActor::getAllDetIDs() const { - const auto &detInfo = getDetectorInfo(); + const auto &detInfo = detectorInfo(); return detInfo.detectorIDs(); } @@ -869,7 +865,7 @@ bool InstrumentActor::wholeRange() const { m_BinMaxValue == m_WkspBinMaxValue; } -size_t InstrumentActor::ndetectors() const { return getDetectorInfo().size(); } +size_t InstrumentActor::ndetectors() const { return detectorInfo().size(); } /** * Set autoscaling of the y axis. If autoscaling is on the minValue() and @@ -889,11 +885,6 @@ void InstrumentActor::setAutoscaling(bool on) { } } -void InstrumentActor::showVolumeRender(bool on) { - m_volumeRender = on; - resetColors(); -} - /** * Extracts the current applied mask to the main workspace * @returns the current applied mask to the main workspace @@ -1231,9 +1222,9 @@ bool InstrumentActor::hasBinMask() const { return !m_maskBinsData.isEmpty(); } QString InstrumentActor::getParameterInfo(size_t index) const { auto instr = getInstrument(); - const auto &componentInfo = getComponentInfo(); + const auto &compInfo = componentInfo(); - auto compID = componentInfo.componentID(index); + auto compID = compInfo.componentID(index); auto comp = instr->getComponentByID(compID); QString text = ""; @@ -1293,8 +1284,8 @@ std::string InstrumentActor::getDefaultView() const { } std::string InstrumentActor::getInstrumentName() const { - const auto &componentInfo = getComponentInfo(); - return componentInfo.name(componentInfo.root()); + const auto &compInfo = componentInfo(); + return compInfo.name(compInfo.root()); } std::vector @@ -1336,13 +1327,12 @@ void InstrumentActor::loadFromProject(const std::string &lines) { } } -const Mantid::Geometry::ComponentInfo & -InstrumentActor::getComponentInfo() const { - return getWorkspace()->componentInfo(); +const Mantid::Geometry::ComponentInfo &InstrumentActor::componentInfo() const { + return getComponentInfo(); } -const Mantid::Geometry::DetectorInfo &InstrumentActor::getDetectorInfo() const { - return getWorkspace()->detectorInfo(); +const Mantid::Geometry::DetectorInfo &InstrumentActor::detectorInfo() const { + return getDetectorInfo(); } void InstrumentActor::invalidateDisplayLists() const { @@ -1370,5 +1360,20 @@ size_t InstrumentActor::decodePickColor(const QRgb &c) { static_cast(qBlue(c))); } +const Mantid::Geometry::ComponentInfo & +InstrumentActor::getComponentInfo() const { + if (m_isPhysicalInstrument) + return *m_physicalComponentInfo; + else + return getWorkspace()->componentInfo(); +} + +const Mantid::Geometry::DetectorInfo &InstrumentActor::getDetectorInfo() const { + if (m_isPhysicalInstrument) + return *m_physicalDetectorInfo; + else + return getWorkspace()->detectorInfo(); +} + } // namespace MantidWidgets } // namespace MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp index 973a8f1d656d..e9be7feccfb9 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeModel.cpp @@ -22,7 +22,7 @@ InstrumentTreeModel::InstrumentTreeModel(const InstrumentWidget *instrWidget, QObject *parent) : QAbstractItemModel(parent), m_instrWidget(instrWidget) { const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + m_instrWidget->getInstrumentActor().componentInfo(); m_componentIndices.resize(componentInfo.size()); std::iota(m_componentIndices.begin(), m_componentIndices.end(), 0); } @@ -43,7 +43,7 @@ int InstrumentTreeModel::columnCount(const QModelIndex &parent) const { return 1; const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + m_instrWidget->getInstrumentActor().componentInfo(); auto index = extractIndex(parent); if (componentInfo.children(index).size() > 0) return 1; @@ -60,7 +60,7 @@ QVariant InstrumentTreeModel::data(const QModelIndex &index, int role) const { return QVariant(); const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + m_instrWidget->getInstrumentActor().componentInfo(); if (!index.isValid()) // not valid has to return the root node return QString::fromStdString(componentInfo.name(componentInfo.root())); @@ -96,7 +96,7 @@ QVariant InstrumentTreeModel::headerData(int section, QModelIndex InstrumentTreeModel::index(int row, int column, const QModelIndex &parent) const { const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + m_instrWidget->getInstrumentActor().componentInfo(); if (!parent.isValid()) { // invalid parent, has to be the root node i.e // instrument return createIndex(row, column, &m_componentIndices[componentInfo.root()]); @@ -120,7 +120,7 @@ QModelIndex InstrumentTreeModel::parent(const QModelIndex &index) const { return QModelIndex(); const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + m_instrWidget->getInstrumentActor().componentInfo(); auto compIndex = extractIndex(index); if (compIndex == componentInfo.root()) @@ -152,7 +152,7 @@ int InstrumentTreeModel::rowCount(const QModelIndex &parent) const { return 1; const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + m_instrWidget->getInstrumentActor().componentInfo(); auto index = extractIndex(parent); const auto &children = componentInfo.children(index); if (children.size() > 0) diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index dc0e41ea518f..57054b8a0cd5 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -54,21 +54,20 @@ namespace MantidWidgets { using namespace boost::math; namespace { +// Get the phi angle between the detector with reference to the origin +// Makes assumptions about beam direction. Legacy code and not robust. double getPhi(const Mantid::Kernel::V3D &pos) { return std::atan2(pos[1], pos[0]); } +// Calculate the phi angle between detector and beam, and then offset. +// Makes assumptions about beam direction. Legacy code and not robust. double getPhiOffset(const Mantid::Kernel::V3D &pos, const double offset) { double avgPos = getPhi(pos); return avgPos < 0 ? -(offset + avgPos) : offset - avgPos; } } // namespace -/// to be used in std::transform -struct Sqrt { - double operator()(double x) { return sqrt(x); } -}; - /** * Constructor. * @param instrWidget :: Parent InstrumentWidget. @@ -1200,7 +1199,7 @@ void DetectorPlotController::plotTube(size_t detindex) { const auto &componentInfo = actor.getComponentInfo(); if (componentInfo.hasParent(detindex) && - componentInfo.detectorsInSubtree(detindex).size() > 0) { + componentInfo.numberOfDetectorsInSubtree(detindex) > 0) { if (m_plotType == TubeSum) // plot sums over detectors vs time bins { plotTubeSums(detindex); @@ -1363,7 +1362,8 @@ void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, } if (err) - std::transform(err->begin(), err->end(), err->begin(), Sqrt()); + std::transform(err->begin(), err->end(), err->begin(), + [](double val) { return sqrt(val); }); } /** diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp index 606959305209..f491739ba5f2 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetRenderTab.cpp @@ -141,11 +141,6 @@ InstrumentWidgetRenderTab::InstrumentWidgetRenderTab( m_displayAxes->setCheckable(true); m_displayAxes->setChecked(true); connect(m_displayAxes, SIGNAL(toggled(bool)), this, SLOT(showAxes(bool))); - m_volumeRender = new QAction("VolumeRender", this); - m_volumeRender->setCheckable(true); - m_volumeRender->setChecked(false); - connect(m_volumeRender, SIGNAL(toggled(bool)), this, - SLOT(showVolumeRender(bool))); m_displayDetectorsOnly = new QAction("Display Detectors Only", this); m_displayDetectorsOnly->setCheckable(true); m_displayDetectorsOnly->setChecked(true); @@ -178,7 +173,6 @@ InstrumentWidgetRenderTab::InstrumentWidgetRenderTab( displaySettingsMenu->addSeparator(); displaySettingsMenu->addAction(m_displayAxes); displaySettingsMenu->addAction(m_displayDetectorsOnly); - displaySettingsMenu->addAction(m_volumeRender); displaySettingsMenu->addAction(m_wireframe); displaySettingsMenu->addAction(m_lighting); displaySettingsMenu->addAction(m_GLView); @@ -449,13 +443,6 @@ void InstrumentWidgetRenderTab::showAxes(bool on) { m_displayAxes->blockSignals(false); } -void InstrumentWidgetRenderTab::showVolumeRender(bool on) { - m_instrWidget->getInstrumentActor().showVolumeRender(on); - m_volumeRender->blockSignals(true); - m_volumeRender->setChecked(on); - m_volumeRender->blockSignals(false); -} - /** * Toggle display of guide and other non-detector components. * @@ -746,7 +733,6 @@ MantidQt::MantidWidgets::InstrumentWidgetRenderTab::saveToProject() const { tab.writeLine("AxesView") << mAxisCombo->currentIndex(); tab.writeLine("AutoScaling") << m_autoscaling->isChecked(); tab.writeLine("DisplayAxes") << m_displayAxes->isChecked(); - tab.writeLine("VolumeRender") << m_volumeRender->isChecked(); tab.writeLine("FlipView") << m_flipCheckBox->isChecked(); tab.writeLine("DisplayDetectorsOnly") << m_displayDetectorsOnly->isChecked(); tab.writeLine("DisplayWireframe") << m_wireframe->isChecked(); @@ -784,7 +770,7 @@ void InstrumentWidgetRenderTab::loadFromProject(const std::string &lines) { tsv >> tabLines; API::TSVSerialiser tab(tabLines); - bool autoScaling, displayAxes, volumeRender, flipView, displayDetectorsOnly, + bool autoScaling, displayAxes, flipView, displayDetectorsOnly, displayWireframe, displayLighting, useOpenGL, useUCorrection; int axesView; @@ -794,8 +780,6 @@ void InstrumentWidgetRenderTab::loadFromProject(const std::string &lines) { tab >> autoScaling; tab.selectLine("DisplayAxes"); tab >> displayAxes; - tab.selectLine("VolumeRender"); - tab >> volumeRender; tab.selectLine("FlipView"); tab >> flipView; tab.selectLine("DisplayDetectorsOnly"); @@ -812,7 +796,6 @@ void InstrumentWidgetRenderTab::loadFromProject(const std::string &lines) { mAxisCombo->setCurrentIndex(axesView); m_autoscaling->setChecked(autoScaling); m_displayAxes->setChecked(displayAxes); - m_volumeRender->setChecked(volumeRender); m_flipCheckBox->setChecked(flipView); m_displayDetectorsOnly->setChecked(displayDetectorsOnly); m_wireframe->setChecked(displayWireframe); diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 27192c9cf1f4..140303890cd7 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -47,7 +47,7 @@ void setupBasisAxes(const Mantid::Kernel::V3D &zaxis, std::vector retrievePanelCorners(const Mantid::Geometry::ComponentInfo &componentInfo, size_t rootIndex) { - auto panel = componentInfo.structuredPanel(rootIndex); + auto panel = componentInfo.quadrilateralComponent(rootIndex); return {componentInfo.position(panel.bottomLeft), componentInfo.position(panel.bottomRight), componentInfo.position(panel.topRight), diff --git a/qt/widgets/instrumentview/src/Projection3D.cpp b/qt/widgets/instrumentview/src/Projection3D.cpp index ffabd695cba4..c136fef02cd3 100644 --- a/qt/widgets/instrumentview/src/Projection3D.cpp +++ b/qt/widgets/instrumentview/src/Projection3D.cpp @@ -196,10 +196,10 @@ void Projection3D::setWireframe(bool on) { m_wireframe = on; } /** This seems to be called when the user has selected a rectangle * using the mouse. * -* @param dets :: returns a list of detector Indices selected. +* @param detIndices :: returns a list of detector Indices selected. */ -void Projection3D::getSelectedDetectors(std::vector &dets) { - dets.clear(); +void Projection3D::getSelectedDetectors(std::vector &detIndices) { + detIndices.clear(); if (!hasSelection()) return; double xmin, xmax, ymin, ymax, zmin, zmax; @@ -219,7 +219,7 @@ void Projection3D::getSelectedDetectors(std::vector &dets) { m_viewport.transform(pos); if (pos.X() >= xLeft && pos.X() <= xRight && pos.Y() >= yBottom && pos.Y() <= yTop) { - dets.push_back(i); + detIndices.push_back(i); } } } @@ -230,7 +230,7 @@ void Projection3D::getSelectedDetectors(std::vector &dets) { * * @param dets :: returns a list of detector Indices to mask. */ -void Projection3D::getMaskedDetectors(std::vector &dets) const { +void Projection3D::getMaskedDetectors(std::vector &detIndices) const { // find the layer of visible detectors QList pixels = m_maskShapes.getMaskedPixels(); double zmin = 1.0; @@ -255,7 +255,7 @@ void Projection3D::getMaskedDetectors(std::vector &dets) const { } // find masked detector in that layer - dets.clear(); + detIndices.clear(); if (m_maskShapes.isEmpty()) return; size_t ndet = m_instrActor->ndetectors(); @@ -268,7 +268,7 @@ void Projection3D::getMaskedDetectors(std::vector &dets) const { if (pos.Z() < zmin || pos.Z() > zmax) continue; if (m_maskShapes.isMasked(pos.X(), pos.Y())) { - dets.push_back(i); + detIndices.push_back(i); } } } diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index e48a79721a3a..6645737d2b8b 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -255,7 +255,7 @@ void UnwrappedSurface::componentSelected(size_t componentIndex) { } } -void UnwrappedSurface::getSelectedDetectors(std::vector &dets) { +void UnwrappedSurface::getSelectedDetectors(std::vector &detIndices) { if (m_selectRect.isNull()) { return; } @@ -314,19 +314,20 @@ void UnwrappedSurface::getSelectedDetectors(std::vector &dets) { UnwrappedDetector &udet = m_unwrappedDetectors[i]; if (udet.u >= uleft && udet.u <= uright && udet.v >= vbottom && udet.v <= vtop) { - dets.push_back(udet.detIndex); + detIndices.push_back(udet.detIndex); } } } -void UnwrappedSurface::getMaskedDetectors(std::vector &dets) const { - dets.clear(); +void UnwrappedSurface::getMaskedDetectors( + std::vector &detIndices) const { + detIndices.clear(); if (m_maskShapes.isEmpty()) return; for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { const UnwrappedDetector &udet = m_unwrappedDetectors[i]; if (m_maskShapes.isMasked(udet.u, udet.v)) { - dets.push_back(udet.detIndex); + detIndices.push_back(udet.detIndex); } } } From c75ae42e764bb1811a8d35b6c730eb60a8b74319 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 24 Jan 2018 15:45:43 +0000 Subject: [PATCH 061/364] cppcheck fix #21339 --- qt/widgets/instrumentview/src/InstrumentActor.cpp | 1 - qt/widgets/instrumentview/src/UnwrappedCylinder.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 6d9d3cb025f2..8dfc4ca22faf 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -643,7 +643,6 @@ void InstrumentActor::resetColors() { auto sharedWorkspace = getWorkspace(); const auto &compInfo = componentInfo(); const auto &detInfo = detectorInfo(); - const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); auto color = m_colorMap.rgb(qwtInterval, 0); m_colors.assign(compInfo.size(), GLColor(qRed(color), qGreen(color), qBlue(color), 1)); diff --git a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp index 8d697506b4f7..c7c8e5cacd04 100644 --- a/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedCylinder.cpp @@ -39,7 +39,7 @@ void UnwrappedCylinder::rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat &R) const { // direction in which to look Mantid::Kernel::V3D eye; - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); // rotation from the global axes to those where // the z axis points to the detector Mantid::Kernel::Quat R1; From 2a8fdea1adcda0f02fd498949498e1eabe1053f1 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 25 Jan 2018 07:40:10 +0000 Subject: [PATCH 062/364] InstrumentActor::componentInfo fix and unit tests #21339 --- Framework/Geometry/test/ComponentInfoTest.h | 38 +++++++++++++------ .../src/InstrumentTreeWidget.cpp | 2 +- .../instrumentview/src/InstrumentWidget.cpp | 2 +- .../src/InstrumentWidgetPickTab.cpp | 22 +++++------ .../instrumentview/src/PanelsSurface.cpp | 16 ++++---- .../instrumentview/src/Projection3D.cpp | 2 +- .../instrumentview/src/RotationSurface.cpp | 8 ++-- .../instrumentview/src/UnwrappedSphere.cpp | 2 +- .../instrumentview/src/UnwrappedSurface.cpp | 8 ++-- 9 files changed, 57 insertions(+), 43 deletions(-) diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index de437e3d77a6..325723019690 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -651,24 +651,38 @@ class ComponentInfoTest : public CxxTest::TestSuite { detectorPos); } - void test_StructuredPanel_for_single_rectangular_bank() { + void test_throws_if_ComponentType_is_not_Quadrilateral() { auto instrument = ComponentCreationHelper::createTestInstrumentRectangular2(1, 4); auto wrappers = InstrumentVisitor::makeWrappers(*instrument); const auto &componentInfo = std::get<0>(wrappers); - // find structured panel - size_t structuredIndex = 0; - for (size_t i = componentInfo->root(); i > 0; --i) { - if (componentInfo->componentType(i) == - Mantid::Beamline::ComponentType::Structured || - componentInfo->componentType(i) == - Mantid::Beamline::ComponentType::Rectangular) { - structuredIndex = i; - break; - } - } + // find quadrilateral component + size_t structuredIndex = componentInfo->root() - 3; + // Does not throw for valid index + TS_ASSERT_THROWS_NOTHING( + componentInfo->quadrilateralComponent(structuredIndex)); + // Throws for other non quadrilateral component + TS_ASSERT_THROWS( + componentInfo->quadrilateralComponent(componentInfo->root() - 1), + std::runtime_error); + // Throws for root + TS_ASSERT_THROWS( + componentInfo->quadrilateralComponent(componentInfo->root()), + std::runtime_error); + // Throws for detector + TS_ASSERT_THROWS(componentInfo->quadrilateralComponent(0), + std::runtime_error); + } + + void test_QuadrilateralComponent_for_single_rectangular_bank() { + auto instrument = + ComponentCreationHelper::createTestInstrumentRectangular2(1, 4); + auto wrappers = InstrumentVisitor::makeWrappers(*instrument); + const auto &componentInfo = std::get<0>(wrappers); + // find quadrilateral component + size_t structuredIndex = componentInfo->root() - 3; auto panel = componentInfo->quadrilateralComponent(structuredIndex); TS_ASSERT_EQUALS(panel.nX, 4); TS_ASSERT_EQUALS(panel.nY, 4); diff --git a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp index 60250559ade7..b1413de658ea 100644 --- a/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp +++ b/qt/widgets/instrumentview/src/InstrumentTreeWidget.cpp @@ -36,7 +36,7 @@ void InstrumentTreeWidget::getSelectedBoundingBox(const QModelIndex &index, double &zmax, double &xmin, double &ymin, double &zmin) { const auto &componentInfo = - m_instrWidget->getInstrumentActor().getComponentInfo(); + m_instrWidget->getInstrumentActor().componentInfo(); auto compIndex = InstrumentTreeModel::extractIndex(index); auto bb = componentInfo.boundingBox(compIndex); diff --git a/qt/widgets/instrumentview/src/InstrumentWidget.cpp b/qt/widgets/instrumentview/src/InstrumentWidget.cpp index e7afb960028e..ce2567b09b38 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidget.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidget.cpp @@ -401,7 +401,7 @@ void InstrumentWidget::setSurfaceType(int type) { // If anything throws during surface creation, store error message here QString errorMessage; try { - const auto &componentInfo = m_instrumentActor->getComponentInfo(); + const auto &componentInfo = m_instrumentActor->componentInfo(); if (!componentInfo.hasSample()) { throw InstrumentHasNoSampleError(); } diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 57054b8a0cd5..4906905ef930 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -829,7 +829,7 @@ void ComponentInfoController::displayInfo(size_t pickID) { } const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); QString text = ""; if (componentInfo.isDetector(pickID)) { text += displayDetectorInfo(pickID); @@ -862,7 +862,7 @@ QString ComponentInfoController::displayDetectorInfo(size_t index) { // collect info about selected detector and add it to text const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); auto detid = actor.getDetID(index); text = "Selected detector: " + @@ -908,7 +908,7 @@ QString ComponentInfoController::displayDetectorInfo(size_t index) { QString ComponentInfoController::displayNonDetectorInfo( Mantid::Geometry::ComponentID compID) { const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); auto component = componentInfo.indexOf(compID); QString text = "Selected component: "; text += QString::fromStdString(componentInfo.name(component)) + '\n'; @@ -1100,7 +1100,7 @@ void DetectorPlotController::setPlotData(size_t pickID) { } const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); if (componentInfo.isDetector(pickID)) { if (m_plotType == Single) { m_currentDetID = actor.getDetID(pickID); @@ -1196,7 +1196,7 @@ void DetectorPlotController::plotSingle(size_t detindex) { */ void DetectorPlotController::plotTube(size_t detindex) { const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); if (componentInfo.hasParent(detindex) && componentInfo.numberOfDetectorsInSubtree(detindex) > 0) { @@ -1229,7 +1229,7 @@ void DetectorPlotController::plotTubeSums(size_t detindex) { return; } const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); auto parent = componentInfo.parent(detindex); auto detid = actor.getDetID(detindex); QString label = QString::fromStdString(componentInfo.name(parent)) + " (" + @@ -1254,7 +1254,7 @@ void DetectorPlotController::plotTubeSums(size_t detindex) { */ void DetectorPlotController::plotTubeIntegrals(size_t detindex) { const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); std::vector x, y; prepareDataForIntegralsPlot(detindex, x, y); if (x.empty() || y.empty()) { @@ -1323,7 +1323,7 @@ void DetectorPlotController::prepareDataForSumsPlot(size_t detindex, std::vector *err) { const auto &actor = m_instrWidget->getInstrumentActor(); auto ws = actor.getWorkspace(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); auto parent = componentInfo.parent(detindex); auto ass = componentInfo.detectorsInSubtree(parent); @@ -1394,7 +1394,7 @@ void DetectorPlotController::prepareDataForIntegralsPlot( return; const auto &actor = m_instrWidget->getInstrumentActor(); - const auto &componentInfo = actor.getComponentInfo(); + const auto &componentInfo = actor.componentInfo(); Mantid::API::MatrixWorkspace_const_sptr ws = actor.getWorkspace(); // Does the instrument definition specify that psi should be offset. @@ -1411,7 +1411,7 @@ void DetectorPlotController::prepareDataForIntegralsPlot( size_t imin, imax; actor.getBinMinMaxIndex(wi, imin, imax); - auto samplePos = actor.getComponentInfo().samplePosition(); + auto samplePos = actor.componentInfo().samplePosition(); auto n = ass.size(); if (n == 0) { @@ -1433,7 +1433,7 @@ void DetectorPlotController::prepareDataForIntegralsPlot( auto normal = componentInfo.position(ass[1]) - componentInfo.position(ass[0]); normal.normalize(); - const auto &detectorInfo = actor.getDetectorInfo(); + const auto &detectorInfo = actor.detectorInfo(); for (auto det : ass) { if (componentInfo.isDetector(det)) { auto id = detectorInfo.detectorIDs()[det]; diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 140303890cd7..9f7555bb49d7 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -142,7 +142,7 @@ void PanelsSurface::project(const Mantid::Kernel::V3D &, double &, double &, void PanelsSurface::rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat &R) const { - const auto &detectorInfo = m_instrActor->getDetectorInfo(); + const auto &detectorInfo = m_instrActor->detectorInfo(); int index = m_detector2bankMap[udet.detIndex]; FlatBankInfo &info = *m_flatBanks[index]; R = info.rotation * detectorInfo.rotation(udet.detIndex); @@ -176,7 +176,7 @@ void PanelsSurface::addFlatBankOfDetectors( info->endDetectorIndex = detectors.back(); // keep reference position on the bank's plane - const auto &detectorInfo = m_instrActor->getDetectorInfo(); + const auto &detectorInfo = m_instrActor->detectorInfo(); auto pos0 = detectorInfo.position(detectors[0]); auto pos1 = detectorInfo.position(detectors[1]) - pos0; @@ -203,7 +203,7 @@ void PanelsSurface::addFlatBankOfDetectors( void PanelsSurface::processStructured(const std::vector &children, size_t rootIndex) { int index = m_flatBanks.size(); - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); auto corners = retrievePanelCorners(componentInfo, rootIndex); auto normal = calculatePanelNormal(corners); // save bank info @@ -234,11 +234,11 @@ PanelsSurface::processUnstructured(const std::vector &children, size_t rootIndex, std::vector &visited) { Mantid::Kernel::V3D normal; - const auto &detectorInfo = m_instrActor->getDetectorInfo(); + const auto &detectorInfo = m_instrActor->detectorInfo(); Mantid::Kernel::V3D pos0; Mantid::Kernel::V3D x, y; bool normalFound = false; - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); std::vector detectors; detectors.reserve(children.size()); for (auto child : children) { @@ -282,7 +282,7 @@ boost::optional, Mantid::Kernel::V3D>> PanelsSurface::findFlatPanels(size_t rootIndex, const std::vector &children, std::vector &visited) { - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); auto parentIndex = componentInfo.parent(rootIndex); auto componentType = componentInfo.componentType(parentIndex); if (componentType == Mantid::Beamline::ComponentType::Rectangular || @@ -304,7 +304,7 @@ PanelsSurface::findFlatPanels(size_t rootIndex, } void PanelsSurface::constructFromComponentInfo() { - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); std::vector visited(componentInfo.size(), false); for (size_t i = 0; i < componentInfo.size() - 1; ++i) { @@ -356,7 +356,7 @@ PanelsSurface::calcBankRotation(const Mantid::Kernel::V3D &detPos, void PanelsSurface::addDetector(size_t detIndex, const Mantid::Kernel::V3D &refPos, int index, Mantid::Kernel::Quat &rotation) { - const auto &detectorInfo = m_instrActor->getDetectorInfo(); + const auto &detectorInfo = m_instrActor->detectorInfo(); Mantid::Kernel::V3D pos = detectorInfo.position(detIndex); m_detector2bankMap[detIndex] = index; diff --git a/qt/widgets/instrumentview/src/Projection3D.cpp b/qt/widgets/instrumentview/src/Projection3D.cpp index c136fef02cd3..206d9454024b 100644 --- a/qt/widgets/instrumentview/src/Projection3D.cpp +++ b/qt/widgets/instrumentview/src/Projection3D.cpp @@ -279,7 +279,7 @@ void Projection3D::getMaskedDetectors(std::vector &detIndices) const { */ void Projection3D::componentSelected(size_t componentIndex) { - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); if (componentIndex == componentInfo.root()) { m_viewport.reset(); diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 0b713b7e5ca5..28d652a7f1e5 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -73,7 +73,7 @@ void RotationSurface::init() { m_u_min = -DBL_MAX; m_u_max = DBL_MAX; - const auto &detectorInfo = m_instrActor->getDetectorInfo(); + const auto &detectorInfo = m_instrActor->detectorInfo(); // Set if one of the threads in the following loop // throws an exception bool exceptionThrown = false; @@ -186,7 +186,7 @@ void RotationSurface::findUVBounds() { m_v_max = -DBL_MAX; for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { const UnwrappedDetector &udet = m_unwrappedDetectors[i]; - if (!m_instrActor->getComponentInfo().hasValidShape(udet.detIndex)) + if (!m_instrActor->componentInfo().hasValidShape(udet.detIndex)) continue; if (udet.u < m_u_min) m_u_min = udet.u; @@ -217,7 +217,7 @@ void RotationSurface::findAndCorrectUGap() { } for (const auto &udet : m_unwrappedDetectors) { - if (!m_instrActor->getComponentInfo().hasValidShape(udet.detIndex)) + if (!m_instrActor->componentInfo().hasValidShape(udet.detIndex)) continue; double u = udet.u; int i = int((u - m_u_min) / bin_width); @@ -254,7 +254,7 @@ void RotationSurface::findAndCorrectUGap() { } for (auto &udet : m_unwrappedDetectors) { - if (!m_instrActor->getComponentInfo().hasValidShape(udet.detIndex)) + if (!m_instrActor->componentInfo().hasValidShape(udet.detIndex)) continue; double &u = udet.u; u = applyUCorrection(u); diff --git a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp index 61095fea1f06..9f142e6577b7 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSphere.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSphere.cpp @@ -44,7 +44,7 @@ void UnwrappedSphere::rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat R1; // direction in which to look: from sample to detector Mantid::Kernel::V3D eye; - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); eye = m_pos - componentInfo.position(udet.detIndex); if (!eye.nullVector()) { InstrumentActor::rotateToLookAt(eye, m_zaxis, R1); diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 6645737d2b8b..37d58eb8de85 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -138,7 +138,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { glShadeModel(GL_FLAT); } - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); for (const auto &udet : m_unwrappedDetectors) { if (!componentInfo.hasValidShape(udet.detIndex)) continue; @@ -182,7 +182,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { componentInfo.scaleFactor(udet.detIndex); glScaled(scaleFactor[0], scaleFactor[1], scaleFactor[2]); - m_instrActor->getComponentInfo().shape(udet.detIndex).draw(); + m_instrActor->componentInfo().shape(udet.detIndex).draw(); glPopMatrix(); } @@ -235,7 +235,7 @@ bool hasParent(boost::shared_ptr comp, * @param id :: ComponentID to zoom to. */ void UnwrappedSurface::componentSelected(size_t componentIndex) { - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); if (componentInfo.isDetector(componentIndex)) { const auto &udet = m_unwrappedDetectors[componentIndex]; zoom(getArea(udet, m_width_max, m_height_max)); @@ -595,7 +595,7 @@ void UnwrappedSurface::calcSize(UnwrappedDetector &udet) { Mantid::Kernel::Quat R; this->rotate(udet, R); - const auto &componentInfo = m_instrActor->getComponentInfo(); + const auto &componentInfo = m_instrActor->componentInfo(); const auto &bbox = componentInfo.shape(udet.detIndex).getBoundingBox(); auto scale = componentInfo.scaleFactor(udet.detIndex); From 38309fc361cc295b385ae4dc8d5165d74272f138 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 25 Jan 2018 09:04:32 +0000 Subject: [PATCH 063/364] InstrumentActor::INVALID_INDEX fix #21339 --- .../inc/MantidQtWidgets/InstrumentView/InstrumentActor.h | 2 +- qt/widgets/instrumentview/src/InstrumentActor.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 6ba1ad4ab82d..58cf01b371a2 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -48,7 +48,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { Q_OBJECT public: /// Invalid workspace index in detector index to workspace index lookup - static const size_t INVALID_INDEX = std::numeric_limits::max(); + static const size_t INVALID_INDEX; /// Constructor InstrumentActor(const QString &wsName, bool autoscaling = true, double scaleMin = 0.0, double scaleMax = 0.0); diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 8dfc4ca22faf..78a7ee13c593 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -28,6 +28,7 @@ #include #include +#include #include using namespace Mantid::Kernel::Exception; @@ -58,6 +59,8 @@ bool isPhysicalView() { } // namespace +const size_t InstrumentActor::INVALID_INDEX = + std::numeric_limits::max(); double InstrumentActor::m_tolerance = 0.00001; /** @@ -407,7 +410,7 @@ Mantid::detid_t InstrumentActor::getDetID(size_t pickID) const { QList InstrumentActor::getDetIDs(const std::vector &dets) const { QList detIDs; - detIDs.reserve(dets.size()); + detIDs.reserve(static_cast(dets.size())); for (auto det : dets) detIDs.append(getDetID(det)); return detIDs; From a9d8cfcc6bc9d681cfa2dcb7ef1312b6394569d6 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 26 Jan 2018 08:14:59 +0000 Subject: [PATCH 064/364] add num det in subtree unit test #21339 --- Framework/Beamline/test/ComponentInfoTest.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index dcd6c92dc07b..64133b9ae171 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -640,6 +640,18 @@ class ComponentInfoTest : public CxxTest::TestSuite { std::vector({0, 2})); } + void test_number_of_detectors() { + auto infos = makeTreeExample(); + const auto &compInfo = *std::get<0>(infos); + auto root = compInfo.root(); + + // Tree contains 3 detectors so from the root we should see all detectors + TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(root), 3); + + // Sub assembly which contains 2 detectors at root-1 + TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(root - 1), 2); + } + void test_component_indexes() { auto infos = makeTreeExample(); From a482d144d84b8d36e226b7899f38459356122651 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 26 Jan 2018 08:24:34 +0000 Subject: [PATCH 065/364] added scenario to num det in subtree unit test #21339 --- Framework/Beamline/src/ComponentInfo.cpp | 2 ++ Framework/Beamline/test/ComponentInfoTest.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 6baef33046eb..4bbae7647b3c 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -169,6 +169,8 @@ size_t ComponentInfo::size() const { return m_size; } size_t ComponentInfo::numberOfDetectorsInSubtree(const size_t componentIndex) const { + if (isDetector(componentIndex)) + return 0; auto range = detectorRangeInSubtree(componentIndex); return std::distance(range.begin(), range.end()); } diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 64133b9ae171..9a0f26da8fc0 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -650,6 +650,9 @@ class ComponentInfoTest : public CxxTest::TestSuite { // Sub assembly which contains 2 detectors at root-1 TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(root - 1), 2); + + // Should return zero for a detector + TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(0), 0); } void test_component_indexes() { From 4fc33d616bc5e5102956dcd6f48119a5d5c51ba4 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 2 Feb 2018 09:55:04 -0500 Subject: [PATCH 066/364] review changes and fix tube plotting #21339 --- Framework/Beamline/src/ComponentInfo.cpp | 7 ++- Framework/Beamline/test/ComponentInfoTest.h | 4 +- Framework/Geometry/test/ComponentInfoTest.h | 6 +- .../InstrumentView/InstrumentActor.h | 4 +- .../instrumentview/src/InstrumentActor.cpp | 55 +++++++++---------- .../src/InstrumentWidgetPickTab.cpp | 11 ++-- 6 files changed, 44 insertions(+), 43 deletions(-) diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 4bbae7647b3c..4564d6be8971 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -170,9 +170,10 @@ size_t ComponentInfo::size() const { return m_size; } size_t ComponentInfo::numberOfDetectorsInSubtree(const size_t componentIndex) const { if (isDetector(componentIndex)) - return 0; - auto range = detectorRangeInSubtree(componentIndex); - return std::distance(range.begin(), range.end()); + return 1; + const auto rangesIndex = compOffsetIndex(componentIndex); + const auto range = (*m_detectorRanges)[rangesIndex]; + return range.second - range.first; } Eigen::Vector3d ComponentInfo::position(const size_t componentIndex) const { diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index 9a0f26da8fc0..c9f2ed5ea998 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -651,8 +651,8 @@ class ComponentInfoTest : public CxxTest::TestSuite { // Sub assembly which contains 2 detectors at root-1 TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(root - 1), 2); - // Should return zero for a detector - TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(0), 0); + // Should return 1 for a detector since the component itself is included. + TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(0), 1); } void test_component_indexes() { diff --git a/Framework/Geometry/test/ComponentInfoTest.h b/Framework/Geometry/test/ComponentInfoTest.h index 325723019690..1bb68e32000b 100644 --- a/Framework/Geometry/test/ComponentInfoTest.h +++ b/Framework/Geometry/test/ComponentInfoTest.h @@ -665,14 +665,14 @@ class ComponentInfoTest : public CxxTest::TestSuite { // Throws for other non quadrilateral component TS_ASSERT_THROWS( componentInfo->quadrilateralComponent(componentInfo->root() - 1), - std::runtime_error); + std::runtime_error &); // Throws for root TS_ASSERT_THROWS( componentInfo->quadrilateralComponent(componentInfo->root()), - std::runtime_error); + std::runtime_error &); // Throws for detector TS_ASSERT_THROWS(componentInfo->quadrilateralComponent(0), - std::runtime_error); + std::runtime_error &); } void test_QuadrilateralComponent_for_single_rectangular_bank() { diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index 58cf01b371a2..e10ff7ac24de 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -206,9 +206,7 @@ class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentActor : public QObject { void setUpWorkspace( boost::shared_ptr sharedWorkspace, double scaleMin, double scaleMax); - void setupPhysicalInstrument(); - const Mantid::Geometry::ComponentInfo &getComponentInfo() const; - const Mantid::Geometry::DetectorInfo &getDetectorInfo() const; + void setupPhysicalInstrumentIfExists(); void resetColors(); void loadSettings(); void saveSettings(); diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 78a7ee13c593..59422c7bb561 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -93,7 +93,7 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, if (!sharedWorkspace) throw std::logic_error( "InstrumentActor passed a workspace that isn't a MatrixWorkspace"); - setupPhysicalInstrument(); + setupPhysicalInstrumentIfExists(); for (size_t i = 0; i < componentInfo().size(); ++i) { if (!componentInfo().isDetector(i)) @@ -207,18 +207,19 @@ void InstrumentActor::setUpWorkspace( m_ragged = !wsValidator.isValid(sharedWorkspace).empty(); } -void InstrumentActor::setupPhysicalInstrument() { +void InstrumentActor::setupPhysicalInstrumentIfExists() { + if (!isPhysicalView()) + return; + auto sharedWorkspace = getWorkspace(); Mantid::Kernel::ReadLock _lock(*sharedWorkspace); - if (isPhysicalView()) { - auto instr = sharedWorkspace->getInstrument()->getPhysicalInstrument(); - if (instr) { - m_isPhysicalInstrument = true; - auto infos = InstrumentVisitor::makeWrappers(*instr); - m_physicalComponentInfo = std::move(infos.first); - m_physicalDetectorInfo = std::move(infos.second); - } + auto instr = sharedWorkspace->getInstrument()->getPhysicalInstrument(); + if (instr) { + auto infos = InstrumentVisitor::makeWrappers(*instr); + m_physicalComponentInfo = std::move(infos.first); + m_physicalDetectorInfo = std::move(infos.second); + m_isPhysicalInstrument = true; } } @@ -1329,12 +1330,26 @@ void InstrumentActor::loadFromProject(const std::string &lines) { } } +/** If instrument.geometry.view is set to Default or Physical, then the physical + * instrument componentInfo is returned. Othewise this returns the neutronic + * version. + */ const Mantid::Geometry::ComponentInfo &InstrumentActor::componentInfo() const { - return getComponentInfo(); + if (m_isPhysicalInstrument) + return *m_physicalComponentInfo; + else + return getWorkspace()->componentInfo(); } +/** If instrument.geometry.view is set to Default or Physical, then the physical +* instrument detectorInfo is returned. Othewise this returns the neutronic +* version. +*/ const Mantid::Geometry::DetectorInfo &InstrumentActor::detectorInfo() const { - return getDetectorInfo(); + if (m_isPhysicalInstrument) + return *m_physicalDetectorInfo; + else + return getWorkspace()->detectorInfo(); } void InstrumentActor::invalidateDisplayLists() const { @@ -1361,21 +1376,5 @@ size_t InstrumentActor::decodePickColor(const QRgb &c) { static_cast(qGreen(c)), static_cast(qBlue(c))); } - -const Mantid::Geometry::ComponentInfo & -InstrumentActor::getComponentInfo() const { - if (m_isPhysicalInstrument) - return *m_physicalComponentInfo; - else - return getWorkspace()->componentInfo(); -} - -const Mantid::Geometry::DetectorInfo &InstrumentActor::getDetectorInfo() const { - if (m_isPhysicalInstrument) - return *m_physicalDetectorInfo; - else - return getWorkspace()->detectorInfo(); -} - } // namespace MantidWidgets } // namespace MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 4906905ef930..0e371b1eeb00 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -1198,8 +1198,13 @@ void DetectorPlotController::plotTube(size_t detindex) { const auto &actor = m_instrWidget->getInstrumentActor(); const auto &componentInfo = actor.componentInfo(); - if (componentInfo.hasParent(detindex) && - componentInfo.numberOfDetectorsInSubtree(detindex) > 0) { + if (!componentInfo.hasParent(detindex)) { + m_plot->clearCurve(); + return; + } + + auto parent = componentInfo.parent(detindex); + if (componentInfo.numberOfDetectorsInSubtree(parent) > 1) { if (m_plotType == TubeSum) // plot sums over detectors vs time bins { plotTubeSums(detindex); @@ -1209,8 +1214,6 @@ void DetectorPlotController::plotTube(size_t detindex) { assert(m_plotType == TubeIntegral); plotTubeIntegrals(detindex); } - } else { - m_plot->clearCurve(); } } From 49ba624daa0556ec8703169357b8a8fbe1f4a7b5 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Fri, 2 Feb 2018 11:53:12 -0500 Subject: [PATCH 067/364] review changes #21339 --- .../Beamline/inc/MantidBeamline/ComponentInfo.h | 1 - Framework/Beamline/src/ComponentInfo.cpp | 9 --------- Framework/Beamline/test/ComponentInfoTest.h | 15 --------------- .../inc/MantidGeometry/Instrument/ComponentInfo.h | 1 - .../Geometry/src/Instrument/ComponentInfo.cpp | 4 ---- .../src/InstrumentWidgetPickTab.cpp | 2 +- 6 files changed, 1 insertion(+), 31 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index f0903aa40d6e..9618c3b5b3da 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -113,7 +113,6 @@ class MANTID_BEAMLINE_DLL ComponentInfo { std::vector componentsInSubtree(const size_t componentIndex) const; const std::vector &children(const size_t componentIndex) const; size_t size() const; - size_t numberOfDetectorsInSubtree(const size_t componentIndex) const; bool isDetector(const size_t componentIndex) const { return componentIndex < m_assemblySortedDetectorIndices->size(); } diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index 4564d6be8971..ffe12a64a974 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -167,15 +167,6 @@ ComponentInfo::children(const size_t componentIndex) const { size_t ComponentInfo::size() const { return m_size; } -size_t -ComponentInfo::numberOfDetectorsInSubtree(const size_t componentIndex) const { - if (isDetector(componentIndex)) - return 1; - const auto rangesIndex = compOffsetIndex(componentIndex); - const auto range = (*m_detectorRanges)[rangesIndex]; - return range.second - range.first; -} - Eigen::Vector3d ComponentInfo::position(const size_t componentIndex) const { checkNoTimeDependence(); if (isDetector(componentIndex)) { diff --git a/Framework/Beamline/test/ComponentInfoTest.h b/Framework/Beamline/test/ComponentInfoTest.h index c9f2ed5ea998..dcd6c92dc07b 100644 --- a/Framework/Beamline/test/ComponentInfoTest.h +++ b/Framework/Beamline/test/ComponentInfoTest.h @@ -640,21 +640,6 @@ class ComponentInfoTest : public CxxTest::TestSuite { std::vector({0, 2})); } - void test_number_of_detectors() { - auto infos = makeTreeExample(); - const auto &compInfo = *std::get<0>(infos); - auto root = compInfo.root(); - - // Tree contains 3 detectors so from the root we should see all detectors - TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(root), 3); - - // Sub assembly which contains 2 detectors at root-1 - TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(root - 1), 2); - - // Should return 1 for a detector since the component itself is included. - TS_ASSERT_EQUALS(compInfo.numberOfDetectorsInSubtree(0), 1); - } - void test_component_indexes() { auto infos = makeTreeExample(); diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h index b7d8a6c554e0..0018c011783c 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentInfo.h @@ -112,7 +112,6 @@ class MANTID_GEOMETRY_DLL ComponentInfo { std::vector componentsInSubtree(size_t componentIndex) const; const std::vector &children(size_t componentIndex) const; size_t size() const; - size_t numberOfDetectorsInSubtree(size_t componentIndex) const; QuadrilateralComponent quadrilateralComponent(const size_t componentIndex) const; size_t indexOf(Geometry::IComponent *id) const; diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index 2218752a18de..8e6c0dbe9a47 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -114,10 +114,6 @@ ComponentInfo::children(size_t componentIndex) const { size_t ComponentInfo::size() const { return m_componentInfo->size(); } -size_t ComponentInfo::numberOfDetectorsInSubtree(size_t componentIndex) const { - return m_componentInfo->numberOfDetectorsInSubtree(componentIndex); -} - ComponentInfo::QuadrilateralComponent ComponentInfo::quadrilateralComponent(const size_t componentIndex) const { auto type = componentType(componentIndex); diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index 0e371b1eeb00..c098389b9b8f 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -1204,7 +1204,7 @@ void DetectorPlotController::plotTube(size_t detindex) { } auto parent = componentInfo.parent(detindex); - if (componentInfo.numberOfDetectorsInSubtree(parent) > 1) { + if (componentInfo.detectorsInSubtree(parent).size() > 0) { if (m_plotType == TubeSum) // plot sums over detectors vs time bins { plotTubeSums(detindex); From 3c661c09a4bed2644d37f4dfb9bfcf0633632838 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 20 Feb 2018 15:56:08 +0000 Subject: [PATCH 068/364] Re #21991: Removed dangling reference to point-detector2. --- instrument/INTER_Definition.xml | 3 --- instrument/INTER_Definition_2017.xml | 3 --- 2 files changed, 6 deletions(-) diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml index f27b4c9f7e55..d2a4f82f07d0 100644 --- a/instrument/INTER_Definition.xml +++ b/instrument/INTER_Definition.xml @@ -235,9 +235,6 @@ - - - - - + name="SURF" + valid-from="2010-01-10 23:59:59" + valid-to="2100-01-30 23:59:59" + last-modified="2018-02-22 00:00:00"> + @@ -28,75 +29,75 @@ 40mm(H) x 60mm(W) - - + + - + + - - - + + - + + --> - + - + - + - - + + - - + + + but that was cosmetic only as it is not in the beam, + and was causing problems with opencascade on windows 8. + Therefore it has been removed. --> - - - + + + - + - + + --> @@ -104,20 +105,20 @@ - - - + + + - - - - + + @@ -126,43 +127,43 @@ - + + + + - - - - + - - - + + + - + - - - + + + - + - - - - + + + + - - + + @@ -175,30 +176,30 @@ - - - + + + - - + + + + - - - + - + - + - + From 8f88dc9a95af747c9b149e2846c0d0b845d0a30c Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Fri, 23 Feb 2018 09:27:19 +0000 Subject: [PATCH 073/364] Re #20991: Updated release notes re RROA v1. --- docs/source/release/v3.12.0/reflectometry.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/reflectometry.rst b/docs/source/release/v3.12.0/reflectometry.rst index 14a88dcb0fcd..df7b40b611e9 100644 --- a/docs/source/release/v3.12.0/reflectometry.rst +++ b/docs/source/release/v3.12.0/reflectometry.rst @@ -74,7 +74,7 @@ Improvements - A new property, *BeamCentre* allows user to manually specify the beam position on the detector. - The *BeamPosition* property was renamed to *DirectBeamPosition* to better reflect its usage. - The *BraggAngle* property of :ref:`algm-LoadILLReflectometry` now works as expected: the detector will be rotated such that the reflected peak on the detector will be at twice *BraggAngle*. - +- Removed version 1 of ``ReflectometryReductionOne`` and ``ReflectometryReductionOneAuto``. Bug fixes ######### From 376213303f0934051d82ed3ee7a4f792326a8895 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Fri, 23 Feb 2018 09:50:23 +0000 Subject: [PATCH 074/364] Re #20991: Removed ReflectometryReductionOneAuto v1. --- Framework/Algorithms/CMakeLists.txt | 6 - .../ReflectometryReductionOne.h | 110 --- .../ReflectometryReductionOneAuto.h | 70 -- .../src/ReflectometryReductionOne.cpp | 855 ------------------ .../src/ReflectometryReductionOneAuto.cpp | 848 ----------------- .../test/CreateTransmissionWorkspaceTest.h | 2 - .../test/ReflectometryReductionOneAutoTest.h | 798 ---------------- .../test/ReflectometryReductionOneTest.h | 395 -------- .../ReflectometryReductionOne-v1.rst | 248 ----- .../ReflectometryReductionOneAuto-v1.rst | 166 ---- 10 files changed, 3498 deletions(-) delete mode 100644 Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h delete mode 100644 Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h delete mode 100644 Framework/Algorithms/src/ReflectometryReductionOne.cpp delete mode 100644 Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp delete mode 100644 Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h delete mode 100644 Framework/Algorithms/test/ReflectometryReductionOneTest.h delete mode 100644 docs/source/algorithms/ReflectometryReductionOne-v1.rst delete mode 100644 docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt index 39fcebb6676a..636cfca4f8fe 100644 --- a/Framework/Algorithms/CMakeLists.txt +++ b/Framework/Algorithms/CMakeLists.txt @@ -240,9 +240,7 @@ set ( SRC_FILES src/RebinToWorkspace.cpp src/Rebunch.cpp src/RecordPythonScript.cpp - src/ReflectometryReductionOne.cpp src/ReflectometryReductionOne2.cpp - src/ReflectometryReductionOneAuto.cpp src/ReflectometryReductionOneAuto2.cpp src/ReflectometryWorkflowBase.cpp src/ReflectometryWorkflowBase2.cpp @@ -576,9 +574,7 @@ set ( INC_FILES inc/MantidAlgorithms/RebinToWorkspace.h inc/MantidAlgorithms/Rebunch.h inc/MantidAlgorithms/RecordPythonScript.h - inc/MantidAlgorithms/ReflectometryReductionOne.h inc/MantidAlgorithms/ReflectometryReductionOne2.h - inc/MantidAlgorithms/ReflectometryReductionOneAuto.h inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h inc/MantidAlgorithms/ReflectometryWorkflowBase.h inc/MantidAlgorithms/ReflectometryWorkflowBase2.h @@ -914,8 +910,6 @@ set ( TEST_FILES RectangularBeamProfileTest.h ReflectometryReductionOne2Test.h ReflectometryReductionOneAuto2Test.h - ReflectometryReductionOneAutoTest.h - ReflectometryReductionOneTest.h RegroupTest.h RemoveBackgroundTest.h RemoveBinsTest.h diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h deleted file mode 100644 index 0a0c6854d408..000000000000 --- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONE_H_ -#define MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONE_H_ - -#include "MantidKernel/System.h" -#include "MantidAlgorithms/DllConfig.h" -#include "MantidAPI/MatrixWorkspace_fwd.h" -#include "MantidGeometry/Instrument.h" -#include "MantidGeometry/IComponent.h" -#include "MantidGeometry/IDetector.h" -#include "MantidAlgorithms/ReflectometryWorkflowBase.h" - -namespace Mantid { -namespace Algorithms { - -/** ReflectometryReductionOne : Reflectometry reduction of a single input TOF - workspace to an IvsQ workspace. - - Copyright © 2013 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ -class DLLExport ReflectometryReductionOne : public ReflectometryWorkflowBase { -public: - const std::string name() const override; - /// Summary of algorithms purpose - const std::string summary() const override { - return "Reduces a single TOF/Lambda reflectometry run into a mod Q vs I/I0 " - "workspace. Performs transmission corrections."; - } - - int version() const override; - const std::string category() const override; - - /// Convert to an IvsQ workspace. Performs detector positional corrections - /// based on the component name and the theta value. - Mantid::API::MatrixWorkspace_sptr toIvsQ(API::MatrixWorkspace_sptr &toConvert, - const bool bCorrectPosition, - OptionalDouble &thetaInDeg, - const bool isPointDetector); - -private: - /** Overridden Algorithm methods **/ - - void init() override; - - void exec() override; - - /// Get the surface sample component - Mantid::Geometry::IComponent_const_sptr - getSurfaceSampleComponent(Mantid::Geometry::Instrument_const_sptr inst); - - /// Get the detector component - Mantid::Geometry::IComponent_const_sptr - getDetectorComponent(Mantid::Geometry::Instrument_const_sptr inst, - const bool isPointDetector); - - /// Correct detector positions. - API::MatrixWorkspace_sptr - correctPosition(API::MatrixWorkspace_sptr &toCorrect, - const double &thetaInDeg, const bool isPointDetector); - - /// Perform a transmission correction on the input IvsLam workspace - API::MatrixWorkspace_sptr transmissonCorrection( - API::MatrixWorkspace_sptr IvsLam, const MinMax &wavelengthInterval, - const OptionalMinMax &wavelengthMonitorBackgroundInterval, - const OptionalMinMax &wavelengthMonitorIntegrationInterval, - const OptionalInteger &i0MonitorIndex, - API::MatrixWorkspace_sptr firstTransmissionRun, - OptionalMatrixWorkspace_sptr secondTransmissionRun, - const OptionalDouble &stitchingStart, - const OptionalDouble &stitchingDelta, const OptionalDouble &stitchingEnd, - const OptionalDouble &stitchingStartOverlap, - const OptionalDouble &stitchingEndOverlap, - const std::string &numeratorProcessingCommands); - - /// Perform transmission correction using either PolynomialCorrection - /// or ExponentialCorrection. - API::MatrixWorkspace_sptr - algorithmicCorrection(API::MatrixWorkspace_sptr IvsLam); - - /// Verify spectrum maps - void verifySpectrumMaps(API::MatrixWorkspace_const_sptr ws1, - API::MatrixWorkspace_const_sptr ws2, - const bool severe = false); - /// returns angle for source rotation - double getAngleForSourceRotation(API::MatrixWorkspace_sptr toConvert, - double thetaOut); -}; - -} // namespace Algorithms -} // namespace Mantid - -#endif /* MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONE_H_ */ diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h deleted file mode 100644 index 5b84f40d8337..000000000000 --- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTO_H_ -#define MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTO_H_ - -#include "MantidAPI/Algorithm.h" -#include "MantidAPI/DataProcessorAlgorithm.h" -#include "MantidAPI/WorkspaceGroup_fwd.h" -#include "MantidKernel/System.h" - -#include - -namespace Mantid { -namespace Algorithms { - -/** ReflectometryReductionOneAuto : Algorithm to run ReflectometryReductionOne, -attempting to pick instrument parameters for - * missing properties. - -Copyright © 2014 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge -National Laboratory & European Spallation Source - -This file is part of Mantid. - -Mantid is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -(at your option) any later version. - -Mantid is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -File change history is stored at: -Code Documentation is available at: -*/ -class DLLExport ReflectometryReductionOneAuto - : public API::DataProcessorAlgorithm { -public: - const std::string name() const override; - int version() const override; - const std::string category() const override; - const std::string summary() const override; - - // For (multiperiod) workspace groups - bool checkGroups() override; - bool processGroups() override; - -private: - void init() override; - void exec() override; - template boost::optional isSet(std::string propName) const; - Mantid::API::Workspace_sptr - sumOverTransmissionGroup(Mantid::API::WorkspaceGroup_sptr &transGroup); - - std::string pNRLabel() const { return "PNR"; } - std::string pALabel() const { return "PA"; } - std::string crhoLabel() const { return "CRho"; } - std::string cppLabel() const { return "CPp"; } - std::string cAlphaLabel() const { return "CAlpha"; } - std::string cApLabel() const { return "CAp"; } - std::string noPolarizationCorrectionMode() const { return "None"; } -}; - -} // namespace Algorithms -} // namespace Mantid - -#endif /* MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTO_H_ */ diff --git a/Framework/Algorithms/src/ReflectometryReductionOne.cpp b/Framework/Algorithms/src/ReflectometryReductionOne.cpp deleted file mode 100644 index 3d8e2a2dc971..000000000000 --- a/Framework/Algorithms/src/ReflectometryReductionOne.cpp +++ /dev/null @@ -1,855 +0,0 @@ -#include "MantidAlgorithms/BoostOptionalToAlgorithmProperty.h" -#include "MantidAlgorithms/ReflectometryReductionOne.h" -#include "MantidAPI/Axis.h" -#include "MantidAPI/WorkspaceUnitValidator.h" -#include "MantidGeometry/Instrument/ReferenceFrame.h" -#include "MantidKernel/ListValidator.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/EnabledWhenProperty.h" -#include "MantidKernel/Tolerance.h" -#include "MantidKernel/Unit.h" - -using namespace Mantid::Kernel; -using namespace Mantid::API; -using namespace Mantid::Geometry; - -namespace Mantid { -namespace Algorithms { - -/*Anonomous namespace */ -namespace { -/** -* Helper non-member function for translating all the workspace indexes in an -*origin workspace into workspace indexes -* of a host end-point workspace. This is done using spectrum numbers as the -*intermediate. -* -* This function will throw a runtime error if the specId are not found to exist -*on the host end-point workspace. -* -* @param originWS : Origin workspace, which provides the original workspace -*index to spectrum number mapping. -* @param hostWS : Workspace onto which the resulting workspace indexes will be -*hosted -* @return Remapped workspace indexes applicable for the host workspace. results -*as comma separated string. -*/ -std::string createWorkspaceIndexListFromDetectorWorkspace( - MatrixWorkspace_const_sptr originWS, MatrixWorkspace_const_sptr hostWS) { - auto spectrumMap = originWS->getSpectrumToWorkspaceIndexMap(); - auto it = spectrumMap.begin(); - std::stringstream result; - specnum_t specId = (*it).first; - result << static_cast(hostWS->getIndexFromSpectrumNumber(specId)); - ++it; - for (; it != spectrumMap.end(); ++it) { - specId = (*it).first; - result << "," - << static_cast(hostWS->getIndexFromSpectrumNumber(specId)); - } - return result.str(); -} - -const std::string multiDetectorAnalysis = "MultiDetectorAnalysis"; -const std::string pointDetectorAnalysis = "PointDetectorAnalysis"; -const std::string tofUnitId = "TOF"; -const std::string wavelengthUnitId = "Wavelength"; - -/** -* Helper free function to get the ordered spectrum numbers from a workspace. -* @param ws -* @return -*/ -std::vector getSpectrumNumbers(MatrixWorkspace_sptr &ws) { - auto specToWSIndexMap = ws->getSpectrumToWorkspaceIndexMap(); - std::vector keys(specToWSIndexMap.size()); - size_t i = 0; - for (auto it = specToWSIndexMap.begin(); it != specToWSIndexMap.end(); - ++it, ++i) { - keys[i] = static_cast(it->first); - } - std::sort( - keys.begin(), - keys.end()); // Sort the keys, as the order is not guaranteed in the map. - - return keys; -} - -/** -* Helper free function to calculate MomentumTransfer from lambda and theta -* @param lambda : Value in wavelength -* @param theta : Value in Degrees -* @return MomentumTransfer -* @ -*/ -double calculateQ(double lambda, double theta) { - if (lambda == 0.0) - throw std::runtime_error("Minimum/Maximum value of the IvsLambda Workspace " - "is 0. Cannot calculate Q"); - double thetaInRad = theta * M_PI / 180; - return (4 * M_PI * sin(thetaInRad)) / lambda; -} -} -/* End of ananomous namespace */ - -// Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(ReflectometryReductionOne) - -//---------------------------------------------------------------------------------------------- -/// Algorithm's name for identification. @see Algorithm::name -const std::string ReflectometryReductionOne::name() const { - return "ReflectometryReductionOne"; -} - -/// Algorithm's version for identification. @see Algorithm::version -int ReflectometryReductionOne::version() const { return 1; } - -/// Algorithm's category for identification. @see Algorithm::category -const std::string ReflectometryReductionOne::category() const { - return "Reflectometry"; -} - -//---------------------------------------------------------------------------------------------- - -//---------------------------------------------------------------------------------------------- -/** Initialize the algorithm's properties. -*/ -void ReflectometryReductionOne::init() { - - declareProperty(make_unique>( - "InputWorkspace", "", Direction::Input), - "Run to reduce."); - - std::vector propOptions; - propOptions.push_back(pointDetectorAnalysis); - propOptions.push_back(multiDetectorAnalysis); - - declareProperty( - "AnalysisMode", "PointDetectorAnalysis", - boost::make_shared(propOptions), - "The type of analysis to perform. Point detector or multi detector."); - - declareProperty(make_unique>("RegionOfDirectBeam"), - "Indices of the spectra a pair (lower, upper) that mark the " - "ranges that correspond to the direct beam in multi-detector " - "mode."); - - this->initIndexInputs(); - this->initWavelengthInputs(); - - declareProperty(make_unique>( - "DetectorComponentName", "", Direction::Input), - "Name of the detector component i.e. point-detector. If " - "these are not specified, the algorithm will attempt lookup " - "using a standard naming convention."); - - declareProperty(make_unique>( - "SampleComponentName", "", Direction::Input), - "Name of the sample component i.e. some-surface-holder. If " - "these are not specified, the algorithm will attempt lookup " - "using a standard naming convention."); - - declareProperty(make_unique>("OutputWorkspace", "", - Direction::Output), - "Output Workspace IvsQ."); - - declareProperty(make_unique>("OutputWorkspaceWavelength", - "", Direction::Output, - PropertyMode::Optional), - "Output Workspace IvsLam. Intermediate workspace."); - - declareProperty(make_unique>( - "ThetaIn", Mantid::EMPTY_DBL(), Direction::Input), - "Final theta value in degrees. Optional, this value will be " - "calculated internally and provided as ThetaOut if not " - "provided."); - - declareProperty(make_unique>( - "ThetaOut", Mantid::EMPTY_DBL(), Direction::Output), - "Calculated final theta in degrees."); - - declareProperty("NormalizeByIntegratedMonitors", true, - "Normalize by dividing by the integrated monitors."); - - declareProperty(make_unique>( - "CorrectDetectorPositions", true, Direction::Input), - "Correct detector positions using ThetaIn (if given)"); - - declareProperty( - make_unique>( - "FirstTransmissionRun", "", Direction::Input, PropertyMode::Optional), - "First transmission run, or the low wavelength transmission run if " - "SecondTransmissionRun is also provided."); - - auto inputValidator = boost::make_shared(tofUnitId); - declareProperty(make_unique>( - "SecondTransmissionRun", "", Direction::Input, - PropertyMode::Optional, inputValidator), - "Second, high wavelength transmission run. Optional. Causes " - "the FirstTransmissionRun to be treated as the low " - "wavelength transmission run."); - - this->initStitchingInputs(); - - declareProperty(make_unique>("StrictSpectrumChecking", - true, Direction::Input), - "Enforces spectrum number checking prior to normalization"); - - std::vector correctionAlgorithms = { - "None", "PolynomialCorrection", "ExponentialCorrection"}; - declareProperty("CorrectionAlgorithm", "None", - boost::make_shared(correctionAlgorithms), - "The type of correction to perform."); - - declareProperty(make_unique>("Polynomial"), - "Coefficients to be passed to the PolynomialCorrection" - " algorithm."); - - declareProperty( - make_unique>("C0", 0.0, Direction::Input), - "C0 value to be passed to the ExponentialCorrection algorithm."); - - declareProperty( - make_unique>("C1", 0.0, Direction::Input), - "C1 value to be passed to the ExponentialCorrection algorithm."); - - setPropertyGroup("CorrectionAlgorithm", "Polynomial Corrections"); - setPropertyGroup("Polynomial", "Polynomial Corrections"); - setPropertyGroup("C0", "Polynomial Corrections"); - setPropertyGroup("C1", "Polynomial Corrections"); - - setPropertySettings( - "Polynomial", - Kernel::make_unique( - "CorrectionAlgorithm", IS_EQUAL_TO, "PolynomialCorrection")); - setPropertySettings( - "C0", Kernel::make_unique( - "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection")); - setPropertySettings( - "C1", Kernel::make_unique( - "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection")); - - setPropertyGroup("FirstTransmissionRun", "Transmission"); - setPropertyGroup("SecondTransmissionRun", "Transmission"); - setPropertyGroup("Params", "Transmission"); - setPropertyGroup("StartOverlap", "Transmission"); - setPropertyGroup("EndOverlap", "Transmission"); - - // Only ask for transmission parameters when a FirstTranmissionRun has been - // provided - setPropertySettings("SecondTransmissionRun", - Kernel::make_unique( - "FirstTransmissionRun", IS_NOT_DEFAULT)); - setPropertySettings("Params", - Kernel::make_unique( - "FirstTransmissionRun", IS_NOT_DEFAULT)); - setPropertySettings("StartOverlap", - Kernel::make_unique( - "FirstTransmissionRun", IS_NOT_DEFAULT)); - setPropertySettings("EndOverlap", - Kernel::make_unique( - "FirstTransmissionRun", IS_NOT_DEFAULT)); - - // Only use region of direct beam when in multi-detector analysis mode. - setPropertySettings( - "RegionOfDirectBeam", - Kernel::make_unique( - "AnalysisMode", IS_EQUAL_TO, "MultiDetectorAnalysis")); - declareProperty("ScaleFactor", Mantid::EMPTY_DBL(), - "Factor you wish to scale Q workspace by.", Direction::Input); - declareProperty("MomentumTransferMinimum", Mantid::EMPTY_DBL(), - "Minimum Q value in IvsQ " - "Workspace. Used for Rebinning " - "the IvsQ Workspace", - Direction::Input); - declareProperty("MomentumTransferStep", Mantid::EMPTY_DBL(), - "Resolution value in IvsQ Workspace. Used for Rebinning the " - "IvsQ Workspace. This value will be made minus to apply " - "logarithmic rebinning. If you wish to have linear " - "bin-widths then please provide a negative DQQ", - Direction::Input); - declareProperty("MomentumTransferMaximum", Mantid::EMPTY_DBL(), - "Maximum Q value in IvsQ " - "Workspace. Used for Rebinning " - "the IvsQ Workspace", - Direction::Input); -} - -/** -* Correct the position of the detectors based on the input theta value. -* @param toCorrect : Workspace to correct detector positions on. -* @param thetaInDeg : Theta in degrees to use in correction calculations. -* @param isPointDetector : True if using point detector analysis -* @return Copy with positions corrected. -*/ -MatrixWorkspace_sptr -ReflectometryReductionOne::correctPosition(API::MatrixWorkspace_sptr &toCorrect, - const double &thetaInDeg, - const bool isPointDetector) { - g_log.debug("Correcting position using theta."); - - auto correctPosAlg = this->createChildAlgorithm( - "SpecularReflectionPositionCorrect", -1, -1, true, 1); - correctPosAlg->initialize(); - correctPosAlg->setProperty("InputWorkspace", toCorrect); - - const std::string analysisMode = this->getProperty("AnalysisMode"); - correctPosAlg->setProperty("AnalysisMode", analysisMode); - auto instrument = toCorrect->getInstrument(); - IComponent_const_sptr sample = this->getSurfaceSampleComponent(instrument); - correctPosAlg->setProperty("SampleComponentName", sample->getName()); - correctPosAlg->setProperty("TwoThetaIn", thetaInDeg * 2); - - if (isPointDetector) { - IComponent_const_sptr detector = - this->getDetectorComponent(instrument, isPointDetector); - correctPosAlg->setProperty("DetectorComponentName", detector->getName()); - } else { - auto specNumbers = getSpectrumNumbers(toCorrect); - correctPosAlg->setProperty("SpectrumNumbersOfDetectors", specNumbers); - for (auto specNumber : specNumbers) { - std::stringstream buffer; - buffer << "Writing out: " << specNumber; - g_log.notice(buffer.str()); - } - } - correctPosAlg->execute(); - MatrixWorkspace_sptr corrected = - correctPosAlg->getProperty("OutputWorkspace"); - - return corrected; -} -/** -* @param toConvert : workspace used to get instrument components -* @param thetaOut : angle between sample and detectors (in Degrees) -* @return Theta : the value by which we rotate the source (in Degrees) -*/ -double ReflectometryReductionOne::getAngleForSourceRotation( - MatrixWorkspace_sptr toConvert, double thetaOut) { - auto instrument = toConvert->getInstrument(); - auto instrumentUpVector = instrument->getReferenceFrame()->vecPointingUp(); - // check to see if calculated theta is the same as theta from instrument setup - auto instrumentBeamDirection = instrument->getBeamDirection(); - double currentThetaInFromInstrument = - instrumentUpVector.angle(instrumentBeamDirection) * (180 / M_PI) - 90; - bool isInThetaEqualToOutTheta = - std::abs(currentThetaInFromInstrument - thetaOut) < - Mantid::Kernel::Tolerance; - // the angle by which we rotate the source - double rotationTheta = 0.0; - if (!isInThetaEqualToOutTheta /*source needs rotation*/) { - rotationTheta = thetaOut - currentThetaInFromInstrument; - } - return rotationTheta; -} - -/** -* Convert an input workspace into an IvsQ workspace. -* -* @param toConvert : Workspace to convert -* @param bCorrectPosition : Flag to indicate that detector positions should be -*corrected based on the input theta values. -* @param thetaInDeg : Theta in Degrees. Used for correction. -* @param isPointDetector: Is point detector analysis -* @return -*/ -Mantid::API::MatrixWorkspace_sptr ReflectometryReductionOne::toIvsQ( - API::MatrixWorkspace_sptr &toConvert, const bool bCorrectPosition, - OptionalDouble &thetaInDeg, const bool isPointDetector) { - /* - * Can either calculate a missing theta value for the purposes of reporting, - * or correct positions based on a theta value, - * but not both. The processing is effectively circular if both are applied. - */ - if (!thetaInDeg.is_initialized()) { - g_log.debug("Calculating final theta."); - - auto correctThetaAlg = this->createChildAlgorithm( - "SpecularReflectionCalculateTheta", -1, -1, true, 1); - correctThetaAlg->initialize(); - correctThetaAlg->setProperty("InputWorkspace", toConvert); - const std::string analysisMode = this->getProperty("AnalysisMode"); - correctThetaAlg->setProperty("AnalysisMode", analysisMode); - const std::string sampleComponentName = - this->getProperty("SampleComponentName"); - correctThetaAlg->setProperty("SampleComponentName", sampleComponentName); - if (isPointDetector) { - const std::string detectorComponentName = - this->getPropertyValue("DetectorComponentName"); - correctThetaAlg->setProperty("DetectorComponentName", - detectorComponentName); - } else { - std::vector spectrumNumbers = getSpectrumNumbers(toConvert); - correctThetaAlg->setProperty("SpectrumNumbersOfDetectors", - spectrumNumbers); - } - correctThetaAlg->execute(); - const double twoTheta = correctThetaAlg->getProperty("TwoTheta"); - - thetaInDeg = twoTheta / 2; - - } else if (bCorrectPosition) { - toConvert = correctPosition(toConvert, thetaInDeg.get(), isPointDetector); - } - - // Rotate the source (needed before ConvertUnits) - double rotationTheta = getAngleForSourceRotation(toConvert, thetaInDeg.get()); - if (rotationTheta != 0.0) { - auto rotateSource = this->createChildAlgorithm("RotateSource"); - rotateSource->setChild(true); - rotateSource->initialize(); - rotateSource->setProperty("Workspace", toConvert); - rotateSource->setProperty("Angle", rotationTheta); - rotateSource->execute(); - } - - // Always convert units. - auto convertUnits = this->createChildAlgorithm("ConvertUnits"); - convertUnits->initialize(); - convertUnits->setProperty("InputWorkspace", toConvert); - convertUnits->setProperty("Target", "MomentumTransfer"); - convertUnits->execute(); - MatrixWorkspace_sptr inQ = convertUnits->getProperty("OutputWorkspace"); - - // Rotate the source back to its original position - if (rotationTheta != 0.0) { - // for IvsLam Workspace - auto rotateSource = this->createChildAlgorithm("RotateSource"); - rotateSource->setChild(true); - rotateSource->initialize(); - rotateSource->setProperty("Workspace", toConvert); - rotateSource->setProperty("Angle", -rotationTheta); - rotateSource->execute(); - // for IvsQ Workspace - rotateSource->setProperty("Workspace", inQ); - rotateSource->setProperty("Angle", -rotationTheta); - rotateSource->execute(); - } - - return inQ; -} - -/** -* Get the sample component. Use the name provided as a property as the basis -*for the lookup as a priority. -* -* Throws if the name is invalid. -* @param inst : Instrument to search through -* @return : The component : The component object found. -*/ -Mantid::Geometry::IComponent_const_sptr -ReflectometryReductionOne::getSurfaceSampleComponent( - Mantid::Geometry::Instrument_const_sptr inst) { - std::string sampleComponent = "some-surface-holder"; - if (!isPropertyDefault("SampleComponentName")) { - sampleComponent = this->getPropertyValue("SampleComponentName"); - } - auto searchResult = inst->getComponentByName(sampleComponent); - if (searchResult == nullptr) { - throw std::invalid_argument(sampleComponent + - " does not exist. Check input properties."); - } - return searchResult; -} - -/** -* Get the detector component. Use the name provided as a property as the basis -*for the lookup as a priority. -* -* Throws if the name is invalid. -* @param inst : Instrument to search through. -* @param isPointDetector : True if this is a point detector. Used to guess a -*name. -* @return The component : The component object found. -*/ -boost::shared_ptr -ReflectometryReductionOne::getDetectorComponent( - Mantid::Geometry::Instrument_const_sptr inst, const bool isPointDetector) { - std::string componentToCorrect = - isPointDetector ? "point-detector" : "line-detector"; - if (!isPropertyDefault("DetectorComponentName")) { - componentToCorrect = this->getPropertyValue("DetectorComponentName"); - } - boost::shared_ptr searchResult = - inst->getComponentByName(componentToCorrect); - if (searchResult == nullptr) { - throw std::invalid_argument(componentToCorrect + - " does not exist. Check input properties."); - } - return searchResult; -} - -//---------------------------------------------------------------------------------------------- -/** Execute the algorithm. -*/ -void ReflectometryReductionOne::exec() { - MatrixWorkspace_sptr runWS = getProperty("InputWorkspace"); - - OptionalMatrixWorkspace_sptr firstTransmissionRun; - OptionalMatrixWorkspace_sptr secondTransmissionRun; - OptionalDouble stitchingStart; - OptionalDouble stitchingDelta; - OptionalDouble stitchingEnd; - OptionalDouble stitchingStartOverlap; - OptionalDouble stitchingEndOverlap; - - getTransmissionRunInfo(firstTransmissionRun, secondTransmissionRun, - stitchingStart, stitchingDelta, stitchingEnd, - stitchingStartOverlap, stitchingEndOverlap); - - OptionalDouble theta; - if (!isPropertyDefault("ThetaIn")) { - double temp = this->getProperty("ThetaIn"); - theta = temp; - } - const std::string strAnalysisMode = getProperty("AnalysisMode"); - const bool isPointDetector = (pointDetectorAnalysis == strAnalysisMode); - const bool isMultiDetector = (multiDetectorAnalysis == strAnalysisMode); - - const MinMax wavelengthInterval = - this->getMinMax("WavelengthMin", "WavelengthMax"); - - const std::string processingCommands = getWorkspaceIndexList(); - - OptionalWorkspaceIndexes directBeam; - fetchOptionalLowerUpperPropertyValue("RegionOfDirectBeam", isPointDetector, - directBeam); - - auto instrument = runWS->getInstrument(); - - const OptionalInteger i0MonitorIndex = checkForOptionalInstrumentDefault( - this, "I0MonitorIndex", instrument, "I0MonitorIndex"); - - const OptionalMinMax monitorBackgroundWavelengthInterval = getOptionalMinMax( - this, "MonitorBackgroundWavelengthMin", "MonitorBackgroundWavelengthMax", - instrument, "MonitorBackgroundWavelengthMin", - "MonitorBackgroundWavelengthMax"); - const OptionalMinMax monitorIntegrationWavelengthInterval = getOptionalMinMax( - this, "MonitorIntegrationWavelengthMin", - "MonitorIntegrationWavelengthMax", instrument, - "MonitorIntegrationWavelengthMin", "MonitorIntegrationWavelengthMax"); - - const bool correctDetectorPositions = getProperty("CorrectDetectorPositions"); - - MatrixWorkspace_sptr IvsLam; // Output workspace - MatrixWorkspace_sptr IvsQ; // Output workspace - - auto xUnitID = runWS->getAxis(0)->unit()->unitID(); - - if (xUnitID == "Wavelength") { - // If the input workspace is in lambda, we don't need to do any corrections, - // just use it as is. - g_log.information("Input workspace already in unit 'Wavelength'. Skipping " - "lambda conversions."); - IvsLam = runWS; - } else if (xUnitID == "TOF") { - // If the input workspace is in TOF, do some corrections and generate IvsLam - // from it. - DetectorMonitorWorkspacePair inLam = - toLam(runWS, processingCommands, i0MonitorIndex, wavelengthInterval, - monitorBackgroundWavelengthInterval); - auto detectorWS = inLam.get<0>(); - auto monitorWS = inLam.get<1>(); - - if (isMultiDetector) { - if (directBeam.is_initialized()) { - // Sum over the direct beam. - WorkspaceIndexList db = directBeam.get(); - std::stringstream buffer; - buffer << db.front() << "-" << db.back(); - MatrixWorkspace_sptr regionOfDirectBeamWS = - this->toLamDetector(buffer.str(), runWS, wavelengthInterval); - - // Rebin to the detector workspace - auto rebinToWorkspaceAlg = - this->createChildAlgorithm("RebinToWorkspace"); - rebinToWorkspaceAlg->initialize(); - rebinToWorkspaceAlg->setProperty("WorkspaceToRebin", - regionOfDirectBeamWS); - rebinToWorkspaceAlg->setProperty("WorkspaceToMatch", detectorWS); - rebinToWorkspaceAlg->execute(); - regionOfDirectBeamWS = - rebinToWorkspaceAlg->getProperty("OutputWorkspace"); - - // Normalize by the direct beam. - detectorWS = divide(detectorWS, regionOfDirectBeamWS); - } - } - - const bool normalizeByIntMon = getProperty("NormalizeByIntegratedMonitors"); - if (normalizeByIntMon) { - auto integrationAlg = this->createChildAlgorithm("Integration"); - integrationAlg->initialize(); - integrationAlg->setProperty("InputWorkspace", monitorWS); - if (monitorIntegrationWavelengthInterval.is_initialized()) { - integrationAlg->setProperty( - "RangeLower", monitorIntegrationWavelengthInterval.get().get<0>()); - integrationAlg->setProperty( - "RangeUpper", monitorIntegrationWavelengthInterval.get().get<1>()); - } - integrationAlg->execute(); - MatrixWorkspace_sptr integratedMonitor = - integrationAlg->getProperty("OutputWorkspace"); - - IvsLam = divide( - detectorWS, - integratedMonitor); // Normalize by the integrated monitor counts. - } else { - IvsLam = divide(detectorWS, monitorWS); - } - } else { - // Neither TOF or Lambda? Abort. - throw std::invalid_argument( - "InputWorkspace must have units of TOF or Wavelength"); - } - - if (firstTransmissionRun.is_initialized()) { - // Perform transmission correction. - IvsLam = this->transmissonCorrection( - IvsLam, wavelengthInterval, monitorBackgroundWavelengthInterval, - monitorIntegrationWavelengthInterval, i0MonitorIndex, - firstTransmissionRun.get(), secondTransmissionRun, stitchingStart, - stitchingDelta, stitchingEnd, stitchingStartOverlap, - stitchingEndOverlap, processingCommands); - } else if (getPropertyValue("CorrectionAlgorithm") != "None") { - IvsLam = algorithmicCorrection(IvsLam); - } else { - g_log.warning("No transmission correction will be applied."); - } - - IvsQ = this->toIvsQ(IvsLam, correctDetectorPositions, theta, isPointDetector); - double momentumTransferMinimum = getProperty("MomentumTransferMinimum"); - double momentumTransferStep = getProperty("MomentumTransferStep"); - double momentumTransferMaximum = getProperty("MomentumTransferMaximum"); - MantidVec QParams; - if (isDefault("MomentumTransferMinimum")) - momentumTransferMinimum = calculateQ(IvsLam->x(0).back(), theta.get()); - if (isDefault("MomentumTransferMaximum")) - momentumTransferMaximum = calculateQ(IvsLam->x(0).front(), theta.get()); - if (isDefault("MomentumTransferStep")) { - // if the DQQ is not given for this run. - // we will use NRCalculateSlitResolution to produce this value - // for us. - IAlgorithm_sptr calcResAlg = - createChildAlgorithm("NRCalculateSlitResolution"); - calcResAlg->setProperty("Workspace", runWS); - calcResAlg->setProperty("TwoTheta", theta.get()); - calcResAlg->execute(); - if (!calcResAlg->isExecuted()) - throw std::runtime_error( - "NRCalculateSlitResolution failed. Please manually " - "enter a value for MomentumTransferStep."); - momentumTransferStep = calcResAlg->getProperty("Resolution"); - } - if (momentumTransferMinimum > momentumTransferMaximum) - throw std::invalid_argument("MomentumTransferMinimum must be less than " - "MomentumTransferMaximum. Please check your " - "inputs for these Properties."); - QParams.push_back(momentumTransferMinimum); - QParams.push_back(-momentumTransferStep); - QParams.push_back(momentumTransferMaximum); - IAlgorithm_sptr algRebin = this->createChildAlgorithm("Rebin"); - algRebin->initialize(); - algRebin->setProperty("InputWorkspace", IvsQ); - algRebin->setProperty("OutputWorkspace", IvsQ); - algRebin->setProperty("Params", QParams); - algRebin->execute(); - if (!algRebin->isExecuted()) - throw std::runtime_error("Failed to run Rebin algorithm"); - IvsQ = algRebin->getProperty("OutputWorkspace"); - double scaleFactor = getProperty("ScaleFactor"); - if (!isDefault("ScaleFactor")) { - IAlgorithm_sptr algScale = this->createChildAlgorithm("Scale"); - algScale->initialize(); - algScale->setProperty("InputWorkspace", IvsQ); - algScale->setProperty("OutputWorkspace", IvsQ); - algScale->setProperty("Factor", 1.0 / scaleFactor); - algScale->execute(); - if (!algScale->isExecuted()) - throw std::runtime_error("Failed to run Scale algorithm"); - IvsQ = algScale->getProperty("OutputWorkspace"); - } - setProperty("ThetaOut", theta.get()); - setProperty("OutputWorkspaceWavelength", IvsLam); - setProperty("OutputWorkspace", IvsQ); - // setting these values so the Interface can retrieve them from - // ReflectometryReductionOneAuto. - setProperty("MomentumTransferMinimum", momentumTransferMinimum); - setProperty("MomentumTransferStep", momentumTransferStep); - setProperty("MomentumTransferMaximum", momentumTransferMaximum); -} - -/** -* Perform Transmission Corrections. -* @param IvsLam : Run workspace which is to be normalized by the results of the -* transmission corrections. -* @param wavelengthInterval : Wavelength interval for the run workspace. -* @param wavelengthMonitorBackgroundInterval : Wavelength interval for the -* monitor background -* @param wavelengthMonitorIntegrationInterval : Wavelength interval for the -* monitor integration -* @param i0MonitorIndex : Monitor index for the I0 monitor -* @param firstTransmissionRun : The first transmission run -* @param secondTransmissionRun : The second transmission run (optional) -* @param stitchingStart : Stitching start in wavelength (optional but dependent -* on secondTransmissionRun) -* @param stitchingDelta : Stitching delta in wavelength (optional but dependent -* on secondTransmissionRun) -* @param stitchingEnd : Stitching end in wavelength (optional but dependent on -* secondTransmissionRun) -* @param stitchingStartOverlap : Stitching start wavelength overlap (optional -* but dependent on secondTransmissionRun) -* @param stitchingEndOverlap : Stitching end wavelength overlap (optional but -* dependent on secondTransmissionRun) -* @param numeratorProcessingCommands: Processing commands used on detector -* workspace. -* @return Normalized run workspace by the transmission workspace, which have -* themselves been converted to Lam, normalized by monitors and possibly -* stitched together. -*/ -MatrixWorkspace_sptr ReflectometryReductionOne::transmissonCorrection( - MatrixWorkspace_sptr IvsLam, const MinMax &wavelengthInterval, - const OptionalMinMax &wavelengthMonitorBackgroundInterval, - const OptionalMinMax &wavelengthMonitorIntegrationInterval, - const OptionalInteger &i0MonitorIndex, - MatrixWorkspace_sptr firstTransmissionRun, - OptionalMatrixWorkspace_sptr secondTransmissionRun, - const OptionalDouble &stitchingStart, const OptionalDouble &stitchingDelta, - const OptionalDouble &stitchingEnd, - const OptionalDouble &stitchingStartOverlap, - const OptionalDouble &stitchingEndOverlap, - const std::string &numeratorProcessingCommands) { - g_log.debug( - "Extracting first transmission run workspace indexes from spectra"); - - const bool strictSpectrumChecking = getProperty("StrictSpectrumChecking"); - - MatrixWorkspace_sptr denominator = firstTransmissionRun; - Unit_const_sptr xUnit = firstTransmissionRun->getAxis(0)->unit(); - if (xUnit->unitID() == tofUnitId) { - std::string spectrumProcessingCommands = numeratorProcessingCommands; - /* - If we have strict spectrum checking, the processing commands need to be - made from the - numerator workspace AND the transmission workspace based on matching - spectrum numbers. - */ - if (strictSpectrumChecking) { - spectrumProcessingCommands = - createWorkspaceIndexListFromDetectorWorkspace(IvsLam, - firstTransmissionRun); - } - - // Make the transmission run. - auto alg = this->createChildAlgorithm("CreateTransmissionWorkspace", -1, -1, - true, 1); - alg->initialize(); - alg->setProperty("FirstTransmissionRun", firstTransmissionRun); - if (secondTransmissionRun.is_initialized()) { - alg->setProperty("SecondTransmissionRun", secondTransmissionRun.get()); - - if (stitchingStart.is_initialized() && stitchingEnd.is_initialized() && - stitchingDelta.is_initialized()) { - const std::vector params = { - stitchingStart.get(), stitchingDelta.get(), stitchingEnd.get()}; - alg->setProperty("Params", params); - } else if (stitchingDelta.is_initialized()) { - alg->setProperty("Params", - std::vector(1, stitchingDelta.get())); - } - if (stitchingStartOverlap.is_initialized()) { - alg->setProperty("StartOverlap", stitchingStartOverlap.get()); - } - if (stitchingEndOverlap.is_initialized()) { - alg->setProperty("EndOverlap", stitchingEndOverlap.get()); - } - } - alg->setProperty("ProcessingInstructions", spectrumProcessingCommands); - if (i0MonitorIndex.is_initialized()) { - alg->setProperty("I0MonitorIndex", i0MonitorIndex.get()); - } - alg->setProperty("WavelengthMin", wavelengthInterval.get<0>()); - alg->setProperty("WavelengthMax", wavelengthInterval.get<1>()); - if (wavelengthMonitorBackgroundInterval.is_initialized()) { - alg->setProperty("MonitorBackgroundWavelengthMin", - wavelengthMonitorBackgroundInterval.get().get<0>()); - alg->setProperty("MonitorBackgroundWavelengthMax", - wavelengthMonitorBackgroundInterval.get().get<1>()); - } - if (wavelengthMonitorIntegrationInterval.is_initialized()) { - alg->setProperty("MonitorIntegrationWavelengthMin", - wavelengthMonitorIntegrationInterval.get().get<0>()); - alg->setProperty("MonitorIntegrationWavelengthMax", - wavelengthMonitorIntegrationInterval.get().get<1>()); - } - alg->execute(); - denominator = alg->getProperty("OutputWorkspace"); - } - - // Rebin the transmission run to be the same as the input. - auto rebinToWorkspaceAlg = this->createChildAlgorithm("RebinToWorkspace"); - rebinToWorkspaceAlg->initialize(); - rebinToWorkspaceAlg->setProperty("WorkspaceToMatch", IvsLam); - rebinToWorkspaceAlg->setProperty("WorkspaceToRebin", denominator); - rebinToWorkspaceAlg->execute(); - denominator = rebinToWorkspaceAlg->getProperty("OutputWorkspace"); - - verifySpectrumMaps(IvsLam, denominator, strictSpectrumChecking); - - // Do normalization. - MatrixWorkspace_sptr normalizedIvsLam = divide(IvsLam, denominator); - return normalizedIvsLam; -} - -/** -* Perform transmission correction using alternative correction algorithms. -* @param IvsLam : Run workspace which is to be normalized by the results of the -* transmission corrections. -* @return Corrected workspace -*/ -MatrixWorkspace_sptr -ReflectometryReductionOne::algorithmicCorrection(MatrixWorkspace_sptr IvsLam) { - - const std::string corrAlgName = getProperty("CorrectionAlgorithm"); - - IAlgorithm_sptr corrAlg = createChildAlgorithm(corrAlgName); - corrAlg->initialize(); - if (corrAlgName == "PolynomialCorrection") { - corrAlg->setPropertyValue("Coefficients", getPropertyValue("Polynomial")); - } else if (corrAlgName == "ExponentialCorrection") { - corrAlg->setPropertyValue("C0", getPropertyValue("C0")); - corrAlg->setPropertyValue("C1", getPropertyValue("C1")); - } else { - throw std::runtime_error("Unknown correction algorithm: " + corrAlgName); - } - - corrAlg->setProperty("InputWorkspace", IvsLam); - corrAlg->setProperty("Operation", "Divide"); - corrAlg->execute(); - - return corrAlg->getProperty("OutputWorkspace"); -} - -/** -@param ws1 : First workspace to compare -@param ws2 : Second workspace to compare against -@param severe: True to indicate that failure to verify should result in an -exception. Otherwise a warning is generated. -*/ -void ReflectometryReductionOne::verifySpectrumMaps( - MatrixWorkspace_const_sptr ws1, MatrixWorkspace_const_sptr ws2, - const bool severe) { - auto map1 = ws1->getSpectrumToWorkspaceIndexMap(); - auto map2 = ws2->getSpectrumToWorkspaceIndexMap(); - if (map1 != map2) { - std::string message = "Spectrum maps between workspaces do NOT match up."; - if (severe) { - throw std::invalid_argument(message); - } else { - this->g_log.warning(message); - } - } -} - -} // namespace Algorithms -} // namespace Mantid diff --git a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp b/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp deleted file mode 100644 index d2a2701bda63..000000000000 --- a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp +++ /dev/null @@ -1,848 +0,0 @@ -#include "MantidAlgorithms/BoostOptionalToAlgorithmProperty.h" -#include "MantidAlgorithms/ReflectometryReductionOneAuto.h" -#include "MantidAPI/WorkspaceGroup.h" -#include "MantidAPI/WorkspaceUnitValidator.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/BoundedValidator.h" -#include "MantidKernel/EnabledWhenProperty.h" -#include "MantidKernel/ListValidator.h" -#include "MantidKernel/RebinParamsValidator.h" -#include - -/*Anonymous namespace*/ -namespace { -/** -* Helper free function to calculate MomentumTransfer from lambda and theta -* @param lambda : Value in wavelength -* @param theta : Value in Degrees -* @return MomentumTransfer -* @ -*/ -double calculateQ(double lambda, double theta) { - if (lambda == 0.0) - throw std::runtime_error("Minimum/Maximum value of the IvsLambda Workspace " - "is 0. Cannot calculate Q"); - double thetaInRad = theta * M_PI / 180; - return (4 * M_PI * sin(thetaInRad)) / lambda; -} -} -/*end of Anonymous namespace*/ -namespace Mantid { -namespace Algorithms { - -using namespace Mantid::Kernel; -using namespace Mantid::API; - -// Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(ReflectometryReductionOneAuto) - -//---------------------------------------------------------------------------------------------- - -/// Algorithm's name for identification. @see Algorithm::name -const std::string ReflectometryReductionOneAuto::name() const { - return "ReflectometryReductionOneAuto"; -} - -/// Algorithm's version for identification. @see Algorithm::version -int ReflectometryReductionOneAuto::version() const { return 1; } - -/// Algorithm's category for identification. @see Algorithm::category -const std::string ReflectometryReductionOneAuto::category() const { - return "Reflectometry\\ISIS"; -} - -/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary -const std::string ReflectometryReductionOneAuto::summary() const { - return "Reduces a single TOF/Lambda reflectometry run into a mod Q vs I/I0 " - "workspace. Performs transmission corrections."; -} - -//---------------------------------------------------------------------------------------------- -/** Initialize the algorithm's properties. -*/ -void ReflectometryReductionOneAuto::init() { - declareProperty( - make_unique>( - "InputWorkspace", "", Direction::Input, PropertyMode::Mandatory), - "Input run in TOF or Lambda"); - - std::vector analysis_modes{"PointDetectorAnalysis", - "MultiDetectorAnalysis"}; - auto analysis_mode_validator = - boost::make_shared(analysis_modes); - - declareProperty( - make_unique>("RegionOfDirectBeam", Direction::Input), - "Indices of the spectra a pair (lower, upper) that mark the ranges that " - "correspond to the direct beam in multi-detector mode."); - - declareProperty("AnalysisMode", analysis_modes[0], analysis_mode_validator, - "Analysis Mode to Choose", Direction::Input); - - declareProperty( - make_unique>( - "FirstTransmissionRun", "", Direction::Input, PropertyMode::Optional), - "First transmission run workspace in TOF or Wavelength"); - - auto tof_validator = boost::make_shared("TOF"); - declareProperty(make_unique>( - "SecondTransmissionRun", "", Direction::Input, - PropertyMode::Optional, tof_validator), - "Second transmission run workspace in TOF"); - declareProperty(make_unique>( - "OutputWorkspace", "", Direction::Output), - "Output workspace in wavelength q"); - declareProperty(make_unique>( - "OutputWorkspaceWavelength", "", Direction::Output), - "Output workspace in wavelength"); - - declareProperty( - make_unique>( - "Params", boost::make_shared(true)), - "A comma separated list of first bin boundary, width, last bin boundary. " - "These parameters are used for stitching together transmission runs. " - "Values are in wavelength (angstroms). This input is only needed if a " - "SecondTransmission run is provided."); - - declareProperty("StartOverlap", Mantid::EMPTY_DBL(), "Overlap in Q.", - Direction::Input); - - declareProperty("EndOverlap", Mantid::EMPTY_DBL(), "End overlap in Q.", - Direction::Input); - declareProperty("ScaleFactor", 1.0, - "Factor you wish to scale Q workspace by.", Direction::Input); - auto index_bounds = boost::make_shared>(); - index_bounds->setLower(0); - - declareProperty(make_unique>( - "I0MonitorIndex", Mantid::EMPTY_INT(), Direction::Input), - "I0 monitor workspace index. Optional."); - declareProperty(make_unique>( - "ProcessingInstructions", "", Direction::Input), - "Grouping pattern of workspace indices to yield only the" - " detectors of interest. See GroupDetectors for syntax."); - declareProperty("WavelengthMin", Mantid::EMPTY_DBL(), - "Wavelength Min in angstroms", Direction::Input); - declareProperty("WavelengthMax", Mantid::EMPTY_DBL(), - "Wavelength Max in angstroms", Direction::Input); - declareProperty("WavelengthStep", Mantid::EMPTY_DBL(), - "Wavelength step in angstroms", Direction::Input); - declareProperty("MomentumTransferMinimum", Mantid::EMPTY_DBL(), - "Minimum Q value in IvsQ " - "Workspace. Used for Rebinning " - "the IvsQ Workspace", - Direction::Input); - declareProperty("MomentumTransferStep", Mantid::EMPTY_DBL(), - "Resolution value in IvsQ Workspace. Used for Rebinning the " - "IvsQ Workspace. This value will be made minus to apply " - "logarithmic rebinning. If you wish to have linear " - "bin-widths then please provide a negative DQQ", - Direction::Input); - declareProperty("MomentumTransferMaximum", Mantid::EMPTY_DBL(), - "Maximum Q value in IvsQ " - "Workspace. Used for Rebinning " - "the IvsQ Workspace", - Direction::Input); - declareProperty("MonitorBackgroundWavelengthMin", Mantid::EMPTY_DBL(), - "Monitor wavelength background min in angstroms", - Direction::Input); - declareProperty("MonitorBackgroundWavelengthMax", Mantid::EMPTY_DBL(), - "Monitor wavelength background max in angstroms", - Direction::Input); - declareProperty("MonitorIntegrationWavelengthMin", Mantid::EMPTY_DBL(), - "Monitor integral min in angstroms", Direction::Input); - declareProperty("MonitorIntegrationWavelengthMax", Mantid::EMPTY_DBL(), - "Monitor integral max in angstroms", Direction::Input); - declareProperty(make_unique>( - "DetectorComponentName", "", Direction::Input), - "Name of the detector component i.e. point-detector. If " - "these are not specified, the algorithm will attempt lookup " - "using a standard naming convention."); - declareProperty(make_unique>( - "SampleComponentName", "", Direction::Input), - "Name of the sample component i.e. some-surface-holder. If " - "these are not specified, the algorithm will attempt lookup " - "using a standard naming convention."); - - declareProperty("ThetaIn", Mantid::EMPTY_DBL(), "Final theta in degrees", - Direction::Input); - declareProperty("ThetaOut", Mantid::EMPTY_DBL(), - "Calculated final theta in degrees.", Direction::Output); - - declareProperty("NormalizeByIntegratedMonitors", true, - "Normalize by dividing by the integrated monitors."); - - declareProperty("CorrectDetectorPositions", true, - "Correct detector positions using ThetaIn (if given)"); - - declareProperty("StrictSpectrumChecking", true, - "Strict checking between spectrum numbers in input " - "workspaces and transmission workspaces."); - std::vector correctionAlgorithms = { - "None", "AutoDetect", "PolynomialCorrection", "ExponentialCorrection"}; - declareProperty("CorrectionAlgorithm", "AutoDetect", - boost::make_shared(correctionAlgorithms), - "The type of correction to perform."); - - declareProperty(make_unique>("Polynomial"), - "Coefficients to be passed to the PolynomialCorrection" - " algorithm."); - - declareProperty( - make_unique>("C0", 0.0, Direction::Input), - "C0 value to be passed to the ExponentialCorrection algorithm."); - - declareProperty( - make_unique>("C1", 0.0, Direction::Input), - "C1 value to be passed to the ExponentialCorrection algorithm."); - - setPropertyGroup("CorrectionAlgorithm", "Polynomial Corrections"); - setPropertyGroup("Polynomial", "Polynomial Corrections"); - setPropertyGroup("C0", "Polynomial Corrections"); - setPropertyGroup("C1", "Polynomial Corrections"); - - setPropertySettings( - "Polynomial", - Kernel::make_unique( - "CorrectionAlgorithm", IS_EQUAL_TO, "PolynomialCorrection")); - setPropertySettings( - "C0", Kernel::make_unique( - "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection")); - setPropertySettings( - "C1", Kernel::make_unique( - "CorrectionAlgorithm", IS_EQUAL_TO, "ExponentialCorrection")); - - // Polarization correction inputs -------------- - std::vector propOptions; - propOptions.push_back(noPolarizationCorrectionMode()); - propOptions.push_back(pALabel()); - propOptions.push_back(pNRLabel()); - - declareProperty("PolarizationAnalysis", noPolarizationCorrectionMode(), - boost::make_shared(propOptions), - "What Polarization mode will be used?\n" - "None: No correction\n" - "PNR: Polarized Neutron Reflectivity mode\n" - "PA: Full Polarization Analysis PNR-PA"); - declareProperty( - Kernel::make_unique>(cppLabel(), Direction::Input), - "Effective polarizing power of the polarizing system. " - "Expressed as a ratio 0 < Pp < 1"); - declareProperty( - Kernel::make_unique>(cApLabel(), Direction::Input), - "Effective polarizing power of the analyzing system. " - "Expressed as a ratio 0 < Ap < 1"); - declareProperty( - Kernel::make_unique>(crhoLabel(), Direction::Input), - "Ratio of efficiencies of polarizer spin-down to polarizer " - "spin-up. This is characteristic of the polarizer flipper. " - "Values are constants for each term in a polynomial " - "expression."); - declareProperty(Kernel::make_unique>(cAlphaLabel(), - Direction::Input), - "Ratio of efficiencies of analyzer spin-down to analyzer " - "spin-up. This is characteristic of the analyzer flipper. " - "Values are factors for each term in a polynomial " - "expression."); - setPropertyGroup("PolarizationAnalysis", "Polarization Corrections"); - setPropertyGroup(cppLabel(), "Polarization Corrections"); - setPropertyGroup(cApLabel(), "Polarization Corrections"); - setPropertyGroup(crhoLabel(), "Polarization Corrections"); - setPropertyGroup(cAlphaLabel(), "Polarization Corrections"); - setPropertySettings(cppLabel(), - Kernel::make_unique( - "PolarizationAnalysis", IS_NOT_EQUAL_TO, - noPolarizationCorrectionMode())); - setPropertySettings(cApLabel(), - Kernel::make_unique( - "PolarizationAnalysis", IS_NOT_EQUAL_TO, - noPolarizationCorrectionMode())); - setPropertySettings(crhoLabel(), - Kernel::make_unique( - "PolarizationAnalysis", IS_NOT_EQUAL_TO, - noPolarizationCorrectionMode())); - setPropertySettings(cAlphaLabel(), - Kernel::make_unique( - "PolarizationAnalysis", IS_NOT_EQUAL_TO, - noPolarizationCorrectionMode())); -} - -//---------------------------------------------------------------------------------------------- -/** Execute the algorithm. -*/ -void ReflectometryReductionOneAuto::exec() { - MatrixWorkspace_sptr in_ws = getProperty("InputWorkspace"); - auto instrument = in_ws->getInstrument(); - - // Get all the inputs. - - std::string output_workspace_name = getPropertyValue("OutputWorkspace"); - std::string output_workspace_lam_name = - getPropertyValue("OutputWorkspaceWavelength"); - std::string analysis_mode = getPropertyValue("AnalysisMode"); - MatrixWorkspace_sptr first_ws = getProperty("FirstTransmissionRun"); - MatrixWorkspace_sptr second_ws = getProperty("SecondTransmissionRun"); - auto start_overlap = isSet("StartOverlap"); - auto end_overlap = isSet("EndOverlap"); - auto params = isSet("Params"); - auto i0_monitor_index = checkForOptionalInstrumentDefault( - this, "I0MonitorIndex", instrument, "I0MonitorIndex"); - - std::string processing_commands; - if (this->getPointerToProperty("ProcessingInstructions")->isDefault()) { - if (analysis_mode == "PointDetectorAnalysis") { - std::vector pointStart = - instrument->getNumberParameter("PointDetectorStart"); - std::vector pointStop = - instrument->getNumberParameter("PointDetectorStop"); - - if (pointStart.empty() || pointStop.empty()) - throw std::runtime_error( - "If ProcessingInstructions is not specified, BOTH " - "PointDetectorStart " - "and PointDetectorStop must exist as instrument parameters.\n" - "Please check if you meant to enter ProcessingInstructions or " - "if your instrument parameter file is correct."); - - const int detStart = static_cast(pointStart[0]); - const int detStop = static_cast(pointStop[0]); - - if (detStart == detStop) { - // If the range given only specifies one detector, we pass along just - // that one detector - processing_commands = std::to_string(detStart); - } else { - // Otherwise, we create a range. - processing_commands = - std::to_string(detStart) + ":" + std::to_string(detStop); - } - } else { - std::vector multiStart = - instrument->getNumberParameter("MultiDetectorStart"); - if (multiStart.empty()) - throw std::runtime_error( - "If ProcessingInstructions is not specified, MultiDetectorStart" - "must exist as an instrument parameter.\n" - "Please check if you meant to enter ProcessingInstructions or " - "if your instrument parameter file is correct."); - processing_commands = std::to_string(static_cast(multiStart[0])) + - ":" + - std::to_string(in_ws->getNumberHistograms() - 1); - } - } else { - std::string processing_commands_temp = - this->getProperty("ProcessingInstructions"); - processing_commands = processing_commands_temp; - } - - double wavelength_min = checkForMandatoryInstrumentDefault( - this, "WavelengthMin", instrument, "LambdaMin"); - double wavelength_max = checkForMandatoryInstrumentDefault( - this, "WavelengthMax", instrument, "LambdaMax"); - auto wavelength_step = isSet("WavelengthStep"); - auto wavelength_back_min = checkForOptionalInstrumentDefault( - this, "MonitorBackgroundWavelengthMin", instrument, - "MonitorBackgroundMin"); - auto wavelength_back_max = checkForOptionalInstrumentDefault( - this, "MonitorBackgroundWavelengthMax", instrument, - "MonitorBackgroundMax"); - auto wavelength_integration_min = checkForOptionalInstrumentDefault( - this, "MonitorIntegrationWavelengthMin", instrument, - "MonitorIntegralMin"); - auto wavelength_integration_max = checkForOptionalInstrumentDefault( - this, "MonitorIntegrationWavelengthMax", instrument, - "MonitorIntegralMax"); - - auto detector_component_name = isSet("DetectorComponentName"); - auto sample_component_name = isSet("SampleComponentName"); - auto theta_in = isSet("ThetaIn"); - auto region_of_direct_beam = isSet>("RegionOfDirectBeam"); - - bool correct_positions = this->getProperty("CorrectDetectorPositions"); - bool strict_spectrum_checking = this->getProperty("StrictSpectrumChecking"); - bool norm_by_int_mons = getProperty("NormalizeByIntegratedMonitors"); - const std::string correction_algorithm = getProperty("CorrectionAlgorithm"); - - // Pass the arguments and execute the main algorithm. - - IAlgorithm_sptr refRedOne = - createChildAlgorithm("ReflectometryReductionOne", -1, -1, true, 1); - refRedOne->initialize(); - if (refRedOne->isInitialized()) { - refRedOne->setProperty("InputWorkspace", in_ws); - refRedOne->setProperty("AnalysisMode", analysis_mode); - refRedOne->setProperty("OutputWorkspace", output_workspace_name); - refRedOne->setProperty("OutputWorkspaceWavelength", - output_workspace_lam_name); - refRedOne->setProperty("NormalizeByIntegratedMonitors", norm_by_int_mons); - - if (i0_monitor_index.is_initialized()) { - if (i0_monitor_index.get() >= 0) - refRedOne->setProperty("I0MonitorIndex", i0_monitor_index.get()); - else - throw std::invalid_argument( - "I0MonitorIndex must be an integer greater than or equal to 0"); - } - refRedOne->setProperty("ProcessingInstructions", processing_commands); - refRedOne->setProperty("WavelengthMin", wavelength_min); - refRedOne->setProperty("WavelengthMax", wavelength_max); - if (wavelength_back_min.is_initialized()) - refRedOne->setProperty("MonitorBackgroundWavelengthMin", - wavelength_back_min.get()); - if (wavelength_back_max.is_initialized()) - refRedOne->setProperty("MonitorBackgroundWavelengthMax", - wavelength_back_max.get()); - if (wavelength_integration_min.is_initialized()) - refRedOne->setProperty("MonitorIntegrationWavelengthMin", - wavelength_integration_min.get()); - if (wavelength_integration_max.is_initialized()) - refRedOne->setProperty("MonitorIntegrationWavelengthMax", - wavelength_integration_max.get()); - refRedOne->setProperty("CorrectDetectorPositions", correct_positions); - refRedOne->setProperty("StrictSpectrumChecking", strict_spectrum_checking); - if (correction_algorithm == "PolynomialCorrection") { - // Copy across the polynomial - refRedOne->setProperty("CorrectionAlgorithm", "PolynomialCorrection"); - refRedOne->setProperty("Polynomial", getPropertyValue("Polynomial")); - } else if (correction_algorithm == "ExponentialCorrection") { - // Copy across c0 and c1 - refRedOne->setProperty("CorrectionAlgorithm", "ExponentialCorrection"); - refRedOne->setProperty("C0", getPropertyValue("C0")); - refRedOne->setProperty("C1", getPropertyValue("C1")); - } else if (correction_algorithm == "AutoDetect") { - // Figure out what to do from the instrument - try { - auto inst = in_ws->getInstrument(); - - const std::vector corrVec = - inst->getStringParameter("correction"); - const std::string correctionStr = !corrVec.empty() ? corrVec[0] : ""; - - if (correctionStr.empty()) - throw std::runtime_error( - "'correction' instrument parameter was not found."); - - const std::vector polyVec = - inst->getStringParameter("polynomial"); - const std::string polyStr = !polyVec.empty() ? polyVec[0] : ""; - - const std::vector c0Vec = inst->getStringParameter("C0"); - const std::string c0Str = !c0Vec.empty() ? c0Vec[0] : ""; - - const std::vector c1Vec = inst->getStringParameter("C1"); - const std::string c1Str = !c1Vec.empty() ? c1Vec[0] : ""; - - if (correctionStr == "polynomial" && polyStr.empty()) - throw std::runtime_error( - "'polynomial' instrument parameter was not found."); - - if (correctionStr == "exponential" && (c0Str.empty() || c1Str.empty())) - throw std::runtime_error( - "'C0' or 'C1' instrument parameter was not found."); - - if (correctionStr == "polynomial") { - refRedOne->setProperty("CorrectionAlgorithm", "PolynomialCorrection"); - refRedOne->setProperty("Polynomial", polyStr); - } else if (correctionStr == "exponential") { - refRedOne->setProperty("CorrectionAlgorithm", - "ExponentialCorrection"); - refRedOne->setProperty("C0", c0Str); - refRedOne->setProperty("C1", c1Str); - } - - } catch (std::runtime_error &e) { - g_log.warning() << "Could not autodetect polynomial correction method. " - "Polynomial correction will not be performed. " - "Reason for failure: " << e.what() << '\n'; - refRedOne->setProperty("CorrectionAlgorithm", "None"); - } - - } else { - // None was selected - refRedOne->setProperty("CorrectionAlgorithm", "None"); - } - - if (first_ws) { - refRedOne->setProperty("FirstTransmissionRun", first_ws); - } - - if (second_ws) { - refRedOne->setProperty("SecondTransmissionRun", second_ws); - } - - if (start_overlap.is_initialized()) { - refRedOne->setProperty("StartOverlap", start_overlap.get()); - } - - if (end_overlap.is_initialized()) { - refRedOne->setProperty("EndOverlap", end_overlap.get()); - } - - if (params.is_initialized()) { - refRedOne->setProperty("Params", params.get()); - } - - if (wavelength_step.is_initialized()) { - refRedOne->setProperty("WavelengthStep", wavelength_step.get()); - } - - if (region_of_direct_beam.is_initialized()) { - refRedOne->setProperty("RegionOfDirectBeam", region_of_direct_beam.get()); - } - - if (detector_component_name.is_initialized()) { - refRedOne->setProperty("DetectorComponentName", - detector_component_name.get()); - } - - if (sample_component_name.is_initialized()) { - refRedOne->setProperty("SampleComponentName", - sample_component_name.get()); - } - - if (theta_in.is_initialized()) { - refRedOne->setProperty("ThetaIn", theta_in.get()); - } - double scaleFactor = getProperty("ScaleFactor"); - if (scaleFactor != 1.0) { - refRedOne->setProperty("ScaleFactor", scaleFactor); - } - auto momentumTransferMinimum = isSet("MomentumTransferMinimum"); - auto momentumTransferStep = isSet("MomentumTransferStep"); - auto momentumTransferMaximum = isSet("MomentumTransferMaximum"); - - if (momentumTransferStep.is_initialized()) { - refRedOne->setProperty("MomentumTransferStep", - momentumTransferStep.get()); - } - if (momentumTransferMinimum.is_initialized()) - refRedOne->setProperty("MomentumTransferMinimum", - momentumTransferMinimum.get()); - if (momentumTransferMaximum.is_initialized()) - refRedOne->setProperty("MomentumTransferMaximum", - momentumTransferMaximum.get()); - if (theta_in.is_initialized()) { - if (!momentumTransferMinimum.is_initialized()) - momentumTransferMinimum = calculateQ(wavelength_max, theta_in.get()); - if (!momentumTransferStep.is_initialized()) { - IAlgorithm_sptr calcResAlg = - AlgorithmManager::Instance().create("NRCalculateSlitResolution"); - calcResAlg->setProperty("Workspace", in_ws); - calcResAlg->setProperty("TwoTheta", theta_in.get()); - calcResAlg->execute(); - if (!calcResAlg->isExecuted()) - throw std::runtime_error( - "NRCalculateSlitResolution failed. Please manually " - "enter a value in the dQ/Q column."); - double resolution = calcResAlg->getProperty("Resolution"); - momentumTransferStep = resolution; - } - if (!momentumTransferMaximum.is_initialized()) - momentumTransferMaximum = calculateQ(wavelength_min, theta_in.get()); - refRedOne->setProperty("MomentumTransferMinimum", - momentumTransferMinimum.get()); - refRedOne->setProperty("MomentumTransferStep", - momentumTransferStep.get()); - refRedOne->setProperty("MomentumTransferMaximum", - momentumTransferMaximum.get()); - } - refRedOne->execute(); - if (!refRedOne->isExecuted()) { - throw std::runtime_error( - "ReflectometryReductionOne did not execute sucessfully"); - } - - MatrixWorkspace_sptr new_IvsQ1 = refRedOne->getProperty("OutputWorkspace"); - MatrixWorkspace_sptr new_IvsLam1 = - refRedOne->getProperty("OutputWorkspaceWavelength"); - double thetaOut1 = refRedOne->getProperty("ThetaOut"); - setProperty("OutputWorkspace", new_IvsQ1); - setProperty("OutputWorkspaceWavelength", new_IvsLam1); - setProperty("ThetaOut", thetaOut1); - // set properties so they can be retrieved by GenericDataProcesser if - // necessary. - setProperty("MomentumTransferMinimum", - boost::lexical_cast( - refRedOne->getPropertyValue("MomentumTransferMinimum"))); - setProperty("MomentumTransferStep", - boost::lexical_cast( - refRedOne->getPropertyValue("MomentumTransferStep"))); - setProperty("MomentumTransferMaximum", - boost::lexical_cast( - refRedOne->getPropertyValue("MomentumTransferMaximum"))); - if (theta_in.is_initialized()) - setProperty("ThetaIn", theta_in.get()); - else - setProperty("ThetaIn", thetaOut1 / 2.); - - } else { - throw std::runtime_error( - "ReflectometryReductionOne could not be initialised"); - } -} - -template -boost::optional -ReflectometryReductionOneAuto::isSet(std::string propName) const { - auto algProperty = this->getPointerToProperty(propName); - if (algProperty->isDefault()) { - return boost::optional(); - } else { - T value = this->getProperty(propName); - return boost::optional(value); - } -} - -bool ReflectometryReductionOneAuto::checkGroups() { - std::string wsName = getPropertyValue("InputWorkspace"); - - try { - auto ws = - AnalysisDataService::Instance().retrieveWS(wsName); - if (ws) - return true; - } catch (...) { - } - return false; -} -/** - * Sum over transmission group workspaces to produce one - * workspace. - * @param transGroup : The transmission group to be processed - * @return A workspace pointer containing the sum of transmission workspaces. - */ -Mantid::API::Workspace_sptr -ReflectometryReductionOneAuto::sumOverTransmissionGroup( - WorkspaceGroup_sptr &transGroup) { - // Handle transmission runs - - // we clone the first member of transmission group as to - // avoid addition in place which would affect the original - // workspace member. - // - // We used .release because clone() will return a unique_ptr. - // we need to release the ownership of the pointer so that it - // can be cast into a shared_ptr of type Workspace. - Workspace_sptr transmissionRunSum(transGroup->getItem(0)->clone()); - - // make a variable to store the overall total of the summation - MatrixWorkspace_sptr total; - // set up and initialize plus algorithm. - auto plusAlg = this->createChildAlgorithm("Plus"); - plusAlg->setChild(true); - // plusAlg->setRethrows(true); - plusAlg->initialize(); - // now accumalate the group members - for (size_t item = 1; item < transGroup->size(); ++item) { - plusAlg->setProperty("LHSWorkspace", transmissionRunSum); - plusAlg->setProperty("RHSWorkspace", transGroup->getItem(item)); - plusAlg->setProperty("OutputWorkspace", transmissionRunSum); - plusAlg->execute(); - total = plusAlg->getProperty("OutputWorkspace"); - } - return total; -} - -bool ReflectometryReductionOneAuto::processGroups() { - // isPolarizationCorrectionOn is used to decide whether - // we should process our Transmission WorkspaceGroup members - // as individuals (not multiperiod) when PolarizationCorrection is off, - // or sum over all of the workspaces in the group - // and used that sum as our TransmissionWorkspace when PolarizationCorrection - // is on. - const bool isPolarizationCorrectionOn = - this->getPropertyValue("PolarizationAnalysis") != - noPolarizationCorrectionMode(); - - // this algorithm effectively behaves as MultiPeriodGroupAlgorithm - m_usingBaseProcessGroups = true; - - // Get our input workspace group - auto group = AnalysisDataService::Instance().retrieveWS( - getPropertyValue("InputWorkspace")); - // Get name of IvsQ workspace - const std::string outputIvsQ = this->getPropertyValue("OutputWorkspace"); - // Get name of IvsLam workspace - const std::string outputIvsLam = - this->getPropertyValue("OutputWorkspaceWavelength"); - - // Create a copy of ourselves - Algorithm_sptr alg = this->createChildAlgorithm( - this->name(), -1, -1, this->isLogging(), this->version()); - alg->setChild(false); - alg->setRethrows(true); - - // Copy all the non-workspace properties over - std::vector props = this->getProperties(); - for (auto &prop : props) { - if (prop) { - IWorkspaceProperty *wsProp = dynamic_cast(prop); - if (!wsProp) - alg->setPropertyValue(prop->name(), prop->value()); - } - } - - // Check if the transmission runs are groups or not - const std::string firstTrans = this->getPropertyValue("FirstTransmissionRun"); - WorkspaceGroup_sptr firstTransG; - if (!firstTrans.empty()) { - auto firstTransWS = - AnalysisDataService::Instance().retrieveWS(firstTrans); - firstTransG = boost::dynamic_pointer_cast(firstTransWS); - - if (!firstTransG) { - // we only have one transmission workspace, so we use it as it is. - alg->setProperty("FirstTransmissionRun", firstTrans); - } else if (group->size() != firstTransG->size() && - !isPolarizationCorrectionOn) { - // if they are not the same size then we cannot associate a transmission - // group workspace member with every input group workpspace member. - throw std::runtime_error("FirstTransmissionRun WorkspaceGroup must be " - "the same size as the InputWorkspace " - "WorkspaceGroup"); - } - } - - const std::string secondTrans = - this->getPropertyValue("SecondTransmissionRun"); - WorkspaceGroup_sptr secondTransG; - if (!secondTrans.empty()) { - auto secondTransWS = - AnalysisDataService::Instance().retrieveWS(secondTrans); - secondTransG = boost::dynamic_pointer_cast(secondTransWS); - - if (!secondTransG) - // we only have one transmission workspace, so we use it as it is. - alg->setProperty("SecondTransmissionRun", secondTrans); - - else if (group->size() != secondTransG->size() && - !isPolarizationCorrectionOn) { - // if they are not the same size then we cannot associate a transmission - // group workspace member with every input group workpspace member. - throw std::runtime_error("SecondTransmissionRun WorkspaceGroup must be " - "the same size as the InputWorkspace " - "WorkspaceGroup"); - } - } - std::vector IvsQGroup, IvsLamGroup; - - // Execute algorithm over each group member (or period, if this is - // multiperiod) - size_t numMembers = group->size(); - for (size_t i = 0; i < numMembers; ++i) { - const std::string IvsQName = outputIvsQ + "_" + std::to_string(i + 1); - const std::string IvsLamName = outputIvsLam + "_" + std::to_string(i + 1); - - // If our transmission run is a group and PolarizationCorrection is on - // then we sum our transmission group members. - // - // This is done inside of the for loop to avoid the wrong workspace being - // used when these arguments are passed through to the exec() method. - // If this is not set in the loop, exec() will fetch the first workspace - // from the specified Transmission Group workspace that the user entered. - if (firstTransG && isPolarizationCorrectionOn) { - auto firstTransmissionSum = sumOverTransmissionGroup(firstTransG); - alg->setProperty("FirstTransmissionRun", firstTransmissionSum); - } - if (secondTransG && isPolarizationCorrectionOn) { - auto secondTransmissionSum = sumOverTransmissionGroup(secondTransG); - alg->setProperty("SecondTransmissionRun", secondTransmissionSum); - } - - // Otherwise, if polarization correction is off, we process them - // using one transmission group member at a time. - if (firstTransG && !isPolarizationCorrectionOn) // polarization off - alg->setProperty("FirstTransmissionRun", - firstTransG->getItem(i)->getName()); - if (secondTransG && !isPolarizationCorrectionOn) // polarization off - alg->setProperty("SecondTransmissionRun", - secondTransG->getItem(i)->getName()); - - alg->setProperty("InputWorkspace", group->getItem(i)->getName()); - alg->setProperty("OutputWorkspace", IvsQName); - alg->setProperty("OutputWorkspaceWavelength", IvsLamName); - alg->execute(); - - MatrixWorkspace_sptr tempFirstTransWS = - alg->getProperty("FirstTransmissionRun"); - - IvsQGroup.push_back(IvsQName); - IvsLamGroup.push_back(IvsLamName); - - // We use the first group member for our thetaout value - if (i == 0) - this->setPropertyValue("ThetaOut", alg->getPropertyValue("ThetaOut")); - } - - // Group the IvsQ and IvsLam workspaces - Algorithm_sptr groupAlg = this->createChildAlgorithm("GroupWorkspaces"); - groupAlg->setChild(false); - groupAlg->setRethrows(true); - - groupAlg->setProperty("InputWorkspaces", IvsLamGroup); - groupAlg->setProperty("OutputWorkspace", outputIvsLam); - groupAlg->execute(); - - groupAlg->setProperty("InputWorkspaces", IvsQGroup); - groupAlg->setProperty("OutputWorkspace", outputIvsQ); - groupAlg->execute(); - - // If this is a multiperiod workspace and we have polarization corrections - // enabled - if (isPolarizationCorrectionOn) { - if (group->isMultiperiod()) { - // Perform polarization correction over the IvsLam group - Algorithm_sptr polAlg = - this->createChildAlgorithm("PolarizationCorrection"); - polAlg->setChild(false); - polAlg->setRethrows(true); - - polAlg->setProperty("InputWorkspace", outputIvsLam); - polAlg->setProperty("OutputWorkspace", outputIvsLam); - polAlg->setProperty("PolarizationAnalysis", - this->getPropertyValue("PolarizationAnalysis")); - polAlg->setProperty("CPp", this->getPropertyValue(cppLabel())); - polAlg->setProperty("CRho", this->getPropertyValue(crhoLabel())); - polAlg->setProperty("CAp", this->getPropertyValue(cApLabel())); - polAlg->setProperty("CAlpha", this->getPropertyValue(cAlphaLabel())); - polAlg->execute(); - - // Now we've overwritten the IvsLam workspaces, we'll need to recalculate - // the IvsQ ones - alg->setProperty("FirstTransmissionRun", ""); - alg->setProperty("SecondTransmissionRun", ""); - for (size_t i = 0; i < numMembers; ++i) { - const std::string IvsQName = outputIvsQ + "_" + std::to_string(i + 1); - const std::string IvsLamName = - outputIvsLam + "_" + std::to_string(i + 1); - alg->setProperty("InputWorkspace", IvsLamName); - alg->setProperty("OutputWorkspace", IvsQName); - alg->setProperty("CorrectionAlgorithm", "None"); - alg->setProperty("OutputWorkspaceWavelength", IvsLamName); - alg->execute(); - } - } else { - g_log.warning("Polarization corrections can only be performed on " - "multiperiod workspaces."); - } - } - - // We finished successfully - // set the values of these properties so they can be retrieved by the - // Interface. - this->setProperty("MomentumTransferMinimum", - boost::lexical_cast( - alg->getPropertyValue("MomentumTransferMinimum"))); - this->setProperty("MomentumTransferStep", - boost::lexical_cast( - alg->getPropertyValue("MomentumTransferStep"))); - this->setProperty("MomentumTransferMaximum", - boost::lexical_cast( - alg->getPropertyValue("MomentumTransferMaximum"))); - // setting output properties. - this->setPropertyValue("OutputWorkspace", outputIvsQ); - this->setPropertyValue("OutputWorkspaceWavelength", outputIvsLam); - return true; -} -} // namespace Algorithms -} // namespace Mantid diff --git a/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h b/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h index 9f715efd114e..8b524bcdf6a3 100644 --- a/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h +++ b/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h @@ -10,7 +10,6 @@ #include #include -#include "MantidAlgorithms/ReflectometryReductionOne.h" #include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/Axis.h" #include "MantidAPI/FrameworkManager.h" @@ -22,7 +21,6 @@ using namespace Mantid; using namespace Mantid::Kernel; using namespace Mantid::API; -using namespace Mantid::Algorithms; using namespace WorkspaceCreationHelper; class CreateTransmissionWorkspaceTest : public CxxTest::TestSuite { diff --git a/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h b/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h deleted file mode 100644 index bd7c8c4f3830..000000000000 --- a/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h +++ /dev/null @@ -1,798 +0,0 @@ -#ifndef MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTOTEST_H_ -#define MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTOTEST_H_ - -#include - -#include "MantidAPI/AlgorithmManager.h" -#include "MantidAPI/Axis.h" -#include "MantidAPI/FrameworkManager.h" -#include "MantidAPI/WorkspaceGroup.h" -#include "MantidAPI/WorkspaceHistory.h" -#include "MantidAlgorithms/ReflectometryReductionOneAuto.h" -#include "MantidGeometry/Instrument.h" -#include "MantidGeometry/Instrument/ReferenceFrame.h" -#include "MantidKernel/Unit.h" -#include "MantidTestHelpers/WorkspaceCreationHelper.h" - -using Mantid::Algorithms::ReflectometryReductionOneAuto; -using namespace Mantid::API; -using namespace Mantid::DataObjects; -using namespace Mantid::Geometry; -using namespace Mantid::Kernel; -using Mantid::MantidVec; -using Mantid::MantidVecPtr; -using Mantid::HistogramData::BinEdges; - -namespace { -class PropertyFinder { -private: - const std::string m_propertyName; - -public: - PropertyFinder(const std::string &propertyName) - : m_propertyName(propertyName) {} - bool operator()(const PropertyHistories::value_type &candidate) const { - return candidate->name() == m_propertyName; - } -}; - -template -T findPropertyValue(PropertyHistories &histories, - const std::string &propertyName) { - PropertyFinder finder(propertyName); - auto it = std::find_if(histories.begin(), histories.end(), finder); - return boost::lexical_cast((*it)->value()); -} -} - -class ReflectometryReductionOneAutoTest : public CxxTest::TestSuite { -public: - // This pair of boilerplate methods prevent the suite being created statically - // This means the constructor isn't called when running other tests - static ReflectometryReductionOneAutoTest *createSuite() { - return new ReflectometryReductionOneAutoTest(); - } - static void destroySuite(ReflectometryReductionOneAutoTest *suite) { - delete suite; - } - - MatrixWorkspace_sptr m_TOF; - MatrixWorkspace_sptr m_NotTOF; - MatrixWorkspace_sptr m_dataWorkspace; - MatrixWorkspace_sptr m_transWorkspace1; - MatrixWorkspace_sptr m_transWorkspace2; - WorkspaceGroup_sptr m_multiDetectorWorkspace; - const std::string outWSQName; - const std::string outWSLamName; - const std::string inWSName; - const std::string transWSName; - - ReflectometryReductionOneAutoTest() - : outWSQName("ReflectometryReductionOneAutoTest_OutputWS_Q"), - outWSLamName("ReflectometryReductionOneAutoTest_OutputWS_Lam"), - inWSName("ReflectometryReductionOneAutoTest_InputWS"), - transWSName("ReflectometryReductionOneAutoTest_TransWS") { - MantidVec xData = {0, 0, 0, 0}; - MantidVec yData = {0, 0, 0}; - - auto createWorkspace = - AlgorithmManager::Instance().create("CreateWorkspace"); - createWorkspace->initialize(); - createWorkspace->setProperty("UnitX", "1/q"); - createWorkspace->setProperty("DataX", xData); - createWorkspace->setProperty("DataY", yData); - createWorkspace->setProperty("NSpec", 1); - createWorkspace->setPropertyValue("OutputWorkspace", "NotTOF"); - createWorkspace->execute(); - m_NotTOF = - AnalysisDataService::Instance().retrieveWS("NotTOF"); - - createWorkspace->setProperty("UnitX", "TOF"); - createWorkspace->setProperty("DataX", xData); - createWorkspace->setProperty("DataY", yData); - createWorkspace->setProperty("NSpec", 1); - createWorkspace->setPropertyValue("OutputWorkspace", "TOF"); - createWorkspace->execute(); - m_TOF = AnalysisDataService::Instance().retrieveWS("TOF"); - - IAlgorithm_sptr lAlg = AlgorithmManager::Instance().create("Load"); - lAlg->setChild(true); - lAlg->initialize(); - lAlg->setProperty("Filename", "INTER00013460.nxs"); - lAlg->setPropertyValue("OutputWorkspace", "demo_ws"); - lAlg->execute(); - Workspace_sptr temp = lAlg->getProperty("OutputWorkspace"); - m_dataWorkspace = boost::dynamic_pointer_cast(temp); - // m_dataWorkspace = - // AnalysisDataService::Instance().retrieveWS("data_ws"); - - lAlg->setProperty("Filename", "INTER00013463.nxs"); - lAlg->setPropertyValue("OutputWorkspace", "trans_ws_1"); - lAlg->execute(); - temp = lAlg->getProperty("OutputWorkspace"); - m_transWorkspace1 = boost::dynamic_pointer_cast(temp); - // m_transWorkspace1 = - // AnalysisDataService::Instance().retrieveWS("trans_ws_1"); - - lAlg->setProperty("Filename", "INTER00013464.nxs"); - lAlg->setPropertyValue("OutputWorkspace", "trans_ws_2"); - lAlg->execute(); - temp = lAlg->getProperty("OutputWorkspace"); - m_transWorkspace2 = boost::dynamic_pointer_cast(temp); - // m_transWorkspace2 = - // AnalysisDataService::Instance().retrieveWS("trans_ws_2"); - - lAlg->setPropertyValue("Filename", "POLREF00004699.nxs"); - lAlg->setPropertyValue("OutputWorkspace", "multidetector_ws_1"); - lAlg->execute(); - temp = lAlg->getProperty("OutputWorkspace"); - m_multiDetectorWorkspace = - boost::dynamic_pointer_cast(temp); - AnalysisDataService::Instance().addOrReplace("multidetector_group", - m_multiDetectorWorkspace); - } - ~ReflectometryReductionOneAutoTest() override { - AnalysisDataService::Instance().remove("TOF"); - AnalysisDataService::Instance().remove("NotTOF"); - AnalysisDataService::Instance().remove("multidetector_group"); - AnalysisDataService::Instance().remove("multidetector_group_1"); - AnalysisDataService::Instance().remove("multidetector_group_2"); - } - - IAlgorithm_sptr construct_standard_algorithm() { - auto alg = - AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1); - alg->initialize(); - alg->setProperty("InputWorkspace", m_TOF); - alg->setProperty("WavelengthMin", 0.0); - alg->setProperty("WavelengthMax", 1.0); - alg->setProperty("I0MonitorIndex", 0); - alg->setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg->setProperty("MonitorBackgroundWavelengthMax", 1.0); - alg->setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg->setProperty("MonitorIntegrationWavelengthMax", 1.0); - alg->setProperty("MomentumTransferStep", 0.1); - alg->setPropertyValue("ProcessingInstructions", "0"); - alg->setPropertyValue("OutputWorkspace", outWSQName); - alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName); - alg->setRethrows(true); - return alg; - } - - void test_Init() { - ReflectometryReductionOneAuto alg; - TS_ASSERT_THROWS_NOTHING(alg.initialize()); - TS_ASSERT(alg.isInitialized()); - } - - void test_check_input_workpace_not_tof_or_wavelength_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("InputWorkspace", m_NotTOF); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void test_check_first_transmission_workspace_not_tof_or_wavelength_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("FirstTransmissionRun", m_NotTOF); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void test_check_second_transmission_workspace_not_tof_throws() { - auto alg = construct_standard_algorithm(); - TS_ASSERT_THROWS(alg->setProperty("SecondTransmissionRun", m_NotTOF), - std::invalid_argument); - } - - void test_proivde_second_transmission_run_without_first_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("SecondTransmissionRun", m_TOF); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void test_end_overlap_must_be_greater_than_start_overlap_or_throw() { - auto alg = construct_standard_algorithm(); - alg->setProperty("FirstTransmissionRun", m_TOF); - alg->setProperty("SecondTransmissionRun", m_TOF); - MantidVec params = {0.0, 0.1, 1.0}; - alg->setProperty("Params", params); - alg->setProperty("StartOverlap", 0.6); - alg->setProperty("EndOverlap", 0.4); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void test_must_provide_wavelengths() { - auto algWithMax = - AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1); - algWithMax->initialize(); - algWithMax->setProperty("InputWorkspace", m_TOF); - algWithMax->setProperty("FirstTransmissionRun", m_TOF); - algWithMax->setProperty("SecondTransmissionRun", m_TOF); - algWithMax->setProperty("ProcessingInstructions", "3:4"); - algWithMax->setProperty("MomentumTransferStep", 0.1); - algWithMax->setProperty("WavelengthMax", 1.0); - algWithMax->setPropertyValue("OutputWorkspace", "out_ws_Q"); - algWithMax->setPropertyValue("OutputWorkspaceWavelength", "out_ws_Lam"); - algWithMax->setRethrows(true); - TS_ASSERT_THROWS(algWithMax->execute(), std::runtime_error); - - auto algWithMin = - AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1); - algWithMin->initialize(); - algWithMin->setProperty("InputWorkspace", m_TOF); - algWithMin->setProperty("FirstTransmissionRun", m_TOF); - algWithMin->setProperty("SecondTransmissionRun", m_TOF); - algWithMin->setProperty("ProcessingInstructions", "3:4"); - algWithMin->setProperty("MomentumTransferStep", 0.1); - algWithMin->setProperty("WavelengthMin", 1.0); - algWithMin->setPropertyValue("OutputWorkspace", "out_ws_Q"); - algWithMin->setPropertyValue("OutputWorkspaceWavelength", "out_ws_Lam"); - algWithMin->setRethrows(true); - TS_ASSERT_THROWS(algWithMin->execute(), std::runtime_error); - } - - void test_wavelength_min_greater_wavelength_max_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("WavelengthMin", 1.0); - alg->setProperty("WavelengthMax", 0.0); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void - test_monitor_background_wavelength_min_greater_monitor_background_wavelength_max_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("MonitorBackgroundWavelengthMin", 1.0); - alg->setProperty("MonitorBackgroundWavelengthMax", 0.0); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void - test_monitor_integration_wavelength_min_greater_monitor_integration_wavelength_max_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("MonitorIntegrationWavelengthMin", 1.0); - alg->setProperty("MonitorIntegrationWavelengthMax", 0.0); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void test_monitor_index_positive() { - auto alg = construct_standard_algorithm(); - auto tempInst = m_TOF->getInstrument(); - m_TOF->setInstrument(m_dataWorkspace->getInstrument()); - alg->setProperty("InputWorkspace", m_TOF); - TS_ASSERT_THROWS(alg->execute(), std::runtime_error); - m_TOF->setInstrument(tempInst); - } - void - test_cannot_set_direct_beam_region_of_interest_without_multidetector_run() { - auto alg = construct_standard_algorithm(); - alg->setProperty("AnalysisMode", "PointDetectorAnalysis"); - std::vector RegionOfDirectBeam = {1, 2}; - alg->setProperty("RegionOfDirectBeam", RegionOfDirectBeam); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void test_region_of_direct_beam_indexes_cannot_be_negative_or_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("AnalysisMode", "MultiDetectorAnalysis"); - std::vector RegionOfDirectBeam = {0, -1}; - alg->setProperty("RegionOfDirectBeam", RegionOfDirectBeam); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void - test_region_of_direct_beam_indexes_must_be_provided_as_min_max_order_or_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("AnalysisMode", "MultiDetectorAnalysis"); - std::vector RegionOfDirectBeam = {1, 0}; - alg->setProperty("RegionOfDirectBeam", RegionOfDirectBeam); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - - void test_bad_detector_component_name_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("DetectorComponentName", "made-up"); - TS_ASSERT_THROWS(alg->execute(), std::runtime_error); - } - - void test_bad_sample_component_name_throws() { - auto alg = construct_standard_algorithm(); - alg->setProperty("SampleComponentName", "made-up"); - TS_ASSERT_THROWS(alg->execute(), std::runtime_error); - } - void test_exec() { - IAlgorithm_sptr alg = - AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1); - alg->setRethrows(true); - TS_ASSERT_THROWS_NOTHING(alg->initialize()); - TS_ASSERT_THROWS_NOTHING( - alg->setProperty("InputWorkspace", m_dataWorkspace)); - TS_ASSERT_THROWS_NOTHING( - alg->setProperty("AnalysisMode", "PointDetectorAnalysis")); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspace", outWSQName)); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName)); - TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1)); - alg->execute(); - TS_ASSERT(alg->isExecuted()); - - MatrixWorkspace_sptr outWS = - AnalysisDataService::Instance().retrieveWS(outWSQName); - - auto inst = m_dataWorkspace->getInstrument(); - auto workspaceHistory = outWS->getHistory(); - AlgorithmHistory_const_sptr workerAlgHistory = - workspaceHistory.getAlgorithmHistory(0)->getChildAlgorithmHistory(0); - auto vecPropertyHistories = workerAlgHistory->getProperties(); - - const double wavelengthMin = - findPropertyValue(vecPropertyHistories, "WavelengthMin"); - const double wavelengthMax = - findPropertyValue(vecPropertyHistories, "WavelengthMax"); - const double monitorBackgroundWavelengthMin = findPropertyValue( - vecPropertyHistories, "MonitorBackgroundWavelengthMin"); - const double monitorBackgroundWavelengthMax = findPropertyValue( - vecPropertyHistories, "MonitorBackgroundWavelengthMax"); - const double monitorIntegrationWavelengthMin = findPropertyValue( - vecPropertyHistories, "MonitorIntegrationWavelengthMin"); - const double monitorIntegrationWavelengthMax = findPropertyValue( - vecPropertyHistories, "MonitorIntegrationWavelengthMax"); - const int i0MonitorIndex = - findPropertyValue(vecPropertyHistories, "I0MonitorIndex"); - std::string processingInstructions = findPropertyValue( - vecPropertyHistories, "ProcessingInstructions"); - std::vector pointDetectorStartStop; - boost::split(pointDetectorStartStop, processingInstructions, - boost::is_any_of(":")); - - TS_ASSERT_EQUALS(inst->getNumberParameter("LambdaMin")[0], wavelengthMin); - TS_ASSERT_EQUALS(inst->getNumberParameter("LambdaMax")[0], wavelengthMax); - TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorBackgroundMin")[0], - monitorBackgroundWavelengthMin); - TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorBackgroundMax")[0], - monitorBackgroundWavelengthMax); - TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorIntegralMin")[0], - monitorIntegrationWavelengthMin); - TS_ASSERT_EQUALS(inst->getNumberParameter("MonitorIntegralMax")[0], - monitorIntegrationWavelengthMax); - TS_ASSERT_EQUALS(inst->getNumberParameter("I0MonitorIndex")[0], - i0MonitorIndex); - TS_ASSERT_EQUALS(inst->getNumberParameter("PointDetectorStart")[0], - boost::lexical_cast(pointDetectorStartStop[0])); - TS_ASSERT_EQUALS(pointDetectorStartStop.size(), 1); - - // Remove workspace from the data service. - AnalysisDataService::Instance().remove(outWSQName); - AnalysisDataService::Instance().remove(outWSLamName); - } - - void test_missing_instrument_parameters_throws() { - auto tinyWS = - WorkspaceCreationHelper::create2DWorkspaceWithReflectometryInstrument(); - auto inst = tinyWS->getInstrument(); - - inst->getParameterMap()->addDouble(inst.get(), "I0MonitorIndex", 1.0); - - tinyWS->mutableRun().addLogData( - new PropertyWithValue("Theta", 0.12345)); - tinyWS->mutableRun().addLogData( - new PropertyWithValue("run_number", "12345")); - - IAlgorithm_sptr alg = - AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1); - alg->setRethrows(true); - TS_ASSERT_THROWS_NOTHING(alg->initialize()); - TS_ASSERT_THROWS_NOTHING(alg->setProperty("InputWorkspace", tinyWS)); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspace", outWSQName)); - TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1)); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName)); - TS_ASSERT_THROWS_ANYTHING(alg->execute()); - - // Remove workspace from the data service. - AnalysisDataService::Instance().remove(outWSQName); - AnalysisDataService::Instance().remove(outWSLamName); - } - - void test_normalize_by_detmon() { - // Prepare workspace - //----------------- - // Single bin from 1->2 - BinEdges x{1, 2}; - - // 2 spectra, 2 x values, 1 y value per spectra - auto tinyWS = createWorkspace(2, 2, 1); - tinyWS->setBinEdges(0, x); - tinyWS->setBinEdges(1, x); - tinyWS->setCounts(0, 1, 10.0); - tinyWS->setCountStandardDeviations(0, 1, 0.0); - tinyWS->setCounts(1, 1, 5.0); - tinyWS->setCountStandardDeviations(1, 1, 0.0); - - tinyWS->setTitle("Test histogram"); - tinyWS->getAxis(0)->setUnit("Wavelength"); - tinyWS->setYUnit("Counts"); - - // Prepare instrument - //------------------ - Instrument_sptr instrument = boost::make_shared(); - instrument->setReferenceFrame( - boost::make_shared(Y, X, Left, "0,0,0")); - - ObjComponent *source = new ObjComponent("source"); - source->setPos(V3D(0, 0, 0)); - instrument->add(source); - instrument->markAsSource(source); - - ObjComponent *sample = new ObjComponent("some-surface-holder"); - source->setPos(V3D(15, 0, 0)); - instrument->add(sample); - instrument->markAsSamplePos(sample); - - Detector *det = new Detector("point-detector", 1, nullptr); - det->setPos(20, (20 - sample->getPos().X()), 0); - instrument->add(det); - instrument->markAsDetector(det); - - Detector *monitor = new Detector("Monitor", 2, nullptr); - monitor->setPos(14, 0, 0); - instrument->add(monitor); - instrument->markAsMonitor(monitor); - - // Add instrument to workspace - tinyWS->setInstrument(instrument); - tinyWS->getSpectrum(0).addDetectorID(det->getID()); - tinyWS->getSpectrum(1).addDetectorID(monitor->getID()); - - // Now we can parameterize the instrument - auto tinyInst = tinyWS->getInstrument(); - ParameterMap_sptr params = tinyInst->getParameterMap(); - params->addDouble(tinyInst.get(), "PointDetectorStart", 0.0); - params->addDouble(tinyInst.get(), "PointDetectorStop", 0.0); - params->addDouble(tinyInst.get(), "I0MonitorIndex", 1.0); - params->addDouble(tinyInst.get(), "LambdaMin", 0.0); - params->addDouble(tinyInst.get(), "LambdaMax", 10.0); - params->addDouble(tinyInst.get(), "MonitorBackgroundMin", 0.0); - params->addDouble(tinyInst.get(), "MonitorBackgroundMax", 0.0); - params->addDouble(tinyInst.get(), "MonitorIntegralMin", 0.0); - params->addDouble(tinyInst.get(), "MonitorIntegralMax", 10.0); - - tinyWS->mutableRun().addLogData( - new PropertyWithValue("Theta", 0.1)); - - // Run the required algorithms - //--------------------------- - - // Convert units - IAlgorithm_sptr conv = AlgorithmManager::Instance().create("ConvertUnits"); - conv->initialize(); - conv->setProperty("InputWorkspace", tinyWS); - conv->setProperty("OutputWorkspace", inWSName); - conv->setProperty("Target", "TOF"); - conv->execute(); - TS_ASSERT(conv->isExecuted()); - - // Reduce - IAlgorithm_sptr alg = - AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1); - alg->setRethrows(true); - TS_ASSERT_THROWS_NOTHING(alg->initialize()); - TS_ASSERT_THROWS_NOTHING(alg->setProperty("InputWorkspace", inWSName)); - TS_ASSERT_THROWS_NOTHING( - alg->setProperty("NormalizeByIntegratedMonitors", false)); - TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1)); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspace", outWSQName)); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName)); - alg->execute(); - TS_ASSERT(alg->isExecuted()); - - // Get results - MatrixWorkspace_sptr outWSLam = - AnalysisDataService::Instance().retrieveWS( - outWSLamName); - - // Check results (10 / 5 = 2) - TS_ASSERT_DELTA(outWSLam->readY(0)[0], 2, 1e-5); - TS_ASSERT_DELTA(outWSLam->readX(0)[0], 1, 1e-5); - TS_ASSERT_DELTA(outWSLam->readX(0)[1], 2, 1e-5); - - // Remove workspace from the data service. - AnalysisDataService::Instance().remove(inWSName); - AnalysisDataService::Instance().remove(outWSQName); - AnalysisDataService::Instance().remove(outWSLamName); - } - - void test_i0_monitor_index_not_required() { - // Prepare instrument - //------------------ - // hold the current instrument assigned to m_dataWorkspace - auto m_dataWorkspaceInstHolder = m_dataWorkspace->getInstrument(); - Instrument_sptr instrument = boost::make_shared(); - instrument->setReferenceFrame( - boost::make_shared(Y, X, Left, "0,0,0")); - - ObjComponent *source = new ObjComponent("source"); - source->setPos(V3D(0, 0, 0)); - instrument->add(source); - instrument->markAsSource(source); - - ObjComponent *sample = new ObjComponent("some-surface-holder"); - source->setPos(V3D(15, 0, 0)); - instrument->add(sample); - instrument->markAsSamplePos(sample); - - Detector *det = new Detector("point-detector", 1, nullptr); - det->setPos(20, (20 - sample->getPos().X()), 0); - instrument->add(det); - instrument->markAsDetector(det); - - Detector *monitor = new Detector("Monitor", 2, nullptr); - monitor->setPos(14, 0, 0); - instrument->add(monitor); - instrument->markAsMonitor(monitor); - - // Add new instrument to workspace - m_dataWorkspace->setInstrument(instrument); - - // Now we can parameterize the instrument - // without setting the I0MonitorIndex - auto tinyInst = m_dataWorkspace->getInstrument(); - ParameterMap_sptr params = tinyInst->getParameterMap(); - params->addDouble(tinyInst.get(), "PointDetectorStart", 0.0); - params->addDouble(tinyInst.get(), "PointDetectorStop", 0.0); - params->addDouble(tinyInst.get(), "LambdaMin", 0.0); - params->addDouble(tinyInst.get(), "LambdaMax", 10.0); - params->addDouble(tinyInst.get(), "MonitorBackgroundMin", 0.0); - params->addDouble(tinyInst.get(), "MonitorBackgroundMax", 0.0); - params->addDouble(tinyInst.get(), "MonitorIntegralMin", 0.0); - params->addDouble(tinyInst.get(), "MonitorIntegralMax", 10.0); - - // Reduce - IAlgorithm_sptr alg = - AlgorithmManager::Instance().create("ReflectometryReductionOneAuto", 1); - alg->setRethrows(true); - alg->setChild(true); - TS_ASSERT_THROWS_NOTHING(alg->initialize()); - TS_ASSERT_THROWS_NOTHING( - alg->setProperty("InputWorkspace", m_dataWorkspace)); - TS_ASSERT_THROWS_NOTHING( - alg->setProperty("I0MonitorIndex", Mantid::EMPTY_INT())); - TS_ASSERT_THROWS_NOTHING(alg->setProperty("MomentumTransferStep", 0.1)); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspace", outWSQName)); - TS_ASSERT_THROWS_NOTHING( - alg->setPropertyValue("OutputWorkspaceWavelength", outWSLamName)); - // we have intentionally not set - TS_ASSERT_THROWS_NOTHING(alg->execute()); - - // Remove workspace from the data service. - AnalysisDataService::Instance().remove(inWSName); - AnalysisDataService::Instance().remove(outWSQName); - AnalysisDataService::Instance().remove(outWSLamName); - - // reset the instrument associated with m_dataWorkspace - m_dataWorkspace->setInstrument(m_dataWorkspaceInstHolder); - } - void test_point_detector_run_with_single_transmission_workspace() { - ReflectometryReductionOneAuto alg; - alg.initialize(); - alg.setChild(true); - alg.setProperty("WavelengthMin", 1.0); - alg.setProperty("WavelengthMax", 2.0); - alg.setProperty("I0MonitorIndex", 0); - alg.setProperty("ProcessingInstructions", "3"); - alg.setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg.setProperty("MonitorBackgroundWavelengthMax", 1.0); - alg.setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg.setProperty("MonitorIntegrationWavelengthMax", 1.0); - alg.setProperty("InputWorkspace", m_dataWorkspace); - alg.setProperty("FirstTransmissionRun", m_transWorkspace1); - alg.setProperty("ThetaIn", 0.2); - alg.setPropertyValue("OutputWorkspace", "IvsQ"); - alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam"); - - TS_ASSERT_THROWS_NOTHING(alg.execute()); - - double thetaOut = alg.getProperty("ThetaOut"); - TSM_ASSERT_EQUALS("Theta in and out should be the same", thetaOut, 0.2); - - MatrixWorkspace_sptr IvsLam = alg.getProperty("OutputWorkspaceWavelength"); - TSM_ASSERT("OutputWorkspaceWavelength should be a valid matrix workspace", - IvsLam); - - MatrixWorkspace_sptr IvsQ = alg.getProperty("OutputWorkspace"); - TSM_ASSERT("OutputWorkspace should be a valid matrix workspace", IvsQ); - - TSM_ASSERT_EQUALS("OutputWorkspaceWavelength should have one histogram", - IvsLam->getNumberHistograms(), 1); - } - - void test_point_detector_run_with_two_transmission_workspaces() { - ReflectometryReductionOneAuto alg; - alg.initialize(); - alg.setChild(true); - alg.setProperty("WavelengthMin", 1.0); - alg.setProperty("WavelengthMax", 2.0); - alg.setProperty("I0MonitorIndex", 0); - alg.setProperty("ProcessingInstructions", "3"); - alg.setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg.setProperty("MonitorBackgroundWavelengthMax", 1.0); - alg.setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg.setProperty("MonitorIntegrationWavelengthMax", 1.0); - alg.setProperty("InputWorkspace", m_dataWorkspace); - alg.setProperty("FirstTransmissionRun", m_transWorkspace1); - alg.setProperty("SecondTransmissionRun", m_transWorkspace2); - alg.setPropertyValue("OutputWorkspace", "IvsQ"); - alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam"); - - TS_ASSERT_THROWS_NOTHING(alg.execute()); - } - - void test_spectrum_map_mismatch_throws_when_strict() { - ReflectometryReductionOneAuto alg; - alg.initialize(); - alg.setChild(true); - alg.setProperty("WavelengthMin", 1.0); - alg.setProperty("WavelengthMax", 2.0); - alg.setProperty("I0MonitorIndex", 0); - alg.setProperty("ProcessingInstructions", "3"); - alg.setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg.setProperty("MonitorBackgroundWavelengthMax", 1.0); - alg.setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg.setProperty("MonitorIntegrationWavelengthMax", 1.0); - alg.setPropertyValue("OutputWorkspace", "IvsQ"); - alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam"); - - alg.setProperty("InputWorkspace", m_dataWorkspace); - alg.execute(); - - MatrixWorkspace_sptr trans = alg.getProperty("OutputWorkspaceWavelength"); - alg.setProperty("FirstTransmissionRun", trans); - alg.setProperty("ProcessingInstructions", "4"); - TS_ASSERT_THROWS_ANYTHING(alg.execute()); - } - - void test_spectrum_map_mismatch_doesnt_throw_when_not_strict() { - ReflectometryReductionOneAuto alg; - alg.initialize(); - alg.setChild(true); - alg.setProperty("WavelengthMin", 1.0); - alg.setProperty("WavelengthMax", 2.0); - alg.setProperty("I0MonitorIndex", 0); - alg.setProperty("ProcessingInstructions", "3"); - alg.setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg.setProperty("MonitorBackgroundWavelengthMax", 1.0); - alg.setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg.setProperty("MonitorIntegrationWavelengthMax", 1.0); - alg.setPropertyValue("OutputWorkspace", "IvsQ"); - alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam"); - - alg.setProperty("InputWorkspace", m_dataWorkspace); - alg.execute(); - - MatrixWorkspace_sptr trans = alg.getProperty("OutputWorkspaceWavelength"); - alg.setProperty("FirstTransmissionRun", trans); - alg.setProperty("ProcessingInstructions", "4"); - alg.setProperty("StrictSpectrumChecking", "0"); - TS_ASSERT_THROWS_NOTHING(alg.execute()); - } - - void test_multidetector_run() { - ReflectometryReductionOneAuto alg; - alg.initialize(); - alg.setChild(false); - alg.setProperty("WavelengthMin", 1.0); - alg.setProperty("WavelengthMax", 2.0); - alg.setProperty("I0MonitorIndex", 0); - alg.setProperty("ProcessingInstructions", "10"); - alg.setProperty("AnalysisMode", "MultiDetectorAnalysis"); - alg.setProperty("CorrectDetectorPositions", "0"); - alg.setProperty("DetectorComponentName", "lineardetector"); - alg.setProperty("RegionOfDirectBeam", "20, 30"); - alg.setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg.setProperty("MonitorBackgroundWavelengthMax", 1.0); - alg.setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg.setProperty("MonitorIntegrationWavelengthMax", 1.0); - alg.setProperty("ThetaIn", 0.1); - alg.setPropertyValue("OutputWorkspace", "IvsQ"); - alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam"); - alg.setPropertyValue("InputWorkspace", "multidetector_group"); - - TS_ASSERT_THROWS_NOTHING(alg.execute()); - - MatrixWorkspace_sptr IvsLam_1 = - AnalysisDataService::Instance().retrieveWS("IvsLam_1"); - TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace", - IvsLam_1); - TS_ASSERT_EQUALS("Wavelength", IvsLam_1->getAxis(0)->unit()->unitID()); - MatrixWorkspace_sptr IvsLam_2 = - AnalysisDataService::Instance().retrieveWS("IvsLam_2"); - TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace", - IvsLam_2); - TS_ASSERT_EQUALS("Wavelength", IvsLam_2->getAxis(0)->unit()->unitID()); - - MatrixWorkspace_sptr IvsQ_1 = - AnalysisDataService::Instance().retrieveWS("IvsQ_1"); - TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_1); - TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_1->getAxis(0)->unit()->unitID()); - MatrixWorkspace_sptr IvsQ_2 = - AnalysisDataService::Instance().retrieveWS("IvsQ_2"); - TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_2); - TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_2->getAxis(0)->unit()->unitID()); - - MatrixWorkspace_sptr tempWS = boost::dynamic_pointer_cast( - m_multiDetectorWorkspace->getItem(0)); - auto instrBefore = tempWS->getInstrument(); - auto detectorBefore = instrBefore->getComponentByName("lineardetector"); - auto instrAfter = IvsLam_1->getInstrument(); - auto detectorAfter = instrAfter->getComponentByName("lineardetector"); - TS_ASSERT_DELTA(detectorBefore->getPos().Z(), detectorAfter->getPos().Z(), - 0.0001) - - AnalysisDataService::Instance().remove("IvsLam"); - AnalysisDataService::Instance().remove("IvsLam_1"); - AnalysisDataService::Instance().remove("IvsLam_2"); - AnalysisDataService::Instance().remove("IvsQ"); - AnalysisDataService::Instance().remove("IvsQ_1"); - AnalysisDataService::Instance().remove("IvsQ_2"); - } - - void test_multidetector_run_correct_positions() { - ReflectometryReductionOneAuto alg; - alg.initialize(); - alg.setChild(false); - alg.setProperty("WavelengthMin", 1.0); - alg.setProperty("WavelengthMax", 2.0); - alg.setProperty("I0MonitorIndex", 0); - alg.setProperty("ProcessingInstructions", "73"); - alg.setProperty("AnalysisMode", "MultiDetectorAnalysis"); - alg.setProperty("CorrectDetectorPositions", "1"); - alg.setProperty("DetectorComponentName", "lineardetector"); - alg.setProperty("RegionOfDirectBeam", "28, 29"); - alg.setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg.setProperty("MonitorBackgroundWavelengthMax", 1.0); - alg.setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg.setProperty("MonitorIntegrationWavelengthMax", 1.0); - alg.setProperty("ThetaIn", 0.49); - alg.setPropertyValue("OutputWorkspace", "IvsQ"); - alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam"); - alg.setPropertyValue("InputWorkspace", "multidetector_group"); - - TS_ASSERT_THROWS_NOTHING(alg.execute()); - - MatrixWorkspace_sptr IvsLam_1 = - AnalysisDataService::Instance().retrieveWS("IvsLam_1"); - TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace", - IvsLam_1); - TS_ASSERT_EQUALS("Wavelength", IvsLam_1->getAxis(0)->unit()->unitID()); - MatrixWorkspace_sptr IvsLam_2 = - AnalysisDataService::Instance().retrieveWS("IvsLam_2"); - TSM_ASSERT("OutputWorkspaceWavelength should be a matrix workspace", - IvsLam_2); - TS_ASSERT_EQUALS("Wavelength", IvsLam_2->getAxis(0)->unit()->unitID()); - - MatrixWorkspace_sptr IvsQ_1 = - AnalysisDataService::Instance().retrieveWS("IvsQ_1"); - TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_1); - TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_1->getAxis(0)->unit()->unitID()); - MatrixWorkspace_sptr IvsQ_2 = - AnalysisDataService::Instance().retrieveWS("IvsQ_2"); - TSM_ASSERT("OutputWorkspace should be a matrix workspace", IvsQ_2); - TS_ASSERT_EQUALS("MomentumTransfer", IvsQ_2->getAxis(0)->unit()->unitID()); - - auto instr = IvsLam_1->getInstrument(); - auto detectorPos = instr->getComponentByName("lineardetector"); - TS_ASSERT_DELTA(-0.05714, detectorPos->getPos().Z(), 0.0001) - - AnalysisDataService::Instance().remove("IvsLam"); - AnalysisDataService::Instance().remove("IvsLam_1"); - AnalysisDataService::Instance().remove("IvsLam_2"); - AnalysisDataService::Instance().remove("IvsQ"); - AnalysisDataService::Instance().remove("IvsQ_1"); - AnalysisDataService::Instance().remove("IvsQ_2"); - } -}; - -#endif /* MANTID_ALGORITHMS_REFLECTOMETRYREDUCTIONONEAUTOTEST_H_ */ diff --git a/Framework/Algorithms/test/ReflectometryReductionOneTest.h b/Framework/Algorithms/test/ReflectometryReductionOneTest.h deleted file mode 100644 index a8072ac9bd1d..000000000000 --- a/Framework/Algorithms/test/ReflectometryReductionOneTest.h +++ /dev/null @@ -1,395 +0,0 @@ -#ifndef ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONETEST_H_ -#define ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONETEST_H_ - -#include -#include -#include "MantidAlgorithms/ReflectometryReductionOne.h" -#include "MantidAPI/AlgorithmManager.h" -#include "MantidAPI/Axis.h" -#include "MantidAPI/FrameworkManager.h" -#include "MantidAPI/MatrixWorkspace.h" -#include "MantidTestHelpers/WorkspaceCreationHelper.h" -#include "MantidGeometry/Instrument/ReferenceFrame.h" -#include "MantidGeometry/Instrument.h" -#include "MantidKernel/Unit.h" - -using namespace Mantid; -using namespace Mantid::Kernel; -using namespace Mantid::API; -using namespace Mantid::Algorithms; -using namespace Mantid::Geometry; -using namespace WorkspaceCreationHelper; - -class ReflectometryReductionOneTest : public CxxTest::TestSuite { -private: - MatrixWorkspace_sptr m_tinyReflWS; - -public: - // This pair of boilerplate methods prevent the suite being created statically - // This means the constructor isn't called when running other tests - static ReflectometryReductionOneTest *createSuite() { - return new ReflectometryReductionOneTest(); - } - static void destroySuite(ReflectometryReductionOneTest *suite) { - delete suite; - } - - ReflectometryReductionOneTest() { - FrameworkManager::Instance(); - m_tinyReflWS = create2DWorkspaceWithReflectometryInstrument(); - } - - void test_tolam() { - MatrixWorkspace_sptr toConvert = m_tinyReflWS; - std::vector detectorIndexRange; - size_t workspaceIndexToKeep1 = 1; - const int monitorIndex = 0; - - specnum_t specId1 = - toConvert->getSpectrum(workspaceIndexToKeep1).getSpectrumNo(); - specnum_t monitorSpecId = - toConvert->getSpectrum(monitorIndex).getSpectrumNo(); - - // Define one spectra to keep - detectorIndexRange.push_back(static_cast(workspaceIndexToKeep1)); - std::stringstream buffer; - buffer << workspaceIndexToKeep1; - const std::string detectorIndexRangesStr = buffer.str(); - - // Define a wavelength range for the detector workspace - const double wavelengthMin = 1.0; - const double wavelengthMax = 15; - const double backgroundWavelengthMin = 17; - const double backgroundWavelengthMax = 20; - - ReflectometryReductionOne alg; - - // Run the conversion. - ReflectometryWorkflowBase::DetectorMonitorWorkspacePair inLam = - alg.toLam(toConvert, detectorIndexRangesStr, monitorIndex, - boost::tuple(wavelengthMin, wavelengthMax), - boost::tuple(backgroundWavelengthMin, - backgroundWavelengthMax)); - - // Unpack the results - MatrixWorkspace_sptr detectorWS = inLam.get<0>(); - MatrixWorkspace_sptr monitorWS = inLam.get<1>(); - - /* ---------- Checks for the detector workspace ------------------*/ - - // Check units. - TS_ASSERT_EQUALS("Wavelength", detectorWS->getAxis(0)->unit()->unitID()); - - // Check the number of spectrum kept. - TS_ASSERT_EQUALS(1, detectorWS->getNumberHistograms()); - - auto map = detectorWS->getSpectrumToWorkspaceIndexMap(); - // Check the spectrum Nos retained. - TS_ASSERT_EQUALS(map[specId1], 0); - - // Check the cropped x range - auto copyX = detectorWS->x(0); - std::sort(copyX.begin(), copyX.end()); - TS_ASSERT(copyX.front() >= wavelengthMin); - TS_ASSERT(copyX.back() <= wavelengthMax); - - /* ------------- Checks for the monitor workspace --------------------*/ - // Check units. - TS_ASSERT_EQUALS("Wavelength", monitorWS->getAxis(0)->unit()->unitID()); - - // Check the number of spectrum kept. This should only ever be 1. - TS_ASSERT_EQUALS(1, monitorWS->getNumberHistograms()); - - map = monitorWS->getSpectrumToWorkspaceIndexMap(); - // Check the spectrum Nos retained. - TS_ASSERT_EQUALS(map[monitorSpecId], 0); - } - - IAlgorithm_sptr construct_standard_algorithm() { - auto alg = - AlgorithmManager::Instance().create("ReflectometryReductionOne", 1); - alg->setRethrows(true); - alg->setChild(true); - alg->initialize(); - alg->setProperty("InputWorkspace", m_tinyReflWS); - alg->setProperty("WavelengthMin", 1.0); - alg->setProperty("WavelengthMax", 2.0); - alg->setProperty("I0MonitorIndex", 1); - alg->setProperty("MonitorBackgroundWavelengthMin", 1.0); - alg->setProperty("MonitorBackgroundWavelengthMax", 2.0); - alg->setProperty("MonitorIntegrationWavelengthMin", 1.2); - alg->setProperty("MonitorIntegrationWavelengthMax", 1.5); - alg->setProperty("MomentumTransferStep", 0.1); - alg->setPropertyValue("ProcessingInstructions", "0"); - alg->setPropertyValue("OutputWorkspace", "x"); - alg->setPropertyValue("OutputWorkspaceWavelength", "y"); - alg->setRethrows(true); - return alg; - } - - void test_execute() { - auto alg = construct_standard_algorithm(); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - MatrixWorkspace_sptr workspaceInQ = alg->getProperty("OutputWorkspace"); - MatrixWorkspace_sptr workspaceInLam = - alg->getProperty("OutputWorkspaceWavelength"); - const double theta = alg->getProperty("ThetaOut"); - UNUSED_ARG(theta) - UNUSED_ARG(workspaceInQ) - UNUSED_ARG(workspaceInLam) - } - - void test_calculate_theta() { - - auto alg = construct_standard_algorithm(); - - alg->execute(); - // Should not throw - - const double outTwoTheta = alg->getProperty("ThetaOut"); - TS_ASSERT_DELTA(45.0, outTwoTheta, 0.00001); - } - - void test_source_rotation_after_second_reduction() { - // set up the axis for the instrument - Instrument_sptr instrument = boost::make_shared(); - instrument->setReferenceFrame(boost::make_shared( - Y /*up*/, Z /*along*/, Right, "0,0,0")); - - // add a source - ObjComponent *source = new ObjComponent("source"); - source->setPos(V3D(0, 0, -1)); - instrument->add(source); - instrument->markAsSource(source); - - // add a sample - ObjComponent *sample = new ObjComponent("some-surface-holder"); - sample->setPos(V3D(0, 0, 0)); - instrument->add(sample); - instrument->markAsSamplePos(sample); - - // add a detector - Detector *det = new Detector("point-detector", 1, nullptr); - det->setPos(V3D(0, 1, 1)); - instrument->add(det); - instrument->markAsDetector(det); - - // set the instrument to this workspace - m_tinyReflWS->setInstrument(instrument); - // set this detector ready for processing instructions - m_tinyReflWS->getSpectrum(0).setDetectorID(det->getID()); - - auto alg = - AlgorithmManager::Instance().create("ReflectometryReductionOne", 1); - alg->setRethrows(true); - alg->setChild(true); - alg->initialize(); - alg->setProperty("InputWorkspace", m_tinyReflWS); - alg->setProperty("WavelengthMin", 1.0); - alg->setProperty("WavelengthMax", 15.0); - alg->setProperty("I0MonitorIndex", 0); - alg->setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg->setProperty("MonitorBackgroundWavelengthMax", 0.0); - alg->setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg->setProperty("MonitorIntegrationWavelengthMax", 0.0); - alg->setProperty("MomentumTransferStep", 0.1); - alg->setProperty("NormalizeByIntegratedMonitors", false); - alg->setProperty("CorrectDetectorPositions", true); - alg->setProperty("CorrectionAlgorithm", "None"); - alg->setPropertyValue("ProcessingInstructions", "1"); - alg->setPropertyValue("OutputWorkspace", "x"); - alg->setPropertyValue("OutputWorkspaceWavelength", "y"); - alg->setRethrows(true); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - MatrixWorkspace_sptr outLam = alg->getProperty("OutputWorkspaceWavelength"); - MatrixWorkspace_sptr outQ = alg->getProperty("OutputWorkspace"); - - TS_ASSERT_EQUALS(m_tinyReflWS->getInstrument()->getSource()->getPos(), - outLam->getInstrument()->getSource()->getPos()); - TS_ASSERT_EQUALS(outLam->getInstrument()->getSource()->getPos(), - outQ->getInstrument()->getSource()->getPos()); - } - void test_post_processing_scale_step() { - auto alg = construct_standard_algorithm(); - auto inWS = - WorkspaceCreationHelper::create2DWorkspaceWithReflectometryInstrument( - 2.0); - inWS->getAxis(0)->setUnit("Wavelength"); - alg->setProperty("InputWorkspace", inWS); - alg->setProperty("ScaleFactor", 1.0); - alg->setProperty("ThetaIn", 1.5); - alg->setProperty("OutputWorkspace", "Test"); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - MatrixWorkspace_sptr nonScaledWS = alg->getProperty("OutputWorkspace"); - alg->setProperty("InputWorkspace", inWS); - alg->setProperty("ScaleFactor", 0.5); - alg->setProperty("OutputWorkspace", "scaledTest"); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - MatrixWorkspace_sptr scaledWS = alg->getProperty("OutputWorkspace"); - // compare y data instead of workspaces. - auto &scaledYData = scaledWS->y(0); - auto &nonScaledYData = nonScaledWS->y(0); - TS_ASSERT_EQUALS(scaledYData.front(), 2 * nonScaledYData.front()); - TS_ASSERT_EQUALS(scaledYData[scaledYData.size() / 2], - 2 * nonScaledYData[nonScaledYData.size() / 2]); - TS_ASSERT_EQUALS(scaledYData.back(), 2 * nonScaledYData.back()); - // Remove workspace from the data service. - AnalysisDataService::Instance().remove("Test"); - AnalysisDataService::Instance().remove("scaledTest"); - } - void test_post_processing_rebin_step_with_params_not_provided() { - auto alg = construct_standard_algorithm(); - auto inWS = create2DWorkspace154(1, 10, true); - // this instrument does not have a "slit-gap" property - // defined in the IPF, so NRCalculateSlitResolution should throw. - inWS->setInstrument(m_tinyReflWS->getInstrument()); - inWS->getAxis(0)->setUnit("Wavelength"); - // Setup bad bin edges, Rebin will throw (not NRCalculateSlitResolution?) - inWS->mutableX(0) = inWS->x(0)[0]; - alg->setProperty("InputWorkspace", inWS); - alg->setProperty("OutputWorkspace", "rebinnedWS"); - TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); - } - void test_post_processing_rebin_step_with_partial_params_provided() { - auto alg = construct_standard_algorithm(); - auto inWS = create2DWorkspace154(1, 10, true); - inWS->setInstrument(m_tinyReflWS->getInstrument()); - inWS->getAxis(0)->setUnit("Wavelength"); - alg->setProperty("InputWorkspace", inWS); - alg->setProperty("MomentumTransferMaximum", 15.0); - alg->setProperty("OutputWorkspace", "rebinnedWS"); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - MatrixWorkspace_sptr rebinnedIvsQWS = alg->getProperty("OutputWorkspace"); - auto &xData = rebinnedIvsQWS->x(0); - // based off the equation for logarithmic binning X(i+1)=X(i)(1+|dX|) - double binWidthFromLogarithmicEquation = fabs((xData[1] / xData[0]) - 1); - TSM_ASSERT_DELTA("DQQ should be the same as abs(x[1]/x[0] - 1)", - binWidthFromLogarithmicEquation, 0.1, 1e-06); - TSM_ASSERT_DELTA("Qmax should be the same as last Params entry (5.0)", - xData.back(), 15.0, 1e-06); - } - void test_post_processing_rebin_step_with_logarithmic_rebinning() { - auto alg = construct_standard_algorithm(); - auto inWS = create2DWorkspace154(1, 10, true); - inWS->setInstrument(m_tinyReflWS->getInstrument()); - inWS->getAxis(0)->setUnit("Wavelength"); - alg->setProperty("InputWorkspace", inWS); - alg->setProperty("MomentumTransferMinimum", 1.0); - alg->setProperty("MomentumTransferStep", 0.2); - alg->setProperty("MomentumTransferMaximum", 5.0); - alg->setProperty("OutputWorkspace", "rebinnedWS"); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - MatrixWorkspace_sptr rebinnedIvsQWS = alg->getProperty("OutputWorkspace"); - auto &xData = rebinnedIvsQWS->x(0); - TSM_ASSERT_EQUALS("QMin should be the same as first Param entry (1.0)", - xData[0], 1.0); - // based off the equation for logarithmic binning X(i+1)=X(i)(1+|dX|) - double binWidthFromLogarithmicEquation = fabs((xData[1] / xData[0]) - 1); - TSM_ASSERT_DELTA("DQQ should be the same as abs(x[1]/x[0] - 1)", - binWidthFromLogarithmicEquation, 0.2, 1e-06); - TSM_ASSERT_EQUALS("QMax should be the same as last Param entry", - xData.back(), 5.0); - } - void test_post_processing_rebin_step_with_linear_rebinning() { - auto alg = construct_standard_algorithm(); - auto inWS = create2DWorkspace154(1, 10, true); - inWS->setInstrument(m_tinyReflWS->getInstrument()); - inWS->getAxis(0)->setUnit("Wavelength"); - alg->setProperty("InputWorkspace", inWS); - alg->setProperty("MomentumTransferMinimum", 1.577); - alg->setProperty("MomentumTransferStep", -0.2); - alg->setProperty("MomentumTransferMaximum", 5.233); - alg->setProperty("OutputWorkspace", "rebinnedWS"); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - MatrixWorkspace_sptr rebinnedIvsQWS = alg->getProperty("OutputWorkspace"); - auto &xData = rebinnedIvsQWS->x(0); - TSM_ASSERT_DELTA("QMin should be the same as the first Param entry (1.577)", - xData[0], 1.577, 1e-06); - TSM_ASSERT_DELTA("DQQ should the same as 0.2", xData[1] - xData[0], 0.2, - 1e-06); - TSM_ASSERT_DELTA("QMax should be the same as the last Param entry (5.233)", - xData.back(), 5.233, 1e-06); - } - void test_Qrange() { - // set up the axis for the instrument - Instrument_sptr instrument = boost::make_shared(); - instrument->setReferenceFrame(boost::make_shared( - Y /*up*/, Z /*along*/, Right, "0,0,0")); - - // add a source - ObjComponent *source = new ObjComponent("source"); - source->setPos(V3D(0, 0, -1)); - instrument->add(source); - instrument->markAsSource(source); - - // add a sample - ObjComponent *sample = new ObjComponent("some-surface-holder"); - sample->setPos(V3D(0, 0, 0)); - instrument->add(sample); - instrument->markAsSamplePos(sample); - - // add a detector - Detector *det = new Detector("point-detector", 1, nullptr); - det->setPos(V3D(0, 1, 1)); - instrument->add(det); - instrument->markAsDetector(det); - - // set the instrument to this workspace - m_tinyReflWS->setInstrument(instrument); - // set this detector ready for processing instructions - m_tinyReflWS->getSpectrum(0).setDetectorID(det->getID()); - - auto alg = - AlgorithmManager::Instance().create("ReflectometryReductionOne", 1); - alg->setRethrows(true); - alg->setChild(true); - alg->initialize(); - alg->setProperty("InputWorkspace", m_tinyReflWS); - alg->setProperty("WavelengthMin", 1.0); - alg->setProperty("WavelengthMax", 15.0); - alg->setProperty("I0MonitorIndex", 0); - alg->setProperty("MonitorBackgroundWavelengthMin", 0.0); - alg->setProperty("MonitorBackgroundWavelengthMax", 0.0); - alg->setProperty("MonitorIntegrationWavelengthMin", 0.0); - alg->setProperty("MonitorIntegrationWavelengthMax", 0.0); - alg->setProperty("MomentumTransferStep", 0.1); - alg->setProperty("NormalizeByIntegratedMonitors", false); - alg->setProperty("CorrectDetectorPositions", true); - alg->setProperty("CorrectionAlgorithm", "None"); - alg->setPropertyValue("ProcessingInstructions", "1"); - alg->setPropertyValue("OutputWorkspace", "x"); - alg->setPropertyValue("OutputWorkspaceWavelength", "y"); - alg->setRethrows(true); - TS_ASSERT_THROWS_NOTHING(alg->execute()); - - // retrieve the IvsLam workspace - MatrixWorkspace_sptr inLam = alg->getProperty("OutputWorkspaceWavelength"); - // retrieve the IvsQ workspace - MatrixWorkspace_sptr inQ = alg->getProperty("OutputWorkspace"); - // retrieve our Theta - double outTheta = alg->getProperty("ThetaOut"); - - TS_ASSERT_DELTA(45.0, outTheta, 0.00001); - TS_ASSERT_EQUALS(source->getPos(), - inQ->getInstrument()->getSource()->getPos()); - // convert from degrees to radians for sin() function - double outThetaInRadians = outTheta * M_PI / 180; - - double lamMin = inLam->x(0).front(); - double lamMax = inLam->x(0).back(); - - // Derive our QMin and QMax from the equation - double qMinFromEQ = (4 * M_PI * sin(outThetaInRadians)) / lamMax; - double qMaxFromEQ = (4 * M_PI * sin(outThetaInRadians)) / lamMin; - - // Get our QMin and QMax from the workspace - auto qMinFromWS = inQ->x(0).front(); - auto qMaxFromWS = inQ->x(0).back(); - - // Compare the two values (they should be identical) - TS_ASSERT_DELTA(qMinFromEQ, qMinFromWS, 0.00001); - TS_ASSERT_DELTA(qMaxFromEQ, qMaxFromWS, 0.00001); - } -}; - -#endif /* ALGORITHMS_TEST_REFLECTOMETRYREDUCTIONONETEST_H_ */ diff --git a/docs/source/algorithms/ReflectometryReductionOne-v1.rst b/docs/source/algorithms/ReflectometryReductionOne-v1.rst deleted file mode 100644 index a39a841536b2..000000000000 --- a/docs/source/algorithms/ReflectometryReductionOne-v1.rst +++ /dev/null @@ -1,248 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -Reduces a single TOF reflectometry run into a mod Q vs I/I0 workspace. -Performs transmission corrections. Handles both point detector and -multidetector cases. The algorithm can correct detector locations based -on an input theta value. - -Historically the work performed by this algorithm was known as the Quick -script. - -If :literal:`MonitorBackgroundWavelengthMin` and -:literal:`MonitorBackgroundWavelengthMax` are both set to :literal:`0`, then -background normalization will not be performed on the monitors. - -The properties of this algorithm should be manually selected by the user. If you -wish to use the default values (found in the Instrument Defintion File) for the -properties of this algorithm, you may want to consider using -:ref:`algm-ReflectometryReductionOneAuto`. - -:ref:`algm-ReflectometryReductionOneAuto` also performs extra processing steps -such as Background subtraction and :ref:`algm-PolarizationCorrection`. If you -want to know how these processing steps are used, please refer to the -:ref:`algm-ReflectometryReductionOneAuto` documentation. - -High-Level Workflow -------------------- - -The diagram below displays a high-level version of the algorithm workflow, -illustrating the main steps taking place in the ReflectometryReductionOne -algorithm. These individual steps are described in more detail in the next -sections. - -.. diagram:: ReflectometryReductionOne_HighLvl-v1_wkflw.dot - -Low-Level Workflow ------------------- - -Conversion to Wavelength -######################## - -The following diagram describes the steps taken in converting the input -workspace into units of wavelength and dividing its constituent detectors by -monitors. - -.. diagram:: ReflectometryReductionOne_ConvertToWavelength-v1_wkflw.dot - -The default analysis mode is *PointDetectorAnalysis*. For PointAnalysisMode the -analysis can be roughly reduced to IvsLam = DetectorWS / sum(I0) / -TransmissionWS / sum(I0). For MultiDetectorAnalysis the analysis can be roughly -reduced to IvsLam = DetectorWS / RegionOfDirectBeamWS / sum(I0) / TransmissionWS -/ sum(I0). - -Transmission Correction -####################### - -This diagram shows how the resultant workspace of the previous step is corrected -by either by provided transmission runs or by a specific correction algorithm. - -.. diagram:: ReflectometryReductionOne_TransmissionCorrection-v1_wkflw.dot - -Transmission correction is a normalization step, which may be applied to both -*PointDetectorAnalysis* and *MultiDetectorAnalysis* reduction. - -Transmission runs are expected to be in TOF. The spectra numbers in the -Transmission run workspaces must be the same as those in the Input Run -workspace. If two Transmission runs are provided then the Stitching -parameters associated with the transmission runs will also be required. -If a single Transmission run is provided, then no stitching parameters -will be needed. - -The normalization by tranmission run(s) is optional. - -The input workspace provided to the workflow in this instance is the original -:literal:`InputWorkspace` after conversion to wavelength and normalization by -monitors, as shown in the previous :literal:`Conversion To Wavelength` diagram. - -The output workspace given is not the output to the whole algorithm. Rather it -will serve as the input workspace to the :literal:`Polynomial Correction` -workflow, where further steps will be applied to it. - -Polynomial Correction -===================== - -If no Transmission runs are provided, then polynomial correction can be -performed instead. Polynomial correction is enabled by setting the -:literal:`CorrectionAlgorithm` property. If set to -:literal:`PolynomialCorrection` it runs the :ref:`algm-PolynomialCorrection` -algorithm, with this algorithms :literal:`Polynomial` property used as its -:literal:`Coefficients` property. - -If the :literal:`CorrectionAlgorithm` property is set to -:literal:`ExponentialCorrection`, then the :Ref:`algm-ExponentialCorrection` -algorithm is used, with C0 and C1 taken from the :literal:`C0` and :literal:`C1` -properties. - -Detector Position Correction -############################ - -The diagram below describes how the input workspace is then corrected by -detector positions after transmission correction. - -.. diagram:: ReflectometryReductionOne_CorrectDetectorPositions-v1_wkflw.dot - -Detector Position Correction is used for when the position of the detector -is not aligned with the reflected beamline. The correction algorithm used is -:ref:`algm-SpecularReflectionPositionCorrect-v1` which is a purely vertical -position correction. - -The detector positions in this process are corrected in terms of -:literal:`ThetaIn`. In general, the detector posistions should always be -corrected unless the :literal:`InputWorkspace` already has the detectors in the -right positions. This can be achieved by running -:literal:`MoveInstrumentComponent` before :literal:`ReflectometryReductionOne`. - -Convert To Momentum Transfer (Q) -################################ - -The last diagram describes the steps involved in converting the input workspace -from units of wavelength into momentum transfer (Q). - -.. diagram:: ReflectometryReductionOne_ConvertToMomentum-v1_wkflw.dot - -ReflectometryReductionOne contains 2 post-processing options that will be -applied to the IvsQ workspace. These two options are `Rebin` and `Scale`. - -Rebinning -========= - -To Rebin your IvsQ workspace you will have to provide values for the following -properties: `MomentumTransferMinimum`, `MomentumTransferStep` and -`MomentumTransferMaximum`. These values will be appended to each other to form -your :ref:`algm-Rebin` Params. These values correspond to your `MinimumExtent`, -`BinWidth` and `MaximumExtent` respectively. - -If you provide a positive `MomentumTransferStep` value then the algorithm will -automatically negate this value which will allow for Logarithmic Rebinning. -Alternatively, a negative `MomentumTransferStep` will result in Linear -Rebinning. More details about the Rebinning process can be found in the -documentation for :ref:`algm-Rebin`. - -If no values are provided for `MomentumTransferMinimum` and -`MomentumTransferMaximum` then the algorithm will attempt to calculate these -values by using the equations below: - - :math:`Q_{min} = 2 \, k \, sin \, \theta = \frac{4 \pi sin \theta}{\lambda_{max}}` - - :math:`Q_{max} = 2 \, k \, sin \, \theta = \frac{4 \pi sin \theta}{\lambda_{min}}` - -Where :math:`\lambda_{min}` is the minimum extent of the `IvsLambda` Workspace -and :math:`\lambda_{max}` is the maximum extent of the `IvsLambda` Workspace. - -If you have not provided a value for `MomentumTransferStep` then the algorithm -will use :ref:`algm-NRCalculateSlitResolution` to calculate this value for you. - -Scaling -======= - -To apply a scaling to the IvsQ workspace that has been produced by the -reduction, you will need to provide a value for the `ScaleFactor` property in -the algorithm. The default for this value is 1.0 and thus no scaling is applied -to the workspace. The scaling of the IvsQ workspace is performed in-place by the -:ref:`algm-Scale` algorithm and your IvsQ workspace will be set to the product -of this algorithm. - -Source Rotation -=============== - -In the workflow diagram above, after we produce the IvsLambda workspace, it may -be necessary to rotate the position of the source to match the value of -ThetaOut (:math:`\theta_f`). - -Below we see the typical experimental setup for a Reflectometry instrument. The -source direction (Beam vector) is along the horizon. This setup is defined in -the Instrument Defintion File and this instrument setup will be attached to any -workspaces associated with that instrument. When we pass the IvsLambda workspace -to :ref:`algm-ConvertUnits` to produce an IvsQ workspace, -:ref:`algm-ConvertUnits` will assume that :math:`2\theta` is the angle between -the Beam vector and the sample-to-detector vector. When we have the typical -setup seen below, :math:`2\theta` will be exactly half the value we wish it to -be. - -.. figure:: /images/CurrentExperimentSetupForReflectometry.png - :width: 650px - :height: 250px - :align: center - -We rotate the position of the Source (and therefore the Beam vector) in the -Instrument Defintion associated with the IvsLambda workspace until the condition -:math:`\theta_i = \theta_f` is satisfied. This will achieve the desired result -for :math:`2\theta` (see below for rotated source diagram). After -:ref:`algm-ConvertUnits` has produced our IvsQ workspace, we will rotate the -position of the source back to its original position so that the experimental -setup remains unchanged for other algorithms that may need to manipulate/use it. - -.. figure:: /images/RotatedExperimentSetupForReflectometry.png - :width: 650px - :height: 250px - :align: center - - -Processing Instructions -####################### - -These enable a grouping pattern on workspace indices to yield only the detectors of interest. It allows usage of the operators :literal:`,:+-` to specify or exclude specific indices or to add -spectra together. See :literal:`Grouping Pattern` from :Ref:`algm-GroupDetectors` for further details on their usage. - -Usage ------ - -**Example - Reduce a Run** - -.. testcode:: ExReflRedOneSimple - - run = Load(Filename='INTER00013460.nxs') - # Basic reduction with no transmission run - IvsQ, IvsLam, thetaOut = ReflectometryReductionOne(InputWorkspace=run, ThetaIn=0.7, I0MonitorIndex=2, ProcessingInstructions='3:4', - WavelengthMin=1.0, WavelengthMax=17.0, - MonitorBackgroundWavelengthMin=15.0, MonitorBackgroundWavelengthMax=17.0, - MonitorIntegrationWavelengthMin=4.0, MonitorIntegrationWavelengthMax=10.0, Version=1) - - print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3])) - print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3])) - print("Theta out is the same as theta in: {}".format(thetaOut)) - - -Output: - -.. testoutput:: ExReflRedOneSimple - - The first four IvsLam Y values are: [ 0.0000e+00, 0.0000e+00, 7.8118e-07, 1.9346e-06 ] - The first four IvsQ Y values are: [ 1.3845e-03, 1.9717e-03, 2.7579e-03, 4.1467e-03 ] - Theta out is the same as theta in: 0.7 - - -.. categories:: - -.. sourcelink:: diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst deleted file mode 100644 index d93dd93e8db7..000000000000 --- a/docs/source/algorithms/ReflectometryReductionOneAuto-v1.rst +++ /dev/null @@ -1,166 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -Facade over :ref:`algm-ReflectometryReductionOne`. - -Pulls numeric parameters out of the instrument parameters where possible. You can override any of these automatically applied defaults by providing your own value for the input. - -See :ref:`algm-ReflectometryReductionOne` for more information on the wrapped algorithm. - -ProcessingInstructions -###################### - -If ProcessingInstructions is not set its value is inferred from other properties: - -* If AnalysisMode = PointDetectorAnalaysis and PointDetectorStart = PointDetectorStop then the spectrum specified by PointDetectorStart is used. -* If AnalysisMode = PointDetectorAnalaysis and PointDetectorStart ≠ PointDetectorStop then the sum of the spectra from PointDetectorStart to PointDetectorStop is used. -* If AnalysisMode = MultiDetectorAnalaysis then all of the spectra from MultiDetectorStart onwards are used. - -Note, the ProcessingInstructions are workspace indicies, not detector IDs. The first few workspaces may correspond to monitors, rather than detectors of interest. -For the syntax of this property, see :ref:`algm-GroupDetectors`. - -Workflow for WorkspaceGroups -############################ - -If a WorkspaceGroup is provided to ReflectometryReductionOneAuto, it will follow the steps shown in the diagram below to produce its output. - -.. diagram:: ReflectometryReductionOneAuto-v1-Groups_wkflw.dot - -Workflow for Polarization Correction -#################################### - -If polarization correction is enabled, it is performed as an additional step once the main processing has completed. -The following diagram shows how the :ref:`algm-PolarizationCorrection` algorithm is used. - -.. diagram:: ReflectometryReductionOneAuto-v1-PolarizationCorrection_wkflw.dot - -Polynomial Correction -##################### - -If no Transmission runs are provided, then polynomial correction can be -performed instead. Polynomial correction is enabled by setting the -:literal:`CorrectionAlgorithm` property. - -If set to :literal:`AutoDetect`, it looks at the instrument -parameters for the :literal:`correction` parameter. If it is set to -:literal:`polynomial`, then polynomial correction is performed using the -:ref:`algm-PolynomialCorrection` algorithm, with the polynomial string taken -from the instrument's :literal:`polynomial` parameter. If the -:literal:`correction` parameter is set to :literal:`exponential` instead, then -the :Ref:`algm-ExponentialCorrection` algorithm is used, with C0 and C1 taken -from the instrument parameters, :literal:`C0` and :literal:`C1`. - -These can be specified manually by setting the :literal:`CorrectionAlgorithm`, -:literal:`Polynomial`, :literal:`C0`, and :literal:`C1` properties accordingly. - -Usage ------ - -**Example - Reduce a Run** - -.. testcode:: ExReflRedOneAutoSimple - - run = Load(Filename='INTER00013460.nxs') - # Basic reduction with no transmission run - IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, ThetaIn=0.7, CorrectDetectorPositions=False, Version=1) - - print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3])) - print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3])) - print("Theta out is the same as theta in: {}".format(thetaOut)) - -Output: - -.. testoutput:: ExReflRedOneAutoSimple - - The first four IvsLam Y values are: [ 5.3860e-06, 9.3330e-06, 6.9796e-06, 6.5687e-06 ] - The first four IvsQ Y values are: [ 1.3648e-03, 1.9490e-03, 2.7277e-03, 4.0995e-03 ] - Theta out is the same as theta in: 0.7 - -**Example - Reduce a Run with a transmission run** - -.. testcode:: ExReflRedOneAutoTrans - - run = Load(Filename='INTER00013460.nxs') - trans = Load(Filename='INTER00013463.nxs') - # Basic reduction with a transmission run - IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, FirstTransmissionRun=trans, ThetaIn=0.7, Version=1) - - print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3])) - print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3])) - print("Theta out is the same as theta in: {}".format(thetaOut)) - -Output: - -.. testoutput:: ExReflRedOneAutoTrans - - The first four IvsLam Y values are: [ 3.2705e-05, 5.5450e-05, 3.9630e-05, 3.5770e-05 ] - The first four IvsQ Y values are: [ 9.3930e-01, 1.3251e+00, 1.2766e+00, 1.1977e+00 ] - Theta out is the same as theta in: 0.7 - -**Example - Reduce a Run overloading default parameters** - -.. testcode:: ExReflRedOneAutoOverload - - run = Load(Filename='INTER00013460.nxs') - # Reduction overriding the default values for MonitorBackgroundWavelengthMin and MonitorBackgroundWavelengthMax which would otherwise be retirieved from the workspace - IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, ThetaIn=0.7, CorrectDetectorPositions=False, MonitorBackgroundWavelengthMin=0.0, MonitorBackgroundWavelengthMax=1.0, Version=1) - - print("The first four IvsLam Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsLam.readY(0)[0], IvsLam.readY(0)[1], IvsLam.readY(0)[2], IvsLam.readY(0)[3])) - print("The first four IvsQ Y values are: [ {:.4e}, {:.4e}, {:.4e}, {:.4e} ]".format( - IvsQ.readY(0)[0], IvsQ.readY(0)[1], IvsQ.readY(0)[2], IvsQ.readY(0)[3])) - print("Theta out is the same as theta in: {}".format(thetaOut)) - -Output: - -.. testoutput:: ExReflRedOneAutoOverload - - The first four IvsLam Y values are: [ 5.3868e-06, 9.3344e-06, 6.9807e-06, 6.5696e-06 ] - The first four IvsQ Y values are: [ 1.3650e-03, 1.9493e-03, 2.7281e-03, 4.1001e-03 ] - Theta out is the same as theta in: 0.7 - -**Example - Polynomial correction** - -.. testcode:: ExReflRedOneAutoPoly - - run = Load(Filename='INTER00013460.nxs') - # Set up some paramters, allowing the algorithm to automatically detect the correction to use - SetInstrumentParameter(run, "correction", Value="polynomial") - SetInstrumentParameter(run, "polynomial", Value="0,0.5,1,2,3") - - IvsQ, IvsLam, thetaOut = ReflectometryReductionOneAuto(InputWorkspace=run, ThetaIn=0.7, Version=1) - - def findByName(histories, name): - return next(x for x in histories if x.name() == name) - - # Find the PolynomialCorrection entry in the workspace's history - algHist = IvsLam.getHistory() - refRedOneAutoHist = findByName(algHist.getAlgorithmHistories(), "ReflectometryReductionOneAuto") - refRedOneHist = findByName(refRedOneAutoHist.getChildHistories(), "ReflectometryReductionOne") - polyCorHist = findByName(refRedOneHist.getChildHistories(), "PolynomialCorrection") - - coefProp = findByName(polyCorHist.getProperties(), "Coefficients") - - print("Coefficients: '{}'".format(coefProp.value())) - -Output: - -.. testoutput:: ExReflRedOneAutoPoly - - Coefficients: '0,0.5,1,2,3' - -.. categories:: - -.. sourcelink:: From c2b8b0d8589f4355e12c7772f447739655e60033 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 26 Feb 2018 08:31:59 +0000 Subject: [PATCH 075/364] force rebuild From c43f7b47b22ed203bb6707292a24427446483f30 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 26 Feb 2018 15:41:14 +0000 Subject: [PATCH 076/364] Re #20991: Deleted OFFSPEC system tests which used RROAv1. --- .../tests/analysis/OFFSPECReflRedOneAuto.py | 55 ------------------- ...PECReflRedOneAutoPolarizationCorrection.py | 48 ---------------- 2 files changed, 103 deletions(-) delete mode 100644 Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAuto.py delete mode 100644 Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAutoPolarizationCorrection.py diff --git a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAuto.py b/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAuto.py deleted file mode 100644 index f61dc4634f95..000000000000 --- a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAuto.py +++ /dev/null @@ -1,55 +0,0 @@ -# pylint: disable=no-init,invalid-name,attribute-defined-outside-init -""" -This system test verifies that OFFSPEC data is processed correctly by -ReflectometryReductionOneAuto -""" - -import stresstesting -from mantid.simpleapi import * - - -class OFFSPECReflRedOneAuto(stresstesting.MantidStressTest): - def runTest(self): - offspec75 = Load("OFFSPEC00027575.raw") #th=0.35 - offspec76 = Load("OFFSPEC00027576.raw") #th=1.00 - offspec78 = Load("OFFSPEC00027578.raw") #th=1.70 - offspec85 = Load("OFFSPEC00027585.raw") #transmission run - - #Process using ReflectometryReductionOneAuto - ivq_75, __, __ = ReflectometryReductionOneAuto(offspec75, - ThetaIn=0.70,#2*th - MomentumTransferStep=1e-3, - FirstTransmissionRun=offspec85, - Version=1) - - ivq_76, __, __ = ReflectometryReductionOneAuto(offspec76, - ThetaIn=2.00,#2*th - MomentumTransferStep=1e-3, - FirstTransmissionRun=offspec85, - Version=1) - - ivq_78, __, __ = ReflectometryReductionOneAuto(offspec78, - ThetaIn=3.40,#2*th - MomentumTransferStep=1e-3, - FirstTransmissionRun=offspec85, - Version=1) - - ivq_75_76, __ = Stitch1D(ivq_75, ivq_76, Params="1e-3") - #pylint: disable=unused-variable - ivq_75_76_78, __ = Stitch1D(ivq_75_76, ivq_78, Params="0,1e-3,0.25") - return True - - def validate(self): - ''' - we only wish to check the Q-range in this system test. It is not necessary - to check the Instrument definition or Instrument Parameters - ''' - self.disableChecking = ["Instrument"] - return ("ivq_75_76_78","OFFSPECReflRedOneAuto_good_v3.nxs") - - def requiredFiles(self): - return ["OFFSPEC00027575.raw", - "OFFSPEC00027576.raw", - "OFFSPEC00027578.raw", - "OFFSPEC00027585.raw", - "OFFSPECReflRedOneAuto_good_v3.nxs"] diff --git a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAutoPolarizationCorrection.py b/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAutoPolarizationCorrection.py deleted file mode 100644 index b4aaf1e46802..000000000000 --- a/Testing/SystemTests/tests/analysis/OFFSPECReflRedOneAutoPolarizationCorrection.py +++ /dev/null @@ -1,48 +0,0 @@ -# pylint: disable=no-init, invalid-name, line-too-long, attribute-defined-outside-init - -""" -This system test verifies that OFFSPEC data is processed correctly -by ReflectometryReductionAutoOne with PolarizationCorrection performed -as part of the workflow. -""" - -import stresstesting -from mantid.simpleapi import * - - -class OFFSPECReflRedOneAutoPolarizationCorrection(stresstesting.MantidStressTest): - def runTest(self): - inputWorkspace = Load("OFFSPEC00033767.nxs") - transmissionGroup = Load("OFFSPEC00033772.nxs") - #set up our transmission workspace - transWorkspace = CreateTransmissionWorkspaceAuto(transmissionGroup, - AnalysisMode="MultiDetectorAnalysis", - ProcessingInstructions="110-120", - WavelengthMin=2.0, WavelengthMax=12.0, Version=1) - # set up our efficiency constants - CRho=[1] - CAlpha=[1] - CAp=[1] - CPp=[1] - #run reflectometryReductionOneAuto - __, _IvsLam_polCorr,__ = ReflectometryReductionOneAuto(inputWorkspace, AnalysisMode="MultiDetectorAnalysis", - ProcessingInstructions="110-120", - FirstTransmissionRun=transWorkspace, - ThetaIn="1.2",WavelengthMin=2.0, - WavelengthMax=12.0,CorrectionAlgorithm='None', - PolarizationAnalysis='PA', MomentumTransferStep=0.1, - CPp=CPp,CAp=CAp,CRho=CRho,CAlpha=CAlpha, Version=1) - return True - - def validate(self): - ''' - we only wish to check the data from PolarizationCorrection in this system test. - It is not necessary to check the Instrument definition or Instrument Parameters - ''' - self.disableChecking = ["Instrument"] - return ("_IvsLam_polCorr", "OFFSPECReflRedOneAutoPolarizationCorrection_good_v2.nxs") - - def requiredFiles(self): - return ["OFFSPEC00033767.nxs", - "OFFSPEC00033772.nxs", - "OFFSPECReflRedOneAutoPolarizationCorrection_good_v2.nxs"] From e957fee39ef232cd08b25e5602aa23649ec139b9 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 27 Feb 2018 10:23:13 +0000 Subject: [PATCH 077/364] clang-format #21230 --- .../Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h | 4 ++-- Framework/Geometry/src/Objects/CSGObject.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index e0ae299248ab..91ef978bb646 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -63,9 +63,9 @@ class MANTID_GEOMETRY_DLL GeometryHandler { nullptr; ///< ObjComponent that uses this geometry handler CSGObject *m_obj = nullptr; ///< Object that uses this geometry handler public: - GeometryHandler(IObjComponent *comp); ///< Constructor + GeometryHandler(IObjComponent *comp); ///< Constructor GeometryHandler(boost::shared_ptr obj); ///< Constructor - GeometryHandler(CSGObject *obj); ///< Constructor + GeometryHandler(CSGObject *obj); ///< Constructor GeometryHandler(RectangularDetector *comp); GeometryHandler(StructuredDetector *comp); GeometryHandler(const GeometryHandler &handler); diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 9b85ec5e74f9..288ca71fbe02 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -2158,8 +2158,8 @@ const std::vector &CSGObject::getTriangleFaces() const { * get info on standard shapes */ void Object::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, - std::vector &vectors, - double &myradius, double &myheight) const { + std::vector &vectors, double &myradius, + double &myheight) const { type = detail::ShapeInfo::GeometryShape::NOSHAPE; if (m_handler == nullptr) return; From 6cd62b563ab21dc05fa463bee369939a4038eaa9 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 27 Feb 2018 10:49:25 +0000 Subject: [PATCH 078/364] ComponentInfo merge issue #21230 --- .../inc/MantidBeamline/ComponentInfo.h | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index 9618c3b5b3da..331b52f1fc02 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -89,22 +89,25 @@ class MANTID_BEAMLINE_DLL ComponentInfo { public: ComponentInfo(); - ComponentInfo(boost::shared_ptr> - assemblySortedDetectorIndices, - boost::shared_ptr>> - detectorRanges, - boost::shared_ptr> - assemblySortedComponentIndices, - boost::shared_ptr>> - componentRanges, - boost::shared_ptr> parentIndices, - boost::shared_ptr>> children, - boost::shared_ptr> positions, - boost::shared_ptr> rotations, - boost::shared_ptr> scaleFactors, - boost::shared_ptr> componentType, - boost::shared_ptr> names, - int64_t sourceIndex, int64_t sampleIndex); + ComponentInfo( + boost::shared_ptr> + assemblySortedDetectorIndices, + boost::shared_ptr>> + detectorRanges, + boost::shared_ptr> + assemblySortedComponentIndices, + boost::shared_ptr>> + componentRanges, + boost::shared_ptr> parentIndices, + boost::shared_ptr>> children, + boost::shared_ptr> positions, + boost::shared_ptr>> + rotations, + boost::shared_ptr> scaleFactors, + boost::shared_ptr> componentType, + boost::shared_ptr> names, + int64_t sourceIndex, int64_t sampleIndex); /// Copy assignment not permitted because of the way DetectorInfo stored ComponentInfo &operator=(const ComponentInfo &other) = delete; /// Clone method From 04b82fbbb244846a6ee23c8081b8e1e9d0419e04 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 27 Feb 2018 11:35:56 +0000 Subject: [PATCH 079/364] Fix Object merge issues #21230 --- .../inc/MantidGeometry/Instrument/Container.h | 5 +++-- .../inc/MantidGeometry/Objects/CSGObject.h | 2 +- .../inc/MantidGeometry/Objects/IObject.h | 6 ++++-- Framework/Geometry/src/Objects/CSGObject.cpp | 20 +++++++++---------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h index 5cc42ac89047..b68a79dded95 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h @@ -102,8 +102,9 @@ class MANTID_GEOMETRY_DLL Container final : public IObject { return m_shape->generatePointInObject(rng, activeRegion, i); } - void GetObjectGeom(int &type, std::vector &vectors, - double &myradius, double &myheight) const override { + void GetObjectGeom(detail::ShapeInfo::GeometryShape &type, + std::vector &vectors, double &myradius, + double &myheight) const override { m_shape->GetObjectGeom(type, vectors, myradius, myheight); } boost::shared_ptr getGeometryHandler() override { diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index 809a9fe1b92a..445d17a85219 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -190,7 +190,7 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { boost::shared_ptr) override; void GetObjectGeom(detail::ShapeInfo::GeometryShape &type, std::vector &vectors, double &myradius, - double &myheight) const; + double &myheight) const override; /// Getter for the shape xml std::string getShapeXML() const override; diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h index 93f33338a2f1..f022076854f6 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h @@ -2,9 +2,10 @@ #define MANTID_GEOMETRY_IOBJECT_H_ #include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include -#include #include +#include namespace Mantid { @@ -89,7 +90,8 @@ class MANTID_GEOMETRY_DLL IObject { const BoundingBox &activeRegion, const size_t) const = 0; - virtual void GetObjectGeom(int &type, std::vector &vectors, + virtual void GetObjectGeom(detail::ShapeInfo::GeometryShape &type, + std::vector &vectors, double &myradius, double &myheight) const = 0; virtual boost::shared_ptr getGeometryHandler() = 0; diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 288ca71fbe02..678522c11498 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -59,7 +59,7 @@ CSGObject::CSGObject(const std::string &shapeXML) vtkCacheWriter(boost::shared_ptr()), m_shapeXML(shapeXML), m_id(), m_material() // empty by default { - handle = boost::make_shared(this); + m_handler = boost::make_shared(this); } /** @@ -2059,7 +2059,7 @@ void CSGObject::draw() const { if (m_handler == nullptr) return; // Render the Object - handle->render(); + m_handler->render(); } /** @@ -2071,7 +2071,7 @@ void CSGObject::initDraw() const { if (m_handler == nullptr) return; // Render the Object - handle->initialize(); + m_handler->initialize(); } /** * set vtkGeometryCache writer @@ -2125,14 +2125,14 @@ void CSGObject::updateGeometryHandler() { // Initialize Draw Object size_t CSGObject::numberOfTriangles() const { - if (handle == nullptr) + if (m_handler == nullptr) return 0; - return m_handler->NumberOfTriangles(); + return m_handler->numberOfTriangles(); } size_t CSGObject::numberOfVertices() const { - if (handle == nullptr) + if (m_handler == nullptr) return 0; - return m_handler->NumberOfPoints(); + return m_handler->numberOfPoints(); } /** * get vertices @@ -2157,9 +2157,9 @@ const std::vector &CSGObject::getTriangleFaces() const { /** * get info on standard shapes */ -void Object::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, - std::vector &vectors, double &myradius, - double &myheight) const { +void CSGObject::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, + std::vector &vectors, + double &myradius, double &myheight) const { type = detail::ShapeInfo::GeometryShape::NOSHAPE; if (m_handler == nullptr) return; From 57ce3f9c0f14bc712442ef15c27559b596b2143b Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 27 Feb 2018 11:42:49 +0000 Subject: [PATCH 080/364] GeometryHandler merge issue #21230 --- .../Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index 91ef978bb646..c72f0c5e806d 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -64,7 +64,7 @@ class MANTID_GEOMETRY_DLL GeometryHandler { CSGObject *m_obj = nullptr; ///< Object that uses this geometry handler public: GeometryHandler(IObjComponent *comp); ///< Constructor - GeometryHandler(boost::shared_ptr obj); ///< Constructor + GeometryHandler(boost::shared_ptr obj); ///< Constructor GeometryHandler(CSGObject *obj); ///< Constructor GeometryHandler(RectangularDetector *comp); GeometryHandler(StructuredDetector *comp); From ff22421eb1b0c9747c1a981e044a1a3c6eac4a60 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 27 Feb 2018 11:46:01 +0000 Subject: [PATCH 081/364] clang-format #21230 --- .../Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index c72f0c5e806d..ffc76e38e95d 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -63,9 +63,9 @@ class MANTID_GEOMETRY_DLL GeometryHandler { nullptr; ///< ObjComponent that uses this geometry handler CSGObject *m_obj = nullptr; ///< Object that uses this geometry handler public: - GeometryHandler(IObjComponent *comp); ///< Constructor + GeometryHandler(IObjComponent *comp); ///< Constructor GeometryHandler(boost::shared_ptr obj); ///< Constructor - GeometryHandler(CSGObject *obj); ///< Constructor + GeometryHandler(CSGObject *obj); ///< Constructor GeometryHandler(RectangularDetector *comp); GeometryHandler(StructuredDetector *comp); GeometryHandler(const GeometryHandler &handler); From ac1c0d8f9bf685df54fff683c98b5964e830ccff Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 27 Feb 2018 12:53:27 +0000 Subject: [PATCH 082/364] fix remaining merge issues #21230 --- .../inc/MantidGeometry/Rendering/GeometryTriangulator.h | 4 ++-- Framework/Geometry/src/Rendering/GeometryHandler.cpp | 2 +- Framework/Geometry/src/Rendering/GeometryTriangulator.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index 91a7ffae1336..be819e4d2cb3 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -9,7 +9,7 @@ class TopoDS_Shape; namespace Mantid { namespace Geometry { -class Object; +class CSGObject; namespace detail { /** GeometryTriangulator : Triangulates object surfaces. May or may not use @@ -47,7 +47,7 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { void checkTriangulated(); public: - GeometryTriangulator(const Object *obj); + GeometryTriangulator(const CSGObject *obj); ~GeometryTriangulator(); void triangulate(); void setGeometryCache(size_t nPoints, size_t nFaces, diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 2f8c96048776..1546337198e1 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -1,6 +1,6 @@ #include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Objects/CSGObject.h" #include "MantidGeometry/Rendering/GeometryTriangulator.h" #include "MantidGeometry/Rendering/Renderer.h" #include diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index 2df4e4da3438..1e9ba44528fb 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -1,5 +1,5 @@ #include "MantidGeometry/Rendering/GeometryTriangulator.h" -#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Objects/CSGObject.h" #include "MantidGeometry/Objects/Rules.h" #include "MantidKernel/Logger.h" #include "MantidKernel/WarningSuppressions.h" @@ -57,7 +57,7 @@ namespace { Kernel::Logger g_log("GeometryTriangulator"); } // namespace -GeometryTriangulator::GeometryTriangulator(const Object *obj) +GeometryTriangulator::GeometryTriangulator(const CSGObject *obj) : m_isTriangulated(false), m_nFaces(0), m_nPoints(0) { m_obj = obj; #ifdef ENABLE_OPENCASCADE From eb6f907f68a43fe9ddc9a66f3f39ebce6cdb5b7a Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 27 Feb 2018 13:16:50 +0000 Subject: [PATCH 083/364] fix CSGObjectTest #21230 --- Framework/Geometry/test/CSGObjectTest.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h index 25006911a20b..5634c0c6a82f 100644 --- a/Framework/Geometry/test/CSGObjectTest.h +++ b/Framework/Geometry/test/CSGObjectTest.h @@ -88,9 +88,9 @@ class CSGObjectTest : public CxxTest::TestSuite { ShapeInfo::GeometryShape objType; double radius(-1.0), height(-1.0); std::vector pts; - auto handler = original->getGeometryHandler(); + auto handler = original.getGeometryHandler(); TS_ASSERT(handler->hasShapeInfo()); - original->GetObjectGeom(objType, pts, radius, height); + original.GetObjectGeom(objType, pts, radius, height); TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType); CSGObject copy(original); @@ -114,9 +114,9 @@ class CSGObjectTest : public CxxTest::TestSuite { ShapeInfo::GeometryShape objType; double radius(-1.0), height(-1.0); std::vector pts; - auto handler = original->getGeometryHandler(); + auto handler = original.getGeometryHandler(); TS_ASSERT(handler->hasShapeInfo()); - original->GetObjectGeom(objType, pts, radius, height); + original.GetObjectGeom(objType, pts, radius, height); TS_ASSERT_EQUALS(ShapeInfo::GeometryShape::SPHERE, objType); CSGObject lhs; // initialize From 695032a6521e3b42656f714cd46b162d33d76e89 Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Wed, 21 Feb 2018 18:17:34 -0500 Subject: [PATCH 084/364] Fix issues from clang-tidy misc-*. --- Framework/API/src/ScriptBuilder.cpp | 3 +-- Framework/Algorithms/src/GeneratePeaks.cpp | 2 +- Framework/Algorithms/src/RemoveBins.cpp | 8 ++++---- Framework/Algorithms/src/SumOverlappingTubes.cpp | 6 ++++-- Framework/Crystal/src/IntegratePeakTimeSlices.cpp | 4 ++-- .../DataHandling/src/FilterEventsByLogValuePreNexus.cpp | 3 --- Framework/DataHandling/src/LoadIDFFromNexus.cpp | 1 - Framework/DataHandling/src/ProcessBankData.cpp | 1 - Framework/DataHandling/src/SaveFullprofResolution.cpp | 9 +++++---- .../Geometry/src/Rendering/vtkGeometryCacheReader.cpp | 1 - .../PythonInterface/mantid/geometry/src/geometry.cpp.in | 2 -- .../mantid/kernel/src/Exports/ConfigObserver.cpp | 1 - .../mantid/kernel/src/Exports/ConfigPropertyObserver.cpp | 1 - Framework/Types/src/Event/TofEvent.cpp | 1 - MantidPlot/src/Mantid/MantidUI.cpp | 1 - 15 files changed, 17 insertions(+), 27 deletions(-) diff --git a/Framework/API/src/ScriptBuilder.cpp b/Framework/API/src/ScriptBuilder.cpp index 79a8c9da3b06..09d704dc60a2 100644 --- a/Framework/API/src/ScriptBuilder.cpp +++ b/Framework/API/src/ScriptBuilder.cpp @@ -159,8 +159,7 @@ ScriptBuilder::buildAlgorithmString(AlgorithmHistory_const_sptr algHistory) { // remove properties that are not present on a fresh algorithm // i.e. remove dynamically added properties for (auto prop_iter = props.begin(); prop_iter != props.end();) { - if (std::find(freshPropNames.begin(), freshPropNames.end(), - (*prop_iter)->name()) == freshPropNames.end()) { + if (freshPropNames.find((*prop_iter)->name()) == freshPropNames.end()) { prop_iter = props.erase(prop_iter); } else { ++prop_iter; diff --git a/Framework/Algorithms/src/GeneratePeaks.cpp b/Framework/Algorithms/src/GeneratePeaks.cpp index 474c3b71b9c1..880d8d42a5ef 100644 --- a/Framework/Algorithms/src/GeneratePeaks.cpp +++ b/Framework/Algorithms/src/GeneratePeaks.cpp @@ -769,11 +769,11 @@ GeneratePeaks::createDataWorkspace(std::vector binparameters) { } Indexing::IndexInfo indices(specNums.size()); - indices.setSpectrumNumbers(std::move(specNums)); // There is no instrument, so the automatic build of a 1:1 mapping would fail. // Need to set empty grouping manually. indices.setSpectrumDefinitions( std::vector(specNums.size())); + indices.setSpectrumNumbers(std::move(specNums)); return create(indices, BinEdges(std::move(xarray))); } diff --git a/Framework/Algorithms/src/RemoveBins.cpp b/Framework/Algorithms/src/RemoveBins.cpp index d6a57216f2a4..3cdeaa1ca488 100644 --- a/Framework/Algorithms/src/RemoveBins.cpp +++ b/Framework/Algorithms/src/RemoveBins.cpp @@ -49,10 +49,10 @@ void RemoveBins::init() { std::vector units = UnitFactory::Instance().getKeys(); // remove some known units that will not work - units.erase(std::remove(units.begin(), units.end(), "Empty")); - units.erase(std::remove(units.begin(), units.end(), "Label")); - units.erase(std::remove(units.begin(), units.end(), "Time")); - units.erase(std::remove(units.begin(), units.end(), "Degrees")); + units.erase(std::remove(units.begin(), units.end(), "Empty"), units.end()); + units.erase(std::remove(units.begin(), units.end(), "Label"), units.end()); + units.erase(std::remove(units.begin(), units.end(), "Time"), units.end()); + units.erase(std::remove(units.begin(), units.end(), "Degrees"), units.end()); // add a default do nothing value units.insert(units.begin(), "AsInput"); diff --git a/Framework/Algorithms/src/SumOverlappingTubes.cpp b/Framework/Algorithms/src/SumOverlappingTubes.cpp index 9f6da909ce7e..375739a4361d 100644 --- a/Framework/Algorithms/src/SumOverlappingTubes.cpp +++ b/Framework/Algorithms/src/SumOverlappingTubes.cpp @@ -21,6 +21,8 @@ #include "MantidKernel/Unit.h" #include "MantidKernel/UnitFactory.h" +#include "boost/math/special_functions/round.hpp" + namespace Mantid { namespace Algorithms { @@ -298,8 +300,8 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) { angle = specInfo.signedTwoTheta(i); angle *= m_mirrorDetectors * 180.0 / M_PI; - int angleIndex = - int((angle - m_startScatteringAngle) / m_stepScatteringAngle + 0.5); + int angleIndex = boost::math::iround((angle - m_startScatteringAngle) / + m_stepScatteringAngle); // point is out of range, a warning should have been generated already for // the theta index diff --git a/Framework/Crystal/src/IntegratePeakTimeSlices.cpp b/Framework/Crystal/src/IntegratePeakTimeSlices.cpp index 9498ee75d2f0..6ecb083a9d3d 100644 --- a/Framework/Crystal/src/IntegratePeakTimeSlices.cpp +++ b/Framework/Crystal/src/IntegratePeakTimeSlices.cpp @@ -598,10 +598,10 @@ void IntegratePeakTimeSlices::exec() { "Mrow is negative."); } - lastRow = static_cast(params[i] + .5); + lastRow = boost::math::iround(params[i]); i = findNameInVector("Mcol", names); if (i >= 0) - lastCol = static_cast(params[i] + .5); + lastCol = boost::math::iround(params[i]); prog.report(); } else if (dir > 0) diff --git a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp index 28512fcfb875..00363ff0ac6b 100644 --- a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp +++ b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp @@ -52,13 +52,10 @@ using namespace API; using namespace DataObjects; using namespace Geometry; using Types::Core::DateAndTime; -using boost::posix_time::ptime; -using boost::posix_time::time_duration; using DataObjects::EventList; using DataObjects::EventWorkspace; using DataObjects::EventWorkspace_sptr; using Types::Event::TofEvent; -using std::cout; using std::ifstream; using std::runtime_error; using std::stringstream; diff --git a/Framework/DataHandling/src/LoadIDFFromNexus.cpp b/Framework/DataHandling/src/LoadIDFFromNexus.cpp index 55d92fbeb0f5..2b8a37211795 100644 --- a/Framework/DataHandling/src/LoadIDFFromNexus.cpp +++ b/Framework/DataHandling/src/LoadIDFFromNexus.cpp @@ -26,7 +26,6 @@ DECLARE_ALGORITHM(LoadIDFFromNexus) using namespace Kernel; using namespace API; -using Geometry::Instrument; using Types::Core::DateAndTime; /// Empty default constructor diff --git a/Framework/DataHandling/src/ProcessBankData.cpp b/Framework/DataHandling/src/ProcessBankData.cpp index 5b93092bf126..99f74298c629 100644 --- a/Framework/DataHandling/src/ProcessBankData.cpp +++ b/Framework/DataHandling/src/ProcessBankData.cpp @@ -3,7 +3,6 @@ #include "MantidDataHandling/ProcessBankData.h" using namespace Mantid::DataObjects; -using Mantid::Types::Event::TofEvent; namespace Mantid { namespace DataHandling { diff --git a/Framework/DataHandling/src/SaveFullprofResolution.cpp b/Framework/DataHandling/src/SaveFullprofResolution.cpp index 0e508d349dcd..550e2701c5c2 100644 --- a/Framework/DataHandling/src/SaveFullprofResolution.cpp +++ b/Framework/DataHandling/src/SaveFullprofResolution.cpp @@ -5,8 +5,9 @@ #include "MantidKernel/ListValidator.h" #include "MantidKernel/BoundedValidator.h" -#include -#include +#include "Poco/File.h" +#include "boost/algorithm/string.hpp" +#include "boost/math/special_functions/round.hpp" #include #include @@ -192,8 +193,8 @@ void SaveFullprofResolution::parseTableWorkspace() { // and BANK matches for (size_t i = 1; i < numcols; ++i) { if (boost::starts_with(colnames[i], "Value")) { - int bankid = static_cast( - m_profileTableWS->cell(rowbankindex, i) + 0.5); + int bankid = boost::math::iround( + m_profileTableWS->cell(rowbankindex, i)); if (bankid == m_bankID) { colindex = static_cast(i); break; diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp index a509c8b577b9..86ff9a92dc65 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp @@ -14,7 +14,6 @@ #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h" using Poco::XML::DOMParser; -using Poco::XML::Document; using Poco::XML::Element; namespace Mantid { diff --git a/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in b/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in index fd9cb6edb933..39e4c8706552 100644 --- a/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in +++ b/Framework/PythonInterface/mantid/geometry/src/geometry.cpp.in @@ -10,8 +10,6 @@ #define PY_ARRAY_UNIQUE_SYMBOL GEOMETRY_ARRAY_API #include -using boost::python::def; - // Forward declare @EXPORT_DECLARE@ diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp index a6808163eb92..8ac77740b694 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigObserver.cpp @@ -7,7 +7,6 @@ using namespace boost::python; using Mantid::Kernel::ConfigObserver; -using Mantid::PythonInterface::Environment::GlobalInterpreterLock; using Mantid::PythonInterface::Environment::callMethod; class ConfigObserverWrapper : public ConfigObserver { diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp index 112c0c3c08b7..4e4c3a1bb6f5 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigPropertyObserver.cpp @@ -7,7 +7,6 @@ using namespace boost::python; using Mantid::Kernel::ConfigPropertyObserver; -using Mantid::PythonInterface::Environment::GlobalInterpreterLock; using Mantid::PythonInterface::Environment::callMethod; class ConfigPropertyObserverWrapper : public ConfigPropertyObserver { diff --git a/Framework/Types/src/Event/TofEvent.cpp b/Framework/Types/src/Event/TofEvent.cpp index ce0ee8e761bc..9e92d192d3a2 100644 --- a/Framework/Types/src/Event/TofEvent.cpp +++ b/Framework/Types/src/Event/TofEvent.cpp @@ -4,7 +4,6 @@ using std::ostream; namespace Mantid { namespace Types { -using Core::DateAndTime; namespace Event { /** Comparison operator. * @param rhs: the other TofEvent to compare. diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index 1d5dfe006447..48bc194af55f 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -104,7 +104,6 @@ using namespace Mantid::API; using namespace MantidQt::API; using namespace MantidQt::MantidWidgets; using MantidQt::MantidWidgets::MantidWSIndexDialog; -using MantidQt::MantidWidgets::MantidTreeWidget; using Mantid::Types::Core::DateAndTime; using Mantid::Types::Core::time_duration; using MantidQt::SliceViewer::SliceViewerWindow; From f5401bfd4659fb04ac2aa5cb60bf61672765730f Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Thu, 22 Feb 2018 14:18:45 -0500 Subject: [PATCH 085/364] iround treats negative numbers differently. --- Framework/Algorithms/src/SumOverlappingTubes.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Framework/Algorithms/src/SumOverlappingTubes.cpp b/Framework/Algorithms/src/SumOverlappingTubes.cpp index 375739a4361d..b0242f3b6388 100644 --- a/Framework/Algorithms/src/SumOverlappingTubes.cpp +++ b/Framework/Algorithms/src/SumOverlappingTubes.cpp @@ -301,7 +301,8 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) { angle *= m_mirrorDetectors * 180.0 / M_PI; int angleIndex = boost::math::iround((angle - m_startScatteringAngle) / - m_stepScatteringAngle); + m_stepScatteringAngle) + + 1; // point is out of range, a warning should have been generated already for // the theta index From ff4f4252293d9ca4eec3e6b2fc7b50830353eb5b Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Thu, 22 Feb 2018 14:59:30 -0500 Subject: [PATCH 086/364] fix misc-throw-by-value-catch-by-reference. --- Framework/Algorithms/src/CompareWorkspaces.cpp | 2 +- Framework/Algorithms/src/ConjoinXRuns.cpp | 2 +- .../src/MonitorEfficiencyCorUser.cpp | 2 +- Framework/DataHandling/src/SaveAscii2.cpp | 2 +- .../src/Kafka/KafkaEventStreamDecoder.cpp | 2 +- MantidPlot/src/muParserScript.cpp | 18 +++++++++--------- .../Filters/SplatterPlot/vtkSplatterPlot.cxx | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Framework/Algorithms/src/CompareWorkspaces.cpp b/Framework/Algorithms/src/CompareWorkspaces.cpp index 5724a852f34b..5f3bf5634af9 100644 --- a/Framework/Algorithms/src/CompareWorkspaces.cpp +++ b/Framework/Algorithms/src/CompareWorkspaces.cpp @@ -383,7 +383,7 @@ bool CompareWorkspaces::compareEventWorkspaces( ews2.sortAll(PULSETIMETOF_SORT, m_progress.get()); if (!m_progress) { - throw new std::runtime_error("The progress pointer was found to be null!"); + throw std::runtime_error("The progress pointer was found to be null!"); } // Determine the tolerance for "tof" attribute and "weight" of events diff --git a/Framework/Algorithms/src/ConjoinXRuns.cpp b/Framework/Algorithms/src/ConjoinXRuns.cpp index 2fea96c2810f..a19028d9bc86 100644 --- a/Framework/Algorithms/src/ConjoinXRuns.cpp +++ b/Framework/Algorithms/src/ConjoinXRuns.cpp @@ -122,7 +122,7 @@ std::map ConjoinXRuns::validateInputs() { } else { try { ws->blocksize(); - } catch (std::length_error) { + } catch (std::length_error &) { issues[INPUT_WORKSPACE_PROPERTY] += "Workspace " + ws->getName() + " has different number of points per histogram\n"; diff --git a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp index 744a0f5aed4c..11eba34270c9 100644 --- a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp +++ b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp @@ -51,7 +51,7 @@ void MonitorEfficiencyCorUser::exec() { // file try { mon_counts_log = getValFromInstrumentDef("monitor_counts_log"); - } catch (Kernel::Exception::InstrumentDefinitionError) { + } catch (Kernel::Exception::InstrumentDefinitionError &) { // the default value is monitor_counts mon_counts_log = "monitor_counts"; } diff --git a/Framework/DataHandling/src/SaveAscii2.cpp b/Framework/DataHandling/src/SaveAscii2.cpp index 55a10b34c34d..f254010925e0 100644 --- a/Framework/DataHandling/src/SaveAscii2.cpp +++ b/Framework/DataHandling/src/SaveAscii2.cpp @@ -357,7 +357,7 @@ void SaveAscii2::populateQMetaData() { boost::shared_ptr detector( &spectrumInfo.detector(i), NoDeleting()); efixed = m_ws->getEFixed(detector); - } catch (std::runtime_error) { + } catch (std::runtime_error &) { throw; } } else { diff --git a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp index 5d4de83d092a..6c79894cfd31 100644 --- a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp +++ b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp @@ -183,7 +183,7 @@ bool KafkaEventStreamDecoder::hasReachedEndOfRun() noexcept { */ API::Workspace_sptr KafkaEventStreamDecoder::extractData() { if (m_exception) { - throw * m_exception; + throw std::runtime_error(*m_exception); } m_extractWaiting = true; diff --git a/MantidPlot/src/muParserScript.cpp b/MantidPlot/src/muParserScript.cpp index 93fc202f0907..749d5ad209e6 100644 --- a/MantidPlot/src/muParserScript.cpp +++ b/MantidPlot/src/muParserScript.cpp @@ -149,7 +149,7 @@ double muParserScript::col(const QString &arg) { .toAscii() .constData()); if (table->text(row, col).isEmpty()) - throw new EmptySourceError(); + throw EmptySourceError(); else { return table->cell(row, col); } @@ -231,7 +231,7 @@ double muParserScript::tablecol(const QString &arg) { .toAscii() .constData()); if (target_table->text(row, col).isEmpty()) - throw new EmptySourceError(); + throw EmptySourceError(); else return target_table->cell(row, col); } @@ -254,7 +254,7 @@ double muParserScript::cell(int row, int col) { .toAscii() .constData()); if (matrix->text(row - 1, col - 1).isEmpty()) - throw new EmptySourceError(); + throw EmptySourceError(); else return matrix->cell(row - 1, col - 1); } @@ -277,7 +277,7 @@ double muParserScript::tableCell(int col, int row) { .toAscii() .constData()); if (table->text(row - 1, col - 1).isEmpty()) - throw new EmptySourceError(); + throw EmptySourceError(); else return table->cell(row - 1, col - 1); } @@ -394,7 +394,7 @@ QString muParserScript::evalSingleLineToString(const QLocale &locale, char f, double val = 0.0; try { val = parser.Eval(); - } catch (EmptySourceError *) { + } catch (EmptySourceError &) { return ""; } catch (ParserError &) { return ""; @@ -406,7 +406,7 @@ double muParserScript::evalSingleLine() { double val = 0.0; try { val = parser.Eval(); - } catch (EmptySourceError *) { + } catch (EmptySourceError &) { return GSL_NAN; } catch (ParserError &) { return GSL_NAN; @@ -467,7 +467,7 @@ bool muParserScript::compileImpl() { parser.SetExpr(muCode[0].toAscii().constData()); try { parser.Eval(); - } catch (EmptySourceError *) { + } catch (EmptySourceError &) { QApplication::restoreOverrideCursor(); return false; } catch (mu::ParserError &e) { @@ -492,7 +492,7 @@ QVariant muParserScript::evaluateImpl() { parser.SetExpr(i->toAscii().constData()); val = parser.Eval(); } - } catch (EmptySourceError *) { + } catch (EmptySourceError &) { return QVariant(""); } catch (ParserError &e) { emit error(e.GetMsg().c_str(), "", 0); @@ -510,7 +510,7 @@ bool muParserScript::executeImpl() { parser.SetExpr(i->toAscii().constData()); parser.Eval(); } - } catch (EmptySourceError *) { + } catch (EmptySourceError &) { return true; } catch (mu::ParserError &e) { emit error(e.GetMsg().c_str(), "", 0); diff --git a/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx b/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx index b1d299bcd5dc..0df416020400 100644 --- a/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx +++ b/qt/paraview_ext/PVPlugins/Filters/SplatterPlot/vtkSplatterPlot.cxx @@ -152,7 +152,7 @@ int vtkSplatterPlot::RequestInformation(vtkInformation *, ADSWorkspaceProvider workspaceProvider; Workspace_sptr result = workspaceProvider.fetchWorkspace(m_wsName); m_presenter->initialize(result); - } catch (const std::runtime_error) { + } catch (const std::runtime_error &) { // Catch incase something goes wrong. It might be that the splatter // plot source is not yet setup correctly and we'll need to run this // call again later. From 57b74caa73c31acfbcd434e198ec66782aa599eb Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Thu, 22 Feb 2018 18:01:49 -0500 Subject: [PATCH 087/364] clang-tidy. --- Framework/API/src/SpectraAxisValidator.cpp | 2 +- Framework/Crystal/src/SaveLauenorm.cpp | 27 ++++++++++--------- .../src/GetSpiceDataRawCountsFromMD.cpp | 2 +- .../mantid/api/src/CloneMatrixWorkspace.cpp | 1 - .../api/src/Exports/AlgorithmHistory.cpp | 2 -- .../mantid/api/src/Exports/Axis.cpp | 1 - .../mantid/api/src/Exports/IEventList.cpp | 1 - MantidPlot/CMakeLists.txt | 1 + qt/paraview_ext/CMakeLists.txt | 1 + 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Framework/API/src/SpectraAxisValidator.cpp b/Framework/API/src/SpectraAxisValidator.cpp index f37f5ebbe8c9..8a5643a92f00 100644 --- a/Framework/API/src/SpectraAxisValidator.cpp +++ b/Framework/API/src/SpectraAxisValidator.cpp @@ -25,7 +25,7 @@ SpectraAxisValidator::checkValidity(const MatrixWorkspace_sptr &value) const { Mantid::API::Axis *axis; try { axis = value->getAxis(m_axisNumber); - } catch (Kernel::Exception::IndexError) { + } catch (Kernel::Exception::IndexError &) { return "No axis at index " + std::to_string(m_axisNumber) + " available in the workspace"; } diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp index 5d097aa0aff0..587c503d3825 100644 --- a/Framework/Crystal/src/SaveLauenorm.cpp +++ b/Framework/Crystal/src/SaveLauenorm.cpp @@ -10,6 +10,9 @@ #include "MantidKernel/Strings.h" #include "MantidAPI/Sample.h" #include "MantidGeometry/Instrument/Goniometer.h" + +#include "boost/math/special_functions/round.hpp" + #include #include #include @@ -312,9 +315,9 @@ void SaveLauenorm::exec() { << 1.0 / lattice.a() << std::setw(12) << std::setprecision(4) << 1.0 / lattice.b() << std::setw(12) << std::setprecision(4) << 1.0 / lattice.c() << std::setw(9) - << static_cast(lattice.alpha() + 0.5) << std::setw(9) - << static_cast(lattice.beta() + 0.5) << std::setw(9) - << static_cast(lattice.gamma() + 0.5) << "\n"; + << boost::math::iround(lattice.alpha()) << std::setw(9) + << boost::math::iround(lattice.beta()) << std::setw(9) + << boost::math::iround(lattice.gamma()) << '\n'; std::vector systemNo = crystalSystem(lattice, peaks); out << "SYST " << systemNo[0] << " " << systemNo[1] << " 0 0" << "\n"; @@ -509,12 +512,12 @@ void SaveLauenorm::sizeBanks(std::string bankName, int &nCols, int &nRows) { std::vector SaveLauenorm::crystalSystem(OrientedLattice lattice, std::vector peaks) { std::vector systemVec; - int alpha = static_cast(lattice.alpha() + 0.5); - int beta = static_cast(lattice.beta() + 0.5); - int gamma = static_cast(lattice.gamma() + 0.5); - int a = static_cast(lattice.a() * 1000 + 0.5); - int b = static_cast(lattice.b() * 1000 + 0.5); - int c = static_cast(lattice.c() * 1000 + 0.5); + int alpha = boost::math::iround(lattice.alpha()); + int beta = boost::math::iround(lattice.beta()); + int gamma = boost::math::iround(lattice.gamma()); + int a = boost::math::iround(lattice.a() * 1000); + int b = boost::math::iround(lattice.b() * 1000); + int c = boost::math::iround(lattice.c() * 1000); if (alpha == 90 && beta == 90 && gamma == 90) { if (a == b && a == c) { systemVec.push_back(7); // cubic I,F @@ -542,9 +545,9 @@ std::vector SaveLauenorm::crystalSystem(OrientedLattice lattice, int r = 0; int total = 0; for (size_t j = 0; j < peaks.size(); j++) { - int h = static_cast(peaks[j].getH() + 0.5); - int k = static_cast(peaks[j].getK() + 0.5); - int l = static_cast(peaks[j].getL() + 0.5); + int h = boost::math::iround(peaks[j].getH()); + int k = boost::math::iround(peaks[j].getK()); + int l = boost::math::iround(peaks[j].getL()); if (h + k + l == 0) continue; total++; diff --git a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp index 6e71b65b7890..0446997a822a 100644 --- a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp +++ b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp @@ -502,7 +502,7 @@ MatrixWorkspace_sptr GetSpiceDataRawCountsFromMD::createOutputWorkspace( throw std::runtime_error("Failed to create output matrix workspace."); // Set data - outws->setHistogram(0, Points(std::move(vecX)), Counts(std::move(vecY))); + outws->setHistogram(0, Points(vecX), Counts(vecY)); auto &dataE = outws->mutableE(0); std::replace_if(dataE.begin(), dataE.end(), [](double val) { return val < 1.0; }, 1.0); diff --git a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp index 804ec003fdf9..85e353ecf5b1 100644 --- a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp @@ -16,7 +16,6 @@ namespace Mantid { namespace PythonInterface { using Mantid::API::MatrixWorkspace_sptr; using Mantid::API::MatrixWorkspace; -namespace bpl = boost::python; // ---------------------------------------------------------------------------------------------------------- namespace { diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp index 28de6020d119..3e98413955b2 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmHistory.cpp @@ -14,8 +14,6 @@ using Mantid::API::AlgorithmHistory; using namespace boost::python; -namespace Policies = Mantid::PythonInterface::Policies; - /** * Return a Python list of child history objects from the history as this is * far easier to work with than a set diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp index def782865742..c5374df149d5 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Axis.cpp @@ -27,7 +27,6 @@ using namespace boost::python; GET_POINTER_SPECIALIZATION(Axis) namespace { -namespace bpl = boost::python; //------------------------------- Overload macros --------------------------- #ifdef __clang__ diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp index f9524b3cce55..3136392fd27c 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp @@ -13,7 +13,6 @@ using Mantid::API::WEIGHTED; using Mantid::API::WEIGHTED_NOTIME; namespace Policies = Mantid::PythonInterface::Policies; -namespace Converters = Mantid::PythonInterface::Converters; using namespace boost::python; GET_POINTER_SPECIALIZATION(IEventList) diff --git a/MantidPlot/CMakeLists.txt b/MantidPlot/CMakeLists.txt index 14147fcf7c18..d61f28d1ad68 100644 --- a/MantidPlot/CMakeLists.txt +++ b/MantidPlot/CMakeLists.txt @@ -834,6 +834,7 @@ elseif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) endif() endif () +set_target_properties( MantidPlot PROPERTIES CXX_CLANG_TIDY "" ) set_target_properties ( MantidPlot PROPERTIES FOLDER "Qt4" ) ########################################################################### diff --git a/qt/paraview_ext/CMakeLists.txt b/qt/paraview_ext/CMakeLists.txt index 28cc66cd2948..14ffc8679e74 100644 --- a/qt/paraview_ext/CMakeLists.txt +++ b/qt/paraview_ext/CMakeLists.txt @@ -24,6 +24,7 @@ if( ParaView_FOUND AND USE_PARAVIEW ) RUNTIME_OUTPUT_DIRECTORY ${PVPLUGINS_LIBRARY_OUTPUT_DIRECTORY}/qt${vers} FOLDER "MantidVatesParaViewPlugins" ) + set_target_properties( ${_target} PROPERTIES CXX_CLANG_TIDY "" ) endfunction() function (install_pvplugin target QT_VERSION vers) From 5f00b08c690aa4cc18d3f439d4d65b5a1591ca53 Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Fri, 23 Feb 2018 11:37:38 -0500 Subject: [PATCH 088/364] avoid failing tests. --- Framework/Algorithms/src/SumOverlappingTubes.cpp | 7 ++----- Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h | 2 +- Framework/Crystal/src/SaveLauenorm.cpp | 10 +++++----- Framework/TestHelpers/src/FileComparisonHelper.cpp | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Framework/Algorithms/src/SumOverlappingTubes.cpp b/Framework/Algorithms/src/SumOverlappingTubes.cpp index b0242f3b6388..9f6da909ce7e 100644 --- a/Framework/Algorithms/src/SumOverlappingTubes.cpp +++ b/Framework/Algorithms/src/SumOverlappingTubes.cpp @@ -21,8 +21,6 @@ #include "MantidKernel/Unit.h" #include "MantidKernel/UnitFactory.h" -#include "boost/math/special_functions/round.hpp" - namespace Mantid { namespace Algorithms { @@ -300,9 +298,8 @@ SumOverlappingTubes::performBinning(MatrixWorkspace_sptr &outputWS) { angle = specInfo.signedTwoTheta(i); angle *= m_mirrorDetectors * 180.0 / M_PI; - int angleIndex = boost::math::iround((angle - m_startScatteringAngle) / - m_stepScatteringAngle) + - 1; + int angleIndex = + int((angle - m_startScatteringAngle) / m_stepScatteringAngle + 0.5); // point is out of range, a warning should have been generated already for // the theta index diff --git a/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h b/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h index 81dc93b6f481..6c65eca2495c 100644 --- a/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h +++ b/Framework/Crystal/inc/MantidCrystal/SaveLauenorm.h @@ -41,7 +41,7 @@ class DLLExport SaveLauenorm : public API::Algorithm { DataObjects::PeaksWorkspace_sptr ws; void sizeBanks(std::string bankName, int &nCols, int &nRows); std::vector crystalSystem(Geometry::OrientedLattice lattice, - std::vector peaks); + const std::vector &peaks); }; } // namespace Mantid diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp index 587c503d3825..61a0c36ce91e 100644 --- a/Framework/Crystal/src/SaveLauenorm.cpp +++ b/Framework/Crystal/src/SaveLauenorm.cpp @@ -510,7 +510,7 @@ void SaveLauenorm::sizeBanks(std::string bankName, int &nCols, int &nRows) { } } std::vector SaveLauenorm::crystalSystem(OrientedLattice lattice, - std::vector peaks) { + const std::vector &peaks) { std::vector systemVec; int alpha = boost::math::iround(lattice.alpha()); int beta = boost::math::iround(lattice.beta()); @@ -544,10 +544,10 @@ std::vector SaveLauenorm::crystalSystem(OrientedLattice lattice, int ac = 0; int r = 0; int total = 0; - for (size_t j = 0; j < peaks.size(); j++) { - int h = boost::math::iround(peaks[j].getH()); - int k = boost::math::iround(peaks[j].getK()); - int l = boost::math::iround(peaks[j].getL()); + for (const auto & peak: peaks) { + int h = boost::math::iround(peak.getH()); + int k = boost::math::iround(peak.getK()); + int l = boost::math::iround(peak.getL()); if (h + k + l == 0) continue; total++; diff --git a/Framework/TestHelpers/src/FileComparisonHelper.cpp b/Framework/TestHelpers/src/FileComparisonHelper.cpp index 95e86c89afdf..9f02a89716f9 100644 --- a/Framework/TestHelpers/src/FileComparisonHelper.cpp +++ b/Framework/TestHelpers/src/FileComparisonHelper.cpp @@ -59,7 +59,7 @@ void logDifferenceError(char refChar, char testChar, size_t numNewLines, ((outError += "\nTest output:\n") += seenChars) += testChar; Mantid::Kernel::Logger g_log("FileComparisonHelper"); - g_log.error(std::move(outError)); + g_log.error(outError); } } // End of anonymous namespace From 4bc36d5b4f50faa29628d5d65c94c568d47dc26d Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Fri, 23 Feb 2018 11:53:25 -0500 Subject: [PATCH 089/364] clang-tidy --- Framework/Crystal/src/SaveLauenorm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp index 61a0c36ce91e..61855c04c7a1 100644 --- a/Framework/Crystal/src/SaveLauenorm.cpp +++ b/Framework/Crystal/src/SaveLauenorm.cpp @@ -544,7 +544,7 @@ std::vector SaveLauenorm::crystalSystem(OrientedLattice lattice, int ac = 0; int r = 0; int total = 0; - for (const auto & peak: peaks) { + for (const auto &peak : peaks) { int h = boost::math::iround(peak.getH()); int k = boost::math::iround(peak.getK()); int l = boost::math::iround(peak.getL()); From 1d7a8b11659d7e1c5688307fa22f988a252b2d31 Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Fri, 23 Feb 2018 15:33:41 -0500 Subject: [PATCH 090/364] more minor fixes. --- Framework/Indexing/inc/MantidIndexing/IndexInfo.h | 4 ++-- Framework/Indexing/src/IndexInfo.cpp | 4 ++-- Framework/Kernel/inc/MantidKernel/LibraryWrapper.h | 4 ++-- Framework/Kernel/src/LibraryWrapper.cpp | 6 ++++-- .../mantid/dataobjects/src/Exports/Workspace2D.cpp | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Framework/Indexing/inc/MantidIndexing/IndexInfo.h b/Framework/Indexing/inc/MantidIndexing/IndexInfo.h index 73db808d8e30..f7b492201433 100644 --- a/Framework/Indexing/inc/MantidIndexing/IndexInfo.h +++ b/Framework/Indexing/inc/MantidIndexing/IndexInfo.h @@ -87,10 +87,10 @@ class MANTID_INDEXING_DLL IndexInfo { IndexInfo(std::vector indices, const IndexInfo &parent); IndexInfo(const IndexInfo &other); - IndexInfo(IndexInfo &&other); + IndexInfo(IndexInfo &&other) noexcept; ~IndexInfo(); IndexInfo &operator=(const IndexInfo &other); - IndexInfo &operator=(IndexInfo &&other); + IndexInfo &operator=(IndexInfo &&other) noexcept; size_t size() const; size_t globalSize() const; diff --git a/Framework/Indexing/src/IndexInfo.cpp b/Framework/Indexing/src/IndexInfo.cpp index f226f2136efb..ab3a15e754db 100644 --- a/Framework/Indexing/src/IndexInfo.cpp +++ b/Framework/Indexing/src/IndexInfo.cpp @@ -83,7 +83,7 @@ IndexInfo::IndexInfo(const IndexInfo &other) m_spectrumDefinitions(other.m_spectrumDefinitions), m_spectrumNumberTranslator(other.m_spectrumNumberTranslator) {} -IndexInfo::IndexInfo(IndexInfo &&) = default; +IndexInfo::IndexInfo(IndexInfo &&) noexcept = default; // Defined as default in source for forward declaration with std::unique_ptr. IndexInfo::~IndexInfo() = default; @@ -93,7 +93,7 @@ IndexInfo &IndexInfo::operator=(const IndexInfo &other) { return *this = std::move(copy); } -IndexInfo &IndexInfo::operator=(IndexInfo &&) = default; +IndexInfo &IndexInfo::operator=(IndexInfo &&) noexcept = default; /// The *local* size, i.e., the number of spectra in this partition. size_t IndexInfo::size() const { diff --git a/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h b/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h index 3bfa68cac7f5..17e3ac4ca477 100644 --- a/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h +++ b/Framework/Kernel/inc/MantidKernel/LibraryWrapper.h @@ -45,8 +45,8 @@ class MANTID_KERNEL_DLL LibraryWrapper { LibraryWrapper(const LibraryWrapper &) = delete; LibraryWrapper &operator=(const LibraryWrapper &) = delete; - LibraryWrapper(LibraryWrapper &&src); - LibraryWrapper &operator=(LibraryWrapper &&rhs); + LibraryWrapper(LibraryWrapper &&src) noexcept; + LibraryWrapper &operator=(LibraryWrapper &&rhs) noexcept; ~LibraryWrapper(); bool openLibrary(const std::string &filepath); diff --git a/Framework/Kernel/src/LibraryWrapper.cpp b/Framework/Kernel/src/LibraryWrapper.cpp index 1dca81052b29..753423937df6 100644 --- a/Framework/Kernel/src/LibraryWrapper.cpp +++ b/Framework/Kernel/src/LibraryWrapper.cpp @@ -8,13 +8,15 @@ namespace Kernel { * Move constructor * @param src Constructor from this temporary */ -LibraryWrapper::LibraryWrapper(LibraryWrapper &&src) { *this = std::move(src); } +LibraryWrapper::LibraryWrapper(LibraryWrapper &&src) noexcept { + *this = std::move(src); +} /** * Move assignment * @param rhs Temporary object as source of assignment */ -LibraryWrapper &LibraryWrapper::operator=(LibraryWrapper &&rhs) { +LibraryWrapper &LibraryWrapper::operator=(LibraryWrapper &&rhs) noexcept { using std::swap; swap(m_module, rhs.m_module); return *this; diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp index a6dabca2af6c..ec12497997cf 100644 --- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp +++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp @@ -138,7 +138,7 @@ class Workspace2DPickleSuite : public boost::python::pickle_suite { specDef.add(detectorIndex); } spectrumDefinitions.emplace_back(std::move(specDef)); - spectrumNumbers.emplace_back(std::move(specNum)); + spectrumNumbers.emplace_back(specNum); } std::string instrumentXML = extract(state["instrument_xml"]); From c4312814e1f9cb70d27c69361c31745bd641dd9c Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Fri, 2 Mar 2018 15:04:33 -0500 Subject: [PATCH 091/364] Remove until we figure out how to separate moc_* and other files. --- MantidPlot/CMakeLists.txt | 1 - qt/paraview_ext/CMakeLists.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/MantidPlot/CMakeLists.txt b/MantidPlot/CMakeLists.txt index d61f28d1ad68..14147fcf7c18 100644 --- a/MantidPlot/CMakeLists.txt +++ b/MantidPlot/CMakeLists.txt @@ -834,7 +834,6 @@ elseif ( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) endif() endif () -set_target_properties( MantidPlot PROPERTIES CXX_CLANG_TIDY "" ) set_target_properties ( MantidPlot PROPERTIES FOLDER "Qt4" ) ########################################################################### diff --git a/qt/paraview_ext/CMakeLists.txt b/qt/paraview_ext/CMakeLists.txt index 14ffc8679e74..28cc66cd2948 100644 --- a/qt/paraview_ext/CMakeLists.txt +++ b/qt/paraview_ext/CMakeLists.txt @@ -24,7 +24,6 @@ if( ParaView_FOUND AND USE_PARAVIEW ) RUNTIME_OUTPUT_DIRECTORY ${PVPLUGINS_LIBRARY_OUTPUT_DIRECTORY}/qt${vers} FOLDER "MantidVatesParaViewPlugins" ) - set_target_properties( ${_target} PROPERTIES CXX_CLANG_TIDY "" ) endfunction() function (install_pvplugin target QT_VERSION vers) From 243832cf3bd6fd6ef411d6fae5f3e36338ff2523 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 6 Mar 2018 09:39:41 +0000 Subject: [PATCH 092/364] review changes #21230 --- .../inc/MantidGeometry/Objects/CSGObject.h | 2 +- .../Rendering/GeometryHandler.h | 7 ++-- .../Rendering/GeometryTriangulator.h | 14 ++++---- .../inc/MantidGeometry/Rendering/ShapeInfo.h | 5 ++- .../Rendering/vtkGeometryCacheReader.h | 2 +- Framework/Geometry/src/Objects/CSGObject.cpp | 4 +-- .../src/Rendering/GeometryHandler.cpp | 34 ++++++++----------- .../src/Rendering/GeometryTriangulator.cpp | 17 ++++++---- Framework/Geometry/src/Rendering/Renderer.cpp | 5 ++- .../src/Rendering/vtkGeometryCacheReader.cpp | 4 +-- .../src/Rendering/vtkGeometryCacheWriter.cpp | 4 +-- 11 files changed, 49 insertions(+), 49 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index 445d17a85219..2c837feb9414 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -261,7 +261,7 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { size_t numberOfTriangles() const; size_t numberOfVertices() const; /// for solid angle from triangulation - const std::vector &getTriangleFaces() const; + const std::vector &getTriangleFaces() const; const std::vector &getTriangleVertices() const; /// original shape xml used to generate this object. std::string m_shapeXML; diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index ffc76e38e95d..f6bea300c0b2 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -14,10 +14,8 @@ namespace Mantid { namespace Geometry { class IObjComponent; -class ObjComponent; class CSGObject; namespace detail { -class Renderer; class GeometryTriangulator; } @@ -54,7 +52,6 @@ class MANTID_GEOMETRY_DLL GeometryHandler { static Kernel::Logger &PLog; ///< The official logger protected: - std::unique_ptr m_renderer; std::shared_ptr m_shapeInfo; std::unique_ptr m_triangulator; RectangularDetector *m_rectDet = nullptr; @@ -85,10 +82,10 @@ class MANTID_GEOMETRY_DLL GeometryHandler { /// Extract the vertices of the triangles const std::vector &getTriangleVertices() const; /// Extract the Faces of the triangles - const std::vector &getTriangleFaces() const; + const std::vector &getTriangleFaces() const; /// Sets the geometry cache using the triangulation information provided void setGeometryCache(size_t nPts, size_t nFaces, std::vector &&pts, - std::vector &&faces); + std::vector &&faces); /// return the actual type and points of one of the "standard" objects, /// cuboid/cone/cyl/sphere void GetObjectGeom(detail::ShapeInfo::GeometryShape &mytype, diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index be819e4d2cb3..938dbe13e351 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -2,7 +2,7 @@ #define MANTID_GEOMETRY_SURFACETRIANGULATOR_H_ #include "MantidGeometry/DllConfig.h" -#include +#include #include class TopoDS_Shape; @@ -42,7 +42,7 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { size_t m_nFaces; size_t m_nPoints; std::vector m_points; ///< double array or points - std::vector m_faces; ///< Integer array of faces + std::vector m_faces; ///< Integer array of faces const CSGObject *m_obj; ///< Input Object void checkTriangulated(); @@ -51,7 +51,8 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { ~GeometryTriangulator(); void triangulate(); void setGeometryCache(size_t nPoints, size_t nFaces, - std::vector &&points, std::vector &&faces); + std::vector &&points, + std::vector &&faces); /// Return the number of triangle faces size_t numTriangleFaces(); /// Return the number of triangle vertices @@ -61,10 +62,10 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { const std::vector &getTriangleVertices(); /// get a pointer to the 3x(NumberOFaces) integers describing points forming /// faces (p1,p2,p3)(p4,p5,p6). - const std::vector &getTriangleFaces(); + const std::vector &getTriangleFaces(); #ifdef ENABLE_OPENCASCADE private: - boost::shared_ptr + std::unique_ptr m_objSurface; ///< Storage for the output surface /// Analyze the object /// OpenCascade analysis of object surface @@ -76,7 +77,8 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { public: /// Return OpenCascade surface. - boost::shared_ptr getOCSurface(); + bool hasOCSurface() const; + const TopoDS_Shape &getOCSurface(); #endif }; } // namespace detail diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h index 1a630e1bfecb..a4d0ea6e3221 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/ShapeInfo.h @@ -13,7 +13,10 @@ class RectangularDetector; class StructuredDetector; class IObjComponent; -/** ShapeInfo : Stored Object related shape information for rendering. +/** ShapeInfo : Stores shape types and information relevant to drawing the +shape. For cylinders, spheres and cones, height and radius are stored. Points +are stored in the winding order shown in the IDF here +http://docs.mantidproject.org/nightly/concepts/HowToDefineGeometricShape.html. Copyright © 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h b/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h index 1240b5d2f5ec..0c3a58e15cf9 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h @@ -56,7 +56,7 @@ class MANTID_GEOMETRY_DLL vtkGeometryCacheReader { void readPoints(Poco::XML::Element *pEle, int noOfPoints, std::vector &points); void readTriangles(Poco::XML::Element *pEle, int noOfTriangles, - std::vector &faces); + std::vector &faces); public: vtkGeometryCacheReader(std::string filename); diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index 678522c11498..32433b9b8d04 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -2147,8 +2147,8 @@ const std::vector &CSGObject::getTriangleVertices() const { /** * get faces */ -const std::vector &CSGObject::getTriangleFaces() const { - static const std::vector empty; +const std::vector &CSGObject::getTriangleFaces() const { + static const std::vector empty; if (m_handler == nullptr) return empty; return m_handler->getTriangleFaces(); diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 1546337198e1..483344f70089 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -7,26 +7,21 @@ namespace Mantid { namespace Geometry { -GeometryHandler::GeometryHandler(IObjComponent *comp) - : m_renderer(new detail::Renderer()), m_objComp(comp) {} +GeometryHandler::GeometryHandler(IObjComponent *comp) : m_objComp(comp) {} GeometryHandler::GeometryHandler(boost::shared_ptr obj) - : m_renderer(new detail::Renderer()), - m_triangulator(new detail::GeometryTriangulator(obj.get())), + : m_triangulator(new detail::GeometryTriangulator(obj.get())), m_obj(obj.get()) {} GeometryHandler::GeometryHandler(CSGObject *obj) - : m_renderer(new detail::Renderer()), - m_triangulator(new detail::GeometryTriangulator(obj)), m_obj(obj) {} + : m_triangulator(new detail::GeometryTriangulator(obj)), m_obj(obj) {} -GeometryHandler::GeometryHandler(RectangularDetector *comp) - : m_renderer(new detail::Renderer()), m_rectDet(comp) {} +GeometryHandler::GeometryHandler(RectangularDetector *comp) : m_rectDet(comp) {} GeometryHandler::GeometryHandler(StructuredDetector *comp) - : m_renderer(new detail::Renderer()), m_structDet(comp) {} + : m_structDet(comp) {} -GeometryHandler::GeometryHandler(const GeometryHandler &handler) - : m_renderer(new detail::Renderer()) { +GeometryHandler::GeometryHandler(const GeometryHandler &handler) { if (handler.m_obj) { m_obj = handler.m_obj; if (handler.m_triangulator) @@ -49,16 +44,17 @@ boost::shared_ptr GeometryHandler::clone() const { GeometryHandler::~GeometryHandler() {} void GeometryHandler::render() const { + detail::Renderer renderer; if (m_rectDet) - m_renderer->renderBitmap(*m_rectDet); + renderer.renderBitmap(*m_rectDet); else if (m_structDet) - m_renderer->renderStructured(*m_structDet); + renderer.renderStructured(*m_structDet); else if (m_shapeInfo) - m_renderer->renderShape(*m_shapeInfo); + renderer.renderShape(*m_shapeInfo); else if (m_objComp != nullptr) - m_renderer->renderIObjComponent(*m_objComp); + renderer.renderIObjComponent(*m_objComp); else if (canTriangulate()) - m_renderer->renderTriangulated(*m_triangulator); + renderer.renderTriangulated(*m_triangulator); } void GeometryHandler::initialize() const { @@ -86,8 +82,8 @@ const std::vector &GeometryHandler::getTriangleVertices() const { return empty; } -const std::vector &GeometryHandler::getTriangleFaces() const { - static std::vector empty; +const std::vector &GeometryHandler::getTriangleFaces() const { + static std::vector empty; if (canTriangulate()) return m_triangulator->getTriangleFaces(); return empty; @@ -95,7 +91,7 @@ const std::vector &GeometryHandler::getTriangleFaces() const { void GeometryHandler::setGeometryCache(size_t nPts, size_t nFaces, std::vector &&pts, - std::vector &&faces) { + std::vector &&faces) { if (canTriangulate()) { m_triangulator->setGeometryCache(nPts, nFaces, std::move(pts), std::move(faces)); diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index 1e9ba44528fb..a1c9a24ad4b9 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -76,10 +76,13 @@ void GeometryTriangulator::triangulate() { } #ifdef ENABLE_OPENCASCADE +bool GeometryTriangulator::hasOCSurface() const { + return m_objSurface != nullptr; +} /// Return OpenCascade surface. -boost::shared_ptr GeometryTriangulator::getOCSurface() { +const TopoDS_Shape &GeometryTriangulator::getOCSurface() { checkTriangulated(); - return m_objSurface; + return *m_objSurface; } #endif @@ -108,7 +111,7 @@ const std::vector &GeometryTriangulator::getTriangleVertices() { } /// get a pointer to the 3x(NumberOFaces) integers describing points forming /// faces (p1,p2,p3)(p4,p5,p6). -const std::vector &GeometryTriangulator::getTriangleFaces() { +const std::vector &GeometryTriangulator::getTriangleFaces() { checkTriangulated(); return m_faces; } @@ -208,9 +211,9 @@ void GeometryTriangulator::setupFaces() { Poly_Triangle trian = tri.Value(i); Standard_Integer index1, index2, index3; trian.Get(index1, index2, index3); - m_faces[index * 3 + 0] = maxindex + index1 - 1; - m_faces[index * 3 + 1] = maxindex + index2 - 1; - m_faces[index * 3 + 2] = maxindex + index3 - 1; + m_faces[index * 3 + 0] = static_cast(maxindex + index1 - 1); + m_faces[index * 3 + 1] = static_cast(maxindex + index2 - 1); + m_faces[index * 3 + 2] = static_cast(maxindex + index3 - 1); index++; } maxindex += facing->NbNodes(); @@ -221,7 +224,7 @@ void GeometryTriangulator::setupFaces() { void GeometryTriangulator::setGeometryCache(size_t nPoints, size_t nFaces, std::vector &&points, - std::vector &&faces) { + std::vector &&faces) { m_nPoints = nPoints; m_nFaces = nFaces; m_points = std::move(points); diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/Renderer.cpp index 2d023c4083fd..e18de7c423fe 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/Renderer.cpp @@ -63,9 +63,8 @@ void Renderer::renderIObjComponent(const IObjComponent &objComp, void Renderer::renderTriangulated(detail::GeometryTriangulator &triangulator, RenderMode mode) const { #ifdef ENABLE_OPENCASCADE - auto surface = triangulator.getOCSurface(); - if (surface && !surface->IsNull()) - render(mode, *surface); + if (triangulator.hasOCSurface() && !triangulator.getOCSurface().IsNull()) + render(mode, triangulator.getOCSurface()); else render(mode, triangulator); #else diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp index 9db17f667543..f18497af38dd 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp @@ -70,7 +70,7 @@ void vtkGeometryCacheReader::readCacheForObject(IObject *obj) { // Read the cache from the element int noOfTriangles = 0, noOfPoints = 0; std::vector Points; - std::vector Faces; + std::vector Faces; std::stringstream buff; // Read number of points buff << pEle->getAttribute("NumberOfPoints"); @@ -141,7 +141,7 @@ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle, */ void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle, int noOfTriangles, - std::vector &faces) { + std::vector &faces) { if (pEle == nullptr) { noOfTriangles = 0; return; diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp index 99f82f472824..93e1ef298840 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheWriter.cpp @@ -122,7 +122,7 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { AutoPtr pFaces = mDoc->createElement("Polys"); AutoPtr pTrisDataArray = mDoc->createElement("DataArray"); // add attribute - pTrisDataArray->setAttribute("type", "Int32"); + pTrisDataArray->setAttribute("type", "UInt32"); pTrisDataArray->setAttribute("Name", "connectivity"); pTrisDataArray->setAttribute("format", "ascii"); @@ -137,7 +137,7 @@ void vtkGeometryCacheWriter::addObject(CSGObject *obj) { // set the offsets AutoPtr pTrisOffsetDataArray = mDoc->createElement("DataArray"); // add attribute - pTrisOffsetDataArray->setAttribute("type", "Int32"); + pTrisOffsetDataArray->setAttribute("type", "UInt32"); pTrisOffsetDataArray->setAttribute("Name", "offsets"); pTrisOffsetDataArray->setAttribute("format", "ascii"); buf.str(""); From 38a4269a71a41dcf99e2ce910b6f2e2da87aaf19 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 6 Mar 2018 10:10:36 +0000 Subject: [PATCH 093/364] Convert Renderer to free funcitons #21230 --- Framework/Geometry/CMakeLists.txt | 4 +- .../inc/MantidGeometry/Rendering/Renderer.h | 120 ----- .../Rendering/RenderingHelpers.h | 40 ++ .../src/Rendering/GeometryHandler.cpp | 13 +- .../{Renderer.cpp => RenderingHelpers.cpp} | 419 +++++++++--------- 5 files changed, 254 insertions(+), 342 deletions(-) delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h create mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/RenderingHelpers.h rename Framework/Geometry/src/Rendering/{Renderer.cpp => RenderingHelpers.cpp} (86%) diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index 90dc8cb7bc9c..e79d1ac7009e 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -109,7 +109,7 @@ set ( SRC_FILES src/Objects/ShapeFactory.cpp src/Objects/Track.cpp src/Rendering/GeometryHandler.cpp - src/Rendering/Renderer.cpp + src/Rendering/RenderingHelpers.cpp src/Rendering/ShapeInfo.cpp src/Rendering/vtkGeometryCacheReader.cpp src/Rendering/vtkGeometryCacheWriter.cpp @@ -261,7 +261,7 @@ set ( INC_FILES inc/MantidGeometry/Objects/ShapeFactory.h inc/MantidGeometry/Objects/Track.h inc/MantidGeometry/Rendering/GeometryHandler.h - inc/MantidGeometry/Rendering/Renderer.h + inc/MantidGeometry/Rendering/RenderingHelpers.h inc/MantidGeometry/Rendering/ShapeInfo.h inc/MantidGeometry/Rendering/OpenGL_Headers.h inc/MantidGeometry/Rendering/vtkGeometryCacheReader.h diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h b/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h deleted file mode 100644 index e6c3640caa65..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/Renderer.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef MANTID_GEOMETRY_RENDERER_H_ -#define MANTID_GEOMETRY_RENDERER_H_ - -#include "MantidGeometry/DllConfig.h" -#include "MantidGeometry/Rendering/OpenGL_Headers.h" -#include - -class TopoDS_Shape; - -namespace Mantid { -namespace Kernel { -class V3D; -} -namespace Geometry { -class RectangularDetector; -class StructuredDetector; -class IObjComponent; - -namespace detail { -class GeometryTriangulator; -} - -/** Renderer : Handles rendering details of geometry within mantid. - - Copyright © 2017 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: -*/ -namespace detail { -class ShapeInfo; - -class MANTID_GEOMETRY_DLL Renderer { -public: - enum class RenderMode { Basic, Volumetric }; - Renderer() = default; - ~Renderer() = default; - - /// General method for rendering geometry - template - void render(RenderMode mode, Args &&... args) const &; - - /// Render Basic geometry without transparency (non-volumetric) - template void render(Args &&... args) const &; - - /// Render IObjComponent - void renderIObjComponent(const IObjComponent &objComp, - RenderMode mode = RenderMode::Basic) const; - /// Render Traingulated Surface - void renderTriangulated(detail::GeometryTriangulator &triangulator, - RenderMode mode = RenderMode::Basic) const; - /// Renders a sphere, cuboid, hexahedron, cone or cylinder - void renderShape(const ShapeInfo &shapeInfo) const; - /// Renders a Bitmap (used for rendering RectangularDetector) - void renderBitmap(const RectangularDetector &rectDet, - RenderMode mode = RenderMode::Basic) const; - /// Renders structured geometry (used for rendering StructuredDetector) - void renderStructured(const StructuredDetector &structDet, - RenderMode mode = RenderMode::Basic) const; - -private: - mutable RenderMode m_renderMode; - /// Renders a sphere - void doRenderSphere(const ShapeInfo &shapeInfo) const; - /// Renders a cuboid - void doRenderCuboid(const ShapeInfo &shapeInfo) const; - /// Renders a Hexahedron from the input values - void doRenderHexahedron(const ShapeInfo &shapeInfo) const; - /// Renders a Cone from the input values - void doRenderCone(const ShapeInfo &shapeInfo) const; - /// Renders a Cylinder/Segmented cylinder from the input values - void doRenderCylinder(const ShapeInfo &shapeInfo) const; - // general geometry - /// Render IObjComponent - void doRender(const IObjComponent &ObjComp) const; - /// Render Traingulated Surface - void doRender(GeometryTriangulator &triangulator) const; -#ifdef ENABLE_OPENCASCADE - /// Render OpenCascade Shape - void doRender(const TopoDS_Shape &ObjSurf) const; -#endif - /// Renders a Bitmap (used for rendering RectangularDetector) - void doRender(const RectangularDetector &rectDet) const; - /// Renders structured geometry (used for rendering StructuredDetector) - void doRender(const StructuredDetector &structDet) const; -}; - -template -void Renderer::render(RenderMode mode, Args &&... args) const & { - // Wait for no OopenGL error - while (glGetError() != GL_NO_ERROR) - ; - m_renderMode = mode; - doRender(std::forward(args)...); -} - -template void Renderer::render(Args &&... args) const & { - render(RenderMode::Basic, std::forward(args)...); -} -} // namespace detail -} // namespace Geometry -} // namespace Mantid - -#endif /* MANTID_GEOMETRY_RENDERER_H_ */ \ No newline at end of file diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/RenderingHelpers.h b/Framework/Geometry/inc/MantidGeometry/Rendering/RenderingHelpers.h new file mode 100644 index 000000000000..1d266bf6730c --- /dev/null +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/RenderingHelpers.h @@ -0,0 +1,40 @@ +#ifndef MANTID_GEOMETRY_RENDERER_H_ +#define MANTID_GEOMETRY_RENDERER_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Rendering/OpenGL_Headers.h" +#include + +class TopoDS_Shape; + +namespace Mantid { +namespace Kernel { +class V3D; +} +namespace Geometry { +class RectangularDetector; +class StructuredDetector; +class IObjComponent; + +namespace detail { +class GeometryTriangulator; +class ShapeInfo; +} // namespace detail + +namespace RenderingHelpers { +/// Render IObjComponent +MANTID_GEOMETRY_DLL void renderIObjComponent(const IObjComponent &objComp); +/// Render Traingulated Surface +MANTID_GEOMETRY_DLL void +renderTriangulated(detail::GeometryTriangulator &triangulator); +/// Renders a sphere, cuboid, hexahedron, cone or cylinder +MANTID_GEOMETRY_DLL void renderShape(const detail::ShapeInfo &shapeInfo); +/// Renders a Bitmap (used for rendering RectangularDetector) +MANTID_GEOMETRY_DLL void renderBitmap(const RectangularDetector &rectDet); +/// Renders structured geometry (used for rendering StructuredDetector) +MANTID_GEOMETRY_DLL void renderStructured(const StructuredDetector &structDet); +} // namespace RenderingHelpers +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_RENDERER_H_ */ \ No newline at end of file diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index 483344f70089..ccf6c7be6adf 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -2,7 +2,7 @@ #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Objects/CSGObject.h" #include "MantidGeometry/Rendering/GeometryTriangulator.h" -#include "MantidGeometry/Rendering/Renderer.h" +#include "MantidGeometry/Rendering/RenderingHelpers.h" #include namespace Mantid { @@ -44,17 +44,16 @@ boost::shared_ptr GeometryHandler::clone() const { GeometryHandler::~GeometryHandler() {} void GeometryHandler::render() const { - detail::Renderer renderer; if (m_rectDet) - renderer.renderBitmap(*m_rectDet); + RenderingHelpers::renderBitmap(*m_rectDet); else if (m_structDet) - renderer.renderStructured(*m_structDet); + RenderingHelpers::renderStructured(*m_structDet); else if (m_shapeInfo) - renderer.renderShape(*m_shapeInfo); + RenderingHelpers::renderShape(*m_shapeInfo); else if (m_objComp != nullptr) - renderer.renderIObjComponent(*m_objComp); + RenderingHelpers::renderIObjComponent(*m_objComp); else if (canTriangulate()) - renderer.renderTriangulated(*m_triangulator); + RenderingHelpers::renderTriangulated(*m_triangulator); } void GeometryHandler::initialize() const { diff --git a/Framework/Geometry/src/Rendering/Renderer.cpp b/Framework/Geometry/src/Rendering/RenderingHelpers.cpp similarity index 86% rename from Framework/Geometry/src/Rendering/Renderer.cpp rename to Framework/Geometry/src/Rendering/RenderingHelpers.cpp index e18de7c423fe..faae5965d9c4 100644 --- a/Framework/Geometry/src/Rendering/Renderer.cpp +++ b/Framework/Geometry/src/Rendering/RenderingHelpers.cpp @@ -1,4 +1,4 @@ -#include "MantidGeometry/Rendering/Renderer.h" +#include "MantidGeometry/Rendering/RenderingHelpers.h" #include "MantidGeometry/IObjComponent.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Instrument/StructuredDetector.h" @@ -54,210 +54,9 @@ namespace Geometry { using Kernel::Quat; using Kernel::V3D; -namespace detail { -void Renderer::renderIObjComponent(const IObjComponent &objComp, - RenderMode mode) const { - render(mode, objComp); -} - -void Renderer::renderTriangulated(detail::GeometryTriangulator &triangulator, - RenderMode mode) const { -#ifdef ENABLE_OPENCASCADE - if (triangulator.hasOCSurface() && !triangulator.getOCSurface().IsNull()) - render(mode, triangulator.getOCSurface()); - else - render(mode, triangulator); -#else - render(mode, triangulator); -#endif -} - -void Renderer::renderShape(const ShapeInfo &shapeInfo) const { - switch (shapeInfo.shape()) { - case ShapeInfo::GeometryShape::CUBOID: - doRenderCuboid(shapeInfo); - break; - case ShapeInfo::GeometryShape::SPHERE: - doRenderSphere(shapeInfo); - break; - case ShapeInfo::GeometryShape::HEXAHEDRON: - doRenderHexahedron(shapeInfo); - break; - case ShapeInfo::GeometryShape::CONE: - doRenderCone(shapeInfo); - break; - case ShapeInfo::GeometryShape::CYLINDER: - doRenderCylinder(shapeInfo); - break; - default: - return; - } -} - -void Renderer::renderBitmap(const RectangularDetector &rectDet, - RenderMode mode) const { - render(mode, rectDet); -} - -void Renderer::renderStructured(const StructuredDetector &structDet, - RenderMode mode) const { - render(mode, structDet); -} - -void Renderer::doRenderSphere(const ShapeInfo &shapeInfo) const { - // create glu sphere - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - glPushMatrix(); - auto center = shapeInfo.points()[0]; - glTranslated(center[0], center[1], center[2]); - gluSphere(qobj, shapeInfo.radius(), Sphere::g_nslices, Sphere::g_nstacks); - glPopMatrix(); - gluDeleteQuadric(qobj); -} - -void Renderer::doRenderCuboid(const ShapeInfo &shapeInfo) const { - const auto &points = shapeInfo.points(); - V3D vec0 = points[0]; - V3D vec1 = points[1] - points[0]; - V3D vec2 = points[2] - points[0]; - V3D vec3 = points[3] - points[0]; - V3D vertex[8]; - vertex[0] = vec0; - vertex[1] = vec0 + vec3; - vertex[2] = vec0 + vec3 + vec1; - vertex[3] = vec0 + vec1; - vertex[4] = vec0 + vec2; - vertex[5] = vec0 + vec2 + vec3; - vertex[6] = vec0 + vec2 + vec3 + vec1; - vertex[7] = vec0 + vec1 + vec2; - - int faceindex[6][4] = { - {0, 1, 2, 3}, // top - {0, 3, 7, 4}, // left - {3, 2, 6, 7}, // back - {2, 1, 5, 6}, // right - {0, 4, 5, 1}, // front - {4, 7, 6, 5}, // bottom - }; - V3D normal; - // first face - glBegin(GL_QUADS); - for (auto &row : faceindex) { - normal = (vertex[row[0]] - vertex[row[1]]) - .cross_prod((vertex[row[0]] - vertex[row[2]])); - normal.normalize(); - glNormal3d(normal[0], normal[1], normal[2]); - for (const int ij : row) { - if (ij == 0) - glTexCoord2i(0, 0); - if (ij == 1) - glTexCoord2i(1, 0); - if (ij == 2) - glTexCoord2i(1, 1); - if (ij == 3) - glTexCoord2i(0, 1); - if (ij == 4) - glTexCoord2i(0, 0); - if (ij == 5) - glTexCoord2i(1, 0); - if (ij == 6) - glTexCoord2i(1, 1); - if (ij == 7) - glTexCoord2i(0, 1); - glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]); - } - } - glEnd(); -} - -void Renderer::doRenderHexahedron(const ShapeInfo &shapeInfo) const { - glBegin(GL_QUADS); - const auto &points = shapeInfo.points(); - // bottom - glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); - glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); - glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); - glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); - // front - glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); - glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); - glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); - glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); - // right - glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); - glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); - glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); - glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); - // back - glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); - glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); - glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); - glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); - // left - glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); - glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); - glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); - glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); - // top - glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); - glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); - glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); - glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); - - glEnd(); -} - -void Renderer::doRenderCone(const ShapeInfo &shapeInfo) const { - glPushMatrix(); - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - auto center = shapeInfo.points()[0]; - glTranslated(center[0], center[1], center[2]); - GLdouble mat[16]; - V3D unit(0, 0, 1); - auto axis = shapeInfo.points()[1]; - Quat rot(unit, axis); - rot.GLMatrix(&mat[0]); - glMultMatrixd(mat); - auto radius = shapeInfo.radius(); - auto height = shapeInfo.height(); - gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, - Geometry::Cone::g_nstacks); - glTranslated(0.0, 0.0, height); - gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); - glPopMatrix(); -} - -void Renderer::doRenderCylinder(const ShapeInfo &shapeInfo) const { - GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - gluQuadricNormals(qobj, GL_SMOOTH); - gluQuadricTexture(qobj, true); - glPushMatrix(); - auto center = shapeInfo.points()[0]; - glTranslated(center[0], center[1], center[2]); - GLdouble mat[16]; - V3D unit(0, 0, 1); - auto axis = shapeInfo.points()[1]; - Quat rot(unit, axis); - rot.GLMatrix(&mat[0]); - glMultMatrixd(mat); - auto radius = shapeInfo.radius(); - auto height = shapeInfo.height(); - gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, - Cylinder::g_nstacks); - gluQuadricTexture(qobj, false); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glTranslated(0.0, 0.0, height); - gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); - glPopMatrix(); -} - +namespace { // Render IObjectComponent -void Renderer::doRender(const IObjComponent &ObjComp) const { +void render(const IObjComponent &ObjComp) { glPushMatrix(); V3D pos = ObjComp.getPos(); Quat rot = ObjComp.getRotation(); @@ -272,7 +71,7 @@ void Renderer::doRender(const IObjComponent &ObjComp) const { } // Render triangulated surface -void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { +void render(detail::GeometryTriangulator &triangulator) { const auto &faces = triangulator.getTriangleFaces(); const auto &points = triangulator.getTriangleVertices(); glBegin(GL_TRIANGLES); @@ -297,7 +96,7 @@ void Renderer::doRender(detail::GeometryTriangulator &triangulator) const { #ifdef ENABLE_OPENCASCADE // Render OpenCascade Shape -void Renderer::doRender(const TopoDS_Shape &ObjSurf) const { +void render(const TopoDS_Shape &ObjSurf) { glBegin(GL_TRIANGLES); if (!ObjSurf.IsNull()) { TopExp_Explorer Ex; @@ -337,7 +136,7 @@ void Renderer::doRender(const TopoDS_Shape &ObjSurf) const { #endif // Render Bitmap for RectangularDetector -void Renderer::doRender(const RectangularDetector &rectDet) const { +void render(const RectangularDetector &rectDet) { // Because texture colours are combined with the geometry colour // make sure the current colour is white glColor3f(1.0f, 1.0f, 1.0f); @@ -389,14 +188,13 @@ void Renderer::doRender(const RectangularDetector &rectDet) const { glEnd(); if (glGetError() > 0) - std::cout - << "OpenGL error in Renderer::doRender(const RectangularDetector &) \n"; + std::cout << "OpenGL error in doRender(const RectangularDetector &) \n"; glDisable( GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. } -void Renderer::doRender(const StructuredDetector &structDet) const { +void render(const StructuredDetector &structDet) { const auto &xVerts = structDet.getXValues(); const auto &yVerts = structDet.getYValues(); const auto &r = structDet.getR(); @@ -437,9 +235,204 @@ void Renderer::doRender(const StructuredDetector &structDet) const { glEnd(); if (glGetError() > 0) - std::cout - << "OpenGL error in Renderer::doRender(const StructuredDetector &) \n"; + std::cout << "OpenGL error in doRender(const StructuredDetector &) \n"; } -} // namespace detail + +void renderSphere(const detail::ShapeInfo &shapeInfo) { + // create glu sphere + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + glPushMatrix(); + auto center = shapeInfo.points()[0]; + glTranslated(center[0], center[1], center[2]); + gluSphere(qobj, shapeInfo.radius(), Sphere::g_nslices, Sphere::g_nstacks); + glPopMatrix(); + gluDeleteQuadric(qobj); +} + +void renderCuboid(const detail::ShapeInfo &shapeInfo) { + const auto &points = shapeInfo.points(); + V3D vec0 = points[0]; + V3D vec1 = points[1] - points[0]; + V3D vec2 = points[2] - points[0]; + V3D vec3 = points[3] - points[0]; + V3D vertex[8]; + vertex[0] = vec0; + vertex[1] = vec0 + vec3; + vertex[2] = vec0 + vec3 + vec1; + vertex[3] = vec0 + vec1; + vertex[4] = vec0 + vec2; + vertex[5] = vec0 + vec2 + vec3; + vertex[6] = vec0 + vec2 + vec3 + vec1; + vertex[7] = vec0 + vec1 + vec2; + + int faceindex[6][4] = { + {0, 1, 2, 3}, // top + {0, 3, 7, 4}, // left + {3, 2, 6, 7}, // back + {2, 1, 5, 6}, // right + {0, 4, 5, 1}, // front + {4, 7, 6, 5}, // bottom + }; + V3D normal; + // first face + glBegin(GL_QUADS); + for (auto &row : faceindex) { + normal = (vertex[row[0]] - vertex[row[1]]) + .cross_prod((vertex[row[0]] - vertex[row[2]])); + normal.normalize(); + glNormal3d(normal[0], normal[1], normal[2]); + for (const int ij : row) { + if (ij == 0) + glTexCoord2i(0, 0); + if (ij == 1) + glTexCoord2i(1, 0); + if (ij == 2) + glTexCoord2i(1, 1); + if (ij == 3) + glTexCoord2i(0, 1); + if (ij == 4) + glTexCoord2i(0, 0); + if (ij == 5) + glTexCoord2i(1, 0); + if (ij == 6) + glTexCoord2i(1, 1); + if (ij == 7) + glTexCoord2i(0, 1); + glVertex3d(vertex[ij][0], vertex[ij][1], vertex[ij][2]); + } + } + glEnd(); +} + +void renderHexahedron(const detail::ShapeInfo &shapeInfo) { + glBegin(GL_QUADS); + const auto &points = shapeInfo.points(); + // bottom + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + // front + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + // right + glVertex3d(points[2].X(), points[2].Y(), points[2].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + // back + glVertex3d(points[3].X(), points[3].Y(), points[3].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + // left + glVertex3d(points[0].X(), points[0].Y(), points[0].Z()); + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[1].X(), points[1].Y(), points[1].Z()); + // top + glVertex3d(points[4].X(), points[4].Y(), points[4].Z()); + glVertex3d(points[5].X(), points[5].Y(), points[5].Z()); + glVertex3d(points[6].X(), points[6].Y(), points[6].Z()); + glVertex3d(points[7].X(), points[7].Y(), points[7].Z()); + + glEnd(); +} + +void renderCone(const detail::ShapeInfo &shapeInfo) { + glPushMatrix(); + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + auto center = shapeInfo.points()[0]; + glTranslated(center[0], center[1], center[2]); + GLdouble mat[16]; + V3D unit(0, 0, 1); + auto axis = shapeInfo.points()[1]; + Quat rot(unit, axis); + rot.GLMatrix(&mat[0]); + glMultMatrixd(mat); + auto radius = shapeInfo.radius(); + auto height = shapeInfo.height(); + gluCylinder(qobj, 0, radius, height, Geometry::Cone::g_nslices, + Geometry::Cone::g_nstacks); + glTranslated(0.0, 0.0, height); + gluDisk(qobj, 0, radius, Geometry::Cone::g_nslices, 1); + glPopMatrix(); +} + +void renderCylinder(const detail::ShapeInfo &shapeInfo) { + GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricNormals(qobj, GL_SMOOTH); + gluQuadricTexture(qobj, true); + glPushMatrix(); + auto center = shapeInfo.points()[0]; + glTranslated(center[0], center[1], center[2]); + GLdouble mat[16]; + V3D unit(0, 0, 1); + auto axis = shapeInfo.points()[1]; + Quat rot(unit, axis); + rot.GLMatrix(&mat[0]); + glMultMatrixd(mat); + auto radius = shapeInfo.radius(); + auto height = shapeInfo.height(); + gluCylinder(qobj, radius, radius, height, Cylinder::g_nslices, + Cylinder::g_nstacks); + gluQuadricTexture(qobj, false); + gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); + glTranslated(0.0, 0.0, height); + gluDisk(qobj, 0, radius, Cylinder::g_nslices, 1); + glPopMatrix(); +} +} // namespace + +namespace RenderingHelpers { +void renderIObjComponent(const IObjComponent &objComp) { render(objComp); } + +void renderTriangulated(detail::GeometryTriangulator &triangulator) { +#ifdef ENABLE_OPENCASCADE + if (triangulator.hasOCSurface() && !triangulator.getOCSurface().IsNull()) + render(triangulator.getOCSurface()); + else + render(triangulator); +#else + render(triangulator); +#endif +} + +void renderShape(const detail::ShapeInfo &shapeInfo) { + switch (shapeInfo.shape()) { + case detail::ShapeInfo::GeometryShape::CUBOID: + renderCuboid(shapeInfo); + break; + case detail::ShapeInfo::GeometryShape::SPHERE: + renderSphere(shapeInfo); + break; + case detail::ShapeInfo::GeometryShape::HEXAHEDRON: + renderHexahedron(shapeInfo); + break; + case detail::ShapeInfo::GeometryShape::CONE: + renderCone(shapeInfo); + break; + case detail::ShapeInfo::GeometryShape::CYLINDER: + renderCylinder(shapeInfo); + break; + default: + return; + } +} + +void renderBitmap(const RectangularDetector &rectDet) { render(rectDet); } + +void renderStructured(const StructuredDetector &structDet) { + render(structDet); +} + +} // namespace RenderingHelpers } // namespace Geometry } // namespace Mantid From 528abd2451bfc75ccf09ac610476d6c48a25d1ff Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 6 Mar 2018 10:14:13 +0000 Subject: [PATCH 094/364] clang format #21230 --- .../inc/MantidGeometry/Rendering/GeometryTriangulator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index 938dbe13e351..d369818d5146 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -41,9 +41,9 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { bool m_isTriangulated; size_t m_nFaces; size_t m_nPoints; - std::vector m_points; ///< double array or points + std::vector m_points; ///< double array or points std::vector m_faces; ///< Integer array of faces - const CSGObject *m_obj; ///< Input Object + const CSGObject *m_obj; ///< Input Object void checkTriangulated(); public: From c3ce711020219b63bb9e1f94e14ee0523f264fbd Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 6 Mar 2018 17:24:33 +0000 Subject: [PATCH 095/364] refs #21961 period algebra is now usable in muon fitting --- .../Muon/MuonAnalysis.cpp | 18 ++++++- qt/scientific_interfaces/Muon/MuonAnalysis.h | 1 + .../Common/MuonFitPropertyBrowser.h | 2 +- .../common/src/MuonFitPropertyBrowser.cpp | 53 +++++++++++++------ 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 956accb99cf4..0f39bc8b0a02 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -512,6 +512,19 @@ std::string MuonAnalysis::getNewAnalysisWSName(ItemType itemType, int tableRow, params.itemName = table->item(tableRow, 0)->text().toStdString(); params.plotType = plotType; params.periods = getPeriodLabels(); + bool isItSummed = false; + if (params.periods.find("+") != std::string::npos) { + isItSummed = true; + + }if (params.periods.find("-") != std::string::npos) { + isItSummed = true; + + } + + if (!m_summedPeriods.contains(QString::fromStdString(params.periods)) && params.periods != "" && isItSummed) { + m_summedPeriods << QString::fromStdString(params.periods); + + } // Version - always "#1" if overwrite is on, otherwise increment params.version = 1; @@ -1106,6 +1119,7 @@ void MuonAnalysis::updatePairTable() { void MuonAnalysis::inputFileChanged_MWRunFiles() { // Handle changed input, then turn buttons back on. handleInputFileChanges(); + m_summedPeriods.clear(); allowLoading(true); } @@ -1961,7 +1975,6 @@ void MuonAnalysis::selectMultiPeak(const QString &wsName, std::transform(groups.pairNames.begin(), groups.pairNames.end(), std::back_inserter(groupsAndPairs), &QString::fromStdString); setGroupsAndPairs(); - m_uiForm.fitBrowser->setNumPeriods(m_numPeriods); // Set the selected run, group/pair and period m_fitDataPresenter->setAssignedFirstRun(wsName, filePath); @@ -2625,7 +2638,8 @@ void MuonAnalysis::changeTab(int newTabIndex) { m_uiForm.fitBrowser->setSingleFitLabel(m_currentDataName.toStdString()); } else { m_uiForm.fitBrowser->setAllGroupsOrPairs(isItGroup); - m_uiForm.fitBrowser->setAllPeriods(); + m_uiForm.fitBrowser->setNumPeriods(m_numPeriods, m_summedPeriods); + //m_uiForm.fitBrowser->setAllPeriods(); } if (parsePlotType(m_uiForm.frontPlotFuncs) == PlotType::Asymmetry && isItGroup) { diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.h b/qt/scientific_interfaces/Muon/MuonAnalysis.h index 58a8384af8b9..4d4b715dbf02 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.h @@ -580,6 +580,7 @@ private slots: /// set the group/pair name std::string m_groupPairName; + QStringList m_summedPeriods; }; } } diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index 8e7644cae7d8..0b9a67d8f467 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -129,7 +129,7 @@ public slots: void periodBtnPressed(); void generateBtnPressed(); void combineBtnPressed(); - void setNumPeriods(size_t numPeriods); + void setNumPeriods(size_t numPeriods,QStringList summedPeriods); signals: /// Emitted when sequential fit is requested by user diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 6a199c0eba5f..9e7e6ebb0709 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -55,7 +55,7 @@ #include #include - +#include #include namespace { @@ -178,8 +178,8 @@ void MuonFitPropertyBrowser::init() { tmp = "bwd"; addGroupCheckbox(tmp); m_periodsToFit = m_enumManager->addProperty("Periods to fit"); - m_periodsToFitOptions << ALL_PERIODS_LABEL << "1" - << "2" << CUSTOM_LABEL; + m_periodsToFitOptions << ALL_PERIODS_LABEL <addProperty("Selected Periods"); m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); @@ -1397,7 +1397,6 @@ void MuonFitPropertyBrowser::genGroupWindow() { */ void MuonFitPropertyBrowser::setAllPeriods() { - clearChosenPeriods(); for (auto iter = m_periodBoxes.constBegin(); iter != m_periodBoxes.constEnd(); ++iter) { m_boolManager->setValue(iter.value(), true); @@ -1408,15 +1407,30 @@ void MuonFitPropertyBrowser::setAllPeriods() { * Sets checkboxes for periods * @param numPeriods :: [input] Number of periods */ -void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods) { - m_periodsToFitOptions.clear(); +void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods,QStringList summedPeriods) { + //has to go here to get the original value + int j = m_enumManager->value(m_periodsToFit); + //delete period checkboxes + clearPeriodCheckboxes(); + if (! m_periodsToFitOptions.empty()) { + m_periodsToFitOptions.clear(); + } + if (numPeriods > 1) { m_periodsToFitOptions << ALL_PERIODS_LABEL; + m_periodsToFitOptions << CUSTOM_LABEL; } + // create more boxes for (size_t i = 0; i != numPeriods; i++) { - QString name = QString::number(i + 1); - addPeriodCheckbox(name); + QString name = QString::number(i + 1); + addPeriodCheckbox(name); + } + if (summedPeriods.size() > 0) { + for (auto period : summedPeriods) { + auto tmp = period.toStdString(); + addPeriodCheckbox(period); + } } if (m_periodsToFitOptions.size() == 1) { m_generateBtn->setDisabled(true); @@ -1426,13 +1440,15 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods) { clearChosenPeriods(); m_boolManager->setValue(m_periodBoxes.constBegin().value(), true); } else { - // add custom back into list + if (j >= m_periodsToFitOptions.size()) { + //set all groups if the selection is no longer available + m_enumManager->setValue(m_periodsToFit, 0); + } m_multiFitSettingsGroup->property()->insertSubProperty(m_periodsToFit, m_showGroup); m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods); m_generateBtn->setDisabled(false); - - m_periodsToFitOptions << CUSTOM_LABEL; + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); } } @@ -1465,10 +1481,11 @@ void MuonFitPropertyBrowser::setAvailablePeriods(const QStringList &periods) { */ void MuonFitPropertyBrowser::clearPeriodCheckboxes() { if (m_periodBoxes.size() > 1) { - for (auto iter = std::next(m_periodBoxes.constBegin()); - iter != m_periodBoxes.constEnd(); ++iter) { - delete (*iter); - } + for (const auto &checkbox : m_periodBoxes) { + delete (checkbox); + } + m_periodBoxes.clear(); + } m_periodsToFitOptions.clear(); m_periodsToFitOptions << "1"; @@ -1498,8 +1515,10 @@ void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); setChosenPeriods(active); m_enumManager->setValue(m_periodsToFit, j); - if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { - setAllPeriods(); + if (j < m_periodsToFitOptions.size()) { + if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { + setAllPeriods(); + } } } /** From 72bfd834ad8a4e06308357df4369f9c61f874aff Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Wed, 7 Mar 2018 10:18:29 +0000 Subject: [PATCH 096/364] refs #21961 period selection does not reset in muon GUI --- .../Muon/MuonAnalysis.cpp | 8 ++--- .../common/src/MuonFitPropertyBrowser.cpp | 34 ++++++++++++++----- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 0f39bc8b0a02..f84a85d4fc10 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -513,14 +513,11 @@ std::string MuonAnalysis::getNewAnalysisWSName(ItemType itemType, int tableRow, params.plotType = plotType; params.periods = getPeriodLabels(); bool isItSummed = false; - if (params.periods.find("+") != std::string::npos) { - isItSummed = true; - - }if (params.periods.find("-") != std::string::npos) { + if (params.periods.find("+") != std::string::npos||params.periods.find("-") != std::string::npos) { isItSummed = true; } - + // add to list of summed periods if it is not already in the list, is not empty (1 period) and a sum if (!m_summedPeriods.contains(QString::fromStdString(params.periods)) && params.periods != "" && isItSummed) { m_summedPeriods << QString::fromStdString(params.periods); @@ -2639,7 +2636,6 @@ void MuonAnalysis::changeTab(int newTabIndex) { } else { m_uiForm.fitBrowser->setAllGroupsOrPairs(isItGroup); m_uiForm.fitBrowser->setNumPeriods(m_numPeriods, m_summedPeriods); - //m_uiForm.fitBrowser->setAllPeriods(); } if (parsePlotType(m_uiForm.frontPlotFuncs) == PlotType::Asymmetry && isItGroup) { diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 9e7e6ebb0709..1c0ed9c9939a 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1410,6 +1410,7 @@ void MuonFitPropertyBrowser::setAllPeriods() { void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods,QStringList summedPeriods) { //has to go here to get the original value int j = m_enumManager->value(m_periodsToFit); + auto selected = getChosenPeriods(); //delete period checkboxes clearPeriodCheckboxes(); if (! m_periodsToFitOptions.empty()) { @@ -1428,7 +1429,6 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods,QStringList summedP } if (summedPeriods.size() > 0) { for (auto period : summedPeriods) { - auto tmp = period.toStdString(); addPeriodCheckbox(period); } } @@ -1441,15 +1441,33 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods,QStringList summedP m_boolManager->setValue(m_periodBoxes.constBegin().value(), true); } else { if (j >= m_periodsToFitOptions.size()) { - //set all groups if the selection is no longer available - m_enumManager->setValue(m_periodsToFit, 0); + //set all groups if the selection is no longer available (0 index) + j = 0; } m_multiFitSettingsGroup->property()->insertSubProperty(m_periodsToFit, m_showGroup); m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods); m_generateBtn->setDisabled(false); - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { + + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + m_periodWindow->close(); + setChosenPeriods(selected); + + } + else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + //explictly set all periods + setAllPeriods(); + } + else { + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + } + } } /** @@ -1515,11 +1533,7 @@ void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); setChosenPeriods(active); m_enumManager->setValue(m_periodsToFit, j); - if (j < m_periodsToFitOptions.size()) { - if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { - setAllPeriods(); - } - } + } /** * Returns a list of the selected periods (checked boxes) @@ -1633,6 +1647,8 @@ void MuonFitPropertyBrowser::combineBtnPressed() { m_positiveCombo->clear(); m_negativeCombo->clear(); addPeriodCheckbox(value); + int j = m_enumManager->value(m_periodsToFit); + if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { setAllPeriods(); } } /** * sets the label for a single fit and From 1fca1d0c713cd939c821b29767b2dfc066261b9b Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Wed, 7 Mar 2018 14:12:53 +0000 Subject: [PATCH 097/364] Move functionality into appropriate functions Refs #21969 --- .../Indirect/ISISCalibration.cpp | 396 ++++++++++-------- .../Indirect/ISISCalibration.h | 38 +- .../Indirect/IndirectDataReductionTab.cpp | 4 +- .../Indirect/IndirectDataReductionTab.h | 4 +- 4 files changed, 251 insertions(+), 191 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp index aa494cecdf32..d761d94c6576 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp @@ -1,8 +1,8 @@ #include "ISISCalibration.h" +#include "MantidAPI/WorkspaceGroup.h" #include "MantidGeometry/Instrument.h" #include "MantidKernel/Logger.h" -#include "MantidAPI/WorkspaceGroup.h" #include @@ -166,125 +166,116 @@ ISISCalibration::ISISCalibration(IndirectDataReduction *idrUI, QWidget *parent) */ ISISCalibration::~ISISCalibration() {} -void ISISCalibration::setup() {} +std::pair ISISCalibration::peakRange() const { + return std::make_pair(m_dblManager->value(m_properties["CalPeakMin"]), + m_dblManager->value(m_properties["CalPeakMax"])); +} -void ISISCalibration::run() { - // Get properties - QStringList filenameList = m_uiForm.leRunNo->getFilenames(); - QString filenames = filenameList.join(","); - QString rawFile = m_uiForm.leRunNo->getFirstFilename(); - QFileInfo rawFileInfo(rawFile); - QString name = rawFileInfo.baseName(); +std::pair ISISCalibration::backgroundRange() const { + return std::make_pair(m_dblManager->value(m_properties["CalBackMin"]), + m_dblManager->value(m_properties["CalBackMax"])); +} - auto instDetails = getInstrumentDetails(); - QString instDetectorRange = - instDetails["spectra-min"] + "," + instDetails["spectra-max"]; +std::pair ISISCalibration::resolutionRange() const { + return std::make_pair(m_dblManager->value(m_properties["ResStart"]), + m_dblManager->value(m_properties["ResEnd"])); +} - QString peakRange = m_properties["CalPeakMin"]->valueText() + "," + - m_properties["CalPeakMax"]->valueText(); - QString backgroundRange = m_properties["CalBackMin"]->valueText() + "," + - m_properties["CalBackMax"]->valueText(); +QString ISISCalibration::peakRangeString() const { + return m_properties["CalPeakMin"]->valueText() + "," + + m_properties["CalPeakMax"]->valueText(); +} - QString outputWorkspaceNameStem = - name + QString::fromStdString("_") + - getInstrumentConfiguration()->getAnalyserName() + - getInstrumentConfiguration()->getReflectionName(); +QString ISISCalibration::backgroundRangeString() const { + return m_properties["CalBackMin"]->valueText() + "," + + m_properties["CalBackMax"]->valueText(); +} - outputWorkspaceNameStem = outputWorkspaceNameStem.toLower(); +QString ISISCalibration::instrumentDetectorRangeString() const { + const auto details = getInstrumentDetails(); + return details["spectra-min"] + "," + details["spectra-max"]; +} - m_outputCalibrationName = outputWorkspaceNameStem; - if (filenameList.size() > 1) - m_outputCalibrationName += "_multi"; - m_outputCalibrationName += "_calib"; +QString ISISCalibration::outputWorkspaceName() const { + const auto configuration = getInstrumentConfiguration(); + auto name = QFileInfo(m_uiForm.leRunNo->getFirstFilename()).baseName(); - bool loadLog = m_uiForm.ckLoadLogFiles->isChecked(); - // Configure the calibration algorithm - IAlgorithm_sptr calibrationAlg = - AlgorithmManager::Instance().create("IndirectCalibration"); - calibrationAlg->initialize(); + if (m_uiForm.leRunNo->getFilenames().size() > 1) + name += "_multi"; - calibrationAlg->setProperty("InputFiles", filenames.toStdString()); - calibrationAlg->setProperty("OutputWorkspace", - m_outputCalibrationName.toStdString()); - calibrationAlg->setProperty("DetectorRange", instDetectorRange.toStdString()); - calibrationAlg->setProperty("PeakRange", peakRange.toStdString()); - calibrationAlg->setProperty("BackgroundRange", backgroundRange.toStdString()); - calibrationAlg->setProperty("LoadLogFiles", loadLog); - - if (m_uiForm.ckScale->isChecked()) { - double scale = m_uiForm.spScale->value(); - calibrationAlg->setProperty("ScaleFactor", scale); - } - m_batchAlgoRunner->addAlgorithm(calibrationAlg); + return name + QString::fromStdString("_") + configuration->getAnalyserName() + + configuration->getReflectionName(); +} + +QString ISISCalibration::resolutionDetectorRangeString() const { + return QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + + "," + QString::number(m_dblManager->value(m_properties["ResSpecMax"])); +} + +QString ISISCalibration::rebinString() const { + return QString::number(m_dblManager->value(m_properties["ResELow"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEWidth"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEHigh"])); +} + +QString ISISCalibration::backgroundString() const { + return QString::number(m_dblManager->value(m_properties["ResStart"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEnd"])); +} + +void ISISCalibration::setPeakRange(const double &peakMin, const double &peakMax, + const QString &minPropertyName, + const QString &maxPropertyName) { + auto calibrationPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + setRangeSelector(calibrationPeak, m_properties[minPropertyName], + m_properties[maxPropertyName], qMakePair(peakMin, peakMax)); +} + +void ISISCalibration::setPeakRange(const double &peakMin, + const double &peakMax) { + setPeakRange(peakMin, peakMax, "CalPeakMin", "CalPeakMax"); +} + +void ISISCalibration::setBackgroundRange(const double &backgroundMin, + const double &backgroundMax, + const QString &minPropertyName, + const QString &maxPropertyName) { + auto background = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + setRangeSelector(background, m_properties[minPropertyName], + m_properties[maxPropertyName], + qMakePair(backgroundMin, backgroundMax)); +} + +void ISISCalibration::setBackgroundRange(const double &backgroundMin, + const double &backgroundMax) { + setBackgroundRange(backgroundMin, backgroundMax, "CalBackMin", "CalBackMax"); +} + +void ISISCalibration::setResolutionSpectraRange(const double &minimum, + const double &maximum) { + m_dblManager->setValue(m_properties["ResSpecMin"], minimum); + m_dblManager->setValue(m_properties["ResSpecMax"], maximum); +} + +void ISISCalibration::setup() {} + +void ISISCalibration::run() { + // Get properties + const auto filenames = m_uiForm.leRunNo->getFilenames().join(","); + const auto outputWorkspaceNameStem = outputWorkspaceName().toLower(); + + m_outputCalibrationName = outputWorkspaceNameStem + "_calib"; + m_batchAlgoRunner->addAlgorithm(calibrationAlgorithm(filenames)); // Initially take the calibration workspace as the result m_pythonExportWsName = m_outputCalibrationName.toStdString(); // Configure the resolution algorithm if (m_uiForm.ckCreateResolution->isChecked()) { - m_outputResolutionName = outputWorkspaceNameStem; - if (filenameList.size() > 1) - m_outputResolutionName += "_multi"; - m_outputResolutionName += "_res"; - - QString resDetectorRange = - QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + - QString::number(m_dblManager->value(m_properties["ResSpecMax"])); - - QString rebinString = - QString::number(m_dblManager->value(m_properties["ResELow"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEWidth"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEHigh"])); - - QString background = - QString::number(m_dblManager->value(m_properties["ResStart"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEnd"])); - - bool smooth = m_uiForm.ckSmoothResolution->isChecked(); - - IAlgorithm_sptr resAlg = - AlgorithmManager::Instance().create("IndirectResolution", -1); - resAlg->initialize(); - - resAlg->setProperty("InputFiles", filenames.toStdString()); - resAlg->setProperty( - "Instrument", - getInstrumentConfiguration()->getInstrumentName().toStdString()); - resAlg->setProperty( - "Analyser", - getInstrumentConfiguration()->getAnalyserName().toStdString()); - resAlg->setProperty( - "Reflection", - getInstrumentConfiguration()->getReflectionName().toStdString()); - resAlg->setProperty("RebinParam", rebinString.toStdString()); - resAlg->setProperty("DetectorRange", resDetectorRange.toStdString()); - resAlg->setProperty("BackgroundRange", background.toStdString()); - resAlg->setProperty("LoadLogFiles", loadLog); - - if (m_uiForm.ckResolutionScale->isChecked()) - resAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); - - if (smooth) - resAlg->setProperty("OutputWorkspace", - m_outputResolutionName.toStdString() + "_pre_smooth"); - else - resAlg->setProperty("OutputWorkspace", - m_outputResolutionName.toStdString()); - - m_batchAlgoRunner->addAlgorithm(resAlg); - - if (smooth) { - IAlgorithm_sptr smoothAlg = - AlgorithmManager::Instance().create("WienerSmooth"); - smoothAlg->initialize(); - smoothAlg->setProperty("OutputWorkspace", - m_outputResolutionName.toStdString()); - - BatchAlgorithmRunner::AlgorithmRuntimeProps smoothAlgInputProps; - smoothAlgInputProps["InputWorkspace"] = - m_outputResolutionName.toStdString() + "_pre_smooth"; - - m_batchAlgoRunner->addAlgorithm(smoothAlg, smoothAlgInputProps); - } + m_outputResolutionName = outputWorkspaceNameStem + "_res"; + m_batchAlgoRunner->addAlgorithm(resolutionAlgorithm(filenames)); + + if (m_uiForm.ckSmoothResolution->isChecked()) + addRuntimeSmoothing(m_outputResolutionName); // When creating resolution file take the resolution workspace as the result m_pythonExportWsName = m_outputResolutionName.toStdString(); @@ -311,22 +302,14 @@ bool ISISCalibration::validate() { uiv.checkMWRunFilesIsValid("Run", m_uiForm.leRunNo); - auto peakRange = - std::make_pair(m_dblManager->value(m_properties["CalPeakMin"]), - m_dblManager->value(m_properties["CalPeakMax"])); - auto backRange = - std::make_pair(m_dblManager->value(m_properties["CalBackMin"]), - m_dblManager->value(m_properties["CalBackMax"])); - - uiv.checkValidRange("Peak Range", peakRange); - uiv.checkValidRange("Back Range", backRange); - uiv.checkRangesDontOverlap(peakRange, backRange); + auto rangeOfPeak = peakRange(); + auto rangeOfBackground = backgroundRange(); + uiv.checkValidRange("Peak Range", rangeOfPeak); + uiv.checkValidRange("Back Range", rangeOfBackground); + uiv.checkRangesDontOverlap(rangeOfPeak, rangeOfBackground); if (m_uiForm.ckCreateResolution->isChecked()) { - auto backgroundRange = - std::make_pair(m_dblManager->value(m_properties["ResStart"]), - m_dblManager->value(m_properties["ResEnd"])); - uiv.checkValidRange("Background", backgroundRange); + uiv.checkValidRange("Background", resolutionRange()); double eLow = m_dblManager->value(m_properties["ResELow"]); double eHigh = m_dblManager->value(m_properties["ResEHigh"]); @@ -348,32 +331,19 @@ bool ISISCalibration::validate() { */ void ISISCalibration::setDefaultInstDetails() { // Get spectra, peak and background details - QMap instDetails = getInstrumentDetails(); + const auto instDetails = getInstrumentDetails(); // Set the search instrument for runs m_uiForm.leRunNo->setInstrumentOverride(instDetails["instrument"]); // Set spectra range - m_dblManager->setValue(m_properties["ResSpecMin"], - instDetails["spectra-min"].toDouble()); - m_dblManager->setValue(m_properties["ResSpecMax"], - instDetails["spectra-max"].toDouble()); + setResolutionSpectraRange(instDetails["spectra-min"].toDouble(), + instDetails["spectra-max"].toDouble()); // Set peak and background ranges - std::map ranges = getRangesFromInstrument(); - - QPair peakRange(ranges["peak-start-tof"], - ranges["peak-end-tof"]); - QPair backgroundRange(ranges["back-start-tof"], - ranges["back-end-tof"]); - - auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); - auto calBackground = - m_uiForm.ppCalibration->getRangeSelector("CalBackground"); - setRangeSelector(calPeak, m_properties["CalPeakMin"], - m_properties["CalPeakMax"], peakRange); - setRangeSelector(calBackground, m_properties["CalBackMin"], - m_properties["CalBackMax"], backgroundRange); + const auto ranges = getRangesFromInstrument(); + setPeakRange(ranges.at("peak-start-tof"), ranges.at("peak-end-tof")); + setBackgroundRange(ranges.at("back-start-tof"), ranges.at("back-end-tof")); } /** @@ -408,24 +378,17 @@ void ISISCalibration::calPlotRaw() { return; } - MatrixWorkspace_sptr input = boost::dynamic_pointer_cast( + const auto input = boost::dynamic_pointer_cast( AnalysisDataService::Instance().retrieve(wsname.toStdString())); - const auto &dataX = input->x(0); - QPair range(dataX.front(), dataX.back()); - m_uiForm.ppCalibration->clear(); m_uiForm.ppCalibration->addSpectrum("Raw", input, 0); m_uiForm.ppCalibration->resizeX(); - auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); - auto calBackground = - m_uiForm.ppCalibration->getRangeSelector("CalBackground"); - setPlotPropertyRange(calPeak, m_properties["CalELow"], - m_properties["CalEHigh"], range); - setPlotPropertyRange(calBackground, m_properties["CalStart"], - m_properties["CalEnd"], range); - + const auto &dataX = input->x(0); + setPeakRange(dataX.front(), dataX.back(), "CalELow", "CalEHigh"); + setBackgroundRange(dataX.front(), dataX.back(), "CalStart", "CalEnd"); + setDefaultInstDetails(); m_uiForm.ppCalibration->replot(); @@ -443,32 +406,8 @@ void ISISCalibration::calPlotEnergy() { return; } - QString files = m_uiForm.leRunNo->getFilenames().join(","); - - QFileInfo fi(m_uiForm.leRunNo->getFirstFilename()); - - QString detRange = - QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + - QString::number(m_dblManager->value(m_properties["ResSpecMax"])); - - IAlgorithm_sptr reductionAlg = - AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); - reductionAlg->initialize(); - reductionAlg->setProperty( - "Instrument", - getInstrumentConfiguration()->getInstrumentName().toStdString()); - reductionAlg->setProperty( - "Analyser", - getInstrumentConfiguration()->getAnalyserName().toStdString()); - reductionAlg->setProperty( - "Reflection", - getInstrumentConfiguration()->getReflectionName().toStdString()); - reductionAlg->setProperty("InputFiles", files.toStdString()); - reductionAlg->setProperty("OutputWorkspace", - "__IndirectCalibration_reduction"); - reductionAlg->setProperty("SpectraRange", detRange.toStdString()); - reductionAlg->setProperty("LoadLogFiles", - m_uiForm.ckLoadLogFiles->isChecked()); + const auto files = m_uiForm.leRunNo->getFilenames().join(","); + auto reductionAlg = energyTransferReductionAlgorithm(files); reductionAlg->execute(); if (!reductionAlg->isExecuted()) { @@ -634,11 +573,11 @@ void ISISCalibration::calUpdateRS(QtProperty *prop, double val) { } /** -* This function enables/disables the display of the options involved in creating -*the RES file. -* -* @param state :: whether checkbox is checked or unchecked -*/ + * This function enables/disables the display of the options involved in + *creating the RES file. + * + * @param state :: whether checkbox is checked or unchecked + */ void ISISCalibration::resCheck(bool state) { m_uiForm.ppResolution->getRangeSelector("ResPeak")->setVisible(state); m_uiForm.ppResolution->getRangeSelector("ResBackground")->setVisible(state); @@ -710,5 +649,94 @@ void ISISCalibration::plotClicked() { } plotSpectrum(plotWorkspaces); } + +void ISISCalibration::addRuntimeSmoothing(const QString &workspaceName) { + auto smoothAlg = AlgorithmManager::Instance().create("WienerSmooth"); + smoothAlg->initialize(); + smoothAlg->setProperty("OutputWorkspace", workspaceName.toStdString()); + + BatchAlgorithmRunner::AlgorithmRuntimeProps smoothAlgInputProps; + smoothAlgInputProps["InputWorkspace"] = + workspaceName.toStdString() + "_pre_smooth"; + m_batchAlgoRunner->addAlgorithm(smoothAlg, smoothAlgInputProps); +} + +IAlgorithm_sptr +ISISCalibration::calibrationAlgorithm(const QString &inputFiles) const { + auto calibrationAlg = + AlgorithmManager::Instance().create("IndirectCalibration"); + calibrationAlg->initialize(); + calibrationAlg->setProperty("InputFiles", inputFiles); + calibrationAlg->setProperty("OutputWorkspace", + m_outputCalibrationName.toStdString()); + calibrationAlg->setProperty("DetectorRange", + instrumentDetectorRangeString().toStdString()); + calibrationAlg->setProperty("PeakRange", peakRangeString().toStdString()); + calibrationAlg->setProperty("BackgroundRange", + backgroundRangeString().toStdString()); + calibrationAlg->setProperty("LoadLogFiles", + m_uiForm.ckLoadLogFiles->isChecked()); + + if (m_uiForm.ckScale->isChecked()) + calibrationAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); + return calibrationAlg; +} + +IAlgorithm_sptr +ISISCalibration::resolutionAlgorithm(const QString &inputFiles) const { + auto resAlg = AlgorithmManager::Instance().create("IndirectResolution", -1); + resAlg->initialize(); + resAlg->setProperty("InputFiles", inputFiles.toStdString()); + resAlg->setProperty( + "Instrument", + getInstrumentConfiguration()->getInstrumentName().toStdString()); + resAlg->setProperty( + "Analyser", + getInstrumentConfiguration()->getAnalyserName().toStdString()); + resAlg->setProperty( + "Reflection", + getInstrumentConfiguration()->getReflectionName().toStdString()); + resAlg->setProperty("RebinParam", rebinString().toStdString()); + resAlg->setProperty("DetectorRange", + resolutionDetectorRangeString().toStdString()); + resAlg->setProperty("BackgroundRange", backgroundString().toStdString()); + resAlg->setProperty("LoadLogFiles", m_uiForm.ckLoadLogFiles->isChecked()); + + if (m_uiForm.ckResolutionScale->isChecked()) + resAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); + + if (m_uiForm.ckSmoothResolution->isChecked()) + resAlg->setProperty("OutputWorkspace", + m_outputResolutionName.toStdString() + "_pre_smooth"); + else + resAlg->setProperty("OutputWorkspace", + m_outputResolutionName.toStdString()); + return resAlg; +} + +IAlgorithm_sptr ISISCalibration::energyTransferReductionAlgorithm( + const QString &inputFiles) const { + IAlgorithm_sptr reductionAlg = + AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); + reductionAlg->initialize(); + reductionAlg->setProperty( + "Instrument", + getInstrumentConfiguration()->getInstrumentName().toStdString()); + reductionAlg->setProperty( + "Analyser", + getInstrumentConfiguration()->getAnalyserName().toStdString()); + reductionAlg->setProperty( + "Reflection", + getInstrumentConfiguration()->getReflectionName().toStdString()); + reductionAlg->setProperty("InputFiles", inputFiles.toStdString()); + reductionAlg->setProperty("OutputWorkspace", + "__IndirectCalibration_reduction"); + reductionAlg->setProperty("SpectraRange", + resolutionDetectorRangeString().toStdString()); + reductionAlg->setProperty("LoadLogFiles", + m_uiForm.ckLoadLogFiles->isChecked()); + return reductionAlg; +} + } // namespace CustomInterfaces -} // namespace Mantid +} // namespace MantidQt diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.h b/qt/scientific_interfaces/Indirect/ISISCalibration.h index 9f6f50d97441..5db1d6c82318 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.h +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.h @@ -1,10 +1,10 @@ #ifndef MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ #define MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ +#include "../General/UserInputValidator.h" #include "IndirectDataReductionTab.h" -#include "ui_ISISCalibration.h" #include "MantidKernel/System.h" -#include "../General/UserInputValidator.h" +#include "ui_ISISCalibration.h" namespace MantidQt { namespace CustomInterfaces { @@ -46,6 +46,30 @@ class DLLExport ISISCalibration : public IndirectDataReductionTab { void run() override; bool validate() override; + std::pair peakRange() const; + std::pair backgroundRange() const; + std::pair resolutionRange() const; + + QString peakRangeString() const; + QString backgroundRangeString() const; + QString instrumentDetectorRangeString() const; + QString outputWorkspaceName() const; + QString resolutionDetectorRangeString() const; + QString rebinString() const; + QString backgroundString() const; + + void setPeakRange(const double &peakMin, const double &peakMax, + const QString &minPropertyName, + const QString &maxPropertyName); + void setPeakRange(const double &peakMin, const double &peakMax); + void setBackgroundRange(const double &backgroundMin, + const double &backgroundMax, + const QString &minPropertyName, + const QString &maxPropertyName); + void setBackgroundRange(const double &backgroundMin, + const double &backgroundMax); + void setResolutionSpectraRange(const double &minimum, const double &maximum); + private slots: void algorithmComplete(bool error); void calPlotRaw(); @@ -68,6 +92,14 @@ private slots: private: void createRESfile(const QString &file); + void addRuntimeSmoothing(const QString &workspaceName); + + Mantid::API::IAlgorithm_sptr + calibrationAlgorithm(const QString &inputFiles) const; + Mantid::API::IAlgorithm_sptr + resolutionAlgorithm(const QString &inputFiles) const; + Mantid::API::IAlgorithm_sptr + energyTransferReductionAlgorithm(const QString &inputFiles) const; Ui::ISISCalibration m_uiForm; QString m_lastCalPlotFilename; @@ -76,6 +108,6 @@ private slots: QString m_outputResolutionName; }; } // namespace CustomInterfaces -} // namespace Mantid +} // namespace MantidQt #endif // MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ diff --git a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp index 08fa4a17aa60..e3ee77772ca7 100644 --- a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp @@ -84,7 +84,7 @@ IndirectDataReductionTab::loadInstrumentIfNotExist(std::string instrumentName, * * @return Map of information ID to value */ -QMap IndirectDataReductionTab::getInstrumentDetails() { +QMap IndirectDataReductionTab::getInstrumentDetails() const { return m_idrUI->getInstrumentDetails(); } @@ -94,7 +94,7 @@ QMap IndirectDataReductionTab::getInstrumentDetails() { * @return Instrument config widget */ MantidWidgets::IndirectInstrumentConfig * -IndirectDataReductionTab::getInstrumentConfiguration() { +IndirectDataReductionTab::getInstrumentConfiguration() const { return m_idrUI->m_uiForm.iicInstrumentConfiguration; } diff --git a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h index 32f08cca9971..3d0c5dcd0b7e 100644 --- a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h +++ b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h @@ -95,12 +95,12 @@ public slots: std::string analyser = "", std::string reflection = ""); /// Function to get details about the instrumet from a given workspace - QMap getInstrumentDetails(); + QMap getInstrumentDetails() const; std::map getRangesFromInstrument(QString instName = "", QString analyser = "", QString reflection = ""); /// Get the instrument config widget - MantidWidgets::IndirectInstrumentConfig *getInstrumentConfiguration(); + MantidWidgets::IndirectInstrumentConfig *getInstrumentConfiguration() const; private slots: void tabExecutionComplete(bool error); From 9f018c83f2ceb768186407cf5de817d6228c3dfe Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Wed, 7 Mar 2018 14:12:53 +0000 Subject: [PATCH 098/364] Move functionality into appropriate functions Refs #21969 --- .../Indirect/ISISCalibration.cpp | 396 ++++++++++-------- .../Indirect/ISISCalibration.h | 38 +- .../Indirect/IndirectDataReductionTab.cpp | 4 +- .../Indirect/IndirectDataReductionTab.h | 4 +- 4 files changed, 251 insertions(+), 191 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp index aa494cecdf32..d761d94c6576 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp @@ -1,8 +1,8 @@ #include "ISISCalibration.h" +#include "MantidAPI/WorkspaceGroup.h" #include "MantidGeometry/Instrument.h" #include "MantidKernel/Logger.h" -#include "MantidAPI/WorkspaceGroup.h" #include @@ -166,125 +166,116 @@ ISISCalibration::ISISCalibration(IndirectDataReduction *idrUI, QWidget *parent) */ ISISCalibration::~ISISCalibration() {} -void ISISCalibration::setup() {} +std::pair ISISCalibration::peakRange() const { + return std::make_pair(m_dblManager->value(m_properties["CalPeakMin"]), + m_dblManager->value(m_properties["CalPeakMax"])); +} -void ISISCalibration::run() { - // Get properties - QStringList filenameList = m_uiForm.leRunNo->getFilenames(); - QString filenames = filenameList.join(","); - QString rawFile = m_uiForm.leRunNo->getFirstFilename(); - QFileInfo rawFileInfo(rawFile); - QString name = rawFileInfo.baseName(); +std::pair ISISCalibration::backgroundRange() const { + return std::make_pair(m_dblManager->value(m_properties["CalBackMin"]), + m_dblManager->value(m_properties["CalBackMax"])); +} - auto instDetails = getInstrumentDetails(); - QString instDetectorRange = - instDetails["spectra-min"] + "," + instDetails["spectra-max"]; +std::pair ISISCalibration::resolutionRange() const { + return std::make_pair(m_dblManager->value(m_properties["ResStart"]), + m_dblManager->value(m_properties["ResEnd"])); +} - QString peakRange = m_properties["CalPeakMin"]->valueText() + "," + - m_properties["CalPeakMax"]->valueText(); - QString backgroundRange = m_properties["CalBackMin"]->valueText() + "," + - m_properties["CalBackMax"]->valueText(); +QString ISISCalibration::peakRangeString() const { + return m_properties["CalPeakMin"]->valueText() + "," + + m_properties["CalPeakMax"]->valueText(); +} - QString outputWorkspaceNameStem = - name + QString::fromStdString("_") + - getInstrumentConfiguration()->getAnalyserName() + - getInstrumentConfiguration()->getReflectionName(); +QString ISISCalibration::backgroundRangeString() const { + return m_properties["CalBackMin"]->valueText() + "," + + m_properties["CalBackMax"]->valueText(); +} - outputWorkspaceNameStem = outputWorkspaceNameStem.toLower(); +QString ISISCalibration::instrumentDetectorRangeString() const { + const auto details = getInstrumentDetails(); + return details["spectra-min"] + "," + details["spectra-max"]; +} - m_outputCalibrationName = outputWorkspaceNameStem; - if (filenameList.size() > 1) - m_outputCalibrationName += "_multi"; - m_outputCalibrationName += "_calib"; +QString ISISCalibration::outputWorkspaceName() const { + const auto configuration = getInstrumentConfiguration(); + auto name = QFileInfo(m_uiForm.leRunNo->getFirstFilename()).baseName(); - bool loadLog = m_uiForm.ckLoadLogFiles->isChecked(); - // Configure the calibration algorithm - IAlgorithm_sptr calibrationAlg = - AlgorithmManager::Instance().create("IndirectCalibration"); - calibrationAlg->initialize(); + if (m_uiForm.leRunNo->getFilenames().size() > 1) + name += "_multi"; - calibrationAlg->setProperty("InputFiles", filenames.toStdString()); - calibrationAlg->setProperty("OutputWorkspace", - m_outputCalibrationName.toStdString()); - calibrationAlg->setProperty("DetectorRange", instDetectorRange.toStdString()); - calibrationAlg->setProperty("PeakRange", peakRange.toStdString()); - calibrationAlg->setProperty("BackgroundRange", backgroundRange.toStdString()); - calibrationAlg->setProperty("LoadLogFiles", loadLog); - - if (m_uiForm.ckScale->isChecked()) { - double scale = m_uiForm.spScale->value(); - calibrationAlg->setProperty("ScaleFactor", scale); - } - m_batchAlgoRunner->addAlgorithm(calibrationAlg); + return name + QString::fromStdString("_") + configuration->getAnalyserName() + + configuration->getReflectionName(); +} + +QString ISISCalibration::resolutionDetectorRangeString() const { + return QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + + "," + QString::number(m_dblManager->value(m_properties["ResSpecMax"])); +} + +QString ISISCalibration::rebinString() const { + return QString::number(m_dblManager->value(m_properties["ResELow"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEWidth"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEHigh"])); +} + +QString ISISCalibration::backgroundString() const { + return QString::number(m_dblManager->value(m_properties["ResStart"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEnd"])); +} + +void ISISCalibration::setPeakRange(const double &peakMin, const double &peakMax, + const QString &minPropertyName, + const QString &maxPropertyName) { + auto calibrationPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + setRangeSelector(calibrationPeak, m_properties[minPropertyName], + m_properties[maxPropertyName], qMakePair(peakMin, peakMax)); +} + +void ISISCalibration::setPeakRange(const double &peakMin, + const double &peakMax) { + setPeakRange(peakMin, peakMax, "CalPeakMin", "CalPeakMax"); +} + +void ISISCalibration::setBackgroundRange(const double &backgroundMin, + const double &backgroundMax, + const QString &minPropertyName, + const QString &maxPropertyName) { + auto background = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + setRangeSelector(background, m_properties[minPropertyName], + m_properties[maxPropertyName], + qMakePair(backgroundMin, backgroundMax)); +} + +void ISISCalibration::setBackgroundRange(const double &backgroundMin, + const double &backgroundMax) { + setBackgroundRange(backgroundMin, backgroundMax, "CalBackMin", "CalBackMax"); +} + +void ISISCalibration::setResolutionSpectraRange(const double &minimum, + const double &maximum) { + m_dblManager->setValue(m_properties["ResSpecMin"], minimum); + m_dblManager->setValue(m_properties["ResSpecMax"], maximum); +} + +void ISISCalibration::setup() {} + +void ISISCalibration::run() { + // Get properties + const auto filenames = m_uiForm.leRunNo->getFilenames().join(","); + const auto outputWorkspaceNameStem = outputWorkspaceName().toLower(); + + m_outputCalibrationName = outputWorkspaceNameStem + "_calib"; + m_batchAlgoRunner->addAlgorithm(calibrationAlgorithm(filenames)); // Initially take the calibration workspace as the result m_pythonExportWsName = m_outputCalibrationName.toStdString(); // Configure the resolution algorithm if (m_uiForm.ckCreateResolution->isChecked()) { - m_outputResolutionName = outputWorkspaceNameStem; - if (filenameList.size() > 1) - m_outputResolutionName += "_multi"; - m_outputResolutionName += "_res"; - - QString resDetectorRange = - QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + - QString::number(m_dblManager->value(m_properties["ResSpecMax"])); - - QString rebinString = - QString::number(m_dblManager->value(m_properties["ResELow"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEWidth"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEHigh"])); - - QString background = - QString::number(m_dblManager->value(m_properties["ResStart"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEnd"])); - - bool smooth = m_uiForm.ckSmoothResolution->isChecked(); - - IAlgorithm_sptr resAlg = - AlgorithmManager::Instance().create("IndirectResolution", -1); - resAlg->initialize(); - - resAlg->setProperty("InputFiles", filenames.toStdString()); - resAlg->setProperty( - "Instrument", - getInstrumentConfiguration()->getInstrumentName().toStdString()); - resAlg->setProperty( - "Analyser", - getInstrumentConfiguration()->getAnalyserName().toStdString()); - resAlg->setProperty( - "Reflection", - getInstrumentConfiguration()->getReflectionName().toStdString()); - resAlg->setProperty("RebinParam", rebinString.toStdString()); - resAlg->setProperty("DetectorRange", resDetectorRange.toStdString()); - resAlg->setProperty("BackgroundRange", background.toStdString()); - resAlg->setProperty("LoadLogFiles", loadLog); - - if (m_uiForm.ckResolutionScale->isChecked()) - resAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); - - if (smooth) - resAlg->setProperty("OutputWorkspace", - m_outputResolutionName.toStdString() + "_pre_smooth"); - else - resAlg->setProperty("OutputWorkspace", - m_outputResolutionName.toStdString()); - - m_batchAlgoRunner->addAlgorithm(resAlg); - - if (smooth) { - IAlgorithm_sptr smoothAlg = - AlgorithmManager::Instance().create("WienerSmooth"); - smoothAlg->initialize(); - smoothAlg->setProperty("OutputWorkspace", - m_outputResolutionName.toStdString()); - - BatchAlgorithmRunner::AlgorithmRuntimeProps smoothAlgInputProps; - smoothAlgInputProps["InputWorkspace"] = - m_outputResolutionName.toStdString() + "_pre_smooth"; - - m_batchAlgoRunner->addAlgorithm(smoothAlg, smoothAlgInputProps); - } + m_outputResolutionName = outputWorkspaceNameStem + "_res"; + m_batchAlgoRunner->addAlgorithm(resolutionAlgorithm(filenames)); + + if (m_uiForm.ckSmoothResolution->isChecked()) + addRuntimeSmoothing(m_outputResolutionName); // When creating resolution file take the resolution workspace as the result m_pythonExportWsName = m_outputResolutionName.toStdString(); @@ -311,22 +302,14 @@ bool ISISCalibration::validate() { uiv.checkMWRunFilesIsValid("Run", m_uiForm.leRunNo); - auto peakRange = - std::make_pair(m_dblManager->value(m_properties["CalPeakMin"]), - m_dblManager->value(m_properties["CalPeakMax"])); - auto backRange = - std::make_pair(m_dblManager->value(m_properties["CalBackMin"]), - m_dblManager->value(m_properties["CalBackMax"])); - - uiv.checkValidRange("Peak Range", peakRange); - uiv.checkValidRange("Back Range", backRange); - uiv.checkRangesDontOverlap(peakRange, backRange); + auto rangeOfPeak = peakRange(); + auto rangeOfBackground = backgroundRange(); + uiv.checkValidRange("Peak Range", rangeOfPeak); + uiv.checkValidRange("Back Range", rangeOfBackground); + uiv.checkRangesDontOverlap(rangeOfPeak, rangeOfBackground); if (m_uiForm.ckCreateResolution->isChecked()) { - auto backgroundRange = - std::make_pair(m_dblManager->value(m_properties["ResStart"]), - m_dblManager->value(m_properties["ResEnd"])); - uiv.checkValidRange("Background", backgroundRange); + uiv.checkValidRange("Background", resolutionRange()); double eLow = m_dblManager->value(m_properties["ResELow"]); double eHigh = m_dblManager->value(m_properties["ResEHigh"]); @@ -348,32 +331,19 @@ bool ISISCalibration::validate() { */ void ISISCalibration::setDefaultInstDetails() { // Get spectra, peak and background details - QMap instDetails = getInstrumentDetails(); + const auto instDetails = getInstrumentDetails(); // Set the search instrument for runs m_uiForm.leRunNo->setInstrumentOverride(instDetails["instrument"]); // Set spectra range - m_dblManager->setValue(m_properties["ResSpecMin"], - instDetails["spectra-min"].toDouble()); - m_dblManager->setValue(m_properties["ResSpecMax"], - instDetails["spectra-max"].toDouble()); + setResolutionSpectraRange(instDetails["spectra-min"].toDouble(), + instDetails["spectra-max"].toDouble()); // Set peak and background ranges - std::map ranges = getRangesFromInstrument(); - - QPair peakRange(ranges["peak-start-tof"], - ranges["peak-end-tof"]); - QPair backgroundRange(ranges["back-start-tof"], - ranges["back-end-tof"]); - - auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); - auto calBackground = - m_uiForm.ppCalibration->getRangeSelector("CalBackground"); - setRangeSelector(calPeak, m_properties["CalPeakMin"], - m_properties["CalPeakMax"], peakRange); - setRangeSelector(calBackground, m_properties["CalBackMin"], - m_properties["CalBackMax"], backgroundRange); + const auto ranges = getRangesFromInstrument(); + setPeakRange(ranges.at("peak-start-tof"), ranges.at("peak-end-tof")); + setBackgroundRange(ranges.at("back-start-tof"), ranges.at("back-end-tof")); } /** @@ -408,24 +378,17 @@ void ISISCalibration::calPlotRaw() { return; } - MatrixWorkspace_sptr input = boost::dynamic_pointer_cast( + const auto input = boost::dynamic_pointer_cast( AnalysisDataService::Instance().retrieve(wsname.toStdString())); - const auto &dataX = input->x(0); - QPair range(dataX.front(), dataX.back()); - m_uiForm.ppCalibration->clear(); m_uiForm.ppCalibration->addSpectrum("Raw", input, 0); m_uiForm.ppCalibration->resizeX(); - auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); - auto calBackground = - m_uiForm.ppCalibration->getRangeSelector("CalBackground"); - setPlotPropertyRange(calPeak, m_properties["CalELow"], - m_properties["CalEHigh"], range); - setPlotPropertyRange(calBackground, m_properties["CalStart"], - m_properties["CalEnd"], range); - + const auto &dataX = input->x(0); + setPeakRange(dataX.front(), dataX.back(), "CalELow", "CalEHigh"); + setBackgroundRange(dataX.front(), dataX.back(), "CalStart", "CalEnd"); + setDefaultInstDetails(); m_uiForm.ppCalibration->replot(); @@ -443,32 +406,8 @@ void ISISCalibration::calPlotEnergy() { return; } - QString files = m_uiForm.leRunNo->getFilenames().join(","); - - QFileInfo fi(m_uiForm.leRunNo->getFirstFilename()); - - QString detRange = - QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + - QString::number(m_dblManager->value(m_properties["ResSpecMax"])); - - IAlgorithm_sptr reductionAlg = - AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); - reductionAlg->initialize(); - reductionAlg->setProperty( - "Instrument", - getInstrumentConfiguration()->getInstrumentName().toStdString()); - reductionAlg->setProperty( - "Analyser", - getInstrumentConfiguration()->getAnalyserName().toStdString()); - reductionAlg->setProperty( - "Reflection", - getInstrumentConfiguration()->getReflectionName().toStdString()); - reductionAlg->setProperty("InputFiles", files.toStdString()); - reductionAlg->setProperty("OutputWorkspace", - "__IndirectCalibration_reduction"); - reductionAlg->setProperty("SpectraRange", detRange.toStdString()); - reductionAlg->setProperty("LoadLogFiles", - m_uiForm.ckLoadLogFiles->isChecked()); + const auto files = m_uiForm.leRunNo->getFilenames().join(","); + auto reductionAlg = energyTransferReductionAlgorithm(files); reductionAlg->execute(); if (!reductionAlg->isExecuted()) { @@ -634,11 +573,11 @@ void ISISCalibration::calUpdateRS(QtProperty *prop, double val) { } /** -* This function enables/disables the display of the options involved in creating -*the RES file. -* -* @param state :: whether checkbox is checked or unchecked -*/ + * This function enables/disables the display of the options involved in + *creating the RES file. + * + * @param state :: whether checkbox is checked or unchecked + */ void ISISCalibration::resCheck(bool state) { m_uiForm.ppResolution->getRangeSelector("ResPeak")->setVisible(state); m_uiForm.ppResolution->getRangeSelector("ResBackground")->setVisible(state); @@ -710,5 +649,94 @@ void ISISCalibration::plotClicked() { } plotSpectrum(plotWorkspaces); } + +void ISISCalibration::addRuntimeSmoothing(const QString &workspaceName) { + auto smoothAlg = AlgorithmManager::Instance().create("WienerSmooth"); + smoothAlg->initialize(); + smoothAlg->setProperty("OutputWorkspace", workspaceName.toStdString()); + + BatchAlgorithmRunner::AlgorithmRuntimeProps smoothAlgInputProps; + smoothAlgInputProps["InputWorkspace"] = + workspaceName.toStdString() + "_pre_smooth"; + m_batchAlgoRunner->addAlgorithm(smoothAlg, smoothAlgInputProps); +} + +IAlgorithm_sptr +ISISCalibration::calibrationAlgorithm(const QString &inputFiles) const { + auto calibrationAlg = + AlgorithmManager::Instance().create("IndirectCalibration"); + calibrationAlg->initialize(); + calibrationAlg->setProperty("InputFiles", inputFiles); + calibrationAlg->setProperty("OutputWorkspace", + m_outputCalibrationName.toStdString()); + calibrationAlg->setProperty("DetectorRange", + instrumentDetectorRangeString().toStdString()); + calibrationAlg->setProperty("PeakRange", peakRangeString().toStdString()); + calibrationAlg->setProperty("BackgroundRange", + backgroundRangeString().toStdString()); + calibrationAlg->setProperty("LoadLogFiles", + m_uiForm.ckLoadLogFiles->isChecked()); + + if (m_uiForm.ckScale->isChecked()) + calibrationAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); + return calibrationAlg; +} + +IAlgorithm_sptr +ISISCalibration::resolutionAlgorithm(const QString &inputFiles) const { + auto resAlg = AlgorithmManager::Instance().create("IndirectResolution", -1); + resAlg->initialize(); + resAlg->setProperty("InputFiles", inputFiles.toStdString()); + resAlg->setProperty( + "Instrument", + getInstrumentConfiguration()->getInstrumentName().toStdString()); + resAlg->setProperty( + "Analyser", + getInstrumentConfiguration()->getAnalyserName().toStdString()); + resAlg->setProperty( + "Reflection", + getInstrumentConfiguration()->getReflectionName().toStdString()); + resAlg->setProperty("RebinParam", rebinString().toStdString()); + resAlg->setProperty("DetectorRange", + resolutionDetectorRangeString().toStdString()); + resAlg->setProperty("BackgroundRange", backgroundString().toStdString()); + resAlg->setProperty("LoadLogFiles", m_uiForm.ckLoadLogFiles->isChecked()); + + if (m_uiForm.ckResolutionScale->isChecked()) + resAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); + + if (m_uiForm.ckSmoothResolution->isChecked()) + resAlg->setProperty("OutputWorkspace", + m_outputResolutionName.toStdString() + "_pre_smooth"); + else + resAlg->setProperty("OutputWorkspace", + m_outputResolutionName.toStdString()); + return resAlg; +} + +IAlgorithm_sptr ISISCalibration::energyTransferReductionAlgorithm( + const QString &inputFiles) const { + IAlgorithm_sptr reductionAlg = + AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); + reductionAlg->initialize(); + reductionAlg->setProperty( + "Instrument", + getInstrumentConfiguration()->getInstrumentName().toStdString()); + reductionAlg->setProperty( + "Analyser", + getInstrumentConfiguration()->getAnalyserName().toStdString()); + reductionAlg->setProperty( + "Reflection", + getInstrumentConfiguration()->getReflectionName().toStdString()); + reductionAlg->setProperty("InputFiles", inputFiles.toStdString()); + reductionAlg->setProperty("OutputWorkspace", + "__IndirectCalibration_reduction"); + reductionAlg->setProperty("SpectraRange", + resolutionDetectorRangeString().toStdString()); + reductionAlg->setProperty("LoadLogFiles", + m_uiForm.ckLoadLogFiles->isChecked()); + return reductionAlg; +} + } // namespace CustomInterfaces -} // namespace Mantid +} // namespace MantidQt diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.h b/qt/scientific_interfaces/Indirect/ISISCalibration.h index 9f6f50d97441..5db1d6c82318 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.h +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.h @@ -1,10 +1,10 @@ #ifndef MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ #define MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ +#include "../General/UserInputValidator.h" #include "IndirectDataReductionTab.h" -#include "ui_ISISCalibration.h" #include "MantidKernel/System.h" -#include "../General/UserInputValidator.h" +#include "ui_ISISCalibration.h" namespace MantidQt { namespace CustomInterfaces { @@ -46,6 +46,30 @@ class DLLExport ISISCalibration : public IndirectDataReductionTab { void run() override; bool validate() override; + std::pair peakRange() const; + std::pair backgroundRange() const; + std::pair resolutionRange() const; + + QString peakRangeString() const; + QString backgroundRangeString() const; + QString instrumentDetectorRangeString() const; + QString outputWorkspaceName() const; + QString resolutionDetectorRangeString() const; + QString rebinString() const; + QString backgroundString() const; + + void setPeakRange(const double &peakMin, const double &peakMax, + const QString &minPropertyName, + const QString &maxPropertyName); + void setPeakRange(const double &peakMin, const double &peakMax); + void setBackgroundRange(const double &backgroundMin, + const double &backgroundMax, + const QString &minPropertyName, + const QString &maxPropertyName); + void setBackgroundRange(const double &backgroundMin, + const double &backgroundMax); + void setResolutionSpectraRange(const double &minimum, const double &maximum); + private slots: void algorithmComplete(bool error); void calPlotRaw(); @@ -68,6 +92,14 @@ private slots: private: void createRESfile(const QString &file); + void addRuntimeSmoothing(const QString &workspaceName); + + Mantid::API::IAlgorithm_sptr + calibrationAlgorithm(const QString &inputFiles) const; + Mantid::API::IAlgorithm_sptr + resolutionAlgorithm(const QString &inputFiles) const; + Mantid::API::IAlgorithm_sptr + energyTransferReductionAlgorithm(const QString &inputFiles) const; Ui::ISISCalibration m_uiForm; QString m_lastCalPlotFilename; @@ -76,6 +108,6 @@ private slots: QString m_outputResolutionName; }; } // namespace CustomInterfaces -} // namespace Mantid +} // namespace MantidQt #endif // MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ diff --git a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp index 08fa4a17aa60..e3ee77772ca7 100644 --- a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.cpp @@ -84,7 +84,7 @@ IndirectDataReductionTab::loadInstrumentIfNotExist(std::string instrumentName, * * @return Map of information ID to value */ -QMap IndirectDataReductionTab::getInstrumentDetails() { +QMap IndirectDataReductionTab::getInstrumentDetails() const { return m_idrUI->getInstrumentDetails(); } @@ -94,7 +94,7 @@ QMap IndirectDataReductionTab::getInstrumentDetails() { * @return Instrument config widget */ MantidWidgets::IndirectInstrumentConfig * -IndirectDataReductionTab::getInstrumentConfiguration() { +IndirectDataReductionTab::getInstrumentConfiguration() const { return m_idrUI->m_uiForm.iicInstrumentConfiguration; } diff --git a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h index 32f08cca9971..3d0c5dcd0b7e 100644 --- a/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h +++ b/qt/scientific_interfaces/Indirect/IndirectDataReductionTab.h @@ -95,12 +95,12 @@ public slots: std::string analyser = "", std::string reflection = ""); /// Function to get details about the instrumet from a given workspace - QMap getInstrumentDetails(); + QMap getInstrumentDetails() const; std::map getRangesFromInstrument(QString instName = "", QString analyser = "", QString reflection = ""); /// Get the instrument config widget - MantidWidgets::IndirectInstrumentConfig *getInstrumentConfiguration(); + MantidWidgets::IndirectInstrumentConfig *getInstrumentConfiguration() const; private slots: void tabExecutionComplete(bool error); From 32b9bcfa8816ff78213742514286a849ec901a85 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Wed, 7 Mar 2018 17:53:32 +0000 Subject: [PATCH 099/364] Seperate setting range limits from setting range values Refs #21969 --- .../Indirect/ISISCalibration.cpp | 53 +++++++++++-------- .../Indirect/ISISCalibration.h | 12 ++--- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp index d761d94c6576..89e85f53485b 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp @@ -223,32 +223,41 @@ QString ISISCalibration::backgroundString() const { QString::number(m_dblManager->value(m_properties["ResEnd"])); } -void ISISCalibration::setPeakRange(const double &peakMin, const double &peakMax, - const QString &minPropertyName, - const QString &maxPropertyName) { +void ISISCalibration::setPeak(const double &minimumTof, + const double &maximumTof) { auto calibrationPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); - setRangeSelector(calibrationPeak, m_properties[minPropertyName], - m_properties[maxPropertyName], qMakePair(peakMin, peakMax)); + setRangeSelector(calibrationPeak, m_properties["CalPeakMin"], + m_properties["CalPeakMax"], + qMakePair(minimumTof, maximumTof)); } -void ISISCalibration::setPeakRange(const double &peakMin, - const double &peakMax) { - setPeakRange(peakMin, peakMax, "CalPeakMin", "CalPeakMax"); +void ISISCalibration::setBackground(const double &minimumTof, + const double &maximumTof) { + auto background = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + setRangeSelector(background, m_properties["CalBackMin"], + m_properties["CalBackMax"], + qMakePair(minimumTof, maximumTof)); } -void ISISCalibration::setBackgroundRange(const double &backgroundMin, - const double &backgroundMax, - const QString &minPropertyName, - const QString &maxPropertyName) { - auto background = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); - setRangeSelector(background, m_properties[minPropertyName], - m_properties[maxPropertyName], - qMakePair(backgroundMin, backgroundMax)); +void ISISCalibration::setRange(MantidWidgets::RangeSelector *rangeSelector, + const double &minimum, const double &maximum, + const QString &minPropertyName, + const QString &maxPropertyName) { + setPlotPropertyRange(rangeSelector, m_properties[minPropertyName], + m_properties[maxPropertyName], + qMakePair(minimum, maximum)); +} + +void ISISCalibration::setPeakRange(const double &peakMin, + const double &peakMax) { + auto calibrationPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); + setRange(calibrationPeak, peakMin, peakMax, "CalELow", "CalEHigh"); } void ISISCalibration::setBackgroundRange(const double &backgroundMin, const double &backgroundMax) { - setBackgroundRange(backgroundMin, backgroundMax, "CalBackMin", "CalBackMax"); + auto background = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); + setRange(background, backgroundMin, backgroundMax, "CalStart", "CalEnd"); } void ISISCalibration::setResolutionSpectraRange(const double &minimum, @@ -342,8 +351,8 @@ void ISISCalibration::setDefaultInstDetails() { // Set peak and background ranges const auto ranges = getRangesFromInstrument(); - setPeakRange(ranges.at("peak-start-tof"), ranges.at("peak-end-tof")); - setBackgroundRange(ranges.at("back-start-tof"), ranges.at("back-end-tof")); + setPeak(ranges.at("peak-start-tof"), ranges.at("peak-end-tof")); + setBackground(ranges.at("back-start-tof"), ranges.at("back-end-tof")); } /** @@ -386,9 +395,9 @@ void ISISCalibration::calPlotRaw() { m_uiForm.ppCalibration->resizeX(); const auto &dataX = input->x(0); - setPeakRange(dataX.front(), dataX.back(), "CalELow", "CalEHigh"); - setBackgroundRange(dataX.front(), dataX.back(), "CalStart", "CalEnd"); - + setPeakRange(dataX.front(), dataX.back()); + setBackgroundRange(dataX.front(), dataX.back()); + setDefaultInstDetails(); m_uiForm.ppCalibration->replot(); diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.h b/qt/scientific_interfaces/Indirect/ISISCalibration.h index 5db1d6c82318..6eeb54e64b28 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.h +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.h @@ -58,14 +58,9 @@ class DLLExport ISISCalibration : public IndirectDataReductionTab { QString rebinString() const; QString backgroundString() const; - void setPeakRange(const double &peakMin, const double &peakMax, - const QString &minPropertyName, - const QString &maxPropertyName); + void setPeak(const double &minimumTof, const double &maximumTof); + void setBackground(const double &minimumTof, const double &maximumTof); void setPeakRange(const double &peakMin, const double &peakMax); - void setBackgroundRange(const double &backgroundMin, - const double &backgroundMax, - const QString &minPropertyName, - const QString &maxPropertyName); void setBackgroundRange(const double &backgroundMin, const double &backgroundMax); void setResolutionSpectraRange(const double &minimum, const double &maximum); @@ -93,6 +88,9 @@ private slots: private: void createRESfile(const QString &file); void addRuntimeSmoothing(const QString &workspaceName); + void setRange(MantidWidgets::RangeSelector *rangeSelector, + const double &minimum, const double &maximum, + const QString &minPropertyName, const QString &maxPropertyName); Mantid::API::IAlgorithm_sptr calibrationAlgorithm(const QString &inputFiles) const; From 0e8dcdf1d4d1917128259a365d0e32b6dbac39e5 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 8 Mar 2018 08:59:04 +0000 Subject: [PATCH 100/364] refs #21961 muon analysis can use period algebra in multi fit --- docs/source/release/v3.12.0/muon.rst | 1 + .../Muon/MuonAnalysis.cpp | 12 +- qt/scientific_interfaces/Muon/MuonAnalysis.h | 2 +- .../Common/MuonFitPropertyBrowser.h | 5 +- .../common/src/MuonFitPropertyBrowser.cpp | 132 ++++++++++++++---- 5 files changed, 118 insertions(+), 34 deletions(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 7d06b13be321..aaa951d9d49d 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -26,6 +26,7 @@ Interface - The Frequency Domain Analysis GUI now uses :ref:`CalMuonDetectorPhases ` to create the phase table for PhaseQuad FFTs. - The Frequency Domain Analysis GUI now uses :ref:`MuonMaxent ` to calculate the frequency spectrum in MaxEnt mode. - The ALC interface now allows background sections with negative values. +- The period summation/subtraction can now be used in multiple fitting. Algorithms ---------- diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index f84a85d4fc10..7b0a691979a7 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -517,10 +517,9 @@ std::string MuonAnalysis::getNewAnalysisWSName(ItemType itemType, int tableRow, isItSummed = true; } - // add to list of summed periods if it is not already in the list, is not empty (1 period) and a sum - if (!m_summedPeriods.contains(QString::fromStdString(params.periods)) && params.periods != "" && isItSummed) { - m_summedPeriods << QString::fromStdString(params.periods); - + if (params.periods != "" && isItSummed) { + m_uiForm.fitBrowser->addPeriodCheckboxToMap(QString::fromStdString(params.periods)); + } // Version - always "#1" if overwrite is on, otherwise increment @@ -1116,7 +1115,7 @@ void MuonAnalysis::updatePairTable() { void MuonAnalysis::inputFileChanged_MWRunFiles() { // Handle changed input, then turn buttons back on. handleInputFileChanges(); - m_summedPeriods.clear(); + m_uiForm.fitBrowser->setNumPeriods(m_numPeriods); allowLoading(true); } @@ -2635,7 +2634,8 @@ void MuonAnalysis::changeTab(int newTabIndex) { m_uiForm.fitBrowser->setSingleFitLabel(m_currentDataName.toStdString()); } else { m_uiForm.fitBrowser->setAllGroupsOrPairs(isItGroup); - m_uiForm.fitBrowser->setNumPeriods(m_numPeriods, m_summedPeriods); + m_uiForm.fitBrowser->updatePeriods(); + } if (parsePlotType(m_uiForm.frontPlotFuncs) == PlotType::Asymmetry && isItGroup) { diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.h b/qt/scientific_interfaces/Muon/MuonAnalysis.h index 4d4b715dbf02..26dba9a4fcf2 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.h @@ -580,7 +580,7 @@ private slots: /// set the group/pair name std::string m_groupPairName; - QStringList m_summedPeriods; + }; } } diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index 0b9a67d8f467..ae933c0a1c28 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -129,7 +129,9 @@ public slots: void periodBtnPressed(); void generateBtnPressed(); void combineBtnPressed(); - void setNumPeriods(size_t numPeriods,QStringList summedPeriods); + void setNumPeriods(size_t numPeriods); + void addPeriodCheckboxToMap(const QString &name); + void updatePeriods(); signals: /// Emitted when sequential fit is requested by user @@ -193,6 +195,7 @@ private slots: void setChosenPeriods(const QStringList &chosenPeriods); void clearPeriodCheckboxes(); void addPeriodCheckbox(const QString &name); + void updatePeriods(const int j, const QStringList &selection); /// Splitter for additional widgets and splitter between this and browser QSplitter *m_widgetSplitter, *m_mainSplitter; diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 1c0ed9c9939a..d7a50ee9b481 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1407,7 +1407,7 @@ void MuonFitPropertyBrowser::setAllPeriods() { * Sets checkboxes for periods * @param numPeriods :: [input] Number of periods */ -void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods,QStringList summedPeriods) { +void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods){//,QStringList summedPeriods) { //has to go here to get the original value int j = m_enumManager->value(m_periodsToFit); auto selected = getChosenPeriods(); @@ -1427,11 +1427,7 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods,QStringList summedP QString name = QString::number(i + 1); addPeriodCheckbox(name); } - if (summedPeriods.size() > 0) { - for (auto period : summedPeriods) { - addPeriodCheckbox(period); - } - } + if (m_periodsToFitOptions.size() == 1) { m_generateBtn->setDisabled(true); m_multiFitSettingsGroup->property()->removeSubProperty(m_periodsToFit); @@ -1440,33 +1436,18 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods,QStringList summedP clearChosenPeriods(); m_boolManager->setValue(m_periodBoxes.constBegin().value(), true); } else { - if (j >= m_periodsToFitOptions.size()) { + // for now always reset to all groups when data is changed + // the commented out code can be used to keep the selection when changing run - but has a bug + // if (j >= m_periodsToFitOptions.size()) { //set all groups if the selection is no longer available (0 index) j = 0; - } + //} m_multiFitSettingsGroup->property()->insertSubProperty(m_periodsToFit, m_showGroup); m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods); m_generateBtn->setDisabled(false); - if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { - - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); - m_periodWindow->close(); - setChosenPeriods(selected); - - } - else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); - //explictly set all periods - setAllPeriods(); - } - else { - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); - } + updatePeriods(j, selected); } } @@ -1518,12 +1499,111 @@ void MuonFitPropertyBrowser::clearChosenPeriods() const { m_boolManager->setValue(iter.value(), false); } } +/** +* updates the period displays +*/ +void MuonFitPropertyBrowser::updatePeriods() { + int j = m_enumManager->value(m_periodsToFit); + auto selected = getChosenPeriods(); + updatePeriods(j, selected); +} +/** +* updates the period displays and conserves the selection +* if selection is niot available default to all periods +* @param j :: [input] index of selection in combobox +* @param selected :: [input] list of selected periods +*/ +void MuonFitPropertyBrowser::updatePeriods(const int j, const QStringList &selected) { + if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { + //currently the below does not work reliably (if period arithmatic is presemnt it gives bad results + /* + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + setChosenPeriods(selected);*/ + // lets default to all periods for now + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + //explictly set all periods + setAllPeriods(); + } + else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + //explictly set all periods + setAllPeriods(); + } + else {//single number + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + setChosenPeriods(m_periodsToFitOptions[j]); + + } +} +/** +* Adds a new checkbox to the list of periods with given name +* It updates the display +* @param name :: [input] Name of period to add +*/ +void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { + if (m_periodBoxes.find(name) != m_periodBoxes.end()) { + // if the box already exists + return; + } + //has to go here to get the original value + int j = m_enumManager->value(m_periodsToFit); + auto selected = getChosenPeriods(); + addPeriodCheckbox(name); + updatePeriods(j, selected); +} + /** * Add a new checkbox to the list of periods with given name * The new checkbox is unchecked by default * @param name :: [input] Name of period to add */ void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { + //check period is sensible + //no frational periods + if (name.contains(".")) { + return; + } + else { + auto tmp = name.toStdString(); + std::vector numbers; + auto num = tmp.find(","); + while (num != std::string::npos) { + numbers.push_back(tmp.substr(0,num)); + tmp = tmp.substr(num + 1); + num = tmp.find(","); + } + numbers.push_back(tmp); + //loop over results + for (auto value : numbers) { + auto tmp = value.find("-"); + if (tmp != std::string::npos) { + // find a minus sign + auto before = value.substr(0,tmp); + auto after = value.substr(tmp + 1); + + } + else { + try { + auto num = boost::lexical_cast(value); + auto included = m_periodBoxes.find(QString::fromStdString(value)); + if (m_periodBoxes.find(QString::fromStdString(value)) == m_periodBoxes.end() && numbers.size()>1) { + // if the box does not exist and there is more than 1 period in name + return; + } + } + catch (boost::bad_lexical_cast) { + // none int value + return; + } + + } + } + } + m_periodBoxes.insert(name, m_boolManager->addProperty(name)); int j = m_enumManager->value(m_periodsToFit); // add new period to list will go after inital list From 13db6751fc006735910ad186364f7d30638c6b88 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 8 Mar 2018 09:05:24 +0000 Subject: [PATCH 101/364] refs #21961 clean up muonFitPriopertyBrowser --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index d7a50ee9b481..333c90ccba03 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1407,7 +1407,7 @@ void MuonFitPropertyBrowser::setAllPeriods() { * Sets checkboxes for periods * @param numPeriods :: [input] Number of periods */ -void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods){//,QStringList summedPeriods) { +void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods){ //has to go here to get the original value int j = m_enumManager->value(m_periodsToFit); auto selected = getChosenPeriods(); @@ -1480,8 +1480,9 @@ void MuonFitPropertyBrowser::setAvailablePeriods(const QStringList &periods) { */ void MuonFitPropertyBrowser::clearPeriodCheckboxes() { if (m_periodBoxes.size() > 1) { - for (const auto &checkbox : m_periodBoxes) { - delete (checkbox); + for (auto iter = std::next(m_periodBoxes.constBegin()); + iter != m_periodBoxes.constEnd(); ++iter) { + delete (*iter); } m_periodBoxes.clear(); From d3e88bcb95b484f2652313084cbfe2bdd5fc4447 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 8 Mar 2018 09:29:51 +0000 Subject: [PATCH 102/364] refs #21961 clang for period algebra in multi fit --- .../Muon/MuonAnalysis.cpp | 21 +- qt/scientific_interfaces/Muon/MuonAnalysis.h | 1 - .../common/src/MuonFitPropertyBrowser.cpp | 211 +++++++++--------- 3 files changed, 114 insertions(+), 119 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 7b0a691979a7..f0c79d02ac69 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -513,14 +513,14 @@ std::string MuonAnalysis::getNewAnalysisWSName(ItemType itemType, int tableRow, params.plotType = plotType; params.periods = getPeriodLabels(); bool isItSummed = false; - if (params.periods.find("+") != std::string::npos||params.periods.find("-") != std::string::npos) { - isItSummed = true; - - } - if (params.periods != "" && isItSummed) { - m_uiForm.fitBrowser->addPeriodCheckboxToMap(QString::fromStdString(params.periods)); - - } + if (params.periods.find("+") != std::string::npos || + params.periods.find("-") != std::string::npos) { + isItSummed = true; + } + if (params.periods != "" && isItSummed) { + m_uiForm.fitBrowser->addPeriodCheckboxToMap( + QString::fromStdString(params.periods)); + } // Version - always "#1" if overwrite is on, otherwise increment params.version = 1; @@ -1115,7 +1115,7 @@ void MuonAnalysis::updatePairTable() { void MuonAnalysis::inputFileChanged_MWRunFiles() { // Handle changed input, then turn buttons back on. handleInputFileChanges(); - m_uiForm.fitBrowser->setNumPeriods(m_numPeriods); + m_uiForm.fitBrowser->setNumPeriods(m_numPeriods); allowLoading(true); } @@ -2634,8 +2634,7 @@ void MuonAnalysis::changeTab(int newTabIndex) { m_uiForm.fitBrowser->setSingleFitLabel(m_currentDataName.toStdString()); } else { m_uiForm.fitBrowser->setAllGroupsOrPairs(isItGroup); - m_uiForm.fitBrowser->updatePeriods(); - + m_uiForm.fitBrowser->updatePeriods(); } if (parsePlotType(m_uiForm.frontPlotFuncs) == PlotType::Asymmetry && isItGroup) { diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.h b/qt/scientific_interfaces/Muon/MuonAnalysis.h index 26dba9a4fcf2..58a8384af8b9 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.h @@ -580,7 +580,6 @@ private slots: /// set the group/pair name std::string m_groupPairName; - }; } } diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 333c90ccba03..8de16fdbfc7e 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -55,7 +55,7 @@ #include #include -#include +#include #include namespace { @@ -178,8 +178,8 @@ void MuonFitPropertyBrowser::init() { tmp = "bwd"; addGroupCheckbox(tmp); m_periodsToFit = m_enumManager->addProperty("Periods to fit"); - m_periodsToFitOptions << ALL_PERIODS_LABEL <addProperty("Selected Periods"); m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); @@ -1407,25 +1407,25 @@ void MuonFitPropertyBrowser::setAllPeriods() { * Sets checkboxes for periods * @param numPeriods :: [input] Number of periods */ -void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods){ - //has to go here to get the original value +void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods) { + // has to go here to get the original value int j = m_enumManager->value(m_periodsToFit); auto selected = getChosenPeriods(); - //delete period checkboxes + // delete period checkboxes clearPeriodCheckboxes(); - if (! m_periodsToFitOptions.empty()) { - m_periodsToFitOptions.clear(); + if (!m_periodsToFitOptions.empty()) { + m_periodsToFitOptions.clear(); } - + if (numPeriods > 1) { m_periodsToFitOptions << ALL_PERIODS_LABEL; - m_periodsToFitOptions << CUSTOM_LABEL; + m_periodsToFitOptions << CUSTOM_LABEL; } // create more boxes for (size_t i = 0; i != numPeriods; i++) { - QString name = QString::number(i + 1); - addPeriodCheckbox(name); + QString name = QString::number(i + 1); + addPeriodCheckbox(name); } if (m_periodsToFitOptions.size() == 1) { @@ -1436,19 +1436,19 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods){ clearChosenPeriods(); m_boolManager->setValue(m_periodBoxes.constBegin().value(), true); } else { - // for now always reset to all groups when data is changed - // the commented out code can be used to keep the selection when changing run - but has a bug - // if (j >= m_periodsToFitOptions.size()) { - //set all groups if the selection is no longer available (0 index) - j = 0; - //} + // for now always reset to all groups when data is changed + // the commented out code can be used to keep the selection when changing + // run - but has a bug + // if (j >= m_periodsToFitOptions.size()) { + // set all groups if the selection is no longer available (0 index) + j = 0; + //} m_multiFitSettingsGroup->property()->insertSubProperty(m_periodsToFit, m_showGroup); m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods); m_generateBtn->setDisabled(false); - - updatePeriods(j, selected); + updatePeriods(j, selected); } } /** @@ -1480,12 +1480,11 @@ void MuonFitPropertyBrowser::setAvailablePeriods(const QStringList &periods) { */ void MuonFitPropertyBrowser::clearPeriodCheckboxes() { if (m_periodBoxes.size() > 1) { - for (auto iter = std::next(m_periodBoxes.constBegin()); - iter != m_periodBoxes.constEnd(); ++iter) { - delete (*iter); - } - m_periodBoxes.clear(); - + for (auto iter = std::next(m_periodBoxes.constBegin()); + iter != m_periodBoxes.constEnd(); ++iter) { + delete (*iter); + } + m_periodBoxes.clear(); } m_periodsToFitOptions.clear(); m_periodsToFitOptions << "1"; @@ -1503,10 +1502,10 @@ void MuonFitPropertyBrowser::clearChosenPeriods() const { /** * updates the period displays */ -void MuonFitPropertyBrowser::updatePeriods() { - int j = m_enumManager->value(m_periodsToFit); - auto selected = getChosenPeriods(); - updatePeriods(j, selected); +void MuonFitPropertyBrowser::updatePeriods() { + int j = m_enumManager->value(m_periodsToFit); + auto selected = getChosenPeriods(); + updatePeriods(j, selected); } /** * updates the period displays and conserves the selection @@ -1514,31 +1513,30 @@ void MuonFitPropertyBrowser::updatePeriods() { * @param j :: [input] index of selection in combobox * @param selected :: [input] list of selected periods */ -void MuonFitPropertyBrowser::updatePeriods(const int j, const QStringList &selected) { - if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { - //currently the below does not work reliably (if period arithmatic is presemnt it gives bad results - /* - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); - setChosenPeriods(selected);*/ - // lets default to all periods for now - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); - //explictly set all periods - setAllPeriods(); - } - else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); - //explictly set all periods - setAllPeriods(); - } - else {//single number - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); - setChosenPeriods(m_periodsToFitOptions[j]); - - } +void MuonFitPropertyBrowser::updatePeriods(const int j, + const QStringList &selected) { + if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { + // currently the below does not work reliably (if period arithmatic is + // presemnt it gives bad results + /* + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + setChosenPeriods(selected);*/ + // lets default to all periods for now + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + // explictly set all periods + setAllPeriods(); + } else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + // explictly set all periods + setAllPeriods(); + } else { // single number + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); + setChosenPeriods(m_periodsToFitOptions[j]); + } } /** * Adds a new checkbox to the list of periods with given name @@ -1546,15 +1544,15 @@ void MuonFitPropertyBrowser::updatePeriods(const int j, const QStringList &sele * @param name :: [input] Name of period to add */ void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { - if (m_periodBoxes.find(name) != m_periodBoxes.end()) { - // if the box already exists - return; - } - //has to go here to get the original value - int j = m_enumManager->value(m_periodsToFit); - auto selected = getChosenPeriods(); - addPeriodCheckbox(name); - updatePeriods(j, selected); + if (m_periodBoxes.find(name) != m_periodBoxes.end()) { + // if the box already exists + return; + } + // has to go here to get the original value + int j = m_enumManager->value(m_periodsToFit); + auto selected = getChosenPeriods(); + addPeriodCheckbox(name); + updatePeriods(j, selected); } /** @@ -1563,47 +1561,45 @@ void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { * @param name :: [input] Name of period to add */ void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { - //check period is sensible - //no frational periods - if (name.contains(".")) { - return; - } - else { - auto tmp = name.toStdString(); - std::vector numbers; - auto num = tmp.find(","); - while (num != std::string::npos) { - numbers.push_back(tmp.substr(0,num)); - tmp = tmp.substr(num + 1); - num = tmp.find(","); - } - numbers.push_back(tmp); - //loop over results - for (auto value : numbers) { - auto tmp = value.find("-"); - if (tmp != std::string::npos) { - // find a minus sign - auto before = value.substr(0,tmp); - auto after = value.substr(tmp + 1); - - } - else { - try { - auto num = boost::lexical_cast(value); - auto included = m_periodBoxes.find(QString::fromStdString(value)); - if (m_periodBoxes.find(QString::fromStdString(value)) == m_periodBoxes.end() && numbers.size()>1) { - // if the box does not exist and there is more than 1 period in name - return; - } - } - catch (boost::bad_lexical_cast) { - // none int value - return; - } - - } - } - } + // check period is sensible + // no frational periods + if (name.contains(".")) { + return; + } else { + auto tmp = name.toStdString(); + std::vector numbers; + auto num = tmp.find(","); + while (num != std::string::npos) { + numbers.push_back(tmp.substr(0, num)); + tmp = tmp.substr(num + 1); + num = tmp.find(","); + } + numbers.push_back(tmp); + // loop over results + for (auto value : numbers) { + auto tmp = value.find("-"); + if (tmp != std::string::npos) { + // find a minus sign + auto before = value.substr(0, tmp); + auto after = value.substr(tmp + 1); + + } else { + try { + auto num = boost::lexical_cast(value); + auto included = m_periodBoxes.find(QString::fromStdString(value)); + if (m_periodBoxes.find(QString::fromStdString(value)) == + m_periodBoxes.end() && + numbers.size() > 1) { + // if the box does not exist and there is more than 1 period in name + return; + } + } catch (boost::bad_lexical_cast) { + // none int value + return; + } + } + } + } m_periodBoxes.insert(name, m_boolManager->addProperty(name)); int j = m_enumManager->value(m_periodsToFit); @@ -1614,7 +1610,6 @@ void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); setChosenPeriods(active); m_enumManager->setValue(m_periodsToFit, j); - } /** * Returns a list of the selected periods (checked boxes) @@ -1729,7 +1724,9 @@ void MuonFitPropertyBrowser::combineBtnPressed() { m_negativeCombo->clear(); addPeriodCheckbox(value); int j = m_enumManager->value(m_periodsToFit); - if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { setAllPeriods(); } + if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { + setAllPeriods(); + } } /** * sets the label for a single fit and From 04d182a3b26d8a51288d913410d0d24b8b43c1c5 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Thu, 8 Mar 2018 10:45:38 +0000 Subject: [PATCH 103/364] Add additional check for if resolution file has not been found Refs #21969 --- .../Indirect/ISISCalibration.cpp | 29 ++++++++++--------- .../Indirect/ISISCalibration.h | 10 +++---- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp index 89e85f53485b..880bc3b37cff 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp @@ -223,16 +223,16 @@ QString ISISCalibration::backgroundString() const { QString::number(m_dblManager->value(m_properties["ResEnd"])); } -void ISISCalibration::setPeak(const double &minimumTof, - const double &maximumTof) { +void ISISCalibration::setPeakRange(const double &minimumTof, + const double &maximumTof) { auto calibrationPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); setRangeSelector(calibrationPeak, m_properties["CalPeakMin"], m_properties["CalPeakMax"], qMakePair(minimumTof, maximumTof)); } -void ISISCalibration::setBackground(const double &minimumTof, - const double &maximumTof) { +void ISISCalibration::setBackgroundRange(const double &minimumTof, + const double &maximumTof) { auto background = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); setRangeSelector(background, m_properties["CalBackMin"], m_properties["CalBackMax"], @@ -248,14 +248,14 @@ void ISISCalibration::setRange(MantidWidgets::RangeSelector *rangeSelector, qMakePair(minimum, maximum)); } -void ISISCalibration::setPeakRange(const double &peakMin, - const double &peakMax) { +void ISISCalibration::setPeakRangeLimits(const double &peakMin, + const double &peakMax) { auto calibrationPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); setRange(calibrationPeak, peakMin, peakMax, "CalELow", "CalEHigh"); } -void ISISCalibration::setBackgroundRange(const double &backgroundMin, - const double &backgroundMax) { +void ISISCalibration::setBackgroundRangeLimits(const double &backgroundMin, + const double &backgroundMax) { auto background = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); setRange(background, backgroundMin, backgroundMax, "CalStart", "CalEnd"); } @@ -351,8 +351,8 @@ void ISISCalibration::setDefaultInstDetails() { // Set peak and background ranges const auto ranges = getRangesFromInstrument(); - setPeak(ranges.at("peak-start-tof"), ranges.at("peak-end-tof")); - setBackground(ranges.at("back-start-tof"), ranges.at("back-end-tof")); + setPeakRange(ranges.at("peak-start-tof"), ranges.at("peak-end-tof")); + setBackgroundRange(ranges.at("back-start-tof"), ranges.at("back-end-tof")); } /** @@ -395,8 +395,8 @@ void ISISCalibration::calPlotRaw() { m_uiForm.ppCalibration->resizeX(); const auto &dataX = input->x(0); - setPeakRange(dataX.front(), dataX.back()); - setBackgroundRange(dataX.front(), dataX.back()); + setPeakRangeLimits(dataX.front(), dataX.back()); + setBackgroundRangeLimits(dataX.front(), dataX.back()); setDefaultInstDetails(); @@ -650,7 +650,8 @@ void ISISCalibration::plotClicked() { plotTimeBin(m_outputCalibrationName); checkADSForPlotSaveWorkspace(m_outputCalibrationName.toStdString(), true); QStringList plotWorkspaces; - if (m_uiForm.ckCreateResolution->isChecked()) { + if (m_uiForm.ckCreateResolution->isChecked() && + m_outputResolutionName.isEmpty()) { checkADSForPlotSaveWorkspace(m_outputResolutionName.toStdString(), true); plotWorkspaces.append(m_outputResolutionName); if (m_uiForm.ckSmoothResolution->isChecked()) @@ -675,7 +676,7 @@ ISISCalibration::calibrationAlgorithm(const QString &inputFiles) const { auto calibrationAlg = AlgorithmManager::Instance().create("IndirectCalibration"); calibrationAlg->initialize(); - calibrationAlg->setProperty("InputFiles", inputFiles); + calibrationAlg->setProperty("InputFiles", inputFiles.toStdString()); calibrationAlg->setProperty("OutputWorkspace", m_outputCalibrationName.toStdString()); calibrationAlg->setProperty("DetectorRange", diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.h b/qt/scientific_interfaces/Indirect/ISISCalibration.h index 6eeb54e64b28..0df4b6f2d9ae 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.h +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.h @@ -58,11 +58,11 @@ class DLLExport ISISCalibration : public IndirectDataReductionTab { QString rebinString() const; QString backgroundString() const; - void setPeak(const double &minimumTof, const double &maximumTof); - void setBackground(const double &minimumTof, const double &maximumTof); - void setPeakRange(const double &peakMin, const double &peakMax); - void setBackgroundRange(const double &backgroundMin, - const double &backgroundMax); + void setPeakRange(const double &minimumTof, const double &maximumTof); + void setBackgroundRange(const double &minimumTof, const double &maximumTof); + void setPeakRangeLimits(const double &peakMin, const double &peakMax); + void setBackgroundRangeLimits(const double &backgroundMin, + const double &backgroundMax); void setResolutionSpectraRange(const double &minimum, const double &maximum); private slots: From ce474bd9de9b0cd80d7c8dcd1cb33429af51898d Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 8 Mar 2018 11:10:48 +0000 Subject: [PATCH 104/364] refs #21961 rm unused variables for period algebra in multi fit --- .../Common/MuonFitPropertyBrowser.h | 2 +- .../common/src/MuonFitPropertyBrowser.cpp | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index ae933c0a1c28..fe70a62bf479 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -195,7 +195,7 @@ private slots: void setChosenPeriods(const QStringList &chosenPeriods); void clearPeriodCheckboxes(); void addPeriodCheckbox(const QString &name); - void updatePeriods(const int j, const QStringList &selection); + void updatePeriods(const int j); /// Splitter for additional widgets and splitter between this and browser QSplitter *m_widgetSplitter, *m_mainSplitter; diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 8de16fdbfc7e..c338b3715d4d 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1448,7 +1448,7 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods) { m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods); m_generateBtn->setDisabled(false); - updatePeriods(j, selected); + updatePeriods(j);// , selected); } } /** @@ -1504,17 +1504,19 @@ void MuonFitPropertyBrowser::clearChosenPeriods() const { */ void MuonFitPropertyBrowser::updatePeriods() { int j = m_enumManager->value(m_periodsToFit); - auto selected = getChosenPeriods(); - updatePeriods(j, selected); + //auto selected = getChosenPeriods(); + updatePeriods(j); } /** * updates the period displays and conserves the selection * if selection is niot available default to all periods * @param j :: [input] index of selection in combobox -* @param selected :: [input] list of selected periods +* selected is an input for changing runs and preserving selection (list of selected periods) +* currently has a bug */ -void MuonFitPropertyBrowser::updatePeriods(const int j, - const QStringList &selected) { +void MuonFitPropertyBrowser::updatePeriods(const int j){ + // this is for switching but has a bug at the moment +//const QStringList &selected) { if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { // currently the below does not work reliably (if period arithmatic is // presemnt it gives bad results @@ -1550,9 +1552,9 @@ void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { } // has to go here to get the original value int j = m_enumManager->value(m_periodsToFit); - auto selected = getChosenPeriods(); + //auto selected = getChosenPeriods(); addPeriodCheckbox(name); - updatePeriods(j, selected); + updatePeriods(j); } /** @@ -1585,8 +1587,7 @@ void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { } else { try { - auto num = boost::lexical_cast(value); - auto included = m_periodBoxes.find(QString::fromStdString(value)); + boost::lexical_cast(value); if (m_periodBoxes.find(QString::fromStdString(value)) == m_periodBoxes.end() && numbers.size() > 1) { From 4f80c4018264de57a5b2c0cb95bd72b4810bcd7a Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 8 Mar 2018 11:14:06 +0000 Subject: [PATCH 105/364] refs #21961 clang d variables for period algebra in multi fit --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index c338b3715d4d..0b86588f8f1f 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1448,7 +1448,7 @@ void MuonFitPropertyBrowser::setNumPeriods(size_t numPeriods) { m_multiFitSettingsGroup->property()->addSubProperty(m_showPeriods); m_generateBtn->setDisabled(false); - updatePeriods(j);// , selected); + updatePeriods(j); // , selected); } } /** @@ -1504,19 +1504,20 @@ void MuonFitPropertyBrowser::clearChosenPeriods() const { */ void MuonFitPropertyBrowser::updatePeriods() { int j = m_enumManager->value(m_periodsToFit); - //auto selected = getChosenPeriods(); + // auto selected = getChosenPeriods(); updatePeriods(j); } /** * updates the period displays and conserves the selection * if selection is niot available default to all periods * @param j :: [input] index of selection in combobox -* selected is an input for changing runs and preserving selection (list of selected periods) +* selected is an input for changing runs and preserving selection (list of +* selected periods) * currently has a bug */ -void MuonFitPropertyBrowser::updatePeriods(const int j){ - // this is for switching but has a bug at the moment -//const QStringList &selected) { +void MuonFitPropertyBrowser::updatePeriods(const int j) { + // this is for switching but has a bug at the moment + // const QStringList &selected) { if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { // currently the below does not work reliably (if period arithmatic is // presemnt it gives bad results @@ -1552,7 +1553,7 @@ void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { } // has to go here to get the original value int j = m_enumManager->value(m_periodsToFit); - //auto selected = getChosenPeriods(); + // auto selected = getChosenPeriods(); addPeriodCheckbox(name); updatePeriods(j); } From db894980c583f1878b1569e9101cf8ff5bf0af1f Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Thu, 8 Mar 2018 16:55:28 +0100 Subject: [PATCH 106/364] Fix a broken link in UnitFactory.rst. --- docs/source/concepts/UnitFactory.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/concepts/UnitFactory.rst b/docs/source/concepts/UnitFactory.rst index fa884d662317..60c483028f2f 100644 --- a/docs/source/concepts/UnitFactory.rst +++ b/docs/source/concepts/UnitFactory.rst @@ -61,7 +61,7 @@ here is the Bragg scattering angle (e.g. half of the Mantid z-axis) **Note on Wavelength**: If the emode property in -:ref: `ConvertUnits ` +:ref:`ConvertUnits ` is specified as inelastic Direct/Indirect (inelastic) then the conversion to wavelength will take into account the fixed initial/final energy respectively. Units conversion into elastic momentum transfer From 7314a5d9c110003dc1b6ef05fe2cb432d0c7d955 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Fri, 9 Mar 2018 10:55:31 +0000 Subject: [PATCH 107/364] Re #20991: Applied autopep8 to l2q.py --- .../Reflectometry/isis_reflectometry/l2q.py | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/scripts/Reflectometry/isis_reflectometry/l2q.py b/scripts/Reflectometry/isis_reflectometry/l2q.py index b192b4ef490e..79aba311d21b 100644 --- a/scripts/Reflectometry/isis_reflectometry/l2q.py +++ b/scripts/Reflectometry/isis_reflectometry/l2q.py @@ -1,11 +1,11 @@ -#pylint: disable=invalid-name +# pylint: disable=invalid-name from __future__ import (absolute_import, division, print_function) import math from mantid.simpleapi import * # New API -def l2q(ws,whichDet,theta, sample_component_name): +def l2q(ws, whichDet, theta, sample_component_name): ''' call signature::call signature:: @@ -33,30 +33,41 @@ def l2q(ws,whichDet,theta, sample_component_name): else: inst = ws.getInstrument() - sampleLocation=inst.getComponentByName(sample_component_name).getPos() - detLocation=inst.getComponentByName(whichDet).getPos() - sample2detector=detLocation-sampleLocation # meters + sampleLocation = inst.getComponentByName(sample_component_name).getPos() + detLocation = inst.getComponentByName(whichDet).getPos() + sample2detector = detLocation - sampleLocation # meters - theta=theta*math.pi/180.0 # convert to radians + theta = theta * math.pi / 180.0 # convert to radians # Fetch the reference frame to determine the instrument orientation. reference_frame = inst.getReferenceFrame() - sample_to_detector_along_beam = sample2detector.scalar_prod( reference_frame.vecPointingAlongBeam() ) + sample_to_detector_along_beam = sample2detector.scalar_prod( + reference_frame.vecPointingAlongBeam()) # calculate new detector position based on angle theta in degrees: - across_offset = 0.0 # Across the beam (side to side) - up_offset = sample_to_detector_along_beam * math.sin(2.0 * theta) # Normal to the beam (up) - beam_offset = detLocation.scalar_prod( reference_frame.vecPointingAlongBeam() ) + # Across the beam (side to side) + across_offset = 0.0 + up_offset = sample_to_detector_along_beam * \ + math.sin(2.0 * theta) # Normal to the beam (up) + beam_offset = detLocation.scalar_prod( + reference_frame.vecPointingAlongBeam()) coord_args = dict() - coord_args[ reference_frame.pointingAlongBeamAxis() ] = beam_offset - coord_args[ reference_frame.pointingUpAxis() ] = up_offset - coord_args[ reference_frame.pointingHorizontalAxis() ] = across_offset + coord_args[reference_frame.pointingAlongBeamAxis()] = beam_offset + coord_args[reference_frame.pointingUpAxis()] = up_offset + coord_args[reference_frame.pointingHorizontalAxis()] = across_offset logger.information('Correcting detector location') - MoveInstrumentComponent(ws, ComponentName=whichDet, RelativePosition=False, **coord_args ) + MoveInstrumentComponent( + ws, + ComponentName=whichDet, + RelativePosition=False, + **coord_args) # Now convert to momentum transfer - IvsQ = ConvertUnits(InputWorkspace=ws,OutputWorkspace="IvsQ",Target="MomentumTransfer") + IvsQ = ConvertUnits( + InputWorkspace=ws, + OutputWorkspace="IvsQ", + Target="MomentumTransfer") return IvsQ From 2f6baba49b2ea5c7c6eba7f27a6ed3284d3fbbef Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Fri, 9 Mar 2018 11:39:22 +0000 Subject: [PATCH 108/364] Re #20991: Updated reference file for L2QScriptTest. --- .../tests/analysis/reference/L2QReferenceResult.nxs.md5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 index 309459a3b1c4..c8a896ea2aab 100644 --- a/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 @@ -1 +1 @@ -57144b9309c8dbb1232a15c6daa2e904 \ No newline at end of file +ab91c31c3afe4344448163c936a6aabb From 54a947eead8496d9a62b04beaa03e048ce3fd549 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Fri, 9 Mar 2018 13:22:21 +0000 Subject: [PATCH 109/364] Re #20991: Fixed ReflQuick System Tests. --- .../tests/analysis/reference/QuickReferenceResult.nxs.md5 | 2 +- .../analysis/reference/QuickStitchedReferenceResult.nxs.md5 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 index 74079775cfa0..ddecb58026e8 100644 --- a/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 @@ -1 +1 @@ -24e66b8ccfde55c58ac97d71d736211d \ No newline at end of file +db61a5ead517dff760aefd84be6d3489 diff --git a/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 index 7966506607d9..5e2740f55973 100644 --- a/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 @@ -1 +1 @@ -8f7725692c8f287ce01b8648e64e70b2 \ No newline at end of file +af5615a686637e41b40acac5dcfbd1c2 From ecb0553f6feaae6be3cf8247aaa572dc8381a92a Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 13:25:41 +0000 Subject: [PATCH 110/364] Update MC Absorption Corrections interface to be consistent with PP Refs #22026 --- .../Indirect/AbsorptionCorrections.ui | 144 +++++++++++++----- 1 file changed, 109 insertions(+), 35 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui index 8048002f1c94..0d9373a92a97 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui @@ -6,8 +6,8 @@ 0 0 - 803 - 689 + 846 + 758 @@ -272,7 +272,7 @@ - 0 + 2 @@ -600,6 +600,9 @@ + + false + Container Outer Radius @@ -634,13 +637,27 @@ Sample Details - + Chemical Formula: + + + + + Mass Density + + + + + Number Density + + + + @@ -657,21 +674,7 @@ - - - - - Mass Density - - - - - Number Density - - - - - + @@ -681,6 +684,26 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + @@ -707,6 +730,26 @@ + + + + Chemical Formula: + + + + + + + false + + + + 0 + 0 + + + + @@ -727,22 +770,22 @@ - - - Chemical Formula: + + + Qt::Horizontal - - - - - - false + + + 40 + 20 + - - - 0 - 0 - + + + + + + @@ -761,13 +804,45 @@ Output Options + + + + Plot Output: + + + + + + + false + + + false + + + + Wavelength + + + + + Angle + + + + + Both + + + + false - Plot Result + Plot @@ -824,7 +899,6 @@ cbCanDensity spCanDensity leCanChemicalFormula - pbPlot pbSave From 16558ece830996be129c67b88e41a3326f9c7767 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 13:28:36 +0000 Subject: [PATCH 111/364] Ensure FlatPlate group box is selected initially Refs #22026 --- qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui index 0d9373a92a97..384101014d97 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui @@ -272,7 +272,7 @@ - 2 + 0 From 6f9e3d2278848d339aea51ba02cb2f6d02dff905 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 13:33:00 +0000 Subject: [PATCH 112/364] Update Calculate Monte Carlo Absorption to plot selected output Refs #22026 --- .../Indirect/AbsorptionCorrections.cpp | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index a473f5a6cfc4..f15957be4db5 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -212,9 +212,11 @@ bool AbsorptionCorrections::validate() { } if (uiv.checkFieldIsNotEmpty("Sample Chemical Formula", - m_uiForm.leSampleChemicalFormula)) + m_uiForm.leSampleChemicalFormula, + m_uiForm.valSampleChemicalFormula)) uiv.checkFieldIsValid("Sample Chemical Formula", - m_uiForm.leSampleChemicalFormula); + m_uiForm.leSampleChemicalFormula, + m_uiForm.valCanChemicalFormula); const auto sampleChem = m_uiForm.leSampleChemicalFormula->text().toStdString(); const auto containerChem = @@ -332,22 +334,15 @@ void AbsorptionCorrections::saveClicked() { * Handle mantid plotting */ void AbsorptionCorrections::plotClicked() { + QString plotType = m_uiForm.cbPlotOutput->currentText(); - QStringList plotData = {QString::fromStdString(m_pythonExportWsName), - m_uiForm.dsSampleInput->getCurrentDataName()}; - auto outputFactorsWsName = - m_absCorAlgo->getPropertyValue("CorrectionsWorkspace"); + if (checkADSForPlotSaveWorkspace(m_pythonExportWsName, true)) { + if (plotType == "Both" || plotType == "Wavelength") + plotSpectrum(QString::fromStdString(m_pythonExportWsName)); - QStringList plotCorr = {QString::fromStdString(outputFactorsWsName) + "_ass"}; - if (m_uiForm.ckUseCan->isChecked()) { - plotCorr.push_back(QString::fromStdString(outputFactorsWsName) + "_acc"); - QString shiftedWs = QString::fromStdString( - m_absCorAlgo->getPropertyValue("ContainerWorkspace")); - plotData.push_back(shiftedWs); + if (plotType == "Both" || plotType == "Angle") + plotTimeBin(QString::fromStdString(m_pythonExportWsName)); } - plotSpectrum(plotCorr, 0); - - plotSpectrum(plotData, 0); } /** From 331daff7f2674ae3ad6d66204514b6a50ad9f792 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 13:40:12 +0000 Subject: [PATCH 113/364] Update the release notes Refs #22026 --- docs/source/release/v3.12.0/indirect_inelastic.rst | 2 ++ qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/indirect_inelastic.rst b/docs/source/release/v3.12.0/indirect_inelastic.rst index 7e53ea32e60f..e40b70b3b4e0 100644 --- a/docs/source/release/v3.12.0/indirect_inelastic.rst +++ b/docs/source/release/v3.12.0/indirect_inelastic.rst @@ -108,6 +108,8 @@ Improved :class: screenshot :width: 800px +- Result plotting in the Calculate Monte Carlo Absorption interface is now the same as that in Apply Absorption Correction; ability to select whether to plot result in Wavelength, Angle or Both. + Bugfixes ######## - In the Calculate Paalman Pings tab of the Indirect Correction interface the container back thickness is now set correctly. diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index f15957be4db5..28f1a904480c 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -334,7 +334,7 @@ void AbsorptionCorrections::saveClicked() { * Handle mantid plotting */ void AbsorptionCorrections::plotClicked() { - QString plotType = m_uiForm.cbPlotOutput->currentText(); + const auto plotType = m_uiForm.cbPlotOutput->currentText(); if (checkADSForPlotSaveWorkspace(m_pythonExportWsName, true)) { if (plotType == "Both" || plotType == "Wavelength") From 47add8b67c8069f9a203db87fe07449951057687 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 16:27:55 +0000 Subject: [PATCH 114/364] Fix structure and tab order in Calculate Monte Carlo Absorption Refs #22026 --- .../Indirect/AbsorptionCorrections.ui | 117 ++++++++++-------- 1 file changed, 66 insertions(+), 51 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui index 384101014d97..f1b2bac10c53 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.ui @@ -6,7 +6,7 @@ 0 0 - 846 + 827 758 @@ -637,25 +637,21 @@ Sample Details - + Chemical Formula: - - - - - Mass Density - - - - - Number Density - - + + + + + 0 + 0 + + @@ -674,31 +670,37 @@ + + + + + Mass Density + + + + + Number Density + + + + - + - + 0 0 - - - - - - Qt::Horizontal - - + - 40 - 20 + 0 + 0 - - - - + + 0 + @@ -731,13 +733,6 @@ - - - Chemical Formula: - - - - false @@ -750,6 +745,13 @@ + + + + Chemical Formula: + + + @@ -769,21 +771,23 @@ - - - - Qt::Horizontal + + + + false - + + + 0 + 0 + + + - 40 - 20 + 0 + 0 - - - - @@ -885,20 +889,31 @@ ckUseCan spNumberWavelengths spNumberEvents + spBeamHeight spBeamWidth cbShape + spFlatSampleHeight spFlatSampleWidth + spFlatSampleThickness + spFlatSampleAngle + spFlatCanFrontThickness + spFlatCanBackThickness + spCylSampleHeight + spCylSampleRadius + spCylCanOuterRadius + spAnnSampleHeight spAnnSampleInnerRadius spAnnSampleOuterRadius spAnnCanInnerRadius spAnnCanOuterRadius - spCylSampleRadius + leSampleChemicalFormula + leCanChemicalFormula cbSampleDensity spSampleDensity - leSampleChemicalFormula cbCanDensity spCanDensity - leCanChemicalFormula + cbPlotOutput + pbPlot pbSave From 9c1e8695256635ed8303cd97573d762a2ab64234 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 16:28:48 +0000 Subject: [PATCH 115/364] Ensure validation is done at the correct times Refs #22026 --- .../Indirect/AbsorptionCorrections.cpp | 57 ++++++++++++------- .../Indirect/AbsorptionCorrections.h | 3 + 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index 28f1a904480c..51af4174bdf6 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -1,5 +1,4 @@ #include "AbsorptionCorrections.h" -#include "../General/UserInputValidator.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidGeometry/Instrument.h" @@ -41,9 +40,16 @@ AbsorptionCorrections::AbsorptionCorrections(QWidget *parent) SLOT(changeSampleDensityUnit(int))); connect(m_uiForm.cbCanDensity, SIGNAL(currentIndexChanged(int)), this, SLOT(changeCanDensityUnit(int))); + + connect(m_uiForm.leSampleChemicalFormula, SIGNAL(editingFinished()), this, + SLOT(doValidation())); + connect(m_uiForm.leCanChemicalFormula, SIGNAL(editingFinished()), this, + SLOT(doValidation())); + connect(m_uiForm.ckUseCan, SIGNAL(stateChanged(int)), this, + SLOT(doValidation())); } -void AbsorptionCorrections::setup() {} +void AbsorptionCorrections::setup() { doValidation(); } void AbsorptionCorrections::run() { // Get correct corrections algorithm @@ -197,6 +203,18 @@ void AbsorptionCorrections::addShapeSpecificCanOptions(IAlgorithm_sptr alg, } bool AbsorptionCorrections::validate() { + UserInputValidator uiv = doValidation(); + + // Give error for failed validation + if (!uiv.isAllInputValid()) { + QString error = uiv.generateErrorMessage(); + showMessageBox(error); + } + + return uiv.isAllInputValid(); +} + +UserInputValidator AbsorptionCorrections::doValidation() { UserInputValidator uiv; uiv.checkDataSelectorIsValid("Sample", m_uiForm.dsSampleInput); @@ -216,7 +234,7 @@ bool AbsorptionCorrections::validate() { m_uiForm.valSampleChemicalFormula)) uiv.checkFieldIsValid("Sample Chemical Formula", m_uiForm.leSampleChemicalFormula, - m_uiForm.valCanChemicalFormula); + m_uiForm.valSampleChemicalFormula); const auto sampleChem = m_uiForm.leSampleChemicalFormula->text().toStdString(); const auto containerChem = @@ -226,16 +244,20 @@ bool AbsorptionCorrections::validate() { } catch (std::runtime_error &ex) { UNUSED_ARG(ex); uiv.addErrorMessage("Chemical Formula for Sample was not recognised."); - } - try { - Mantid::Kernel::Material::parseChemicalFormula(containerChem); - } catch (std::runtime_error &ex) { - UNUSED_ARG(ex); - uiv.addErrorMessage("Chemical Formula for Container was not recognised."); + uiv.setErrorLabel(m_uiForm.valSampleChemicalFormula, false); } bool useCan = m_uiForm.ckUseCan->isChecked(); if (useCan) { + try { + Mantid::Kernel::Material::parseChemicalFormula(containerChem); + } + catch (std::runtime_error &ex) { + UNUSED_ARG(ex); + uiv.addErrorMessage("Chemical Formula for Container was not recognised."); + uiv.setErrorLabel(m_uiForm.valCanChemicalFormula, false); + } + uiv.checkDataSelectorIsValid("Container", m_uiForm.dsCanInput); const auto containerWsName = @@ -250,19 +272,16 @@ bool AbsorptionCorrections::validate() { } if (uiv.checkFieldIsNotEmpty("Container Chemical Formula", - m_uiForm.leCanChemicalFormula)) { + m_uiForm.leCanChemicalFormula, + m_uiForm.valCanChemicalFormula)) { uiv.checkFieldIsValid("Container Chemical Formula", - m_uiForm.leCanChemicalFormula); + m_uiForm.leCanChemicalFormula, + m_uiForm.valCanChemicalFormula); } - } + } else + uiv.setErrorLabel(m_uiForm.valCanChemicalFormula, true); - // Give error for failed validation - if (!uiv.isAllInputValid()) { - QString error = uiv.generateErrorMessage(); - showMessageBox(error); - } - - return uiv.isAllInputValid(); + return uiv; } void AbsorptionCorrections::loadSettings(const QSettings &settings) { diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h index 8bb0e33c91dd..f0b38bab5169 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h @@ -4,6 +4,8 @@ #include "ui_AbsorptionCorrections.h" #include "CorrectionsTab.h" +#include "../General/UserInputValidator.h" + namespace MantidQt { namespace CustomInterfaces { class DLLExport AbsorptionCorrections : public CorrectionsTab { @@ -25,6 +27,7 @@ private slots: void getBeamDefaults(const QString &dataName); void changeSampleDensityUnit(int); void changeCanDensityUnit(int); + UserInputValidator doValidation(); private: void addSaveWorkspace(QString wsName); From c928aa63cc5ff6d34493522814c6f4fee43f34a0 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Fri, 9 Mar 2018 16:30:32 +0000 Subject: [PATCH 116/364] Numerical derivatives must apply ties after parameter shift. Re #22004 --- Framework/API/src/IFunction.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Framework/API/src/IFunction.cpp b/Framework/API/src/IFunction.cpp index ca4687f773f0..7d9a3509d7e5 100644 --- a/Framework/API/src/IFunction.cpp +++ b/Framework/API/src/IFunction.cpp @@ -944,6 +944,7 @@ void IFunction::calNumericalDeriv(const FunctionDomain &domain, applyTies(); function(domain, plusStep); setActiveParameter(iP, val); + applyTies(); } step = paramPstep - val; From ba71a9e61063c65ce4ac7af5215a60001f4d7d55 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 16:43:10 +0000 Subject: [PATCH 117/364] Apply ClangFormat change Refs #22026 --- qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index 51af4174bdf6..c739d6a68b39 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -251,8 +251,7 @@ UserInputValidator AbsorptionCorrections::doValidation() { if (useCan) { try { Mantid::Kernel::Material::parseChemicalFormula(containerChem); - } - catch (std::runtime_error &ex) { + } catch (std::runtime_error &ex) { UNUSED_ARG(ex); uiv.addErrorMessage("Chemical Formula for Container was not recognised."); uiv.setErrorLabel(m_uiForm.valCanChemicalFormula, false); From d3102c23bf6e145f8630d6ea8f955e017fee295d Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Fri, 9 Mar 2018 16:56:02 +0000 Subject: [PATCH 118/364] refs #22020 fixed browse button for muon sequential fit --- docs/source/release/v3.12.0/muon.rst | 1 + .../Muon/MuonSequentialFitDialog.cpp | 45 ++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 5343f131ac60..345b8a782060 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -27,6 +27,7 @@ Interface - The Frequency Domain Analysis GUI now uses :ref:`CalMuonDetectorPhases ` to create the phase table for PhaseQuad FFTs. - The Frequency Domain Analysis GUI now uses :ref:`MuonMaxent ` to calculate the frequency spectrum in MaxEnt mode. - The ALC interface now allows background sections with negative values. +- Muon analysis no longer crashes when using the browse button in sequential fitting. Algorithms ---------- diff --git a/qt/scientific_interfaces/Muon/MuonSequentialFitDialog.cpp b/qt/scientific_interfaces/Muon/MuonSequentialFitDialog.cpp index 394cc3f97249..a375818532d4 100644 --- a/qt/scientific_interfaces/Muon/MuonSequentialFitDialog.cpp +++ b/qt/scientific_interfaces/Muon/MuonSequentialFitDialog.cpp @@ -20,20 +20,41 @@ using MantidQt::MantidWidgets::MuonFitPropertyBrowser; namespace { Logger g_log("MuonSequentialFitDialog"); + +std::string removeSubPath(const std::string &labelIn) { + size_t path = labelIn.find_last_of("/"); + if (path == std::string::npos) { + path = labelIn.find_last_of('\\'); + } + std::string useThisLabel = labelIn; + if (path != std::string::npos) { + path = path + 1; + size_t end = labelIn.find_last_of("."); + useThisLabel = labelIn.substr(path); + useThisLabel = useThisLabel.substr(0, end - path); + size_t start = useThisLabel.find_first_of("0123456789"); + useThisLabel = useThisLabel.substr(start); + } + return useThisLabel; +} + std::string removePath(const std::string &labelIn) { - size_t path = labelIn.find_last_of("/"); - if (path == std::string::npos) { - path = labelIn.find_last_of('\\'); - } - std::string useThisLabel = labelIn; - if (path != std::string::npos) { - path = path + 1; - size_t end = labelIn.find_last_of("."); - useThisLabel = labelIn.substr(path); - useThisLabel = useThisLabel.substr(0, end - path); - auto test = useThisLabel; + std::string useThisLabel; + std::string tmp = labelIn; + size_t end = tmp.find_first_of(","); // always seperate by commas + + if (end != std::string::npos) { + while (end != std::string::npos) { + useThisLabel += removeSubPath(tmp.substr(0, end))+","; + tmp = tmp.substr(end+1); + end = tmp.find_first_of(","); + } + //get the last input + useThisLabel += removeSubPath(tmp); + return useThisLabel; + } - return useThisLabel; + return removeSubPath(labelIn); } } const std::string MuonSequentialFitDialog::SEQUENTIAL_PREFIX("MuonSeqFit_"); From 0c64896d4708befc848c26560ff8989347dd319b Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 17:18:32 +0000 Subject: [PATCH 119/364] Validate container chemical formula after validating field Refs #22026 --- .../Indirect/AbsorptionCorrections.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index c739d6a68b39..dc3ecc135610 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -237,8 +237,6 @@ UserInputValidator AbsorptionCorrections::doValidation() { m_uiForm.valSampleChemicalFormula); const auto sampleChem = m_uiForm.leSampleChemicalFormula->text().toStdString(); - const auto containerChem = - m_uiForm.leCanChemicalFormula->text().toStdString(); try { Mantid::Kernel::Material::parseChemicalFormula(sampleChem); } catch (std::runtime_error &ex) { @@ -249,14 +247,8 @@ UserInputValidator AbsorptionCorrections::doValidation() { bool useCan = m_uiForm.ckUseCan->isChecked(); if (useCan) { - try { - Mantid::Kernel::Material::parseChemicalFormula(containerChem); - } catch (std::runtime_error &ex) { - UNUSED_ARG(ex); - uiv.addErrorMessage("Chemical Formula for Container was not recognised."); - uiv.setErrorLabel(m_uiForm.valCanChemicalFormula, false); - } - + const auto containerChem = + m_uiForm.leCanChemicalFormula->text().toStdString(); uiv.checkDataSelectorIsValid("Container", m_uiForm.dsCanInput); const auto containerWsName = @@ -277,6 +269,15 @@ UserInputValidator AbsorptionCorrections::doValidation() { m_uiForm.leCanChemicalFormula, m_uiForm.valCanChemicalFormula); } + + try { + Mantid::Kernel::Material::parseChemicalFormula(containerChem); + } + catch (std::runtime_error &ex) { + UNUSED_ARG(ex); + uiv.addErrorMessage("Chemical Formula for Container was not recognised."); + uiv.setErrorLabel(m_uiForm.valCanChemicalFormula, false); + } } else uiv.setErrorLabel(m_uiForm.valCanChemicalFormula, true); From 7f8eee8ec3f86f55d35ae39503536c19ae8f7c29 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 17:24:09 +0000 Subject: [PATCH 120/364] Apply ClangFormat Changes Refs #22026 --- qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index dc3ecc135610..62df3a6b8130 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -248,7 +248,7 @@ UserInputValidator AbsorptionCorrections::doValidation() { bool useCan = m_uiForm.ckUseCan->isChecked(); if (useCan) { const auto containerChem = - m_uiForm.leCanChemicalFormula->text().toStdString(); + m_uiForm.leCanChemicalFormula->text().toStdString(); uiv.checkDataSelectorIsValid("Container", m_uiForm.dsCanInput); const auto containerWsName = @@ -272,8 +272,7 @@ UserInputValidator AbsorptionCorrections::doValidation() { try { Mantid::Kernel::Material::parseChemicalFormula(containerChem); - } - catch (std::runtime_error &ex) { + } catch (std::runtime_error &ex) { UNUSED_ARG(ex); uiv.addErrorMessage("Chemical Formula for Container was not recognised."); uiv.setErrorLabel(m_uiForm.valCanChemicalFormula, false); From efdb01e4b6cf919603d0c2aa97cde8466d98f8e8 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 17:26:25 +0000 Subject: [PATCH 121/364] Enable plot option drop-down menu Refs #22026 --- qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index 62df3a6b8130..8dbc34f79d69 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -301,6 +301,7 @@ void AbsorptionCorrections::algorithmComplete(bool error) { // Enable plot and save m_uiForm.pbPlot->setEnabled(true); + m_uiForm.cbPlotOutput->setEnabled(true); m_uiForm.pbSave->setEnabled(true); } From a3e0bc45c8da4d927874bf94a6153519394166ad Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Fri, 9 Mar 2018 17:54:56 +0000 Subject: [PATCH 122/364] Update plot output to show sample unit (not necessarily wavelength) Refs #22026 --- qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index 8dbc34f79d69..76667c40bd7d 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -1,5 +1,6 @@ #include "AbsorptionCorrections.h" +#include "MantidAPI/Axis.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidGeometry/Instrument.h" #include "MantidKernel/Material.h" @@ -314,6 +315,9 @@ void AbsorptionCorrections::getBeamDefaults(const QString &dataName) { return; } + auto unit = sampleWs->getAxis(0)->unit()->unitID(); + m_uiForm.cbPlotOutput->setItemText(0, QString::fromStdString(unit)); + auto instrument = sampleWs->getInstrument(); const std::string beamWidthParamName = "Workflow.beam-width"; if (instrument->hasParameter(beamWidthParamName)) { @@ -354,6 +358,8 @@ void AbsorptionCorrections::saveClicked() { */ void AbsorptionCorrections::plotClicked() { const auto plotType = m_uiForm.cbPlotOutput->currentText(); + const auto sampleWSName = + m_uiForm.dsSampleInput->getCurrentDataName().toStdString(); if (checkADSForPlotSaveWorkspace(m_pythonExportWsName, true)) { if (plotType == "Both" || plotType == "Wavelength") From 79762fb419722ee9d03c9f597ee028fe83eeb039 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Sun, 11 Mar 2018 15:27:56 +0000 Subject: [PATCH 123/364] Initialize ReferenceFrame::thetaSign in all constructors Use delegating constructors to remove common init and remove duplicate check for up and beam direction being the same. --- .../Instrument/ReferenceFrame.h | 2 - .../src/Instrument/ReferenceFrame.cpp | 101 ++++++++---------- 2 files changed, 43 insertions(+), 60 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h index aa40ca05e075..444e77c69a33 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ReferenceFrame.h @@ -79,8 +79,6 @@ class DLLExport ReferenceFrame { bool isVectorPointingAlongBeam(const Mantid::Kernel::V3D &v) const; private: - /// Common setup - void init(); /// Disabled assignment ReferenceFrame &operator=(const ReferenceFrame &); /// Pointing up axis diff --git a/Framework/Geometry/src/Instrument/ReferenceFrame.cpp b/Framework/Geometry/src/Instrument/ReferenceFrame.cpp index a9c128f12806..520aafe8cd56 100644 --- a/Framework/Geometry/src/Instrument/ReferenceFrame.cpp +++ b/Framework/Geometry/src/Instrument/ReferenceFrame.cpp @@ -6,65 +6,15 @@ using namespace Mantid::Kernel; namespace Mantid { namespace Geometry { -//---------------------------------------------------------------------------------------------- -/** Constructor -@param up : pointing up axis -@param alongBeam : axis pointing along the beam -@param handedness : Handedness -@param origin : origin -*/ -ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam, - Handedness handedness, std::string origin) - : m_up(up), m_alongBeam(alongBeam), m_thetaSign(up), - m_handedness(handedness), m_origin(origin) { - if (up == alongBeam) { - throw std::invalid_argument( - "Cannot have up direction the same as the beam direction"); - } - init(); -} - -//---------------------------------------------------------------------------------------------- -/** Constructor -@param up : pointing up axis -@param alongBeam : axis pointing along the beam -@param thetaSign : axis defining the sign of 2theta -@param handedness : Handedness -@param origin : origin -*/ -ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam, - PointingAlong thetaSign, Handedness handedness, - std::string origin) - : m_up(up), m_alongBeam(alongBeam), m_thetaSign(thetaSign), - m_handedness(handedness), m_origin(origin) { - if (up == alongBeam) { - throw std::invalid_argument( - "Cannot have up direction the same as the beam direction"); - } - if (thetaSign == alongBeam) { - throw std::invalid_argument( - "Scattering angle sign axis cannot be the same as the beam direction"); - } - init(); -} - -//---------------------------------------------------------------------------------------------- -/** Constructor -Default constructor -*/ -ReferenceFrame::ReferenceFrame() - : m_up(Y), m_alongBeam(Z), m_handedness(Right), m_origin("source") { - init(); -} - +namespace { /** -Non-member helper method to convert x y z enumeration directions into proper -3D vectors. -@param direction : direction marker -@return 3D vector + * Non-member helper method to convert x y z enumeration directions into proper + * 3D vectors. + * @param direction : direction marker + * @return 3D vector */ V3D directionToVector(const PointingAlong &direction) { - Mantid::Kernel::V3D result; + V3D result; if (direction == X) { result = V3D(1, 0, 0); } else if (direction == Y) { @@ -91,9 +41,44 @@ std::string directionToString(const PointingAlong &direction) { } return result; } +} + +/** + * Default constructor. up=Y, beam=Z, thetaSign=Y + */ +ReferenceFrame::ReferenceFrame() : ReferenceFrame(Y, Z, Y, Right, "source") {} -/// Perform common initalisation steps. -void ReferenceFrame::init() { +/** Constructor specifying thetaSign=up + * @param up :pointing up axis + * @param alongBeam : axis pointing along the beam + * @param handedness : Handedness + * @param origin : origin +*/ +ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam, + Handedness handedness, std::string origin) + : ReferenceFrame(up, alongBeam, up, handedness, std::move(origin)) {} + +/** + * Constructor specifying all attributes + * @param up : pointing up axis + * @param alongBeam : axis pointing along the beam + * @param thetaSign : axis defining the sign of 2theta + * @param handedness : Handedness + * @param origin : origin +*/ +ReferenceFrame::ReferenceFrame(PointingAlong up, PointingAlong alongBeam, + PointingAlong thetaSign, Handedness handedness, + std::string origin) + : m_up(up), m_alongBeam(alongBeam), m_thetaSign(thetaSign), + m_handedness(handedness), m_origin(std::move(origin)) { + if (up == alongBeam) { + throw std::invalid_argument( + "Cannot have up direction the same as the beam direction"); + } + if (thetaSign == alongBeam) { + throw std::invalid_argument( + "Scattering angle sign axis cannot be the same as the beam direction"); + } m_vecPointingUp = directionToVector(m_up); m_vecPointingAlongBeam = directionToVector(m_alongBeam); m_vecThetaSign = directionToVector(m_thetaSign); From 4cfabda08af1da8e2960ebb9bbf600afbf605b57 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Mon, 12 Mar 2018 11:16:30 +0000 Subject: [PATCH 124/364] Ensure ranges exist in map, else use default of 0 Refs #21969 --- .../Indirect/ISISCalibration.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp index 771c24104715..2c9ba29ae103 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp @@ -6,12 +6,24 @@ #include +#include + using namespace Mantid::API; namespace { Mantid::Kernel::Logger g_log("ISISCalibration"); + +template +Value getValueOr(const Map &map, const Key &key, const Value &defaultValue) { + try { + return map.at(key); + } catch (std::out_of_range &) { + return defaultValue; + } } +} // namespace + using namespace Mantid::API; using MantidQt::API::BatchAlgorithmRunner; @@ -352,8 +364,10 @@ void ISISCalibration::setDefaultInstDetails() { // Set peak and background ranges const auto ranges = getRangesFromInstrument(); - setPeakRange(ranges.at("peak-start-tof"), ranges.at("peak-end-tof")); - setBackgroundRange(ranges.at("back-start-tof"), ranges.at("back-end-tof")); + setPeakRange(getValueOr(ranges, "peak-start-tof", 0.0), + getValueOr(ranges, "peak-end-tof", 0.0)); + setBackgroundRange(getValueOr(ranges, "back-start-tof", 0.0), + getValueOr(ranges, "back-end-tof", 0.0)); } /** From 18f3fcb312a731d616c2dc71c8918f43385120d1 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Mon, 12 Mar 2018 11:37:56 +0000 Subject: [PATCH 125/364] Ensure sample unit is considered rather than constant "Wavelength" Refs #22026 --- .../Indirect/AbsorptionCorrections.cpp | 34 ++++++++++++------- .../Indirect/AbsorptionCorrections.h | 4 ++- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index 76667c40bd7d..b199c98c3a5a 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -12,7 +12,14 @@ using namespace Mantid::API; namespace { Mantid::Kernel::Logger g_log("AbsorptionCorrections"); + +std::string workspaceUnit(MatrixWorkspace_sptr workspace, + const size_t &axisIndex) { + if (workspace) + return workspace->getAxis(axisIndex)->unit()->unitID(); + return ""; } +} // namespace namespace MantidQt { namespace CustomInterfaces { @@ -50,6 +57,16 @@ AbsorptionCorrections::AbsorptionCorrections(QWidget *parent) SLOT(doValidation())); } +MatrixWorkspace_sptr AbsorptionCorrections::sampleWorkspace() const { + const auto sampleWSName = + m_uiForm.dsSampleInput->getCurrentDataName().toStdString(); + + if (AnalysisDataService::Instance().doesExist(sampleWSName)) + return AnalysisDataService::Instance().retrieveWS( + sampleWSName); + return nullptr; +} + void AbsorptionCorrections::setup() { doValidation(); } void AbsorptionCorrections::run() { @@ -217,18 +234,11 @@ bool AbsorptionCorrections::validate() { UserInputValidator AbsorptionCorrections::doValidation() { UserInputValidator uiv; - uiv.checkDataSelectorIsValid("Sample", m_uiForm.dsSampleInput); - const auto sampleWsName = - m_uiForm.dsSampleInput->getCurrentDataName().toStdString(); - bool sampleExists = AnalysisDataService::Instance().doesExist(sampleWsName); - if (sampleExists && - !AnalysisDataService::Instance().retrieveWS( - sampleWsName)) { + if (!sampleWorkspace()) uiv.addErrorMessage( "Invalid sample workspace. Ensure a MatrixWorkspace is provided."); - } if (uiv.checkFieldIsNotEmpty("Sample Chemical Formula", m_uiForm.leSampleChemicalFormula, @@ -315,7 +325,7 @@ void AbsorptionCorrections::getBeamDefaults(const QString &dataName) { return; } - auto unit = sampleWs->getAxis(0)->unit()->unitID(); + auto unit = workspaceUnit(sampleWs, 0); m_uiForm.cbPlotOutput->setItemText(0, QString::fromStdString(unit)); auto instrument = sampleWs->getInstrument(); @@ -358,11 +368,11 @@ void AbsorptionCorrections::saveClicked() { */ void AbsorptionCorrections::plotClicked() { const auto plotType = m_uiForm.cbPlotOutput->currentText(); - const auto sampleWSName = - m_uiForm.dsSampleInput->getCurrentDataName().toStdString(); if (checkADSForPlotSaveWorkspace(m_pythonExportWsName, true)) { - if (plotType == "Both" || plotType == "Wavelength") + const auto unit = workspaceUnit(sampleWorkspace(), 0); + + if (plotType == "Both" || plotType == QString::fromStdString(unit)) plotSpectrum(QString::fromStdString(m_pythonExportWsName)); if (plotType == "Both" || plotType == "Angle") diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h index f0b38bab5169..8ceef472a9c5 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h @@ -1,8 +1,8 @@ #ifndef MANTIDQTCUSTOMINTERFACESIDA_ABSORPTIONCORRECTIONS_H_ #define MANTIDQTCUSTOMINTERFACESIDA_ABSORPTIONCORRECTIONS_H_ -#include "ui_AbsorptionCorrections.h" #include "CorrectionsTab.h" +#include "ui_AbsorptionCorrections.h" #include "../General/UserInputValidator.h" @@ -14,6 +14,8 @@ class DLLExport AbsorptionCorrections : public CorrectionsTab { public: AbsorptionCorrections(QWidget *parent = nullptr); + Mantid::API::MatrixWorkspace_sptr sampleWorkspace() const; + private: void setup() override; void run() override; From 5b1974237e88922c01f12cdffda401e19c021a64 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Mon, 12 Mar 2018 11:53:54 +0000 Subject: [PATCH 126/364] Always use "Wavelength" as plot type Refs #22026 --- .../Indirect/AbsorptionCorrections.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index b199c98c3a5a..a377ac69cc06 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -12,13 +12,6 @@ using namespace Mantid::API; namespace { Mantid::Kernel::Logger g_log("AbsorptionCorrections"); - -std::string workspaceUnit(MatrixWorkspace_sptr workspace, - const size_t &axisIndex) { - if (workspace) - return workspace->getAxis(axisIndex)->unit()->unitID(); - return ""; -} } // namespace namespace MantidQt { @@ -325,9 +318,6 @@ void AbsorptionCorrections::getBeamDefaults(const QString &dataName) { return; } - auto unit = workspaceUnit(sampleWs, 0); - m_uiForm.cbPlotOutput->setItemText(0, QString::fromStdString(unit)); - auto instrument = sampleWs->getInstrument(); const std::string beamWidthParamName = "Workflow.beam-width"; if (instrument->hasParameter(beamWidthParamName)) { @@ -370,9 +360,7 @@ void AbsorptionCorrections::plotClicked() { const auto plotType = m_uiForm.cbPlotOutput->currentText(); if (checkADSForPlotSaveWorkspace(m_pythonExportWsName, true)) { - const auto unit = workspaceUnit(sampleWorkspace(), 0); - - if (plotType == "Both" || plotType == QString::fromStdString(unit)) + if (plotType == "Both" || plotType == "Wavelength") plotSpectrum(QString::fromStdString(m_pythonExportWsName)); if (plotType == "Both" || plotType == "Angle") From 76be3f69451b7dceaa39d3c0ec7423e7bdfb1edb Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 12:13:39 +0000 Subject: [PATCH 127/364] refs #22042 muon analysis can now handle user dirs again --- qt/scientific_interfaces/Muon/MuonAnalysis.cpp | 1 - .../Muon/MuonAnalysisFitDataPresenter.cpp | 11 ++++++++++- qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp | 9 ++++++--- qt/widgets/common/src/MuonFitDataSelector.cpp | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 5dddcac3068e..9c072901f46a 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -1966,7 +1966,6 @@ bool MuonAnalysis::plotExists(const QString &wsName) { void MuonAnalysis::selectMultiPeak(const QString &wsName, const boost::optional &filePath) { disableAllTools(); - if (!plotExists(wsName)) { plotSpectrum(wsName); setCurrentDataName(wsName); diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index 5affb55d8f70..ecf3c68af040 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -303,7 +303,15 @@ std::vector MuonAnalysisFitDataPresenter::generateWorkspaceNames( const auto periods = m_dataSelector->getPeriodSelections(); Muon::DatasetParams params; - const std::string instRuns = instrument + runString; + std::string runNumber = runString; + auto index = runString.find(instrument); + if (index != std::string::npos) { + // trim path + runNumber = runString.substr(index+instrument.size()); + // trim extension + runNumber = runNumber.substr(0, runNumber.find_first_of(".")); + } + const std::string instRuns = instrument + runNumber; std::vector selectedRuns; MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, selectedRuns); params.version = 1; @@ -828,6 +836,7 @@ bool MuonAnalysisFitDataPresenter::isSimultaneousFit() const { */ void MuonAnalysisFitDataPresenter::setSelectedWorkspace( const QString &wsName, const boost::optional &filePath) { + auto tm = wsName.toStdString(); updateWorkspaceNames(std::vector{wsName.toStdString()}); setUpDataSelector(wsName, filePath); } diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp index 703fee399829..52209fdb458a 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp @@ -1016,11 +1016,14 @@ void parseRunLabel(const std::string &label, std::string &instrument, // Single run runNumbers.push_back(boost::lexical_cast(pairTokenizer[0])); } else { - throw std::invalid_argument("Failed to parse run label: " + label); + throw std::invalid_argument("Failed to parse run label: " + label +" too many tokens "); } } catch (const boost::bad_lexical_cast &) { - throw std::invalid_argument("Failed to parse run label: " + label); - } + throw std::invalid_argument("Failed to parse run label: " + label +" not a good run number"); + } + catch(...) { + throw std::invalid_argument("Failed to parse run label: " + label); + } } } else { // The string was "INST000" or similar... diff --git a/qt/widgets/common/src/MuonFitDataSelector.cpp b/qt/widgets/common/src/MuonFitDataSelector.cpp index c82e0f951b98..9bc84c5d7704 100644 --- a/qt/widgets/common/src/MuonFitDataSelector.cpp +++ b/qt/widgets/common/src/MuonFitDataSelector.cpp @@ -179,7 +179,8 @@ void MuonFitDataSelector::setWorkspaceDetails( // Set initial run to be run number of the workspace loaded in Home tab // and search for filenames. Use busy cursor until search finished. setBusyState(); - if (filePath) { // load current run: use special file path + + if (filePath) { // load current run: use special file path m_ui.runs->setUserInput(filePath.get()); m_ui.runs->setText(runs); } else { // default From 660d31d492a7b8e77ecfc4af6bc598d268a471b4 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 12:14:52 +0000 Subject: [PATCH 128/364] refs #22042 muon analysis can now handle user dirs again --- qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index ecf3c68af040..3768432b049a 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -836,8 +836,7 @@ bool MuonAnalysisFitDataPresenter::isSimultaneousFit() const { */ void MuonAnalysisFitDataPresenter::setSelectedWorkspace( const QString &wsName, const boost::optional &filePath) { - auto tm = wsName.toStdString(); - updateWorkspaceNames(std::vector{wsName.toStdString()}); + updateWorkspaceNames(std::vector{wsName.toStdString()}); setUpDataSelector(wsName, filePath); } From 692bf3673e1b160ccbb6007d101ccc3bd4f265f1 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 12:26:53 +0000 Subject: [PATCH 129/364] refs #22042 clang format for muonAnalysis files --- .../Muon/MuonAnalysisFitDataPresenter.cpp | 10 +++++----- .../Muon/MuonAnalysisHelper.cpp | 13 +++++++------ qt/widgets/common/src/MuonFitDataSelector.cpp | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index 3768432b049a..ef9451380a82 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -306,10 +306,10 @@ std::vector MuonAnalysisFitDataPresenter::generateWorkspaceNames( std::string runNumber = runString; auto index = runString.find(instrument); if (index != std::string::npos) { - // trim path - runNumber = runString.substr(index+instrument.size()); - // trim extension - runNumber = runNumber.substr(0, runNumber.find_first_of(".")); + // trim path + runNumber = runString.substr(index + instrument.size()); + // trim extension + runNumber = runNumber.substr(0, runNumber.find_first_of(".")); } const std::string instRuns = instrument + runNumber; std::vector selectedRuns; @@ -836,7 +836,7 @@ bool MuonAnalysisFitDataPresenter::isSimultaneousFit() const { */ void MuonAnalysisFitDataPresenter::setSelectedWorkspace( const QString &wsName, const boost::optional &filePath) { - updateWorkspaceNames(std::vector{wsName.toStdString()}); + updateWorkspaceNames(std::vector{wsName.toStdString()}); setUpDataSelector(wsName, filePath); } diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp index 52209fdb458a..152f003d30f5 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp @@ -1016,14 +1016,15 @@ void parseRunLabel(const std::string &label, std::string &instrument, // Single run runNumbers.push_back(boost::lexical_cast(pairTokenizer[0])); } else { - throw std::invalid_argument("Failed to parse run label: " + label +" too many tokens "); + throw std::invalid_argument("Failed to parse run label: " + label + + " too many tokens "); } } catch (const boost::bad_lexical_cast &) { - throw std::invalid_argument("Failed to parse run label: " + label +" not a good run number"); - } - catch(...) { - throw std::invalid_argument("Failed to parse run label: " + label); - } + throw std::invalid_argument("Failed to parse run label: " + label + + " not a good run number"); + } catch (...) { + throw std::invalid_argument("Failed to parse run label: " + label); + } } } else { // The string was "INST000" or similar... diff --git a/qt/widgets/common/src/MuonFitDataSelector.cpp b/qt/widgets/common/src/MuonFitDataSelector.cpp index 9bc84c5d7704..e65920d81309 100644 --- a/qt/widgets/common/src/MuonFitDataSelector.cpp +++ b/qt/widgets/common/src/MuonFitDataSelector.cpp @@ -179,8 +179,8 @@ void MuonFitDataSelector::setWorkspaceDetails( // Set initial run to be run number of the workspace loaded in Home tab // and search for filenames. Use busy cursor until search finished. setBusyState(); - - if (filePath) { // load current run: use special file path + + if (filePath) { // load current run: use special file path m_ui.runs->setUserInput(filePath.get()); m_ui.runs->setText(runs); } else { // default From d53774b302c5fa5c6d2e81385ec4cf7e8caef935 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 12 Mar 2018 13:09:03 +0000 Subject: [PATCH 130/364] Check and reinitialize minimizer if function adds new active params The GSL fitting expects the number of paramters to remain constant during an optimization. The CrystalField function can add new peaks depending on the parameter values and if this happens the fitting must be restarted and a new set of parameter vectors allocated. Refs #21943 --- Framework/CurveFitting/src/GSLFunctions.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Framework/CurveFitting/src/GSLFunctions.cpp b/Framework/CurveFitting/src/GSLFunctions.cpp index cf506c0eab83..c60278085918 100644 --- a/Framework/CurveFitting/src/GSLFunctions.cpp +++ b/Framework/CurveFitting/src/GSLFunctions.cpp @@ -15,16 +15,20 @@ namespace CurveFitting { * @return A GSL status information */ int gsl_f(const gsl_vector *x, void *params, gsl_vector *f) { - + assert(x->data); struct GSL_FitData *p = reinterpret_cast(params); // update function parameters - if (x->data) { - size_t ia = 0; - for (size_t i = 0; i < p->function->nParams(); ++i) { - if (p->function->isActive(i)) { + size_t ia = 0; + for (size_t i = 0; i < p->function->nParams(); ++i) { + if (p->function->isActive(i)) { + if (ia < x->size) { p->function->setActiveParameter(i, x->data[ia]); ++ia; + } else { + // The number of active parameters now exceeds the space + // originally allocated + throw Kernel::Exception::FitSizeWarning(x->size); } } } @@ -63,10 +67,7 @@ int gsl_f(const gsl_vector *x, void *params, gsl_vector *f) { for (size_t i = 0; i < p->n; i++) { f->data[i] = (values->getCalculated(i) - values->getFitData(i)) * values->getFitWeight(i); - // std::cerr << values.getCalculated(i) << ' ' << values.getFitData(i) << ' - // ' << values.getFitWeight(i) << '\n'; } - return GSL_SUCCESS; } From 1f9c87d776bb04e7d3a93f4ae674fa57c700ea2a Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 12 Mar 2018 13:35:35 +0000 Subject: [PATCH 131/364] Re #22048: Applied modernize-use-using fixes for Framework/Algorithms. --- .../inc/MantidAlgorithms/AbsorptionCorrection.h | 3 +-- .../inc/MantidAlgorithms/BinaryOperation.h | 4 ++-- .../inc/MantidAlgorithms/ConvertAxisByFormula.h | 2 +- .../Algorithms/inc/MantidAlgorithms/IQTransform.h | 2 +- .../MantidAlgorithms/PDDetermineCharacterizations.h | 2 +- .../inc/MantidAlgorithms/PaddingAndApodization.h | 2 +- .../inc/MantidAlgorithms/SpectrumAlgorithm.h | 4 ++-- Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h | 2 +- Framework/Algorithms/src/CalculateTransmission.cpp | 2 +- Framework/Algorithms/src/CreateCalFileByNames.cpp | 6 +++--- Framework/Algorithms/src/CreateDummyCalFile.cpp | 6 +++--- Framework/Algorithms/src/CreateGroupingWorkspace.cpp | 6 +++--- Framework/Algorithms/src/NormaliseByDetector.cpp | 2 +- Framework/Algorithms/src/PaddingAndApodization.cpp | 2 +- Framework/Algorithms/src/PerformIndexOperations.cpp | 4 ++-- Framework/Algorithms/src/PolarizationCorrection.cpp | 2 +- Framework/Algorithms/src/SmoothNeighbours.cpp | 4 ++-- Framework/Algorithms/src/SofQWNormalisedPolygon.cpp | 2 +- Framework/Algorithms/src/SofQWPolygon.cpp | 3 +-- .../Algorithms/src/VesuvioL1ThetaResolution.cpp | 2 +- Framework/Algorithms/test/RebinByPulseTimesTest.h | 2 +- Framework/Algorithms/test/RebinByTimeAtSampleTest.h | 2 +- .../Algorithms/test/SofQWNormalisedPolygonTest.h | 2 +- Framework/Algorithms/test/SofQWPolygonTest.h | 2 +- .../MantidDataHandling/EventWorkspaceCollection.h | 5 ++--- .../inc/MantidDataHandling/LoadEventPreNexus2.h | 4 ++-- Framework/Nexus/inc/MantidNexus/NexusClasses.h | 12 ++++++------ 27 files changed, 44 insertions(+), 47 deletions(-) diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h index e6364cd9839f..805130499c34 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h @@ -147,8 +147,7 @@ class DLLExport AbsorptionCorrection : public API::Algorithm { double m_lambdaFixed; ///< The wavelength corresponding to the fixed energy, /// if provided - typedef double (*expfunction)( - double); ///< Typedef pointer to exponential function + using expfunction = double (*)(double); ///< Typedef pointer to exponential function expfunction EXPONENTIAL; ///< Pointer to exponential function }; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h index 6dfa0e3120bd..27e60f7b4330 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h @@ -63,8 +63,8 @@ class DLLExport BinaryOperation : public API::Algorithm { * Value at that index: workspace index of the rhs to apply to the WI in the * lhs. -1 if not found. */ - typedef std::vector BinaryOperationTable; - typedef boost::shared_ptr BinaryOperationTable_sptr; + using BinaryOperationTable = std::vector; + using BinaryOperationTable_sptr = boost::shared_ptr; static BinaryOperationTable_sptr buildBinaryOperationTable(const API::MatrixWorkspace_const_sptr &lhs, diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h index 568f6a168fa9..ada468038c9f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h @@ -72,7 +72,7 @@ class DLLExport ConvertAxisByFormula : public ConvertUnits { double value; bool isGeometric; }; - typedef boost::shared_ptr Variable_ptr; + using Variable_ptr = boost::shared_ptr; void setAxisValue(const double &value, std::vector &variables); void calculateValues(mu::Parser &p, std::vector &vec, diff --git a/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h b/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h index b648722f7c7b..5b0c8bd04e47 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h @@ -87,7 +87,7 @@ class DLLExport IQTransform : public API::Algorithm { subtractBackgroundWS(API::MatrixWorkspace_sptr ws, API::MatrixWorkspace_sptr background); - typedef void (IQTransform::*TransformFunc)(API::MatrixWorkspace_sptr); + using TransformFunc = void (IQTransform::*)(API::MatrixWorkspace_sptr); typedef std::map TransformMap; TransformMap m_transforms; ///< A map of transformation name and function pointers diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h b/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h index 860285ea1a8e..597021442b17 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PDDetermineCharacterizations.h @@ -15,7 +15,7 @@ namespace Kernel { /// forward declaration class PropertyMantager; /// Typedef for a shared pointer to a PropertyManager -typedef boost::shared_ptr PropertyManager_sptr; +using PropertyManager_sptr = boost::shared_ptr; } namespace Algorithms { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h b/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h index a5fe87e91037..28577cc96ab6 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PaddingAndApodization.h @@ -67,7 +67,7 @@ class DLLExport PaddingAndApodization : public API::Algorithm { // Overridden Algorithm methods void init() override; void exec() override; - typedef double (*fptr)(const double time, const double decayConstant); + using fptr = double (*)(const double, const double); fptr getApodizationFunction(const std::string method); HistogramData::Histogram applyApodizationFunction(const HistogramData::Histogram &histogram, diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h b/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h index 4b8ebfaa3b7c..37b9b8bc7808 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SpectrumAlgorithm.h @@ -63,7 +63,7 @@ class MANTID_ALGORITHMS_DLL SpectrumAlgorithm : public API::Algorithm { : gens /** @endcond */ {/** @cond */ }; template struct gens<0, S...> {/** @endcond */ - typedef seq type; + using type = seq; }; /** Helpers for for_each(), struct contains and 2 specializations. @@ -169,7 +169,7 @@ void SpectrumAlgorithm::ifEventWorkspaceClearMRU( const DataObjects::EventWorkspace &workspace); /// Typedef for a shared pointer to a SpectrumAlgorithm -typedef boost::shared_ptr SpectrumAlgorithm_sptr; +using SpectrumAlgorithm_sptr = boost::shared_ptr; } // namespace Algorithms } // namespace Mantid diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h index a11a01e463b5..183ec88c50d8 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h @@ -49,7 +49,7 @@ class DLLExport Stitch1D : public API::Algorithm { private: /// Helper typedef. For storing indexes of special values per spectra per /// workspace. - typedef std::vector> SpecialTypeIndexes; + using SpecialTypeIndexes = std::vector >; /// Overwrites Algorithm method. void init() override; /// Overwrites Algorithm method. diff --git a/Framework/Algorithms/src/CalculateTransmission.cpp b/Framework/Algorithms/src/CalculateTransmission.cpp index e1ea669899be..77feb1f7a857 100644 --- a/Framework/Algorithms/src/CalculateTransmission.cpp +++ b/Framework/Algorithms/src/CalculateTransmission.cpp @@ -265,7 +265,7 @@ CalculateTransmission::extractSpectra(API::MatrixWorkspace_sptr ws, // means that lexical_cast cannot be used directly as the call is ambiguous // so we need to define a function pointer that can resolve the overloaded // lexical_cast function - typedef std::string (*from_size_t)(const size_t &); + using from_size_t = std::string (*)(const size_t &); std::transform( indices.begin(), indices.end(), indexStrings.begin(), diff --git a/Framework/Algorithms/src/CreateCalFileByNames.cpp b/Framework/Algorithms/src/CreateCalFileByNames.cpp index c15105423451..dbc4804af458 100644 --- a/Framework/Algorithms/src/CreateCalFileByNames.cpp +++ b/Framework/Algorithms/src/CreateCalFileByNames.cpp @@ -88,9 +88,9 @@ void CreateCalFileByNames::exec() { vgroups.clear(); // Find Detectors that belong to groups - typedef boost::shared_ptr sptr_ICompAss; - typedef boost::shared_ptr sptr_IComp; - typedef boost::shared_ptr sptr_IDet; + using sptr_ICompAss = boost::shared_ptr; + using sptr_IComp = boost::shared_ptr; + using sptr_IDet = boost::shared_ptr; std::queue> assemblies; sptr_ICompAss current = boost::dynamic_pointer_cast(inst); diff --git a/Framework/Algorithms/src/CreateDummyCalFile.cpp b/Framework/Algorithms/src/CreateDummyCalFile.cpp index 163b64b8c4ae..607310f25805 100644 --- a/Framework/Algorithms/src/CreateDummyCalFile.cpp +++ b/Framework/Algorithms/src/CreateDummyCalFile.cpp @@ -85,9 +85,9 @@ void CreateDummyCalFile::exec() { vgroups.clear(); // Find Detectors that belong to groups - typedef boost::shared_ptr sptr_ICompAss; - typedef boost::shared_ptr sptr_IComp; - typedef boost::shared_ptr sptr_IDet; + using sptr_ICompAss = boost::shared_ptr; + using sptr_IComp = boost::shared_ptr; + using sptr_IDet = boost::shared_ptr; std::queue> assemblies; sptr_ICompAss current = boost::dynamic_pointer_cast(inst); diff --git a/Framework/Algorithms/src/CreateGroupingWorkspace.cpp b/Framework/Algorithms/src/CreateGroupingWorkspace.cpp index fba1465d0357..c22d148a5ede 100644 --- a/Framework/Algorithms/src/CreateGroupingWorkspace.cpp +++ b/Framework/Algorithms/src/CreateGroupingWorkspace.cpp @@ -249,9 +249,9 @@ std::map makeGroupingByNames(std::string GroupNames, // Find Detectors that belong to groups if (!group_map.empty()) { // Find Detectors that belong to groups - typedef boost::shared_ptr sptr_ICompAss; - typedef boost::shared_ptr sptr_IComp; - typedef boost::shared_ptr sptr_IDet; + using sptr_ICompAss = boost::shared_ptr; + using sptr_IComp = boost::shared_ptr; + using sptr_IDet = boost::shared_ptr; std::queue> assemblies; sptr_ICompAss current = boost::dynamic_pointer_cast(inst); diff --git a/Framework/Algorithms/src/NormaliseByDetector.cpp b/Framework/Algorithms/src/NormaliseByDetector.cpp index 35d8b68ea84b..5ff4b8526afb 100644 --- a/Framework/Algorithms/src/NormaliseByDetector.cpp +++ b/Framework/Algorithms/src/NormaliseByDetector.cpp @@ -108,7 +108,7 @@ void NormaliseByDetector::processHistogram(size_t wsIndex, const std::string &fitFunctionName = foundFittingParam.getFunction(); IFunction_sptr function = FunctionFactory::Instance().createFunction(fitFunctionName); - typedef std::vector ParamNames; + using ParamNames = std::vector; ParamNames allParamNames = function->getParameterNames(); // Lookup each parameter name. diff --git a/Framework/Algorithms/src/PaddingAndApodization.cpp b/Framework/Algorithms/src/PaddingAndApodization.cpp index f6e5086ab4ef..971921a9fafa 100644 --- a/Framework/Algorithms/src/PaddingAndApodization.cpp +++ b/Framework/Algorithms/src/PaddingAndApodization.cpp @@ -125,7 +125,7 @@ void PaddingAndApodization::exec() { setProperty("OutputWorkspace", outputWS); } -typedef double (*fptr)(const double time, const double decayConstant); +using fptr = double (*)(const double, const double); /** * Gets a pointer to the relevant * apodization function diff --git a/Framework/Algorithms/src/PerformIndexOperations.cpp b/Framework/Algorithms/src/PerformIndexOperations.cpp index 8b31982a6ad0..55c225f3d526 100644 --- a/Framework/Algorithms/src/PerformIndexOperations.cpp +++ b/Framework/Algorithms/src/PerformIndexOperations.cpp @@ -45,7 +45,7 @@ class Command { }; /// Helper typedef -typedef std::vector> VecCommands; +using VecCommands = std::vector >; /** * Command yielding no result. @@ -140,7 +140,7 @@ class CommandParser { }; /// Helper typedef for vector of command parsers -typedef std::vector> VecCommandParsers; +using VecCommandParsers = std::vector >; /** * Command parser base class for common concrete command parser types. diff --git a/Framework/Algorithms/src/PolarizationCorrection.cpp b/Framework/Algorithms/src/PolarizationCorrection.cpp index d3f4983a28dd..b3c949ab0997 100644 --- a/Framework/Algorithms/src/PolarizationCorrection.cpp +++ b/Framework/Algorithms/src/PolarizationCorrection.cpp @@ -102,7 +102,7 @@ void validateInputWorkspace(WorkspaceGroup_sptr &ws) { } } -typedef std::vector VecDouble; +using VecDouble = std::vector; } namespace Mantid { diff --git a/Framework/Algorithms/src/SmoothNeighbours.cpp b/Framework/Algorithms/src/SmoothNeighbours.cpp index dbbae50f50d7..53f1f980a86a 100644 --- a/Framework/Algorithms/src/SmoothNeighbours.cpp +++ b/Framework/Algorithms/src/SmoothNeighbours.cpp @@ -24,8 +24,8 @@ using namespace Mantid::Geometry; using namespace Mantid::API; using namespace Mantid::DataObjects; -typedef std::vector VecProperties; -typedef const VecProperties ConstVecProperties; +using VecProperties = std::vector; +using ConstVecProperties = const VecProperties; namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp index e5833ee1064a..912ded1386f0 100644 --- a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp +++ b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp @@ -21,7 +21,7 @@ namespace Mantid { namespace Algorithms { // Setup typedef for later use typedef std::map SpectraDistanceMap; -typedef Geometry::IDetector_const_sptr DetConstPtr; +using DetConstPtr = Geometry::IDetector_const_sptr; // Register the algorithm into the AlgorithmFactory DECLARE_ALGORITHM(SofQWNormalisedPolygon) diff --git a/Framework/Algorithms/src/SofQWPolygon.cpp b/Framework/Algorithms/src/SofQWPolygon.cpp index 8fe9b4c015a2..75d0c160cd60 100644 --- a/Framework/Algorithms/src/SofQWPolygon.cpp +++ b/Framework/Algorithms/src/SofQWPolygon.cpp @@ -63,8 +63,7 @@ void SofQWPolygon::exec() { // Select the calculate Q method based on the mode // rather than doing this repeatedly in the loop - typedef double (SofQWPolygon::*QCalculation)(double, double, double, double) - const; + using QCalculation = double (SofQWPolygon::*)(double, double, double, double) const; QCalculation qCalculator; if (m_EmodeProperties.m_emode == 1) { qCalculator = &SofQWPolygon::calculateDirectQ; diff --git a/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp b/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp index 5058883a3801..1598952f01ef 100644 --- a/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp +++ b/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp @@ -461,7 +461,7 @@ VesuvioL1ThetaResolution::processDistribution(MatrixWorkspace_sptr ws, /** Generates a random number. */ double VesuvioL1ThetaResolution::random() { - typedef boost::uniform_real uniform_double; + using uniform_double = boost::uniform_real; return boost::variate_generator( m_generator, uniform_double(0.0, 1.0))(); } diff --git a/Framework/Algorithms/test/RebinByPulseTimesTest.h b/Framework/Algorithms/test/RebinByPulseTimesTest.h index 63095f03137d..fe6bfb4b78f7 100644 --- a/Framework/Algorithms/test/RebinByPulseTimesTest.h +++ b/Framework/Algorithms/test/RebinByPulseTimesTest.h @@ -10,7 +10,7 @@ using Mantid::Algorithms::RebinByPulseTimes; //===================================================================================== // Functional Tests //===================================================================================== -typedef RebinByTimeBaseTest Super; +using Super = RebinByTimeBaseTest; class RebinByPulseTimesTest : public CxxTest::TestSuite, public Super { public: diff --git a/Framework/Algorithms/test/RebinByTimeAtSampleTest.h b/Framework/Algorithms/test/RebinByTimeAtSampleTest.h index 6529dd117106..aaf90573ec8e 100644 --- a/Framework/Algorithms/test/RebinByTimeAtSampleTest.h +++ b/Framework/Algorithms/test/RebinByTimeAtSampleTest.h @@ -55,7 +55,7 @@ createSinglePulseEventWorkspace(const V3D &sourcePosition, //===================================================================================== // Functional Tests //===================================================================================== -typedef RebinByTimeBaseTest Super; +using Super = RebinByTimeBaseTest; class RebinByTimeAtSampleTest : public CxxTest::TestSuite, public Super { public: diff --git a/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h b/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h index 26588e4816b3..009c38a3c49d 100644 --- a/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h +++ b/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h @@ -62,7 +62,7 @@ class SofQWNormalisedPolygonTest : public CxxTest::TestSuite { // Spectra-detector mapping const size_t nspectra(6); - typedef std::set IDSet; + using IDSet = std::set; std::vector expectedIDs(nspectra); IDSet s1 = {3}; expectedIDs[0] = s1; diff --git a/Framework/Algorithms/test/SofQWPolygonTest.h b/Framework/Algorithms/test/SofQWPolygonTest.h index ba471e5d4503..a4befaa06112 100644 --- a/Framework/Algorithms/test/SofQWPolygonTest.h +++ b/Framework/Algorithms/test/SofQWPolygonTest.h @@ -59,7 +59,7 @@ class SofQWPolygonTest : public CxxTest::TestSuite { // Spectra-detector mapping const size_t nspectra(6); - typedef std::set IDSet; + using IDSet = std::set; std::vector expectedIDs(nspectra); IDSet s1 = {3}; expectedIDs[0] = s1; diff --git a/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h b/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h index 736817697cba..2637ec6f1438 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h +++ b/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h @@ -109,9 +109,8 @@ class DLLExport EventWorkspaceCollection { virtual bool threadSafe() const; }; -typedef boost::shared_ptr - EventWorkspaceCollection_sptr; -typedef std::unique_ptr EventWorkspaceCollection_uptr; +using EventWorkspaceCollection_sptr = boost::shared_ptr; +using EventWorkspaceCollection_uptr = std::unique_ptr; } // namespace DataHandling } // namespace Mantid diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h index b02b915af12f..21e12011e364 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h @@ -40,10 +40,10 @@ namespace DataHandling { #undef LOADEVENTPRENEXUS_ALLOW_PARALLEL /// Make the code clearer by having this an explicit type -typedef int PixelType; +using PixelType = int; /// Type for the DAS time of flight (data file) -typedef int DasTofType; +using DasTofType = int; /// Structure that matches the form in the binary event list. #pragma pack(push, 4) // Make sure the structure is 8 bytes. diff --git a/Framework/Nexus/inc/MantidNexus/NexusClasses.h b/Framework/Nexus/inc/MantidNexus/NexusClasses.h index 4a49958af930..f8598304b6c1 100644 --- a/Framework/Nexus/inc/MantidNexus/NexusClasses.h +++ b/Framework/Nexus/inc/MantidNexus/NexusClasses.h @@ -471,17 +471,17 @@ template class NXDataSetTyped : public NXDataSet { }; /// The integer dataset type -typedef NXDataSetTyped NXInt; +using NXInt = NXDataSetTyped; /// The float dataset type -typedef NXDataSetTyped NXFloat; +using NXFloat = NXDataSetTyped; /// The double dataset type -typedef NXDataSetTyped NXDouble; +using NXDouble = NXDataSetTyped; /// The char dataset type -typedef NXDataSetTyped NXChar; +using NXChar = NXDataSetTyped; /// The size_t dataset type -typedef NXDataSetTyped NXSize; +using NXSize = NXDataSetTyped; /// The size_t dataset type -typedef NXDataSetTyped NXUInt; +using NXUInt = NXDataSetTyped; //-------------------- classes --------------------------// From 7325785267bb0eb3ad2fc24c122905bb6035d6c3 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Mon, 12 Mar 2018 14:24:46 +0000 Subject: [PATCH 132/364] Convert output to wavelength workspace Refs #22026 --- .../Indirect/AbsorptionCorrections.cpp | 63 ++++++++++++++++++- .../Indirect/AbsorptionCorrections.h | 1 + 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index a377ac69cc06..e84003e1c15d 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -2,6 +2,7 @@ #include "MantidAPI/Axis.h" #include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/WorkspaceGroup.h" #include "MantidGeometry/Instrument.h" #include "MantidKernel/Material.h" #include "MantidKernel/Unit.h" @@ -12,6 +13,46 @@ using namespace Mantid::API; namespace { Mantid::Kernel::Logger g_log("AbsorptionCorrections"); + +MatrixWorkspace_sptr convertUnits(MatrixWorkspace_sptr workspace, + const std::string &target) { + auto convertAlg = AlgorithmManager::Instance().create("ConvertUnits"); + convertAlg->initialize(); + convertAlg->setChild(true); + convertAlg->setProperty("InputWorkspace", workspace); + convertAlg->setProperty("OutputWorkspace", "__converted"); + convertAlg->setProperty( + "EMode", Mantid::Kernel::DeltaEMode::asString(workspace->getEMode())); + convertAlg->setProperty("Target", target); + convertAlg->execute(); + return convertAlg->getProperty("OutputWorkspace"); +} + +WorkspaceGroup_sptr +groupWorkspaces(const std::vector &workspaceNames) { + auto groupAlg = AlgorithmManager::Instance().create("GroupWorkspaces"); + groupAlg->initialize(); + groupAlg->setChild(true); + groupAlg->setProperty("InputWorkspaces", workspaceNames); + groupAlg->setProperty("OutputWorkspace", "__grouped"); + groupAlg->execute(); + return groupAlg->getProperty("OutputWorkspace"); +} + +WorkspaceGroup_sptr convertUnits(WorkspaceGroup_sptr workspaceGroup, + const std::string &target) { + std::vector convertedNames; + convertedNames.reserve(workspaceGroup->size()); + + for (const auto &workspace : *workspaceGroup) { + const auto name = "__" + workspace->getName() + "_" + target; + const auto wavelengthWorkspace = convertUnits( + boost::dynamic_pointer_cast(workspace), target); + AnalysisDataService::Instance().addOrReplace(name, wavelengthWorkspace); + convertedNames.emplace_back(name); + } + return groupWorkspaces(convertedNames); +} } // namespace namespace MantidQt { @@ -50,6 +91,11 @@ AbsorptionCorrections::AbsorptionCorrections(QWidget *parent) SLOT(doValidation())); } +AbsorptionCorrections::~AbsorptionCorrections() { + if (AnalysisDataService::Instance().doesExist("__mc_corrections_wavelength")) + AnalysisDataService::Instance().remove("__mc_corrections_wavelength"); +} + MatrixWorkspace_sptr AbsorptionCorrections::sampleWorkspace() const { const auto sampleWSName = m_uiForm.dsSampleInput->getCurrentDataName().toStdString(); @@ -301,12 +347,23 @@ void AbsorptionCorrections::algorithmComplete(bool error) { if (error) { emit showMessageBox( "Could not run absorption corrections.\nSee Results Log for details."); + return; } // Enable plot and save m_uiForm.pbPlot->setEnabled(true); m_uiForm.cbPlotOutput->setEnabled(true); m_uiForm.pbSave->setEnabled(true); + + auto correctionsWorkspace = + AnalysisDataService::Instance().retrieveWS( + m_pythonExportWsName); + + if (correctionsWorkspace) { + auto wavelengthWorkspace = convertUnits(correctionsWorkspace, "Wavelength"); + AnalysisDataService::Instance().addOrReplace("__mc_corrections_wavelength", + wavelengthWorkspace); + } } void AbsorptionCorrections::getBeamDefaults(const QString &dataName) { @@ -359,12 +416,12 @@ void AbsorptionCorrections::saveClicked() { void AbsorptionCorrections::plotClicked() { const auto plotType = m_uiForm.cbPlotOutput->currentText(); - if (checkADSForPlotSaveWorkspace(m_pythonExportWsName, true)) { + if (checkADSForPlotSaveWorkspace("__mc_corrections_wavelength", false)) { if (plotType == "Both" || plotType == "Wavelength") - plotSpectrum(QString::fromStdString(m_pythonExportWsName)); + plotSpectrum(QString::fromStdString("__mc_corrections_wavelength")); if (plotType == "Both" || plotType == "Angle") - plotTimeBin(QString::fromStdString(m_pythonExportWsName)); + plotTimeBin(QString::fromStdString("__mc_corrections_wavelength")); } } diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h index 8ceef472a9c5..d8040ad276c1 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.h @@ -13,6 +13,7 @@ class DLLExport AbsorptionCorrections : public CorrectionsTab { public: AbsorptionCorrections(QWidget *parent = nullptr); + ~AbsorptionCorrections(); Mantid::API::MatrixWorkspace_sptr sampleWorkspace() const; From f159660fa58da2734dcee325ae3bb4ab0866bec6 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Mon, 12 Mar 2018 14:26:03 +0000 Subject: [PATCH 133/364] Enable plot/save after conversion Refs #22026 --- .../Indirect/AbsorptionCorrections.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index e84003e1c15d..92b88bc52827 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -350,11 +350,6 @@ void AbsorptionCorrections::algorithmComplete(bool error) { return; } - // Enable plot and save - m_uiForm.pbPlot->setEnabled(true); - m_uiForm.cbPlotOutput->setEnabled(true); - m_uiForm.pbSave->setEnabled(true); - auto correctionsWorkspace = AnalysisDataService::Instance().retrieveWS( m_pythonExportWsName); @@ -363,6 +358,11 @@ void AbsorptionCorrections::algorithmComplete(bool error) { auto wavelengthWorkspace = convertUnits(correctionsWorkspace, "Wavelength"); AnalysisDataService::Instance().addOrReplace("__mc_corrections_wavelength", wavelengthWorkspace); + + // Enable plot and save + m_uiForm.pbPlot->setEnabled(true); + m_uiForm.cbPlotOutput->setEnabled(true); + m_uiForm.pbSave->setEnabled(true); } } From acd845ea79b499a58f98d6db871c15b7b265eb12 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Mon, 12 Mar 2018 14:57:20 +0000 Subject: [PATCH 134/364] Use EFixed value when converting units Refs #22026 --- qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index 92b88bc52827..ed624db04f3f 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -23,6 +23,8 @@ MatrixWorkspace_sptr convertUnits(MatrixWorkspace_sptr workspace, convertAlg->setProperty("OutputWorkspace", "__converted"); convertAlg->setProperty( "EMode", Mantid::Kernel::DeltaEMode::asString(workspace->getEMode())); + convertAlg->setProperty("EFixed", + workspace->getEFixed(workspace->getDetector(0))); convertAlg->setProperty("Target", target); convertAlg->execute(); return convertAlg->getProperty("OutputWorkspace"); From f8a6875ee970a3e9b5eb9e46e5c70336cd05b123 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 15:01:06 +0000 Subject: [PATCH 135/364] refs #22031 FDA throw error if data changes --- scripts/Muon/fft_model.py | 8 +++++++- scripts/Muon/fft_presenter.py | 9 ++++++--- scripts/Muon/maxent_presenter.py | 8 ++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/scripts/Muon/fft_model.py b/scripts/Muon/fft_model.py index 40b0d90d72b6..38cbd2b48737 100644 --- a/scripts/Muon/fft_model.py +++ b/scripts/Muon/fft_model.py @@ -4,7 +4,6 @@ import mantid.simpleapi as mantid - class FFTWrapper(object): """ A class to wrap the different parts @@ -20,6 +19,13 @@ def loadData(self,inputs): store the data in the wrapper for later """ if "phaseTable" in inputs: + ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") + if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): + ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") + digit = lambda x:int(filter(str.isdigit,x) or 0) + if digit(inputs["Run"]) != ws.getRunNumber(): + mantid.logger.error("Active workspace has changed. Restart this interface") + inputs.clear() self.phaseTable = inputs["phaseTable"] else: self.phaseTable = None diff --git a/scripts/Muon/fft_presenter.py b/scripts/Muon/fft_presenter.py index fd6fb68509cc..dd620f76ff4c 100644 --- a/scripts/Muon/fft_presenter.py +++ b/scripts/Muon/fft_presenter.py @@ -98,9 +98,12 @@ def handleButton(self): if self.view.isRaw(): self.view.addRaw(FFTInputs,"OutputWorkspace") inputs["FFT"]=FFTInputs - self.thread.loadData(inputs) - self.thread.start() - self.view.setPhaseBox() + try: + self.thread.loadData(inputs) + self.thread.start() + self.view.setPhaseBox() + except: + pass # kills the thread at end of execution def handleFinished(self): diff --git a/scripts/Muon/maxent_presenter.py b/scripts/Muon/maxent_presenter.py index a11ff3401e2a..218a671f16a2 100644 --- a/scripts/Muon/maxent_presenter.py +++ b/scripts/Muon/maxent_presenter.py @@ -43,6 +43,14 @@ def createPhaseThread(self): return thread_model.ThreadModel(self.calcAlg) def handleMaxEntButton(self): + ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") + if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): + ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") + digit = lambda x:int(filter(str.isdigit,x) or 0) + run = self.load.getRunName() + if str(digit(run)) != str(ws.getRunNumber()): + mantid.logger.error("Active workspace has changed. Restart this interface") + return if self.view.calcPhases() and self.view.usePhases(): self.DoPhase() else: From 49b4b2d8671c2f57a125f62cc23a3a47d7eed7ca Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Mon, 12 Mar 2018 15:29:20 +0000 Subject: [PATCH 136/364] Disable create resolution for instruments without resolution params Refs #21969 --- qt/scientific_interfaces/Indirect/ISISCalibration.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp index 2c9ba29ae103..5c5647f54e08 100644 --- a/qt/scientific_interfaces/Indirect/ISISCalibration.cpp +++ b/qt/scientific_interfaces/Indirect/ISISCalibration.cpp @@ -368,6 +368,14 @@ void ISISCalibration::setDefaultInstDetails() { getValueOr(ranges, "peak-end-tof", 0.0)); setBackgroundRange(getValueOr(ranges, "back-start-tof", 0.0), getValueOr(ranges, "back-end-tof", 0.0)); + + if (instDetails.contains("resolution") && + !instDetails["resolution"].isEmpty()) { + m_uiForm.ckCreateResolution->setEnabled(true); + } else { + m_uiForm.ckCreateResolution->setChecked(false); + m_uiForm.ckCreateResolution->setEnabled(false); + } } /** @@ -489,7 +497,7 @@ void ISISCalibration::calSetDefaultResolution(MatrixWorkspace_const_sptr ws) { auto params = comp->getNumberParameter("resolution", true); // Set the default instrument resolution - if (params.size() > 0) { + if (!params.empty()) { double res = params[0]; const auto energyRange = m_uiForm.ppResolution->getCurveRange("Energy"); From 0988feeeb74ea7f588da14d3e7f05c1af71c6e1f Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 15:34:07 +0000 Subject: [PATCH 137/364] refs #21961 period handling improved in muon Analysis --- .../Common/MuonFitPropertyBrowser.h | 1 + .../common/src/MuonFitPropertyBrowser.cpp | 113 +++++++++--------- 2 files changed, 59 insertions(+), 55 deletions(-) diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index fe70a62bf479..4a6ab89afab1 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -196,6 +196,7 @@ private slots: void clearPeriodCheckboxes(); void addPeriodCheckbox(const QString &name); void updatePeriods(const int j); + bool isPeriodValid(const QString &name); /// Splitter for additional widgets and splitter between this and browser QSplitter *m_widgetSplitter, *m_mainSplitter; diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 0b86588f8f1f..f6a1353e61c6 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1518,26 +1518,20 @@ void MuonFitPropertyBrowser::updatePeriods() { void MuonFitPropertyBrowser::updatePeriods(const int j) { // this is for switching but has a bug at the moment // const QStringList &selected) { + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + m_enumManager->setValue(m_periodsToFit, j); if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { // currently the below does not work reliably (if period arithmatic is // presemnt it gives bad results /* - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); setChosenPeriods(selected);*/ // lets default to all periods for now - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); // explictly set all periods setAllPeriods(); } else if (m_periodsToFitOptions[j] == ALL_PERIODS_LABEL) { - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); // explictly set all periods setAllPeriods(); } else { // single number - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - m_enumManager->setValue(m_periodsToFit, j); setChosenPeriods(m_periodsToFitOptions[j]); } } @@ -1557,7 +1551,51 @@ void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { addPeriodCheckbox(name); updatePeriods(j); } - +/** +* Check if a period is valid +* @param name :: [input] Name of period to add +*/ +bool MuonFitPropertyBrowser::isPeriodValid(const QString &name) { + // check period is sensible + // no frational periods + if (name.contains(".")) { + return false; + } + // wshould only ever have 1 minus sign + else if (name.count("-") > 1) { + return false; + } + else { + std::vector numbers; + boost::algorithm::split(numbers, name.toStdString(), boost::is_any_of(",")); + // loop over results + for (auto value : numbers) { + auto tmp = value.find("-"); + if (tmp != std::string::npos) { + // find a minus sign + auto before = value.substr(0, tmp); + auto after = value.substr(tmp + 1); + + } + else { + try { + boost::lexical_cast(value); + if (m_periodBoxes.find(QString::fromStdString(value)) == + m_periodBoxes.end() && + numbers.size() > 1) { + // if the box does not exist and there is more than 1 period in name + return false; + } + } + catch (boost::bad_lexical_cast) { + // none int value + return false; + } + } + } + } + return true; +} /** * Add a new checkbox to the list of periods with given name * The new checkbox is unchecked by default @@ -1566,52 +1604,17 @@ void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { // check period is sensible // no frational periods - if (name.contains(".")) { - return; - } else { - auto tmp = name.toStdString(); - std::vector numbers; - auto num = tmp.find(","); - while (num != std::string::npos) { - numbers.push_back(tmp.substr(0, num)); - tmp = tmp.substr(num + 1); - num = tmp.find(","); - } - numbers.push_back(tmp); - // loop over results - for (auto value : numbers) { - auto tmp = value.find("-"); - if (tmp != std::string::npos) { - // find a minus sign - auto before = value.substr(0, tmp); - auto after = value.substr(tmp + 1); - - } else { - try { - boost::lexical_cast(value); - if (m_periodBoxes.find(QString::fromStdString(value)) == - m_periodBoxes.end() && - numbers.size() > 1) { - // if the box does not exist and there is more than 1 period in name - return; - } - } catch (boost::bad_lexical_cast) { - // none int value - return; - } - } - } - } - - m_periodBoxes.insert(name, m_boolManager->addProperty(name)); - int j = m_enumManager->value(m_periodsToFit); - // add new period to list will go after inital list - m_periodsToFitOptions << name; - - auto active = getChosenPeriods(); - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - setChosenPeriods(active); - m_enumManager->setValue(m_periodsToFit, j); + if (isPeriodValid(name)) { + m_periodBoxes.insert(name, m_boolManager->addProperty(name)); + int j = m_enumManager->value(m_periodsToFit); + // add new period to list will go after inital list + m_periodsToFitOptions << name; + + auto active = getChosenPeriods(); + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + setChosenPeriods(active); + m_enumManager->setValue(m_periodsToFit, j); + } } /** * Returns a list of the selected periods (checked boxes) From 319db47442678740f04e73229071e5055182c05e Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 15:37:16 +0000 Subject: [PATCH 138/364] refs #21961 clang for period handling improved in muon Analysis --- .../common/src/MuonFitPropertyBrowser.cpp | 97 +++++++++---------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index f6a1353e61c6..21235d62d942 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1556,45 +1556,42 @@ void MuonFitPropertyBrowser::addPeriodCheckboxToMap(const QString &name) { * @param name :: [input] Name of period to add */ bool MuonFitPropertyBrowser::isPeriodValid(const QString &name) { - // check period is sensible - // no frational periods - if (name.contains(".")) { - return false; - } - // wshould only ever have 1 minus sign - else if (name.count("-") > 1) { - return false; - } - else { - std::vector numbers; - boost::algorithm::split(numbers, name.toStdString(), boost::is_any_of(",")); - // loop over results - for (auto value : numbers) { - auto tmp = value.find("-"); - if (tmp != std::string::npos) { - // find a minus sign - auto before = value.substr(0, tmp); - auto after = value.substr(tmp + 1); - - } - else { - try { - boost::lexical_cast(value); - if (m_periodBoxes.find(QString::fromStdString(value)) == - m_periodBoxes.end() && - numbers.size() > 1) { - // if the box does not exist and there is more than 1 period in name - return false; - } - } - catch (boost::bad_lexical_cast) { - // none int value - return false; - } - } - } - } - return true; + // check period is sensible + // no frational periods + if (name.contains(".")) { + return false; + } + // wshould only ever have 1 minus sign + else if (name.count("-") > 1) { + return false; + } else { + std::vector numbers; + boost::algorithm::split(numbers, name.toStdString(), boost::is_any_of(",")); + // loop over results + for (auto value : numbers) { + auto tmp = value.find("-"); + if (tmp != std::string::npos) { + // find a minus sign + auto before = value.substr(0, tmp); + auto after = value.substr(tmp + 1); + + } else { + try { + boost::lexical_cast(value); + if (m_periodBoxes.find(QString::fromStdString(value)) == + m_periodBoxes.end() && + numbers.size() > 1) { + // if the box does not exist and there is more than 1 period in name + return false; + } + } catch (boost::bad_lexical_cast) { + // none int value + return false; + } + } + } + } + return true; } /** * Add a new checkbox to the list of periods with given name @@ -1604,17 +1601,17 @@ bool MuonFitPropertyBrowser::isPeriodValid(const QString &name) { void MuonFitPropertyBrowser::addPeriodCheckbox(const QString &name) { // check period is sensible // no frational periods - if (isPeriodValid(name)) { - m_periodBoxes.insert(name, m_boolManager->addProperty(name)); - int j = m_enumManager->value(m_periodsToFit); - // add new period to list will go after inital list - m_periodsToFitOptions << name; - - auto active = getChosenPeriods(); - m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); - setChosenPeriods(active); - m_enumManager->setValue(m_periodsToFit, j); - } + if (isPeriodValid(name)) { + m_periodBoxes.insert(name, m_boolManager->addProperty(name)); + int j = m_enumManager->value(m_periodsToFit); + // add new period to list will go after inital list + m_periodsToFitOptions << name; + + auto active = getChosenPeriods(); + m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); + setChosenPeriods(active); + m_enumManager->setValue(m_periodsToFit, j); + } } /** * Returns a list of the selected periods (checked boxes) From d0d192df4a579ebe0d6e9cdf2c95393a40b96c4a Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 15:48:10 +0000 Subject: [PATCH 139/364] refs #22042 added catch to muon fit data presenter --- .../Muon/MuonAnalysisFitDataPresenter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index ef9451380a82..4406ccef91b4 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -313,7 +313,12 @@ std::vector MuonAnalysisFitDataPresenter::generateWorkspaceNames( } const std::string instRuns = instrument + runNumber; std::vector selectedRuns; - MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, selectedRuns); + try { + MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, selectedRuns); + } + catch (...) { + throw std::invalid_argument("Failed to parse run label: " + instRuns); + } params.version = 1; params.plotType = m_plotType; From 41755e888d3d16e4a7d6595cbca796c0ca705c47 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 15:53:34 +0000 Subject: [PATCH 140/364] refs #22042 clang for catch to muon fit data presenter --- .../Muon/MuonAnalysisFitDataPresenter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index 4406ccef91b4..e5f5861775f3 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -314,10 +314,10 @@ std::vector MuonAnalysisFitDataPresenter::generateWorkspaceNames( const std::string instRuns = instrument + runNumber; std::vector selectedRuns; try { - MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, selectedRuns); - } - catch (...) { - throw std::invalid_argument("Failed to parse run label: " + instRuns); + MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, + selectedRuns); + } catch (...) { + throw std::invalid_argument("Failed to parse run label: " + instRuns); } params.version = 1; params.plotType = m_plotType; From 62da313f18d7abec4e18fa007f0bdbef7afa102c Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 16:03:11 +0000 Subject: [PATCH 141/364] refs #22031 flake8 for FDA throw error if data changes --- scripts/Muon/fft_model.py | 11 +++++++---- scripts/Muon/maxent_presenter.py | 10 ++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/scripts/Muon/fft_model.py b/scripts/Muon/fft_model.py index 38cbd2b48737..2aa0f3d2e95f 100644 --- a/scripts/Muon/fft_model.py +++ b/scripts/Muon/fft_model.py @@ -4,6 +4,7 @@ import mantid.simpleapi as mantid + class FFTWrapper(object): """ A class to wrap the different parts @@ -14,6 +15,9 @@ def __init__(self,FFT): self.name = "FFT" self.model = FFT + def digit(self,x): + return int(filter(str.isdigit,x) or 0) + def loadData(self,inputs): """ store the data in the wrapper for later @@ -22,10 +26,9 @@ def loadData(self,inputs): ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") - digit = lambda x:int(filter(str.isdigit,x) or 0) - if digit(inputs["Run"]) != ws.getRunNumber(): - mantid.logger.error("Active workspace has changed. Restart this interface") - inputs.clear() + if self.digit(inputs["Run"]) != ws.getRunNumber(): + mantid.logger.error("Active workspace has changed. Restart this interface") + inputs.clear() self.phaseTable = inputs["phaseTable"] else: self.phaseTable = None diff --git a/scripts/Muon/maxent_presenter.py b/scripts/Muon/maxent_presenter.py index 218a671f16a2..0b4081ae8203 100644 --- a/scripts/Muon/maxent_presenter.py +++ b/scripts/Muon/maxent_presenter.py @@ -42,15 +42,17 @@ def createThread(self): def createPhaseThread(self): return thread_model.ThreadModel(self.calcAlg) + def digit(self,x): + return int(filter(str.isdigit,x) or 0) + def handleMaxEntButton(self): ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") - digit = lambda x:int(filter(str.isdigit,x) or 0) run = self.load.getRunName() - if str(digit(run)) != str(ws.getRunNumber()): - mantid.logger.error("Active workspace has changed. Restart this interface") - return + if str(self.digit(run)) != str(ws.getRunNumber()): + mantid.logger.error("Active workspace has changed. Restart this interface") + return if self.view.calcPhases() and self.view.usePhases(): self.DoPhase() else: From 1bcb446fabe7dd9530430825292bf5d7e255b872 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 12 Mar 2018 16:10:35 +0000 Subject: [PATCH 142/364] Re #22049: Added some manual fixes. --- .../Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h | 2 +- .../Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h | 2 +- .../Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h | 2 +- Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h | 2 +- Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h | 4 ++-- Framework/Algorithms/src/DiffractionFocussing2.cpp | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h index b49059fc4fd1..72d23586f7a8 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h @@ -80,7 +80,7 @@ class DLLExport CreateCalFileByNames : public API::Algorithm { private: /// Calibration entries map - typedef std::map> instrcalmap; + using instrcalmap = std::map>; /// Initialisation code void init() override; /// Execution code diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h index c67ea73bb2e8..819b5a108447 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h @@ -79,7 +79,7 @@ class DLLExport CreateDummyCalFile : public API::Algorithm { private: /// Calibration entries map - typedef std::map> instrcalmap; + using instrcalmap = std::map>; /// Initialisation code void init() override; /// Execution code diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h index f480d4d18789..bc4b37726ca0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h @@ -123,7 +123,7 @@ class DLLExport DiffractionFocussing2 : public API::Algorithm { // This map needs to be ordered to process the groups in order. /// typedef for the storage of each group's X vector - typedef std::map> group2vectormap; + using group2vectormap = std::map>; /// Map from udet to group std::vector udet2group; /// The list of group numbers diff --git a/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h b/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h index 5b0c8bd04e47..d1f01cdafa48 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/IQTransform.h @@ -88,7 +88,7 @@ class DLLExport IQTransform : public API::Algorithm { API::MatrixWorkspace_sptr background); using TransformFunc = void (IQTransform::*)(API::MatrixWorkspace_sptr); - typedef std::map TransformMap; + using TransformMap = std::map; TransformMap m_transforms; ///< A map of transformation name and function pointers diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h b/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h index b8c0717991ba..6624446363e4 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h @@ -75,8 +75,8 @@ class DLLExport SmoothData : public API::Algorithm { void exec() override; int validateSpectrumInGroup(size_t wi); // This map does not need to be ordered, just a lookup for udet - /// typedef for the storage of the UDET-group mapping - typedef std::map udet2groupmap; + /// type alias for the storage of the UDET-group mapping + using udet2groupmap = std::map; std::vector udet2group; API::MatrixWorkspace_const_sptr inputWorkspace; }; diff --git a/Framework/Algorithms/src/DiffractionFocussing2.cpp b/Framework/Algorithms/src/DiffractionFocussing2.cpp index 3924340f985a..58c6ee88d20a 100644 --- a/Framework/Algorithms/src/DiffractionFocussing2.cpp +++ b/Framework/Algorithms/src/DiffractionFocussing2.cpp @@ -532,7 +532,7 @@ void DiffractionFocussing2::determineRebinParameters() { std::ostringstream mess; // typedef for the storage of the group ranges - typedef std::map> group2minmaxmap; + using group2minmaxmap = std::map>; // Map from group number to its associated range parameters group2minmaxmap group2minmax; group2minmaxmap::iterator gpit; From def8b2132fc2b055c4dd10a5990376fbbf908ba2 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 17:51:38 +0000 Subject: [PATCH 143/364] refs #22023 muon handles auto background gracefully --- docs/source/release/v3.12.0/muon.rst | 3 ++- .../Muon/MuonAnalysis.cpp | 3 ++- .../common/src/MuonFitPropertyBrowser.cpp | 20 +++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 25f61f3ccead..fe75b25c05ae 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -28,7 +28,8 @@ Interface - The Frequency Domain Analysis GUI now uses :ref:`MuonMaxent ` to calculate the frequency spectrum in MaxEnt mode. - The ALC interface now allows background sections with negative values. - If data is loaded with 0 good frames into Muon Analysis then it will try to load the data without dead time correction (does not need number of good frames). -- Muon analysis no longer disables the "aco add" and "simultaneous" buttons in the multiple fitting interface. +- Muon analysis no longer disables the "co add" and "simultaneous" buttons in the multiple fitting interface. +- Muon analysis now handles the "auto background" gracefully in single and multiple fitting modes. Algorithms ---------- diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 5dddcac3068e..502c8039a124 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -2654,7 +2654,8 @@ void MuonAnalysis::changeTab(int newTabIndex) { m_uiForm.fitBrowser->setTFAsymm(true); } else { m_uiForm.fitBrowser->setTFAsymm(false); - } + } m_uiForm.fitBrowser->checkFitEnabled(); + } else if (newTab == m_uiForm.ResultsTable) { m_resultTableTab->refresh(); } diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 6a199c0eba5f..6bd6d8a09f69 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -287,6 +287,7 @@ void MuonFitPropertyBrowser::init() { connect(this, SIGNAL(functionChanged()), SLOT(updateStructureTooltips())); // disable TFAsymm mode by default setTFAsymmMode(TFAsymmMode); + m_autoBackground = getAutoBackgroundString(); } // Set up the execution of the muon fit menu void MuonFitPropertyBrowser::executeFitMenu(const QString &item) { @@ -332,6 +333,18 @@ void MuonFitPropertyBrowser::setFitEnabled(bool yes) { m_fitActionTFAsymm->setEnabled(false); } } + +void MuonFitPropertyBrowser::checkFitEnabled() { + if (m_reselectGroupBtn->isVisible()) { + setFitEnabled(false); + } + else if(getAutoBackgroundString() != "") { + setFitEnabled(true); + } + else { + setFitEnabled(false); + } +} /** * Set the input workspace name */ @@ -1184,7 +1197,13 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { if (enabled) { setAllGroups(); setAllPeriods(); + setAutoBackgroundName(""); + } else { // clear current selection + if (m_autoBackground != "") { + setAutoBackgroundName(m_autoBackground); + addAutoBackground(); + } clearChosenGroups(); clearChosenPeriods(); } @@ -1199,6 +1218,7 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { widget->setVisible(enabled); } } + if (enabled){ setFitEnabled(false); } } /** * Set TF asymmetry mode on or off. From a5e7f4e3d064660c8a77a202b6a3a6f3cfcc93f5 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 17:59:07 +0000 Subject: [PATCH 144/364] refs #22023 clang for muon handles auto background gracefully --- .../Muon/MuonAnalysis.cpp | 3 +- .../Common/MuonFitPropertyBrowser.h | 2 ++ .../common/src/MuonFitPropertyBrowser.cpp | 30 +++++++++---------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 502c8039a124..f63d848540ed 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -2654,7 +2654,8 @@ void MuonAnalysis::changeTab(int newTabIndex) { m_uiForm.fitBrowser->setTFAsymm(true); } else { m_uiForm.fitBrowser->setTFAsymm(false); - } m_uiForm.fitBrowser->checkFitEnabled(); + } + m_uiForm.fitBrowser->checkFitEnabled(); } else if (newTab == m_uiForm.ResultsTable) { m_resultTableTab->refresh(); diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index 8e7644cae7d8..92824b46421a 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -118,6 +118,7 @@ class EXPORT_OPT_MANTIDQT_COMMON MuonFitPropertyBrowser void setChosenPeriods(const QString &period); void setSingleFitLabel(std::string name); void setNormalization(const std::string name); + void checkFitEnabled(); public slots: /// Perform the fit algorithm void fit() override; @@ -230,6 +231,7 @@ private slots: QDialog *m_comboWindow; std::vector m_groupsList; + QString m_autoBackground; }; std::map readMultipleNormalization(); diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 6bd6d8a09f69..4a0a2cc11f28 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -335,15 +335,13 @@ void MuonFitPropertyBrowser::setFitEnabled(bool yes) { } void MuonFitPropertyBrowser::checkFitEnabled() { - if (m_reselectGroupBtn->isVisible()) { - setFitEnabled(false); - } - else if(getAutoBackgroundString() != "") { - setFitEnabled(true); - } - else { - setFitEnabled(false); - } + if (m_reselectGroupBtn->isVisible()) { + setFitEnabled(false); + } else if (getAutoBackgroundString() != "") { + setFitEnabled(true); + } else { + setFitEnabled(false); + } } /** * Set the input workspace name @@ -1197,13 +1195,13 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { if (enabled) { setAllGroups(); setAllPeriods(); - setAutoBackgroundName(""); + setAutoBackgroundName(""); } else { // clear current selection - if (m_autoBackground != "") { - setAutoBackgroundName(m_autoBackground); - addAutoBackground(); - } + if (m_autoBackground != "") { + setAutoBackgroundName(m_autoBackground); + addAutoBackground(); + } clearChosenGroups(); clearChosenPeriods(); } @@ -1218,7 +1216,9 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { widget->setVisible(enabled); } } - if (enabled){ setFitEnabled(false); } + if (enabled) { + setFitEnabled(false); + } } /** * Set TF asymmetry mode on or off. From ad28685779d9c2cf598933286cc5c85f87f11b3e Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 18:04:51 +0000 Subject: [PATCH 145/364] refs #22042 added alternative to catch in muon analysis parse run --- .../Muon/MuonAnalysisFitDataPresenter.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index e5f5861775f3..7874ce0ef6ab 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -317,7 +317,14 @@ std::vector MuonAnalysisFitDataPresenter::generateWorkspaceNames( MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, selectedRuns); } catch (...) { - throw std::invalid_argument("Failed to parse run label: " + instRuns); + params.instrument = instrument; + try { + MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, + selectedRuns); + } + catch (...) { + g_log.error("Cannot Parse workspace " + instRuns); + } } params.version = 1; params.plotType = m_plotType; From a0f8eadca85282e39c6850cc52efa1935535bef3 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Mon, 12 Mar 2018 18:07:55 +0000 Subject: [PATCH 146/364] refs #22042 clang for added alternative to catch in muon analysis --- .../Muon/MuonAnalysisFitDataPresenter.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index 7874ce0ef6ab..476db8ec0082 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -317,14 +317,13 @@ std::vector MuonAnalysisFitDataPresenter::generateWorkspaceNames( MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, selectedRuns); } catch (...) { - params.instrument = instrument; - try { - MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, - selectedRuns); - } - catch (...) { - g_log.error("Cannot Parse workspace " + instRuns); - } + params.instrument = instrument; + try { + MuonAnalysisHelper::parseRunLabel(instRuns, params.instrument, + selectedRuns); + } catch (...) { + g_log.error("Cannot Parse workspace " + instRuns); + } } params.version = 1; params.plotType = m_plotType; From b95844fc07333a83d6f2a81975115da5bb010d2c Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 07:46:23 +0000 Subject: [PATCH 147/364] refs #21961 muon fit browser uses split --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 21235d62d942..8d4bd708677e 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1566,7 +1566,8 @@ bool MuonFitPropertyBrowser::isPeriodValid(const QString &name) { return false; } else { std::vector numbers; - boost::algorithm::split(numbers, name.toStdString(), boost::is_any_of(",")); + std::string nameString = name.toStdString(); + boost::algorithm::split(numbers, nameString, boost::is_any_of(",")); // loop over results for (auto value : numbers) { auto tmp = value.find("-"); From 38a05ad144eaaaa9482973f93dd1e2f37a57db36 Mon Sep 17 00:00:00 2001 From: Gagik Vardanyan Date: Thu, 1 Mar 2018 14:30:29 +0100 Subject: [PATCH 148/364] Re #0 try copy over matplotlib --- MantidPlot/make_package.rb.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MantidPlot/make_package.rb.in b/MantidPlot/make_package.rb.in index d281c0774c7a..d81580171414 100755 --- a/MantidPlot/make_package.rb.in +++ b/MantidPlot/make_package.rb.in @@ -165,7 +165,7 @@ if( "@MAKE_VATES@" == "ON" ) currentname = dependency.strip.split(" ") filename = currentname[0] if filename.include? "#{ParaView_dir}" - #p "fixing #{library} #{filename}" + #p "fixing #{library} #{filename}" issues_found = issues_found + 1 name_split_on_slash = filename.strip.split("/") filename_no_dir = name_split_on_slash[-1] @@ -209,7 +209,7 @@ end #We'll use macdeployqt to fix qt dependencies. Qt_Executables = "-executable=Contents/MacOS/mantidqtpython.so -executable=Contents/MacOS/libqwtplot3d.dylib -executable=Contents/MacOS/libqwt.dylib " -Qt_Executables << "-executable=Contents/MacOS/#{findQScintilla2(lib_dir)}" +Qt_Executables << "-executable=Contents/MacOS/#{findQScintilla2(lib_dir)}" if( "@MAKE_VATES@" == "ON" ) list = ["Contents/Libraries/vtkParaViewWebCorePython.so", @@ -314,10 +314,10 @@ end `install_name_tool -change #{QtLinkingDir[0]}/QtCore.framework/Versions/4/QtCore @loader_path/../../Frameworks/QtCore.framework/Versions/4/QtCore Contents/MacOS/PyQt4/QtXml.so` -#Copy over python libraries not included with OSX. +#Copy over python libraries not included with OSX. #currently missing epics path = "/Library/Python/2.7/site-packages" -directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml"] +directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml", "matplotlib", "mpl_toolkits"] directories.each do |directory| addPythonLibrary("#{path}/#{directory}","Contents/MacOS/") end From e72a24480cb9eb7fbd0ab25fbab7ef0df0972e60 Mon Sep 17 00:00:00 2001 From: Gagik Vardanyan Date: Mon, 12 Mar 2018 09:52:19 +0100 Subject: [PATCH 149/364] Re #0 attempt 2, from system python extra libs --- MantidPlot/make_package.rb.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MantidPlot/make_package.rb.in b/MantidPlot/make_package.rb.in index d81580171414..9d320e3471d8 100755 --- a/MantidPlot/make_package.rb.in +++ b/MantidPlot/make_package.rb.in @@ -317,11 +317,17 @@ end #Copy over python libraries not included with OSX. #currently missing epics path = "/Library/Python/2.7/site-packages" -directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml", "matplotlib", "mpl_toolkits"] +directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml"] directories.each do |directory| addPythonLibrary("#{path}/#{directory}","Contents/MacOS/") end +system_python_extras = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python" +modules = ["matplotlib", "mpl_toolkits"] +modules.each do |directory| + addPythonLibrary("#{{system_python_extras}}/#{directory}","Contents/MacOS/") +end + if( "@MAKE_VATES@" == "ON" ) addPythonLibrariesInDirectory("#{ParaView_dir}/lib/site-packages","Contents/Python/") end From b44f2a00cd7bf08e6f9d4639dd89f57b919eb56c Mon Sep 17 00:00:00 2001 From: Gagik Vardanyan Date: Mon, 12 Mar 2018 09:54:14 +0100 Subject: [PATCH 150/364] Re #0 trim extra brackets --- MantidPlot/make_package.rb.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MantidPlot/make_package.rb.in b/MantidPlot/make_package.rb.in index 9d320e3471d8..2da0e445d8e6 100755 --- a/MantidPlot/make_package.rb.in +++ b/MantidPlot/make_package.rb.in @@ -325,7 +325,7 @@ end system_python_extras = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python" modules = ["matplotlib", "mpl_toolkits"] modules.each do |directory| - addPythonLibrary("#{{system_python_extras}}/#{directory}","Contents/MacOS/") + addPythonLibrary("#{system_python_extras}/#{directory}","Contents/MacOS/") end if( "@MAKE_VATES@" == "ON" ) From a1c367a513286ce87e86b623cbc9f622a6462d05 Mon Sep 17 00:00:00 2001 From: Gagik Vardanyan Date: Mon, 12 Mar 2018 16:18:08 +0100 Subject: [PATCH 151/364] Re #0 touch empty init.py, remove mpl itself --- MantidPlot/make_package.rb.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MantidPlot/make_package.rb.in b/MantidPlot/make_package.rb.in index 2da0e445d8e6..03a8e72da834 100755 --- a/MantidPlot/make_package.rb.in +++ b/MantidPlot/make_package.rb.in @@ -322,11 +322,15 @@ directories.each do |directory| addPythonLibrary("#{path}/#{directory}","Contents/MacOS/") end +# System mpl_toolkits in macOS 10.12 and above do not have __init__.py which causes a problem importing +# So we pack the mpl_toolkits and touch an empty file to temporarily work around it +#TODO: consider installing mpl_toolkits (thus matplotlib) with pip system_python_extras = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python" -modules = ["matplotlib", "mpl_toolkits"] +modules = ["mpl_toolkits"] modules.each do |directory| addPythonLibrary("#{system_python_extras}/#{directory}","Contents/MacOS/") end +`touch Contents/MacOS/mpl_toolkits/__init__.py` if( "@MAKE_VATES@" == "ON" ) addPythonLibrariesInDirectory("#{ParaView_dir}/lib/site-packages","Contents/Python/") From 4e00d2e4e6175e344cdfa1fce906321b1ee05fe0 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 08:06:11 +0000 Subject: [PATCH 152/364] refs #21961 clang for muon fit browser uses split --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 8d4bd708677e..de6a2b0d0922 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1566,7 +1566,7 @@ bool MuonFitPropertyBrowser::isPeriodValid(const QString &name) { return false; } else { std::vector numbers; - std::string nameString = name.toStdString(); + std::string nameString = name.toStdString(); boost::algorithm::split(numbers, nameString, boost::is_any_of(",")); // loop over results for (auto value : numbers) { From cc045a9713f6f6284150149276d26d26997833ed Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 09:03:27 +0000 Subject: [PATCH 153/364] refs #22031 improved error checking in FDA --- docs/source/release/v3.12.0/muon.rst | 1 + scripts/Muon/fft_model.py | 9 --------- scripts/Muon/fft_presenter.py | 3 ++- scripts/Muon/fft_view.py | 2 +- scripts/Muon/maxent_presenter.py | 23 ++++++++--------------- scripts/Muon/maxent_view.py | 11 +++++------ scripts/Muon/thread_model.py | 24 +++++++++++++++++++++--- 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 25f61f3ccead..663cb2b4d2f8 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -29,6 +29,7 @@ Interface - The ALC interface now allows background sections with negative values. - If data is loaded with 0 good frames into Muon Analysis then it will try to load the data without dead time correction (does not need number of good frames). - Muon analysis no longer disables the "aco add" and "simultaneous" buttons in the multiple fitting interface. +- Frequency domain analysis will produce an error if the active workspace has changed. Algorithms ---------- diff --git a/scripts/Muon/fft_model.py b/scripts/Muon/fft_model.py index 2aa0f3d2e95f..40b0d90d72b6 100644 --- a/scripts/Muon/fft_model.py +++ b/scripts/Muon/fft_model.py @@ -15,20 +15,11 @@ def __init__(self,FFT): self.name = "FFT" self.model = FFT - def digit(self,x): - return int(filter(str.isdigit,x) or 0) - def loadData(self,inputs): """ store the data in the wrapper for later """ if "phaseTable" in inputs: - ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") - if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): - ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") - if self.digit(inputs["Run"]) != ws.getRunNumber(): - mantid.logger.error("Active workspace has changed. Restart this interface") - inputs.clear() self.phaseTable = inputs["phaseTable"] else: self.phaseTable = None diff --git a/scripts/Muon/fft_presenter.py b/scripts/Muon/fft_presenter.py index dd620f76ff4c..1fc9e81ddbdd 100644 --- a/scripts/Muon/fft_presenter.py +++ b/scripts/Muon/fft_presenter.py @@ -47,7 +47,8 @@ def tableClicked(self,row,col): self.view.changed(self.view.getShiftBox(),self.view.getShiftBoxRow()+1) def createThread(self): - return thread_model.ThreadModel(self.alg) + runName=self.load.getRunName() + return thread_model.ThreadModel(self.alg,runName) # constructs the inputs for the FFT algorithms # then executes them (see fft_model to see the order diff --git a/scripts/Muon/fft_view.py b/scripts/Muon/fft_view.py index 49fd1f8bd59b..e57d107b55a6 100644 --- a/scripts/Muon/fft_view.py +++ b/scripts/Muon/fft_view.py @@ -170,7 +170,7 @@ def initFFTInput(self): inputs['InputWorkspace'] = "__ReTmp__"#str( self.ws.currentText()).replace(";","; ") inputs['Real'] = 0 # always zero out = str( self.ws.currentText()).replace(";","; ") - inputs['OutputWorkspace'] = out+";FFT" + inputs['OutputWorkspace'] = self.getRunName()+";"+out+";FFT" inputs["AcceptXRoundingErrors"] = True return inputs diff --git a/scripts/Muon/maxent_presenter.py b/scripts/Muon/maxent_presenter.py index 0b4081ae8203..a05a634cbacd 100644 --- a/scripts/Muon/maxent_presenter.py +++ b/scripts/Muon/maxent_presenter.py @@ -37,25 +37,17 @@ def getWorkspaceNames(self): self.view.addNPoints(values) def createThread(self): - return thread_model.ThreadModel(self.alg) + runName=self.load.getRunName() + return thread_model.ThreadModel(self.alg,runName) def createPhaseThread(self): - return thread_model.ThreadModel(self.calcAlg) - - def digit(self,x): - return int(filter(str.isdigit,x) or 0) + runName=self.load.getRunName() + return thread_model.ThreadModel(self.calcAlg,runName) def handleMaxEntButton(self): - ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") - if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): - ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") - run = self.load.getRunName() - if str(self.digit(run)) != str(ws.getRunNumber()): - mantid.logger.error("Active workspace has changed. Restart this interface") - return - if self.view.calcPhases() and self.view.usePhases(): + if self.view.calcPhases() and self.view.usePhases(): self.DoPhase() - else: + else: self.DoMaxEnt() def DoMaxEnt(self): @@ -66,8 +58,8 @@ def DoMaxEnt(self): inputs = self.getMaxEntInput() if self.view.usePhases(): self.view.addPhaseTable(inputs) - runName=self.load.getRunName() + runName=self.load.getRunName() self.thread.setInputs(inputs,runName) self.thread.start() @@ -82,6 +74,7 @@ def DoPhase(self): self.calcThread.started.connect(self.deactivate) self.calcThread.finished.connect(self.handleFinishedCalc) self.calcThread.loadData(inputs_phase) + runName=self.load.getRunName() self.calcThread.start() def handlePhase(self,row,col): diff --git a/scripts/Muon/maxent_view.py b/scripts/Muon/maxent_view.py index 9854597b4f89..82af799bca30 100644 --- a/scripts/Muon/maxent_view.py +++ b/scripts/Muon/maxent_view.py @@ -187,8 +187,7 @@ def initMaxEntInput(self): # will remove this when sim maxent Works out=self.run.replace(";","; ") - inputs['OutputWorkspace']=out+";FrequencyDomain;MaxEnt" - + inputs['OutputWorkspace']=out+";"+ str( self.ws.currentText()) +";FrequencyDomain;MaxEnt" return inputs def addPhaseTable(self,inputs): @@ -198,25 +197,25 @@ def outputPhases(self): return self.output_phase_box.checkState() == QtCore.Qt.Checked def addOutputPhases(self,inputs): - inputs['OutputPhaseTable']=self.run+";PhaseTable;MaxEnt" + inputs['OutputPhaseTable']=self.run+";"+ str( self.ws.currentText()) +";PhaseTable;MaxEnt" def outputDeadTime(self): return self.output_dead_box.checkState() == QtCore.Qt.Checked def addOutputDeadTime(self,inputs): - inputs['OutputDeadTimeTable']=self.run+";DeadTimeTable;MaxEnt" + inputs['OutputDeadTimeTable']=self.run+";"+ str( self.ws.currentText()) +";DeadTimeTable;MaxEnt" def outputPhaseEvo(self): return self.output_phase_evo_box.checkState() == QtCore.Qt.Checked def addOutputPhaseEvo(self,inputs): - inputs['PhaseConvergenceTable']=self.run+";PhaseConvergenceTable;MaxEnt" + inputs['PhaseConvergenceTable']=self.run+";"+ str( self.ws.currentText()) +";PhaseConvergenceTable;MaxEnt" def outputTime(self): return self.output_data_box.checkState() == QtCore.Qt.Checked def addOutputTime(self,inputs): - inputs['ReconstructedSpectra']=self.run+";TimeDomain;MaxEnt" + inputs['ReconstructedSpectra']=self.run+";"+ str( self.ws.currentText()) +";TimeDomain;MaxEnt" def calcPhases(self): return self.phaseTable_box.checkState() == QtCore.Qt.Checked diff --git a/scripts/Muon/thread_model.py b/scripts/Muon/thread_model.py index 50f9140b7f2d..4d578e33dda4 100644 --- a/scripts/Muon/thread_model.py +++ b/scripts/Muon/thread_model.py @@ -1,6 +1,7 @@ from __future__ import (absolute_import, division, print_function) from PyQt4.QtCore import QThread +import mantid.simpleapi as mantid class ThreadModel(QThread): @@ -9,18 +10,35 @@ class ThreadModel(QThread): A wrapper to allow threading with the MaxEnt models. """ - def __init__(self,model): + def __init__(self,model,run): QThread.__init__(self) self.model=model + self.run = run def __del__(self): self.wait() + + def digit(self,x): + return int(filter(str.isdigit,x) or 0) + + def hasDataChanged(self): + ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") + if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): + ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") + + current = ws.getInstrument().getName()+str(ws.getRunNumber()).zfill(8) + if self.run != current: + mantid.logger.error("Active workspace has changed. Restart this interface") + return True + return False def run(self): - try: + if self.hasDataChanged(): + return + try: self.model.execute() self.model.output() - except KeyboardInterrupt: + except KeyboardInterrupt: pass def cancel(self): From 9d5d485c17c6dcdc63b8f15b4d31ed60dc59df7c Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 09:10:30 +0000 Subject: [PATCH 154/364] refs #22031 flake8 for improved error checking in FDA --- scripts/Muon/maxent_presenter.py | 5 ++--- scripts/Muon/thread_model.py | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/scripts/Muon/maxent_presenter.py b/scripts/Muon/maxent_presenter.py index a05a634cbacd..1aa6866a9000 100644 --- a/scripts/Muon/maxent_presenter.py +++ b/scripts/Muon/maxent_presenter.py @@ -45,9 +45,9 @@ def createPhaseThread(self): return thread_model.ThreadModel(self.calcAlg,runName) def handleMaxEntButton(self): - if self.view.calcPhases() and self.view.usePhases(): + if self.view.calcPhases() and self.view.usePhases(): self.DoPhase() - else: + else: self.DoMaxEnt() def DoMaxEnt(self): @@ -74,7 +74,6 @@ def DoPhase(self): self.calcThread.started.connect(self.deactivate) self.calcThread.finished.connect(self.handleFinishedCalc) self.calcThread.loadData(inputs_phase) - runName=self.load.getRunName() self.calcThread.start() def handlePhase(self,row,col): diff --git a/scripts/Muon/thread_model.py b/scripts/Muon/thread_model.py index 4d578e33dda4..563a80366ac6 100644 --- a/scripts/Muon/thread_model.py +++ b/scripts/Muon/thread_model.py @@ -17,7 +17,7 @@ def __init__(self,model,run): def __del__(self): self.wait() - + def digit(self,x): return int(filter(str.isdigit,x) or 0) @@ -33,12 +33,12 @@ def hasDataChanged(self): return False def run(self): - if self.hasDataChanged(): - return - try: + if self.hasDataChanged(): + return + try: self.model.execute() self.model.output() - except KeyboardInterrupt: + except KeyboardInterrupt: pass def cancel(self): From a5b6ffdd34f0f49e272fa88af3af9fa30c5659e5 Mon Sep 17 00:00:00 2001 From: Elliot Oram Date: Mon, 12 Mar 2018 15:20:19 +0000 Subject: [PATCH 155/364] Add validation for workspaces to have x>0 Refs #22029 --- qt/scientific_interfaces/Indirect/IqtFit.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Indirect/IqtFit.cpp b/qt/scientific_interfaces/Indirect/IqtFit.cpp index 9144339b7938..dc168ad34453 100644 --- a/qt/scientific_interfaces/Indirect/IqtFit.cpp +++ b/qt/scientific_interfaces/Indirect/IqtFit.cpp @@ -345,6 +345,11 @@ bool IqtFit::validate() { if (isEmptyModel()) uiv.addErrorMessage("No fit function has been selected"); + if (inputWorkspace()->getXMin() < 0) { + uiv.addErrorMessage("Error in input workspace: All X data must be " + "greater than or equal to 0."); + } + auto error = uiv.generateErrorMessage(); emit showMessageBox(error); return error.isEmpty(); @@ -364,7 +369,7 @@ void IqtFit::loadSettings(const QSettings &settings) { void IqtFit::newDataLoaded(const QString wsName) { IndirectFitAnalysisTab::newInputDataLoaded(wsName); - int maxWsIndex = + const auto maxWsIndex = static_cast(inputWorkspace()->getNumberHistograms()) - 1; m_uiForm->spPlotSpectrum->setMaximum(maxWsIndex); From 46c2afc407b86ba8baef1e680a3a4707a60dc2cf Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Tue, 13 Mar 2018 09:35:22 +0000 Subject: [PATCH 156/364] Fixed links/ordering; consistent format of points. --- docs/source/release/v3.12.0/framework.rst | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst index 2ca2ef8cdf35..281f82e05a3c 100644 --- a/docs/source/release/v3.12.0/framework.rst +++ b/docs/source/release/v3.12.0/framework.rst @@ -5,8 +5,8 @@ Framework Changes .. contents:: Table of Contents :local: -.. warning:: **Developers:** Sort changes under appropriate heading - putting new features at the top of the section, followed by +.. warning:: **Developers:** Sort changes under appropriate heading. + Put new features at the top of the section, followed by improvements, followed by bug fixes. Instrument Definition Updates @@ -16,9 +16,9 @@ Instrument Definition Updates Concepts -------- -Corrupted Instrument Definitions +Instrument Definitions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. warning:: Instruments in Mantid will no longer silently discard detectors defined with duplicate IDs. This has been a long-standing source of hard to find issue in Mantid. We have endeavoured to ensure that all :ref:`Instrument Definition Files ` shipped with Mantid are now corrected. **If you have local IDFs, please update them to remove any duplicate IDs, or ask the Mantid Team for help**, the warning and error information in Mantid will give details about duplicates in IDFs that cannot be loaded. +.. warning:: **Users:** Instruments in Mantid will no longer silently discard detectors defined with duplicate IDs. This has been a long-standing source of hard to find issue in Mantid. We have endeavoured to ensure that all :ref:`Instrument Definition Files ` shipped with Mantid are now corrected. **If you have local IDFs, please update them to remove any duplicate IDs, or ask the Mantid Team for help**, the warning and error information in Mantid will give details about duplicates in IDFs that cannot be loaded. Beware that :ref:`LoadNexusProcessed ` will now **NOT load the Instrument from historic Processed Nexus files if the embedded IDF is corruped with duplicate detector IDs**. The workspace (data) part will still load, but the workspace will not have any Instrument attached. There are new warnings generated that describe the exact problem and the remedy when this happens. Note that the fix is generally easy. You should be able to run :ref:`LoadInstrument ` on the Workspace, pointing it to an updated IDF, which is free of duplicates. @@ -26,27 +26,28 @@ Please contact the Mantid Team if you experience any further problems as a resul Algorithms ---------- - +- :ref:`MostLikelyMean ` is a new algorithm that computes the mean of the given array, that has the least distance from the rest of the elements. +- :ref:`LoadAndMerge ` is a new algorithm that can load and merge multiple runs. +- :ref:`CropWorkspaceRagged `: New algorithm that will crop each spectrum with a different x-range. +- :ref:`LoadLamp `: New algorithm to load processed HDF5 files produced by LAMP program at ILL. +- :ref:`SaveReflections ` is a new algorithm to save PeaksWorkspaces to Fullprof, Jana, GSAS, and SHELX text formats. - :ref:`NormaliseToMonitor ` now supports workspaces with detector scans and workspaces with single-count point data. -- It is now possible to choose between weighted and unweighted fitting in :ref:`CalculatePolynomialBackground `. +- :ref:`CalculatePolynomialBackground `: It is now possible to choose between weighted and unweighted fitting. - :ref:`CreateWorkspace ` will no longer create a default (and potentially wrong) mapping from spectra to detectors, unless a parent workspace is given. This change ensures that accidental bad mappings that could lead to corrupted data are not created silently anymore. This change does *not* affect the use of this algorithm if: (1) a parent workspace is given, or (2) no instrument is loaded into to workspace at a later point, or (3) an instrument is loaded at a later point but ``LoadInstrument`` is used with ``RewriteSpectraMapping=True``. See also the algorithm documentation for details. - :ref:`ConjoinWorkspaces ` now supports non-constant bins. - :ref:`Fit ` will now respect excluded ranges when ``CostFunction = 'Unweighted least squares'``. -- :ref:`NormaliseToMonitor ` now supports non-constant number of bins. -- :ref:`MostLikelyMean ` is a new algorithm that computes the mean of the given array, that has the least distance from the rest of the elements. -- :ref:`LoadAndMerge ` is a new algorithm that can load and merge multiple runs. +- :ref:`NormaliseToMonitor ` now supports a non-constant number of bins. - :ref:`CompressEvents ` now supports compressing events with pulse time. - :ref:`MaskBins ` now uses a modernized and standardized way for providing a list of workspace indices. For compatibility reasons the previous ``SpectraList`` property is still supported. -- :ref:`Fit ` has had a bug fixed that prevented a fix from being removed. - :ref:`LoadMcStas ` now loads event data in separate workspaces (single scattering, multiple scattering) as well as all scattering. -- :ref:`LoadMask ` has had a bug fixed that could, under certain conditions, cause detectors from previously loaded masking to be added to the currently loaded masking. -- In :ref:`MaxEnt ` the ``EvolChi`` and ``EvolAngle`` workspaces only contain data up until the result has converged. -- New algorithm :ref:`CropWorkspaceRagged ` will crop each spectrum with a different x-range -- :ref:`LoadLamp ` is a new algorithm to load processed HDF5 files produced by LAMP program at ILL. +- :ref:`MaxEnt `: The ``EvolChi`` and ``EvolAngle`` workspaces now only contain data up until the result has converged. - :ref:`SaveNexus ` will no longer crash when passed a ``PeaksWorkspace`` with integrated peaks that have missing radius information. -- :ref:`SaveReflections ` is a new algorithm to save PeaksWorkspaces to Fullprof, Jana, GSAS, and SHELX text formats. - :ref:`ConjoinXRuns ` will now accept workspaces with varying x-axes per spectrum. -- :ref:`LoadEXED ` has better handling of monitor workspace and sample logs +- :ref:`LoadEXED ` has better handling of monitor workspace and sample logs. +- :ref:`Fit ` has had a bug fixed that prevented a fix from being removed. +- :ref:`LoadMask ` has had a bug fixed that could, under certain conditions, cause detectors from previously loaded masking to be added to the currently loaded masking. + + Known Issues ^^^^^^^^^^^^ @@ -68,13 +69,13 @@ Core Functionality - :class:`mantid.kernel.FloatTimeSeriesProperty` now returns :class:`numpy.datetime64` for the log times. - The duration reported by a running algorithm now includes time spent for validation of properties and inputs. This fixes a discrepancy between observed and reported timings if validation is expensive, e.g., when checking if a file exists. More detailed timing information is now available when setting the log level to ``debug``. - Fixed an issue where certain isotopes could not be accessed using the `Atom` classes, e.g Si28. -- Added new functionality to ``datasearch.searcharchive`` :ref:`property ` to only search the default facility +- ``datasearch.searcharchive`` :ref:`property ` has new functionality to only search the default facility. - The status of a fit in the fit window is now at the top of the of the dialog instead of the bottom. - Condition to check if a property is enabled when serializing. - Workspace locking no longer prevents simple read operations required to display the workspace conext menu in Mantidplot. -- TableWorkspaces can new be converted to a python dictionary by calling the ``table.toDict()`` function. +- TableWorkspaces can now be converted to a Python dictionary by calling the ``table.toDict()`` function. - Added new classes ``ConfigObserver`` for listening for changes to any configuration property and ``ConfigPropertyObserver`` for listening to changes to an individual config property of interest. -- Fixed the calculation of scattering length and scattering length squared for :py:obj:`Material ` +- Fixed the calculation of scattering length and scattering length squared for :py:obj:`Material `. - Fixed the behaviour of ``UpdateInstrumentDefinitions.OnStartup`` in the :ref:`properties file `. It was not being used correctly for using the updated ``Facilities.xml`` file. - ``MultiFileProperty`` now accepts complex summation ranges for run numbers, such as ``111-113+115`` and ``111-115+123-132``. @@ -86,11 +87,10 @@ Live Data Performance ----------- -- Improved performance for second and consecutive loads of instrument geometry, particularly for instruments with many detector pixels. This affects :ref:`LoadEmptyInstrument ` and load algorithms that are using it. -- Up to 30% performance improvement for :ref:`CropToComponent ` based on ongoing work on Instrument-2.0. -- Improved rate of convergence for :ref:`MaxEnt `. The ``ChiTarget`` property has been replaced by ``ChiTargetOverN``. - -A `bug `_ in the handling of fractional bin weights in a specialised form (`RebinnedOutput `_) of :ref:`Workspace2D ` has been fixed. This mainly affects the algorithms :ref:`algm-SofQWNormalisedPolygon` and :ref:`algm-Rebin2D`, which underlies the `SliceViewer `_. +- :ref:`LoadEmptyInstrument ` and load algorithms that are using it. Improved performance for second and consecutive loads of instrument geometry, particularly for instruments with many detector pixels. +- :ref:`CropToComponent `: Up to 30% performance improvement, based on ongoing work on Instrument-2.0. +- :ref:`MaxEnt `: Improved rate of convergence. The ``ChiTarget`` property has been replaced by ``ChiTargetOverN``. +- A `bug `_ in the handling of fractional bin weights in a specialised form (`RebinnedOutput `_) of :ref:`Workspace2D ` has been fixed. This mainly affects the algorithms :ref:`algm-SofQWNormalisedPolygon` and :ref:`algm-Rebin2D`, which underlies the `SliceViewer `_. Python ------ From 81d520ba4e56deaeed7ce78bc95f21a3f8b196a6 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 13 Mar 2018 09:25:29 +0000 Subject: [PATCH 157/364] Made Reflectometry GUI postprocess using unbinned IvsQ workspace. - Added method postprocessedOutputPrefix and postprocessedOutputPropertyName to ProcessingAlgorithm. - Added index parameter to constructor. - Specified index 1 as postprocessed output property index in ReflGenericDataProcessorPresenterFactory. - Updated Sans to pass a dummy value here. --- .../mantidqtpython/mantidqtpython_def.sip | 2 +- ...flGenericDataProcessorPresenterFactory.cpp | 2 +- .../DataProcessorUI/ProcessingAlgorithm.h | 9 +++++ .../GenericDataProcessorPresenter.cpp | 6 +-- .../DataProcessorUI/ProcessingAlgorithm.cpp | 37 ++++++++++++++++--- .../ui/sans_isis/sans_data_processor_gui.py | 3 +- 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/qt/python/mantidqtpython/mantidqtpython_def.sip b/qt/python/mantidqtpython/mantidqtpython_def.sip index 18c1193d7a72..7c8f52894c39 100644 --- a/qt/python/mantidqtpython/mantidqtpython_def.sip +++ b/qt/python/mantidqtpython/mantidqtpython_def.sip @@ -1529,7 +1529,7 @@ class ProcessingAlgorithm #include "MantidQtWidgets/Common/DataProcessorUI/ProcessingAlgorithm.h" %End public: -ProcessingAlgorithm(const QString &, const QString &, const QString &blacklist = ""); +ProcessingAlgorithm(const QString &, const QString &, int, const QString &blacklist = ""); }; class PostprocessingAlgorithm diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp index 3cb871a8e63d..17ea85b0dc6e 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp +++ b/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp @@ -73,7 +73,7 @@ ReflGenericDataProcessorPresenterFactory::create(int group) { /*The name of the algorithm */ "ReflectometryReductionOneAuto", /*Prefixes to the output workspaces*/ - std::vector{"IvsQ_binned_", "IvsQ_", "IvsLam_"}, + std::vector{"IvsQ_binned_", "IvsQ_", "IvsLam_"}, 1, /*The blacklist*/ std::set{"ThetaIn", "ThetaOut", "InputWorkspace", "OutputWorkspace", "OutputWorkspaceBinned", diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/ProcessingAlgorithm.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/ProcessingAlgorithm.h index 194a685fb4d4..133ff33ff241 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/ProcessingAlgorithm.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/ProcessingAlgorithm.h @@ -42,9 +42,11 @@ class EXPORT_OPT_MANTIDQT_COMMON ProcessingAlgorithm ProcessingAlgorithm(); // Constructor ProcessingAlgorithm(QString name, std::vector prefix, + std::size_t postprocessedOutputPrefixIndex, std::set blacklist = std::set()); // Delegating constructor ProcessingAlgorithm(QString name, QString const &prefix, + std::size_t postprocessedOutputPrefixIndex, QString const &blacklist = ""); // Destructor virtual ~ProcessingAlgorithm(); @@ -62,6 +64,10 @@ class EXPORT_OPT_MANTIDQT_COMMON ProcessingAlgorithm QString defaultOutputPropertyName() const; // The default input ws property QString defaultInputPropertyName() const; + // The prefix for the postprocessed output ws property + QString postprocessedOutputPrefix() const; + // The postprocessed output ws property + QString postprocessedOutputPropertyName() const; // The input properties std::vector inputProperties() const; // The output properties @@ -70,6 +76,9 @@ class EXPORT_OPT_MANTIDQT_COMMON ProcessingAlgorithm std::vector prefixes() const; private: + bool isValidOutputPrefixIndex(std::size_t outputPrefixIndex) const; + void ensureValidPostprocessedOutput() const; + std::size_t m_postprocessedOutputPrefixIndex; // The prefix of the output workspace(s) std::vector m_prefix; // The names of the input workspace properties diff --git a/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp b/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp index 33ae9bbf33ad..d42d17eb7b25 100644 --- a/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp +++ b/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp @@ -622,9 +622,9 @@ void GenericDataProcessorPresenter::postProcessGroup( const GroupData &groupData) { if (hasPostprocessing()) { const auto outputWSName = getPostprocessedWorkspaceName(groupData); - m_postprocessing->postProcessGroup(outputWSName, - m_processor.defaultOutputPropertyName(), - m_whitelist, groupData); + m_postprocessing->postProcessGroup( + outputWSName, m_processor.postprocessedOutputPropertyName(), + m_whitelist, groupData); } } diff --git a/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp b/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp index 8940b87f2c16..e52ac65020fb 100644 --- a/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp +++ b/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp @@ -10,12 +10,15 @@ namespace DataProcessor { * workspaces' names * @param blacklist : The list of properties we do not want to show */ -ProcessingAlgorithm::ProcessingAlgorithm(QString name, - std::vector prefix, - std::set blacklist) +ProcessingAlgorithm::ProcessingAlgorithm( + QString name, std::vector prefix, + std::size_t postprocessedOutputPrefixIndex, std::set blacklist) : ProcessingAlgorithmBase(std::move(name), std::move(blacklist)), + m_postprocessedOutputPrefixIndex(postprocessedOutputPrefixIndex), m_prefix(std::move(prefix)) { + ensureValidPostprocessedOutput(); + m_inputProperties = getInputWsProperties(); if (!m_inputProperties.size()) throw std::invalid_argument("Invalid Processing algorithm. A valid " @@ -44,9 +47,11 @@ ProcessingAlgorithm::ProcessingAlgorithm(QString name, * workspaces' names, as a string * @param blacklist : The list of properties we do not want to show, as a string */ -ProcessingAlgorithm::ProcessingAlgorithm(QString name, QString const &prefix, - QString const &blacklist) +ProcessingAlgorithm::ProcessingAlgorithm( + QString name, QString const &prefix, + std::size_t postprocessedOutputPrefixIndex, QString const &blacklist) : ProcessingAlgorithm(std::move(name), convertStringToVector(prefix), + postprocessedOutputPrefixIndex, convertStringToSet(blacklist)) {} /** @@ -96,6 +101,28 @@ QString ProcessingAlgorithm::defaultOutputPropertyName() const { return m_outputProperties[0]; } +bool ProcessingAlgorithm::isValidOutputPrefixIndex( + std::size_t outputPrefixIndex) const { + return outputPrefixIndex < m_prefix.size(); +} + +void ProcessingAlgorithm::ensureValidPostprocessedOutput() const { + if (!isValidOutputPrefixIndex(m_postprocessedOutputPrefixIndex)) + throw std::runtime_error("Postprocessed output index must be a valid index " + "into the prefix array."); +} + +QString ProcessingAlgorithm::postprocessedOutputPrefix() const { + return m_prefix[m_postprocessedOutputPrefixIndex]; +} + +/** Returns the postprocessed output ws property. This is property + * name specified on construction. + */ +QString ProcessingAlgorithm::postprocessedOutputPropertyName() const { + return m_outputProperties[m_postprocessedOutputPrefixIndex]; +} + /** Returns the default input ws property. This is just the first * property declared by the algorithm. Algorithm properties are * extracted in order, so this is the first in our list. diff --git a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py index 7423e1acce19..cbbe92c448b1 100644 --- a/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py +++ b/scripts/Interface/ui/sans_isis/sans_data_processor_gui.py @@ -322,8 +322,9 @@ def create_data_table(self, show_periods): entry.show_value, entry.prefix) # Processing algorithm (mandatory) + unused_postprocessing_index = 0 alg = MantidQt.MantidWidgets.DataProcessor.ProcessingAlgorithm(self._gui_algorithm_name, - 'unused_', self._black_list) + 'unused_', unused_postprocessing_index, self._black_list) self.data_processor_table = MantidQt.MantidWidgets.DataProcessor.QDataProcessorWidget(white_list, alg, self) self.data_processor_table.setForcedReProcessing(True) From 7668bf820f3cd99071e62ffbfd7f53136a4d1dfb Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 13 Mar 2018 10:02:15 +0000 Subject: [PATCH 158/364] remove MeshGeometryGenerator and clang format #21230 --- .../Rendering/GeometryHandler.h | 5 +- .../Rendering/GeometryTriangulator.h | 2 +- .../Rendering/MeshGeometryGenerator.h | 63 ---------------- Framework/Geometry/src/Objects/MeshObject.cpp | 7 +- .../src/Rendering/GeometryTriangulator.cpp | 3 +- .../src/Rendering/MeshGeometryGenerator.cpp | 73 ------------------- 6 files changed, 8 insertions(+), 145 deletions(-) delete mode 100644 Framework/Geometry/inc/MantidGeometry/Rendering/MeshGeometryGenerator.h delete mode 100644 Framework/Geometry/src/Rendering/MeshGeometryGenerator.cpp diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index a16c1bacbd76..d166cc5a0866 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -56,10 +56,11 @@ class MANTID_GEOMETRY_DLL GeometryHandler { std::shared_ptr m_shapeInfo; std::unique_ptr m_triangulator; RectangularDetector *m_rectDet = nullptr; - MeshObject *m_meshObj = nullptr; ///< Mesh Object that uses this geometry handler + MeshObject *m_meshObj = + nullptr; ///< Mesh Object that uses this geometry handler StructuredDetector *m_structDet = nullptr; IObjComponent *m_objComp = - nullptr; ///< ObjComponent that uses this geometry handler + nullptr; ///< ObjComponent that uses this geometry handler CSGObject *m_csgObj = nullptr; ///< Object that uses this geometry handler public: GeometryHandler(IObjComponent *comp); ///< Constructor diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index c936e0f1ded9..a457c8f71f4c 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -44,7 +44,7 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { size_t m_nPoints; std::vector m_points; ///< double array or points std::vector m_faces; ///< Integer array of faces - const CSGObject *m_csgObj; ///< Input Object + const CSGObject *m_csgObj; ///< Input Object const MeshObject *m_meshObj; void checkTriangulated(); diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/MeshGeometryGenerator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/MeshGeometryGenerator.h deleted file mode 100644 index 18020711526b..000000000000 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/MeshGeometryGenerator.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef MESH_GEOMETRYGENERATOR_H -#define MESH_GEOMETRYGENERATOR_H - -#include "MantidGeometry/DllConfig.h" - -namespace Mantid { - -namespace Geometry { - -/** - This class delivers the triangles of a MeshObject for rendering via - the CacheGeometryRenderer. - - Copyright © 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: -*/ -class MeshObject; -class MANTID_GEOMETRY_DLL MeshGeometryGenerator { -private: - MeshObject *Obj; ///< Input Object - int mNoOfVertices; ///< number of vertices - int mNoOfTriangles; ///< number of triangles - double *mPoints; /// MeshObject::getVertices() const { /** * get info on standard shapes (none for Mesh Object) */ -void MeshObject::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, std::vector &vectors, +void MeshObject::GetObjectGeom(detail::ShapeInfo::GeometryShape &type, + std::vector &vectors, double &myradius, double &myheight) const { // In practice, this outputs type = -1, // to indicate not a "standard" object (cuboid/cone/cyl/sphere). diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index badbb0c398b4..dc43afa598f0 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -66,8 +66,7 @@ GeometryTriangulator::GeometryTriangulator(const CSGObject *obj) } GeometryTriangulator::GeometryTriangulator(const MeshObject *obj) - : m_isTriangulated(false), m_meshObj(obj) { -} + : m_isTriangulated(false), m_meshObj(obj) {} GeometryTriangulator::~GeometryTriangulator() {} diff --git a/Framework/Geometry/src/Rendering/MeshGeometryGenerator.cpp b/Framework/Geometry/src/Rendering/MeshGeometryGenerator.cpp deleted file mode 100644 index e7706d37ac1c..000000000000 --- a/Framework/Geometry/src/Rendering/MeshGeometryGenerator.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include "MantidKernel/Matrix.h" -#include "MantidGeometry/Objects/MeshObject.h" -#include "MantidGeometry/Rendering/MeshGeometryGenerator.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" - -#ifdef ENABLE_OPENCASCADE -#include "MantidGeometry/Rendering/OCGeometryHandler.h" -#endif - -namespace Mantid { - -namespace Geometry { -/** - * Constructor - * @param obj :: input object - */ -MeshGeometryGenerator::MeshGeometryGenerator(MeshObject *obj) : Obj(obj) { - mNoOfVertices = 0; - mNoOfTriangles = 0; - mFaces = nullptr; - mPoints = nullptr; -} - -/** - * Generate geometry, get triangles from object if not in cache. - */ -void MeshGeometryGenerator::Generate() { - if (mNoOfVertices <= 0) { // Get triangles from object - } -} - -/** - * Destroy the surface generated for the object - */ -MeshGeometryGenerator::~MeshGeometryGenerator() { - if (mFaces != nullptr) - delete[] mFaces; - if (mPoints != nullptr) - delete[] mPoints; -} - -int MeshGeometryGenerator::getNumberOfTriangles() { return mNoOfTriangles; } - -int MeshGeometryGenerator::getNumberOfPoints() { return mNoOfVertices; } - -double *MeshGeometryGenerator::getTriangleVertices() { return mPoints; } - -int *MeshGeometryGenerator::getTriangleFaces() { return mFaces; } - -/** - Sets the geometry cache using the triangulation information provided - @param noPts :: the number of points - @param noFaces :: the number of faces - @param pts :: a double array of the points - @param faces :: an int array of the faces -*/ -void MeshGeometryGenerator::setGeometryCache(int noPts, int noFaces, - double *pts, int *faces) { - if (mPoints != nullptr) - delete[] mPoints; - if (mFaces != nullptr) - delete[] mFaces; - mNoOfVertices = noPts; - mNoOfTriangles = noFaces; - mPoints = pts; - mFaces = faces; -} - -} // NAMESPACE Geometry - -} // NAMESPACE Mantid From e86125c6c6278b2e06f5f9293da1db62ebd218ba Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Tue, 13 Mar 2018 10:02:16 +0000 Subject: [PATCH 159/364] Resized figures, link to privacy policy doc --- docs/source/release/v3.12.0/ui.rst | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/source/release/v3.12.0/ui.rst b/docs/source/release/v3.12.0/ui.rst index b9b7c6b81f2b..13cd8e3a1b42 100644 --- a/docs/source/release/v3.12.0/ui.rst +++ b/docs/source/release/v3.12.0/ui.rst @@ -8,15 +8,21 @@ UI & Usability Changes General ------- +- Added :mod:`mantid.plots` to provide convenience functions for plotting mantid workspaces with matplotlib. + An example :ref:`gallery ` is available. - Fixed a bug where MantidPlot could freeze when performing a long running search for files. - Fixed a bug where MantidPlot would crash if the sample log fields used for run start and end contained non-ISO8601 conforming values. - Fixed an issue where updating a workspace changes the number format from decimal to scientific notation if the workspace is being viewed. -- Added :mod:`mantid.plots` to provide convenience functions for plotting mantid workspaces with matplotlib. - An example :ref:`gallery ` is available. + SliceViewer and Vates Simple Interface -------------------------------------- +.. figure:: ../../images/VatesMultiSliceView.png + :class: screenshot + :align: right + :figwidth: 50% + - Update SwitchToSliceViewer (shift + click) in MultiSlice view to work with nonorthogonal axes. - Pressing alt while clicking an arrow in the MultiSlice view opens a text box where one may precisely enter the slice position. - Peaks can now be added in the SliceViewer in MDWorkspace in QLab and QSample frames as well as HKL. @@ -25,9 +31,7 @@ SliceViewer and Vates Simple Interface - Fixed a bug where overwriting peaks workspaces with overlaid in the slice viewer with peak backgrounds shown cause Mantid to crash. - Fixed an issue preventing sorting of the VSI peaks table. -.. figure:: ../../images/VatesMultiSliceView.png - :class: screenshot - :align: right + MultiDataset Fitting Interface ------------------------------ @@ -75,11 +79,11 @@ HFIR HB3A Interface Error Reporting --------------- -Error reporting has been enabled in place of the new last chance error handler. If mantid catches an unknown exception it will now display the dialog box below. Currently there is no automatic error reporting enabled if Mantid crashes to desktop but the same system is planned to be implemented in this case as well. - -.. image:: ../../images/errorReporter.png +.. figure:: ../../images/errorReporter.png :align: right - :width: 800px + :figwidth: 50% + +Error reporting has been enabled in place of the new last chance error handler. If Mantid catches an unknown exception it will now display the dialog box below. Currently there is no automatic error reporting enabled if Mantid crashes to desktop but the same system is planned to be implemented in this case as well. The three options do the following: @@ -105,4 +109,6 @@ An error report will be sent to errorreports.mantidproject.org. It will contain All the information from the non-identifiable information will be shared. In addition the optional name and email will be shared if given. +Full details of the privacy policy are available `from the homepage `_. + :ref:`Release 3.12.0 ` From e3a3dd9ff93128e3d8d0c66ee5c52c0511db0de6 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 13 Mar 2018 10:18:32 +0000 Subject: [PATCH 160/364] Fixed unit test build errors. --- .../DataProcessorUI/GenerateNotebookTest.h | 2 +- .../GenericDataProcessorPresenterTest.h | 3 +-- .../DataProcessorUI/ProcessingAlgorithmTest.h | 27 +++++++++++-------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h index 5f7ea571ced0..19f911f5ed8d 100644 --- a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h +++ b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h @@ -44,7 +44,7 @@ class GenerateNotebookTest : public CxxTest::TestSuite { return ProcessingAlgorithm( "ReflectometryReductionOneAuto", - std::vector{"IvsQ_binned_", "IvsQ_", "IvsLam_"}, + std::vector{"IvsQ_binned_", "IvsQ_", "IvsLam_"}, 1, std::set{"ThetaIn", "ThetaOut", "InputWorkspace", "OutputWorkspace", "OutputWorkspaceWavelength", "FirstTransmissionRun", "SecondTransmissionRun"}); diff --git a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h index 31094046f1cb..a1ed8d3ee700 100644 --- a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h +++ b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h @@ -160,10 +160,9 @@ class GenericDataProcessorPresenterTest : public CxxTest::TestSuite { } ProcessingAlgorithm createReflectometryProcessor() { - return ProcessingAlgorithm( "ReflectometryReductionOneAuto", - std::vector{"IvsQ_binned_", "IvsQ_", "IvsLam_"}, + std::vector{"IvsQ_binned_", "IvsQ_", "IvsLam_"}, 1, std::set{"ThetaIn", "ThetaOut", "InputWorkspace", "OutputWorkspace", "OutputWorkspaceWavelength", "FirstTransmissionRun", "SecondTransmissionRun"}); diff --git a/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h b/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h index c4f12ae190fb..ee5fccb16ceb 100644 --- a/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h +++ b/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h @@ -35,9 +35,9 @@ class ProcessingAlgorithmTest : public CxxTest::TestSuite { // Currently ws must be either MatrixWorkspace or Workspace but this can be // changed std::vector prefix = {"run_"}; - TS_ASSERT_THROWS_NOTHING(ProcessingAlgorithm("Rebin", prefix)); - TS_ASSERT_THROWS_NOTHING(ProcessingAlgorithm("ExtractSpectra", prefix)); - TS_ASSERT_THROWS_NOTHING(ProcessingAlgorithm("ConvertUnits", prefix)); + TS_ASSERT_THROWS_NOTHING(ProcessingAlgorithm("Rebin", prefix, 0)); + TS_ASSERT_THROWS_NOTHING(ProcessingAlgorithm("ExtractSpectra", prefix, 0)); + TS_ASSERT_THROWS_NOTHING(ProcessingAlgorithm("ConvertUnits", prefix, 0)); } void test_invalid_algorithms() { @@ -45,10 +45,10 @@ class ProcessingAlgorithmTest : public CxxTest::TestSuite { std::vector prefix = {"IvsQ_"}; // Algorithms with no input workspace properties - TS_ASSERT_THROWS(ProcessingAlgorithm("Stitch1DMany", prefix), + TS_ASSERT_THROWS(ProcessingAlgorithm("Stitch1DMany", prefix, 0), std::invalid_argument); // Algorithms with no output workspace properties - TS_ASSERT_THROWS(ProcessingAlgorithm("SaveAscii", prefix), + TS_ASSERT_THROWS(ProcessingAlgorithm("SaveAscii", prefix, 0), std::invalid_argument); } void test_ReflectometryReductionOneAuto() { @@ -58,28 +58,33 @@ class ProcessingAlgorithmTest : public CxxTest::TestSuite { // ReflectometryReductionOneAuto has three output ws properties // We should provide three prefixes, one for each ws std::vector prefixes; + prefixes.emplace_back("IvsQ_"); prefixes.emplace_back("IvsQ_binned_"); // This should throw TS_ASSERT_THROWS( - ProcessingAlgorithm(algName, prefixes, std::set()), + ProcessingAlgorithm(algName, prefixes, 0, std::set()), std::invalid_argument); - prefixes.push_back("IvsQ_"); + prefixes.emplace_back("IvsQ_"); + prefixes.emplace_back("IvsQ_binned_"); // This should also throw TS_ASSERT_THROWS( - ProcessingAlgorithm(algName, prefixes, std::set()), + ProcessingAlgorithm(algName, prefixes, 0, std::set()), std::invalid_argument); // But this should be OK - prefixes.push_back("IvsLam_"); + prefixes.emplace_back("IvsLam_"); TS_ASSERT_THROWS_NOTHING( - ProcessingAlgorithm(algName, prefixes, std::set())); + ProcessingAlgorithm(algName, prefixes, 0, std::set())); - auto alg = ProcessingAlgorithm(algName, prefixes, std::set()); + auto const postprocessedOutputPrefixIndex = 1; + auto alg = ProcessingAlgorithm( + algName, prefixes, postprocessedOutputPrefixIndex, std::set()); TS_ASSERT_EQUALS(alg.name(), "ReflectometryReductionOneAuto"); TS_ASSERT_EQUALS(alg.numberOfOutputProperties(), 3); TS_ASSERT_EQUALS(alg.prefix(0), "IvsQ_binned_"); TS_ASSERT_EQUALS(alg.prefix(1), "IvsQ_"); TS_ASSERT_EQUALS(alg.prefix(2), "IvsLam_"); + TS_ASSERT_EQUALS(alg.postprocessedOutputPrefix(), "IvsQ_"); TS_ASSERT_EQUALS(alg.inputPropertyName(0), "InputWorkspace"); TS_ASSERT_EQUALS(alg.inputPropertyName(1), "FirstTransmissionRun"); TS_ASSERT_EQUALS(alg.inputPropertyName(2), "SecondTransmissionRun"); From bf1efb751c01eaeecfcd5109cad962a5a0173a2b Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 10:18:36 +0000 Subject: [PATCH 161/364] refs #22031 moved FDA error check to load_utils and reloads data --- docs/source/release/v3.12.0/muon.rst | 2 +- scripts/Muon/fft_presenter.py | 6 ++++-- scripts/Muon/load_utils.py | 32 +++++++++++++++++++++------- scripts/Muon/maxent_presenter.py | 16 ++++++++------ scripts/Muon/thread_model.py | 20 +---------------- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 663cb2b4d2f8..d9a301869a34 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -29,7 +29,7 @@ Interface - The ALC interface now allows background sections with negative values. - If data is loaded with 0 good frames into Muon Analysis then it will try to load the data without dead time correction (does not need number of good frames). - Muon analysis no longer disables the "aco add" and "simultaneous" buttons in the multiple fitting interface. -- Frequency domain analysis will produce an error if the active workspace has changed. +- Frequency domain analysis will reload the data if the active workspace has changed. Algorithms ---------- diff --git a/scripts/Muon/fft_presenter.py b/scripts/Muon/fft_presenter.py index 1fc9e81ddbdd..65b9c0f3850b 100644 --- a/scripts/Muon/fft_presenter.py +++ b/scripts/Muon/fft_presenter.py @@ -47,13 +47,15 @@ def tableClicked(self,row,col): self.view.changed(self.view.getShiftBox(),self.view.getShiftBoxRow()+1) def createThread(self): - runName=self.load.getRunName() - return thread_model.ThreadModel(self.alg,runName) + return thread_model.ThreadModel(self.alg) # constructs the inputs for the FFT algorithms # then executes them (see fft_model to see the order # of execution def handleButton(self): + if self.load.hasDataChanged(): + self.getWorkspaceNames() + return # put this on its own thread so not to freeze Mantid self.thread=self.createThread() self.thread.started.connect(self.deactivate) diff --git a/scripts/Muon/load_utils.py b/scripts/Muon/load_utils.py index 6707fdc85d0e..6a4b9718a50e 100644 --- a/scripts/Muon/load_utils.py +++ b/scripts/Muon/load_utils.py @@ -11,16 +11,18 @@ class LoadUtils(object): def __init__(self, parent=None): exists,tmpWS = self.MuonAnalysisExists() if exists: - # get everything from the ADS - self.options = mantid.AnalysisDataService.getObjectNames() - self.options = [item.replace(" ","") for item in self.options] - self.N_points = len(tmpWS.readX(0)) - self.instrument=tmpWS.getInstrument().getName() - self.runName=self.instrument+str(tmpWS.getRunNumber()).zfill(8) - + self.setUp(tmpWS) else: mantid.logger.error("Muon Analysis workspace does not exist - no data loaded") + def setUp(self,tmpWS): + # get everything from the ADS + self.options = mantid.AnalysisDataService.getObjectNames() + self.options = [item.replace(" ","") for item in self.options] + self.N_points = len(tmpWS.readX(0)) + self.instrument=tmpWS.getInstrument().getName() + self.runName=self.instrument+str(tmpWS.getRunNumber()).zfill(8) + # get methods def getNPoints(self): return self.N_points @@ -34,6 +36,20 @@ def getRunName(self): def getInstrument(self): return self.instrument + # check if data matches current + def digit(self,x): + return int(filter(str.isdigit,x) or 0) + + def hasDataChanged(self): + exists,ws = self.MuonAnalysisExists() + if exists: + current = ws.getInstrument().getName()+str(ws.getRunNumber()).zfill(8) + if self.runName != current: + mantid.logger.error("Active workspace has changed. Reloading the data") + self.setUp(ws) + return True + return False + # check if muon analysis exists def MuonAnalysisExists(self): # if period data look for the first period @@ -66,6 +82,6 @@ def getGroupedWorkspaceNames(self): final_options=[] # only keep the relevant WS (same run as Muon Analysis) for pick in options: - if "MuonAnalysisGrouped_" in pick: + if "MuonAnalysisGrouped_" in pick and ";" not in pick: final_options.append(pick) return final_options diff --git a/scripts/Muon/maxent_presenter.py b/scripts/Muon/maxent_presenter.py index 1aa6866a9000..6e6748a287c8 100644 --- a/scripts/Muon/maxent_presenter.py +++ b/scripts/Muon/maxent_presenter.py @@ -37,18 +37,20 @@ def getWorkspaceNames(self): self.view.addNPoints(values) def createThread(self): - runName=self.load.getRunName() - return thread_model.ThreadModel(self.alg,runName) + return thread_model.ThreadModel(self.alg) def createPhaseThread(self): - runName=self.load.getRunName() - return thread_model.ThreadModel(self.calcAlg,runName) + return thread_model.ThreadModel(self.calcAlg) def handleMaxEntButton(self): - if self.view.calcPhases() and self.view.usePhases(): - self.DoPhase() + do_maxent = self.load.hasDataChanged() + if do_maxent: + self.getWorkspaceNames() else: - self.DoMaxEnt() + if self.view.calcPhases() and self.view.usePhases(): + self.DoPhase() + else: + self.DoMaxEnt() def DoMaxEnt(self): self.thread=self.createThread() diff --git a/scripts/Muon/thread_model.py b/scripts/Muon/thread_model.py index 563a80366ac6..50f9140b7f2d 100644 --- a/scripts/Muon/thread_model.py +++ b/scripts/Muon/thread_model.py @@ -1,7 +1,6 @@ from __future__ import (absolute_import, division, print_function) from PyQt4.QtCore import QThread -import mantid.simpleapi as mantid class ThreadModel(QThread): @@ -10,31 +9,14 @@ class ThreadModel(QThread): A wrapper to allow threading with the MaxEnt models. """ - def __init__(self,model,run): + def __init__(self,model): QThread.__init__(self) self.model=model - self.run = run def __del__(self): self.wait() - def digit(self,x): - return int(filter(str.isdigit,x) or 0) - - def hasDataChanged(self): - ws = mantid.AnalysisDataService.retrieve("MuonAnalysis") - if mantid.AnalysisDataService.doesExist("MuonAnalysis_1"): - ws = mantid.AnalysisDataService.retrieve("MuonAnalysis_1") - - current = ws.getInstrument().getName()+str(ws.getRunNumber()).zfill(8) - if self.run != current: - mantid.logger.error("Active workspace has changed. Restart this interface") - return True - return False - def run(self): - if self.hasDataChanged(): - return try: self.model.execute() self.model.output() From d81dbc24954a8b8b72a0e0775a308124fccfc768 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 13 Mar 2018 10:25:15 +0000 Subject: [PATCH 162/364] remove obsolete header include #21230 --- Framework/Geometry/test/MeshObjectTest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Geometry/test/MeshObjectTest.h b/Framework/Geometry/test/MeshObjectTest.h index 61f176997572..65b2c6ac1e6a 100644 --- a/Framework/Geometry/test/MeshObjectTest.h +++ b/Framework/Geometry/test/MeshObjectTest.h @@ -5,7 +5,7 @@ #include "MantidGeometry/Math/Algebra.h" #include "MantidGeometry/Objects/Track.h" -#include "MantidGeometry/Rendering/CacheGeometryHandler.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/make_unique.h" #include "MantidKernel/Material.h" From 9108a8bc0f23c46b37c1ef1074e068488ac770c2 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Tue, 13 Mar 2018 10:27:03 +0000 Subject: [PATCH 163/364] Update test files. Re #22004 --- .../tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 | 2 +- docs/source/fitting/fitfunctions/IsoRotDiff.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 index 519fca822ca2..edb4373c11ff 100644 --- a/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 @@ -1 +1 @@ -ce0d536337942b5662b8ecd107a5c71f +d3c125646057bc0d1291c3286ddfab82 diff --git a/docs/source/fitting/fitfunctions/IsoRotDiff.rst b/docs/source/fitting/fitfunctions/IsoRotDiff.rst index 23a4bac75991..deb0dcb37344 100644 --- a/docs/source/fitting/fitfunctions/IsoRotDiff.rst +++ b/docs/source/fitting/fitfunctions/IsoRotDiff.rst @@ -170,8 +170,8 @@ and the overal intensity of the signal with a fit to the following model: print("Optimal Radius within 5% of nominal value") else: print("Error. Obtained Radius= {0} instead of {1}".format(Radius,R)) - if abs(tau-Tau)/tau < 0.1: - print("Optimal Tau within 10% of nominal value") + if abs(tau-Tau)/tau < 0.4: + print("Optimal Tau within 40% of nominal value") else: print("Error. Obtained Tau= {0} instead of {1}".format(Tau,tau)) @@ -181,7 +181,7 @@ Output: Optimal Height within 10% of nominal value Optimal Radius within 5% of nominal value - Optimal Tau within 10% of nominal value + Optimal Tau within 40% of nominal value .. categories:: From 4456f69e908883e8a0b22edc33440bf5d1c58f65 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 10:53:11 +0000 Subject: [PATCH 164/364] refs #22031 fixed fialing FDA tests --- scripts/test/Muon/FFTPresenter_test.py | 493 ++++++++++++---------- scripts/test/Muon/MaxEntPresenter_test.py | 5 + 2 files changed, 264 insertions(+), 234 deletions(-) diff --git a/scripts/test/Muon/FFTPresenter_test.py b/scripts/test/Muon/FFTPresenter_test.py index 70fa576c51df..7d30be8b4f2e 100644 --- a/scripts/test/Muon/FFTPresenter_test.py +++ b/scripts/test/Muon/FFTPresenter_test.py @@ -8,262 +8,287 @@ import unittest -if sys.version_info.major == 3: - from unittest import mock +if sys.version_info.major == 3: + from unittest import mock else: - import mock + import mock class FFTPresenterTest(unittest.TestCase): - def setUp(self): - self.load = mock.create_autospec(load_utils.LoadUtils,spec_set=True) - self.load.getCurrentWS = mock.Mock(return_value=["TEST00000001",["fwd","bkwd"]]) - self.load.getRunName = mock.MagicMock(return_value="MUSR00023456") - self.view = mock.create_autospec(fft_view.FFTView,spec_set=True) - #signals - self.view.tableClickSignal = mock.Mock(return_value=[3,1]) - self.view.phaseCheckSignal = mock.Mock(return_value =True) - #needed for connect in presenter - self.view.buttonSignal = mock.Mock() - self.view.changed = mock.MagicMock() - self.view.changedHideUnTick = mock.MagicMock() - self.view.initFFTInput = mock.Mock(return_value={"InputWorkspace":"testWS","OutputWorkspace":"muon"}) - self.view.addFFTComplex = mock.Mock(return_value={"InputImWorkspace":"MuonFFT"}) - self.view.addFFTShift = mock.Mock() - self.view.addRaw = mock.Mock() - self.view.RePhaseAdvanced = mock.Mock() - self.view.getFFTRePhase = mock.Mock() - self.view.getFFTImPhase = mock.Mock() - self.view.getWS = mock.Mock(return_value="MUSR00023456") - self.view.getFirstGoodData = mock.Mock(return_value=0.1) - self.view.getLastGoodData = mock.Mock(return_value=15.) - self.view.getImBoxRow = mock.Mock(return_value=3) - self.view.getShiftBoxRow = mock.Mock(return_value=5) - self.view.isRaw = mock.Mock(return_value=True) - self.view.isComplex = mock.Mock(return_value=True) - self.view.isAutoShift = mock.Mock(return_value=True) - self.view.setPhaseBox = mock.Mock() - self.view.isNewPhaseTable = mock.Mock(return_value=True) - self.view.activateButton = mock.Mock() - self.view.deactivateButton = mock.Mock() - # setup model - self.model1 = mock.create_autospec(fft_model.FFTModel,spec_set=False) - self.model = mock.create_autospec(fft_model.FFTWrapper,spec_set=False) - #set presenter - self.presenter = fft_presenter.FFTPresenter(self.view,self.model,self.load) + def setUp(self): + self.load = mock.create_autospec(load_utils.LoadUtils, spec_set=True) + self.load.getCurrentWS = mock.Mock( + return_value=["TEST00000001", ["fwd", "bkwd"]]) + self.load.getRunName = mock.MagicMock(return_value="MUSR00023456") + self.load.hasDataChanged = mock.MagicMock(return_value=False) + self.view = mock.create_autospec(fft_view.FFTView, spec_set=True) + # signals + self.view.tableClickSignal = mock.Mock(return_value=[3, 1]) + self.view.phaseCheckSignal = mock.Mock(return_value=True) + # needed for connect in presenter + self.view.buttonSignal = mock.Mock() + self.view.changed = mock.MagicMock() + self.view.changedHideUnTick = mock.MagicMock() + self.view.initFFTInput = mock.Mock( + return_value={ + "InputWorkspace": "testWS", + "OutputWorkspace": "muon"}) + self.view.addFFTComplex = mock.Mock( + return_value={"InputImWorkspace": "MuonFFT"}) + self.view.addFFTShift = mock.Mock() + self.view.addRaw = mock.Mock() + self.view.RePhaseAdvanced = mock.Mock() + self.view.getFFTRePhase = mock.Mock() + self.view.getFFTImPhase = mock.Mock() + self.view.getWS = mock.Mock(return_value="MUSR00023456") + self.view.getFirstGoodData = mock.Mock(return_value=0.1) + self.view.getLastGoodData = mock.Mock(return_value=15.) + self.view.getImBoxRow = mock.Mock(return_value=3) + self.view.getShiftBoxRow = mock.Mock(return_value=5) + self.view.isRaw = mock.Mock(return_value=True) + self.view.isComplex = mock.Mock(return_value=True) + self.view.isAutoShift = mock.Mock(return_value=True) + self.view.setPhaseBox = mock.Mock() + self.view.isNewPhaseTable = mock.Mock(return_value=True) + self.view.activateButton = mock.Mock() + self.view.deactivateButton = mock.Mock() + # setup model + self.model1 = mock.create_autospec(fft_model.FFTModel, spec_set=False) + self.model = mock.create_autospec(fft_model.FFTWrapper, spec_set=False) - # mock thread - self.thread = mock.create_autospec(thread_model.ThreadModel) - self.thread.start = mock.Mock() - self.thread.started = mock.Mock() - self.thread.finished = mock.Mock() - self.thread.setInputs = mock.Mock() - self.thread.loadData = mock.Mock() - self.presenter.createThread = mock.Mock(return_value=self.thread) + # set presenter + self.presenter = fft_presenter.FFTPresenter( + self.view, self.model, self.load) - def sendSignal(self): - row,col = self.view.tableClickSignal() - self.presenter.tableClicked(row,col) + # mock thread + self.thread = mock.create_autospec(thread_model.ThreadModel) + self.thread.start = mock.Mock() + self.thread.started = mock.Mock() + self.thread.finished = mock.Mock() + self.thread.setInputs = mock.Mock() + self.thread.loadData = mock.Mock() + self.presenter.createThread = mock.Mock(return_value=self.thread) - def test_ImBox(self): - self.sendSignal() - self.view.tableClickSignal = mock.Mock(return_value=[3,1]) - assert(self.view.changedHideUnTick.call_count == 1) - assert(self.view.changed.call_count == 0) + def sendSignal(self): + row, col = self.view.tableClickSignal() + self.presenter.tableClicked(row, col) - def test_shiftBox(self): - self.view.tableClickSignal = mock.Mock(return_value=[5,1]) - self.sendSignal() - assert(self.view.changed.call_count == 1) - assert(self.view.changedHideUnTick.call_count == 0) + def test_ImBox(self): + self.sendSignal() + self.view.tableClickSignal = mock.Mock(return_value=[3, 1]) + assert(self.view.changedHideUnTick.call_count == 1) + assert(self.view.changed.call_count == 0) - def test_buttonNotRawAndNoIm(self): - self.view.isAutoShift = mock.Mock(return_value=True) - self.view.isComplex = mock.Mock(return_value=False) - self.view.isRaw = mock.Mock(return_value=False) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 0) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_shiftBox(self): + self.view.tableClickSignal = mock.Mock(return_value=[5, 1]) + self.sendSignal() + assert(self.view.changed.call_count == 1) + assert(self.view.changedHideUnTick.call_count == 0) - def test_buttonNotRawAndIm(self): - self.view.isAutoShift = mock.Mock(return_value=True) - self.view.isComplex = mock.Mock(return_value=True) - self.view.isRaw = mock.Mock(return_value=False) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 1) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonNotRawAndNoIm(self): + self.view.isAutoShift = mock.Mock(return_value=True) + self.view.isComplex = mock.Mock(return_value=False) + self.view.isRaw = mock.Mock(return_value=False) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 0) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonRawAndIm(self): - self.view.isAutoShift = mock.Mock(return_value=True) - self.view.isComplex = mock.Mock(return_value=True) - self.view.isRaw = mock.Mock(return_value=True) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 1) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 3) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonNotRawAndIm(self): + self.view.isAutoShift = mock.Mock(return_value=True) + self.view.isComplex = mock.Mock(return_value=True) + self.view.isRaw = mock.Mock(return_value=False) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 1) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonRawAndNoIm(self): - self.view.isAutoShift = mock.Mock(return_value=True) - self.view.isComplex = mock.Mock(return_value=False) - self.view.isRaw = mock.Mock(return_value=True) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 0) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 2) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonRawAndIm(self): + self.view.isAutoShift = mock.Mock(return_value=True) + self.view.isComplex = mock.Mock(return_value=True) + self.view.isRaw = mock.Mock(return_value=True) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 1) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 3) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonNoShiftNotRawAndNoIm(self): - self.view.isAutoShift = mock.Mock(return_value=False) - self.view.isComplex = mock.Mock(return_value=False) - self.view.isRaw = mock.Mock(return_value=False) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 0) - assert(self.view.addFFTShift.call_count == 1) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonRawAndNoIm(self): + self.view.isAutoShift = mock.Mock(return_value=True) + self.view.isComplex = mock.Mock(return_value=False) + self.view.isRaw = mock.Mock(return_value=True) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 0) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 2) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonNoShiftNotRawAndIm(self): - self.view.isAutoShift = mock.Mock(return_value=False) - self.view.isComplex = mock.Mock(return_value=True) - self.view.isRaw = mock.Mock(return_value=False) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 1) - assert(self.view.addFFTShift.call_count == 1) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonNoShiftNotRawAndNoIm(self): + self.view.isAutoShift = mock.Mock(return_value=False) + self.view.isComplex = mock.Mock(return_value=False) + self.view.isRaw = mock.Mock(return_value=False) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 0) + assert(self.view.addFFTShift.call_count == 1) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonNoShiftRawAndIm(self): - self.view.isAutoShift = mock.Mock(return_value=False) - self.view.isComplex = mock.Mock(return_value=True) - self.view.isRaw = mock.Mock(return_value=True) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 1) - assert(self.view.addFFTShift.call_count == 1) - assert(self.view.addRaw.call_count == 3) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonNoShiftNotRawAndIm(self): + self.view.isAutoShift = mock.Mock(return_value=False) + self.view.isComplex = mock.Mock(return_value=True) + self.view.isRaw = mock.Mock(return_value=False) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 1) + assert(self.view.addFFTShift.call_count == 1) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonNoShiftRawAndNoIm(self): - self.view.isAutoShift = mock.Mock(return_value=False) - self.view.isComplex = mock.Mock(return_value=False) - self.view.isRaw = mock.Mock(return_value=True) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 0) - assert(self.view.addFFTShift.call_count == 1) - assert(self.view.addRaw.call_count == 2) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 0) - assert(self.view.getLastGoodData.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonNoShiftRawAndIm(self): + self.view.isAutoShift = mock.Mock(return_value=False) + self.view.isComplex = mock.Mock(return_value=True) + self.view.isRaw = mock.Mock(return_value=True) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 1) + assert(self.view.addFFTShift.call_count == 1) + assert(self.view.addRaw.call_count == 3) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonPhaseQuad(self): - self.view.getWS = mock.Mock(return_value="PhaseQuad") - self.view.isComplex = mock.Mock(return_value=False) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 0) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 1) - assert(self.view.getLastGoodData.call_count == 1) - assert(self.view.RePhaseAdvanced.call_count == 1) - assert(self.view.getFFTRePhase.call_count == 1) - assert(self.view.getFFTImPhase.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonNoShiftRawAndNoIm(self): + self.view.isAutoShift = mock.Mock(return_value=False) + self.view.isComplex = mock.Mock(return_value=False) + self.view.isRaw = mock.Mock(return_value=True) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 0) + assert(self.view.addFFTShift.call_count == 1) + assert(self.view.addRaw.call_count == 2) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonImPhaseQuad(self): - self.view.getWS = mock.Mock(return_value="PhaseQuad") - self.view.isComplex = mock.Mock(return_value=True) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 1) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 1) - assert(self.view.getLastGoodData.call_count == 1) - assert(self.view.RePhaseAdvanced.call_count == 1) - assert(self.view.getFFTRePhase.call_count == 1) - assert(self.view.getFFTImPhase.call_count == 1) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonPhaseQuad(self): + self.view.getWS = mock.Mock(return_value="PhaseQuad") + self.view.isComplex = mock.Mock(return_value=False) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 0) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 1) + assert(self.view.getLastGoodData.call_count == 1) + assert(self.view.RePhaseAdvanced.call_count == 1) + assert(self.view.getFFTRePhase.call_count == 1) + assert(self.view.getFFTImPhase.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonPhaseQuadNoTable(self): - self.view.getWS = mock.Mock(return_value="PhaseQuad") - self.view.isComplex = mock.Mock(return_value=False) - self.view.isNewPhaseTable = mock.Mock(return_value=False) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 0) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 1) - assert(self.view.getLastGoodData.call_count == 1) - assert(self.view.RePhaseAdvanced.call_count == 1) - assert(self.view.getFFTRePhase.call_count == 1) - assert(self.view.getFFTImPhase.call_count == 0) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonImPhaseQuad(self): + self.view.getWS = mock.Mock(return_value="PhaseQuad") + self.view.isComplex = mock.Mock(return_value=True) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 1) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 1) + assert(self.view.getLastGoodData.call_count == 1) + assert(self.view.RePhaseAdvanced.call_count == 1) + assert(self.view.getFFTRePhase.call_count == 1) + assert(self.view.getFFTImPhase.call_count == 1) + assert(self.presenter.thread.start.call_count == 1) - def test_buttonImPhaseQuadNoTable(self): - self.view.getWS = mock.Mock(return_value="PhaseQuad") - self.view.isNewPhaseTable = mock.Mock(return_value=False) - self.view.isComplex = mock.Mock(return_value=True) - self.presenter.handleButton() - assert(self.view.initFFTInput.call_count == 1) - assert(self.view.addFFTComplex.call_count == 1) - assert(self.view.addFFTShift.call_count == 0) - assert(self.view.addRaw.call_count == 0) - assert(self.view.setPhaseBox.call_count == 1) - assert(self.view.getFirstGoodData.call_count == 1) - assert(self.view.getLastGoodData.call_count == 1) - assert(self.view.RePhaseAdvanced.call_count == 1) - assert(self.view.getFFTRePhase.call_count == 1) - assert(self.view.getFFTImPhase.call_count == 1) - assert(self.presenter.thread.start.call_count == 1) + def test_buttonPhaseQuadNoTable(self): + self.view.getWS = mock.Mock(return_value="PhaseQuad") + self.view.isComplex = mock.Mock(return_value=False) + self.view.isNewPhaseTable = mock.Mock(return_value=False) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 0) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 1) + assert(self.view.getLastGoodData.call_count == 1) + assert(self.view.RePhaseAdvanced.call_count == 1) + assert(self.view.getFFTRePhase.call_count == 1) + assert(self.view.getFFTImPhase.call_count == 0) + assert(self.presenter.thread.start.call_count == 1) - def test_activateButton(self): - self.presenter.activate() - assert(self.view.activateButton.call_count == 1) + def test_buttonImPhaseQuadNoTable(self): + self.view.getWS = mock.Mock(return_value="PhaseQuad") + self.view.isNewPhaseTable = mock.Mock(return_value=False) + self.view.isComplex = mock.Mock(return_value=True) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 1) + assert(self.view.addFFTComplex.call_count == 1) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 1) + assert(self.view.getFirstGoodData.call_count == 1) + assert(self.view.getLastGoodData.call_count == 1) + assert(self.view.RePhaseAdvanced.call_count == 1) + assert(self.view.getFFTRePhase.call_count == 1) + assert(self.view.getFFTImPhase.call_count == 1) + assert(self.presenter.thread.start.call_count == 1) - def test_deactivateButton(self): - self.presenter.deactivate() - assert(self.view.deactivateButton.call_count == 1) + def test_activateButton(self): + self.presenter.activate() + assert(self.view.activateButton.call_count == 1) + def test_deactivateButton(self): + self.presenter.deactivate() + assert(self.view.deactivateButton.call_count == 1) -if __name__ == '__main__': - unittest.main() + def test_hasDataChanged(self): + self.load.hasDataChanged = mock.MagicMock(return_value=True) + self.view.getWS = mock.Mock(return_value="PhaseQuad") + self.view.isNewPhaseTable = mock.Mock(return_value=True) + self.view.isComplex = mock.Mock(return_value=True) + self.presenter.handleButton() + assert(self.view.initFFTInput.call_count == 0) + assert(self.view.addFFTComplex.call_count == 0) + assert(self.view.addFFTShift.call_count == 0) + assert(self.view.addRaw.call_count == 0) + assert(self.view.setPhaseBox.call_count == 0) + assert(self.view.getFirstGoodData.call_count == 0) + assert(self.view.getLastGoodData.call_count == 0) + assert(self.view.RePhaseAdvanced.call_count == 0) + assert(self.view.getFFTRePhase.call_count == 0) + assert(self.view.getFFTImPhase.call_count == 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/test/Muon/MaxEntPresenter_test.py b/scripts/test/Muon/MaxEntPresenter_test.py index 949a1044619b..0b47e03f31bd 100644 --- a/scripts/test/Muon/MaxEntPresenter_test.py +++ b/scripts/test/Muon/MaxEntPresenter_test.py @@ -19,6 +19,7 @@ class MaxEntPresenterTest(unittest.TestCase): def setUp(self): self.load=mock.create_autospec(load_utils.LoadUtils,spec_set=True) self.load.getCurrentWS=mock.Mock(return_value=["TEST00000001",["fwd","bkwd"]]) + self.load.hasDataChanged = mock.MagicMock(return_value=False) self.model=mock.create_autospec(maxent_model.MaxEntModel,spec_set=True) @@ -54,6 +55,10 @@ def test_button(self): assert(self.view.initMaxEntInput.call_count==1) assert(self.thread.start.call_count==1) + def test_dataHasChanged(self): + self.load.hasDataChanged = mock.MagicMock(return_value=True) + self.presenter.handleMaxEntButton() + assert(self.view.initMaxEntInput.call_count==0) def test_activateButton(self): self.presenter.activate() From 3558f8d10e8c410f6caa6f4a43e72304787d368c Mon Sep 17 00:00:00 2001 From: Verena Reimund Date: Tue, 13 Mar 2018 12:11:14 +0100 Subject: [PATCH 165/364] Exchange X and Z in documentation rather than in C++ code Refs #21075 --- .../algorithms/CreateSampleWorkspace-v1.rst | 2 +- .../CreateSampleWorkspaceInstrument.png | Bin 40096 -> 52475 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/algorithms/CreateSampleWorkspace-v1.rst b/docs/source/algorithms/CreateSampleWorkspace-v1.rst index 3fd42ca473a1..3a1433919d77 100644 --- a/docs/source/algorithms/CreateSampleWorkspace-v1.rst +++ b/docs/source/algorithms/CreateSampleWorkspace-v1.rst @@ -48,7 +48,7 @@ this. The sample is placed at the origin. The source is seperated from the sample in the negative direction by the value you specify in "SourceDistanceFromSample". -The instrument has "NumBanks" detector banks, each bank is moved down the X axis +The instrument has "NumBanks" detector banks, each bank is moved down the Z axis by "BankDistanceFromSample" from the sample or the previous bank. Each bank is a square rectangular bank comprising of "BankPixelWidth" pixels in diff --git a/docs/source/images/CreateSampleWorkspaceInstrument.png b/docs/source/images/CreateSampleWorkspaceInstrument.png index b9ba27860a10c651e250aec6f4f5f824df889a62..a674aa7bbf3ca52f2f6766839846b9f213be8082 100644 GIT binary patch literal 52475 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

T4W$H~FiCh%#*o`9HJ3+xgHMxWlO? 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 Date: Tue, 13 Mar 2018 11:30:25 +0000 Subject: [PATCH 166/364] fix nullptr issue #21230 --- .../inc/MantidGeometry/Rendering/GeometryTriangulator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index a457c8f71f4c..0e7cb5885457 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -44,8 +44,8 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { size_t m_nPoints; std::vector m_points; ///< double array or points std::vector m_faces; ///< Integer array of faces - const CSGObject *m_csgObj; ///< Input Object - const MeshObject *m_meshObj; + const CSGObject *m_csgObj = nullptr; ///< Input Object + const MeshObject *m_meshObj = nullptr; void checkTriangulated(); public: From 77591e34e68a61a0d908c148176e74ae664fb39e Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Tue, 13 Mar 2018 11:34:53 +0000 Subject: [PATCH 167/364] clang-format #21230 --- .../inc/MantidGeometry/Rendering/GeometryTriangulator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index 0e7cb5885457..75df0cbbf6f4 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -42,8 +42,8 @@ class MANTID_GEOMETRY_DLL GeometryTriangulator { bool m_isTriangulated; size_t m_nFaces; size_t m_nPoints; - std::vector m_points; ///< double array or points - std::vector m_faces; ///< Integer array of faces + std::vector m_points; ///< double array or points + std::vector m_faces; ///< Integer array of faces const CSGObject *m_csgObj = nullptr; ///< Input Object const MeshObject *m_meshObj = nullptr; void checkTriangulated(); From 0463b4bc7eec7a8435eb2264db44da3b817297c4 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 12:02:56 +0000 Subject: [PATCH 168/364] refs #22031 FDA make sure thread is set to none at tart --- scripts/Muon/fft_presenter.py | 1 + scripts/Muon/maxent_presenter.py | 1 + 2 files changed, 2 insertions(+) diff --git a/scripts/Muon/fft_presenter.py b/scripts/Muon/fft_presenter.py index 65b9c0f3850b..085c399f0c16 100644 --- a/scripts/Muon/fft_presenter.py +++ b/scripts/Muon/fft_presenter.py @@ -14,6 +14,7 @@ def __init__(self,view,alg,load): self.view=view self.alg=alg self.load=load + self.thread = None # set data self.getWorkspaceNames() #connect diff --git a/scripts/Muon/maxent_presenter.py b/scripts/Muon/maxent_presenter.py index 6e6748a287c8..8dd617003f47 100644 --- a/scripts/Muon/maxent_presenter.py +++ b/scripts/Muon/maxent_presenter.py @@ -18,6 +18,7 @@ def __init__(self,view,alg,load): self.alg=alg self.calcAlg = maxent_model.PhaseModel() self.load=load + self.thread =None # set data self.getWorkspaceNames() #connect From 78923d000742e6e2dd4ff3fb3894d28cd74eee61 Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 13 Mar 2018 12:13:08 +0000 Subject: [PATCH 169/364] Remove invalid context menu items for muon multi fit re #22022 --- MantidPlot/src/Mantid/PeakPickerTool.cpp | 93 ++++++++++++------- MantidPlot/src/Mantid/PeakPickerTool.h | 5 + .../Common/IMuonFitFunctionModel.h | 1 + .../Common/MuonFitPropertyBrowser.h | 6 ++ .../common/src/MuonFitPropertyBrowser.cpp | 18 +++- 5 files changed, 84 insertions(+), 39 deletions(-) diff --git a/MantidPlot/src/Mantid/PeakPickerTool.cpp b/MantidPlot/src/Mantid/PeakPickerTool.cpp index 718608590cff..1b88d6db407b 100644 --- a/MantidPlot/src/Mantid/PeakPickerTool.cpp +++ b/MantidPlot/src/Mantid/PeakPickerTool.cpp @@ -665,49 +665,54 @@ void PeakPickerTool::replot(MantidQt::MantidWidgets::PropertyHandler *h) const { * @param menu :: A reference to the context menu */ void PeakPickerTool::prepareContextMenu(QMenu &menu) { - QAction *action = new QAction("Add peak...", this); - connect(action, SIGNAL(triggered()), this, SLOT(addPeak())); - menu.addAction(action); - - action = new QAction("Add background...", this); - connect(action, SIGNAL(triggered()), this, SLOT(addBackground())); - menu.addAction(action); + QAction *action; + // several of the context menu options do not work for muon multi fit data, + // so don't show them + if (!isMuonMultiFitData()) { + action = new QAction("Add peak...", this); + connect(action, SIGNAL(triggered()), this, SLOT(addPeak())); + menu.addAction(action); - action = new QAction("Add other function...", this); - connect(action, SIGNAL(triggered()), this, SLOT(addOther())); - menu.addAction(action); + action = new QAction("Add background...", this); + connect(action, SIGNAL(triggered()), this, SLOT(addBackground())); + menu.addAction(action); - menu.addSeparator(); + action = new QAction("Add other function...", this); + connect(action, SIGNAL(triggered()), this, SLOT(addOther())); + menu.addAction(action); - if (m_fitPropertyBrowser->count() > 0) { - if (m_fitPropertyBrowser->getHandler()->hasPlot()) { - action = new QAction("Remove guess", this); - connect(action, SIGNAL(triggered()), this, SLOT(removeGuess())); - menu.addAction(action); - } else { - action = new QAction("Plot guess", this); - connect(action, SIGNAL(triggered()), this, SLOT(plotGuess())); - menu.addAction(action); - } + menu.addSeparator(); - MantidQt::MantidWidgets::PropertyHandler *h = - m_fitPropertyBrowser->currentHandler(); - if (h && h->pfun()) { - if (h->hasPlot()) { - action = new QAction("Remove guess for this peak", this); - connect(action, SIGNAL(triggered()), this, SLOT(removeCurrentGuess())); + if (m_fitPropertyBrowser->count() > 0) { + if (m_fitPropertyBrowser->getHandler()->hasPlot()) { + action = new QAction("Remove guess", this); + connect(action, SIGNAL(triggered()), this, SLOT(removeGuess())); menu.addAction(action); } else { - action = new QAction("Plot guess for this peak", this); - connect(action, SIGNAL(triggered()), this, SLOT(plotCurrentGuess())); + action = new QAction("Plot guess", this); + connect(action, SIGNAL(triggered()), this, SLOT(plotGuess())); menu.addAction(action); } - menu.addSeparator(); + MantidQt::MantidWidgets::PropertyHandler *h = + m_fitPropertyBrowser->currentHandler(); + if (h && h->pfun()) { + if (h->hasPlot()) { + action = new QAction("Remove guess for this peak", this); + connect(action, SIGNAL(triggered()), this, SLOT(removeCurrentGuess())); + menu.addAction(action); + } else { + action = new QAction("Plot guess for this peak", this); + connect(action, SIGNAL(triggered()), this, SLOT(plotCurrentGuess())); + menu.addAction(action); + } - action = new QAction("Remove peak", this); - connect(action, SIGNAL(triggered()), this, SLOT(deletePeak())); - menu.addAction(action); + menu.addSeparator(); + + action = new QAction("Remove peak", this); + connect(action, SIGNAL(triggered()), this, SLOT(deletePeak())); + menu.addAction(action); + } } } @@ -1055,8 +1060,24 @@ void PeakPickerTool::addExistingFitsAndGuess(const QStringList &curvesList) { * @returns :: True for muon data, false otherwise */ bool PeakPickerTool::isMuonData() const { + return (getMuonPointer() != nullptr); +} +/** +* Tests if the peak picker tool is connected to a MuonFitPropertyBrowser and set to multiple fitting +* @returns :: True for muon multiple fit data, false otherwise +*/ +bool PeakPickerTool::isMuonMultiFitData() const { + const auto muonBrowser = getMuonPointer(); + if (muonBrowser != nullptr) { + return muonBrowser->isMultiFittingMode(); + } + return false; +} + +/// Returns a pointer to the MuonFitPropertyBrowser or NULL +const MantidQt::MantidWidgets::MuonFitPropertyBrowser* PeakPickerTool::getMuonPointer() const { const auto muonBrowser = - dynamic_cast( - m_fitPropertyBrowser); - return (muonBrowser != nullptr); + dynamic_cast( + m_fitPropertyBrowser); + return muonBrowser; } diff --git a/MantidPlot/src/Mantid/PeakPickerTool.h b/MantidPlot/src/Mantid/PeakPickerTool.h index 1802d3dafba5..e74a7d6b17c3 100644 --- a/MantidPlot/src/Mantid/PeakPickerTool.h +++ b/MantidPlot/src/Mantid/PeakPickerTool.h @@ -29,6 +29,7 @@ namespace MantidQt { namespace MantidWidgets { class FitPropertyBrowser; class PropertyHandler; +class MuonFitPropertyBrowser; } } @@ -196,6 +197,10 @@ private slots: void addExistingFitsAndGuess(const QStringList &curvesList); // Test if we are fitting muon data bool isMuonData() const; + // Test if we are fitting muon multi fit data + bool isMuonMultiFitData() const; + // Returns a pointer to the MuonFitPropertyBrowser or NULL + const MantidQt::MantidWidgets::MuonFitPropertyBrowser* getMuonPointer() const; /// Creates a pointer to fitPropertyBrowser MantidQt::MantidWidgets::FitPropertyBrowser *m_fitPropertyBrowser; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/IMuonFitFunctionModel.h b/qt/widgets/common/inc/MantidQtWidgets/Common/IMuonFitFunctionModel.h index 206e6eeb9fbb..aa8bb5003a54 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/IMuonFitFunctionModel.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/IMuonFitFunctionModel.h @@ -42,6 +42,7 @@ class EXPORT_OPT_MANTIDQT_COMMON IMuonFitFunctionModel { virtual Mantid::API::IFunction_sptr getFunction() const = 0; virtual std::vector getWorkspaceNamesToFit() const = 0; virtual void setMultiFittingMode(bool enabled) = 0; + virtual bool isMultiFittingMode() const = 0; virtual void doRemoveGuess() = 0; virtual void doPlotGuess() = 0; virtual bool hasGuess() const = 0; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index 8e7644cae7d8..74cded7c78bf 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -87,6 +87,9 @@ class EXPORT_OPT_MANTIDQT_COMMON MuonFitPropertyBrowser } /// Set multiple fitting mode on or off void setMultiFittingMode(bool enabled) override; + /// returns true if the browser is set to multi fitting mode + bool isMultiFittingMode() const override; + /// After fit checks done, continue void continueAfterChecks(bool sequential) override; @@ -230,6 +233,9 @@ private slots: QDialog *m_comboWindow; std::vector m_groupsList; + + //stores if this is in multi fitting mode + bool m_isMultiFittingMode; }; std::map readMultipleNormalization(); diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 6a199c0eba5f..ca91e2614a1c 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -79,9 +79,10 @@ const std::string MuonFitPropertyBrowser::SIMULTANEOUS_PREFIX{"MuonSimulFit_"}; * @param mantidui :: The UI form for MantidPlot */ MuonFitPropertyBrowser::MuonFitPropertyBrowser(QWidget *parent, - QObject *mantidui) - : FitPropertyBrowser(parent, mantidui), m_widgetSplitter(nullptr), - m_mainSplitter(nullptr) {} + QObject *mantidui) + : FitPropertyBrowser(parent, mantidui), m_widgetSplitter(nullptr), + m_mainSplitter(nullptr), m_isMultiFittingMode(false) { +} /** * Initialise the muon fit property browser. @@ -1178,6 +1179,7 @@ std::string MuonFitPropertyBrowser::outputName() const { * @param enabled :: [input] Whether to turn this mode on or off */ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { + m_isMultiFittingMode = enabled; // First, clear whatever model is currently set this->clear(); // set default selection (all groups) @@ -1200,6 +1202,16 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { } } } + +/** +* Returns true is the browser is set to multi fitting mode +* This works using the visibility state of the button group +* which is controlled in setMultiFittingMode +*/ +bool MuonFitPropertyBrowser::isMultiFittingMode() const { + return m_isMultiFittingMode; +} + /** * Set TF asymmetry mode on or off. * If turned off, the fit property browser looks like Mantid 3.8. From 96b633db2982b323ebc01222a8315384b606a994 Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 13 Mar 2018 12:21:51 +0000 Subject: [PATCH 170/364] clang formatting re #22022 --- MantidPlot/src/Mantid/PeakPickerTool.cpp | 19 +++++++++++-------- MantidPlot/src/Mantid/PeakPickerTool.h | 2 +- .../Common/MuonFitPropertyBrowser.h | 3 +-- .../common/src/MuonFitPropertyBrowser.cpp | 7 +++---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/MantidPlot/src/Mantid/PeakPickerTool.cpp b/MantidPlot/src/Mantid/PeakPickerTool.cpp index 1b88d6db407b..d52359f8ac1a 100644 --- a/MantidPlot/src/Mantid/PeakPickerTool.cpp +++ b/MantidPlot/src/Mantid/PeakPickerTool.cpp @@ -695,11 +695,12 @@ void PeakPickerTool::prepareContextMenu(QMenu &menu) { } MantidQt::MantidWidgets::PropertyHandler *h = - m_fitPropertyBrowser->currentHandler(); + m_fitPropertyBrowser->currentHandler(); if (h && h->pfun()) { if (h->hasPlot()) { action = new QAction("Remove guess for this peak", this); - connect(action, SIGNAL(triggered()), this, SLOT(removeCurrentGuess())); + connect(action, SIGNAL(triggered()), this, + SLOT(removeCurrentGuess())); menu.addAction(action); } else { action = new QAction("Plot guess for this peak", this); @@ -1063,21 +1064,23 @@ bool PeakPickerTool::isMuonData() const { return (getMuonPointer() != nullptr); } /** -* Tests if the peak picker tool is connected to a MuonFitPropertyBrowser and set to multiple fitting +* Tests if the peak picker tool is connected to a MuonFitPropertyBrowser and set +* to multiple fitting * @returns :: True for muon multiple fit data, false otherwise */ bool PeakPickerTool::isMuonMultiFitData() const { const auto muonBrowser = getMuonPointer(); - if (muonBrowser != nullptr) { - return muonBrowser->isMultiFittingMode(); + if (muonBrowser != nullptr) { + return muonBrowser->isMultiFittingMode(); } return false; } /// Returns a pointer to the MuonFitPropertyBrowser or NULL -const MantidQt::MantidWidgets::MuonFitPropertyBrowser* PeakPickerTool::getMuonPointer() const { +const MantidQt::MantidWidgets::MuonFitPropertyBrowser * +PeakPickerTool::getMuonPointer() const { const auto muonBrowser = - dynamic_cast( - m_fitPropertyBrowser); + dynamic_cast( + m_fitPropertyBrowser); return muonBrowser; } diff --git a/MantidPlot/src/Mantid/PeakPickerTool.h b/MantidPlot/src/Mantid/PeakPickerTool.h index e74a7d6b17c3..02f9b0533ea6 100644 --- a/MantidPlot/src/Mantid/PeakPickerTool.h +++ b/MantidPlot/src/Mantid/PeakPickerTool.h @@ -200,7 +200,7 @@ private slots: // Test if we are fitting muon multi fit data bool isMuonMultiFitData() const; // Returns a pointer to the MuonFitPropertyBrowser or NULL - const MantidQt::MantidWidgets::MuonFitPropertyBrowser* getMuonPointer() const; + const MantidQt::MantidWidgets::MuonFitPropertyBrowser *getMuonPointer() const; /// Creates a pointer to fitPropertyBrowser MantidQt::MantidWidgets::FitPropertyBrowser *m_fitPropertyBrowser; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h index 74cded7c78bf..3065904012f7 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MuonFitPropertyBrowser.h @@ -90,7 +90,6 @@ class EXPORT_OPT_MANTIDQT_COMMON MuonFitPropertyBrowser /// returns true if the browser is set to multi fitting mode bool isMultiFittingMode() const override; - /// After fit checks done, continue void continueAfterChecks(bool sequential) override; /// Remove a plotted guess @@ -234,7 +233,7 @@ private slots: std::vector m_groupsList; - //stores if this is in multi fitting mode + // stores if this is in multi fitting mode bool m_isMultiFittingMode; }; diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index ca91e2614a1c..ea69c4b6de3e 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -79,10 +79,9 @@ const std::string MuonFitPropertyBrowser::SIMULTANEOUS_PREFIX{"MuonSimulFit_"}; * @param mantidui :: The UI form for MantidPlot */ MuonFitPropertyBrowser::MuonFitPropertyBrowser(QWidget *parent, - QObject *mantidui) - : FitPropertyBrowser(parent, mantidui), m_widgetSplitter(nullptr), - m_mainSplitter(nullptr), m_isMultiFittingMode(false) { -} + QObject *mantidui) + : FitPropertyBrowser(parent, mantidui), m_widgetSplitter(nullptr), + m_mainSplitter(nullptr), m_isMultiFittingMode(false) {} /** * Initialise the muon fit property browser. From 6ec568f04e7c8149a55ae272d0b4cbabcbcbe8d7 Mon Sep 17 00:00:00 2001 From: Verena Reimund Date: Tue, 13 Mar 2018 13:34:15 +0100 Subject: [PATCH 171/364] Update release notes Refs #21075 --- docs/source/release/v3.13.0/framework.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/source/release/v3.13.0/framework.rst b/docs/source/release/v3.13.0/framework.rst index 89615c6d3526..51e2d0abe055 100644 --- a/docs/source/release/v3.13.0/framework.rst +++ b/docs/source/release/v3.13.0/framework.rst @@ -9,4 +9,9 @@ Framework Changes putting new features at the top of the section, followed by improvements, followed by bug fixes. +Bug fixes +######### + +- The documentation of the algorithm :ref:`algm-CreateSampleWorkspace` did not match its implementation. The axis in beam direction will now be correctly described as Z instead of X. + :ref:`Release 3.13.0 ` From aff36c0bd6c27b29dfa66adb4936898526e4d771 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Tue, 13 Mar 2018 12:52:24 +0000 Subject: [PATCH 172/364] Increase tolerance a bit. Re #22004 --- docs/source/fitting/fitfunctions/IsoRotDiff.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/fitting/fitfunctions/IsoRotDiff.rst b/docs/source/fitting/fitfunctions/IsoRotDiff.rst index deb0dcb37344..38173d7ff97c 100644 --- a/docs/source/fitting/fitfunctions/IsoRotDiff.rst +++ b/docs/source/fitting/fitfunctions/IsoRotDiff.rst @@ -170,8 +170,8 @@ and the overal intensity of the signal with a fit to the following model: print("Optimal Radius within 5% of nominal value") else: print("Error. Obtained Radius= {0} instead of {1}".format(Radius,R)) - if abs(tau-Tau)/tau < 0.4: - print("Optimal Tau within 40% of nominal value") + if abs(tau-Tau)/tau < 1.0: + print("Optimal Tau within 100% of nominal value") else: print("Error. Obtained Tau= {0} instead of {1}".format(Tau,tau)) @@ -181,7 +181,7 @@ Output: Optimal Height within 10% of nominal value Optimal Radius within 5% of nominal value - Optimal Tau within 40% of nominal value + Optimal Tau within 100% of nominal value .. categories:: From 77f29b151b2330ed4cb44818dad87a0a21f4903d Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 13 Mar 2018 13:15:31 +0000 Subject: [PATCH 173/364] Add mock statement to test re #22022 --- .../test/MuonAnalysisFitFunctionPresenterTest.h | 1 + 1 file changed, 1 insertion(+) diff --git a/qt/scientific_interfaces/test/MuonAnalysisFitFunctionPresenterTest.h b/qt/scientific_interfaces/test/MuonAnalysisFitFunctionPresenterTest.h index d42731259c67..467a458e9a64 100644 --- a/qt/scientific_interfaces/test/MuonAnalysisFitFunctionPresenterTest.h +++ b/qt/scientific_interfaces/test/MuonAnalysisFitFunctionPresenterTest.h @@ -65,6 +65,7 @@ class MockFitFunctionControl : public IMuonFitFunctionModel { MOCK_CONST_METHOD0(getWorkspaceNamesToFit, std::vector()); MOCK_METHOD1(userChangedDatasetIndex, void(int)); MOCK_METHOD1(setMultiFittingMode, void(bool)); + MOCK_CONST_METHOD0(isMultiFittingMode, bool()); MOCK_METHOD1(fitRawDataClicked, void(bool)); MOCK_METHOD0(doRemoveGuess, void()); MOCK_METHOD0(doPlotGuess, void()); From f16cb4d60eaa8c90732f8bbc7c6300184135d870 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 13 Mar 2018 13:38:13 +0000 Subject: [PATCH 174/364] Fixed test failures + doxygen errors. --- .../src/DataProcessorUI/ProcessingAlgorithm.cpp | 4 ++++ .../GenericDataProcessorPresenterTest.h | 11 ++++++----- .../test/DataProcessorUI/ProcessingAlgorithmTest.h | 4 +--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp b/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp index e52ac65020fb..1aaa65903e07 100644 --- a/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp +++ b/qt/widgets/common/src/DataProcessorUI/ProcessingAlgorithm.cpp @@ -8,6 +8,8 @@ namespace DataProcessor { * @param name : The name of this algorithm * @param prefix : The list of prefixes that will be used for the output * workspaces' names +* @param postprocessedOutputPrefixIndex The zero based index of the prefix for +* the workspace which should be postprocessed * @param blacklist : The list of properties we do not want to show */ ProcessingAlgorithm::ProcessingAlgorithm( @@ -45,6 +47,8 @@ ProcessingAlgorithm::ProcessingAlgorithm( * @param name : The name of this algorithm * @param prefix : The list of prefixes that will be used for the output * workspaces' names, as a string +* @param postprocessedOutputPrefixIndex The zero based index of the prefix for +* the workspace which should be postprocessed * @param blacklist : The list of properties we do not want to show, as a string */ ProcessingAlgorithm::ProcessingAlgorithm( diff --git a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h index a1ed8d3ee700..a2288a803ea8 100644 --- a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h +++ b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h @@ -198,7 +198,8 @@ class GenericDataProcessorPresenterTest : public CxxTest::TestSuite { void createTOFWorkspace(const QString &wsName, const QString &runNumber = "") { auto tinyWS = - WorkspaceCreationHelper::create2DWorkspaceWithReflectometryInstrument(); + WorkspaceCreationHelper::create2DWorkspaceWithReflectometryInstrument( + 2000); auto inst = tinyWS->getInstrument(); inst->getParameterMap()->addDouble(inst.get(), "I0MonitorIndex", 1.0); @@ -3190,16 +3191,16 @@ class GenericDataProcessorPresenterTest : public CxxTest::TestSuite { "IvsQ_TOF_12345_TOF_12346"); TSM_ASSERT_DELTA( "Logarithmic rebinning should have been applied, with param 0.04", - out->x(0)[0], 0.100, 1e-5); + out->x(0)[0], 0.01108, 1e-5); TSM_ASSERT_DELTA( "Logarithmic rebinning should have been applied, with param 0.04", - out->x(0)[1], 0.104, 1e-5); + out->x(0)[1], 0.01153, 1e-5); TSM_ASSERT_DELTA( "Logarithmic rebinning should have been applied, with param 0.04", - out->x(0)[2], 0.10816, 1e-5); + out->x(0)[2], 0.01199, 1e-5); TSM_ASSERT_DELTA( "Logarithmic rebinning should have been applied, with param 0.04", - out->x(0)[3], 0.11248, 1e-5); + out->x(0)[3], 0.01247, 1e-5); // Check output and tidy up checkWorkspacesExistInADS(m_defaultWorkspacesNoPrefix); diff --git a/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h b/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h index ee5fccb16ceb..1e1adfd32f8b 100644 --- a/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h +++ b/qt/widgets/common/test/DataProcessorUI/ProcessingAlgorithmTest.h @@ -58,15 +58,13 @@ class ProcessingAlgorithmTest : public CxxTest::TestSuite { // ReflectometryReductionOneAuto has three output ws properties // We should provide three prefixes, one for each ws std::vector prefixes; - prefixes.emplace_back("IvsQ_"); prefixes.emplace_back("IvsQ_binned_"); + prefixes.emplace_back("IvsQ_"); // This should throw TS_ASSERT_THROWS( ProcessingAlgorithm(algName, prefixes, 0, std::set()), std::invalid_argument); - prefixes.emplace_back("IvsQ_"); - prefixes.emplace_back("IvsQ_binned_"); // This should also throw TS_ASSERT_THROWS( ProcessingAlgorithm(algName, prefixes, 0, std::set()), From a6e8324c5080cd62f4911aaaf6d409be9f292c5e Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 13 Mar 2018 13:40:47 +0000 Subject: [PATCH 175/364] Disable Get Parameters and add release notes re #22022 --- MantidPlot/src/Mantid/PeakPickerTool.cpp | 10 ++++++---- docs/source/release/v3.12.0/muon.rst | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/MantidPlot/src/Mantid/PeakPickerTool.cpp b/MantidPlot/src/Mantid/PeakPickerTool.cpp index d52359f8ac1a..976158b6ce60 100644 --- a/MantidPlot/src/Mantid/PeakPickerTool.cpp +++ b/MantidPlot/src/Mantid/PeakPickerTool.cpp @@ -727,11 +727,13 @@ void PeakPickerTool::prepareContextMenu(QMenu &menu) { menu.addSeparator(); - action = new QAction("Get Parameters", this); - connect(action, SIGNAL(triggered()), this, SLOT(getParameters())); - menu.addAction(action); + if (!isMuonMultiFitData()) { + action = new QAction("Get Parameters", this); + connect(action, SIGNAL(triggered()), this, SLOT(getParameters())); + menu.addAction(action); - menu.addSeparator(); + menu.addSeparator(); + } if (m_fitPropertyBrowser->isFitEnabled()) { action = new QAction("Fit", this); diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 25f61f3ccead..cd68e760d1c4 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -29,6 +29,7 @@ Interface - The ALC interface now allows background sections with negative values. - If data is loaded with 0 good frames into Muon Analysis then it will try to load the data without dead time correction (does not need number of good frames). - Muon analysis no longer disables the "aco add" and "simultaneous" buttons in the multiple fitting interface. +- We have disabled some non functional graph right click context menu items or adding functions when in multi data fitting mode, in the Data Analysis tab of the Muon Analysis Interface. Algorithms ---------- From 27c50c134e8f376e3b613a4dbad37dbf7036e436 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 13 Mar 2018 13:55:01 +0000 Subject: [PATCH 176/364] Re #22049: Applied fixes from patched version of clang-tidy. --- Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h | 2 +- Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h | 2 +- .../Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h | 2 +- .../RunCombinationHelpers/SampleLogsBehaviour.h | 4 ++-- Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h | 4 ++-- Framework/Algorithms/src/CreatePSDBleedMask.cpp | 2 +- Framework/Algorithms/src/SofQWNormalisedPolygon.cpp | 2 +- Framework/Algorithms/src/Stitch1D.cpp | 2 +- Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h | 2 +- Framework/Algorithms/test/Stitch1DTest.h | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h index 3eba93548076..fba8e6c81c1a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h @@ -66,7 +66,7 @@ class DLLExport MaskDetectorsIf : public API::Algorithm { /// Returns an allowed values statement to insert into decumentation std::string allowedValuesStatement(const std::vector &vals); // Typedef for det to value map - typedef std::unordered_map udet2valuem; + using udet2valuem = std::unordered_map; /// A map of detector numbers to mask boolean udet2valuem umap; /// Get the properties diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h index 90d1c922c6ac..6fda6c1cf0fd 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h @@ -96,7 +96,7 @@ class DLLExport MergeRuns : public API::MultiPeriodGroupAlgorithm { /// An addition table is a list of pairs: First int = workspace index in the /// EW being added, Second int = workspace index to which it will be added in /// the OUTPUT EW. -1 if it should add a new entry at the end. - typedef std::vector> AdditionTable; + using AdditionTable = std::vector >; /// Copy the history from the input workspaces to the output workspaces template void copyHistoryFromInputWorkspaces(const Container &workspaces) { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h index a217c2db1be6..70c95c765da1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h @@ -98,7 +98,7 @@ class DLLExport ReadGroupsFromFile : public API::Algorithm { private: /// Map containing the detector entries found in the *.cal file. The key is /// the udet number, the value of is a pair of . - typedef std::unordered_map> calmap; + using calmap = std::unordered_map >; /// Initialisation code void init() override; /// Execution code diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h b/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h index 6863ce49bdf7..babc0ee6c3b0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h @@ -86,8 +86,8 @@ class MANTID_ALGORITHMS_DLL SampleLogsBehaviour { private: Kernel::Logger &m_logger; - typedef std::pair SampleLogsKey; - typedef std::map SampleLogsMap; + using SampleLogsKey = std::pair; + using SampleLogsMap = std::map; SampleLogsMap m_logMap; std::vector> m_addeeLogMap; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h b/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h index 0417d77a594f..5a9375d1842e 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h @@ -12,7 +12,7 @@ namespace Mantid { namespace Algorithms { -typedef std::map SpectraDistanceMap; +using SpectraDistanceMap = std::map; /* Filters spectra detector list by radius. @@ -149,7 +149,7 @@ class DLLExport SmoothNeighbours : public API::Algorithm { Mantid::API::MatrixWorkspace_sptr inWS; /// Each neighbours is specified as a pair with workspace index, weight. - typedef std::pair weightedNeighbour; + using weightedNeighbour = std::pair; /// Vector of list of neighbours (with weight) for each workspace index. std::vector> m_neighbours; diff --git a/Framework/Algorithms/src/CreatePSDBleedMask.cpp b/Framework/Algorithms/src/CreatePSDBleedMask.cpp index 5d6b750f40d4..91c76baf564d 100644 --- a/Framework/Algorithms/src/CreatePSDBleedMask.cpp +++ b/Framework/Algorithms/src/CreatePSDBleedMask.cpp @@ -94,7 +94,7 @@ void CreatePSDBleedMask::exec() { const int numSpectra = static_cast(inputWorkspace->getNumberHistograms()); // Keep track of a map of tubes to lists of indices - typedef std::map> TubeIndex; + using TubeIndex = std::map >; TubeIndex tubeMap; API::Progress progress(this, 0.0, 1.0, numSpectra); diff --git a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp index 912ded1386f0..c8eb6140d2a1 100644 --- a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp +++ b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp @@ -20,7 +20,7 @@ namespace Mantid { namespace Algorithms { // Setup typedef for later use -typedef std::map SpectraDistanceMap; +using SpectraDistanceMap = std::map; using DetConstPtr = Geometry::IDetector_const_sptr; // Register the algorithm into the AlgorithmFactory diff --git a/Framework/Algorithms/src/Stitch1D.cpp b/Framework/Algorithms/src/Stitch1D.cpp index e334f7b4cae7..553365f31092 100644 --- a/Framework/Algorithms/src/Stitch1D.cpp +++ b/Framework/Algorithms/src/Stitch1D.cpp @@ -25,7 +25,7 @@ using Mantid::HistogramData::HistogramE; namespace { -typedef boost::tuple MinMaxTuple; +using MinMaxTuple = boost::tuple; MinMaxTuple calculateXIntersection(MatrixWorkspace_sptr lhsWS, MatrixWorkspace_sptr rhsWS) { return MinMaxTuple(rhsWS->x(0).front(), lhsWS->x(0).back()); diff --git a/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h b/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h index b30cda65156c..4ff1d63a9e96 100644 --- a/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h +++ b/Framework/Algorithms/test/SpecularReflectionAlgorithmTest.h @@ -22,7 +22,7 @@ using namespace Mantid::API; using namespace Mantid::Kernel; -typedef boost::tuple VerticalHorizontalOffsetType; +using VerticalHorizontalOffsetType = boost::tuple; class SpecularReflectionAlgorithmTest { protected: diff --git a/Framework/Algorithms/test/Stitch1DTest.h b/Framework/Algorithms/test/Stitch1DTest.h index 5c23756d31da..1e787942a341 100644 --- a/Framework/Algorithms/test/Stitch1DTest.h +++ b/Framework/Algorithms/test/Stitch1DTest.h @@ -66,7 +66,7 @@ class Stitch1DTest : public CxxTest::TestSuite { MatrixWorkspace_sptr a; MatrixWorkspace_sptr b; std::vector x; - typedef boost::tuple ResultType; + using ResultType = boost::tuple; MatrixWorkspace_sptr make_arbitrary_point_ws() { const auto &x = HistogramX(3, LinearGenerator(-1, 0.2)); From 60b1a3964f04133972271f04d3d9ddb29b73cda8 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Tue, 13 Mar 2018 15:01:39 +0000 Subject: [PATCH 177/364] refs #22004 release notes for tie bug fix --- docs/source/release/v3.12.0/framework.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst index 2ca2ef8cdf35..7543657fc3bd 100644 --- a/docs/source/release/v3.12.0/framework.rst +++ b/docs/source/release/v3.12.0/framework.rst @@ -61,6 +61,7 @@ Fitting - :ref:`EISFDiffSphere ` fits the Q-dependence on the EISF of a particle undergoing continuous diffusion but confined to a spherical volume. - :ref:`EISFDiffSphereAlkyl ` fits the Q-dependence on the EISF of an alkyl molecule, like a membrane lipd. - :ref:`EISFDiffCylinder ` models the elastic incoherent scattering intensity of a particle diffusing within a cylinder. +- Fix for a bug in calculating numerical derivatives by applying ties correctly. Core Functionality ------------------ From fe7efdb7975a6aa4a413e48413b57595c7910f44 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 13 Mar 2018 15:09:14 +0000 Subject: [PATCH 178/364] Applied clang-format. --- .../Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h | 3 ++- Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h | 2 +- .../Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h | 2 +- Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h | 2 +- Framework/Algorithms/src/CreatePSDBleedMask.cpp | 2 +- Framework/Algorithms/src/PerformIndexOperations.cpp | 4 ++-- Framework/Algorithms/src/SofQWPolygon.cpp | 3 ++- .../inc/MantidDataHandling/EventWorkspaceCollection.h | 3 ++- 8 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h index 805130499c34..486756882e07 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AbsorptionCorrection.h @@ -147,7 +147,8 @@ class DLLExport AbsorptionCorrection : public API::Algorithm { double m_lambdaFixed; ///< The wavelength corresponding to the fixed energy, /// if provided - using expfunction = double (*)(double); ///< Typedef pointer to exponential function + using expfunction = + double (*)(double); ///< Typedef pointer to exponential function expfunction EXPONENTIAL; ///< Pointer to exponential function }; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h index 6fda6c1cf0fd..d3d22f26abca 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h @@ -96,7 +96,7 @@ class DLLExport MergeRuns : public API::MultiPeriodGroupAlgorithm { /// An addition table is a list of pairs: First int = workspace index in the /// EW being added, Second int = workspace index to which it will be added in /// the OUTPUT EW. -1 if it should add a new entry at the end. - using AdditionTable = std::vector >; + using AdditionTable = std::vector>; /// Copy the history from the input workspaces to the output workspaces template void copyHistoryFromInputWorkspaces(const Container &workspaces) { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h index 70c95c765da1..11505f00e7c9 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h @@ -98,7 +98,7 @@ class DLLExport ReadGroupsFromFile : public API::Algorithm { private: /// Map containing the detector entries found in the *.cal file. The key is /// the udet number, the value of is a pair of . - using calmap = std::unordered_map >; + using calmap = std::unordered_map>; /// Initialisation code void init() override; /// Execution code diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h index 183ec88c50d8..973bd63c7cc8 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h @@ -49,7 +49,7 @@ class DLLExport Stitch1D : public API::Algorithm { private: /// Helper typedef. For storing indexes of special values per spectra per /// workspace. - using SpecialTypeIndexes = std::vector >; + using SpecialTypeIndexes = std::vector>; /// Overwrites Algorithm method. void init() override; /// Overwrites Algorithm method. diff --git a/Framework/Algorithms/src/CreatePSDBleedMask.cpp b/Framework/Algorithms/src/CreatePSDBleedMask.cpp index 91c76baf564d..cbbe9f8f9bde 100644 --- a/Framework/Algorithms/src/CreatePSDBleedMask.cpp +++ b/Framework/Algorithms/src/CreatePSDBleedMask.cpp @@ -94,7 +94,7 @@ void CreatePSDBleedMask::exec() { const int numSpectra = static_cast(inputWorkspace->getNumberHistograms()); // Keep track of a map of tubes to lists of indices - using TubeIndex = std::map >; + using TubeIndex = std::map>; TubeIndex tubeMap; API::Progress progress(this, 0.0, 1.0, numSpectra); diff --git a/Framework/Algorithms/src/PerformIndexOperations.cpp b/Framework/Algorithms/src/PerformIndexOperations.cpp index 55c225f3d526..b00698a069e3 100644 --- a/Framework/Algorithms/src/PerformIndexOperations.cpp +++ b/Framework/Algorithms/src/PerformIndexOperations.cpp @@ -45,7 +45,7 @@ class Command { }; /// Helper typedef -using VecCommands = std::vector >; +using VecCommands = std::vector>; /** * Command yielding no result. @@ -140,7 +140,7 @@ class CommandParser { }; /// Helper typedef for vector of command parsers -using VecCommandParsers = std::vector >; +using VecCommandParsers = std::vector>; /** * Command parser base class for common concrete command parser types. diff --git a/Framework/Algorithms/src/SofQWPolygon.cpp b/Framework/Algorithms/src/SofQWPolygon.cpp index 75d0c160cd60..7dd7a6dede9a 100644 --- a/Framework/Algorithms/src/SofQWPolygon.cpp +++ b/Framework/Algorithms/src/SofQWPolygon.cpp @@ -63,7 +63,8 @@ void SofQWPolygon::exec() { // Select the calculate Q method based on the mode // rather than doing this repeatedly in the loop - using QCalculation = double (SofQWPolygon::*)(double, double, double, double) const; + using QCalculation = + double (SofQWPolygon::*)(double, double, double, double) const; QCalculation qCalculator; if (m_EmodeProperties.m_emode == 1) { qCalculator = &SofQWPolygon::calculateDirectQ; diff --git a/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h b/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h index 2637ec6f1438..e7f551b27e82 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h +++ b/Framework/DataHandling/inc/MantidDataHandling/EventWorkspaceCollection.h @@ -109,7 +109,8 @@ class DLLExport EventWorkspaceCollection { virtual bool threadSafe() const; }; -using EventWorkspaceCollection_sptr = boost::shared_ptr; +using EventWorkspaceCollection_sptr = + boost::shared_ptr; using EventWorkspaceCollection_uptr = std::unique_ptr; } // namespace DataHandling From fd7b127a348b62c8d53b8e607147bd70a966e32a Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Tue, 13 Mar 2018 11:48:33 -0400 Subject: [PATCH 179/364] Add missing categories/sourcelink to LoadWAND --- docs/source/algorithms/LoadWAND-v1.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/source/algorithms/LoadWAND-v1.rst b/docs/source/algorithms/LoadWAND-v1.rst index d48ee523711b..8d075bc5ef6b 100644 --- a/docs/source/algorithms/LoadWAND-v1.rst +++ b/docs/source/algorithms/LoadWAND-v1.rst @@ -39,3 +39,7 @@ Output: .. code-block:: none ws has 1966080 spectrum and 1 point in units Wavelength + +.. categories:: + +.. sourcelink:: From 4e6444b0a2ead6c6ccc72ffd176c42d38b29d932 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 13 Mar 2018 16:31:49 +0000 Subject: [PATCH 180/364] Fixed GenericDataProcessorPresenterTest::testTreeUpdatedAfterProcess. - Failure caused by badly ordered angles violating the contract for Stitch1D. - Fixed by removing the set angle in the table for both, rather than just one run. --- .../test/DataProcessorUI/GenericDataProcessorPresenterTest.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h index a2288a803ea8..c6317dcaf4f2 100644 --- a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h +++ b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h @@ -1296,6 +1296,8 @@ class GenericDataProcessorPresenterTest : public CxxTest::TestSuite { auto ws = createPrefilledWorkspace("TestWorkspace", presenter->getWhiteList()); ws->String(0, ThetaCol) = ""; + ws->String(1, ThetaCol) = ""; + ws->String(0, ScaleCol) = ""; ws->String(1, ScaleCol) = ""; expectGetWorkspace(mockDataProcessorView, Exactly(1), "TestWorkspace"); presenter->notify(DataProcessorPresenter::OpenTableFlag); @@ -1318,6 +1320,8 @@ class GenericDataProcessorPresenterTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); TS_ASSERT_EQUALS(ws->String(1, RunCol), "12346"); TS_ASSERT(ws->String(0, ThetaCol) != ""); + TS_ASSERT(ws->String(0, ScaleCol) != ""); + TS_ASSERT(ws->String(1, ThetaCol) != ""); TS_ASSERT(ws->String(1, ScaleCol) != ""); // Check output and tidy up From 23b235d6291242f3cb4e752e1f3f2af450f5bf7f Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 13 Mar 2018 17:07:22 +0000 Subject: [PATCH 181/364] special case for diagnostics graphs in SANS when no range given re #22069 --- qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp b/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp index bca52e8b28c8..40c51e3162a5 100644 --- a/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp +++ b/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp @@ -1450,6 +1450,10 @@ QString SANSDiagnostics::createOutputWorkspaceName( // Detector, Min value, and Max values, QString appendix = "-" + detectorName + "-" + integrationType + min + "-" + integrationType + max; + if (min == max) { + // special case which means that it is all of the range + appendix = "-" + detectorName + "-" + integrationType + "_ALL"; + } outputWorkspaceName += appendix; outputWorkspaceName.replace("-", "_"); From 2f37b372818ee0ac1b622fdbd38520a5c506dbd5 Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Tue, 13 Mar 2018 17:13:14 +0000 Subject: [PATCH 182/364] clang formatting re #22069 --- qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp b/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp index 40c51e3162a5..9574a03dd554 100644 --- a/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp +++ b/qt/scientific_interfaces/ISISSANS/SANSDiagnostics.cpp @@ -1450,7 +1450,7 @@ QString SANSDiagnostics::createOutputWorkspaceName( // Detector, Min value, and Max values, QString appendix = "-" + detectorName + "-" + integrationType + min + "-" + integrationType + max; - if (min == max) { + if (min == max) { // special case which means that it is all of the range appendix = "-" + detectorName + "-" + integrationType + "_ALL"; } From 92b467d65388166efecaacec839dd1210a66e42d Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 13 Mar 2018 20:55:20 +0000 Subject: [PATCH 183/364] Include python qtawesome as a dependency Required for mslice and will be required for the workbench in the future --- CMakeLists.txt | 5 +++-- MantidPlot/make_package.rb.in | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86181c70cdf3..88066b5f782c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -308,7 +308,7 @@ if ( ENABLE_CPACK ) set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},scl-utils,mantidlibs34,mantidlibs34-runtime,mantidlibs34-qt,mantidlibs34-qt-x11,mantidlibs34-qt-webkit,mantidlibs34-qwt5-qt4" ) else() # Require matplotlib >= 1.5 to fix bug in latex rendering - set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES} qscintilla,qwt5-qt4,python2-matplotlib-qt4 >= 1.5.2,boost >= 1.53.0" ) + set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES} qscintilla,qwt5-qt4,python2-matplotlib-qt4 >= 1.5.2,python2-QtAwesome,boost >= 1.53.0" ) endif() # Add software collections for RHEL @@ -353,7 +353,8 @@ if ( ENABLE_CPACK ) "librdkafka++1," "libpocofoundation${POCO_SOLIB_VERSION},libpocoutil${POCO_SOLIB_VERSION},libpoconet${POCO_SOLIB_VERSION},libpoconetssl${POCO_SOLIB_VERSION},libpococrypto${POCO_SOLIB_VERSION},libpocoxml${POCO_SOLIB_VERSION}," "python-pycifrw (>= 4.2.1)," - "python-yaml") + "python-yaml," + "python-qtawesome") set ( PERFTOOLS_DEB_PACKAGE "libgoogle-perftools4 (>= 1.7)" ) if( "${UNIX_CODENAME}" STREQUAL "xenial") list ( APPEND DEPENDS_LIST ", libhdf5-cpp-11,libnexus0v5 (>= 4.3),libjsoncpp1,libqscintilla2-12v5, libmuparser2v5,libqwtplot3d-qt4-0v5,libgsl2,liboce-foundation10,liboce-modeling10") diff --git a/MantidPlot/make_package.rb.in b/MantidPlot/make_package.rb.in index 03a8e72da834..9653a13085df 100755 --- a/MantidPlot/make_package.rb.in +++ b/MantidPlot/make_package.rb.in @@ -317,7 +317,8 @@ end #Copy over python libraries not included with OSX. #currently missing epics path = "/Library/Python/2.7/site-packages" -directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml"] +directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports", "qtawesome", "qtpy", + "certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess","CifFile","yaml"] directories.each do |directory| addPythonLibrary("#{path}/#{directory}","Contents/MacOS/") end From e63a7a8521c0ff352213bf3700a8a05a589c9c7f Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Wed, 14 Mar 2018 09:07:17 +0000 Subject: [PATCH 184/364] Make figure format consistent with other docs --- docs/source/release/v3.12.0/diffraction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/release/v3.12.0/diffraction.rst b/docs/source/release/v3.12.0/diffraction.rst index ddb35708ddf1..54f48e56f0d6 100644 --- a/docs/source/release/v3.12.0/diffraction.rst +++ b/docs/source/release/v3.12.0/diffraction.rst @@ -67,8 +67,8 @@ Engineering Diffraction .. figure:: ../../images/engineering_gsas_gui.PNG :class: screenshot - :width: 385px - :align: center + :align: right + :figwidth: 50% The Engineering diffraction GSAS-II GUI From f1a2e3ce4bb4a5193b1e4086527c78b6dc3a9723 Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Wed, 14 Mar 2018 10:42:56 +0000 Subject: [PATCH 185/364] Updated order to new/improve/fix format --- docs/source/release/v3.12.0/diffraction.rst | 49 ++++++++++++--------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/docs/source/release/v3.12.0/diffraction.rst b/docs/source/release/v3.12.0/diffraction.rst index 54f48e56f0d6..9e6586e6fc3d 100644 --- a/docs/source/release/v3.12.0/diffraction.rst +++ b/docs/source/release/v3.12.0/diffraction.rst @@ -7,9 +7,7 @@ Diffraction Changes Powder Diffraction ------------------ -- :ref:`SaveFocusedXYE ` has been amended to write the metadata (e.g. temperature) value in the header, in the form of the Fullprof readable keyword. -- Some new functionality for POLARIS in the ISIS Powder scripts. Adjusted some default parameters and output unsplined vanadium workspace by default - New features in ISIS Powder which affect all instruments: + 'suffix' parameter added for output filenames @@ -24,6 +22,12 @@ Powder Diffraction + Scripts now support creation of grouping .cal files from ceria run(s) + Absorption corrections enabled for all samples, not just vanadium + ``subtract_empty_instrument`` parameter added for disabling empty subtraction, useful for focusing empties +- New functionality for POLARIS in the ISIS Powder scripts. Some default parameters adjusted and output unsplined vanadium workspace by default. +- New algorithm :ref:`algm-EstimateDivergence` estimates the beam divergence due to finite slit size. +- New algorithm :ref:`algm-SumOverlappingTubes` combines a detector scan for D2B into a single workspace. +- :ref:`CalculateDIFC ` has been extended to allow for calibration workspaces from :ref:`PDCalibration `. + +- :ref:`SaveFocusedXYE ` has been amended to write the metadata (e.g. temperature) value in the header, in the form of the Fullprof readable keyword. - Improvements in ISIS Powder for HRPD: + The prompt pulse is now masked out for the long window @@ -33,36 +37,22 @@ Powder Diffraction + The ``mode`` parameter now behaves as described in the documentation - it persists through function calls and is case insensitive + After calling create_vanadium and focus, the output workspaces always contain the sample material if it is set using ``set_sample_material``. (To view the sample material, right click the workspace and click 'Sample Material...') - + - The ``CalibrationFile`` is now optional in :ref:`SNSPowderReduction `. In this case time focussing will use :ref:`ConvertUnits ` and the instrument geometry. Care must be taken to supply a ``GroupingFile`` otherwise all of the spectra will be kept separate. - :ref:`SaveGSS ` is relaxed to accept non-TOF point data workspaces as well. -- New algorithm :ref:`algm-EstimateDivergence` estimates the beam divergence due to finite slit size - :ref:`PDCalibration ` returns three more diagnostic workspaces: one for the fitted peak heights, one for the fitted peak widths, and one for observed resolution. - :ref:`LoadILLDiffraction ` now supports D2B files with calibrated data. - :ref:`PowderDiffILLReduction ` and :ref:`PowderDiffILLDetEffCorr ` enable the basic data reduction for D20 scanning powder diffractometer at ILL. - :ref:`ApplyDetectorScanEffCorr ` applies the calibration file generated by :ref:`PowderDiffILLDetEffCorr ` to detector scan workspaces. - :ref:`PowderDiffILLDetScanReduction ` supports D2B and D20 (when doing a detector scan) powder diffraction reduction at the ILL. -- New algorithm :ref:`algm-SumOverlappingTubes` combines a detector scan for D2B into a single workspace. -- :ref:`CalculateDIFC ` has been extended to allow for calibration workspaces from :ref:`PDCalibration ` - :ref:`SaveGSS ` has been extended to allow user to specify GSAS general header, each bank's header and XYE decimal precision for SLOG. - :ref:`SaveVulcanGSS ` has been moved to a workflow algorithm and largely rewritten by using recent change in histogram and Workspace2D. It is also improved such that there is no contraint on the number of spectra and number of various binning parameters on the workspace to be saved to a GSAS file for VULCAN. - :ref:`PDLoadCharacterizations ` now allows for the azimuthal angles to be optionally specified in the file. + Engineering Diffraction ----------------------- -- Fixed a bug where the engineering diffraction GUI could hang when performing a long running file search. - -- :ref:`GSASIIRefineFitPeaks ` has been re-integrated with the - latest version of GSAS-II, allowing Rietveld and Pawley refinement - within Mantid. - + Fitted peaks are now output as a Mantid workspace -- Usability improvements in the GUI: - - + The "Invalid RB number" popup window in the GUI has been replaced with a more user-friendly message - + Improved progress reporting for Calibration and Focus - + Enabled multi-run fitting and plotting in the Fitting tab - + Improved unit conversions when using the peak picker - GSAS Fitting tab was added to the GUI to allow convenient GSAS-style refinement using GSASIIRefineFitPeaks .. figure:: ../../images/engineering_gsas_gui.PNG @@ -72,13 +62,28 @@ Engineering Diffraction The Engineering diffraction GSAS-II GUI +- :ref:`GSASIIRefineFitPeaks ` has been re-integrated with the + latest version of GSAS-II, allowing Rietveld and Pawley refinement + within Mantid. + + Fitted peaks are now output as a Mantid workspace. + +- Usability improvements in the GUI: + + + The "Invalid RB number" popup window in the GUI has been replaced with a more user-friendly message. + + Improved progress reporting for Calibration and Focus. + + Enabled multi-run fitting and plotting in the Fitting tab. + + Improved unit conversions when using the peak picker. + +- Fixed a bug where the engineering diffraction GUI could hang when performing a long running file search. + Single Crystal Diffraction -------------------------- + +- New algorithm :ref:`LoadWAND ` that will load event data for WAND² integrating out the events and correctly setting the units. + - :ref:`FilterPeaks ` now supports filtering peaks by TOF, d-spacing, and wavelength. - HB3A reduction interface has been enhanced. A child window is added to it for users to pre-process scans and save the processed and merged data to NeXus files in order to save time when they start to reduce and visualize the data. A record file is generated along with processed scans to record the calibration information. During data reduction, scans that have been processed in pre-processing will be loaded automatically from corresponding MD files. -- Fixed a bug in :ref:`IntegrateEllipsoids ` and :ref:`IntegrateEllipsoidsTwoStep ` that forced output to be weighted by the bin width. -- Fixed a bug in :ref:`IntegrateEllipsoidsTwoStep ` where peaks with negative intensity values would be set to zero. - :ref:`IntegratePeaksMDHKL ` now has option to specify background shell instead of using default background determination. - In HB3A reduction interface, section for downloading experimental data via http server has been removed from main UI. @@ -99,7 +104,9 @@ Single Crystal Diffraction - :ref:`StatisticsOfPeaksWorkspace ` now can accept long or short names for the point group and reflection condition. -- New algorithm :ref:`LoadWAND ` that will load event data for WAND² integrating out the events and correctly setting the units. +- Fixed a bug in :ref:`IntegrateEllipsoids ` and :ref:`IntegrateEllipsoidsTwoStep ` that forced output to be weighted by the bin width. +- Fixed a bug in :ref:`IntegrateEllipsoidsTwoStep ` where peaks with negative intensity values would be set to zero. + Total Scattering ---------------- From 79d6dd86252771cec4b4d9fbc11bea06bf51e2a4 Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Wed, 14 Mar 2018 10:51:40 +0000 Subject: [PATCH 186/364] Add sub-headings for New/Improved/Fix --- docs/source/release/v3.12.0/diffraction.rst | 28 ++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/diffraction.rst b/docs/source/release/v3.12.0/diffraction.rst index 9e6586e6fc3d..80babc99adb1 100644 --- a/docs/source/release/v3.12.0/diffraction.rst +++ b/docs/source/release/v3.12.0/diffraction.rst @@ -8,6 +8,9 @@ Diffraction Changes Powder Diffraction ------------------ +New features +############ + - New features in ISIS Powder which affect all instruments: + 'suffix' parameter added for output filenames @@ -25,8 +28,12 @@ Powder Diffraction - New functionality for POLARIS in the ISIS Powder scripts. Some default parameters adjusted and output unsplined vanadium workspace by default. - New algorithm :ref:`algm-EstimateDivergence` estimates the beam divergence due to finite slit size. - New algorithm :ref:`algm-SumOverlappingTubes` combines a detector scan for D2B into a single workspace. -- :ref:`CalculateDIFC ` has been extended to allow for calibration workspaces from :ref:`PDCalibration `. + +Improvements +############ + +- :ref:`CalculateDIFC ` has been extended to allow for calibration workspaces from :ref:`PDCalibration `. - :ref:`SaveFocusedXYE ` has been amended to write the metadata (e.g. temperature) value in the header, in the form of the Fullprof readable keyword. - Improvements in ISIS Powder for HRPD: @@ -53,6 +60,9 @@ Powder Diffraction Engineering Diffraction ----------------------- +Improvements +############ + - GSAS Fitting tab was added to the GUI to allow convenient GSAS-style refinement using GSASIIRefineFitPeaks .. figure:: ../../images/engineering_gsas_gui.PNG @@ -73,6 +83,9 @@ Engineering Diffraction + Improved progress reporting for Calibration and Focus. + Enabled multi-run fitting and plotting in the Fitting tab. + Improved unit conversions when using the peak picker. + +Bug fixes +######### - Fixed a bug where the engineering diffraction GUI could hang when performing a long running file search. @@ -80,8 +93,14 @@ Engineering Diffraction Single Crystal Diffraction -------------------------- +New features +############ + - New algorithm :ref:`LoadWAND ` that will load event data for WAND² integrating out the events and correctly setting the units. +Improvements +############ + - :ref:`FilterPeaks ` now supports filtering peaks by TOF, d-spacing, and wavelength. - HB3A reduction interface has been enhanced. A child window is added to it for users to pre-process scans and save the processed and merged data to NeXus files in order to save time when they start to reduce and visualize the data. A record file is generated along with processed scans to record the calibration information. During data reduction, scans that have been processed in pre-processing will be loaded automatically from corresponding MD files. - :ref:`IntegratePeaksMDHKL ` now has option to specify background shell instead of using default background determination. @@ -104,12 +123,19 @@ Single Crystal Diffraction - :ref:`StatisticsOfPeaksWorkspace ` now can accept long or short names for the point group and reflection condition. +Bug fixes +######### + - Fixed a bug in :ref:`IntegrateEllipsoids ` and :ref:`IntegrateEllipsoidsTwoStep ` that forced output to be weighted by the bin width. - Fixed a bug in :ref:`IntegrateEllipsoidsTwoStep ` where peaks with negative intensity values would be set to zero. Total Scattering ---------------- + +New features +############ + - A basic analysis for total scattering method ``create_total_scattering_pdf`` has been added to POLARIS. More information can be found on the POLARIS reference page. From c44319326d95155e1892b934887a6591078a4b9a Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Wed, 14 Mar 2018 11:04:31 +0000 Subject: [PATCH 187/364] Rearranged order to New/Improved/Fix format --- docs/source/release/v3.12.0/muon.rst | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index ba6d28c8c275..185ae1d95505 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -8,16 +8,14 @@ MuSR Changes .. figure:: ../../images/muon_release_3_12.png :class: screenshot :align: right - :width: 500 px - - -Bug Fixes ---------- -- :ref:`CalMuonDetectorPhases ` has had the sign of the phase shift changed, this produces data with a positive frequency spike as expected. -- Log values are no longer filtered by start time when loaded into muon analysis. + :figwidth: 50% Interface --------- + +Improvements +############ + - Added a cancel button to the MaxEnt widget in Frequency Domain Analysis. - Added checkboxes for "add all pairs" and "add all groups" to the settings tab. - The data plot style in the settings tab of Muon Analysis, only alters the plot range. It no longer crops the data. @@ -35,11 +33,24 @@ Interface - Muon analysis now handles the "auto background" gracefully in single and multiple fitting modes. - We have disabled some non functional graph right click context menu items or adding functions when in multi data fitting mode, in the Data Analysis tab of the Muon Analysis Interface. +Bug fixes +######### + +- Log values are no longer filtered by start time when loaded into muon analysis. Algorithms ---------- + +Improvements +############ + - :ref:`MuonProcess ` now has a flag to determine if to crop the input workspace (default is true). In the Muon Analysis interface this flag has been set to false. - :ref:`MuonMaxent ` calculates a single frequency spectrum from multiple time domain spectra. - :ref:`EstimateMuonAsymmetryFromCounts `: if the number of good frames is zero, then a value of 1 is assumed for the number of good frames. +Bug fixes +######### + +- :ref:`CalMuonDetectorPhases ` has had the sign of the phase shift changed, this produces data with a positive frequency spike as expected. + :ref:`Release 3.12.0 ` From b524c6ffa7abd844999566e06d80dd55b8404bcb Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Wed, 14 Mar 2018 11:13:37 +0000 Subject: [PATCH 188/364] Updated figure format to match other docs --- docs/source/release/v3.12.0/sans.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/source/release/v3.12.0/sans.rst b/docs/source/release/v3.12.0/sans.rst index 8939231f13f5..dfa291a97ea1 100644 --- a/docs/source/release/v3.12.0/sans.rst +++ b/docs/source/release/v3.12.0/sans.rst @@ -10,6 +10,9 @@ SANS Changes ILL SANS -------- +Improvements +############ + - Minor changes of the D33 instrument definition file, e.g. detector indexing. - New instrument definition file for the D22 instrument - New instrument definition file for the D11 instrument @@ -17,10 +20,10 @@ ILL SANS ISIS SANS --------- -.. image:: ../../images/ISIS_SANS_312.png +.. figure:: ../../images/ISIS_SANS_312.png :align: right :class: screenshot - :width: 800px + :figwidth: 50% New features ############ From e5015517d2f2388195d71416e94d7d4466125dd3 Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Wed, 14 Mar 2018 11:26:09 +0000 Subject: [PATCH 189/364] Reordered to match other docs --- .../release/v3.12.0/direct_inelastic.rst | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/docs/source/release/v3.12.0/direct_inelastic.rst b/docs/source/release/v3.12.0/direct_inelastic.rst index d6095c0aa2c8..69920aeb6c42 100644 --- a/docs/source/release/v3.12.0/direct_inelastic.rst +++ b/docs/source/release/v3.12.0/direct_inelastic.rst @@ -5,41 +5,56 @@ Direct Inelastic Changes .. contents:: Table of Contents :local: +Interfaces +---------- + New features ------------- +############ - The `MSlice `_ user interface can now be lauched from the MantidPlot Interfaces menu. -- The algorithms :ref:`algm-SofQWCentre`, :ref:`algm-SofQWPolygon` and :ref:`algm-SofQWNormalisedPolygon`, which rebin an inelastic workspace (has a `DeltaE` axis) from spectrum numbers (angle) to `MomentumTransfer` may now rebin the energy (`DeltaE`) axis as well as the :math:`|Q|` (`MomentumTransfer`) axes. -- :ref:`algm-SofQWNormalisedPolygon` now has uses a faster method for calculating the polygon intersections. -- The crystal field computation and fitting engine is now feature complete. It can now handle multi-site computation and simultaneous fitting of inelastic spectra and physical properties dataset. See the :ref:`Crystal Field Python Interface` help page for details, and ``_ for examples of use. - A new Python module :ref:`directtools ` includes utilities for plotting :math:`S(Q,W)` workspaces and cuts (line profiles) in constant :math:`Q` and :math:`E`. -Interfaces ----------- +Improvements +############ - PyChop has been updated with new look-up tables for the upgraded MAPS (with guide). Some minor bugs in PyChop have been fixed. - TOFTOF data reduction GUI has been improved. In the new version it has options to delete intermediate workspaces, to replace NaNs in S(Q,W), to create diffractograms and to save the reduced data in NXSPE and NeXus format. - :ref:`algm-MonitorEfficiencyCorUser` is not anymore restricted to TOFTOF instrument. -Instrument definitions ----------------------- +Crystal Field +------------- + +New features +############ + +- The crystal field computation and fitting engine is now feature complete. It can now handle multi-site computation and simultaneous fitting of inelastic spectra and physical properties dataset. See the :ref:`Crystal Field Python Interface` help page for details, and ``_ for examples of use. +- Multi-site calculations and fitting are now supported by the crystal field (Python commandline) interface. +- Calculation of dipole transition matrix elements has been added, together with the addition of a :math:`\chi_0` term in the :ref:`CrystalFieldSusceptibility ` function. -* The MAPS instrument definition file dating back to 2017-06-03 was changed. +Bug fixes +######### + +Several bugs in the Python and C++ code has been fixed - see the `github page `_ for details. Algorithms ---------- -- Fixed a bug in :ref:`algm-DirectILLApplySelfShielding` which could cause confusion among workspaces when the algorithm was run without both self shielding correction and empty container workspaces. +New features +############ + - New algorithm :ref:`HyspecScharpfCorrection ` that can be used to calculate spin incoherent scattering from polarized neutron data -- A `bug `_ in the handling of workspaces with fractional bin weights (generated by :ref:`algm-SofQWNormalisedPolygon`) has been fixed. +- The algorithms :ref:`algm-SofQWCentre`, :ref:`algm-SofQWPolygon` and :ref:`algm-SofQWNormalisedPolygon`, which rebin an inelastic workspace (has a `DeltaE` axis) from spectrum numbers (angle) to `MomentumTransfer` may now rebin the energy (`DeltaE`) axis as well as the :math:`|Q|` (`MomentumTransfer`) axes. +- :ref:`algm-SofQWNormalisedPolygon` now has uses a faster method for calculating the polygon intersections. -Crystal Field -------------- +Bug fixes +######### -Multi-site calculations and fitting are now supported by the crystal field (Python commandline) interface. +- Fixed a bug in :ref:`algm-DirectILLApplySelfShielding` which could cause confusion among workspaces when the algorithm was run without both self shielding correction and empty container workspaces. +- A `bug `_ in the handling of workspaces with fractional bin weights (generated by :ref:`algm-SofQWNormalisedPolygon`) has been fixed. -Calculation of dipole transition matrix elements has been added, together with the addition of a :math:`\chi_0` term in the :ref:`CrystalFieldSusceptibility ` function. +Instrument definitions +---------------------- -Several bugs in the Python and C++ code has been fixed - see the `github page `_ for details. +- The MAPS instrument definition file dating back to 2017-06-03 was changed. Features Removed ---------------- @@ -47,3 +62,5 @@ Features Removed * The Direct Convert To Energy graphical interface has been removed, it had not been used for several years, and was a source of bugs as well as using testing effort that is better directed elsewhere. `Full list of changes on GitHub `_ + +:ref:`Release 3.12.0 ` From cf596710c713d5a585eaebbfb4a46580ac57c5e3 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 11:28:30 +0000 Subject: [PATCH 190/364] Re #22048: Applied fixes to Framework/API. --- Framework/API/inc/MantidAPI/Algorithm.h | 4 +- .../API/inc/MantidAPI/AlgorithmFactory.h | 10 +-- .../API/inc/MantidAPI/AlgorithmHistory.h | 7 +- .../API/inc/MantidAPI/AlgorithmManager.h | 2 +- .../API/inc/MantidAPI/AlgorithmProperty.h | 2 +- Framework/API/inc/MantidAPI/AlgorithmProxy.h | 2 +- .../API/inc/MantidAPI/AnalysisDataService.h | 90 +++++++------------ .../API/inc/MantidAPI/ArchiveSearchFactory.h | 3 +- Framework/API/inc/MantidAPI/BoxController.h | 4 +- Framework/API/inc/MantidAPI/CatalogFactory.h | 2 +- Framework/API/inc/MantidAPI/CatalogManager.h | 2 +- Framework/API/inc/MantidAPI/CatalogSession.h | 4 +- Framework/API/inc/MantidAPI/Column.h | 4 +- Framework/API/inc/MantidAPI/ColumnFactory.h | 2 +- .../API/inc/MantidAPI/CompositeFunction.h | 4 +- .../API/inc/MantidAPI/ConstraintFactory.h | 3 +- Framework/API/inc/MantidAPI/CoordTransform.h | 4 +- .../API/inc/MantidAPI/CostFunctionFactory.h | 3 +- .../API/inc/MantidAPI/DetectorSearcher.h | 2 +- .../API/inc/MantidAPI/DomainCreatorFactory.h | 3 +- Framework/API/inc/MantidAPI/ExperimentInfo.h | 4 +- Framework/API/inc/MantidAPI/Expression.h | 4 +- Framework/API/inc/MantidAPI/FileFinder.h | 2 +- .../API/inc/MantidAPI/FileLoaderRegistry.h | 3 +- .../API/inc/MantidAPI/FrameworkManager.h | 2 +- .../API/inc/MantidAPI/FuncMinimizerFactory.h | 3 +- Framework/API/inc/MantidAPI/FunctionDomain.h | 2 +- .../API/inc/MantidAPI/FunctionDomain1D.h | 4 +- Framework/API/inc/MantidAPI/FunctionFactory.h | 8 +- .../MantidAPI/FunctionParameterDecorator.h | 3 +- Framework/API/inc/MantidAPI/FunctionValues.h | 2 +- Framework/API/inc/MantidAPI/GridDomain.h | 2 +- Framework/API/inc/MantidAPI/GridDomain1D.h | 2 +- Framework/API/inc/MantidAPI/IAlgorithm.h | 2 +- Framework/API/inc/MantidAPI/IAlgorithm_fwd.h | 8 +- Framework/API/inc/MantidAPI/IArchiveSearch.h | 2 +- .../API/inc/MantidAPI/IBackgroundFunction.h | 2 +- Framework/API/inc/MantidAPI/ICatalog.h | 4 +- Framework/API/inc/MantidAPI/ICostFunction.h | 2 +- Framework/API/inc/MantidAPI/IDomainCreator.h | 2 +- .../API/inc/MantidAPI/IEventWorkspace_fwd.h | 8 +- Framework/API/inc/MantidAPI/IFuncMinimizer.h | 2 +- Framework/API/inc/MantidAPI/IFunction.h | 4 +- Framework/API/inc/MantidAPI/IFunction1D.h | 2 +- .../API/inc/MantidAPI/ILatticeFunction.h | 2 +- Framework/API/inc/MantidAPI/ILiveListener.h | 2 +- .../API/inc/MantidAPI/IMDEventWorkspace_fwd.h | 8 +- .../API/inc/MantidAPI/IMDHistoWorkspace_fwd.h | 8 +- Framework/API/inc/MantidAPI/IMDWorkspace.h | 4 +- Framework/API/inc/MantidAPI/IMaskWorkspace.h | 4 +- Framework/API/inc/MantidAPI/IPawleyFunction.h | 2 +- Framework/API/inc/MantidAPI/IPeakFunction.h | 4 +- .../API/inc/MantidAPI/IPeaksWorkspace_fwd.h | 8 +- .../inc/MantidAPI/IPowderDiffPeakFunction.h | 2 +- .../API/inc/MantidAPI/IRemoteJobManager.h | 2 +- .../API/inc/MantidAPI/ISplittersWorkspace.h | 5 +- .../API/inc/MantidAPI/ITableWorkspace_fwd.h | 8 +- Framework/API/inc/MantidAPI/ITransformScale.h | 2 +- .../inc/MantidAPI/ImplicitFunctionFactory.h | 3 +- .../inc/MantidAPI/ImplicitFunctionParameter.h | 8 +- .../ImplicitFunctionParameterParser.h | 4 +- .../ImplicitFunctionParameterParserFactory.h | 4 +- .../inc/MantidAPI/ImplicitFunctionParser.h | 4 +- .../MantidAPI/ImplicitFunctionParserFactory.h | 3 +- .../API/inc/MantidAPI/InstrumentDataService.h | 3 +- .../API/inc/MantidAPI/LiveListenerFactory.h | 2 +- Framework/API/inc/MantidAPI/LogManager.h | 6 +- Framework/API/inc/MantidAPI/MatrixWorkspace.h | 12 +-- .../API/inc/MantidAPI/MatrixWorkspace_fwd.h | 8 +- Framework/API/inc/MantidAPI/MuParserUtils.h | 2 +- .../inc/MantidAPI/MultiPeriodGroupAlgorithm.h | 2 +- .../inc/MantidAPI/MultiPeriodGroupWorker.h | 2 +- .../inc/MantidAPI/MultipleExperimentInfos.h | 5 +- Framework/API/inc/MantidAPI/Projection.h | 2 +- .../inc/MantidAPI/RemoteJobManagerFactory.h | 3 +- .../API/inc/MantidAPI/ScriptRepository.h | 2 +- .../inc/MantidAPI/ScriptRepositoryFactory.h | 3 +- .../API/inc/MantidAPI/SingleValueParameter.h | 2 +- .../API/inc/MantidAPI/SpectraDetectorTypes.h | 6 +- .../inc/MantidAPI/SpectrumDetectorMapping.h | 2 +- .../API/inc/MantidAPI/TransformScaleFactory.h | 3 +- Framework/API/inc/MantidAPI/VectorParameter.h | 2 +- .../API/inc/MantidAPI/VectorParameterParser.h | 2 +- .../API/inc/MantidAPI/WorkspaceFactory.h | 2 +- .../API/inc/MantidAPI/WorkspaceGroup_fwd.h | 8 +- .../MantidAPI/WorkspaceNearestNeighbours.h | 9 +- Framework/API/inc/MantidAPI/Workspace_fwd.h | 8 +- Framework/API/src/Expression.cpp | 2 +- Framework/API/src/MuParserUtils.cpp | 2 +- Framework/API/src/MultiPeriodGroupWorker.cpp | 4 +- Framework/API/test/ADSValidatorTest.h | 2 +- Framework/API/test/AnalysisDataServiceTest.h | 2 +- Framework/API/test/FermiChopperModelTest.h | 3 +- .../API/test/IkedaCarpenterModeratorTest.h | 3 +- Framework/API/test/ScopedWorkspaceTest.h | 2 +- .../API/test/VectorParameterParserTest.h | 9 +- 96 files changed, 193 insertions(+), 255 deletions(-) diff --git a/Framework/API/inc/MantidAPI/Algorithm.h b/Framework/API/inc/MantidAPI/Algorithm.h index 5b2fe7cf4790..4b7c6a50b85a 100644 --- a/Framework/API/inc/MantidAPI/Algorithm.h +++ b/Framework/API/inc/MantidAPI/Algorithm.h @@ -301,7 +301,7 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, /// parent object to fill. void trackAlgorithmHistory(boost::shared_ptr parentHist); - typedef std::vector> WorkspaceVector; + using WorkspaceVector = std::vector >; void findWorkspaceProperties(WorkspaceVector &inputWorkspaces, WorkspaceVector &outputWorkspaces) const; @@ -502,7 +502,7 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, }; /// Typedef for a shared pointer to an Algorithm -typedef boost::shared_ptr Algorithm_sptr; +using Algorithm_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/AlgorithmFactory.h b/Framework/API/inc/MantidAPI/AlgorithmFactory.h index 9fb52f0d815a..f5b04a3a072e 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmFactory.h +++ b/Framework/API/inc/MantidAPI/AlgorithmFactory.h @@ -163,18 +163,16 @@ class MANTID_API_DLL AlgorithmFactoryImpl final void fillHiddenCategories(std::unordered_set *categorySet) const; /// A typedef for the map of algorithm versions - typedef std::map VersionMap; + using VersionMap = std::map; /// The map holding the registered class names and their highest versions VersionMap m_vmap; }; -typedef Mantid::Kernel::SingletonHolder AlgorithmFactory; +using AlgorithmFactory = Mantid::Kernel::SingletonHolder; /// Convenient typedef for an UpdateNotification -typedef Mantid::Kernel::DynamicFactory::UpdateNotification - AlgorithmFactoryUpdateNotification; -typedef const Poco::AutoPtr::UpdateNotification> &AlgorithmFactoryUpdateNotification_ptr; +using AlgorithmFactoryUpdateNotification = Mantid::Kernel::DynamicFactory::UpdateNotification; +using AlgorithmFactoryUpdateNotification_ptr = const Poco::AutoPtr::UpdateNotification> &; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/AlgorithmHistory.h b/Framework/API/inc/MantidAPI/AlgorithmHistory.h index 7e6fd4808187..b4275f302487 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmHistory.h +++ b/Framework/API/inc/MantidAPI/AlgorithmHistory.h @@ -34,10 +34,9 @@ template struct CompareHistory { } // typedefs for algorithm history pointers -typedef boost::shared_ptr AlgorithmHistory_sptr; -typedef boost::shared_ptr AlgorithmHistory_const_sptr; -typedef std::set> AlgorithmHistories; +using AlgorithmHistory_sptr = boost::shared_ptr; +using AlgorithmHistory_const_sptr = boost::shared_ptr; +using AlgorithmHistories = std::set >; /** @class AlgorithmHistory AlgorithmHistory.h API/MAntidAPI/AlgorithmHistory.h diff --git a/Framework/API/inc/MantidAPI/AlgorithmManager.h b/Framework/API/inc/MantidAPI/AlgorithmManager.h index cc777057963b..cc48017841dd 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmManager.h +++ b/Framework/API/inc/MantidAPI/AlgorithmManager.h @@ -102,7 +102,7 @@ class MANTID_API_DLL AlgorithmManagerImpl { mutable std::mutex m_managedMutex; }; -typedef Mantid::Kernel::SingletonHolder AlgorithmManager; +using AlgorithmManager = Mantid::Kernel::SingletonHolder; } // namespace API } // Namespace Mantid diff --git a/Framework/API/inc/MantidAPI/AlgorithmProperty.h b/Framework/API/inc/MantidAPI/AlgorithmProperty.h index facb554cb583..ed516f223bf9 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmProperty.h +++ b/Framework/API/inc/MantidAPI/AlgorithmProperty.h @@ -53,7 +53,7 @@ class DLLExport AlgorithmProperty : public Kernel::PropertyWithValue> { public: /// Typedef the held type - typedef boost::shared_ptr HeldType; + using HeldType = boost::shared_ptr; /// Constructor AlgorithmProperty(const std::string &propName, diff --git a/Framework/API/inc/MantidAPI/AlgorithmProxy.h b/Framework/API/inc/MantidAPI/AlgorithmProxy.h index a8a47f066b1d..6c2cac0c6ba5 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmProxy.h +++ b/Framework/API/inc/MantidAPI/AlgorithmProxy.h @@ -26,7 +26,7 @@ class Void; namespace Mantid { namespace API { class Algorithm; -typedef boost::shared_ptr Algorithm_sptr; +using Algorithm_sptr = boost::shared_ptr; /** diff --git a/Framework/API/inc/MantidAPI/AnalysisDataService.h b/Framework/API/inc/MantidAPI/AnalysisDataService.h index d46cd86ba7f8..b8249697f377 100644 --- a/Framework/API/inc/MantidAPI/AnalysisDataService.h +++ b/Framework/API/inc/MantidAPI/AnalysisDataService.h @@ -178,65 +178,37 @@ class DLLExport AnalysisDataServiceImpl final std::string m_illegalChars; }; -typedef Mantid::Kernel::SingletonHolder - AnalysisDataService; - -typedef Mantid::Kernel::DataService::AddNotification - WorkspaceAddNotification; -typedef const Poco::AutoPtr::AddNotification> &WorkspaceAddNotification_ptr; - -typedef Mantid::Kernel::DataService:: - BeforeReplaceNotification WorkspaceBeforeReplaceNotification; -typedef const Poco::AutoPtr::BeforeReplaceNotification> & - WorkspaceBeforeReplaceNotification_ptr; - -typedef Mantid::Kernel::DataService:: - AfterReplaceNotification WorkspaceAfterReplaceNotification; -typedef const Poco::AutoPtr::AfterReplaceNotification> & - WorkspaceAfterReplaceNotification_ptr; - -typedef Mantid::Kernel::DataService:: - PreDeleteNotification WorkspacePreDeleteNotification; -typedef const Poco::AutoPtr::PreDeleteNotification> & - WorkspacePreDeleteNotification_ptr; - -typedef Mantid::Kernel::DataService:: - PostDeleteNotification WorkspacePostDeleteNotification; -typedef const Poco::AutoPtr::PostDeleteNotification> & - WorkspacePostDeleteNotification_ptr; - -typedef Mantid::Kernel::DataService::ClearNotification - ClearADSNotification; -typedef const Poco::AutoPtr::ClearNotification> &ClearADSNotification_ptr; - -typedef Mantid::Kernel::DataService::RenameNotification - WorkspaceRenameNotification; -typedef const Poco::AutoPtr< - Mantid::Kernel::DataService::RenameNotification> & - WorkspaceRenameNotification_ptr; - -typedef AnalysisDataServiceImpl::GroupWorkspacesNotification - WorkspacesGroupedNotification; -typedef const Poco::AutoPtr< - AnalysisDataServiceImpl::GroupWorkspacesNotification> & - WorkspacesGroupedNotification_ptr; - -typedef AnalysisDataServiceImpl::UnGroupingWorkspaceNotification - WorkspaceUnGroupingNotification; -typedef const Poco::AutoPtr< - AnalysisDataServiceImpl::UnGroupingWorkspaceNotification> & - WorkspaceUnGroupingNotification_ptr; - -typedef AnalysisDataServiceImpl::GroupUpdatedNotification - GroupUpdatedNotification; -typedef const Poco::AutoPtr & - GroupUpdatedNotification_ptr; +using AnalysisDataService = Mantid::Kernel::SingletonHolder; + +using WorkspaceAddNotification = Mantid::Kernel::DataService::AddNotification; +using WorkspaceAddNotification_ptr = const Poco::AutoPtr::AddNotification> &; + +using WorkspaceBeforeReplaceNotification = Mantid::Kernel::DataService::BeforeReplaceNotification; +using WorkspaceBeforeReplaceNotification_ptr = const Poco::AutoPtr::BeforeReplaceNotification> &; + +using WorkspaceAfterReplaceNotification = Mantid::Kernel::DataService::AfterReplaceNotification; +using WorkspaceAfterReplaceNotification_ptr = const Poco::AutoPtr::AfterReplaceNotification> &; + +using WorkspacePreDeleteNotification = Mantid::Kernel::DataService::PreDeleteNotification; +using WorkspacePreDeleteNotification_ptr = const Poco::AutoPtr::PreDeleteNotification> &; + +using WorkspacePostDeleteNotification = Mantid::Kernel::DataService::PostDeleteNotification; +using WorkspacePostDeleteNotification_ptr = const Poco::AutoPtr::PostDeleteNotification> &; + +using ClearADSNotification = Mantid::Kernel::DataService::ClearNotification; +using ClearADSNotification_ptr = const Poco::AutoPtr::ClearNotification> &; + +using WorkspaceRenameNotification = Mantid::Kernel::DataService::RenameNotification; +using WorkspaceRenameNotification_ptr = const Poco::AutoPtr::RenameNotification> &; + +using WorkspacesGroupedNotification = AnalysisDataServiceImpl::GroupWorkspacesNotification; +using WorkspacesGroupedNotification_ptr = const Poco::AutoPtr &; + +using WorkspaceUnGroupingNotification = AnalysisDataServiceImpl::UnGroupingWorkspaceNotification; +using WorkspaceUnGroupingNotification_ptr = const Poco::AutoPtr &; + +using GroupUpdatedNotification = AnalysisDataServiceImpl::GroupUpdatedNotification; +using GroupUpdatedNotification_ptr = const Poco::AutoPtr &; } // Namespace API } // Namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h b/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h index a08b918d1fd2..b3b4d06a6ada 100644 --- a/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h +++ b/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h @@ -56,8 +56,7 @@ class MANTID_API_DLL ArchiveSearchFactoryImpl ~ArchiveSearchFactoryImpl() override = default; }; -typedef Mantid::Kernel::SingletonHolder - ArchiveSearchFactory; +using ArchiveSearchFactory = Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/BoxController.h b/Framework/API/inc/MantidAPI/BoxController.h index 4443f09bee81..33b4a976be39 100644 --- a/Framework/API/inc/MantidAPI/BoxController.h +++ b/Framework/API/inc/MantidAPI/BoxController.h @@ -505,10 +505,10 @@ class DLLExport BoxController { }; /// Shared ptr to BoxController -typedef boost::shared_ptr BoxController_sptr; +using BoxController_sptr = boost::shared_ptr; /// Shared ptr to a const BoxController -typedef boost::shared_ptr BoxController_const_sptr; +using BoxController_const_sptr = boost::shared_ptr; } // namespace API diff --git a/Framework/API/inc/MantidAPI/CatalogFactory.h b/Framework/API/inc/MantidAPI/CatalogFactory.h index b6133d3315da..2ddd4da9e058 100644 --- a/Framework/API/inc/MantidAPI/CatalogFactory.h +++ b/Framework/API/inc/MantidAPI/CatalogFactory.h @@ -78,7 +78,7 @@ class MANTID_API_DLL CatalogFactoryImpl /// The specialisation of the SingletonHolder class that holds the /// CatalogFactory -typedef Mantid::Kernel::SingletonHolder CatalogFactory; +using CatalogFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/CatalogManager.h b/Framework/API/inc/MantidAPI/CatalogManager.h index d7bc46ddcffe..5b03f204dda9 100644 --- a/Framework/API/inc/MantidAPI/CatalogManager.h +++ b/Framework/API/inc/MantidAPI/CatalogManager.h @@ -67,7 +67,7 @@ class MANTID_API_DLL CatalogManagerImpl { std::map m_activeCatalogs; }; -typedef Kernel::SingletonHolder CatalogManager; +using CatalogManager = Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/CatalogSession.h b/Framework/API/inc/MantidAPI/CatalogSession.h index 7de21287b532..cc40d7ee8d1b 100644 --- a/Framework/API/inc/MantidAPI/CatalogSession.h +++ b/Framework/API/inc/MantidAPI/CatalogSession.h @@ -49,8 +49,8 @@ class MANTID_API_DLL CatalogSession { std::string m_endpoint; }; -typedef boost::shared_ptr CatalogSession_sptr; -typedef boost::shared_ptr CatalogSession_const_sptr; +using CatalogSession_sptr = boost::shared_ptr; +using CatalogSession_const_sptr = boost::shared_ptr; } } diff --git a/Framework/API/inc/MantidAPI/Column.h b/Framework/API/inc/MantidAPI/Column.h index 151296175225..9f7feec96c3b 100644 --- a/Framework/API/inc/MantidAPI/Column.h +++ b/Framework/API/inc/MantidAPI/Column.h @@ -227,8 +227,8 @@ MANTID_API_DLL std::ostream &operator<<(std::ostream &, const API::Boolean &); /// Redaing a Boolean from an input stream MANTID_API_DLL std::istream &operator>>(std::istream &istr, API::Boolean &); -typedef boost::shared_ptr Column_sptr; -typedef boost::shared_ptr Column_const_sptr; +using Column_sptr = boost::shared_ptr; +using Column_const_sptr = boost::shared_ptr; } // namespace API } // Namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ColumnFactory.h b/Framework/API/inc/MantidAPI/ColumnFactory.h index df6a3d92e981..7b64c5f1d07a 100644 --- a/Framework/API/inc/MantidAPI/ColumnFactory.h +++ b/Framework/API/inc/MantidAPI/ColumnFactory.h @@ -63,7 +63,7 @@ class MANTID_API_DLL ColumnFactoryImpl : public Kernel::DynamicFactory { ~ColumnFactoryImpl() override = default; }; -typedef Mantid::Kernel::SingletonHolder ColumnFactory; +using ColumnFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/CompositeFunction.h b/Framework/API/inc/MantidAPI/CompositeFunction.h index aa036857ee7b..5b09515864fd 100644 --- a/Framework/API/inc/MantidAPI/CompositeFunction.h +++ b/Framework/API/inc/MantidAPI/CompositeFunction.h @@ -247,9 +247,9 @@ class MANTID_API_DLL CompositeFunction : public virtual IFunction { }; /// shared pointer to the composite function base class -typedef boost::shared_ptr CompositeFunction_sptr; +using CompositeFunction_sptr = boost::shared_ptr; /// shared pointer to the composite function base class (const version) -typedef boost::shared_ptr CompositeFunction_const_sptr; +using CompositeFunction_const_sptr = boost::shared_ptr; /** A Jacobian for individual functions */ diff --git a/Framework/API/inc/MantidAPI/ConstraintFactory.h b/Framework/API/inc/MantidAPI/ConstraintFactory.h index 560770e3bc4f..3a738805e232 100644 --- a/Framework/API/inc/MantidAPI/ConstraintFactory.h +++ b/Framework/API/inc/MantidAPI/ConstraintFactory.h @@ -72,8 +72,7 @@ class MANTID_API_DLL ConstraintFactoryImpl final ~ConstraintFactoryImpl() override = default; }; -typedef Mantid::Kernel::SingletonHolder - ConstraintFactory; +using ConstraintFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/CoordTransform.h b/Framework/API/inc/MantidAPI/CoordTransform.h index 44559433475f..653aff2d0c2c 100644 --- a/Framework/API/inc/MantidAPI/CoordTransform.h +++ b/Framework/API/inc/MantidAPI/CoordTransform.h @@ -59,10 +59,10 @@ class DLLExport CoordTransform { }; // Helper typedef for a shared pointer of this type. -typedef boost::shared_ptr CoordTransform_sptr; +using CoordTransform_sptr = boost::shared_ptr; // Helper typdef for a const shared pointer of this type. -typedef boost::shared_ptr CoordTransform_const_sptr; +using CoordTransform_const_sptr = boost::shared_ptr; } // namespace Mantid } // namespace API diff --git a/Framework/API/inc/MantidAPI/CostFunctionFactory.h b/Framework/API/inc/MantidAPI/CostFunctionFactory.h index 26d5b33867be..68b367c1fc26 100644 --- a/Framework/API/inc/MantidAPI/CostFunctionFactory.h +++ b/Framework/API/inc/MantidAPI/CostFunctionFactory.h @@ -63,8 +63,7 @@ class MANTID_API_DLL CostFunctionFactoryImpl CostFunctionFactoryImpl(); }; -typedef Mantid::Kernel::SingletonHolder - CostFunctionFactory; +using CostFunctionFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/DetectorSearcher.h b/Framework/API/inc/MantidAPI/DetectorSearcher.h index 72bbcadc39a0..869ce4b64f92 100644 --- a/Framework/API/inc/MantidAPI/DetectorSearcher.h +++ b/Framework/API/inc/MantidAPI/DetectorSearcher.h @@ -56,7 +56,7 @@ class MANTID_API_DLL DetectorSearcher { public: /// Search result type representing whether a detector was found and if so /// which detector index it was. - typedef std::tuple DetectorSearchResult; + using DetectorSearchResult = std::tuple; /// Create a new DetectorSearcher with the given instrument & detectors DetectorSearcher(Geometry::Instrument_const_sptr instrument, diff --git a/Framework/API/inc/MantidAPI/DomainCreatorFactory.h b/Framework/API/inc/MantidAPI/DomainCreatorFactory.h index 3759129207aa..90f667d54a6e 100644 --- a/Framework/API/inc/MantidAPI/DomainCreatorFactory.h +++ b/Framework/API/inc/MantidAPI/DomainCreatorFactory.h @@ -73,8 +73,7 @@ class MANTID_API_DLL DomainCreatorFactoryImpl using Kernel::DynamicFactory::createUnwrapped; }; -typedef Mantid::Kernel::SingletonHolder - DomainCreatorFactory; +using DomainCreatorFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Framework/API/inc/MantidAPI/ExperimentInfo.h index 04a28cd65fee..3da43e523a84 100644 --- a/Framework/API/inc/MantidAPI/ExperimentInfo.h +++ b/Framework/API/inc/MantidAPI/ExperimentInfo.h @@ -237,10 +237,10 @@ class MANTID_API_DLL ExperimentInfo { }; /// Shared pointer to ExperimentInfo -typedef boost::shared_ptr ExperimentInfo_sptr; +using ExperimentInfo_sptr = boost::shared_ptr; /// Shared pointer to const ExperimentInfo -typedef boost::shared_ptr ExperimentInfo_const_sptr; +using ExperimentInfo_const_sptr = boost::shared_ptr; } // namespace Mantid } // namespace API diff --git a/Framework/API/inc/MantidAPI/Expression.h b/Framework/API/inc/MantidAPI/Expression.h index 338db52c0c4b..5f37f9f8789b 100644 --- a/Framework/API/inc/MantidAPI/Expression.h +++ b/Framework/API/inc/MantidAPI/Expression.h @@ -94,7 +94,7 @@ class MANTID_API_DLL Expression { /// Returns the number of argumens size_t size() const { return m_terms.size(); } /// Const Iterator tpyedef - typedef std::vector::const_iterator iterator; + using iterator = std::vector::const_iterator; /// An iterator pointing to the start of the expressions iterator begin() const { return m_terms.begin(); } @@ -161,7 +161,7 @@ class MANTID_API_DLL Expression { size_t prec; ///< The precedence of the connecting operator. }; /// The container type - typedef std::vector Tokens; + using Tokens = std::vector; /// Get i-th token std::string GetToken(size_t i); /// Get the operator connecting i-th token diff --git a/Framework/API/inc/MantidAPI/FileFinder.h b/Framework/API/inc/MantidAPI/FileFinder.h index 0e0820eab3b3..e9d486f52f2a 100644 --- a/Framework/API/inc/MantidAPI/FileFinder.h +++ b/Framework/API/inc/MantidAPI/FileFinder.h @@ -97,7 +97,7 @@ class MANTID_API_DLL FileFinderImpl { int m_globOption; }; -typedef Mantid::Kernel::SingletonHolder FileFinder; +using FileFinder = Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/FileLoaderRegistry.h b/Framework/API/inc/MantidAPI/FileLoaderRegistry.h index a55583d29387..0b6e1484a39c 100644 --- a/Framework/API/inc/MantidAPI/FileLoaderRegistry.h +++ b/Framework/API/inc/MantidAPI/FileLoaderRegistry.h @@ -144,8 +144,7 @@ class MANTID_API_DLL FileLoaderRegistryImpl { }; /// Type for the actual singleton instance -typedef Mantid::Kernel::SingletonHolder - FileLoaderRegistry; +using FileLoaderRegistry = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FrameworkManager.h b/Framework/API/inc/MantidAPI/FrameworkManager.h index d6583bda63ac..204a9f621ae7 100644 --- a/Framework/API/inc/MantidAPI/FrameworkManager.h +++ b/Framework/API/inc/MantidAPI/FrameworkManager.h @@ -135,7 +135,7 @@ class MANTID_API_DLL FrameworkManagerImpl { #endif }; -typedef Mantid::Kernel::SingletonHolder FrameworkManager; +using FrameworkManager = Mantid::Kernel::SingletonHolder; } // namespace Kernel } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h b/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h index 7944b5e2f915..576287f6417d 100644 --- a/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h +++ b/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h @@ -61,8 +61,7 @@ class MANTID_API_DLL FuncMinimizerFactoryImpl FuncMinimizerFactoryImpl(); }; -typedef Mantid::Kernel::SingletonHolder - FuncMinimizerFactory; +using FuncMinimizerFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FunctionDomain.h b/Framework/API/inc/MantidAPI/FunctionDomain.h index cad64a787ac0..3be1f23a5427 100644 --- a/Framework/API/inc/MantidAPI/FunctionDomain.h +++ b/Framework/API/inc/MantidAPI/FunctionDomain.h @@ -56,7 +56,7 @@ class MANTID_API_DLL FunctionDomain //: public Kernel::PropertyManager }; /// typedef for a shared pointer -typedef boost::shared_ptr FunctionDomain_sptr; +using FunctionDomain_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FunctionDomain1D.h b/Framework/API/inc/MantidAPI/FunctionDomain1D.h index 42f2fd295b58..dabd2d5284da 100644 --- a/Framework/API/inc/MantidAPI/FunctionDomain1D.h +++ b/Framework/API/inc/MantidAPI/FunctionDomain1D.h @@ -173,9 +173,9 @@ class MANTID_API_DLL FunctionDomain1DHistogram : public FunctionDomain1D { }; /// typedef for a shared pointer to a FunctionDomain1D -typedef boost::shared_ptr FunctionDomain1D_sptr; +using FunctionDomain1D_sptr = boost::shared_ptr; /// typedef for a shared pointer to a const FunctionDomain1D -typedef boost::shared_ptr FunctionDomain1D_const_sptr; +using FunctionDomain1D_const_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FunctionFactory.h b/Framework/API/inc/MantidAPI/FunctionFactory.h index 36962ff28982..1e6aa7e0d414 100644 --- a/Framework/API/inc/MantidAPI/FunctionFactory.h +++ b/Framework/API/inc/MantidAPI/FunctionFactory.h @@ -142,14 +142,12 @@ const std::vector &FunctionFactoryImpl::getFunctionNames() const { return typeNames; } -typedef Mantid::Kernel::SingletonHolder FunctionFactory; +using FunctionFactory = Mantid::Kernel::SingletonHolder; /// Convenient typedef for an UpdateNotification -typedef FunctionFactoryImpl::UpdateNotification - FunctionFactoryUpdateNotification; +using FunctionFactoryUpdateNotification = FunctionFactoryImpl::UpdateNotification; /// Convenient typedef for an UpdateNotification AutoPtr -typedef const Poco::AutoPtr & - FunctionFactoryUpdateNotification_ptr; +using FunctionFactoryUpdateNotification_ptr = const Poco::AutoPtr &; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h b/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h index 0fc89d44739a..fce242505cc2 100644 --- a/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h +++ b/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h @@ -150,8 +150,7 @@ class MANTID_API_DLL FunctionParameterDecorator : virtual public IFunction { IFunction_sptr m_wrappedFunction; }; -typedef boost::shared_ptr - FunctionParameterDecorator_sptr; +using FunctionParameterDecorator_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FunctionValues.h b/Framework/API/inc/MantidAPI/FunctionValues.h index de5cbba73574..a4cd43e19643 100644 --- a/Framework/API/inc/MantidAPI/FunctionValues.h +++ b/Framework/API/inc/MantidAPI/FunctionValues.h @@ -121,7 +121,7 @@ class MANTID_API_DLL FunctionValues { }; /// typedef for a shared pointer -typedef boost::shared_ptr FunctionValues_sptr; +using FunctionValues_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/GridDomain.h b/Framework/API/inc/MantidAPI/GridDomain.h index 252221c1f403..4400f9398b81 100644 --- a/Framework/API/inc/MantidAPI/GridDomain.h +++ b/Framework/API/inc/MantidAPI/GridDomain.h @@ -58,7 +58,7 @@ class MANTID_API_DLL GridDomain : public API::FunctionDomain { }; // class IGridDomain /// typedef for a shared pointer -typedef boost::shared_ptr GridDomain_sptr; +using GridDomain_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/GridDomain1D.h b/Framework/API/inc/MantidAPI/GridDomain1D.h index aea1cebcb6dc..f96efdfa043e 100644 --- a/Framework/API/inc/MantidAPI/GridDomain1D.h +++ b/Framework/API/inc/MantidAPI/GridDomain1D.h @@ -58,7 +58,7 @@ class MANTID_API_DLL GridDomain1D : public API::GridDomain { }; // class IGridDomain /// typedef for a shared pointer -typedef boost::shared_ptr GridDomain1D_sptr; +using GridDomain1D_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IAlgorithm.h b/Framework/API/inc/MantidAPI/IAlgorithm.h index 8f239467dbed..376780fda330 100644 --- a/Framework/API/inc/MantidAPI/IAlgorithm.h +++ b/Framework/API/inc/MantidAPI/IAlgorithm.h @@ -21,7 +21,7 @@ namespace API { * we need a way of uniquely identifying managed algorithms. It can be * AlgorithmID. */ -typedef void *AlgorithmID; +using AlgorithmID = void *; /** IAlgorithm is the interface implemented by the Algorithm base class. diff --git a/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h b/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h index 84e31b1a6a1b..5a4db0b5e7a0 100644 --- a/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h +++ b/Framework/API/inc/MantidAPI/IAlgorithm_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::IAlgorithm class IAlgorithm; /// shared pointer to Mantid::API::IAlgorithm -typedef boost::shared_ptr IAlgorithm_sptr; +using IAlgorithm_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::IAlgorithm (const version) -typedef boost::shared_ptr IAlgorithm_const_sptr; +using IAlgorithm_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::IAlgorithm -typedef std::unique_ptr IAlgorithm_uptr; +using IAlgorithm_uptr = std::unique_ptr; /// unique pointer to Mantid::API::IAlgorithm (const version) -typedef std::unique_ptr IAlgorithm_const_uptr; +using IAlgorithm_const_uptr = std::unique_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IArchiveSearch.h b/Framework/API/inc/MantidAPI/IArchiveSearch.h index 293709de702f..62a7a773dd71 100644 --- a/Framework/API/inc/MantidAPI/IArchiveSearch.h +++ b/Framework/API/inc/MantidAPI/IArchiveSearch.h @@ -68,7 +68,7 @@ class MANTID_API_DLL IArchiveSearch { }; /// Typedef for a shared pointer to an IArchiveSearch -typedef boost::shared_ptr IArchiveSearch_sptr; +using IArchiveSearch_sptr = boost::shared_ptr; } } diff --git a/Framework/API/inc/MantidAPI/IBackgroundFunction.h b/Framework/API/inc/MantidAPI/IBackgroundFunction.h index 9e670692b8f5..0f80ccc8ea7b 100644 --- a/Framework/API/inc/MantidAPI/IBackgroundFunction.h +++ b/Framework/API/inc/MantidAPI/IBackgroundFunction.h @@ -44,7 +44,7 @@ class DLLExport IBackgroundFunction : public IFunctionWithLocation { const std::vector &Y) = 0; }; -typedef boost::shared_ptr IBackgroundFunction_sptr; +using IBackgroundFunction_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ICatalog.h b/Framework/API/inc/MantidAPI/ICatalog.h index d11a7ee7dbff..e5d68b799a02 100644 --- a/Framework/API/inc/MantidAPI/ICatalog.h +++ b/Framework/API/inc/MantidAPI/ICatalog.h @@ -71,8 +71,8 @@ class DLLExport ICatalog { virtual void keepAlive() = 0; }; -typedef boost::shared_ptr ICatalog_sptr; -typedef boost::shared_ptr ICatalog_const_sptr; +using ICatalog_sptr = boost::shared_ptr; +using ICatalog_const_sptr = boost::shared_ptr; } } diff --git a/Framework/API/inc/MantidAPI/ICostFunction.h b/Framework/API/inc/MantidAPI/ICostFunction.h index 1522861f9183..eab3633fb6e5 100644 --- a/Framework/API/inc/MantidAPI/ICostFunction.h +++ b/Framework/API/inc/MantidAPI/ICostFunction.h @@ -73,7 +73,7 @@ class MANTID_API_DLL ICostFunction { }; /// define a shared pointer to a cost function -typedef boost::shared_ptr ICostFunction_sptr; +using ICostFunction_sptr = boost::shared_ptr; /** * Macro for declaring a new type of cost functions to be used with the diff --git a/Framework/API/inc/MantidAPI/IDomainCreator.h b/Framework/API/inc/MantidAPI/IDomainCreator.h index 81968349aae3..9e127ad3dde2 100644 --- a/Framework/API/inc/MantidAPI/IDomainCreator.h +++ b/Framework/API/inc/MantidAPI/IDomainCreator.h @@ -147,7 +147,7 @@ class DLLExport IDomainCreator { }; /// Typedef for a shared pointer to IDomainCreator. -typedef boost::shared_ptr IDomainCreator_sptr; +using IDomainCreator_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h index fa4c3ced2657..20ccaa322baf 100644 --- a/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h +++ b/Framework/API/inc/MantidAPI/IEventWorkspace_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::IEventWorkspace class IEventWorkspace; /// shared pointer to Mantid::API::IEventWorkspace -typedef boost::shared_ptr IEventWorkspace_sptr; +using IEventWorkspace_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::IEventWorkspace (const version) -typedef boost::shared_ptr IEventWorkspace_const_sptr; +using IEventWorkspace_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::IEventWorkspace -typedef std::unique_ptr IEventWorkspace_uptr; +using IEventWorkspace_uptr = std::unique_ptr; /// unique pointer to Mantid::API::IEventWorkspace (const version) -typedef std::unique_ptr IEventWorkspace_const_uptr; +using IEventWorkspace_const_uptr = std::unique_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IFuncMinimizer.h b/Framework/API/inc/MantidAPI/IFuncMinimizer.h index 5ad967a5f66d..9f0ae001b6ed 100644 --- a/Framework/API/inc/MantidAPI/IFuncMinimizer.h +++ b/Framework/API/inc/MantidAPI/IFuncMinimizer.h @@ -74,7 +74,7 @@ class MANTID_API_DLL IFuncMinimizer : public Kernel::PropertyManager { std::string m_errorString; }; -typedef boost::shared_ptr IFuncMinimizer_sptr; +using IFuncMinimizer_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IFunction.h b/Framework/API/inc/MantidAPI/IFunction.h index 4c3a319b5cb6..3df44db33cea 100644 --- a/Framework/API/inc/MantidAPI/IFunction.h +++ b/Framework/API/inc/MantidAPI/IFunction.h @@ -625,9 +625,9 @@ class MANTID_API_DLL IFunction { }; /// shared pointer to the function base class -typedef boost::shared_ptr IFunction_sptr; +using IFunction_sptr = boost::shared_ptr; /// shared pointer to the function base class (const version) -typedef boost::shared_ptr IFunction_const_sptr; +using IFunction_const_sptr = boost::shared_ptr; /** * Classes inherited from FunctionHandler will handle the function. diff --git a/Framework/API/inc/MantidAPI/IFunction1D.h b/Framework/API/inc/MantidAPI/IFunction1D.h index e4fb9302f254..635dc267cf72 100644 --- a/Framework/API/inc/MantidAPI/IFunction1D.h +++ b/Framework/API/inc/MantidAPI/IFunction1D.h @@ -95,7 +95,7 @@ class MANTID_API_DLL IFunction1D : public virtual IFunction { friend class CurveFitting::Algorithms::Fit; }; -typedef boost::shared_ptr IFunction1D_sptr; +using IFunction1D_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ILatticeFunction.h b/Framework/API/inc/MantidAPI/ILatticeFunction.h index 8d6825ae82d7..e5091bb253d5 100644 --- a/Framework/API/inc/MantidAPI/ILatticeFunction.h +++ b/Framework/API/inc/MantidAPI/ILatticeFunction.h @@ -66,7 +66,7 @@ class MANTID_API_DLL ILatticeFunction : public FunctionParameterDecorator { virtual Geometry::UnitCell getUnitCell() const = 0; }; -typedef boost::shared_ptr ILatticeFunction_sptr; +using ILatticeFunction_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ILiveListener.h b/Framework/API/inc/MantidAPI/ILiveListener.h index 1d9d8be5da5d..2b35b37063d7 100644 --- a/Framework/API/inc/MantidAPI/ILiveListener.h +++ b/Framework/API/inc/MantidAPI/ILiveListener.h @@ -146,7 +146,7 @@ class MANTID_API_DLL ILiveListener : public Kernel::PropertyManager { }; /// Shared pointer to an ILiveListener -typedef boost::shared_ptr ILiveListener_sptr; +using ILiveListener_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h index c1c1e973e850..8caef8801b5f 100644 --- a/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h +++ b/Framework/API/inc/MantidAPI/IMDEventWorkspace_fwd.h @@ -35,13 +35,13 @@ namespace API { /// forward declare of Mantid::API::IMDEventWorkspace class IMDEventWorkspace; /// Shared pointer to Mantid::API::IMDEventWorkspace -typedef boost::shared_ptr IMDEventWorkspace_sptr; +using IMDEventWorkspace_sptr = boost::shared_ptr; /// Shared pointer to Mantid::API::IMDEventWorkspace (const version) -typedef boost::shared_ptr IMDEventWorkspace_const_sptr; +using IMDEventWorkspace_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::IMDEventWorkspace -typedef std::unique_ptr IMDEventWorkspace_uptr; +using IMDEventWorkspace_uptr = std::unique_ptr; /// unique pointer to Mantid::API::IMDEventWorkspace (const version) -typedef std::unique_ptr IMDEventWorkspace_const_uptr; +using IMDEventWorkspace_const_uptr = std::unique_ptr; } // namespace MDEvents } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h index 9ef1c56f82e4..24d1e97de610 100644 --- a/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h +++ b/Framework/API/inc/MantidAPI/IMDHistoWorkspace_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::IMDHistoWorkspace class IMDHistoWorkspace; /// shared pointer to Mantid::API::IMDHistoWorkspace -typedef boost::shared_ptr IMDHistoWorkspace_sptr; +using IMDHistoWorkspace_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::IMDHistoWorkspace (const version) -typedef boost::shared_ptr IMDHistoWorkspace_const_sptr; +using IMDHistoWorkspace_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::IMDHistoWorkspace -typedef std::unique_ptr IMDHistoWorkspace_uptr; +using IMDHistoWorkspace_uptr = std::unique_ptr; /// unique pointer to Mantid::API::IMDHistoWorkspace (const version) -typedef std::unique_ptr IMDHistoWorkspace_const_uptr; +using IMDHistoWorkspace_const_uptr = std::unique_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Framework/API/inc/MantidAPI/IMDWorkspace.h index d8970c6fdc7b..6c5441eda94a 100644 --- a/Framework/API/inc/MantidAPI/IMDWorkspace.h +++ b/Framework/API/inc/MantidAPI/IMDWorkspace.h @@ -189,9 +189,9 @@ class MANTID_API_DLL IMDWorkspace : public Workspace, public API::MDGeometry { }; /// Shared pointer to the IMDWorkspace base class -typedef boost::shared_ptr IMDWorkspace_sptr; +using IMDWorkspace_sptr = boost::shared_ptr; /// Shared pointer to the IMDWorkspace base class (const version) -typedef boost::shared_ptr IMDWorkspace_const_sptr; +using IMDWorkspace_const_sptr = boost::shared_ptr; } } #endif // MANTID_API_IMDWORKSPACE_H_ diff --git a/Framework/API/inc/MantidAPI/IMaskWorkspace.h b/Framework/API/inc/MantidAPI/IMaskWorkspace.h index cd51c350aaf3..afb86d897521 100644 --- a/Framework/API/inc/MantidAPI/IMaskWorkspace.h +++ b/Framework/API/inc/MantidAPI/IMaskWorkspace.h @@ -65,9 +65,9 @@ class DLLExport IMaskWorkspace { }; /// shared pointer to the matrix workspace base class -typedef boost::shared_ptr IMaskWorkspace_sptr; +using IMaskWorkspace_sptr = boost::shared_ptr; /// shared pointer to the matrix workspace base class (const version) -typedef boost::shared_ptr IMaskWorkspace_const_sptr; +using IMaskWorkspace_const_sptr = boost::shared_ptr; } } diff --git a/Framework/API/inc/MantidAPI/IPawleyFunction.h b/Framework/API/inc/MantidAPI/IPawleyFunction.h index fcba0af04d20..66a966769415 100644 --- a/Framework/API/inc/MantidAPI/IPawleyFunction.h +++ b/Framework/API/inc/MantidAPI/IPawleyFunction.h @@ -70,7 +70,7 @@ class MANTID_API_DLL IPawleyFunction : public FunctionParameterDecorator { virtual Kernel::V3D getPeakHKL(size_t i) const = 0; }; -typedef boost::shared_ptr IPawleyFunction_sptr; +using IPawleyFunction_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IPeakFunction.h b/Framework/API/inc/MantidAPI/IPeakFunction.h index 16984f0a6c18..c80531b5ed4c 100644 --- a/Framework/API/inc/MantidAPI/IPeakFunction.h +++ b/Framework/API/inc/MantidAPI/IPeakFunction.h @@ -103,8 +103,8 @@ class MANTID_API_DLL IPeakFunction : public IFunctionWithLocation { static constexpr double DEFAULT_SEARCH_LEVEL = 1e-5; }; -typedef boost::shared_ptr IPeakFunction_sptr; -typedef boost::shared_ptr IPeakFunction_const_sptr; +using IPeakFunction_sptr = boost::shared_ptr; +using IPeakFunction_const_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h b/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h index 1b62f578bc62..1c195e34f250 100644 --- a/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h +++ b/Framework/API/inc/MantidAPI/IPeaksWorkspace_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::IPeaksWorkspace class IPeaksWorkspace; /// shared pointer to Mantid::API::IPeaksWorkspace -typedef boost::shared_ptr IPeaksWorkspace_sptr; +using IPeaksWorkspace_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::IPeaksWorkspace (const version) -typedef boost::shared_ptr IPeaksWorkspace_const_sptr; +using IPeaksWorkspace_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::IPeaksWorkspace -typedef std::unique_ptr IPeaksWorkspace_uptr; +using IPeaksWorkspace_uptr = std::unique_ptr; /// unique pointer to Mantid::API::IPeaksWorkspace (const version) -typedef std::unique_ptr IPeaksWorkspace_const_uptr; +using IPeaksWorkspace_const_uptr = std::unique_ptr; } } #endif // MANTID_API_IPEAKWORKSPACE_FWD_H_ diff --git a/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h b/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h index c9c0cedae084..954ede14500a 100644 --- a/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h +++ b/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h @@ -159,7 +159,7 @@ class MANTID_API_DLL IPowderDiffPeakFunction size_t HEIGHTINDEX; }; -typedef boost::shared_ptr IPowderDiffPeakFunction_sptr; +using IPowderDiffPeakFunction_sptr = boost::shared_ptr; /// Integral for Gamma std::complex MANTID_API_DLL E1(std::complex z); diff --git a/Framework/API/inc/MantidAPI/IRemoteJobManager.h b/Framework/API/inc/MantidAPI/IRemoteJobManager.h index 3abb44a3d1c3..fd0a780c7ed1 100644 --- a/Framework/API/inc/MantidAPI/IRemoteJobManager.h +++ b/Framework/API/inc/MantidAPI/IRemoteJobManager.h @@ -290,7 +290,7 @@ class MANTID_API_DLL IRemoteJobManager { }; // shared pointer type for the IRemoteJobManager -typedef boost::shared_ptr IRemoteJobManager_sptr; +using IRemoteJobManager_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ISplittersWorkspace.h b/Framework/API/inc/MantidAPI/ISplittersWorkspace.h index 6d6d3562cd98..495bf221eaff 100644 --- a/Framework/API/inc/MantidAPI/ISplittersWorkspace.h +++ b/Framework/API/inc/MantidAPI/ISplittersWorkspace.h @@ -80,10 +80,9 @@ class MANTID_API_DLL ISplittersWorkspace { }; /// Typedef for a shared pointer to \c TableWorkspace -typedef boost::shared_ptr ISplittersWorkspace_sptr; +using ISplittersWorkspace_sptr = boost::shared_ptr; /// Typedef for a shared pointer to \c const \c TableWorkspace -typedef boost::shared_ptr - ISplittersWorkspace_const_sptr; +using ISplittersWorkspace_const_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h b/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h index 296fafc43735..57f6fe154c00 100644 --- a/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h +++ b/Framework/API/inc/MantidAPI/ITableWorkspace_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::ITableWorkspace class ITableWorkspace; /// shared pointer to Mantid::API::ITableWorkspace -typedef boost::shared_ptr ITableWorkspace_sptr; +using ITableWorkspace_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::ITableWorkspace (const version) -typedef boost::shared_ptr ITableWorkspace_const_sptr; +using ITableWorkspace_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::ITableWorkspace -typedef std::unique_ptr ITableWorkspace_uptr; +using ITableWorkspace_uptr = std::unique_ptr; /// unique pointer to Mantid::API::ITableWorkspace (const version) -typedef std::unique_ptr ITableWorkspace_const_uptr; +using ITableWorkspace_const_uptr = std::unique_ptr; } // namespace API } // Namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ITransformScale.h b/Framework/API/inc/MantidAPI/ITransformScale.h index 1f13b998a443..4469fbbca198 100644 --- a/Framework/API/inc/MantidAPI/ITransformScale.h +++ b/Framework/API/inc/MantidAPI/ITransformScale.h @@ -54,7 +54,7 @@ class MANTID_API_DLL ITransformScale { }; // class ITransformScale /// typedef for a shared pointer -typedef boost::shared_ptr ITransformScale_sptr; +using ITransformScale_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h index 10b8c9f04b4e..c8cedde1fe21 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h @@ -64,8 +64,7 @@ class MANTID_API_DLL ImplicitFunctionFactoryImpl ~ImplicitFunctionFactoryImpl() override = default; }; -typedef Mantid::Kernel::SingletonHolder - ImplicitFunctionFactory; +using ImplicitFunctionFactory = Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h index f8a5a4bcc7d2..e479bcfe1302 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameter.h @@ -103,7 +103,7 @@ template struct ElementTraits {}; /** ElementTraits for boolean element types. */ template <> struct ElementTraits { - typedef size_t ValueType; + using ValueType = size_t; static std::string formatCS(const ValueType &value) { return boost::str(boost::format("%u,") % value); } @@ -115,7 +115,7 @@ template <> struct ElementTraits { /** ElementTraits for boolean element types. */ template <> struct ElementTraits { - typedef bool ValueType; + using ValueType = bool; static std::string formatCS(const ValueType &value) { return boost::str(boost::format("%u,") % value); } @@ -127,7 +127,7 @@ template <> struct ElementTraits { /** ElementTraits for double element types. */ template <> struct ElementTraits { - typedef double ValueType; + using ValueType = double; static std::string formatCS(const ValueType &value) { return boost::str(boost::format("%.4f,") % value); } @@ -139,7 +139,7 @@ template <> struct ElementTraits { /** ElementTraits for float element types. */ template <> struct ElementTraits { - typedef double ValueType; + using ValueType = double; static std::string formatCS(const ValueType &value) { return boost::str(boost::format("%.4f,") % value); } diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h index d4a3ba774a61..234c5a8b1df5 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h @@ -81,9 +81,7 @@ class MANTID_API_DLL ImplicitFunctionParameterParser { public: /// Successor type. Unique shared pointer with stack scoped deletion /// semantics. - typedef boost::interprocess::unique_ptr< - ImplicitFunctionParameterParser, - DeleterPolicy> SuccessorType; + using SuccessorType = boost::interprocess::unique_ptr >; virtual ImplicitFunctionParameter * createParameter(Poco::XML::Element *parameterElement) = 0; diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h index 98578f7383c4..6196d30601da 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h @@ -62,9 +62,7 @@ class MANTID_API_DLL ImplicitFunctionParameterParserFactoryImpl ~ImplicitFunctionParameterParserFactoryImpl() override = default; }; -typedef Mantid::Kernel::SingletonHolder< - ImplicitFunctionParameterParserFactoryImpl> - ImplicitFunctionParameterParserFactory; +using ImplicitFunctionParameterParserFactory = Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h index b922fe1ae088..4d0cf8e78922 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h @@ -68,9 +68,7 @@ namespace API { class MANTID_API_DLL ImplicitFunctionParser { public: /// Successor type. Unique pointer with stack scoped deletion semantics. - typedef boost::interprocess::unique_ptr> - SuccessorType; + using SuccessorType = boost::interprocess::unique_ptr >; protected: ImplicitFunctionParameterParser::SuccessorType diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h index 0c6b2e00f187..47b11ede7636 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h @@ -66,8 +66,7 @@ class MANTID_API_DLL ImplicitFunctionParserFactoryImpl ~ImplicitFunctionParserFactoryImpl() override = default; }; -typedef Mantid::Kernel::SingletonHolder - ImplicitFunctionParserFactory; +using ImplicitFunctionParserFactory = Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/InstrumentDataService.h b/Framework/API/inc/MantidAPI/InstrumentDataService.h index 3ff486fb1cec..620e4ae2bd03 100644 --- a/Framework/API/inc/MantidAPI/InstrumentDataService.h +++ b/Framework/API/inc/MantidAPI/InstrumentDataService.h @@ -48,8 +48,7 @@ class MANTID_API_DLL InstrumentDataServiceImpl operator=(const InstrumentDataServiceImpl &) = delete; }; -typedef Mantid::Kernel::SingletonHolder - InstrumentDataService; +using InstrumentDataService = Mantid::Kernel::SingletonHolder; } // Namespace API } // Namespace Mantid diff --git a/Framework/API/inc/MantidAPI/LiveListenerFactory.h b/Framework/API/inc/MantidAPI/LiveListenerFactory.h index 5b241e996978..4346d7d15685 100644 --- a/Framework/API/inc/MantidAPI/LiveListenerFactory.h +++ b/Framework/API/inc/MantidAPI/LiveListenerFactory.h @@ -80,7 +80,7 @@ class MANTID_API_DLL LiveListenerFactoryImpl ILiveListener *createUnwrapped(const std::string &className) const override; }; -typedef Kernel::SingletonHolder LiveListenerFactory; +using LiveListenerFactory = Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/LogManager.h b/Framework/API/inc/MantidAPI/LogManager.h index 384de831562c..50552a46f487 100644 --- a/Framework/API/inc/MantidAPI/LogManager.h +++ b/Framework/API/inc/MantidAPI/LogManager.h @@ -22,7 +22,7 @@ namespace Kernel { template class Cache; template class TimeSeriesProperty; class SplittingInterval; -typedef std::vector TimeSplitterType; +using TimeSplitterType = std::vector; class PropertyManager; } @@ -209,9 +209,9 @@ class MANTID_API_DLL LogManager { m_singleValueCache; }; /// shared pointer to the logManager base class -typedef boost::shared_ptr LogManager_sptr; +using LogManager_sptr = boost::shared_ptr; /// shared pointer to the logManager base class (const version) -typedef boost::shared_ptr LogManager_const_sptr; +using LogManager_const_sptr = boost::shared_ptr; /** * Add a property of a specified type (Simply creates a Kernel::Property of that diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h index 089c24ecf53a..88a722256f8d 100644 --- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h +++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h @@ -32,11 +32,11 @@ class Axis; class SpectrumDetectorMapping; /// typedef for the image type -typedef std::vector> MantidImage; +using MantidImage = std::vector >; /// shared pointer to MantidImage -typedef boost::shared_ptr MantidImage_sptr; +using MantidImage_sptr = boost::shared_ptr; /// shared pointer to const MantidImage -typedef boost::shared_ptr MantidImage_const_sptr; +using MantidImage_const_sptr = boost::shared_ptr; //---------------------------------------------------------------------- /** Base MatrixWorkspace Abstract Class. @@ -449,7 +449,7 @@ class MANTID_API_DLL MatrixWorkspace : public IMDWorkspace, bool hasMaskedBins(const size_t &workspaceIndex) const; /// Masked bins for each spectrum are stored as a set of pairs containing - typedef std::map MaskList; + using MaskList = std::map; const MaskList &maskedBins(const size_t &workspaceIndex) const; void setMaskedBins(const size_t workspaceIndex, const MaskList &maskedBins); @@ -622,9 +622,9 @@ class MANTID_API_DLL MatrixWorkspace : public IMDWorkspace, }; /// shared pointer to the matrix workspace base class -typedef boost::shared_ptr MatrixWorkspace_sptr; +using MatrixWorkspace_sptr = boost::shared_ptr; /// shared pointer to the matrix workspace base class (const version) -typedef boost::shared_ptr MatrixWorkspace_const_sptr; +using MatrixWorkspace_const_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h b/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h index 1d764b9fd8bc..ce00dc64d50a 100644 --- a/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h +++ b/Framework/API/inc/MantidAPI/MatrixWorkspace_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::MatrixWorkspace class MatrixWorkspace; /// shared pointer to Mantid::API::MatrixWorkspace -typedef boost::shared_ptr MatrixWorkspace_sptr; +using MatrixWorkspace_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::MatrixWorkspace (const version) -typedef boost::shared_ptr MatrixWorkspace_const_sptr; +using MatrixWorkspace_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::MatrixWorkspace -typedef std::unique_ptr MatrixWorkspace_uptr; +using MatrixWorkspace_uptr = std::unique_ptr; /// unique pointer to Mantid::API::MatrixWorkspace (const version) -typedef std::unique_ptr MatrixWorkspace_const_uptr; +using MatrixWorkspace_const_uptr = std::unique_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/MuParserUtils.h b/Framework/API/inc/MantidAPI/MuParserUtils.h index dd075d7598bb..2476429184a6 100644 --- a/Framework/API/inc/MantidAPI/MuParserUtils.h +++ b/Framework/API/inc/MantidAPI/MuParserUtils.h @@ -42,7 +42,7 @@ extern const MANTID_API_DLL std::map MUPARSER_CONSTANTS; /// Add a set of default constants to a muParser. void MANTID_API_DLL addDefaultConstants(mu::Parser &parser); -typedef double (*oneVarFun)(double); // pointer to a function of one variable +using oneVarFun = double (*)(double); // pointer to a function of one variable extern const MANTID_API_DLL std::map MUPARSER_ONEVAR_FUNCTIONS; diff --git a/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h b/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h index e3fa26d30917..3ed263ca4781 100644 --- a/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h +++ b/Framework/API/inc/MantidAPI/MultiPeriodGroupAlgorithm.h @@ -52,7 +52,7 @@ class DLLExport MultiPeriodGroupAlgorithm : public Algorithm { virtual bool useCustomInputPropertyName() const { return false; } /// Convenience typdef for workspace names. - typedef MultiPeriodGroupWorker::VecWSGroupType VecWSGroupType; + using VecWSGroupType = MultiPeriodGroupWorker::VecWSGroupType; /// multi period group workspaces. VecWSGroupType m_multiPeriodGroups; /// Multiperiod group worker. diff --git a/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h b/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h index 89b2cad4803e..18a888dadbde 100644 --- a/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h +++ b/Framework/API/inc/MantidAPI/MultiPeriodGroupWorker.h @@ -46,7 +46,7 @@ namespace API { class DLLExport MultiPeriodGroupWorker { public: /// Convenience typdef for workspace names. - typedef std::vector VecWSGroupType; + using VecWSGroupType = std::vector; /// Constructor MultiPeriodGroupWorker() = default; /// Constructor diff --git a/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h b/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h index 053cb9f33fdd..e9f73c150481 100644 --- a/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h +++ b/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h @@ -63,9 +63,8 @@ class DLLExport MultipleExperimentInfos { std::vector m_expInfos; }; -typedef boost::shared_ptr MultipleExperimentInfos_sptr; -typedef boost::shared_ptr - MultipleExperimentInfos_const_sptr; +using MultipleExperimentInfos_sptr = boost::shared_ptr; +using MultipleExperimentInfos_const_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/Projection.h b/Framework/API/inc/MantidAPI/Projection.h index 08a600f47a8f..ecb29ba18490 100644 --- a/Framework/API/inc/MantidAPI/Projection.h +++ b/Framework/API/inc/MantidAPI/Projection.h @@ -82,7 +82,7 @@ class DLLExport Projection { ProjectionUnit m_units[3]; }; -typedef boost::shared_ptr Projection_sptr; +using Projection_sptr = boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h b/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h index 8fb819cd541c..664f5fef16ba 100644 --- a/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h +++ b/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h @@ -87,8 +87,7 @@ class MANTID_API_DLL RemoteJobManagerFactoryImpl }; // The factory is just a specialisation of SingletonHolder -typedef Mantid::Kernel::SingletonHolder - RemoteJobManagerFactory; +using RemoteJobManagerFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ScriptRepository.h b/Framework/API/inc/MantidAPI/ScriptRepository.h index e41d02288b99..36169d635cf3 100644 --- a/Framework/API/inc/MantidAPI/ScriptRepository.h +++ b/Framework/API/inc/MantidAPI/ScriptRepository.h @@ -605,7 +605,7 @@ class MANTID_API_DLL ScriptRepository { }; /// shared pointer to the function base class -typedef boost::shared_ptr ScriptRepository_sptr; +using ScriptRepository_sptr = boost::shared_ptr; } } diff --git a/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h b/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h index f5bad9732e70..bc984a7e30af 100644 --- a/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h +++ b/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h @@ -67,8 +67,7 @@ class MANTID_API_DLL ScriptRepositoryFactoryImpl ~ScriptRepositoryFactoryImpl() override = default; }; -typedef Mantid::Kernel::SingletonHolder - ScriptRepositoryFactory; +using ScriptRepositoryFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/SingleValueParameter.h b/Framework/API/inc/MantidAPI/SingleValueParameter.h index a8bfdf43a801..b7a024450eb8 100644 --- a/Framework/API/inc/MantidAPI/SingleValueParameter.h +++ b/Framework/API/inc/MantidAPI/SingleValueParameter.h @@ -43,7 +43,7 @@ Code Documentation is available at: template class DLLExport SingleValueParameter : public ImplicitFunctionParameter { public: - typedef ValType ValueType; + using ValueType = ValType; SingleValueParameter(ValType value); SingleValueParameter(); SingleValueParameter(const SingleValueParameter &other); diff --git a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h index c21655a2b8c8..5eb6843ccead 100644 --- a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h +++ b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h @@ -10,11 +10,11 @@ namespace Mantid { /// Map with key = spectrum number, value = workspace index -typedef std::unordered_map spec2index_map; +using spec2index_map = std::unordered_map; /// Map with key = detector ID, value = workspace index -typedef std::unordered_map detid2index_map; +using detid2index_map = std::unordered_map; /// Map single det ID of group to its members -typedef std::unordered_map> det2group_map; +using det2group_map = std::unordered_map >; } #endif // MANTID_API_SPECTRADETECTORMAP_TYPES diff --git a/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h b/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h index 8e08dd2de442..5b37bd0df31f 100644 --- a/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h +++ b/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h @@ -50,7 +50,7 @@ class MatrixWorkspace; Code Documentation is available at: */ class MANTID_API_DLL SpectrumDetectorMapping { - typedef std::unordered_map> sdmap; + using sdmap = std::unordered_map >; public: explicit SpectrumDetectorMapping(const MatrixWorkspace *const workspace, diff --git a/Framework/API/inc/MantidAPI/TransformScaleFactory.h b/Framework/API/inc/MantidAPI/TransformScaleFactory.h index 1ec1309ad16e..d34f27cf8819 100644 --- a/Framework/API/inc/MantidAPI/TransformScaleFactory.h +++ b/Framework/API/inc/MantidAPI/TransformScaleFactory.h @@ -66,8 +66,7 @@ class MANTID_API_DLL TransformScaleFactoryImpl // Do not use default methods }; -typedef Mantid::Kernel::SingletonHolder - TransformScaleFactory; +using TransformScaleFactory = Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/VectorParameter.h b/Framework/API/inc/MantidAPI/VectorParameter.h index 0c64e01b19ed..df8419c2fa91 100644 --- a/Framework/API/inc/MantidAPI/VectorParameter.h +++ b/Framework/API/inc/MantidAPI/VectorParameter.h @@ -39,7 +39,7 @@ Code Documentation is available at: template class DLLExport VectorParameter : public ImplicitFunctionParameter { public: - typedef ElemType ValueType; + using ValueType = ElemType; VectorParameter(); VectorParameter(size_t size); VectorParameter(const VectorParameter &other); diff --git a/Framework/API/inc/MantidAPI/VectorParameterParser.h b/Framework/API/inc/MantidAPI/VectorParameterParser.h index e9908fbb58fe..b84dd9635f68 100644 --- a/Framework/API/inc/MantidAPI/VectorParameterParser.h +++ b/Framework/API/inc/MantidAPI/VectorParameterParser.h @@ -80,7 +80,7 @@ VectorParameterParser::parseVectorParameter( boost::split(strs, sValue, boost::is_any_of(",")); auto product = new VectorValueParameterType(strs.size()); - typedef typename VectorValueParameterType::ValueType ValType; + using ValType = typename VectorValueParameterType::ValueType; ValType value = 0; for (size_t i = 0; i < strs.size(); i++) { diff --git a/Framework/API/inc/MantidAPI/WorkspaceFactory.h b/Framework/API/inc/MantidAPI/WorkspaceFactory.h index 87f72dbc64bf..beab0e3ab6c9 100644 --- a/Framework/API/inc/MantidAPI/WorkspaceFactory.h +++ b/Framework/API/inc/MantidAPI/WorkspaceFactory.h @@ -95,7 +95,7 @@ class MANTID_API_DLL WorkspaceFactoryImpl using Kernel::DynamicFactory::create; }; -typedef Mantid::Kernel::SingletonHolder WorkspaceFactory; +using WorkspaceFactory = Mantid::Kernel::SingletonHolder; template boost::shared_ptr createWorkspace(InitArgs... args) { diff --git a/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h b/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h index d63dfcb8f033..ee809df0f0a4 100644 --- a/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h +++ b/Framework/API/inc/MantidAPI/WorkspaceGroup_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::WorkspaceGroup class WorkspaceGroup; /// shared pointer to Mantid::API::WorkspaceGroup -typedef boost::shared_ptr WorkspaceGroup_sptr; +using WorkspaceGroup_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::WorkspaceGroup, pointer to const version -typedef boost::shared_ptr WorkspaceGroup_const_sptr; +using WorkspaceGroup_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::WorkspaceGroup -typedef std::unique_ptr WorkspaceGroup_uptr; +using WorkspaceGroup_uptr = std::unique_ptr; /// unique pointer to Mantid::API::WorkspaceGroup (const version) -typedef std::unique_ptr WorkspaceGroup_const_uptr; +using WorkspaceGroup_const_uptr = std::unique_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h b/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h index 218c656f7482..1ca57f0e2426 100644 --- a/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h +++ b/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h @@ -82,14 +82,11 @@ class MANTID_API_DLL WorkspaceNearestNeighbours { const std::vector m_spectrumNumbers; /// typedef for Graph object used to hold the calculated information - typedef boost::adjacency_list< - boost::vecS, boost::vecS, boost::directedS, - boost::property, - boost::property> Graph; + using Graph = boost::adjacency_list, boost::property >; /// Vertex descriptor object for Graph - typedef boost::graph_traits::vertex_descriptor Vertex; + using Vertex = boost::graph_traits::vertex_descriptor; /// map object of int to Graph Vertex descriptor - typedef std::unordered_map MapIV; + using MapIV = std::unordered_map; /// Construct the graph based on the given number of neighbours and the /// current instument and spectra-detector mapping diff --git a/Framework/API/inc/MantidAPI/Workspace_fwd.h b/Framework/API/inc/MantidAPI/Workspace_fwd.h index 20f00cde3a83..58d576fdb386 100644 --- a/Framework/API/inc/MantidAPI/Workspace_fwd.h +++ b/Framework/API/inc/MantidAPI/Workspace_fwd.h @@ -34,13 +34,13 @@ namespace API { /// forward declare of Mantid::API::Workspace class Workspace; /// shared pointer to Mantid::API::Workspace -typedef boost::shared_ptr Workspace_sptr; +using Workspace_sptr = boost::shared_ptr; /// shared pointer to Mantid::API::Workspace (const version) -typedef boost::shared_ptr Workspace_const_sptr; +using Workspace_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::API::Workspace -typedef std::unique_ptr Workspace_uptr; +using Workspace_uptr = std::unique_ptr; /// unique pointer to Mantid::API::Workspace (const version) -typedef std::unique_ptr Workspace_const_uptr; +using Workspace_const_uptr = std::unique_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/src/Expression.cpp b/Framework/API/src/Expression.cpp index d2c5c4d74548..2dd513000347 100644 --- a/Framework/API/src/Expression.cpp +++ b/Framework/API/src/Expression.cpp @@ -9,7 +9,7 @@ namespace Mantid { namespace API { -typedef Mantid::Kernel::StringTokenizer tokenizer; +using tokenizer = Mantid::Kernel::StringTokenizer; const std::string DEFAULT_OPS_STR[] = {";", ",", "=", "== != > < <= >=", "&& || ^^", "+ -", "* /", "^"}; diff --git a/Framework/API/src/MuParserUtils.cpp b/Framework/API/src/MuParserUtils.cpp index 7ff53a0c45b4..c5daee5fee1d 100644 --- a/Framework/API/src/MuParserUtils.cpp +++ b/Framework/API/src/MuParserUtils.cpp @@ -41,7 +41,7 @@ void DLLExport addDefaultConstants(mu::Parser &parser) { } } -typedef double (*oneVarFun)(double); // pointer to a function of one variable +using oneVarFun = double (*)(double); // pointer to a function of one variable const std::map MUPARSER_ONEVAR_FUNCTIONS = { {"erf", gsl_sf_erf}, {"erfc", gsl_sf_erfc}}; diff --git a/Framework/API/src/MultiPeriodGroupWorker.cpp b/Framework/API/src/MultiPeriodGroupWorker.cpp index 8d862fefd411..2c54d9839ff8 100644 --- a/Framework/API/src/MultiPeriodGroupWorker.cpp +++ b/Framework/API/src/MultiPeriodGroupWorker.cpp @@ -58,7 +58,7 @@ MultiPeriodGroupWorker::findMultiPeriodGroups( // This is currenly the case for algorithms that take an array of strings as // an input where each entry is the name of a workspace. if (this->useCustomWorkspaceProperty()) { - typedef std::vector WorkspaceNameType; + using WorkspaceNameType = std::vector; // Perform a check that the input property is the correct type. Property *inputProperty = @@ -85,7 +85,7 @@ MultiPeriodGroupWorker::findMultiPeriodGroups( vecWorkspaceGroups); } } else { - typedef std::vector> WorkspaceVector; + using WorkspaceVector = std::vector >; WorkspaceVector inWorkspaces; WorkspaceVector outWorkspaces; sourceAlg->findWorkspaceProperties(inWorkspaces, outWorkspaces); diff --git a/Framework/API/test/ADSValidatorTest.h b/Framework/API/test/ADSValidatorTest.h index 7431b0855267..7302df6f7191 100644 --- a/Framework/API/test/ADSValidatorTest.h +++ b/Framework/API/test/ADSValidatorTest.h @@ -28,7 +28,7 @@ class MockWorkspace : public Workspace { }; } -typedef std::vector StringVector; +using StringVector = std::vector; class ADSValidatorTest : public CxxTest::TestSuite { public: diff --git a/Framework/API/test/AnalysisDataServiceTest.h b/Framework/API/test/AnalysisDataServiceTest.h index 6e1aabdb7018..8b8c0c2240a2 100644 --- a/Framework/API/test/AnalysisDataServiceTest.h +++ b/Framework/API/test/AnalysisDataServiceTest.h @@ -23,7 +23,7 @@ class MockWorkspace : public Workspace { throw std::runtime_error("Cloning of MockWorkspace is not implemented."); } }; -typedef boost::shared_ptr MockWorkspace_sptr; +using MockWorkspace_sptr = boost::shared_ptr; } class AnalysisDataServiceTest : public CxxTest::TestSuite { diff --git a/Framework/API/test/FermiChopperModelTest.h b/Framework/API/test/FermiChopperModelTest.h index 527a4c39080c..90abb283ad80 100644 --- a/Framework/API/test/FermiChopperModelTest.h +++ b/Framework/API/test/FermiChopperModelTest.h @@ -9,8 +9,7 @@ #include class FermiChopperModelTest : public CxxTest::TestSuite { - typedef boost::shared_ptr - FermiChopperModel_sptr; + using FermiChopperModel_sptr = boost::shared_ptr; public: void test_Default_Object_Throws_When_Computing_Pulse_Variance() { diff --git a/Framework/API/test/IkedaCarpenterModeratorTest.h b/Framework/API/test/IkedaCarpenterModeratorTest.h index 96c73f6ce2e5..c79e24b8254d 100644 --- a/Framework/API/test/IkedaCarpenterModeratorTest.h +++ b/Framework/API/test/IkedaCarpenterModeratorTest.h @@ -8,8 +8,7 @@ class IkedaCarpenterModeratorTest : public CxxTest::TestSuite { public: - typedef boost::shared_ptr - IkedaCarpenterModerator_sptr; + using IkedaCarpenterModerator_sptr = boost::shared_ptr; void test_Default_Object_Returns_Zero_Mean_Time() { Mantid::API::IkedaCarpenterModerator ikmod; diff --git a/Framework/API/test/ScopedWorkspaceTest.h b/Framework/API/test/ScopedWorkspaceTest.h index 52cf923ba5bc..4ccccfd06a49 100644 --- a/Framework/API/test/ScopedWorkspaceTest.h +++ b/Framework/API/test/ScopedWorkspaceTest.h @@ -26,7 +26,7 @@ class MockWorkspace : public Workspace { throw std::runtime_error("Cloning of MockWorkspace is not implemented."); } }; -typedef boost::shared_ptr MockWorkspace_sptr; +using MockWorkspace_sptr = boost::shared_ptr; class ScopedWorkspaceTest : public CxxTest::TestSuite { public: diff --git a/Framework/API/test/VectorParameterParserTest.h b/Framework/API/test/VectorParameterParserTest.h index 00fd6f9a94c0..55c717ae0442 100644 --- a/Framework/API/test/VectorParameterParserTest.h +++ b/Framework/API/test/VectorParameterParserTest.h @@ -15,15 +15,13 @@ class VectorParameterParserTest : public CxxTest::TestSuite { DECLARE_VECTOR_PARAMETER(ConcreteVectorDblParam, double) // Declare a concrete vector parameter parser for testing. - typedef VectorParameterParser - ConcreteVectorDblParamParser; + using ConcreteVectorDblParamParser = VectorParameterParser; // Declare a concrete type with elements of type bool for testing. DECLARE_VECTOR_PARAMETER(ConcreteVectorBoolParam, bool) // Declare a concrete vector parameter parser for testing. - typedef VectorParameterParser - ConcreteVectorBoolParamParser; + using ConcreteVectorBoolParamParser = VectorParameterParser; public: void testParsesParmeterValue1D() { @@ -97,8 +95,7 @@ class VectorParameterParserTest : public CxxTest::TestSuite { void testChainOfResponsibility() { // Local declare of a successor parser with a successor parameter. - typedef VectorParameterParser - ConcreteSuccessorVectorParameterParser; + using ConcreteSuccessorVectorParameterParser = VectorParameterParser; DOMParser pParser; std::string xmlToParse = "SucessorVectorParameter Date: Wed, 14 Mar 2018 11:44:08 +0000 Subject: [PATCH 191/364] Changed format to match other documents Figures made to 50% width Algorithms placed after interfaces --- .../release/v3.12.0/indirect_inelastic.rst | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/docs/source/release/v3.12.0/indirect_inelastic.rst b/docs/source/release/v3.12.0/indirect_inelastic.rst index 7d6c680e7ecc..8435f27760cf 100644 --- a/docs/source/release/v3.12.0/indirect_inelastic.rst +++ b/docs/source/release/v3.12.0/indirect_inelastic.rst @@ -5,28 +5,6 @@ Indirect Inelastic Changes .. contents:: Table of Contents :local: -Algorithms ----------- - -New -### - -- :ref:`algm-ExtractQENSMembers` can be used to extract the fit members from any QENS fit. -- New algorithm :ref:`BASISDiffraction ` to determine the orientation of crystal samples for the BASIS beamline. - - -Improved -######## - -- :ref:`algm-ApplyPaalmanPingsCorrection` now accepts a corrections group containing only an :math:`A_{s,s}` and an :math:`A_{c,c}` workspace (produced by :ref:`algm-CalculateMonteCarloAbsorption`). -- :ref:`BASISReduction ` now permits the user to exclude a contiguous time segment from the reduction process. -- :ref:`BASISReduction ` option *noMonitorNorm* changed to *MonitorNorm*. -- :ref:`BASISReduction ` now contains log entry *asString* storing the options passed to to the algorithm. -- :ref:`IqtFitSequential ` and :ref:`IqtFitMultiple ` can now both extract members from the fit (when the ExtractMembers property is set to True). -- Loading the sample log files into a workspace can be disabled when calling the :ref:`LoadVesuvio ` algorithm by supplying *LoadLogFiles=False* to the algorithm call -- :ref:`OSIRISDiffractionReduction ` no longer has options *DetectDRange* and *DRange*, D-Ranges are now always calculated automatically within the algorithm. - - Vesuvio ------- @@ -54,8 +32,8 @@ New .. figure:: ../../images/Indirect_ConvFit_3_12_release.png :class: screenshot - :align: center - :width: 500 px + :align: right + :figwidth: 50% The new design of the Indirect Fitting tabs, shown here within ConvFit (the IndirectFitPropertyBrowser is seen on the left and can be ejected into a separate window). @@ -104,10 +82,10 @@ Improved - The Apply Absorption Correction interface no longer requires workspaces to be in units of wavelength (this is done within :ref:`algm-ApplyPaalmanPingsCorrection`). - Calculate Monte Carlo Absorption interface has been restructured in a more appropriate format, as outlined in the following image: -.. image:: ../../images/AbsorbtionCorrectionsGui312.png - :align: center +.. figure:: ../../images/AbsorbtionCorrectionsGui312.png + :align: right :class: screenshot - :width: 800px + :figwidth: 50% - Result plotting in the Calculate Monte Carlo Absorption interface is now the same as that in Apply Absorption Correction; ability to select whether to plot result in Wavelength, Angle or Both. @@ -126,4 +104,25 @@ Improved ######## - Performance of Abins rebinning routines significantly improved (a factor of 10-20 times for data size of 4000). +Algorithms +---------- + +New +### + +- :ref:`algm-ExtractQENSMembers` can be used to extract the fit members from any QENS fit. +- New algorithm :ref:`BASISDiffraction ` to determine the orientation of crystal samples for the BASIS beamline. + + +Improved +######## + +- :ref:`algm-ApplyPaalmanPingsCorrection` now accepts a corrections group containing only an :math:`A_{s,s}` and an :math:`A_{c,c}` workspace (produced by :ref:`algm-CalculateMonteCarloAbsorption`). +- :ref:`BASISReduction ` now permits the user to exclude a contiguous time segment from the reduction process. +- :ref:`BASISReduction ` option *noMonitorNorm* changed to *MonitorNorm*. +- :ref:`BASISReduction ` now contains log entry *asString* storing the options passed to to the algorithm. +- :ref:`IqtFitSequential ` and :ref:`IqtFitMultiple ` can now both extract members from the fit (when the ExtractMembers property is set to True). +- Loading the sample log files into a workspace can be disabled when calling the :ref:`LoadVesuvio ` algorithm by supplying *LoadLogFiles=False* to the algorithm call +- :ref:`OSIRISDiffractionReduction ` no longer has options *DetectDRange* and *DRange*, D-Ranges are now always calculated automatically within the algorithm. + :ref:`Release 3.12.0 ` From a640a89abc70ac01214c7d09b135d31c27b21892 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 12:08:12 +0000 Subject: [PATCH 192/364] Re #22048: Applied fixes to Framework/Crystal. --- .../inc/MantidCrystal/ClusterRegister.h | 2 +- .../MantidCrystal/ConnectedComponentLabeling.h | 18 ++++++++---------- .../Crystal/inc/MantidCrystal/FilterPeaks.h | 2 +- .../Crystal/inc/MantidCrystal/FindSXPeaks.h | 2 +- Framework/Crystal/inc/MantidCrystal/ICluster.h | 2 +- .../inc/MantidCrystal/PeaksIntersection.h | 4 ++-- .../inc/MantidCrystal/SetSpecialCoordinates.h | 3 +-- Framework/Crystal/src/Cluster.cpp | 2 +- Framework/Crystal/src/ClusterRegister.cpp | 4 ++-- .../Crystal/src/ConnectedComponentLabeling.cpp | 4 ++-- Framework/Crystal/src/FindClusterFaces.cpp | 8 ++++---- Framework/Crystal/src/FindSXPeaksHelper.cpp | 6 +++--- Framework/Crystal/src/PeaksOnSurface.cpp | 2 +- Framework/Crystal/src/SaveHKL.cpp | 4 ++-- Framework/Crystal/src/SaveIsawPeaks.cpp | 4 ++-- Framework/Crystal/test/CentroidPeaksTest.h | 3 +-- .../Crystal/test/ClusterIntegrationBaseTest.h | 6 ++---- Framework/Crystal/test/DisjointElementTest.h | 4 ++-- .../Crystal/test/IntegratePeaksHybridTest.h | 3 +-- Framework/Crystal/test/NormaliseVanadiumTest.h | 3 +-- Framework/Crystal/test/PeakIntegrationTest.h | 3 +-- Framework/Crystal/test/PeaksInRegionTest.h | 3 +-- 22 files changed, 41 insertions(+), 51 deletions(-) diff --git a/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h b/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h index 713b976808e8..02b43fa2671b 100644 --- a/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h +++ b/Framework/Crystal/inc/MantidCrystal/ClusterRegister.h @@ -40,7 +40,7 @@ class ImplClusterRegister; class DLLExport ClusterRegister { public: /// Cluster map - typedef std::map> MapCluster; + using MapCluster = std::map >; /// Constructor ClusterRegister(); diff --git a/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h b/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h index c097b1ea5bee..1016d219d97b 100644 --- a/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h +++ b/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h @@ -22,16 +22,14 @@ class ICluster; * Namespace containing useful typedefs */ namespace ConnectedComponentMappingTypes { -typedef boost::tuple SignalErrorSQPair; -typedef std::map LabelIdIntensityMap; -typedef std::map PositionToLabelIdMap; -typedef std::vector VecIndexes; -typedef std::vector VecElements; -typedef std::unordered_set SetIds; -typedef std::map> - ClusterMap; -typedef boost::tuple - ClusterTuple; +using SignalErrorSQPair = boost::tuple; +using LabelIdIntensityMap = std::map; +using PositionToLabelIdMap = std::map; +using VecIndexes = std::vector; +using VecElements = std::vector; +using SetIds = std::unordered_set; +using ClusterMap = std::map >; +using ClusterTuple = boost::tuple; } class BackgroundStrategy; diff --git a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h index 94af78ff45a5..bcae377a112d 100644 --- a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h @@ -46,7 +46,7 @@ class DLLExport FilterPeaks : public API::Algorithm { private: /// Typedef for the function to get the variable we're filtering against - typedef std::function FilterFunction; + using FilterFunction = std::function; /// Override for algorithm init void init() override; diff --git a/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h b/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h index afc833946a84..f3f4a60123a2 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h @@ -14,7 +14,7 @@ namespace Mantid { namespace Crystal { -typedef std::vector peakvector; +using peakvector = std::vector; /** Search detector space for single crystal peaks. diff --git a/Framework/Crystal/inc/MantidCrystal/ICluster.h b/Framework/Crystal/inc/MantidCrystal/ICluster.h index 0b07650f4cc3..745c9401cb80 100644 --- a/Framework/Crystal/inc/MantidCrystal/ICluster.h +++ b/Framework/Crystal/inc/MantidCrystal/ICluster.h @@ -39,7 +39,7 @@ namespace Crystal { */ class DLLExport ICluster { public: - typedef boost::tuple ClusterIntegratedValues; + using ClusterIntegratedValues = boost::tuple; /// integrate the cluster virtual ClusterIntegratedValues integrate( diff --git a/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h b/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h index 90e23d87c02a..ecd5100e933c 100644 --- a/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h +++ b/Framework/Crystal/inc/MantidCrystal/PeaksIntersection.h @@ -8,8 +8,8 @@ namespace Mantid { namespace Crystal { -typedef std::vector VecV3D; -typedef std::vector VecVecV3D; +using VecV3D = std::vector; +using VecVecV3D = std::vector; /** PeaksIntersection : Abstract base algorithm class for algorithms that identify peaks interacting with one or more surfaces diff --git a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h index 61ce8d748da1..45b3862f4841 100644 --- a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h +++ b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h @@ -54,8 +54,7 @@ class DLLExport SetSpecialCoordinates : public API::Algorithm { void init() override; void exec() override; std::vector m_specialCoordinatesNames; - typedef std::map - SpecialCoordinatesNameMap; + using SpecialCoordinatesNameMap = std::map; SpecialCoordinatesNameMap m_specialCoordinatesMap; static const std::string QLabOption(); static const std::string QSampleOption(); diff --git a/Framework/Crystal/src/Cluster.cpp b/Framework/Crystal/src/Cluster.cpp index b64629b5be1a..629f7b3df24d 100644 --- a/Framework/Crystal/src/Cluster.cpp +++ b/Framework/Crystal/src/Cluster.cpp @@ -2,7 +2,7 @@ #include "MantidAPI/IMDHistoWorkspace.h" namespace { -typedef std::vector VecElements; +using VecElements = std::vector; } namespace Mantid { diff --git a/Framework/Crystal/src/ClusterRegister.cpp b/Framework/Crystal/src/ClusterRegister.cpp index a82c609abea3..b4a01e25981d 100644 --- a/Framework/Crystal/src/ClusterRegister.cpp +++ b/Framework/Crystal/src/ClusterRegister.cpp @@ -26,13 +26,13 @@ class ImplClusterRegister { ClusterRegister::MapCluster m_unique; /// Type for identifying label groups - typedef std::list> GroupType; + using GroupType = std::list >; /// Groups of labels to maintain GroupType m_groups; /// Type for identifying labels already seen - typedef std::unordered_set LabelHash; + using LabelHash = std::unordered_set; /// Hash of labels merged LabelHash m_labelHash; diff --git a/Framework/Crystal/src/ConnectedComponentLabeling.cpp b/Framework/Crystal/src/ConnectedComponentLabeling.cpp index 920b852f6ff4..327fb52ffb01 100644 --- a/Framework/Crystal/src/ConnectedComponentLabeling.cpp +++ b/Framework/Crystal/src/ConnectedComponentLabeling.cpp @@ -95,8 +95,8 @@ bool does_contain_key(const Container &container, return container.find(value) != container.end(); } -typedef boost::tuple EdgeIndexPair; -typedef std::vector VecEdgeIndexPair; +using EdgeIndexPair = boost::tuple; +using VecEdgeIndexPair = std::vector; /** * Free function performing the CCL implementation over a range defined by the diff --git a/Framework/Crystal/src/FindClusterFaces.cpp b/Framework/Crystal/src/FindClusterFaces.cpp index 1341c61e917a..c5bad728f4d7 100644 --- a/Framework/Crystal/src/FindClusterFaces.cpp +++ b/Framework/Crystal/src/FindClusterFaces.cpp @@ -20,9 +20,9 @@ using namespace Mantid::API; namespace { using namespace Mantid::Crystal; // Map of label ids to peak index in peaks workspace. -typedef std::map LabelMap; +using LabelMap = std::map; // Optional set of labels -typedef boost::optional OptionalLabelPeakIndexMap; +using OptionalLabelPeakIndexMap = boost::optional; /** * Create an optional label set for filtering. @@ -72,8 +72,8 @@ struct ClusterFace { double radius; }; -typedef std::deque ClusterFaces; -typedef std::vector VecClusterFaces; +using ClusterFaces = std::deque; +using VecClusterFaces = std::vector; /** Check that the data point signal value is an integer. diff --git a/Framework/Crystal/src/FindSXPeaksHelper.cpp b/Framework/Crystal/src/FindSXPeaksHelper.cpp index cd9e4099fb0f..2346859acb55 100644 --- a/Framework/Crystal/src/FindSXPeaksHelper.cpp +++ b/Framework/Crystal/src/FindSXPeaksHelper.cpp @@ -587,9 +587,9 @@ FindMaxReduceStrategy::reduce(const std::vector &peaks, } // Define some graph elements -typedef adjacency_list PeakGraph; -typedef boost::graph_traits::vertex_descriptor Vertex; -typedef boost::graph_traits::edge_descriptor Edge; +using PeakGraph = adjacency_list; +using Vertex = boost::graph_traits::vertex_descriptor; +using Edge = boost::graph_traits::edge_descriptor; std::vector> FindMaxReduceStrategy::getPeakGroups( const std::vector &peakList, diff --git a/Framework/Crystal/src/PeaksOnSurface.cpp b/Framework/Crystal/src/PeaksOnSurface.cpp index 232a9f159d71..0a3953f32f07 100644 --- a/Framework/Crystal/src/PeaksOnSurface.cpp +++ b/Framework/Crystal/src/PeaksOnSurface.cpp @@ -3,7 +3,7 @@ #include "MantidKernel/MandatoryValidator.h" using namespace Mantid::Kernel; -typedef std::vector VecDouble; +using VecDouble = std::vector; namespace Mantid { namespace Crystal { diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp index 95f66ca36c1a..cde781e8e878 100644 --- a/Framework/Crystal/src/SaveHKL.cpp +++ b/Framework/Crystal/src/SaveHKL.cpp @@ -185,8 +185,8 @@ void SaveHKL::exec() { std::string bankPart = "?"; // We must sort the peaks first by run, then bank #, and save the list of // workspace indices of it - typedef std::map> bankMap_t; - typedef std::map runMap_t; + using bankMap_t = std::map >; + using runMap_t = std::map; std::set uniqueBanks; std::set uniqueRuns; runMap_t runMap; diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp index fd1d3c1b0023..31118b8ccfe4 100644 --- a/Framework/Crystal/src/SaveIsawPeaks.cpp +++ b/Framework/Crystal/src/SaveIsawPeaks.cpp @@ -62,8 +62,8 @@ void SaveIsawPeaks::exec() { // We must sort the peaks first by run, then bank #, and save the list of // workspace indices of it - typedef std::map> bankMap_t; - typedef std::map runMap_t; + using bankMap_t = std::map >; + using runMap_t = std::map; std::set> uniqueBanks; if (!inst) throw std::runtime_error( diff --git a/Framework/Crystal/test/CentroidPeaksTest.h b/Framework/Crystal/test/CentroidPeaksTest.h index 42a0d5a74db7..625063d288e9 100644 --- a/Framework/Crystal/test/CentroidPeaksTest.h +++ b/Framework/Crystal/test/CentroidPeaksTest.h @@ -56,8 +56,7 @@ class CentroidPeaksTest : public CxxTest::TestSuite { rng.seed((unsigned int)(randomSeed)); size_t nd = 1; // Make a random generator for each dimensions - typedef boost::variate_generator> gen_t; + using gen_t = boost::variate_generator >; gen_t *gens[1]; for (size_t d = 0; d < nd; ++d) { double min = -1.; diff --git a/Framework/Crystal/test/ClusterIntegrationBaseTest.h b/Framework/Crystal/test/ClusterIntegrationBaseTest.h index d9b6e454ef05..c20f7e367737 100644 --- a/Framework/Crystal/test/ClusterIntegrationBaseTest.h +++ b/Framework/Crystal/test/ClusterIntegrationBaseTest.h @@ -28,11 +28,9 @@ using namespace Mantid::DataObjects; using namespace Mantid::Geometry; // Helper typedef -typedef boost::tuple - MDHistoPeaksWSTuple; +using MDHistoPeaksWSTuple = boost::tuple; // Helper typedef -typedef boost::tuple - MDEventPeaksWSTuple; +using MDEventPeaksWSTuple = boost::tuple; class ClusterIntegrationBaseTest { protected: diff --git a/Framework/Crystal/test/DisjointElementTest.h b/Framework/Crystal/test/DisjointElementTest.h index d3ffecfe6588..f5601020bed7 100644 --- a/Framework/Crystal/test/DisjointElementTest.h +++ b/Framework/Crystal/test/DisjointElementTest.h @@ -139,8 +139,8 @@ class DisjointElementTest : public CxxTest::TestSuite { } void test_complex() { - typedef boost::shared_ptr DisjointElement_sptr; - typedef std::vector VecDisjointElement; + using DisjointElement_sptr = boost::shared_ptr; + using VecDisjointElement = std::vector; // Create elements from 0-9 VecDisjointElement vecElements; diff --git a/Framework/Crystal/test/IntegratePeaksHybridTest.h b/Framework/Crystal/test/IntegratePeaksHybridTest.h index 693cf2f8bbce..fbc9229779d2 100644 --- a/Framework/Crystal/test/IntegratePeaksHybridTest.h +++ b/Framework/Crystal/test/IntegratePeaksHybridTest.h @@ -19,8 +19,7 @@ using namespace Mantid::DataObjects; using namespace Mantid::API; namespace { -typedef boost::tuple - AlgorithmOutputs; +using AlgorithmOutputs = boost::tuple; // Execute the clustering integration algorithm AlgorithmOutputs execute_integration(const MDEventPeaksWSTuple &inputWorkspaces, diff --git a/Framework/Crystal/test/NormaliseVanadiumTest.h b/Framework/Crystal/test/NormaliseVanadiumTest.h index d7f353631291..0128e08c3c05 100644 --- a/Framework/Crystal/test/NormaliseVanadiumTest.h +++ b/Framework/Crystal/test/NormaliseVanadiumTest.h @@ -52,8 +52,7 @@ EventWorkspace_sptr createDiffractionEventWorkspace(int numEvents) { rng.seed((unsigned int)(randomSeed)); size_t nd = 1; // Make a random generator for each dimensions - typedef boost::variate_generator> gen_t; + using gen_t = boost::variate_generator >; gen_t *gens[1]; for (size_t d = 0; d < nd; ++d) { double min = -1.; diff --git a/Framework/Crystal/test/PeakIntegrationTest.h b/Framework/Crystal/test/PeakIntegrationTest.h index b20f054df2ae..75ae43d49fa9 100644 --- a/Framework/Crystal/test/PeakIntegrationTest.h +++ b/Framework/Crystal/test/PeakIntegrationTest.h @@ -59,8 +59,7 @@ class PeakIntegrationTest : public CxxTest::TestSuite { rng.seed((unsigned int)(randomSeed)); size_t nd = 1; // Make a random generator for each dimensions - typedef boost::variate_generator> gen_t; + using gen_t = boost::variate_generator >; gen_t *gens[1]; for (size_t d = 0; d < nd; ++d) { double min = -1.; diff --git a/Framework/Crystal/test/PeaksInRegionTest.h b/Framework/Crystal/test/PeaksInRegionTest.h index d22b5b8bdb04..5bb6f1af4a61 100644 --- a/Framework/Crystal/test/PeaksInRegionTest.h +++ b/Framework/Crystal/test/PeaksInRegionTest.h @@ -19,8 +19,7 @@ Functional Tests class PeaksInRegionTest : public CxxTest::TestSuite { private: - typedef boost::tuple> - PeakWorkspaceWithExtents; + using PeakWorkspaceWithExtents = boost::tuple >; /** Helper function. Creates a peaksworkspace with a single peak From 957d4315838df12356e65b1147a4e4000a9ca230 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 12:11:06 +0000 Subject: [PATCH 193/364] Re #22048: Applied fixes to Framework/CurveFitting. --- .../inc/MantidCurveFitting/Algorithms/LeBailFunction.h | 2 +- .../MantidCurveFitting/AugmentedLagrangianOptimizer.h | 2 +- .../inc/MantidCurveFitting/ComplexVector.h | 2 +- .../CurveFitting/inc/MantidCurveFitting/FortranDefs.h | 10 +++++----- .../inc/MantidCurveFitting/FortranMatrix.h | 5 ++--- .../Functions/BackToBackExponential.h | 2 +- .../MantidCurveFitting/Functions/BackgroundFunction.h | 2 +- .../inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h | 2 +- .../inc/MantidCurveFitting/Functions/ChebfunBase.h | 4 ++-- .../inc/MantidCurveFitting/Functions/Chebyshev.h | 2 +- .../inc/MantidCurveFitting/Functions/CubicSpline.h | 4 ++-- .../MantidCurveFitting/Functions/FullprofPolynomial.h | 2 +- .../inc/MantidCurveFitting/Functions/PawleyFunction.h | 4 ++-- .../inc/MantidCurveFitting/Functions/Polynomial.h | 2 +- .../MantidCurveFitting/Functions/ReflectivityMulf.h | 2 +- .../Functions/ThermalNeutronBk2BkExpAlpha.h | 3 +-- .../Functions/ThermalNeutronBk2BkExpBeta.h | 3 +-- .../Functions/ThermalNeutronBk2BkExpConvPVoigt.h | 3 +-- .../Functions/ThermalNeutronBk2BkExpSigma.h | 3 +-- .../Functions/ThermalNeutronDtoTOFFunction.h | 3 +-- .../inc/MantidCurveFitting/LatticeFunction.h | 2 +- .../inc/MantidCurveFitting/MSVesuvioHelpers.h | 4 ++-- .../CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp | 2 +- Framework/CurveFitting/src/MSVesuvioHelpers.cpp | 6 ++---- Framework/CurveFitting/src/ParameterEstimator.cpp | 2 +- .../test/Algorithms/PlotPeakByLogValueTest.h | 4 ++-- Framework/CurveFitting/test/CompositeFunctionTest.h | 4 ++-- Framework/CurveFitting/test/FortranMatrixTest.h | 4 ++-- Framework/CurveFitting/test/FortranVectorTest.h | 6 +++--- .../CurveFitting/test/Functions/ProductFunctionTest.h | 2 +- .../CurveFitting/test/Functions/ProductLinearExpTest.h | 6 +++--- .../test/Functions/ProductQuadraticExpTest.h | 6 +++--- 32 files changed, 51 insertions(+), 59 deletions(-) diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h index b628c897ef3d..9b20a8740fa4 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFunction.h @@ -218,7 +218,7 @@ class DLLExport LeBailFunction { */ }; -typedef boost::shared_ptr LeBailFunction_sptr; +using LeBailFunction_sptr = boost::shared_ptr; } // namespace Algorithms } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h index 8156c721362c..7e47a5920dae 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h @@ -97,7 +97,7 @@ class MANTID_CURVEFITTING_DLL AugmentedLagrangianOptimizer { public: /// Function type - typedef boost::function ObjFunction; + using ObjFunction = boost::function; public: /** diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h b/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h index 5c5f0038e87f..bb65a1d668f1 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/ComplexVector.h @@ -11,7 +11,7 @@ namespace Mantid { namespace CurveFitting { -typedef std::complex ComplexType; +using ComplexType = std::complex; class ComplexVector; /// Struct helping converting complex values diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h b/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h index 9a43f7124b2c..94c7fdcdc091 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h @@ -9,11 +9,11 @@ namespace Mantid { namespace CurveFitting { -typedef FortranMatrix ComplexFortranMatrix; -typedef FortranMatrix DoubleFortranMatrix; -typedef FortranVector ComplexFortranVector; -typedef FortranVector DoubleFortranVector; -typedef FortranVector> IntFortranVector; +using ComplexFortranMatrix = FortranMatrix; +using DoubleFortranMatrix = FortranMatrix; +using ComplexFortranVector = FortranVector; +using DoubleFortranVector = FortranVector; +using IntFortranVector = FortranVector >; } // namespace CurveFitting } // namespace Mantid diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h b/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h index 457fb6c159ae..dc1632592b4b 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h @@ -41,9 +41,8 @@ template class FortranMatrix : public MatrixClass { int m_base2; /// Typedef the types returned by the base class's operators []. They aren't /// necessarily the same as the stored type (double or complex). - typedef decltype( - std::declval().operator()(0, 0)) ElementConstType; - typedef decltype(std::declval().operator()(0, 0)) ElementRefType; + using ElementConstType = decltype(std::declval().operator()(0, 0)); + using ElementRefType = decltype(std::declval().operator()(0, 0)); public: /// Constructor diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h index 93136d0d369f..e4421c2258c7 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackToBackExponential.h @@ -86,7 +86,7 @@ class DLLExport BackToBackExponential : public API::IPeakFunction { double expWidth() const; }; -typedef boost::shared_ptr BackToBackExponential_sptr; +using BackToBackExponential_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h index bc496f54e98c..06903f773359 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/BackgroundFunction.h @@ -73,7 +73,7 @@ class DLLExport BackgroundFunction : public API::IBackgroundFunction { const std::string category() const override { return "Background"; } }; -typedef boost::shared_ptr BackgroundFunction_sptr; +using BackgroundFunction_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h index 21f5007bd7a6..1c980f42ed0c 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Bk2BkExpConvPV.h @@ -90,7 +90,7 @@ class DLLExport Bk2BkExpConvPV : virtual public API::IPeakFunction, // typedef boost::shared_ptr TableWorkspace_sptr; -typedef boost::shared_ptr Bk2BkExpConvPV_sptr; +using Bk2BkExpConvPV_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h index 84ebfa834424..3e72fdd3c93f 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h @@ -18,7 +18,7 @@ namespace CurveFitting { namespace Functions { /// Type of the approximated function -typedef std::function ChebfunFunctionType; +using ChebfunFunctionType = std::function; /** @@ -200,7 +200,7 @@ class MANTID_CURVEFITTING_DLL ChebfunBase { static const size_t g_maxNumberPoints; }; -typedef boost::shared_ptr ChebfunBase_sptr; +using ChebfunBase_sptr = boost::shared_ptr; /// Find best fit with highest possible tolerance (to be used with noisy data). template diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h index cfa5cadbed39..54e696d7fe17 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Chebyshev.h @@ -70,7 +70,7 @@ class DLLExport Chebyshev : public BackgroundFunction { mutable std::valarray m_b; }; -typedef boost::shared_ptr Chebyshev_sptr; +using Chebyshev_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h index 4de520dcc24f..614a8948a086 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/CubicSpline.h @@ -115,8 +115,8 @@ class DLLExport CubicSpline : public BackgroundFunction { double splineEval(const double x) const; }; -typedef boost::shared_ptr CubicSpline_sptr; -typedef const boost::shared_ptr CubicSpline_const_sptr; +using CubicSpline_sptr = boost::shared_ptr; +using CubicSpline_const_sptr = const boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h index 8b8171dd0804..8b86ec74119f 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FullprofPolynomial.h @@ -73,7 +73,7 @@ class DLLExport FullprofPolynomial : public BackgroundFunction { double m_bkpos; }; -typedef boost::shared_ptr FullprofPolynomial_sptr; +using FullprofPolynomial_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h index ee758caabba0..ad40dd3f765b 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/PawleyFunction.h @@ -74,7 +74,7 @@ class DLLExport PawleyParameterFunction : virtual public API::IFunction, std::string m_profileFunctionCenterParameterName; }; -typedef boost::shared_ptr PawleyParameterFunction_sptr; +using PawleyParameterFunction_sptr = boost::shared_ptr; /** @class PawleyFunction @@ -171,7 +171,7 @@ class DLLExport PawleyFunction : public API::IPawleyFunction { int m_peakRadius; }; -typedef boost::shared_ptr PawleyFunction_sptr; +using PawleyFunction_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h index 283ea6d945d6..3e57798ce676 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Polynomial.h @@ -68,7 +68,7 @@ class DLLExport Polynomial : public BackgroundFunction { int m_n; }; -typedef boost::shared_ptr Polynomial_sptr; +using Polynomial_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h index cb80ea23af52..8b3cec7e9714 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ReflectivityMulf.h @@ -58,7 +58,7 @@ class DLLExport ReflectivityMulf : public API::IFunction1D, int m_nlayer, m_nlayer_old; }; -typedef boost::shared_ptr ReflectivityMulf_sptr; +using ReflectivityMulf_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h index 8991009a3f26..074f4edff0b4 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h @@ -66,8 +66,7 @@ class DLLExport ThermalNeutronBk2BkExpAlpha : virtual public API::IFunction1D, double alph1t) const; }; -typedef boost::shared_ptr - ThermalNeutronBk2BkExpAlpha_sptr; +using ThermalNeutronBk2BkExpAlpha_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h index b9d10abd0283..42219eb66712 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h @@ -66,8 +66,7 @@ class DLLExport ThermalNeutronBk2BkExpBeta : virtual public API::IFunction1D, double beta1t) const; }; -typedef boost::shared_ptr - ThermalNeutronBk2BkExpBeta_sptr; +using ThermalNeutronBk2BkExpBeta_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h index 7b268015a320..f9f8740e0c9e 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h @@ -179,8 +179,7 @@ class DLLExport ThermalNeutronBk2BkExpConvPVoigt }; /// Shared pointer to ThermalNeutronBk2BkExpConvPVoigt peak/function -typedef boost::shared_ptr - ThermalNeutronBk2BkExpConvPVoigt_sptr; +using ThermalNeutronBk2BkExpConvPVoigt_sptr = boost::shared_ptr; //--- Public inline function -------------------------------------------------- /** Calculate d = a/sqrt(h**2+k**2+l**2) diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h index 61847c892303..78cf35e042f7 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h @@ -65,8 +65,7 @@ class DLLExport ThermalNeutronBk2BkExpSigma : virtual public API::IFunction1D, double sig2sq) const; }; -typedef boost::shared_ptr - ThermalNeutronBk2BkExpSigma_sptr; +using ThermalNeutronBk2BkExpSigma_sptr = boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h index 85c3694e521f..b5c29abea3d0 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h @@ -81,8 +81,7 @@ class DLLExport ThermalNeutronDtoTOFFunction : virtual public API::IFunction1D, // jacobian); }; -typedef boost::shared_ptr - ThermalNeutronDtoTOFFunction_sptr; +using ThermalNeutronDtoTOFFunction_sptr = boost::shared_ptr; /// Calcualte TOF from d-spacing value for thermal neutron inline double calThermalNeutronTOF(double dh, double dtt1, double dtt1t, diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h index 8b4fceaf82f0..6c5d8d30ae45 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/LatticeFunction.h @@ -63,7 +63,7 @@ class DLLExport LatticeFunction : public API::ILatticeFunction { Functions::PawleyParameterFunction_sptr m_cellParameters; }; -typedef boost::shared_ptr LatticeFunction_sptr; +using LatticeFunction_sptr = boost::shared_ptr; } // namespace CurveFitting } // namespace Mantid diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h b/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h index 8e105b053445..2363f17e44b3 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h @@ -20,8 +20,8 @@ double finalEnergyUranium(const double randv); // Ties together random numbers with various probability distributions // @todo: Should move to Kernel class RandomNumberGenerator { - typedef boost::uniform_real uniform_double; - typedef boost::normal_distribution gaussian_double; + using uniform_double = boost::uniform_real; + using gaussian_double = boost::normal_distribution; public: RandomNumberGenerator(const int seed); diff --git a/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp b/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp index 7bfa2e7ea945..d435dc2e5a86 100644 --- a/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp +++ b/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp @@ -537,7 +537,7 @@ PlotPeakByLogValue::makeNames() const { double start = 0; double end = 0; - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer names(inputList, ";", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); for (const auto &input : names) { diff --git a/Framework/CurveFitting/src/MSVesuvioHelpers.cpp b/Framework/CurveFitting/src/MSVesuvioHelpers.cpp index d39034cf5651..1180052c9b72 100644 --- a/Framework/CurveFitting/src/MSVesuvioHelpers.cpp +++ b/Framework/CurveFitting/src/MSVesuvioHelpers.cpp @@ -358,14 +358,12 @@ RandomNumberGenerator::RandomNumberGenerator(const int seed) : m_generator() { } /// Returns a flat random number between 0.0 & 1.0 double RandomNumberGenerator::flat() { - typedef boost::variate_generator - uniform_generator; + using uniform_generator = boost::variate_generator; return uniform_generator(m_generator, uniform_double(0.0, 1.0))(); } /// Returns a random number distributed by a normal distribution double RandomNumberGenerator::gaussian(const double mean, const double sigma) { - typedef boost::variate_generator - gauss_generator; + using gauss_generator = boost::variate_generator; return gauss_generator(m_generator, gaussian_double(mean, sigma))(); } diff --git a/Framework/CurveFitting/src/ParameterEstimator.cpp b/Framework/CurveFitting/src/ParameterEstimator.cpp index a395a5de317f..e055dd408e1c 100644 --- a/Framework/CurveFitting/src/ParameterEstimator.cpp +++ b/Framework/CurveFitting/src/ParameterEstimator.cpp @@ -25,7 +25,7 @@ std::recursive_mutex FUNCTION_MAP_MUTEX; } enum Function { None, Gaussian, Lorentzian, BackToBackExponential }; -typedef std::map> FunctionMapType; +using FunctionMapType = std::map >; //---------------------------------------------------------------------------------------------- diff --git a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h index 9c1d7d0d1ed4..557a80dc32ea 100644 --- a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h +++ b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h @@ -33,8 +33,8 @@ using namespace Mantid::CurveFitting::Algorithms; using Mantid::HistogramData::BinEdges; using Mantid::HistogramData::LinearGenerator; -typedef Mantid::DataObjects::Workspace2D_sptr WS_type; -typedef Mantid::DataObjects::TableWorkspace_sptr TWS_type; +using WS_type = Mantid::DataObjects::Workspace2D_sptr; +using TWS_type = Mantid::DataObjects::TableWorkspace_sptr; struct Fun { double operator()(double, int i) { return double(i + 1); } diff --git a/Framework/CurveFitting/test/CompositeFunctionTest.h b/Framework/CurveFitting/test/CompositeFunctionTest.h index 66694429e332..0dfad1276af7 100644 --- a/Framework/CurveFitting/test/CompositeFunctionTest.h +++ b/Framework/CurveFitting/test/CompositeFunctionTest.h @@ -33,8 +33,8 @@ using namespace Mantid::CurveFitting::Functions; using namespace Mantid::CurveFitting::FuncMinimisers; using namespace Mantid::CurveFitting::CostFunctions; -typedef Mantid::DataObjects::Workspace2D_sptr WS_type; -typedef Mantid::DataObjects::TableWorkspace_sptr TWS_type; +using WS_type = Mantid::DataObjects::Workspace2D_sptr; +using TWS_type = Mantid::DataObjects::TableWorkspace_sptr; class CurveFittingGauss : public IPeakFunction { public: diff --git a/Framework/CurveFitting/test/FortranMatrixTest.h b/Framework/CurveFitting/test/FortranMatrixTest.h index a217f132c95f..087bba8ef667 100644 --- a/Framework/CurveFitting/test/FortranMatrixTest.h +++ b/Framework/CurveFitting/test/FortranMatrixTest.h @@ -12,8 +12,8 @@ using Mantid::CurveFitting::GSLMatrix; using Mantid::CurveFitting::ComplexMatrix; using Mantid::CurveFitting::ComplexType; -typedef FortranMatrix DoubleFortranMatrix; -typedef FortranMatrix ComplexFortranMatrix; +using DoubleFortranMatrix = FortranMatrix; +using ComplexFortranMatrix = FortranMatrix; class FortranMatrixTest : public CxxTest::TestSuite { public: diff --git a/Framework/CurveFitting/test/FortranVectorTest.h b/Framework/CurveFitting/test/FortranVectorTest.h index b9c505579184..bbe3a0a3d2af 100644 --- a/Framework/CurveFitting/test/FortranVectorTest.h +++ b/Framework/CurveFitting/test/FortranVectorTest.h @@ -9,8 +9,8 @@ using Mantid::CurveFitting::FortranVector; using Mantid::CurveFitting::ComplexType; -typedef FortranVector FortranDoubleVector; -typedef FortranVector FortranComplexVector; +using FortranDoubleVector = FortranVector; +using FortranComplexVector = FortranVector; class FortranVectorTest : public CxxTest::TestSuite { public: @@ -207,7 +207,7 @@ class FortranVectorTest : public CxxTest::TestSuite { } void test_int_array() { - typedef FortranVector> FortranIntVector; + using FortranIntVector = FortranVector >; FortranIntVector ivec(1, 3); ivec(1) = 11; ivec(2) = 22; diff --git a/Framework/CurveFitting/test/Functions/ProductFunctionTest.h b/Framework/CurveFitting/test/Functions/ProductFunctionTest.h index b56e955f424c..1c44aa2d174f 100644 --- a/Framework/CurveFitting/test/Functions/ProductFunctionTest.h +++ b/Framework/CurveFitting/test/Functions/ProductFunctionTest.h @@ -10,7 +10,7 @@ #include "MantidCurveFitting/Jacobian.h" #include "MantidDataObjects/Workspace2D.h" -typedef Mantid::DataObjects::Workspace2D_sptr WS_type; +using WS_type = Mantid::DataObjects::Workspace2D_sptr; using Mantid::CurveFitting::Functions::ProductFunction; using Mantid::CurveFitting::Functions::Gaussian; diff --git a/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h b/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h index b51bc222d761..4368e1a70304 100644 --- a/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h +++ b/Framework/CurveFitting/test/Functions/ProductLinearExpTest.h @@ -73,7 +73,7 @@ to check that the results are equal. benchmark.addFunction(expFunction); const size_t nResults = 10; - typedef std::vector VecDouble; + using VecDouble = std::vector; VecDouble xValues(nResults); std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.0001)); @@ -171,7 +171,7 @@ to check that the results are equal. benchmark.setParameter("Lifetime", Lifetime); const size_t nResults = 10; - typedef std::vector VecDouble; + using VecDouble = std::vector; VecDouble xValues(nResults); std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.1)); @@ -196,7 +196,7 @@ to check that the results are equal. void test_calculate_derivative_throws_nothing() { const size_t nResults = 10; - typedef std::vector VecDouble; + using VecDouble = std::vector; VecDouble xValues(nResults); std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.1)); diff --git a/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h b/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h index 952f687448f2..36ee78deb164 100644 --- a/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h +++ b/Framework/CurveFitting/test/Functions/ProductQuadraticExpTest.h @@ -75,7 +75,7 @@ to check that the results are equal. benchmark.addFunction(expFunction); const size_t nResults = 10; - typedef std::vector VecDouble; + using VecDouble = std::vector; VecDouble xValues(nResults); std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.0001)); @@ -169,7 +169,7 @@ to check that the results are equal. benchmark.setParameter("Lifetime", Lifetime); const size_t nResults = 10; - typedef std::vector VecDouble; + using VecDouble = std::vector; VecDouble xValues(nResults); std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.1)); @@ -194,7 +194,7 @@ to check that the results are equal. void test_calculate_derivative_throws_nothing() { const size_t nResults = 10; - typedef std::vector VecDouble; + using VecDouble = std::vector; VecDouble xValues(nResults); std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.1)); From a11e093014017de8050a344c0733d2186a6dc892 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 12:14:39 +0000 Subject: [PATCH 194/364] Re #22048: Applied fixes to Framework/DataHandling. --- .../DataHandling/inc/MantidDataHandling/DetermineChunking.h | 4 ++-- .../inc/MantidDataHandling/DownloadInstrument.h | 2 +- .../inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h | 4 ++-- .../DataHandling/inc/MantidDataHandling/GroupDetectors2.h | 2 +- .../DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h | 2 +- Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h | 6 +++--- Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h | 3 +-- Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h | 3 +-- Framework/DataHandling/src/CreateChunkingFromInstrument.cpp | 2 +- Framework/DataHandling/src/CreateSimulationWorkspace.cpp | 2 +- Framework/DataHandling/src/DetermineChunking.cpp | 2 +- .../DataHandling/src/FilterEventsByLogValuePreNexus.cpp | 4 ++-- Framework/DataHandling/src/GroupDetectors2.cpp | 4 ++-- Framework/DataHandling/src/LoadEventNexus.cpp | 6 +++--- Framework/DataHandling/src/LoadEventPreNexus2.cpp | 2 +- Framework/DataHandling/src/LoadNXSPE.cpp | 2 +- Framework/DataHandling/src/LoadNexusMonitors2.cpp | 4 ++-- Framework/DataHandling/src/LoadNexusProcessed.cpp | 4 ++-- Framework/DataHandling/src/LoadRaw/item_struct.h | 3 +-- Framework/DataHandling/src/LoadRaw/vms_convert.h | 2 +- Framework/DataHandling/src/LoadSNSspec.cpp | 2 +- Framework/DataHandling/src/LoadSassena.cpp | 2 +- Framework/DataHandling/src/LoadSpec.cpp | 2 +- Framework/DataHandling/src/SaveGSASInstrumentFile.cpp | 2 +- Framework/DataHandling/src/SaveNXSPE.cpp | 4 ++-- Framework/DataHandling/src/SaveNexusProcessed.cpp | 2 +- Framework/DataHandling/test/SaveNXSPETest.h | 4 +--- Framework/DataHandling/test/SaveParameterFileTest.h | 2 +- 28 files changed, 39 insertions(+), 44 deletions(-) diff --git a/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h b/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h index 8b8daff910fa..f705e389fffa 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h +++ b/Framework/DataHandling/inc/MantidDataHandling/DetermineChunking.h @@ -36,9 +36,9 @@ namespace DataHandling { Code Documentation is available at: */ /// Make the code clearer by having this an explicit type -typedef int PixelType; +using PixelType = int; /// Type for the DAS time of flight (data file) -typedef int DasTofType; +using DasTofType = int; /// Structure that matches the form in the binary event list. #pragma pack(push, 4) // Make sure the structure is 8 bytes. diff --git a/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h index f234f05d2a0f..08183f6e02ce 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h +++ b/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h @@ -45,7 +45,7 @@ class DLLExport DownloadInstrument : public API::Algorithm { protected: // Convenience typedef - typedef std::map StringToStringMap; + using StringToStringMap = std::map; private: void init() override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h b/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h index 3040fe655c7f..161bbb543cc6 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/FilterEventsByLogValuePreNexus.h @@ -41,10 +41,10 @@ namespace DataHandling { #undef LOADEVENTPRENEXUS_ALLOW_PARALLEL /// Make the code clearer by having this an explicit type -typedef int PixelType; +using PixelType = int; /// Type for the DAS time of flight (data file) -typedef int DasTofType; +using DasTofType = int; /// Structure that matches the form in the binary event list. #pragma pack(push, 4) // Make sure the structure is 8 bytes. diff --git a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h index a3ff6210b4ab..7ae07d960165 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h @@ -149,7 +149,7 @@ class DLLExport GroupDetectors2 : public API::Algorithm { /// used to store the lists of WORKSPACE INDICES that will be grouped, the /// keys are not used - typedef std::map> storage_map; + using storage_map = std::map >; /// An estimate of the percentage of the algorithm runtimes that has been /// completed diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h index a9a2939b46d2..e3b60a454d33 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h @@ -24,7 +24,7 @@ namespace DataHandling { namespace ANSTO { /// pointer to the vector of events -typedef std::vector *EventVector_pt; +using EventVector_pt = std::vector *; /// helper class to keep track of progress class ProgressTracker { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h index ad92b109c532..d2af4e82ce47 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h @@ -6,9 +6,9 @@ #include -typedef std::vector Column; -typedef std::unordered_map ColumnMap; -typedef std::unordered_map AttributeMap; +using Column = std::vector; +using ColumnMap = std::unordered_map; +using AttributeMap = std::unordered_map; namespace Mantid { namespace DataHandling { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h index 75c104fc42cd..daacd95d4034 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h @@ -70,8 +70,7 @@ class DLLExport LoadSNSspec : public API::IFileLoader, /// Allowed values for the cache property std::vector m_seperator_options; std::map m_separatormap; /// - separator_pair; ///; /// m_seperator_options; std::map m_separatormap; /// - separator_pair; ///; ///> NXIntArray; + using NXIntArray = boost::scoped_ptr >; nxsFile.openData("NDET"); NXIntArray ndets(nxsFile.getData()); diff --git a/Framework/DataHandling/src/DetermineChunking.cpp b/Framework/DataHandling/src/DetermineChunking.cpp index 498f30ba0fec..93b147d699e5 100644 --- a/Framework/DataHandling/src/DetermineChunking.cpp +++ b/Framework/DataHandling/src/DetermineChunking.cpp @@ -289,7 +289,7 @@ void DetermineChunking::exec() { /// set the name of the top level NXentry m_top_entry_name std::string DetermineChunking::setTopEntryName(std::string filename) { std::string top_entry_name; - typedef std::map string_map_t; + using string_map_t = std::map; try { string_map_t::const_iterator it; ::NeXus::File file = ::NeXus::File(filename); diff --git a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp index 28512fcfb875..7e2552f986ba 100644 --- a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp +++ b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp @@ -910,7 +910,7 @@ void FilterEventsByLogValuePreNexus::procEvents( std::vector buffers; /// Pointer to the vector of events - typedef std::vector *EventVector_pt; + using EventVector_pt = std::vector *; /// Bare array of arrays of pointers to the EventVectors EventVector_pt **eventVectors; @@ -1515,7 +1515,7 @@ void FilterEventsByLogValuePreNexus::filterEvents() { std::vector buffers; /// Pointer to the vector of events - typedef std::vector *EventVector_pt; + using EventVector_pt = std::vector *; /// Bare array of arrays of pointers to the EventVectors EventVector_pt **eventVectors; diff --git a/Framework/DataHandling/src/GroupDetectors2.cpp b/Framework/DataHandling/src/GroupDetectors2.cpp index 859a8adf62a4..534b5b1b0f67 100644 --- a/Framework/DataHandling/src/GroupDetectors2.cpp +++ b/Framework/DataHandling/src/GroupDetectors2.cpp @@ -732,7 +732,7 @@ void GroupDetectors2::processGroupingWorkspace( std::vector &unUsedSpec) { detid2index_map detIdToWiMap = workspace->getDetectorIDToWorkspaceIndexMap(); - typedef std::map> Group2SetMapType; + using Group2SetMapType = std::map >; Group2SetMapType group2WSIndexSetmap; const auto &spectrumInfo = groupWS->spectrumInfo(); @@ -785,7 +785,7 @@ void GroupDetectors2::processMatrixWorkspace( std::vector &unUsedSpec) { detid2index_map detIdToWiMap = workspace->getDetectorIDToWorkspaceIndexMap(); - typedef std::map> Group2SetMapType; + using Group2SetMapType = std::map >; Group2SetMapType group2WSIndexSetmap; const auto &spectrumInfo = groupWS->spectrumInfo(); diff --git a/Framework/DataHandling/src/LoadEventNexus.cpp b/Framework/DataHandling/src/LoadEventNexus.cpp index 040c535ac29e..4d1233a7f13a 100644 --- a/Framework/DataHandling/src/LoadEventNexus.cpp +++ b/Framework/DataHandling/src/LoadEventNexus.cpp @@ -318,7 +318,7 @@ void LoadEventNexus::setTopEntryName() { m_top_entry_name = nxentryProperty; return; } - typedef std::map string_map_t; + using string_map_t = std::map; try { string_map_t::const_iterator it; // assume we're at the top, otherwise: m_file->openPath("/"); @@ -1143,7 +1143,7 @@ bool LoadEventNexus::hasEventMonitors() { try { m_file->openPath("/" + m_top_entry_name); // Start with the base entry - typedef std::map string_map_t; + using string_map_t = std::map; // Now we want to go through and find the monitors string_map_t entries = m_file->getEntries(); for (string_map_t::const_iterator it = entries.begin(); it != entries.end(); @@ -1418,7 +1418,7 @@ void LoadEventNexus::loadTimeOfFlight(EventWorkspaceCollection_sptr WS, m_file->openPath("/"); m_file->openGroup(entry_name, "NXentry"); - typedef std::map string_map_t; + using string_map_t = std::map; string_map_t entries = m_file->getEntries(); if (entries.find("detector_1_events") == entries.end()) { // not an ISIS file diff --git a/Framework/DataHandling/src/LoadEventPreNexus2.cpp b/Framework/DataHandling/src/LoadEventPreNexus2.cpp index 8d0b1a657eb3..c7fdace12dd0 100644 --- a/Framework/DataHandling/src/LoadEventPreNexus2.cpp +++ b/Framework/DataHandling/src/LoadEventPreNexus2.cpp @@ -744,7 +744,7 @@ void LoadEventPreNexus2::procEvents( std::vector buffers; /// Pointer to the vector of events - typedef std::vector *EventVector_pt; + using EventVector_pt = std::vector *; /// Bare array of arrays of pointers to the EventVectors EventVector_pt **eventVectors; diff --git a/Framework/DataHandling/src/LoadNXSPE.cpp b/Framework/DataHandling/src/LoadNXSPE.cpp index 5379e7ac00e6..0186d41d008d 100644 --- a/Framework/DataHandling/src/LoadNXSPE.cpp +++ b/Framework/DataHandling/src/LoadNXSPE.cpp @@ -65,7 +65,7 @@ int LoadNXSPE::identiferConfidence(const std::string &value) { */ int LoadNXSPE::confidence(Kernel::NexusDescriptor &descriptor) const { int confidence(0); - typedef std::map string_map_t; + using string_map_t = std::map; try { ::NeXus::File file = ::NeXus::File(descriptor.filename()); string_map_t entries = file.getEntries(); diff --git a/Framework/DataHandling/src/LoadNexusMonitors2.cpp b/Framework/DataHandling/src/LoadNexusMonitors2.cpp index 790af0f22d51..4a899cf5d9dd 100644 --- a/Framework/DataHandling/src/LoadNexusMonitors2.cpp +++ b/Framework/DataHandling/src/LoadNexusMonitors2.cpp @@ -128,7 +128,7 @@ void LoadNexusMonitors2::exec() { ::NeXus::File file(m_filename); // Start with the base entry - typedef std::map string_map_t; + using string_map_t = std::map; string_map_t::const_iterator it; string_map_t entries = file.getEntries(); for (it = entries.begin(); it != entries.end(); ++it) { @@ -588,7 +588,7 @@ size_t LoadNexusMonitors2::getMonitorInfo( size_t &numHistMon, size_t &numEventMon, size_t &numPeriods, std::map &monitorNumber2Name, std::vector &isEventMonitors) { - typedef std::map string_map_t; + using string_map_t = std::map; // Now we want to go through and find the monitors string_map_t entries = file.getEntries(); diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp index 2d3c2bb55a22..233a1faf072d 100644 --- a/Framework/DataHandling/src/LoadNexusProcessed.cpp +++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp @@ -55,7 +55,7 @@ using Mantid::Types::Event::TofEvent; namespace { // Helper typedef -typedef boost::shared_array IntArray_shared; +using IntArray_shared = boost::shared_array; // Struct to contain spectrum information. struct SpectraInfo { @@ -83,7 +83,7 @@ struct SpectraInfo { }; // Helper typdef. -typedef boost::optional SpectraInfo_optional; +using SpectraInfo_optional = boost::optional; /** * Extract ALL the detector, spectrum number and workspace index mapping diff --git a/Framework/DataHandling/src/LoadRaw/item_struct.h b/Framework/DataHandling/src/LoadRaw/item_struct.h index a14028aa556e..874bcc3c1103 100644 --- a/Framework/DataHandling/src/LoadRaw/item_struct.h +++ b/Framework/DataHandling/src/LoadRaw/item_struct.h @@ -23,8 +23,7 @@ class item_struct { item_struct() : m_items(), m_spec_array(nullptr), m_ndet(0){}; private: - typedef std::map - items_map_t; ///; /// mypair; +using mypair = std::pair; bool compare(const mypair &left, const mypair &right) { return left.first < right.first; } diff --git a/Framework/DataHandling/src/LoadSpec.cpp b/Framework/DataHandling/src/LoadSpec.cpp index 540703f58b13..b2069c5f0747 100644 --- a/Framework/DataHandling/src/LoadSpec.cpp +++ b/Framework/DataHandling/src/LoadSpec.cpp @@ -134,7 +134,7 @@ size_t LoadSpec::readNumberOfSpectra(std::ifstream &file) const { void LoadSpec::readLine(const std::string &line, std::vector &buffer) const { if (!line.empty() && line[0] != '#') { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; const std::string sep = " "; tokenizer tok(line, sep, Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY); for (const auto &beg : tok) { diff --git a/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp b/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp index 84d34e586b1e..a33d67c68be5 100644 --- a/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp +++ b/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp @@ -67,7 +67,7 @@ class ChopperConfiguration { std::vector m_vruns; }; -typedef boost::shared_ptr ChopperConfiguration_sptr; +using ChopperConfiguration_sptr = boost::shared_ptr; //---------------------------------------------------------------------------------------------- /** Constructor diff --git a/Framework/DataHandling/src/SaveNXSPE.cpp b/Framework/DataHandling/src/SaveNXSPE.cpp index b76d875c1362..ae857d46c99b 100644 --- a/Framework/DataHandling/src/SaveNXSPE.cpp +++ b/Framework/DataHandling/src/SaveNXSPE.cpp @@ -194,7 +194,7 @@ void SaveNXSPE::exec() { nxFile.closeData(); // let's create some blank arrays in the nexus file - typedef std::vector Dimensions; + using Dimensions = std::vector; Dimensions arrayDims(2); arrayDims[0] = nHist; arrayDims[1] = nBins; @@ -221,7 +221,7 @@ void SaveNXSPE::exec() { slabSize[1] = nBins; // Allocate the temporary buffers for the signal and errors - typedef boost::scoped_array Buffer; + using Buffer = boost::scoped_array; const size_t bufferSize(slabSize[0] * slabSize[1]); Buffer signalBuffer(new double[bufferSize]); Buffer errorBuffer(new double[bufferSize]); diff --git a/Framework/DataHandling/src/SaveNexusProcessed.cpp b/Framework/DataHandling/src/SaveNexusProcessed.cpp index 0cb8b34a0a9e..3d7910b3fd38 100644 --- a/Framework/DataHandling/src/SaveNexusProcessed.cpp +++ b/Framework/DataHandling/src/SaveNexusProcessed.cpp @@ -28,7 +28,7 @@ using namespace API; using namespace DataObjects; using Geometry::Instrument_const_sptr; -typedef NeXus::NexusFileIO::optional_size_t optional_size_t; +using optional_size_t = NeXus::NexusFileIO::optional_size_t; // Register the algorithm into the algorithm factory DECLARE_ALGORITHM(SaveNexusProcessed) diff --git a/Framework/DataHandling/test/SaveNXSPETest.h b/Framework/DataHandling/test/SaveNXSPETest.h index 7c8612bdfa2b..1c7ddb10bf61 100644 --- a/Framework/DataHandling/test/SaveNXSPETest.h +++ b/Framework/DataHandling/test/SaveNXSPETest.h @@ -165,9 +165,7 @@ class SaveNXSPETest : public CxxTest::TestSuite { return inputWS; } - typedef boost::tuple, - boost::shared_array, - boost::shared_array> DataHolder; + using DataHolder = boost::tuple, boost::shared_array, boost::shared_array >; DataHolder saveAndReloadWorkspace(const MatrixWorkspace_sptr inputWS) { SaveNXSPE saver; diff --git a/Framework/DataHandling/test/SaveParameterFileTest.h b/Framework/DataHandling/test/SaveParameterFileTest.h index 257cf753d9a7..80f833414907 100644 --- a/Framework/DataHandling/test/SaveParameterFileTest.h +++ b/Framework/DataHandling/test/SaveParameterFileTest.h @@ -136,7 +136,7 @@ class SaveParameterFileTest : public CxxTest::TestSuite { param->value(); // Info about fitting parameter is in string value, see FitParameter class - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer values(value, ",", tokenizer::TOK_TRIM); TS_ASSERT_EQUALS(fitParam.getFormula(), values[7]); TS_ASSERT_EQUALS(fitParam.getFunction(), values[1]); From f94979986b4e80d7022e5b16ed567d74ab0ca780 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Wed, 14 Mar 2018 12:36:36 +0000 Subject: [PATCH 195/364] Re #22076 Simplified PrintParser --- scripts/SANS/sans/user_file/user_file_parser.py | 13 +++++++++---- .../test/SANS/user_file/user_file_parser_test.py | 8 ++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/scripts/SANS/sans/user_file/user_file_parser.py b/scripts/SANS/sans/user_file/user_file_parser.py index 1913eed23918..ed79a85ec794 100644 --- a/scripts/SANS/sans/user_file/user_file_parser.py +++ b/scripts/SANS/sans/user_file/user_file_parser.py @@ -2085,11 +2085,16 @@ def __init__(self): def parse_line(self, line): # Get the settings, ie remove command - setting = UserFileComponentParser.get_settings(line, PrintParser.get_type_pattern()) - # Determine the qualifier and extract the user setting - original_setting = re.search(setting.strip(), line, re.IGNORECASE).group(0) - return {PrintId.print_line: original_setting} + setting = line.strip() + + if setting.upper().startswith('PRINT'): + setting = setting[len('PRINT'):] + setting = setting.strip() + else: + raise RuntimeError("PrintParser: Failed to extract line {} it does not start with PRINT".format(line)) + + return {PrintId.print_line: setting} @staticmethod def get_type(): diff --git a/scripts/test/SANS/user_file/user_file_parser_test.py b/scripts/test/SANS/user_file/user_file_parser_test.py index 5c765f67dccd..155d9c711af2 100644 --- a/scripts/test/SANS/user_file/user_file_parser_test.py +++ b/scripts/test/SANS/user_file/user_file_parser_test.py @@ -888,9 +888,13 @@ def test_that_gets_type(self): self.assertTrue(PrintParser.get_type(), "PRINT") def test_that_print_is_parsed_correctly(self): - valid_settings = {"PRINT OdlfP slsk 23lksdl2 34l": {PrintId.print_line: "OdlfP slsk 23lksdl2 34l"}} + valid_settings = {"PRINT OdlfP slsk 23lksdl2 34l": {PrintId.print_line: "OdlfP slsk 23lksdl2 34l"}, + "PRiNt OdlfP slsk 23lksdl2 34l": {PrintId.print_line: "OdlfP slsk 23lksdl2 34l"}, + " PRINT Loaded: USER_LOQ_174J, 12/03/18, Xuzhi (Lu), 12mm, Sample Changer, Banjo cells": + {PrintId.print_line: "Loaded: USER_LOQ_174J, 12/03/18, Xuzhi (Lu), 12mm, Sample Changer, Banjo cells"} + } - invalid_settings = {} + invalid_settings = {"j PRINT OdlfP slsk 23lksdl2 34l ": RuntimeError,} print_parser = PrintParser() do_test(print_parser, valid_settings, invalid_settings, self.assertTrue, self.assertRaises) From d6e653e9496ef92614411c5cfd82a69300523fd2 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Wed, 14 Mar 2018 13:14:46 +0000 Subject: [PATCH 196/364] Re #22076 removed uneeded member variables --- scripts/SANS/sans/user_file/user_file_parser.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/SANS/sans/user_file/user_file_parser.py b/scripts/SANS/sans/user_file/user_file_parser.py index ed79a85ec794..cd2b8d99c9ed 100644 --- a/scripts/SANS/sans/user_file/user_file_parser.py +++ b/scripts/SANS/sans/user_file/user_file_parser.py @@ -2079,10 +2079,6 @@ class PrintParser(UserFileComponentParser): def __init__(self): super(PrintParser, self).__init__() - # Print - self._print = "\\s*PRINT\\s+" - self._print_pattern = re.compile(start_string + self._print + "\\s*.*\\s*" + end_string) - def parse_line(self, line): # Get the settings, ie remove command From e52fd83626dd5ee3d6007a6531e790748fbfbe9e Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Mon, 12 Mar 2018 18:00:17 -0400 Subject: [PATCH 197/364] Fix or suppress warnings from clang 6.0 --- Framework/API/inc/MantidAPI/IMaskWorkspace.h | 1 + Framework/Algorithms/src/PolarizationEfficiencyCor.cpp | 4 ++-- .../Crystal/inc/MantidCrystal/FindSXPeaksHelper.h | 4 ++++ .../src/FuncMinimizers/FABADAMinimizer.cpp | 4 ++-- .../Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h | 2 +- .../Geometry/inc/MantidGeometry/Objects/IObject.h | 1 + Framework/Geometry/src/Crystal/HKLGenerator.cpp | 10 +++++----- Framework/Geometry/src/Math/BnId.cpp | 4 ---- Framework/Kernel/src/MaterialXMLParser.cpp | 1 + .../LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h | 2 +- Framework/Parallel/inc/MantidParallel/Status.h | 9 ++++++--- Framework/Parallel/test/EventParserTest.h | 2 +- .../mantid/kernel/src/Converters/CloneToNumpy.cpp | 1 + .../mantid/kernel/src/Converters/DateAndTime.cpp | 7 +++++++ .../mantid/kernel/src/Converters/NDArrayToVector.cpp | 8 ++++++++ .../lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp | 5 +---- .../IEnggDiffMultiRunFittingWidgetAdder.h | 1 + 17 files changed, 43 insertions(+), 23 deletions(-) diff --git a/Framework/API/inc/MantidAPI/IMaskWorkspace.h b/Framework/API/inc/MantidAPI/IMaskWorkspace.h index cd51c350aaf3..b1a9dddd6d87 100644 --- a/Framework/API/inc/MantidAPI/IMaskWorkspace.h +++ b/Framework/API/inc/MantidAPI/IMaskWorkspace.h @@ -38,6 +38,7 @@ class DLLExport IMaskWorkspace { public: IMaskWorkspace() = default; IMaskWorkspace &operator=(const IMaskWorkspace &) = delete; + virtual ~IMaskWorkspace() = default; /// Return the workspace typeID virtual const std::string id() const { return "IMaskWorkspace"; } /// Total number of masked pixels diff --git a/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp b/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp index 553dcd3ab957..3d30c504028c 100644 --- a/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp +++ b/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp @@ -557,8 +557,8 @@ void PolarizationEfficiencyCor::checkConsistentX( const auto &P2x = efficiencies.P2->x(); checkX(P2x, "P2"); // A local helper function to check an input workspace against F1. - auto checkWS = [&F1x, &checkX](const API::MatrixWorkspace_sptr &ws, - const std::string &tag) { + auto checkWS = [&checkX](const API::MatrixWorkspace_sptr &ws, + const std::string &tag) { const auto nHist = ws->getNumberHistograms(); for (size_t i = 0; i != nHist; ++i) { checkX(ws->x(i), tag); diff --git a/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h b/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h index 83c03c8fc5f1..e021920f5c8e 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h +++ b/Framework/Crystal/inc/MantidCrystal/FindSXPeaksHelper.h @@ -122,6 +122,7 @@ class PeakContainer { * ------------------------------------------------------------------------------------------ */ struct DLLExport BackgroundStrategy { + virtual ~BackgroundStrategy() = default; virtual bool isBelowBackground(const double intensity, const HistogramData::HistogramY &y) const = 0; }; @@ -155,6 +156,7 @@ class DLLExport PeakFindingStrategy { const double minValue = EMPTY_DBL(), const double maxValue = EMPTY_DBL(), const XAxisUnit units = XAxisUnit::TOF); + virtual ~PeakFindingStrategy() = default; PeakList findSXPeaks(const HistogramData::HistogramX &x, const HistogramData::HistogramY &y, const int workspaceIndex) const; @@ -219,6 +221,7 @@ class DLLExport AllPeaksStrategy : public PeakFindingStrategy { */ class DLLExport CompareStrategy { public: + virtual ~CompareStrategy() = default; virtual bool compare(const SXPeak &lhs, const SXPeak &rhs) const = 0; }; @@ -253,6 +256,7 @@ class DLLExport AbsoluteCompareStrategy : public CompareStrategy { class DLLExport ReducePeakListStrategy { public: ReducePeakListStrategy(const CompareStrategy *compareStrategy); + virtual ~ReducePeakListStrategy() = default; virtual std::vector reduce(const std::vector &peaks, Mantid::Kernel::ProgressBase &progress) const = 0; diff --git a/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp index 98ecd9628f88..fa2ce0ddb6a3 100644 --- a/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp +++ b/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp @@ -959,12 +959,12 @@ void FABADAMinimizer::calculateConvChainAndBestParameters( auto posBestPar = std::find(reducedChain[j].begin(), reducedChain[j].end(), bestParameters[j]); double varLeft = 0, varRight = 0; - for (auto k = reducedChain[j].begin(); k < reducedChain[j].end(); k++) { + for (auto k = reducedChain[j].begin(); k < reducedChain[j].end(); + k += 2) { if (k < posBestPar) varLeft += (*k - bestParameters[j]) * (*k - bestParameters[j]); else if (k > posBestPar) varRight += (*k - bestParameters[j]) * (*k - bestParameters[j]); - ++k; } if (posBestPar != reducedChain[j].begin()) varLeft /= double(posBestPar - reducedChain[j].begin()); diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h index b20d11ccf2f0..b3467fdf7092 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLGenerator.h @@ -143,7 +143,7 @@ class MANTID_GEOMETRY_DLL HKLGenerator { int m_h, m_k, m_l; Kernel::V3D m_hkl; - int m_hMin, m_hMax; + int m_hMax; int m_kMin, m_kMax; int m_lMin, m_lMax; }; diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h index 24331e807521..6b186d0b7acc 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h @@ -54,6 +54,7 @@ class vtkGeometryCacheWriter; */ class MANTID_GEOMETRY_DLL IObject { public: + virtual ~IObject() = default; virtual bool isValid(const Kernel::V3D &) const = 0; virtual bool isOnSide(const Kernel::V3D &) const = 0; virtual int calcValidType(const Kernel::V3D &Pt, diff --git a/Framework/Geometry/src/Crystal/HKLGenerator.cpp b/Framework/Geometry/src/Crystal/HKLGenerator.cpp index 9d56c3a2f5dd..0979b69dff53 100644 --- a/Framework/Geometry/src/Crystal/HKLGenerator.cpp +++ b/Framework/Geometry/src/Crystal/HKLGenerator.cpp @@ -62,20 +62,20 @@ V3D HKLGenerator::getEndHKL() const { /// Default constructor, requirement from boost::iterator_facade HKLGenerator::const_iterator::const_iterator() - : m_h(0), m_k(0), m_l(0), m_hkl(V3D(0, 0, 0)), m_hMin(0), m_hMax(0), - m_kMin(0), m_kMax(0), m_lMin(0), m_lMax(0) {} + : m_h(0), m_k(0), m_l(0), m_hkl(V3D(0, 0, 0)), m_hMax(0), m_kMin(0), + m_kMax(0), m_lMin(0), m_lMax(0) {} /// Return an iterator with min = max = current. HKLGenerator::const_iterator::const_iterator(const V3D ¤t) : m_h(static_cast(current.X())), m_k(static_cast(current.Y())), - m_l(static_cast(current.Z())), m_hkl(current), m_hMin(m_h), - m_hMax(m_h), m_kMin(m_k), m_kMax(m_k), m_lMin(m_l), m_lMax(m_l) {} + m_l(static_cast(current.Z())), m_hkl(current), m_hMax(m_h), + m_kMin(m_k), m_kMax(m_k), m_lMin(m_l), m_lMax(m_l) {} /// Return an iterator that can move from min to max, with current = min HKLGenerator::const_iterator::const_iterator(const V3D &hklMin, const V3D &hklMax) : m_h(static_cast(hklMin.X())), m_k(static_cast(hklMin.Y())), - m_l(static_cast(hklMin.Z())), m_hkl(hklMin), m_hMin(m_h), + m_l(static_cast(hklMin.Z())), m_hkl(hklMin), m_hMax(static_cast(hklMax.X())), m_kMin(m_k), m_kMax(static_cast(hklMax.Y())), m_lMin(m_l), m_lMax(static_cast(hklMax.Z())) {} diff --git a/Framework/Geometry/src/Math/BnId.cpp b/Framework/Geometry/src/Math/BnId.cpp index 84088af00145..7fb6b3b33b71 100644 --- a/Framework/Geometry/src/Math/BnId.cpp +++ b/Framework/Geometry/src/Math/BnId.cpp @@ -110,8 +110,6 @@ int BnId::operator<(const BnId &A) const { if (A.size != size) return size < A.size; - std::pair cntA(0, 0); // count for A - std::pair cntT(0, 0); // count for this if (Znum != A.Znum) return (Znum < A.Znum) ? 1 : 0; @@ -282,8 +280,6 @@ std::pair BnId::makeCombination(const BnId &A) const return std::pair(0, BnId()); int flag(0); // numb of diff - std::pair Tcnt(0, 0); // this counter - std::pair Acnt(0, 0); // A counter auto avc = A.Tval.cbegin(); std::vector::const_iterator chpt; // change point for (auto tvc = Tval.cbegin(); tvc != Tval.cend(); ++tvc, ++avc) { diff --git a/Framework/Kernel/src/MaterialXMLParser.cpp b/Framework/Kernel/src/MaterialXMLParser.cpp index 1e110f55d4e2..514254387319 100644 --- a/Framework/Kernel/src/MaterialXMLParser.cpp +++ b/Framework/Kernel/src/MaterialXMLParser.cpp @@ -51,6 +51,7 @@ const char *ABSORB_ATT = "absorptionxsec"; // Base type to put in a hash struct BuilderHandle { + virtual ~BuilderHandle() = default; virtual void operator()(MaterialBuilder &builder, const std::string &value) const = 0; }; diff --git a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h index 0b83329afb84..6104a95cd486 100644 --- a/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h +++ b/Framework/LiveData/inc/MantidLiveData/Kafka/IKafkaBroker.h @@ -35,7 +35,7 @@ namespace LiveData { */ class DLLExport IKafkaBroker { public: - ~IKafkaBroker() = default; + virtual ~IKafkaBroker() = default; virtual std::unique_ptr subscribe(std::vector topics, diff --git a/Framework/Parallel/inc/MantidParallel/Status.h b/Framework/Parallel/inc/MantidParallel/Status.h index adbb5c852be0..965a117cf8c7 100644 --- a/Framework/Parallel/inc/MantidParallel/Status.h +++ b/Framework/Parallel/inc/MantidParallel/Status.h @@ -44,7 +44,8 @@ class ThreadingBackend; class MANTID_PARALLEL_DLL Status { public: #ifdef MPI_EXPERIMENTAL - Status(const boost::mpi::status &status) : m_status(status) {} + Status(const boost::mpi::status &status) + : m_status(status), m_threadingBackend{false} {} #endif template boost::optional count() const { @@ -56,12 +57,14 @@ class MANTID_PARALLEL_DLL Status { } private: - Status(const size_t size) : m_size(size), m_threadingBackend(true) {} + Status(const size_t size) : m_size(size) {} #ifdef MPI_EXPERIMENTAL boost::mpi::status m_status; #endif const size_t m_size{0}; - const bool m_threadingBackend{false}; +#ifdef MPI_EXPERIMENTAL + bool m_threadingBackend{true}; +#endif // For accessing constructor based on size. friend class detail::ThreadingBackend; }; diff --git a/Framework/Parallel/test/EventParserTest.h b/Framework/Parallel/test/EventParserTest.h index 0dce40044bdb..2de672e236ad 100644 --- a/Framework/Parallel/test/EventParserTest.h +++ b/Framework/Parallel/test/EventParserTest.h @@ -97,7 +97,7 @@ class FakeParserDataGenerator { static_cast(m_bank_offsets[bank] + absolutePixel)); std::transform(list.cbegin() + prev_end, list.cend(), std::back_inserter(m_event_time_offsets[bank]), - [this](const TofEvent &event) { + [](const TofEvent &event) { return static_cast(event.tof()); }); } diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp index bf501e26a4bc..fb49c9d5934b 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Converters/CloneToNumpy.cpp @@ -22,6 +22,7 @@ extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; +extern template int NDArrayTypeIndex::typenum; namespace Impl { /** diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp index 17e46c708855..539d41c26a28 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Converters/DateAndTime.cpp @@ -42,7 +42,14 @@ PyArray_Descr *descr_ns() { return func_PyArray_Descr("M8[ns]"); } // internal function that handles raw pointer boost::shared_ptr to_dateandtime(const PyObject *datetime) { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcast-qual" +#endif if (!PyArray_IsScalar(datetime, Datetime)) { +#if __clang__ +#pragma clang diagnostic pop +#endif throw std::runtime_error("Expected datetime64"); } diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp index 94668f5a1d3f..93f0a100d4cf 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp @@ -27,6 +27,14 @@ extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; +extern template int NDArrayTypeIndex::typecode; +extern template int NDArrayTypeIndex::typecode; +extern template int NDArrayTypeIndex::typecode; +extern template int NDArrayTypeIndex::typecode; +extern template int NDArrayTypeIndex::typecode; +extern template int NDArrayTypeIndex::typecode; +extern template int NDArrayTypeIndex::typecode; +extern template int NDArrayTypeIndex::typecode; } namespace { diff --git a/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp b/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp index 0ebcec2d711d..c599b26d407b 100644 --- a/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp +++ b/MantidPlot/src/lib/3rdparty/qtcolorpicker/src/qtcolorpicker.cpp @@ -605,10 +605,7 @@ void ColorPickerPopup::insertColor(const QColor &col, const QString &text, QColor ColorPickerPopup::color(int index) const { if (index < 0 || index > (int)items.count() - 1) return QColor(); - - // cppcheck-suppress cstyleCast - ColorPickerPopup *that = (ColorPickerPopup *)this; - return that->items.at(index)->color(); + return this->items.at(index)->color(); } /*! \internal diff --git a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h index 55657b8990ba..03c3c3e8e202 100644 --- a/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h +++ b/qt/scientific_interfaces/EnggDiffraction/IEnggDiffMultiRunFittingWidgetAdder.h @@ -9,6 +9,7 @@ namespace CustomInterfaces { class IEnggDiffMultiRunFittingWidgetAdder { public: + virtual ~IEnggDiffMultiRunFittingWidgetAdder() = default; virtual void operator()(IEnggDiffMultiRunFittingWidgetOwner &owner) = 0; }; From 378c536110186a595cb96936df3cb59b85f17044 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 13:49:33 +0000 Subject: [PATCH 198/364] Re #22048: Applied fixes to Framework/DataObjects. --- .../MantidDataObjects/AffineMatrixParameter.h | 2 +- .../CoordTransformAffineParser.h | 3 +- .../inc/MantidDataObjects/EventList.h | 2 +- .../inc/MantidDataObjects/EventWorkspace.h | 4 +- .../inc/MantidDataObjects/GroupingWorkspace.h | 4 +- .../DataObjects/inc/MantidDataObjects/MDBox.h | 4 +- .../inc/MantidDataObjects/MDBoxBase.h | 2 +- .../inc/MantidDataObjects/MDEventFactory.h | 190 +++++++++--------- .../inc/MantidDataObjects/MDEventInserter.h | 2 +- .../inc/MantidDataObjects/MDEventWorkspace.h | 4 +- .../MantidDataObjects/MDEventWorkspace.tcc | 2 +- .../inc/MantidDataObjects/MDGridBox.h | 4 +- .../inc/MantidDataObjects/MDHistoWorkspace.h | 4 +- .../MDHistoWorkspaceIterator.h | 7 +- .../inc/MantidDataObjects/MaskWorkspace.h | 4 +- .../inc/MantidDataObjects/OffsetsWorkspace.h | 4 +- .../inc/MantidDataObjects/PeakColumn.h | 2 +- .../MantidDataObjects/PeakShapeEllipsoid.h | 5 +- .../inc/MantidDataObjects/PeakShapeFactory.h | 4 +- .../inc/MantidDataObjects/PeaksWorkspace.h | 4 +- .../inc/MantidDataObjects/RebinnedOutput.h | 4 +- .../ReflectometryTransform.h | 2 +- .../inc/MantidDataObjects/SkippingPolicy.h | 2 +- .../MantidDataObjects/SpecialWorkspace2D.h | 5 +- .../MantidDataObjects/SplittersWorkspace.h | 5 +- .../inc/MantidDataObjects/TableColumn.h | 8 +- .../inc/MantidDataObjects/TableWorkspace.h | 10 +- .../inc/MantidDataObjects/Workspace2D.h | 4 +- .../MantidDataObjects/WorkspaceSingleValue.h | 5 +- .../src/AffineMatrixParameterParser.cpp | 4 +- .../src/CoordTransformAffineParser.cpp | 6 +- .../src/CoordTransformDistanceParser.cpp | 12 +- Framework/DataObjects/src/FakeMD.cpp | 6 +- Framework/DataObjects/src/MDBoxFlatTree.cpp | 2 +- Framework/DataObjects/test/MDBinTest.h | 2 +- Framework/DataObjects/test/MDBoxBaseTest.h | 4 +- .../DataObjects/test/MDBoxIteratorTest.h | 6 +- .../DataObjects/test/MDBoxSaveableTest.h | 2 +- Framework/DataObjects/test/MDBoxTest.h | 5 +- .../DataObjects/test/MDEventInserterTest.h | 4 +- Framework/DataObjects/test/MDGridBoxTest.h | 12 +- 41 files changed, 170 insertions(+), 197 deletions(-) diff --git a/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h b/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h index 0dcf3f9b0a5e..2d506d179600 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h +++ b/Framework/DataObjects/inc/MantidDataObjects/AffineMatrixParameter.h @@ -9,7 +9,7 @@ namespace Mantid { namespace DataObjects { /// Convenience typedef for a specific matrix type. -typedef Mantid::Kernel::Matrix AffineMatrixType; +using AffineMatrixType = Mantid::Kernel::Matrix; /** Type to wrap an affine matrix and allow serialization via xml. * diff --git a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h index 9267f1277cab..60d388b82856 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h +++ b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h @@ -31,8 +31,7 @@ class DLLExport CoordTransformAffineParser { createTransform(Poco::XML::Element *coordTransElement) const; virtual void setSuccessor(CoordTransformAffineParser *other); virtual ~CoordTransformAffineParser() = default; - typedef boost::shared_ptr - SuccessorType_sptr; ///< successor parser shared ptr typedef + using SuccessorType_sptr = boost::shared_ptr; ///< successor parser shared ptr typedef protected: SuccessorType_sptr m_successor; ///< successor parser private: diff --git a/Framework/DataObjects/inc/MantidDataObjects/EventList.h b/Framework/DataObjects/inc/MantidDataObjects/EventList.h index a4ddd64c6897..fa60d100681a 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/EventList.h +++ b/Framework/DataObjects/inc/MantidDataObjects/EventList.h @@ -17,7 +17,7 @@ class DateAndTime; } // namespace Types namespace Kernel { class SplittingInterval; -typedef std::vector TimeSplitterType; +using TimeSplitterType = std::vector; class Unit; } // namespace Kernel namespace DataObjects { diff --git a/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h index de80fb2e826b..f61a1b1d97c3 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h @@ -162,9 +162,9 @@ class DLLExport EventWorkspace : public API::IEventWorkspace { }; /// shared pointer to the EventWorkspace class -typedef boost::shared_ptr EventWorkspace_sptr; +using EventWorkspace_sptr = boost::shared_ptr; /// shared pointer to a const Workspace2D -typedef boost::shared_ptr EventWorkspace_const_sptr; +using EventWorkspace_const_sptr = boost::shared_ptr; } /// namespace DataObjects } /// namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h index 50f21824e37b..d19fe009f990 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/GroupingWorkspace.h @@ -58,10 +58,10 @@ class DLLExport GroupingWorkspace : public SpecialWorkspace2D { }; /// shared pointer to the GroupingWorkspace class -typedef boost::shared_ptr GroupingWorkspace_sptr; +using GroupingWorkspace_sptr = boost::shared_ptr; /// shared pointer to a const GroupingWorkspace -typedef boost::shared_ptr GroupingWorkspace_const_sptr; +using GroupingWorkspace_const_sptr = boost::shared_ptr; } // namespace Mantid } // namespace DataObjects diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBox.h b/Framework/DataObjects/inc/MantidDataObjects/MDBox.h index d5369975c26e..bc0b580f2c4c 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBox.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBox.h @@ -227,10 +227,10 @@ class DLLExport MDBox : public MDBoxBase { public: /// Typedef for a shared pointer to a MDBox - typedef boost::shared_ptr> sptr; + using sptr = boost::shared_ptr >; /// Typedef for a vector of the conatined events - typedef std::vector vec_t; + using vec_t = std::vector; }; #ifndef __INTEL_COMPILER diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h index 12cee44a4717..1deab64c5080 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h @@ -372,7 +372,7 @@ class DLLExport MDBoxBase : public Mantid::API::IMDNode { public: /// Convenience typedef for a shared pointer to a this type of class - typedef boost::shared_ptr> sptr; + using sptr = boost::shared_ptr >; }; //(end class MDBoxBase) diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h index 2bad03cb3184..6525a5ebc4eb 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h @@ -65,20 +65,14 @@ class DLLExport MDEventFactory { static size_t getMaxNumDim() { return size_t(MAX_MD_DIMENSIONS_NUM); } private: - typedef API::IMDNode *(*fpCreateBox)( - API::BoxController *, - const std::vector> &, - const uint32_t, const size_t, const size_t); + using fpCreateBox = API::IMDNode *(*)(API::BoxController *, const std::vector > &, const uint32_t, const size_t, const size_t); // vector of function pointers to the functions which create MDBox or // MDGridBox; static std::vector boxCreatorFP; // typedef for the class function pointer to the function, which creates MD // Workspaces - typedef API::IMDEventWorkspace *(*fpCreateMDWS)( - const std::string &eventType, - const Mantid::API::MDNormalization &preferredNormalization, - const Mantid::API::MDNormalization &preferredNormalizationHisto); + using fpCreateMDWS = API::IMDEventWorkspace *(*)(const std::string &, const Mantid::API::MDNormalization &, const Mantid::API::MDNormalization &); // vector of function pointers to the funcions static std::vector wsCreatorFP; @@ -425,197 +419,197 @@ class DLLExport MDEventFactory { // ------------- Typedefs for MDBox ------------------ /// Typedef for a MDBox with 1 dimension -typedef MDBox, 1> MDBox1Lean; +using MDBox1Lean = MDBox, 1>; /// Typedef for a MDBox with 2 dimensions -typedef MDBox, 2> MDBox2Lean; +using MDBox2Lean = MDBox, 2>; /// Typedef for a MDBox with 3 dimensions -typedef MDBox, 3> MDBox3Lean; +using MDBox3Lean = MDBox, 3>; /// Typedef for a MDBox with 4 dimensions -typedef MDBox, 4> MDBox4Lean; +using MDBox4Lean = MDBox, 4>; /// Typedef for a MDBox with 5 dimensions -typedef MDBox, 5> MDBox5Lean; +using MDBox5Lean = MDBox, 5>; /// Typedef for a MDBox with 6 dimensions -typedef MDBox, 6> MDBox6Lean; +using MDBox6Lean = MDBox, 6>; /// Typedef for a MDBox with 7 dimensions -typedef MDBox, 7> MDBox7Lean; +using MDBox7Lean = MDBox, 7>; /// Typedef for a MDBox with 8 dimensions -typedef MDBox, 8> MDBox8Lean; +using MDBox8Lean = MDBox, 8>; /// Typedef for a MDBox with 9 dimensions -typedef MDBox, 9> MDBox9Lean; +using MDBox9Lean = MDBox, 9>; /// Typedef for a MDBox with 1 dimension -typedef MDBox, 1> MDBox1; +using MDBox1 = MDBox, 1>; /// Typedef for a MDBox with 2 dimensions -typedef MDBox, 2> MDBox2; +using MDBox2 = MDBox, 2>; /// Typedef for a MDBox with 3 dimensions -typedef MDBox, 3> MDBox3; +using MDBox3 = MDBox, 3>; /// Typedef for a MDBox with 4 dimensions -typedef MDBox, 4> MDBox4; +using MDBox4 = MDBox, 4>; /// Typedef for a MDBox with 5 dimensions -typedef MDBox, 5> MDBox5; +using MDBox5 = MDBox, 5>; /// Typedef for a MDBox with 6 dimensions -typedef MDBox, 6> MDBox6; +using MDBox6 = MDBox, 6>; /// Typedef for a MDBox with 7 dimensions -typedef MDBox, 7> MDBox7; +using MDBox7 = MDBox, 7>; /// Typedef for a MDBox with 8 dimensions -typedef MDBox, 8> MDBox8; +using MDBox8 = MDBox, 8>; /// Typedef for a MDBox with 9 dimensions -typedef MDBox, 9> MDBox9; +using MDBox9 = MDBox, 9>; // ------------- Typedefs for MDBoxBase ------------------ /// Typedef for a MDBoxBase with 1 dimension -typedef MDBoxBase, 1> MDBoxBase1Lean; +using MDBoxBase1Lean = MDBoxBase, 1>; /// Typedef for a MDBoxBase with 2 dimensions -typedef MDBoxBase, 2> MDBoxBase2Lean; +using MDBoxBase2Lean = MDBoxBase, 2>; /// Typedef for a MDBoxBase with 3 dimensions -typedef MDBoxBase, 3> MDBoxBase3Lean; +using MDBoxBase3Lean = MDBoxBase, 3>; /// Typedef for a MDBoxBase with 4 dimensions -typedef MDBoxBase, 4> MDBoxBase4Lean; +using MDBoxBase4Lean = MDBoxBase, 4>; /// Typedef for a MDBoxBase with 5 dimensions -typedef MDBoxBase, 5> MDBoxBase5Lean; +using MDBoxBase5Lean = MDBoxBase, 5>; /// Typedef for a MDBoxBase with 6 dimensions -typedef MDBoxBase, 6> MDBoxBase6Lean; +using MDBoxBase6Lean = MDBoxBase, 6>; /// Typedef for a MDBoxBase with 7 dimensions -typedef MDBoxBase, 7> MDBoxBase7Lean; +using MDBoxBase7Lean = MDBoxBase, 7>; /// Typedef for a MDBoxBase with 8 dimensions -typedef MDBoxBase, 8> MDBoxBase8Lean; +using MDBoxBase8Lean = MDBoxBase, 8>; /// Typedef for a MDBoxBase with 9 dimensions -typedef MDBoxBase, 9> MDBoxBase9Lean; +using MDBoxBase9Lean = MDBoxBase, 9>; /// Typedef for a MDBoxBase with 1 dimension -typedef MDBoxBase, 1> MDBoxBase1; +using MDBoxBase1 = MDBoxBase, 1>; /// Typedef for a MDBoxBase with 2 dimensions -typedef MDBoxBase, 2> MDBoxBase2; +using MDBoxBase2 = MDBoxBase, 2>; /// Typedef for a MDBoxBase with 3 dimensions -typedef MDBoxBase, 3> MDBoxBase3; +using MDBoxBase3 = MDBoxBase, 3>; /// Typedef for a MDBoxBase with 4 dimensions -typedef MDBoxBase, 4> MDBoxBase4; +using MDBoxBase4 = MDBoxBase, 4>; /// Typedef for a MDBoxBase with 5 dimensions -typedef MDBoxBase, 5> MDBoxBase5; +using MDBoxBase5 = MDBoxBase, 5>; /// Typedef for a MDBoxBase with 6 dimensions -typedef MDBoxBase, 6> MDBoxBase6; +using MDBoxBase6 = MDBoxBase, 6>; /// Typedef for a MDBoxBase with 7 dimensions -typedef MDBoxBase, 7> MDBoxBase7; +using MDBoxBase7 = MDBoxBase, 7>; /// Typedef for a MDBoxBase with 8 dimensions -typedef MDBoxBase, 8> MDBoxBase8; +using MDBoxBase8 = MDBoxBase, 8>; /// Typedef for a MDBoxBase with 9 dimensions -typedef MDBoxBase, 9> MDBoxBase9; +using MDBoxBase9 = MDBoxBase, 9>; // ------------- Typedefs for MDGridBox ------------------ /// Typedef for a MDGridBox with 1 dimension -typedef MDGridBox, 1> MDGridBox1Lean; +using MDGridBox1Lean = MDGridBox, 1>; /// Typedef for a MDGridBox with 2 dimensions -typedef MDGridBox, 2> MDGridBox2Lean; +using MDGridBox2Lean = MDGridBox, 2>; /// Typedef for a MDGridBox with 3 dimensions -typedef MDGridBox, 3> MDGridBox3Lean; +using MDGridBox3Lean = MDGridBox, 3>; /// Typedef for a MDGridBox with 4 dimensions -typedef MDGridBox, 4> MDGridBox4Lean; +using MDGridBox4Lean = MDGridBox, 4>; /// Typedef for a MDGridBox with 5 dimensions -typedef MDGridBox, 5> MDGridBox5Lean; +using MDGridBox5Lean = MDGridBox, 5>; /// Typedef for a MDGridBox with 6 dimensions -typedef MDGridBox, 6> MDGridBox6Lean; +using MDGridBox6Lean = MDGridBox, 6>; /// Typedef for a MDGridBox with 7 dimensions -typedef MDGridBox, 7> MDGridBox7Lean; +using MDGridBox7Lean = MDGridBox, 7>; /// Typedef for a MDGridBox with 8 dimensions -typedef MDGridBox, 8> MDGridBox8Lean; +using MDGridBox8Lean = MDGridBox, 8>; /// Typedef for a MDGridBox with 9 dimensions -typedef MDGridBox, 9> MDGridBox9Lean; +using MDGridBox9Lean = MDGridBox, 9>; /// Typedef for a MDGridBox with 1 dimension -typedef MDGridBox, 1> MDGridBox1; +using MDGridBox1 = MDGridBox, 1>; /// Typedef for a MDGridBox with 2 dimensions -typedef MDGridBox, 2> MDGridBox2; +using MDGridBox2 = MDGridBox, 2>; /// Typedef for a MDGridBox with 3 dimensions -typedef MDGridBox, 3> MDGridBox3; +using MDGridBox3 = MDGridBox, 3>; /// Typedef for a MDGridBox with 4 dimensions -typedef MDGridBox, 4> MDGridBox4; +using MDGridBox4 = MDGridBox, 4>; /// Typedef for a MDGridBox with 5 dimensions -typedef MDGridBox, 5> MDGridBox5; +using MDGridBox5 = MDGridBox, 5>; /// Typedef for a MDGridBox with 6 dimensions -typedef MDGridBox, 6> MDGridBox6; +using MDGridBox6 = MDGridBox, 6>; /// Typedef for a MDGridBox with 7 dimensions -typedef MDGridBox, 7> MDGridBox7; +using MDGridBox7 = MDGridBox, 7>; /// Typedef for a MDGridBox with 8 dimensions -typedef MDGridBox, 8> MDGridBox8; +using MDGridBox8 = MDGridBox, 8>; /// Typedef for a MDGridBox with 9 dimensions -typedef MDGridBox, 9> MDGridBox9; +using MDGridBox9 = MDGridBox, 9>; // ------------- Typedefs for MDEventWorkspace ------------------ /// Typedef for a MDEventWorkspace with 1 dimension -typedef MDEventWorkspace, 1> MDEventWorkspace1Lean; +using MDEventWorkspace1Lean = MDEventWorkspace, 1>; /// Typedef for a MDEventWorkspace with 2 dimensions -typedef MDEventWorkspace, 2> MDEventWorkspace2Lean; +using MDEventWorkspace2Lean = MDEventWorkspace, 2>; /// Typedef for a MDEventWorkspace with 3 dimensions -typedef MDEventWorkspace, 3> MDEventWorkspace3Lean; +using MDEventWorkspace3Lean = MDEventWorkspace, 3>; /// Typedef for a MDEventWorkspace with 4 dimensions -typedef MDEventWorkspace, 4> MDEventWorkspace4Lean; +using MDEventWorkspace4Lean = MDEventWorkspace, 4>; /// Typedef for a MDEventWorkspace with 5 dimensions -typedef MDEventWorkspace, 5> MDEventWorkspace5Lean; +using MDEventWorkspace5Lean = MDEventWorkspace, 5>; /// Typedef for a MDEventWorkspace with 6 dimensions -typedef MDEventWorkspace, 6> MDEventWorkspace6Lean; +using MDEventWorkspace6Lean = MDEventWorkspace, 6>; /// Typedef for a MDEventWorkspace with 7 dimensions -typedef MDEventWorkspace, 7> MDEventWorkspace7Lean; +using MDEventWorkspace7Lean = MDEventWorkspace, 7>; /// Typedef for a MDEventWorkspace with 8 dimensions -typedef MDEventWorkspace, 8> MDEventWorkspace8Lean; +using MDEventWorkspace8Lean = MDEventWorkspace, 8>; /// Typedef for a MDEventWorkspace with 9 dimensions -typedef MDEventWorkspace, 9> MDEventWorkspace9Lean; +using MDEventWorkspace9Lean = MDEventWorkspace, 9>; /// Typedef for a MDEventWorkspace with 1 dimension -typedef MDEventWorkspace, 1> MDEventWorkspace1; +using MDEventWorkspace1 = MDEventWorkspace, 1>; /// Typedef for a MDEventWorkspace with 2 dimensions -typedef MDEventWorkspace, 2> MDEventWorkspace2; +using MDEventWorkspace2 = MDEventWorkspace, 2>; /// Typedef for a MDEventWorkspace with 3 dimensions -typedef MDEventWorkspace, 3> MDEventWorkspace3; +using MDEventWorkspace3 = MDEventWorkspace, 3>; /// Typedef for a MDEventWorkspace with 4 dimensions -typedef MDEventWorkspace, 4> MDEventWorkspace4; +using MDEventWorkspace4 = MDEventWorkspace, 4>; /// Typedef for a MDEventWorkspace with 5 dimensions -typedef MDEventWorkspace, 5> MDEventWorkspace5; +using MDEventWorkspace5 = MDEventWorkspace, 5>; /// Typedef for a MDEventWorkspace with 6 dimensions -typedef MDEventWorkspace, 6> MDEventWorkspace6; +using MDEventWorkspace6 = MDEventWorkspace, 6>; /// Typedef for a MDEventWorkspace with 7 dimensions -typedef MDEventWorkspace, 7> MDEventWorkspace7; +using MDEventWorkspace7 = MDEventWorkspace, 7>; /// Typedef for a MDEventWorkspace with 8 dimensions -typedef MDEventWorkspace, 8> MDEventWorkspace8; +using MDEventWorkspace8 = MDEventWorkspace, 8>; /// Typedef for a MDEventWorkspace with 9 dimensions -typedef MDEventWorkspace, 9> MDEventWorkspace9; +using MDEventWorkspace9 = MDEventWorkspace, 9>; // ------------- Typedefs for MDBin ------------------ /// Typedef for a MDBin with 1 dimension -typedef MDBin, 1> MDBin1Lean; +using MDBin1Lean = MDBin, 1>; /// Typedef for a MDBin with 2 dimensions -typedef MDBin, 2> MDBin2Lean; +using MDBin2Lean = MDBin, 2>; /// Typedef for a MDBin with 3 dimensions -typedef MDBin, 3> MDBin3Lean; +using MDBin3Lean = MDBin, 3>; /// Typedef for a MDBin with 4 dimensions -typedef MDBin, 4> MDBin4Lean; +using MDBin4Lean = MDBin, 4>; /// Typedef for a MDBin with 5 dimensions -typedef MDBin, 5> MDBin5Lean; +using MDBin5Lean = MDBin, 5>; /// Typedef for a MDBin with 6 dimensions -typedef MDBin, 6> MDBin6Lean; +using MDBin6Lean = MDBin, 6>; /// Typedef for a MDBin with 7 dimensions -typedef MDBin, 7> MDBin7Lean; +using MDBin7Lean = MDBin, 7>; /// Typedef for a MDBin with 8 dimensions -typedef MDBin, 8> MDBin8Lean; +using MDBin8Lean = MDBin, 8>; /// Typedef for a MDBin with 9 dimensions -typedef MDBin, 9> MDBin9Lean; +using MDBin9Lean = MDBin, 9>; /// Typedef for a MDBin with 1 dimension -typedef MDBin, 1> MDBin1; +using MDBin1 = MDBin, 1>; /// Typedef for a MDBin with 2 dimensions -typedef MDBin, 2> MDBin2; +using MDBin2 = MDBin, 2>; /// Typedef for a MDBin with 3 dimensions -typedef MDBin, 3> MDBin3; +using MDBin3 = MDBin, 3>; /// Typedef for a MDBin with 4 dimensions -typedef MDBin, 4> MDBin4; +using MDBin4 = MDBin, 4>; /// Typedef for a MDBin with 5 dimensions -typedef MDBin, 5> MDBin5; +using MDBin5 = MDBin, 5>; /// Typedef for a MDBin with 6 dimensions -typedef MDBin, 6> MDBin6; +using MDBin6 = MDBin, 6>; /// Typedef for a MDBin with 7 dimensions -typedef MDBin, 7> MDBin7; +using MDBin7 = MDBin, 7>; /// Typedef for a MDBin with 8 dimensions -typedef MDBin, 8> MDBin8; +using MDBin8 = MDBin, 8>; /// Typedef for a MDBin with 9 dimensions -typedef MDBin, 9> MDBin9; +using MDBin9 = MDBin, 9>; /* CODE ABOWE WAS AUTO-GENERATED BY generate_mdevent_declarations.py - DO NOT * EDIT! */ diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h index db2057aa2b56..4fd01d327a01 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventInserter.h @@ -50,7 +50,7 @@ template class DLLExport MDEventInserter { public: /// Type of MDEvent used by the MDEventWorkspace. - typedef typename MDEW_SPTR::element_type::MDEventType MDEventType; + using MDEventType = typename MDEW_SPTR::element_type::MDEventType; /** Constructor diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h index 92669de6c7df..3c95e81fc0b9 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h @@ -35,9 +35,9 @@ class DLLExport MDEventWorkspace : public API::IMDEventWorkspace { public: /// Typedef for a shared pointer of this kind of event workspace - typedef boost::shared_ptr> sptr; + using sptr = boost::shared_ptr >; /// Typedef to access the MDEventType. - typedef MDE MDEventType; + using MDEventType = MDE; MDEventWorkspace(Mantid::API::MDNormalization preferredNormalization = Mantid::API::MDNormalization::VolumeNormalization, diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc index 4db8da03a561..e1e125b7e903 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc @@ -493,7 +493,7 @@ TMDE(Mantid::API::ITableWorkspace_sptr MDEventWorkspace)::makeBoxTable( } // Now sort by ID - typedef MDBoxBase *ibox_t; + using ibox_t = MDBoxBase *; std::sort(boxes_filtered.begin(), boxes_filtered.end(), SortBoxesByID); diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h index c45eda990df0..18f6d303ae43 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h @@ -205,10 +205,10 @@ class DLLExport MDGridBox : public MDBoxBase { public: /// Typedef for a shared pointer to a MDGridBox - typedef boost::shared_ptr> sptr; + using sptr = boost::shared_ptr >; /// Typedef for a vector of MDBoxBase pointers - typedef std::vector *> boxVector_t; + using boxVector_t = std::vector *>; private: /// Compute the index of the child box for the given event diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h index 5c4839ad64ce..2b4fcd178c1f 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h @@ -499,10 +499,10 @@ class DLLExport MDHistoWorkspace : public API::IMDHistoWorkspace { }; /// A shared pointer to a MDHistoWorkspace -typedef boost::shared_ptr MDHistoWorkspace_sptr; +using MDHistoWorkspace_sptr = boost::shared_ptr; /// A shared pointer to a const MDHistoWorkspace -typedef boost::shared_ptr MDHistoWorkspace_const_sptr; +using MDHistoWorkspace_const_sptr = boost::shared_ptr; } // namespace Mantid } // namespace DataObjects diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h index 6ff675621f9f..81aff98e9501 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h @@ -15,12 +15,11 @@ namespace DataObjects { // Typedef for a map for mapping width of neighbours (key) to permutations // needed in the calcualtion. -typedef std::map, std::vector> PermutationsMap; +using PermutationsMap = std::map, std::vector >; // Typedef for extents -typedef boost::tuple - MDExtentPair; // Min/Max pair +using MDExtentPair = boost::tuple; // Min/Max pair // Typedef for vector of extents -typedef std::vector VecMDExtents; +using VecMDExtents = std::vector; /** An implementation of IMDIterator that iterates through a MDHistoWorkspace. It treats the bin in the workspace as diff --git a/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h index a71caabb1c74..5304998b667c 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MaskWorkspace.h @@ -64,10 +64,10 @@ class DLLExport MaskWorkspace : public SpecialWorkspace2D, }; /// shared pointer to the MaskWorkspace class -typedef boost::shared_ptr MaskWorkspace_sptr; +using MaskWorkspace_sptr = boost::shared_ptr; /// shared pointer to a const MaskWorkspace -typedef boost::shared_ptr MaskWorkspace_const_sptr; +using MaskWorkspace_const_sptr = boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h index b3108ad69bb3..4b7fcfffa40e 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/OffsetsWorkspace.h @@ -48,10 +48,10 @@ class DLLExport OffsetsWorkspace : public SpecialWorkspace2D { }; /// shared pointer to the OffsetsWorkspace class -typedef boost::shared_ptr OffsetsWorkspace_sptr; +using OffsetsWorkspace_sptr = boost::shared_ptr; /// shared pointer to a const OffsetsWorkspace -typedef boost::shared_ptr OffsetsWorkspace_const_sptr; +using OffsetsWorkspace_const_sptr = boost::shared_ptr; } // namespace Mantid } // namespace DataObjects diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h b/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h index 95384de57acf..9f4c6beb8171 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h +++ b/Framework/DataObjects/inc/MantidDataObjects/PeakColumn.h @@ -78,7 +78,7 @@ class DLLExport PeakColumn : public Mantid::API::Column { int m_hklPrec; /// Type of the row cache value - typedef boost::variant CacheValueType; + using CacheValueType = boost::variant; /// mutable std::list m_oldRows; /// Sets the correct value in the referenced peak. diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h index da9a6b7730aa..e016c03afef1 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h +++ b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h @@ -79,9 +79,8 @@ class DLLExport PeakShapeEllipsoid : public PeakShapeBase { std::vector m_abc_radiiBackgroundOuter; }; -typedef boost::shared_ptr PeakShapeEllipsoid_sptr; -typedef boost::shared_ptr - PeakShapeEllipsoid_const_sptr; +using PeakShapeEllipsoid_sptr = boost::shared_ptr; +using PeakShapeEllipsoid_const_sptr = boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h index 020b05598dba..ae24f173e2d5 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h +++ b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeFactory.h @@ -48,9 +48,9 @@ class DLLExport PeakShapeFactory { }; /// Helper typedef -typedef boost::shared_ptr PeakShapeFactory_sptr; +using PeakShapeFactory_sptr = boost::shared_ptr; /// Helper typedef -typedef boost::shared_ptr PeakShapeFactory_const_sptr; +using PeakShapeFactory_const_sptr = boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h index bc2af2cc06c1..055b61169a34 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h @@ -295,10 +295,10 @@ class DLLExport PeaksWorkspace : public Mantid::API::IPeaksWorkspace { }; /// Typedef for a shared pointer to a peaks workspace. -typedef boost::shared_ptr PeaksWorkspace_sptr; +using PeaksWorkspace_sptr = boost::shared_ptr; /// Typedef for a shared pointer to a const peaks workspace. -typedef boost::shared_ptr PeaksWorkspace_const_sptr; +using PeaksWorkspace_const_sptr = boost::shared_ptr; } } #endif diff --git a/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h b/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h index 312b03d2be14..40f0aa5e3974 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h +++ b/Framework/DataObjects/inc/MantidDataObjects/RebinnedOutput.h @@ -97,9 +97,9 @@ class DLLExport RebinnedOutput : public Workspace2D { }; /// shared pointer to the RebinnedOutput class -typedef boost::shared_ptr RebinnedOutput_sptr; +using RebinnedOutput_sptr = boost::shared_ptr; /// shared pointer to a const RebinnedOutput -typedef boost::shared_ptr RebinnedOutput_const_sptr; +using RebinnedOutput_const_sptr = boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h b/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h index 9f85163383ed..83e5f2cb2e6e 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h +++ b/Framework/DataObjects/inc/MantidDataObjects/ReflectometryTransform.h @@ -123,7 +123,7 @@ MANTID_DATAOBJECTS_DLL DetectorAngularCache initAngularCaches(const Mantid::API::MatrixWorkspace *const workspace); // Helper typedef for scoped pointer of this type. -typedef boost::shared_ptr ReflectometryTransform_sptr; +using ReflectometryTransform_sptr = boost::shared_ptr; } } #endif diff --git a/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h b/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h index 8762bb00b73d..294892336ce9 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h +++ b/Framework/DataObjects/inc/MantidDataObjects/SkippingPolicy.h @@ -66,7 +66,7 @@ class DLLExport SkipNothing : public SkippingPolicy { bool keepGoing() const override { return false; } }; -typedef boost::scoped_ptr SkippingPolicy_scptr; +using SkippingPolicy_scptr = boost::scoped_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h b/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h index 651e261f3ce0..bf1db875535d 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h +++ b/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h @@ -89,11 +89,10 @@ class DLLExport SpecialWorkspace2D : public Workspace2D { }; /// shared pointer to the SpecialWorkspace2D class -typedef boost::shared_ptr SpecialWorkspace2D_sptr; +using SpecialWorkspace2D_sptr = boost::shared_ptr; /// shared pointer to a const SpecialWorkspace2D -typedef boost::shared_ptr - SpecialWorkspace2D_const_sptr; +using SpecialWorkspace2D_const_sptr = boost::shared_ptr; } // namespace Mantid } // namespace DataObjects diff --git a/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h index ac998ac153f2..f58f040c931f 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h @@ -81,9 +81,8 @@ class DLLExport SplittersWorkspace : public DataObjects::TableWorkspace, } }; -typedef boost::shared_ptr SplittersWorkspace_sptr; -typedef boost::shared_ptr - SplittersWorkspace_const_sptr; +using SplittersWorkspace_sptr = boost::shared_ptr; +using SplittersWorkspace_const_sptr = boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h index eee53c5d06d2..f475a2c29925 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h @@ -142,9 +142,7 @@ template class TableColumn : public API::Column { * @param value :: The value of the element. */ template double convertToDouble(const T &value) const { - typedef - typename std::conditional::value, T, - InconvertibleToDoubleType>::type DoubleType; + using DoubleType = typename std::conditional::value, T, InconvertibleToDoubleType>::type; return boost::numeric_cast(value); } @@ -175,9 +173,7 @@ template class TableColumn : public API::Column { * @param value: cast this value */ void fromDouble(size_t i, double value) override { - typedef typename std::conditional::value, - Type, InconvertibleToDoubleType>::type - DoubleType; + using DoubleType = typename std::conditional::value, Type, InconvertibleToDoubleType>::type; m_data[i] = static_cast(boost::numeric_cast(value)); } diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h index 20fa71db955e..88039b9cdc5b 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h @@ -410,10 +410,8 @@ class MANTID_DATAOBJECTS_DLL TableWorkspace : public API::ITableWorkspace { } }; - typedef std::vector>::iterator - column_it; ///< Column iterator - typedef std::vector>::const_iterator - column_const_it; ///< Column const iterator + using column_it = std::vector >::iterator; ///< Column iterator + using column_const_it = std::vector >::const_iterator; ///< Column const iterator /// Shared pointers to the columns. std::vector> m_columns; /// row count @@ -425,9 +423,9 @@ class MANTID_DATAOBJECTS_DLL TableWorkspace : public API::ITableWorkspace { }; /// Typedef for a shared pointer to \c TableWorkspace -typedef boost::shared_ptr TableWorkspace_sptr; +using TableWorkspace_sptr = boost::shared_ptr; /// Typedef for a shared pointer to \c const \c TableWorkspace -typedef boost::shared_ptr TableWorkspace_const_sptr; +using TableWorkspace_const_sptr = boost::shared_ptr; } // namespace DataObjects } // Namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h b/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h index 7e5a075d581f..4eda3b3d6655 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h +++ b/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h @@ -118,9 +118,9 @@ class DLLExport Workspace2D : public API::HistoWorkspace { }; /// shared pointer to the Workspace2D class -typedef boost::shared_ptr Workspace2D_sptr; +using Workspace2D_sptr = boost::shared_ptr; /// shared pointer to a const Workspace2D -typedef boost::shared_ptr Workspace2D_const_sptr; +using Workspace2D_const_sptr = boost::shared_ptr; } // namespace DataObjects } // Namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h index 343e7f218e1d..d899d2bdb16a 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h +++ b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h @@ -96,9 +96,8 @@ class DLLExport WorkspaceSingleValue : public API::HistoWorkspace { }; /// shared pointer to the WorkspaceSingleValue class -typedef boost::shared_ptr WorkspaceSingleValue_sptr; -typedef boost::shared_ptr - WorkspaceSingleValue_const_sptr; +using WorkspaceSingleValue_sptr = boost::shared_ptr; +using WorkspaceSingleValue_const_sptr = boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/src/AffineMatrixParameterParser.cpp b/Framework/DataObjects/src/AffineMatrixParameterParser.cpp index 0f60ea75a535..bdae316f1676 100644 --- a/Framework/DataObjects/src/AffineMatrixParameterParser.cpp +++ b/Framework/DataObjects/src/AffineMatrixParameterParser.cpp @@ -17,8 +17,8 @@ AffineMatrixParameter *AffineMatrixParameterParser::createParameter( typeName)); } else { // Convenience typedefs - typedef std::vector VecStrings; - typedef std::vector VecDoubles; + using VecStrings = std::vector; + using VecDoubles = std::vector; std::string sParameterValue = parameterElement->getChildElement("Value")->innerText(); diff --git a/Framework/DataObjects/src/CoordTransformAffineParser.cpp b/Framework/DataObjects/src/CoordTransformAffineParser.cpp index a6acc7ad9ca2..e5d3683ce065 100644 --- a/Framework/DataObjects/src/CoordTransformAffineParser.cpp +++ b/Framework/DataObjects/src/CoordTransformAffineParser.cpp @@ -20,10 +20,8 @@ Create the transform object. */ Mantid::API::CoordTransform *CoordTransformAffineParser::createTransform( Poco::XML::Element *coordTransElement) const { - typedef Mantid::API::SingleValueParameterParser - InDimParameterParser; - typedef Mantid::API::SingleValueParameterParser - OutDimParameterParser; + using InDimParameterParser = Mantid::API::SingleValueParameterParser; + using OutDimParameterParser = Mantid::API::SingleValueParameterParser; using namespace Poco::XML; if ("CoordTransform" != coordTransElement->localName()) { std::string message = "This is not a coordinate transform element: " + diff --git a/Framework/DataObjects/src/CoordTransformDistanceParser.cpp b/Framework/DataObjects/src/CoordTransformDistanceParser.cpp index 5d2e2c963f33..869cd0fc04c6 100644 --- a/Framework/DataObjects/src/CoordTransformDistanceParser.cpp +++ b/Framework/DataObjects/src/CoordTransformDistanceParser.cpp @@ -17,14 +17,10 @@ Create the transform object. Mantid::API::CoordTransform *CoordTransformDistanceParser::createTransform( Poco::XML::Element *coordTransElement) const { // Typdef the parameter parsers required. - typedef Mantid::API::SingleValueParameterParser - InDimParameterParser; - typedef Mantid::API::SingleValueParameterParser - OutDimParameterParser; - typedef Mantid::API::VectorParameterParser - CoordCenterParser; - typedef Mantid::API::VectorParameterParser - DimsUsedParser; + using InDimParameterParser = Mantid::API::SingleValueParameterParser; + using OutDimParameterParser = Mantid::API::SingleValueParameterParser; + using CoordCenterParser = Mantid::API::VectorParameterParser; + using DimsUsedParser = Mantid::API::VectorParameterParser; using namespace Poco::XML; if ("CoordTransform" != coordTransElement->localName()) { diff --git a/Framework/DataObjects/src/FakeMD.cpp b/Framework/DataObjects/src/FakeMD.cpp index 9de20b32894d..8a8d88ce3867 100644 --- a/Framework/DataObjects/src/FakeMD.cpp +++ b/Framework/DataObjects/src/FakeMD.cpp @@ -236,8 +236,7 @@ void FakeMD::addFakeRandomData(const std::vector ¶ms, genUnit(rng, u2); // Make a random generator for each dimensions - typedef boost::variate_generator> gen_t; + using gen_t = boost::variate_generator >; // Inserter to help choose the correct event type auto eventHelper = @@ -365,8 +364,7 @@ detid_t FakeMD::pickDetectorID() { } else { /// A variate generator to combine a random number generator with a /// distribution - typedef boost::variate_generator< - boost::mt19937 &, boost::uniform_int> uniform_generator; + using uniform_generator = boost::variate_generator >; uniform_generator uniformRand(m_randGen, m_uniformDist); const size_t randIndex = uniformRand(); return m_detIDs[randIndex]; diff --git a/Framework/DataObjects/src/MDBoxFlatTree.cpp b/Framework/DataObjects/src/MDBoxFlatTree.cpp index 7a9232e17ff2..aa705020ca0a 100644 --- a/Framework/DataObjects/src/MDBoxFlatTree.cpp +++ b/Framework/DataObjects/src/MDBoxFlatTree.cpp @@ -8,7 +8,7 @@ #include "MantidKernel/Strings.h" #include -typedef std::unique_ptr<::NeXus::File> file_holder_type; +using file_holder_type = std::unique_ptr< ::NeXus::File>; namespace Mantid { namespace DataObjects { diff --git a/Framework/DataObjects/test/MDBinTest.h b/Framework/DataObjects/test/MDBinTest.h index 451ddc9e0744..00eb8ed17b76 100644 --- a/Framework/DataObjects/test/MDBinTest.h +++ b/Framework/DataObjects/test/MDBinTest.h @@ -13,7 +13,7 @@ using namespace Mantid::DataObjects; class MDBinTest : public CxxTest::TestSuite { public: void test_constructor() { - typedef MDLeanEvent<3> MDE; + using MDE = MDLeanEvent<3>; MDBin bin; for (size_t d = 0; d < 3; d++) { TS_ASSERT_EQUALS(bin.m_min[d], -std::numeric_limits::max()); diff --git a/Framework/DataObjects/test/MDBoxBaseTest.h b/Framework/DataObjects/test/MDBoxBaseTest.h index a5b1c1e0ed8c..046b09bca0a4 100644 --- a/Framework/DataObjects/test/MDBoxBaseTest.h +++ b/Framework/DataObjects/test/MDBoxBaseTest.h @@ -161,7 +161,7 @@ class MDBoxBaseTest : public CxxTest::TestSuite { } void test_extents_constructor() { - typedef MDBoxBaseTester, 3> ibox3; + using ibox3 = MDBoxBaseTester, 3>; std::vector> extentsVector; TS_ASSERT_THROWS_ANYTHING(ibox3 box(extentsVector)); extentsVector.resize(3); @@ -179,7 +179,7 @@ class MDBoxBaseTest : public CxxTest::TestSuite { } void test_transformDimensions() { - typedef MDBoxBaseTester, 2> ibox3; + using ibox3 = MDBoxBaseTester, 2>; std::vector> extentsVector; TS_ASSERT_THROWS_ANYTHING(ibox3 box(extentsVector)); extentsVector.resize(2); diff --git a/Framework/DataObjects/test/MDBoxIteratorTest.h b/Framework/DataObjects/test/MDBoxIteratorTest.h index 6654f3fcac89..1ee036378ca7 100644 --- a/Framework/DataObjects/test/MDBoxIteratorTest.h +++ b/Framework/DataObjects/test/MDBoxIteratorTest.h @@ -26,8 +26,8 @@ using Mantid::Geometry::MDBoxImplicitFunction; class MDBoxIteratorTest : public CxxTest::TestSuite { public: - typedef MDGridBox, 1> gbox_t; - typedef MDBoxBase, 1> ibox_t; + using gbox_t = MDGridBox, 1>; + using ibox_t = MDBoxBase, 1>; //-------------------------------------------------------------------------------------- /** Make a gridded box with this structure: @@ -82,7 +82,7 @@ class MDBoxIteratorTest : public CxxTest::TestSuite { //-------------------------------------------------------------------------------------- void test_ctor_with_null_box_fails() { - typedef MDBoxIterator, 1> boxit_t; + using boxit_t = MDBoxIterator, 1>; TS_ASSERT_THROWS_ANYTHING(new boxit_t(NULL, 10, false);); } diff --git a/Framework/DataObjects/test/MDBoxSaveableTest.h b/Framework/DataObjects/test/MDBoxSaveableTest.h index f2da62d402ac..12c374388df1 100644 --- a/Framework/DataObjects/test/MDBoxSaveableTest.h +++ b/Framework/DataObjects/test/MDBoxSaveableTest.h @@ -795,7 +795,7 @@ class MDBoxSaveableTest : public CxxTest::TestSuite { */ void test_splitAllIfNeeded_fileBacked() { using Mantid::DataObjects::BoxControllerNeXusIO; - typedef MDLeanEvent<2> MDE; + using MDE = MDLeanEvent<2>; // Create the grid box and make it file-backed. MDBoxBase *b = MDEventsTestHelper::makeMDGridBox<2>(); diff --git a/Framework/DataObjects/test/MDBoxTest.h b/Framework/DataObjects/test/MDBoxTest.h index 2f6391b05381..dc7ea136be9a 100644 --- a/Framework/DataObjects/test/MDBoxTest.h +++ b/Framework/DataObjects/test/MDBoxTest.h @@ -365,15 +365,14 @@ class MDBoxTest : public CxxTest::TestSuite { } void test_sptr() { - typedef MDBox, 3> mdbox3; + using mdbox3 = MDBox, 3>; TS_ASSERT_THROWS_NOTHING(mdbox3::sptr a(new mdbox3(sc.get()));) } void test_bad_splitter() { BoxController_sptr sc(new BoxController(4)); sc->setSplitThreshold(10); - typedef MDBox, 3> - MACROS_ARE_DUMB; //...since they get confused by commas + using MACROS_ARE_DUMB = MDBox, 3>; //...since they get confused by commas TS_ASSERT_THROWS(MACROS_ARE_DUMB b3(sc.get()), std::invalid_argument); } diff --git a/Framework/DataObjects/test/MDEventInserterTest.h b/Framework/DataObjects/test/MDEventInserterTest.h index 8caccd71a86f..3defd0f38041 100644 --- a/Framework/DataObjects/test/MDEventInserterTest.h +++ b/Framework/DataObjects/test/MDEventInserterTest.h @@ -52,7 +52,7 @@ class MDEventInserterTest : public CxxTest::TestSuite { static void destroySuite(MDEventInserterTest *suite) { delete suite; } void test_add_md_lean_events() { - typedef MDEventWorkspace, 2> MDEW_LEAN_2D; + using MDEW_LEAN_2D = MDEventWorkspace, 2>; // Check the type deduction used internally in the MDEventInserter template. TS_ASSERT_EQUALS(sizeof(MDEW_LEAN_2D::MDEventType), @@ -84,7 +84,7 @@ class MDEventInserterTest : public CxxTest::TestSuite { } void test_add_md_full_events() { - typedef MDEventWorkspace, 2> MDEW_2D; + using MDEW_2D = MDEventWorkspace, 2>; // Check the type deduction used internally in the MDEventInserter template. TS_ASSERT_EQUALS(sizeof(MDEW_2D::MDEventType), diff --git a/Framework/DataObjects/test/MDGridBoxTest.h b/Framework/DataObjects/test/MDGridBoxTest.h index d2e98dbe7adb..0ae4ef00585b 100644 --- a/Framework/DataObjects/test/MDGridBoxTest.h +++ b/Framework/DataObjects/test/MDGridBoxTest.h @@ -987,9 +987,9 @@ class MDGridBoxTest : public CxxTest::TestSuite { * further. * */ void test_splitAllIfNeeded() { - typedef MDGridBox, 2> gbox_t; - typedef MDBox, 2> box_t; - typedef MDBoxBase, 2> ibox_t; + using gbox_t = MDGridBox, 2>; + using box_t = MDBox, 2>; + using ibox_t = MDBoxBase, 2>; gbox_t *b0 = MDEventsTestHelper::makeMDGridBox<2>(); b0->getBoxController()->setSplitThreshold(100); @@ -1051,8 +1051,8 @@ class MDGridBoxTest : public CxxTest::TestSuite { * to use all cores. */ void test_splitAllIfNeeded_usingThreadPool() { - typedef MDGridBox, 2> gbox_t; - typedef MDBoxBase, 2> ibox_t; + using gbox_t = MDGridBox, 2>; + using ibox_t = MDBoxBase, 2>; gbox_t *b = MDEventsTestHelper::makeMDGridBox<2>(); b->getBoxController()->setSplitThreshold(100); @@ -1135,7 +1135,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { //------------------------------------------------------------------------------------------------ /** Test binning in orthogonal axes */ void test_centerpointBin() { - typedef MDGridBox, 2> gbox_t; + using gbox_t = MDGridBox, 2>; // 10x10 bins, 2 events per bin, each weight of 1.0 gbox_t *b = MDEventsTestHelper::makeMDGridBox<2>(); From 7fcb5f269bdf9d674e8b81ebab8cdc555a5dea55 Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Wed, 14 Mar 2018 13:50:18 +0000 Subject: [PATCH 199/364] Added New/Improved/Fix headings --- docs/source/release/v3.12.0/framework.rst | 77 ++++++++++++++++------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst index 838e12ae47ae..da0a70005d31 100644 --- a/docs/source/release/v3.12.0/framework.rst +++ b/docs/source/release/v3.12.0/framework.rst @@ -5,32 +5,33 @@ Framework Changes .. contents:: Table of Contents :local: -.. warning:: **Developers:** Sort changes under appropriate heading. - Put new features at the top of the section, followed by - improvements, followed by bug fixes. - Instrument Definition Updates ----------------------------- - The MAPS IDF has been updated following its upgrade. -Concepts --------- Instrument Definitions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +###################### .. warning:: **Users:** Instruments in Mantid will no longer silently discard detectors defined with duplicate IDs. This has been a long-standing source of hard to find issue in Mantid. We have endeavoured to ensure that all :ref:`Instrument Definition Files ` shipped with Mantid are now corrected. **If you have local IDFs, please update them to remove any duplicate IDs, or ask the Mantid Team for help**, the warning and error information in Mantid will give details about duplicates in IDFs that cannot be loaded. Beware that :ref:`LoadNexusProcessed ` will now **NOT load the Instrument from historic Processed Nexus files if the embedded IDF is corruped with duplicate detector IDs**. The workspace (data) part will still load, but the workspace will not have any Instrument attached. There are new warnings generated that describe the exact problem and the remedy when this happens. Note that the fix is generally easy. You should be able to run :ref:`LoadInstrument ` on the Workspace, pointing it to an updated IDF, which is free of duplicates. Please contact the Mantid Team if you experience any further problems as a result of these changes. + Algorithms ---------- + +New +### - :ref:`MostLikelyMean ` is a new algorithm that computes the mean of the given array, that has the least distance from the rest of the elements. - :ref:`LoadAndMerge ` is a new algorithm that can load and merge multiple runs. - :ref:`CropWorkspaceRagged `: New algorithm that will crop each spectrum with a different x-range. - :ref:`LoadLamp `: New algorithm to load processed HDF5 files produced by LAMP program at ILL. - :ref:`SaveReflections ` is a new algorithm to save PeaksWorkspaces to Fullprof, Jana, GSAS, and SHELX text formats. + +Improved +######## - :ref:`NormaliseToMonitor ` now supports workspaces with detector scans and workspaces with single-count point data. - :ref:`CalculatePolynomialBackground `: It is now possible to choose between weighted and unweighted fitting. - :ref:`CreateWorkspace ` will no longer create a default (and potentially wrong) mapping from spectra to detectors, unless a parent workspace is given. This change ensures that accidental bad mappings that could lead to corrupted data are not created silently anymore. This change does *not* affect the use of this algorithm if: (1) a parent workspace is given, or (2) no instrument is loaded into to workspace at a later point, or (3) an instrument is loaded at a later point but ``LoadInstrument`` is used with ``RewriteSpectraMapping=True``. See also the algorithm documentation for details. @@ -44,14 +45,14 @@ Algorithms - :ref:`SaveNexus ` will no longer crash when passed a ``PeaksWorkspace`` with integrated peaks that have missing radius information. - :ref:`ConjoinXRuns ` will now accept workspaces with varying x-axes per spectrum. - :ref:`LoadEXED ` has better handling of monitor workspace and sample logs. + +Bugfixes +######## - :ref:`Fit ` has had a bug fixed that prevented a fix from being removed. - :ref:`LoadMask ` has had a bug fixed that could, under certain conditions, cause detectors from previously loaded masking to be added to the currently loaded masking. - - Known Issues -^^^^^^^^^^^^ - +############ - :ref:`LoadEventNexus ` is incorrectly ignoring the `FilterMonBy*` properties. When loading monitors as events the output `*_monitors` workspace then contains all recorded events rather than those accepted by the filters. To work around this issue run the :ref:`FilterByTime ` algorithm on the output `*_monitors` workspace with the same values as passed to the `FilterMonBy*` @@ -59,56 +60,84 @@ Known Issues Fitting ------- +Improved +######## - :ref:`EISFDiffSphere ` fits the Q-dependence on the EISF of a particle undergoing continuous diffusion but confined to a spherical volume. - :ref:`EISFDiffSphereAlkyl ` fits the Q-dependence on the EISF of an alkyl molecule, like a membrane lipd. - :ref:`EISFDiffCylinder ` models the elastic incoherent scattering intensity of a particle diffusing within a cylinder. + +Bugfixes +######## - Fix for a bug in calculating numerical derivatives by applying ties correctly. Core Functionality ------------------ +New +### +- Added new classes ``ConfigObserver`` for listening for changes to any configuration property and ``ConfigPropertyObserver`` for listening to changes to an individual config property of interest. + +Improved +######## - :class:`mantid.kernel.FloatTimeSeriesProperty` now returns :class:`numpy.datetime64` for the log times. - The duration reported by a running algorithm now includes time spent for validation of properties and inputs. This fixes a discrepancy between observed and reported timings if validation is expensive, e.g., when checking if a file exists. More detailed timing information is now available when setting the log level to ``debug``. -- Fixed an issue where certain isotopes could not be accessed using the `Atom` classes, e.g Si28. -- ``datasearch.searcharchive`` :ref:`property ` has new functionality to only search the default facility. - The status of a fit in the fit window is now at the top of the of the dialog instead of the bottom. - Condition to check if a property is enabled when serializing. - Workspace locking no longer prevents simple read operations required to display the workspace conext menu in Mantidplot. - TableWorkspaces can now be converted to a Python dictionary by calling the ``table.toDict()`` function. -- Added new classes ``ConfigObserver`` for listening for changes to any configuration property and ``ConfigPropertyObserver`` for listening to changes to an individual config property of interest. +- ``MultiFileProperty`` now accepts complex summation ranges for run numbers, such as ``111-113+115`` and ``111-115+123-132``. + +Bugfixes +######## +- Fixed an issue where certain isotopes could not be accessed using the `Atom` classes, e.g Si28. +- ``datasearch.searcharchive`` :ref:`property ` has new functionality to only search the default facility. - Fixed the calculation of scattering length and scattering length squared for :py:obj:`Material `. - Fixed the behaviour of ``UpdateInstrumentDefinitions.OnStartup`` in the :ref:`properties file `. It was not being used correctly for using the updated ``Facilities.xml`` file. -- ``MultiFileProperty`` now accepts complex summation ranges for run numbers, such as ``111-113+115`` and ``111-115+123-132``. + Live Data --------- +New +### - ``KafkaEventListener`` is a new live listener for neutron event and sample environment data which is in development for the ESS and ISIS. Performance ----------- +Improved +######## - :ref:`LoadEmptyInstrument ` and load algorithms that are using it. Improved performance for second and consecutive loads of instrument geometry, particularly for instruments with many detector pixels. - :ref:`CropToComponent `: Up to 30% performance improvement, based on ongoing work on Instrument-2.0. - :ref:`MaxEnt `: Improved rate of convergence. The ``ChiTarget`` property has been replaced by ``ChiTargetOverN``. + +Bugfixes +######## - A `bug `_ in the handling of fractional bin weights in a specialised form (`RebinnedOutput `_) of :ref:`Workspace2D ` has been fixed. This mainly affects the algorithms :ref:`algm-SofQWNormalisedPolygon` and :ref:`algm-Rebin2D`, which underlies the `SliceViewer `_. Python ------ -In ``mantid.simpleapi``, a keyword has been implemented for function-like algorithm calls to control the storing on the Analysis Data Service. -``StoreInADS=False`` can be passed to function calls to not to store their output on the ADS. -- The standard Python operators, e.g. ``+``, ``+=``, etc., now work also with workspaces not in the ADS. -- The ``isDefault`` attribute for workspace properties now works correctly with workspaces not in the ADS. -- The previously mentioned ``ConfigObserver`` and ``ConfigPropertyObserver`` classes are also exposed to python. -- ``mantid.kernel.V3D`` vectors now support negation through the usual ``-`` operator. -- It is now possible to `pickle `_ and de-pickle :ref:`Workspace2D ` and :ref:`TableWorkspace ` in Python. This has been added to make it easier to transfer your workspaces over a network. Only these two workspace types currently supports the pickling process, and there are limitations to be aware of described :ref:`here `. +New +### - ``mantid.api.IPeak`` has three new functions: - ``getEnergyTransfer`` which returns the difference between the initial and final energy. - ``getIntensityOverSigma`` which returns the peak intensity divided by the error in intensity. - ``getGoniometerMatrix`` which returns the goniometer rotation matrix associated with the peak. -Support for unicode property names has been added to python. This means that one can run the following in python2 or python3. + +Improved +######## + + +- In ``mantid.simpleapi``, a keyword has been implemented for function-like algorithm calls to control the storing on the Analysis Data Service. +``StoreInADS=False`` can be passed to function calls to not to store their output on the ADS. +- The standard Python operators, e.g. ``+``, ``+=``, etc., now work also with workspaces not in the ADS. +- The ``isDefault`` attribute for workspace properties now works correctly with workspaces not in the ADS. +- The previously mentioned ``ConfigObserver`` and ``ConfigPropertyObserver`` classes are also exposed to Python. +- ``mantid.kernel.V3D`` vectors now support negation through the usual ``-`` operator. +- It is now possible to `pickle `_ and de-pickle :ref:`Workspace2D ` and :ref:`TableWorkspace
` in Python. This has been added to make it easier to transfer your workspaces over a network. Only these two workspace types currently supports the pickling process, and there are limitations to be aware of described :ref:`here `. +- Support for unicode property names has been added to Python. This means that one can run the following in Python2 or Python3. .. code-block:: python @@ -117,6 +146,8 @@ Support for unicode property names has been added to python. This means that one props = json.loads('{"DryRun":true}') Segfault(**props) +Bugfixes +######## - Fixed an issue with coercing data from python lists or numpy arrays where the datatype!=float64 into a workspace :ref:`Release 3.12.0 ` From d798b706902e79f73b943d9924e5dc3406875258 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 13:53:18 +0000 Subject: [PATCH 200/364] Re #22048: Applied fixes to Framework/Geometry. --- .../MantidGeometry/Crystal/BraggScatterer.h | 4 ++-- .../Crystal/BraggScattererFactory.h | 3 +-- .../BraggScattererInCrystalStructure.h | 3 +-- .../MantidGeometry/Crystal/CenteringGroup.h | 7 +++---- .../Crystal/CompositeBraggScatterer.h | 2 +- .../MantidGeometry/Crystal/CrystalStructure.h | 2 +- .../inc/MantidGeometry/Crystal/CyclicGroup.h | 4 ++-- .../inc/MantidGeometry/Crystal/Group.h | 4 ++-- .../inc/MantidGeometry/Crystal/HKLFilter.h | 2 +- .../Crystal/IsotropicAtomBraggScatterer.h | 6 ++---- .../inc/MantidGeometry/Crystal/PeakShape.h | 4 ++-- .../MantidGeometry/Crystal/PeakTransform.h | 4 ++-- .../Crystal/PeakTransformFactory.h | 2 +- .../MantidGeometry/Crystal/PeakTransformHKL.h | 2 +- .../Crystal/PeakTransformQLab.h | 3 +-- .../Crystal/PeakTransformQSample.h | 3 +-- .../Crystal/PeakTransformSelector.h | 2 +- .../inc/MantidGeometry/Crystal/PointGroup.h | 5 ++--- .../Crystal/PointGroupFactory.h | 5 ++--- .../Crystal/ReflectionCondition.h | 2 +- .../inc/MantidGeometry/Crystal/SpaceGroup.h | 4 ++-- .../Crystal/SpaceGroupFactory.h | 6 ++---- .../Crystal/StructureFactorCalculator.h | 3 +-- .../StructureFactorCalculatorSummation.h | 3 +-- .../MantidGeometry/Crystal/SymmetryElement.h | 16 +++++++-------- .../Crystal/SymmetryElementFactory.h | 6 ++---- .../Crystal/SymmetryOperationFactory.h | 3 +-- .../Geometry/inc/MantidGeometry/Crystal/V3R.h | 2 +- .../inc/MantidGeometry/ICompAssembly.h | 4 ++-- .../Geometry/inc/MantidGeometry/IComponent.h | 6 +++--- .../Geometry/inc/MantidGeometry/IDTypes.h | 4 ++-- .../Geometry/inc/MantidGeometry/IDetector.h | 5 ++--- .../inc/MantidGeometry/IObjComponent.h | 4 ++-- .../Geometry/inc/MantidGeometry/Instrument.h | 6 ++---- .../MantidGeometry/Instrument/CompAssembly.h | 5 ++--- .../inc/MantidGeometry/Instrument/Container.h | 6 +++--- .../MantidGeometry/Instrument/DetectorGroup.h | 6 +++--- .../inc/MantidGeometry/Instrument/IDFObject.h | 4 ++-- .../Instrument/ObjCompAssembly.h | 9 ++++----- .../inc/MantidGeometry/Instrument/Parameter.h | 2 +- .../Instrument/ParameterFactory.h | 4 ++-- .../MantidGeometry/Instrument/ParameterMap.h | 20 +++++++------------ .../Instrument/RectangularDetector.h | 5 ++--- .../Instrument/StructuredDetector.h | 5 ++--- .../inc/MantidGeometry/Instrument_fwd.h | 8 ++++---- .../MDGeometry/CompositeImplicitFunction.h | 3 +-- .../MantidGeometry/MDGeometry/IMDDimension.h | 8 ++++---- .../inc/MantidGeometry/MDGeometry/MDFrame.h | 8 ++++---- .../MDGeometry/MDFrameFactory.h | 2 +- .../MDGeometry/MDGeometryXMLBuilder.h | 2 +- .../MDGeometry/MDHistoDimension.h | 4 ++-- .../MDGeometry/MDHistoDimensionBuilder.h | 2 +- .../MDGeometry/MDImplicitFunction.h | 2 +- .../inc/MantidGeometry/MDGeometry/MDTypes.h | 4 ++-- .../inc/MantidGeometry/Objects/BoundingBox.h | 4 ++-- .../inc/MantidGeometry/Objects/IObject.h | 8 ++++---- .../Objects/InstrumentRayTracer.h | 2 +- .../MantidGeometry/Surfaces/SurfaceFactory.h | 3 +-- .../Geometry/src/Instrument/FitParameter.cpp | 2 +- .../SampleEnvironmentSpecParser.cpp | 2 +- .../src/Instrument/XMLInstrumentParameter.cpp | 3 +-- Framework/Geometry/src/Math/mathSupport.cpp | 2 +- Framework/Geometry/test/CSGObjectTest.h | 4 ++-- .../Geometry/test/MDBoxImplicitFunctionTest.h | 2 +- .../Geometry/test/MatrixVectorPairTest.h | 2 +- Framework/Geometry/test/ParameterMapTest.h | 4 +--- .../Geometry/test/PeakTransformSelectorTest.h | 6 +++--- .../test/XMLInstrumentParameterTest.h | 2 +- 68 files changed, 130 insertions(+), 166 deletions(-) diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h index 82f4460245b4..40e0ebff6cd5 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h @@ -13,11 +13,11 @@ namespace Mantid { namespace Geometry { -typedef std::complex StructureFactor; +using StructureFactor = std::complex; class BraggScatterer; -typedef boost::shared_ptr BraggScatterer_sptr; +using BraggScatterer_sptr = boost::shared_ptr; /** @class BraggScatterer diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h index a9782105dc3d..be5ef1c6c67b 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h @@ -85,8 +85,7 @@ class MANTID_GEOMETRY_DLL BraggScattererFactoryImpl BraggScattererFactoryImpl(); }; -typedef Mantid::Kernel::SingletonHolder - BraggScattererFactory; +using BraggScattererFactory = Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h index b08fbe7e9945..5c2a82875033 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h @@ -72,8 +72,7 @@ class MANTID_GEOMETRY_DLL BraggScattererInCrystalStructure UnitCell m_cell; }; -typedef boost::shared_ptr - BraggScattererInCrystalStructure_sptr; +using BraggScattererInCrystalStructure_sptr = boost::shared_ptr; /** * Helper class for validating unit cell strings. diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h index 85c03b85504d..d70a80d40b3e 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h @@ -65,8 +65,8 @@ class MANTID_GEOMETRY_DLL CenteringGroup : public Group { std::string m_symbol; }; -typedef boost::shared_ptr CenteringGroup_sptr; -typedef boost::shared_ptr CenteringGroup_const_sptr; +using CenteringGroup_sptr = boost::shared_ptr; +using CenteringGroup_const_sptr = boost::shared_ptr; /// Helper class to keep this out of the interface of CenteringGroup. class MANTID_GEOMETRY_DLL CenteringGroupCreatorImpl { @@ -94,8 +94,7 @@ class MANTID_GEOMETRY_DLL CenteringGroupCreatorImpl { friend struct Mantid::Kernel::CreateUsingNew; }; -typedef Mantid::Kernel::SingletonHolder - CenteringGroupCreator; +using CenteringGroupCreator = Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h index 49d08693628b..c4317a23dad7 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h @@ -59,7 +59,7 @@ namespace Geometry { */ class CompositeBraggScatterer; -typedef boost::shared_ptr CompositeBraggScatterer_sptr; +using CompositeBraggScatterer_sptr = boost::shared_ptr; class MANTID_GEOMETRY_DLL CompositeBraggScatterer : public BraggScatterer { public: diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h index cfa639ec75e0..fe8787ea2120 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CrystalStructure.h @@ -116,7 +116,7 @@ class DLLExport CrystalStructure { CompositeBraggScatterer_sptr m_scatterers; }; -typedef boost::shared_ptr CrystalStructure_sptr; +using CrystalStructure_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h index 8c1c07f5923a..991c674c0b07 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h @@ -89,8 +89,8 @@ class MANTID_GEOMETRY_DLL CyclicGroup : public Group { generateAllOperations(const SymmetryOperation &operation) const; }; -typedef boost::shared_ptr CyclicGroup_sptr; -typedef boost::shared_ptr CyclicGroup_const_sptr; +using CyclicGroup_sptr = boost::shared_ptr; +using CyclicGroup_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h b/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h index ec5f164f1407..459d2f6b27f3 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h @@ -195,8 +195,8 @@ class MANTID_GEOMETRY_DLL Group { CoordinateSystem m_axisSystem; }; -typedef boost::shared_ptr Group_sptr; -typedef boost::shared_ptr Group_const_sptr; +using Group_sptr = boost::shared_ptr; +using Group_const_sptr = boost::shared_ptr; namespace GroupFactory { /// Creates a Group sub-class of type T if T has a constructor that takes a diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h index 04647bd3ee37..f687ff7e9962 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/HKLFilter.h @@ -88,7 +88,7 @@ class MANTID_GEOMETRY_DLL HKLFilter { virtual bool isAllowed(const Kernel::V3D &hkl) const = 0; }; -typedef boost::shared_ptr HKLFilter_const_sptr; +using HKLFilter_const_sptr = boost::shared_ptr; /// Base class for unary logic operations for HKLFilter. class MANTID_GEOMETRY_DLL HKLFilterUnaryLogicOperation : public HKLFilter { diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h index 890bcbbb1f6b..aa241526f50a 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h @@ -10,8 +10,7 @@ namespace Geometry { class IsotropicAtomBraggScatterer; -typedef boost::shared_ptr - IsotropicAtomBraggScatterer_sptr; +using IsotropicAtomBraggScatterer_sptr = boost::shared_ptr; /** @class IsotropicAtomBraggScatterer @@ -121,8 +120,7 @@ class MANTID_GEOMETRY_DLL IsotropicAtomBraggScatterer std::string m_label; }; -typedef boost::shared_ptr - IsotropicAtomBraggScatterer_sptr; +using IsotropicAtomBraggScatterer_sptr = boost::shared_ptr; class MANTID_GEOMETRY_DLL IsotropicAtomBraggScattererParser { public: diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h index c23c23d963f9..bed0e0194972 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakShape.h @@ -55,8 +55,8 @@ class DLLExport PeakShape { virtual ~PeakShape() = default; }; -typedef boost::shared_ptr PeakShape_sptr; -typedef boost::shared_ptr PeakShape_const_sptr; +using PeakShape_sptr = boost::shared_ptr; +using PeakShape_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h index a00796790c71..8af664f9342b 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransform.h @@ -56,8 +56,8 @@ class DLLExport PeakTransform { }; /// Typedef for a PeakTransform wrapped in a shared_pointer. -typedef boost::shared_ptr PeakTransform_sptr; -typedef boost::shared_ptr PeakTransform_const_sptr; +using PeakTransform_sptr = boost::shared_ptr; +using PeakTransform_const_sptr = boost::shared_ptr; /** @class PeakTransformException diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h index 17acec02f1bc..9cd3c1163b5f 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformFactory.h @@ -21,7 +21,7 @@ class DLLExport PeakTransformFactory { }; /// Factory Shared Pointer typedef. -typedef boost::shared_ptr PeakTransformFactory_sptr; +using PeakTransformFactory_sptr = boost::shared_ptr; } } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h index 260a392c4156..774a1b1eb8eb 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformHKL.h @@ -31,7 +31,7 @@ class DLLExport PeakTransformHKL : public PeakTransform { }; /// Typedef a factory for type of PeaksTransform. -typedef ConcretePeakTransformFactory PeakTransformHKLFactory; +using PeakTransformHKLFactory = ConcretePeakTransformFactory; } } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h index 1cb77266541c..8d2f10ce2f8b 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h @@ -31,8 +31,7 @@ class DLLExport PeakTransformQLab : public PeakTransform { }; /// Typedef a factory for type of PeaksTransform. -typedef ConcretePeakTransformFactory - PeakTransformQLabFactory; +using PeakTransformQLabFactory = ConcretePeakTransformFactory; } } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h index f6e0e2b7bfe7..cca344bbfcd6 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h @@ -31,8 +31,7 @@ class DLLExport PeakTransformQSample : public PeakTransform { }; /// Typedef a factory for type of PeaksTransform. -typedef ConcretePeakTransformFactory - PeakTransformQSampleFactory; +using PeakTransformQSampleFactory = ConcretePeakTransformFactory; } } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h index b7fe36dce4c2..6706bcdb5d04 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformSelector.h @@ -34,7 +34,7 @@ class DLLExport PeakTransformSelector { /// Disabled assigment operator PeakTransformSelector &operator=(const PeakTransformSelector &); /// Collection of candidate factories. - typedef std::set Factories; + using Factories = std::set; Factories m_candidateFactories; }; } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h index 0de5373f0a9f..659807b5e1ab 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h @@ -77,7 +77,7 @@ class MANTID_GEOMETRY_DLL PointGroup : public Group { }; /// Shared pointer to a PointGroup -typedef boost::shared_ptr PointGroup_sptr; +using PointGroup_sptr = boost::shared_ptr; MANTID_GEOMETRY_DLL std::vector getAllPointGroups(); @@ -107,8 +107,7 @@ struct MANTID_GEOMETRY_DLL CrystalSystemComparator { const PointGroup::CrystalSystem &rhs) const; }; -typedef std::multimap PointGroupCrystalSystemMap; +using PointGroupCrystalSystemMap = std::multimap; MANTID_GEOMETRY_DLL PointGroupCrystalSystemMap getPointGroupsByCrystalSystem(); diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h index 6e22e4a622a6..36fcf28c04ba 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h @@ -38,7 +38,7 @@ class MANTID_GEOMETRY_DLL PointGroupGenerator { PointGroup_sptr m_prototype; }; -typedef boost::shared_ptr PointGroupGenerator_sptr; +using PointGroupGenerator_sptr = boost::shared_ptr; /** @class PointGroupFactory @@ -120,8 +120,7 @@ class MANTID_GEOMETRY_DLL PointGroupFactoryImpl { boost::regex m_originChoiceRegex; }; -typedef Mantid::Kernel::SingletonHolder - PointGroupFactory; +using PointGroupFactory = Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h b/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h index 3eb01e35222b..aa2a989a57fd 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/ReflectionCondition.h @@ -168,7 +168,7 @@ class MANTID_GEOMETRY_DLL ReflectionConditionHexagonallyReverse }; /// Shared pointer to a ReflectionCondition -typedef boost::shared_ptr ReflectionCondition_sptr; +using ReflectionCondition_sptr = boost::shared_ptr; MANTID_GEOMETRY_DLL std::vector getAllReflectionConditions(); diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h index 11a16a63a4c4..26e56434b3d2 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h @@ -101,8 +101,8 @@ class MANTID_GEOMETRY_DLL SpaceGroup : public Group { MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &stream, const SpaceGroup &self); -typedef boost::shared_ptr SpaceGroup_sptr; -typedef boost::shared_ptr SpaceGroup_const_sptr; +using SpaceGroup_sptr = boost::shared_ptr; +using SpaceGroup_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h index 49239db44a40..967f4dd95d3a 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h @@ -61,8 +61,7 @@ class MANTID_GEOMETRY_DLL AbstractSpaceGroupGenerator { SpaceGroup_const_sptr m_prototype; }; -typedef boost::shared_ptr - AbstractSpaceGroupGenerator_sptr; +using AbstractSpaceGroupGenerator_sptr = boost::shared_ptr; /// Concrete space group generator that uses space group generators as given in /// ITA. @@ -265,8 +264,7 @@ class MANTID_GEOMETRY_DLL SpaceGroupFactoryImpl { friend struct Mantid::Kernel::CreateUsingNew; }; -typedef Mantid::Kernel::SingletonHolder - SpaceGroupFactory; +using SpaceGroupFactory = Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h index 0e14ff57b0e2..d11c333c45e8 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h @@ -59,8 +59,7 @@ class MANTID_GEOMETRY_DLL StructureFactorCalculator { crystalStructureSetHook(const CrystalStructure &crystalStructure); }; -typedef boost::shared_ptr - StructureFactorCalculator_sptr; +using StructureFactorCalculator_sptr = boost::shared_ptr; namespace StructureFactorCalculatorFactory { /// Small templated factory function that creates the desired calculator diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h index cc3a36bb6e01..ea21a3a3fe46 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h @@ -54,8 +54,7 @@ class MANTID_GEOMETRY_DLL StructureFactorCalculatorSummation CompositeBraggScatterer_sptr m_unitCellScatterers; }; -typedef boost::shared_ptr - StructureFactorSummation_sptr; +using StructureFactorSummation_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h index 24f2452565f0..fcbb80c04317 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h @@ -65,7 +65,7 @@ class MANTID_GEOMETRY_DLL SymmetryElement { std::string m_hmSymbol; }; -typedef boost::shared_ptr SymmetryElement_sptr; +using SymmetryElement_sptr = boost::shared_ptr; /** @class SymmetryElementIdentity @@ -79,7 +79,7 @@ class MANTID_GEOMETRY_DLL SymmetryElementIdentity : public SymmetryElement { SymmetryElement_sptr clone() const override; }; -typedef boost::shared_ptr SymmetryElementIdentity_sptr; +using SymmetryElementIdentity_sptr = boost::shared_ptr; /** @class SymmetryElementInversion @@ -100,8 +100,7 @@ class MANTID_GEOMETRY_DLL SymmetryElementInversion : public SymmetryElement { V3R m_inversionPoint; }; -typedef boost::shared_ptr - SymmetryElementInversion_sptr; +using SymmetryElementInversion_sptr = boost::shared_ptr; /** @class SymmetryElementTranslation @@ -122,8 +121,7 @@ class MANTID_GEOMETRY_DLL SymmetryElementTranslation : public SymmetryElement { V3R m_translation; }; -typedef boost::shared_ptr - SymmetryElementTranslation_sptr; +using SymmetryElementTranslation_sptr = boost::shared_ptr; /** @class SymmetryElementWithAxis @@ -150,7 +148,7 @@ class MANTID_GEOMETRY_DLL SymmetryElementWithAxis : public SymmetryElement { V3R m_translation; }; -typedef boost::shared_ptr SymmetryElementWithAxis_sptr; +using SymmetryElementWithAxis_sptr = boost::shared_ptr; /** @class SymmetryElementRotation @@ -183,7 +181,7 @@ class MANTID_GEOMETRY_DLL SymmetryElementRotation RotationSense m_rotationSense; }; -typedef boost::shared_ptr SymmetryElementRotation_sptr; +using SymmetryElementRotation_sptr = boost::shared_ptr; /** @class SymmetryElementMirror @@ -203,7 +201,7 @@ class MANTID_GEOMETRY_DLL SymmetryElementMirror SymmetryElement_sptr clone() const override; }; -typedef boost::shared_ptr SymmetryElementMirror_sptr; +using SymmetryElementMirror_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h index b0e3c5c11952..5d764b1ee2e9 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h @@ -41,8 +41,7 @@ class MANTID_GEOMETRY_DLL AbstractSymmetryElementGenerator { virtual bool canProcess(const SymmetryOperation &operation) const = 0; }; -typedef boost::shared_ptr - AbstractSymmetryElementGenerator_sptr; +using AbstractSymmetryElementGenerator_sptr = boost::shared_ptr; /** @class SymmetryElementIdentityGenerator @@ -258,8 +257,7 @@ class MANTID_GEOMETRY_DLL SymmetryElementFactoryImpl { friend struct Mantid::Kernel::CreateUsingNew; }; -typedef Mantid::Kernel::SingletonHolder - SymmetryElementFactory; +using SymmetryElementFactory = Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h index e9fa3cb12dea..ce5f4451ac5f 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h @@ -78,8 +78,7 @@ class MANTID_GEOMETRY_DLL SymmetryOperationFactoryImpl { SymmetryOperationFactoryImpl(); }; -typedef Mantid::Kernel::SingletonHolder - SymmetryOperationFactory; +using SymmetryOperationFactory = Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h b/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h index 3b794970e9ae..abd1a45938be 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h @@ -47,7 +47,7 @@ namespace Geometry { Code Documentation is available at: */ -typedef boost::rational RationalNumber; +using RationalNumber = boost::rational; class MANTID_GEOMETRY_DLL V3R { public: diff --git a/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h b/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h index 63684d264f83..bd7af1c70f9a 100644 --- a/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h +++ b/Framework/Geometry/inc/MantidGeometry/ICompAssembly.h @@ -95,9 +95,9 @@ class MANTID_GEOMETRY_DLL ICompAssembly : public virtual IComponent { }; /// Shared pointer to a ICompAssembly -typedef boost::shared_ptr ICompAssembly_sptr; +using ICompAssembly_sptr = boost::shared_ptr; /// Shared pointer to a const ICompAssembly -typedef boost::shared_ptr ICompAssembly_const_sptr; +using ICompAssembly_const_sptr = boost::shared_ptr; } // Namespace Geometry } // Namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/IComponent.h b/Framework/Geometry/inc/MantidGeometry/IComponent.h index 251abc2d4ff4..25b3bbc9cfa4 100644 --- a/Framework/Geometry/inc/MantidGeometry/IComponent.h +++ b/Framework/Geometry/inc/MantidGeometry/IComponent.h @@ -25,7 +25,7 @@ class IComponent; class ParameterMap; /// Define a type for a unique component identifier. -typedef IComponent *ComponentID; +using ComponentID = IComponent *; /** @class IComponent @brief base class for Geometric IComponent @@ -186,9 +186,9 @@ class MANTID_GEOMETRY_DLL IComponent { }; /// Typedef of a shared pointer to a IComponent -typedef boost::shared_ptr IComponent_sptr; +using IComponent_sptr = boost::shared_ptr; /// Typdef of a shared pointer to a const IComponent -typedef boost::shared_ptr IComponent_const_sptr; +using IComponent_const_sptr = boost::shared_ptr; } // Namespace Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/IDTypes.h b/Framework/Geometry/inc/MantidGeometry/IDTypes.h index 45d54a1a702a..c6d38b6be083 100644 --- a/Framework/Geometry/inc/MantidGeometry/IDTypes.h +++ b/Framework/Geometry/inc/MantidGeometry/IDTypes.h @@ -8,10 +8,10 @@ namespace Mantid { /// Typedef for a spectrum Number -typedef int32_t specnum_t; +using specnum_t = int32_t; /// Typedef for a detector ID -typedef int32_t detid_t; +using detid_t = int32_t; } #endif // MANTID_GEOMETRY_IDTYPES_H_ diff --git a/Framework/Geometry/inc/MantidGeometry/IDetector.h b/Framework/Geometry/inc/MantidGeometry/IDetector.h index 078f18709382..9aa29c982526 100644 --- a/Framework/Geometry/inc/MantidGeometry/IDetector.h +++ b/Framework/Geometry/inc/MantidGeometry/IDetector.h @@ -115,10 +115,9 @@ class MANTID_GEOMETRY_DLL IDetector : public virtual IObjComponent { }; /// Shared pointer to IDetector -typedef boost::shared_ptr IDetector_sptr; +using IDetector_sptr = boost::shared_ptr; /// Shared pointer to IDetector (const version) -typedef boost::shared_ptr - IDetector_const_sptr; +using IDetector_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h index 8cafbd21fb18..d5a239686bdc 100644 --- a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h +++ b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h @@ -120,9 +120,9 @@ class MANTID_GEOMETRY_DLL IObjComponent : public virtual IComponent { }; /// Shared pointer to IObjComponent -typedef boost::shared_ptr IObjComponent_sptr; +using IObjComponent_sptr = boost::shared_ptr; /// Shared pointer to IObjComponent (const version) -typedef boost::shared_ptr IObjComponent_const_sptr; +using IObjComponent_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument.h b/Framework/Geometry/inc/MantidGeometry/Instrument.h index 82c605c140a2..c786b5abec29 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument.h @@ -17,7 +17,7 @@ namespace Mantid { /// Typedef of a map from detector ID to detector shared pointer. -typedef std::map detid2det_map; +using detid2det_map = std::map; namespace Geometry { class ComponentInfo; @@ -26,9 +26,7 @@ class XMLInstrumentParameter; class ParameterMap; class ReferenceFrame; /// Convenience typedef -typedef std::map, - boost::shared_ptr> - InstrumentParameterCache; +using InstrumentParameterCache = std::map, boost::shared_ptr >; /** Base Instrument Class. diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h b/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h index 41169e9142b4..cfeb0f6342a7 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h @@ -47,9 +47,8 @@ namespace Geometry { class MANTID_GEOMETRY_DLL CompAssembly : public ICompAssembly, public Component { protected: - typedef std::vector::iterator comp_it; ///< Iterator type - typedef std::vector::const_iterator - const_comp_it; ///< Const iterator type + using comp_it = std::vector::iterator; ///< Iterator type + using const_comp_it = std::vector::const_iterator; ///< Const iterator type public: /// String description of the type of component diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h index bcb6b982222e..e3a2e8b85c69 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Container.h @@ -39,7 +39,7 @@ namespace Geometry { */ class MANTID_GEOMETRY_DLL Container final : public IObject { public: - typedef std::unordered_map ShapeArgs; + using ShapeArgs = std::unordered_map; Container(); Container(IObject_sptr shape); @@ -126,9 +126,9 @@ class MANTID_GEOMETRY_DLL Container final : public IObject { }; /// Typdef for a shared pointer -typedef boost::shared_ptr Container_sptr; +using Container_sptr = boost::shared_ptr; /// Typdef for a shared pointer to a const object -typedef boost::shared_ptr Container_const_sptr; +using Container_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h index 21a8388e1036..32ab21ebbd60 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/DetectorGroup.h @@ -190,7 +190,7 @@ class MANTID_GEOMETRY_DLL DetectorGroup : public virtual IDetector { /// The type of collection used for the detectors /// - a map of detector pointers with the detector ID as the key // May want to change this to a hash_map in due course - typedef std::map DetCollection; + using DetCollection = std::map; /// The collection of grouped detectors DetCollection m_detectors; /** the parameter describes the topology of the detector's group namely if @@ -263,9 +263,9 @@ class MANTID_GEOMETRY_DLL DetectorGroup : public virtual IDetector { }; /// Typedef for shared pointer -typedef boost::shared_ptr DetectorGroup_sptr; +using DetectorGroup_sptr = boost::shared_ptr; /// Typedef for shared pointer to a const object -typedef boost::shared_ptr DetectorGroup_const_sptr; +using DetectorGroup_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h b/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h index 7f066b14efe7..bcb33a9e17d0 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/IDFObject.h @@ -112,8 +112,8 @@ class DLLExport NullIDFObject : public AbstractIDFObject { bool exists() const override { return false; } }; -typedef boost::shared_ptr IDFObject_sptr; -typedef boost::shared_ptr IDFObject_const_sptr; +using IDFObject_sptr = boost::shared_ptr; +using IDFObject_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h index f8e055ce25c9..c301aca85d8b 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h @@ -45,9 +45,8 @@ namespace Geometry { */ class MANTID_GEOMETRY_DLL ObjCompAssembly : public virtual ICompAssembly, public virtual ObjComponent { - typedef std::vector::iterator comp_it; ///< Iterator type - typedef std::vector::const_iterator - const_comp_it; ///< Const iterator type + using comp_it = std::vector::iterator; ///< Iterator type + using const_comp_it = std::vector::const_iterator; ///< Const iterator type public: /// String description of the type of component std::string type() const override { return "ObjCompAssembly"; } @@ -114,9 +113,9 @@ class MANTID_GEOMETRY_DLL ObjCompAssembly : public virtual ICompAssembly, }; /// Shared pointer to ObjCompAssembly -typedef boost::shared_ptr ObjCompAssembly_sptr; +using ObjCompAssembly_sptr = boost::shared_ptr; /// Shared pointer to ObjCompAssembly (const version) -typedef boost::shared_ptr ObjCompAssembly_const_sptr; +using ObjCompAssembly_const_sptr = boost::shared_ptr; MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &, const ObjCompAssembly &); diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h index 18c9254403b6..ad07be97ef72 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h @@ -219,7 +219,7 @@ ParameterType &ParameterType::operator=(const Type &value) { } /// Typedef for the shared pointer -typedef boost::shared_ptr Parameter_sptr; +using Parameter_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h index 68738d6152cc..12385412020d 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h @@ -67,8 +67,8 @@ class MANTID_GEOMETRY_DLL ParameterFactory { ParameterFactory &operator=(const ParameterFactory &); /// A typedef for the instantiator - typedef Kernel::AbstractInstantiator AbstractFactory; - typedef std::map> FactoryMap; + using AbstractFactory = Kernel::AbstractInstantiator; + using FactoryMap = std::map >; /// The map holding the registered class names and their instantiators static FactoryMap s_map; }; diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h index 13f7ebc2b72a..4d2120d4c5bf 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h @@ -54,23 +54,17 @@ class Instrument; Code Documentation is available at: */ /// Parameter map iterator typedef -typedef tbb::concurrent_unordered_multimap< - ComponentID, boost::shared_ptr>::iterator component_map_it; -typedef tbb::concurrent_unordered_multimap< - ComponentID, boost::shared_ptr>::const_iterator - component_map_cit; +using component_map_it = tbb::concurrent_unordered_multimap >::iterator; +using component_map_cit = tbb::concurrent_unordered_multimap >::const_iterator; class MANTID_GEOMETRY_DLL ParameterMap { public: /// Parameter map typedef - typedef tbb::concurrent_unordered_multimap> pmap; + using pmap = tbb::concurrent_unordered_multimap >; /// Parameter map iterator typedef - typedef tbb::concurrent_unordered_multimap< - ComponentID, boost::shared_ptr>::iterator pmap_it; + using pmap_it = tbb::concurrent_unordered_multimap >::iterator; /// Parameter map iterator typedef - typedef tbb::concurrent_unordered_multimap< - ComponentID, boost::shared_ptr>::const_iterator pmap_cit; + using pmap_cit = tbb::concurrent_unordered_multimap >::const_iterator; /// Default constructor ParameterMap(); /// Const constructor @@ -388,9 +382,9 @@ class MANTID_GEOMETRY_DLL ParameterMap { }; /// ParameterMap shared pointer typedef -typedef boost::shared_ptr ParameterMap_sptr; +using ParameterMap_sptr = boost::shared_ptr; /// ParameterMap constant shared pointer typedef -typedef boost::shared_ptr ParameterMap_const_sptr; +using ParameterMap_const_sptr = boost::shared_ptr; } // Namespace Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h b/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h index bdf087392e85..5033068f3ac0 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h @@ -211,9 +211,8 @@ class MANTID_GEOMETRY_DLL RectangularDetector : public CompAssembly, MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &, const RectangularDetector &); -typedef boost::shared_ptr RectangularDetector_sptr; -typedef boost::shared_ptr - RectangularDetector_const_sptr; +using RectangularDetector_sptr = boost::shared_ptr; +using RectangularDetector_const_sptr = boost::shared_ptr; } // Namespace Geometry } // Namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h index 428afb7c6576..ce1b5f4fad19 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h @@ -192,9 +192,8 @@ class MANTID_GEOMETRY_DLL StructuredDetector : public CompAssembly, MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &, const StructuredDetector &); -typedef boost::shared_ptr StructuredDetector_sptr; -typedef boost::shared_ptr - StructuredDetector_const_sptr; +using StructuredDetector_sptr = boost::shared_ptr; +using StructuredDetector_const_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid #endif // STRUCTUREDDETECTOR_H diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h b/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h index e5272b713fc1..64ee5ae4b3a0 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument_fwd.h @@ -34,13 +34,13 @@ namespace Geometry { class Instrument; /// Shared pointer to an instrument object -typedef boost::shared_ptr Instrument_sptr; +using Instrument_sptr = boost::shared_ptr; /// Shared pointer to an const instrument object -typedef boost::shared_ptr Instrument_const_sptr; +using Instrument_const_sptr = boost::shared_ptr; /// unique pointer to an instrument -typedef std::unique_ptr Instrument_uptr; +using Instrument_uptr = std::unique_ptr; /// unique pointer to an instrument (const version) -typedef std::unique_ptr Instrument_const_uptr; +using Instrument_const_uptr = std::unique_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h index 49819de15c96..1c0c7a16cdc4 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h @@ -63,8 +63,7 @@ class DLLExport CompositeImplicitFunction protected: std::vector m_Functions; - typedef std::vector::const_iterator - FunctionIterator; + using FunctionIterator = std::vector::const_iterator; }; } } diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h index 5ed0c0e6278b..0f3980196e75 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/IMDDimension.h @@ -117,14 +117,14 @@ class MANTID_GEOMETRY_DLL IMDDimension { }; /// Shared Pointer for IMDDimension. Frequently used type in framework. -typedef boost::shared_ptr IMDDimension_sptr; +using IMDDimension_sptr = boost::shared_ptr; /// Shared Pointer to const IMDDimension. Not strictly necessary since /// IMDDimension is pure abstract. -typedef boost::shared_ptr IMDDimension_const_sptr; +using IMDDimension_const_sptr = boost::shared_ptr; /// Vector of constant shared pointers to IMDDimensions. -typedef std::vector VecIMDDimension_const_sptr; +using VecIMDDimension_const_sptr = std::vector; /// Vector of shared pointers to IMDDimensions. -typedef std::vector VecIMDDimension_sptr; +using VecIMDDimension_sptr = std::vector; } } #endif diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h index 29152ae5a55c..799e5261a667 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrame.h @@ -50,10 +50,10 @@ class DLLExport MDFrame { virtual ~MDFrame() = default; }; -typedef std::unique_ptr MDFrame_uptr; -typedef std::unique_ptr MDFrame_const_uptr; -typedef std::shared_ptr MDFrame_sptr; -typedef std::shared_ptr MDFrame_const_sptr; +using MDFrame_uptr = std::unique_ptr; +using MDFrame_const_uptr = std::unique_ptr; +using MDFrame_sptr = std::shared_ptr; +using MDFrame_const_sptr = std::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h index f702e0e9ce8d..13aa7104ffa0 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDFrameFactory.h @@ -54,7 +54,7 @@ class MANTID_GEOMETRY_DLL MDFrameFactory MDFrameArgument> {}; /// Helper typedef -typedef std::unique_ptr MDFrameFactory_uptr; +using MDFrameFactory_uptr = std::unique_ptr; //----------------------------------------------------------------------- // Derived MDFrameFactory declarations diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h index 407531076977..0b9b680a10ff 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h @@ -95,7 +95,7 @@ class MANTID_GEOMETRY_DLL MDGeometryBuilderXML { bool hasIntegratedTDimension() const; private: - typedef std::vector DimensionContainerType; + using DimensionContainerType = std::vector; mutable DimensionContainerType m_vecDimensions; diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h index 79e1381b8117..a4b16a6b7c75 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimension.h @@ -147,10 +147,10 @@ class MANTID_GEOMETRY_DLL MDHistoDimension : public IMDDimension { }; /// Shared pointer to a MDHistoDimension -typedef boost::shared_ptr MDHistoDimension_sptr; +using MDHistoDimension_sptr = boost::shared_ptr; /// Shared pointer to a const MDHistoDimension -typedef boost::shared_ptr MDHistoDimension_const_sptr; +using MDHistoDimension_const_sptr = boost::shared_ptr; } // namespace Mantid } // namespace Geometry diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h index e4fcc69ce53e..dba705588230 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h @@ -79,7 +79,7 @@ class MANTID_GEOMETRY_DLL MDHistoDimensionBuilder { }; /// Handy typedef for collection of builders. -typedef std::vector Vec_MDHistoDimensionBuilder; +using Vec_MDHistoDimensionBuilder = std::vector; } } diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h index a94e881bc2b9..b7c4faf5f4d6 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDImplicitFunction.h @@ -294,7 +294,7 @@ class DLLExport MDImplicitFunction { size_t m_numPlanes; }; -typedef boost::shared_ptr MDImplicitFunction_sptr; +using MDImplicitFunction_sptr = boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h index 84983b49ca7d..b75542c177f2 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDTypes.h @@ -40,7 +40,7 @@ namespace Mantid { * We can change this in order to compare * performance/memory/accuracy requirements. */ -typedef float coord_t; +using coord_t = float; /// Define indicating that the coord_t type is a float (not double) //#undef COORDT_IS_FLOAT @@ -49,7 +49,7 @@ typedef float coord_t; /** Typedef for the signal recorded in a MDBox, etc. * Note: MDEvents use 'float' internally to save memory */ -typedef double signal_t; +using signal_t = double; /** Macro TMDE to make declaring template functions * faster. Put this macro before function declarations. diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h b/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h index f1b0a16b005f..8b808c019269 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h @@ -218,9 +218,9 @@ class MANTID_GEOMETRY_DLL BoundingBox { }; /// A shared pointer to a BoundingBox -typedef boost::shared_ptr BoundingBox_sptr; +using BoundingBox_sptr = boost::shared_ptr; /// A shared pointer to a const BoundingBox -typedef boost::shared_ptr BoundingBox_const_sptr; +using BoundingBox_const_sptr = boost::shared_ptr; /// Print out the bounding box values to a stream. MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &os, diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h index 24331e807521..11e92711d706 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h @@ -103,13 +103,13 @@ class MANTID_GEOMETRY_DLL IObject { }; /// Typdef for a shared pointer -typedef boost::shared_ptr IObject_sptr; +using IObject_sptr = boost::shared_ptr; /// Typdef for a shared pointer to a const object -typedef boost::shared_ptr IObject_const_sptr; +using IObject_const_sptr = boost::shared_ptr; /// Typdef for a unique pointer -typedef std::unique_ptr IObject_uptr; +using IObject_uptr = std::unique_ptr; /// Typdef for a unique pointer to a const object -typedef std::unique_ptr IObject_const_uptr; +using IObject_const_uptr = std::unique_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h b/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h index ef45f935d615..ad1110e26bc0 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h @@ -19,7 +19,7 @@ class IComponent; struct Link; class Track; /// Typedef for object intersections -typedef Track::LType Links; +using Links = Track::LType; /** This class is responsible for tracking rays and accumulating a list of objects diff --git a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h index c6b87cc774c4..87a1023e55c0 100644 --- a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h @@ -42,8 +42,7 @@ class MANTID_GEOMETRY_DLL SurfaceFactory { private: // workaround because gcc 4.4 cannot have std::unique_ptr inside a std::map. // http://stackoverflow.com/questions/7342703/gcc-4-4-4-5-unique-ptr-not-work-for-unordered-set-unordered-map - typedef std::vector>> - MapType; ///< Storage of surface pointers + using MapType = std::vector > >; ///< Storage of surface pointers static SurfaceFactory *FOBJ; ///< Effective "this" MapType SGrid; ///< The tally stack diff --git a/Framework/Geometry/src/Instrument/FitParameter.cpp b/Framework/Geometry/src/Instrument/FitParameter.cpp index 196afb8cadb3..55be129701de 100644 --- a/Framework/Geometry/src/Instrument/FitParameter.cpp +++ b/Framework/Geometry/src/Instrument/FitParameter.cpp @@ -160,7 +160,7 @@ std::ostream &operator<<(std::ostream &os, const FitParameter &f) { */ std::istream &operator>>(std::istream &in, FitParameter &f) { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; std::string str; getline(in, str); diff --git a/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp b/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp index 36daa0b05ce2..441989fcdca5 100644 --- a/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp +++ b/Framework/Geometry/src/Instrument/SampleEnvironmentSpecParser.cpp @@ -50,7 +50,7 @@ namespace Geometry { SampleEnvironmentSpec_uptr SampleEnvironmentSpecParser::parse(const std::string &name, std::istream &istr) { - typedef AutoPtr DocumentPtr; + using DocumentPtr = AutoPtr; InputSource src(istr); DOMParser parser; diff --git a/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp b/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp index 317b8056141e..6378c827da7e 100644 --- a/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp +++ b/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp @@ -117,8 +117,7 @@ double XMLInstrumentParameter::createParamValue( if (!m_logfileID.empty()) { // get value from time series - typedef std::map - StatisticsMapType; + using StatisticsMapType = std::map; StatisticsMapType statistics_types; statistics_types.emplace("first_value", Kernel::Math::FirstValue); statistics_types.emplace("last_value", Kernel::Math::LastValue); diff --git a/Framework/Geometry/src/Math/mathSupport.cpp b/Framework/Geometry/src/Math/mathSupport.cpp index e662bf7f4463..69ad25b1df9e 100644 --- a/Framework/Geometry/src/Math/mathSupport.cpp +++ b/Framework/Geometry/src/Math/mathSupport.cpp @@ -65,7 +65,7 @@ int solveCubic(const CInputIter Coef, std::complex &AnsA, */ { - typedef std::complex Cpair; + using Cpair = std::complex; double q, r; /* solution parameters */ double termR, discrim; double r13; diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h index bf96ea743aad..e9b79fdd159b 100644 --- a/Framework/Geometry/test/CSGObjectTest.h +++ b/Framework/Geometry/test/CSGObjectTest.h @@ -1147,7 +1147,7 @@ class CSGObjectTest : public CxxTest::TestSuite { private: /// Surface type - typedef std::map> STYPE; + using STYPE = std::map >; /// set timeTest true to get time comparisons of soild angle methods const static bool timeTest = false; @@ -1240,7 +1240,7 @@ class CSGObjectTest : public CxxTest::TestSuite { // PLANE SURFACES: - typedef std::pair SCompT; + using SCompT = std::pair; std::vector SurfLine; if (desired.find("60001") != std::string::npos) SurfLine.push_back(SCompT(60001, "px -1")); diff --git a/Framework/Geometry/test/MDBoxImplicitFunctionTest.h b/Framework/Geometry/test/MDBoxImplicitFunctionTest.h index e27544409c8f..38c8ea2c8ffe 100644 --- a/Framework/Geometry/test/MDBoxImplicitFunctionTest.h +++ b/Framework/Geometry/test/MDBoxImplicitFunctionTest.h @@ -11,7 +11,7 @@ using namespace Mantid; using namespace Mantid::Geometry; namespace { -typedef boost::tuple Extent; +using Extent = boost::tuple; } class MDBoxImplicitFunctionTest : public CxxTest::TestSuite { diff --git a/Framework/Geometry/test/MatrixVectorPairTest.h b/Framework/Geometry/test/MatrixVectorPairTest.h index 5cd141103460..160907e874b4 100644 --- a/Framework/Geometry/test/MatrixVectorPairTest.h +++ b/Framework/Geometry/test/MatrixVectorPairTest.h @@ -10,7 +10,7 @@ using namespace Mantid::Geometry; using namespace Mantid::Kernel; -typedef MatrixVectorPair V3RIntPair; +using V3RIntPair = MatrixVectorPair; class MatrixVectorPairTest : public CxxTest::TestSuite { public: diff --git a/Framework/Geometry/test/ParameterMapTest.h b/Framework/Geometry/test/ParameterMapTest.h index c9da12fe965c..f9c03f4d78a8 100644 --- a/Framework/Geometry/test/ParameterMapTest.h +++ b/Framework/Geometry/test/ParameterMapTest.h @@ -304,9 +304,7 @@ class ParameterMapTest : public CxxTest::TestSuite { test_Replacing_Existing_Parameter_On_A_Copy_Does_Not_Update_Original_Value_Using_AddHelpers_As_Strings() { // -- Specialized Helper Functions -- - typedef boost::function AddFuncHelper; + using AddFuncHelper = boost::function; // double AddFuncHelper faddDouble; diff --git a/Framework/Geometry/test/PeakTransformSelectorTest.h b/Framework/Geometry/test/PeakTransformSelectorTest.h index c2a1f2b76495..ac3c438324c0 100644 --- a/Framework/Geometry/test/PeakTransformSelectorTest.h +++ b/Framework/Geometry/test/PeakTransformSelectorTest.h @@ -31,9 +31,9 @@ class PeakTransformSelectorTest : public CxxTest::TestSuite { GCC_DIAG_ON_SUGGEST_OVERRIDE }; - typedef MockPeakTransformFactoryType<0> MockPeakTransformFactory; - typedef MockPeakTransformFactoryType<0> MockPeakTransformFactoryA; - typedef MockPeakTransformFactoryType<1> MockPeakTransformFactoryB; + using MockPeakTransformFactory = MockPeakTransformFactoryType<0>; + using MockPeakTransformFactoryA = MockPeakTransformFactoryType<0>; + using MockPeakTransformFactoryB = MockPeakTransformFactoryType<1>; public: void test_Constructor() { diff --git a/Framework/Geometry/test/XMLInstrumentParameterTest.h b/Framework/Geometry/test/XMLInstrumentParameterTest.h index b2bfe5cd2bf6..ce2ac3c2ceb9 100644 --- a/Framework/Geometry/test/XMLInstrumentParameterTest.h +++ b/Framework/Geometry/test/XMLInstrumentParameterTest.h @@ -16,7 +16,7 @@ using namespace Mantid::Kernel; class XMLInstrumentParameterTest : public CxxTest::TestSuite { private: - typedef boost::shared_ptr XMLInstrumentParameter_sptr; + using XMLInstrumentParameter_sptr = boost::shared_ptr; /** Construction logic for the XMLInstrumentParameter type isn't great, so this From bf8d1cbd760598b52db6aeebc0932bec8c0083ab Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Wed, 14 Mar 2018 09:58:14 -0400 Subject: [PATCH 201/364] clang-format --- .../Algorithms/src/PolarizationEfficiencyCor.cpp | 14 +++++++------- Framework/Geometry/src/Math/BnId.cpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp b/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp index 3d30c504028c..8a143b35f67b 100644 --- a/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp +++ b/Framework/Algorithms/src/PolarizationEfficiencyCor.cpp @@ -557,13 +557,13 @@ void PolarizationEfficiencyCor::checkConsistentX( const auto &P2x = efficiencies.P2->x(); checkX(P2x, "P2"); // A local helper function to check an input workspace against F1. - auto checkWS = [&checkX](const API::MatrixWorkspace_sptr &ws, - const std::string &tag) { - const auto nHist = ws->getNumberHistograms(); - for (size_t i = 0; i != nHist; ++i) { - checkX(ws->x(i), tag); - } - }; + auto checkWS = + [&checkX](const API::MatrixWorkspace_sptr &ws, const std::string &tag) { + const auto nHist = ws->getNumberHistograms(); + for (size_t i = 0; i != nHist; ++i) { + checkX(ws->x(i), tag); + } + }; if (inputs.mmWS) { checkWS(inputs.mmWS, Flippers::OffOff); } diff --git a/Framework/Geometry/src/Math/BnId.cpp b/Framework/Geometry/src/Math/BnId.cpp index 7fb6b3b33b71..5c5ae0742ea7 100644 --- a/Framework/Geometry/src/Math/BnId.cpp +++ b/Framework/Geometry/src/Math/BnId.cpp @@ -279,7 +279,7 @@ std::pair BnId::makeCombination(const BnId &A) const if (Tnum == A.Tnum) return std::pair(0, BnId()); - int flag(0); // numb of diff + int flag(0); // numb of diff auto avc = A.Tval.cbegin(); std::vector::const_iterator chpt; // change point for (auto tvc = Tval.cbegin(); tvc != Tval.cend(); ++tvc, ++avc) { From 75a6070f6715b1025934706c3c465e99148ec778 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:03:13 +0000 Subject: [PATCH 202/364] Re #22048: Applied fixes to Framework/HistogramData. --- .../HistogramData/inc/MantidHistogramData/FixedLengthVector.h | 4 ++-- Framework/HistogramData/inc/MantidHistogramData/Iterable.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h b/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h index 43c2f53d227f..417c30240c68 100644 --- a/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h +++ b/Framework/HistogramData/inc/MantidHistogramData/FixedLengthVector.h @@ -169,8 +169,8 @@ template class FixedLengthVector { const double &back() const { return m_data.back(); } // expose typedefs for the iterator types in the underlying container - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; }; } // namespace detail diff --git a/Framework/HistogramData/inc/MantidHistogramData/Iterable.h b/Framework/HistogramData/inc/MantidHistogramData/Iterable.h index cdfea120b060..864bb4c84f82 100644 --- a/Framework/HistogramData/inc/MantidHistogramData/Iterable.h +++ b/Framework/HistogramData/inc/MantidHistogramData/Iterable.h @@ -86,8 +86,8 @@ template class Iterable { } // expose typedefs for the iterator types in the underlying container - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; protected: ~Iterable() = default; From 63cd4a6f47c47ffc6d350a14535f07fa5ffbccc8 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:04:49 +0000 Subject: [PATCH 203/364] Re #22048: Applied fixes to Framework/ICat. --- .../inc/MantidICat/GSoap/soapserializersStub.h | 4 ++-- Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h | 15 +++++++-------- .../MantidICat/ICat3/GSoapGenerated/ICat3Stub.h | 4 ++-- .../MantidICat/ICat4/GSoapGenerated/ICat4Stub.h | 4 ++-- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h b/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h index 9041bbe85cc0..3e7c7bb57d7a 100644 --- a/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h +++ b/Framework/ICat/inc/MantidICat/GSoap/soapserializersStub.h @@ -146,12 +146,12 @@ struct SOAP_ENV__Fault { #ifndef SOAP_TYPE__QName #define SOAP_TYPE__QName (5) -typedef char *_QName; +using _QName = char *; #endif #ifndef SOAP_TYPE__XML #define SOAP_TYPE__XML (6) -typedef char *_XML; +using _XML = char *; #endif /******************************************************************************\ diff --git a/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h b/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h index 7a37356b858f..64e7e0721acc 100644 --- a/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h +++ b/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h @@ -1254,7 +1254,7 @@ extern const char soap_base64o[], soap_base64i[]; /* gSOAP status/error codes */ -typedef soap_int32 soap_status; +using soap_status = int32_t; #define SOAP_EOF EOF #define SOAP_ERR EOF @@ -1364,7 +1364,7 @@ typedef soap_int32 soap_status; /* gSOAP transport, connection, and content encoding modes */ -typedef soap_int32 soap_mode; +using soap_mode = int32_t; #define SOAP_IO 0x00000003 /* IO mask */ #define SOAP_IO_FLUSH 0x00000000 /* flush output immediately, no buffering */ @@ -1621,7 +1621,7 @@ typedef soap_int32 soap_mode; /* UCS-4 requires 32 bits (0-7FFFFFFF, the sign bit is used by gSOAP to * distinguish XML entities) */ -typedef soap_int32 soap_wchar; +using soap_wchar = int32_t; /* namespace table row */ struct Namespace { @@ -1822,7 +1822,7 @@ struct soap_multipart { const char *location; /* MIME Content-Location (optional) */ const char *description; /* MIME Content-Description (optional) */ #ifdef __cplusplus - typedef soap_multipart_iterator iterator; + using iterator = soap_multipart_iterator; #endif }; #endif @@ -1868,7 +1868,7 @@ struct soap_dom_attribute { wchar_t *wide; struct soap *soap; #ifdef __cplusplus - typedef soap_dom_attribute_iterator iterator; + using iterator = soap_dom_attribute_iterator; struct soap_dom_attribute &set(const char *nstr, const char *name); /* set namespace and name */ struct soap_dom_attribute &set(const char *data); /* set data */ @@ -1920,7 +1920,7 @@ struct soap_dom_element { char *tail; /* leading content before end tag */ struct soap *soap; /* soap context that manages this node */ #ifdef __cplusplus - typedef soap_dom_element_iterator iterator; + using iterator = soap_dom_element_iterator; struct soap_dom_element &set(const char *nstr, const char *name); struct soap_dom_element &set(const char *data); struct soap_dom_element &set(void *node, int type); @@ -2430,8 +2430,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_rand(void); #endif /* soap_traverse() traversal/walker routines take walker function arguments */ -typedef void soap_walker(struct soap *, void *, int, const char *, - const char *); +using soap_walker = void (struct soap *, void *, int, const char *, const char *); SOAP_FMAC5 int SOAP_FMAC6 soap_serve(struct soap *soap); SOAP_FMAC5 int SOAP_FMAC6 soap_serve_request(struct soap *soap); diff --git a/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h b/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h index 63eb0cc97f50..55b4342d456f 100644 --- a/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h +++ b/Framework/ICat/inc/MantidICat/ICat3/GSoapGenerated/ICat3Stub.h @@ -11887,12 +11887,12 @@ struct SOAP_ENV__Fault { #ifndef SOAP_TYPE_ICat3__QName #define SOAP_TYPE_ICat3__QName (5) -typedef char *_QName; +using _QName = char *; #endif #ifndef SOAP_TYPE_ICat3__XML #define SOAP_TYPE_ICat3__XML (6) -typedef char *_XML; +using _XML = char *; #endif /******************************************************************************\ diff --git a/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h b/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h index d033a6828382..8c998ddb6bd8 100644 --- a/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h +++ b/Framework/ICat/inc/MantidICat/ICat4/GSoapGenerated/ICat4Stub.h @@ -3265,12 +3265,12 @@ struct SOAP_ENV__Fault { #ifndef SOAP_TYPE_ICat4__QName #define SOAP_TYPE_ICat4__QName (5) -typedef char *_QName; +using _QName = char *; #endif #ifndef SOAP_TYPE_ICat4__XML #define SOAP_TYPE_ICat4__XML (6) -typedef char *_XML; +using _XML = char *; #endif /******************************************************************************\ From d85c9e38ab20c51381814e24fdd1dd98a336da80 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:07:13 +0000 Subject: [PATCH 204/364] Re #22048: Applied fixes to Framework/Kernel. --- Framework/Kernel/inc/MantidKernel/ANN/ANN.h | 16 ++++++++-------- Framework/Kernel/inc/MantidKernel/ANN/ANNx.h | 2 +- Framework/Kernel/inc/MantidKernel/Cache.h | 5 ++--- .../Kernel/inc/MantidKernel/ConfigService.h | 8 +++----- Framework/Kernel/inc/MantidKernel/DataItem.h | 4 ++-- Framework/Kernel/inc/MantidKernel/DataService.h | 7 +++---- Framework/Kernel/inc/MantidKernel/DiskBuffer.h | 12 ++---------- .../Kernel/inc/MantidKernel/DynamicFactory.h | 6 +++--- Framework/Kernel/inc/MantidKernel/FacilityInfo.h | 3 +-- Framework/Kernel/inc/MantidKernel/FunctionTask.h | 2 +- Framework/Kernel/inc/MantidKernel/IValidator.h | 2 +- .../Kernel/inc/MantidKernel/InstrumentInfo.h | 2 +- .../Kernel/inc/MantidKernel/InternetHelper.h | 2 +- .../Kernel/inc/MantidKernel/LibraryManager.h | 2 +- .../Kernel/inc/MantidKernel/ListValidator.h | 2 +- Framework/Kernel/inc/MantidKernel/LogParser.h | 2 +- Framework/Kernel/inc/MantidKernel/Logger.h | 2 +- Framework/Kernel/inc/MantidKernel/MDUnit.h | 4 ++-- .../Kernel/inc/MantidKernel/MDUnitFactory.h | 4 ++-- Framework/Kernel/inc/MantidKernel/MRUList.h | 10 ++-------- Framework/Kernel/inc/MantidKernel/Material.h | 6 +++--- .../Kernel/inc/MantidKernel/MaterialBuilder.h | 2 +- Framework/Kernel/inc/MantidKernel/Matrix.h | 6 +++--- .../Kernel/inc/MantidKernel/MatrixProperty.h | 2 +- .../Kernel/inc/MantidKernel/NearestNeighbours.h | 5 ++--- .../Kernel/inc/MantidKernel/PropertyHelper.h | 6 +++--- .../Kernel/inc/MantidKernel/PropertyHistory.h | 6 +++--- .../Kernel/inc/MantidKernel/PropertyManager.h | 4 ++-- .../MantidKernel/PropertyManagerDataService.h | 3 +-- .../inc/MantidKernel/PropertyManagerProperty.h | 4 ++-- .../inc/MantidKernel/PropertyManager_fwd.h | 8 ++++---- .../MantidKernel/PseudoRandomNumberGenerator.h | 2 +- .../Kernel/inc/MantidKernel/RemoteJobManager.h | 2 +- .../Kernel/inc/MantidKernel/SingletonHolder.h | 4 ++-- .../Kernel/inc/MantidKernel/StringTokenizer.h | 6 +++--- Framework/Kernel/inc/MantidKernel/TestChannel.h | 2 +- .../inc/MantidKernel/ThreadSchedulerMutexes.h | 4 ++-- Framework/Kernel/inc/MantidKernel/TimeSplitter.h | 2 +- .../Kernel/inc/MantidKernel/TypedValidator.h | 2 +- Framework/Kernel/inc/MantidKernel/Unit.h | 12 +++++------- Framework/Kernel/inc/MantidKernel/UnitFactory.h | 2 +- Framework/Kernel/inc/MantidKernel/UnitLabel.h | 4 ++-- Framework/Kernel/inc/MantidKernel/UsageService.h | 2 +- .../Kernel/inc/MantidKernel/UserCatalogInfo.h | 2 +- Framework/Kernel/inc/MantidKernel/VMD.h | 4 ++-- Framework/Kernel/inc/MantidKernel/cow_ptr.h | 8 ++++---- Framework/Kernel/src/ANN/kd_tree.h | 10 +--------- Framework/Kernel/src/ANN/pr_queue.h | 4 ++-- Framework/Kernel/src/ANN/pr_queue_k.h | 4 ++-- Framework/Kernel/src/ConfigService.cpp | 2 +- Framework/Kernel/src/FacilityInfo.cpp | 2 +- Framework/Kernel/src/Interpolation.cpp | 2 +- Framework/Kernel/src/MagneticIon.cpp | 2 +- Framework/Kernel/src/Material.cpp | 4 ++-- Framework/Kernel/src/MaterialBuilder.cpp | 2 +- Framework/Kernel/src/MaterialXMLParser.cpp | 11 +++++------ Framework/Kernel/src/PropertyManager.cpp | 2 +- Framework/Kernel/src/Strings.cpp | 4 ++-- Framework/Kernel/src/UserStringParser.cpp | 4 ++-- Framework/Kernel/src/VectorHelper.cpp | 6 +++--- Framework/Kernel/test/BinaryFileTest.h | 4 ++-- Framework/Kernel/test/DataServiceTest.h | 4 ++-- Framework/Kernel/test/DynamicFactoryTest.h | 2 +- Framework/Kernel/test/FilterChannelTest.h | 2 +- Framework/Kernel/test/IValidatorTest.h | 2 +- Framework/Kernel/test/MDAxisValidatorTest.h | 2 +- Framework/Kernel/test/MultiFileNameParserTest.h | 2 +- .../test/NDPseudoRandomNumberGeneratorTest.h | 4 ++-- Framework/Kernel/test/PropertyWithValueTest.h | 4 ++-- 69 files changed, 130 insertions(+), 162 deletions(-) diff --git a/Framework/Kernel/inc/MantidKernel/ANN/ANN.h b/Framework/Kernel/inc/MantidKernel/ANN/ANN.h index 11e2f98825fe..66646cfd0a6c 100644 --- a/Framework/Kernel/inc/MantidKernel/ANN/ANN.h +++ b/Framework/Kernel/inc/MantidKernel/ANN/ANN.h @@ -176,8 +176,8 @@ enum ANNbool { ANNfalse = 0, ANNtrue = 1 }; // ANN boolean type (non ANSI C++) // not occur in distance calculation. //---------------------------------------------------------------------- -typedef double ANNcoord; // coordinate data type -typedef double ANNdist; // distance data type +using ANNcoord = double; // coordinate data type +using ANNdist = double; // distance data type //---------------------------------------------------------------------- // ANNidx @@ -193,7 +193,7 @@ typedef double ANNdist; // distance data type // It should be distinguishable from any valid array index. //---------------------------------------------------------------------- -typedef int ANNidx; // point index +using ANNidx = int; // point index const ANNidx ANN_NULL_IDX = -1; // a NULL point index //---------------------------------------------------------------------- @@ -408,10 +408,10 @@ const ANNbool ANN_ALLOW_SELF_MATCH = ANNfalse; // when returning the results of k-nearest neighbor queries. //---------------------------------------------------------------------- -typedef ANNcoord *ANNpoint; // a point -typedef ANNpoint *ANNpointArray; // an array of points -typedef ANNdist *ANNdistArray; // an array of distances -typedef ANNidx *ANNidxArray; // an array of point indices +using ANNpoint = ANNcoord *; // a point +using ANNpointArray = ANNpoint *; // an array of points +using ANNdistArray = ANNdist *; // an array of distances +using ANNidxArray = ANNidx *; // an array of point indices //---------------------------------------------------------------------- // Basic point and array utilities: @@ -768,7 +768,7 @@ const int ANN_N_SHRINK_RULES = 4; // number of shrink rules //---------------------------------------------------------------------- class ANNkdStats; // stats on kd-tree class ANNkd_node; // generic node in a kd-tree -typedef ANNkd_node *ANNkd_ptr; // pointer to a kd-tree node +using ANNkd_ptr = ANNkd_node *; // pointer to a kd-tree node class DLL_API ANNkd_tree : public ANNpointSet { protected: diff --git a/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h b/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h index f5d990c5c51b..0a6b7860f396 100644 --- a/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h +++ b/Framework/Kernel/inc/MantidKernel/ANN/ANNx.h @@ -200,6 +200,6 @@ class ANNorthHalfSpace { }; // array of halfspaces -typedef ANNorthHalfSpace *ANNorthHSArray; +using ANNorthHSArray = ANNorthHalfSpace *; #endif diff --git a/Framework/Kernel/inc/MantidKernel/Cache.h b/Framework/Kernel/inc/MantidKernel/Cache.h index e403a2bf8a8c..f8ff898e1161 100644 --- a/Framework/Kernel/inc/MantidKernel/Cache.h +++ b/Framework/Kernel/inc/MantidKernel/Cache.h @@ -167,10 +167,9 @@ template class DLLExport Cache { /// internal mutex mutable std::mutex m_mutex; /// iterator typedef - typedef typename std::map::iterator CacheMapIterator; + using CacheMapIterator = typename std::map::iterator; /// const_iterator typedef - typedef typename std::map::const_iterator - CacheMapConstIterator; + using CacheMapConstIterator = typename std::map::const_iterator; }; } // namespace Kernel diff --git a/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Framework/Kernel/inc/MantidKernel/ConfigService.h index e22ad3433e9a..0b9f4daa61e4 100644 --- a/Framework/Kernel/inc/MantidKernel/ConfigService.h +++ b/Framework/Kernel/inc/MantidKernel/ConfigService.h @@ -357,12 +357,10 @@ class MANTID_KERNEL_DLL ConfigServiceImpl final { EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; -typedef Mantid::Kernel::SingletonHolder ConfigService; +using ConfigService = Mantid::Kernel::SingletonHolder; -typedef Mantid::Kernel::ConfigServiceImpl::ValueChanged - ConfigValChangeNotification; -typedef const Poco::AutoPtr & - ConfigValChangeNotification_ptr; +using ConfigValChangeNotification = Mantid::Kernel::ConfigServiceImpl::ValueChanged; +using ConfigValChangeNotification_ptr = const Poco::AutoPtr &; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/DataItem.h b/Framework/Kernel/inc/MantidKernel/DataItem.h index fd02ec7edaab..ec3a665f266f 100644 --- a/Framework/Kernel/inc/MantidKernel/DataItem.h +++ b/Framework/Kernel/inc/MantidKernel/DataItem.h @@ -92,9 +92,9 @@ class MANTID_KERNEL_DLL DataItem { }; /// Shared pointer to a DataItem -typedef boost::shared_ptr DataItem_sptr; +using DataItem_sptr = boost::shared_ptr; /// Shared pointer to a const DataItem -typedef boost::shared_ptr DataItem_const_sptr; +using DataItem_const_sptr = boost::shared_ptr; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/DataService.h b/Framework/Kernel/inc/MantidKernel/DataService.h index c29896cf0470..12a78532ade3 100644 --- a/Framework/Kernel/inc/MantidKernel/DataService.h +++ b/Framework/Kernel/inc/MantidKernel/DataService.h @@ -75,12 +75,11 @@ struct CaseInsensitiveCmp { template class DLLExport DataService { private: /// Typedef for the map holding the names of and pointers to the data objects - typedef std::map, CaseInsensitiveCmp> - svcmap; + using svcmap = std::map, CaseInsensitiveCmp>; /// Iterator for the data store map - typedef typename svcmap::iterator svc_it; + using svc_it = typename svcmap::iterator; /// Const iterator for the data store map - typedef typename svcmap::const_iterator svc_constit; + using svc_constit = typename svcmap::const_iterator; public: /// Class for named object notifications diff --git a/Framework/Kernel/inc/MantidKernel/DiskBuffer.h b/Framework/Kernel/inc/MantidKernel/DiskBuffer.h index 638fcaebc9be..5806a3deb46b 100644 --- a/Framework/Kernel/inc/MantidKernel/DiskBuffer.h +++ b/Framework/Kernel/inc/MantidKernel/DiskBuffer.h @@ -61,18 +61,10 @@ class DLLExport DiskBuffer { * Index 1: Position in the file. * Index 2: Size of the free block */ - typedef boost::multi_index::multi_index_container< - FreeBlock, - boost::multi_index::indexed_by< - boost::multi_index::ordered_non_unique< - BOOST_MULTI_INDEX_CONST_MEM_FUN(FreeBlock, uint64_t, - getFilePosition)>, - boost::multi_index::ordered_non_unique< - BOOST_MULTI_INDEX_CONST_MEM_FUN(FreeBlock, uint64_t, getSize)>>> - freeSpace_t; + using freeSpace_t = boost::multi_index::multi_index_container >, boost::multi_index::ordered_non_unique< ::boost::multi_index::const_mem_fun > > >; /// A way to index the free space by their size - typedef freeSpace_t::nth_index<1>::type freeSpace_bySize_t; + using freeSpace_bySize_t = freeSpace_t::nth_index<1>::type; DiskBuffer(); DiskBuffer(uint64_t m_writeBufferSize); diff --git a/Framework/Kernel/inc/MantidKernel/DynamicFactory.h b/Framework/Kernel/inc/MantidKernel/DynamicFactory.h index 625381c994f7..84d7d8efd903 100644 --- a/Framework/Kernel/inc/MantidKernel/DynamicFactory.h +++ b/Framework/Kernel/inc/MantidKernel/DynamicFactory.h @@ -32,7 +32,7 @@ namespace Kernel { //---------------------------------------------------------------------------- class Logger; -typedef std::less CaseSensitiveStringComparator; +using CaseSensitiveStringComparator = std::less; /** @class DynamicFactory DynamicFactory.h Kernel/DynamicFactory.h @@ -96,7 +96,7 @@ class DynamicFactory { void disableNotifications() { m_notifyStatus = Disabled; } /// A typedef for the instantiator - typedef AbstractInstantiator AbstractFactory; + using AbstractFactory = AbstractInstantiator; /// Destroys the DynamicFactory and deletes the instantiators for /// all registered classes. virtual ~DynamicFactory() { @@ -237,7 +237,7 @@ class DynamicFactory { } /// A typedef for the map of registered classes - typedef std::map FactoryMap; + using FactoryMap = std::map; /// The map holding the registered class names and their instantiators FactoryMap _map; /// Flag marking whether we should dispatch notifications diff --git a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h index a1da07cbd62f..05f1a335f0a2 100644 --- a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h +++ b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h @@ -131,8 +131,7 @@ class MANTID_KERNEL_DLL FacilityInfo { /// this facility // TODO: remove RemoteJobManager form here (trac ticket #11373) - typedef std::map> - ComputeResourcesMap; + using ComputeResourcesMap = std::map >; ComputeResourcesMap m_computeResources; ///< list of compute resources ///(clusters, etc...) available at /// this facility diff --git a/Framework/Kernel/inc/MantidKernel/FunctionTask.h b/Framework/Kernel/inc/MantidKernel/FunctionTask.h index 64ee25057731..ad73391beea5 100644 --- a/Framework/Kernel/inc/MantidKernel/FunctionTask.h +++ b/Framework/Kernel/inc/MantidKernel/FunctionTask.h @@ -25,7 +25,7 @@ namespace Kernel { class DLLExport FunctionTask final : public Task { public: /// Typedef for a function with no arguments and no return - typedef void (*voidFunction)(); + using voidFunction = void (*)(); //--------------------------------------------------------------------------------------------- /** Constructor for a simple void function. * diff --git a/Framework/Kernel/inc/MantidKernel/IValidator.h b/Framework/Kernel/inc/MantidKernel/IValidator.h index c814d71e84f5..f1f0aad93984 100644 --- a/Framework/Kernel/inc/MantidKernel/IValidator.h +++ b/Framework/Kernel/inc/MantidKernel/IValidator.h @@ -19,7 +19,7 @@ namespace Kernel { class IValidator; /// A shared_ptr to an IValidator -typedef boost::shared_ptr IValidator_sptr; +using IValidator_sptr = boost::shared_ptr; namespace { /// Helper object to determine if a type is either a pointer/shared_ptr diff --git a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h index 85dc0b5de58c..924739756217 100644 --- a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h +++ b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h @@ -90,7 +90,7 @@ class MANTID_KERNEL_DLL InstrumentInfo { /// Typedef for the zeropadding holder, first is starting run-number, /// second is file prefix - zero padding pair - typedef std::map> ZeroPaddingMap; + using ZeroPaddingMap = std::map >; /// get the zeropadding part int getZeroPadding(ZeroPaddingMap::const_iterator it) const { return it->second.second; diff --git a/Framework/Kernel/inc/MantidKernel/InternetHelper.h b/Framework/Kernel/inc/MantidKernel/InternetHelper.h index 7f6902353e39..a7c3835ae2a2 100644 --- a/Framework/Kernel/inc/MantidKernel/InternetHelper.h +++ b/Framework/Kernel/inc/MantidKernel/InternetHelper.h @@ -99,7 +99,7 @@ class MANTID_KERNEL_DLL InternetHelper { virtual ~InternetHelper(); // Convenience typedef - typedef std::map StringToStringMap; + using StringToStringMap = std::map; // getters and setters void setTimeout(int seconds); diff --git a/Framework/Kernel/inc/MantidKernel/LibraryManager.h b/Framework/Kernel/inc/MantidKernel/LibraryManager.h index d8bb2acee8eb..aa308087a3a9 100644 --- a/Framework/Kernel/inc/MantidKernel/LibraryManager.h +++ b/Framework/Kernel/inc/MantidKernel/LibraryManager.h @@ -82,7 +82,7 @@ class MANTID_KERNEL_DLL LibraryManagerImpl { EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; -typedef Mantid::Kernel::SingletonHolder LibraryManager; +using LibraryManager = Mantid::Kernel::SingletonHolder; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/ListValidator.h b/Framework/Kernel/inc/MantidKernel/ListValidator.h index 136cd4e50c9e..67408b649129 100644 --- a/Framework/Kernel/inc/MantidKernel/ListValidator.h +++ b/Framework/Kernel/inc/MantidKernel/ListValidator.h @@ -196,7 +196,7 @@ template class ListValidator : public TypedValidator { }; /// ListValidator is used heavily -typedef ListValidator StringListValidator; +using StringListValidator = ListValidator; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/LogParser.h b/Framework/Kernel/inc/MantidKernel/LogParser.h index f74caf208127..ed5175e83598 100644 --- a/Framework/Kernel/inc/MantidKernel/LogParser.h +++ b/Framework/Kernel/inc/MantidKernel/LogParser.h @@ -107,7 +107,7 @@ class MANTID_KERNEL_DLL LogParser { /// Typedef for a map of string commands to an enum of strongly typed /// commands. - typedef std::map CommandMap; + using CommandMap = std::map; /// TimeSeriesProperty containing data periods. Created by LogParser boost::shared_ptr m_periods; diff --git a/Framework/Kernel/inc/MantidKernel/Logger.h b/Framework/Kernel/inc/MantidKernel/Logger.h index b13542c7dbc7..ed1a37ffe4f4 100644 --- a/Framework/Kernel/inc/MantidKernel/Logger.h +++ b/Framework/Kernel/inc/MantidKernel/Logger.h @@ -67,7 +67,7 @@ class ThreadSafeLogStream; class MANTID_KERNEL_DLL Logger { public: // Our logger's priority types are the same as POCO's Message's types. - typedef Poco::Message::Priority Priority; + using Priority = Poco::Message::Priority; static const std::string *PriorityNames; diff --git a/Framework/Kernel/inc/MantidKernel/MDUnit.h b/Framework/Kernel/inc/MantidKernel/MDUnit.h index e76bd5eaaf05..6b483b5f2794 100644 --- a/Framework/Kernel/inc/MantidKernel/MDUnit.h +++ b/Framework/Kernel/inc/MantidKernel/MDUnit.h @@ -83,8 +83,8 @@ class DLLExport LabelUnit : public MDUnit { LabelUnit *clone() const override; }; -typedef std::unique_ptr MDUnit_uptr; -typedef std::unique_ptr MDUnit_const_uptr; +using MDUnit_uptr = std::unique_ptr; +using MDUnit_const_uptr = std::unique_ptr; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h b/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h index 5cd8d1726e8c..10c97e81a4a3 100644 --- a/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h +++ b/Framework/Kernel/inc/MantidKernel/MDUnitFactory.h @@ -65,9 +65,9 @@ class MANTID_KERNEL_DLL ReciprocalLatticeUnitFactory : public MDUnitFactory { bool canInterpret(const std::string &unitString) const override; }; -typedef std::unique_ptr MDUnitFactory_uptr; +using MDUnitFactory_uptr = std::unique_ptr; -typedef std::unique_ptr MDUnitFactory_const_uptr; +using MDUnitFactory_const_uptr = std::unique_ptr; /// Convience method. Pre-constructed builder chain. MDUnitFactory_uptr MANTID_KERNEL_DLL makeMDUnitFactoryChain(); diff --git a/Framework/Kernel/inc/MantidKernel/MRUList.h b/Framework/Kernel/inc/MantidKernel/MRUList.h index 34c47702f471..59d3dadfee05 100644 --- a/Framework/Kernel/inc/MantidKernel/MRUList.h +++ b/Framework/Kernel/inc/MantidKernel/MRUList.h @@ -48,16 +48,10 @@ namespace Kernel { template class DLLExport MRUList { private: /// hideous typedef for the container holding the list - typedef typename boost::multi_index::multi_index_container< - T *, - boost::multi_index::indexed_by< - boost::multi_index::sequenced<>, - boost::multi_index::hashed_unique>> item_list; + using item_list = typename boost::multi_index::multi_index_container, boost::multi_index::hashed_unique< ::boost::multi_index::const_mem_fun > > >; /// This typedef makes an ordered item list (you access it by the 1st index) - typedef typename boost::multi_index::nth_index::type - ordered_item_list; + using ordered_item_list = typename boost::multi_index::nth_index::type; /// The most recently used list mutable item_list il; diff --git a/Framework/Kernel/inc/MantidKernel/Material.h b/Framework/Kernel/inc/MantidKernel/Material.h index c77bd7991eeb..3cf75d93ad12 100644 --- a/Framework/Kernel/inc/MantidKernel/Material.h +++ b/Framework/Kernel/inc/MantidKernel/Material.h @@ -64,7 +64,7 @@ class MANTID_KERNEL_DLL Material { FormulaUnit(const PhysicalConstants::Atom &atom, const double multiplicity); }; - typedef std::vector ChemicalFormula; + using ChemicalFormula = std::vector; static ChemicalFormula parseChemicalFormula(const std::string chemicalSymbol); @@ -193,9 +193,9 @@ class MANTID_KERNEL_DLL Material { }; /// Typedef for a shared pointer -typedef boost::shared_ptr Material_sptr; +using Material_sptr = boost::shared_ptr; /// Typedef for a shared pointer to a const object -typedef boost::shared_ptr Material_const_sptr; +using Material_const_sptr = boost::shared_ptr; } } diff --git a/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h b/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h index 52746165bacf..dc5d05f7e273 100644 --- a/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h +++ b/Framework/Kernel/inc/MantidKernel/MaterialBuilder.h @@ -62,7 +62,7 @@ class MANTID_KERNEL_DLL MaterialBuilder { Material build() const; private: - typedef std::tuple Composition; + using Composition = std::tuple; bool hasOverrideNeutronProperties() const; void overrideNeutronProperties(PhysicalConstants::NeutronAtom &neutron) const; diff --git a/Framework/Kernel/inc/MantidKernel/Matrix.h b/Framework/Kernel/inc/MantidKernel/Matrix.h index 0c1661aa1782..13564d466ac0 100644 --- a/Framework/Kernel/inc/MantidKernel/Matrix.h +++ b/Framework/Kernel/inc/MantidKernel/Matrix.h @@ -43,7 +43,7 @@ Code Documentation is available at: template class DLLExport Matrix { public: /// Enable users to retrieve the element type - typedef T value_type; + using value_type = T; private: size_t m_numRows; ///< Number of rows (x coordinate) @@ -194,9 +194,9 @@ template class DLLExport Matrix { // Typedefs //------------------------------------------------------------------------- /// A matrix of doubles -typedef Mantid::Kernel::Matrix DblMatrix; +using DblMatrix = Mantid::Kernel::Matrix; /// A matrix of ints -typedef Mantid::Kernel::Matrix IntMatrix; +using IntMatrix = Mantid::Kernel::Matrix; //------------------------------------------------------------------------- // Utility methods diff --git a/Framework/Kernel/inc/MantidKernel/MatrixProperty.h b/Framework/Kernel/inc/MantidKernel/MatrixProperty.h index 2d0a49f831f1..1fe8149a0f52 100644 --- a/Framework/Kernel/inc/MantidKernel/MatrixProperty.h +++ b/Framework/Kernel/inc/MantidKernel/MatrixProperty.h @@ -35,7 +35,7 @@ Code Documentation is available at: template class MatrixProperty : public PropertyWithValue> { /// Typedef the held type - typedef Kernel::Matrix HeldType; + using HeldType = Kernel::Matrix; public: /// Constructor diff --git a/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h b/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h index 3ba554a9bdc2..2ab313617113 100644 --- a/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h +++ b/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h @@ -103,9 +103,8 @@ template class DLLExport NearestNeighbours { public: // typedefs for code brevity - typedef Eigen::Matrix VectorType; - typedef std::vector> - NearestNeighbourResults; + using VectorType = Eigen::Matrix; + using NearestNeighbourResults = std::vector >; /** Create a nearest neighbour search object * diff --git a/Framework/Kernel/inc/MantidKernel/PropertyHelper.h b/Framework/Kernel/inc/MantidKernel/PropertyHelper.h index 86c67e618ab1..1fbe4423e46f 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyHelper.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyHelper.h @@ -210,7 +210,7 @@ namespace detail { template void toValue(const std::string &strvalue, std::vector &value, std::true_type) { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer values(strvalue, ",", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); value.clear(); @@ -224,7 +224,7 @@ template void toValue(const std::string &strvalue, std::vector &value, std::false_type) { // Split up comma-separated properties - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer values(strvalue, ",", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); @@ -263,7 +263,7 @@ template void toValue(const std::string &strvalue, std::vector> &value, const std::string &outerDelimiter = ",", const std::string &innerDelimiter = "+") { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer tokens(strvalue, outerDelimiter, tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); diff --git a/Framework/Kernel/inc/MantidKernel/PropertyHistory.h b/Framework/Kernel/inc/MantidKernel/PropertyHistory.h index c45a142bc2bb..9ddcba5d976a 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyHistory.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyHistory.h @@ -96,9 +96,9 @@ class MANTID_KERNEL_DLL PropertyHistory { }; // typedefs for property history pointers -typedef boost::shared_ptr PropertyHistory_sptr; -typedef boost::shared_ptr PropertyHistory_const_sptr; -typedef std::vector PropertyHistories; +using PropertyHistory_sptr = boost::shared_ptr; +using PropertyHistory_const_sptr = boost::shared_ptr; +using PropertyHistories = std::vector; MANTID_KERNEL_DLL std::ostream &operator<<(std::ostream &, const PropertyHistory &); diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManager.h b/Framework/Kernel/inc/MantidKernel/PropertyManager.h index dc1d192135b8..40d847287ed5 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyManager.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyManager.h @@ -135,7 +135,7 @@ class MANTID_KERNEL_DLL PropertyManager : virtual public IPropertyManager { const std::unordered_set &ignoreProperties); /// typedef for the map holding the properties - typedef std::map> PropertyMap; + using PropertyMap = std::map >; /// The properties under management PropertyMap m_properties; /// Stores the order in which the properties were declared. @@ -143,7 +143,7 @@ class MANTID_KERNEL_DLL PropertyManager : virtual public IPropertyManager { }; /// Typedef for a shared pointer to a PropertyManager -typedef boost::shared_ptr PropertyManager_sptr; +using PropertyManager_sptr = boost::shared_ptr; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h b/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h index f516aec4ccac..5a3493f1efdc 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h @@ -53,8 +53,7 @@ class MANTID_KERNEL_DLL PropertyManagerDataServiceImpl final EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; -typedef Mantid::Kernel::SingletonHolder - PropertyManagerDataService; +using PropertyManagerDataService = Mantid::Kernel::SingletonHolder; } // Namespace Kernel } // Namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h b/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h index 04a9a5839d6d..f71e0094bcb1 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyManagerProperty.h @@ -35,8 +35,8 @@ class MANTID_KERNEL_DLL PropertyManagerProperty final : public PropertyWithValue { public: // Convenience typedefs - typedef PropertyWithValue BaseClass; - typedef PropertyManager_sptr ValueType; + using BaseClass = PropertyWithValue; + using ValueType = PropertyManager_sptr; PropertyManagerProperty(const std::string &name, unsigned int direction = Direction::Input); diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h b/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h index 1bbe4f8b0289..a5ba001ece5b 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyManager_fwd.h @@ -34,13 +34,13 @@ namespace Kernel { /// forward declare of Mantid::Kernel::PropertyManager class PropertyManager; /// shared pointer to Mantid::Kernel::PropertyManager -typedef boost::shared_ptr PropertyManager_sptr; +using PropertyManager_sptr = boost::shared_ptr; /// shared pointer to Mantid::Kernel::PropertyManager(const version) -typedef boost::shared_ptr PropertyManager_const_sptr; +using PropertyManager_const_sptr = boost::shared_ptr; /// unique pointer to Mantid::Kernel::PropertyManager -typedef std::unique_ptr PropertyManager_uptr; +using PropertyManager_uptr = std::unique_ptr; /// unique pointer to Mantid::Kernel::PropertyManager (const version) -typedef std::unique_ptr PropertyManager_const_uptr; +using PropertyManager_const_uptr = std::unique_ptr; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h b/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h index 1d028f768176..64e321d8a22f 100644 --- a/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h +++ b/Framework/Kernel/inc/MantidKernel/PseudoRandomNumberGenerator.h @@ -62,7 +62,7 @@ class MANTID_KERNEL_DLL PseudoRandomNumberGenerator void generateNextPoint() override; // Interface to boost distribution generators /// Result (output) value type. - typedef double result_type; + using result_type = double; /// Return the minimum value of the range virtual double min() const = 0; /// Return the maximum value of the range diff --git a/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h b/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h index 534d9b219ae9..69ad397f50f4 100644 --- a/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h +++ b/Framework/Kernel/inc/MantidKernel/RemoteJobManager.h @@ -32,7 +32,7 @@ class MANTID_KERNEL_DLL RemoteJobManager { // Name/Value pairs for POST data. Note that the second string might be // binary, and might be // fairly large. (If it were a JPG image for example...) - typedef std::map PostDataMap; + using PostDataMap = std::map; // Low level HTTP functions - GET, POST, etc... // It's up to the various algorithms to know what to do with these functions diff --git a/Framework/Kernel/inc/MantidKernel/SingletonHolder.h b/Framework/Kernel/inc/MantidKernel/SingletonHolder.h index b4a440788d8a..be71da991e35 100644 --- a/Framework/Kernel/inc/MantidKernel/SingletonHolder.h +++ b/Framework/Kernel/inc/MantidKernel/SingletonHolder.h @@ -34,7 +34,7 @@ namespace Mantid { namespace Kernel { /// prototype for function passed to atexit() -typedef void (*atexit_func_t)(); +using atexit_func_t = void (*)(); extern MANTID_KERNEL_DLL void CleanupSingletons(); extern MANTID_KERNEL_DLL void AddSingleton(atexit_func_t func); @@ -43,7 +43,7 @@ extern MANTID_KERNEL_DLL void AddSingleton(atexit_func_t func); template class SingletonHolder { public: /// Allow users to access to the type returned by Instance() - typedef T HeldType; + using HeldType = T; static T &Instance(); diff --git a/Framework/Kernel/inc/MantidKernel/StringTokenizer.h b/Framework/Kernel/inc/MantidKernel/StringTokenizer.h index a2a039a56d08..7bb06f574ea1 100644 --- a/Framework/Kernel/inc/MantidKernel/StringTokenizer.h +++ b/Framework/Kernel/inc/MantidKernel/StringTokenizer.h @@ -50,9 +50,9 @@ class DLLExport StringTokenizer { TOK_IGNORE_FINAL_EMPTY_TOKEN = 4 ///< ignore an empty token at the end of the string. }; - typedef std::vector TokenVec; - typedef std::vector::iterator Iterator; - typedef std::vector::const_iterator ConstIterator; + using TokenVec = std::vector; + using Iterator = std::vector::iterator; + using ConstIterator = std::vector::const_iterator; /// Constructs an object from an empty string. StringTokenizer() = default; /// Constructor requiring a string to tokenize and a string of separators. diff --git a/Framework/Kernel/inc/MantidKernel/TestChannel.h b/Framework/Kernel/inc/MantidKernel/TestChannel.h index 24cfa6a0aa01..8cadb9a7613b 100644 --- a/Framework/Kernel/inc/MantidKernel/TestChannel.h +++ b/Framework/Kernel/inc/MantidKernel/TestChannel.h @@ -44,7 +44,7 @@ namespace Mantid { class MANTID_KERNEL_DLL TestChannel : public Poco::Channel { public: - typedef std::list MsgList; + using MsgList = std::list; void log(const Poco::Message &msg) override; MsgList &list(); void clear(); diff --git a/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h b/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h index 95fbce921a05..396e49499d85 100644 --- a/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h +++ b/Framework/Kernel/inc/MantidKernel/ThreadSchedulerMutexes.h @@ -157,9 +157,9 @@ class DLLExport ThreadSchedulerMutexes : public ThreadScheduler { protected: /// Map to tasks, sorted by cost - typedef std::multimap InnerMap; + using InnerMap = std::multimap; /// Map to maps, sorted by Mutex* - typedef std::map, InnerMap> SuperMap; + using SuperMap = std::map, InnerMap>; /** A super map; first key = a Mutex * * Inside it: second key = the cost. */ diff --git a/Framework/Kernel/inc/MantidKernel/TimeSplitter.h b/Framework/Kernel/inc/MantidKernel/TimeSplitter.h index 53c6af492c48..0e6f664ff496 100644 --- a/Framework/Kernel/inc/MantidKernel/TimeSplitter.h +++ b/Framework/Kernel/inc/MantidKernel/TimeSplitter.h @@ -53,7 +53,7 @@ class MANTID_KERNEL_DLL SplittingInterval { * It is a vector of SplittingInterval classes. * */ -typedef std::vector TimeSplitterType; +using TimeSplitterType = std::vector; // -------------- Operators --------------------- MANTID_KERNEL_DLL TimeSplitterType diff --git a/Framework/Kernel/inc/MantidKernel/TypedValidator.h b/Framework/Kernel/inc/MantidKernel/TypedValidator.h index eb83c0be3a35..67279f4ee7da 100644 --- a/Framework/Kernel/inc/MantidKernel/TypedValidator.h +++ b/Framework/Kernel/inc/MantidKernel/TypedValidator.h @@ -78,7 +78,7 @@ template class DLLExport TypedValidator> : public IValidator { /// Shared ptr type - typedef boost::shared_ptr ElementType_sptr; + using ElementType_sptr = boost::shared_ptr; protected: /// Override this function to check the validity of the type diff --git a/Framework/Kernel/inc/MantidKernel/Unit.h b/Framework/Kernel/inc/MantidKernel/Unit.h index b2ee0891898a..3cbb16907fb8 100644 --- a/Framework/Kernel/inc/MantidKernel/Unit.h +++ b/Framework/Kernel/inc/MantidKernel/Unit.h @@ -226,23 +226,21 @@ class MANTID_KERNEL_DLL Unit { private: /// A 'quick conversion' requires the constant by which to multiply the input /// and the power to which to raise it - typedef std::pair ConstantAndPower; + using ConstantAndPower = std::pair; /// Lists, for a given starting unit, the units to which a 'quick conversion' /// can be made - typedef tbb::concurrent_unordered_map - UnitConversions; + using UnitConversions = tbb::concurrent_unordered_map; /// The possible 'quick conversions' are held in a map with the starting unit /// as the key - typedef tbb::concurrent_unordered_map - ConversionsMap; + using ConversionsMap = tbb::concurrent_unordered_map; /// The table of possible 'quick conversions' static ConversionsMap s_conversionFactors; }; /// Shared pointer to the Unit base class -typedef boost::shared_ptr Unit_sptr; +using Unit_sptr = boost::shared_ptr; /// Shared pointer to the Unit base class (const version) -typedef boost::shared_ptr Unit_const_sptr; +using Unit_const_sptr = boost::shared_ptr; //---------------------------------------------------------------------- // Now the concrete units classes diff --git a/Framework/Kernel/inc/MantidKernel/UnitFactory.h b/Framework/Kernel/inc/MantidKernel/UnitFactory.h index d8de9c7e8fa7..8e4c70e2817b 100644 --- a/Framework/Kernel/inc/MantidKernel/UnitFactory.h +++ b/Framework/Kernel/inc/MantidKernel/UnitFactory.h @@ -86,7 +86,7 @@ class MANTID_KERNEL_DLL UnitFactoryImpl final : public DynamicFactory { EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; -typedef SingletonHolder UnitFactory; +using UnitFactory = SingletonHolder; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/UnitLabel.h b/Framework/Kernel/inc/MantidKernel/UnitLabel.h index 9348e7d16a61..2f4bab8a3163 100644 --- a/Framework/Kernel/inc/MantidKernel/UnitLabel.h +++ b/Framework/Kernel/inc/MantidKernel/UnitLabel.h @@ -38,11 +38,11 @@ class MANTID_KERNEL_DLL UnitLabel { UnitLabel() = delete; /// Type that contains a plain-text string - typedef std::string AsciiString; + using AsciiString = std::string; /// Type that can hold a unicode string. This may vary per-platform depending /// on the /// width of the the built-in std::wstring - typedef std::wstring Utf8String; + using Utf8String = std::wstring; /// Constructor giving labels as ascii, unicode, and latex respectively UnitLabel(const AsciiString &ascii, const Utf8String &unicode, diff --git a/Framework/Kernel/inc/MantidKernel/UsageService.h b/Framework/Kernel/inc/MantidKernel/UsageService.h index e5dc24cfc374..aa4090fe6e5f 100644 --- a/Framework/Kernel/inc/MantidKernel/UsageService.h +++ b/Framework/Kernel/inc/MantidKernel/UsageService.h @@ -147,7 +147,7 @@ class MANTID_KERNEL_DLL UsageServiceImpl { EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; -typedef Mantid::Kernel::SingletonHolder UsageService; +using UsageService = Mantid::Kernel::SingletonHolder; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h b/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h index 86e92bda36aa..9c9028f6127e 100644 --- a/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h +++ b/Framework/Kernel/inc/MantidKernel/UserCatalogInfo.h @@ -9,7 +9,7 @@ namespace Mantid { namespace Kernel { -typedef boost::optional OptionalPath; +using OptionalPath = boost::optional; class CatalogConfigService { public: diff --git a/Framework/Kernel/inc/MantidKernel/VMD.h b/Framework/Kernel/inc/MantidKernel/VMD.h index 4cfce09de7a6..f3e73f0d26c8 100644 --- a/Framework/Kernel/inc/MantidKernel/VMD.h +++ b/Framework/Kernel/inc/MantidKernel/VMD.h @@ -98,10 +98,10 @@ template class DLLExport VMDBase { }; /// Underlying data type for the VMD type -typedef float VMD_t; +using VMD_t = float; /// Define the VMD as using the double or float data type. -typedef VMDBase VMD; +using VMD = VMDBase; // Overload operator << MANTID_KERNEL_DLL std::ostream &operator<<(std::ostream &, diff --git a/Framework/Kernel/inc/MantidKernel/cow_ptr.h b/Framework/Kernel/inc/MantidKernel/cow_ptr.h index dce5b0dd32b6..d062271470df 100644 --- a/Framework/Kernel/inc/MantidKernel/cow_ptr.h +++ b/Framework/Kernel/inc/MantidKernel/cow_ptr.h @@ -56,8 +56,8 @@ namespace Kernel { */ template class cow_ptr { public: - typedef boost::shared_ptr ptr_type; ///< typedef for the storage - typedef DataType value_type; ///< typedef for the data type + using ptr_type = boost::shared_ptr; ///< typedef for the storage + using value_type = DataType; ///< typedef for the data type private: ptr_type Data; ///< Real object Ptr @@ -203,10 +203,10 @@ cow_ptr::cow_ptr(const ptr_type &resourceSptr) noexcept { } // NAMESPACE Kernel /// typedef for the data storage used in Mantid matrix workspaces -typedef std::vector MantidVec; +using MantidVec = std::vector; /// typedef for the pointer to data storage used in Mantid matrix workspaces -typedef Kernel::cow_ptr MantidVecPtr; +using MantidVecPtr = Kernel::cow_ptr; } // NAMESPACE Mantid diff --git a/Framework/Kernel/src/ANN/kd_tree.h b/Framework/Kernel/src/ANN/kd_tree.h index 93db64f4cf14..01d9e464154f 100644 --- a/Framework/Kernel/src/ANN/kd_tree.h +++ b/Framework/Kernel/src/ANN/kd_tree.h @@ -70,15 +70,7 @@ class ANNkd_node { // generic kd-tree node (empty shell) // for building the tree. //---------------------------------------------------------------------- -typedef void (*ANNkd_splitter)( // splitting routine for kd-trees - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) +using ANNkd_splitter = void (*)(ANNpointArray, ANNidxArray, const ANNorthRect &, int, int, int &, ANNcoord &, int &); // num of points on low side (returned) //---------------------------------------------------------------------- // Leaf kd-tree node diff --git a/Framework/Kernel/src/ANN/pr_queue.h b/Framework/Kernel/src/ANN/pr_queue.h index f25bbad05ba7..ff6d7db8a636 100644 --- a/Framework/Kernel/src/ANN/pr_queue.h +++ b/Framework/Kernel/src/ANN/pr_queue.h @@ -32,8 +32,8 @@ //---------------------------------------------------------------------- // Basic types. //---------------------------------------------------------------------- -typedef void *PQinfo; // info field is generic pointer -typedef ANNdist PQkey; // key field is distance +using PQinfo = void *; // info field is generic pointer +using PQkey = ANNdist; // key field is distance //---------------------------------------------------------------------- // Priority queue diff --git a/Framework/Kernel/src/ANN/pr_queue_k.h b/Framework/Kernel/src/ANN/pr_queue_k.h index ed501d3f1859..8da43d1e0bb9 100644 --- a/Framework/Kernel/src/ANN/pr_queue_k.h +++ b/Framework/Kernel/src/ANN/pr_queue_k.h @@ -31,8 +31,8 @@ //---------------------------------------------------------------------- // Basic types //---------------------------------------------------------------------- -typedef ANNdist PQKkey; // key field is distance -typedef int PQKinfo; // info field is int +using PQKkey = ANNdist; // key field is distance +using PQKinfo = int; // info field is int //---------------------------------------------------------------------- // Constants diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp index 53385cfa7e4e..ff37f5e09b0d 100644 --- a/Framework/Kernel/src/ConfigService.cpp +++ b/Framework/Kernel/src/ConfigService.cpp @@ -110,7 +110,7 @@ std::vector splitPath(const std::string &path) { template class ConfigServiceImpl::WrappedObject : public T { public: /// The template type of class that is being wrapped - typedef T element_type; + using element_type = T; /// Simple constructor WrappedObject() : T() { m_pPtr = static_cast(this); } diff --git a/Framework/Kernel/src/FacilityInfo.cpp b/Framework/Kernel/src/FacilityInfo.cpp index 52de210b3fad..519821a771f7 100644 --- a/Framework/Kernel/src/FacilityInfo.cpp +++ b/Framework/Kernel/src/FacilityInfo.cpp @@ -90,7 +90,7 @@ void FacilityInfo::fillExtensions(const Poco::XML::Element *elem) { g_log.error("No file extensions defined"); throw std::runtime_error("No file extensions defined"); } - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer exts(extsStr, ",", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); for (const auto &ext : exts) { diff --git a/Framework/Kernel/src/Interpolation.cpp b/Framework/Kernel/src/Interpolation.cpp index 6ff8d02d72ac..4b866761d461 100644 --- a/Framework/Kernel/src/Interpolation.cpp +++ b/Framework/Kernel/src/Interpolation.cpp @@ -174,7 +174,7 @@ std::ostream &operator<<(std::ostream &os, const Interpolation &f) { */ std::istream &operator>>(std::istream &in, Interpolation &f) { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; std::string str; getline(in, str); tokenizer values(str, ";", tokenizer::TOK_TRIM); diff --git a/Framework/Kernel/src/MagneticIon.cpp b/Framework/Kernel/src/MagneticIon.cpp index 72034db1325a..a6a611fd394f 100644 --- a/Framework/Kernel/src/MagneticIon.cpp +++ b/Framework/Kernel/src/MagneticIon.cpp @@ -807,7 +807,7 @@ constexpr double j_Au5[3][9] = { } /// Typedef the map type -typedef std::unordered_map IonIndex; +using IonIndex = std::unordered_map; /// Forward decalre intializer void createIonLookup(IonIndex &ion_map); diff --git a/Framework/Kernel/src/Material.cpp b/Framework/Kernel/src/Material.cpp index 4d81289c1b94..099e90ab8241 100644 --- a/Framework/Kernel/src/Material.cpp +++ b/Framework/Kernel/src/Material.cpp @@ -10,8 +10,8 @@ namespace Mantid { namespace Kernel { -typedef Mantid::Kernel::StringTokenizer tokenizer; -typedef std::pair str_pair; +using tokenizer = Mantid::Kernel::StringTokenizer; +using str_pair = std::pair; using PhysicalConstants::Atom; using PhysicalConstants::getAtom; diff --git a/Framework/Kernel/src/MaterialBuilder.cpp b/Framework/Kernel/src/MaterialBuilder.cpp index 9d74c5bc1cff..1d9113f21b51 100644 --- a/Framework/Kernel/src/MaterialBuilder.cpp +++ b/Framework/Kernel/src/MaterialBuilder.cpp @@ -59,7 +59,7 @@ MaterialBuilder &MaterialBuilder::setFormula(const std::string &formula) { throw std::invalid_argument( "MaterialBuilder::setFormula() - Empty formula provided."); } - typedef Material::ChemicalFormula ChemicalFormula; + using ChemicalFormula = Material::ChemicalFormula; try { m_formula = Mantid::Kernel::make_unique( ChemicalFormula(Material::parseChemicalFormula(formula))); diff --git a/Framework/Kernel/src/MaterialXMLParser.cpp b/Framework/Kernel/src/MaterialXMLParser.cpp index 1e110f55d4e2..e376188d2ef2 100644 --- a/Framework/Kernel/src/MaterialXMLParser.cpp +++ b/Framework/Kernel/src/MaterialXMLParser.cpp @@ -54,7 +54,7 @@ struct BuilderHandle { virtual void operator()(MaterialBuilder &builder, const std::string &value) const = 0; }; -typedef std::unique_ptr BuilderHandle_uptr; +using BuilderHandle_uptr = std::unique_ptr; // Pointer to member function on MaterialBuilder template @@ -65,8 +65,7 @@ using BuilderMethod = MaterialBuilder &(MaterialBuilder::*)(ArgType); template struct TypedBuilderHandle final : public BuilderHandle { // Remove const/reference qualifiers from ArgType - typedef typename std::remove_const< - typename std::remove_reference::type>::type ValueType; + using ValueType = typename std::remove_const::type>::type; explicit TypedBuilderHandle(BuilderMethod m) : BuilderHandle(), m_method(m) {} @@ -81,7 +80,7 @@ struct TypedBuilderHandle final : public BuilderHandle { BuilderMethod m_method; }; -typedef std::unordered_map Handlers; +using Handlers = std::unordered_map; // Insert a handle into the given map template @@ -148,7 +147,7 @@ void addToBuilder(MaterialBuilder *builder, const std::string &attr, */ Material MaterialXMLParser::parse(std::istream &istr) const { using namespace Poco::XML; - typedef AutoPtr DocumentPtr; + using DocumentPtr = AutoPtr; InputSource src(istr); DOMParser parser; @@ -195,7 +194,7 @@ Material MaterialXMLParser::parse(std::istream &istr) const { */ Material MaterialXMLParser::parse(Poco::XML::Element *element) const { using namespace Poco::XML; - typedef AutoPtr NamedNodeMapPtr; + using NamedNodeMapPtr = AutoPtr; NamedNodeMapPtr attrs = element->attributes(); const auto id = attrs->getNamedItem(ID_ATT); if (!id || id->nodeValue().empty()) { diff --git a/Framework/Kernel/src/PropertyManager.cpp b/Framework/Kernel/src/PropertyManager.cpp index 6cf843553ef2..ca022354426d 100644 --- a/Framework/Kernel/src/PropertyManager.cpp +++ b/Framework/Kernel/src/PropertyManager.cpp @@ -347,7 +347,7 @@ void PropertyManager::setPropertiesWithSimpleString( const std::unordered_set &ignoreProperties) { ::Json::Value propertyJson; // Split up comma-separated properties - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; boost::char_separator sep(";"); tokenizer propPairs(propertiesString, ";", diff --git a/Framework/Kernel/src/Strings.cpp b/Framework/Kernel/src/Strings.cpp index a1f1868ee9a7..7798b8f2d862 100644 --- a/Framework/Kernel/src/Strings.cpp +++ b/Framework/Kernel/src/Strings.cpp @@ -850,7 +850,7 @@ int setValues(const std::string &Line, const std::vector &Index, // mathFunc::crossSort(sIndex,OPt); - typedef std::vector::const_iterator iVecIter; + using iVecIter = std::vector::const_iterator; std::vector::const_iterator sc = sIndex.begin(); std::vector::const_iterator oc = OPt.begin(); int cnt(0); @@ -1072,7 +1072,7 @@ int isMember(const std::vector &group, */ std::vector parseRange(const std::string &str, const std::string &elemSep, const std::string &rangeSep) { - typedef Mantid::Kernel::StringTokenizer Tokenizer; + using Tokenizer = Mantid::Kernel::StringTokenizer; Tokenizer elements; diff --git a/Framework/Kernel/src/UserStringParser.cpp b/Framework/Kernel/src/UserStringParser.cpp index d365130ca67d..7c094e615dc2 100644 --- a/Framework/Kernel/src/UserStringParser.cpp +++ b/Framework/Kernel/src/UserStringParser.cpp @@ -84,7 +84,7 @@ bool UserStringParser::Contains(const std::string &input, char ch) { */ std::vector UserStringParser::separateComma(const std::string &input) { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer tokens(input, ",", Mantid::Kernel::StringTokenizer::TOK_TRIM); return tokens.asVector(); } @@ -142,7 +142,7 @@ void UserStringParser::Tokenize(const std::string &input, const std::string &delimiter, unsigned int &start, unsigned int &end, unsigned int &step) { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer tokens(input, delimiter); // validate the separated tokens if (!isValidStepSeparator(input, tokens.asVector())) { diff --git a/Framework/Kernel/src/VectorHelper.cpp b/Framework/Kernel/src/VectorHelper.cpp index 199281c7001d..d2aa37397932 100644 --- a/Framework/Kernel/src/VectorHelper.cpp +++ b/Framework/Kernel/src/VectorHelper.cpp @@ -211,7 +211,7 @@ void rebin(const std::vector &xold, const std::vector &yold, } } else { // non-distribution, just square root final error value - typedef double (*pf)(double); + using pf = double (*)(double); pf uf = std::sqrt; std::transform(enew.begin(), enew.end(), enew.begin(), uf); } @@ -322,7 +322,7 @@ void rebinHistogram(const std::vector &xold, // (should be done externally) { // Now take the root-square of the errors - typedef double (*pf)(double); + using pf = double (*)(double); pf uf = std::sqrt; std::transform(enew.begin(), enew.end(), enew.begin(), uf); } @@ -523,7 +523,7 @@ std::vector splitStringIntoVector(std::string listString) { // Split the string and turn it into a vector. std::vector values; - typedef std::vector split_vector_type; + using split_vector_type = std::vector; split_vector_type strs; boost::split(strs, listString, boost::is_any_of(", ")); diff --git a/Framework/Kernel/test/BinaryFileTest.h b/Framework/Kernel/test/BinaryFileTest.h index 11dae6ad287e..b0d5bd2efd60 100644 --- a/Framework/Kernel/test/BinaryFileTest.h +++ b/Framework/Kernel/test/BinaryFileTest.h @@ -16,9 +16,9 @@ using std::cout; //========================================================================================== /// Make the code clearer by having this an explicit type -typedef uint32_t PixelType; +using PixelType = uint32_t; /// Type for the DAS time of flight (data file) -typedef uint32_t DasTofType; +using DasTofType = uint32_t; /// Structure that matches the form in the binary event list. struct DasEvent { /// Time of flight. diff --git a/Framework/Kernel/test/DataServiceTest.h b/Framework/Kernel/test/DataServiceTest.h index 14b39c910d0b..cdd80bae12fb 100644 --- a/Framework/Kernel/test/DataServiceTest.h +++ b/Framework/Kernel/test/DataServiceTest.h @@ -295,8 +295,8 @@ class DataServiceTest : public CxxTest::TestSuite { svc.add("Four", four); svc.add("Two", two); - typedef Mantid::Kernel::DataServiceSort sortedEnum; - typedef Mantid::Kernel::DataServiceHidden hiddenEnum; + using sortedEnum = Mantid::Kernel::DataServiceSort; + using hiddenEnum = Mantid::Kernel::DataServiceHidden; // First assert that sort does not impact size TS_ASSERT_EQUALS(svc.getObjectNames(sortedEnum::Sorted).size(), diff --git a/Framework/Kernel/test/DynamicFactoryTest.h b/Framework/Kernel/test/DynamicFactoryTest.h index fbbc52509ead..19d9e912b759 100644 --- a/Framework/Kernel/test/DynamicFactoryTest.h +++ b/Framework/Kernel/test/DynamicFactoryTest.h @@ -20,7 +20,7 @@ class CaseSensitiveIntFactory : public DynamicFactory {}; class DynamicFactoryTest : public CxxTest::TestSuite { - typedef boost::shared_ptr int_ptr; + using int_ptr = boost::shared_ptr; public: // This pair of boilerplate methods prevent the suite being created statically diff --git a/Framework/Kernel/test/FilterChannelTest.h b/Framework/Kernel/test/FilterChannelTest.h index e59ffadbaa43..e21210140e4e 100644 --- a/Framework/Kernel/test/FilterChannelTest.h +++ b/Framework/Kernel/test/FilterChannelTest.h @@ -140,7 +140,7 @@ class FilterChannelTest : public CxxTest::TestSuite { a.addChannel(tChannel.get()); // create a priority map - typedef std::map priorityMap; + using priorityMap = std::map; priorityMap pMap; pMap.insert(priorityMap::value_type(1, "FATAL")); pMap.insert(priorityMap::value_type(2, "CRITICAL")); diff --git a/Framework/Kernel/test/IValidatorTest.h b/Framework/Kernel/test/IValidatorTest.h index 3aac7815d0e2..8005c39019cc 100644 --- a/Framework/Kernel/test/IValidatorTest.h +++ b/Framework/Kernel/test/IValidatorTest.h @@ -25,7 +25,7 @@ class DataNotCopiedValidator : public Mantid::Kernel::IValidator { private: std::string check(const boost::any &value) const override { - typedef std::vector HeldType; + using HeldType = std::vector; const HeldType *dataPtr = boost::any_cast(value); m_head = dataPtr->data(); return ""; diff --git a/Framework/Kernel/test/MDAxisValidatorTest.h b/Framework/Kernel/test/MDAxisValidatorTest.h index df39af877fa1..f21d126f0b44 100644 --- a/Framework/Kernel/test/MDAxisValidatorTest.h +++ b/Framework/Kernel/test/MDAxisValidatorTest.h @@ -11,7 +11,7 @@ #include "boost/make_shared.hpp" using Mantid::Kernel::MDAxisValidator; -typedef boost::shared_ptr MDAxisValidator_sptr; +using MDAxisValidator_sptr = boost::shared_ptr; class MDAxisValidatorTest : public CxxTest::TestSuite { public: diff --git a/Framework/Kernel/test/MultiFileNameParserTest.h b/Framework/Kernel/test/MultiFileNameParserTest.h index 32038147bfbd..85eb85dead2b 100644 --- a/Framework/Kernel/test/MultiFileNameParserTest.h +++ b/Framework/Kernel/test/MultiFileNameParserTest.h @@ -19,7 +19,7 @@ class MultiFileNameParserTest : public CxxTest::TestSuite { } static void destroySuite(MultiFileNameParserTest *suite) { delete suite; } - typedef std::vector> ParsedRuns; + using ParsedRuns = std::vector >; ///////////////////////////////////////////////////////////////////////////// // Testing of parseMultiRunString. diff --git a/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h b/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h index b2d023026329..18de5157a0f2 100644 --- a/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h +++ b/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h @@ -13,7 +13,7 @@ using Mantid::Kernel::NDRandomNumberGenerator; class NDPseudoRandomNumberGeneratorTest : public CxxTest::TestSuite { private: - typedef boost::shared_ptr NDGenerator_sptr; + using NDGenerator_sptr = boost::shared_ptr; public: void test_That_Next_Always_Returns_ND_Size_Array() { @@ -63,7 +63,7 @@ class NDPseudoRandomNumberGeneratorTest : public CxxTest::TestSuite { createTestGenerator(const size_t seedValue, const double start = -1.0, const double end = -1.0) { using namespace Mantid::Kernel; - typedef NDPseudoRandomNumberGenerator NDMersenneTwister; + using NDMersenneTwister = NDPseudoRandomNumberGenerator; const unsigned int ndims(3); if (start > 0.0 && end > 0.0) return boost::make_shared(ndims, seedValue, start, diff --git a/Framework/Kernel/test/PropertyWithValueTest.h b/Framework/Kernel/test/PropertyWithValueTest.h index 7ed65e384702..0dd1155b1402 100644 --- a/Framework/Kernel/test/PropertyWithValueTest.h +++ b/Framework/Kernel/test/PropertyWithValueTest.h @@ -107,8 +107,8 @@ class PropertyWithValueTest : public CxxTest::TestSuite { the size of the property is 2. */ void testSizeOfVectorOfVectorProperty() { - typedef std::vector VecInt; - typedef std::vector VecVecInt; + using VecInt = std::vector; + using VecVecInt = std::vector; // Test vector value property. VecVecInt v; v.push_back(VecInt(1, 0)); From 823000ada38f42067a5fece751f8eda8ef247b87 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:21:37 +0000 Subject: [PATCH 205/364] Re #22048: Applied fixes to Framework/LiveData. --- .../ISIS/ISISHistoDataListener.h | 2 +- .../ISIS/ISISLiveEventDataListener.h | 2 +- .../MantidLiveData/SNSLiveEventDataListener.h | 5 ++-- Framework/LiveData/src/ISIS/DAE/idc.h | 4 +-- .../LiveData/src/ISIS/DAE/isisds_command.h | 3 +- .../private/Schema/flatbuffers/flatbuffers.h | 28 ++++++++----------- 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h index acc637fc511a..c0cd15cf9b7e 100644 --- a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h +++ b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISHistoDataListener.h @@ -12,7 +12,7 @@ //---------------------------------------------------------------------- struct idc_info; -typedef struct idc_info *idc_handle_t; +using idc_handle_t = struct idc_info *; namespace Mantid { //---------------------------------------------------------------------- diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h index 64e5871e0376..1609026442d0 100644 --- a/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h +++ b/Framework/LiveData/inc/MantidLiveData/ISIS/ISISLiveEventDataListener.h @@ -25,7 +25,7 @@ const long RECV_WAIT = 1; // Forward declarations //---------------------------------------------------------------------- struct idc_info; -typedef struct idc_info *idc_handle_t; +using idc_handle_t = struct idc_info *; namespace Mantid { namespace LiveData { diff --git a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h index ea02545c2332..ae59b224e1c9 100644 --- a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h +++ b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h @@ -180,7 +180,7 @@ class SNSLiveEventDataListener : public API::LiveListener, // maps to variable name // (variable names are unique, so we don't need to worry about device names.) - typedef std::map, std::string> NameMapType; + using NameMapType = std::map, std::string>; NameMapType m_nameMap; // --------------------------------------------------------------------------- @@ -195,8 +195,7 @@ class SNSLiveEventDataListener : public API::LiveListener, // Maps the device ID / variable ID pair to the actual packet. Using a map // means we will only keep one packet (the most recent one) for each variable - typedef std::map, - boost::shared_ptr> VariableMapType; + using VariableMapType = std::map, boost::shared_ptr >; VariableMapType m_variableMap; // Process all the variable value packets stored in m_variableMap diff --git a/Framework/LiveData/src/ISIS/DAE/idc.h b/Framework/LiveData/src/ISIS/DAE/idc.h index ba5aee984fc0..442d560fc16a 100644 --- a/Framework/LiveData/src/ISIS/DAE/idc.h +++ b/Framework/LiveData/src/ISIS/DAE/idc.h @@ -25,12 +25,12 @@ * holds information about the DAE connection - defined fully in idc.c */ struct idc_info; -typedef struct idc_info *idc_handle_t; +using idc_handle_t = struct idc_info *; /** * prototype for error reporting function passed to IDCsetreportfunc() */ -typedef void (*idc_error_report_t)(int status, int code, const char *messsage); +using idc_error_report_t = void (*)(int, int, const char *); #ifdef __cplusplus #include diff --git a/Framework/LiveData/src/ISIS/DAE/isisds_command.h b/Framework/LiveData/src/ISIS/DAE/isisds_command.h index 4a9f25406f4b..145e9493c932 100644 --- a/Framework/LiveData/src/ISIS/DAE/isisds_command.h +++ b/Framework/LiveData/src/ISIS/DAE/isisds_command.h @@ -20,8 +20,7 @@ #ifndef ISISDS_COMMAND_H #define ISISDS_COMMAND_H -typedef void (*isisds_error_report_t)(int status, int code, - const char *messsage); +using isisds_error_report_t = void (*)(int, int, const char *); #define ISISDS_PORT 6789 diff --git a/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h b/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h index 21c1c3cb91c3..2c57e5aa153a 100644 --- a/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h +++ b/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h @@ -100,20 +100,19 @@ namespace flatbuffers { // Our default offset / size type, 32bit on purpose on 64bit systems. // Also, using a consistent offset type maintains compatibility of serialized // offset values between 32bit and 64bit systems. -typedef uint32_t uoffset_t; +using uoffset_t = uint32_t; // Signed offsets for references that can go in both directions. -typedef int32_t soffset_t; +using soffset_t = int32_t; // Offset/index used in v-tables, can be changed to uint8_t in // format forks to save a bit of space if desired. -typedef uint16_t voffset_t; +using voffset_t = uint16_t; -typedef uintmax_t largest_scalar_t; +using largest_scalar_t = uintmax_t; // Pointer to relinquished memory. -typedef std::unique_ptr> - unique_ptr_t; +using unique_ptr_t = std::unique_ptr >; // Wrapper for uoffset_t to allow safe template specialization. template struct Offset { @@ -195,14 +194,14 @@ template size_t AlignOf() { // The typedef is for the convenience of callers of this function // (avoiding the need for a trailing return decltype) template struct IndirectHelper { - typedef T return_type; + using return_type = T; static const size_t element_stride = sizeof(T); static return_type Read(const uint8_t *p, uoffset_t i) { return EndianScalar((reinterpret_cast(p))[i]); } }; template struct IndirectHelper> { - typedef const T *return_type; + using return_type = const T *; static const size_t element_stride = sizeof(uoffset_t); static return_type Read(const uint8_t *p, uoffset_t i) { p += i * sizeof(uoffset_t); @@ -210,7 +209,7 @@ template struct IndirectHelper> { } }; template struct IndirectHelper { - typedef const T *return_type; + using return_type = const T *; static const size_t element_stride = sizeof(T); static return_type Read(const uint8_t *p, uoffset_t i) { return reinterpret_cast(p + i * sizeof(T)); @@ -226,10 +225,7 @@ struct VectorIterator : public const typename IndirectHelper::return_type, typename IndirectHelper::return_type > ::type, uoffset_t > { - typedef std::iterator::return_type, - typename IndirectHelper::return_type>::type, uoffset_t> super_type; + using super_type = std::iterator::return_type, typename IndirectHelper::return_type>::type, uoffset_t>; public: VectorIterator(const uint8_t *data, uoffset_t i) : @@ -286,15 +282,15 @@ struct VectorIterator : public // Vector::data() assumes the vector elements start after the length field. template class Vector { public: - typedef VectorIterator iterator; - typedef VectorIterator const_iterator; + using iterator = VectorIterator; + using const_iterator = VectorIterator; uoffset_t size() const { return EndianScalar(length_); } // Deprecated: use size(). Here for backwards compatibility. uoffset_t Length() const { return size(); } - typedef typename IndirectHelper::return_type return_type; + using return_type = typename IndirectHelper::return_type; return_type Get(uoffset_t i) const { assert(i < size()); From fbfe4ca7877bc0108d22ec798322e8d923897c51 Mon Sep 17 00:00:00 2001 From: Brandon Hewer Date: Wed, 14 Mar 2018 14:20:49 +0000 Subject: [PATCH 206/364] MWRunFiles - only emit findingFiles() when find begins Refs #22074 --- qt/widgets/common/src/MWRunFiles.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qt/widgets/common/src/MWRunFiles.cpp b/qt/widgets/common/src/MWRunFiles.cpp index d978a5363a2c..9640ea3bd7a7 100644 --- a/qt/widgets/common/src/MWRunFiles.cpp +++ b/qt/widgets/common/src/MWRunFiles.cpp @@ -550,9 +550,6 @@ void MWRunFiles::findFiles(bool isModified) { * @return search text to create search params with */ const QString MWRunFiles::findFilesGetSearchText(QString &searchText) { - - emit findingFiles(); - // If we have an override instrument then add it in appropriate places to // the search text if (!m_defaultInstrumentName.isEmpty()) { @@ -590,6 +587,8 @@ const QString MWRunFiles::findFilesGetSearchText(QString &searchText) { */ void MWRunFiles::runFindFiles(const QString &searchText) { if (!searchText.isEmpty()) { + emit findingFiles(); + const auto parameters = createFindFilesSearchParameters(searchText.toStdString()); m_pool.createWorker(this, parameters); From 3650d022e3f81bad3a78353118c07ddbdff744c9 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:27:02 +0000 Subject: [PATCH 207/364] Re #22048: Applied fixes to Framework/MDAlgorithms. --- .../ConvertSpiceDataToRealSpace.h | 2 +- .../inc/MantidMDAlgorithms/ImportMDEventWorkspace.h | 2 +- .../inc/MantidMDAlgorithms/Integrate3DEvents.h | 5 ++--- .../MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h | 3 +-- .../inc/MantidMDAlgorithms/MDEventWSWrapper.h | 9 ++++----- .../inc/MantidMDAlgorithms/MDTransfFactory.h | 2 +- .../inc/MantidMDAlgorithms/MDTransfInterface.h | 4 ++-- .../Quantification/ForegroundModel.h | 4 ++-- .../Quantification/ForegroundModelFactory.h | 5 ++--- .../Quantification/MDResolutionConvolutionFactory.h | 5 ++--- .../SimulateResolutionConvolvedModel.h | 3 +-- .../src/BoxControllerSettingsAlgorithm.cpp | 2 +- Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp | 2 +- .../src/ConvertToDiffractionMDWorkspace.cpp | 2 +- Framework/MDAlgorithms/src/CutMD.cpp | 2 +- Framework/MDAlgorithms/src/FindPeaksMD.cpp | 6 +++--- .../MDAlgorithms/src/ImportMDHistoWorkspace.cpp | 2 +- Framework/MDAlgorithms/src/LoadMD.cpp | 2 +- Framework/MDAlgorithms/src/LoadSQW2.cpp | 2 +- Framework/MDAlgorithms/src/MDNormDirectSC.cpp | 2 +- Framework/MDAlgorithms/src/MDNormSCD.cpp | 2 +- .../Resolution/TobyFitResolutionModel.cpp | 2 +- Framework/MDAlgorithms/src/SaveMD.cpp | 2 +- Framework/MDAlgorithms/src/SaveMD2.cpp | 2 +- Framework/MDAlgorithms/src/SmoothMD.cpp | 13 +++++-------- Framework/MDAlgorithms/test/ConvertToMDTest.h | 2 +- Framework/MDAlgorithms/test/LoadMDTest.h | 2 +- Framework/MDAlgorithms/test/LoadSQW2Test.h | 6 +++--- Framework/MDAlgorithms/test/SmoothMDTest.h | 2 +- Framework/MDAlgorithms/test/WeightedMeanMDTest.h | 2 +- 30 files changed, 46 insertions(+), 55 deletions(-) diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h index f435fb8a2c11..2f0451581b8c 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h @@ -61,7 +61,7 @@ class DLLExport ConvertSpiceDataToRealSpace : public API::Algorithm { private: /// Typdef for the white-space separated file data type. - typedef std::deque DataCollectionType; + using DataCollectionType = std::deque; /// Initialisation code void init() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h index b7c7fec64c46..1be7c21e3619 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h @@ -56,7 +56,7 @@ class DLLExport ImportMDEventWorkspace : public API::Algorithm { private: /// Typdef for the white-space separated file data type. - typedef std::deque DataCollectionType; + using DataCollectionType = std::deque; /// All read-in data. DataCollectionType m_file_data; /// Iterator for the dimensionality start position. diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h index 99a771ecec23..2e582a03d626 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h @@ -67,9 +67,8 @@ struct IntegrationParameters { */ -typedef std::unordered_map< - int64_t, std::vector>> EventListMap; -typedef std::unordered_map PeakQMap; +using EventListMap = std::unordered_map > >; +using PeakQMap = std::unordered_map; class DLLExport Integrate3DEvents { public: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h index 34504cb5c9bb..2952d8e2b55e 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h @@ -53,8 +53,7 @@ class DLLExport LoadSQW2 : public API::IFileLoader { private: /// Local typedef for - typedef DataObjects::MDEventWorkspace, 4> - SQWWorkspace; + using SQWWorkspace = DataObjects::MDEventWorkspace, 4>; void init() override; void exec() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h index f3690c1e134a..ada40278317e 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h @@ -39,7 +39,7 @@ File change history is stored at: Code Documentation is available at: */ /// vectors of strings are often used here -typedef std::vector Strings; +using Strings = std::vector; /// predefenition of the class name class MDEventWSWrapper; @@ -47,13 +47,12 @@ class MDEventWSWrapper; // Boost function pointers with multiple arguments // appear not portable to all architectures supported (Fail on MAC) /// signature to void templated function -typedef void (MDEventWSWrapper::*fpVoidMethod)(); +using fpVoidMethod = void (MDEventWSWrapper::*)(); /// signature for the internal templated function pointer to add data to an /// existing workspace -typedef void (MDEventWSWrapper::*fpAddData)(float *, uint16_t *, uint32_t *, - coord_t *, size_t) const; +using fpAddData = void (MDEventWSWrapper::*)(float *, uint16_t *, uint32_t *, coord_t *, size_t) const; /// signature for the internal templated function pointer to create workspace -typedef void (MDEventWSWrapper::*fpCreateWS)(const MDWSDescription &mwsd); +using fpCreateWS = void (MDEventWSWrapper::*)(const MDWSDescription &); class DLLExport MDEventWSWrapper { public: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h index bfe1777de983..61bca51533de 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfFactory.h @@ -110,7 +110,7 @@ class MANTID_MDALGORITHMS_DLL MDTransfFactoryImpl /// The specialization of the SingletonHolder class that holds the /// MDTransformations Factory -typedef Kernel::SingletonHolder MDTransfFactory; +using MDTransfFactory = Kernel::SingletonHolder; } // namespace MDAlgorithms } // namespace Mantid diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h index 519e14f6ad93..e9ff3893a1e0 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfInterface.h @@ -236,8 +236,8 @@ class MDTransfInterface { Mantid::API::MatrixWorkspace_sptr underlyingWorkspace) const = 0; }; -typedef boost::shared_ptr MDTransf_sptr; -typedef boost::shared_ptr MDTransf_const_sptr; +using MDTransf_sptr = boost::shared_ptr; +using MDTransf_const_sptr = boost::shared_ptr; } // End MDAlgorighms namespace } // End Mantid namespace diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h index 8e54a0340f9b..23f983d13c2c 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModel.h @@ -135,9 +135,9 @@ class DLLExport ForegroundModel : public API::ParamFunction { }; /// boost::shared_ptr typedef -typedef boost::shared_ptr ForegroundModel_sptr; +using ForegroundModel_sptr = boost::shared_ptr; /// boost::shared_ptr to const typedef -typedef boost::shared_ptr ForegroundModel_const_sptr; +using ForegroundModel_const_sptr = boost::shared_ptr; } } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h index a54cbd7928f1..a857f1102d3f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h @@ -44,7 +44,7 @@ class MANTID_MDALGORITHMS_DLL ForegroundModelFactoryImpl : public Kernel::DynamicFactory { private: /// Base-class type - typedef Kernel::DynamicFactory BaseClass; + using BaseClass = Kernel::DynamicFactory; public: /// A create method to ensure the model is initialized properly @@ -69,8 +69,7 @@ class MANTID_MDALGORITHMS_DLL ForegroundModelFactoryImpl }; /// Typedef singleton instance to ForegroundFactory -typedef Kernel::SingletonHolder - ForegroundModelFactory; +using ForegroundModelFactory = Kernel::SingletonHolder; } } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h index 460fc90faa5b..4ccac15f70c6 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h @@ -42,7 +42,7 @@ class MANTID_MDALGORITHMS_DLL MDResolutionConvolutionFactoryImpl : public Kernel::DynamicFactory { private: /// Base-class type - typedef Kernel::DynamicFactory BaseClass; + using BaseClass = Kernel::DynamicFactory; public: /// A create method to ensure the type is initialized properly @@ -70,8 +70,7 @@ class MANTID_MDALGORITHMS_DLL MDResolutionConvolutionFactoryImpl }; /// Typedef singleton instance to MDResolutionConvolutionFactory -typedef Kernel::SingletonHolder - MDResolutionConvolutionFactory; +using MDResolutionConvolutionFactory = Kernel::SingletonHolder; } } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h index 5925817133cf..2b15e099219f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h @@ -66,8 +66,7 @@ class DLLExport SimulateResolutionConvolvedModel /// The input domain boost::shared_ptr m_calculatedValues; /// The output workspace type - typedef DataObjects::MDEventWorkspace, 4> - QOmegaWorkspace; + using QOmegaWorkspace = DataObjects::MDEventWorkspace, 4>; /// The output workspace boost::shared_ptr m_outputWS; diff --git a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp index 0d15d133c947..45f90cf92ef9 100644 --- a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp +++ b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp @@ -26,7 +26,7 @@ void BoxControllerSettingsAlgorithm::initBoxControllerProps( mustBeMoreThen1->setLower(1); // Split up comma-separated properties - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer values(SplitInto, ",", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); std::vector valueVec; diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp index bb5f39c02881..4383a4134ce6 100644 --- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp +++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp @@ -634,7 +634,7 @@ CalculateCoverageDGS::calculateIntersections(const double theta, } // sort intersections by final momentum - typedef std::vector::iterator IterType; + using IterType = std::vector::iterator; std::stable_sort( intersections.begin(), intersections.end(), compareMomentum); diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp index db50f17dd78e..76aa5e8e2b2b 100644 --- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp +++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp @@ -125,7 +125,7 @@ void ConvertToDiffractionMDWorkspace::init() { } /// Our MDLeanEvent dimension -typedef DataObjects::MDLeanEvent<3> MDE; +using MDE = DataObjects::MDLeanEvent<3>; /** Convert one spectrum to DataObjects. * Depending on options, it uses the histogram view or the diff --git a/Framework/MDAlgorithms/src/CutMD.cpp b/Framework/MDAlgorithms/src/CutMD.cpp index 024f5545e901..b1f6e68ac956 100644 --- a/Framework/MDAlgorithms/src/CutMD.cpp +++ b/Framework/MDAlgorithms/src/CutMD.cpp @@ -23,7 +23,7 @@ using namespace Mantid::Kernel; namespace { // Typedef to simplify function signatures -typedef std::pair MinMax; +using MinMax = std::pair; MinMax getDimensionExtents(IMDEventWorkspace_sptr ws, size_t index) { if (!ws) diff --git a/Framework/MDAlgorithms/src/FindPeaksMD.cpp b/Framework/MDAlgorithms/src/FindPeaksMD.cpp index a3f838e59389..309a9a590d71 100644 --- a/Framework/MDAlgorithms/src/FindPeaksMD.cpp +++ b/Framework/MDAlgorithms/src/FindPeaksMD.cpp @@ -394,7 +394,7 @@ void FindPeaksMD::findPeaks(typename MDEventWorkspace::sptr ws) { } g_log.information() << "Threshold signal density: " << threshold << '\n'; - typedef API::IMDNode *boxPtr; + using boxPtr = API::IMDNode *; // We will fill this vector with pointers to all the boxes (up to a given // depth) typename std::vector boxes; @@ -404,7 +404,7 @@ void FindPeaksMD::findPeaks(typename MDEventWorkspace::sptr ws) { ws->getBox()->getBoxes(boxes, 1000, true); // This pair is the - typedef std::pair dens_box; + using dens_box = std::pair; // Map that will sort the boxes by increasing density. The key = density; // value = box *. @@ -586,7 +586,7 @@ void FindPeaksMD::findPeaksHisto( peakWS->copyExperimentInfoFrom(ei.get()); // This pair is the - typedef std::pair dens_box; + using dens_box = std::pair; // Map that will sort the boxes by increasing density. The key = density; // value = box index. diff --git a/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp b/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp index 8a47aa239b57..bf3e213f1339 100644 --- a/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp +++ b/Framework/MDAlgorithms/src/ImportMDHistoWorkspace.cpp @@ -68,7 +68,7 @@ void ImportMDHistoWorkspace::exec() { } // Copy each string present in the file stream into a deque. - typedef std::deque box_collection; + using box_collection = std::deque; box_collection box_elements; std::copy(std::istream_iterator(file), std::istream_iterator(), diff --git a/Framework/MDAlgorithms/src/LoadMD.cpp b/Framework/MDAlgorithms/src/LoadMD.cpp index d96f7c0f220b..f587ebb61e0a 100644 --- a/Framework/MDAlgorithms/src/LoadMD.cpp +++ b/Framework/MDAlgorithms/src/LoadMD.cpp @@ -31,7 +31,7 @@ #include #include -typedef std::unique_ptr file_holder_type; +using file_holder_type = std::unique_ptr; using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/MDAlgorithms/src/LoadSQW2.cpp b/Framework/MDAlgorithms/src/LoadSQW2.cpp index 2c278d4e528b..434846121ae7 100644 --- a/Framework/MDAlgorithms/src/LoadSQW2.cpp +++ b/Framework/MDAlgorithms/src/LoadSQW2.cpp @@ -91,7 +91,7 @@ void LoadSQW2::init() { using namespace API; using Kernel::PropertyWithValue; using Kernel::StringListValidator; - typedef std::initializer_list StringInitializerList; + using StringInitializerList = std::initializer_list; // Inputs declareProperty( diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp index 11edab9841fc..c98032f79725 100644 --- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp +++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp @@ -450,7 +450,7 @@ void MDNormDirectSC::calculateNormalization( PhysicalConstants::meV * 1e-20 / (PhysicalConstants::h * PhysicalConstants::h); const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0)); - typedef Kernel::PropertyWithValue> VectorDoubleProperty; + using VectorDoubleProperty = Kernel::PropertyWithValue >; auto *rubwLog = dynamic_cast(exptInfoZero.getLog("RUBW_MATRIX")); if (!rubwLog) { diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp index 3aab5f50c708..bc80e73cfbb8 100644 --- a/Framework/MDAlgorithms/src/MDNormSCD.cpp +++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp @@ -403,7 +403,7 @@ void MDNormSCD::calculateNormalization( getProperty("SolidAngleWorkspace"); const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0)); - typedef Kernel::PropertyWithValue> VectorDoubleProperty; + using VectorDoubleProperty = Kernel::PropertyWithValue >; auto *rubwLog = dynamic_cast(exptInfoZero.getLog("RUBW_MATRIX")); if (!rubwLog) { diff --git a/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp b/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp index aa4e5a9ef975..6bb75c91ab39 100644 --- a/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp +++ b/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp @@ -597,7 +597,7 @@ void TobyFitResolutionModel::setupRandomNumberGenerator() { else if (m_mcType == 4) seed = static_cast(Poco::Timestamp().epochMicroseconds()); - typedef NDPseudoRandomNumberGenerator NDMersenneTwister; + using NDMersenneTwister = NDPseudoRandomNumberGenerator; for (size_t i = 0; i < ngenerators; ++i) { m_randomNumbers[i] = new NDMersenneTwister(nrand, seed, 0.0, 1.0); } diff --git a/Framework/MDAlgorithms/src/SaveMD.cpp b/Framework/MDAlgorithms/src/SaveMD.cpp index d82bd5c0c963..57e53480d49a 100644 --- a/Framework/MDAlgorithms/src/SaveMD.cpp +++ b/Framework/MDAlgorithms/src/SaveMD.cpp @@ -17,7 +17,7 @@ #include "MantidKernel/System.h" #include -typedef std::unique_ptr<::NeXus::File> file_holder_type; +using file_holder_type = std::unique_ptr< ::NeXus::File>; using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/MDAlgorithms/src/SaveMD2.cpp b/Framework/MDAlgorithms/src/SaveMD2.cpp index b9d3f5203375..56db72040b16 100644 --- a/Framework/MDAlgorithms/src/SaveMD2.cpp +++ b/Framework/MDAlgorithms/src/SaveMD2.cpp @@ -18,7 +18,7 @@ #include "MantidDataObjects/BoxControllerNeXusIO.h" #include "MantidKernel/ConfigService.h" -typedef std::unique_ptr<::NeXus::File> file_holder_type; +using file_holder_type = std::unique_ptr< ::NeXus::File>; using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/MDAlgorithms/src/SmoothMD.cpp b/Framework/MDAlgorithms/src/SmoothMD.cpp index 2b84722ff26c..6f2891f26407 100644 --- a/Framework/MDAlgorithms/src/SmoothMD.cpp +++ b/Framework/MDAlgorithms/src/SmoothMD.cpp @@ -30,22 +30,19 @@ using namespace Mantid::API; using namespace Mantid::DataObjects; // Typedef for width vector -typedef std::vector WidthVector; +using WidthVector = std::vector; // Typedef for kernel vector -typedef std::vector KernelVector; +using KernelVector = std::vector; // Typedef for an optional md histo workspace -typedef boost::optional - OptionalIMDHistoWorkspace_const_sptr; +using OptionalIMDHistoWorkspace_const_sptr = boost::optional; // Typedef for a smoothing function -typedef boost::function SmoothFunction; +using SmoothFunction = boost::function; // Typedef for a smoothing function map keyed by name. -typedef std::map SmoothFunctionMap; +using SmoothFunctionMap = std::map; namespace { diff --git a/Framework/MDAlgorithms/test/ConvertToMDTest.h b/Framework/MDAlgorithms/test/ConvertToMDTest.h index f57e4376c944..e92accccc487 100644 --- a/Framework/MDAlgorithms/test/ConvertToMDTest.h +++ b/Framework/MDAlgorithms/test/ConvertToMDTest.h @@ -76,7 +76,7 @@ class ConvertToMDTest : public CxxTest::TestSuite { static ConvertToMDTest *createSuite() { return new ConvertToMDTest(); } static void destroySuite(ConvertToMDTest *suite) { delete suite; } - typedef std::vector PropertyAllowedValues; + using PropertyAllowedValues = std::vector; void testInit() { diff --git a/Framework/MDAlgorithms/test/LoadMDTest.h b/Framework/MDAlgorithms/test/LoadMDTest.h index 41cd937c81aa..00394b574974 100644 --- a/Framework/MDAlgorithms/test/LoadMDTest.h +++ b/Framework/MDAlgorithms/test/LoadMDTest.h @@ -171,7 +171,7 @@ class LoadMDTest : public CxxTest::TestSuite { template void do_test_exec(bool FileBackEnd, bool deleteWorkspace = true, double memory = 0, bool BoxStructureOnly = false) { - typedef MDLeanEvent MDE; + using MDE = MDLeanEvent; //------ Start by creating the file //---------------------------------------------- diff --git a/Framework/MDAlgorithms/test/LoadSQW2Test.h b/Framework/MDAlgorithms/test/LoadSQW2Test.h index b7360bdbcc99..f54287f8e6f8 100644 --- a/Framework/MDAlgorithms/test/LoadSQW2Test.h +++ b/Framework/MDAlgorithms/test/LoadSQW2Test.h @@ -145,9 +145,9 @@ class LoadSQW2Test : public CxxTest::TestSuite { enum class DataType { SQW, Cut3D }; struct DimensionProperties { - typedef std::array StringList; - typedef std::array DoubleList; - typedef std::array SizeTList; + using StringList = std::array; + using DoubleList = std::array; + using SizeTList = std::array; StringList ids, names, units, frameNames; DoubleList ulimits; SizeTList nbins; diff --git a/Framework/MDAlgorithms/test/SmoothMDTest.h b/Framework/MDAlgorithms/test/SmoothMDTest.h index a2052d837604..1ab8191f72d4 100644 --- a/Framework/MDAlgorithms/test/SmoothMDTest.h +++ b/Framework/MDAlgorithms/test/SmoothMDTest.h @@ -14,7 +14,7 @@ using namespace Mantid::API; using namespace Mantid::DataObjects; // Typedef for width vector -typedef std::vector WidthVector; +using WidthVector = std::vector; class SmoothMDTest : public CxxTest::TestSuite { public: diff --git a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h index f2de896a9cfb..93ba7996521c 100644 --- a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h +++ b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h @@ -197,7 +197,7 @@ class WeightedMeanMDTest : public CxxTest::TestSuite { /// MatrixWorkspaces (WeightedMean). void test_compare_to_matrix_weightedmean() { // Create some input data. Signal values as two offset sine waves. - typedef std::vector VecDouble; + using VecDouble = std::vector; VecDouble s1, s2, e1, e2, x; double theta_shift = 0.4; for (size_t i = 0; i < 40; ++i) { From 1de019800173907e953df4e3f791ff7abb2b6426 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:31:18 +0000 Subject: [PATCH 208/364] Re #22048: Applied fixes to Framework/Nexus. --- Framework/Nexus/inc/MantidNexus/NexusFileIO.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Nexus/inc/MantidNexus/NexusFileIO.h b/Framework/Nexus/inc/MantidNexus/NexusFileIO.h index 3995cb08d88b..2acac12b0bb7 100644 --- a/Framework/Nexus/inc/MantidNexus/NexusFileIO.h +++ b/Framework/Nexus/inc/MantidNexus/NexusFileIO.h @@ -55,7 +55,7 @@ class DLLExport NexusFileIO { public: // Helper typedef - typedef boost::optional optional_size_t; + using optional_size_t = boost::optional; /// Default constructor NexusFileIO(); @@ -426,7 +426,7 @@ void NexusFileIO::writeNumericTimeLog( } /// Helper typedef for a shared pointer of a NexusFileIO. -typedef boost::shared_ptr NexusFileIO_sptr; +using NexusFileIO_sptr = boost::shared_ptr; } // namespace NeXus } // namespace Mantid From 42129c80630ab9df771f8970915fb11e89f73cc4 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:33:52 +0000 Subject: [PATCH 209/364] Re #22048: Applied fixes to Framework/PythonInterface. --- .../api/PythonAlgorithm/AlgorithmAdapter.h | 2 +- .../api/WorkspacePropertyExporter.h | 4 +- .../kernel/Converters/MatrixToNDArray.h | 2 +- .../kernel/Converters/VectorToNDArray.h | 2 +- .../kernel/DataServiceExporter.h | 4 +- .../kernel/Policies/AsType.h | 6 +-- .../kernel/Policies/MatrixToNumpy.h | 17 ++------- .../kernel/Policies/RemoveConst.h | 20 ++++------ .../kernel/Policies/ToWeakPtr.h | 8 ++-- .../kernel/Policies/VectorToNumpy.h | 17 ++------- .../Registry/RegisterWorkspacePtrToPython.h | 4 +- .../Registry/TypedPropertyValueHandler.h | 8 ++-- .../kernel/StlExportDefinitions.h | 6 +-- .../mantid/api/src/CloneMatrixWorkspace.cpp | 3 +- .../mantid/api/src/Exports/Algorithm.cpp | 27 ++++--------- .../api/src/Exports/AlgorithmProperty.cpp | 2 +- .../api/src/Exports/AnalysisDataService.cpp | 3 +- .../api/src/Exports/BinaryOperations.cpp | 38 ++++++------------- .../api/src/Exports/CompositeFunction.cpp | 8 ++-- .../api/src/Exports/FunctionProperty.cpp | 2 +- .../mantid/api/src/Exports/IAlgorithm.cpp | 2 +- .../mantid/api/src/Exports/IEventList.cpp | 2 +- .../mantid/api/src/Exports/IFunction.cpp | 7 ++-- .../mantid/api/src/Exports/IPeak.cpp | 2 +- .../api/src/Exports/MatrixWorkspace.cpp | 8 ++-- .../api/src/Exports/MultipleFileProperty.cpp | 4 +- .../api/src/Exports/WorkspaceFactory.cpp | 4 +- .../mantid/api/src/ExtractWorkspace.cpp | 2 +- .../src/Exports/MDEventWorkspace.cpp | 2 +- .../geometry/src/Exports/Goniometer.cpp | 3 +- .../geometry/src/Exports/OrientedLattice.cpp | 3 +- .../mantid/geometry/src/Exports/UnitCell.cpp | 3 +- .../kernel/src/Exports/ArrayProperty.cpp | 3 +- .../mantid/kernel/src/Exports/Logger.cpp | 2 +- .../kernel/src/Exports/OptionalBool.cpp | 2 +- .../Exports/PropertyManagerDataService.cpp | 5 +-- .../src/Exports/PropertyManagerProperty.cpp | 4 +- .../mantid/kernel/src/Exports/Statistics.cpp | 6 +-- .../kernel/src/Exports/UnitConversion.cpp | 5 +-- .../mantid/kernel/src/Exports/UnitLabel.cpp | 2 +- .../src/Registry/PropertyWithValueFactory.cpp | 22 +++++------ .../src/Registry/SequenceTypeHandler.cpp | 4 +- .../kernel/src/Registry/TypeRegistry.cpp | 3 +- .../test/cpp/PropertyWithValueFactoryTest.h | 2 +- .../test/cpp/PySequenceToVectorTest.h | 4 +- .../WorkspaceCreationHelperModule.cpp | 10 ++--- 46 files changed, 108 insertions(+), 191 deletions(-) diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h index 8d65758f0514..6a52ea528c88 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h @@ -42,7 +42,7 @@ namespace PythonInterface { */ template class AlgorithmAdapter : public BaseAlgorithm { - typedef BaseAlgorithm SuperClass; + using SuperClass = BaseAlgorithm; public: /// A constructor that looks like a Python __init__ method diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h index aff1c6a9507c..f59da6aa037f 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/WorkspacePropertyExporter.h @@ -37,9 +37,9 @@ namespace PythonInterface { */ template struct WorkspacePropertyExporter { /// The export type - typedef Mantid::API::WorkspaceProperty TypedWorkspaceProperty; + using TypedWorkspaceProperty = Mantid::API::WorkspaceProperty; /// Shared pointer to Worksapce type - typedef boost::shared_ptr WorkspaceType_sptr; + using WorkspaceType_sptr = boost::shared_ptr; /** * Factory function to act as a constructor so that the validator can be diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h index 85ff6c7942e8..4d72bca602bf 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h @@ -52,7 +52,7 @@ struct DLLExport MatrixToNDArray { const std::pair matrixDims = cmatrix.size(); Py_intptr_t dims[2] = {static_cast(matrixDims.first), static_cast(matrixDims.second)}; - typedef typename ConversionPolicy::template apply policy; + using policy = typename ConversionPolicy::apply; return policy::createFromArray(&(cmatrix[0][0]), 2, dims); } }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h index 0e25b3224b3e..bcf269619edd 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h @@ -48,7 +48,7 @@ struct VectorToNDArray { */ inline PyObject *operator()(const std::vector &cdata) const { // Hand off the work to the conversion policy - typedef typename ConversionPolicy::template apply policy; + using policy = typename ConversionPolicy::apply; return policy::create1D(cdata); } }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h index 7657c6abae07..0c8b560c2415 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/DataServiceExporter.h @@ -43,8 +43,8 @@ namespace PythonInterface { */ template struct DataServiceExporter { // typedef the type created by boost.python - typedef boost::python::class_ PythonType; - typedef boost::weak_ptr WeakPtr; + using PythonType = boost::python::class_; + using WeakPtr = boost::weak_ptr; /** * Define the necessary boost.python framework to expor the templated diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h index 9a3dc8690723..ba484e549419 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h @@ -73,11 +73,7 @@ template struct AsType { template struct apply { // Deduce if type is correct for policy, needs to be convertible to // ReturnType - typedef typename boost::mpl::if_c< - std::is_convertible::value, - AsTypeImpl, - AsType_Requires_New_Type_Automatically_Convertible_To_Original< - InputType>>::type type; + using type = typename boost::mpl::if_c::value, AsTypeImpl, AsType_Requires_New_Type_Automatically_Convertible_To_Original >::type; }; }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h index 173f5a1c319f..2a4ef9f0d6f6 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h @@ -88,15 +88,9 @@ template struct MatrixRefToNumpy { template struct apply { // Typedef that removes and const or reference qualifiers from the return // type - typedef typename std::remove_const< - typename std::remove_reference::type>::type non_const_type; + using non_const_type = typename std::remove_const::type>::type; // MPL compile-time check that T is a reference to a Kernel::Matrix - typedef typename boost::mpl::if_c< - boost::mpl::and_, - is_matrix>::value, - MatrixRefToNumpyImpl, - MatrixRefToNumpy_Requires_Reference_To_Matrix_Return_Type>::type - type; + using type = typename boost::mpl::if_c, is_matrix >::value, MatrixRefToNumpyImpl, MatrixRefToNumpy_Requires_Reference_To_Matrix_Return_Type >::type; }; }; @@ -132,12 +126,9 @@ struct MatrixToNumpy { // The boost::python framework calls return_value_policy::apply::type template struct apply { // Typedef that removes any const from the type - typedef typename std::remove_const::type non_const_type; + using non_const_type = typename std::remove_const::type; // MPL compile-time check that T is a std::vector - typedef typename boost::mpl::if_c< - is_matrix::value, - MatrixRefToNumpyImpl, - MatrixToNumpy_Requires_Matrix_Return_By_Value>::type type; + using type = typename boost::mpl::if_c::value, MatrixRefToNumpyImpl, MatrixToNumpy_Requires_Matrix_Return_By_Value >::type; }; }; } diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h index 0c1070c6745b..911c6f796024 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h @@ -72,9 +72,9 @@ struct IsConstSharedPtr> : std::true_type {}; // call to this struct template struct RemoveConstImpl { // Remove the pointer type to leave value type - typedef typename std::remove_pointer::type ValueType; + using ValueType = typename std::remove_pointer::type; // Remove constness - typedef typename std::remove_const::type NonConstValueType; + using NonConstValueType = typename std::remove_const::type; inline PyObject *operator()(const ConstPtrType &p) const { using namespace boost::python; @@ -99,10 +99,9 @@ template struct RemoveConst_Requires_Pointer_Return_Value {}; // a check as to whether the return type is valid, if so it forwards the // call to this struct template struct RemoveConstSharedPtrImpl { - typedef typename ConstSharedPtr::element_type ConstElementType; - typedef - typename std::remove_const::type NonConstElementType; - typedef typename boost::shared_ptr NonConstSharedPtr; + using ConstElementType = typename ConstSharedPtr::element_type; + using NonConstElementType = typename std::remove_const::type; + using NonConstSharedPtr = typename boost::shared_ptr; inline PyObject *operator()(const ConstSharedPtr &p) const { using namespace boost::python; @@ -130,9 +129,7 @@ struct RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value {}; struct RemoveConst { template struct apply { // Deduce if type is correct for policy, needs to be a "T*" - typedef typename boost::mpl::if_c< - std::is_pointer::value, RemoveConstImpl, - RemoveConst_Requires_Pointer_Return_Value>::type type; + using type = typename boost::mpl::if_c::value, RemoveConstImpl, RemoveConst_Requires_Pointer_Return_Value >::type; }; }; @@ -143,10 +140,7 @@ struct RemoveConstSharedPtr { template struct apply { // Deduce if type is correct for policy, needs to be a // "boost::shared_ptr" - typedef typename boost::mpl::if_c< - IsConstSharedPtr::value, RemoveConstSharedPtrImpl, - RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value< - T>>::type type; + using type = typename boost::mpl::if_c::value, RemoveConstSharedPtrImpl, RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value >::type; }; }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h index bed30370d7f0..b8e0de8b9446 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h @@ -53,8 +53,8 @@ struct IsSharedPtr> : boost::true_type {}; */ template struct ToWeakPtrImpl { // Useful types - typedef typename ArgType::element_type PointeeType; - typedef boost::weak_ptr WeakPtr; + using PointeeType = typename ArgType::element_type; + using WeakPtr = boost::weak_ptr; inline PyObject *operator()(const ArgType &p) const { if (!p) @@ -80,9 +80,7 @@ template struct ToWeakPtr_Requires_Shared_Ptr_Return_Value {}; struct ToWeakPtr { template struct apply { // Deduce if type is correct for policy - typedef typename boost::mpl::if_c< - IsSharedPtr::value, ToWeakPtrImpl, - ToWeakPtr_Requires_Shared_Ptr_Return_Value>::type type; + using type = typename boost::mpl::if_c::value, ToWeakPtrImpl, ToWeakPtr_Requires_Shared_Ptr_Return_Value >::type; }; }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h index 829d88da8d5b..a8f712d71969 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h @@ -85,15 +85,9 @@ template struct VectorRefToNumpy { // The boost::python framework calls return_value_policy::apply::type template struct apply { // Typedef that removes and const or reference qualifiers from the type - typedef typename std::remove_const< - typename std::remove_reference::type>::type non_const_type; + using non_const_type = typename std::remove_const::type>::type; // MPL compile-time check that T is a reference to a std::vector - typedef typename boost::mpl::if_c< - boost::mpl::and_, - is_std_vector>::value, - VectorRefToNumpyImpl, - VectorRefToNumpy_Requires_Reference_To_StdVector_Return_Type>::type - type; + using type = typename boost::mpl::if_c, is_std_vector >::value, VectorRefToNumpyImpl, VectorRefToNumpy_Requires_Reference_To_StdVector_Return_Type >::type; }; }; @@ -130,12 +124,9 @@ struct VectorToNumpy { // The boost::python framework calls return_value_policy::apply::type template struct apply { // Typedef that removes any const from the type - typedef typename std::remove_const::type non_const_type; + using non_const_type = typename std::remove_const::type; // MPL compile-time check that T is a std::vector - typedef typename boost::mpl::if_c< - is_std_vector::value, - VectorRefToNumpyImpl, - VectorToNumpy_Requires_StdVector_Return_By_Value>::type type; + using type = typename boost::mpl::if_c::value, VectorRefToNumpyImpl, VectorToNumpy_Requires_StdVector_Return_By_Value >::type; }; }; } diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h index 3c69a5b0a711..9337da3725dd 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h @@ -40,8 +40,8 @@ namespace Registry { * - Registers a new PropertyValueHandler for a boost::shared_ptr */ template struct DLLExport RegisterWorkspacePtrToPython { - typedef boost::shared_ptr IType_sptr; - typedef boost::weak_ptr IType_wptr; + using IType_sptr = boost::shared_ptr; + using IType_wptr = boost::weak_ptr; /// Constructor RegisterWorkspacePtrToPython() { using namespace boost::python; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h index 73b19f29ecb6..b7e517a42b5b 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h @@ -47,7 +47,7 @@ namespace Registry { template struct DLLExport TypedPropertyValueHandler : public PropertyValueHandler { /// Type required by TypeRegistry framework - typedef ValueType HeldType; + using HeldType = ValueType; /** * Set function to handle Python -> C++ calls and get the correct type @@ -101,12 +101,12 @@ struct DLLExport TypedPropertyValueHandler< typename std::enable_if::value>::type> : public PropertyValueHandler { /// Type required by TypeRegistry framework - typedef boost::shared_ptr HeldType; + using HeldType = boost::shared_ptr; /// Convenience typedef - typedef T PointeeType; + using PointeeType = T; /// Convenience typedef - typedef boost::shared_ptr PropertyValueType; + using PropertyValueType = boost::shared_ptr; /** * Set function to handle Python -> C++ calls and get the correct type diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h index df59421b3177..8b6dbfacd1c4 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/StlExportDefinitions.h @@ -83,7 +83,7 @@ std::string toString(const SequenceType &values) { */ template struct std_vector_exporter { /// A typedef of a vector of template ElementTypes - typedef std::vector w_t; + using w_t = std::vector; static std::string to_string(const w_t &values) { if (values.empty()) @@ -111,8 +111,8 @@ template struct std_vector_exporter { // Found this at // http://cctbx.svn.sourceforge.net/viewvc/cctbx/trunk/scitbx/stl/set_wrapper.h?view=log template struct std_set_exporter { - typedef std::set w_t; - typedef ElementType e_t; + using w_t = std::set; + using e_t = ElementType; static void insert_element(w_t &self, e_t const &x) { self.insert(x); } diff --git a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp index 804ec003fdf9..80b6cae9b855 100644 --- a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp @@ -38,8 +38,7 @@ PyArrayObject *cloneArray(MatrixWorkspace &workspace, DataField field, npy_intp stride(0); // Find out which function we need to call to access the data - typedef const MantidVec &(MatrixWorkspace::*ArrayAccessFn)(const size_t) - const; + using ArrayAccessFn = const MantidVec &(MatrixWorkspace::*)(const size_t) const; ArrayAccessFn dataAccesor; /** * Can do better than this with a templated object that knows how to access diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp index 9331a1548ac8..e4a4c0ed9877 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp @@ -34,30 +34,19 @@ GET_POINTER_SPECIALIZATION(ParallelAlgorithm) GET_POINTER_SPECIALIZATION(DistributedAlgorithm) namespace { -typedef AlgorithmAdapter PythonAlgorithm; -typedef AlgorithmAdapter PythonSerialAlgorithm; -typedef AlgorithmAdapter PythonParallelAlgorithm; -typedef AlgorithmAdapter PythonDistributedAlgorithm; +using PythonAlgorithm = AlgorithmAdapter; +using PythonSerialAlgorithm = AlgorithmAdapter; +using PythonParallelAlgorithm = AlgorithmAdapter; +using PythonDistributedAlgorithm = AlgorithmAdapter; // declarePyAlgProperty(property*,doc) -typedef void (*declarePropertyType1)(boost::python::object &self, - Mantid::Kernel::Property *, - const std::string &); +using declarePropertyType1 = void (*)(boost::python::object &, Mantid::Kernel::Property *, const std::string &); // declarePyAlgProperty(name, defaultValue, validator, doc, direction) -typedef void (*declarePropertyType2)(boost::python::object &self, - const std::string &, - const boost::python::object &, - const boost::python::object &, - const std::string &, const int); +using declarePropertyType2 = void (*)(boost::python::object &, const std::string &, const boost::python::object &, const boost::python::object &, const std::string &, const int); // declarePyAlgProperty(name, defaultValue, doc, direction) -typedef void (*declarePropertyType3)(boost::python::object &self, - const std::string &, - const boost::python::object &, - const std::string &, const int); +using declarePropertyType3 = void (*)(boost::python::object &, const std::string &, const boost::python::object &, const std::string &, const int); // declarePyAlgProperty(name, defaultValue, direction) -typedef void (*declarePropertyType4)(boost::python::object &self, - const std::string &, - const boost::python::object &, const int); +using declarePropertyType4 = void (*)(boost::python::object &, const std::string &, const boost::python::object &, const int); #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp index cbf839d44c7e..64689baa89e2 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmProperty.cpp @@ -43,7 +43,7 @@ AlgorithmProperty *createPropertyWithValidator(const std::string &name, void export_AlgorithmProperty() { // AlgorithmProperty has base PropertyWithValue> // which must be exported - typedef boost::shared_ptr HeldType; + using HeldType = boost::shared_ptr; PropertyWithValueExporter::define("AlgorithmPropertyWithValue"); class_>, diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp index 229b8b7f9925..5fb70dde0595 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp @@ -11,8 +11,7 @@ using namespace boost::python; GET_POINTER_SPECIALIZATION(AnalysisDataServiceImpl) void export_AnalysisDataService() { - typedef DataServiceExporter - ADSExporter; + using ADSExporter = DataServiceExporter; auto pythonClass = ADSExporter::define("AnalysisDataServiceImpl"); pythonClass.def("Instance", &AnalysisDataService::Instance, return_value_policy(), diff --git a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp index 1687bd990b1a..9648e9df0248 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp @@ -18,35 +18,19 @@ void export_BinaryOperations() { using namespace boost::python; // Typedefs the various function types - typedef IMDWorkspace_sptr (*binary_fn_md_md)( - const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &, - const std::string &, bool, bool); - typedef WorkspaceGroup_sptr (*binary_fn_md_gp)( - const IMDWorkspace_sptr, const WorkspaceGroup_sptr, const std::string &, - const std::string &, bool, bool); - typedef WorkspaceGroup_sptr (*binary_fn_gp_md)( - const WorkspaceGroup_sptr, const IMDWorkspace_sptr, const std::string &, - const std::string &, bool, bool); - typedef WorkspaceGroup_sptr (*binary_fn_gp_gp)( - const WorkspaceGroup_sptr, const WorkspaceGroup_sptr, const std::string &, - const std::string &, bool, bool); - - typedef IMDHistoWorkspace_sptr (*binary_fn_mh_mh)( - const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr, - const std::string &, const std::string &, bool, bool); - - typedef IMDWorkspace_sptr (*binary_fn_md_db)(const IMDWorkspace_sptr, double, - const std::string &, - const std::string &, bool, bool); - typedef IMDHistoWorkspace_sptr (*binary_fn_mh_db)( - const IMDHistoWorkspace_sptr, double, const std::string &, - const std::string &, bool, bool); - typedef WorkspaceGroup_sptr (*binary_fn_gp_db)( - const WorkspaceGroup_sptr, double, const std::string &, - const std::string &, bool, bool); + using binary_fn_md_md = IMDWorkspace_sptr (*)(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &, const std::string &, bool, bool); + using binary_fn_md_gp = WorkspaceGroup_sptr (*)(const IMDWorkspace_sptr, const WorkspaceGroup_sptr, const std::string &, const std::string &, bool, bool); + using binary_fn_gp_md = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, const IMDWorkspace_sptr, const std::string &, const std::string &, bool, bool); + using binary_fn_gp_gp = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, const WorkspaceGroup_sptr, const std::string &, const std::string &, bool, bool); + + using binary_fn_mh_mh = IMDHistoWorkspace_sptr (*)(const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr, const std::string &, const std::string &, bool, bool); + + using binary_fn_md_db = IMDWorkspace_sptr (*)(const IMDWorkspace_sptr, double, const std::string &, const std::string &, bool, bool); + using binary_fn_mh_db = IMDHistoWorkspace_sptr (*)(const IMDHistoWorkspace_sptr, double, const std::string &, const std::string &, bool, bool); + using binary_fn_gp_db = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, double, const std::string &, const std::string &, bool, bool); // Always a return a Workspace_sptr - typedef return_value_policy> ReturnWorkspaceSptr; + using ReturnWorkspaceSptr = return_value_policy >; // Binary operations that return a workspace using boost::python::def; diff --git a/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp index 9085e895a26f..88a617d4bb95 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp @@ -12,12 +12,10 @@ GET_POINTER_SPECIALIZATION(CompositeFunction) namespace { -typedef double (CompositeFunction::*getParameterType1)(size_t) const; -typedef double (CompositeFunction::*getParameterType2)( - const std::string &) const; +using getParameterType1 = double (CompositeFunction::*)(size_t) const; +using getParameterType2 = double (CompositeFunction::*)(const std::string &) const; -typedef void (CompositeFunction::*setParameterType2)(const std::string &, - const double &, bool); +using setParameterType2 = void (CompositeFunction::*)(const std::string &, const double &, bool); #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" diff --git a/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp index ee7761b2cd9a..98c18f2b2cc5 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/FunctionProperty.cpp @@ -11,7 +11,7 @@ using namespace boost::python; void export_FunctionProperty() { // FuncitonProperty has base PropertyWithValue> // which must be exported - typedef boost::shared_ptr HeldType; + using HeldType = boost::shared_ptr; PropertyWithValueExporter::define("FunctionPropertyWithValue"); class_>, diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp index dd2b55e13c98..56fc63c961bf 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp @@ -100,7 +100,7 @@ struct MandatoryFirst { //----------------------- Property ordering ------------------------------ /// Vector of property pointers -typedef std::vector PropertyVector; +using PropertyVector = std::vector; /** * Returns the vector of properties ordered by the criteria defined in diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp index f9524b3cce55..e261c662ba52 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IEventList.cpp @@ -19,7 +19,7 @@ using namespace boost::python; GET_POINTER_SPECIALIZATION(IEventList) /// return_value_policy for copied numpy array -typedef return_value_policy return_clone_numpy; +using return_clone_numpy = return_value_policy; void export_IEventList() { register_ptr_to_python(); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp index 0406931e6735..be19095f2fb0 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp @@ -42,7 +42,7 @@ PyObject *getCategories(IFunction &self) { // -- Set property overloads -- // setProperty(index,value,explicit) -typedef void (IFunction::*setParameterType1)(size_t, const double &value, bool); +using setParameterType1 = void (IFunction::*)(size_t, const double &, bool); #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -54,8 +54,7 @@ GCC_DIAG_OFF(conversion) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads, setParameter, 2, 3) // setProperty(index,value,explicit) -typedef void (IFunction::*setParameterType2)(const std::string &, - const double &value, bool); +using setParameterType2 = void (IFunction::*)(const std::string &, const double &, bool); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads, setParameter, 2, 3) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(tie_Overloads, tie, 2, 3) @@ -65,7 +64,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fixParameter_Overloads, fixParameter, 1, 2) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fix_Overloads, fix, 1, 2) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fixAll_Overloads, fixAll, 0, 1) -typedef void (IFunction::*removeTieByName)(const std::string &); +using removeTieByName = void (IFunction::*)(const std::string &); GCC_DIAG_ON(conversion) #ifdef __clang__ diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp index ecd32b1cad97..3955a865e41d 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp @@ -48,7 +48,7 @@ void setGoniometerMatrix(IPeak &self, const object &data) { void export_IPeak() { // return_value_policy for read-only numpy array - typedef return_value_policy return_copy_to_numpy; + using return_copy_to_numpy = return_value_policy; register_ptr_to_python(); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp index f23ec4eb8816..390c73c4957b 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp @@ -38,14 +38,12 @@ GET_POINTER_SPECIALIZATION(MatrixWorkspace) namespace { /// Typedef for data access, i.e. dataX,Y,E members -typedef Mantid::MantidVec &(MatrixWorkspace::*data_modifier)(const std::size_t); +using data_modifier = Mantid::MantidVec &(MatrixWorkspace::*)(const std::size_t); /// return_value_policy for read-only numpy array -typedef return_value_policy> - return_readonly_numpy; +using return_readonly_numpy = return_value_policy >; /// return_value_policy for read-write numpy array -typedef return_value_policy> - return_readwrite_numpy; +using return_readwrite_numpy = return_value_policy >; //------------------------------- Overload macros --------------------------- #ifdef __clang__ diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp index 2ffd86de5fbf..9b8daa3240fd 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp @@ -17,7 +17,7 @@ using namespace boost::python; namespace { /// The PropertyWithValue type -typedef std::vector> HeldType; +using HeldType = std::vector >; /** * Converts the value from a MultipleFileProperty to a python object rather than @@ -71,7 +71,7 @@ createMultipleFileProperty(const std::string &name, } void export_MultipleFileProperty() { - typedef PropertyWithValue BaseClass; + using BaseClass = PropertyWithValue; PropertyWithValueExporter::define( "VectorVectorStringPropertyWithValue"); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp index 0fcdf9243941..c1cc7cc3584e 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp @@ -73,9 +73,7 @@ void export_WorkspaceFactory() { const char *createFromScratchDoc = "Create a clean new worksapce of the given size."; - typedef MatrixWorkspace_sptr (WorkspaceFactoryImpl::*createFromScratchPtr)( - const std::string &, const size_t &, const size_t &, const size_t &) - const; + using createFromScratchPtr = MatrixWorkspace_sptr (WorkspaceFactoryImpl::*)(const std::string &, const size_t &, const size_t &, const size_t &) const; class_("WorkspaceFactoryImpl", no_init) diff --git a/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp index 4540b383f2d4..2ced6615e53b 100644 --- a/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp @@ -22,7 +22,7 @@ using boost::python::extract; ExtractWorkspace::ExtractWorkspace(const boost::python::api::object &pyvalue) : m_value() { // Test for a weak pointer first - typedef boost::weak_ptr Workspace_wptr; + using Workspace_wptr = boost::weak_ptr; extract extractWeak(pyvalue); if (extractWeak.check()) { m_value = extractWeak().lock(); diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp index b56c86b52a72..a28814977f3f 100644 --- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp +++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/MDEventWorkspace.cpp @@ -40,7 +40,7 @@ namespace { */ template void MDEventWorkspaceExportImpl(const char *className) { - typedef MDEventWorkspace ExportType; + using ExportType = MDEventWorkspace; class_, boost::noncopyable>(className, no_init); diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp index 99f9c702f972..886d034e307f 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp @@ -42,8 +42,7 @@ void setR(Goniometer &self, const object &data) { void export_Goniometer() { // return_value_policy for read-only numpy array - typedef return_value_policy> return_readonly_numpy; + using return_readonly_numpy = return_value_policy >; class_("Goniometer", init<>(arg("self"))) .def(init((arg("self"), arg("other")))) diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp index 1256ce10fc66..7b411cb9e74a 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp @@ -45,8 +45,7 @@ Mantid::Kernel::V3D hklFromQ(OrientedLattice &self, const object &vec) { void export_OrientedLattice() { /// return_value_policy for read-only numpy array - typedef return_value_policy> return_readonly_numpy; + using return_readonly_numpy = return_value_policy >; class_>( "OrientedLattice", diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp index 38682c016d52..ca407057476c 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp @@ -67,8 +67,7 @@ void export_UnitCell() { .export_values(); /// return_value_policy for read-only numpy array - typedef return_value_policy> return_readonly_numpy; + using return_readonly_numpy = return_value_policy >; class_( "UnitCell", diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp index b27dc7f3d441..ba07c31b9f6a 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp @@ -24,8 +24,7 @@ using namespace boost::python; namespace { /// return_value_policy for cloned numpy array -typedef return_value_policy> - return_cloned_numpy; +using return_cloned_numpy = return_value_policy >; #define EXPORT_ARRAY_PROP(type, prefix) \ class_, bases>>, \ diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp index 74dba6e8084a..28827a4f74c1 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Logger.cpp @@ -24,7 +24,7 @@ void export_Logger() { register_ptr_to_python>(); // To distinguish between the overloaded functions - typedef void (Logger::*LogLevelFunction)(const std::string &); + using LogLevelFunction = void (Logger::*)(const std::string &); class_( "Logger", init((arg("self"), arg("name")))) diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp index a95a63d7ba23..e3edcdc1183c 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/OptionalBool.cpp @@ -52,7 +52,7 @@ class OptionalBoolPropertyValueHandler : public Registry::PropertyValueHandler { } public: - typedef OptionalBool HeldType; + using HeldType = OptionalBool; /** * Set function to handle Python -> C++ calls and get the correct type diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp index be80c22864f2..5792ea62ff74 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp @@ -15,7 +15,7 @@ using Mantid::PythonInterface::Registry::createPropertyManager; using namespace boost::python; /// Weak pointer to DataItem typedef -typedef boost::weak_ptr PropertyManager_wptr; +using PropertyManager_wptr = boost::weak_ptr; namespace { /** @@ -48,8 +48,7 @@ void export_PropertyManagerDataService() { register_ptr_to_python(); - typedef DataServiceExporter PMDExporter; + using PMDExporter = DataServiceExporter; auto pmdType = PMDExporter::define("PropertyManagerDataServiceImpl"); pmdType.def("Instance", &PropertyManagerDataService::Instance, diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp index 2a04f3d761ff..4f4aa9871ac8 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerProperty.cpp @@ -29,12 +29,12 @@ createPropertyManagerPropertyWithDict(const std::string &name, void export_PropertyManagerProperty() { // export base class - typedef PropertyManager_sptr BaseValueType; + using BaseValueType = PropertyManager_sptr; PropertyWithValueExporter::define( "PropertyManagerPropertyWithValue"); // leaf class type - typedef PropertyManagerProperty::BaseClass BaseClassType; + using BaseClassType = PropertyManagerProperty::BaseClass; class_, boost::noncopyable>( "PropertyManagerProperty", no_init) .def(init( diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp index f63ae0fca86e..e8119bea4d8a 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp @@ -180,9 +180,7 @@ GCC_DIAG_ON(conversion) //============================================ // Function pointer to real implementation of getMoments -typedef std::vector(*MomentsFunction)(const std::vector &indep, - const std::vector &depend, - const int); +using MomentsFunction = std::vector (*)(const std::vector &, const std::vector &, const int); /** * The implementation for getMomentsAboutOrigin & getMomentsAboutOriginMean for @@ -275,7 +273,7 @@ GCC_DIAG_ON(conversion) void export_Statistics() { // typedef std::vector --> numpy array result converter - typedef return_value_policy ReturnNumpyArray; + using ReturnNumpyArray = return_value_policy; // define a new "Statistics" scope so that everything is called as // Statistics.getXXX diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp index 8027b450a639..e74509990f18 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp @@ -7,10 +7,7 @@ using namespace boost::python; void export_UnitConversion() { // Function pointer typedef - typedef double (*StringVersion)( - const std::string &src, const std::string &dest, const double srcValue, - const double l1, const double l2, const double theta, - const DeltaEMode::Type emode, const double efixed); + using StringVersion = double (*)(const std::string &, const std::string &, const double, const double, const double, const double, const DeltaEMode::Type, const double); class_("UnitConversion", no_init) .def("run", (StringVersion)&UnitConversion::run, diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp index 6f3e76a80835..fe450438ced6 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitLabel.cpp @@ -16,7 +16,7 @@ using namespace boost::python; namespace { boost::shared_ptr createLabel(const object &ascii, const object &utf8, const object &latex) { - typedef UnitLabel::Utf8String::value_type Utf8Char; + using Utf8Char = UnitLabel::Utf8String::value_type; if (PyUnicode_Check(utf8.ptr())) { auto length = PyUnicode_GetSize(utf8.ptr()); boost::scoped_array buffer(new Utf8Char[length]); diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp index e59a71bc8174..a728650d18d0 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp @@ -16,8 +16,7 @@ namespace PythonInterface { namespace Registry { namespace { /// Lookup map type -typedef std::map> - PyTypeIndex; +using PyTypeIndex = std::map >; /** * Initialize lookup map @@ -26,21 +25,21 @@ void initTypeLookup(PyTypeIndex &index) { assert(index.empty()); // Map the Python types to the best match in C++ - typedef TypedPropertyValueHandler FloatHandler; + using FloatHandler = TypedPropertyValueHandler; index.emplace(&PyFloat_Type, boost::make_shared()); - typedef TypedPropertyValueHandler BoolHandler; + using BoolHandler = TypedPropertyValueHandler; index.emplace(&PyBool_Type, boost::make_shared()); // Python 2/3 have an arbitrary-sized long type. The handler // will raise an error if the input value overflows a C long - typedef TypedPropertyValueHandler IntHandler; + using IntHandler = TypedPropertyValueHandler; index.emplace(&PyLong_Type, boost::make_shared()); // In Python 3 all strings are unicode but in Python 2 unicode strings // must be explicitly requested. The C++ string handler will accept both // but throw and error if the unicode string contains non-ascii characters - typedef TypedPropertyValueHandler AsciiStrHandler; + using AsciiStrHandler = TypedPropertyValueHandler; // Both versions have unicode objects index.emplace(&PyUnicode_Type, boost::make_shared()); @@ -67,8 +66,7 @@ const PyTypeIndex &getTypeIndex() { } // Lookup map for arrays -typedef std::map> - PyArrayIndex; +using PyArrayIndex = std::map >; /** * Initialize lookup map @@ -77,18 +75,18 @@ void initArrayLookup(PyArrayIndex &index) { assert(index.empty()); // Map the Python array types to the best match in C++ - typedef SequenceTypeHandler> FloatArrayHandler; + using FloatArrayHandler = SequenceTypeHandler >; index.emplace("FloatArray", boost::make_shared()); - typedef SequenceTypeHandler> StringArrayHandler; + using StringArrayHandler = SequenceTypeHandler >; index.emplace("StringArray", boost::make_shared()); - typedef SequenceTypeHandler> LongIntArrayHandler; + using LongIntArrayHandler = SequenceTypeHandler >; index.emplace("LongIntArray", boost::make_shared()); #if PY_MAJOR_VERSION < 3 // Backwards compatible behaviour - typedef SequenceTypeHandler> IntArrayHandler; + using IntArrayHandler = SequenceTypeHandler >; index.emplace("IntArray", boost::make_shared()); #endif } diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp index 0c6518234b9e..fdde2e989b87 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Registry/SequenceTypeHandler.cpp @@ -44,7 +44,7 @@ void SequenceTypeHandler::set( Kernel::IPropertyManager *alg, const std::string &name, const boost::python::object &value) const { using namespace boost::python; - typedef typename ContainerType::value_type DestElementType; + using DestElementType = typename ContainerType::value_type; // Current workaround for things that still pass back wrapped vectors... if (boost::starts_with(value.ptr()->ob_type->tp_name, "std_vector")) { @@ -82,7 +82,7 @@ std::unique_ptr SequenceTypeHandler::create( const std::string &name, const boost::python::object &defaultValue, const boost::python::object &validator, const unsigned int direction) const { - typedef typename ContainerType::value_type DestElementType; + using DestElementType = typename ContainerType::value_type; using Kernel::IValidator; using Kernel::PropertyWithValue; using boost::python::extract; diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp index f111c6099938..4c5d4cb6e911 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp @@ -15,8 +15,7 @@ namespace // /// Typedef the map of type_info -> handler objects. We store /// boost::python::type_info objects so that they work across DLL boundaries /// unlike std::type_info objects -typedef std::map> TypeIDMap; +using TypeIDMap = std::map >; /** * Returns a reference to the static type map diff --git a/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h b/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h index 0e00aa76c28a..d389030f288b 100644 --- a/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h +++ b/Framework/PythonInterface/test/cpp/PropertyWithValueFactoryTest.h @@ -92,7 +92,7 @@ class PropertyWithValueFactoryTest : public CxxTest::TestSuite { template void testCreateArrayProperty(PyObject *pyValue) { using namespace boost::python; using namespace Mantid::Kernel; - typedef std::vector TypeVec; + using TypeVec = std::vector; object pyvalue = object(handle<>(pyValue)); auto valueProp = createAndCheckPropertyTraits( "TestProperty", pyvalue, Direction::Input); diff --git a/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h b/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h index 323e6bea1b4f..3e7c5c17fa29 100644 --- a/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h +++ b/Framework/PythonInterface/test/cpp/PySequenceToVectorTest.h @@ -11,7 +11,7 @@ using namespace Mantid::PythonInterface::Converters; class PySequenceToVectorTest : public CxxTest::TestSuite { private: - typedef PySequenceToVector PySequenceToVectorDouble; + using PySequenceToVectorDouble = PySequenceToVector; public: void test_construction_succeeds_with_a_valid_sequence_type() { @@ -37,7 +37,7 @@ class PySequenceToVectorTest : public CxxTest::TestSuite { test_that_trying_to_convert_a_list_of_incompatible_types_throws_error_already_set() { // Double->int is not generally safe so should not be allowed boost::python::list testlist = createHomogeneousPythonList(); - typedef PySequenceToVector PySequenceToVectorInt; + using PySequenceToVectorInt = PySequenceToVector; std::vector cvector; TS_ASSERT_THROWS(cvector = PySequenceToVectorInt(testlist)(), boost::python::error_already_set); diff --git a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp index 4fa0facbe277..7dd55b3bdc43 100644 --- a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp +++ b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp @@ -54,10 +54,8 @@ BOOST_PYTHON_MODULE(WorkspaceCreationHelper) { //=================================== // Function pointers to disambiguate the calls - typedef Workspace2D_sptr (*Signature1_2D)( - int nHist, int nBins, bool includeMonitors, bool startYNegative); - typedef Workspace2D_sptr (*Signature2_2D)(int numBanks, int numPixels, - int numBins); + using Signature1_2D = Workspace2D_sptr (*)(int, int, bool, bool); + using Signature2_2D = Workspace2D_sptr (*)(int, int, int); def("create2DWorkspaceWithFullInstrument", reinterpret_cast(&create2DWorkspaceWithFullInstrument), @@ -90,9 +88,7 @@ BOOST_PYTHON_MODULE(WorkspaceCreationHelper) { //=================================== // Typedef for function pointer to disabiguate references - typedef MDHistoWorkspace_sptr (*Signature1_MDHisto)( - double, size_t, size_t, Mantid::coord_t max, double, std::string name, - double); + using Signature1_MDHisto = MDHistoWorkspace_sptr (*)(double, size_t, size_t, Mantid::coord_t, double, std::string, double); def("makeFakeMDHistoWorkspace", (Signature1_MDHisto)&makeFakeMDHistoWorkspace, makeFakeMDHistoWorkspace_overloads() From c25487204a388fe8e582ecfb57426f835a8c44e3 Mon Sep 17 00:00:00 2001 From: Gemma Guest Date: Wed, 14 Mar 2018 11:21:38 +0000 Subject: [PATCH 210/364] Remove hard-coded separator for output workspace names - This commit adds a separator to the preprocessing algorithm class rather than hard-coding it. This means that a different separator can be used for output workspaces preprocessed with different algorithms. - Stitched transmission workspaces names have been changed to use "_" rather than "+" as their separator to be consistent with previous behaviour and other stitching. Re #22073 --- ...flGenericDataProcessorPresenterFactory.cpp | 4 +- .../test/ReflDataProcessorPresenterTest.h | 8 +-- .../Common/DataProcessorUI/PreprocessMap.h | 3 +- .../DataProcessorUI/PreprocessingAlgorithm.h | 7 ++- .../DataProcessorUI/WorkspaceNameUtils.h | 8 +-- .../src/DataProcessorUI/GenerateNotebook.cpp | 3 +- .../GenericDataProcessorPresenter.cpp | 6 +-- .../src/DataProcessorUI/PreprocessMap.cpp | 7 ++- .../PreprocessingAlgorithm.cpp | 14 +++++- .../DataProcessorUI/WorkspaceNameUtils.cpp | 43 ++++++++++------ .../DataProcessorUI/GenerateNotebookTest.h | 50 +++++++++++-------- .../GenericDataProcessorPresenterTest.h | 25 +++++----- .../test/DataProcessorUI/PreprocessMapTest.h | 6 ++- .../PreprocessingAlgorithmTest.h | 3 +- 14 files changed, 119 insertions(+), 68 deletions(-) diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp index 17ea85b0dc6e..25dc242eaa0a 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp +++ b/qt/scientific_interfaces/ISISReflectometry/ReflGenericDataProcessorPresenterFactory.cpp @@ -88,13 +88,13 @@ ReflGenericDataProcessorPresenterFactory::create(int group) { std::map preprocessMap = { /* 'Plus' will be applied to column 'Run(s)'*/ {"Run(s)", - PreprocessingAlgorithm("Plus", "TOF_", + PreprocessingAlgorithm("Plus", "TOF_", "+", std::set{"LHSWorkspace", "RHSWorkspace", "OutputWorkspace"})}, /* 'CreateTransmissionWorkspaceAuto' will be applied to column 'Transmission Run(s)'*/ {"Transmission Run(s)", - PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_", + PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_", "_", std::set{"FirstTransmissionRun", "SecondTransmissionRun", "OutputWorkspace"})}}; diff --git a/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h b/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h index 881f5075a80f..4783012bd668 100644 --- a/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h +++ b/qt/scientific_interfaces/test/ReflDataProcessorPresenterTest.h @@ -220,7 +220,7 @@ class ReflDataProcessorPresenterTest : public CxxTest::TestSuite { TS_ASSERT(workspaceExists("TOF_13462_monitors")); TS_ASSERT(workspaceExists("TRANS_13463")); TS_ASSERT(workspaceExists("TRANS_13464")); - TS_ASSERT(workspaceExists("TRANS_13463+13464")); + TS_ASSERT(workspaceExists("TRANS_13463_13464")); // Tidy up AnalysisDataService::Instance().clear(); @@ -303,7 +303,7 @@ class ReflDataProcessorPresenterTest : public CxxTest::TestSuite { TS_ASSERT(workspaceExists("TOF_13462_monitors")); TS_ASSERT(workspaceExists("TRANS_13463")); TS_ASSERT(workspaceExists("TRANS_13464")); - TS_ASSERT(workspaceExists("TRANS_13463+13464")); + TS_ASSERT(workspaceExists("TRANS_13463_13464")); // Tidy up AnalysisDataService::Instance().clear(); @@ -380,7 +380,7 @@ class ReflDataProcessorPresenterTest : public CxxTest::TestSuite { TS_ASSERT(workspaceExists("TOF_13462_monitors")); TS_ASSERT(workspaceExists("TRANS_13463")); TS_ASSERT(workspaceExists("TRANS_13464")); - TS_ASSERT(workspaceExists("TRANS_13463+13464")); + TS_ASSERT(workspaceExists("TRANS_13463_13464")); // Tidy up AnalysisDataService::Instance().clear(); @@ -456,7 +456,7 @@ class ReflDataProcessorPresenterTest : public CxxTest::TestSuite { TS_ASSERT(workspaceExists("TOF_13462_monitors")); TS_ASSERT(workspaceExists("TRANS_13463")); TS_ASSERT(workspaceExists("TRANS_13464")); - TS_ASSERT(workspaceExists("TRANS_13463+13464")); + TS_ASSERT(workspaceExists("TRANS_13463_13464")); // Tidy up AnalysisDataService::Instance().clear(); diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h index dc489e5171cf..c571c33ea639 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessMap.h @@ -45,7 +45,8 @@ class EXPORT_OPT_MANTIDQT_COMMON PreprocessMap { virtual ~PreprocessMap(); // Add a column to pre-process void addElement(const QString &column, const QString &algorithm, - const QString &prefix = "", const QString &blacklist = ""); + const QString &prefix = "", const QString &separator = "", + const QString &blacklist = ""); // Returns a map where keys are columns and values pre-processing algorithms std::map asMap() const; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h index bbd03c3de238..5b2a3e08268a 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/PreprocessingAlgorithm.h @@ -40,9 +40,10 @@ class EXPORT_OPT_MANTIDQT_COMMON PreprocessingAlgorithm public: // Constructor PreprocessingAlgorithm(QString name, QString prefix = "", + QString separator = "", std::set blacklist = std::set()); // Delegating constructor - PreprocessingAlgorithm(QString name, QString prefix, + PreprocessingAlgorithm(QString name, QString prefix, QString separator, const QString &blacklist); // Default constructor PreprocessingAlgorithm(); @@ -57,10 +58,14 @@ class EXPORT_OPT_MANTIDQT_COMMON PreprocessingAlgorithm QString outputProperty() const; // The prefix to add to the output property QString prefix() const; + // The separator to use between values in the output property + QString separator() const; private: // A prefix to the name of the pre-processed output ws QString m_prefix; + // A separator between values in the pre-processed output ws name + QString m_separator; // The name of the LHS input property QString m_lhs; // The name of the RHS input property diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h index 84afee2096b3..3ca1d132e77b 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/WorkspaceNameUtils.h @@ -43,10 +43,12 @@ class WhiteList; QStringList preprocessingStringToList(const QString &inputStr); // Create string of trimmed values from a list of values QString preprocessingListToString(const QStringList &values, - const QString prefix = QString()); + const QString &prefix, + const QString &separator); // Returns the name of the reduced workspace for a given row -QString DLLExport -getReducedWorkspaceName(const RowData_sptr data, const WhiteList &whitelist); +QString DLLExport getReducedWorkspaceName( + const RowData_sptr data, const WhiteList &whitelist, + const std::map &preprocessor); // Consolidate global options with row values OptionsMap DLLExport getCanonicalOptions( const RowData_sptr data, const OptionsMap &globalOptions, diff --git a/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp b/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp index fde30a6539b3..a1edd93f9f72 100644 --- a/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp +++ b/qt/widgets/common/src/DataProcessorUI/GenerateNotebook.cpp @@ -492,7 +492,8 @@ loadWorkspaceString(const QString &runStr, const QString &instrument, } const QString prefix = preprocessor.prefix(); - const QString outputName = preprocessingListToString(runs, prefix); + const QString outputName = + preprocessingListToString(runs, prefix, preprocessor.separator()); boost::tuple loadString; diff --git a/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp b/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp index c6ed8ddf2da2..4e6ee7ccf9b0 100644 --- a/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp +++ b/qt/widgets/common/src/DataProcessorUI/GenericDataProcessorPresenter.cpp @@ -291,7 +291,7 @@ Returns the name of the reduced workspace for a given row QString GenericDataProcessorPresenter::getReducedWorkspaceName( const RowData_sptr data) const { return MantidQt::MantidWidgets::DataProcessor::getReducedWorkspaceName( - data, m_whitelist); + data, m_whitelist, m_preprocessing.m_map); } void GenericDataProcessorPresenter::settingsChanged() { @@ -651,8 +651,8 @@ Workspace_sptr GenericDataProcessorPresenter::prepareRunWorkspace( if (runs.size() == 1) return getRun(runs[0], instrument, preprocessor.prefix()); - auto const outputName = - preprocessingListToString(runs, preprocessor.prefix()); + auto const outputName = preprocessingListToString(runs, preprocessor.prefix(), + preprocessor.separator()); /* Ideally, this should be executed as a child algorithm to keep the ADS tidy, * but that doesn't preserve history nicely, so we'll just take care of tidying diff --git a/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp b/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp index 0aecc560c359..5f9a6f29258c 100644 --- a/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp +++ b/qt/widgets/common/src/DataProcessorUI/PreprocessMap.cpp @@ -17,14 +17,17 @@ PreprocessMap::~PreprocessMap() {} * applied to that column * @param prefix :: a list with the prefix(es) to be added to the output * workspace(s), as a string +* @param separator :: the separator to use between elements of the output +* workspace name * @param blacklist :: the list of algorithm properties to black list, as a * string */ void PreprocessMap::addElement(const QString &column, const QString &algorithm, - const QString &prefix, + const QString &prefix, const QString &separator, const QString &blacklist) { - m_map[column] = PreprocessingAlgorithm(algorithm, prefix, blacklist); + m_map[column] = + PreprocessingAlgorithm(algorithm, prefix, separator, blacklist); } /** Return a map where keys are columns and values pre-processing algorithms diff --git a/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp b/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp index 26ab39bca725..49be4d935a2f 100644 --- a/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp +++ b/qt/widgets/common/src/DataProcessorUI/PreprocessingAlgorithm.cpp @@ -7,13 +7,16 @@ namespace DataProcessor { /** Constructor * @param name : The name of the pre-processing algorithm * @param prefix : A prefix that will added to the output workspace name + * @param separator : A separator that will added between values in the output + * workspace name * @param blacklist : The list of properties we don't want to show * algorithm in the processed workspace's name */ PreprocessingAlgorithm::PreprocessingAlgorithm(QString name, QString prefix, + QString separator, std::set blacklist) : ProcessingAlgorithmBase(std::move(name), std::move(blacklist)), - m_prefix(std::move(prefix)) { + m_prefix(std::move(prefix)), m_separator(std::move(separator)) { auto inputWsProperties = getInputWsProperties(); @@ -39,18 +42,22 @@ PreprocessingAlgorithm::PreprocessingAlgorithm(QString name, QString prefix, * * @param name : The name of the pre-processing algorithm * @param prefix : A prefix that will added to the output workspace name +* @param separator : A separator that will used between values in the output +* workspace name * @param blacklist : The list of properties we don't want to show, as a string * algorithm in the processed workspace's name */ PreprocessingAlgorithm::PreprocessingAlgorithm(QString name, QString prefix, + QString separator, const QString &blacklist) : PreprocessingAlgorithm(std::move(name), std::move(prefix), + std::move(separator), convertStringToSet(blacklist)) {} /** Default constructor: do nothing */ PreprocessingAlgorithm::PreprocessingAlgorithm() - : m_prefix(), m_lhs(), m_rhs(), m_outProperty() {} + : m_prefix(), m_separator(), m_lhs(), m_rhs(), m_outProperty() {} // Destructor PreprocessingAlgorithm::~PreprocessingAlgorithm() {} @@ -66,6 +73,9 @@ QString PreprocessingAlgorithm::outputProperty() const { return m_outProperty; } // Returns the prefix to add to the output property QString PreprocessingAlgorithm::prefix() const { return m_prefix; } + +// Returns the separator to separate multiple values in the output property +QString PreprocessingAlgorithm::separator() const { return m_separator; } } } } diff --git a/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp b/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp index 4cc13be9896e..1e0157865469 100644 --- a/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp +++ b/qt/widgets/common/src/DataProcessorUI/WorkspaceNameUtils.cpp @@ -120,19 +120,23 @@ QStringList preprocessingStringToList(const QString &inputStr) { * separated by '+' with an optional prefix */ QString preprocessingListToString(const QStringList &values, - const QString prefix) { - return prefix + values.join("+"); + const QString &prefix, + const QString &separator) { + return prefix + values.join(separator); } /** Returns the name of the reduced workspace for a given row @param data :: [input] The data for this row @param whitelist :: [input] The list of columns +@param preprocessMap :: [input] a map of column names to the preprocessing +algorithm for that column @throws std::runtime_error if the workspace could not be prepared @returns : The name of the workspace */ -QString getReducedWorkspaceName(const RowData_sptr data, - const WhiteList &whitelist) { +QString getReducedWorkspaceName( + const RowData_sptr data, const WhiteList &whitelist, + const std::map &preprocessMap) { if (data->size() != static_cast(whitelist.size())) throw std::invalid_argument("Can't find reduced workspace name"); @@ -153,17 +157,28 @@ QString getReducedWorkspaceName(const RowData_sptr data, auto columnIt = whitelist.cbegin(); auto runNumbersIt = data->constBegin(); for (; columnIt != whitelist.cend(); ++columnIt, ++runNumbersIt) { + // Check the column is relevant to the generation of the output name auto column = *columnIt; - // Do we want to use this column to generate the name of the output ws? - if (column.isShown()) { - auto const runNumbers = *runNumbersIt; - - if (!runNumbers.isEmpty()) { - auto values = preprocessingStringToList(runNumbers); - if (!values.isEmpty()) - names.append(preprocessingListToString(values, column.prefix())); - } - } + if (!column.isShown()) + continue; + + // Check there is a value in the column + auto const runNumbers = *runNumbersIt; + if (runNumbers.isEmpty()) + continue; + + // Convert the string value to a list + auto values = preprocessingStringToList(runNumbers); + if (values.isEmpty()) + continue; + + // Get the separator to use if preprocessing multiple input values + QString separator = "+"; + if (preprocessMap.count(column.name())) + separator = preprocessMap.at(column.name()).separator(); + + // Convert the value list to a correctly-formatted output name + names.append(preprocessingListToString(values, column.prefix(), separator)); } // Columns QString wsname; diff --git a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h index 19f911f5ed8d..fe471deac852 100644 --- a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h +++ b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h @@ -26,17 +26,18 @@ class GenerateNotebookTest : public CxxTest::TestSuite { private: // Creates a map with pre-processing instruction for reflectometry std::map - reflPreprocessMap(const QString &plusPrefix = "") { + reflPreprocessMap(const QString &plusPrefix = "", + const QString &transPrefix = "TRANS_") { // Reflectometry pre-process map return std::map{ {"Run(s)", - PreprocessingAlgorithm("Plus", plusPrefix, std::set())}, + PreprocessingAlgorithm("Plus", plusPrefix, "+", std::set())}, {"Transmission Run(s)", - PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_", - std::set{"FirstTransmissionRun", - "SecondTransmissionRun", - "OutputWorkspace"})}}; + PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", transPrefix, + "_", std::set{"FirstTransmissionRun", + "SecondTransmissionRun", + "OutputWorkspace"})}}; } // Creates a reflectometry processing algorithm @@ -265,7 +266,7 @@ class GenerateNotebookTest : public CxxTest::TestSuite { } void testLoadWorkspaceStringThreeRunsWithOptions() { - PreprocessingAlgorithm preprocessor("WeightedMean"); + PreprocessingAlgorithm preprocessor("WeightedMean", "", "+"); auto output = loadWorkspaceString("RUN1+RUN2,RUN3", "INST_", preprocessor, "Property1 = 1, Property2 = 2"); auto outputLines = splitIntoLines(boost::get<0>(output)); @@ -345,7 +346,8 @@ class GenerateNotebookTest : public CxxTest::TestSuite { // Create a pre-process map std::map preprocessMap = { - {"Run", PreprocessingAlgorithm("Plus", "RUN_", std::set())}}; + {"Run", + PreprocessingAlgorithm("Plus", "RUN_", "+", std::set())}}; // Specify some pre-processing options auto runOptions = OptionsMap{{"Property", "prop"}}; auto userPreProcessingOptions = ColumnOptionsMap{{"Run", runOptions}}; @@ -425,16 +427,18 @@ class GenerateNotebookTest : public CxxTest::TestSuite { // Create some data const auto data = makeRowData( {"1000,1001", "0.5", "2000,2001", "1.4", "2.9", "0.04", "1", "", ""}); - TS_ASSERT_THROWS_ANYTHING(getReducedWorkspaceName(data, whitelist)); + auto reflectometryPreprocessMap = reflPreprocessMap(); + TS_ASSERT_THROWS_ANYTHING( + getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap)); } void testReducedWorkspaceNameOnlyRun() { // Create a whitelist WhiteList whitelist; - whitelist.addElement("Run", "", "", true, "run_"); + whitelist.addElement("Run(s)", "", "", true, "run_"); whitelist.addElement("Angle", "", "", false, ""); - whitelist.addElement("Trans", "", "", false, ""); + whitelist.addElement("Transmission Run(s)", "", "", false, ""); whitelist.addElement("Q min", "MomentumTransferMinimum", ""); whitelist.addElement("Q max", "MomentumTransferMaximum", ""); whitelist.addElement("dQ/Q", "MomentumTransferStep", ""); @@ -446,7 +450,9 @@ class GenerateNotebookTest : public CxxTest::TestSuite { const auto data = makeRowData( {"1000,1001", "0.5", "2000,2001", "1.4", "2.9", "0.04", "1", "", ""}); - auto name = getReducedWorkspaceName(data, whitelist); + auto reflectometryPreprocessMap = reflPreprocessMap("run_", ""); + auto name = + getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap); TS_ASSERT_EQUALS(name.toStdString(), "run_1000+1001") } @@ -454,9 +460,9 @@ class GenerateNotebookTest : public CxxTest::TestSuite { // Create a whitelist WhiteList whitelist; - whitelist.addElement("Run", "", "", true, "run_"); + whitelist.addElement("Run(s)", "", "", true, "run_"); whitelist.addElement("Angle", "", "", false, ""); - whitelist.addElement("Trans", "", "", true, "trans_"); + whitelist.addElement("Transmission Run(s)", "", "", true, "trans_"); whitelist.addElement("Q min", "MomentumTransferMinimum", ""); whitelist.addElement("Q max", "MomentumTransferMaximum", ""); whitelist.addElement("dQ/Q", "MomentumTransferStep", ""); @@ -468,17 +474,19 @@ class GenerateNotebookTest : public CxxTest::TestSuite { const auto data = makeRowData( {"1000,1001", "0.5", "2000,2001", "1.4", "2.9", "0.04", "1", "", ""}); - auto name = getReducedWorkspaceName(data, whitelist); - TS_ASSERT_EQUALS(name.toStdString(), "run_1000+1001_trans_2000+2001") + auto reflectometryPreprocessMap = reflPreprocessMap("run_", "trans_"); + auto name = + getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap); + TS_ASSERT_EQUALS(name.toStdString(), "run_1000+1001_trans_2000_2001") } void testReducedWorkspaceNameTransNoPrefix() { // Create a whitelist WhiteList whitelist; - whitelist.addElement("Run", "", "", false, ""); + whitelist.addElement("Run(s)", "", "", false, ""); whitelist.addElement("Angle", "", "", false, ""); - whitelist.addElement("Trans", "", "", true, ""); + whitelist.addElement("Transmission Run(s)", "", "", true, ""); whitelist.addElement("Q min", "MomentumTransferMinimum", ""); whitelist.addElement("Q max", "MomentumTransferMaximum", ""); whitelist.addElement("dQ/Q", "MomentumTransferStep", ""); @@ -489,8 +497,10 @@ class GenerateNotebookTest : public CxxTest::TestSuite { const auto data = makeRowData( {"1000,1001", "0.5", "2000+2001", "1.4", "2.9", "0.04", "1", "", ""}); - auto name = getReducedWorkspaceName(data, whitelist); - TS_ASSERT_EQUALS(name.toStdString(), "2000+2001") + auto reflectometryPreprocessMap = reflPreprocessMap("", ""); + auto name = + getReducedWorkspaceName(data, whitelist, reflectometryPreprocessMap); + TS_ASSERT_EQUALS(name.toStdString(), "2000_2001") } void testPostprocessGroupString() { diff --git a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h index c6317dcaf4f2..97d545b6165a 100644 --- a/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h +++ b/qt/widgets/common/test/DataProcessorUI/GenericDataProcessorPresenterTest.h @@ -148,15 +148,16 @@ class GenericDataProcessorPresenterTest : public CxxTest::TestSuite { const std::map createReflectometryPreprocessingStep() { - return {{"Run(s)", PreprocessingAlgorithm( - "Plus", "TOF_", - std::set{"LHSWorkspace", "RHSWorkspace", - "OutputWorkspace"})}, - {"Transmission Run(s)", - PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_", - std::set{"FirstTransmissionRun", - "SecondTransmissionRun", - "OutputWorkspace"})}}; + return { + {"Run(s)", PreprocessingAlgorithm( + "Plus", "TOF_", "+", + std::set{"LHSWorkspace", "RHSWorkspace", + "OutputWorkspace"})}, + {"Transmission Run(s)", + PreprocessingAlgorithm("CreateTransmissionWorkspaceAuto", "TRANS_", + "_", std::set{"FirstTransmissionRun", + "SecondTransmissionRun", + "OutputWorkspace"})}}; } ProcessingAlgorithm createReflectometryProcessor() { @@ -2951,13 +2952,13 @@ class GenericDataProcessorPresenterTest : public CxxTest::TestSuite { // Test the names of the reduced workspaces TS_ASSERT_EQUALS(row0->reducedName().toStdString(), - "TOF_12345_TRANS_11115+11116"); + "TOF_12345_TRANS_11115_11116"); TS_ASSERT_EQUALS(row1->reducedName().toStdString(), - "TOF_12346_TRANS_11115+11116"); + "TOF_12346_TRANS_11115_11116"); // Test the names of the post-processed ws TS_ASSERT_EQUALS( presenter->getPostprocessedWorkspaceName(group).toStdString(), - "IvsQ_TOF_12345_TRANS_11115+11116_TOF_12346_TRANS_11115+11116"); + "IvsQ_TOF_12345_TRANS_11115_11116_TOF_12346_TRANS_11115_11116"); TS_ASSERT(Mock::VerifyAndClearExpectations(&mockDataProcessorView)); } diff --git a/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h b/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h index 60bac99346df..f1284069265b 100644 --- a/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h +++ b/qt/widgets/common/test/DataProcessorUI/PreprocessMapTest.h @@ -28,9 +28,9 @@ class PreprocessMapTest : public CxxTest::TestSuite { void test_add_element() { PreprocessMap preprocessMap; - preprocessMap.addElement("Runs", "Plus"); + preprocessMap.addElement("Runs", "Plus", "", "+"); preprocessMap.addElement("Transmission Runs", - "CreateTransmissionWorkspaceAuto", "TRANS_", + "CreateTransmissionWorkspaceAuto", "TRANS_", "_", "FirstTransmissionRun,SecondTransmissionRun"); auto preprocessingInstructions = preprocessMap.asMap(); @@ -38,12 +38,14 @@ class PreprocessMapTest : public CxxTest::TestSuite { PreprocessingAlgorithm algPlus = preprocessingInstructions["Runs"]; TS_ASSERT_EQUALS(algPlus.name(), "Plus"); TS_ASSERT_EQUALS(algPlus.prefix(), ""); + TS_ASSERT_EQUALS(algPlus.separator(), "+"); TS_ASSERT_EQUALS(algPlus.blacklist(), std::set()); PreprocessingAlgorithm algTrans = preprocessingInstructions["Transmission Runs"]; TS_ASSERT_EQUALS(algTrans.name(), "CreateTransmissionWorkspaceAuto"); TS_ASSERT_EQUALS(algTrans.prefix(), "TRANS_"); + TS_ASSERT_EQUALS(algTrans.separator(), "_"); std::set blacklist = {"FirstTransmissionRun", "SecondTransmissionRun"}; TS_ASSERT_EQUALS(algTrans.blacklist(), blacklist); diff --git a/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h b/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h index 15f0109aab70..f47a0b99b42c 100644 --- a/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h +++ b/qt/widgets/common/test/DataProcessorUI/PreprocessingAlgorithmTest.h @@ -61,6 +61,7 @@ class PreprocessingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(plus.rhsProperty(), ""); TS_ASSERT_EQUALS(plus.outputProperty(), ""); TS_ASSERT_EQUALS(plus.prefix(), ""); + TS_ASSERT_EQUALS(plus.separator(), ""); TS_ASSERT_EQUALS(plus.blacklist().size(), 0); } @@ -69,7 +70,7 @@ class PreprocessingAlgorithmTest : public CxxTest::TestSuite { // WeightedMean std::set blacklist = {"InputWorkspace1", "InputWorkspace2", "OutputWorkspace"}; - auto mean = PreprocessingAlgorithm("WeightedMean", "", blacklist); + auto mean = PreprocessingAlgorithm("WeightedMean", "", "+", blacklist); TS_ASSERT_EQUALS(mean.lhsProperty(), "InputWorkspace1"); TS_ASSERT_EQUALS(mean.rhsProperty(), "InputWorkspace2"); TS_ASSERT_EQUALS(mean.outputProperty(), "OutputWorkspace"); From 1eac22557c5e39a78be41f9519599c5907897f0d Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:38:54 +0000 Subject: [PATCH 211/364] Re #22048: Applied fixes to Framework/RemoteAlgorithms. --- .../RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h index 3c97fb97f165..e5775dd1d833 100644 --- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h +++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SimpleJSON.h @@ -23,8 +23,8 @@ #include "MantidKernel/System.h" class JSONValue; -typedef std::map JSONObject; -typedef std::vector JSONArray; +using JSONObject = std::map; +using JSONArray = std::vector; // Note: according to the JSON spec, an array is a type of value. // That isn't strictly true in the C++ sense here (ie: JSONArray // doesn't inherit from JSONValue), but I think we'll be all right. From 455f252c7fbcf3efe9965b2d9f99a0079c5012c8 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:42:53 +0000 Subject: [PATCH 212/364] Re #22048: Applied fixes to Framework/RemoteJobManagers. --- .../inc/MantidRemoteJobManagers/LSFJobManager.h | 4 ++-- .../inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h | 2 +- .../inc/MantidRemoteJobManagers/SimpleJSON.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h index 72cefdac31cb..70e5197ee589 100644 --- a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h +++ b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/LSFJobManager.h @@ -83,7 +83,7 @@ class DLLExport LSFJobManager : public Mantid::API::IRemoteJobManager { virtual std::string guessJobSubmissionAppName(const std::string &runnablePath, const std::string &jobOptions); - typedef std::map StringToStringMap; + using StringToStringMap = std::map; /// method that deals with the actual HTTP(S) connection (convenient to /// mock up all inet messaging) @@ -114,7 +114,7 @@ class DLLExport LSFJobManager : public Mantid::API::IRemoteJobManager { std::string m_token_str; }; - typedef std::pair UsernameToken; + using UsernameToken = std::pair; // store for username-token pairs static std::map g_tokenStash; diff --git a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h index 06d9636e3e9d..d01cf35640a2 100644 --- a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h +++ b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/MantidWebServiceAPIHelper.h @@ -65,7 +65,7 @@ class DLLExport MantidWebServiceAPIHelper { // Name/Value pairs for POST data. Note that the second string might be // binary, and might be // fairly large. (If it were a JPG image for example...) - typedef std::map PostDataMap; + using PostDataMap = std::map; // Low level HTTP functions - GET, POST, etc... // It's up to the various algorithms to know what to do with these functions diff --git a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h index b7d004d4a556..51ef80c3fb6e 100644 --- a/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h +++ b/Framework/RemoteJobManagers/inc/MantidRemoteJobManagers/SimpleJSON.h @@ -21,8 +21,8 @@ #include class JSONValue; -typedef std::map JSONObject; -typedef std::vector JSONArray; +using JSONObject = std::map; +using JSONArray = std::vector; // Note: according to the JSON spec, an array is a type of value. // That isn't strictly true in the C++ sense here (ie: JSONArray // doesn't inherit from JSONValue), but I think we'll be all right. From 9245ed7559a562f9f701d96dd26d7bffcb423fac Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:43:42 +0000 Subject: [PATCH 213/364] Re #22048: Applied fixes to Framework/ScriptRepository. --- .../inc/MantidScriptRepository/ScriptRepositoryImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h b/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h index 4b81bee83471..560238d7bfe1 100644 --- a/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h +++ b/Framework/ScriptRepository/inc/MantidScriptRepository/ScriptRepositoryImpl.h @@ -71,7 +71,7 @@ class SCRIPT_DLL_EXPORT ScriptRepositoryImpl : public ScriptRepository { auto_update(false), author(""), status(BOTH_UNCHANGED){}; }; - typedef std::map Repository; + using Repository = std::map; Repository repo; From 8fb66edbe825ed74ef11e3b2a7a1dcfa00697c6a Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:45:33 +0000 Subject: [PATCH 214/364] Re #22048: Applied fixes to Framework/SINQ. --- Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h | 2 +- .../SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h | 2 +- .../inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h | 2 +- .../inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h | 2 +- .../inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h | 5 ++--- .../MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h | 2 +- Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h | 2 +- .../SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h | 2 +- .../SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h | 5 ++--- .../MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h | 2 +- .../inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h | 5 ++--- 11 files changed, 14 insertions(+), 17 deletions(-) diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h index f9dc4155e5d1..ac94ab788350 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h @@ -46,7 +46,7 @@ class MANTID_SINQ_DLL RefinedRange { double m_width; }; -typedef boost::shared_ptr RefinedRange_sptr; +using RefinedRange_sptr = boost::shared_ptr; bool MANTID_SINQ_DLL operator<(const RefinedRange_sptr &lhs, const RefinedRange_sptr &rhs); diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h index 92cb42098078..d5b0f5f1fc9f 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/Poldi2DFunction.h @@ -63,7 +63,7 @@ class MANTID_SINQ_DLL Poldi2DFunction : public API::IFunction1DSpectrum, size_t m_iteration; }; -typedef boost::shared_ptr Poldi2DFunction_sptr; +using Poldi2DFunction_sptr = boost::shared_ptr; } // namespace SINQ } // namespace Mantid diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h index 56213449295e..be2d9c4873a3 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractChopper.h @@ -60,7 +60,7 @@ class MANTID_SINQ_DLL PoldiAbstractChopper { PoldiAbstractChopper() = default; }; -typedef boost::shared_ptr PoldiAbstractChopper_sptr; +using PoldiAbstractChopper_sptr = boost::shared_ptr; } } diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h index f3f0134ca76f..fb699ad8839d 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiAbstractDetector.h @@ -66,7 +66,7 @@ class MANTID_SINQ_DLL PoldiAbstractDetector { PoldiAbstractDetector() = default; }; -typedef boost::shared_ptr PoldiAbstractDetector_sptr; +using PoldiAbstractDetector_sptr = boost::shared_ptr; } } #endif // POLDIABSTRACTDETECTOR_H diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h index 3e1de9f95051..a9f5665ea065 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h @@ -45,8 +45,7 @@ class AbstractDoubleValueExtractor { const std::string &propertyName) const = 0; }; -typedef boost::shared_ptr - AbstractDoubleValueExtractor_sptr; +using AbstractDoubleValueExtractor_sptr = boost::shared_ptr; class NumberDoubleValueExtractor : public AbstractDoubleValueExtractor { public: @@ -128,7 +127,7 @@ class MANTID_SINQ_DLL PoldiInstrumentAdapter { static std::map m_extractors; }; -typedef boost::shared_ptr PoldiInstrumentAdapter_sptr; +using PoldiInstrumentAdapter_sptr = boost::shared_ptr; } // namespace Poldi } // namespace Mantid diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h index b8578dda7b67..3af9624cf8bf 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h @@ -34,7 +34,7 @@ namespace Poldi { using namespace Geometry; -typedef std::pair DoublePair; +using DoublePair = std::pair; class MockDetector : public PoldiAbstractDetector { protected: diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h index 850cf66b8b85..ae281b626a9b 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeak.h @@ -39,7 +39,7 @@ namespace Poldi { class PoldiPeak; -typedef boost::shared_ptr PoldiPeak_sptr; +using PoldiPeak_sptr = boost::shared_ptr; class MANTID_SINQ_DLL PoldiPeak { public: diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h index 16f302e6d9b9..9fae2aeeb678 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiPeakCollection.h @@ -42,7 +42,7 @@ namespace Poldi { class PoldiPeakCollection; -typedef boost::shared_ptr PoldiPeakCollection_sptr; +using PoldiPeakCollection_sptr = boost::shared_ptr; class MANTID_SINQ_DLL PoldiPeakCollection { public: diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h index 4ebd57e8a09d..cdbcadabbcdf 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h @@ -59,9 +59,8 @@ class MANTID_SINQ_DLL PoldiSourceSpectrum { Kernel::Interpolation m_spectrum; }; -typedef boost::shared_ptr PoldiSourceSpectrum_sptr; -typedef boost::shared_ptr - PoldiSourceSpectrum_const_sptr; +using PoldiSourceSpectrum_sptr = boost::shared_ptr; +using PoldiSourceSpectrum_const_sptr = boost::shared_ptr; } } diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h index e57e64b294f0..c8a1fedf5087 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h @@ -97,7 +97,7 @@ struct MANTID_SINQ_DLL Poldi2DHelper { int minTOFN; }; -typedef boost::shared_ptr Poldi2DHelper_sptr; +using Poldi2DHelper_sptr = boost::shared_ptr; class WrapAroundJacobian : public API::Jacobian { public: diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h index 6ca9692d5979..4b43516f6fdd 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h @@ -93,8 +93,7 @@ class DetectorElementData { double m_tofFactor; }; -typedef boost::shared_ptr - DetectorElementData_const_sptr; +using DetectorElementData_const_sptr = boost::shared_ptr; class MANTID_SINQ_DLL PoldiTimeTransformer { public: @@ -128,7 +127,7 @@ class MANTID_SINQ_DLL PoldiTimeTransformer { PoldiSourceSpectrum_const_sptr m_spectrum; }; -typedef boost::shared_ptr PoldiTimeTransformer_sptr; +using PoldiTimeTransformer_sptr = boost::shared_ptr; } // namespace Poldi } // namespace Mantid From c1da7cfb22378fd27ec8039128168101e73d1a30 Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Wed, 14 Mar 2018 15:46:55 +0100 Subject: [PATCH 215/364] ConvertToPointData, ConvertToHistogram: fix Dx propagation. XDataConverter now propagates the Dx histogram from the input workspace to the output. Re #22075 --- .../inc/MantidAlgorithms/XDataConverter.h | 1 + Framework/Algorithms/src/XDataConverter.cpp | 3 + .../Algorithms/test/ConvertToHistogramTest.h | 66 ++++++++++--------- .../Algorithms/test/ConvertToPointDataTest.h | 35 +++++++++- docs/source/release/v3.13.0/framework.rst | 5 ++ 5 files changed, 75 insertions(+), 35 deletions(-) diff --git a/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h b/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h index 89030b9cee06..dd4cc1b0f358 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/XDataConverter.h @@ -6,6 +6,7 @@ namespace Mantid { namespace HistogramData { +class HistogramDx; class HistogramX; } namespace Algorithms { diff --git a/Framework/Algorithms/src/XDataConverter.cpp b/Framework/Algorithms/src/XDataConverter.cpp index 84a3750a3232..06c4dab887f3 100644 --- a/Framework/Algorithms/src/XDataConverter.cpp +++ b/Framework/Algorithms/src/XDataConverter.cpp @@ -69,6 +69,9 @@ void XDataConverter::exec() { outputWS->setSharedY(i, inputWS->sharedY(i)); outputWS->setSharedE(i, inputWS->sharedE(i)); setXData(outputWS, inputWS, i); + if (inputWS->hasDx(i)) { + outputWS->setSharedDx(i, inputWS->sharedDx(i)); + } prog.report(); PARALLEL_END_INTERUPT_REGION diff --git a/Framework/Algorithms/test/ConvertToHistogramTest.h b/Framework/Algorithms/test/ConvertToHistogramTest.h index 0af9416c715e..6468d1989ef3 100644 --- a/Framework/Algorithms/test/ConvertToHistogramTest.h +++ b/Framework/Algorithms/test/ConvertToHistogramTest.h @@ -13,12 +13,19 @@ using Mantid::API::MatrixWorkspace_sptr; using Mantid::Algorithms::ConvertToHistogram; using Mantid::DataObjects::Workspace2D_sptr; using Mantid::MantidVecPtr; +using Mantid::HistogramData::HistogramDx; using Mantid::HistogramData::LinearGenerator; using Mantid::HistogramData::Points; +using Mantid::Kernel::make_cow; class ConvertToHistogramTest : public CxxTest::TestSuite { public: + + void tearDown() override { + Mantid::API::AnalysisDataService::Instance().clear(); + } + void test_That_The_Algorithm_Has_Two_Properties() { ConvertToHistogram alg; TS_ASSERT_THROWS_NOTHING(alg.initialize()); @@ -38,7 +45,6 @@ class ConvertToHistogramTest : public CxxTest::TestSuite { // Check that the algorithm just pointed the output data at the input TS_ASSERT_EQUALS(&(*testWS), &(*outputWS)); - Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName()); } void test_A_Point_Data_InputWorkspace_Is_Converted_To_A_Histogram() { @@ -63,43 +69,39 @@ class ConvertToHistogramTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(outputWS->isHistogramData(), true); const int numBoundaries = numYPoints + 1; - // This makes the new X values more readable rather than using a dynamic - // array - // so I'll live with the hard coding const double expectedX[11] = {-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5}; for (int j = 0; j < numBoundaries; ++j) { TS_ASSERT_EQUALS(outputWS->readX(0)[j], expectedX[j]); } + } - // for( int i = 0; i < numSpectra; ++i ) - // { - // const Mantid::MantidVec & yValues = outputWS->readY(i); - // const Mantid::MantidVec & xValues = outputWS->readX(i); - // const Mantid::MantidVec & eValues = outputWS->readE(i); - - // TS_ASSERT_EQUALS(xValues.size(), numBins); - // // The y and e values sizes be unchanged - // TS_ASSERT_EQUALS(yValues.size(), numYPoints); - // TS_ASSERT_EQUALS(eValues.size(), numYPoints); - - // for( int j = 0; j < numYPoints; ++j ) - // { - // // Now the data. Y and E unchanged - // TS_ASSERT_EQUALS(yValues[j], 2.0); - // TS_ASSERT_EQUALS(eValues[j], M_SQRT2); - - // // X data originally was 0->10 in steps of 1. Now it should be the - // centre of each bin which is - // // 1.0 away from the last centre - // const double expectedX = 0.5 + j*1.0; - // TS_ASSERT_EQUALS(xValues[j], expectedX); - // } - // // And the final X points - // TS_ASSERT_EQUALS(xValues.back(), 100.); - // } - - Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName()); + void test_Dx_Data_Is_Handled_Correctly() { + // Creates a workspace with 10 points + constexpr int numYPoints{10}; + constexpr int numSpectra{2}; + Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspace123( + numSpectra, numYPoints, false); + double xErrors[numYPoints] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + auto dxs = make_cow(xErrors, xErrors + numYPoints); + // Reset the X data to something reasonable, set Dx. + Points x(numYPoints, LinearGenerator(0.0, 1.0)); + for (int i = 0; i < numSpectra; ++i) { + testWS->setPoints(i, x); + testWS->setSharedDx(i, dxs); + } + TS_ASSERT(!testWS->isHistogramData()) + MatrixWorkspace_sptr outputWS = runAlgorithm(testWS); + TS_ASSERT(outputWS); + TS_ASSERT(outputWS->isHistogramData()) + for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) { + TS_ASSERT(outputWS->hasDx(i)) + const auto &dx = outputWS->dx(i); + TS_ASSERT_EQUALS(dx.size(), numYPoints) + for (size_t j = 0; j < dx.size(); ++j) { + TS_ASSERT_EQUALS(dx[j], xErrors[j]) + } + } } private: diff --git a/Framework/Algorithms/test/ConvertToPointDataTest.h b/Framework/Algorithms/test/ConvertToPointDataTest.h index 287621e1ecb9..410bc4d73b1e 100644 --- a/Framework/Algorithms/test/ConvertToPointDataTest.h +++ b/Framework/Algorithms/test/ConvertToPointDataTest.h @@ -13,10 +13,17 @@ using Mantid::API::IAlgorithm_sptr; using Mantid::API::MatrixWorkspace; using Mantid::API::MatrixWorkspace_sptr; using Mantid::DataObjects::Workspace2D_sptr; +using Mantid::HistogramData::HistogramDx; +using Mantid::Kernel::make_cow; class ConvertToPointDataTest : public CxxTest::TestSuite { public: + + void tearDown() override { + Mantid::API::AnalysisDataService::Instance().clear(); + } + void test_That_The_Algorithm_Has_Two_Properties() { ConvertToPointData alg; TS_ASSERT_THROWS_NOTHING(alg.initialize()); @@ -35,7 +42,6 @@ class ConvertToPointDataTest : public CxxTest::TestSuite { // Check that the algorithm just pointed the output data at the input TS_ASSERT_EQUALS(&(*testWS), &(*outputWS)); - Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName()); } void test_A_Uniformly_Binned_Histogram_Is_Transformed_Correctly() { @@ -94,8 +100,6 @@ class ConvertToPointDataTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS((*(outputWS->getAxis(1)))(0), 0); TS_ASSERT_EQUALS((*(outputWS->getAxis(1)))(1), 2); TS_ASSERT_EQUALS((*(outputWS->getAxis(1)))(2), 4); - - Mantid::API::AnalysisDataService::Instance().remove(outputWS->getName()); } void test_A_Non_Uniformly_Binned_Histogram_Is_Transformed_Correctly() { @@ -139,6 +143,31 @@ class ConvertToPointDataTest : public CxxTest::TestSuite { } } + void test_Dx_Data_Is_Handled_Correctly() { + constexpr size_t numBins{11}; + double xBoundaries[numBins] = {0.0, 1.0, 3.0, 5.0, 6.0, 7.0, + 10.0, 13.0, 16.0, 17.0, 17.5}; + constexpr int numSpectra{2}; + Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspaceBinned( + numSpectra, numBins, xBoundaries); + TS_ASSERT(testWS->isHistogramData()) + double xErrors[numBins - 1] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + auto dxs = make_cow(xErrors, xErrors + numBins - 1); + testWS->setSharedDx(0, dxs); + testWS->setSharedDx(1, dxs); + MatrixWorkspace_sptr outputWS = runAlgorithm(testWS); + TS_ASSERT(outputWS) + TS_ASSERT(!outputWS->isHistogramData()) + for (size_t i = 0; i < outputWS->getNumberHistograms(); ++i) { + TS_ASSERT(outputWS->hasDx(i)) + const auto &dx = outputWS->dx(i); + TS_ASSERT_EQUALS(dx.size(), numBins - 1) + for (size_t j = 0; j < dx.size(); ++j) { + TS_ASSERT_EQUALS(dx[j], xErrors[j]) + } + } + } + private: MatrixWorkspace_sptr runAlgorithm(Workspace2D_sptr inputWS) { IAlgorithm_sptr alg(new ConvertToPointData()); diff --git a/docs/source/release/v3.13.0/framework.rst b/docs/source/release/v3.13.0/framework.rst index 89615c6d3526..bf1973474bbf 100644 --- a/docs/source/release/v3.13.0/framework.rst +++ b/docs/source/release/v3.13.0/framework.rst @@ -9,4 +9,9 @@ Framework Changes putting new features at the top of the section, followed by improvements, followed by bug fixes. +Algorithms +---------- + +- :ref:`ConvertToPointData ` and :ref:`ConvertToHistogram ` now propagate the Dx errors to the output. + :ref:`Release 3.13.0 ` From 4db7bffd819dd9b4033673384e15c31ac3f9da35 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:54:39 +0000 Subject: [PATCH 216/364] Re #22048: Applied fixes to Framework/Types. --- Framework/Types/src/Core/DateAndTime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Types/src/Core/DateAndTime.cpp b/Framework/Types/src/Core/DateAndTime.cpp index f421c9b045fb..c922c025c41c 100644 --- a/Framework/Types/src/Core/DateAndTime.cpp +++ b/Framework/Types/src/Core/DateAndTime.cpp @@ -726,7 +726,7 @@ time_duration DateAndTime::durationFromSeconds(double duration) { else if (duration <= std::numeric_limits::min()) return boost::posix_time::time_duration(boost::posix_time::min_date_time); - typedef boost::posix_time::time_res_traits::sec_type sec_type; + using sec_type = boost::posix_time::time_res_traits::sec_type; #ifdef BOOST_DATE_TIME_HAS_NANOSECONDS // Nanosecond resolution From 5abbd30c190d8cd1eeb3c8d826da7705045feb82 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 14:56:00 +0000 Subject: [PATCH 217/364] Re #22048: Applied fixes to Framework/WorkflowAlgorithms. --- Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp | 2 +- .../WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp b/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp index 71dc6c39698a..aa7bf397b527 100644 --- a/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp +++ b/Framework/WorkflowAlgorithms/src/DgsDiagnose.cpp @@ -290,7 +290,7 @@ void DgsDiagnose::exec() { diag->execute(); maskWS = diag->getProperty("OutputWorkspace"); } else { - typedef Mantid::Kernel::StringTokenizer tokenizer; + using tokenizer = Mantid::Kernel::StringTokenizer; tokenizer tokens(diag_spectra[0], "(,);", Mantid::Kernel::StringTokenizer::TOK_IGNORE_EMPTY); for (auto tok_iter = tokens.begin(); tok_iter != tokens.end();) { diff --git a/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h b/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h index 60ba8ec8af9d..86b61dde7b13 100644 --- a/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h +++ b/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h @@ -16,7 +16,7 @@ using Mantid::WorkflowAlgorithms::IMuonAsymmetryCalculator; using Mantid::WorkflowAlgorithms::MuonGroupCountsCalculator; using Mantid::WorkflowAlgorithms::MuonGroupAsymmetryCalculator; using Mantid::WorkflowAlgorithms::MuonPairAsymmetryCalculator; -typedef std::unique_ptr IMuonAsymCalc_uptr; +using IMuonAsymCalc_uptr = std::unique_ptr; /** * Tests for all classes deriving from IMuonAsymmetryCalculator: From bbdad36512fe994966daec6bd20dfe986116391e Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Wed, 14 Mar 2018 15:44:18 +0000 Subject: [PATCH 218/364] Add missing list prefix --- docs/source/release/v3.12.0/framework.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst index da0a70005d31..15e5685a588d 100644 --- a/docs/source/release/v3.12.0/framework.rst +++ b/docs/source/release/v3.12.0/framework.rst @@ -131,7 +131,7 @@ Improved - In ``mantid.simpleapi``, a keyword has been implemented for function-like algorithm calls to control the storing on the Analysis Data Service. -``StoreInADS=False`` can be passed to function calls to not to store their output on the ADS. +- ``StoreInADS=False`` can be passed to function calls to not to store their output on the ADS. - The standard Python operators, e.g. ``+``, ``+=``, etc., now work also with workspaces not in the ADS. - The ``isDefault`` attribute for workspace properties now works correctly with workspaces not in the ADS. - The previously mentioned ``ConfigObserver`` and ``ConfigPropertyObserver`` classes are also exposed to Python. From 7d4b1e200805c50a416c1f1ab6e9a16c1d13810e Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Wed, 14 Mar 2018 13:48:18 +0000 Subject: [PATCH 219/364] Re #22070 Remove vtk directory from Paraview python path --- Framework/Kernel/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Framework/Kernel/CMakeLists.txt b/Framework/Kernel/CMakeLists.txt index b1915069fc17..81ebe6576c52 100644 --- a/Framework/Kernel/CMakeLists.txt +++ b/Framework/Kernel/CMakeLists.txt @@ -578,9 +578,9 @@ set ( QT_PLUGINS_DIR "." ) if ( MAKE_VATES ) set ( PV_PLUGINS_DIR "./plugins/paraview/qt%V" ) if ( MSVC ) - set (PARAVIEW_PYTHON_PATHS "${ParaView_DIR}/bin/$<$:Release>$<$:Debug>;${ParaView_DIR}/lib/$<$:Release>$<$:Debug>;${ParaView_DIR}/lib/site-packages;${ParaView_DIR}/lib/site-packages/vtk") + set (PARAVIEW_PYTHON_PATHS "${ParaView_DIR}/bin/$<$:Release>$<$:Debug>;${ParaView_DIR}/lib/$<$:Release>$<$:Debug>;${ParaView_DIR}/lib/site-packages;") else() - set ( PARAVIEW_PYTHON_PATHS "${ParaView_DIR}/lib;${ParaView_DIR}/lib/site-packages;${ParaView_DIR}/lib/site-packages/vtk") + set ( PARAVIEW_PYTHON_PATHS "${ParaView_DIR}/lib;${ParaView_DIR}/lib/site-packages;") endif() else () set ( PV_PLUGINS_DIR "" ) @@ -691,13 +691,13 @@ set ( FRAMEWORK_PLUGINS_DIR ${MANTID_ROOT}/plugins ) set ( PYTHONPLUGIN_DIRS "${FRAMEWORK_PLUGINS_DIR}/python" ) if(MAKE_VATES) if (APPLE) - set ( PARAVIEW_PYTHON_PATHS "../Libraries;../Python;../Python/vtk") + set ( PARAVIEW_PYTHON_PATHS "../Libraries;../Python;") elseif (WIN32) set ( PV_LIBS "../lib/paraview-${PARAVIEW_VERSION_MAJOR}.${PARAVIEW_VERSION_MINOR}" ) - set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS}/site-packages;${PV_LIBS}/site-packages/vtk" ) + set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS}/site-packages;" ) else () #Linux set ( PV_LIBS "${CMAKE_INSTALL_PREFIX}/lib/paraview-${PARAVIEW_VERSION}") - set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS};${PV_LIBS}/site-packages;${PV_LIBS}/site-packages/vtk") + set ( PARAVIEW_PYTHON_PATHS "${PV_LIBS};${PV_LIBS}/site-packages;") endif () else () set ( PARAVIEW_PYTHON_PATHS "") From 560192029dc486496ea0031d60be4a7f1456600c Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Wed, 14 Mar 2018 12:00:36 -0400 Subject: [PATCH 220/364] fix failing build with gcc. --- .../kernel/src/Converters/NDArrayToVector.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp index 93f0a100d4cf..2045edd668b0 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Converters/NDArrayToVector.cpp @@ -27,14 +27,14 @@ extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; extern template int NDArrayTypeIndex::typenum; -extern template int NDArrayTypeIndex::typecode; -extern template int NDArrayTypeIndex::typecode; -extern template int NDArrayTypeIndex::typecode; -extern template int NDArrayTypeIndex::typecode; -extern template int NDArrayTypeIndex::typecode; -extern template int NDArrayTypeIndex::typecode; -extern template int NDArrayTypeIndex::typecode; -extern template int NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; +extern template char NDArrayTypeIndex::typecode; } namespace { From 3f6190f5290f4ffaba1f74a0580a1dd13cc330cd Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Wed, 14 Mar 2018 16:12:24 +0000 Subject: [PATCH 221/364] Re #22076 Removed hardcoded prints --- scripts/SANS/sans/user_file/user_file_parser.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/SANS/sans/user_file/user_file_parser.py b/scripts/SANS/sans/user_file/user_file_parser.py index cd2b8d99c9ed..492d58b6083f 100644 --- a/scripts/SANS/sans/user_file/user_file_parser.py +++ b/scripts/SANS/sans/user_file/user_file_parser.py @@ -2084,11 +2084,11 @@ def parse_line(self, line): setting = line.strip() - if setting.upper().startswith('PRINT'): - setting = setting[len('PRINT'):] + if setting.upper().startswith(PrintParser.Type): + setting = setting[len(PrintParser.Type):] setting = setting.strip() else: - raise RuntimeError("PrintParser: Failed to extract line {} it does not start with PRINT".format(line)) + raise RuntimeError("PrintParser: Failed to extract line {} it does not start with {}".format(line, PrintParser.Type)) return {PrintId.print_line: setting} From 381852f8f3aa6eb74606387cd064d176e7c2e180 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Wed, 14 Mar 2018 16:50:29 +0000 Subject: [PATCH 222/364] Re #22086 Changed save algorithms to write out can_run --- .../MantidDataHandling/NXcanSASDefinitions.h | 1 + .../inc/MantidDataHandling/SaveCanSAS1D2.h | 3 + Framework/DataHandling/src/SaveCanSAS1D2.cpp | 103 ++++++++++++++++++ Framework/DataHandling/src/SaveNXcanSAS.cpp | 43 +++++++- 4 files changed, 149 insertions(+), 1 deletion(-) diff --git a/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h b/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h index 79b19a278908..0149fb4c9f86 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h +++ b/Framework/DataHandling/inc/MantidDataHandling/NXcanSASDefinitions.h @@ -94,6 +94,7 @@ const std::string sasProcessName = "name"; const std::string sasProcessNameValue = "Mantid_generated_NXcanSAS"; const std::string sasProcessDate = "date"; const std::string sasProcessTermSvn = "svn"; +const std::string sasProcessTermCan = "can_trans_run"; const std::string sasProcessTermUserFile = "user_file"; const std::string sasProcessUserFileInLogs = "UserFile"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h index c1f19c140134..8763bb1052a4 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h @@ -92,6 +92,9 @@ class DLLExport SaveCanSAS1D2 : public SaveCanSAS1D { /// this method creates SAStransmission_spectrum element void createSASTransElement(std::string &sasTrans, const std::string &name); + /// this method creates SASProcess element + void createSASProcessElement(std::string &sasProcess); + /// Overwrites writeHeader method void writeHeader(const std::string &fileName) override; diff --git a/Framework/DataHandling/src/SaveCanSAS1D2.cpp b/Framework/DataHandling/src/SaveCanSAS1D2.cpp index ac1eb4afbf97..7212f7627c5d 100644 --- a/Framework/DataHandling/src/SaveCanSAS1D2.cpp +++ b/Framework/DataHandling/src/SaveCanSAS1D2.cpp @@ -9,6 +9,37 @@ #include "MantidKernel/MantidVersion.h" #include "MantidKernel/Unit.h" +namespace { +void encode(std::string &data) { + std::string buffer; + buffer.reserve(data.size()); + + for (auto &element : data) { + switch (element) { + case '&': + buffer.append("&"); + break; + case '\"': + buffer.append("""); + break; + case '\'': + buffer.append("'"); + break; + case '<': + buffer.append("<"); + break; + case '>': + buffer.append(">"); + break; + default: + buffer.push_back(element); + } + } + + data.swap(buffer); +} +} + using namespace Mantid::Kernel; using namespace Mantid::Geometry; using namespace Mantid::API; @@ -134,6 +165,78 @@ void SaveCanSAS1D2::createSASRootElement(std::string &rootElem) { "http://www.cansas.org/formats/1.1/cansas1d.xsd\"\n\t\t>"; } +/** This method creates an XML element named "SASprocess" + * @param sasProcess :: string for sasprocess element in the xml + */ +void SaveCanSAS1D2::createSASProcessElement(std::string &sasProcess) { + sasProcess = "\n\t\t"; + // outFile<"; + sasProcsvn += MantidVersion::version(); + sasProcsvn += ""; + sasProcess += sasProcsvn; + + const API::Run &run = m_workspace->run(); + std::string user_file; + if (run.hasProperty("UserFile")) { + user_file = run.getLogData("UserFile")->value(); + } + + std::string sasProcuserfile = "\n\t\t\t"; + sasProcuserfile += user_file; + sasProcuserfile += ""; + // outFile<run().hasProperty("run_number")) { + Kernel::Property *logP = m_transcan_ws->run().getLogData("run_number"); + auto can_run = logP->value(); + std::string sasProcCanRun = "\n\t\t\t"; + sasProcCanRun += can_run; + sasProcCanRun += ""; + sasProcess += sasProcCanRun; + } else { + g_log.debug() << "Didn't find RunNumber log in workspace. Writing " + " to the CANSAS file\n"; + } + } + +// Reduction process note, if available + std::string process_xml = getProperty("Process"); + if (!process_xml.empty()) { + std::string processNote = "\n\t\t\t"; + encode(process_xml); + processNote += process_xml; + processNote += ""; + sasProcess += processNote; + } else { + sasProcess += "\n\t\t\t"; + } + + sasProcess += "\n\t\t"; +} + + /** This method creates an XML element named "SAStransmission_spectrum" * @param sasTrans :: string for sasdata element in the xml * @param name :: name of the type of spectrum. Two values are acceptable: diff --git a/Framework/DataHandling/src/SaveNXcanSAS.cpp b/Framework/DataHandling/src/SaveNXcanSAS.cpp index 9e24e515ac84..416b41d62760 100644 --- a/Framework/DataHandling/src/SaveNXcanSAS.cpp +++ b/Framework/DataHandling/src/SaveNXcanSAS.cpp @@ -321,6 +321,43 @@ void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace) { } } +/** + * Add the process information to the NXcanSAS file. This information + * about the run number, the Mantid version and the user file (if available) + * @param group: the sasEntry + * @param workspace: the workspace which is being stored + */ +void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace, Mantid::API::MatrixWorkspace_sptr canWorkspace) { + // Setup process + const std::string sasProcessNameForGroup = sasProcessGroupName; + auto process = Mantid::DataHandling::H5Util::createGroupCanSAS( + group, sasProcessNameForGroup, nxProcessClassAttr, sasProcessClassAttr); + + // Add name + Mantid::DataHandling::H5Util::write(process, sasProcessName, + sasProcessNameValue); + + // Add creation date of the file + auto date = getDate(); + Mantid::DataHandling::H5Util::write(process, sasProcessDate, date); + + // Add Mantid version + const auto version = std::string(MantidVersion::version()); + Mantid::DataHandling::H5Util::write(process, sasProcessTermSvn, version); + + const auto run = workspace->run(); + if (run.hasProperty(sasProcessUserFileInLogs)) { + auto userFileProperty = run.getProperty(sasProcessUserFileInLogs); + auto userFileString = userFileProperty->value(); + Mantid::DataHandling::H5Util::write(process, sasProcessTermUserFile, + userFileString); + } + + // Add can run number + const auto canRun = canWorkspace->getRunNumber(); + Mantid::DataHandling::H5Util::write(process, sasProcessTermCan, std::to_string(canRun)); +} + WorkspaceDimensionality getWorkspaceDimensionality(Mantid::API::MatrixWorkspace_sptr workspace) { auto numberOfHistograms = workspace->getNumberHistograms(); @@ -814,7 +851,11 @@ void SaveNXcanSAS::exec() { // Add the process information progress.report("Adding process information."); - addProcess(sasEntry, workspace); + if (transmissionCan){ + addProcess(sasEntry, workspace, transmissionCan); + } else { + addProcess(sasEntry, workspace); + } // Add the transmissions for sample if (transmissionSample) { From 77acb2a58fc13df1aeecf3de5bf2af02786c2ddc Mon Sep 17 00:00:00 2001 From: Gemma Guest Date: Wed, 14 Mar 2018 16:57:55 +0000 Subject: [PATCH 223/364] Fix a crash pasting into the reflectometry GUI - Add an out-of-bounds check - Fix a potential unexpected exception caused by empty data Re #22050 --- .../common/src/DataProcessorUI/TwoLevelTreeManager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp b/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp index cf52683fc3b0..a86fb0f0f979 100644 --- a/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp +++ b/qt/widgets/common/src/DataProcessorUI/TwoLevelTreeManager.cpp @@ -332,12 +332,17 @@ void TwoLevelTreeManager::pasteSelected(const QString &text) { // Add as many new rows as required for (auto i = 0; i < lines.size(); ++i) { auto values = lines[i].split("\t"); + auto const valuesSizeLessOne = static_cast(values.size()) - 1; + + if (valuesSizeLessOne < 1) + continue; auto groupId = parseDenaryInteger(values.front()); int rowId = numRowsInGroup(groupId); if (!m_model->insertRow(rowId, m_model->index(groupId, 0))) return; - for (int col = 0; col < m_model->columnCount(); col++) { + for (int col = 0; col < m_model->columnCount() && col < valuesSizeLessOne; + col++) { m_model->setData(m_model->index(rowId, col, m_model->index(groupId, 0)), values[col + 1]); } From 260d531d8e500313f6882c15f0ee0d15fb8993e4 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Wed, 14 Mar 2018 17:04:33 +0000 Subject: [PATCH 224/364] Re #22086 Applied clang format --- Framework/DataHandling/src/SaveCanSAS1D2.cpp | 7 +++---- Framework/DataHandling/src/SaveNXcanSAS.cpp | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Framework/DataHandling/src/SaveCanSAS1D2.cpp b/Framework/DataHandling/src/SaveCanSAS1D2.cpp index 7212f7627c5d..37afe167ba19 100644 --- a/Framework/DataHandling/src/SaveCanSAS1D2.cpp +++ b/Framework/DataHandling/src/SaveCanSAS1D2.cpp @@ -207,7 +207,7 @@ void SaveCanSAS1D2::createSASProcessElement(std::string &sasProcess) { sasProcess += sasProcuserfile; // can run number if available - if(m_transcan_ws){ + if (m_transcan_ws) { if (m_transcan_ws->run().hasProperty("run_number")) { Kernel::Property *logP = m_transcan_ws->run().getLogData("run_number"); auto can_run = logP->value(); @@ -217,11 +217,11 @@ void SaveCanSAS1D2::createSASProcessElement(std::string &sasProcess) { sasProcess += sasProcCanRun; } else { g_log.debug() << "Didn't find RunNumber log in workspace. Writing " - " to the CANSAS file\n"; + " to the CANSAS file\n"; } } -// Reduction process note, if available + // Reduction process note, if available std::string process_xml = getProperty("Process"); if (!process_xml.empty()) { std::string processNote = "\n\t\t\t"; @@ -236,7 +236,6 @@ void SaveCanSAS1D2::createSASProcessElement(std::string &sasProcess) { sasProcess += "\n\t\t"; } - /** This method creates an XML element named "SAStransmission_spectrum" * @param sasTrans :: string for sasdata element in the xml * @param name :: name of the type of spectrum. Two values are acceptable: diff --git a/Framework/DataHandling/src/SaveNXcanSAS.cpp b/Framework/DataHandling/src/SaveNXcanSAS.cpp index 416b41d62760..cc5e6b95341f 100644 --- a/Framework/DataHandling/src/SaveNXcanSAS.cpp +++ b/Framework/DataHandling/src/SaveNXcanSAS.cpp @@ -327,7 +327,8 @@ void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace) { * @param group: the sasEntry * @param workspace: the workspace which is being stored */ -void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace, Mantid::API::MatrixWorkspace_sptr canWorkspace) { +void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace, + Mantid::API::MatrixWorkspace_sptr canWorkspace) { // Setup process const std::string sasProcessNameForGroup = sasProcessGroupName; auto process = Mantid::DataHandling::H5Util::createGroupCanSAS( @@ -355,7 +356,8 @@ void addProcess(H5::Group &group, Mantid::API::MatrixWorkspace_sptr workspace, M // Add can run number const auto canRun = canWorkspace->getRunNumber(); - Mantid::DataHandling::H5Util::write(process, sasProcessTermCan, std::to_string(canRun)); + Mantid::DataHandling::H5Util::write(process, sasProcessTermCan, + std::to_string(canRun)); } WorkspaceDimensionality @@ -851,7 +853,7 @@ void SaveNXcanSAS::exec() { // Add the process information progress.report("Adding process information."); - if (transmissionCan){ + if (transmissionCan) { addProcess(sasEntry, workspace, transmissionCan); } else { addProcess(sasEntry, workspace); From 33ef103e52fbf3429f28c8f989321bcbb49dc34c Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Wed, 14 Mar 2018 17:54:07 -0400 Subject: [PATCH 225/364] Add -fno-omit-frame-pointer to RelWithDebInfo config. --- buildconfig/CMake/GNUSetup.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildconfig/CMake/GNUSetup.cmake b/buildconfig/CMake/GNUSetup.cmake index 22b202ff95bd..05525e7c8417 100644 --- a/buildconfig/CMake/GNUSetup.cmake +++ b/buildconfig/CMake/GNUSetup.cmake @@ -63,7 +63,7 @@ elseif ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) endif() # Add some options for debug build to help the Zoom profiler -add_compile_options ( $<$:-fno-omit-frame-pointer> ) +add_compile_options ( $<$,$>:-fno-omit-frame-pointer> ) option(WITH_ASAN "Enable address sanitizer" OFF) if(WITH_ASAN) From 90e3b4aa05789a2ce254b2df68531b4c96616203 Mon Sep 17 00:00:00 2001 From: Gemma Guest Date: Thu, 15 Mar 2018 09:12:49 +0000 Subject: [PATCH 226/364] Add screenshot and tidy reflectometry release notes --- .../ISIS_Reflectometry_per_angle_options.png | Bin 0 -> 32859 bytes docs/source/release/v3.12.0/reflectometry.rst | 21 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 docs/source/images/ISIS_Reflectometry_per_angle_options.png diff --git a/docs/source/images/ISIS_Reflectometry_per_angle_options.png b/docs/source/images/ISIS_Reflectometry_per_angle_options.png new file mode 100644 index 0000000000000000000000000000000000000000..f556647014038eef6b68956cd2a939adb905ecc9 GIT binary patch literal 32859 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 Date: Thu, 15 Mar 2018 09:27:55 +0000 Subject: [PATCH 227/364] Reordered and grouped sections to read better --- docs/source/release/v3.12.0/reflectometry.rst | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/source/release/v3.12.0/reflectometry.rst b/docs/source/release/v3.12.0/reflectometry.rst index a0c57dfe6ba8..b5e0ba2ba044 100644 --- a/docs/source/release/v3.12.0/reflectometry.rst +++ b/docs/source/release/v3.12.0/reflectometry.rst @@ -41,24 +41,32 @@ New features Improvements ############ -- Output workspace names for time sliced data now contain the time periods, rather than just a slice index number. -- Grid lines are now displayed in the runs tab. -- Plotting results in event handling mode now plots the `IvsQ_binned_` workspaces rather than `IvsQ_`, to make the behaviour consistent with non-event mode. -- Menu items and toolbar buttons are now enabled/disabled when appropriate, e.g. to prevent table modification during processing. Directly editing table rows and settings is also disabled during processing. -- Removed the 'DirectBeam' box from the settings tab of the ISIS Reflectometry interface because this is not used. +- Output workspace names and plotting: + + - Output workspace names now use ``+`` to indicate preprocessed (i.e. summed) workspaces, rather than ``_``, which is used to indicate postprocessed (i.e. stitched) workspaces. + - Output workspace names for time sliced data now contain the time periods, rather than just a slice index number. + - Plotting results in event handling mode now plots the ``IvsQ_binned_`` workspaces rather than ``IvsQ_``, to make the behaviour consistent with non-event mode. + - The Python code generated when you tick ``Output Notebook`` has been improved to support special characters (e.g. ``+``) in workspace names. + - The ``Output Notebook`` option now works for all groups that are processed as non-event workspaces. Previously, if event handling was enabled but a group contained non-event workspaces, generating the notebook was not performed. + - Properties on the Runs tab now take precedence over properties on the Settings tab. -- Output workspace names have been improved. Names now use '+' to indicate preprocessed (i.e. summed) workspaces, rather than '_', which is used to indicate postprocessed (i.e. stitched) workspaces. -- The Python code generated when you tick `Output Notebook` has been improved to support special characters (e.g. `+`) in workspace names. Output workspaces are now set using the output properties of the algorithm rather than by variable assignment. This avoids the possibility of invalid characters being used in Python variable names. -- The `Output Notebook` option now works for all groups that are processed as non-event workspaces. Previously, if event handling was enabled but a group contained non-event workspaces, generating the notebook was disabled. -- Added a new `?` button to the ISIS Reflectometry Interface which links to the documentation page. -- Added extra tooltips to the ISIS Reflectometry Interface. + +- Extra tooltips have been added along with a new ``?`` button which links to the documentation page. + +- The runs tab table now contains grid lines to make it easier to see where to enter text. + +- Menu items and toolbar buttons are now enabled/disabled when appropriate, e.g. to prevent table modification during processing. Directly editing table rows and settings is also disabled during processing. + +- The 'DirectBeam' box has been from the settings tab because this is not used. Bug fixes ######### - Fixed some bugs where transmission runs entered on the Settings tab were not being found, whether entered as a run number to load or as the name of an existing workspace in the ADS. -- The Python code generated when you tick `Output Notebook` has been changed so that all algorithm property values are enclosed in quotes. Unquoted values were causing failures in some algorithms. A bug has also been fixed in setting the legend location for the 4th (stitched) plot, which is shown when post-processing is performed. + +- The Python code generated when you tick ``Output Notebook`` has been changed so that all algorithm property values are enclosed in quotes. Unquoted values were causing failures in some algorithms. A bug has also been fixed in setting the legend location for the 4th (stitched) plot, which is shown when post-processing is performed. + - If any of the mandatory parameters listed below are missing when pressing 'Get Default' a warning is shown rather than a crash. - MonitorIntegralMax @@ -92,7 +100,6 @@ New features Improvements ############ -- Removed the ``RegionOfDirectBeam`` property from :ref:`algm-ReflectometryReductionOne` and :ref:`algm-ReflectometryReductionOneAuto` because this is not used. - Improvements to :ref:`algm-LoadILLReflectometry`: - Figaro NeXus files are now properly handled. @@ -102,6 +109,8 @@ Improvements - Slits S2 and S3 have been added to D17 and Figaro IDFs; the loader will adjust their positions according to the NeXus files. - The MagnetismReflectometryReduction now computes a Q-resolution estimate based on slit openings. +- Removed the ``RegionOfDirectBeam`` property from :ref:`algm-ReflectometryReductionOne` and :ref:`algm-ReflectometryReductionOneAuto` because this is not used. + Bug fixes ######### From e0ce357865b77c3085751884d9db3c0a84729ede Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Thu, 15 Mar 2018 10:30:52 +0000 Subject: [PATCH 228/364] Add deprecation for Mantid.pyplot --- docs/source/release/v3.12.0/framework.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst index 15e5685a588d..4e95502b10e9 100644 --- a/docs/source/release/v3.12.0/framework.rst +++ b/docs/source/release/v3.12.0/framework.rst @@ -146,6 +146,12 @@ Improved props = json.loads('{"DryRun":true}') Segfault(**props) +Deprecated +########## + +- `MantidPlot.pyplot `_ was an early attempt to provide Matplotlib style syntax over Mantidplot plotting. This will be replaced in Mantid 4.0 with MatPlotlib itself, and this packages would cause namespace clashes and confusion. This package is now deprecated, and will not be included in future releases of Mantid. To the best of our knowledge the impact of this should be minimal as it is at best only rarely used. + + Bugfixes ######## - Fixed an issue with coercing data from python lists or numpy arrays where the datatype!=float64 into a workspace From b4a984a2d1f609d3f787ceb9a5ddfec92f876fca Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Thu, 15 Mar 2018 10:55:27 +0000 Subject: [PATCH 229/364] Added depreciation warning to release notes --- docs/source/release/v3.12.0/sans.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/release/v3.12.0/sans.rst b/docs/source/release/v3.12.0/sans.rst index dfa291a97ea1..4c109631c980 100644 --- a/docs/source/release/v3.12.0/sans.rst +++ b/docs/source/release/v3.12.0/sans.rst @@ -42,6 +42,7 @@ Improvements - Added more prominent instrument selection and process buttons to Isis Gui v2. - Added manage directories button to Isis Gui v2. - Added link to documentation at the bottom left of Isis Gui v2. +- As an advance warning we plan to remove the 1D Analysis tab from the old Gui for the next release. Bug fixes ######### From 233e820f72be507aff83e4eaf38f988144418b2b Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 15:53:22 +0000 Subject: [PATCH 230/364] Re #20048: Fixed broken code in PythonInterface. --- .../MantidPythonInterface/kernel/Converters/MatrixToNDArray.h | 2 +- .../MantidPythonInterface/kernel/Converters/VectorToNDArray.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h index 4d72bca602bf..08783aaaf85f 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/MatrixToNDArray.h @@ -52,7 +52,7 @@ struct DLLExport MatrixToNDArray { const std::pair matrixDims = cmatrix.size(); Py_intptr_t dims[2] = {static_cast(matrixDims.first), static_cast(matrixDims.second)}; - using policy = typename ConversionPolicy::apply; + using policy = typename ConversionPolicy::template apply; return policy::createFromArray(&(cmatrix[0][0]), 2, dims); } }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h index bcf269619edd..80313d2f103e 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/VectorToNDArray.h @@ -48,7 +48,7 @@ struct VectorToNDArray { */ inline PyObject *operator()(const std::vector &cdata) const { // Hand off the work to the conversion policy - using policy = typename ConversionPolicy::apply; + using policy = typename ConversionPolicy::template apply; return policy::create1D(cdata); } }; From 310d3e61c539d02c5e9bf236e12bbd2ed8587563 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 14 Mar 2018 15:06:03 +0000 Subject: [PATCH 231/364] Re #22048: Applied fixes to MantidPlot/. --- MantidPlot/src/ConfigDialog.cpp | 4 ++-- MantidPlot/src/Fit.h | 9 ++++----- MantidPlot/src/Mantid/InputHistory.h | 4 ++-- MantidPlot/src/Mantid/MantidMatrix.h | 2 +- MantidPlot/src/MdiSubWindow.h | 2 +- MantidPlot/src/PluginFit.cpp | 2 +- MantidPlot/src/PluginFit.h | 2 +- MantidPlot/src/ScriptingEnv.h | 2 +- MantidPlot/src/WindowFactory.h | 8 +++----- MantidPlot/src/origin/tree.hh | 20 ++++++++++---------- 10 files changed, 26 insertions(+), 29 deletions(-) diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp index c32b03847cb7..c674a20ae33c 100644 --- a/MantidPlot/src/ConfigDialog.cpp +++ b/MantidPlot/src/ConfigDialog.cpp @@ -1277,8 +1277,8 @@ void ConfigDialog::updateSendToTab() { } } -typedef std::map categoriesType; -typedef QMap widgetMap; +using categoriesType = std::map; +using widgetMap = QMap; void ConfigDialog::refreshTreeCategories() { treeCategories->clear(); diff --git a/MantidPlot/src/Fit.h b/MantidPlot/src/Fit.h index 1c5aa79798ea..2204852328c1 100644 --- a/MantidPlot/src/Fit.h +++ b/MantidPlot/src/Fit.h @@ -45,11 +45,10 @@ class Fit : public Filter { Q_OBJECT public: - typedef double (*fit_function_simplex)(const gsl_vector *, void *); - typedef int (*fit_function)(const gsl_vector *, void *, gsl_vector *); - typedef int (*fit_function_df)(const gsl_vector *, void *, gsl_matrix *); - typedef int (*fit_function_fdf)(const gsl_vector *, void *, gsl_vector *, - gsl_matrix *); + using fit_function_simplex = double (*)(const gsl_vector *, void *); + using fit_function = int (*)(const gsl_vector *, void *, gsl_vector *); + using fit_function_df = int (*)(const gsl_vector *, void *, gsl_matrix *); + using fit_function_fdf = int (*)(const gsl_vector *, void *, gsl_vector *, gsl_matrix *); enum Algorithm { ScaledLevenbergMarquardt, diff --git a/MantidPlot/src/Mantid/InputHistory.h b/MantidPlot/src/Mantid/InputHistory.h index 23f085ff23e3..e13cd4881663 100644 --- a/MantidPlot/src/Mantid/InputHistory.h +++ b/MantidPlot/src/Mantid/InputHistory.h @@ -11,7 +11,7 @@ namespace Mantid { namespace API { class IAlgorithm; -typedef boost::shared_ptr IAlgorithm_sptr; +using IAlgorithm_sptr = boost::shared_ptr; } } @@ -88,6 +88,6 @@ class InputHistoryImpl { QMap> m_history; }; -typedef Mantid::Kernel::SingletonHolder InputHistory; +using InputHistory = Mantid::Kernel::SingletonHolder; #endif /* INPUTHISTORY_H */ diff --git a/MantidPlot/src/Mantid/MantidMatrix.h b/MantidPlot/src/Mantid/MantidMatrix.h index 5888ec088c9f..58203c250bb8 100644 --- a/MantidPlot/src/Mantid/MantidMatrix.h +++ b/MantidPlot/src/Mantid/MantidMatrix.h @@ -333,7 +333,7 @@ public slots: }; /// Typedef for a shared pointer to a MantidMatrix -typedef QSharedPointer MantidMatrix_sptr; +using MantidMatrix_sptr = QSharedPointer; class ProjectData { public: diff --git a/MantidPlot/src/MdiSubWindow.h b/MantidPlot/src/MdiSubWindow.h index aca03dc68ef0..61bf3903eba4 100644 --- a/MantidPlot/src/MdiSubWindow.h +++ b/MantidPlot/src/MdiSubWindow.h @@ -353,7 +353,7 @@ public slots: friend class FloatingWindow; }; -typedef QList MDIWindowList; +using MDIWindowList = QList; /* Used to register classes into the factory. creates a global object in an * anonymous namespace. The object itself does nothing, but the comma operator diff --git a/MantidPlot/src/PluginFit.cpp b/MantidPlot/src/PluginFit.cpp index 7b5aae539e18..50fd84fa5112 100644 --- a/MantidPlot/src/PluginFit.cpp +++ b/MantidPlot/src/PluginFit.cpp @@ -161,7 +161,7 @@ bool PluginFit::load(const QString &pluginName) { if (!f_eval) return false; - typedef char *(*fitFunc)(); + using fitFunc = char *(*)(); ff_union ff; ff.ptr = lib.resolve("parameters"); fitFunc fitFunction = ff.func; diff --git a/MantidPlot/src/PluginFit.h b/MantidPlot/src/PluginFit.h index 0253cb40b2e5..ad3c01dcfa87 100644 --- a/MantidPlot/src/PluginFit.h +++ b/MantidPlot/src/PluginFit.h @@ -48,7 +48,7 @@ class PluginFit : public Fit { private: void init(); - typedef double (*fitFunctionEval)(double, double *); + using fitFunctionEval = double (*)(double, double *); void calculateFitCurveData(double *X, double *Y) override; fitFunctionEval f_eval; }; diff --git a/MantidPlot/src/ScriptingEnv.h b/MantidPlot/src/ScriptingEnv.h index 58544a890615..861d9f8ce08f 100644 --- a/MantidPlot/src/ScriptingEnv.h +++ b/MantidPlot/src/ScriptingEnv.h @@ -169,7 +169,7 @@ class ScriptingLangManager { static int numLanguages(); private: - typedef ScriptingEnv *(*ScriptingEnvConstructor)(ApplicationWindow *); + using ScriptingEnvConstructor = ScriptingEnv *(*)(ApplicationWindow *); typedef struct { const char *name; ScriptingEnvConstructor constructor; diff --git a/MantidPlot/src/WindowFactory.h b/MantidPlot/src/WindowFactory.h index 7a777ced661b..6d7564a13fc3 100644 --- a/MantidPlot/src/WindowFactory.h +++ b/MantidPlot/src/WindowFactory.h @@ -101,8 +101,7 @@ class ProjectWindowInstantiator : public AbstractProjectInstantiator { class WindowFactoryImpl final { private: - typedef AbstractProjectInstantiator - AbstractFactory; + using AbstractFactory = AbstractProjectInstantiator; public: WindowFactoryImpl(); @@ -173,8 +172,7 @@ class WindowFactoryImpl final { } /// A typedef for the map of registered classes - typedef Mantid::Kernel::CaseInsensitiveMap> - FactoryMap; + using FactoryMap = Mantid::Kernel::CaseInsensitiveMap >; /// The map holding the registered class names and their instantiators FactoryMap _map; }; @@ -184,7 +182,7 @@ class WindowFactoryImpl final { template class Mantid::Kernel::SingletonHolder; #endif /* _WIN32 */ -typedef Mantid::Kernel::SingletonHolder WindowFactory; +using WindowFactory = Mantid::Kernel::SingletonHolder; } } diff --git a/MantidPlot/src/origin/tree.hh b/MantidPlot/src/origin/tree.hh index beb1bf1e38e0..bd6a2576a4a0 100644 --- a/MantidPlot/src/origin/tree.hh +++ b/MantidPlot/src/origin/tree.hh @@ -66,10 +66,10 @@ tree_node_::tree_node_(const T& val) template > > class tree { protected: - typedef tree_node_ tree_node; + using tree_node = tree_node_; public: /// Value of the data stored at a node. - typedef T value_type; + using value_type = T; class iterator_base; class pre_order_iterator; @@ -91,12 +91,12 @@ class tree { class iterator_base { #endif public: - typedef T value_type; - typedef T* pointer; - typedef T& reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; + using value_type = T; + using pointer = T *; + using reference = T &; + using size_type = size_t; + using difference_type = ptrdiff_t; + using iterator_category = std::bidirectional_iterator_tag; iterator_base(); iterator_base(tree_node *); @@ -175,8 +175,8 @@ class tree { }; /// The default iterator types throughout the tree class. - typedef pre_order_iterator iterator; - typedef breadth_first_queued_iterator breadth_first_iterator; + using iterator = pre_order_iterator; + using breadth_first_iterator = breadth_first_queued_iterator; /// Iterator which traverses only the nodes at a given depth from the root. class fixed_depth_iterator : public iterator_base { From 84ef36bfbda731645ebf9cf4027d4303413436b6 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 10:36:40 +0000 Subject: [PATCH 232/364] Re #22048: Applied fixes to qt. --- .../ISISReflectometry/MeasurementItem.h | 2 +- .../ReflMeasureTransferStrategy.cpp | 5 +- .../ISISReflectometry/ReflSearchModel.h | 2 +- .../ISISReflectometry/ReflTableSchema.h | 8 ++-- .../ISISReflectometry/ReflTransferStrategy.h | 2 +- .../ISISSANS/SANSRunWindow.cpp | 5 +- .../ISISSANS/SANSRunWindow.h | 5 +- .../Muon/IALCBaselineModellingModel.h | 2 +- .../Muon/IALCBaselineModellingView.h | 4 +- .../Muon/MuonAnalysisFitDataPresenter.cpp | 3 +- .../Muon/MuonAnalysisFitDataPresenter.h | 4 +- .../Muon/MuonAnalysisHelper.cpp | 2 +- .../Muon/MuonAnalysisResultTableCreator.h | 4 +- .../Muon/MuonAnalysisResultTableTab.h | 2 +- .../test/ALCDataLoadingPresenterTest.h | 2 +- .../Common/AlgorithmInputHistory.h | 3 +- .../Common/AlgorithmSelectorWidget.h | 2 +- .../Common/BatchAlgorithmRunner.h | 5 +- .../Common/FindFilesThreadPoolManager.h | 3 +- .../Common/FitOptionsBrowser.h | 4 +- .../MantidQtWidgets/Common/InterfaceFactory.h | 6 +-- .../inc/MantidQtWidgets/Common/Message.h | 2 +- .../MantidQtWidgets/Common/PythonThreading.h | 2 +- .../CompositeEditorFactory.h | 2 +- .../QtPropertyBrowser/qteditorfactory.h | 6 +-- .../QtPropertyBrowser/qtpropertymanager.h | 46 +++++++++---------- .../QtPropertyBrowser/qttreepropertybrowser.h | 4 +- .../QtPropertyBrowser/qtvariantproperty.h | 2 +- .../MantidQtWidgets/Common/SaveWorkspaces.h | 2 +- .../Common/SelectionNotificationService.h | 3 +- .../Common/SlicingAlgorithmDialog.h | 2 +- .../inc/MantidQtWidgets/Common/pqHelpWindow.h | 2 +- .../common/src/AlgorithmPropertiesWidget.cpp | 2 +- .../common/src/AlgorithmSelectorWidget.cpp | 2 +- .../QtPropertyBrowser/qtpropertybrowser.cpp | 8 +--- .../QtPropertyBrowser/qtpropertymanager.cpp | 22 ++++----- .../QtPropertyBrowser/qtvariantproperty.cpp | 2 +- .../common/src/SelectWorkspacesDialog.cpp | 2 +- qt/widgets/common/src/pqHelpWindow.cxx | 4 +- .../InstrumentView/ProjectionSurface.h | 2 +- .../src/StartLiveDataDialog.cpp | 7 +-- .../SliceViewer/CompositePeaksPresenter.h | 2 +- .../SliceViewer/ConcretePeaksPresenter.h | 2 +- .../SliceViewer/PeakBoundingBox.h | 14 +++--- .../SliceViewer/PeakOverlayView.h | 4 +- .../SliceViewer/PeakOverlayViewFactory.h | 2 +- .../MantidQtWidgets/SliceViewer/PeakPalette.h | 2 +- .../SliceViewer/PeakRepresentation.h | 6 +-- .../SliceViewer/PeaksPresenter.h | 7 ++- .../SliceViewer/QPeaksTableModel.h | 8 ++-- .../test/ConcretePeaksPresenterTest.h | 5 +- .../test/PeakRepresentationCrossTest.h | 6 +-- .../test/PeakRepresentationSphereTest.h | 6 +-- .../SpectrumViewer/ArrayDataSource.h | 4 +- .../SpectrumViewer/DataArray.h | 4 +- .../SpectrumViewer/MatrixWSDataSource.h | 5 +- .../SpectrumViewer/SpectrumDataSource.h | 5 +- 57 files changed, 127 insertions(+), 154 deletions(-) diff --git a/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h b/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h index d526bf200c37..a2c75848ce26 100644 --- a/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h +++ b/qt/scientific_interfaces/ISISReflectometry/MeasurementItem.h @@ -33,7 +33,7 @@ namespace CustomInterfaces { class MANTIDQT_ISISREFLECTOMETRY_DLL MeasurementItem { public: - typedef std::string IDType; + using IDType = std::string; /// Constructor MeasurementItem(const IDType &measurementItemId, const IDType &subId, diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp index 30709e657448..334aef8c297d 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp +++ b/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp @@ -43,9 +43,8 @@ TransferResults MantidQt::CustomInterfaces::ReflMeasureTransferStrategy::transferRuns( SearchResultMap &searchResults, Mantid::Kernel::ProgressBase &progress) { - typedef std::vector VecSameMeasurement; - typedef std::map - MapGroupedMeasurement; + using VecSameMeasurement = std::vector; + using MapGroupedMeasurement = std::map; // table-like output for successful runs std::vector> runs; diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h b/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h index a9e687d12eeb..62795fc59c57 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h +++ b/qt/scientific_interfaces/ISISReflectometry/ReflSearchModel.h @@ -72,7 +72,7 @@ class ReflSearchModel : public QAbstractTableModel { }; /// Typedef for a shared pointer to \c ReflSearchModel -typedef boost::shared_ptr ReflSearchModel_sptr; +using ReflSearchModel_sptr = boost::shared_ptr; } // namespace CustomInterfaces } // namespace Mantid diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h b/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h index 7b439c644bb6..73de805ca1e0 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h +++ b/qt/scientific_interfaces/ISISReflectometry/ReflTableSchema.h @@ -9,10 +9,10 @@ namespace MantidQt { namespace CustomInterfaces { namespace ReflTableSchema { -typedef std::string ColumnNameType; -typedef std::string ColumnValueType; -typedef std::map ColumnIndexNameMap; -typedef std::map ColumnNameIndexMap; +using ColumnNameType = std::string; +using ColumnValueType = std::string; +using ColumnIndexNameMap = std::map; +using ColumnNameIndexMap = std::map; /// Label for run number column static const std::string RUNS("Run(s)"); diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h b/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h index dc6ba41cd2ae..797138bc9f29 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h +++ b/qt/scientific_interfaces/ISISReflectometry/ReflTransferStrategy.h @@ -29,7 +29,7 @@ struct SearchResult { }; /// Helper typdef for map of SearchResults keyed by run -typedef std::map SearchResultMap; +using SearchResultMap = std::map; /** ReflTransferStrategy : Provides an stratgegy for transferring runs from search results to a format suitable for processing. diff --git a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp index b7d4cd41da78..ed12722f9fcf 100644 --- a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp +++ b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp @@ -61,7 +61,7 @@ Logger g_log("SANSRunWindow"); /// static logger for centre finding Logger g_centreFinderLog("CentreFinder"); -typedef boost::shared_ptr ReductionSettings_sptr; +using ReductionSettings_sptr = boost::shared_ptr; /** * Returns the PropertyManager object that is used to store the settings @@ -2145,8 +2145,7 @@ bool SANSRunWindow::handleLoadButtonClick() { m_uiForm.sample_geomid->setCurrentIndex(geomId - 1); using namespace boost; - typedef tuple, std::string> - GeomSampleInfo; + using GeomSampleInfo = tuple, std::string>; std::vector sampleInfoList; sampleInfoList.push_back(make_tuple(m_uiForm.sample_thick, diff --git a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h index 1d39d0f96997..549e2b2a6086 100644 --- a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h +++ b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h @@ -330,7 +330,7 @@ private slots: enum TransSettings { M3, M4, RADIUS, ROI }; /// holds pointer to validators and their locations - typedef std::map> ValMap; + using ValMap = std::map >; /// The form generated by Qt Designer Ui::SANSRunWindow m_uiForm; /// this object holds the functionality in the Add Files tab @@ -383,8 +383,7 @@ private slots: /// Holds pointers to the check box for each supported save format with the /// name of its save algorithm QHash m_savFormats; - typedef QHash::const_iterator - SavFormatsConstIt; + using SavFormatsConstIt = QHash::const_iterator; /// Get notified when the system input directories have changed Poco::NObserver m_newInDir; diff --git a/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h b/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h index 82e0c41bd81d..dc25f8dd5dc0 100644 --- a/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h +++ b/qt/scientific_interfaces/Muon/IALCBaselineModellingModel.h @@ -40,7 +40,7 @@ class MANTIDQT_MUONINTERFACE_DLL IALCBaselineModellingModel : public QObject { Q_OBJECT public: - typedef std::pair Section; + using Section = std::pair; /** * @return Function produced by the last fit diff --git a/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h b/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h index 2a9eb8dbc04e..e09dbd73ee6a 100644 --- a/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h +++ b/qt/scientific_interfaces/Muon/IALCBaselineModellingView.h @@ -39,8 +39,8 @@ class MANTIDQT_MUONINTERFACE_DLL IALCBaselineModellingView : public QObject { Q_OBJECT public: - typedef std::pair SectionRow; - typedef std::pair SectionSelector; + using SectionRow = std::pair; + using SectionSelector = std::pair; /// Function chosen to fit the data to /// @return Function string, or empty string if nothing chosen diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index 476db8ec0082..95d636cc1fd5 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -23,8 +23,7 @@ using Mantid::API::ITableWorkspace; using Mantid::API::MatrixWorkspace; using Mantid::API::TableRow; using Mantid::API::WorkspaceGroup; -typedef MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType - RebinType; +using RebinType = MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType; namespace { /// static logger diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h index 22779970184e..091b69d5d557 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h @@ -11,9 +11,7 @@ #include /// Save some typing -typedef std::pair< - MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType, - std::string> RebinOptions; +using RebinOptions = std::pair; namespace Mantid { namespace API { diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp index 152f003d30f5..9d7e86183bae 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp @@ -1102,7 +1102,7 @@ getWorkspaceColors(const std::vector &workspaces) { QMap colors; // position, color // Vector of pairs - typedef std::pair> FitProp; + using FitProp = std::pair >; std::vector fitProperties; // Get fit properties for each input workspace diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h index e6f4892dc48e..d4c4f8c58ee8 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h @@ -9,8 +9,8 @@ namespace MantidQt { namespace CustomInterfaces { -typedef QMap> WSParameterList; -typedef QMap> LogValuesMap; +using WSParameterList = QMap >; +using LogValuesMap = QMap >; /** MuonAnalysisResultTableCreator : Creates table of muon fit results Used in the "result table" tab of Muon Analysis interface diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h index 0bc9675b88a1..6f4ae326f7af 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h @@ -16,7 +16,7 @@ class MuonAnalysis; namespace MantidQt { namespace CustomInterfaces { namespace Muon { -typedef QMap> WSParameterList; +using WSParameterList = QMap >; /** This is a Helper class for MuonAnalysis. In particular this helper class deals diff --git a/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h b/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h index 2bc5d686928e..198408673ed0 100644 --- a/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h +++ b/qt/scientific_interfaces/test/ALCDataLoadingPresenterTest.h @@ -30,7 +30,7 @@ GCC_DIAG_OFF_SUGGEST_OVERRIDE class MockALCDataLoadingView : public IALCDataLoadingView { // XXX: A workaround, needed because of the way the comma is treated in a // macro - typedef std::pair PAIR_OF_DOUBLES; + using PAIR_OF_DOUBLES = std::pair; public: MOCK_CONST_METHOD0(firstRun, std::string()); diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h index 206b584b4d38..53706682c1b2 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h @@ -96,8 +96,7 @@ class EXPORT_OPT_MANTIDQT_COMMON AlgorithmInputHistoryImpl friend struct Mantid::Kernel::CreateUsingNew; }; -typedef Mantid::Kernel::SingletonHolder - AlgorithmInputHistory; +using AlgorithmInputHistory = Mantid::Kernel::SingletonHolder; } } diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h index 53a6bb39d45b..b315f69edf0c 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h @@ -136,7 +136,7 @@ public slots: void keyPressEvent(QKeyEvent *e) override; private: - typedef std::vector AlgNamesType; + using AlgNamesType = std::vector; void addAliases(AlgNamesType &algNamesList); QString stripAlias(const QString &text) const; }; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h b/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h index 72a0a56c5574..1e976435e309 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h @@ -59,9 +59,8 @@ class EXPORT_OPT_MANTIDQT_COMMON BatchAlgorithmRunner : public QObject { Q_OBJECT public: - typedef std::map AlgorithmRuntimeProps; - typedef std::pair - ConfiguredAlgorithm; + using AlgorithmRuntimeProps = std::map; + using ConfiguredAlgorithm = std::pair; explicit BatchAlgorithmRunner(QObject *parent = nullptr); ~BatchAlgorithmRunner() override; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h index 48432fe6d999..4e4d57dd03aa 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h @@ -21,8 +21,7 @@ namespace API { */ class EXPORT_OPT_MANTIDQT_COMMON FindFilesThreadPoolManager : public QObject { Q_OBJECT - typedef std::function - ThreadAllocator; + using ThreadAllocator = std::function; public: /// Create a new thread pool manager for finding files diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h index 80cd05a4efdd..e95c5d6f6f81 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FitOptionsBrowser.h @@ -164,8 +164,8 @@ private slots: /// Precision of doubles in m_doubleManager int m_decimals; - typedef void (FitOptionsBrowser::*SetterType)(QtProperty *, const QString &); - typedef QString (FitOptionsBrowser::*GetterType)(QtProperty *) const; + using SetterType = void (FitOptionsBrowser::*)(QtProperty *, const QString &); + using GetterType = QString (FitOptionsBrowser::*)(QtProperty *) const; /// Maps algorithm property name to the QtProperty QMap m_propertyNameMap; /// Store for the properties setter methods diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h index 094ba14c25c0..1141964429b3 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h @@ -70,8 +70,7 @@ class EXPORT_OPT_MANTIDQT_COMMON AlgorithmDialogFactoryImpl }; /// The specific instantiation of the templated type -typedef Mantid::Kernel::SingletonHolder - AlgorithmDialogFactory; +using AlgorithmDialogFactory = Mantid::Kernel::SingletonHolder; /** The UserSubWindowFactory is responsible for creating concrete instances of @@ -180,8 +179,7 @@ void UserSubWindowFactoryImpl::saveAliasNames(const std::string &realName) { } /// The specific instantiation of the templated type -typedef Mantid::Kernel::SingletonHolder - UserSubWindowFactory; +using UserSubWindowFactory = Mantid::Kernel::SingletonHolder; } } diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h b/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h index 2b22c374a34d..3c722c06c983 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/Message.h @@ -25,7 +25,7 @@ class EXPORT_OPT_MANTIDQT_COMMON Message : public QObject { public: /// Priority matches Mantid Logger priority - typedef Mantid::Kernel::Logger::Priority Priority; + using Priority = Mantid::Kernel::Logger::Priority; /// Default constuctor required by Qt meta-type system Message(); diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h b/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h index bc5f3ecddb30..44d070dba1bf 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/PythonThreading.h @@ -56,6 +56,6 @@ template class ScopedGIL { }; /// Typedef for scoped lock -typedef ScopedGIL ScopedPythonGIL; +using ScopedPythonGIL = ScopedGIL; #endif /* PYTHONTHREADING_H_ */ diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h index 4ec5eaf81f0e..a508c7cd806e 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h @@ -14,7 +14,7 @@ */ template class CompositeEditorFactory : public QtAbstractEditorFactory { - typedef QtAbstractEditorFactory FactoryBaseType; + using FactoryBaseType = QtAbstractEditorFactory; public: CompositeEditorFactory(QObject *parent, FactoryBaseType *defaultFactory) diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h index b6bb2a21e303..0c1ad5d5c908 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h @@ -515,9 +515,9 @@ class EXPORT_OPT_MANTIDQT_COMMON QtFontEditorFactory template class EditorFactoryPrivate { public: - typedef QList EditorList; - typedef QMap PropertyToEditorListMap; - typedef QMap EditorToPropertyMap; + using EditorList = QList; + using PropertyToEditorListMap = QMap; + using EditorToPropertyMap = QMap; Editor *createEditor(QtProperty *property, QWidget *parent); void initializeEditor(QtProperty *property, Editor *e); diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h index d1992e797a69..f2208d878263 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h @@ -942,8 +942,8 @@ template static Value getData(const QMap &propertyMap, Value PrivateData::*data, const QtProperty *property, const Value &defaultValue = Value()) { - typedef QMap PropertyToData; - typedef typename PropertyToData::const_iterator PropertyToDataConstIterator; + using PropertyToData = QMap; + using PropertyToDataConstIterator = typename PropertyToData::const_iterator; const PropertyToDataConstIterator it = propertyMap.constFind(property); if (it == propertyMap.constEnd()) return defaultValue; @@ -980,8 +980,8 @@ static void setSimpleValue( void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter), QtProperty *property, const Value &val) { - typedef QMap PropertyToData; - typedef typename PropertyToData::iterator PropertyToDataIterator; + using PropertyToData = QMap; + using PropertyToDataIterator = typename PropertyToData::iterator; const PropertyToDataIterator it = propertyMap.find(property); if (it == propertyMap.end()) return; @@ -1005,9 +1005,9 @@ static void setValueInRange( QtProperty *property, const Value &val, void (PropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, ValueChangeParameter)) { - typedef typename PropertyManagerPrivate::Data PrivateData; - typedef QMap PropertyToData; - typedef typename PropertyToData::iterator PropertyToDataIterator; + using PrivateData = typename PropertyManagerPrivate::Data; + using PropertyToData = QMap; + using PropertyToDataIterator = typename PropertyToData::iterator; const PropertyToDataIterator it = managerPrivate->m_values.find(property); if (it == managerPrivate->m_values.end()) return; @@ -1046,9 +1046,9 @@ static void setBorderValues( ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) { - typedef typename PropertyManagerPrivate::Data PrivateData; - typedef QMap PropertyToData; - typedef typename PropertyToData::iterator PropertyToDataIterator; + using PrivateData = typename PropertyManagerPrivate::Data; + using PropertyToData = QMap; + using PropertyToDataIterator = typename PropertyToData::iterator; const PropertyToDataIterator it = managerPrivate->m_values.find(property); if (it == managerPrivate->m_values.end()) return; @@ -1097,8 +1097,8 @@ static void setBorderValue( ValueChangeParameter, ValueChangeParameter, ValueChangeParameter)) { - typedef QMap PropertyToData; - typedef typename PropertyToData::iterator PropertyToDataIterator; + using PropertyToData = QMap; + using PropertyToDataIterator = typename PropertyToData::iterator; const PropertyToDataIterator it = managerPrivate->m_values.find(property); if (it == managerPrivate->m_values.end()) return; @@ -1184,7 +1184,7 @@ class QtFontPropertyManagerPrivate { QStringList m_familyNames; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtIntPropertyManager *m_intPropertyManager; @@ -1224,7 +1224,7 @@ class QtFlagPropertyManagerPrivate { QStringList flagNames; }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtBoolPropertyManager *m_boolPropertyManager; @@ -1241,7 +1241,7 @@ class QtColorPropertyManagerPrivate { void slotIntChanged(QtProperty *property, int value); void slotPropertyDestroyed(QtProperty *property); - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtIntPropertyManager *m_intPropertyManager; @@ -1266,7 +1266,7 @@ class QtLocalePropertyManagerPrivate { void slotEnumChanged(QtProperty *property, int value); void slotPropertyDestroyed(QtProperty *property); - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtEnumPropertyManager *m_enumPropertyManager; @@ -1285,7 +1285,7 @@ class QtPointPropertyManagerPrivate { void slotIntChanged(QtProperty *property, int value); void slotPropertyDestroyed(QtProperty *property); - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtIntPropertyManager *m_intPropertyManager; @@ -1310,7 +1310,7 @@ class QtPointFPropertyManagerPrivate { void slotDoubleChanged(QtProperty *property, double value); void slotPropertyDestroyed(QtProperty *property); - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtDoublePropertyManager *m_doublePropertyManager; @@ -1338,7 +1338,7 @@ class QtRectFPropertyManagerPrivate { int decimals; }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtDoublePropertyManager *m_doublePropertyManager; @@ -1369,7 +1369,7 @@ class QtRectPropertyManagerPrivate { QRect constraint; }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtIntPropertyManager *m_intPropertyManager; @@ -1413,7 +1413,7 @@ class QtSizeFPropertyManagerPrivate { } }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtDoublePropertyManager *m_doublePropertyManager; @@ -1435,7 +1435,7 @@ class QtSizePolicyPropertyManagerPrivate { void slotEnumChanged(QtProperty *property, int value); void slotPropertyDestroyed(QtProperty *property); - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtIntPropertyManager *m_intPropertyManager; @@ -1479,7 +1479,7 @@ class QtSizePropertyManagerPrivate { } }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; QtIntPropertyManager *m_intPropertyManager; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h index 23334c1e56d3..1603eb634ea7 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h @@ -356,10 +356,10 @@ private slots: private: int indentation(const QModelIndex &index) const; - typedef QMap EditorToPropertyMap; + using EditorToPropertyMap = QMap; mutable EditorToPropertyMap m_editorToProperty; - typedef QMap PropertyToEditorMap; + using PropertyToEditorMap = QMap; mutable PropertyToEditorMap m_propertyToEditor; QtTreePropertyBrowserPrivate *m_editorPrivate; mutable QTreeWidgetItem *m_editedItem; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h index 823cfa3c95ae..761488c8ba7f 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtvariantproperty.h @@ -96,7 +96,7 @@ QT_BEGIN_NAMESPACE #endif -typedef QMap QtIconMap; +using QtIconMap = QMap; class QtVariantPropertyManager; class QtVariantPropertyPrivate; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h b/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h index a03d8c57b0d8..2d2b75b10282 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/SaveWorkspaces.h @@ -76,7 +76,7 @@ public slots: QString m_sampleThickness; QHash m_savFormats; - typedef QHash::const_iterator SavFormatsConstIt; + using SavFormatsConstIt = QHash::const_iterator; void setupLine1(QHBoxLayout *const lineOne); void setupLine2(QHBoxLayout *const lineTwo, diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h b/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h index cfedb31c1775..c1b5adfc1f7a 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h @@ -63,8 +63,7 @@ class EXPORT_OPT_MANTIDQT_COMMON SelectionNotificationServiceImpl SelectionNotificationServiceImpl>; }; -typedef Mantid::Kernel::SingletonHolder - SelectionNotificationService; +using SelectionNotificationService = Mantid::Kernel::SingletonHolder; } } namespace Mantid { diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h b/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h index da2a3699630e..df640d59287d 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/SlicingAlgorithmDialog.h @@ -14,7 +14,7 @@ namespace MantidQt { namespace MantidWidgets { -typedef QMap PropertyDimensionMap; +using PropertyDimensionMap = QMap; /* Class SlicingAlgorithmDialog diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h b/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h index 43914261b212..9fceb9b3b084 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h @@ -72,7 +72,7 @@ class DelegatingWebPage : public QWebEnginePage { /// a QHelpEngine. class EXPORT_OPT_MANTIDQT_COMMON pqHelpWindow : public QMainWindow { Q_OBJECT - typedef QMainWindow Superclass; + using Superclass = QMainWindow; public: pqHelpWindow(QHelpEngine *engine, QWidget *parent = 0, diff --git a/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp b/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp index 625f584e735c..7f6eed9a9970 100644 --- a/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp +++ b/qt/widgets/common/src/AlgorithmPropertiesWidget.cpp @@ -295,7 +295,7 @@ bool isCalledInputWorkspace(PropertyWidget *const candidate) { */ void AlgorithmPropertiesWidget::replaceWSClicked(const QString &propName) { if (m_propWidgets.contains(propName)) { - typedef std::vector CollectionOfPropertyWidget; + using CollectionOfPropertyWidget = std::vector; CollectionOfPropertyWidget candidateReplacementSources; PropertyWidget *propWidget = m_propWidgets[propName]; if (propWidget) { diff --git a/qt/widgets/common/src/AlgorithmSelectorWidget.cpp b/qt/widgets/common/src/AlgorithmSelectorWidget.cpp index d94dfbe5290f..465619911e41 100644 --- a/qt/widgets/common/src/AlgorithmSelectorWidget.cpp +++ b/qt/widgets/common/src/AlgorithmSelectorWidget.cpp @@ -269,7 +269,7 @@ void AlgorithmTreeWidget::mouseDoubleClickEvent(QMouseEvent *e) { void AlgorithmTreeWidget::update() { this->clear(); - typedef std::vector AlgNamesType; + using AlgNamesType = std::vector; AlgNamesType names = AlgorithmFactory::Instance().getDescriptors(); // sort by category/name/version to fill QTreeWidget diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp index 9dc93ffc64f2..18d98aa5fe6f 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp @@ -1172,12 +1172,8 @@ QtBrowserItem::~QtBrowserItem() { delete d_ptr; } //////////////////////////////////// -typedef QMap> - Map1; -typedef QMap>> Map2; +using Map1 = QMap >; +using Map2 = QMap > >; Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory) Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews) diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp index fc25dbddf2d3..7a3c69996970 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertymanager.cpp @@ -361,7 +361,7 @@ class QtIntPropertyManagerPrivate { } }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; @@ -638,7 +638,7 @@ class QtDoublePropertyManagerPrivate { } }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; @@ -969,7 +969,7 @@ class QtStringPropertyManagerPrivate { QRegExp regExp; }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; QMap m_values; }; @@ -1320,7 +1320,7 @@ class QtDatePropertyManagerPrivate { QString m_format; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; QMap m_values; }; @@ -1537,7 +1537,7 @@ class QtTimePropertyManagerPrivate { public: QString m_format; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; @@ -1646,7 +1646,7 @@ class QtDateTimePropertyManagerPrivate { public: QString m_format; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; @@ -1755,7 +1755,7 @@ class QtKeySequencePropertyManagerPrivate { public: QString m_format; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; @@ -1861,7 +1861,7 @@ class QtCharPropertyManagerPrivate { QtCharPropertyManager *q_ptr; Q_DECLARE_PUBLIC(QtCharPropertyManager) public: - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; @@ -4170,7 +4170,7 @@ class QtEnumPropertyManagerPrivate { QMap enumIcons; }; - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; @@ -5125,7 +5125,7 @@ void QtFontPropertyManagerPrivate::slotFontDatabaseChanged() { } void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange() { - typedef QMap PropertyPropertyMap; + using PropertyPropertyMap = QMap; // rescan available font names const QStringList oldFamilies = m_familyNames; m_familyNames = fontDatabase()->families(); @@ -5732,7 +5732,7 @@ class QtCursorPropertyManagerPrivate { QtCursorPropertyManager *q_ptr; Q_DECLARE_PUBLIC(QtCursorPropertyManager) public: - typedef QMap PropertyValueMap; + using PropertyValueMap = QMap; PropertyValueMap m_values; }; diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp index e732afdb2ee7..afcd20445505 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qtvariantproperty.cpp @@ -171,7 +171,7 @@ int QtVariantPropertyManager::iconMapTypeId() { return qMetaTypeId(); } -typedef QMap PropertyMap; +using PropertyMap = QMap; Q_GLOBAL_STATIC(PropertyMap, propertyToWrappedProperty) static QtProperty *wrappedProperty(QtProperty *property) { diff --git a/qt/widgets/common/src/SelectWorkspacesDialog.cpp b/qt/widgets/common/src/SelectWorkspacesDialog.cpp index 723c1fac9af3..02988668ed26 100644 --- a/qt/widgets/common/src/SelectWorkspacesDialog.cpp +++ b/qt/widgets/common/src/SelectWorkspacesDialog.cpp @@ -56,7 +56,7 @@ SelectWorkspacesDialog::SelectWorkspacesDialog( Mantid::API::AnalysisDataServiceImpl &ADS = Mantid::API::AnalysisDataService::Instance(); - typedef std::vector VecWorkspaces; + using VecWorkspaces = std::vector; VecWorkspaces workspaces = ADS.getObjects(); WorkspaceIsNotOfType comparitor(typeFilter); workspaces.erase( diff --git a/qt/widgets/common/src/pqHelpWindow.cxx b/qt/widgets/common/src/pqHelpWindow.cxx index 07f81f424fde..e84364deec18 100644 --- a/qt/widgets/common/src/pqHelpWindow.cxx +++ b/qt/widgets/common/src/pqHelpWindow.cxx @@ -58,7 +58,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /// Internal class used to add support to QWeb(Engine)View to load files from /// QHelpEngine. class pqHelpWindowNetworkReply : public QNetworkReply { - typedef QNetworkReply Superclass; + using Superclass = QNetworkReply; public: pqHelpWindowNetworkReply(const QUrl &url, QHelpEngineCore *helpEngine, @@ -139,7 +139,7 @@ qint64 pqHelpWindowNetworkReply::readData(char *data, qint64 maxSize) { // **************************************************************************** //----------------------------------------------------------------------------- class pqHelpWindow::pqNetworkAccessManager : public QNetworkAccessManager { - typedef QNetworkAccessManager Superclass; + using Superclass = QNetworkAccessManager; QPointer Engine; public: diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h index 2d38ea074650..50e4c840ab28 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/ProjectionSurface.h @@ -380,7 +380,7 @@ protected slots: mutable bool m_redrawPicking; }; -typedef boost::shared_ptr ProjectionSurface_sptr; +using ProjectionSurface_sptr = boost::shared_ptr; } // MantidWidgets } // MantidQt diff --git a/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp b/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp index 596a517fadb0..718bde630b71 100644 --- a/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp +++ b/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp @@ -40,8 +40,7 @@ class LiveDataAlgInputHistoryImpl : public AbstractAlgorithmInputHistory { template class Mantid::Kernel::SingletonHolder; #endif /* _WIN32 */ /// The specific instantiation of the templated type -typedef Mantid::Kernel::SingletonHolder - LiveDataAlgInputHistory; +using LiveDataAlgInputHistory = Mantid::Kernel::SingletonHolder; class LiveDataPostProcessingAlgInputHistoryImpl : public AbstractAlgorithmInputHistory { @@ -61,9 +60,7 @@ template class Mantid::Kernel::SingletonHolder< LiveDataPostProcessingAlgInputHistoryImpl>; #endif /* _WIN32 */ /// The specific instantiation of the templated type -typedef Mantid::Kernel::SingletonHolder< - LiveDataPostProcessingAlgInputHistoryImpl> - LiveDataPostProcessingAlgInputHistory; +using LiveDataPostProcessingAlgInputHistory = Mantid::Kernel::SingletonHolder; } // Add this class to the list of specialised dialogs in this namespace diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h index 3d0db9f5f3b0..27d4f1189751 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/CompositePeaksPresenter.h @@ -166,7 +166,7 @@ class EXPORT_OPT_MANTIDQT_SLICEVIEWER CompositePeaksPresenter boost::shared_ptr toWorkspace) override; /// Alias for container of subjects type. - typedef std::vector SubjectContainer; + using SubjectContainer = std::vector; /// Subject presenters. SubjectContainer m_subjects; /// Use default diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h index 2f2fd9eaaca7..273a122d19af 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h @@ -14,7 +14,7 @@ namespace MantidQt { namespace SliceViewer { /// Alias for Vector of Peak Overlay Views -typedef std::vector> VecPeakOverlayView; +using VecPeakOverlayView = std::vector >; /// Coordinate System Enum to String. std::string DLLExport diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h index 16d4323e9a5f..b57cf4b2ff05 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakBoundingBox.h @@ -29,13 +29,13 @@ template class EXPORT_OPT_MANTIDQT_SLICEVIEWER DoubleParam { enum { typeValue = I }; }; -typedef DoubleParam<0> Left; -typedef DoubleParam<1> Right; -typedef DoubleParam<2> Top; -typedef DoubleParam<3> Bottom; -typedef DoubleParam<4> SlicePoint; -typedef DoubleParam<5> Front; -typedef DoubleParam<6> Back; +using Left = DoubleParam<0>; +using Right = DoubleParam<1>; +using Top = DoubleParam<2>; +using Bottom = DoubleParam<3>; +using SlicePoint = DoubleParam<4>; +using Front = DoubleParam<5>; +using Back = DoubleParam<6>; /** A bounding box for a peak. Allows the SliceViewer to zoom to that region. diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h index 848740645bc9..c287fb7e5fb6 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayView.h @@ -91,8 +91,8 @@ class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakOverlayView { virtual ~PeakOverlayView() {} }; -typedef boost::shared_ptr PeakOverlayView_const_sptr; -typedef boost::shared_ptr PeakOverlayView_sptr; +using PeakOverlayView_const_sptr = boost::shared_ptr; +using PeakOverlayView_sptr = boost::shared_ptr; } } diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h index 5b5eabd18d01..d6b453339180 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakOverlayViewFactory.h @@ -64,7 +64,7 @@ class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakOverlayViewFactory { }; /// Factory Shared Pointer typedef. -typedef boost::shared_ptr PeakOverlayViewFactory_sptr; +using PeakOverlayViewFactory_sptr = boost::shared_ptr; } } diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h index 5bbbbcfa111d..d126155960e4 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakPalette.h @@ -26,7 +26,7 @@ template class DLLExport PeakPalette { ~PeakPalette(); private: - typedef std::map ColourMapType; + using ColourMapType = std::map; ColourMapType m_backgroundMap; ColourMapType m_foregroundMap; typename ColourMapType::iterator safeFetchPair(ColourMapType &map, diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h index ffc350bdb1b1..91c44dce7d15 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeakRepresentation.h @@ -22,7 +22,7 @@ struct EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakRepresentationViewInformation { class PeakBoundingBox; /// Alisas for a boost optional double. -typedef boost::optional optional_double; +using optional_double = boost::optional; /** PeakRepresentation : Allows the draw a general visual peak shape. @@ -82,8 +82,8 @@ class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeakRepresentation { PeakRepresentationViewInformation viewInformation) = 0; }; -typedef std::shared_ptr PeakRepresentation_sptr; -typedef std::vector VecPeakRepresentation; +using PeakRepresentation_sptr = std::shared_ptr; +using VecPeakRepresentation = std::vector; } } diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h index 182073415b33..ecb866c7734b 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h @@ -35,8 +35,7 @@ class PeakOverlayView; class UpdateableOnDemand; // Alias -typedef std::set> - SetPeaksWorkspaces; +using SetPeaksWorkspaces = std::set >; /*--------------------------------------------------------- Abstract PeaksPresenter. @@ -79,8 +78,8 @@ class EXPORT_OPT_MANTIDQT_SLICEVIEWER PeaksPresenter : public QObject { ~PeaksPresenter() override{}; }; -typedef boost::shared_ptr PeaksPresenter_sptr; -typedef boost::shared_ptr PeaksPresenter_const_sptr; +using PeaksPresenter_sptr = boost::shared_ptr; +using PeaksPresenter_const_sptr = boost::shared_ptr; } } diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h index 246d2bf018b8..d294d2cb3681 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h @@ -70,10 +70,10 @@ class EXPORT_OPT_MANTIDQT_SLICEVIEWER QPeaksTableModel void peaksSorted(const std::string &, const bool); private: - typedef QString ColumnNameType; - typedef QString ColumnValueType; - typedef std::map ColumnNameSortableMap; - typedef std::map ColumnIndexNameMap; + using ColumnNameType = QString; + using ColumnValueType = QString; + using ColumnNameSortableMap = std::map; + using ColumnIndexNameMap = std::map; public: /// Label for run number column diff --git a/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h b/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h index 6988b6df9438..3fee2f048849 100644 --- a/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h +++ b/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h @@ -26,12 +26,11 @@ using namespace testing; using boost::regex; // Alias. -typedef boost::shared_ptr MDGeometry_sptr; +using MDGeometry_sptr = boost::shared_ptr; class ConcretePeaksPresenterTest : public CxxTest::TestSuite { /// Alias. - typedef boost::shared_ptr - ConcretePeaksPresenter_sptr; + using ConcretePeaksPresenter_sptr = boost::shared_ptr; /// Helper method to create a good 'Integrated' peaks workspace Mantid::API::IPeaksWorkspace_sptr diff --git a/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h b/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h index 2859d9b72033..9bb481526a66 100644 --- a/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h +++ b/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h @@ -182,11 +182,9 @@ class PeakRepresentationCrossTest : public CxxTest::TestSuite { class PeakRepresentationCrossTestPerformance : public CxxTest::TestSuite { private: - typedef std::vector> - VecPeakRepCross; + using VecPeakRepCross = std::vector >; - typedef std::vector> VecPeakRepCrossWrapped; + using VecPeakRepCrossWrapped = std::vector >; /// Collection to store a large number of PeakRepresentationCross. VecPeakRepCross m_peaks; diff --git a/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h b/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h index 487b38031335..ad8be837c9ce 100644 --- a/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h +++ b/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h @@ -316,10 +316,8 @@ class PeakRepresentationSphereTestPerformance : public CxxTest::TestSuite { } private: - typedef boost::shared_ptr - PeaksRepresentationSphere_sptr; - typedef std::vector - VecPeaksRepresentationSphere; + using PeaksRepresentationSphere_sptr = boost::shared_ptr; + using VecPeaksRepresentationSphere = std::vector; /// Collection to store a large number of physicalPeaks. VecPeaksRepresentationSphere m_peaks; diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h index 88cd8aad3aea..598c5a874475 100644 --- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h +++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/ArrayDataSource.h @@ -67,8 +67,8 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER ArrayDataSource std::vector m_data; }; -typedef boost::shared_ptr ArrayDataSource_sptr; -typedef boost::shared_ptr ArrayDataSource_const_sptr; +using ArrayDataSource_sptr = boost::shared_ptr; +using ArrayDataSource_const_sptr = boost::shared_ptr; } // namespace SpectrumView } // namespace MantidQt diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h index 16a654936831..0b8af1ded382 100644 --- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h +++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/DataArray.h @@ -124,8 +124,8 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER DataArray { std::vector m_data; }; -typedef boost::shared_ptr DataArray_sptr; -typedef boost::shared_ptr DataArray_const_sptr; +using DataArray_sptr = boost::shared_ptr; +using DataArray_const_sptr = boost::shared_ptr; } // namespace SpectrumView } // namespace MantidQt diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h index fb3c7c88f7d4..390f92a2041e 100644 --- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h +++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h @@ -103,9 +103,8 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER MatrixWSDataSource const Mantid::API::SpectrumInfo &m_spectrumInfo; }; -typedef boost::shared_ptr MatrixWSDataSource_sptr; -typedef boost::shared_ptr - MatrixWSDataSource_const_sptr; +using MatrixWSDataSource_sptr = boost::shared_ptr; +using MatrixWSDataSource_const_sptr = boost::shared_ptr; } // namespace SpectrumView } // namespace MantidQt diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h index 70cab21712a3..d78b385e57d2 100644 --- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h +++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h @@ -106,9 +106,8 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumDataSource { size_t m_totalCols; }; -typedef boost::shared_ptr SpectrumDataSource_sptr; -typedef boost::shared_ptr - SpectrumDataSource_const_sptr; +using SpectrumDataSource_sptr = boost::shared_ptr; +using SpectrumDataSource_const_sptr = boost::shared_ptr; } // namespace SpectrumView } // namespace MantidQt From 1d879cf35d944a4576c0e53a5b5ced8632ee42ae Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 11:17:37 +0000 Subject: [PATCH 233/364] Re #22048: Applied clang-format patch. --- Framework/API/inc/MantidAPI/Algorithm.h | 2 +- .../API/inc/MantidAPI/AlgorithmFactory.h | 6 +- .../API/inc/MantidAPI/AlgorithmHistory.h | 3 +- .../API/inc/MantidAPI/AnalysisDataService.h | 87 ++++++++++++------- .../API/inc/MantidAPI/ArchiveSearchFactory.h | 3 +- .../API/inc/MantidAPI/ConstraintFactory.h | 3 +- .../API/inc/MantidAPI/CostFunctionFactory.h | 3 +- .../API/inc/MantidAPI/DomainCreatorFactory.h | 3 +- .../API/inc/MantidAPI/FileLoaderRegistry.h | 3 +- .../API/inc/MantidAPI/FuncMinimizerFactory.h | 3 +- Framework/API/inc/MantidAPI/FunctionFactory.h | 6 +- .../MantidAPI/FunctionParameterDecorator.h | 3 +- .../API/inc/MantidAPI/ISplittersWorkspace.h | 3 +- .../inc/MantidAPI/ImplicitFunctionFactory.h | 3 +- .../ImplicitFunctionParameterParser.h | 4 +- .../ImplicitFunctionParameterParserFactory.h | 3 +- .../inc/MantidAPI/ImplicitFunctionParser.h | 4 +- .../MantidAPI/ImplicitFunctionParserFactory.h | 3 +- .../API/inc/MantidAPI/InstrumentDataService.h | 3 +- Framework/API/inc/MantidAPI/MatrixWorkspace.h | 2 +- .../inc/MantidAPI/MultipleExperimentInfos.h | 3 +- .../inc/MantidAPI/RemoteJobManagerFactory.h | 3 +- .../inc/MantidAPI/ScriptRepositoryFactory.h | 3 +- .../API/inc/MantidAPI/SpectraDetectorTypes.h | 2 +- .../inc/MantidAPI/SpectrumDetectorMapping.h | 2 +- .../API/inc/MantidAPI/TransformScaleFactory.h | 3 +- .../MantidAPI/WorkspaceNearestNeighbours.h | 5 +- Framework/API/src/MultiPeriodGroupWorker.cpp | 2 +- Framework/API/test/FermiChopperModelTest.h | 3 +- .../API/test/IkedaCarpenterModeratorTest.h | 3 +- .../API/test/VectorParameterParserTest.h | 9 +- .../inc/MantidCrystal/ClusterRegister.h | 2 +- .../ConnectedComponentLabeling.h | 6 +- .../Crystal/inc/MantidCrystal/FilterPeaks.h | 2 +- .../inc/MantidCrystal/SetSpecialCoordinates.h | 3 +- Framework/Crystal/src/ClusterRegister.cpp | 2 +- Framework/Crystal/src/SaveHKL.cpp | 2 +- Framework/Crystal/src/SaveIsawPeaks.cpp | 2 +- Framework/Crystal/test/CentroidPeaksTest.h | 3 +- .../Crystal/test/ClusterIntegrationBaseTest.h | 6 +- .../Crystal/test/IntegratePeaksHybridTest.h | 3 +- .../Crystal/test/NormaliseVanadiumTest.h | 3 +- Framework/Crystal/test/PeakIntegrationTest.h | 3 +- Framework/Crystal/test/PeaksInRegionTest.h | 3 +- .../AugmentedLagrangianOptimizer.h | 2 +- .../inc/MantidCurveFitting/FortranDefs.h | 2 +- .../inc/MantidCurveFitting/FortranMatrix.h | 3 +- .../Functions/ChebfunBase.h | 2 +- .../Functions/ThermalNeutronBk2BkExpAlpha.h | 3 +- .../Functions/ThermalNeutronBk2BkExpBeta.h | 3 +- .../ThermalNeutronBk2BkExpConvPVoigt.h | 3 +- .../Functions/ThermalNeutronBk2BkExpSigma.h | 3 +- .../Functions/ThermalNeutronDtoTOFFunction.h | 3 +- .../CurveFitting/src/MSVesuvioHelpers.cpp | 6 +- .../CurveFitting/src/ParameterEstimator.cpp | 2 +- .../CurveFitting/test/FortranVectorTest.h | 2 +- .../inc/MantidDataHandling/GroupDetectors2.h | 2 +- .../inc/MantidDataHandling/LoadSNSspec.h | 3 +- .../inc/MantidDataHandling/LoadSpec.h | 3 +- .../src/CreateSimulationWorkspace.cpp | 2 +- .../DataHandling/src/GroupDetectors2.cpp | 4 +- .../DataHandling/src/LoadRaw/item_struct.h | 5 +- Framework/DataHandling/test/SaveNXSPETest.h | 4 +- .../CoordTransformAffineParser.h | 3 +- .../DataObjects/inc/MantidDataObjects/MDBox.h | 2 +- .../inc/MantidDataObjects/MDBoxBase.h | 2 +- .../inc/MantidDataObjects/MDEventFactory.h | 9 +- .../inc/MantidDataObjects/MDEventWorkspace.h | 2 +- .../inc/MantidDataObjects/MDGridBox.h | 2 +- .../MDHistoWorkspaceIterator.h | 5 +- .../MantidDataObjects/PeakShapeEllipsoid.h | 3 +- .../MantidDataObjects/SpecialWorkspace2D.h | 3 +- .../MantidDataObjects/SplittersWorkspace.h | 3 +- .../inc/MantidDataObjects/TableColumn.h | 8 +- .../inc/MantidDataObjects/TableWorkspace.h | 8 +- .../MantidDataObjects/WorkspaceSingleValue.h | 3 +- .../src/CoordTransformAffineParser.cpp | 6 +- .../src/CoordTransformDistanceParser.cpp | 12 ++- Framework/DataObjects/src/FakeMD.cpp | 6 +- Framework/DataObjects/src/MDBoxFlatTree.cpp | 2 +- Framework/DataObjects/test/MDBoxTest.h | 3 +- .../Crystal/BraggScattererFactory.h | 3 +- .../BraggScattererInCrystalStructure.h | 3 +- .../MantidGeometry/Crystal/CenteringGroup.h | 3 +- .../Crystal/IsotropicAtomBraggScatterer.h | 6 +- .../Crystal/PeakTransformQLab.h | 3 +- .../Crystal/PeakTransformQSample.h | 3 +- .../inc/MantidGeometry/Crystal/PointGroup.h | 4 +- .../Crystal/PointGroupFactory.h | 3 +- .../Crystal/SpaceGroupFactory.h | 6 +- .../Crystal/StructureFactorCalculator.h | 3 +- .../StructureFactorCalculatorSummation.h | 3 +- .../MantidGeometry/Crystal/SymmetryElement.h | 6 +- .../Crystal/SymmetryElementFactory.h | 6 +- .../Crystal/SymmetryOperationFactory.h | 3 +- .../Geometry/inc/MantidGeometry/IDetector.h | 3 +- .../Geometry/inc/MantidGeometry/Instrument.h | 4 +- .../MantidGeometry/Instrument/CompAssembly.h | 3 +- .../Instrument/ObjCompAssembly.h | 3 +- .../Instrument/ParameterFactory.h | 2 +- .../MantidGeometry/Instrument/ParameterMap.h | 16 ++-- .../Instrument/RectangularDetector.h | 3 +- .../Instrument/StructuredDetector.h | 3 +- .../MDGeometry/CompositeImplicitFunction.h | 3 +- .../MantidGeometry/Surfaces/SurfaceFactory.h | 7 +- .../src/Instrument/XMLInstrumentParameter.cpp | 3 +- Framework/Geometry/test/CSGObjectTest.h | 2 +- Framework/Geometry/test/ParameterMapTest.h | 4 +- .../ICat/inc/MantidICat/GSoap/stdsoap2.h | 3 +- Framework/Kernel/inc/MantidKernel/ANN/ANN.h | 4 +- Framework/Kernel/inc/MantidKernel/Cache.h | 3 +- .../Kernel/inc/MantidKernel/ConfigService.h | 6 +- .../Kernel/inc/MantidKernel/DataService.h | 3 +- .../Kernel/inc/MantidKernel/DiskBuffer.h | 9 +- .../Kernel/inc/MantidKernel/FacilityInfo.h | 3 +- .../Kernel/inc/MantidKernel/InstrumentInfo.h | 2 +- Framework/Kernel/inc/MantidKernel/MRUList.h | 10 ++- .../inc/MantidKernel/NearestNeighbours.h | 3 +- .../Kernel/inc/MantidKernel/PropertyManager.h | 2 +- .../MantidKernel/PropertyManagerDataService.h | 3 +- Framework/Kernel/inc/MantidKernel/Unit.h | 6 +- Framework/Kernel/src/ANN/kd_tree.h | 4 +- Framework/Kernel/src/ANN/pr_queue.h | 2 +- Framework/Kernel/src/MaterialXMLParser.cpp | 3 +- .../Kernel/test/MultiFileNameParserTest.h | 2 +- .../MantidLiveData/SNSLiveEventDataListener.h | 6 +- .../MantidMDAlgorithms/Integrate3DEvents.h | 4 +- .../inc/MantidMDAlgorithms/LoadSQW2.h | 3 +- .../inc/MantidMDAlgorithms/MDEventWSWrapper.h | 3 +- .../Quantification/ForegroundModelFactory.h | 3 +- .../MDResolutionConvolutionFactory.h | 3 +- .../SimulateResolutionConvolvedModel.h | 3 +- Framework/MDAlgorithms/src/MDNormDirectSC.cpp | 2 +- Framework/MDAlgorithms/src/MDNormSCD.cpp | 2 +- Framework/MDAlgorithms/src/SaveMD.cpp | 2 +- Framework/MDAlgorithms/src/SaveMD2.cpp | 2 +- Framework/MDAlgorithms/src/SmoothMD.cpp | 7 +- .../kernel/Policies/AsType.h | 6 +- .../kernel/Policies/MatrixToNumpy.h | 14 ++- .../kernel/Policies/RemoveConst.h | 12 ++- .../kernel/Policies/ToWeakPtr.h | 4 +- .../kernel/Policies/VectorToNumpy.h | 14 ++- .../mantid/api/src/CloneMatrixWorkspace.cpp | 3 +- .../mantid/api/src/Exports/Algorithm.cpp | 19 +++- .../api/src/Exports/AnalysisDataService.cpp | 3 +- .../api/src/Exports/BinaryOperations.cpp | 38 +++++--- .../api/src/Exports/CompositeFunction.cpp | 6 +- .../mantid/api/src/Exports/IFunction.cpp | 3 +- .../api/src/Exports/MatrixWorkspace.cpp | 9 +- .../api/src/Exports/MultipleFileProperty.cpp | 2 +- .../api/src/Exports/WorkspaceFactory.cpp | 4 +- .../geometry/src/Exports/Goniometer.cpp | 3 +- .../geometry/src/Exports/OrientedLattice.cpp | 3 +- .../mantid/geometry/src/Exports/UnitCell.cpp | 3 +- .../kernel/src/Exports/ArrayProperty.cpp | 3 +- .../Exports/PropertyManagerDataService.cpp | 3 +- .../mantid/kernel/src/Exports/Statistics.cpp | 4 +- .../kernel/src/Exports/UnitConversion.cpp | 4 +- .../src/Registry/PropertyWithValueFactory.cpp | 14 +-- .../kernel/src/Registry/TypeRegistry.cpp | 3 +- .../WorkspaceCreationHelperModule.cpp | 3 +- .../PoldiUtilities/PoldiInstrumentAdapter.h | 3 +- .../PoldiUtilities/PoldiSourceSpectrum.h | 3 +- .../PoldiUtilities/PoldiTimeTransformer.h | 3 +- 164 files changed, 522 insertions(+), 253 deletions(-) diff --git a/Framework/API/inc/MantidAPI/Algorithm.h b/Framework/API/inc/MantidAPI/Algorithm.h index 4b7c6a50b85a..8115702290f4 100644 --- a/Framework/API/inc/MantidAPI/Algorithm.h +++ b/Framework/API/inc/MantidAPI/Algorithm.h @@ -301,7 +301,7 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, /// parent object to fill. void trackAlgorithmHistory(boost::shared_ptr parentHist); - using WorkspaceVector = std::vector >; + using WorkspaceVector = std::vector>; void findWorkspaceProperties(WorkspaceVector &inputWorkspaces, WorkspaceVector &outputWorkspaces) const; diff --git a/Framework/API/inc/MantidAPI/AlgorithmFactory.h b/Framework/API/inc/MantidAPI/AlgorithmFactory.h index f5b04a3a072e..49ed56890b29 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmFactory.h +++ b/Framework/API/inc/MantidAPI/AlgorithmFactory.h @@ -171,8 +171,10 @@ class MANTID_API_DLL AlgorithmFactoryImpl final using AlgorithmFactory = Mantid::Kernel::SingletonHolder; /// Convenient typedef for an UpdateNotification -using AlgorithmFactoryUpdateNotification = Mantid::Kernel::DynamicFactory::UpdateNotification; -using AlgorithmFactoryUpdateNotification_ptr = const Poco::AutoPtr::UpdateNotification> &; +using AlgorithmFactoryUpdateNotification = + Mantid::Kernel::DynamicFactory::UpdateNotification; +using AlgorithmFactoryUpdateNotification_ptr = const Poco::AutoPtr< + Mantid::Kernel::DynamicFactory::UpdateNotification> &; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/AlgorithmHistory.h b/Framework/API/inc/MantidAPI/AlgorithmHistory.h index b4275f302487..4485f149f636 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmHistory.h +++ b/Framework/API/inc/MantidAPI/AlgorithmHistory.h @@ -36,7 +36,8 @@ template struct CompareHistory { // typedefs for algorithm history pointers using AlgorithmHistory_sptr = boost::shared_ptr; using AlgorithmHistory_const_sptr = boost::shared_ptr; -using AlgorithmHistories = std::set >; +using AlgorithmHistories = + std::set>; /** @class AlgorithmHistory AlgorithmHistory.h API/MAntidAPI/AlgorithmHistory.h diff --git a/Framework/API/inc/MantidAPI/AnalysisDataService.h b/Framework/API/inc/MantidAPI/AnalysisDataService.h index b8249697f377..81847922571f 100644 --- a/Framework/API/inc/MantidAPI/AnalysisDataService.h +++ b/Framework/API/inc/MantidAPI/AnalysisDataService.h @@ -178,37 +178,62 @@ class DLLExport AnalysisDataServiceImpl final std::string m_illegalChars; }; -using AnalysisDataService = Mantid::Kernel::SingletonHolder; - -using WorkspaceAddNotification = Mantid::Kernel::DataService::AddNotification; -using WorkspaceAddNotification_ptr = const Poco::AutoPtr::AddNotification> &; - -using WorkspaceBeforeReplaceNotification = Mantid::Kernel::DataService::BeforeReplaceNotification; -using WorkspaceBeforeReplaceNotification_ptr = const Poco::AutoPtr::BeforeReplaceNotification> &; - -using WorkspaceAfterReplaceNotification = Mantid::Kernel::DataService::AfterReplaceNotification; -using WorkspaceAfterReplaceNotification_ptr = const Poco::AutoPtr::AfterReplaceNotification> &; - -using WorkspacePreDeleteNotification = Mantid::Kernel::DataService::PreDeleteNotification; -using WorkspacePreDeleteNotification_ptr = const Poco::AutoPtr::PreDeleteNotification> &; - -using WorkspacePostDeleteNotification = Mantid::Kernel::DataService::PostDeleteNotification; -using WorkspacePostDeleteNotification_ptr = const Poco::AutoPtr::PostDeleteNotification> &; - -using ClearADSNotification = Mantid::Kernel::DataService::ClearNotification; -using ClearADSNotification_ptr = const Poco::AutoPtr::ClearNotification> &; - -using WorkspaceRenameNotification = Mantid::Kernel::DataService::RenameNotification; -using WorkspaceRenameNotification_ptr = const Poco::AutoPtr::RenameNotification> &; - -using WorkspacesGroupedNotification = AnalysisDataServiceImpl::GroupWorkspacesNotification; -using WorkspacesGroupedNotification_ptr = const Poco::AutoPtr &; - -using WorkspaceUnGroupingNotification = AnalysisDataServiceImpl::UnGroupingWorkspaceNotification; -using WorkspaceUnGroupingNotification_ptr = const Poco::AutoPtr &; - -using GroupUpdatedNotification = AnalysisDataServiceImpl::GroupUpdatedNotification; -using GroupUpdatedNotification_ptr = const Poco::AutoPtr &; +using AnalysisDataService = + Mantid::Kernel::SingletonHolder; + +using WorkspaceAddNotification = + Mantid::Kernel::DataService::AddNotification; +using WorkspaceAddNotification_ptr = const Poco::AutoPtr< + Mantid::Kernel::DataService::AddNotification> &; + +using WorkspaceBeforeReplaceNotification = Mantid::Kernel::DataService< + Mantid::API::Workspace>::BeforeReplaceNotification; +using WorkspaceBeforeReplaceNotification_ptr = + const Poco::AutoPtr::BeforeReplaceNotification> &; + +using WorkspaceAfterReplaceNotification = Mantid::Kernel::DataService< + Mantid::API::Workspace>::AfterReplaceNotification; +using WorkspaceAfterReplaceNotification_ptr = + const Poco::AutoPtr::AfterReplaceNotification> &; + +using WorkspacePreDeleteNotification = + Mantid::Kernel::DataService::PreDeleteNotification; +using WorkspacePreDeleteNotification_ptr = + const Poco::AutoPtr::PreDeleteNotification> &; + +using WorkspacePostDeleteNotification = + Mantid::Kernel::DataService::PostDeleteNotification; +using WorkspacePostDeleteNotification_ptr = + const Poco::AutoPtr::PostDeleteNotification> &; + +using ClearADSNotification = + Mantid::Kernel::DataService::ClearNotification; +using ClearADSNotification_ptr = const Poco::AutoPtr< + Mantid::Kernel::DataService::ClearNotification> &; + +using WorkspaceRenameNotification = + Mantid::Kernel::DataService::RenameNotification; +using WorkspaceRenameNotification_ptr = const Poco::AutoPtr< + Mantid::Kernel::DataService::RenameNotification> &; + +using WorkspacesGroupedNotification = + AnalysisDataServiceImpl::GroupWorkspacesNotification; +using WorkspacesGroupedNotification_ptr = + const Poco::AutoPtr &; + +using WorkspaceUnGroupingNotification = + AnalysisDataServiceImpl::UnGroupingWorkspaceNotification; +using WorkspaceUnGroupingNotification_ptr = const Poco::AutoPtr< + AnalysisDataServiceImpl::UnGroupingWorkspaceNotification> &; + +using GroupUpdatedNotification = + AnalysisDataServiceImpl::GroupUpdatedNotification; +using GroupUpdatedNotification_ptr = + const Poco::AutoPtr &; } // Namespace API } // Namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h b/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h index b3b4d06a6ada..ff983a5556c8 100644 --- a/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h +++ b/Framework/API/inc/MantidAPI/ArchiveSearchFactory.h @@ -56,7 +56,8 @@ class MANTID_API_DLL ArchiveSearchFactoryImpl ~ArchiveSearchFactoryImpl() override = default; }; -using ArchiveSearchFactory = Mantid::Kernel::SingletonHolder; +using ArchiveSearchFactory = + Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/ConstraintFactory.h b/Framework/API/inc/MantidAPI/ConstraintFactory.h index 3a738805e232..1b4102898280 100644 --- a/Framework/API/inc/MantidAPI/ConstraintFactory.h +++ b/Framework/API/inc/MantidAPI/ConstraintFactory.h @@ -72,7 +72,8 @@ class MANTID_API_DLL ConstraintFactoryImpl final ~ConstraintFactoryImpl() override = default; }; -using ConstraintFactory = Mantid::Kernel::SingletonHolder; +using ConstraintFactory = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/CostFunctionFactory.h b/Framework/API/inc/MantidAPI/CostFunctionFactory.h index 68b367c1fc26..c03230c26d0c 100644 --- a/Framework/API/inc/MantidAPI/CostFunctionFactory.h +++ b/Framework/API/inc/MantidAPI/CostFunctionFactory.h @@ -63,7 +63,8 @@ class MANTID_API_DLL CostFunctionFactoryImpl CostFunctionFactoryImpl(); }; -using CostFunctionFactory = Mantid::Kernel::SingletonHolder; +using CostFunctionFactory = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/DomainCreatorFactory.h b/Framework/API/inc/MantidAPI/DomainCreatorFactory.h index 90f667d54a6e..a8c9c4448bcd 100644 --- a/Framework/API/inc/MantidAPI/DomainCreatorFactory.h +++ b/Framework/API/inc/MantidAPI/DomainCreatorFactory.h @@ -73,7 +73,8 @@ class MANTID_API_DLL DomainCreatorFactoryImpl using Kernel::DynamicFactory::createUnwrapped; }; -using DomainCreatorFactory = Mantid::Kernel::SingletonHolder; +using DomainCreatorFactory = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FileLoaderRegistry.h b/Framework/API/inc/MantidAPI/FileLoaderRegistry.h index 0b6e1484a39c..38cebdea4154 100644 --- a/Framework/API/inc/MantidAPI/FileLoaderRegistry.h +++ b/Framework/API/inc/MantidAPI/FileLoaderRegistry.h @@ -144,7 +144,8 @@ class MANTID_API_DLL FileLoaderRegistryImpl { }; /// Type for the actual singleton instance -using FileLoaderRegistry = Mantid::Kernel::SingletonHolder; +using FileLoaderRegistry = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h b/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h index 576287f6417d..79212a1a391a 100644 --- a/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h +++ b/Framework/API/inc/MantidAPI/FuncMinimizerFactory.h @@ -61,7 +61,8 @@ class MANTID_API_DLL FuncMinimizerFactoryImpl FuncMinimizerFactoryImpl(); }; -using FuncMinimizerFactory = Mantid::Kernel::SingletonHolder; +using FuncMinimizerFactory = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FunctionFactory.h b/Framework/API/inc/MantidAPI/FunctionFactory.h index 1e6aa7e0d414..1f88005af127 100644 --- a/Framework/API/inc/MantidAPI/FunctionFactory.h +++ b/Framework/API/inc/MantidAPI/FunctionFactory.h @@ -145,9 +145,11 @@ const std::vector &FunctionFactoryImpl::getFunctionNames() const { using FunctionFactory = Mantid::Kernel::SingletonHolder; /// Convenient typedef for an UpdateNotification -using FunctionFactoryUpdateNotification = FunctionFactoryImpl::UpdateNotification; +using FunctionFactoryUpdateNotification = + FunctionFactoryImpl::UpdateNotification; /// Convenient typedef for an UpdateNotification AutoPtr -using FunctionFactoryUpdateNotification_ptr = const Poco::AutoPtr &; +using FunctionFactoryUpdateNotification_ptr = + const Poco::AutoPtr &; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h b/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h index fce242505cc2..0b24a04663ed 100644 --- a/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h +++ b/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h @@ -150,7 +150,8 @@ class MANTID_API_DLL FunctionParameterDecorator : virtual public IFunction { IFunction_sptr m_wrappedFunction; }; -using FunctionParameterDecorator_sptr = boost::shared_ptr; +using FunctionParameterDecorator_sptr = + boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ISplittersWorkspace.h b/Framework/API/inc/MantidAPI/ISplittersWorkspace.h index 495bf221eaff..95fcecee9f7e 100644 --- a/Framework/API/inc/MantidAPI/ISplittersWorkspace.h +++ b/Framework/API/inc/MantidAPI/ISplittersWorkspace.h @@ -82,7 +82,8 @@ class MANTID_API_DLL ISplittersWorkspace { /// Typedef for a shared pointer to \c TableWorkspace using ISplittersWorkspace_sptr = boost::shared_ptr; /// Typedef for a shared pointer to \c const \c TableWorkspace -using ISplittersWorkspace_const_sptr = boost::shared_ptr; +using ISplittersWorkspace_const_sptr = + boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h index c8cedde1fe21..69c2261c0063 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionFactory.h @@ -64,7 +64,8 @@ class MANTID_API_DLL ImplicitFunctionFactoryImpl ~ImplicitFunctionFactoryImpl() override = default; }; -using ImplicitFunctionFactory = Mantid::Kernel::SingletonHolder; +using ImplicitFunctionFactory = + Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h index 234c5a8b1df5..a769902c6477 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParser.h @@ -81,7 +81,9 @@ class MANTID_API_DLL ImplicitFunctionParameterParser { public: /// Successor type. Unique shared pointer with stack scoped deletion /// semantics. - using SuccessorType = boost::interprocess::unique_ptr >; + using SuccessorType = boost::interprocess::unique_ptr< + ImplicitFunctionParameterParser, + DeleterPolicy>; virtual ImplicitFunctionParameter * createParameter(Poco::XML::Element *parameterElement) = 0; diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h index 6196d30601da..7bf1cfd831dd 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParameterParserFactory.h @@ -62,7 +62,8 @@ class MANTID_API_DLL ImplicitFunctionParameterParserFactoryImpl ~ImplicitFunctionParameterParserFactoryImpl() override = default; }; -using ImplicitFunctionParameterParserFactory = Mantid::Kernel::SingletonHolder; +using ImplicitFunctionParameterParserFactory = + Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h index 4d0cf8e78922..4ad8da99e9b7 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParser.h @@ -68,7 +68,9 @@ namespace API { class MANTID_API_DLL ImplicitFunctionParser { public: /// Successor type. Unique pointer with stack scoped deletion semantics. - using SuccessorType = boost::interprocess::unique_ptr >; + using SuccessorType = + boost::interprocess::unique_ptr>; protected: ImplicitFunctionParameterParser::SuccessorType diff --git a/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h b/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h index 47b11ede7636..38219e7c9cd2 100644 --- a/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h +++ b/Framework/API/inc/MantidAPI/ImplicitFunctionParserFactory.h @@ -66,7 +66,8 @@ class MANTID_API_DLL ImplicitFunctionParserFactoryImpl ~ImplicitFunctionParserFactoryImpl() override = default; }; -using ImplicitFunctionParserFactory = Mantid::Kernel::SingletonHolder; +using ImplicitFunctionParserFactory = + Mantid::Kernel::SingletonHolder; } } diff --git a/Framework/API/inc/MantidAPI/InstrumentDataService.h b/Framework/API/inc/MantidAPI/InstrumentDataService.h index 620e4ae2bd03..f5d22334a71c 100644 --- a/Framework/API/inc/MantidAPI/InstrumentDataService.h +++ b/Framework/API/inc/MantidAPI/InstrumentDataService.h @@ -48,7 +48,8 @@ class MANTID_API_DLL InstrumentDataServiceImpl operator=(const InstrumentDataServiceImpl &) = delete; }; -using InstrumentDataService = Mantid::Kernel::SingletonHolder; +using InstrumentDataService = + Mantid::Kernel::SingletonHolder; } // Namespace API } // Namespace Mantid diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h index 88a722256f8d..ad3657c215dd 100644 --- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h +++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h @@ -32,7 +32,7 @@ class Axis; class SpectrumDetectorMapping; /// typedef for the image type -using MantidImage = std::vector >; +using MantidImage = std::vector>; /// shared pointer to MantidImage using MantidImage_sptr = boost::shared_ptr; /// shared pointer to const MantidImage diff --git a/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h b/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h index e9f73c150481..a1eedc145f1e 100644 --- a/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h +++ b/Framework/API/inc/MantidAPI/MultipleExperimentInfos.h @@ -64,7 +64,8 @@ class DLLExport MultipleExperimentInfos { }; using MultipleExperimentInfos_sptr = boost::shared_ptr; -using MultipleExperimentInfos_const_sptr = boost::shared_ptr; +using MultipleExperimentInfos_const_sptr = + boost::shared_ptr; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h b/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h index 664f5fef16ba..e386c860b1cb 100644 --- a/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h +++ b/Framework/API/inc/MantidAPI/RemoteJobManagerFactory.h @@ -87,7 +87,8 @@ class MANTID_API_DLL RemoteJobManagerFactoryImpl }; // The factory is just a specialisation of SingletonHolder -using RemoteJobManagerFactory = Mantid::Kernel::SingletonHolder; +using RemoteJobManagerFactory = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h b/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h index bc984a7e30af..69c01aaa76b0 100644 --- a/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h +++ b/Framework/API/inc/MantidAPI/ScriptRepositoryFactory.h @@ -67,7 +67,8 @@ class MANTID_API_DLL ScriptRepositoryFactoryImpl ~ScriptRepositoryFactoryImpl() override = default; }; -using ScriptRepositoryFactory = Mantid::Kernel::SingletonHolder; +using ScriptRepositoryFactory = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h index 5eb6843ccead..9c1bbce1b7bb 100644 --- a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h +++ b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h @@ -14,7 +14,7 @@ using spec2index_map = std::unordered_map; /// Map with key = detector ID, value = workspace index using detid2index_map = std::unordered_map; /// Map single det ID of group to its members -using det2group_map = std::unordered_map >; +using det2group_map = std::unordered_map>; } #endif // MANTID_API_SPECTRADETECTORMAP_TYPES diff --git a/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h b/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h index 5b37bd0df31f..e8429fa25dfd 100644 --- a/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h +++ b/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h @@ -50,7 +50,7 @@ class MatrixWorkspace; Code Documentation is available at: */ class MANTID_API_DLL SpectrumDetectorMapping { - using sdmap = std::unordered_map >; + using sdmap = std::unordered_map>; public: explicit SpectrumDetectorMapping(const MatrixWorkspace *const workspace, diff --git a/Framework/API/inc/MantidAPI/TransformScaleFactory.h b/Framework/API/inc/MantidAPI/TransformScaleFactory.h index d34f27cf8819..7ec4daa8562c 100644 --- a/Framework/API/inc/MantidAPI/TransformScaleFactory.h +++ b/Framework/API/inc/MantidAPI/TransformScaleFactory.h @@ -66,7 +66,8 @@ class MANTID_API_DLL TransformScaleFactoryImpl // Do not use default methods }; -using TransformScaleFactory = Mantid::Kernel::SingletonHolder; +using TransformScaleFactory = + Mantid::Kernel::SingletonHolder; } // namespace API } // namespace Mantid diff --git a/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h b/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h index 1ca57f0e2426..1a071bf00963 100644 --- a/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h +++ b/Framework/API/inc/MantidAPI/WorkspaceNearestNeighbours.h @@ -82,7 +82,10 @@ class MANTID_API_DLL WorkspaceNearestNeighbours { const std::vector m_spectrumNumbers; /// typedef for Graph object used to hold the calculated information - using Graph = boost::adjacency_list, boost::property >; + using Graph = boost::adjacency_list< + boost::vecS, boost::vecS, boost::directedS, + boost::property, + boost::property>; /// Vertex descriptor object for Graph using Vertex = boost::graph_traits::vertex_descriptor; /// map object of int to Graph Vertex descriptor diff --git a/Framework/API/src/MultiPeriodGroupWorker.cpp b/Framework/API/src/MultiPeriodGroupWorker.cpp index 2c54d9839ff8..ff9e531ee5b7 100644 --- a/Framework/API/src/MultiPeriodGroupWorker.cpp +++ b/Framework/API/src/MultiPeriodGroupWorker.cpp @@ -85,7 +85,7 @@ MultiPeriodGroupWorker::findMultiPeriodGroups( vecWorkspaceGroups); } } else { - using WorkspaceVector = std::vector >; + using WorkspaceVector = std::vector>; WorkspaceVector inWorkspaces; WorkspaceVector outWorkspaces; sourceAlg->findWorkspaceProperties(inWorkspaces, outWorkspaces); diff --git a/Framework/API/test/FermiChopperModelTest.h b/Framework/API/test/FermiChopperModelTest.h index 90abb283ad80..195295e201b4 100644 --- a/Framework/API/test/FermiChopperModelTest.h +++ b/Framework/API/test/FermiChopperModelTest.h @@ -9,7 +9,8 @@ #include class FermiChopperModelTest : public CxxTest::TestSuite { - using FermiChopperModel_sptr = boost::shared_ptr; + using FermiChopperModel_sptr = + boost::shared_ptr; public: void test_Default_Object_Throws_When_Computing_Pulse_Variance() { diff --git a/Framework/API/test/IkedaCarpenterModeratorTest.h b/Framework/API/test/IkedaCarpenterModeratorTest.h index c79e24b8254d..7e21d119bb08 100644 --- a/Framework/API/test/IkedaCarpenterModeratorTest.h +++ b/Framework/API/test/IkedaCarpenterModeratorTest.h @@ -8,7 +8,8 @@ class IkedaCarpenterModeratorTest : public CxxTest::TestSuite { public: - using IkedaCarpenterModerator_sptr = boost::shared_ptr; + using IkedaCarpenterModerator_sptr = + boost::shared_ptr; void test_Default_Object_Returns_Zero_Mean_Time() { Mantid::API::IkedaCarpenterModerator ikmod; diff --git a/Framework/API/test/VectorParameterParserTest.h b/Framework/API/test/VectorParameterParserTest.h index 55c717ae0442..68d06dd2bc30 100644 --- a/Framework/API/test/VectorParameterParserTest.h +++ b/Framework/API/test/VectorParameterParserTest.h @@ -15,13 +15,15 @@ class VectorParameterParserTest : public CxxTest::TestSuite { DECLARE_VECTOR_PARAMETER(ConcreteVectorDblParam, double) // Declare a concrete vector parameter parser for testing. - using ConcreteVectorDblParamParser = VectorParameterParser; + using ConcreteVectorDblParamParser = + VectorParameterParser; // Declare a concrete type with elements of type bool for testing. DECLARE_VECTOR_PARAMETER(ConcreteVectorBoolParam, bool) // Declare a concrete vector parameter parser for testing. - using ConcreteVectorBoolParamParser = VectorParameterParser; + using ConcreteVectorBoolParamParser = + VectorParameterParser; public: void testParsesParmeterValue1D() { @@ -95,7 +97,8 @@ class VectorParameterParserTest : public CxxTest::TestSuite { void testChainOfResponsibility() { // Local declare of a successor parser with a successor parameter. - using ConcreteSuccessorVectorParameterParser = VectorParameterParser; + using ConcreteSuccessorVectorParameterParser = + VectorParameterParser; DOMParser pParser; std::string xmlToParse = "SucessorVectorParameter >; + using MapCluster = std::map>; /// Constructor ClusterRegister(); diff --git a/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h b/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h index 1016d219d97b..6f7c72faba9e 100644 --- a/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h +++ b/Framework/Crystal/inc/MantidCrystal/ConnectedComponentLabeling.h @@ -28,8 +28,10 @@ using PositionToLabelIdMap = std::map; using VecIndexes = std::vector; using VecElements = std::vector; using SetIds = std::unordered_set; -using ClusterMap = std::map >; -using ClusterTuple = boost::tuple; +using ClusterMap = + std::map>; +using ClusterTuple = + boost::tuple; } class BackgroundStrategy; diff --git a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h index bcae377a112d..ca4816edd601 100644 --- a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h @@ -46,7 +46,7 @@ class DLLExport FilterPeaks : public API::Algorithm { private: /// Typedef for the function to get the variable we're filtering against - using FilterFunction = std::function; + using FilterFunction = std::function; /// Override for algorithm init void init() override; diff --git a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h index 45b3862f4841..6104fcc75d2f 100644 --- a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h +++ b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h @@ -54,7 +54,8 @@ class DLLExport SetSpecialCoordinates : public API::Algorithm { void init() override; void exec() override; std::vector m_specialCoordinatesNames; - using SpecialCoordinatesNameMap = std::map; + using SpecialCoordinatesNameMap = + std::map; SpecialCoordinatesNameMap m_specialCoordinatesMap; static const std::string QLabOption(); static const std::string QSampleOption(); diff --git a/Framework/Crystal/src/ClusterRegister.cpp b/Framework/Crystal/src/ClusterRegister.cpp index b4a01e25981d..81ffb3b33c92 100644 --- a/Framework/Crystal/src/ClusterRegister.cpp +++ b/Framework/Crystal/src/ClusterRegister.cpp @@ -26,7 +26,7 @@ class ImplClusterRegister { ClusterRegister::MapCluster m_unique; /// Type for identifying label groups - using GroupType = std::list >; + using GroupType = std::list>; /// Groups of labels to maintain GroupType m_groups; diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp index cde781e8e878..42043c5f3545 100644 --- a/Framework/Crystal/src/SaveHKL.cpp +++ b/Framework/Crystal/src/SaveHKL.cpp @@ -185,7 +185,7 @@ void SaveHKL::exec() { std::string bankPart = "?"; // We must sort the peaks first by run, then bank #, and save the list of // workspace indices of it - using bankMap_t = std::map >; + using bankMap_t = std::map>; using runMap_t = std::map; std::set uniqueBanks; std::set uniqueRuns; diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp index 31118b8ccfe4..a50badfca018 100644 --- a/Framework/Crystal/src/SaveIsawPeaks.cpp +++ b/Framework/Crystal/src/SaveIsawPeaks.cpp @@ -62,7 +62,7 @@ void SaveIsawPeaks::exec() { // We must sort the peaks first by run, then bank #, and save the list of // workspace indices of it - using bankMap_t = std::map >; + using bankMap_t = std::map>; using runMap_t = std::map; std::set> uniqueBanks; if (!inst) diff --git a/Framework/Crystal/test/CentroidPeaksTest.h b/Framework/Crystal/test/CentroidPeaksTest.h index 625063d288e9..9ceedd8f975a 100644 --- a/Framework/Crystal/test/CentroidPeaksTest.h +++ b/Framework/Crystal/test/CentroidPeaksTest.h @@ -56,7 +56,8 @@ class CentroidPeaksTest : public CxxTest::TestSuite { rng.seed((unsigned int)(randomSeed)); size_t nd = 1; // Make a random generator for each dimensions - using gen_t = boost::variate_generator >; + using gen_t = + boost::variate_generator>; gen_t *gens[1]; for (size_t d = 0; d < nd; ++d) { double min = -1.; diff --git a/Framework/Crystal/test/ClusterIntegrationBaseTest.h b/Framework/Crystal/test/ClusterIntegrationBaseTest.h index c20f7e367737..56d0fe03679e 100644 --- a/Framework/Crystal/test/ClusterIntegrationBaseTest.h +++ b/Framework/Crystal/test/ClusterIntegrationBaseTest.h @@ -28,9 +28,11 @@ using namespace Mantid::DataObjects; using namespace Mantid::Geometry; // Helper typedef -using MDHistoPeaksWSTuple = boost::tuple; +using MDHistoPeaksWSTuple = + boost::tuple; // Helper typedef -using MDEventPeaksWSTuple = boost::tuple; +using MDEventPeaksWSTuple = + boost::tuple; class ClusterIntegrationBaseTest { protected: diff --git a/Framework/Crystal/test/IntegratePeaksHybridTest.h b/Framework/Crystal/test/IntegratePeaksHybridTest.h index fbc9229779d2..97c2a4a92e98 100644 --- a/Framework/Crystal/test/IntegratePeaksHybridTest.h +++ b/Framework/Crystal/test/IntegratePeaksHybridTest.h @@ -19,7 +19,8 @@ using namespace Mantid::DataObjects; using namespace Mantid::API; namespace { -using AlgorithmOutputs = boost::tuple; +using AlgorithmOutputs = + boost::tuple; // Execute the clustering integration algorithm AlgorithmOutputs execute_integration(const MDEventPeaksWSTuple &inputWorkspaces, diff --git a/Framework/Crystal/test/NormaliseVanadiumTest.h b/Framework/Crystal/test/NormaliseVanadiumTest.h index 0128e08c3c05..3c05af399efa 100644 --- a/Framework/Crystal/test/NormaliseVanadiumTest.h +++ b/Framework/Crystal/test/NormaliseVanadiumTest.h @@ -52,7 +52,8 @@ EventWorkspace_sptr createDiffractionEventWorkspace(int numEvents) { rng.seed((unsigned int)(randomSeed)); size_t nd = 1; // Make a random generator for each dimensions - using gen_t = boost::variate_generator >; + using gen_t = + boost::variate_generator>; gen_t *gens[1]; for (size_t d = 0; d < nd; ++d) { double min = -1.; diff --git a/Framework/Crystal/test/PeakIntegrationTest.h b/Framework/Crystal/test/PeakIntegrationTest.h index 75ae43d49fa9..86a5b3762b96 100644 --- a/Framework/Crystal/test/PeakIntegrationTest.h +++ b/Framework/Crystal/test/PeakIntegrationTest.h @@ -59,7 +59,8 @@ class PeakIntegrationTest : public CxxTest::TestSuite { rng.seed((unsigned int)(randomSeed)); size_t nd = 1; // Make a random generator for each dimensions - using gen_t = boost::variate_generator >; + using gen_t = + boost::variate_generator>; gen_t *gens[1]; for (size_t d = 0; d < nd; ++d) { double min = -1.; diff --git a/Framework/Crystal/test/PeaksInRegionTest.h b/Framework/Crystal/test/PeaksInRegionTest.h index 5bb6f1af4a61..0d15e62e69ae 100644 --- a/Framework/Crystal/test/PeaksInRegionTest.h +++ b/Framework/Crystal/test/PeaksInRegionTest.h @@ -19,7 +19,8 @@ Functional Tests class PeaksInRegionTest : public CxxTest::TestSuite { private: - using PeakWorkspaceWithExtents = boost::tuple >; + using PeakWorkspaceWithExtents = + boost::tuple>; /** Helper function. Creates a peaksworkspace with a single peak diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h index 7e47a5920dae..52c2db3f26b7 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/AugmentedLagrangianOptimizer.h @@ -97,7 +97,7 @@ class MANTID_CURVEFITTING_DLL AugmentedLagrangianOptimizer { public: /// Function type - using ObjFunction = boost::function; + using ObjFunction = boost::function; public: /** diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h b/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h index 94c7fdcdc091..dea108cfb57b 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/FortranDefs.h @@ -13,7 +13,7 @@ using ComplexFortranMatrix = FortranMatrix; using DoubleFortranMatrix = FortranMatrix; using ComplexFortranVector = FortranVector; using DoubleFortranVector = FortranVector; -using IntFortranVector = FortranVector >; +using IntFortranVector = FortranVector>; } // namespace CurveFitting } // namespace Mantid diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h b/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h index dc1632592b4b..bdbf98db9e0c 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/FortranMatrix.h @@ -41,7 +41,8 @@ template class FortranMatrix : public MatrixClass { int m_base2; /// Typedef the types returned by the base class's operators []. They aren't /// necessarily the same as the stored type (double or complex). - using ElementConstType = decltype(std::declval().operator()(0, 0)); + using ElementConstType = + decltype(std::declval().operator()(0, 0)); using ElementRefType = decltype(std::declval().operator()(0, 0)); public: diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h index 3e72fdd3c93f..51be2281977e 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ChebfunBase.h @@ -18,7 +18,7 @@ namespace CurveFitting { namespace Functions { /// Type of the approximated function -using ChebfunFunctionType = std::function; +using ChebfunFunctionType = std::function; /** diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h index 074f4edff0b4..27766fd6de1a 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpAlpha.h @@ -66,7 +66,8 @@ class DLLExport ThermalNeutronBk2BkExpAlpha : virtual public API::IFunction1D, double alph1t) const; }; -using ThermalNeutronBk2BkExpAlpha_sptr = boost::shared_ptr; +using ThermalNeutronBk2BkExpAlpha_sptr = + boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h index 42219eb66712..55c3d3d3fd6e 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpBeta.h @@ -66,7 +66,8 @@ class DLLExport ThermalNeutronBk2BkExpBeta : virtual public API::IFunction1D, double beta1t) const; }; -using ThermalNeutronBk2BkExpBeta_sptr = boost::shared_ptr; +using ThermalNeutronBk2BkExpBeta_sptr = + boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h index f9f8740e0c9e..c6cab7ae451a 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h @@ -179,7 +179,8 @@ class DLLExport ThermalNeutronBk2BkExpConvPVoigt }; /// Shared pointer to ThermalNeutronBk2BkExpConvPVoigt peak/function -using ThermalNeutronBk2BkExpConvPVoigt_sptr = boost::shared_ptr; +using ThermalNeutronBk2BkExpConvPVoigt_sptr = + boost::shared_ptr; //--- Public inline function -------------------------------------------------- /** Calculate d = a/sqrt(h**2+k**2+l**2) diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h index 78cf35e042f7..268e33694b48 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronBk2BkExpSigma.h @@ -65,7 +65,8 @@ class DLLExport ThermalNeutronBk2BkExpSigma : virtual public API::IFunction1D, double sig2sq) const; }; -using ThermalNeutronBk2BkExpSigma_sptr = boost::shared_ptr; +using ThermalNeutronBk2BkExpSigma_sptr = + boost::shared_ptr; } // namespace Functions } // namespace CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h index b5c29abea3d0..224e293bcc77 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/ThermalNeutronDtoTOFFunction.h @@ -81,7 +81,8 @@ class DLLExport ThermalNeutronDtoTOFFunction : virtual public API::IFunction1D, // jacobian); }; -using ThermalNeutronDtoTOFFunction_sptr = boost::shared_ptr; +using ThermalNeutronDtoTOFFunction_sptr = + boost::shared_ptr; /// Calcualte TOF from d-spacing value for thermal neutron inline double calThermalNeutronTOF(double dh, double dtt1, double dtt1t, diff --git a/Framework/CurveFitting/src/MSVesuvioHelpers.cpp b/Framework/CurveFitting/src/MSVesuvioHelpers.cpp index 1180052c9b72..0908408c9115 100644 --- a/Framework/CurveFitting/src/MSVesuvioHelpers.cpp +++ b/Framework/CurveFitting/src/MSVesuvioHelpers.cpp @@ -358,12 +358,14 @@ RandomNumberGenerator::RandomNumberGenerator(const int seed) : m_generator() { } /// Returns a flat random number between 0.0 & 1.0 double RandomNumberGenerator::flat() { - using uniform_generator = boost::variate_generator; + using uniform_generator = + boost::variate_generator; return uniform_generator(m_generator, uniform_double(0.0, 1.0))(); } /// Returns a random number distributed by a normal distribution double RandomNumberGenerator::gaussian(const double mean, const double sigma) { - using gauss_generator = boost::variate_generator; + using gauss_generator = + boost::variate_generator; return gauss_generator(m_generator, gaussian_double(mean, sigma))(); } diff --git a/Framework/CurveFitting/src/ParameterEstimator.cpp b/Framework/CurveFitting/src/ParameterEstimator.cpp index e055dd408e1c..82b093b48dc6 100644 --- a/Framework/CurveFitting/src/ParameterEstimator.cpp +++ b/Framework/CurveFitting/src/ParameterEstimator.cpp @@ -25,7 +25,7 @@ std::recursive_mutex FUNCTION_MAP_MUTEX; } enum Function { None, Gaussian, Lorentzian, BackToBackExponential }; -using FunctionMapType = std::map >; +using FunctionMapType = std::map>; //---------------------------------------------------------------------------------------------- diff --git a/Framework/CurveFitting/test/FortranVectorTest.h b/Framework/CurveFitting/test/FortranVectorTest.h index bbe3a0a3d2af..fd4dfb020e99 100644 --- a/Framework/CurveFitting/test/FortranVectorTest.h +++ b/Framework/CurveFitting/test/FortranVectorTest.h @@ -207,7 +207,7 @@ class FortranVectorTest : public CxxTest::TestSuite { } void test_int_array() { - using FortranIntVector = FortranVector >; + using FortranIntVector = FortranVector>; FortranIntVector ivec(1, 3); ivec(1) = 11; ivec(2) = 22; diff --git a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h index 7ae07d960165..9424a2ce8ea3 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h @@ -149,7 +149,7 @@ class DLLExport GroupDetectors2 : public API::Algorithm { /// used to store the lists of WORKSPACE INDICES that will be grouped, the /// keys are not used - using storage_map = std::map >; + using storage_map = std::map>; /// An estimate of the percentage of the algorithm runtimes that has been /// completed diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h index daacd95d4034..6ded9e3c0817 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h @@ -70,7 +70,8 @@ class DLLExport LoadSNSspec : public API::IFileLoader, /// Allowed values for the cache property std::vector m_seperator_options; std::map m_separatormap; ///; ///; /// m_seperator_options; std::map m_separatormap; ///; ///; /// >; + using NXIntArray = boost::scoped_ptr>; nxsFile.openData("NDET"); NXIntArray ndets(nxsFile.getData()); diff --git a/Framework/DataHandling/src/GroupDetectors2.cpp b/Framework/DataHandling/src/GroupDetectors2.cpp index 534b5b1b0f67..ffde59f3348e 100644 --- a/Framework/DataHandling/src/GroupDetectors2.cpp +++ b/Framework/DataHandling/src/GroupDetectors2.cpp @@ -732,7 +732,7 @@ void GroupDetectors2::processGroupingWorkspace( std::vector &unUsedSpec) { detid2index_map detIdToWiMap = workspace->getDetectorIDToWorkspaceIndexMap(); - using Group2SetMapType = std::map >; + using Group2SetMapType = std::map>; Group2SetMapType group2WSIndexSetmap; const auto &spectrumInfo = groupWS->spectrumInfo(); @@ -785,7 +785,7 @@ void GroupDetectors2::processMatrixWorkspace( std::vector &unUsedSpec) { detid2index_map detIdToWiMap = workspace->getDetectorIDToWorkspaceIndexMap(); - using Group2SetMapType = std::map >; + using Group2SetMapType = std::map>; Group2SetMapType group2WSIndexSetmap; const auto &spectrumInfo = groupWS->spectrumInfo(); diff --git a/Framework/DataHandling/src/LoadRaw/item_struct.h b/Framework/DataHandling/src/LoadRaw/item_struct.h index 874bcc3c1103..aa5ec35f37fe 100644 --- a/Framework/DataHandling/src/LoadRaw/item_struct.h +++ b/Framework/DataHandling/src/LoadRaw/item_struct.h @@ -23,8 +23,9 @@ class item_struct { item_struct() : m_items(), m_spec_array(nullptr), m_ndet(0){}; private: - using items_map_t = std::map; ///; ///, boost::shared_array, boost::shared_array >; + using DataHolder = + boost::tuple, boost::shared_array, + boost::shared_array>; DataHolder saveAndReloadWorkspace(const MatrixWorkspace_sptr inputWS) { SaveNXSPE saver; diff --git a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h index 60d388b82856..0f8f235fdb27 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h +++ b/Framework/DataObjects/inc/MantidDataObjects/CoordTransformAffineParser.h @@ -31,7 +31,8 @@ class DLLExport CoordTransformAffineParser { createTransform(Poco::XML::Element *coordTransElement) const; virtual void setSuccessor(CoordTransformAffineParser *other); virtual ~CoordTransformAffineParser() = default; - using SuccessorType_sptr = boost::shared_ptr; ///< successor parser shared ptr typedef + using SuccessorType_sptr = boost::shared_ptr< + CoordTransformAffineParser>; ///< successor parser shared ptr typedef protected: SuccessorType_sptr m_successor; ///< successor parser private: diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBox.h b/Framework/DataObjects/inc/MantidDataObjects/MDBox.h index bc0b580f2c4c..6c3e433311e7 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBox.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBox.h @@ -227,7 +227,7 @@ class DLLExport MDBox : public MDBoxBase { public: /// Typedef for a shared pointer to a MDBox - using sptr = boost::shared_ptr >; + using sptr = boost::shared_ptr>; /// Typedef for a vector of the conatined events using vec_t = std::vector; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h index 1deab64c5080..2617c286f005 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h @@ -372,7 +372,7 @@ class DLLExport MDBoxBase : public Mantid::API::IMDNode { public: /// Convenience typedef for a shared pointer to a this type of class - using sptr = boost::shared_ptr >; + using sptr = boost::shared_ptr>; }; //(end class MDBoxBase) diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h index 6525a5ebc4eb..5c7f31d9ebab 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventFactory.h @@ -65,14 +65,19 @@ class DLLExport MDEventFactory { static size_t getMaxNumDim() { return size_t(MAX_MD_DIMENSIONS_NUM); } private: - using fpCreateBox = API::IMDNode *(*)(API::BoxController *, const std::vector > &, const uint32_t, const size_t, const size_t); + using fpCreateBox = API::IMDNode *(*)( + API::BoxController *, + const std::vector> &, + const uint32_t, const size_t, const size_t); // vector of function pointers to the functions which create MDBox or // MDGridBox; static std::vector boxCreatorFP; // typedef for the class function pointer to the function, which creates MD // Workspaces - using fpCreateMDWS = API::IMDEventWorkspace *(*)(const std::string &, const Mantid::API::MDNormalization &, const Mantid::API::MDNormalization &); + using fpCreateMDWS = API::IMDEventWorkspace *(*)( + const std::string &, const Mantid::API::MDNormalization &, + const Mantid::API::MDNormalization &); // vector of function pointers to the funcions static std::vector wsCreatorFP; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h index 3c95e81fc0b9..d111f289f1d2 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h @@ -35,7 +35,7 @@ class DLLExport MDEventWorkspace : public API::IMDEventWorkspace { public: /// Typedef for a shared pointer of this kind of event workspace - using sptr = boost::shared_ptr >; + using sptr = boost::shared_ptr>; /// Typedef to access the MDEventType. using MDEventType = MDE; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h index 18f6d303ae43..5d83894a3a3f 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDGridBox.h @@ -205,7 +205,7 @@ class DLLExport MDGridBox : public MDBoxBase { public: /// Typedef for a shared pointer to a MDGridBox - using sptr = boost::shared_ptr >; + using sptr = boost::shared_ptr>; /// Typedef for a vector of MDBoxBase pointers using boxVector_t = std::vector *>; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h index 81aff98e9501..622a532b6230 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h @@ -15,9 +15,10 @@ namespace DataObjects { // Typedef for a map for mapping width of neighbours (key) to permutations // needed in the calcualtion. -using PermutationsMap = std::map, std::vector >; +using PermutationsMap = std::map, std::vector>; // Typedef for extents -using MDExtentPair = boost::tuple; // Min/Max pair +using MDExtentPair = + boost::tuple; // Min/Max pair // Typedef for vector of extents using VecMDExtents = std::vector; diff --git a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h index e016c03afef1..667a43d825a4 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h +++ b/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h @@ -80,7 +80,8 @@ class DLLExport PeakShapeEllipsoid : public PeakShapeBase { }; using PeakShapeEllipsoid_sptr = boost::shared_ptr; -using PeakShapeEllipsoid_const_sptr = boost::shared_ptr; +using PeakShapeEllipsoid_const_sptr = + boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h b/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h index bf1db875535d..4b19d5910323 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h +++ b/Framework/DataObjects/inc/MantidDataObjects/SpecialWorkspace2D.h @@ -92,7 +92,8 @@ class DLLExport SpecialWorkspace2D : public Workspace2D { using SpecialWorkspace2D_sptr = boost::shared_ptr; /// shared pointer to a const SpecialWorkspace2D -using SpecialWorkspace2D_const_sptr = boost::shared_ptr; +using SpecialWorkspace2D_const_sptr = + boost::shared_ptr; } // namespace Mantid } // namespace DataObjects diff --git a/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h index f58f040c931f..2821ec983c54 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/SplittersWorkspace.h @@ -82,7 +82,8 @@ class DLLExport SplittersWorkspace : public DataObjects::TableWorkspace, }; using SplittersWorkspace_sptr = boost::shared_ptr; -using SplittersWorkspace_const_sptr = boost::shared_ptr; +using SplittersWorkspace_const_sptr = + boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h index f475a2c29925..b6c071a889d0 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h @@ -142,7 +142,9 @@ template class TableColumn : public API::Column { * @param value :: The value of the element. */ template double convertToDouble(const T &value) const { - using DoubleType = typename std::conditional::value, T, InconvertibleToDoubleType>::type; + using DoubleType = + typename std::conditional::value, T, + InconvertibleToDoubleType>::type; return boost::numeric_cast(value); } @@ -173,7 +175,9 @@ template class TableColumn : public API::Column { * @param value: cast this value */ void fromDouble(size_t i, double value) override { - using DoubleType = typename std::conditional::value, Type, InconvertibleToDoubleType>::type; + using DoubleType = + typename std::conditional::value, + Type, InconvertibleToDoubleType>::type; m_data[i] = static_cast(boost::numeric_cast(value)); } diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h index 88039b9cdc5b..7fbc3e0790b5 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h @@ -410,8 +410,12 @@ class MANTID_DATAOBJECTS_DLL TableWorkspace : public API::ITableWorkspace { } }; - using column_it = std::vector >::iterator; ///< Column iterator - using column_const_it = std::vector >::const_iterator; ///< Column const iterator + using column_it = std::vector< + boost::shared_ptr>::iterator; ///< Column iterator + using column_const_it = + std::vector>::const_iterator; ///< Column + ///const + ///iterator /// Shared pointers to the columns. std::vector> m_columns; /// row count diff --git a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h index d899d2bdb16a..539bcd16ab35 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h +++ b/Framework/DataObjects/inc/MantidDataObjects/WorkspaceSingleValue.h @@ -97,7 +97,8 @@ class DLLExport WorkspaceSingleValue : public API::HistoWorkspace { /// shared pointer to the WorkspaceSingleValue class using WorkspaceSingleValue_sptr = boost::shared_ptr; -using WorkspaceSingleValue_const_sptr = boost::shared_ptr; +using WorkspaceSingleValue_const_sptr = + boost::shared_ptr; } // namespace DataObjects } // namespace Mantid diff --git a/Framework/DataObjects/src/CoordTransformAffineParser.cpp b/Framework/DataObjects/src/CoordTransformAffineParser.cpp index e5d3683ce065..713e53cf6d29 100644 --- a/Framework/DataObjects/src/CoordTransformAffineParser.cpp +++ b/Framework/DataObjects/src/CoordTransformAffineParser.cpp @@ -20,8 +20,10 @@ Create the transform object. */ Mantid::API::CoordTransform *CoordTransformAffineParser::createTransform( Poco::XML::Element *coordTransElement) const { - using InDimParameterParser = Mantid::API::SingleValueParameterParser; - using OutDimParameterParser = Mantid::API::SingleValueParameterParser; + using InDimParameterParser = + Mantid::API::SingleValueParameterParser; + using OutDimParameterParser = + Mantid::API::SingleValueParameterParser; using namespace Poco::XML; if ("CoordTransform" != coordTransElement->localName()) { std::string message = "This is not a coordinate transform element: " + diff --git a/Framework/DataObjects/src/CoordTransformDistanceParser.cpp b/Framework/DataObjects/src/CoordTransformDistanceParser.cpp index 869cd0fc04c6..d5776a7c5ab9 100644 --- a/Framework/DataObjects/src/CoordTransformDistanceParser.cpp +++ b/Framework/DataObjects/src/CoordTransformDistanceParser.cpp @@ -17,10 +17,14 @@ Create the transform object. Mantid::API::CoordTransform *CoordTransformDistanceParser::createTransform( Poco::XML::Element *coordTransElement) const { // Typdef the parameter parsers required. - using InDimParameterParser = Mantid::API::SingleValueParameterParser; - using OutDimParameterParser = Mantid::API::SingleValueParameterParser; - using CoordCenterParser = Mantid::API::VectorParameterParser; - using DimsUsedParser = Mantid::API::VectorParameterParser; + using InDimParameterParser = + Mantid::API::SingleValueParameterParser; + using OutDimParameterParser = + Mantid::API::SingleValueParameterParser; + using CoordCenterParser = + Mantid::API::VectorParameterParser; + using DimsUsedParser = + Mantid::API::VectorParameterParser; using namespace Poco::XML; if ("CoordTransform" != coordTransElement->localName()) { diff --git a/Framework/DataObjects/src/FakeMD.cpp b/Framework/DataObjects/src/FakeMD.cpp index 8a8d88ce3867..873a7a0de06b 100644 --- a/Framework/DataObjects/src/FakeMD.cpp +++ b/Framework/DataObjects/src/FakeMD.cpp @@ -236,7 +236,8 @@ void FakeMD::addFakeRandomData(const std::vector ¶ms, genUnit(rng, u2); // Make a random generator for each dimensions - using gen_t = boost::variate_generator >; + using gen_t = + boost::variate_generator>; // Inserter to help choose the correct event type auto eventHelper = @@ -364,7 +365,8 @@ detid_t FakeMD::pickDetectorID() { } else { /// A variate generator to combine a random number generator with a /// distribution - using uniform_generator = boost::variate_generator >; + using uniform_generator = + boost::variate_generator>; uniform_generator uniformRand(m_randGen, m_uniformDist); const size_t randIndex = uniformRand(); return m_detIDs[randIndex]; diff --git a/Framework/DataObjects/src/MDBoxFlatTree.cpp b/Framework/DataObjects/src/MDBoxFlatTree.cpp index aa705020ca0a..b350f07c9ea0 100644 --- a/Framework/DataObjects/src/MDBoxFlatTree.cpp +++ b/Framework/DataObjects/src/MDBoxFlatTree.cpp @@ -8,7 +8,7 @@ #include "MantidKernel/Strings.h" #include -using file_holder_type = std::unique_ptr< ::NeXus::File>; +using file_holder_type = std::unique_ptr<::NeXus::File>; namespace Mantid { namespace DataObjects { diff --git a/Framework/DataObjects/test/MDBoxTest.h b/Framework/DataObjects/test/MDBoxTest.h index dc7ea136be9a..0f64cf5f143a 100644 --- a/Framework/DataObjects/test/MDBoxTest.h +++ b/Framework/DataObjects/test/MDBoxTest.h @@ -372,7 +372,8 @@ class MDBoxTest : public CxxTest::TestSuite { void test_bad_splitter() { BoxController_sptr sc(new BoxController(4)); sc->setSplitThreshold(10); - using MACROS_ARE_DUMB = MDBox, 3>; //...since they get confused by commas + using MACROS_ARE_DUMB = + MDBox, 3>; //...since they get confused by commas TS_ASSERT_THROWS(MACROS_ARE_DUMB b3(sc.get()), std::invalid_argument); } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h index be5ef1c6c67b..bc496e93ce61 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h @@ -85,7 +85,8 @@ class MANTID_GEOMETRY_DLL BraggScattererFactoryImpl BraggScattererFactoryImpl(); }; -using BraggScattererFactory = Mantid::Kernel::SingletonHolder; +using BraggScattererFactory = + Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h index 5c2a82875033..584133be8207 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h @@ -72,7 +72,8 @@ class MANTID_GEOMETRY_DLL BraggScattererInCrystalStructure UnitCell m_cell; }; -using BraggScattererInCrystalStructure_sptr = boost::shared_ptr; +using BraggScattererInCrystalStructure_sptr = + boost::shared_ptr; /** * Helper class for validating unit cell strings. diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h index d70a80d40b3e..3356098ff91b 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h @@ -94,7 +94,8 @@ class MANTID_GEOMETRY_DLL CenteringGroupCreatorImpl { friend struct Mantid::Kernel::CreateUsingNew; }; -using CenteringGroupCreator = Mantid::Kernel::SingletonHolder; +using CenteringGroupCreator = + Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h index aa241526f50a..a3151c95f177 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h @@ -10,7 +10,8 @@ namespace Geometry { class IsotropicAtomBraggScatterer; -using IsotropicAtomBraggScatterer_sptr = boost::shared_ptr; +using IsotropicAtomBraggScatterer_sptr = + boost::shared_ptr; /** @class IsotropicAtomBraggScatterer @@ -120,7 +121,8 @@ class MANTID_GEOMETRY_DLL IsotropicAtomBraggScatterer std::string m_label; }; -using IsotropicAtomBraggScatterer_sptr = boost::shared_ptr; +using IsotropicAtomBraggScatterer_sptr = + boost::shared_ptr; class MANTID_GEOMETRY_DLL IsotropicAtomBraggScattererParser { public: diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h index 8d2f10ce2f8b..ac135a8df023 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQLab.h @@ -31,7 +31,8 @@ class DLLExport PeakTransformQLab : public PeakTransform { }; /// Typedef a factory for type of PeaksTransform. -using PeakTransformQLabFactory = ConcretePeakTransformFactory; +using PeakTransformQLabFactory = + ConcretePeakTransformFactory; } } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h index cca344bbfcd6..b2204cf33ff8 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PeakTransformQSample.h @@ -31,7 +31,8 @@ class DLLExport PeakTransformQSample : public PeakTransform { }; /// Typedef a factory for type of PeaksTransform. -using PeakTransformQSampleFactory = ConcretePeakTransformFactory; +using PeakTransformQSampleFactory = + ConcretePeakTransformFactory; } } diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h index 659807b5e1ab..1d6e64c7cc89 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h @@ -107,7 +107,9 @@ struct MANTID_GEOMETRY_DLL CrystalSystemComparator { const PointGroup::CrystalSystem &rhs) const; }; -using PointGroupCrystalSystemMap = std::multimap; +using PointGroupCrystalSystemMap = + std::multimap; MANTID_GEOMETRY_DLL PointGroupCrystalSystemMap getPointGroupsByCrystalSystem(); diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h index 36fcf28c04ba..51f76496811c 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h @@ -120,7 +120,8 @@ class MANTID_GEOMETRY_DLL PointGroupFactoryImpl { boost::regex m_originChoiceRegex; }; -using PointGroupFactory = Mantid::Kernel::SingletonHolder; +using PointGroupFactory = + Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h index 967f4dd95d3a..536711ebbc55 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h @@ -61,7 +61,8 @@ class MANTID_GEOMETRY_DLL AbstractSpaceGroupGenerator { SpaceGroup_const_sptr m_prototype; }; -using AbstractSpaceGroupGenerator_sptr = boost::shared_ptr; +using AbstractSpaceGroupGenerator_sptr = + boost::shared_ptr; /// Concrete space group generator that uses space group generators as given in /// ITA. @@ -264,7 +265,8 @@ class MANTID_GEOMETRY_DLL SpaceGroupFactoryImpl { friend struct Mantid::Kernel::CreateUsingNew; }; -using SpaceGroupFactory = Mantid::Kernel::SingletonHolder; +using SpaceGroupFactory = + Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h index d11c333c45e8..ca7da50362ef 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculator.h @@ -59,7 +59,8 @@ class MANTID_GEOMETRY_DLL StructureFactorCalculator { crystalStructureSetHook(const CrystalStructure &crystalStructure); }; -using StructureFactorCalculator_sptr = boost::shared_ptr; +using StructureFactorCalculator_sptr = + boost::shared_ptr; namespace StructureFactorCalculatorFactory { /// Small templated factory function that creates the desired calculator diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h index ea21a3a3fe46..890695c8f852 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/StructureFactorCalculatorSummation.h @@ -54,7 +54,8 @@ class MANTID_GEOMETRY_DLL StructureFactorCalculatorSummation CompositeBraggScatterer_sptr m_unitCellScatterers; }; -using StructureFactorSummation_sptr = boost::shared_ptr; +using StructureFactorSummation_sptr = + boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h index fcbb80c04317..1786880dff5f 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h @@ -100,7 +100,8 @@ class MANTID_GEOMETRY_DLL SymmetryElementInversion : public SymmetryElement { V3R m_inversionPoint; }; -using SymmetryElementInversion_sptr = boost::shared_ptr; +using SymmetryElementInversion_sptr = + boost::shared_ptr; /** @class SymmetryElementTranslation @@ -121,7 +122,8 @@ class MANTID_GEOMETRY_DLL SymmetryElementTranslation : public SymmetryElement { V3R m_translation; }; -using SymmetryElementTranslation_sptr = boost::shared_ptr; +using SymmetryElementTranslation_sptr = + boost::shared_ptr; /** @class SymmetryElementWithAxis diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h index 5d764b1ee2e9..5da8c6f963ba 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h @@ -41,7 +41,8 @@ class MANTID_GEOMETRY_DLL AbstractSymmetryElementGenerator { virtual bool canProcess(const SymmetryOperation &operation) const = 0; }; -using AbstractSymmetryElementGenerator_sptr = boost::shared_ptr; +using AbstractSymmetryElementGenerator_sptr = + boost::shared_ptr; /** @class SymmetryElementIdentityGenerator @@ -257,7 +258,8 @@ class MANTID_GEOMETRY_DLL SymmetryElementFactoryImpl { friend struct Mantid::Kernel::CreateUsingNew; }; -using SymmetryElementFactory = Mantid::Kernel::SingletonHolder; +using SymmetryElementFactory = + Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h index ce5f4451ac5f..03b1d78c0d16 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h @@ -78,7 +78,8 @@ class MANTID_GEOMETRY_DLL SymmetryOperationFactoryImpl { SymmetryOperationFactoryImpl(); }; -using SymmetryOperationFactory = Mantid::Kernel::SingletonHolder; +using SymmetryOperationFactory = + Mantid::Kernel::SingletonHolder; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/IDetector.h b/Framework/Geometry/inc/MantidGeometry/IDetector.h index 9aa29c982526..1ad29b9e9598 100644 --- a/Framework/Geometry/inc/MantidGeometry/IDetector.h +++ b/Framework/Geometry/inc/MantidGeometry/IDetector.h @@ -117,7 +117,8 @@ class MANTID_GEOMETRY_DLL IDetector : public virtual IObjComponent { /// Shared pointer to IDetector using IDetector_sptr = boost::shared_ptr; /// Shared pointer to IDetector (const version) -using IDetector_const_sptr = boost::shared_ptr; +using IDetector_const_sptr = + boost::shared_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument.h b/Framework/Geometry/inc/MantidGeometry/Instrument.h index c786b5abec29..53d40e5079c7 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument.h @@ -26,7 +26,9 @@ class XMLInstrumentParameter; class ParameterMap; class ReferenceFrame; /// Convenience typedef -using InstrumentParameterCache = std::map, boost::shared_ptr >; +using InstrumentParameterCache = + std::map, + boost::shared_ptr>; /** Base Instrument Class. diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h b/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h index cfeb0f6342a7..2102997d7672 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/CompAssembly.h @@ -48,7 +48,8 @@ class MANTID_GEOMETRY_DLL CompAssembly : public ICompAssembly, public Component { protected: using comp_it = std::vector::iterator; ///< Iterator type - using const_comp_it = std::vector::const_iterator; ///< Const iterator type + using const_comp_it = + std::vector::const_iterator; ///< Const iterator type public: /// String description of the type of component diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h index c301aca85d8b..aaf251206b4e 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjCompAssembly.h @@ -46,7 +46,8 @@ namespace Geometry { class MANTID_GEOMETRY_DLL ObjCompAssembly : public virtual ICompAssembly, public virtual ObjComponent { using comp_it = std::vector::iterator; ///< Iterator type - using const_comp_it = std::vector::const_iterator; ///< Const iterator type + using const_comp_it = + std::vector::const_iterator; ///< Const iterator type public: /// String description of the type of component std::string type() const override { return "ObjCompAssembly"; } diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h index 12385412020d..c6fa3fc9bb47 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterFactory.h @@ -68,7 +68,7 @@ class MANTID_GEOMETRY_DLL ParameterFactory { /// A typedef for the instantiator using AbstractFactory = Kernel::AbstractInstantiator; - using FactoryMap = std::map >; + using FactoryMap = std::map>; /// The map holding the registered class names and their instantiators static FactoryMap s_map; }; diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h index 4d2120d4c5bf..2002187149a5 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h @@ -54,17 +54,23 @@ class Instrument; Code Documentation is available at: */ /// Parameter map iterator typedef -using component_map_it = tbb::concurrent_unordered_multimap >::iterator; -using component_map_cit = tbb::concurrent_unordered_multimap >::const_iterator; +using component_map_it = + tbb::concurrent_unordered_multimap>::iterator; +using component_map_cit = tbb::concurrent_unordered_multimap< + ComponentID, boost::shared_ptr>::const_iterator; class MANTID_GEOMETRY_DLL ParameterMap { public: /// Parameter map typedef - using pmap = tbb::concurrent_unordered_multimap >; + using pmap = tbb::concurrent_unordered_multimap>; /// Parameter map iterator typedef - using pmap_it = tbb::concurrent_unordered_multimap >::iterator; + using pmap_it = tbb::concurrent_unordered_multimap< + ComponentID, boost::shared_ptr>::iterator; /// Parameter map iterator typedef - using pmap_cit = tbb::concurrent_unordered_multimap >::const_iterator; + using pmap_cit = tbb::concurrent_unordered_multimap< + ComponentID, boost::shared_ptr>::const_iterator; /// Default constructor ParameterMap(); /// Const constructor diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h b/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h index 5033068f3ac0..d7b11738945d 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/RectangularDetector.h @@ -212,7 +212,8 @@ MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &, const RectangularDetector &); using RectangularDetector_sptr = boost::shared_ptr; -using RectangularDetector_const_sptr = boost::shared_ptr; +using RectangularDetector_const_sptr = + boost::shared_ptr; } // Namespace Geometry } // Namespace Mantid diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h index ce1b5f4fad19..fdfb8b637d15 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h @@ -193,7 +193,8 @@ MANTID_GEOMETRY_DLL std::ostream &operator<<(std::ostream &, const StructuredDetector &); using StructuredDetector_sptr = boost::shared_ptr; -using StructuredDetector_const_sptr = boost::shared_ptr; +using StructuredDetector_const_sptr = + boost::shared_ptr; } // namespace Geometry } // namespace Mantid #endif // STRUCTUREDDETECTOR_H diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h index 1c0c7a16cdc4..20cae05ac533 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h @@ -63,7 +63,8 @@ class DLLExport CompositeImplicitFunction protected: std::vector m_Functions; - using FunctionIterator = std::vector::const_iterator; + using FunctionIterator = + std::vector::const_iterator; }; } } diff --git a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h index 87a1023e55c0..a017602c9869 100644 --- a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h @@ -42,7 +42,12 @@ class MANTID_GEOMETRY_DLL SurfaceFactory { private: // workaround because gcc 4.4 cannot have std::unique_ptr inside a std::map. // http://stackoverflow.com/questions/7342703/gcc-4-4-4-5-unique-ptr-not-work-for-unordered-set-unordered-map - using MapType = std::vector > >; ///< Storage of surface pointers + using MapType = + std::vector>>; ///< + ///Storage + ///of + ///surface + ///pointers static SurfaceFactory *FOBJ; ///< Effective "this" MapType SGrid; ///< The tally stack diff --git a/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp b/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp index 6378c827da7e..82278e59f50d 100644 --- a/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp +++ b/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp @@ -117,7 +117,8 @@ double XMLInstrumentParameter::createParamValue( if (!m_logfileID.empty()) { // get value from time series - using StatisticsMapType = std::map; + using StatisticsMapType = + std::map; StatisticsMapType statistics_types; statistics_types.emplace("first_value", Kernel::Math::FirstValue); statistics_types.emplace("last_value", Kernel::Math::LastValue); diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h index e9b79fdd159b..0557002c49ca 100644 --- a/Framework/Geometry/test/CSGObjectTest.h +++ b/Framework/Geometry/test/CSGObjectTest.h @@ -1147,7 +1147,7 @@ class CSGObjectTest : public CxxTest::TestSuite { private: /// Surface type - using STYPE = std::map >; + using STYPE = std::map>; /// set timeTest true to get time comparisons of soild angle methods const static bool timeTest = false; diff --git a/Framework/Geometry/test/ParameterMapTest.h b/Framework/Geometry/test/ParameterMapTest.h index f9c03f4d78a8..bfa297487d90 100644 --- a/Framework/Geometry/test/ParameterMapTest.h +++ b/Framework/Geometry/test/ParameterMapTest.h @@ -304,7 +304,9 @@ class ParameterMapTest : public CxxTest::TestSuite { test_Replacing_Existing_Parameter_On_A_Copy_Does_Not_Update_Original_Value_Using_AddHelpers_As_Strings() { // -- Specialized Helper Functions -- - using AddFuncHelper = boost::function; + using AddFuncHelper = boost::function; // double AddFuncHelper faddDouble; diff --git a/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h b/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h index 64e7e0721acc..4147d2a9e1fa 100644 --- a/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h +++ b/Framework/ICat/inc/MantidICat/GSoap/stdsoap2.h @@ -2430,7 +2430,8 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_rand(void); #endif /* soap_traverse() traversal/walker routines take walker function arguments */ -using soap_walker = void (struct soap *, void *, int, const char *, const char *); +using soap_walker = void(struct soap *, void *, int, const char *, + const char *); SOAP_FMAC5 int SOAP_FMAC6 soap_serve(struct soap *soap); SOAP_FMAC5 int SOAP_FMAC6 soap_serve_request(struct soap *soap); diff --git a/Framework/Kernel/inc/MantidKernel/ANN/ANN.h b/Framework/Kernel/inc/MantidKernel/ANN/ANN.h index 66646cfd0a6c..dff6a293d751 100644 --- a/Framework/Kernel/inc/MantidKernel/ANN/ANN.h +++ b/Framework/Kernel/inc/MantidKernel/ANN/ANN.h @@ -766,8 +766,8 @@ const int ANN_N_SHRINK_RULES = 4; // number of shrink rules // Some types and objects used by kd-tree functions // See src/kd_tree.h and src/kd_tree.cpp for definitions //---------------------------------------------------------------------- -class ANNkdStats; // stats on kd-tree -class ANNkd_node; // generic node in a kd-tree +class ANNkdStats; // stats on kd-tree +class ANNkd_node; // generic node in a kd-tree using ANNkd_ptr = ANNkd_node *; // pointer to a kd-tree node class DLL_API ANNkd_tree : public ANNpointSet { diff --git a/Framework/Kernel/inc/MantidKernel/Cache.h b/Framework/Kernel/inc/MantidKernel/Cache.h index f8ff898e1161..eb6167cad323 100644 --- a/Framework/Kernel/inc/MantidKernel/Cache.h +++ b/Framework/Kernel/inc/MantidKernel/Cache.h @@ -169,7 +169,8 @@ template class DLLExport Cache { /// iterator typedef using CacheMapIterator = typename std::map::iterator; /// const_iterator typedef - using CacheMapConstIterator = typename std::map::const_iterator; + using CacheMapConstIterator = + typename std::map::const_iterator; }; } // namespace Kernel diff --git a/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Framework/Kernel/inc/MantidKernel/ConfigService.h index 0b9f4daa61e4..1da60b745ee0 100644 --- a/Framework/Kernel/inc/MantidKernel/ConfigService.h +++ b/Framework/Kernel/inc/MantidKernel/ConfigService.h @@ -359,8 +359,10 @@ EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; using ConfigService = Mantid::Kernel::SingletonHolder; -using ConfigValChangeNotification = Mantid::Kernel::ConfigServiceImpl::ValueChanged; -using ConfigValChangeNotification_ptr = const Poco::AutoPtr &; +using ConfigValChangeNotification = + Mantid::Kernel::ConfigServiceImpl::ValueChanged; +using ConfigValChangeNotification_ptr = + const Poco::AutoPtr &; } // namespace Kernel } // namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/DataService.h b/Framework/Kernel/inc/MantidKernel/DataService.h index 12a78532ade3..788d75a803fa 100644 --- a/Framework/Kernel/inc/MantidKernel/DataService.h +++ b/Framework/Kernel/inc/MantidKernel/DataService.h @@ -75,7 +75,8 @@ struct CaseInsensitiveCmp { template class DLLExport DataService { private: /// Typedef for the map holding the names of and pointers to the data objects - using svcmap = std::map, CaseInsensitiveCmp>; + using svcmap = + std::map, CaseInsensitiveCmp>; /// Iterator for the data store map using svc_it = typename svcmap::iterator; /// Const iterator for the data store map diff --git a/Framework/Kernel/inc/MantidKernel/DiskBuffer.h b/Framework/Kernel/inc/MantidKernel/DiskBuffer.h index 5806a3deb46b..9322b0a94e0b 100644 --- a/Framework/Kernel/inc/MantidKernel/DiskBuffer.h +++ b/Framework/Kernel/inc/MantidKernel/DiskBuffer.h @@ -61,7 +61,14 @@ class DLLExport DiskBuffer { * Index 1: Position in the file. * Index 2: Size of the free block */ - using freeSpace_t = boost::multi_index::multi_index_container >, boost::multi_index::ordered_non_unique< ::boost::multi_index::const_mem_fun > > >; + using freeSpace_t = boost::multi_index::multi_index_container< + FreeBlock, boost::multi_index::indexed_by< + boost::multi_index::ordered_non_unique< + ::boost::multi_index::const_mem_fun< + FreeBlock, uint64_t, &FreeBlock::getFilePosition>>, + boost::multi_index::ordered_non_unique< + ::boost::multi_index::const_mem_fun< + FreeBlock, uint64_t, &FreeBlock::getSize>>>>; /// A way to index the free space by their size using freeSpace_bySize_t = freeSpace_t::nth_index<1>::type; diff --git a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h index 05f1a335f0a2..a1af17b73ffd 100644 --- a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h +++ b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h @@ -131,7 +131,8 @@ class MANTID_KERNEL_DLL FacilityInfo { /// this facility // TODO: remove RemoteJobManager form here (trac ticket #11373) - using ComputeResourcesMap = std::map >; + using ComputeResourcesMap = + std::map>; ComputeResourcesMap m_computeResources; ///< list of compute resources ///(clusters, etc...) available at /// this facility diff --git a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h index 924739756217..67f12f60fc93 100644 --- a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h +++ b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h @@ -90,7 +90,7 @@ class MANTID_KERNEL_DLL InstrumentInfo { /// Typedef for the zeropadding holder, first is starting run-number, /// second is file prefix - zero padding pair - using ZeroPaddingMap = std::map >; + using ZeroPaddingMap = std::map>; /// get the zeropadding part int getZeroPadding(ZeroPaddingMap::const_iterator it) const { return it->second.second; diff --git a/Framework/Kernel/inc/MantidKernel/MRUList.h b/Framework/Kernel/inc/MantidKernel/MRUList.h index 59d3dadfee05..33a8dcee1b7b 100644 --- a/Framework/Kernel/inc/MantidKernel/MRUList.h +++ b/Framework/Kernel/inc/MantidKernel/MRUList.h @@ -48,10 +48,16 @@ namespace Kernel { template class DLLExport MRUList { private: /// hideous typedef for the container holding the list - using item_list = typename boost::multi_index::multi_index_container, boost::multi_index::hashed_unique< ::boost::multi_index::const_mem_fun > > >; + using item_list = typename boost::multi_index::multi_index_container< + T *, + boost::multi_index::indexed_by< + boost::multi_index::sequenced<>, + boost::multi_index::hashed_unique<::boost::multi_index::const_mem_fun< + T, std::uintptr_t, &T::hashIndexFunction>>>>; /// This typedef makes an ordered item list (you access it by the 1st index) - using ordered_item_list = typename boost::multi_index::nth_index::type; + using ordered_item_list = + typename boost::multi_index::nth_index::type; /// The most recently used list mutable item_list il; diff --git a/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h b/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h index 2ab313617113..e8fa5ef6424e 100644 --- a/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h +++ b/Framework/Kernel/inc/MantidKernel/NearestNeighbours.h @@ -104,7 +104,8 @@ template class DLLExport NearestNeighbours { public: // typedefs for code brevity using VectorType = Eigen::Matrix; - using NearestNeighbourResults = std::vector >; + using NearestNeighbourResults = + std::vector>; /** Create a nearest neighbour search object * diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManager.h b/Framework/Kernel/inc/MantidKernel/PropertyManager.h index 40d847287ed5..e9b4e33ab162 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyManager.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyManager.h @@ -135,7 +135,7 @@ class MANTID_KERNEL_DLL PropertyManager : virtual public IPropertyManager { const std::unordered_set &ignoreProperties); /// typedef for the map holding the properties - using PropertyMap = std::map >; + using PropertyMap = std::map>; /// The properties under management PropertyMap m_properties; /// Stores the order in which the properties were declared. diff --git a/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h b/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h index 5a3493f1efdc..2a64ff336c20 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyManagerDataService.h @@ -53,7 +53,8 @@ class MANTID_KERNEL_DLL PropertyManagerDataServiceImpl final EXTERN_MANTID_KERNEL template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; -using PropertyManagerDataService = Mantid::Kernel::SingletonHolder; +using PropertyManagerDataService = + Mantid::Kernel::SingletonHolder; } // Namespace Kernel } // Namespace Mantid diff --git a/Framework/Kernel/inc/MantidKernel/Unit.h b/Framework/Kernel/inc/MantidKernel/Unit.h index 3cbb16907fb8..26374a5194af 100644 --- a/Framework/Kernel/inc/MantidKernel/Unit.h +++ b/Framework/Kernel/inc/MantidKernel/Unit.h @@ -229,10 +229,12 @@ class MANTID_KERNEL_DLL Unit { using ConstantAndPower = std::pair; /// Lists, for a given starting unit, the units to which a 'quick conversion' /// can be made - using UnitConversions = tbb::concurrent_unordered_map; + using UnitConversions = + tbb::concurrent_unordered_map; /// The possible 'quick conversions' are held in a map with the starting unit /// as the key - using ConversionsMap = tbb::concurrent_unordered_map; + using ConversionsMap = + tbb::concurrent_unordered_map; /// The table of possible 'quick conversions' static ConversionsMap s_conversionFactors; }; diff --git a/Framework/Kernel/src/ANN/kd_tree.h b/Framework/Kernel/src/ANN/kd_tree.h index 01d9e464154f..e47a54f1574b 100644 --- a/Framework/Kernel/src/ANN/kd_tree.h +++ b/Framework/Kernel/src/ANN/kd_tree.h @@ -70,7 +70,9 @@ class ANNkd_node { // generic kd-tree node (empty shell) // for building the tree. //---------------------------------------------------------------------- -using ANNkd_splitter = void (*)(ANNpointArray, ANNidxArray, const ANNorthRect &, int, int, int &, ANNcoord &, int &); // num of points on low side (returned) +using ANNkd_splitter = void (*)(ANNpointArray, ANNidxArray, const ANNorthRect &, + int, int, int &, ANNcoord &, + int &); // num of points on low side (returned) //---------------------------------------------------------------------- // Leaf kd-tree node diff --git a/Framework/Kernel/src/ANN/pr_queue.h b/Framework/Kernel/src/ANN/pr_queue.h index ff6d7db8a636..ca53d2ee82b3 100644 --- a/Framework/Kernel/src/ANN/pr_queue.h +++ b/Framework/Kernel/src/ANN/pr_queue.h @@ -32,7 +32,7 @@ //---------------------------------------------------------------------- // Basic types. //---------------------------------------------------------------------- -using PQinfo = void *; // info field is generic pointer +using PQinfo = void *; // info field is generic pointer using PQkey = ANNdist; // key field is distance //---------------------------------------------------------------------- diff --git a/Framework/Kernel/src/MaterialXMLParser.cpp b/Framework/Kernel/src/MaterialXMLParser.cpp index e376188d2ef2..f1411168f7cc 100644 --- a/Framework/Kernel/src/MaterialXMLParser.cpp +++ b/Framework/Kernel/src/MaterialXMLParser.cpp @@ -65,7 +65,8 @@ using BuilderMethod = MaterialBuilder &(MaterialBuilder::*)(ArgType); template struct TypedBuilderHandle final : public BuilderHandle { // Remove const/reference qualifiers from ArgType - using ValueType = typename std::remove_const::type>::type; + using ValueType = typename std::remove_const< + typename std::remove_reference::type>::type; explicit TypedBuilderHandle(BuilderMethod m) : BuilderHandle(), m_method(m) {} diff --git a/Framework/Kernel/test/MultiFileNameParserTest.h b/Framework/Kernel/test/MultiFileNameParserTest.h index 85eb85dead2b..d5754a82f95f 100644 --- a/Framework/Kernel/test/MultiFileNameParserTest.h +++ b/Framework/Kernel/test/MultiFileNameParserTest.h @@ -19,7 +19,7 @@ class MultiFileNameParserTest : public CxxTest::TestSuite { } static void destroySuite(MultiFileNameParserTest *suite) { delete suite; } - using ParsedRuns = std::vector >; + using ParsedRuns = std::vector>; ///////////////////////////////////////////////////////////////////////////// // Testing of parseMultiRunString. diff --git a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h index ae59b224e1c9..7b76f388e850 100644 --- a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h +++ b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h @@ -180,7 +180,8 @@ class SNSLiveEventDataListener : public API::LiveListener, // maps to variable name // (variable names are unique, so we don't need to worry about device names.) - using NameMapType = std::map, std::string>; + using NameMapType = + std::map, std::string>; NameMapType m_nameMap; // --------------------------------------------------------------------------- @@ -195,7 +196,8 @@ class SNSLiveEventDataListener : public API::LiveListener, // Maps the device ID / variable ID pair to the actual packet. Using a map // means we will only keep one packet (the most recent one) for each variable - using VariableMapType = std::map, boost::shared_ptr >; + using VariableMapType = std::map, + boost::shared_ptr>; VariableMapType m_variableMap; // Process all the variable value packets stored in m_variableMap diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h index 2e582a03d626..271c61fca3b2 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Integrate3DEvents.h @@ -67,7 +67,9 @@ struct IntegrationParameters { */ -using EventListMap = std::unordered_map > >; +using EventListMap = + std::unordered_map>>; using PeakQMap = std::unordered_map; class DLLExport Integrate3DEvents { diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h index 2952d8e2b55e..c770267191d9 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h @@ -53,7 +53,8 @@ class DLLExport LoadSQW2 : public API::IFileLoader { private: /// Local typedef for - using SQWWorkspace = DataObjects::MDEventWorkspace, 4>; + using SQWWorkspace = + DataObjects::MDEventWorkspace, 4>; void init() override; void exec() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h index ada40278317e..aed554526a03 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDEventWSWrapper.h @@ -50,7 +50,8 @@ class MDEventWSWrapper; using fpVoidMethod = void (MDEventWSWrapper::*)(); /// signature for the internal templated function pointer to add data to an /// existing workspace -using fpAddData = void (MDEventWSWrapper::*)(float *, uint16_t *, uint32_t *, coord_t *, size_t) const; +using fpAddData = void (MDEventWSWrapper::*)(float *, uint16_t *, uint32_t *, + coord_t *, size_t) const; /// signature for the internal templated function pointer to create workspace using fpCreateWS = void (MDEventWSWrapper::*)(const MDWSDescription &); diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h index a857f1102d3f..e39225d31795 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h @@ -69,7 +69,8 @@ class MANTID_MDALGORITHMS_DLL ForegroundModelFactoryImpl }; /// Typedef singleton instance to ForegroundFactory -using ForegroundModelFactory = Kernel::SingletonHolder; +using ForegroundModelFactory = + Kernel::SingletonHolder; } } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h index 4ccac15f70c6..7f6e826cba43 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h @@ -70,7 +70,8 @@ class MANTID_MDALGORITHMS_DLL MDResolutionConvolutionFactoryImpl }; /// Typedef singleton instance to MDResolutionConvolutionFactory -using MDResolutionConvolutionFactory = Kernel::SingletonHolder; +using MDResolutionConvolutionFactory = + Kernel::SingletonHolder; } } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h index 2b15e099219f..d869716128e4 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h @@ -66,7 +66,8 @@ class DLLExport SimulateResolutionConvolvedModel /// The input domain boost::shared_ptr m_calculatedValues; /// The output workspace type - using QOmegaWorkspace = DataObjects::MDEventWorkspace, 4>; + using QOmegaWorkspace = + DataObjects::MDEventWorkspace, 4>; /// The output workspace boost::shared_ptr m_outputWS; diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp index c98032f79725..c4ca06ff0f13 100644 --- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp +++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp @@ -450,7 +450,7 @@ void MDNormDirectSC::calculateNormalization( PhysicalConstants::meV * 1e-20 / (PhysicalConstants::h * PhysicalConstants::h); const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0)); - using VectorDoubleProperty = Kernel::PropertyWithValue >; + using VectorDoubleProperty = Kernel::PropertyWithValue>; auto *rubwLog = dynamic_cast(exptInfoZero.getLog("RUBW_MATRIX")); if (!rubwLog) { diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp index bc80e73cfbb8..2d4d6ba74233 100644 --- a/Framework/MDAlgorithms/src/MDNormSCD.cpp +++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp @@ -403,7 +403,7 @@ void MDNormSCD::calculateNormalization( getProperty("SolidAngleWorkspace"); const auto &exptInfoZero = *(m_inputWS->getExperimentInfo(0)); - using VectorDoubleProperty = Kernel::PropertyWithValue >; + using VectorDoubleProperty = Kernel::PropertyWithValue>; auto *rubwLog = dynamic_cast(exptInfoZero.getLog("RUBW_MATRIX")); if (!rubwLog) { diff --git a/Framework/MDAlgorithms/src/SaveMD.cpp b/Framework/MDAlgorithms/src/SaveMD.cpp index 57e53480d49a..9461c7ac2a76 100644 --- a/Framework/MDAlgorithms/src/SaveMD.cpp +++ b/Framework/MDAlgorithms/src/SaveMD.cpp @@ -17,7 +17,7 @@ #include "MantidKernel/System.h" #include -using file_holder_type = std::unique_ptr< ::NeXus::File>; +using file_holder_type = std::unique_ptr<::NeXus::File>; using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/MDAlgorithms/src/SaveMD2.cpp b/Framework/MDAlgorithms/src/SaveMD2.cpp index 56db72040b16..6f5717415df4 100644 --- a/Framework/MDAlgorithms/src/SaveMD2.cpp +++ b/Framework/MDAlgorithms/src/SaveMD2.cpp @@ -18,7 +18,7 @@ #include "MantidDataObjects/BoxControllerNeXusIO.h" #include "MantidKernel/ConfigService.h" -using file_holder_type = std::unique_ptr< ::NeXus::File>; +using file_holder_type = std::unique_ptr<::NeXus::File>; using namespace Mantid::Kernel; using namespace Mantid::API; diff --git a/Framework/MDAlgorithms/src/SmoothMD.cpp b/Framework/MDAlgorithms/src/SmoothMD.cpp index 6f2891f26407..34d380cd7b6c 100644 --- a/Framework/MDAlgorithms/src/SmoothMD.cpp +++ b/Framework/MDAlgorithms/src/SmoothMD.cpp @@ -36,10 +36,13 @@ using WidthVector = std::vector; using KernelVector = std::vector; // Typedef for an optional md histo workspace -using OptionalIMDHistoWorkspace_const_sptr = boost::optional; +using OptionalIMDHistoWorkspace_const_sptr = + boost::optional; // Typedef for a smoothing function -using SmoothFunction = boost::function; +using SmoothFunction = boost::function; // Typedef for a smoothing function map keyed by name. using SmoothFunctionMap = std::map; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h index ba484e549419..d926e13c9259 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/AsType.h @@ -73,7 +73,11 @@ template struct AsType { template struct apply { // Deduce if type is correct for policy, needs to be convertible to // ReturnType - using type = typename boost::mpl::if_c::value, AsTypeImpl, AsType_Requires_New_Type_Automatically_Convertible_To_Original >::type; + using type = typename boost::mpl::if_c< + std::is_convertible::value, + AsTypeImpl, + AsType_Requires_New_Type_Automatically_Convertible_To_Original< + InputType>>::type; }; }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h index 2a4ef9f0d6f6..1d33ec6e22ba 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/MatrixToNumpy.h @@ -88,9 +88,14 @@ template struct MatrixRefToNumpy { template struct apply { // Typedef that removes and const or reference qualifiers from the return // type - using non_const_type = typename std::remove_const::type>::type; + using non_const_type = typename std::remove_const< + typename std::remove_reference::type>::type; // MPL compile-time check that T is a reference to a Kernel::Matrix - using type = typename boost::mpl::if_c, is_matrix >::value, MatrixRefToNumpyImpl, MatrixRefToNumpy_Requires_Reference_To_Matrix_Return_Type >::type; + using type = typename boost::mpl::if_c< + boost::mpl::and_, + is_matrix>::value, + MatrixRefToNumpyImpl, + MatrixRefToNumpy_Requires_Reference_To_Matrix_Return_Type>::type; }; }; @@ -128,7 +133,10 @@ struct MatrixToNumpy { // Typedef that removes any const from the type using non_const_type = typename std::remove_const::type; // MPL compile-time check that T is a std::vector - using type = typename boost::mpl::if_c::value, MatrixRefToNumpyImpl, MatrixToNumpy_Requires_Matrix_Return_By_Value >::type; + using type = typename boost::mpl::if_c< + is_matrix::value, + MatrixRefToNumpyImpl, + MatrixToNumpy_Requires_Matrix_Return_By_Value>::type; }; }; } diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h index 911c6f796024..fea7b26f85d6 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/RemoveConst.h @@ -100,7 +100,8 @@ template struct RemoveConst_Requires_Pointer_Return_Value {}; // call to this struct template struct RemoveConstSharedPtrImpl { using ConstElementType = typename ConstSharedPtr::element_type; - using NonConstElementType = typename std::remove_const::type; + using NonConstElementType = + typename std::remove_const::type; using NonConstSharedPtr = typename boost::shared_ptr; inline PyObject *operator()(const ConstSharedPtr &p) const { @@ -129,7 +130,9 @@ struct RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value {}; struct RemoveConst { template struct apply { // Deduce if type is correct for policy, needs to be a "T*" - using type = typename boost::mpl::if_c::value, RemoveConstImpl, RemoveConst_Requires_Pointer_Return_Value >::type; + using type = typename boost::mpl::if_c< + std::is_pointer::value, RemoveConstImpl, + RemoveConst_Requires_Pointer_Return_Value>::type; }; }; @@ -140,7 +143,10 @@ struct RemoveConstSharedPtr { template struct apply { // Deduce if type is correct for policy, needs to be a // "boost::shared_ptr" - using type = typename boost::mpl::if_c::value, RemoveConstSharedPtrImpl, RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value >::type; + using type = typename boost::mpl::if_c< + IsConstSharedPtr::value, RemoveConstSharedPtrImpl, + RemoveConstSharedPtr_Requires_SharedPtr_Const_T_Pointer_Return_Value< + T>>::type; }; }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h index b8e0de8b9446..ba9e1d2eff14 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/ToWeakPtr.h @@ -80,7 +80,9 @@ template struct ToWeakPtr_Requires_Shared_Ptr_Return_Value {}; struct ToWeakPtr { template struct apply { // Deduce if type is correct for policy - using type = typename boost::mpl::if_c::value, ToWeakPtrImpl, ToWeakPtr_Requires_Shared_Ptr_Return_Value >::type; + using type = typename boost::mpl::if_c< + IsSharedPtr::value, ToWeakPtrImpl, + ToWeakPtr_Requires_Shared_Ptr_Return_Value>::type; }; }; diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h index a8f712d71969..7f7cb2046bbd 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/VectorToNumpy.h @@ -85,9 +85,14 @@ template struct VectorRefToNumpy { // The boost::python framework calls return_value_policy::apply::type template struct apply { // Typedef that removes and const or reference qualifiers from the type - using non_const_type = typename std::remove_const::type>::type; + using non_const_type = typename std::remove_const< + typename std::remove_reference::type>::type; // MPL compile-time check that T is a reference to a std::vector - using type = typename boost::mpl::if_c, is_std_vector >::value, VectorRefToNumpyImpl, VectorRefToNumpy_Requires_Reference_To_StdVector_Return_Type >::type; + using type = typename boost::mpl::if_c< + boost::mpl::and_, + is_std_vector>::value, + VectorRefToNumpyImpl, + VectorRefToNumpy_Requires_Reference_To_StdVector_Return_Type>::type; }; }; @@ -126,7 +131,10 @@ struct VectorToNumpy { // Typedef that removes any const from the type using non_const_type = typename std::remove_const::type; // MPL compile-time check that T is a std::vector - using type = typename boost::mpl::if_c::value, VectorRefToNumpyImpl, VectorToNumpy_Requires_StdVector_Return_By_Value >::type; + using type = typename boost::mpl::if_c< + is_std_vector::value, + VectorRefToNumpyImpl, + VectorToNumpy_Requires_StdVector_Return_By_Value>::type; }; }; } diff --git a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp index 80b6cae9b855..082b034567b4 100644 --- a/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/CloneMatrixWorkspace.cpp @@ -38,7 +38,8 @@ PyArrayObject *cloneArray(MatrixWorkspace &workspace, DataField field, npy_intp stride(0); // Find out which function we need to call to access the data - using ArrayAccessFn = const MantidVec &(MatrixWorkspace::*)(const size_t) const; + using ArrayAccessFn = + const MantidVec &(MatrixWorkspace::*)(const size_t) const; ArrayAccessFn dataAccesor; /** * Can do better than this with a templated object that knows how to access diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp index e4a4c0ed9877..d2621202c0de 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/Algorithm.cpp @@ -40,13 +40,24 @@ using PythonParallelAlgorithm = AlgorithmAdapter; using PythonDistributedAlgorithm = AlgorithmAdapter; // declarePyAlgProperty(property*,doc) -using declarePropertyType1 = void (*)(boost::python::object &, Mantid::Kernel::Property *, const std::string &); +using declarePropertyType1 = void (*)(boost::python::object &, + Mantid::Kernel::Property *, + const std::string &); // declarePyAlgProperty(name, defaultValue, validator, doc, direction) -using declarePropertyType2 = void (*)(boost::python::object &, const std::string &, const boost::python::object &, const boost::python::object &, const std::string &, const int); +using declarePropertyType2 = void (*)(boost::python::object &, + const std::string &, + const boost::python::object &, + const boost::python::object &, + const std::string &, const int); // declarePyAlgProperty(name, defaultValue, doc, direction) -using declarePropertyType3 = void (*)(boost::python::object &, const std::string &, const boost::python::object &, const std::string &, const int); +using declarePropertyType3 = void (*)(boost::python::object &, + const std::string &, + const boost::python::object &, + const std::string &, const int); // declarePyAlgProperty(name, defaultValue, direction) -using declarePropertyType4 = void (*)(boost::python::object &, const std::string &, const boost::python::object &, const int); +using declarePropertyType4 = void (*)(boost::python::object &, + const std::string &, + const boost::python::object &, const int); #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" diff --git a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp index 5fb70dde0595..69bb97725cdc 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp @@ -11,7 +11,8 @@ using namespace boost::python; GET_POINTER_SPECIALIZATION(AnalysisDataServiceImpl) void export_AnalysisDataService() { - using ADSExporter = DataServiceExporter; + using ADSExporter = + DataServiceExporter; auto pythonClass = ADSExporter::define("AnalysisDataServiceImpl"); pythonClass.def("Instance", &AnalysisDataService::Instance, return_value_policy(), diff --git a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp index 9648e9df0248..2b17e22dd612 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp @@ -18,19 +18,35 @@ void export_BinaryOperations() { using namespace boost::python; // Typedefs the various function types - using binary_fn_md_md = IMDWorkspace_sptr (*)(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &, const std::string &, bool, bool); - using binary_fn_md_gp = WorkspaceGroup_sptr (*)(const IMDWorkspace_sptr, const WorkspaceGroup_sptr, const std::string &, const std::string &, bool, bool); - using binary_fn_gp_md = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, const IMDWorkspace_sptr, const std::string &, const std::string &, bool, bool); - using binary_fn_gp_gp = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, const WorkspaceGroup_sptr, const std::string &, const std::string &, bool, bool); - - using binary_fn_mh_mh = IMDHistoWorkspace_sptr (*)(const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr, const std::string &, const std::string &, bool, bool); - - using binary_fn_md_db = IMDWorkspace_sptr (*)(const IMDWorkspace_sptr, double, const std::string &, const std::string &, bool, bool); - using binary_fn_mh_db = IMDHistoWorkspace_sptr (*)(const IMDHistoWorkspace_sptr, double, const std::string &, const std::string &, bool, bool); - using binary_fn_gp_db = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, double, const std::string &, const std::string &, bool, bool); + using binary_fn_md_md = IMDWorkspace_sptr ( + *)(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &, + const std::string &, bool, bool); + using binary_fn_md_gp = WorkspaceGroup_sptr ( + *)(const IMDWorkspace_sptr, const WorkspaceGroup_sptr, + const std::string &, const std::string &, bool, bool); + using binary_fn_gp_md = WorkspaceGroup_sptr ( + *)(const WorkspaceGroup_sptr, const IMDWorkspace_sptr, + const std::string &, const std::string &, bool, bool); + using binary_fn_gp_gp = WorkspaceGroup_sptr ( + *)(const WorkspaceGroup_sptr, const WorkspaceGroup_sptr, + const std::string &, const std::string &, bool, bool); + + using binary_fn_mh_mh = IMDHistoWorkspace_sptr ( + *)(const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr, + const std::string &, const std::string &, bool, bool); + + using binary_fn_md_db = IMDWorkspace_sptr ( + *)(const IMDWorkspace_sptr, double, const std::string &, + const std::string &, bool, bool); + using binary_fn_mh_db = IMDHistoWorkspace_sptr ( + *)(const IMDHistoWorkspace_sptr, double, const std::string &, + const std::string &, bool, bool); + using binary_fn_gp_db = WorkspaceGroup_sptr ( + *)(const WorkspaceGroup_sptr, double, const std::string &, + const std::string &, bool, bool); // Always a return a Workspace_sptr - using ReturnWorkspaceSptr = return_value_policy >; + using ReturnWorkspaceSptr = return_value_policy>; // Binary operations that return a workspace using boost::python::def; diff --git a/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp index 88a617d4bb95..60de8bbbdceb 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/CompositeFunction.cpp @@ -13,9 +13,11 @@ GET_POINTER_SPECIALIZATION(CompositeFunction) namespace { using getParameterType1 = double (CompositeFunction::*)(size_t) const; -using getParameterType2 = double (CompositeFunction::*)(const std::string &) const; +using getParameterType2 = + double (CompositeFunction::*)(const std::string &) const; -using setParameterType2 = void (CompositeFunction::*)(const std::string &, const double &, bool); +using setParameterType2 = void (CompositeFunction::*)(const std::string &, + const double &, bool); #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp index be19095f2fb0..7e892d026eed 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IFunction.cpp @@ -54,7 +54,8 @@ GCC_DIAG_OFF(conversion) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType1_Overloads, setParameter, 2, 3) // setProperty(index,value,explicit) -using setParameterType2 = void (IFunction::*)(const std::string &, const double &, bool); +using setParameterType2 = void (IFunction::*)(const std::string &, + const double &, bool); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads, setParameter, 2, 3) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(tie_Overloads, tie, 2, 3) diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp index 390c73c4957b..38480dd58b83 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp @@ -38,12 +38,15 @@ GET_POINTER_SPECIALIZATION(MatrixWorkspace) namespace { /// Typedef for data access, i.e. dataX,Y,E members -using data_modifier = Mantid::MantidVec &(MatrixWorkspace::*)(const std::size_t); +using data_modifier = + Mantid::MantidVec &(MatrixWorkspace::*)(const std::size_t); /// return_value_policy for read-only numpy array -using return_readonly_numpy = return_value_policy >; +using return_readonly_numpy = + return_value_policy>; /// return_value_policy for read-write numpy array -using return_readwrite_numpy = return_value_policy >; +using return_readwrite_numpy = + return_value_policy>; //------------------------------- Overload macros --------------------------- #ifdef __clang__ diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp index 9b8daa3240fd..8bce6bdea86d 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MultipleFileProperty.cpp @@ -17,7 +17,7 @@ using namespace boost::python; namespace { /// The PropertyWithValue type -using HeldType = std::vector >; +using HeldType = std::vector>; /** * Converts the value from a MultipleFileProperty to a python object rather than diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp index c1cc7cc3584e..3ded562f0ae9 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceFactory.cpp @@ -73,7 +73,9 @@ void export_WorkspaceFactory() { const char *createFromScratchDoc = "Create a clean new worksapce of the given size."; - using createFromScratchPtr = MatrixWorkspace_sptr (WorkspaceFactoryImpl::*)(const std::string &, const size_t &, const size_t &, const size_t &) const; + using createFromScratchPtr = MatrixWorkspace_sptr ( + WorkspaceFactoryImpl::*)(const std::string &, const size_t &, + const size_t &, const size_t &) const; class_("WorkspaceFactoryImpl", no_init) diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp index 886d034e307f..696b7904f1be 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/Goniometer.cpp @@ -42,7 +42,8 @@ void setR(Goniometer &self, const object &data) { void export_Goniometer() { // return_value_policy for read-only numpy array - using return_readonly_numpy = return_value_policy >; + using return_readonly_numpy = + return_value_policy>; class_("Goniometer", init<>(arg("self"))) .def(init((arg("self"), arg("other")))) diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp index 7b411cb9e74a..be82085147f6 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/OrientedLattice.cpp @@ -45,7 +45,8 @@ Mantid::Kernel::V3D hklFromQ(OrientedLattice &self, const object &vec) { void export_OrientedLattice() { /// return_value_policy for read-only numpy array - using return_readonly_numpy = return_value_policy >; + using return_readonly_numpy = + return_value_policy>; class_>( "OrientedLattice", diff --git a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp index ca407057476c..d8a6c0fb89ee 100644 --- a/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp +++ b/Framework/PythonInterface/mantid/geometry/src/Exports/UnitCell.cpp @@ -67,7 +67,8 @@ void export_UnitCell() { .export_values(); /// return_value_policy for read-only numpy array - using return_readonly_numpy = return_value_policy >; + using return_readonly_numpy = + return_value_policy>; class_( "UnitCell", diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp index ba07c31b9f6a..365d7a182bcf 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/ArrayProperty.cpp @@ -24,7 +24,8 @@ using namespace boost::python; namespace { /// return_value_policy for cloned numpy array -using return_cloned_numpy = return_value_policy >; +using return_cloned_numpy = + return_value_policy>; #define EXPORT_ARRAY_PROP(type, prefix) \ class_, bases>>, \ diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp index 5792ea62ff74..4149d476e7a3 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyManagerDataService.cpp @@ -48,7 +48,8 @@ void export_PropertyManagerDataService() { register_ptr_to_python(); - using PMDExporter = DataServiceExporter; + using PMDExporter = + DataServiceExporter; auto pmdType = PMDExporter::define("PropertyManagerDataServiceImpl"); pmdType.def("Instance", &PropertyManagerDataService::Instance, diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp index e8119bea4d8a..ff875b073324 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Statistics.cpp @@ -180,7 +180,9 @@ GCC_DIAG_ON(conversion) //============================================ // Function pointer to real implementation of getMoments -using MomentsFunction = std::vector (*)(const std::vector &, const std::vector &, const int); +using MomentsFunction = std::vector(*)(const std::vector &, + const std::vector &, + const int); /** * The implementation for getMomentsAboutOrigin & getMomentsAboutOriginMean for diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp index e74509990f18..86d0f2bb481c 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Exports/UnitConversion.cpp @@ -7,7 +7,9 @@ using namespace boost::python; void export_UnitConversion() { // Function pointer typedef - using StringVersion = double (*)(const std::string &, const std::string &, const double, const double, const double, const double, const DeltaEMode::Type, const double); + using StringVersion = double ( + *)(const std::string &, const std::string &, const double, const double, + const double, const double, const DeltaEMode::Type, const double); class_("UnitConversion", no_init) .def("run", (StringVersion)&UnitConversion::run, diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp index a728650d18d0..17530ed6d4fa 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Registry/PropertyWithValueFactory.cpp @@ -16,7 +16,8 @@ namespace PythonInterface { namespace Registry { namespace { /// Lookup map type -using PyTypeIndex = std::map >; +using PyTypeIndex = + std::map>; /** * Initialize lookup map @@ -66,7 +67,8 @@ const PyTypeIndex &getTypeIndex() { } // Lookup map for arrays -using PyArrayIndex = std::map >; +using PyArrayIndex = + std::map>; /** * Initialize lookup map @@ -75,18 +77,18 @@ void initArrayLookup(PyArrayIndex &index) { assert(index.empty()); // Map the Python array types to the best match in C++ - using FloatArrayHandler = SequenceTypeHandler >; + using FloatArrayHandler = SequenceTypeHandler>; index.emplace("FloatArray", boost::make_shared()); - using StringArrayHandler = SequenceTypeHandler >; + using StringArrayHandler = SequenceTypeHandler>; index.emplace("StringArray", boost::make_shared()); - using LongIntArrayHandler = SequenceTypeHandler >; + using LongIntArrayHandler = SequenceTypeHandler>; index.emplace("LongIntArray", boost::make_shared()); #if PY_MAJOR_VERSION < 3 // Backwards compatible behaviour - using IntArrayHandler = SequenceTypeHandler >; + using IntArrayHandler = SequenceTypeHandler>; index.emplace("IntArray", boost::make_shared()); #endif } diff --git a/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp b/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp index 4c5d4cb6e911..eb9f856cde50 100644 --- a/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp +++ b/Framework/PythonInterface/mantid/kernel/src/Registry/TypeRegistry.cpp @@ -15,7 +15,8 @@ namespace // /// Typedef the map of type_info -> handler objects. We store /// boost::python::type_info objects so that they work across DLL boundaries /// unlike std::type_info objects -using TypeIDMap = std::map >; +using TypeIDMap = std::map>; /** * Returns a reference to the static type map diff --git a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp index 7dd55b3bdc43..61e734beea9b 100644 --- a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp +++ b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp @@ -88,7 +88,8 @@ BOOST_PYTHON_MODULE(WorkspaceCreationHelper) { //=================================== // Typedef for function pointer to disabiguate references - using Signature1_MDHisto = MDHistoWorkspace_sptr (*)(double, size_t, size_t, Mantid::coord_t, double, std::string, double); + using Signature1_MDHisto = MDHistoWorkspace_sptr ( + *)(double, size_t, size_t, Mantid::coord_t, double, std::string, double); def("makeFakeMDHistoWorkspace", (Signature1_MDHisto)&makeFakeMDHistoWorkspace, makeFakeMDHistoWorkspace_overloads() diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h index a9f5665ea065..66d3c4b5b42c 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h @@ -45,7 +45,8 @@ class AbstractDoubleValueExtractor { const std::string &propertyName) const = 0; }; -using AbstractDoubleValueExtractor_sptr = boost::shared_ptr; +using AbstractDoubleValueExtractor_sptr = + boost::shared_ptr; class NumberDoubleValueExtractor : public AbstractDoubleValueExtractor { public: diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h index cdbcadabbcdf..fd5761a402db 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSourceSpectrum.h @@ -60,7 +60,8 @@ class MANTID_SINQ_DLL PoldiSourceSpectrum { }; using PoldiSourceSpectrum_sptr = boost::shared_ptr; -using PoldiSourceSpectrum_const_sptr = boost::shared_ptr; +using PoldiSourceSpectrum_const_sptr = + boost::shared_ptr; } } diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h index 4b43516f6fdd..798d08fb11b2 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h @@ -93,7 +93,8 @@ class DetectorElementData { double m_tofFactor; }; -using DetectorElementData_const_sptr = boost::shared_ptr; +using DetectorElementData_const_sptr = + boost::shared_ptr; class MANTID_SINQ_DLL PoldiTimeTransformer { public: From 951f1977407dc3ff1f0e5426ac60b9728e2a39b7 Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Thu, 15 Mar 2018 11:33:49 +0000 Subject: [PATCH 234/364] MuonMaxent is moved to New category --- docs/source/release/v3.12.0/muon.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 185ae1d95505..288c2d8f1f22 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -41,11 +41,15 @@ Bug fixes Algorithms ---------- +New +### + +- :ref:`MuonMaxent ` calculates a single frequency spectrum from multiple time domain spectra. + Improvements ############ - :ref:`MuonProcess ` now has a flag to determine if to crop the input workspace (default is true). In the Muon Analysis interface this flag has been set to false. -- :ref:`MuonMaxent ` calculates a single frequency spectrum from multiple time domain spectra. - :ref:`EstimateMuonAsymmetryFromCounts `: if the number of good frames is zero, then a value of 1 is assumed for the number of good frames. Bug fixes From 0a8a7da27e69ec9eda9ffbfc0effc0ff793f654c Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 11:37:47 +0000 Subject: [PATCH 235/364] Re #22107: Set to be checked by default in UI file. --- .../ISISReflectometry/ReflSettingsWidget.ui | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui index 823be8d95615..39cb00420365 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui +++ b/qt/scientific_interfaces/ISISReflectometry/ReflSettingsWidget.ui @@ -6,8 +6,8 @@ 0 0 - 764 - 631 + 858 + 679 @@ -605,7 +605,11 @@ - + + + true + + From 956ac2760d2238e3791d5871a4557bf637c5faad Mon Sep 17 00:00:00 2001 From: Elliot Oram Date: Wed, 14 Mar 2018 16:24:06 +0000 Subject: [PATCH 236/364] Speed up findingDetectors for IPeaks in PredictFractionalPeaks PredictFractionalPeaks was using a new raytracer for every peak it created and therefore throwing away the caching information about the bounding boxs of detectors / panels causing a huge slow down. Resolved by exposing the findDetector(raytracer) overload to IPeaks and using single raytracer for all calls. Work also include small refactor for const autos Refs #22060 --- .../Crystal/src/PredictFractionalPeaks.cpp | 20 ++++--- .../DataObjects/inc/MantidDataObjects/Peak.h | 2 +- Framework/DataObjects/src/Peak.cpp | 8 +++ .../inc/MantidGeometry/Crystal/IPeak.h | 2 + Framework/Geometry/test/MockObjects.h | 3 + .../mantid/api/src/Exports/IPeak.cpp | 3 +- qt/widgets/sliceviewer/test/MockObjects.h | 60 ------------------- 7 files changed, 27 insertions(+), 71 deletions(-) diff --git a/Framework/Crystal/src/PredictFractionalPeaks.cpp b/Framework/Crystal/src/PredictFractionalPeaks.cpp index 635338b4dcdd..1bf1b8f4caa5 100644 --- a/Framework/Crystal/src/PredictFractionalPeaks.cpp +++ b/Framework/Crystal/src/PredictFractionalPeaks.cpp @@ -9,6 +9,7 @@ #include "MantidAPI/WorkspaceFactory.h" #include "MantidDataObjects/PeaksWorkspace.h" #include "MantidGeometry/Crystal/OrientedLattice.h" +#include "MantidGeometry/Objects/InstrumentRayTracer.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/ArrayLengthValidator.h" #include "MantidKernel/EnabledWhenProperty.h" @@ -129,16 +130,16 @@ void PredictFractionalPeaks::exec() { V3D hkl; int peakNum = 0; - int NPeaks = Peaks->getNumberPeaks(); + const auto NPeaks = Peaks->getNumberPeaks(); Kernel::Matrix Gon; Gon.identityMatrix(); - double Hmin = getProperty("Hmin"); - double Hmax = getProperty("Hmax"); - double Kmin = getProperty("Kmin"); - double Kmax = getProperty("Kmax"); - double Lmin = getProperty("Lmin"); - double Lmax = getProperty("Lmax"); + const double Hmin = getProperty("Hmin"); + const double Hmax = getProperty("Hmax"); + const double Kmin = getProperty("Kmin"); + const double Kmax = getProperty("Kmax"); + const double Lmin = getProperty("Lmin"); + const double Lmax = getProperty("Lmax"); int N = NPeaks; if (includePeaksInRange) { @@ -147,7 +148,7 @@ void PredictFractionalPeaks::exec() { N = max(100, N); } IPeak &peak0 = Peaks->getPeak(0); - int RunNumber = peak0.getRunNumber(); + auto RunNumber = peak0.getRunNumber(); Gon = peak0.getGoniometerMatrix(); Progress prog(this, 0.0, 1.0, N); if (includePeaksInRange) { @@ -165,6 +166,7 @@ void PredictFractionalPeaks::exec() { vector> AlreadyDonePeaks; bool done = false; int ErrPos = 1; // Used to determine position in code of a throw + Geometry::InstrumentRayTracer tracer(Peaks->getInstrument()); while (!done) { for (double hOffset : hOffsets) { for (double kOffset : kOffsets) { @@ -190,7 +192,7 @@ void PredictFractionalPeaks::exec() { peak->setGoniometerMatrix(Gon); - if (Qs[2] > 0 && peak->findDetector()) { + if (Qs[2] > 0 && peak->findDetector(tracer)) { ErrPos = 2; vector SavPk{RunNumber, boost::math::iround(1000.0 * hkl1[0]), diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h index 844c24758c2f..82b728b87121 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h +++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h @@ -86,7 +86,7 @@ class DLLExport Peak : public Geometry::IPeak { Geometry::Instrument_const_sptr getInstrument() const override; bool findDetector() override; - bool findDetector(const Geometry::InstrumentRayTracer &tracer); + bool findDetector(const Geometry::InstrumentRayTracer &tracer) override; int getRunNumber() const override; void setRunNumber(int m_runNumber) override; diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp index f0607804cd6d..c99817f94740 100644 --- a/Framework/DataObjects/src/Peak.cpp +++ b/Framework/DataObjects/src/Peak.cpp @@ -628,6 +628,14 @@ bool Peak::findDetector() { return findDetector(tracer); } +/** + * Performs the same algorithm as findDetector() but uses a pre-existing + * InstrumentRayTracer object to be able to take adavtange of its caches. + * This method should be preferred if findDetector is to be called many times + * over the same instrument. + * @param tracer A reference to an existing InstrumentRayTracer object. + * @return true if the detector ID was found. + */ bool Peak::findDetector(const InstrumentRayTracer &tracer) { // Scattered beam direction V3D beam = detPos - samplePos; diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h index 9d871cd30587..2b8afe944721 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h @@ -11,6 +11,7 @@ namespace Mantid { namespace Geometry { +class InstrumentRayTracer; /** Structure describing a single-crystal peak * @@ -49,6 +50,7 @@ class MANTID_GEOMETRY_DLL IPeak { virtual Mantid::Kernel::V3D getQLabFrame() const = 0; virtual Mantid::Kernel::V3D getQSampleFrame() const = 0; virtual bool findDetector() = 0; + virtual bool findDetector(const InstrumentRayTracer &tracer) = 0; virtual void setQSampleFrame(const Mantid::Kernel::V3D &QSampleFrame, boost::optional detectorDistance) = 0; diff --git a/Framework/Geometry/test/MockObjects.h b/Framework/Geometry/test/MockObjects.h index 5427e27c2623..3ac5a0a72781 100644 --- a/Framework/Geometry/test/MockObjects.h +++ b/Framework/Geometry/test/MockObjects.h @@ -11,6 +11,7 @@ #include "MantidGeometry/Crystal/IPeak.h" #include "MantidGeometry/Crystal/PeakTransform.h" #include "MantidGeometry/Crystal/PeakTransformFactory.h" +#include "MantidGeometry/Objects/InstrumentRayTracer.h" #include "MantidKernel/SpecialCoordinateSystem.h" #include "MantidKernel/WarningSuppressions.h" #include @@ -80,6 +81,8 @@ class MockIPeak : public Mantid::Geometry::IPeak { MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D()); MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D()); MOCK_METHOD0(findDetector, bool()); + MOCK_METHOD1(findDetector, + bool(const Mantid::Geometry::InstrumentRayTracer &tracer)); MOCK_METHOD2(setQSampleFrame, void(const Mantid::Kernel::V3D &QSampleFrame, boost::optional detectorDistance)); MOCK_METHOD2(setQLabFrame, void(const Mantid::Kernel::V3D &QLabFrame, diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp index ecd32b1cad97..0e4d31109398 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp @@ -89,7 +89,8 @@ void export_IPeak() { ":class:`~mantid.geometry.Goniometer` rotation was NOT taken " "out.\n" "Note: There is no 2*pi factor used, so \\|Q| = 1/wavelength.") - .def("findDetector", &IPeak::findDetector, arg("self"), + .def("findDetector", (bool (IPeak::*)()) & IPeak::findDetector, + arg("self"), "Using the :class:`~mantid.geometry.Instrument` set in the peak, " "perform ray tracing to find " "the exact :class:`~mantid.geometry.Detector`.") diff --git a/qt/widgets/sliceviewer/test/MockObjects.h b/qt/widgets/sliceviewer/test/MockObjects.h index 8e5c21d29e16..52b357fc4e4d 100644 --- a/qt/widgets/sliceviewer/test/MockObjects.h +++ b/qt/widgets/sliceviewer/test/MockObjects.h @@ -160,66 +160,6 @@ class MockPeakOverlayFactory : public PeakOverlayViewFactory { void(boost::shared_ptr &)); }; -/*------------------------------------------------------------ -Mock IPeak -------------------------------------------------------------*/ -class MockIPeak : public Mantid::Geometry::IPeak { -public: - MOCK_METHOD1(setInstrument, - void(const Geometry::Instrument_const_sptr &inst)); - MOCK_CONST_METHOD0(getDetectorID, int()); - MOCK_METHOD1(setDetectorID, void(int m_DetectorID)); - MOCK_CONST_METHOD0(getDetector, Geometry::IDetector_const_sptr()); - MOCK_CONST_METHOD0(getInstrument, Geometry::Instrument_const_sptr()); - MOCK_CONST_METHOD0(getRunNumber, int()); - MOCK_METHOD1(setRunNumber, void(int m_RunNumber)); - MOCK_CONST_METHOD0(getMonitorCount, double()); - MOCK_METHOD1(setMonitorCount, void(double m_MonitorCount)); - MOCK_CONST_METHOD0(getH, double()); - MOCK_CONST_METHOD0(getK, double()); - MOCK_CONST_METHOD0(getL, double()); - MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D()); - MOCK_METHOD1(setH, void(double m_H)); - MOCK_METHOD1(setK, void(double m_K)); - MOCK_METHOD1(setL, void(double m_L)); - MOCK_METHOD3(setHKL, void(double H, double K, double L)); - MOCK_METHOD1(setHKL, void(const Mantid::Kernel::V3D &HKL)); - MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D()); - MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D()); - MOCK_METHOD0(findDetector, bool()); - MOCK_METHOD2(setQSampleFrame, void(const Mantid::Kernel::V3D &QSampleFrame, - boost::optional detectorDistance)); - MOCK_METHOD2(setQLabFrame, void(const Mantid::Kernel::V3D &QLabFrame, - boost::optional detectorDistance)); - MOCK_METHOD1(setWavelength, void(double wavelength)); - MOCK_CONST_METHOD0(getWavelength, double()); - MOCK_CONST_METHOD0(getScattering, double()); - MOCK_CONST_METHOD0(getDSpacing, double()); - MOCK_CONST_METHOD0(getTOF, double()); - MOCK_CONST_METHOD0(getInitialEnergy, double()); - MOCK_CONST_METHOD0(getFinalEnergy, double()); - MOCK_METHOD1(setInitialEnergy, void(double m_InitialEnergy)); - MOCK_METHOD1(setFinalEnergy, void(double m_FinalEnergy)); - MOCK_CONST_METHOD0(getIntensity, double()); - MOCK_CONST_METHOD0(getSigmaIntensity, double()); - MOCK_METHOD1(setIntensity, void(double m_Intensity)); - MOCK_METHOD1(setSigmaIntensity, void(double m_SigmaIntensity)); - MOCK_CONST_METHOD0(getBinCount, double()); - MOCK_METHOD1(setBinCount, void(double m_BinCount)); - MOCK_CONST_METHOD0(getGoniometerMatrix, Mantid::Kernel::Matrix()); - MOCK_METHOD1(setGoniometerMatrix, - void(const Mantid::Kernel::Matrix &m_GoniometerMatrix)); - MOCK_CONST_METHOD0(getBankName, std::string()); - MOCK_CONST_METHOD0(getRow, int()); - MOCK_CONST_METHOD0(getCol, int()); - MOCK_CONST_METHOD0(getDetPos, Mantid::Kernel::V3D()); - MOCK_CONST_METHOD0(getL1, double()); - MOCK_CONST_METHOD0(getL2, double()); - MOCK_CONST_METHOD0(getDetectorPosition, Mantid::Kernel::V3D()); - MOCK_CONST_METHOD0(getDetectorPositionNoCheck, Mantid::Kernel::V3D()); - MOCK_CONST_METHOD0(getPeakShape, const Mantid::Geometry::PeakShape &()); -}; - /*------------------------------------------------------------ Mock MDGeometry ------------------------------------------------------------*/ From d4e5901037f9f944f15ac1c52fa7ae272deba5a0 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 11:54:39 +0000 Subject: [PATCH 237/364] Re #22048: Applied clang-format patch. --- MantidPlot/src/Fit.h | 3 ++- MantidPlot/src/WindowFactory.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/MantidPlot/src/Fit.h b/MantidPlot/src/Fit.h index 2204852328c1..bd6a6bf2efda 100644 --- a/MantidPlot/src/Fit.h +++ b/MantidPlot/src/Fit.h @@ -48,7 +48,8 @@ class Fit : public Filter { using fit_function_simplex = double (*)(const gsl_vector *, void *); using fit_function = int (*)(const gsl_vector *, void *, gsl_vector *); using fit_function_df = int (*)(const gsl_vector *, void *, gsl_matrix *); - using fit_function_fdf = int (*)(const gsl_vector *, void *, gsl_vector *, gsl_matrix *); + using fit_function_fdf = int (*)(const gsl_vector *, void *, gsl_vector *, + gsl_matrix *); enum Algorithm { ScaledLevenbergMarquardt, diff --git a/MantidPlot/src/WindowFactory.h b/MantidPlot/src/WindowFactory.h index 6d7564a13fc3..46e7c447554a 100644 --- a/MantidPlot/src/WindowFactory.h +++ b/MantidPlot/src/WindowFactory.h @@ -101,7 +101,8 @@ class ProjectWindowInstantiator : public AbstractProjectInstantiator { class WindowFactoryImpl final { private: - using AbstractFactory = AbstractProjectInstantiator; + using AbstractFactory = + AbstractProjectInstantiator; public: WindowFactoryImpl(); @@ -172,7 +173,8 @@ class WindowFactoryImpl final { } /// A typedef for the map of registered classes - using FactoryMap = Mantid::Kernel::CaseInsensitiveMap >; + using FactoryMap = + Mantid::Kernel::CaseInsensitiveMap>; /// The map holding the registered class names and their instantiators FactoryMap _map; }; From b989df22b6346f742dbf446ad77c69d2e2137aaf Mon Sep 17 00:00:00 2001 From: Matthew Bowles Date: Thu, 15 Mar 2018 11:57:05 +0000 Subject: [PATCH 238/364] add screenshots / detail re #22102 --- docs/source/images/mslice_cut.png | Bin 0 -> 90917 bytes docs/source/images/mslice_interface.png | Bin 0 -> 52958 bytes docs/source/images/mslice_slice.png | Bin 0 -> 235932 bytes .../release/v3.12.0/direct_inelastic.rst | 16 +++++++++++++++- 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 docs/source/images/mslice_cut.png create mode 100644 docs/source/images/mslice_interface.png create mode 100644 docs/source/images/mslice_slice.png diff --git a/docs/source/images/mslice_cut.png b/docs/source/images/mslice_cut.png new file mode 100644 index 0000000000000000000000000000000000000000..0ab194f1daf03ac4122766d9b12d6acddbc6c74d GIT binary patch literal 90917 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

d_VEUfrnk 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 ZuT*UrMtZn#%Pa7oq^O)omCz^u{|7t4j==x` literal 0 HcmV?d00001 diff --git a/docs/source/images/mslice_interface.png b/docs/source/images/mslice_interface.png new file mode 100644 index 0000000000000000000000000000000000000000..e8f813f33d2fb3175dd0ad6b5342ef2f74796944 GIT binary patch literal 52958 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 JdFA%K{|~k7_PPK7 literal 0 HcmV?d00001 diff --git a/docs/source/images/mslice_slice.png b/docs/source/images/mslice_slice.png new file mode 100644 index 0000000000000000000000000000000000000000..e207a2177198aaaa466d4669cc1854c34606af74 GIT binary patch literal 235932 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�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

ETpR4!&b0fQwNrA#<+^wsZD`elAneHSbvw0cS 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 Ki7GL}fd2ytIH9)y literal 0 HcmV?d00001 diff --git a/docs/source/release/v3.12.0/direct_inelastic.rst b/docs/source/release/v3.12.0/direct_inelastic.rst index d6095c0aa2c8..37105436176a 100644 --- a/docs/source/release/v3.12.0/direct_inelastic.rst +++ b/docs/source/release/v3.12.0/direct_inelastic.rst @@ -8,7 +8,21 @@ Direct Inelastic Changes New features ------------ -- The `MSlice `_ user interface can now be lauched from the MantidPlot Interfaces menu. +- The `MSlice `_ user interface can now be launched from the MantidPlot Interfaces menu. +figure:: ../../images/mslice_interface.png + :class: screenshot + :align: center + +figure:: ../../images/mslice_slice.png + :class: screenshot + :align: center + +figure:: ../../images/mslice_cut.png + :class: screenshot + :align: center + + Similar to the slice viewer, MSlice plots slices and cuts from workspaces. It creates customisable publication quality figures. Cuts can be created interactively by dragging a rectangle across a slice, and information such as recoil lines and bragg peaks can be overplotted. + - The algorithms :ref:`algm-SofQWCentre`, :ref:`algm-SofQWPolygon` and :ref:`algm-SofQWNormalisedPolygon`, which rebin an inelastic workspace (has a `DeltaE` axis) from spectrum numbers (angle) to `MomentumTransfer` may now rebin the energy (`DeltaE`) axis as well as the :math:`|Q|` (`MomentumTransfer`) axes. - :ref:`algm-SofQWNormalisedPolygon` now has uses a faster method for calculating the polygon intersections. - The crystal field computation and fitting engine is now feature complete. It can now handle multi-site computation and simultaneous fitting of inelastic spectra and physical properties dataset. See the :ref:`Crystal Field Python Interface` help page for details, and ``_ for examples of use. From 36e19e4c9a7579a0019bb2ad8bf38f373e881153 Mon Sep 17 00:00:00 2001 From: Matthew Bowles Date: Thu, 15 Mar 2018 12:03:27 +0000 Subject: [PATCH 239/364] fix images re #22102 --- docs/source/release/v3.12.0/direct_inelastic.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/source/release/v3.12.0/direct_inelastic.rst b/docs/source/release/v3.12.0/direct_inelastic.rst index 37105436176a..356f73468219 100644 --- a/docs/source/release/v3.12.0/direct_inelastic.rst +++ b/docs/source/release/v3.12.0/direct_inelastic.rst @@ -9,15 +9,16 @@ New features ------------ - The `MSlice `_ user interface can now be launched from the MantidPlot Interfaces menu. -figure:: ../../images/mslice_interface.png + +.. figure:: ../../images/mslice_interface.png :class: screenshot :align: center -figure:: ../../images/mslice_slice.png +.. figure:: ../../images/mslice_slice.png :class: screenshot :align: center -figure:: ../../images/mslice_cut.png +.. figure:: ../../images/mslice_cut.png :class: screenshot :align: center From bfd3a60151005a28365100d19434efb3ca92f7f0 Mon Sep 17 00:00:00 2001 From: Matthew Bowles Date: Thu, 15 Mar 2018 12:11:47 +0000 Subject: [PATCH 240/364] adjust images re #22102 --- docs/source/images/mslice_cut.png | Bin 90917 -> 84582 bytes docs/source/images/mslice_interface.png | Bin 52958 -> 61854 bytes docs/source/images/mslice_slice.png | Bin 235932 -> 221743 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/source/images/mslice_cut.png b/docs/source/images/mslice_cut.png index 0ab194f1daf03ac4122766d9b12d6acddbc6c74d..fcf753b8abfbb25265cc37f337cf103f4ff65e49 100644 GIT binary patch literal 84582 zcmV)dK&QWnP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TU7=k$ItkQs2P-r-iQZcOS?zB>|NL`VV1fCisj(@s{b``@o;Y!$ zl$MrCWkp4Scl;D&ayc3I-M3OTc!-o%R%!*oFA~Qh{M@=ry%t)bq$DSwfAGG{K5S0; z;m03j&N=3mjW*guuDSX`$@HCVXnwL%>XG9&YpZ*I01qPbbvYHrqWtT0JO@E1sz z>Mah^gS#5lFZXII(f^#}a;1{f$}K4^*GewaYlU4)%hX(6q4_VfFhf{`Mj8@*l9y() z2yvJPO91gG;nSPBwHYhDhC2e#Q(ksk5`Ksvxg=Ku8uep#(Vm-W-`L{?2Q`?R{#e-r zXS*jjBp0>7)yhjFxAMV0g^(XSgm7Z~1*o3blHxFPh>Rcn5@z}aMQ{rBS?rcV!6k;- z27-0UG3_rYcdP5v6;I}p4FPAd$FDUiwL@=8orBR}#*}_$p;bQHL*mu}FNtRAx&+qN zqD$(A)_yThox{+!5~$Y7Bi?BjT0-lP5{K3>tClv?Dkj`Ck%hbTp_w{NMTk89OpR%| zO&6&YMJ?^YuKI871gpdmH?`ySM~tyOVX$|G`NIy+!ALz6%&J zmC%kEGg>m`6=nIYw%k^B+HF^P`<-{Bwze+0wS9!>l1?qTnqF^fqBc}x7ejbC^S%#W z^e=f^o0*?j$!cQ~tY9!SCmn@(BaDOuG&Mrp)I$H8mBeLp>VtbDvr^=nG+?~swF))N zY>ARHC1@o|$jZz6NSU(cGQCz*R7rWCDk-bzBYpbxlaeweYDm?T)R7h=9-3&9VquZa z<|Yj~V{wyrlbl&0kOsX+^?JAY!PdwT*VxK6X-%4b@?-f@YYo!wP@|O@8q2L^BOy&# z6NaS)8`2i;F?a0E4ny=45cP$+N&K4D^ro|4EJ#DVom8VmWt!A2$woxtE##+QN{}+f z@LE|WXk`-(Y0KnAV2LSQ^fxgF=g{!GFrlw74h!>^`$MmtdE?j?69bo4Cei75wXe(&Wr9e$YohwC&{I5U-$+ zUbT&S-ZY8E0*G<6ScPX8U)oK|()0G0lTREaC!Tncj2%C*aG!x^H|je8gevd6@siA| zB&~A5FnwpV(7sab=SxbUUQ>fKH8eCx6WkzJNO@J2yngF-vd9ASN%q^XwIH&hPqCJ3 zUUK>}qI^nJkwl{zxFxE*BxmmQsr4FWsd~t10g)BVO?rQL4=PvCtEEyM8?_Io|IasP z_1?Tx4Vg_Y`uEMU`w8dCm*bmdSpQNv>!c&)x~s30%zy#?^JkuYp8POwyfij8Xay9i zzg<8Qtdi3&nFK^g0zn{S(WD8tw{I{<+rUutss&?VS-@NaIl?Z!!V4kmJwcMCZmQ>x z+h`J`2|Im@>ixkFX+qSR%auru3e*ZNE3Z_dRw<=Q%ql7&Y<<*RC4H*;nKTWF8!7~- zF<8F1TC7ISLZrdX;v*lVfwWSNxEs{0-XWEt3=|d~X`~V@HHB-xJGyKAFk9z zv;OgApIC*fxtUMZCt=%7*c1Z77e9&K5*du@*W8jUgtR6`+)RTH{D)t2Ex0K{0@OOV zCO!fzSs{f3 zR|_-YoiNo*zG6PH4vxjpR3-iku=^rHeFtp}rv=m{D7X~zAMP`I^Fr=h%DUjc;70K3 zUp<62r%Jt`Grvi=v3*2yOhJgJB^)#@X(HZuL%g>oUnY4{KW0vDF}nnXIDu-DSX$>L z2|oA*YG-~Eb0N4yV?iW0719O@9yt6xXQkZOgqq~v04SzIkuXV;L9lzRcR_~0S5nZ#OA2*TVF zbK=g0CXShrtN`-a;vqI4v*9Q4k0!j665lB|6z_;25e|-a0ZDk)WKAE#NqnJYqzf~8 z{Rw}7e5!wSY*e-MyaVK<<44KyC!S~|Exb$9;I3l3wvd;yvT}LzwHIaHx#pCrL6Ec{ zJSkOj_TIbi$_vlEr2TvmQPZG#@2~gk5ihH_H@Z`iK^LVmkX7o?Rm;Y^6~f8M)W3r`+@AT?QbRbtL0ZX z_BWetCSQH^wPhd_looO*@u?J%X}G4aL1VTr@UJJ)YW1Q{{aO}3W;68 zDTb|Km>qd2MAU-dzjc5GZ(45lBw?XHX5T6Ts|9t^IB*YE1#ovPu@HtT+F)X5|AqT# zYq$_%;@8|%W8PcB$v|kMU%MBV5USl{n&97TQ{k9*ez4=u$|nYb89n}xA}6WgKc>&Z zO1xuEeA|D)EtQv6euE+UvunXGz>X#c?~!kQuX;h-9R1A^apZz|wce&YRRXHU=GyDZr0QyEM$*)-YHGu-MUnT>-+v?h`u3GfX@xX4 zHd%P3Wo2^3#h1z9f8SGqYb`^$n75Xi$BlBH)k{|GKmC4;yfNEC zviD&J$VZbKRSsOW*UbNf+U0ga5brizLepRgvpIu zb9$4xCH{#wG!RXLeZ3L_4xs@dzO?&sBAvvoW+Ra1mjLj{zuIB1X1(3a{1*Hu=t}KM zTx#M9L$*9YF_e)tY2G23NcAAIlm+(93>j(zp<(eC>{N%Heii5?_=kw9U%TJjxROu3 zhcLKeXJ+mT{+P$dRf7&!b*DixOl#qbHn?VOeB48$WcXI&=Zge|nRbA?*;!a292@H8 zUQ@v>Tve%m4N&zOW)e=kx0OG2Q_o4*ZL1JY^rvYl@*BcVr6Y;k(p~UF9yKjZ4W>79 zW3X$&F4`w{W;PY?p$rHwDT^fB7L}w+mE~8J24?l4KiXc9a?nJT!^ zp7Qp^W_GwG_XoG2)KcwKuWh>ZbJe0k9MLU=SMW=?$@38W(S%#fh4{Hg9l4Jo0P}~v zda|#|)V=0Uulgxue#|YVuT?&iI1^RKi`_GI`eHoMpQ$3ZLb_0Dz^&j{6>dE5(^uNu z^s1F-=`q+Jat5)Z!AzVJ-w#hwBDCK)zCu{nn@ zY1ful4cj#8$nalvb&X7!TrHDpYGktNgTkyT>I?R5s41${Z(Uuz4P9cMl5%TOGBsqj zA@cnXW8~$R-;h^ddrMw^E`6!vpu8s+;(ACQM0dO~*GYExNs)6M0y6AzUM6DG>F zr<^70%+W_Cj~iqDYgN^u#*fkP#%kEAxQ^4X#*USm2@^E_YAZK`mQzJ}sg#$O^FE-o zo0ahB3r|}U1wY%6A+qX9E6Hjrt)OZ}Q!B5qysV^ZRkd4bh2> zX={df7`f57xIYO4S*(#mi#G`iA4Wpd4{0ULawY2haBDAH;6 zgps(XRoY*;sy%*Vn5wKiQI@xGpOp>fs3#qIzm=a7QS#lCxO3&J&B8LhUd>N(KX&Gi zxVS%to0u(5?vF~%`lp)Ys!c@?xsU9Q~U; zC~`~E4yL+K(-#rqnlZ)Q7CmOw6zY@qj)r!CUhBM2->8CFpB1ykKG>OiK@pCENVwor zGii6IRjBK5fA~w>{I3Ilp*&m4y7NH0Y%_+I2gv-S6^Qq=*waR^2|0-MpUwyGvuKV4 zF1D+9Pw=M~gKDsgZ7c3M*XgF4GnK<4+YF%&rCZmYjuf^bXurSt#_g zNy03@swYfTnUawbMzU-{AJ^83;mvSQ@?-a^jYY2dM43KG#zhxjD-#+@WXzPjy!pY` za__wlO05zxcn7esLICy-G+Q%j$l+ycZrI^9e82^JuBFOB4qkaddGTNWkXvs5uk5n@ z@8#`xKa^1i9w|qxIIj%rQ)Y9|LZGCU`+~_zlJuHw2%q2R+dyAJe%2kaUjDe_kC&&P zea43T8kB{uq(p3^4K|S1KOL)f+H|xwhW4+JIr>*6cZ+;7x>nwQodTTN0AzC=@Vyz49O3 z%-E8ifYfKRjjaBO-E|6CCp-k)1CSc6hhuw{Dn)g8PK4ULQy16 z3e^?+OQpRK7MMy~@YLFzM!_u!H;u%5t2kx|R=Y{4`fD1@=rdu6HN z1LerW50Nc*_>+7y`bQJaa0dkK@q7OxgZt!6(w2tBp=wfNPS*VOM$%AUXJMC@m&uP` ze=3VDG{1Z`p~0RhP*z?c58d`}x&G?YW$(WnA;XtmLA^K2kE2J+67vj_-)+939C5-W zvi@e9N_}0uy5*&6z(5&$%lWd*@OkC4yKj}UO63L`7832UoT$E8N|ghZXnL_{rW?`W zPTBlJ=8~oM{EO_g)o9(>a||8*QjNIJ-d+9 zt35)3LGvykH@yD39RJ8G@~LvG+L~%veEwmw@1J)@;H1T$g>g#GXd3pK!IscUkO>Jo|XZMzrsN(+8tP;CmE>%5d zb5}Prt391yi7NBQJsLl8+sX*j2ebXziw>m?NA1FkFV%>wqJtaKwVZ~@z9%_VHt&r1 zP)Qut0jr)`wZ_E1^|}P6jZ_OB@`N5{Ze)m;Kkm4h2sjK+;9~99t~7Af#fFSt?YPfe z)ZYFQf5!R=2fZpHC2VuUoT%v6(qUn!j(hE&AJU?VqDk^#%F+>){vzcuiWuT#7%G-4 zWgN<1>ykNotXR=9qYQ%zWy^$0Bd)41!7rp&{hM8)N>$;;edY(He%J>lT!XT?fMyp~ z;xNgxwOeZy?3p*HVV4qqNDst2DhN?YPScabZ-hLCfu4mU=AQUb|CT57t9DAvE$`S9 zPq80}yIxBYe=&cgg*I!_Tl=%-6(q}A4_40Bbi=b|Qsa~g?LARiA6zr4rgGDJxd!_r zUVUCorTp1*kff=#(lkwF*P?hP!+ojylQ`3As&o~Urpek(TWm3A|y;w#FFsU!`p z)0c8Ds8|j`>mF<-D82d*9yC#6cMPa9MbX zBA%M+YT0VbO=SK-Iaz47a#?xtxn;$bmbK|xRzB*lQ1rK%rDha_tCTQRnHvS7ks2Gt4~1j#27MrED2;`LqSUOOh)%EeZ}v4+x~H#3n74mX%6rxhlPutGP_SRLaVf9AU3zSEdaT zzokl0khr36ant+FE|^R8J~kPIc$F%lLT~pc;Rl7kv^lMkFp5-}x{+233x9;K^&A!P zWl5u6A!pnZ#OJ|pNn$pA;o6QOe?@lWgNdmjjj1d7w=xLNL+r$@>}i8m)}bBR%UA8& zR_Z4S!#b@53)?B|OZDpCq23CmpW3tD+uTwJGX2ZB8kBw{tZW z+JwF1RfW#HwTgCu93?7kXZp|?+{{1ba1ZXmEpbo$wD=^^oqRs#v4*mUZKy0zUP%7@v%)G zZ)s80@)54@VP{tNQEx{Uxg^r~0hg=lWNvdmoKc@v&9Lh~#q+ud}93{w``R5Drqu;lWx$7-8NL%u;@ zv}N-24^PRs7pvu+_g<9&{rf3lLc*g_Kq4$?r8~r@5izGJ3}G4tQoa3Z8mPdSl5lNS zqLR=bn;V3l`9ZiN@iJKx^Mi~?LYzWunk%a?%N!~~bK{KV!R&M5pL?o%;pD;A+!pa(pC-}2Gs5^71cnOG>M<5QG zPreecOUS6jtNugYHPhUxb{3sJa2mXYX}1t1_mDOW77c#QvtIBN8lGNE1y5Wl1G5NW zT0qn~hQv$a4hVt2FfUKz(0{X0KUOA`MM`mp#;(K`y_$$1c(XV#>g&Vo%tjMqFQCNE zUSR6kUPAn7&&`X6Hxajxo-lme9QN+hva)E+zxq}GmKJ0cVw&{LYA(2?QEcC0 zKt~9PjiR+%D;Luy4y|u$@tfF%w3#OA6zEbn7TgM&7ISh*bc&=d3#Nz`zi9+xi(A2r zrgah$q}(D}91X!3Ev@DP()Soz+(O$+Z1}fEfZ}5di_mVYy;*xu7qc@j;n~BlJy7b- zLt$aWP_PT8WtMzS?{+UK;(2UTl z+TLh-4_k6HHs@?ytEpM-G*1JE&o9?J@}wMd&*Sp>m^!Jeu9ijSpI!d8$Ig;jPf6N| zC!QeBKKram23Rez?6S+sBJ->$yWW3}%r>A@N!kSY!@{e{ZYyjd_4!7t1c=S;cit@@ zzW=uLSCVF(r$!!l0D6*@R1{{rno$!PI$`e7z=EYU2`CtIqsWvh!m|Le$2WfSLDI*H zJL{pbr(@L4(8vazq6KImZh|26jI!o1j8$%P(n`uJrL0u-l}gmgs%&l=B#pdfvPfW% zJh5U^J75OYi7_EBmN$!tt3{-)dPztFmRzk-s~x*o1aFiLegg0l%f;*yN36_^hNSU@ z1_fbDJSXwnA91L{rSOZJHnMzEAW}wrlSWApnyo<2jI^SZlxpjP7+aDXo3v4BIX5kD;JR5Yn7Rh$)FLxkOkwC>e^YVJ$ui zS!>z8=4b=@7rr1vI<1TV=~3Uf+rLGPf7K*@>>e~)9u}U4Q&3iBdQBvf_W1GeX?mI( zSq(}_6Ng^aA7q#>Q2cPU`t1lv0A5qxL;EM6DJ1UZ#!$TePwlJVDY+y*T5f59IR%gQ zO93Sw3gH&)C^gj-MHucbj-#MST#9Z2dSkdZ2_Z&PK(IFy{DyF+%7-EGuNPv&l-LAJ z9l?yj>NSK-+iAHH3vG|9+R{!`8$MEKJG2F!kqU!>P)fQ?pK%0fxx79SUZ)pLoK|8VcZmKa9{3n`pJ4w3*Yi)6=;T2UN zZHcGohqQ$jOS2B~*)?$omJjocLBr6D(042`PhUCZ#1mzk9si^xZDNQBuX;o1g951v z@#|IZv#YA+2Hy9L7A|ozC+(}x-jhWZ7%t;$g9M7uh&E1Hi3qU-;LdwGY`TwIUMlTXSd7zA+G(nbLdTHt3udm#F z@BifEkKU1f{rc;>BNUQ#=&G?Iu+r9xCJ@(1Fp`Ve@glNJQX8s^SBiiYbpZdd3QW2~ z2d#?A3ajfh94$5b+Te!SGGK9QoZeWrTH|`azaXZfm=xuPjpj7$ABw;qz!@$S_njmiIEW*Q+AQ` zu>C~6?dPHmT8SDP9Ycx;-||9;dSxgEeI#jCXQWrdu#QLlgpPA7WT7*AS21 zMA}VbK{bViCGDauB+l)oHMFx9AFceUA?<2z*d_6q8LM;{`mfD0 zYFn;o)gO;qZ0fXAdlJ+xv{{jPhV+%&{&lqtSB}_dGwp{ft)C;1LNvhi(NGMv*MCOB z-hS;xS#-hSB9%kbdmu~G1epU?pg~VG75)0jo0l9fE3Ce%)PDK7_Wev}ApHp$Q&p-2 zjefy)tk8SoGP{ldqDH?0A)|ZLkOFB_)uer6qjHe9z8@!_eDaCxFzPh<^t(w?TRTM- z9X?F<*;7dxt2>W9{y2I1>1S-NPrY`?E3UATY`np`T5!rn2^mtV3AK(}J8hQ3!c_0R z=RSG;^_P{T^^0X^Bu3-bM5zf4dj6tOHRvgT05xmo`NP&o8ZRtN`lDU2-DuT}o8BCy zDA)y37z$Kx3x4#U7hN1uBrPKh2spf7T!b@89N}0m28y*w?q&<){$R^|? zxEYx;Go%nn9z;YHOF}HnM50roFK*3aMhPXi5SPt8W31gssa75@_ZY7#D=)rW)Sfw9 zfuxmM8i`K}SMywN`^MDQ*J^$nrJ6xBG#Gh@;(ygIOz7Lw;2mNrRwio$wVB+JmM|-K?H9aiJVYWH8&@Fd~bA zYJ8fE0E~KxUxqw{M(UFIY;l9O7n8c`7hDPR^-9Xrjj|0v7)jF)9LOX0(oTriNLrE} zhMq~qPlY`{q|H(bH1c3+lG@-Ft_8QkMSsa~lGm8`5SFS$)Z5}${}WFvXyH*x3^AB+ zuQm1IzkWu}7cy zb^K&djS*I*K|4#4j@PcyqMgJ{BWQ z^rv7G{f0{tC-1rN-r!!|0?Zrj(>zh0cCpsK@W-va4m6cOHJ#M4&x1VN*-z{vd!Pq8us(o$Mh zscEi|vOayRf-97uLDHC)#@U^Lq=iZ7NQI1`G%9J)Yoke(kf>?SAT%02tk`m`=^-z4 z(6Lhpk}f4d5GM^2|1rNdGzg)AaB5hMCLKbbH;I|K>9yI22ziD8g-jKsXj(2vb;5(B zW+fGvOH0bb=?PjlVS=`jIEz%n*AQBUIW=AEPoq~Fp~ZvLu)ap>*f3Cu8q1zds>X(| zw^&bhQQ+GUy+>jbJZd~z{~CtX3F%Zj2qWoa zW7-BbomKK0$hxM7`_Mz$jI1#iG3ZGxuyR&Eb`J@&G%D20{d||id3v;wa*hq_LmR1( z3Wmum^+UzTXUK=ujkb$WKY)B9X;eS<)DwOpUHq9K2Ph*e7P}%TL`}XGyX7-6;ADhJ zk@zmS1#V^)Q}Bx?uF0KRSgK3gQATD^lWKyUnz=FYXZ2hh2aZH#esJSnE`%TSxTFF} zr7zf-b?~V6tvn?$@T<0V3HE^J(`riX6YnXs4(BI({7i)QH0xn)Cq>64wv${9YCwx((8jEjXEiu*uWG`-A-Y)@+@B=c+OYZ!Ve9)( z-`{f&u9ShCWNvmvDBNGrhM$6=1^Q~X{DnNW_EM||MYp#?rnJSq_`Zl~-9J5~!zvCJ zaAf)y-%i$kmwvX{8Jo>G!VXKzUfb8HMnDYKWd#$tu8 zDo*r^5y!D!EJBB^h^1)Imywx+U8s6%GG-GS5r}sM|G4Yb-b6}T^exN|`4*kJ<0sr7 z{Bw(ij9EPqE~LvOWGoseW3fPA>vWBvX(tR>vwhMkDy>szc#C`4u(zR6i3-O%C>aO` zv}&i!AEZYW(jyxNRc2_Nj>c_~YdC?RL58%`*L1|ZGBg&XK->%I2*Y=TY4#dkkg#bN zqh_RQ`9_VyhIX}uLT2r<)4k6bLg#jJiPAH9Yy6rna{Or2;Hbf#)cK0u7? zry}Gq$!8iAfm#JyHCUl)zC#wxSa4I1!LNBr%7JUJp-L?dJSmckLhH-CYWdmSE#~B= zBxUJ1uu&v|n0LL2t4)<4PIC$&#z0!#8*VDfOTkm(i~H>oehTSnP14c`#+Gn?7A#6l zgVs0t&{+{E?H&)>uF%*&KW5otM>{dAls~ST4}!F-g&D{h?-%_I!%!CG&y&_VT9C9l zs^Av|RU6X~o-;H>S4FWCNb6}X;oZv>m*h#qUa#T#!!4L2Ods8n8)DlHX46{u_R7Xw zuvbkXU{&ggxmo5$?D}u*3m5u^%wFQfHnpf$|G<6Yzs--S#tBuKmW1o ztTRGB`{Hx!6kEdOWl*ftR{dB7+Z#h)ky@DKi*i8G>Dg6(f?55j9exT*?<}aa8-Era z9cj4Qy-CL!{03rRyW|74D|EKpZ+cQjdekpO&RmioO?xCLCPgx$QW^-HULh++Xe~m6;O>8}qlA*T>K>q>Fo+n$ar}BQ0viACe!tuf9&N8orVu zlUQ+8b6p+7jD)Wwgt!RX!qqS#7)cp0KM!*tcp*JTV6@zMV#qQz#W=f_VW^ZqfT&Ze zPsj))g1_KS*^!qZ6%3NS&_M(h#lM7ag`IRRkPzIAl$v`|C;CU4!@>e?3h^WcwJ&H3 z;RFN!A+B6j>&A!^B#wGid*X|6a--!SNUThvrm(q%)VbkPw zFNma_*l=f=65sMbdX3m>o3S`7i9zy7{p!7z0?mx226z3z#AI=^B(HjD1?*=KHaC&D z;?4F#B)$;7eeG(lEiRkm6ysI<hZJxQ9>jc~Z#!qg0euvH~tW3~|&{3O@-k!5!H zFIM#nCH?F;oBBCv`#g@LP9hAGttqnSgX zcnNN%><09q@XU<27;Z>SqLSYvafaXtP09^xHSwQBlo*4);1_!uOkj>i-mr&BDr~4p z^Js*OP8)Kjoh^G{(dk;}TT*7^%?d(6rwv(&!)vz65t3#4gajt!$4FsJ4@uz9>_TPp z6Z}Hl2p94N!BV1?5IPH&do*0aw7hUqfTad=$OjD)NgDRqgji5E9N zW5R+^P{EG+wxPhB%}?W=2x5%oNV@q8o7M&rYs08qxmWGjCk%-lr#Tp@!5@Um+|{3@ zA;f9+*cky*lAM&i9dfVXLWH=61MpEu`q(ywxrF#74!yUu+$Nz~82BT>a37avv%^>U^s~fIKIG7U@!c@Do8!t_KN3Zycxd@k_k3pLoR>`H1W3$tC z6g{fFJ)3I4&c2|7b#h2 z!(TwFJUC_yR-V5+NJCU0)-6|i)S^WZ(oSvV!`hDmw^n}B28C%;X2Z11DSZsPCI09b zp7rQPS_(tAYteuSwT-; zuth>bXN;5#a$qYv%POQSS;@&I*9JqQi3HN}r;4i$?@`Wt-sp{_*`OMvRCb8Dx-(zPh^~gObjZpJ--Y2nGGjLA z@u51qQdnxzup!kDF(Xn&szRQFG%OHY>WHh_S~-XNC@a2sLVArPlOC-%8z!}TLtPez zfgyiofsoN2Y@rFm$4J!Fj*W7ufQ${1g}NhuEF1`L2Q5cUe~|L=aX=nauc z5!Td_q$c46YsXK;PpS7=fS9b}>czge&dn}p+wkAIofP}!b;f(Em3^YIiyERm8r~JW z^0*;haX@cwc#duWciecFCQ|akixPia3D+zl@Ta{)5+)CP=u;A47Y*r`0e0qJwbnl; zb`dGB7I5M>-bWk}1#R*D#SX3PT6<5s(Pxou`rPW88d-F{Ic48J@022GPdsJP0m#SV zi!Ew|jhi9}$2d<4xECT!xuI>}Ef}oa@L-HLu<5)n*lHeXn%-Y!2K6q8=s3>e>J&N-=#j)in?w=Ftpeunv|awr^K)Q z0*y-zF|Pr*rv0@ktEVH&N%`N?Pr({xrC zp$&vKq$+6})@E?F_8o38JO1=){<)W%aMt$44fcN1G*ZUq)bbO4Nj{oj<>-mfI;MIH zEwux6-r6a&ox=SI%uf;yZ8M_K27`~_CtmPtCfcUzEN#JtCTr$kG+Xq%iV~}Won^s( zQf`TTI*e8@M@5p@LYncL+!(Ej5xgX>dMVseKxjFo~%~_E|tte=^07wg&n0Y7^$qb?+sfghQze!9TicmduB!XWWv5{C>^{1uL z6y?1GS)LZSnYQhi0d$83q$qAE5mx6xJ8ev-U9{mGf=&YGlK4q`wfAPC|2YV81;p?= zlr2NrXY16oPHS73UMy{;rga=(YMT}?qOwzfu= zn17h;v)8W0BrPv%tg@oq^6y*a`m3*$I-7*XT*>CRxNjpYK+S4{>y80?B$vl2%4#xvaHSHpNM)43WlQAycOR6;J}Q?j{;-ae)I-!}2C`CGQ6_l}FVpa?Jn`rU zviSPz$&hSAt7&>a2h2U2@cHZV(pw)(|M}ODm6o29LE=>Uvr?vMXlC!S8O#)6fB*K= z@?~~GS#|08jI42T!OSCp4u`|xa5%aplnnImUm<6lrzCB=?d9vSwNg_vSr#2WhwN7@ zNn;-MnyalO*WYlnTz&P`GGW4$B$SM>b;aawACVjX@rC?u|3Aq*6>NWi3oGXIn*Tul zb>4qvnXUgQOU>JdJHn*&X0|y9li6*BU7l&=3cZ&}{P`v&ESVCU=+4ng5I@_iOwCNj z&X!lpvsd3N{kPm(mZ_K^-~BK}s)h`fGL4uOcf=p=gGh!6-$ZMxF*_)33lqh^kXui^ zLFU`*C|P4zPFQ(KdRf_7QaMQ;yYzOMYp17_qf}2EEA=IVBs2awdG75h`SovBl8mhuZPa350)IHfy=5_i!{Kl^9FE?A0sX7w zyo)bWlD30`NuVu+iwv*Kt86w|&^qPG7 z?O3TAwzw>@&~TaZ!)G#X%=a>(d9V!amyt}l$k!iyBC{nN|v7O2f62}TO_;k=CbCm7L?krM@zqjmXLw+y}a`Lt5TyRXQ350 zlVO!V$`@~cA$6rS^23-ZvcS@7$w{vEmJ`g^2utu18DrIwbe#!uzVH$Rq4)k3n&s>9_+)z_ER$~WJPk$E&f z!)MFNcW*r-pZqvQ1}(Un4DT~RCg#iJ`xow(*S{^1CD&M2hLz=I$UF;6WqyKu@bPyt z*CGo^Ijc026geCYhr{9M;m}Th;DEkz?LV%S9d_J7z8P05)zwJSX1CRyVSfQttoTM6 z#4p<$u;l=fptQ1ml`>hWsGJ~=-gc9G-_TFWzI{%fc;j>FGuuEZFDaM4ef!Cz@1B;Y zU;I=C4;>=ky?npC_3dP-`Q~YP@Yzpg*s#9x{cHb`dmnyRhW4+Ohwr*r-kUf?hG#yJ z`yYHs8Y;`B|B&G_|3U-hi%0(}qe})#-^vQpNNAc<51?Qqd%D-gkq1mt8>S z>HniVa@PY=SJ^19+<%k2H>OmE*1RJRJo&aXS2BmLbspMQS<#D?LrGbqeEICZ<&pPl zWWI_YMY{O>bTF??wmQ1hmIIA)T3{P@lC{1Vi66^b zAAhQ4hvaSQGI!<5l`B`ST=h)FKAPN`VCk>R$gl@ zS#qO|Wbn7|$&>~*YHgi|wpGY0xksOu!Lr(V8_41tZYm2@eu$GH2tL^6B`zRFs8N4#@wo z1?G`~gXWcm7gu3Wit<;qphR)Kv@4P{lKi zCraNzl{RsW!@uLEpB%N+%&|jiww>r3>ZB=KF6CpNmxsPwKn^|n5LtL&h1lUlU1eBQ zUDuY7kOrk=V219L?wFwkK?y;+I~3_|7-s11Mkxs?l^!~z1!+lq&-=dL53Y+j z*O@uz?7jBdYu)#~*4a3VM{s_-^vLWiWl56O)0w!exD}P=)YHftC|eof4#jfkBC;{t zVqPgXLt;aKyr~kP_T-y}h`m{r>*NvUtOGF}!t0wA zt9T_W)sAZ?M+lK2%T>Ej@(8EVfft;MnRmc{tb_MSw()0eYj7-GaxJW4xa-vQYHQ@h zM#ETF%ALokHS1Y(j>vxpL`!cKr{%HXhV^a&TH@}YcS(P_BEI?T*JF2Jf8+fna|HJj z*_622ZF3WF9eB+?D5Ta@taE)Iw#6}^i zh8c-WJeu0?taAD!w7b*Q0&ex;e;Y(J{#lb}+w)50dWJhLIqxCfVnfq)*eEpJpH}@~S6lQ_f13HL5clxcX zUA(GSwR%<`(OghJ=bxrLycV{rljT^{%=^1c0n4h4bu$S;sM#g=* z?zl&HjAM}4z~bAJjfFku$9PNQrc2)>ZMWHMo4$tyhM$G z>X64|zB4>)^4OhyVjwGP*J&skpHpO>6F)ln6U-tKJ%K)9@^2Hnx<{K2Mx!SF!FkNd7-$6N~(ou=SIx-qUH=Y3p!ya6ew|dv8d8+y6~qcI##+#0u%8RQ{hW8ly)JH^d<_YhQjYHx_vMi2b?YW=Tb-p}l=&O1lsTzfOoXzYwJlDNZ_q>2uv| zyq9njBMl}2ALe{H7jqZ}+FG{atz0Eeml!UYxrmazLsf~%AcgZ)L@fsI@3oaRr}xcA z4zNUlI!bb9S`!nf8nB!`9ILW8RI#f0TPQ%0SjmJ922{ektdZ8RI zpzI*xjj-eKXeu2+=EVYxVJNW*zVu|9WDUC#9(sSkXF{F5$ybBs3d| z^j__fzfT3N>vmB?LuXHyAQYzF;p*AiPTmO_vFa?WRwiwYRmDH>eRF^Rj(g$bjoWy(}56RH7{^*4xHV$DDkx2>SXXS`g0}!Gp2-* z7F&$G7}&`}57SK8ja=H|{fZz?sExt;%cFTK2I#^k<;etH#Ci4LyuPWGPwVAm)kYXn zGi4CT!W{f>)b1*3ErR0Y*yuC*1;4*pTt41Rr>@8)6>0cB1_hk)hKf7aG*TT? z=V9wXlhNibCoi&3c?-#CidQ8~_it!QD@a5O_F3>r8%kYt567S)`LmJ)|HfNE7jI=m6XTb>;PQl-;%|^Ws5cgP$-Ei6;-L zPFkn=Uo0y*KCP{-49c-XDs-OZ^6)9yV^{97@fJk9r{R4)z0_5nDryu zycPe8??Q|0474dJDNdF3_4PfoS{N5&`+QURBk+Ld*TLSvV5yABb^bgW9To@A3^Djj zLw)uK%ZAP4zv(9#Ie&ry*@7XM^vRPa)~33;g5O6ATvj?+Mt(qsL-Rz z%1SQhN!e}e@!5u?eb3MS8wFv4IRR!u!on~or<$Y{xAi`QPv%#n96j|v+3BPX@aok9 zIF?rj3NP7|LM0`D+85Y?3Cp-iFC~vI?Oj%>A3t&Dm)zkuyEJs1Vo|=|Jo{dCa)vHRX7^_i9>i%x??qCUODF7o*A{gK0$$a;5@3{S><-&| zyC9#;lYkPI`^1I_QnLj(MUIFkYV-30Fa0`?n~Sb{ZkLX;)SW%9*y=kS2E0dZi~FO)Ki!?{IYit_maf94%$@x@Xl5Q55vg-XsLji=waW?y-H zRL>NGNndS{?F|EhuN@H>HQf@0sUKt8etm2lz0{{CW`zpH-NtWM!{gZ|Ry~u;C+ehc zkGg00&vvHDWI1pcV8nD&hi$)jROq~tORBgFm2D*Lr`gmnc3cvNM;?v)=%y0mLbo>t zku_wwdXV_H&K+m^KF5QsR%hQ{Gz;7^4_R0TogaP0&mLQV*Y6yIeUi|WC7j4r0Lx;#U31F(RR?3g-F= zoDQIEZ05XKu5-n;D2f+BXo$@BKy2Z$7t6j{cUNP9hMx#!Ze8~r7ZEyqJ>eVni%!ic z1qzWYO*yzMAHYg>5`n~8lNx1spcbbjAykS_NSwwtNLPbE#O7%G0sDd+HXVesrV&BV zJu-L1s}ffbC;>KK=BJoMzPRr}wS?c!fbESu2}r+s)f`TmMmGKj0*5WnkVW z?|XrnDvngF*WG2m3~H{<;sA^(ag6qsoY6N-NwWF7cNRX4NcBh}+doUzNfFWHPXgo2 z{yy0Hj5flgREod<%@$%bF#!z`b{bAtKnYL4X7C#?rt&29Ooejh`fO3rTnE?k`w89b zHw=LjCCy3k#8d3hm~gHNk&wfcyYpuEtqdE~R+bA-;AJ<%#+$C29M~9$_Ok6~VeBIh z!~%NG?;l@6YslzCUGwp&C7*AlTZm8_7_PfGSM^_91Q&&kNs&A|JcypL92T|VTLqRpGz z(gL*@pgGCFVv1f5*m5h=lUJ{UA7Fa8y#_dy(Fn zcsfy)!O2mgGm?_>#QuG)gB7!NNB>uCk8ck$I(DeUET=&j?Fi6$6GC`JF|g7Ff8oTUtqBjT_3&s*Yx>xZ(#<7M3q{0 zI>AmsLh#i3V`+g}$Lb}|LxbZV6ifDX)?I*i$fW&umpDZCc^nB$7;cY*jz;^x}_h#nsmvs|PiQ!Tg@bFLTO%rzi zn`Bh~2T5LrM5p8cy#f>MDc-4>pt)LGjQY^$9tGj#2&s#uDJW48v@R%!C}<~%<7=T) zlJsp-LSu{*ZN5G z4%H}|Jv=KM9q|0!oLbtT+n1#DIA0lU{s{AeZ}Cz-{dIyXsi4EH}10?yn_~RzB3`KA_lR?Oc}Rx|0D}NPgV2q zk57et6tYoG;X2bLEvj_MnEoaLV_9`MKCr!yq_V^7}zv$x&M<_F{LH* z9TMH>0~rld%grwTyQZH;c#EBio6$6a{01^jt|+F;Gd~Ij%Y^-z40#?aCaER)JIw2` zQ*Z)$JyxB0FIAZ10Gv?-{~^r6Yw_~;`iP6K+2hdBq|xY6Qai$)xYp-vQB-v6ekUU~ zq$IK`-|2rd5)~)4w59^l>$7JpCCsYQ*C{BX#1(Kqy-#wSq^qge@orkN&uQp!pwS`I z&7GHxfp<;UfYG{iT9yhOs|vkW7_Hw%?{P21J#wYGF@@H9_^y6$3%v35>F&l~8aTE2V7E8T$adcze$4zRg-xVyYD0o0!Q{Fpvzjnlf_V9o-&^*){<= zj3y<$xbsgizE=c(aS~1E?d=Oj5@DZaX$p?hof@W-Fm^>aUdAK$fo7%EC^=d6l*`3kkyKj@Ukz!}Nl zS9^OEb+Q?I?M@}sV!YgTiaEd2v$t_zL!X9Bq-F=-cjn#x3F$9(*EZ#zl0F{U(}K?1 zOAL}2xiG2me2m+FGjAYpy$0S4xsgWBV^0rU6^$lgGl-fty>xL9`!VjYDf5PwRl=n! zhxW~A=<$3O^;Qz~mfX#tS(+57@JK* z$@nj@b{^X=6gNL?)EyWhRpT;4UKV{Fj>KVj*w~x^mtI&B+s?L#m5a)Il7|0`r(sy2 z<}re2%i_51OMfpASKGv@*seGQxA>%9;skG)vGC|;GsP>ThHp_V+ynvXL?}UJqc?vu zgQrRbd(oMatb}2>s|4{Hm6;lOFDCnpg(Lhf#cfJxuA3gX#dr*Wto$~oe#^~iN}WBY zDV3X)EyFZ(;LVPjOX8^?V47k4?lC4MLaP)Bog3D&C=}_|gR6+Md{r`^Apa@5Gpv32 zEq0R|sV9(}!`5v2u0ry72K#vA=bMdEi!tP$>05==`>vDCy0XKh?k3|`ES)}S*%yhv z8x6m@5GpQz%9f5dA_acA?+y7hOL8>lUc8|CGvMXkms8??gRKQfjB}asHu{Iu5~Vq0 z66UpYuQ$5t&k7YvOooI?(S)6ZU>YOs?gKe5P!cvyyhMIA8~O*a1R2 z^OsRIhksM6TxvBn>l20TROU#+WEYtm?OeZIH=p}{_T%X%*h8BZ$^#8g>9|}>JQ9{} zP!fjLzfiAia=97K55QKfq#2^;G=n2`>7~sxyG5PvO;m55!%|2qt5e@}1^Aa3!@i;K z-NKwZetBkm_+*m0e9m=sk+L`_xSf|4c9na3Q{1q*9*ki*&#eWI%=3BK^s3xg`NfOD zYl&M8&CX-zt3A~xI#na(7Mt_v3j!W&8Be1Z?8a_jMs9yC<^oF~GWAaG z#=h8wxZxeM^_j*`Mkjoyt(p@v-_Y~U@twy_OYUk}#6)J|`?cMUI8iB{G%oFR2M@-w z1?=y*S~Off(&iB6klhE(w1gfi8gj6gVUb@9R zPqiZm-otlc>sEgEN*hb}?OePacON6J;9<}#$ z4-dk7IUT7&h4=}U;IH`|MY&0z1p8jM2G!PGc^JjmptDns;aq5NIv!(?gy!>)Ate#| zO$)N(@oPm7Wq;J#P(M&~RYraNn?Ak5%f{)YMkDr3t3F4YF?%X3Qen?1uz-AN^R-U< zK;yCuDZAEdFDhOQq~`PIMdn(KfQd}(@0_NCG+Fz8>(FJ0YOoI8>A=N{?VzIxqH8!t z-v(2B#Hv%l8c^1s4;Hf$6#}4HUU8MG^#sR9Pi_X@In*#o(4Hncw)M*kxcAuC_w90` zcH45fv+mt!d^X!Vth&#dQ`P9-Dr_0A&ID z%?ru_!oK<(Y2TH2<^#zF#~J{qKV5pnmw)A>=}r2O77euhnfuhb8D&HW7we*7l}Vsu z_29a2uzP!@ZD7+OyxAVvm0Ws_d#td7IR21Sg))756+2uv=_+yS)K-UsIN<>ZTA$_b>13mtC5Wi>6o47Uv#k@YO|- zcvpPLDDJ7zv`^VMY&=7ECpUXvhp4VUU>E3o4l{@+eaDQ_Z49W&;;_tkh}vksH+sSI zu0ZoTIlR@sJOM$r@W7Iuof=_EPN?YBP4INix*0#u8?$Ff<ZJxi!BdT{PUgs2Qm{g0vGqP>#j_BObWWO$@69WST^E@&UHU(UJW_YW z8Aa8~eVXZoJ%x(b&-K_^pVhx8w6oJU&w9~@YLB}z3$f(9hU#T_ACH^~z@m*y+f}b$ zMBr{dmfj$%04X>mKlF%SSYVC6GQTQSM%t&cT@8x}L#1DESTU>C9&6~lFeH~28je`4^V@dCXFKclVkiOyfCREdR(+Iv$vAL@8UM`PAmq5jc8NF`KPHT ziTAk=i|KL5F7o5=5bhr_pH@gb3lH5jz{R}^8)*KfdG#_#_Swv3*{fP%^~`ZyX?TTA zp1=N#fel?N094g{4}y1A$i1CrEPL$gN!^{$+kF)_6p4okZ_R*n7IzSJ^?Re=2 z-Aq|Vc#cy|&dZO_{Ycd%pnRkxk4WWkm8;NvDQ!B_J+WNVtA&|{)B1i7@(sMLiq81WmU5FAuK(T5xAIn_k9pz^MN*LrPB z>?ga|4zMeBkZ?nsUR(hW89OQ=1aI`3HR27N9w^$3E)yl^;H~=b6>Ts3yHASu78xF- zu*Ram8q+g?STy1tW#MZ37pfhgr8uc%M62jbBqO)@2Xg_K&AG>mSAGBrStI^64X6x;X_>J(D{A9Ab6L)%23zBVGq399l>YXFNGa?#g4hH6P zn0^PHDeH}B_~=PrE&M%~FtVt@Obv5Cvej<*nF0k%h1)3NE;8pr?0sa;a!%oYXsTiH z&r@pvj@krN$f_KGG}e!pO6(_x`S-6GqyVPipUYZ5M1YCO+zdnn>c1MqBz6AhtD@H2 zaKxAX#|C{;^9(gYS;%a65s9^h*35sOw7)w1n0N8Bh-+hQpc4=B;}n)Vv+86$vGBi- zLfBvZaKBnfy%Z8}Q6QjGiCLqrr+H>TcrRu)6cEE$>*wUVs1hxw|K>f_#+pKz4F@j=8DE|E2R9sC}3% zeEtxv=ghY|S!XrtVmo#7_lHO5Xh6K@}%qU+dk;0XaM;C@&%t{Lj3bK9Wlyf74)P zBy=-qElS8ii&wIM{^o!7DB#$ls~1zoP8XWL*=^nA?OkT@zsY-&oSqRhj6*GR#NV;y zF2+7$Rnjixpdx=YpYxyFZoqOooh;9wCQayr+K4`?EQZ+FytNj4E!Fbho3chDHJN$T z*Pot9K6)^$s(cn8^dGVon8jPXN91VG4Q z0~dT=Y}TYj9Vsg;BtIic8bgMiUGhI`gm9uKm-K!_Gr%!~SkpE-BZNBs|4G)8w6C+& zH5)Kyp2a_liQvFl_>YCs<`8X~1eeS|OjjgO#d_AzYFjz3LiFER8GT6F2qd!zp(v`G z605ZZt%m=%F^D3!nF9+<(7jY7E@JD1$_V=7pS9Dynyw_PY0aTJeLRSc?x;sWX!w-o zzn04zBHNdoxk;9gni7}u{*ddh2LtZJLZ1mb@_1NOtvvkz*=LtSTj{+0R+-|z-{J~( z6D)aM8lnf!vT{t(?HPD&3hiu~EEB7952G^r(pj70`0mYNK&V zGYy$Q!;CCb=TA&H|AN^yIjJ+X?XOq;&r*}2nRnFR-P`k3>M{g;%hQ#UC|dUc#^d!K z<%)_NCcF`;to_dQnSaU8KXDBk8QXcyIZySCoejh`lXa7e>DD1m;z9Ys!oq{Gyq#(u^sYhWYc|eZZ3W9)Og(4!su}DNcTOlBQ3FADB&JP2RIIG8tOdoqXdu{++SshpF214qSZkZs% zQ|D~;2^;@qpY4OX9C0s0pz*M2z*PxX)10|fr)J>oZxvtV?M#RF^cvG|u>-Gn$^;f2 z8(?~RdWnJeoxq+|e>$l~!+uZ^^=k#7wG94JYpA2uZr|HTJ&0W-2aE;}R#lODwMAbE zaZ&@s23HMZVp_SrtIQ|2RV8W3WSZhIO>czAt0RGpULx4dZqrZ}DY{xxdI?hJb3LWo=xcufDjDUy=#(~hsvbutq5r=9SXB%lHOaDaW6N^i zsrCWQU%UPsxcvP*#M@;oGWQz8z_uWq6!?rmC@Kr=BTGHg9$#+K68rv=me&A{Tm)l} zf*kNc>~yJ1-s{5_j1{b!51Kc6g5xaf#RgL>52_$YJ(jGcpFb&WWoz%3gO>UHNGGOD z@kyWz@2*|ZL5UqDnu9hj<+|fW3%ozM4=7Gk#ho6Oka%As?K32ma9^iZXS$U(5 zET{IxQu@}GpAtO8AqP~{&c%Q;Tz6d?!@s{-k(xMj2BNuDTw@5nW-k4zOS!hXuzZf&Yt|+XHTlC>-^;1lfW zr-gp{9d>s1ohPI$S)U584tB`iqmk_<`CVYyQ8Oe;X;A+q(zS#cQb}mGieJ6??$u$h zxv&~Z%d~EvSuCA_Z0c?b)JBMyE8a~G@gQeSd^I|(EmydkOXMUbF+T=G@*CgFo{!Qst=I(a16X*vFA-IfK(*v zY-Y&Rr}xS6!rq6)wAoucE>MwjJi;PDdI7fJ`2#YtY8&5m|L0c|s`Y7g3=sLq5RFNm z#L@a4eeu>PYDP4I2_+O+WG990ySH;Syytd_ym6B0*C^;nFO> z1*8ZELsU|2F>f#(TW&UxTI3NbE#`g8fFt}Q;h6N`n4c}3RM7kT0|Sp|DT86rrSPVK zAAen>b^fPM3sDOIl?wvqrSsr6v9(C&Y3Y+6_ed@2x|?|`dJnBE#qTMu6G{|=bZ?fD z(g9%61|y*lU2~C>Ae6}g+!4+A&dwbeSW#=Hxh)HTLFfNgro~`1(o4>&5P=W#Q>W>U zAVAhMFE1RfU*;V&uPhJGy}^VlNXrKT%yeVs%5fi!OZuNwBj=2{#s@b*g7%dE;orFy zupI|w1&X`=kd>(4ilA|Z8h7Wu`pemK0Z?|T$X1m+6b$VLv?p9dRUbM(CC%b!;>?*v z(mC>s(s~RtI=pW!&9Nl?a<~UL(UxK9n|<ik3Gc2KSME~hMkSYge|5|p#>fzN-W*DB zDkPX>(!;SDoCuIBFN~Z%_B8n$2mU#mp)YTn(v;w?BcPOe*XaLN`;NxBrNBREnC&mY ztcGW$D*DsL)8wa9^LLiNvVo5`365u92C*9-F6`>Pc$G4Te z`&5)%4^P{^`F41HJ;m3y<#&6`Ji6<^zSVr2qz|Rcc}siFf^`vGdvajz#P9g2YT!Gcr8Sg4QR9YJs-y^OJhC$ z%0s-dJ!9nZu?gynjbzcNCnA>C2enIL_+^Wg68X}Vn}2A$v>xC93#P>(ge06~&qhXg zRDrlrkfOboksitg5Bn{UM{?wK*S7L!^bl|;fi7DKAw*i8*RzHW++a!)Ko->&Zs4~> zrNcB@9-b_Dcex(T{h|M8R}m4`6FZv5+4FE1csG@@bCeCRWK#eyJr$)*n;Jd`3eE>B z?xtet@ImxAt7}8J+K;{}KN#fX>__XthJl=n+2|52%LN7~%x2YhjR=ztV|>IxuG25%ZAJ z?XCgqUd^!=$I|J)OSXzDau9<4FMS3M~TTMy&;$HzR*L1}5B)>-N+lkdA3T>{{8$j7~5F^AGZ%1%HUXe&EHi<)L z`7neeIBX*doB;2*00KI|gM>83X{KmWO+I)Qn(kSwtGN57kIH5M2;3ZtG0dYL6Y{l3 zTjI&uQpzi2Vxd_=cNHanHZGg#Sazq(IO&|7X_2B3=3V!5=H07Rmen1 z>xc|6k*Y^HBvJDF#Y__&GsxwFNa2D}f8m^0l&KN`FBF&Ge~UH=xZOpT(gd@29!!j` z#C5>S%Gl~is%RDnWYLFQ8M}uc6l(e_*iYv3fLya7ay}EeAQ_T$yVjWUB4?uiNE* zSdv7IIx5*{n({QM2`BJC|E?1fPk3)WG9RO4sx?il27UGuFc}*AoM8i&{1Ch#8>7-BwVM*1qF>nW&B6Q*ApjdBVR3xH0}$x^{cyHkGv zD29kTET;%$Ti2oe243{@!u0++4MvtkJgPqKT`|`9yb6$pj^|PyM|>_0_H`_R7XZ+l z>R%zG&yQg2xFEUCK|D)dg59L!c#aux_YK@XipnY1Jrp8fnZaTxh@Q(lNhNo;hE2hs zIUFCGAOCw8&eHFhe;Ug@0WX%D16iCGTgK%B;@O$g(Ft0@{$Wf79j8^m2%F6~B9<0( ziHRdR7UWf!?H;(x_J?eQ`^e%yYZ5NQ!Nt#cguvZebTt(ZfHI%BzRG5_~Ikgc1E zwOat19V5LrQ*wj!t$$yObNE9Y7ATt9%>q+EsJ<@7SSRR&mP)q`y(>U&xhr z_xOs-3VGA0{En>_90VQDkgF|(Fm-4@TKkd>g3u287wTH1pXd4lZ#OGOzqBcQy79mc zv+CjREGz_`xb>k6o``*cnG#ITH=oQ#AkauQlU`!5?Xh=+uHVqPylxzZeKHGeBS1HR}fkPVu~x!)<6KBeVb)0#D%R$zLG`5EO~!lp2e*n+K*$xHCmw4lsa0oHq;w7hCb-T zCu|28T<>H_ap3}Bv^Wsgf^uEYIKMEPS4{3$`b&(3KH?gygPvd=O6bR7o-@>n>1Av5X^5UbNQ2|S?_RQ(Hgw{W26T;7#3e29{~+kD4I?jZQI-xsG@w1#9OIwi|3mr92jMS_kFB6d5L2^hfM zc)*v(p?U_lXEZC$21>orX>m!r+md}DrErfe54q|EaBlB;Qh8l1dNk=(Xrr9+6ej#Q z*iUE0O(MSO^H;3No^kfgN9Nh^vZzM-N&3i(bnIwL!BlRA_rnDk_}x0#ZXa1E1*Fy2 z+9j99!GocXpV326aKk@98Z06cv<=b7p6GYa--m~gVp*n0F1dCSu*?@OS^Vk0;qUh? zqEWm^QlV$RG|QBI_l-N2ajo+8BwlNR$Mhw!#br)7D1k8K4Z{m3YdJ(|%F9B`nqtMS zNA6~l(|?DZWu~M^rudb>|b`w{9|!;1qwlhs6=A-E)Jr)ZD5UAk{hr zW`EC0J7NZp^mJ^+G6Vc#Yy4<_R(xC%I)UGH?g^twZ`a_=K<5y%I%YId2vk0f=;W{b zx;V&83?h|Gc9KNNV=hW)9wUKA4?pT%6-SZ!KE~sKJMxX$8|HKU49hsdG&6e}*TRM& zo6%z?4lyPc-U^tQm;W?H^IhJ)f^2d`gb+WkevImM78$vXqANWZ4-*F)UAZMG3L%5@ z`LC4vaN5oICz@M6E!!ea)U!-l#=0*=mw@ow$ujs;Q8ioE+P6He&q02I{m#k{(1KkB z_J`!jAXPh8p~Ny!?$@JCI$F1Itte@Q1rlPGVQ4EG-oR_4*HOs_u&Aun!^X!{lUgR` zQaVHjusqz*f`Bbyri|Fl{zuC#Ux8E78z>ghduZgT%D7#Xd81N=^|aM}7XWsu!9a)JVOmmqOEwAoGMi1sC4E_5>p<2kzV+lF@cK1 z(N}BZWuljFMA3gXUZV15mi3{glxw#Ym+Ti)bzmp?HC=phZ*h*VR+q7wrEe)o*|EYR z67Xbt6@1`A5iChO{Lg6QNlJ)~ceL3lCeaK^x|M$4$rh4Co={%LkR4L#6oTV^_|s|` zyiOqBi31rgfwGI~n$0Urjec~5d-AA8fSiY~nDU^WIAE!r905oIpkVT-yr5g{xp+-` zjSiQBi0+&s(q3BklIlNj3wbMRyY46SVCQS#Fpc$E%t=8DkvrwKOcFzs;Mq|7(xcemV^DzbE-1F#8-#vJ;+|Huv8Ww%3n5YaTQZwzO6Y{f8m5C@u3OAbon-O4H1 zGkcf+o$(AZ0^J%Q+bJMGnC_--v#K^n$JQ4yI6BzU+(UoZa_)#EV@--l3*82t>9p?1 zBo5T6&~tperkl?{@H(6au-UFfd4atTM6kAQ6WV!4O+1f$jcPivV_R0csbB!bFA`n= z+d<*~r~=*P?Z1pun$Fi>W zSQUUqZ5f4ei#mdhbb}e21y6qgDZC6WR0KW>dbZX(j7RCAQY`gAJ~EJnS#Twm_ua5` zn1BbsT-Rf$WY4t(?M7oi{1k zDs(PxT`ok)aPP({2Hr0C@H|*oJah6m&!r1=l z8at*$40i{5uirCPIlm0pZXFQ}vSfq}$0!IB@ zSQxD4ar(G+Bg@}Dy?kVX(-Hi+J|H6ZUohB{Kxq2}_2nzp$Pr(dwLw5`;Eq-6dhX3e zLfbDSk@Phbr7F?+cz#0aGr}>|zX9?uS)wwFwm79(Ju<{voqezFPL=(vsb#Zo07kJor8Uo`8}>&_j2$<; zvq;6Io}1d&ukWVS{Elj|MywQroTfIo78n^nJ|ZV`C#0W9sj~F7bBN!cb;uxeIYOpH z9cJL8)cU-9Z3C^r^AtxCzz4nac@%Pj{7W?@fA>%=AADcE6npLR?3~MLY~qzSiJ3#A z*!G5FcTczHXH6Q9v60o0)d2GFdKX)jH$PrCXz7Q#hv`!LwbYXN8!_x}VS+tu>h zFL~u5G3PpRG*qWvyRd5Fy#y*v4n7|X&5?#G)XoRz((U@tgXd^sz@bpqwmuJM3u-va zxh3RP7r?0-^$xKV(^6|?YCBencaUL6xqRq2=U56gcX(W?@BmdTdJoiy)a4Y)Qm^}z zl4Q$&o_O_ppvW$`k%aKXBDUnl(eH0$Z%B0%EY|RaDw`Ijk1rAm0H1-2yV)b>vOYj% zdXk7!F}UnWtrn<^tyVyco+1^?Y9ty1fWK57t?`q^F8beDRy|4R$t2;^%5dNI$$zCz zl#Q(#U^}$aAP!E)9vQ^`eJR|3igxix#jCFuW6;$G#sf|%5v$-@#~&ljYTwE#@d|Y1 zq2WDg`aHn^5K&)gJ)){xSt1Rw3wzn+s%ppw^i_ZXUFuqmSiK_<`4RW|^$JNX|I@5h zdB|LfG`e8_#bXBkhiC;2eNyy-m_G;ZPx9{Pn#gJWyAv+C2BNng*H1}~k>}7^#l84#v(=UA}__vUK>h$ zCu5-#RZ*!^!trhCEy`tcXmT)9;#hU_BfrYX00nN`00@PaBf6-4w1=S>wZprhpKkb+ zx=_&A6nYs`Z5Kn>U2QjE!-2&lX4)Ge>^s3X>D)SVv(C!DSMKj#G_3^qR>|xp6_v8J zC4@|Ih)yAi9xPB`=60N}@oV>jI^aM57SA*-I!hRF(tzq2#+3c>7@)+mT;8WerJ$8Iw+_S#Gy+V?b#Sy8A?(~KrjSKs*g(FH1;&D z4{Vpc>>v5Vn&Vlx@EkjmFa+!@N+ZxwPX#0BDZ8X(BP=RyFmG6bewOuf22xFS^Z<~t zTfZlSGCK=arnv2U@%_!B**b8fm@usW%Mmg1)Wk|17S!Shlv}ZQ1qaoMOQ^DgM6xrY zP9tai|`yEqnaN#D-$*VE2Ryk+KupEduZy9(H-? z+f-H?Pj_jSe!h7;*kB}qML8#+BHYu~cy+~)Q3dz8#>ws^*J>1Vk2sLE#h%iYu| z(E)}Z#nhIfWDlysy95U8~)L;yvG+oWBtN^<_2sYg*HZzvrt7a&oG+vxp!FRCyS=;;{ zu*zZOmQ0oZ(CWezIwX3EfYKy12(8%0a}FNd*ce9`k$^PgB1Gk;PE+C1>Een~kQR^G zW7airA6~8pA36oEH^A%VxI|mT{g>Gkf}z9kJ~yb3WD9NK=T>+&a=;+X@#9pI#UD@s zJZ(EKaQSQK=e`OOBFUqmBwE=FMl<=4$gpt6y15-4lev-$lTfyCF$#>3@J2rF)osu< zG#zeP!W@LZim-u51+D7eDnQwc)+}uk{NPv-Mqm(DPdA(f+g||=ma}=8B%qFDjAA;l zQ2xwsGlgM=1B(rkZOGsQNx@Ivny_MKxbvhQGv=&md*ZO3#fCk?)yE{2T9fO2XUQf* zuz(%;WlCgDk-C1MR)R&*FU19A4Z-E=uNDz#Hgz#*F5|4E!p*wXpN_}%R6vhZ49MN1-ZpK{CIG&l*I zh^(_1)1{k4J7jpDb20C}xpV6#`CiCkTZL(+@~6wD!&SX93SZ$oO%!X|@1Q(C@a-YN`20+a=9I2Lg{tsV zNCB}83J)~M#Dnu=7}JS|UVt90AQ3Y&^ad;!8ziKJu6}n34LSv}0}XMcc_>A+h-`GU z@C}e!yCl7Q()s(gD#QU$-c`ZpvB^yxjL&drPskXPoq!~Zh)mXB#a*kT>|`jC*iBPQ z{3r0j0z=esH(tyivCMfeK?9NZInEJ+_bx<5eT<^Co1gRd?|x`PjLj8M8U|r{KJR61 zdA?Nd&D{o)YR3M1hTNs}4VNcA9a@f5jwsnZBN)yv?zH7mA{W`mM__vA$p=q76%18G zhmk0#c?Nk}I>EpoY-mOd>xvc;^eu=Q&K%J{NlF5-X_@euN>WgN03oO#$pK@=5VnEG z#OPSfYClIM(BP^=%6ny1m3-tlG$js%vcUcAV8UsYUD8NTG%L(2ZY=L)JL=2$?vWN< zEs~$W>lEdwGgGX%)>MM^4bYu4ers%=v!R`9+apwiK#DQbtY#_Gq&N%6(eZlf6K;vt#d zwSc&5@tNZ=jm0tuF@7GTn6w?r7sK35a?06zMmLnuSayOpU}1Fdg`Yd@cx3W*R%T|& z`#J+4RAW&bv9kNlFx)0vJ*p-gQ?rwQxwciZ?mEmdEU2YasJ8A4P|(t=q?T*MD0`MCL?9_ZtJQUn1cM zWw(Y{;Ij&Rk>oxIc`Z*K`(>OWM;Ma>{rF4iVvz4-l|B`HuZ#}eIC(S&i+`Ooqxm!q zf;Hk1)vkq`>}eu|R0rdCNO9?QXNlZ*COONuL_14y4@hy{SPpSej|6aSLwkFOE?VBA zMROoD7a+0xFY`&5!|leEpE(6H>X1L?>x#Riq~~$|K*A*()UKmxXZMmHDx>omXTa2$ zOTJA>l|s&+?+xG9JimoDf@LxvQq$S_%$_E5zu+T^$Nnv}SE?;|B-*A5&i$ z5LMTOOCyqk(jYOEgwg_nAT>iucjq8THz-|_LrK>FA|ahpg3>jFbV;WIBBH|Gqwja` z{pBB-IdjfFd$0A>a@t+P15zK?%Uwr~B-1rvnFta|Q;BxT`Y*)gj~296k;x>VSI+2# z8mnfF;-zSR#fK6cdRz?4zG8UZ>fQ#(_QQ-d0~!9^yU|#hq7jubFf6%n3v~$TtpFT; zetNeD=3PO(jl$L2%ja9a<(M`@T^exN_gI-72t67ZBm<-*9j6(0nt!g!T4FQZgsw4} zY=pjGC3&ausabG^;AzJ!=9U@rch69`C2*p9J8Lifi@zN0{a`nNu zz-6D6Z_Bd9Lpba5es3N}7{m08%;Ohi>~kkynZ>s;Js;ZM0p3yz8qp&kKpC`8*O$|K%@PRsovAAM&F9t| z$Hv4kqh@_F4%&`o9OiY-7mmsPJn4LLC~@w|*tu1dg3A&Fxhef<9mfSi1?|VsBtt&* zh?$6 z^5_pE&M+q-8{>6PzF2*764uK_^7$5(bwu-5_1Ey)Ny>G6vGUW`{*k@mzYKf{IFp<6 zLt30YhEs6iR(bq4v~lDJC3NW#BwIZnEudT48fmx4ps2n_QjH}{X0CkHh!>5{=1@|W zkq$3ca!ELw2gIT0dvi>C_8e>qIvimngH&v;p*a-D8;Ov#IoEhSqrYEYI zKZBwP9rd|X48Afy5vP{2ql-U>RN=1zY#xn=+v_tFL{_0eq8=DUBMVNMmVsxqf)(1dEZ^U zq_K-N?5iDK>3Ka?(E~xh$2m9rwI<-VDR?6wG>uy-Tnu zM}wr&l(y%z8kE8cxmjcLLF^~=GXcDLzp72;0}eryY{4oTvC?_``it?Spp=^*D4O!j zrS6t%7fmH_F~OrLl9y=6!!JhrUFc;IjutXM#}%2rL2}5HF)~;>`BnN^5f7m3){Pge z8GefEI7y-Pqnw=gx1K6+vDiS{lUC4^IF?XSMZK}yr}Iz>cP1{y6S-elQ>4D@Jt5~t zi`O-l>5aIs=gI>3Ou>oD5$=<#Jp==EV>eNQuixdyoYZRm{L!A!&-hXjx_sqVs6zi( zH_g!eO}5KdQv^-TGTzVcqI25MJHC^^M@5HBUoPq}2JT?e`1Y=~hakVXZDFqChCLA) zeuZtR@TJK0Bxn-Dw;IK=a`Xh{Gf`t66#oG{LX`w0^J|N#q8v$qQo`lwGv~+OUjW;H z=PHDkNfouMfe^t&h;$)H3yWkhCK;*cCE*bit&;-lJ>Bx^LrV7B zr)+VOW`waTb*01K`tCa8MDhoU=O5ugchqyqa|@TXH)3_WP% z`n7cYdVA`dRnDyVt0W|E6VZV>PBj1_N6(s0E~}`}zKH3nOw& z456|7$N{wx<0NFwg1|3K8OL=-1&!K%JuV8`S1{VGDz%URwM;ABf;Lrr@RyxL>uKyC z^N$aoe@GmCV!L!}fBW;&j;Pz0PUi-K)9a?~qmvz3(gA)&2Ige{?!8eV{mc1n>(DUJ0Y|6DMsLYYc?=n>vXV2)`7HxpAo@a@PwnGX$gU4gYDMc%Kr#T3NWy zpcfaLKDfJ}jefVb3yZKHFwwT|ZI<{c>~IrLL8DPdIdSTQ(|=EuyGYd8)<^|)Gr2^- z5HDl7?leM29RHYwM%M3BA!a;vaK1bYgM*Yw#_AQxqCL-&>XR;u7Gwth%YPcmC470o z1q0Qjn$Bg6C|awP?3D;h|2QE6*#r|0ZmG7q@=(F`*Zm_cFC5K((s^C~Q+ZDCnnQTA z^bFHRlthw+;f6DM9bW$QemezT=Fe%-f(OF#OT=7<+-$*IgbPI0io-odx5nS#0Ct3Dz z<=homE)Ep=BjVSrPpPS^iAX&`WoxHxq`Yyx#6Vw_s;cV$F6={4S`B+p<@f`c@t`=D zG9pLXb^ebJ~TK!L--TE+7_T|X!;`a#94F}cbBZ**!25R?|+!0!JIV77q zx6oof^b+_SLF_W0+Ynb)IbMHFVwDS>6!06FT@<>am&7LWju15X?}-VI%Pug|jaW2O zFdItc)s!a*eR=k2ar|^Y$4@<2`M=gey z6YqEeDm!X4931G7tyM5u+Dv5202^EqH_;{Uf1jvm+&sskUt?83s}eH<`A!^%>fH+o z0eJe-8ju(MU8V79Il=;5BqbhkY6GHr5X)2TUV^iJX|F^`IP?^Z85<_}Q2VY@xxAL;pu&gqdM|e6J*-;>qnUy&;U|^^o^uK4yQCqR@sBJm( zRFCz0gD`4Q|GsZTKRIdq5izv+fB)yMU6sYs>Z}2c(6YwL-%dKK8IVVtEAa{ zt$M|~f!baxf!<<3FJ=Sud8t&UJ~H?2-9xms;)4VGzipv0(#Zg(aBr|yvp}vAQVvmt z898I(*sk|Ry8-BS==bTEb6DJ3_XHTb&Q+St(ns$ei>9Q3xIMC;fFqm9sxSUf7ukoV zF40AU{|5-%rkG9Bpycg)Ii=L<@9ZtgD;3Ejr9XkvkmdXL@3y367BA+301>`bQo;_mw@(B~O@m|g>$?1|_{@FLH1vzf)?C2NRgHomU!v{+U$B@y3Yq5%r&B>n?tICSJ5H}}YWIs6BAD@#gj@1a6zqK)-%e9zX@K!!dL zaB%?rq@|@pH;8;l-vKwrYAdAUb2uSpV}_Gf9kl35NMy4?>vMcNRkaY(9xWYCs=39g z&=2CcMsiQg``yR$Wx|AcHu1Ph9X8d~+XPq8tRr z*%86ki^-Sqw8BbgM|OsQO$>pGpG56=+~p_RvPx%x>G3HfgTKqcK>kT5P^HoxEdpJp z4H#aWj?PE{T00W4)gWxg7xMt(eU1_qzX$yc!iDYw9dA}lkc9%R_mqaB0rmnIzuczs zB?ReND&`Si6%K?-_a+)X)eiAxp?~3*Z7UFp)o|s$(Vyh@wHtpS`)d`;!3A4Vc%m>h z>{-fQt3q;#@b{3Avhs4E#GI3R-nz?f^w0&Z5Pe%-bq}3IkW>lU(1oph6TjVJg$@1P zmVTC3{e`di91x8{_E6~TY-4D|bSjb*Int>>|M(6Mtvw;QjAf;|gD3M&W7CJWh@F4IBaQ1Je{5A#Q&b-`Z6!Q&6{h^Wnpw_<_QqiNYs`Rc6n zF^z`Aenp+iJ)K931g-bJ{8&>{v0maeDx3WN9yoNrY_ImSCa8Gu>H}$< zO{$JAOa;Bc?(n>Zj6h`HUTCSh?1r0LU?ksRWwLf`;eWpPuMks|<4rAiQr78}kdJM+XCczbUA(Ctw&TFcs7EEeVo^ z1cm>`Lgpm!Or}0G&WUr>peGD(X~W>UwE)N1GUX4>dl$fdS3CqVg1$^FF2ONcO`E@O z19=R@dM)TXn8uQht5ZnCJE?a5|`qwn8LL^c_ z>t*QOd+qfA)HZwWc0G>BVuqHbt|=n57L~nGFMG^qBHl(09+eK-Y%+_yLaT7MhAPn6 zSLqRfqkg{_Ewmfo9eMmVuFg!}9?|mzCM3n}u7`#t4V*w6zwNn2y(bq_^2gVEcQOeX z2v&0Khnw89UbNRhNaNT>v^Bz0KmMfANx?Z!C;{T6nQ^JoiF~3GW?(crRBL`_q z=;af>mAP4&eE9qiPdP7oAxSLn0?BxTJ03_m9Qi;=%O`Vlqf9VTf=1UiPi#H^J$Ngw zdp}MjW6XK~EuuWwKQPh-$KqZUwu^3ix(#CZN0e!bPJ0nf&CCp zlu!VLN}*E=(cVo3#vNlnLGffHfA;&$G^0V#;wH|9vs2EjQI4o zq=?PhP0$b)i!m;zYrvtQXVDi5~^xQx6P z0=#UC1gS`VAHTd#2EJ$!{)V8RLGiix5fc8tPB+lIDHcU`cPI6Egmfi@=F{!1kOasVK1oBIpzr{eIn4zt>i`1?+%u!l_q9cEQ^* zzIjrMXdi73u8jjOm%$TMBGNVAFEA7#q!Txy>bh*0j>~{&c1Gk~>jD4*2M34YSW9(| z(M9W8!5995;viog*w33<{Jbg~W|TbQb1@qdLI7UbwPH2P8Vye5CZE+y*u+5HjgH#Q0MPQApv9~W z#{z=ha(duxavSFF>qo1GDLw-^oKgmmxcmP}e`$vhss{4*!N*tMNGI!pR`afZm+mr1 z;=4vAPv?LG4Qx)Mn16(y2!fkc6h56J_D6|tphl0jlsK#%MgD`2AmVET5e& z9DwdA7RVO-_A5Ei9*v5cPqYfl;FW;qx3rjw|Kd5|gaOyZ+`-|7{ zPVvB4%1S=PL1F5}uZ5M&dGrYY5+72~ z;ezS+>Fv|rzP+>2OF@-xm2hXyT|Fs@RsQNyFNq^h<^3>Dvq!NVs}d?3T{0KWH$f#26qdp;kXo`I1y^yVwcd%KVX=4FZw+`sz|dkCab zY^CClgZ>Aa(W9vq&G_(pYX_q$O&M<@QVz;Wa}gRv3Il*4_s+W8FlU>UaoKbCib*z- zL^#^WSpnqrY`lB<#}N1iScFYjixkZ`+K$9E7++ijuUfD(rSX?LGDwobVVTORpq?&r z$GBf-G1{D{Wf2f7JFV=dG!A+nevV3sARW7kufKt6)+s@#G1Q#VP`f?w7qPxC-)F^l zeK=N_zXrHUjnj8tN?BUDA!Y=FA#viiYeD}WOkI9pnLtCe50gAk_6T?>DeS2f&f)VD<|gPs>mn z?*}L+C#{8L9@PcQSNo}Njw)I?LgYcd^e4LOdlT0IaxhxE5^+C9CisEs4UPT7NqlrY zS0}A^lcTOvWk;`0UqnP0#%t&Oc0KVsa_sQLJjxx=hpF6E%^%M9TEBgwQ%$%;%kN$h z_?>3aT=`7N2f4k?V<2~njI&wdyC|+FqyC8ne7e?S9G+~e=48U;3p@xk7ZDfk- zFs^TY5cp#8w$_-A_EdA_4Mg=0N+>>hkB>?AZot>zgU;)#+U;Eb`QVk6fYZ1`zp-%@ z=QQNzsVm|KREPU*rqMLWgZ7i;7y=8qz$jD^l!Rd$}+|fohIx20mX`T^y{?0lt&@0)*i-ryS`<|!$j5d0IST?2V zVsA7zniKZL*X`ed#*%LyjfKlku~olEvPyW3PVF=X#n=g`-{;5K%`SlxrfEdk2;d}s z-_u`eY1Ih{ZRmU#UB4HS`7?^4={R{t5EEwQ@UOuxI!$cq%zwq>v{%#hTxg7OcMhbz zT9iKo>7zz;%Zs2k-URQIC~z3Lf8SHXXx5LPeYagaLJPbk!0?v-cJF(^AL0x9`o zMv}Fvd?|({5!g9+7xaA+B+nnz71?3H3>QOs{@p35^?=LgswnC~^!-8iI3jLcy7Xwj zP5`J!&No-GnpUFBo9jy0xl^_Bh=jGO!Jaq^BZWV`i?&Hvx_Nki?e1~0%RWUPo$+dT z5Y_88VVKpEQy>%J@m_R|GzO-}T5th#Fl^9KG@(JW6ChSvAX9agH(&QHdw2W@X6Vl? z9%!|Y8`_MEj}YR3gR+aCJJGS*qH~ElU{f%|H^U|^3FO)upi5MvZ$E)oa8S=Ia1)|B zk>QS-=U#cJJ~HtK6ZXpe-|pU5A=`8e`}KXF1LQ0h7=yr?+J)x__>Hd^C_I6U?#E@F z1m>@`>FG@gC(mt6eEP&4Lkt=8Hct+wp0YmgUUNqyD^@dwM#=SW-`-=jQqg`1{tjIO z)yd8n9JZkMXn*Hr0dOms;5i&HI)2Nr18~=(VUEvN!Fk80%u^$0`DN!w8bO&5{%=(d zi(8k@Q}MV@wwO#xD*E(Sh1BnI8YNmdBf!7b@(ADAGmk|Prf8P9u(iNu(CcJ z5nZVt4O0sn4b#G>K0i1F7_IoL5l0DkLXyE8ap`sP?QStYl66Y@e+Rn(A%*Z}%2dkh z!8cMxk1C(l37so~Wp{e8!vUqv`kV`D@RG~6!|#OnOpC(8^a^?48h3g# z^wk17SOdpo{REBvJ-q$IVhY7-T|A8GI#d8|)Qi2&PYAH?l7$!dSW zN*}S0M@(z2cl0XgfSCG0*J87m=m#not&xkz%m>V%+r+!<-+VciPZOmm2lvsVifkED zkZ^p{%;Xrk)U>D#^4iJNThY`TOe7!W+!YCEH`YPYbIQu^Em0B7Tz6?RAdh0T3;PL7 zMGK9L&ng?zatH>O&6+)_; zHj2S#H5jB&=gt0p8%iSH-}tS0?`^p?I(u7|M64G=uvAvWQkfIzWe0(GvGGchPB}m7 zwlW<1n}_fMZw9M4K#nJq^2{p*Su>rE?c=So)<+Tl(O$#Jw z+^(*Ebke!@jMYOVJj5$VHXnF3#;)pfiL>5V0Yrd>p4$DOdpoGC6#Q2kO$~s zWw16s#~}$4h1iR18j^)ysbTh5Xdt#AmD@qv&n~{Mod6T^nA*1sU_RaY4rIjibvKnh z)_Qzlch#_=x}Zrjp{HP1Nd$*YKS+RfvQOS`cKu>~vN2$raJzyPhgezwOo*^Amk}dO ziI4vJa0EjxS{ooXHiIc#xct^Qwn!oqV&)|zH*0aR?KBs340gIUnu`f+WQ#7cKLKP# zL6-!c>`d-`bRVlSp668xmlwP3J?fqM})$(w`ZEdrc4@uO`N9D zo$-ATcc6d*U1V;rULQtMksz(GLrRWeS2QjVyS%GBgQ$?v5t0k9$0B*L258;Ciyf%(7r3y7aDqYuSP4J?rTwdyETN za-3aRUUZ74equ==D4@0ynALUtQE-`?3oPapI3FM1OMuaR_&pO7_+1uwVk3=3s~Y0y6^O za&bTH0hpNMR2(cvME;qQ8q3;r0no7bK@wMKnTgk&yw^OO!vJ6#j?Jf_IZOW%FEM(q z^kv)&y6Om6QXLL?*${d!VJ6tnb`sL_=mX|psCWTAy2R;vLda_^dkqSARmWb_Y-o)b z-Z1*mCp;@{f0ciyi0!!1rEA!b>64^D_qX(P>;_V#NUVWuMWP||w-3W)o50)02Rir; zV}PwRRx0@Sh$Ip~a2>z64swl#v81U8fo$wyAi z&c`Cw;{@`6m#W-Z?*0teeuoJDdg)@-wD0r*hDgTRqG5mb}XiLN8Y>_cl477 zO|eknFY=ILKijRF>(jlLlC7h=fmHX6&Uu)aMN+eSb9FzL|5@XB^9Dk>;>&9F88B|6 zBDiQipz9$2pL&l8@x@=JUx3x;y?Pibd7&SL0N&MXi^HaJmKVLfyt)@VT0s6X$1lG-?)DjF5{N`_@(TWtSu49%r^h*-YMk=N7AOs%zUp4=*Bi#NFg z9i9zA2m9CFd9C8G6^1FE*d2=B)K*y66ikw~HYycpOANE>4p&CaEBg10=19{2aVLX$ zL)QMXSVeV7O)sCWT0y7Q?|-f$LRu5u;wO!h9MKPM0T$Ldi+ywx{T{#%>=s}2OLs>A z`U4MPe**=Q|UEMmd^qm zKOfs0Obp2Ev>kV}IkmWU<5JDOur&+(o*GLpruhQcix)K1v&qMeqG>fJ0y>^to*xtCJMb?$qw73Wgd{!)6c!#Tgclb)^h zZCFEMjviK&lj2v1dRwF^M0U5BLYdG9qSpQPGeibDjllPyrqA(Oh#igw@EVKQ{q`N| zO}rV{K*W6;`7|z=Ng*#Xw=otyG%SD6zuOh4HecV(f=SsJa6V@jt@>HPFb3~GaN#a=<*OxcDjO%%u7B!FBf0%;#HVZ0CK=bJavU>+Xj)~4w z=%lV8yx5dm-v8I(yYJo;=A7otzF*?rk^dQ%H3Wyd(|pkCQ-%63M?n`!6vc2d*MF7a zsl~gwfZ7Zv7PDGm9ABfy`AQ6`p048q{1ucEkGi_|h(cKkR*}H~JD3;$Fxzq_l9HZ$ zTqZF&IGE8H6(VlFd{+*%+oi-(w4AK-w%$zjt{Tv=e`qK~dbs}8=z|ftIT~lv-n;WH z4*2EwR~%tw^Q%SscZu$Fer3i3lv4d~5U!Yl#?QRwY^aRpqBGnd?P~jh$j_5^ml6Wh zHy^4DIpoPbJ|)}cm6>YA{&vBJ2`hTf1UK=eSh#_rjTFc9C%cSBQ+^W$_L8IzUlr89 z*B+dsl)i&x|D$;{_@<%)jPvOR&YS^4RcLI^loxyJ}xh={QjVX7v^wNvN-}yBzT!3_Vhp^aqYrw(Of|QOq zg+^eqF?^Sb48EghtQ|qJq&c*$Tmzi1c6nk7^Sj`J?_BEdoXU^bQM^Ygp1I=G@6W9a2ih<{|UAO zQB;$&Sys^}rB+VNowzsU&mIh@+7U{j7+RE3C2?TNhvwg=)cWUYC~4ZXu8}GuD4Ba3 z_L*m#0^b)-{qjkoKT6~*Wc!o~UWDX#8N6pgMM09n1tpu#qlMEdd#5`AaKVW@$D z!W0PKFqjd;7^snuClG7g*)`ykiB6N*dlQ|Ofgk|8qhti_bmQ`YafUOPZB)iFKxK;d((K)>}^C*~L zlQSDrsj%cwUb%5P_E_B!e16Zjx~``jgJ-ry5Z=3^-Hy6$GgFCVLWk0=9rV1z2^Md5 z06x;>Bsyc_Z88U#YSo(SDNx3Z+e9YW5;LiQ!2le@AzSXK64HpRpFTks)z!u2*aBd7 zMKnk5>)HCCaB*~m2YK?}f=fK)Hm@+lh`FLqtt+iWk?Xwpd4gzbS@YEpn=8$ciXaJdmlINqMU+xUeul&_7p(NIqY z#(u4l`vZx#I!HR25lcz6c49SZxX12pLat(N3hHxfkjzyriE6$AX!ee)2(bs3FMh-(=G)dmGjwzZ5q1AiK{C59kZ>-UFhe(Iuz=3FyD4 zQdbvN`{pDP2M>(oKhsg&lIsxSrXpzuhhY>X?$E0B6@-`Exv>Eq5wmf9b$orW5r!Tz z^jEMLpNDN@OK==>f@IPk3=;z)1cT&~)be{1qm6Aha+vS{nh}ofKhVVKJS8S{A~AQO zrn>tOoY9sss?Ke%!d$kPwNENmONBVok*as6r>7OhsgLAVrey+4ipR0>h#qidj>)5m zoQzPWM_-_7hl=j8O5q&~j=tAVrpCtyGR3}wm{)krj>&E$8Moq8$&yv}sH)M6Wzsmio^4M?6^; z%Ldhr%3AJHZ%SPbk6RYU`4{A;Ta60ta?4{E$5q=&tV%QJrJ;wzcX%@dP zy7aDV(sp(^#Ex)%sYS8C2fYIULi1MM7cOrqh6g9rUsm3I{!;V1o!FnV&-Esre=H2a z9u)#mL7luWrJJA!R&t~_A%>0#D2=+ckPnRKvA`y!9uaaq)11!7sgxN|(bAf=uam%l z^#Z%$Gw^Hu8`0ETM$X^fuw%etAIeK2bz$Ci-cj%n0lC0j;cpL7KfteCgy@>oq=Ofz~`&EMAY>MLgo>zFW}@vh;6;@IgfpG{rmJ#D2-TT zmdVxgOrg4e8%$kOQ?Xd-0idF3RYzt5pQ0WXX!P&j^1)$N2Gh%i9he;6(q>T~9kfD- z1-cTqfY{KQqT0;=P`CxmvU6%a1;hFHlaA0+wK#5l)ghp!JZ#?yfEmJI%Mr(y=e(1o zK~<_>U&6=NKCO)&$=EL#I%*kSV7Pej+22PC8J)ZZfOsIQqXy7FgMcH;ys+;E6r5Np zB+GjZu#^daVRrHXw-~L7+-fL##hjFVM`%DoWT8TQt58@7ZyHJJtM>wPvc+|A65YFT zj~u-}RTBenz$TE@B!Lva&vL)t06fzK(A9#hp6z$QirZE~ooJejlze!ZM&}%$0g$DX zS&4b9)A7W@8u3~Q6>fd2xVf_*k>=0`*8TVb*T3BX18Wz;dQ8p0iC2XG(Y)B-Xf<0$ z@mMag|6wb!0Q~?Bl$KjE7>1%=LiR|9P!1Ts_Y(dJ+~n~R^Fz;oTFMOog$p+UUz_xX zd8-q2^NxjpR;-%m*7H=rAsP3DRJQuP=V?30eOsPvmuJ&~k`QpSE?e|}m$$7?)L|_4 zA=V4cT{X>9H*#A|z41Kr*3$8Q(`saPS!7)|!k7v;AX+;`4l9MI-(aWD-7yRWle&(3 z^MG1J?lTq+Ro3%C!NVQDr(1Wf2ye8xLLR$5i?6y0On~Nv=AiXItWFdhYW1l(JS?;5 zQ%tn;XI#s7TQ1rgi26|p*Hz#LP8MBR)bX_G{^0VOydjIC9s7YOT6)!#5Pd^RKtFhK zx)@HuJ~fbLbUrB})a2OlbJ6W=qCwLvugY1`uCV>jj(&hr&`j0XY-w~EE+}bYx z!9c`%g7sn8Ugh2LVH4Zj6L5@jCv&K)Ir`t#-)#dSZ1W+>VC|}bb9@QtEj%Yapj3Qx z-*%D-snM_cj#{^#KNR_L0K^#WJPlKt?9tSMwz0PabZfy#I~7o0G8kA!vki~cf7+O< zPydLIjZad~T1-s|?F7LvR7H_vR@HA5{qe^GUY+Y)Kq9Rd1KWJFOJ>{v(6Vl zfy+%{rBPl{8{_2K<)9W{l`)fRavOt~Dw^(BMP=vJWn&*LaYj1*O+*uTA`4dn^!y(u zG$;35+StVtkWQ_;#|@`G+MeEJ>$n$HL^QSUfV8XNp#=H3>nMO1qs#mY%F1L)RLZIo zM4y_CvA=KkZ8*D+EydmqQtO=VrXB`+vmn$)`Hm{3feKOe{%dnT%;TTSH!fwjY=79o zExm&^?r*ZgZ`xXx(95Z27;xDs@XySBgc+KcPctfi7VMNn=;DrO$b;RL5E{wKzR?w830D!Hj98 zwE%SJ+CXaYyiRt48I*zzm5^tL!S9HmcP#|U5ZvU=Kw~rxWjr0HmJ0e^)64L9$>uoY zE8oE)_6+ub{mgy6h)?#4Qf6h6U-`RPsOIm;>ejdIHjJ4u8uN;? z7L-vE17)SAnavWmz(-+}l%<_Rhvn?cMC z$-w-v*0XnW*c)n7hMyTC3qP~QEuwBj!$0F55YGoSMcb{8}-mUjmyZg>gIu--3dG0}dS9U!vrGD44*0Tg>FR zQUM0D<1-5FkEzHErD`WHmX2T8(dGV7kRJCr9%pYQ^bu{96Ji3X-}l!IB`DucAel#$ zru+!)Z#YhNKjjEZ7;*7!`BqFNF+QvBQ)7M?W`qMtNGDF#%JbXfLXV3qJvki$$%Gzz zE_R98Iyj*zjVwd)WtcKW?MwxmJ^AINGE@8Dg0=8tCM23XFN(X`ZV(vwm)?{E9GM{i zi`W+8-*Cg!KoVxH+-F*l$Dmo5MCF~8(y5D zc~AFdn7cEZ!>%JYOcs$QTBsWdsWgBYuFp=&V6To_M$x#B%qm8xQ55on&zQ&2mX5rc zWF^3t+yxkpfVK6zcOuzez{A3^f2x^0B!e2vy42Ow_|toyDYGDix)h2{VDl4{C%&j3 z&mSNk__*{%{Lb+2lTrn|@|LA9TJ1y>eVINR~dIS0$=E+Vlzfoc9Ymah5!ML=Fp|sU{eJF3^>=QIO zvcOaQEC4exVpLVpinZ@KF3eC?wm41xSTdrVHNUbqoWlbdKtEpNr4xJivEfVg$9%-Bd>gbE0ze?k=zoy3BYxM!T}f#>^cK?=7Ud5k6Jnm#SATXuB;|_J zsAz6RHDg_&tQI3bEBXg^tIrKu57)9QjbaQi3TjGStp6&Uwsn>T}(u!Yrbo<`yjT-H{{d zdygF?Xvb~*f5{WzyDMB^G_OU_4KLpL`mOJ{-)o`0`2Nu3RDIUW;hJB&!oI&6+n33g z5+0=_1?5HU1jp~wF|1=pjF=sqFn8H{6g!13cG`jcM`bJ;!zo8tT(HX^wc;Ydyy5X_ zcxeNHi#pyhRmu0SDuv!2fpYioYJ>A#pW8iUYcYPv{gx`I#dcWI>aNh1fBtM=%u;(2 z8Gk^~Mr?t4hg_>2_VN3{M;nQuspD5lo))5iKAT^ym}$ESwrt6t zSHFbGwR%}j_R8~ilv(-Jun!rCj$XUgi+ZxWc<`jFM0Dky{^hkYYgP6!Pjx5T-34@# ztu-Jv_EK7$mvC>;7eXqz<1Zf02T7fLD{D$KGDIZR0`;yeYO16>Z%Is0riWJ-&d-e^ zIcWXxKAuM2P6?IxJKL8X#iSyGK!+Pc;c#yWk!Lf^B;Jipg>~G#NzN~4Tgzk_u0T%v z;g=F>km=}9=CK1mshm2t|ZLis*_A3O3Gz9Alo1Q>@?G)b?Hb!bZc&kw=y zU>#c`@5XSSC@;M(fGSi#_JezGe~TgywJENudXd>11Un?!r_8(S3$Uqv5CWa{ntl?y ze2IyMXu3F9J4y_$GKS$8KYSJM6inP~V6mVRak=iQTIVo-<5hPevP=?)dwrumS1UC#m%;iLd=ODk|zzJ4VkkA$!)vkXr`(<1=bqtn;$0XvRR$*$X z8Mw$2oT|rT4$C|Iscbb{{c~efLNq-lW@*}^J|&Iu9wFaFE6{ZDX_}cysv^!otIp9n zvvc#bu$5vy6N3~@l1jkYuvq%C=Kxc~T|+?UEXaRdoNkH$;L`n?KbyCHJkQdx4z??A z8tZxTWK5Cbuy-5j`Is6;*e4xcK<($TZ7+#EqFckpkSQxvWZ&)~MN)kB`JHgygJnja zj*Cp2A`Oz`$ch{gdTzUAeq9v-K3mmmIU^@gZ|2=Mt<5(@BvbojPI|>oMqZ{nTzIDr%zXfL4?7h8SOZNI*;@2s>y?B^WFch~UJrqT1Voms z&`2Zj;CB6OP3a%6o4gr=G_;MVrMQseZMTbA?}fw^hOl5^6=Esra8XKYALv(G-8b)x z$-iMKi!0}QBP0YXL`ee~&D8!QG57uH(%gWW2;Gh9EJu;ko{`bvqtVgDmd(ymO3JS8 z1Don^N5fN?p9hyREN*1U&l}(NBKyIoj}UT10TOIqqxcC91yU)sgwa`@ss+={ijMzF zb4U)9lU4W*Lf3SCy&n-oTq-Z*o{Y4(PBGHQC2BF*V3_^>6MIzU%6wrIF@P09u0(_H zD2;mBj`wTcae+G|fyz^Y=ir(N4m~o-s{eqW!|O3Vjrn=wNJaI&P>X~KJxyb)Ahie_ z9S1D%0^rw?NQ)kF%}T>SC)ol9nNB9mngZ!j39bgo#(=E&-+F03w7oTpEmFr^pz*oh+%=E=CD>RF-4J0;by zZj3PMXqJ0piDB4xHacZ3jlO6hz>FJCDa zD;07#LjS0KX6F@ME$f3kQ%2p`q1l5MXnGn~!)QV1+9WeP^2b+5E)yi42)p@;;(faP zPn_GHN#5hSOw?#z6ZSpK?qKbS-UCe8VSOC)mvT1>o_5FF;a2gNX8Q$nSVO?#7}_db zGhGHfj1h+wnK;hZ54_e{m3!i1O;tcBv7v^HtffIj81m>47{-wF?^b*oHsZS}QQ<3e z0}oCDVHcqO#BE?@F85@kF?SJzxvrQVgA4Ws92*Q&*$`qFEzTj7+wJJqyPi*RbXoc1 zD&&0ejAT`|BbhXX5q1?zUcb9v@C8KTO20`IdSVW!B4KvIaN>U2c;fC5RSZ{p&Orz< zK1CD_<0j-mpGEXX^4#tMxpk8blF2U`-X$e=)Hj83u_dYdtW3Pa7V5RPk4->480smwuS!fEQjDvv+GG~DQ z=J9|*PL@^7E3)9xg```pZ|r2U3tmDi;(IW-Ygj80CbvmuqKUCmQc^Q2`T0-6$(hw1l8|#=8fg$>#S~U$6b3SwDHG}$vnNM$gNdMUM0%=g z&2hwsFERNk0?D9uNyQ`m6y7vt^kyLt51S{ZUo?mAX&~iyrp|Ee3`P^`jaVvE$pyZf zk1NRN!Tne}iAKhQYfz7_=y$yr(TiFLXkcg`N>l*Bk{bB0FteC|#m-)TXr_3D4g>sX& zMsSPJVq$QMW<3=ahLnwnMK{=;JPVon>s}Qpj+SohiS^*k%-&v%zc}vPKXcAJSp1pR z@q%ZeNj<$p^>G@nQLSQ@H}lEqn7ik#vp0xYZ=3xY@6E2@IUrpvu0Im-le%R%+v*uw zq5myG&F7cR+J}{}eo~Rg4^fb=-hMe)^9}aF-%#w^Rr!ogg|R6-q9?e%b;V8v8!4I% z4mxPvWbG|sL~a6|=x804&n!xDuYePAOMAH^w_DAeL&;H+s(>_IDU$z079rw&^z!nv zlDZWun@tp8i}c5G3F!dU9d{MjKmW~qEVpg5D1qJQ{0Tlay{NrQt>fawJ7h6Kif*Oh zVAQQ5kFR~Nmui(I=$|$exRq&_A(-J+t*5hV5IB>lF#A0zC_(;M;T!V1s}DXBgF z<3VAF6C&*sYaZO1KbkF)FHhiuNlGU&T(^yTSore#>I6vF?4D`yJ)z=*5nAbsz`Fx` zcXzMI-%&c2nvSnH1q_$I~yBNR5`ff%I#JtEE$V@&I66NabmZ7Krf9oA#+ z?-=~g=4y*!k44=!`g@e-jKe665tN^*p@uGOaGRmpw@sSuJ~b-%>khe2R3dwyBfnnE z+g7HvdY1b%%HmT~8U=+Jh4FB~I}yB(v=ew>tY?_kSpJY~{FrqJ4d*K7YKq^60*c87 z8joSkJM}2CMp=$Q`RTMd1r!2TLr~t!t@;^eZsj)c{ z`=O57OwYQzY3vePw-|Y~8h)2-y0@%FBv^L^8F?&(Q^-b~&2$ob6kckWQ91n7&lIBJ zk@P=bKO_qmJvZ?X+RY!Hv2a2~MSltldiD4nnkG)GOnFs=9~MzBg^^Xi2&IMGAfUY= z51Y@G^e2*G{XZOCWgy)DAOB&~lf!hK?wHAGbGo}Gr>C2lZccZdZcf*9$4>WjPn#J2 z-~FF?;K6a9cz<5WiVS7q7(5+9w*!KMX!{!(SETC23MN!GdMaIrdH~gQ@4H24T_h$@ z%N3C?5t6zS^I2hT--}+yRu176^AYbHktk#IZX7OICHqH|ARNw_b5>jwveY~+3)ru+>=wls z6Q?C5zJEBQ2ECc7A0OwZGkY#vUno;&81o-RgG;vZd;jA70o?5&X?9mMV4GtI+Pd{$+W_kpa$P5YeOXLq z30Q7Oe+=?kj*B0cgH;c7NXew(&FZd6cOm2>=Xmz`W+}YN+Q>-NEfa?uI8}=31UI!c zCcXjbVQZRZ79e#rhHxT62yp}3W?pXaP;7zGXepdz-Qr(Gq1DvD&mZ*Gi%x;GV7MIw z83Fx$SuyzsYK?4tS@V(OAUsmKMB?AY)=u?PIyJ`{i?By~S7tfv1APx$v=? zdKJQy4Ug(_sSbHNXo9j5;nKr)C=f#TNA3`w0tH>i=SaiZsKs@$OHZJ4Nhmt{i}PK zN+J3?|6v11qwULo`oftlv|ty!KdZ7Gw)HBtwZpo_lLhnLva-5K?q4v+3k#zT5$Ih{ zf6eb3zLnrC-EbOGbiUtB9UhEf0ahO$@NKzIwFgR@(uD5jklTMCCLVwVwjL=3$SPW# zKWZ`<&;-7e?|RUQ{2A$wD3L9aW4K7bkt#N-u~P48Xd*+wdWk-sud*dXljSbgtk^?t z5RnlZF17V37?@=Kpe!A`0{kg}pHPZjw_a+#@}fAp&!p3Sr75TL2ZD9Fy3LN1svhU` zSr+qGt88K5VUWYdLFEkajh$9g(*Av0hJPnu$yxEdPe|fXb1-UsC-Yj=2;&SK|mTPV}WK^k!O-30Xa+yoA zF6&^{GXoD|vNRGXUQ@-r&J_F|pb2D9;0PqJo3Shn5s+rixJPk4d_7WH5nI=`!9yRO z=yP7EHbkK0DaC+1J|gLIMxtXefN6W40NyQ!u4usF8u%e4^bKi-AJILAWP5yG!eoNB zaw;dE^-nHUHP(+Zkply=8s&8K&ga_BbY_0A867P}`6?eZ}shHlfCHw3C3b~* z(08cZJg!>!J6Z!03S!fvG!1rl(1sAQpC5OSsz9NPJ%7fjotzTn1Z(A8=CYr0aK%e1 z=-=By_|TZpZU~No`Pfmw^2(ylzm-U3Wz#?g5O+He3aPQj&v z$lRAYuH+1TU3&e;&Y^|}#Yj6((pBj2;*G2X2Qj`C>Qc-V1MVIuF9ZaUYGm1ak4?kabG@V zLK8n&2dyF}krTtaUlO@LBi<_n#3!?erV#TKnD0;i6hsT-21`B=a8PVUBkZwQTYEKt z8`L1u!+-CuV#;lQueMTuB9kERI-2YNiWChQ%Y}3q0q(V7umT_ZR~V)LA}m4dTSU%P zEYK(esa)qwhUs-jdR36Rl|4fZ9H7fyUb%9nQ9XuFUx4s1O4^aPt-qLz;Vbp%l~ zD$bW542`4hGXN#^;eqH3>_BLK@mQ%og!sM9>~w@vj_cXF@}%&UuWqeL7tCgE`O3lM zeBFm~M4n@Awg*Rfpu}RXeBa_~uiI5(3B<)^QHkBkxma(}iRF!%G)dKDxHCklinN!T zJ^7PHBzw-@01K>VX<13|PV)20XU{ z4PQ&pd_c6nA^a(dlbiOMnCWG-pJqZ59`6k;v5?gRI^>Fe{m%X^C(-*KF77~)-BKiQ zSEI4L7x{z~_PGz$b8&8Yq?amP$OEcNEDG>I)XfkMMraY2uHcrAXM7e}u2th_aVjRX zLrJGF5Sut!uY{qWV|>7~?r(tK%_IlEMzCZC^C(O%^0YFJFLsNnq9s}}{E$_+Rw6Sx zH%m!40$OhlK42-UO8NR$D&+{EbaGqZ!6>~kr6qB+jOKM{Meqd}PnX{$FEwb7t#@`p zJMD(gmE5-c9vLn#-H0 z2K-1?|LH?yRxYYsGI<{hj5@t@s($^~-VfAA{sbN(ldq^$n9n7`FgqQyvD5Ilg|8$) z!E9^sFb%MxQZnos#>$l$)f*Fp(#hn97!!yzwa_i9FQl7RIdM-+eI7lI%VLaE5v>2`W{( z*Fk=mun!?>`6|$Ex76&IyD$3_5m=L*siK*@&ZqO`nk<p2h`;MG*$ zcgx9E4tldUP_Xtz#||?1c{clS`7`67j-s}Sbka~L0T#L3ocKxuz6o%r+QTarc-OpD z$J+HA;NQ{58wD=Ij5@0mDMb7=;C}<>*N84}SI9vEt%=okiLTsl6sLxE%*UL*ars~F z1h}=w3OLZRof-h6b7PJOhC(Q%-*v)2X=1(29P`xAlYapX!uss7!7!KxlW|wlc*c88 zKsRcbF5(lbWb&-3K};OMZQ9SvWaym*vu_uluRf*O9*Vo@(Es`^I)+ko9S7ORnVwaO z6Xf@Qvlh9~ylnVC(Y9`rT{>8K(2+>mB+*iS>@OHjbt}94@$MJW_N;gox83Z&+}tUK z??J1xmF7$c(hEE2-z~xL6Txs^CxPiewQGa|e75pAde z)wsy-QGuBE!1?}Si0ktC(W%~iL}H4eV-d!r>;LlP4_53n{DW*mO#NZqQ!MVube)4S z%lC4mP4>`Yco|SYe@0AAVN$36b)-ZJ)Sz-ltO9Zc2eZN4HQV)vCO& zJE(h~nwC04(^1daWn%t8 z8v_4APY&K_FatGm4Nhks2_CF^Ffj)BCs>S%W9hiH+O( z494sYmIPTIwCkP0?q5wGt`9?hpvV_lkan*0V-{#>kfUTlcxSV_m@R{Oa4gZcRs2Jk z|5en-1kWHhMg9{OM%Zh^5)30{ukiEF@oN%Pn`o zvD#NUC>f{AW@ZW}K!~eJQJzzE@=fd>FH|h>`7J4FIss*+^R60o zI}SQusg-`nFyd(QWCT-~cVd#lENSitHkIOl*Ec&H5%24GK;t;YpRu$)B27YpW!WjU z2%7jzijy@E6Xo0A;BIs)W7Z(St5GHAB9~w}G3g?d zNeN;odG~#g|4UrR;UO`#P$0Be;uW)encDobB=#DsV^>7XOgaE`rOH1&cxmfzvBu|G zTcHcZ^R2l|`L%_ZvzE9P>Tq#fEH~MAy8ix~>mZV6@m;{O&~B*?UNlCR)A<(#FJl#_ z@-{xhTg?48YZ*plm)^tJk3f8=t98Ko!6vqZA=QX^phmSpYvpTd2+24Wm38nTl@al+ z&pmO49iYIbU*v@RSrvAPBJpIer)I3O1!W7^KVA|^aeCAqyf zcZh($T-(yjQBZ*Rm}L*K)XtO^hD6!9p3zbZ2xyK((n%NAs!2fp|6OjKbvwNxrlXa? zOd#gz;vK4#pGX4Eu*tzNg0>a*%h(uF`?5tuHXay1kvbhab) z9*!nK`=Q)vCt#2=l`*8$j7au@O}{N1DXg2SslR!g<7BmUW)X|~xs_f^>5F07(XTi* zFiXL=;D1Rp@GAWeeFqyrngDCTpwCLv=aspYMeTeRtAU;il~3*NATD>TqXcn=&9l_fXQOKfM16qm7^C@V23 zm}S^l4jGwr_6D#5Wl6)+R{m0dh&wScdGaQFYs#%mbs@RDpCP65Y6ViFE0Ij22rtFd z@y+D3j~?S%x05AMo#4#Jq!3;V4<0cK-Q@9h=^w~v_aYOzl{uUa6n}cpMhg`WN`(bA z#b54nv0{;xwns;|u)38LZAK?PJw_F`KPJQ{X^hX}zIsz{X-z?+AQDQ*4czduH7+%c zEI6SKmnRKef;|p=kDuh>SVT-4(n_u;i@N37e-6?oOrFvRL6Uv2r;|++!eXWD>VSx!(>nSO*pt8m z-?QmE#-8eIt&sZ(=f!Ecb`ASKb99388;g-i;p=fp9!xMxd4UWGz_=Ki1CUQ~!lILp ziY@#b&d?>rt2eZtw1_LwB@HvQTAkVMe+wbsya)6%hUWK|nEE%sX?{dY2@pIpSrP~@I*3hB(5gJ;`=`*8l~k94mBtE~5zFMOPq{>JI_pni+!mw9 z!LNTx&;-v0Js6d|+V?gTvuxgtjFy^f)x)56beM&MFF1`b@i+fdX-A&)c^(qNsO|1O*H5qC(X8=lm7`$lPtWK^m|~4a&~00 zEwC^d`dLPd|34zHPsz+~JLy&=NAt<>;)z7H!a*sotq2s0v-OjxJceA~(S}BOjFm^X z&jO>R#gZZK3X2%ESS3=}4H#cr8ZX(hl_YLC%Rv^Xj^>_=ab|%S@MdfLDDf6dIDlm;c|7!oWOT z4&89p<+m{-^j2@gdWSi5Mz`lJ1CWEXh3<0kPw>Tsu79Cb;DN;KczDd}XS3&R6{hVJ z(S_91J3((gS4zX32iciDrA7fMX+h1Tj=>C&Two8N33F~j>fFOz9&g1US{i1W*O|Nkt;#vbkJG02NPP0Qc%zkAaRou=*N$MRILz=SW zS|wxY*Hv$GzR|tjZ!+Vf8+@)!q!<-y-+$lZ3CXTy3Ag}rOTc>sp^J=*PtTW>s=83B zcVaimITU9ANU;z>2XjUaMTf(;8hUll4RD5KqzV4?(_*jz7Q6`{A$+muCZ5mUd&DZ& zK3?0%YknqY7{Sx^lynF|8{&S=?-?&BKZBNp^PxbBLBjp_Ds%VWOL?tnt@D2TxWk4r z7IGmzh-L--XtAQKgBi>|BouUdzrQid z(KJ&g5_4rH*o@blgg2l6FD|DYyWLsRT00Uc@9iRP;ll4FOvHGog}Eo4b;`C_B@6f} zsMF`eNSEJX{gis!5C-3Tf3rFtvC%^zlQ2)`NJ&bror`D^CobhcP$I0BBSe4fNfP6#ZN>rr-& zB6eitu*_ng<0XG2p; z^9B*#V?+5E(dKqc0$%P7!I;=TPZ5s{ErHZ{N1oAC{|h)&{F@6fdV9<7uCNUXlRda} zs1}*1`RiAp$@2)k$!Yv`o)@Nc!VET@pfLbFU;C2Gp`YBmu&JBq|*d-K~hYO3atsxKM(&pj(NoGPra`HWyI`o@$#zON1(#X zd`#ASpabIvjCz=oR~>{1)2Lm*LZ0CSh;0jlZx`(Mn_-jy)1#b3Eg3qDuPpr8v?$?@ zpi^WpxeGHl^sRS}E#~+I#mJ|xCg5)XR;m}DJU^#Xy4VwpT#H@zOT)f)k!0j@gm6y zQM5>h?>@WoIr=LZ+h&?6z-Tto*$RL*h{_aZx9_o^&j2TDcIBs!^W5?Pfxvw@vro5% z6`SC1^dpN5_orra3kn1B*wqyFtsM#$j};zdN1y!h;Y&Md(Tbz|{be(=*Qxb72Rap^ zxLsv;OYlmgQb+%y^Fb{=+As<8kjZxyZ6IALd$MM3{G*wCw|_P;?|51oapn?=d@p|L zzxqG}$Kh$P;-gJYB5pK(Rqy=t&5Px)IMP7)#Xk`ZfF-8?3lql<8?%G#73d;L}+uv;xEfZj-A0aTc>i&Kd_h}hidIS0F_$1e2tngGOa3=HA zN1rN#uYpBMm~D3klE=_Y4x#6ddY5H@UOM?OTmy1}@iZSN8*(HAG6y<)U+;qrtU1qo(Qv5RQE z!K74oSH!ja6;f2_;pEmrH)0b%xyJ(|l7aVm|5!p&iMb zN0654e`me;wfgq6V>!D5jvZLfKb{w`^bs8x2&pzxB*?QbF|RcFu>tyY1BY2^0Hmmz zdh3>V2@A0ZpGeBXZ3yn4`YAUX84G$7p>uz^8zaPN#GdqUb4*&JwBGj>cZ9fH84^N7 zpGgv>K)8U$=UIU(v_HDqiamV3$#E$& z{A-%pj;j*_Q_P$P*BD8))mRDl3c7c!F2>$%0q^qU?iWi~NYa+-2g4O9D?s*!w9FoK zEJElYD>pjrlzzL-5dt?l+;~B5NRIz17G@uwB}zNXe}6s0A-wWB=xVY8`ec$1+;~iY z2Sjl~qD78Cxg7G}W=U?>!fR|O_I@xrBt1gPDa-fIngThB(==M6%7-55$6KNUUm3>O zFqr-9!T{W}DsgQ&r^CL#?00__!y@pON5Qg7sHo0hP%qBPlM;~-JfI~N(c7tR7p7$F z{pKf~*UQPvI-}+x!w8O=rQ?xy6_SY1Q^n<#7_8-TAuLHFSo=8S$)+Io6xdIjb~G7{ zd166RFHBg~Wh{Y3!Ab@n{M(!9xLl!2A>*J#cVjV;L7sCuE#}M}^&vCZ>PW6R7s!~i zYMYP~){t~83_4U^&08nf5SnZ8V8HS!I^B)e;JXdh;&O=Z)+RXrUFa-Cv| zu&a1=O5*k8R$)&r7#!RL`N$D~G4kH|YNB}zLKh|Scpn#p@`pwBhBTft@ zfHN!*uXQ^Ag`nH+-rf{u3uG3vm>*2bTRi(Zl2p*V*){))Q#d0v77-`}RC&S+E|7s! z&+x60j_OF%G4sguMV`qVGkjWVJlgj!-xzej+Pi){f6hzSR_XXL=4?b-8CQ5c1w(+vKTr%L?Oowy;k4}eoFNuFE4GC;kXP5+N zfJ)7HZ5&RXQGffirL1303a!B?O)IR*giiT_U6lR3_Bae$w217%fIsQa@MN}nQtgv+ z#(RD0zR+Fe!622;_h!c%vSZh*c-n{>S-1&5Ln}A$tflOwWl{)pYPF;;mQErNBY<)* zHHY>X9VxoqNESU{6KNj>KP4!gObzD-uqRApW}~ee&Q=?$o0^S{R5cqhbw7_rUJxF? z!5&TV6Q}S`d%z@z7Rv~91liZeL6ISQ%2k$|WhH5EsotiL&Ng*zkCqy=b_IdsdJa$%)?9ei|PxWx6@a ze-85{obf@ee5f;Q=W|~7GCoXE*L#9!)c7ZN>FGfVUYYKkuE~oIjQ2)_*4w396#ql( zdlGUXFkISNFs<7rz%}=hbGsfmH)x*!#6`zydNomOVsxftfEu0AaG<5c-;)9r5V=Bp z4UYie(rv+r?cLE=^~!^BFEZK}i{Cov^qU=~121UPKduoNuPin@*34^HDrsDI+tfSn zij`@d+W3`Zr#L(Rl$MXFb7Tad1->X~GMm2Aq(Di81D7-Bl0LqFgXM%mo*n}L&aum< zVkL50_)m+JJlI#k9M44S8ltiQlrjte1vct!Gy??gce;RK^p;^oM?rE?aU*m%CNZ@;2S*1eF>p$;_Iw zd`Y4di%d)gsY6PGfs$dB2qma4yh!^`nG6J*`Ifg8QN7r9y5FVY;pA2bU^K<>xrHxm z`?mS7>%4u`+Fb8dj1B+OueZKRkH8mAoyeS;WrL8NC66SQfRE<^;!CphTkv_4BCR`% zr)aLn`chk%lT#b)i&IxLdDNP&67X@mFp1%kD5P1`@p~QgZb!n<+%v~@4pyp`y>MJw zb0CaLrZLlavE3sx%a5^@GQz-lxuyO|Nhs!$ssNB~86HmcEv!KpfRV)N??(wAm7%%u!dS`xC7j_qVJP zJ(KU(*=(amvWNHvdVE2GMA*h{Bs~_%de;FPci`Jo^#B5bCo(Er8;v{> zBdc}lBt|T0|AhrB`j0DR3y!cgn`^71V9XRNE^K_FNh)&GS}nK#0x>sFnxwyIdGS|! zS**MJ4{v31Svi$NdBw2ZJ^h#i6_XfI{5&S^w$x~4f0;qJ&Id8tupI(55U`~;OZW_~ zk+-C6l18w$MoB)&Vp(g;E`Nf>L2d%QuQBiM_l?wAofZ9FzNI_>NhRa}&cdF^q)w4+ zG3K86?F2|j33Y=|ZGOjKJ~W1G6y}7cspc%aR^{;vff5*|Sk}Kudq+k%ZkKs@mnxzF zEJbvXwW?|ln&k?RWx=HSeJL~6A`v#1qs_oKn#T2N&b7|x4@GuTF~Gq3F=g`Ux)aHn zHJZnDk;}RBSX=Ywn0M!dqmpQFMZ|u*eAVt$DBI~xP^6Si^3d5p$5eJ6T#KNfg+s>h z55w^Svc^SxditK9FyT3id{|OaQr1F|nuw=#WMJ?!NR3ObcI^0yw%K9wYKI7w8iEg+ z8hjpUAT)rY}UDY4ghq6Wib0L?M^=`Ii)*H_f)@yB4XZHmT@KQFdu4%bNW z;|nkvV87xd^->Bw3NKw%?|RA;cGf=bNg#-yE;qUry@&#*6z`h+`_Lan@(p@Tvn+(1 z204Wli&VA!5~2P5*?_uUR%kMLKSv0xB;ppsV28HlUjvG{lkVTeATYOt`~QtW*|8FF zHqmo_Kf^bg5&|8x)<-2r%pm#;Xnp|Hn(EH2R<+&T>!}^SJc0;GKwoYytOvs<1yCfm z!^p~MeRrw4KiZ1Un6}t zKp{;vaBfx7xnBDKGeLR?g4z3Y156LTT!-2?&G_JKnWSrv6zD})kMJP)PoRPO5`ERN zzaTE5-AU&Vg^!FLtVO%IYpz}e{K9L!bcxUz#^SnqryNJ#N>0vpdn*6I9*g`ZkcZ25 zyznRa{;J|I?Ixqr@Hp2qj5Nm+v7{dMTnTHX4%{0j9 z`B80neB&iG7WzhV_wnpeHVmug(6&DM-6nFw4UL-JK0+!qgc@jlkn_6RTyW)Hsvys+ z5`JLZ#6gTZT}l5@1^xpB+%JG%7YwSEwj{9<+eRl}JhL3#J$aaZurRJGhVsHA?(iZa znOU+0vmGH8_={X`zvcf0EaOG50%8El5X|s5O5{u@JT5LlGA#Dwwaob?esc3dWkig* zZm0IiC7JVIoT1v!eZu-nstCGAYh-9u)Ol#3^!Yd^ zuT!vXZ9gfV63eZs)6vsw0fQ{d>4rIW>xTE(e?#cDPH%<{$-e-TAP{PyU^kq{!h3n3%zN?VL^9f4UKqWvj$tK8YDsBDESC8IY!*tJSYUzy8`s(0MNS= z^(XW7QA-ib)}s~XxS`lQMmlHc>>N#K^;E*d#YC6PY*+|_w&UgU$rX4h680t`1AU5@!Z?QllB~*USf_ zDMcP%V=pggY8%o4QBrLqq%nnZRLcuD3;6yPU5(q~zJINjWmq5k$%UxSN+lm{sBMQQ z^o)Mi>w4cDnGT+rq!~pMUq!I$!VQ|U+#%V!WhGx_odbJ_XU9i|EB`8&Qk`rSr~s-O zyIealELJ`Tuie*#XlSzP9pZ`?Uz^n=rSBAIq)9othJ%A+a$;Ut!*?(amm8BEtmGJr ze)gIyVrbN99Z^`d134=qkE<8=`}pPy)thqcALBOy0_5YOwYJV1)~_fZNZnCWr%@)6 z8g1qvvE)LdfSDfzfJGi%A@x6mu!ry*#XdtVOZB&XLFU$wG#v$SeCok3&bLI`%u@9M zAbB}Cr);C9u_@7&&pviZDZ67lAlmJ_Y&kxM)l$%nL4zkiG!N};1U%6tb6BFu-H_`_?l>*-!?F7bXAcmUfe%t1M!^u~NT3YVs zlZ#iTT0DV*6og#2=weA-r|Jnh5f4eo5ufca7{4Yo`1nTKY)Cpk^n);R5H)BbLjj4> zURa&szsb{NC|9~pta*_e6|3ia`O-Ycjo;2gZA)+GDA+SOM2+X`AS_g zXqK$dKY4kXR#nD+_OHH3Hyy3xm1PvV6hks9b{O&W{|k`#+2Y%MZD zALof$xE=M&skzxuEmk}(vEQ?-+ESMt;&qU{;K zIwIZiZI6v`h__`>@Hl5Q5vHwyH(;`*A5=2Us}hA^|09{LqIN$Znbu<|sB)Y97dj9q z)kbZt#fXK03DY8Jxm;c{gzQP(9JyVeJ=WW=pm5vH9}5QNn9!?%67r?sz?Lizx<<

l}N2dZsJt{>v>7en(*{o5>%iUiJC&@q917hAU8(BFA3NtQwgJsPued z_pmF$9TI$iAn(oDG7`%9cmpmi6BAvL68T9DD~>x2eX+T0snE=fdJR^y5{hh@T8g5bukY*DhohY3YA{9!G~v!0Mq01>i&5p1 z`>D5Tbq6=U0B>PoKH1b4;DX_0>j&F%ICd*4h!OEs!Vn4NqsBEXV}>-5cUUDc#AjWF z9*-8JKZ^sxaad1x{!RoMw>ZP9oQ$Ss2^NUDR#strb~4vbtWH)>+K)rZ6`dMUUT8N< z2aGzg@x|;HIdiE|XIph!2{?vCfkIUd#Irjx+zFhQHhS=a~TzBiBMS z9$W!_bSnwsHurrd0zaYN`{tq|_h~a(+vv(}Ga`DzK>Kj5y(`NZooU}dr!p$M5x4C} z?X7~zN_4dAh^+Dq0d~!Nn88~kAf>?`-g?!jR-t9T)aKR>b6A_dQli3TT50B32<6qD zuPSWNO+>)x3lGQlo#kT3!v{b8N-*{@St5}>_KAm0qrt$i3(*&Y@}0cmzt=NgTF<)j zb39mecHp9DaZ!@YUnHaV=>sO2RDXVf`ube)tp znDnXnWdAC2!~mQ_ZVhzQ$E&Rkt6uwN%b}4Y%Z;MP<{n+X4~Op(mk=MPVXzbXYAUhm zWf324s9qzg{gtLU912)-D!>eU`s;pw{KBGu4RHW`0+EcL@s907}Vb&_#FV|bgzqs71okT9u8o=SV8E5)Qc*gA%c z!MwrmzI>#Fs?`23M$!E4Yez~ZI9rftY_ZPK_I}lSCWHt}To*dR6Q7X3qku+&$;Pu* zDr6|2w>kKG4JC#;p!R%LeQI=TpkyS44XoCF%bd;1s_g)v0EtkLHe~OWRHdg=KqvF4 zEL?)E=GXI+&o!|ODJi3|4&r|=ET@3CKrV`qpLj7a#(3c}zX|O`1(~T;hdG8ccYiw% z$2(2ftDg7Ev{HbG&fi-XVOy zgD+_LdS?FUpw=$ECMn&?r@7-cgUw#h+q{{ns7@zpcX;?MPtDnqi)@bnayt0i-=3Xt zH)NUs$sDiZASoQ0}afp;vHK=Nu zmX5A>+nU%@A^kF0`1W0e+DdX)jS}J04xnv|FV{@(XW7%CCbWkhg9zv>#spWd>%W1j z(v*q=F~q-iEVkW<9>PN+elr~|UU=XCy*k;{uk_7%PIVfHOpXVJJGFw_lq439PMD2b zkVYjx7=;W^B-e%>-BjG|c%E%1yzEWKZ$L(rsMtAD_wr18XY>4dtu3Ijn#J0<{sd8+ z*vy@EoLbg^zX*<945i9zu}cT(_})eDH)scM#d3%csQl(Xvx{4gUr z20D3)I`$>nHS!Y$ep5MbPkjt`nm6{o=u1R4$+UUYF#TB<(pn+0*>Ag?*G~Za6z6ar z`_;SL{-K3QdTRI2eI(l1$ec2elt4uisfhzYHq!S*A;gDm=yBtFZIrSk142Lk`%g{| zEG4cnp4lw%@<6h|2Z_LcnT;TRZ$wN-!4AIarLo=}+lPrWX_lv5%wr^Xd~bKRhZHLs zLqag9t#cWIp50n?0km(I^ThigkidPsf$L9!%fpgV6jjNK=15(IT+f2)@OrT|JxCX` zX62n$JPgJ=_4KHuNhaO9^DAd(ZdoTH(MLYJ8+#Z}|7uJzXw+0G1oe)I>Ll3P=mJFZB)oymM?CD@x5_0LJ*i>y@1y zMuD#;?a>sSDnlR`CChG{Xmvc#IW|0KO#X^)rMy~i)> zuH6QLxDvR`s4OsNg4=W%0H0AR0gHd?NMgkJN4a%>pFmcfTG`yOY+vb~yv|A4>5sr> zrL$^M)H4r+z^EmE1Mu_Lx2@7ZDkUD>m$R{A#l>6k)lTRW5c_^eohS3tgoAjsD z={A3LK+q{+PuhHVfv~LYn5^&k^a=0~R=CJ`Ep-aD+#CHlSt@qXh>rD>^_2V+go9pN zmYVq8D}`c^n{7puD1>NaWJHkjlcz8nQXG(HrWTP=6LpK~buM0@U8uyMlmXDsG+GQH zo@Kf`4B#?@)?hps1dnJRB>g%p>FtBRl0LPtm%R>f1}MJ^KUr*21SUaYaTeKy>fmiE z0_=QTRs+AAIk_#eK`rW6YU%leS15M=;r&XMp(dM!ak6Hw!pWsYM|qDXTqX}$I6A(@ z{#Kr8dodJrlbf|t)wNlm-y=}H7P2+OP6iar!?KDh3>KCtaOuP@&HvK4%*u_Z3Xjczgl>1yENoy%-|sj{{mwRqZIKD`<+<|@;Q<9PS_l8vyv|C4`!M$U zio-1yPqiJt$EMNC-8olZ&ri!RF9Wn)6(DeuF2}?0KQpa^Jd@Y6eul5`7xPRK_gvSo zK{g8?6}#^DXx0i=q2!N(UZ;(Cf~|%&Bs!Ls5s2D#!Fa%(Ne4*GBgS){vRU{(*nH__MqbzGajpa||ZM-=@6C^^SXor%8XW9bBl!JxASQ zeaHw<0+GC|7hmbU-L|Rf+fk~02FPej>zbyR0q-rrzYUyz$K?x-t7Yn>9M#YYO#aK*5lHX{++fJ1nCy|+& zOz*d%{=kA_eolG>2~0ZHdwWQJ)iL4jzTZP}b<1#&NY3(q2mubgZS&q>rnb>+TA$nK z1%w;N*5m3}KnO|o6zZYIjtZ#A3@HN03LPY@YPX(^7@{BDE(280K8LMOsQ~2-rUr9! zXy;FMLC3uzIAp>CH8Ugo$k|j6EUlSE!TIH@{ywBnQeNaqR--`Kf`nG2Wzc_3b#>%! z7-}(Gg6@Jl{C`z2E`GTmN$ip~kbe=r!lXw34=zmKz$e44RhdQ}Fp1os;O!>&nFHwN zGRnh%`Iz@1J9GVp09lgqa!ChlBO^VUX7>fA(z0HYPI-Ebn4J{;bt(O~|C0IY%-Ay9 zw+CX$>8?F8$6gb`0Bv2x*!gD7n6@!4qGj%E=}#3v!`;;6*zS)(QK3}@0i2=lz@`Au ztSA!&M7U@H6q^U_g%IJ%a-(>4%l9Oemv=+i^ooK^XwRP>&-lUeD|t0*H=QT94sOT( z>_o<^5-ULX%&(A)`vY2G`-JM{QmXD}J!7JBXsPq(J|=}L>(}0k)Rr!){J6LY`9a=b za;PxM_iz1DCulSxKvvL} zG)l!v?1xdn=AtLx+0wK z!9l3|V>4fw4;54*vhiSU?GU5zJzv~LrDvdwcUW6j-|7=k$qdNDpe0k#F}rA z)ppsl{+?D@$f$Zl!Nv6dNtrl+ZzcgJ!W>gq(?+}3oBlyHgYJ|0O_Tm?NCsEe~GI&ufdQdy`Y5suR2*j+6!02h*xL#1(2rpzixYg z`=ID#`8BcFk$*BFa#XwdR=;wQE>A}s^Dux~;!WRM?oaCY@jXNDEG%Z|9T^k9BR_r1 zYjo_m2))f5GCx^V4K+Dkbn=Z#o2$?si4!eQ;v=67${HL=PcKdNIed51a{H5rj+)wN zFs5BstLj0?$ZOZpFpXLfn{00)li}&H(0kDJ2eI%6O%h%mhDIBKn&vNkAV2Q@@#VPS zMrj#ou!bv4%BJo*pBtKW<~>2Em{YkvusuQ}3s zpDy}>?PAv#n*5JK9WxG~)+J^*UQkX-Ve6iY*yOnKSAEr_Xe0(_&xg5CGL}24uuc`$;#-%D5yvi~cPx zu5c6_U@5tlTAV_%+~!}AS2!U*D$G|usj;`1K-jNe_;TO83Xl0>NGe{5V$&12vYbD;7%tm@WmR90e5S3w|_yEBHeSz@v1|d60PD>lTC1=N38wX7K7%9r>x(%&x|{ zF%r;)rhuW>XzHdkDaK&Qk}fcS-$Z8w))Pn365-}^FrYPTV@(=YSZ?S}l6HgI0%-d8 zAf;?nnYPj8i#&z&*5w?VOh&M*Sf%+QpVrZhd!qe{Ad^>z{$T8r&I&Q4g?xTxFtNS? z&yi)(-hUGasF)WBVG{-vZ=b&&7LmKsNT}&5xu2rj5rzc^!`rBaTX7h*tAio=)A3u+ z0G@rh;s^y78ojHaW(`(rRVHfZknQ%Dm5qC&S*|g?mAQwetaNhD3MV7_APM~I$DNT$ zK4ztbbEMgGDN_->x*>D;-H= zc&u`XjbI6|?ps^4WDALwR~+ooEA)21xTjQ9e?Msg+EsK}Yr10-JinMUf7}Xv(+Rk1 zXVLJNWtZxMeSY9%?kj3smjQ7D>M=b1-w*)Vi&<|E;hrs%)`?;3Veu}o&kRMBSm~1f zhID~WJO6x)uhQpQ4ukF`jV3YTuD;U;Vm0y%oFkHzFp$nn2iE5YCcUfn9RVlA1KCA` z0-iGVD6jQ zDZaP5l2!V4j80f-R75~n&!dCe;q)eWty=|rS=jcUc)6$^vsQHclxS}8N>{jwnxni# z93{DsJ8zQ*;a9R+jj1W&pr9ZO4yrG*;NNxjFxCog@hO+1ur} zvU52$ba<48gC;wX12_j-6dwM3(u`idQUKl#(D$9LI1NzM{BLFI-SO!>FG+wiN@j1I zny4UzXR1Smg!jkb0XrK`2$+oT?(s}>@VDLG_~*+Z${R)0VCksI1faV~XZj)Ky_3BB zp(*uOBml$d#ZVx_;az4w;~k2+m* zoU;7({rX^L#*Da1)6aQ87k96y-S>HEf|NMNucq^5fDG`4UHE`Q*Ut0omIy@fh)_Zg z=gKl48}Z&O71H6kfJXDXfv&>O?NfB?^(Sua=1aGeq(;Ss3O-1#M2tlHPNrkP+;&|h zx}shuAUjEC^DA`BEYxq6%{kdd`}FGC*3?;Fr3+tw+;3{#<9m5>EyTvPi^x(q98Xiv zZ}ad0+S%0!)oFyncVx}SHDn-=hAiZ-GU>U{k0uS?;S?!G*eNRUQv5=t6;QSb5a2MT zj1&sIb``gX=oF+{Hg=!TN#B)!XPT5(kf41muQ!!6qHyQ`sxXD?;}}1@=4lFxr+2)j z^v{OX|B*NC;if&vovkUi9^jwSwtQAlOs%trJF=>#(dc}>ZB?-S+`_#fXOrsh{AJp3 z;EBTYY+c!Ur6G#j!LOswOOFlN4OM-q`Rb0=x)fDaK%N*NFOUoqT%O0v zfO?*-=T5lgG<1KX;i@&7@ecxe(S|FSIVr*@Z_gyNAT$!}PVysXiVZ>sH)OgWVj{>| zlq@DhKe+Byq^`HO+CJ;r7?edr@j-Wsqr0&Z}uy( zalCmdH#3SJ{qb3H-5-BW!AN|V2t|3eq}O983_phrSdPMDh@maaTA2AE-S6}v{){ul zrbmCM=-Uz<<@5WEvJ*a@8)W<59w%Z^+Yw6!C+KLT8TW=C&{*nkR2gGBBc*xPtHHfw zI=HmlSq|pO)ViDW{48iu&R*7C8OW@0vo>lUd>i!+H&UNV8>PWeULuXacMY3XHR*Gi z2cXx@&qHS&h?NS~RtB68luMmrzJ6R~W3w~7rb@II=QPiW@WP1T03uM-;Y?W#;7PCL zwt3HgFqBy33zhZ0H^;M{7|s${I>}uB_AUK*@uHwyyY{9@;c+OD+U!I}vo(P;U{8pJ z9HQ?jk{jwC)zBUf0J3Og*cc%J+Al9cPLyJC@PLed?ty}Nz>Njdek+yIW{Xoj6U_P*k>TODo#ZEN7hCWuk#r#VA2pskV>`9+5_#fngET zWKx*`X-Gnw^iPu8jr|f{PQZh9iz2uzG)&8@g{f&2!e!Z)5uO$eoxi7 zUVOX_S*#T~+{mq0Woiyfmtf6`r)0oO#&;N@Sl|GVsu1=)et7%uBr?(P+)&=1b>3+F zn(Y;gdip`Ry1EG$oNWH|O##*W7V7dLd36g^0WFJ4&Tpa( zR`P|~@3HVF7FLZzfh;E)d&iDud5rktoSswEsz|CR5wd^Le-{k#y@o`f*)zOs9L~|B z*-FHDIZk@j=eH|C+E(A7Yw-`|7nkmN@ePj0y83rLp^`ISWz*%6baZ@vr6_**jJOT- zUWNiInw5W71-+-n*K^7NCe5*yuiA~71c~kx60?`pre6=$HTDMj1D>#4V?Nb)aVj17U4^5PMD|@SCS*i$g?+8DHU0O3 zbbrDp{3Q#kQRy(4GEaPvE}CAbazW>hMT9w3;?Jv#sleuyU%IoaUb?!bXwl3{Gcm|- zFJ7{|bi&bEzYe-JELbD^@y9IHs#iaRUpptlF7wu;r&&tiW-t(f6eUkXLqO%UDqm;h zR@n943v;H}K~Gk`ewAwSFqJ1U{vzA%3q{`V@;mzNI4nnAKgAoY=pKmOyHaR5(P=jJ zVYn?VcUeJScY!n=oVNDWZj|LI=6I@M0>d-lG=W@57C zf5#wv0f&ur++lZ@bT^j3bRNp7A85{qOq@5E zu=A61BrY@*RAU)06F{%_q6oHD({6T216pgC)bL{c!%d`a%!cDUW@>VvM0Kg%3AvMf z;wEm{%8Pv(SygUZ1co3u{%XY)3)5$nZ)VJEIse|l-5h~w%tv%ISWy;#KOj^;OCQb& zDd0QHSxRY@PQyQ>^}{plT2V8jBfb*mcj|-MUVOOxPx7OOG668<3#a?x{dE3dy~b~% zlQ@D*1CYnOwt?@EX+MyIXEsXE)^UO4xg|!5@4Cyva(Ql@nMg=T2+H!3M<-jPM@GC= zvQhkQmb;8Jb}=KvDsCd7X$jP1;2*!?QScORhoFNIQ~3a)bKSYo!JhTo)291LKz?{8P4raPW#1($qi0apHf%hNSZcrUYa>|;L1L%=>| zu^Y|5ghYvAC?7-Lhp9#yYXVcS`+Tt?KjG82q{M}-y1f=7dW8hB-3MZ z6xi+Pax=#v=nTinox{fZw25 zu|@Ex1I;jAxJvDpCIdBK{Q2p2is~(EA8Qu(r?5V@j#-!oys5*v67)7ALa-`( zY=Ex^WvLZE;{7rAlw@-9-Cdj_iGmof(#T9p6LBFpGs|2Sgb#2DGmjU$-zLPss_OmT z5m}QzQA!b%K;}3c-(2=|oO^ld00I_i9}F1ok89ZgO=qOLiqt+JKbs8o5HRrid>lhq za*;S`>gyTTcCB&RP%eXywLBq``CXngqh5+uNkb!;hL$XOmYdd^&LnSS`W+4x^~qkC z=VY4B&{s?EpYSeo1h{|M)^&J{z%i!K|tJSQ;-65Ke#G^?4~q; z81@yQb@6F`S6BBxhnWaYd7;y8yE8mkZ;#-ZMBKTpd!ummODy0yWtQPSeo>1KZiIR~ z%4Y6kik3#A9C?5E0O869Rgcp)L(!K-K9R&&tKT6o)3x+AQULsv#s5J$3A!$&xZ|FS zMB6v`h>bcsCtsPhZ}|dJWJ`$rPSsUX$<3pPXx|f5byp+A6$g{RU;GKvAZVn(V(gRo z5T@Nhi7B!C8Z*yAjd}OPTa7mUf&?vn)$4iD897xUG@go2bN-Fo_C9`;!8QxBzZE+( zsDY%ZwMZWO&JkS-BDlET$RCDmjAEL5Htzarxc%o}qjTom}OlA*iKa z9b32^Rrhd!&F(tTqD%SD1T(DaYCL{-HfS2`jzZRMtKAM56`jbFCdBBO`WbX0Fpj>HnI25O^$-HI z#5FW@E^GvuT#4f;?{EV^t`jnOT_uq|;R~Ja8pj|0jv%TM@q1q`CiB z{=HJDNO2J!az5=*buamA%=M@&=^>jl;EAavwl_TK&33h1^%i}F;kRSi2XC2!=~G+`{CM(Qpx>&S5-5()FtX;^ zNv$Sot&l&G`uo?mI(hcC#nF0_V)&O23WT%(3h9IR796 zVKpp@<0-6X*%6rpS^_9;#-k=!423hUf>Npi=5e4(55*oWX6#_Nh;+z9=89YQeR9CU z!xI{xFoj`&g0BuU;4B9<*z*DG0+7S;V&ab~EUe=chW4Zg6E+(ph95)l0s&xnhM&J_%QHO= zT^qG-1BoccwwjoP?9ni==OQ?lzY6L~GmQKCcC0T-ksN}e5w-+~FysWMsGY?%j92E} z(t!OIzox)oyzg090eh4LD7!&Zs%~SA2A63*$$6W?k{^qk<4lVtQWTnKw>m^)_fv;w zg$xyuT+(@xzMAJ3B?{gXo!HYK)JbBmwrh|K9!p9NF2)gHo8;!LG1`=rr$!+dVTO$% z;E?2XY`FB@#eIaH&7M&{%P^|kp*>7Z06AKQ49Hc>)|~;32YHFN$MyBgRmLGPq)OjL z4BPJMCgz!V8pREbVg_obW!1bNtY_!EU7f19NxWk6IL)2AskV(-NX?eHg{%Ih&Xp0` zlFgcggiYhr_&<6it=#9wTj}Cwcrvg4lAcPvB`21R@ltsd#6qZ9q1Tb;XzLAwRUERT z{2@}4PLrLXII7&u)o14``j<-0D0iF%E+|$dlXs}|U&Z`*jqF#ypn6jn6#V6BB10N@ z<+WzdGgkeJb$aq|%EKAvE$<$r$pV^MD*k8_YV&HP#=nIkau`pR(yeoU2tyHjxy!d? z68etMRQU&7$qTFy>z zbW9Alc8ysgkgDAO;Fru;S*ZH41W9Qm1VfbV^RFz5Z~wCYL7;o%H{@Wn;;2F;%2JPW^TXh~ z&r;Wd$e4;Ba5Wc{O?LF3^~k(KAv{i?z`3$SILhvwrIm3Q6`(VrLwAkbbjWBoy>BQ$ z`vaHJE1O^-X46%E2AOPlCk77PL>lwcaTDv*Ube`K4#iZR^`{K(1HfFPHV?nr37nFw zxj*TeKA>|Y^3eQ|L9zb1w(vJFO3stJ3Uvi}_ee7h8>OPKL7`0aOXcp;MM$04Z1%iY zy-C>27nZwp{tK?=6JE_93Dm{hI8?hN1=`0(e0cPGSyJ;zY#onr1Wrr97E|_MIYqE< zJl2&uw*NGtgNTyHhCA6Z=Vy*9>lWoC7FM+&z45M@!bmp17yFk-*V|(>xsWgv?eoP$ z`(o`O2mN!}gW&5$d#ql(<@e=S3pO}dENl+h-UiXp=EwBl1F7NURs^(!X4l;zQw+4k zkT5rwF*a#g*>@76z@Y%;^W%mQ0!8$>O+O>o@MuiJ{=OH`pFU|(G}fqfx`f2K$t6Vlh}T>l8)GLtjjp?)(Ass^eM8e? z0oPqMKo^G_J~UhQRSoQF2#~kpE1ba7g3kaCp=Hi*@C9ugp27*BqWzdh#0hrH`l+D! zGAuumihl$p2Q{u!!3cqkt7^7%w6V)$T>th=q*h9%>{QQktIyXP$atgU~;iG2>Q zn84fjq@|)(T=FwB(;8!*wTAS2CRm8Zit`hvUnTuMK0XlpsK~RcXUrfv;eDUG*g|X% zr>ikX(O}igN|3`_V?KP*eCrXGT>yr%FoPzsDv5m#YAAN|=$mV+5-8^J>^k($X9ZwZD|ipIbNS80?C% z3D=TB^;k5-6xtU9QkWV96UE_bU|W-k9SHK0xXWxc;p7KD{+;AF+1T@>h=*Dk2kt?2 zY^w98b(@ZBMs@&7ZW52}7lsUp!olxR4Ivt&c>|8@K`VQ=?TCl5J$nKJk0se3v0T*T z>+V>g6YlEda=-8&vq)+;u72x2w%!W($8$BS$16uVyDVEPi~8P(Cca++Z)e>K@DGUM z2-wgSye$9@J?AC=4p)9qZ_=}w7uH4|<^m4g{4h#!;bOaEf_|Lk^%#SX8Y&~c?zvy; zc0f^&?GI-fYhRWVpp51?Da zbXj^^AOm0;34PRnf~0(z<(CKBsDNTH>-&VF3xUII59I3Jr#C!!a8WJ8zYR`~uD^oc z$1R;*Xus?1?L+^0vx`>vyX|^!SMW^`uAZ0$sh*vSy5_rs3YeAVJjTR}w0^(j~j;73sefGU==LhGn z$@)E#-k3BpJqnf*i}w1?a@jZ|;hTQw13!lSsZB2;y?p!&045NJm@2QQJO-Y`y|CX+ z+vt8C5Ce^2dP0w8?D<>eBrA!E)qguOfY-eBov-dhw2bC=Cy0AJgobm#Dee`d zw~*YWqy7&OwaE}ajaieQ-WBg8{7CL$@NVq+!4{=!y~rWKK?5-ci{E;ZE**Nuy54XF zqz)GXwbv^6TSDA-l46;pf|Jx|Uk}B6!Oy4)(Ezddb`r;S9#r^^h3ok4$#o(X?Px)1 z1P@>FyX~x}R#h+s!V*CJU_iv+{7~&;f>|t8t7GzaNLuZU#OzPhTsH#*wlAZ0rn)`3 z826NPxTF~F@1{zA(~NwfM$C%0d~2Pzz3nb*X_{bC_?B?HG2Kf2b2gLx$_xG2kLCGQe2m#XyYy=1Cg$+~|7#Z_L=Cf^%T|JH$*{EgN z)m_{BRyMg%vrw6DMV!u1KZewwKPG4ivUSQlCs6#5NR)VAkAcG&!gvD_q3qujEH#x! z$X*boUpLE2f+TO3@ZE{x5Mc`-pba50!pS4vsIGB%ZQ+i*u><2!8w_!UFfKT^t{Z+o zUg~{5w~Ne~FdC`d%D6c83MUveY3vstI-{W7&XCC4NMq|Pr?&);?bTV>Xih$ufQ&zG zdur)(IdRClcGjVxmQ#vjI@9^k5hEyMNfTg}iVeMms%GYra%NBpY<5_oWW`H>kTYFf z+PxmChh?UF;0C{^`bO|`XiL_KrK;!W6-q@oXfs&^Tt(3*$WpZb@hm|>Fwi@?7YUx9 zpPE=m;u>FM28h@VPnRQ98KT)odjgd3TiP7wSAI>1ts*mYR!pnJ6K@ZQ;Ru6!Y9;67 zA1yR4PpCaIZ%(M&T*R`HJY@AheLT__Eb;J;!^E!u`%0ssXdCsk=Mxh}igJaEDrX>#l)c$8{Rk(jA#&uc`0R2W!C=w9;9;wosPC^nkd&*;B+>eE$O{|FQ_YW&8!@%#f$4-F?@(ufBjU6s7ko z;G1nZOwV9Y6NR`>#%o84W8diyA?+2Tv8OI|4svbQW?|$_2sr;R3X%|!OitXrZ2ouM z5iwF{?SGweG)?=L*zh2Iu-%D#mg6LqcZ7$Nl?%a$PtH!5X1ER`=22katQzy;#8VHy zAd^?=U;f4vE5Dd~FV7UOm0^sC{7}NJu~cLq26nF&9+S$CCpCOqj1Pq0m%acX4z z&xhS-Fz%Qi>&yq>mYGkYFG4ude0B)1`6KDK&!`3Y){1UEe#W2TGKXLNoQv} zaJlHum@ZAi#W@Gi8dD9b+3c)UnDkXF?#gSQ_O4k5EKZkBb&p*QPE%gQSBy}Dobm$x ziXOlX}w#DKQxlCEce)+|g?T-tAy2K1KP0%{E> zA~XPy$VD;?#Ob-K32>f-#dl(-%;U+{>Q4D3uP7rFjSHd~LP`uGK+TXsgcg#`s8 zlWz5z^>sO(tyH3Bji>O#vL<1|Vuv8W677Ts1w&Tp=24}iuyK+o07V0*iA@)e<64Wh z#wP*tJ@YOjnY}Y;lLwvn_?V;me)8>^6WY@_LaBahD)t;)Hh%&qhZZ|zWzTIMabd)0 z;AZk-zYkRy^$vB|gH+NZy~?Ewf5TN{Fe~22A`@mwwAf$mw)xUWwIUIh9Xi_XDl+SC zFb)yj+a~l)5(Gj3AvNDR=PJMB$EVDdsaHB@lZ3djFYbEy-!kE#EOgaYSH@a)?{phM zuD0$kT0Q&$nA`K}$=7Av6~74E1|!2tk$c;#DM+eMZk#o&Uwn(j)*kL89s0qa7QanW^`R$d{d}(Kks0R7ZxI5B-iSTFr)_`<*0eWcS+9%u) zXlQ7=;^fIuVYajC^4meb%A~K$@%FwuzS$m+HDFx-H%=_GSQ9}k%o%5UE6;p|_cY43p%M||;c#QsxeS$R-O1Q3 zbX?ki5k|~`d0x%YYaYB2RQ>ZgvmQQykF|s)IWa21=VbULB!Uz z8mp}z*%M!^EuVc{_CMymXToDSn!i9jz8z)?b0sT{U%WBy1g8ZIGToRiL_h2M3g;V8 zT(1(JJm*Tw(Ob1=?GU2y(?dt^PXde<;?LZd+>M|Nc)9DjTe%vv*cWM&@B*PI)5Gnq zv4MNdiZ=6gGzkU!m!de2s~!H)XF9G5;~nPT<~zv7C49F%@BP{CRCWu17>}O#-@1)N zd+0rZaMSlJ?>CbRSPU9yQEN3ejd&!#DXsv_ZG@~$mVYakGC|6bLHO*8tI)iNx z81UtGBWi93uh@>uW|7|Bdz)jrP-zf*O5;h?!l>6CuRrTYbZ%U=Bkr9^TeU`|CMRoh z3H0@`cTN9{b5o_yf_8b{Rh$X<8D6=JuXbdvl${9(ATAh_H`32gXRmYwbPRIbx~qAX z()${ju;+DD!HlkmtW1$=CczTxx!RRO{m;(+uHRN! z$HeWr-kx0$H*Z>_kui|4hIzdt-A>8#;c$uL0ICXf`-=U*5P7!LJ=dPgB6$oSPfHoe6g3qegcL8o9u@{$|LUMfOCpB?)=_*vGpdXUM&BJnw*xanPB6 zxUN_s+ww`Oz#Q_PuoAO|Za?|Bk%bJ0rCK$sf)K)_lgHV*{WPij!E}Ez&?M|C5%y-w z>UstMrJo$yZ@wG=R4KQU<!U|ipO+= zy{`3qdB!U@z*u3nsTknmzc!4SNd?^!0H@wCu;nKEA|1;ct-l-y0}Dh{eA&%taNICp zZ9A7t>R_frFugv9N#Y?3j2FI)1SHf`1$K|X;X`knpDVZz)%UQp7_i&1r2t@X!jK0i z@0{zg{%HIWAVHY|c(YOg5rg>}u`9-*Y8;0u8VUa-oGiv52P1JEo3AUNfpN?9Qy*5sd4C(6D)JQWw*A@hmgtH@3`c-t*52KQ3*{>(~>z? znaWz7;3m!iv?T{2BD(=v;~a4a`4VMQQsQ8*(2#plKG=MVBVlW^aTq%|}vMEJoXb6l+v<>YqMMF-icp9^8ySKz*HH>3Ta*#Ve4EipWmARlczEfAt24<(lBu;QpS%LET1T^f5>! zi(mbf%gqIG2Fr&eQiYqkSoYuoW_yO|CTG*yF7Y{t$V^c${Ph$t6d(Wzni@moI>9>? zXuaKwIb?3g`IAs9oEv`54{}J<@FAE`n*zIMrH-gw53s#C>b*EuA%xt~{ zD}C0n^@JA~*__==fd&5mM3%VwN??Fk2e;<^yyzG=77~0y=3icMF$#U@HZw)Bn&ny? zNdk`SM?y)HIiXfy@)V=R}ltyf?6F7cYb97^&M7qf)0mo4y*)vSUOd*)t#s zxk`?oRN$ZsTdy>8`Bo4^ zIyU7^S+mop{5Q);x8y*$3=b1O9p7onBRaj4Au+FA0x*jJ7&rqaL<|dz1VUD$xAfvn z4PgLYHY|pSXLvE+|86tF*wSoV3xP6|&oL(v(D4X<22|q=6CzMOApEckPPS@MCK^ux z$nC13YjT2#MtwcVejaV=tCguSY<4j>4aQ#oIIF49brMX00kG=8%Ec=d9XOn(EjgfiHFqp7S-KcVWAPxY4qEy6A6#K3|k;2)q`a2nWq7h5nGJ`PLv3%&7z_f^}84%VJPhH=ADwVp5K>$rVR54jlZL7W5C`(D9*t zAQ6gH`Pd|;m@gX}^MMH0u_*!n6to+h|7kQp$-q-`ca3?eT80tgamd>uzEp5_*>$T5QJwu+7}Bj4+PqXs&U7sV^0J zguJHMMs58hFoSi#iPdU)R=J^?&+ld9`dk+fYlC&|A_0}k_Wh-@^@6Y`9Kz;&QM0cD z!zVXX-VEY4sHKjprdgfnIl-qqCo-gbSu$q!NvTnSeeDDG{h5TG*iBb8xA$GSU2mfH zsI%c*h*)t*p}p@;fJ89P1}nfw$`=9$-N==IpO0ms6wh2A^9Neu6}lJ=KpsNoEs_jrs_ z0oJ=l%VGb#`F?aqfEO@eoCi#O##eUMwWCb$8yJ9G!gm%q^@Tl{PRCXgfZbBcpckFj z{al$VTxs7!I@9BXYsLMT)llU{6-vDmZrd_kPWUg$_l$%F+1O$P^FuD4>E{qE5k_iF zxe^iR*@ok>4*`1*yc?)-BVeWc&-o?I`g`XYGXHCJ(}IydSgg697AZBovPJz{0FbP| zMUNB^ffFJIOExVrDLqeLrD9YVYR+V z%$9a|<}3{RPwE4UHgji*7c;ys%vsf@@6tLHA4xe(LZgo4HVV*8b)&ph_!mcOvF1iRYv^e5L0=vpkO>r0H?at38Xg{9X{YN9bTfMW1EQzq-N(MFys%$6((=mIznkhCQOL z=dcym8@@D`cn@-S(QPMvHz4+d5P*LQnL!>zT%7(HSZg-^XgmMIf(?l+E~HcXUcvYY zCy9ndWXy|TzskaYCCqSA+vqxh(-K*3F+1e3F!Ty;4{m~A4-x)x-7BXpe0yg%v=%MG z_t89<=^Y%J6L@ny{G>S?J8ojGLu^m@@Hl_ml4L&6#d}(Uu!qPvgF##^rJzt=W15l$ z8I+nAyC$vS`d@MQS|wt+@sl9j;hSse7RgLcb4}BV#D18=taAfW!TwtP-!k$Zp2kXX z1l6=wON%CxF7O97PhZ@Z81(;&(Eq;b9^Ohjw1#~|luc>Pddc<=w|F&F|9{t@ta>{* zPoX7af@U22|Ifcb*G)V~NNO&H2d+Y$MnaD+*t!KMT4g>^FjcoKT`m@6biV$+dgvR8 z*LB73YK%{tqvZ0fB{Ti&w;&NvScd0oJHYOK=Fi zqy?O54;m-*n)m#s{LZ5(1I~MnUH_p6cds zZiJHbiUm{XlJ0FqzwE(up~_pk%Vki@z<*zj7xOuTPRVE)!s| zOMwo6&Mh$4$YX>?N<)G0nrdaBbOH?itibXB0+Q%5f_{5lY+ZIElHa9NB-;5t-Cf8Q zdXEe2nJJZ;t`ztK_ps~AdpEZ6?Vmm#i;h`=W7`W*2Jb!r7-kM|z0`Y&V|f#U20Lv) znr@tx)V4s+Z;)JJdohNPs{lxF1Er_$3mo>pMq7Ox@nT&yjyI&;eTEr|)32IA z|6K+Off_+RU`qVp>*0{(@9Uuea?qt2^P?E{`_N-%L|x7odVBuCHqjWmTfC} z4%LX|J1FcLq({gJCa|%wW8i)ROV85ryqDwNc(w-60Hn^4THf^oUp?Y=IX2kL4P#0@ zUbW>Rgb52y{P&J|%Y_yI^F>YE*T>sa5bWda{-V3Qf=>7cmfBeq^~9+nX<2E|#?0&3 zd50?BLt!0D%*R_WRO%r8P!C9$^DW$#Gwyp{;#h9p+PSW#`T>LTBhU+Xl+T=@?83*a z0!%LItnJqtz+t00ucQTd<3;54vGNnKhtm|(DD?zA*VwM$Ew$RVk_dWr@ne3Vj{fL^ zM?2MjZo){HXpzgwAoBXk=ZU}Bl)#qtLZ#8hWPBI?7~0;YdR#Z7I#M*?7JQbE7xw35 zsg_>pa6sTrbec`l)o#5_8(6>TJ{7Bu?TY`wz~n;8OCoSFDDW#$QqO;#68hDp7Q7Dt z3Pf@;1+b3+J^MoCHB5pb#bn4K(ept}biAr2TifnDgeThSE!<p9h?FjDUff za~n(cMZWF)`ZbvAFTma6GUjpl#NpEB@^|>Z&|F{ztU-ETU=PGf0+|O;z!{+rG*Bx6 zk-aZKki!{0<1cjZhM}zK~ade3R^#6K|erdJucEF z5qSE{vI;uRQPHsr-OO~ha|i$J!-JBO-)}R&fjnH#sKvtB0vzK@U^_DMNlnCDGhR-^ zorgT26}LpmN2uN>fZ z4o!pVv~p^o|6b34AC~^1a>%L@Lbe)2v7Y20!_!#NXbdZiJn;1Ev zaV?_e0H3P}?7Myg`_{e$?r&h%Xx-JV)LuN&Ol2f=(r+3d93YVz0t7{G5Ka~8KaSp# zwn9Q78`VsFdTXBpGDJR+5prswlPR;qCcaJ^JBV7$ASImXPkGYFuBgZayoP;L)Cnx0 zN+8Rq7uCTpr>jAJ?Mb1Ve-QA|D~AWYMhc!$z=Xssf%l%?-@4X1Um;dRdD)vu2Hr`$ zdmVUNR_edZ6uj>)=>O);+nZf4s=3E}Pd?Qbgj_pzG|20;#_9hZfqaU^)!E1aqAfr& zm%B%7%^`8X)m)NdvJHWNgJhyToXeg7@OH!}9+TGaD?sok9_plB z`CM4^c2K2ha{pvqLivn|ElINc6$h;~VTQ*jI+*RWB}JIzc82m@ti0O!;xFR%Ve09> z#TF{gW%LIZRV|tOAf7MFihMflMzkdg3@=?fdWz=Wkp5xJStQzp4H&~wS z{N=3eNPqT|gY7IvDt7*d^x3rC|M&*K=x$@~(cDt0oX#ziM}?f3%D~ZY5`!3wD>mkeceS;I^v3IMFrZ=5 zS}?2z3;##7M+6dnci%;f<$6O#e##G6bUtSNW1Wa{>YTyL6-pD!9?Mlaj`fjo;bcMzqJ>q^hygMN3wverV7}*=Vsw7oU-#Sl``$~oLl}= zB{l5CljXSDIK8_!mMUuRb$(l7BNr6V)LJS}u-Y!j4#X2OU?r-9yeCAYb~aR2%+`b9 zvB`;x!3*DpkB=iv61i9&z|;pVoBn#-j_Xi+`}ql7uviH|Apd*6ctC0&2!e$+3ImW-f|=YH9=OUvrz8uR^U*4?%( zVAg)(ztQa2zF$mwrfYc92EIY`in~9CJxe7|=fikJK5LEmw`gqSe-UX2_3P^B+?I^{ z#6SKcVg_-C$j(bOrPvkW+%nrKXMRdB9zCwo?4L&hYs*kKk#G5)>6r|$P=dHc_UuYE zib7F|Z`-7kD?jpHP5w0V-d)-=A6$Rt^xsvZQ;{gr*pEa#GA8)dZ_xt6_3!r>yPsV8 z9{HWKeB~)OfS-$cjlB;EV`iLptT&LL-0U4eg5*^xC(@Fb;RBoGw;6Ah4zW#nUh z;9xu2@3f5S)n|S`-Lgzr9oz-BTd!9ej&V$s^{m%zjL5Ew&sSVMQ5@Md_g-illI;FA z4RpuuEWRWe?VTedj1Z8CyCT1>UGIbm+SBwFb$s(}IZF6nfWu^^PbX8*2M)K5O>=@IL20>15>gA4Sg<>^K;HH+`?AX1$hiPTuTR;G=j{~dmZNdhnvpMUB1H&~K*n&`9eS<)Ln6_A zA`GF#;x?SCwWek=7Iwx$OboM>uc&T~v_d{YOmr*W#`Dae)^HIEi_p5q zrA=T9ZK>HbVy}cutWvvnbcQIK;ZrA=QsE(JWJRBfn6Er7B0`t~IRaal-1U!@9QxiK zDcCfr@pyrRe|ZC${TMv#Oc=m6|KGwCmB%;PBxO7G2F`xrRA1w#Ul?x(-toYY=La#{dP!s4hQlwBYG2Kb{Oqbgk?X%zgw0R6h`eEPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D|D{PpK~#8N?41XI z6UFz()2>jZTajWxz>Wn(6s1T{O+CuZ0m@Gu3 z3e;vfVB+=qF!gzTKD;^hQ%pI)Y4Y${jgktTD;cRd0W_z)WOnNvnJ9{)D2k#S-mu^? zQTW38^~;s3P^t2fM;}>n;K2UgV~;y32ss%F?c0}Gs#K}lZ@;}~&z|I)2O?@nQdowa za1brH;>yElxFWC2i?l5n2_#+1;R>yCnL5QJ&mM*GqBpyesHBukSYtArfTU#U$uF6W zml$0u8zV_K&K9|^y~&a)}Shx}~w zLf=1J73Qt>1YQoamCRdxIgytd(o?)Q-PC*hi(^f`kQh7eg`0cdWHN=p_&aazHKLFk zdB9xT`mzbL=8u2%^^s3Mosku6dda0VYaIXVvm?Am9bFlUa`*0ig9Z(1-n{wuKm7R5 zrp;!i9AN=wG#I{idCO5!1YRf{4u|k%9Qiti-5$RLlExb$W~-9{QjR>l-Y{jUUUKGI z%nT@^#Q-w_T)-80Jv7MZ69s01YI)NaK%wpU)o%r1%1fq{593Q1M*70)gW7fp>v=g@7Sa>4XUN){`rSK@ozLH;D+b?Eg=DKyQoyA4O zW~E}i>=`4wlxyd5)l5mwI$gxU&O0hJnFK}DzY;~;3DftHGV(J?YbwA~3}%+P$CkXI z*G;dyG;Y_vEXvFGfpebxZCCOxm7X%;m6vYr-FxfKePS&jsPNqZeXhLq?%k_aAnQkm zatr;YrQra@9;g!%D4q~v*qtk3h+`sT75TtR(hC7;#6hxnk(OgJ`X(6mlsvxro%h}S z%#?W>w(L3bh}2m#ram;F|5cs-_s%oShxa&JJ@L7Pe=Hg9xDzm6{OBMm8MI4w)cnIKYZHh%{$8fl5$HRUr`)Xo{Jj z4oN0q#iYy#N{)DyJ>m;5nt`jZmLe6%Qpt`aX)LZ9vr#{y5>rzcVwNmOnok3^pln9$ zv~((*6f4;v7Afm6a)Q(BLRp%Lt1*I-wKCNe5tNkVj|>7fs+7PYg57q62<1RU9H_}w zQ+f6Nv<)M2!oC1$%-ZDi@l zIWYDE4zzV7#93?l#S&$VwNQwi*I1|q2{EOP%Eg5&*1lm`;@4ny{=|XijWd@CPNUd4 z;c~VEl{)rV%YvqI%3(hgAqqB{y~Vw!x%VPhO!i0|<%tS8K^0P#cRaGNQI=?SLMyA` z-~_@<4hgiiImBd$7(+C?BRShofp$wtqsZ(_4x{*3Ge#D{7P~fAnzQT>X^c47)k@lO zW(TP@x`-3>apsQ$L!Ml}_2uI;Gb6xE32Sz)N7B~3#zKLsrMUooPegivO%7rVF_^im zM#ifoK2A58%Nab7O%N)c>@0*}R#qr8%aesfMmQ_Ola(3D%JgJshO#rm*+^uQ4&yjF zWO0ZxvNM#NCp#$hhqAN62wAiU)Qk|$%noH{2eaUVQs^ma)UJKmzx=VIQIpm~9vSxD z?77+5*}kl-tkR`RHEq^x`S(At7|UxwjnHGF6ph3rmC4Nu1t|?57JDocO^D1+x{gXs zAPdVpGP2T>G~R?{#0aoFsapzpcjes(Wz_Zb%}Y8`yh&EFL=6HYWa&JkRXxX;O)OFY z)fpMHqkW9}kR&1^K1u?<(vo79l0Md#tS2RSyngKGlon^&acM@>&PnXw^hqEiFM^>p z;XJRB!1J*Sy*LfHnVc0H1x^DR=jD$Nt%&$=kU~bX{2{f1wdMx%*{2jYhYCs7Q=WtA zH>br^z|**P`oSY1Qc5AlpWDxkmln8#eCSQqct%Pom}N#RRA+2ev;ufz!&9I^cC?LR zXOVHBT%^c2OA!YuMV(SaQ*txGwa|ni25ZCRCAgevXGDT_I}VPbxIz47SB>&V#Zi?b zu)nKvYl)1*lV^_!W=6-nl#kSwL$H=2OLr9|ZYs|a<9{fF)i&&?y!TQfW(SZR-iisk z$dQ&A*+=T3&jM1EFiVLnSHmF*-2c(WLl9gG<*n}wiCe`#{F$gCnT6((sb#bsDC?M! z_C_Q2WCjj)&axOA&0-c!7H1KNq>!dv+BQf%_$K8H#|%})S&GO<+Qc6evRLaVlcnIQy7y)4psh^dq% zAmk?GASu6KrYBJ_(lgU*1!TRXBT*;Uz%eOH)}V-GiHNhIWuZYs*=Ulq^^eWFTea(u zmg3LO&hn$;E_ik_s^zHvJ&E#E7-KMjpI7=A(T4;2UfN?q2nx1&D)-sx@bZb zoBAP+xY$JY94O`kx@ChPrEj&H4W)>_=rpdG(W21I%z63a)Os&ElQGzWrcWRwTcsPvF3#~q1hy3&qyXNFlqB9 z$l&s{5_n5(gjmFE*-Ra-NG6h!B(=@TOMzW#=j?JO()-5Xa^ODC>=6Pd9lJ{O zi}nSMOzg@y{NxoWw6j)%)7I2Vf#^czz@govPg+8iHoSCQawfVB>v`+n(#=XdPQBvZU^ zj{HEgmoAa=()jVW-qL&P&i!JwnK5npS6_T(GVwUS;rZ>a=wLDysPNr8dvxsEfBW}K zWgrS`At%1+mpS{$>2EfMWu!{h`OP0UELy*X3q2QCtJLMxe)ZMtxgUgV z86vnhn3Jduw>K2N@sW%aBJc2&q%Bh%xGY>QUyM9K7O|<927z$6O^Z z%H-u`S+Ophku@^@QY`+6Y#Un$vEpS6CPh{xxX`kjgp|vCVzFl?Na2fz2J| zT*MP+HJpqh%IZi_()o@@ypD-p>o{E<>7ppe9OEw-tD`ip7RxFV8!mDg<69!QnjPQS zZLu-dsD{xbvA^|>#hOM)t0vykRATKl(L~HvD$3D0quIS85kUznW2TP1(k_iD;)E&UBqHfw%fp(Q zTBtm1jhixdI(on7Z-TnVk*0iM?C5`YWw6oV#923a+O}m&rHvo|;%&FyvgzMF$YLI= z&hW$cJ^1cBFPL0BuDt4|Ax{kBWMo-oOQlck+pXgr{r~;;D^w-51$ZLL(&$SHmY|f` zy`Eb?TwyN}m0xsRxljMt?zBALq&6qbb(5Ga$Q4M|7{f+lqO|l$b^1Nnf85;9Y)u&q zW}SILm2>LVBXwJ)QY9lO(ce}`c>0O_BETZZ_deHRi2B+lN4X%v5$riQP2g*h7R?DN zwHImRCBq7u$}K-Ck2+^Y?#>qQd^88U%OEEwr2s-vlo&fu0nN;_SZPj(XtS_%qE$+f zSw01c5ZmV%Xu)!9x6h2C#6%>M>6EFMUUoY~`7yGMa^aEXd8W@GLa56w_s+ zoM3}-uouToqCJ6zd*O-+6??)#DM29b5VzB5K|)+3nAZ;P%)nWwpVymb2tT*FexU9d_(7F z3eAmu`}bS^W-h95|2_z~j9t4CGI#IJ+Pyo2;$4}$cTv1&SC$pBIUo^4*uCq*BTGRz zO3jdxQGybs*{ETUsX=1Qp1FIc6=)HeyC`IE$jZpb&diV+1RS+WrKe(wJ&=0U=i^{~ zAP}-Mv*QQ%)tz*~CLaRj!X^n^f%)3D0~Y4Y$`utfW-IztoH3;$yA~gp^5`I&4dh0! z7cv56`0O?DxyYHMJBL%GJ)k$q)1$4LGC(ei4iwP5C=OL zyUgrxvqC&)gcxUD4J#YJDmbt@#G3^ob%At*gs{m{iOWc_7%7%CUr3Au1*?8;AsQO7 zaG-0jSqJkTLtpW{_h9#mA9&A87#yXh64~)hh%Jp+;)EPa`DQBnBX3){6xle-if#jD zk2S`I*rv*&t$A~q9l>f?d}k@;BXdp;lqMfnQT_tY8?|vci_akv^l8NIA+ZUx!;k~V z;^T^`C}Ov(;)Jyb6XGphL!kxPHx6lt`|C5F%!~y7Wn*Vut6+bVM%%4GI}ZnwwH@4Z zVGp#OZ8xV6&CXe~Z*!KMEq^I>6*=uzJvele1!*!FJF-|adlpI{$15A+EE%jKe0gUF z>B))|vaJLs31`-%a|(Qfpzn0Ioo1&NG0<~S!4!BrW~q)DQ6XK$hy-6xnVpdtM94(Q z$jZz>Y(f@7rWNR#NQ92ZmTp+Ngk8T&P{Mv(>5$y?!}sDy$j-_LNyvnJ+#jSs*Hg;U zLv$B*kUG%pK4I=>0}xebAQxEt zl$0#bg*PV%o{f5h1MhU)aTJUcpp+;83)(SlA50`cP$E)Fdl}8iQj1)yI#_Q|hIc}W z$iQitgT3jnVqxs0-cTQ9j6a;rj4bTL#uJ`PW~3bZaF+9?DkLI8kjhvO(Fc&%!z#m+ zsu!cRmcX)5CA7+pQVPc63W!XaUE}&lFy9Gz3%NSWIz|rGY@viRD;>`rDOvF$3-=FF zR?J3@P1X@x-DWC8Hj&Vz%ANgy&nos!Yk!Oi_I^r%c3}=qBN;ehmr95@L zvYeKL&Mwc0GaD_71oJVrosHeHM1sS|xVe2I_BbI$} z>qRMoW=B9CRx0Bp3g~FZ(Bo?&AT2?#vmCNxvJilP6d-}`b+SYP`CwT)7$oj|;C?$e z?OcmgXaWHxhvl&5lQ@SEc888fr8lgY3K1!b07zd@G4+b0(&=8G#KD%5&Oo5mW#X}4@P}78pjRU_0m?N%qOc!{6;(K)HCY?YaB^4oZ zn~vP6lahvXDyRK{6de9Uo}%rtUa~wp#YTC%i;=KQmc=A!A_WwjFXPG)Wh6&2w1=@9 zPkCDjlyk~>PzhpdfrdzqejZXeCpp9YiI0Pna}m@wCWvHnh|y$hKVX(>+pIiKtT*Fs zj%|-v?Iqc;A=WWIIXTPz;DUAshn=%DIQB~S)Mbf^gy^KJ+%=8VCOC4Y zT!>^G9!{cK8-*!LP?{&qW{qrJD`o97CJ{HwFWNm~UvT8z#$mEvj1*F_Ox#()l~Iz8 z+_zsm54JgXY4<*npwfuhN<}$3W^^VaZj|6m#Nu+KcO*}xID)VTTU`k&#>6?3sSgJp z<7s($J++T1dBcr24H)q7%JqM95h1;R^x}mdZ2o&A=i*cOsH5vQZEmWwdav5i69sM>4ngA9z7MzS+Rg6n_uqKkwzutijeCtzVWkCEH|#X<=@pY+ zqDv?F1|0;SCmir05e|4l0nFp2J9XGj!O6U|W0$2=l0^V4rC!#SmKlFa7N8|`nVOf* zZe%0y087y0gE1I_#Rof$6@@*=HE(;@V?(B|-SW#HJG1C|O47I&oO*oix~FEV zJLyf*l)(Nfy8YHZpDg<6g+;4;fsijH>`M*$Q-e=*Y+9j0d3Ge4-1*LjBd&UU_^8wr zPa0{;$hN>z!kAyJ?1|fr50+WmEtzY z@_1^csYIL{dCSdM<&7lU5xHhDv6ORKrfio&HW)X4Q$GuoAt!5A%2Fh0Gr!cwS^Tb| ztWoI%^)snS?s3^tlofyTMkGmlE(3K?wAHj3SSgywR;IV@9yMFk6u2Ft;KJxC;?BYA zdh72>+u#3_jJ$v3j6&@RD|J&~l@ zb131C9WTom<0&skQB)dmmZq+WQWz9`-#9>W*^0Ss7oHg0+(YXENeO z3C=`H$<^eXMj&PrC91?uNJP-)Fd3e!_R%G;zwxI24?OhCI+u17pV@D|W}hsM%avE% z)Vj+xlyYq6>c>=?_$q12Wk0XudLjqD*>An^%+n7camQVch{eXXx9;3kEHw?p&)~<6ZpZ~?OWxS5`5}hule~jT}9DQVoV~#3$%u(sb zAW@|R+u|Ve1~4N9PWvelpa=C(OhIavA|ubtDRMhtxtu@^bSj*hBWJNGEeZS0`xEa- zoZ!BcMsu1X%uTCA=ezw_9ygKeAp<688`VU^jywnDD8cpc8xams=xKA*=ZvHYE+A+t z@TE)C;k;wf=>vAQ8%54!C$&sP6dTROflBS!fpOp&*$&uWX5cirNzR(^SyZ0ai@C%R z^U<|#QWa;plKYqh+lR#7E>&~SV<%hcyZh+!t^(K8@nW5&0#uUwt}R22QEP18ZhCk z4QJ^yVFErGoDeK~WM0>$EUsWx!XIQwJ8EzSS4*sb+3Axi^D=CaQkS!9cAJ>ljYCY} z*(EsqBSu-M6q)TqxJqpYPCH6-2-M^VlC?{biB6M~>;~3{kz#xIumicV(RgyToRyu& zws4*HQk-cjiUe$84TTk)9eYRvZ{Rq=IM@c;;tsY4Wob(L7$wZk$a|JM2;vayWACtz z9hlu{Y7r?RcrJ6;q9hw(rRFhY;VR%nIkTi#Xj@2|sN8bn*{FUT`^07khK{oT<_OIy zb4Zs--*J))s3x-$uoeDt`_5C3-yapk&J_y0Mih9$W_;y%SRdKD7q2rGA>Wl0kmg_< z=9Q`jL21_yDJcn9V4qjI8eOnR!H)oOX3g%XM2?uU5*+am2sg-z1*|mnreF3I>-!Nc z+{1S#l`og_>$bmFY~Jw8mh~&Qu9JCK*N{4?e46K(j9tk|BGr?`4V2m_1MJAw$TsL3~-r`5?r<7$j zS<6O|QJl0|c+;}X8j>#s@{=U37_1agA5nkt$BvA$3t?YkSYJUzvOo&>Ek#E$Ya?Jy zWiMdCMiWv|0Hu(kVq`Z=%nZhXlVmfR%VZF2t?3A^(m26t9#v-iX)0pU1T2zTN>eN! zG0n&mfq#c^ftBV&4uR^jVyZ@Bh8jdMM0q5^DVjq*3>0{iQU9C3X8KUjPGJh;26m?k z_>&bkSfy?Um^s0v5*$8OX(Yt@JA613$=VHz1a{_$V-akWz_Ytr80{SKkzm~1MV66v zXv835VOQ~V1fJavaU2{$N^@{X5UgfUw^(VHg+8bJ!R1e=WH~KHE;U*6nWwJ`WKDvL z91bStF9=hWvwq&KWa*S;A7nKY@&&Icu&X^GA%L%GL=dYNf!Og2AW7Yy*XvMQ2|$OTEiVebMo@}%~|vzMe?#{ zXAi+N1f^6Pa+uJMHtIpl$}7$v4SXJ`Go=#aExk{3@zN!x7Kp1XojQXX!}CdGzbtq1 z22@HjQ^L4fkrS)=R7Gs58>@ZNHkz0@c)4bw98<*oCuL@0zoQbCZ=?dpi)>~Oq>Ml& zGDx%0B?Mo8Ee~n3%F*lO&a=~tOcdo6S-se)4IA86N6u9m$v8Z0ctxU|t!Y%`Btdxs zi%o1%-YizuiOWxjlZzKQu?+D`qi{JBymtuE+n09(D{1WovNv%elC@&X&GB;hyFHDC zre+d93nD3{P|0m?Ib^uDaJF%fI~m*I$02bOLJDs&&Ts4Nb

d_VEUfrnk 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 ZuT*UrMtZn#%Pa7oq^O)omCz^u{|7t4j==x` diff --git a/docs/source/images/mslice_interface.png b/docs/source/images/mslice_interface.png index e8f813f33d2fb3175dd0ad6b5342ef2f74796944..05483944fbafda8b6ca4b9eb29af6793ff2070d1 100644 GIT binary patch literal 61854 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 literal 52958 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 JdFA%K{|~k7_PPK7 diff --git a/docs/source/images/mslice_slice.png b/docs/source/images/mslice_slice.png index e207a2177198aaaa466d4669cc1854c34606af74..380a77fffbbe555ad0e3d83c7f1c87d1be28841e 100644 GIT binary patch literal 221743 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

Yq4$tF{o_u)E>fAllHeC2r|@+)e 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

&ISWZ&c|HM$EmJ`lQrhX683}3w%T)Eb*>%X z+h>2U?s!|pm|5eoJcz1JdG(7PDShv4T7GxJQrpw+C=hj7usv&27Y|!*S@oP${|Hod z-K4q=s-7x~lUBtW1za>FDx;$LrqIs($Oo;aLAuz|+^7rch-8f}t%1dc1If&^fJs7h z5^(L=+Oo3x38QG**S)iDrLn-4*2S%`Q?%DqK^4i#wO;l8-~apn+Q?kq5)&;e4Rfqs zeYB9U#a|3sQu)>ULzhq)C(zc^ES;*^jR!`pzL2&rU3x!NBxa`^zhbMaFV;iH(&0*) z2F~XW`QPDViN93>@Q~n@Y~C?sCL#GjTY-v@$vIXB*!kz#QE z=Vq-rF{%8t0IP2?Vs3@%>y;HYnSQbh=Yw!mfDdtoP=Q%0Z9%^PO1GH2b_>C*fELoH z(S8f&%9dEDTHy9yfi?OvRvRfegGTBQj`Ul7Oh79|2~lcvr7aTh|qoN1ZYF$bzs&)waNYVh`}d9jxv`m4uHX^ zTQoyble}h!>MgnfWRx$yimW919y9@3dfru70%(beB|mM{IBv{Zr)?5&675lQ3E*Hf zotR#-o`XgCt>i4EVSjtw{h^Adh_d$b=(AecAyZ(E7tW<4Sw?JF? z`vsf4hd_!zQ=?boQlJnpih3-+r(~&edyUZWYjT`TV1vBzI1M-`55+w07E+R`rZa}Y zfV->!6F`v@QMtVU#lX_*)Arx%ulDTT|JcXbiM#dS@6B4Gu5m6BRs>*5YXugvfz97v z^WcnSs~jh~3z$?#b**pN>WFBzQ+3esCCjb3tNiN;t5gI3tInkIi$7xA}3mvpd{-ubD6 zOfS0VA`dx%H)dj8p?Hcj5kx8=2z>w;969%sTe?vDxIP9@ zgR?$uJ7O64sv7}11P(O-0l#zVOF*SHKIOd}%jUI;i(zBK<0>x!B#yi%B4cUy+>E4$ zlWX|$;k!l*&mjHqm|iLM15z>Uh3G%!!OLFPQq_%#-3F)Ju=tXI5C+Y9AhC+!GGi%9 zIH_v_UeXzhRRrjk#jpib9E?z>WXf83)lqdKrWTSE?0q=tg?h)sXP~YtsEve>KuD=N zsUi;iIC78r&((I+SJ@IO!lg}mkJCq-yb1;4+z`5x07CpNpy|>ZJWeZjS9bue_?Hln zYjG4gp{@dW=o#p%Cy8;@C;)b}m*B{_CfMw0grmTaSmeimSO5hunC57;%E|98J1|P1 z0^74{*Im;#u2!B%Ymf*5lvamTXEhy<%$zc66a{Ry3wSM5TuM_K5r7#$zXDb3H>XVE{sz4S#e9HYPSHEGGl|%)`q9Rm-%@*;;Fw!P~C=UN>J)xxpI4BPZ z7>(pKRz}#?O6QF_rP7=ty2t^V+pes~u&PMIg@^VxC2SDYp+W zfmB9A02`m0`b_oEBN;*bfxS=yDqkrm_Qk4lInicPIy_a>OKa| zDL|)ahv70i#>_Mh8}+;HW#(00RsG2L5{*~K%p=Tar-h9LTDvT5fAt3su*Pgzz(`|2 zfCqq77ag+W0?~UjmdN8IQe&m7;q4E_Skqa}ApzmNOZ|5B@&=o&{7iH`rsg^L zIesXYKYxTJB>VswE~2x;Pk;2IAK5?r!$0_GXdM0$Z<6pz#N)z6%h8f>wSsi6AuPiM z3-uq`DZn9CO-!Lyt%~RA0mS@=sgKbsa(s>mvaf&r>)p5*2@et<07k)%w!bAml_lb=|Ni5D>SS2liXy`n?uEFe8v8 zfTZ%hUfo6QZdX))F?t*-;sqLpziqD@N^?xT(JO#AyI{?={kHs=dw6-!0Q;YofE{98 zf~mUg5$naPrMZ>>1sZ`w8uzk3J!vye>2TGRTU-AH-LZ{AHQCXIT)i;Z)Vz7~?=j^;_zZ!b}fXU>t z-d$~3dU`cFu_Z>kygpL-pmIX;1OUWe4-A|7A(^9(szW);Y4QBr`+wloc+ANsYp&|~ zAhfyw4z@bb-W?+fBo=Q zkAP3rdTvr5?Tr9ZwJT=bI~pE)3~5?IbqBDshg4kaZwf8*6HVsqwb9Z1q|Fwm)wP(fivI zr`csQ$Jys+X6=flTTb>JOLtyk{NK@w{yWkVYAwt|aI%ZPyVtztHO^B%_OXxIM?Ufq z*Q%g7xwE1h{H`RrN-RZSM{|tJ`|p+x44V3}-l+K%MOkkiF3jVg2Nf2f_y6NR{=**h zpa=QMDMWEZp5^ou2F?HZpa1E>((cZwv{JDvesHaLrx>*oG(fKAT>68(6(14xyl=VO2(q-LsX ztFPcE#e5NKr&YjOrTrT=JUpv19oW$i7%>Y}!Vu$26^kzl;OKXJ=OCFPcqg_#w3Wb` zgdp&?DL+mq;h+#Z8jNa@)|7@5RvHt)(sOA6mq2vv>Q+A~t=}+U8;&2+JdECh!BQ_j z2F?+10kkGwtkX%i=}8Ef0C0$B1`tA>=yAc?4P=ALNOF~o@=DFA9mcjHy{rS5r*FSRo_9a>tn#4g6ch6+S_;+~aD zs)y(Wu;Szw5*wrY^)6t~jg<#TO!bW1p`xuD3L{9fIGim_YiZ-o6U^A7Hef_fQ?aVVaS#z@PpozIaND6F~8of<{ zSL}?G?*gDud9AA7Dym0C8Px)-*Alk1a)O<^70-#s(w&_|Wd>2SDLj-bnodVtLW+TZ zBP2cWP;7coa{+(|Iq{8ee8W{;#N0YsQq;HJz0Nb8r`{&9yo(=d=OU&9;L&64TZbnB zd)8I>US;o2>5n(O#3px5SOQg!7_+OlkdokwCyjlN ze$$|a$-BCyF2>A>CK&qIurpSSkX^dLJ4orUUBM@h`jVcVv$OI`*&jY+#0H~g#w#ulN8rJN|Sfd|5Hp)-$2YMa{damNh zq{WQu#!>E0YVF-`>C1Oo_YbyPYt5j=`g<%S3i?QIRIZ+Jd*4+78*FkkG946YJcJvE z^;_KHvj8vsr-me}8o4lJ;)VfQR?8N46|FVgr?#Oo1n9&qR5=cuXb0`_47^I7UiGeL zYD@|gLL&edpa@$jXbAY5U2vwDoLR9X;U*@QEm)3JcrBz<0t1{#OU03uF|!KkxSRn@QJ z%sPdJRJEi&nSF~^ym8Ue+h+x)H1YYrV^IlSG8uB`d;O80*y%Ny<4ibcw$W8sx2K+6(K)rscM({L-oyy$?yKgq+NK$ zc6;j|Kg#xvPMLa6ASq_kXT}5$wJHg;R0jnV=hRhYvw^Dw=5T!2t>4wfN#&2<9)OlQ z+`4zF&oo>B6zOTTjPmpx_CZC}{X^$nXpg+d3AQv;x8<>zEp3chb{5}5En8k2x9Kxd z{vByfcBW-ryG7%{xJ&I&^A+}21$Y_)VjAOWRHc`;M2=A3{gaFB(;xi{JH`5~)L-|L zZF%9B!j8atu8Udkb%ExX>UdLNiHW597~$1;X_Xt}ly~AeaBjeO# z=}t_}TNo#Yc(HIEp$XsvKLzY?Ac*J&_?yGm9PU`K>v{LP-|ge_Xh`0(T2xr_3E||I zcjGO67&syl!{WNF7vjT}P`RLEL>z}lWGv19`JeyU9{SLS`my!PF1yTu(A_mXDtMX@ z_>9`9m0a}44#JP43z&peF>iv0(l2yQrP8*u(&}5SsGr2LcJH-tcGlv3y>5IQavDn+ zkw-YcXhE-5chR)9cV84v0zgz3KqAm500&<@3yTq`Aa5i-F&w68U|>firr%s#u;#X# ztiEHL>LI3a!;RLs`YLPQxGiF~+oyC*S_?H2Kw(~BpjvZP7a7VH;Tgt0QyL@W5mDZ%)rYF#JD)%RC z=5%6y35#jxA8TlLFU*vl6%bic+cHVpQdze7cHq_0I3BCbW=}6zGpBKpijIh)VoEVfXwq!@kIjNKE{sPO}BT4ObQy^B`Ebt9bj7kdXHKJ~v4Cg-NXb zyg9LEdve26|Ks4>hbK`EdPa_~;~)_C*%)3CWgVLy94rBZ?vCk_Z(eDwMAFi!f|zFn zR8XNflkP}X=p_t_Q7;Ig!`x%}jD@If1dLpTgQN#Z4ac+#THTqLE+Nr7*xvBBfTIVK zRo*Pn91VA=5hDV?fc+4*G?c@|JE(U6FZqH6T?48E_0iZUbXzQ;a{7C$eD8G;NMIsq zhwrK&45a~4fGaWZW=~#>UiIuG4C#t$%bK-j0!`iyq)f$pWY0t031KmXGep%9bphU~ z#bj|(*ipgRk^mlHi0JRrvwqJ81%}9jG0go*F?2pL3g@W5%8tzl5Os^@fa!x4u~6V8 zKC3(`bu(ggd7LhdJ^BFY5603+bm#-+)f^Jg6limstD^d(5QWU(c?^(IJEdpp9{UQF zNOq!T#ogH0sP3`QGBXjl@xZO>hhVj4>85u7eUS+ICC~hQtMv#NE$a9AhL~j_hOE4m ze+~aQV&-_P_HY#g1#1Y*1oI_7@z&_edc8cddQVpMR6}C|uzjMj`ld!$3(>YboVJB~ z6SY$X0<;Thw_VZ*vEF-c@OqqdzvJwFk3Y*A7^DO60Dl5h7)-}!1oG%#G4Rw>$$kD* z*Y;XsMR};5`Eibei>U*?1b*V8EfN@xey0{&)+HdqQEzOvlI6&^P-!TzLRX~bd+fbV zvNQG|NbFm=SZCl3ouogt@QUHVVBI<4;m16lK%Rgf)LER|TEBk1`xC&<2kFn<^@!bN zKfKOL_0SSIF>aVQ_BQRrfQ@WuknE@<#E`s0>J3+8#l?VIbqplcSDdEuW9}u3Aq~>A zftWSN)g9cF%Pt|}n7Zdv)u0zhLh1w34FouX0fB|ZB?~#-S*58OE)Jy7xoveanc&qTkqi+8e?hw zjtA++#(r1bwfcI@= z$EPjWJL#vrP!Xs0EQp~uT+LP3zUY#it{WCCJ6`gWOxSe<3uUWyVUS$0vY2FIsUrHd zY(&7}>8HKc>vQ6!VLu_1*|lidor{M5A5K0YrQ);{NA#CAq>Qi_*fu4nRBu#@F|`+4 zplaQ6H%_`UNz)jEp*FiS0vQ6@6D2X!f@Kb@Sl87vF5UHw4$c@=c0QS~PyNGJ?1syC zTE07HoA0sS!ihPHPt98>K$6%$?(I*yDFwC5!@A!N$f4R&sov@6@Y39^kw(2y4o`o?UL2F zy9ii3BWFLna=U%*tDi21Sj?rY<& zipx*x@$DH~xO~_y**9ztIRBrlj$Pfcbmu14m_xeS&)-ghPj!6a{Hl172m8*!Vc>1~ z8|o+SbuQFZcSdT62OL#^hs2TsvJubntNn8)IV2*`s0SMr=m}sX?VE=y!Q25mAX36U zU}^pbfA9zXH$DZ3X?1rM#}#`E4m`2DaWBN004`Bb*I<9+zpF1`Mo3Ov5+r*0Jx(Q= z?(u%PqQ4_x;)c8=<=1gG=rO#IzF^}6EsrUtm*)UKs%Ius zw9mc&+wEE@A#tIdm#7$9;<0qQS>5`yz1!oJ!&Vwf_kEo z3IPSQSAfcGW$06VCwOXlPIXFfqNnc1``sBL47VL^owPDv5H+XXGY4Y=J5gv2(NT2`a4S%$3p}Yj{Z9A@Bs(6bO$$O(<+|}UwBr=u z!m<`!0X-!~TPL`yt12}Nma{#KtZJ9y$bq*nwy_3@^vd)NZLj&l|s71=`tZ!<;r-}lE=JCvDpjk{O?|4kG? zE0)`Z9ap59^VoBcpro?6pnp|mDG$IF@1Sm@ok=ja>M}IgWsiQ&18rWL3isZuEGXmta7MFA(dC`4=9PESeBF*A~%~EUcxX1a5VY?$bhAV0dZ4hI2KR;@x z12Pz0hJ{6R<+!@qoYCK(J?G0&rIY}UVRhM>^Yf8ZNc0X4%tQc3?RRMxOkL%;7i<9| z2a?bldQ3q#G2}G@MVeiJJx*8w4lwoxWVrp0+EyLT3nVCu#k!@YROdv}Y8!j~h<+fD z(@CFt$8)SaA%@HGb3#t6L@G(tDgdc0N7^S=tv;C7`~B9)B~>TY1yG{)H3qt@zOFkO zSMMz4*!R^LivuAx?-EqGfD$No~-( z8ZKc|G;R>lJmYG&kie`Of2rA$B?MHG3w4W&Ca&V@Ppkd{Bm!>vy#iHneBLyzcT3Yx zWpxQ`0GbMWYnB!O`@%V2_p+bym@{o=V_+*|Nh|DAJHW=JmJ!whn`XKVFd#?$g=gx@K%jiI@zS&Z^U(|K6R&@!-M`#rw%BkVNCabT z^r$^$d@I$hduz$^2g;UG+gL$cX|0(vt8TQ7vq%E4x^X09M<6hFpzf-==RW=YcFqU> z)E<4xab`0$!)FreIaGBRM`LU~aHaC!S=Fb;g{B<-hPY4-a|9nSl%MLdPhS5+r^~VQ z+b69u`aeMR(68I$iL6JQG-lI|X~xfg{`1?lMMbiMaWOt~062s^!f7BuLIFugeg5me z{>u%L+3>>~d53lEjwCjpH?jqs8al!3nkoFXhszb*mJ>%u?yBu8bwzo}|6~ zILxWhXn3p;1`Gzx_!FR`U;EnE+Vh_Gyt}1H?y;x-i8afs+G~owVt9B%#&IBiV4OiC z;c?KZg&TDdlan1byKq1dOjmRZaW4RJ@LU29t@#DLpAhqJJN=^^{}349U7izo z3UX;Tg63YlM=Pv=PGWS#TD|%XbJyf+tu9+^aKPfjgKmTjXz}RnI2P1<0e*B)(djqp zkAEHN3oyd>$#dTL6uZ~&o#^e3l3oIg31}hNYHeO;v2`QXyoVS9r^0%>Eu5N*08~MM zhI%2{YS-IOb}0qjT`o0h?b;WCENppHe+Pq2F>!$5@Q_Pk@Y&N^DtXY=mKZ+y1tmUuX?-C{a$i(-Fh5|^5DYYA; z=Kg}(q_G9i?(g<;69?waP|fwK?xLZftAjYCT5*+mV8@i#Ijk{L z60lh)TW;ID6)xMWDriv=gI^g<+WxcqEGe)_5WmjvzvBs@C2%1D&O;I{~PPS>rG zjobW5375{mgi!DFZC|y^)~D@XKOHgnPyXX`Y)N$VSYt~yfdS1NO%K*6z*|P(C%3<0 zeOv0baDv9PfR*py#f-`$TFbzQ`G~=ZRED>252djzASnETk+qFQwp3dmnXn}di+D3> zm0`^_#;5>QuqY5GfLa~Ns$FrHUYUSxyjr*H&IPOXr7bOb5g4{QBoG83PQ@%MkhSlo zDf`#geo1Rvm!sJf`1auWhU%XRl%w74l{rJ>OJuWwjd*t6ElF?MyM#(jRT zo)`7fKOgma9!qyZ(l9|}6TERJC^6Nr;o02Kx{5*0B}?-=@qiH0gi&w1>tuqi$!#>C|lfrr#jaWOhT0@4T# zdKP<_QY;lod_ov26A=KQ?Y#phBp(_G4k&o9A(ls3NJfyBpynd?ZZSBXLEUE zEo=9W%8RfR0tQHhe3z>Q!0WF(kVI9M#8nPT7)B#S3OJ5WemnPCOZ5*h(nM|3CAy$O zA`dMR?sQN92gZ+@%a6=+4?7hcEOu#pz?hH}sh%9Qr;edMTS$JWJGM9iF0oB(91H=L z!d-im|1DBPSBC*Qk!B#hN{A*!jJOLH-!o~kiD{RbQLo6cW3Q|Bh{4qy?XwmV8ok>Z z)Azn^S7Etvw}5J5uB zM}s5kcctpM^4(u^L+Dn9_+j`q3N1M;;8haX!WR$?uQsgrnkCCj3LNUs#7fojJ64Ra z8K}0({Q_c~rqerdjr}x^8U;*Jjks-zt=KoVY_ZQg^^a`d-X-^N?Ez&QEvxit15r#{ zWo@^m<|1QkRE%+5)nS2e0`3aH)JJ*+qM9zji>puE`!wpX%{}(ROSjv@A9{+bEc4@< zH|o#yLc`Ud7;&SjngO*eeQF9z3W}?a?i{FD%5XCk?!_MeZ`*NUGQKFr|$=MpVKv= z|HawyYT-RJGXHjoLK!Gee)5xTixwQzTYP`glb&QxdCF7l?6c3lLn!xmA#J^MoA`|u zcP*IC#1dkT+CAgvg`Gr*eGZHVb%7=cK}5Z?xb!!%(ZUsh3^C~Vz>vj}Fu-t7YdMn@ zBT~Mo8?eI(1a9Iz1?5||=JJvSgrpE4z^ij}dGY3xUkwbIXXhivhF9mFZh-?W&YGO4 zcig_Fr^}DQ2YtP++M!ZJRSyJALxG^?Ck!CLvGs#f?6ecaY}3}9Jzypf z67-8XZ{O`l-RokW+S0ppCt#=O5 zSZPz2tE8HP1xr=pmYb+sam#{L))g(cZ`B5Vq5ct2%U!iki%`OrH)U*eKCYea7i~pj z5LICv37guSn!rprTRy&EwXVRj`7F1q5)w!CZ3 zy04h=ej;e=(q@eXh|C<JPk8r&gMlooiZQykUb^3Iu5kJo|4yVLMgMv2^Do z7~!E@o^Jkf>vX6psE!l}_1D!`Uv1y~<~Qxx&wjQ8A0$R>^s(h3VgZsPz)MF8^s5pQ zBBC2`H2p;{dXZgz`Q>)O1sAxpU#=hj_{XkxLwkb1p7*}@y)N~+TPM~reYgfh-Q!A+ zgOWB%Vj6x^JInS%hdTj!Fzmu&{r&HMze{)kJOCd+4p|v2y}oR0ReG1WGe;tF9LfRafkPI%!qliP&WHzl&!9%h*r}Bm-(m`v`RbO1;{gnb3859Zu~VoHE5HLp4V2Fj|lz#S)` zN^3PnMB9}OIa}G7v05Q!mCgN;I&4*-vL4!6OWD7@_3QQrk38K@Ibqbw#BCEOto9`> zJ0&o1fB?KeL%&mR*ijW+a?-U`{mpPzzCIS{GK`GrZd6UPbxVW-8d-j52@Ew<$CP0x zp6<@rk3SX}2~TUR*OzMoB{+Ia*wS$sKaqyI4nuPCP0fgA?cF)HT-c}Kb^ys*e16sY zD8LiAe#f0aR)GHBKk@^;gPoB!Cxi@HtQ%oNpd}~6aPUZ8?yn~iGdxM7`fQ|QRvOZJ zAds9^7mN;e+lSx(eJ}f1`ppw#CAu_Te#wPoJ)TNiTx$@UDPIGA%Y-Hc6%*zhk9_1K z{j@Thd%{ToN-+2M{ont6=ZQOZ?6B*vzy8NEPGpx?tukrsS*qkWhH&id|i4#r%sv7|n4@RoN5g+KY zSf4Ijl`|Rid>pkBg{nLZt{W56Zg{K`9Mll_)R`a5UW>bXPv(6+>ju(Dn(&izP)hyy zI!o`EvrHpnF{CyuF4)rwkf2kdrwyTw#eYMY){avwZubF4?t zsEy&&OmtKo`zSH}aB9{tK!XXo6W#{rZWSG-cTUDxim|9tb8Jg>9=q}eAN>Zjz? zvOs{qkj5$Tz1)A3+DG_~#8Sg!h+$j9Z?&PE08h=*c%jyi4)phVZB@?i-RF2K$6Ibw zlbI}AX13~}DzVzI2{<>0yR=(u zT4v9@rU?DUGdb^5jQATPMQikF3{@MJnP0I>FSya3`PBE?hJ?lubwe7bu|4p!83#Xv z@PG-Yap<_eYF#@j4hHM_m}OLl`IAI50m9a3%08OE$zJ^RuR3jxrQa+uA2k{EskwK1 zmkEq&Ud?>|Je&IXCv5UVACKlp8|)rx>Zq!9Y(q;RJi*8{g=Bx03)b03ZMg zp(QZ?n3|gUwY(5sx@OH92QsM6@Oel4E#9O2P8mp)_&zi=bhFgyZkwD}ivDP?u$5Ie z9NZTHi$uL9g6L|p$h$v?JJz|sNkYtrO%Hm^_q^vl_Ms1b$S(q@oqO)NcPkOxEB@vm zttZ{*fCaC}?3j^Q1UUg0-S?y0`WxF6q;0;nCvrI5pvmG4mCgeMXyW({qzD?sE(K!e zu1*caVCZe{U_HmDOFxzu{dWgY6sU4sU7^2`jKow{ux3QNVlnh~2n?h_@d53?aVSW> z>Msn2VceYba;XnV_dHC6tGzU!XdeMhqr11H`tmqg0PCl4sKA_;puwAXe8l)mXxWwxM4H13aJXG?&efi7RBi~v#B}J zSp6jii2ouF6*9G;XG4oY*Xeov7M;k-?pw0lR?%POWw%UPFm{U_+q0ke09)7B<%ZbU z?s)Wfl@;usv?hJpm9drMidNg8aa9wr<%l|T#Yd6GMQgCf!kpSOBVaPE@-ckYGvR>1 z&cdpNlLCsg2k^Y4z66N6{#!tV@j0Ny5owuH{02Q+5xrDzH?(Km#?)_sKcFfqP>n&H z7zR^I7T+(BoD&%8%UNZ;z@GkL^Ma&>(^j?qluLSC8l!(4rO)gX@WoYtfN7!`7htN1 zF?_*Z@v^gRwpFuwR=^POq-U^7PGYposlH;?$^wT0;W$d_kM{V-0K7I@5WrY<6(WG0 z#Sp1e*9`)=qFL8gjSGR6L~qs_?bCDR<9cjmea_13G#-PNr4FdS^?qeIXDNXk{3c=i zuK&5p(CPwE0yriR#pVTR7T^_NgYA{&GnQJZ+G)RcqCNFxkFgceo;es_5FiBT&BK&< zNoDsZYjWQzR{>JEP&c_mUt*^>GMK2ug)CqNu$H;50xyG)z;tD^?$Az;(kn!Ci{o^y*n8@;ANW3{;;08|}JXRmAh^7nr0oaX?d7(SjbrOo%ZdZ&wF9lXmrw z?spg64u-H3uFil7BmgAJS7mY(9b@IFEWNLZ>iLgPX#v+H)ebi3;{BR6CnmiJ%5ZfX z5);+ePgji&J2>)uRmT88!boGH>+g{I9F&5qw|j^OH!iN$tfd{Z8)pmDH1e$P?>x%5=MQ8WJzs~X;BFVBS(gKTK4wl1rDZW#Wj?#PinOp2Z&_wH zxFnD&(k^8jNz^(?_n{L;+EHH!1iB%;7_xTiZah9SD>CRF(j~x1Z^4O`@}!*n)fv0dX4=t31Gu;|Vq zp|RQ<>(Vov(#qwn=>Svj0fO3n_*ZXwvTZnhy*2bc_Fw*v+Kwa2FsxgAH%E>lnzqE` z8^?_pflq_gx+Rd_sO^pJv;~!>A7@XjG~Hq2(s3L$S9XoS>TA@G0fAH-mfk<_AgKWO zQi`VluT86Vr>v^yl1nv>F#))-ejoQP)tQ(P=+PP`08r~`!LH&rNhYcQd zn>%yR;sS9o)+KB2?*t%%hT`QIvU$(GMz+CetyJOyJYec7{7E%oH zkroYWEU5n*HI4m6jT3CW)UUW|s14;^dgrQ8jfa(8v-Zrt{X-kQ_eQI!4%DNvsW&qE zRvn;6aaY;$2h{HUp?k7UYN(>d%S;PQG2GV(SoSCFOFM3~i?{4{+8j&2L27eAO|M^m zY5s)TST?ohu?G2Cd7A{t!8n-BI;tqbCt)+QefxHs)y5DvEJ$839>$>fqKhuFhdksV zesul3^Uia78-UKXZQDE|`e#1#84n)%;upWz?OF*Z(ST306Ts8TQpbq_|7lXqK=;#zo$upN~%>C;6XZr zL_>G{csqTx1Vhp?T@W}S?v?177#S3^)1ru)iHX8CQ3+rHv&K#c2?$2G&S;)NMWg+L&xggDZrV&3cMr=+l% zp&oi3qiKMhOSn|W=FE&}Cb|ezxQz|=KK-gMk|cf~5{DkS-A6iwb?^z5w9&)sLwA8o89k^}RZhxA?3;quK{!bo(7K#>}jMAE(?aVJ z1WJGYsUO+5zH+&pci|gsI;MH9GE*30FVsA6DKG>N?cK+J)N} z)K}OBb<|}@i|~DScQYCJ)v3+jl@X3fI16i$S$4EL2806 zNlpw1gf3}$%mt_c>}*=A;#EFU9+d^n!isj(Dv$F0Q|*AMx%2|* z4uFjJRS*A-cVW;1X6(8FS1~JEVX!Bvn9{;N0Ud0Xcn;|hV2n!(mOD|z*cbXBA)^h{ z5eW*k)IX;sL0$!jpjQjE()tniP957nRk6`QmxeSpkLo>5QGu=A z_6aUhNObm$>MvlL92Zbo72TDO%`0Exm#J;U6KiJmn*bP07rPpc%_pwf?h73bD_OXa zEMRZN@bdRi3+ivbCTHAnqf4j&H3CLCJ@ejIe%9+j!hs^;LCDj61kqL`UCP^Sx&Z7L zS2GS&pvUN1ZCPbQkGW$(q&ySL4s3832q-ZXh5ZjsG%+d;GfAs#?6L9*1J)Ss61I!h zfQ|QFZ;yHW8Md0$conD!IANzbfdfB|vC{{Q-keo&$f!OUjZ5fuHz+IR|BK_l6%Sy<1#2WS@M?muzl!*(%#-H4D_1g67+t>L9R- zgTvfZ&7-xiZY?3lms6IbfGo**0;W80|NtYFwI=WR}VHq0I#Db(PQf7TXkIY z8_9jX0d)9BoTIxc0cw!)5NnI$dJGC2H}Q#$4}<1+IsNSX%j`*Ky}%c@c&iO^+VpjQ zI%>a5G*HoqQM>d6=Bejl)O>QZ8qvDzVKL0bdvIO5cho*eX80W@t9+Vb&g21j@QCV2 zKjQk1I!a*6L4eA1PtbrRz!UE~1MiE#g352MR;-DWy53%k_Xudg5C9&$PaBZ%=x^$P zM`(<(X%$EB5%B|}*d4b7puC;!1fzVyHZ11wH}VP_=z07w7?OrjQy9(9`lii5z0cHPiO zzhRH%eJ2__coWFspg^-%3|&AEH46TXIBE`q_gG$PE6fauT2EKTp8R`%?{y;OcK{Na z0s!4&rezEEO{s0V0n?@5^C@c#7A>(LdMQ7=Vh7vyiC%gZwHiQc-H7)E#^WAwpFYvw zeD@F}NW^-&ydRO)Ab|+gp7`{%ZN2OYyAkynX=YZyNbf*J;*_cHID(HKnTGxbbi3V< zzzxz#R9Pv3oXn1C>%A^&FKVZHj{tZgX6dQ2ti9*U zKeY=l-|pagbWOL#w@*7j4u`r02m{eZV`^c=R!<$UU`cJ(&~|CnPW3wnGSqMJW#zl5 z8_I)C1xNc)F~$XWY9j@!juma?M1W%4G8#U=`1y8w=ritbU5_})s(Jdb>8G*60ri2# zhD-F6s+%=#MT=HmAX%`e)!n7O&?ZInKnlrNW8QEg5lLTCeX)JZluc}zwDYfetA$+} zS5?t!09Oc2t9M6^8soK?gR|U}K;lZv@>8LEg=T!=joSSbX&i0;*|hCAc6|LeOYlEB zh=uD=uUmNLtrEb8;Mv%xb}kHtS+g%o=iZ$q27J?#-fnAbNcjpNh>3WDu`>x^Fm1r12b^)MU0+5ka^m2FC07g=2ZcyB0wfuL5KSgj4lrceh5CvzBHJKMMok6>TL7$v zm@}EPt5BT)GeKH3(4wtMi-Cz*I7kvR^^%pyOV72cVmL@mXxoN0+Wo7(fR1(>!@+L- zrnYsG9>dO~)+fL-J1@{w6L^`l*gox^k^BgpxGx|v4`&wq#u$JufS7r`gJ)%q&x=m3 zhM}GuyH-_cKg`8Jot|}d8Ey0xOZT<&;qM?61L^CrV&8F=JV+81tUKPNJ1tIoiFQZ~ z08W6;Sa%^ZR#y2ouKEI`=o6$O#V(aAzzBdqg#_R`Fl8}pfz+4H(>D649yc;Z(nI}_ zzOdj?_hQbS@-_Merj|?AWs$)lX-3)A`>CUdr!hevVOP=^C^|q1W>)<4QVfY6k{;^7 zX*_{lej|hgN2)!DEOk|#oj%-GTLF>oqM!r~MJbHaF`x$|i+)|{9((gM-s^Q)nvcel zpWYL}eGFpnpnowWastgQfF5Ne)qkpcv!5gR`mNUR(^5oaPcCT8HB?qMX|;6%)f#_< zbl~WItzRHh^=SwYBp1roGhel#A<)-h`r_Hf+ z2NRt{*WB{;S6)YY0$8nGyVlJ@kTenHfbZv?d#;;~z}tM|d@Ol#etK6Y7Eh2bc0FgD zafVx#gGA}Lr$7Da?sMSIbeT?Ufs2JpaXQ_sStUBAAFX~Wp`sRfbWIf9M^1)CnE5^iX$Pj`~n6!R5>^Y>tCVpupf#Q#jZyH|hf zeP*Wa@!=Mx_y!Ii=_YtnhaXV{bUYxR6Qb(#$tp>ch-$s zQ;d_{h=U!K6IXvFMn*j^2Wi`O3lwPA->3QrP;e^EuD{V@7}B;=lM_PMZMW3C~I0Jl?+5vV|+lEF&@$sn(x3BiK5<%i=HXMl_;IJ z``>M@wBIFe*aJBzX7#|P3>&Ac=nR0u3F2zqZDwHRtwL77jfnC!YxL zd=06NuYA)JZJ+2gb1YwTWq82nM?-+jK{9Gm)Yfs$ zHI3`$`r$~rB$~|&aDDlsKd_AQ!AT>1hqQ}m>(t#Nxa+DF@j%`1(_-bZv@IU5xvFtQ zaMhmeCCk+UyKH&d-v8B~IDL+#Lr=aoXiPAF59RU$2}dyeVeFwIJN@+2?UYkau~Sby z)i3OM5FQ})VH_THi7vaHZbMxi4T9+JyCl&`038r2j+D?vV)?#j&mRB0v!pE~I-3i% z85Z&!=i9n<>&?K1!2&8KHVUFabgM+b{cV9yLJJh+bxDO7ic2M^3#t(@3ujI+YJrp( zDisE$-ht_~1ausnxQa?ljXVG+?4-%3ArOL3r4{WkwZON^Vv>5_ZFpctbTnn5vJw;b z-LLM&^qxQGyMEnA`hawa-9L4zXh%z3@i!xI;HP*FOd7T`Nr#$cY#Fz5GrJ?s1X@$8WYoSC>nNVj}~}drC}F`Q6;#+L2Q}K8CPA!DTvS zK{FUC3ZvC;FKlpE^z@4-N?Wv||6i5bznz!7)RE~igD<9&i82=D+c=E@dZT($V5nD`_T z3DJec6GLyL0Cn}B12=t&dE@KG4T0;S6-IjOMSuK3uMya#e#2Fk+&gb!KJ9*g0?nED z_5%*YT0J@c-EC{|4@6(!M+Z=gjS#8qwb z==RDhsq(gNpRse_`yEROV3kE9@(lNkyX4UOhCEO=>Ult$GkpQ7+NcvzF?F5pNTRfC5NvSHyS}UE-ouMs<1Nvp;Ol{+qKccIJAk ztnZ7A@Ret2LzntdJ$dy`KmJX*sQYRHH~>RHr#oCk6sU1k8Aw`UZq;&I<}JH@*77&Z zS@E(1Zhutijr%e7qT2j|zxjmIfAx|Z{3v{F)1dlPeYj!FYA3Jtb}%2}0{ZT}QUDmA zQyyYuayFtd^GoB}!+Zz~Bjxm{`1&o;T`;xKQak1?KCx&C0b?X#^)Ue>jHK1?h20t- z$|E%&89Jxu8&>U2>eBcW0I&Bd|8;45=iAP=`2~&hW9g97%>hLH^AIjiozEjL!K*mE zg|_7R&wsvOn2g||84u6zc*i?_=gmd#Sc;I&tufCn-?aLvGc~zxzV3p~Mbt*T5Uknp z8cFaqP$|*XvGe)czx~^r^_{Z2dn1E6T$i90Jr(Ghu7u!%_ch0~g8;C#NHT12`gM73HE^-FNWN zBPNO=HlQS<9kl4f(NpN_o~Z-%hw2x%wAHn1?xd9N6XX>z0vJM7)fD)}j)h3`zEi^K zA7BqUwDYH5LXP_v1sF1Vjy}Wi8R?L|w@??+|7w@V>EehzK#6gI0W2yg0J5GB=!>m8 ztvDOmYUGPqd(Am7vGSsx!*L*>p_sOCPyj`3ju8tBY1*n7F2P!TTnIqyov;=*I7mGf zIRz;qso&jTnKHNlgzBRhewg~y590#27+h=oIQ>Ll#z8PYXF2z9X!hziJj4 z(aW7{&M$kv(~bax@BwI_w$$!93#K_qrTo;(jg5oW80)p5q`cH834IoJlq@y1YDqnp zII!S`+{DYmV|SpwAtHUeT(u(eMJd0aaXMdB+XNO?Dwex`%6H*_Iiw)ODhp;;1!&Yx z+OGQ7hKd4)DND?kEx%KJiJgvyLQ{YdVAUM!5#UMqadD4xwOFy8-?`B)zi6BN*G=!S zX#tU#>QZ0R<4zV+JJdHCBOxk7)T!9?FdqbDJl>ebfgfe3{Hn&J#;rH6y1ne}&#?OVwABX-*6bFTtq3d%eECe*_#-3-G=S+gF#6W;Yvcr&Gz>!3zqqqz z#RD39$7Qr}Q(cawLrxsvfUZ$Af?t1mwAyI3IU*D5A6gR}9}>Nt7+e6LK(z+YVXy#%e$#Z*6+7+CulYAIQ88e^g2?FrMoa`%3rw5^ zQU7q#NNV~S)at&B2Pcc4%lF48+E8IcKa!J zsOPpGFlI4vj<9zmKw(|Lsf3|h)b|dOP~T_)cbf(3k=4SS&-rgisW_623JRu*N{Vt} znivebgF?U;fUTW^(P5W#gnRZ!G=MQLE~-S;wYS@CQBWn2C=xq~76!6vKL+-0yba)B zw@iBlxEcaa^ds%_Q&*yAYgu^+==mrYEj@rL^w!^zDo@X-U%JJto_f!hczL8RZhMcK zBJf4qk$rPa9cP6wZIufsLyZ$jNz^{tOXv#a7mRY`TmK<}XxneN9SuLyW*8%&?SPmu zk`Msy+R;dbrf~vj#4B}ZO^cs$oXux@Y?>q6O8qB~S$R#b`H|>;G1Qb8yWT^c#hAhY zA&l1n7=**X7|Dol|IRJpk zmC#a)s!K_Es)K@RXlt&i*w-(+#{1`3I<&;tW;h(`b)+YF2%CBQ0ujQA2<@BzJLjBp z{BRHk&cDqj{&y|;I;ehw&-=x1(JfDb%X(lOY=1Nyc>ZuFBrT|raH7;fps2Y(t90Pu zhz$bBx-Hs8*NH*(#*G{OJNJq1&a>$3i6caItaX$yd)ecuy{Zy?4) z_6|n0AnG@mkxK`-PiMg(^#}}#fTYbyocL)G=RVH?0@|PkaNw#kE~F)V!kqb3K`;qF z+Rfkxj6jQn=;0@(e5B}uLfecn6cA{&w8*yci_?TW0Zsb!_VF&i!%$U@A*CT7^<^i; zUN~5WFXB#`hv7Y`G>P&Dq=FIxV#;022R-+Hv7)I zslMZsQQMH42KgyB=t~tf#;_+s<GL2(0VfLwo%_o2r+6F`Zif1-(g3yNvm zwR^_C`#)EDy%scvmU;ySQVDDHYF)ESpZZrF5CMS+t4{p`-0*v@(~1 zIf0g$C8twzO6}uW(E|TGwH~#TfhzjfRR<(CxCO{Hs`iDCeZiKdmuzKbT7XpVsjk)a z>Qm;~jQRio&1Ocxza^mOG}l=4%?tBU>xqwf;>$r((H-AR%=f~^5qsa?f6l7qnk}!^ z1a343L_4^(MsC!sx^Xg0eIM$1fKYZ;wB6WeZ~W zp!FeL?PrhV1mA>j9ei=@o#X2rlMxJ>e-obeyPE(!nx|^=!L1e>6z-m&A3`*0`P39vz;gk4W3b!>TV4|x4LJ0BM1hYUW$iZ~zB z0E_qcx@5%}E~hT^kKa+VILLu<={?-qBZR%7OE%*1OON$MtYLIa&?#YqOSIP zZq$p98r_4Dxhf4wgxZF!h=U23Hj6a2AlSAr90a8B)*SToxm1Qo?D$}DkHK2h@#_-w z4p=Za5-~LD#iGw8z(ctnp`1lsV}~ZWx((?MJNARIKNq^GH+z?OI|(gL*##gT%p#uN$+(*m{@pKrES}ep{v>2zY9X2B}yvAopXa`PU zsV{>}(!&03q1}OqMgXqK8H}ke)L27$L|-!|=^suU0@RuZM5EG8Myx5)J%)4E zymo5@{sww2F`}`dPnYt|&S{A0IZlRgY`!W+U9Ma8gh4knZVu!vb?rXOUo&C#V#4YK z+f4j807;l1>lfE5h5cc@R;ADajJC>yD(0J@l06IcxDYM zY_O$D-M+N_->q`|fX{`@gx+0L|DLecrAK(W2E;PQ+2FWM6>4PWooLH}gVv6H>T3bS zA?BFI3t(|>USM<4PCIGX-tpdNS>vWjtM#S@el!eBeP_)3eHpp(20=0OG0< zrCsAcfqx&-JNx~Tz3}y)_WrrMq~F%2^4BE?K3XCU`8vWAylirE(l_y)i@25;H{+$5 z13WlVd5VqI7 z?se|O>2L!d%17jfdv1ItKnJdlTJ5%OyJ18Cv^Tx!Ol=_iRHSbcd2ivkLu_4 zI!HQT!UEV1aH+p&7nLI*3ynmp5Q!U%SW_U8 zq;#i%0808=z{lyrnA*8dw8HjBZ33`p1AxS*GLW*00Hph~!WK(3%?uXp6@T?#cG~74 zJAO^SH3ahUWZe?&8{O(x#=n3UV>2euOT>MQvfbE!Y1vQoao~XQ?EqIar|WT1;Nwv9 z<;~CfcYETK?<=5{@vs|6JYB_?j$3+K{Ue$Y)jc(*dR7JgtD37C)5PHd7&%>4|M*ze zzH#x5cEgT?K>Y7my70ma?eG5X?|f}#jXjhIA1-o5!-eP11~weAL9T_h16k#fPzj5wme} z3sn-w>M&;R0E}n>K0JwmLAd}Mzz!FN%)~b#?iV17dT?~Tr>Dp3d2oF|(imI6<~6Tz zfJSgPLirz@+$o?w3DyY_U2VWOBswh4s1ULBP`0QOVY?2t0Ge&7559Q3RE`a6am2{E ziKv|V@K1f^-&Hrt!Y+jHAskC@w!s@kjeU(9Tno4bs-xQ$sZHVj$V;u;HK0DzyD*cc7zL51J82Ea zisz~0iptb8gff5*JzXx=cK|3bh3ct+#9(RO;-jM$!>$OR18~!B+tdyXWf%Q>TlrMq zhU{Qe4#(_0Ki<)C5e?(w&fOr`Vo_7{HKpSj2VHrrpm>JO|Eh!z?bM0EGa z?|>4FuaStT?_wK9-LN^F5W~hu7?09Zgq#o{tX7J#d zW;h50SnZ#3+a_X(!ARY4Akr#SU#NYc1O3IgqMo8V^b02@+)m1YHS|&4kN_pEXyX|0 zw$rHU*Hjk4t_kI@ai+H8(H#TsSQ_9cAggw#_RLvgpZZeuto7xsx>n#AP*SN`b);aG zd#-ggR;V_tp4_WvvQ}HuW!*QZZJhGcKMb4;_t<2A`|{7XOE()5aH{n}FO5wMxG^La zz{UY1j{X2n4usUtsD=R7fXNn)FhzS*SU7U@a43zIWhbkaoGZJ%l%+L4x{9toDqtI> zG$Q&m@qmq7T;n2n%`VL?b(Uxod0y7qiJEig{%AfSU1Hub#+mP;71B%qWNUWOW5?wL zkiY%e3+=#72Q1Y1(WJKI?itHoyI*x|T2m;m*)7nRVZK8&(L61{CP0LdHbGG=B$$ZEfDX*?H-G?sFfH z--X*3VtB#l@brwd=SyGuk^`bU>iqC`E%_lE^%;DR7;0>U4(>yj>%ibq2^?-iX3D`= z&Ue52T|d1=XMpPQ7}>f0`JeyUUiGS1-D#({NC2KKTef&?6Lg(;uSCyD=Re^IPw+4p zU-`;ce0RZsdCF6sax1{oNz@;31X$wpVB@e0zId^H>$?|djnhKOu2{5Wk#okZfTw9OOWNXUJXC7>q^*(7 zM$^?x?hA(402j)~|Bc$`5)mXhsw0vUmE?6GsHYn^LkBTU?{~ni@^WKZ zq+qDR*zMz;8L*_?yGOX!MU-xAVHy|)x5v(#|LKoxCd84RcJ`du(k{O_ShQvlHIT-V z>fm-`Flm@MZ5I=DwIBbK4+h;1u6Z7MVQj5_q<%=u=rcc}kE9JlWuz$BxTqf8#Xft{ zL*D9jA${QDx7tcwdCo0F;0Xg}0dG7%qdJ6ME)iP+bj002*VRD_E7rgt4ek~+2Ju7F zh^sEyxCbI7{#I(fVu@+dcur$W?LwjvESFr3_~lRh*vo&%$Di-f%3aks*zM}nRxgeM zbyM`m0NNccYL3P+2v@&(Sd%{Wsm3*q90``{8;2EbDthwP6p*VY1uR5+KTV~+Sll&j zTd&-0|NP}w+Oj}U9Y=|3N5F|i#yoAr?EqsjuDtkN$yL%wmqbhVw2sOP38Fx;1NT+> z0)c1JKJ|g`*|YxcaaJa@MloZ}zM|-&HGn=A?P`6R6RI*EzzN10U#VMavEczpO~V{d z&iVbS$GryZ37`19U3l$Iufy+JVvWYUfsH5YD;x3KTZ8Y6M7DS2(iDoWBQ(L6ko4@{ zz1!_%2}v=k4I`2t9RGg&;~)18I|q3%BLO7cy%QbBROb+k)))WfmJZa^(+~b@^rPR5 z*4jHgF|bi-5oMOtal3un>&^r`BmfGQ>;!T{r%9L#d>Bv`$NB(T#6!VH4^eOt4R+LA z2d7^(35!}NQx>U*T=cC)-HnYq@94WjPW|onFGR*h-38OrZ@lM>SpS?kD!Cyt42)eg zV1%7IV4~Ir7T%G%4|Aj(7&B@sEf_q{0uR{n`v57*;cu89zqQ}<^7SqZ4<-sDbYC=l z2iQ3iRerRM(@<@|<-2L_!`KDTVu2Vp%v9OJ(AX_^(n{Nxh&!?q19Jf3^%EUf;9!*c z%?&{HyE_t8{i6B`ki)b9jDQ%m-NBve5rGQYr@Fwn9T@3-F&mhmgE^NU!mo{Ns!3jn$r1n_{34?v4@h{aVbh*_!KfGX%g-2^;c zy+S{$4Ixej8C!q_>Z(2riFdXnX06`?oEc7P=P#z~8Mjkmw*Uk{5t<`Gq&>W^{ISb% zNmE{+hqCEA055e@3Iqru+ExWr<~&!Y1@xt%fLQ3xxX@ic(S;-rAV%Ajiuk-~rxhen z&`OU}2M5R+qd{4HgAq4<1prgN*vR0a8C6Vr?}9b;y}GW~YC|~>%vss2e3b`I_wd4u zqzsiU4jtX66~IeiGOv1m?!!N9*B~m_y%V#7`5aLl7(=M?0F*QZNe*L`{uY2rObDb2 z6mjI=Hv_1+gg%(3x!p@v*s@@Wd4X1e4Z^rAO)c2>zkI2er{1=@z>)h9V$%W;M$*T4 z#5jEzR}-QIbCUnmc9&=(`BDDZQn_Cwjdz!rs!rL#Ui;i9ernHqbMZF)=drgshzNol zZlZunLGu6+kUgKby>4qy^V=qDc0T*r&w2!0BH|Lz^s1|_^70uZsHwjF?Qh#pe)1Cs zM(i@~C><_1@8<$NIW<5_`rcezuuub7+d}~WF*%sA?!^cC#hApL#GqlUo)63h<_=hB*MrIHzyxMNr|XBC zo%6M4wFm!HU0j`njS8bh69}e;w`KP-OI=|~VyaX0!XiosE4Ckgb$Q@vt_+HqI4qgR`86W~BrbnsJS zY2`(^NLOy!9;re&4OXfeerB4B%dRSFahx09MPibSc?X`+lXn0B|MW>jK~yK$(rn%9 zzJ>y%B7hN<6%%uH`yYWsRB6FrpZj8owj@z152UR*((MuoBom1P^A_w;{xfN8=vPT}ep&j+NB`Th0itN_ngJj%1QJXc$%DT70;~iuaX`c~@M7)> zc(7Ymr6Rz??*azcOz<1i&s7*Of0#M|Kp@5gV`_n=*Id0qz5pNWictTkUp>FN82w7y zU>iwEn>o1@qiuxjr=~n#F#wh6zHwF-{P|EcL#p9*ZKyoJg38BNk3SD{QZ-`(y?(l> zQ7c)zOXYMD4O$Y@haMO)!+;o#IM;)5qfQY+a5WX`DS;Sv&MtjGdcsaw49nG3*w`pP z2WM(uWYr2t6a!K}J4KO{Knt~l=Ntq=CsYjjjrPJQIX2%((6UhzAW>Pdks+!jKVIZnmt3Ip zpuYfAVmF%iq63! zW$3jQC#-S;hwbs_eWAKKb5`NQtA?W&LCPU{hoQ0A2?qm`Hd; z=Rkmi=D6A`D}bDiTVgc=y2Kj8pg(g!eXskgrw&@zl{3~%N9D&=7ET6z3}`&~i9^(a ztvMU$R(VPbGXj^4VT{M=n@J>b^FDrCNV-rF={-N@O&<;mU?NpylYvn>V|PXUn$X5T zpfeObh^iilG(PqRyDfEKQQMf%2Ko!OpmEyNRKZOEV>DE`As(_>r!*eDp3J`ifn??s z4d%K^yd?#WwpulA>HbzR0%BRx)^W9gSC?+yL$P%nSs2u|=ZjFaE?wzt{S zp7u2N%L5N(^Zx$#zu$v;BMCZc5=69J=T@mG5T0T36li-EhNJ0v0O zE&(NC&b&upP?sX8Zyb!VKr8v2<6Rg`4nyRWHJ7#EmsWj8PSkatqEBJEfPk1dO00#n zNB6~OVfFx_SXS@n#Hf`&&k_r&xf(*#fK;2XBr8q?D%TX~7;u<(OvTxv5i;5&X* zP78a&8e-fIgz%u<-!`PyVvqF2!)~BH5ODERQh;^U8EKH8kkg27sZIEcAsRhE%Yhzr z#BrV4La2;HrqAMo0wwJfQ#py^8VmRA^}wPWZw~}a2+@E+uS?44SC|$6Zcq&7xV2ti z;-+EKgpCMC)csmB?99*AM?3dK06_g1LoJ3X4o80K;Mk@$1_LA-dmUSyfr1SPQ2qWH zZ)n%d?DSJl7VuR5%K|<*je%U+0;CKgU`uTX`c+5e>kcG`hAbE!7Kjsgpv?duf{6lV z1bhPZpXnY_3O_jpkOmkr#>9Ma-sh)|bTy#G(z4}M=D+{rXY7W{cG!dd@ZR?9H~fW_ zdo?zA51S@z$dsS$!?+pXu3=F{y(Lf}Ko5{h2wWt0O!@eZ&n&6GH1>*l%kNyV(rH6( zgwD9CovybXXJ)Nw&kV;h?=2eO(A z7J7U^FJY>CZM6G8=#6&9J=R%q zPJP4}(D)1XO}arj<3C^?(GQwGEsYxv0eCnMfG+@RsNbco0Lxgh%k9&GHc*f2`}{)1 zp7+;}ut&Z5F}66?Wy$?Z7B35!*HuFSpu|$$^1Id7s&jcDW%XWx&~nqtYcw}1Evt^? zEHhQHf$@fY=7MYNo&SC7Q>Dk!trLQ64bSNF5H98@7avDzVou=#hSORA9)fpcwsGJ4 z-uG^AxP05h8UkO5Ym-30Z>HYCNq=fV(iiVw|0(+a;YuJ*JT4RV;nSb~v`2wG_(BZ@ zI>p}RcOhMS;f*$P-3~3vVz__~7%!3@7C3+#j7E&ow+u*N^tVd{m_qE*nM?vIF4fWB zzB}ZC0l4oSF(NIZ@pWtTyihCBBJx0zVZv$svTAY99P76+o>rK>c-IpF-Fk= zDGB}J#=$UGz5@pJokb=#x!{iKoNh>epcB$6)IanU5-foNFO0kZ5=g{2z6{e7Edg_} z-3LS;wYglg&GjQ=fwgBoZ#Yfaa8gL9vQJYGDFsOlG$| zqS1^)KbkHk4}ehlx~n>B9MK-pnz})IvVb-&4Wy3+5)z{${yu7&zC^}8`r7Ce)zhAH zmZeag=@|#nyf3iffM4wo1vpe2Kjt0m6A%`inq66|oHXpVDoCknC#~_Q;?0cepnfFw zRgF*!&|u%J_nAw|kmjH&Ri6&_uCe#N^?z*bx&b@mJ{zpAaZ+2?6SYYVU~DtCLZm&k zLo~&sH%HX5r@}9fdsJov0zhKi;f_JT2V-FzVY+IKm}{a>YR{B)?_RL$uHI{(|LN|9$SD%2NKyQFBv&6C+Q*GcTgKoz~_;fKy{V(Ur5ESMRYu zd-yr_mcMwUm9N?z*?m>&ZWouB0>lYa71b~5>(r9w7ZM+Eoj#D{x<9D2#a6gKm@5mA2Bs^&V*E-j8r0frq&rsj0>v7vgwkoCRU&YQ&X^%|;9)t)2Z zjw3p50@k{`5nX&@=8H@|xwxv%0K5bLgkHEdrXeW!03BeY3Zx{$T+ zfA{B})20&zhVlXu&;|xh8cM8DHshD<95fFtP@S`>oWHVk>ope8h zd6S3oB{I7=45=El*Od}T_}*79(~s(}p)QyHg{rF8zoZREd)yd)gaizI98m}8&72S@ z;AxLg4>+lcKD1RSzJ$a}V`4?~AQgdf^_0{5TVMLQ4R0C}HrE)0eyEt}C&r4Bt0+;Y zVPC}W8lRlfJA79-4B3=Iww{dwx*o4AAbLOf9F{GC5ZvU^g5J_XBme_Xo7cRuE7Bz zKAo2zOX@PMCGC!5N$4b&Gp+FnZRE9EXSb<|Mjs!J1mM93&OPpNk7$8rar+%k)c!~3 zUu{{->AU_ye+Y9$iortHe#liSqCLRIfdi^6DDR8A7EqW33=`(=>L~3#VL&ifEuyF< z!hHwaw+l=RwUVonV1in(>DI8Jg^%)BPyq-0LH;bd zKlSG|Xk@*!XH;e8l6stqJDEbz(?dmERw&>lc^J3%YG=#mNdLcCP+ zIy)mGAC49ht(zn4FnhfU<91skqzTj&l^%=@kG3A96bX(Vgp7-#4fRHn!u#q6KRqM* za15Wi#=DCVedq`6_>+meU3bw6w4?XzL&A5noc#BXX14OsKIHI`I) zQ;Vzi_H(}Gbvxy_VY`1SXEpU{0#C=NaA2akpi>iRf*4?HayIe^O@Gi&s0^1^oXH01 ztV?20lg2dR&u$Cl5riz+Umzr`pQ+jAgDL7ckJ62V}8fVtg^Cs8bmgo@OWX-#u=@?2=0r-4GgS z4ywtdfFP1XB?7P#JIg&>dnk`$B$3HQ($HtT`f*lT5pBpHx-r(2M1^Qh3XniY{iVP4 z3}c}^Hr#NWy0Br;m~pz&e|kP!%-D~exaq$`x}yKxe&UoA5d{dL^y{4d z@hma2;DNV&7NEkx8t!qd9DAHYO{`ZZoph2P&f&N^e;?h+XJ7Qu{(8_CXdSmyI-~iR z)|!Ehg^2wtI{CLrbjArMoZw;a51ZquyD)JK`+MKI+|mg#H_alKez5anVN?5DLc`@r zL>FDLH-RsDf3*MSjMBgAyFahL#QB=P4lL z3>y$c;`w%c9DGq%KoQT9k=KRXbdgv4zUNEQ`wmF>WMYvQ_2fIgQIICFqZX5Le=VMA zJ1OtDp|ZmVk3R8HGdk?*AeY3b$f%`JeY_koY$Q}J#Zj4FFUs?J07Nu~XdB>xvXNGW zv|U+HH=a@5BB__&!$}{&2;)`(p;TYDUAOBd+j8kGwnuna=D4ymDe9xY{R9qD15_Dg z4v7G=Vq*C7!9NX*&Erw2ZVtwD;rGVDEDVzRD=**et8Q)pE?PK+sGkEp(c1G7J>A|Z z(1IE<tO*09KcES9f!0XF@c*Lxyw9k=K79;82cAc51+DeBgK~ig%5=~r z8mZ)nM${7ktUii@wR-WI&#WVusVdikLFv zBNewsUeD9#oSt$ztDcN$vS)3eZXGbBdrn^pr9J%CPD%akfKT=FkSw&JGxt<4S1%%I z1GLkpjER2Hp5N7fZf8du^uEtGfel6>G>r)yc~}bzdggO~&uS|(5twm+t>0VP zQv!f_06GDPwPEo5lwA6R+F9j0=wU2r{I~;59#Gpd`ts>_pKmK7IR1I~jbr}UC#5F^ z`UJM!u$jD+2Yz~Led=d&P#XdyLeNEHDb|&>@vVF9vhQ3)?#I&YBv*mlfh+3VTPK7C z1gC!KOJC|IfHBwjWxxmDLpZ^G_OqXDk9*wX?DL=hyn`U-D1e8iGCk@6e^Jik5#fp!xqEpX{%$_;0*W+*6L`)nlIaKp@RstVT(|Y%S?x3ky2;URP9Kq|zaCUw#R#aUCL>Ia z=i^8NP@}*c$xronW6|E8s0_8u^XZRHe!27k=Gs%VW>f`F!)yEOwV!yAakeUCr_SlA z8@Bpx)!!2hoB<(e)B=ECo>28bD&@gFSs-W^|9B2Zjo98$7R*iW<513xy>r^FV_QPI zNU9@Jf+h~)L?4ce<0}P;M#}OQ2S9Yv^n3)4M6Y0U#KSS*HQG<5;e{D*(M%CkkyEn~ zc-Xebh(YE-K2>i&IzKevvAg_q9eHRM=XFIACK_SWf$FYFz)l7ZetzgH!Z_@kuv#u| ziA>UNylSu2P^l;_ZYQX@c%};nuTy$L(nNuKETA(HV!1*jS0~*<{RK{IJMT;a4hOwB=k;V^#Hw zYy2}FR4#psgoLpl(>TB>V1UY~Cl@&|R3D^fO0G%@1dae?slBt77+>)IAqDel3$|vW zGj10=)f>^c(E73Ky1o9>7q`6276lHVr2`Jlh1P}cu?Uup}$Dy}iVNB#J@_kPDtK*fsM zE}yi-YQq{`89%0;o>Q9yYQlU%->a6MQGTmxJJLrz-{QoYXcV7XwDe$~U3=q{)96^b zbz-@7Aj42Ql*>Ey|0dRNoZjN}4@u82Q!T+$@u34adeoyH<)N28{NWGV`RAXny+!1V z5pUEt-gu(}A0$UFc)<%iFWnCtXydw|`vvUV%svXb5jEFvtWP}r1rh5R1aK636)xDcfiwUsdJvKTKqXiof zqq@V4!ipHA+8UM@o$2~%AL2FXLe=AH4Wvu}Fwv$~ymkMs>iKZPaAZRv#scv2Bfq-b z2M)ldJvLnW;pEc9$9PyY@Upa+BZY}h>xemE#5pf;p?0_wjJAu}G#BS0kS3Zq<8c}a zPys@HH>A7%*$~-o8S@LX9JN-#qLupuQt~6$IWaMPkFQ;0t>ZW7OZ1LQATVMTtuQS1 zMGC;WZ?DDHjYWL|qvgK(%Ozmi4Z5_YW5We#SZW(oJB>!HzP8tL^_Knkyen+`O;Jpx z$*^LJYg1Mk6wLq+*pDF9fj*Q2T>%J4niyl+EfU&;wxSwzP@wxx7wFv{OSCuSL>%|k z@7@ML0d++!2I%D;FY50uq%=yi0xGMhiU?wgt-5*WkrXDg%rM>2&Ah=Mi*xK>b`nR}^CBlgw* z{+X>T3v3-rw@Mw!4dd>RE}p-g1n42w6@cYeh0Ori5CYvnSeS-o%HGzokh;aZG^mjNuVd1q~ zo$0u7t^QSe<2HB7ZTfV(fWT!Ji56l2fIy@n+C}5U&uw(DC4tGP4(@dtX$B{_Xt&B| z=iJz_%V`kfJ`y499MWn7AcUPXV;JVC-<;?$I_x|EhqRHrU7984pv4AQcI_qGqWURa zQ2C_IFNq-$I$+;^0jQG2Cgv=@pifjJ+Ofwjx!UukuEF4dGc-TlwP)Oj#!ZTK_xtXj zITusA0GR+0mujg$VSv!xPdfq9u-k%ps(y*>2P}8_9*a-RTUvGR%Batj{^R9Ox8wh7 zi{&q$u%;MYxU_1)qyXRatTp%UwI+dB3Eu%jrk|-7<43?JD5&p|LLsryT%*r0xaBz? z3k71FseaH|bamAh(lG&Kq)|Se0a5}bo#3MzjvuzSeDbfXbYRlmAHevPxdR^$^oLri zPh$n?9nuIfW{!>%eVu+?U6=Et=`QgU0Kk`zdpQ=pnu8ik`2X3s)}@qDs0WR0G5M_4 zs?U7lBD?YOUBX5hYxHYYZ62R?Al2wn-_8Om@U5fKi0>>m19-lsegZ(jK#zmcVB@-o zR`k!#NwbqTTC-nsvs-jp7D!`b0iY>2Y*2OIFTnHn?|YUF#u`?ioOY=v9eBxA;h;&UHthYe${d1l47HcpZj&?1~>;Zy!4Mg|@CQXN@J|fvIhP zAEkrriG{i~h{;vbT-5waj0>P585$7HCT2wA84L7oFp#ioF1o?rJ(g}s>Z$0` z5IvO3Q|I$G2|k8zw_l}JLbHJz7EUd5nrcP!kr-J38zQ3<{s?K&$jFH21wX__2S>Vh zR4W2V0%RS0p+-BpQq);+;M?mq%~3Si+C^xQf?0K>Fo!cC;i1FPZ@%nhFLVDqfFBIF z=(M{Ec>Ol%qObkJ{q2awIx|Hr1P%Z=u+u|gBvr_Jm;7KH?EHB~<@j^h z!sxO1z(CaRp0^mW7VwZAu=0#+7v1sf>qfZp{6RVBt9MLpNEsP>Yy z_LhVlOFT2?O~d0Y%nb$v5WuT(Fgg^0FqP{^r`heZ6J~6pf)W!&^~a7H|5CKwK?H4W zGhC-Pzzlm0KpE{qS_Ex*R)0EuR0a}^LaN8!_75MVMxGXDmaJi7@~R(gWT(x$ZvUZo zTumsT+RUgVqv&Y>DyOS)1)`Ux;E(k*XMci;?5}j}uT{55^G=CPh1#DCIdoV@xm()owo} z$5kj>6@NPd zCoXkEEyGv?w5u&%54A6tThY%dhw)!jT?AY>l8x74)}1gL7tj!JU>+bbWKIz*mNClG z#dyd^zK`fXzV`?qedM*Dvy<<+&i=m#9cMM~TisMU5&%>IMK%(NE&KJG>aKos19C!8 z0Du@u8zr()0@1A5hGP}A$LpZj6^@j;;eSW<#e&`h7d z?DA*WG_iI#l)e3QDEtzBhI8Cb+$-Ke!o&K{NoMZB{{T4LLt<3WyaOB^sxW{u$RD8e z^{;>3zWn7c`-Oz*2S511Q3ibIL_VTVD0px`1$07F6O{$WJu_=3ceoRsIy^k=or1MF zdd!DD^r7xd2^}dxK|6!sNKIE?aGkB17D)bJ!2~d9k=7E%4-OonQzOw1pks&`siXX- z=sQ4$@4C3}@30u^9*d#_9smx^mU5T`dWSOotu|2c4rXV~`!IDT7mG2>4uGNOVIf`y z??YRD0}QcH^S-`!41-~Y4l?wt11$1HOix+lbg&_3yI!uI(_LrmTIZYnDy_`I-cB$t zJQGt65)`k$>H@Qa`M?ZCHy@x}$`9ZZCDk3^p`CKaAlJ*HEwq(9{3%_~%HLOAseii- z{tj(}zA$8OOU&{HaEcQ10VwP06{j&(Q9sZ|m>2X$Is=md6altWDz+dnY2VqyfB{+h z?g@IRTvRWewz|4VbIr$xzI*=EQF(<~)s1&Vi=Z!S-}=$DQ9eo|8~UwIzc8LC9~$Xz zKORlrLr40XdI5SVN6$f1?{_WYE)|3(^Z*MxeL(*~8|p{iND$QyrvL*M+9{8?>U2O% zdEc%XuTM>NZUR*GKA^H75}@FG@G=@YqHk0P&U-DcxH~e{qQC_cyMsgYLH7@cov`mqa`Xj&!}8L6-=8Tn1ef%Z##Y9XK%K7e9WjU zZ`Z<7)YqZ`ed+2>(bAbIyHvlIiKIG6)zr5EM#|nU0Sw*)XrL0KT|smo36|{}7t>ch z(7rvM7~k1i#lHEupLu;A`uiu^KrSg}tox{-G-f#-AAxDnK<#Xd^*W#pd&TT~a~7sV z3-xnVRUpKI$D~5tsl1z_Z@ow3(2w3vo9)==s!t?0o~O?jjdRg0Z#ld0{44C4fAw%n zo;qT+L5)e#nK)=oq;NP89MX8vZ`P+Vq&f!U^U?s&_d_w*0C$L1$LphK=M1iCu1D$*%v>FKm^l^vBZ8i7+U)3wZoek7%rwc5SnjZP(k% zmh1cwgwNyKqz;HV`06A84S&Py)~;Ra<{W?zejgtn_ql-=<#p@Ud3YqGJ^&chTl@Cy zb9EQ*{!{qKK&+qP|+J@0wX^RN_08cLlxFmIP! zcC9609)KPIiZgVfcNhq}ITl}-CQMzwIYVPo=$_`3FU~GC;5k5zXyJ^I3udqPoTAU4O3|d162efDlk{Z@pTqy={8W{hgp@QD0Ivzco`WD-XsjGc0D>PIVUVxg`rm zh8;}6cu@(_7MIkpL+6B%fCD~O+&%{8Bj)c%vN8Mw$WTwQ0hfwFE84H+{Rh|!}`R6gDgU2by(fPj?&fB~4IDStOcdMv>3R~M1jkx(#R zI;k|hVkx?aKWI1Lm5$Zea6qfN`H^`fajK(_LjbMH@bLs)L=U$&fuZv|KnvRx)x`sr ziq0;@Q@O5g%?pGxo&X!lE0v7d`JcMb>vQ6LHd%I~00XvHv|06tj<2g+>~u6v!lLp3 zT*L)N^ZL7xvBZ4Y${Pek1cs6;YLE)^`YMHZqEfn|7~z-OIm^jg9%c@IcgBmtA(5 zpZ0p-10U$`|GGrI$Y;~0P0l|#?heT5Tt`)~(N5B|h$ezAb=$!`7vL1GsRhk1b_nf- z=Wr$#COVU_69AiMKJ%IO^Pm6RUj6DdtC)YVuQio?EVBQTsj2fh3RTS5VHve<{*RL^Lc-k%-FSsnh-qO zgz+n3jH+1@F;*sGSJA@`xEe!?9xn0y7`c9P)g{si7!iyvsrU3upq*u6&6pb!lictU zV1;C8a8L|Ei#?~0U^Zd|&I~kkkO;WygPkh*BB9cx!sxTHw%<>d5K}5B6Esu(3~z6z zd!D)3>_Pq3+_FQ9xab1IAhNrdPh2}~-|Z4uRNv!nP4*fJt`L_IoEkNQyH8Gti3tar4~t88Mq zMLNTu3zu9g z5FmisTlAyeEp>O8OS_~A02#(r2LLGZ_4=Ix7y=5S7pfzot=F@0YYY`FwPRY(2{4SS z-b(_NYKNbgnnr4;!fFR>bi<&1@uqiMc1SekN9JN%P3SHO1R4VzKr&t@u@O_>s1L9+ z3pTFzcxwPF0s%8lk-DM&YYz8XBA2keJEv__;CpgY(aNWcDBG4TZ^+p4W&ttPx7Mq= zb|oz_D{!v0qS>Qy)y4WF0L3PW!N3vS8W63F_fuT?4=P$c7Ua{A5 z+eOw@e!NYBFP(SZc^=vP```b*OI4ou#3$NMfBI7o3-R3NKG!8M03blmh7B8>-#zPD z&$278ywdqx$8P6MZ+erx^PTT>p7)ZMyu`H~oCs?$kAF=ffAYp8%U35GFhn_;rsb&#QV;=RNiQo>gZ z^&np*S1V|uVsPubPe6edU^>>NHavq0LJM_l&8SO1c$etn;Ygn?-FMU~r$w>8Dr>uK z`iUoqsp_TvUN^e+WAUm-*vDzDtcMdINM&3MjbrTfjesUGD&eHCp}gDajI&R-;YZxZ znqA%280fO6j6HW%O7he-{)Q?>ZpAH zOx1UoYx=XMCy?M!nv@03I!J9urLT ziUH_Edro4}sFpwp5+96H7ap?FN&|VfRcWs6vQK>BBC6)8vLJe$y3uUYn1f>a-WO#g z7XZSB0Eg(oZa)U?@HxX6WIU=4?krKXqkob7xz}UOIlvAQNoePQRCHrKa3I0h0xT|S zkk_tjoXQh`jH4>z1d>2Wv#(%HoEeJdzG(o^DKCP=Mm9TvyJQFiwBxi(DI=!; z?3X>sN}_9JIBzS*DG!X91yqRpg=B}L>u!t1`~+xdBjJ)D(W$z&Xvu|!&7YRHsWZoX zyf={+sUEGIz{N5EQv*-s=CdRArYF7AHfsD1=VK-~<8|^rR{yo21Cmko0dcfQEo}~( z!`-64#x#HsH81Kn#wF5IRGnHokn$x32EVy;kDYqlu>JchpJEFdpVhvM&7G#PkO{1k zk6Se_@YHPiSaH8nS;mv{)jVkd2w6u|A(sfV**Q~V{#f$V7WUnt>-G{G_cPBt(|zi^ z>s{~iDCgMK9Dn@r)~^lCzy9mLIvC+OY;Mju=Nx;@YhL5W+&}V>kGS_`1Py3A&N}NX z`{+kMYEOUq)BQaJ0r0^?NdOwa4M*HR_OXxIpZ@8e+H;=s9KQfwuYK)nU4nGfB&~Cr zO6s^V|74qYbVIWAE2=;){qhC>nY-IWQ$ z*T|!>m@a^Y#SkQoB*Y|BT*o+5?E%L}oE^Nss@fzhPJ`oN6n(Z~&Bp5l`ww z<>jJ&-qCm7>v$UG;+}Ul&*>R<=5Bn`%Bhs3RV%m&70ZD5Udxd)}pO{xo0 zBHkC6aMh0L77~j~^)6}A-aA&X863C81jJyzNK2qI3%ly&APZ*42{XOxG@x!y3l#z# z_zqZst}4o(gPzb9wH1I0;34LKN^ohhtc58WXW4w(y2RAo&Zt9U-dDm1cXl9adynt2 zi2*VCmhuu!ogu*wk;+De^N4*(;li5y6XS>aKaIP~SQv@K@Ecm)o^ zQ>wODNLW%>c8uqFR(0|5pyW~^ z-s63qMOCGLsPzb4(Hay8WvNhJjCF6LF6v*Vf0Rx!3(KCo#%cmK^=!<>Hwjpc6)h;KPUNSWx&IwnMt|~~+UhDLz?RxV@YC_0 zjGc7fIhz5HD1V-97DOvRiY}f{4))l!7jN}4PkX@e8hTNlPCJbSr!jeFGzXEwF}Kv7 zdUwjIz05(iOZ0P96!Q^@qmOa@&JlZ!?^u^M6{^#zXRfzh*`_TIs^-eJnu}R}(~=eP z0;;u`)w`m8Ah{ip`q|w#s19BaHnaK+^zvR4C_0v+wM=9=)C)l;L+-W-J_e|H$U`3D ze2VMg4}Z8HKL?0lrh)VY-ikB^a}JKG^IUIl@2#Xbd|$tQy?b^(_0&`E5YOY;(@s0h zuD$kJyY9N{`~=s*7j{0xv^;uJdp`JQ^xfC+cJg2N+ZpmLzaQ3wqzB#RGoJAbce%~Q z(RD1(LBd=h;Ug`0T24&&{2yI!Wi9aGX6*)1xgeckcgN9W7Cj~hi;fm&4>f>@o(qYD zp5th-&mS=sx3%CCqu}nMp3%-yfDh?MoL#z0R>W|ym+93rFfG(SJ^CGHfI0$Z#l+IC zp9RkQk==f=V4>>4(c}22%ExgVQXS>zUV+6F85Zu2U;W<1$h4TT_=13h7WcXq*M$=c zRvuBC!iLq>tE~&m0veHYf&~_TE43c&tVaq~AIMpwH={*Z?bf2bC@}Db$NtdX^2iHl z?ae8@f8He=!Ni=U_Yw(Q)gJ8io&Nmhej9$mlKt~*zhck*_zqioc#qZA3^>#99lD;b z4QLntKrvX1V`E~z`W@qGPX9RlkXm9q43WpQ_;4Iwba1;I^1*>%xe@^a44D^~ETvuf zP5V~uf6x7i*O3&$XrU!w3|b>eQomHnX?x5IFSd8T?0kFoIp48u59<+=62=@~R^BP? zyw!j7h5FGp>T^i-=SVvKY6J#?4eMQ^))M2y4hk>^;AyNMwCZr$w*G#Po%Pq3+21|? z8}`9}_=-L38Cz|tH!FM-ff-UIpR|R6jLmHBvXy&o61WgB#X%sTh4~V+fiEBw`y3=S zqCpF%f1GAwY*9aeH4-7}r(I_YmF7sl#;@{Gy((++ws_VWn>w@CX3rRi?ujl)w*rCF z?E;FQ{?Et&{H3q_Lt#(>c8xuJI-xdet{t%Qx}uG1Y`owPe{TQ!(*Ly&yy|OK3lp|E zF>hx-_7Z#3^S)x|{KMC*@W(T@JS;}gt^N`CjL)sA9Q8R;DaJl+8R)lQ?Wp=C8rO+p z&aS+4hkfVsk<-AlpLiczBOtnbT-{#$q6_TLUwpaEZeAZbK1>Q|t{ZfTB&%LH+G|aX zEsU4z{c4kb+xDQM{n=wKvroVB(>DCZn#~C8adHYNOKlW-3B;)ExB&S|7`I=1?^=7s z$6sWnP%n>&KB5gON%vFKBU&moyOeiV!EKpV$1=9-iCwn)`D0eoJOMyq+#L>dyK2e` z8LN)#No#Bz zbg5R@#rO}kfxw%28(6ggS7sq?6O#`XcirOkI;v9}z_9il%0=>Z{dN+-2b&$FHJuB9 z1JD7CxCFMHI=}He@7*>5e7N_UZ1Ow6ihTKg+j5V}q|WnA`fZYCE9v0wy=xK(n9fE2 ziI@**5Bg0EmkG*-6zK7ff4m(yaKI7rk&seaM1FALjaFYL27y;vBpsrllhtPB!doiyj%AEL`j|wc~4{(&1e#?)d899WO(V!rXYj z!`xVq#iFBZw1afxx@^DJBdN zvz4)gcDs5W35`oHqG8j-211K_W?D?DtO|gwFqjkkAQ)(3@!nQ{B7eD$A19`_t=n zdM|&iJu}is$ROv(#BD!a&CI>$p0dwAd#|%kv(R-a(|}iF^nSrAs z5fC)Puib!YxCMM{!nWpj2-xt?&HC{XfHog?VuXig-cqc3j@I6;EfqcCSohSEUV$oC&<5YZG4B@eo$5 z8bW>^`A=D}V?LN~lXC(f@y&*P1?Cj7@~wL3FT#DK_Scus_x8832Tf4y@Z!?QUR*q9 zFD5$(A~cVUaj0wp?5g*2J3Ak0V@yO#!PR~<1ksoD?KNIJZQ*Wo&C8%5Z&!h3k4UDN zekyD8^D>D%9=f9rAhdUqdCkN_1K*6B`O~>sHD=W&b~B%j0@G_NAb29{jB?`2li#Yd zPJ$loU&Q>BSv?iXsi*3}L%Y_&iy~gLW&kgU?t(}Ad$B#9?3l%z1sS9|S+9(_>S8>6 zSF)_%CQq6?uDYjORl+`$D95L^-;HYS7G?QKO(s{YZ#BoGx)}DcOtO#K;PANPjx$eE z^V06lx-{ISqb;74q{=>wqy}2(2q7LN65tUk{oeP!hmU{!djL?X$E% zCofYwvKL=wn2PQNoP0h9rDX%CEbK+4CrU-g_d1x*dF?31+{i6r-15W_BxqhrW>pvR zD|%5|wS>KM=9|j0+#N=$+lA>xE)*}wAbV;733jgYQ4caF%t3xtpY5xXpUWQgGR?h_ zk)yKp2q+O8@pEQn2xBLDk!4!Q-Go~D`wa#HBXbCdj_pTjDSNwJVe=B@=Fw2CY)7`; zjeI}LRSsc}YZj+38pWQa%&R7uhG-Dxbs4y7TQ>zaKWhXGmAUNwD-V<<+ux?Q3)SP7 zo9D{*!Vz#GP$`M;T~Pu$8Wo$1L<22@IIo|;kf4Pi$^cY@UiOCbQJ7BIoDU5@Rrox! zv;!mObr6`b*I#1TbOhHu_a~S+1<17QU+h=_0*f;1#4($()k>94*7N*M%19f^ z1i6}!EiXWUb(v;8lnD@1z7Sq<%zB*d$)c0Sxmpb1;*%f3x8C$Se8agN*YB+lsl4H` zF5LVt-^KO+_yzppEB}FUZ-*J=N+f{d(moW{ETmkKugkiDIg|x~knVQonMRo33v*aj z0$bI!EqA6I*19@ST+xRr<0;CE))s?{#UESjz$;#Q8-Dce@1S-v4J~E7KzXeYV7Mof za7{4~>Fj47gVUaK0?KLeDumMF9y@YkY`~3+F5HMUbM~WFVmnSn@T2$t7^ke*hquNC z;dihu@-ckjv|F+I+g1h(vZs|BQUF#S*1DTVVe)dWxdF*W?myc1bf=? z*$@8;SAMs?nrttDz_MBjUHLM4deZ2A={RQkA_Vl5Zh^Q zryHx*?7@QeN#-Yr_b$B?zx(L-F&c>4kq?r=+|o{zm-Zt^{^7U*+|dAAFL>Pr$Ytg3 z(>g$)*vEGW4zr8f;mTAPK7{0oFort)_`*5Y;r?fQ2aZcBm|9I)@RQ%|gf=WoYChX) zrx&RO9?X!3pS$8_ApQ)N{|#`n{r%f}zK8by1Uej9ynn&1cJ z@BjYqZHkEI2g!r<6xFE?dj5J?$4HyWEF7mDJ2i55_K_qMq+ZaiEBflEc+1sW_@&5h)u01``SSd`Bo72({70hAI!S7sRvK8;5u7C~}l8x^D< zp}{Psk9FIskbIvX@nr-(1a09_94+lgV9Cf(C5Iw{*hLLU@7m%Coj4Q$6mGr@y<5JE>Dz;{A4e^lVGtUWJbFZq_SVp z!LkxKEsi3woM4kI$oI0`?W_+PpezkRiAKRYOM~opBDo}h_^~kptv1Xa7sK#{?c^ze zk$U_Mde)0i!|?GP$SvyM+DW=nZy+*Z^0}9Pp;dI>>M8^ z&WK?4q)wz31(93RZ(f32uMgR7@lGpnLKr!Vz_C+?n81jdRUWKa%EA?kx8sDs6smF& zkZRcgE?c#p#;+G|`Q~rzo&#sWnVUzX)s9fsi_zm4H^F3%d>nk5AI^LM6&mw6<#X!9 zFwzSGNYA0{b(2R6DLXM5d;+l=2$To}6UPvE5x{CvvE(+}>%_!4?bx>_iuYaiN4!70 z9ZTE=yzI3*u=m&wjGs=qrJ>F)qg<}(vOI|@W3tnL14$y*q%%*#}8ikTX>=buMC-|yeC$L3DN_YrMzX?hH3=n@?_<^ zDf5ghxw@S|z73v>m*XctyT|hIpI>|v<`cYhcTS?ioyFZR{0=hb<&h`Q$@UQV6Wq)k z!wv_5dZw2kn{uoT|8ngPB-Ame)V(q&c`;q_V|9_Uhnq2t zi$3)Yyz;%zLA;GZ7piw~QuEoy2|#i^Op_pf>Nv(p>|D4Yg-bhzDBmS4d*&dcaGf2MKmoa^#QXO2=_j2)tACTyPVNe{tJs1mgr+({DCjJ*kORd_=F#5iS$l$1use zsvVxsJ@;H&=H9%tN=%ccwX*DJH#&SWkf8~~Jby*tqe{|5E_r*t_{A^Urb^n3NykxW zS7ue7(Ce+Y-fEM(jx_%Hzd>?y=K35oA~e>)8YR1FsuV(isL>Juhq6x2J@GFeST)X-4XO4S`0HC=EFWiywCKiHk`uDkZsc8GS;4Cm3aUG29|;srU$ty3rE8wZ%dJS*vWS_ERbjZas)ydO?YP6O0gQ_=lg*g zB0eQh)~LZD)ZI@I64G#%^2#144W;-N8m?IRoZbu#KFiI^>&xRA{riw4zhwxDVXf{W z&j?Q3nVRuV20GX8uJe-diD$}-ye#US%X?-W5cahl0=AG%1$heaw&Kmw6R<98PxB1+wJE zY29N4c`3>VWrpv#!d~3Jd8j_2p7g8>R--ao2f|GrRdX)ZBj1<6ki;|M4X_#1`PZPT z#im4f0Q`Ofx|9^mgb7m}=(;h7{Bvs1CvTS7L= z!pN;xE1=p{Muzp9?^HWfy7jchms~IFR~e!VXl|Cv#xnSu`HgytICa4Yie-1b9`p{| zj>&<)hLF>PeG_pknA4690`Q`SFy)f*^g;; zLRf};8{1Mh-(|9{9P5hAD~18TWI+%x_Y20`%l90(gdK_b?nVP-T+dy;9iC7b+4&WA zM5@#+s(nL&K93sc9lH@}j-M=EN0YNl7y z7}K~U7P1$-g1x|b?EO)3k35q-<5QiOJlTP%Q-L(WNRmCtnbkGKSFsnngmJIXJs`zr zv#Z$qW=Ad4&mKI(%`T?`TN1$dSze5t>BGqR0hDQ2U0DalPxT|obfi!-{Vq(L%hcGF7vwVxtx6L<3-@0o@`whh1D%gH+dZE>+n^*%wuYRhKfM94kmd~ zkq9UrXfQ<&{`TB^aNLWwA$1asPdDQyAl51*0mQ@-%EL0%6=i^RDr1(Rp%p-!Wj#-w zT}J7YoXsaW^}@Zlv}ezuJWxVq559KUukg0#{;_e74L9~NW<0}ZF8u5BuEEg!fYpIJ zU&HtrJ`7#zM)KGa@&vp&8q_4qKhC;Oo>M@6b&2xf!}M`}j9lgpeh-4+_K$Rv}}@~mArjc8L2Y@_`!YaG1b`Z_r=dT8GBADn%5-V z$M^_-R-d*T;lq%xmSnd(n?Rz4a$cN&#r+r_2q4=}xo5t{&UBkx8_YBzi+4PIEk@6#e6Fb>VfA5QZ#Tu6oWv! zA6NhQofuqAc{`4vT3Znje5VO$Qws=s*d``VbK;8m_aa>H(cq=soAKfEZ^iC~0i@TI zkzZa!dTAB;HFZE!=qpp-P!60y)H2^@9Za+H=fa!%HsTrK5$2H{0LsNh%QvEZAnDO0ft@W|wwPyW-@bhh3w+8114~2Why`*~!Zmn1 z3+U;dg+HK)z*QY+kP>lCh_8mpkv z#?N_0lr@FJ(qMond%jfkE*eA+m2|1Qik#-@uoGWwuc6dgMYXqVWB+M_rF_nemsEK7m)6`OSBzj_M#!V6+rgewYt0 zKgHuHd&{hkqK~{K&no1#Dx>CPITn|V&$gvMc~I!DkVj<%{fG93vU4?;qdqxQz4apN zw8);kJRMC%C=W$X+caW58Sht77u3gM1g$<7M+xSZ;xxB7sPugLNiwMBWuC z0~MCLt0M!CJ7Wg-a7q?@NaSL;Z;E^s)zYZdvP{Q`)r-fG@c2-XA!HHCA@Zk}Y562m zb@?bT4>j_}c*Qy_F`#%RFN5St-`#1+47nO3f0*Aaf!Mhn!643M8G%6x{v0Y%m~+XeBj z&3jXuQ63A-x4dRfuU4y2@%ug4m95V&dU{(sI$X2LgvEJ$XbM#y>yk1g52(90k7`c| zCCXlfL0oJf9=7H75W$;ej5kFDdUHc5IJ(IXwP%JeFfWoD0i#lv=8@IIM%#lJj}-`Z zD0>|h${wRCI?a>lqkiy33RoGNfs=eNxn_Z$)wdT57fe#N8LrIw3i0Y;-LXCNwIzrS zS-(uj;fye@4RE+uu?+H_w#aG8WBkZvG>M)%DOj>LYHfh=N^g`q$v7wFuHddqmR3DF z$-pNmsm6qdsS1wjQrMM2gffP#CaF4$2*tajFUTta9sZo+LugYhDs(Cabs##4XLFBA^mxz*t4!K z$`fGFTrSALd-^PaRoM(efWW4^D~|G<0#XD5a*f*%7F$_0Tt?@jY4k6jAo!^w+?7RP zQ3*vV?BW6fk27*`&{&s>RAN-xp=0AnbudSyWF?!M!q#q=u^&72)w$(C03ga(6hiA>Wr99IR70?#GF%c476? zwxfJn3LPg;A(!{yvx{%1p*hSu>rQ zm?SFs`n(7kkPK*@7Uz(h$MVt`X9-}OG;mcu8#&d9iHIMgbA1L(0wFiPy6X-aii74j zc}a#n?>tJq1dR*J7+(pz^cnYKX$OHv69|aPKD?p*E}TDaGjgl)a7T;C&iGM1g(%`! zf|Fy?24s}4{6GbT#YKXsD&p`W7S5q#K?2z`3b;Sfjs59vhCEE>nWc7D4QCO+?HPMV z{hlKXN9Zj~yNKg@MsUjNJqRsjJo8F$%we7xOT=45b$Je%eu7+*ane-r&&}2i`_dfd9Y2iTV<(U!c z=tl~fZU<&gs$%l&GV&Lukh&m`LO0tM>oc*MX$@4-ePRl~%>5R-lQTH6^B5cxT|!_| zra^F`Cy>Sa&$u0-?kqAagXRzwShfmfBf27v-rfYd7tO%Vx@+ORyeVgd_v1Au-GhuK zxu+xn)4@sUe@i=5`QC4&aqlSMyPU9=q??HNSpPqRG`5Xsw*Dk9do>g%d64-I zdGjPSga@1W(a|Ff|5qm2NFCszyJHc+mRRA8vJ7)` z({am&aO%>%=$xBCj*1cN!LB)b4?34kA+R(F?}8LobWftQH;LH%B$lrnMzk}73cIEu z_8jG1$|eKs#g%aEc{{LX{s@XRYMvD-bU6!%bYzfQl1Gl59(?gc zg1qBz#MRILHyk%_KfLV9#E05&>Uo=y_c&2v?=culBI?fIrweXGv|7O(Ykr9@uKqo4 z->?dP8cL6^gr5FcoV0QeRxTb!k-f<)PQM4wTDl4I!`dgO(YPF5)bcm*H^Ehdp8Kr3 z;Ea^vBEEUS(g*Rv#q02*bMMBI5S4H%m=KXQZGjBB=f(+Eswh-l=;}$pxikge@+3|; zcLy9NByq#}pTo0OZotx&V+eNT5KL9^`e)yam!7#67cbk4%TKu%m!Etu(n&uGb4yrx z>=3^El5gTu7ySg8fD3_G1wGN9Gr#qr8qxB${aCen7^S`nqR})KEttUBu@U&)IRi0G zQqTLsa1viybpw{g#?XHJ6yEmnUm`@HrnyZ%H+%jxb^(Icj=rRMgJPX2{Kv&Vz})^B z#A$?1K6W?y2PUyQA7dU41wBfu*PF$~JrClf&X&0tzB4HgIdrkEmM@*aqT_~e`qDjE z-aCO894 zKFSMLu_M!4K(Hf)H}>4dLdY}sm#JFu;e6Kj50+dF%{g*h$oL0x?46XbVE!alc1*zI zA?SA#^bXYE_ZKne#BogL1DKxeVgzcl?Wnr?DLORv%Cob~Hc`a*bPR8~^m>HnCUN?* z-PUH7c1~gMR0pQwVcd}#z`jB|`O?CFf{N8$L-2L7&fD0QB6*y8!4|yaq_sG=b1&R3 zFTOkdZfr|!!b_GNk0gP_{I*$~+P@F8jPv=c@5gbGVN4LzbodB@<$Y>Ujb(kVZycAM z@F31UcN1K(BKlcZCF;O^)hJRKjkhW!=5WMVrk4D%Jv_f{j53hGN0$EvuU~Kr z+9>}oKK*W-)V~`k>YqZ%ZJnEwmkuKA5@2GRENHdc!8ZA%BeGB)!lSti^yqqwl5D5W zuawuex$?>@Z5x>X_>cdv4*ioI`24Sc9+4&|>lAg3Jqnr1>!a)a?|;87 zz58pNuC94J+PYhlsA)?S#Rxl`cxC$@?8vv{*sejW zXdl70OfR-%`fPaT;@-_Td(KWQn>U8;wiFfxXVB%(qL;>TWpn})xiAg58*Mb8eStI< zw6h0EC8-I-E`kuv2^ot=Q7LQlItQkwqVTxOnBP6io?i_`D!VEH)X6=Am`aB+N`)>} z7zh;+^%mgaudY}M3wx){i*x+qef+Gjr|Uza62yJ83$P(OK!7rdH9a(zi+7>VpM2F{Cx&J_a7yn!Ois3u zZ+R?ko54cz_1xZF*k0(v*0Ekp)3^j^2)hOn*p}$Qrs;l66@z$MbQBjw#}Q)>+7m5e zALIJN_%WDug|LL+QhXcFb;0cj*ApdOK5!nq&Xjq+mb6b}QFt0Y0=|P~Yate7Tec6Q z$rz>yAh*z91z2Ab$uNdf5d;<_(MCBqvvUvTw#D(!i|)WG?>H6(rZ9(qqsN;Ba7B9UJH0e$7TcwhPnx87gCm@es(GpzLl7l<2)JG|2W#iImA3UtO$=|d$Jb}P1vX0 zcxZHd1g--#Ea!PwV&C32^hFYAi)N5__^>D2iSAGq6Pg9z62Ad5%F=nEo%US-EbK23 z*i`ZM`L|<%PeYk?*+(_We#0Of;rFmXjM@95dTcHn>rb%7SJ{SY=%x$}6Fg@q0}DE5 z(8EqbB$`J%fpd>npq||~7xhK@zwGTND@i1e<~m#?9&4n|xu%2YWPCma2#cKs`m#vtYG(b-yWeB&E!3{smD>XcX=vZk%QAMIf+kr1*3MW@_q zC`~|2!(Ez3w0rmNKLI^bC^zN0aTyiZGig}Ph;GD3I=186%WucK=WW6{!JYWqu3Kj#`Yjt_2OUWt;72lJ^*x;cyBM>cIFLu z_L7INJJXF0j|{L2s|m`s<=pth&ZlF|q9No7Rs^~xvk~k|wIN;#;u$?#;H1$!Ca@o` z?6}tq&BM`stA2%-3~a?6x2-}t>%nL#iW9v#w0U&+h>1cNzuUD2E^h_%Xn0TOvpKQ2l^dM}##cbu;Wl725Ew!@KoIAz;_735iC-S~ zZ9Kbc10I^3k2_EP5~ATeQsp^#{hbF7W<0m^65P0_AKqvI+a`Mvq=CFJwv~B0LbGAE z_ZQpIOHfse*08`ejRnzZe0KFMSbOG`_=oduVmiOX4dYAjoH-kCLvB8 z1vlZPU3cNi1-FrZ2?IEXlk{#U71zIx_u#JC4R+7rUP|M&1hoqAw*GB+Z`U?l5Zj2C zci+YG#_^{9TkwwloABuqegTh{{E6;C*j>Olfth$-=^=<-G>PNq3}Hpv1mmjVCC9GA zIRs`u-*X(^*tQ+-?AXb=Y-tBH(kF)F_{ZhHC$J`n&IWMl;=LHF{uhR_dvHSc8eIEK zKmKdwm6)mcY`A7qehxGHmxs5Sq|SxQ5yD07qxkJf-^Qsccd-qXaT+@p>!;>oWo!&@ zI{p^)&z;7pi}s>Bki|*!_v74EGq_{q`4)%Me~|$NQI(+iqKCMNqo}67VevevNMJ@dy#Z>D=6WoX?AF}5 zbMd*)ea_DJlGC7hX(F@szSCkL9cudQXFuCkbUm5re+~5L05lytp}90#t)&^~+MrOL z9_=mg*I2P7#H-2F^7trEqUJE0kn`b)*h!-^KjuVVXAZu$8iGC_x;=ULrLg#Xq7ueX zsg1@sf_OQ^p1TWvD#sE5%cz#nl039fy9s7oG%x}}bG&h!9NA~e)$c2zPqdoOp~TL$ybE4`386>{ULPn}Y|k1GqQ6kj#B}(E9uMeC#2Q z-nw)njZ7R*BarCz5s(}{v}NSPJnt+njBdw6m0s+Kcf;wcSdUoz)1={I&4V2I7YSq# zau<=92_a7KH$d>$$=-Xi;ANQ|xH~<74qp!23vJkz@5YWy4+ux`=~PNf3M;raxd6z5)kR`|o`isbw z+&D2fWc)c=Qh8iVvyW-V*eO`vJ%VK&WAL!tVR`rhQz$Wnyrk{^EcRqNurx4^2o3y} z%t5{32t1FXS@&>hGpV4vjKO`qm`+6~Ry7O}q|UJH@<_QD_mbcQ!-}`9?OyK^BoO#b z=R=I9W}s)b7=(u%r4u9j;c+>!ONaiFlI$or*&a8?dre+6aoNqZrix+gE&EtD#obc3 z{5esLpx>WFiU2V#?+n|mmu-ERos$FPU=3^HItm1*y^Nwh4^kwM=5snIb8efw{6KP^ z)oZUOi2>g%a(S{d7fFuC0I$YMBr1)U(?{xV~hUWD%$@MQWZSX>oH8STRKhs z+H0@HZ-4t+yZ-pcKiUDLn#g?9O*did)~!!^FOTSd1@wpnEOZE(K+ZFs@eKUrCqJ?K zU;EnEuy*a*zshDxP4K13)6GUEu%nsoIvS(Z+ob0kHa&nZy!{t=(d(0V`D=&q;2+0P z^JZ}^mG1Xumf}Z~XW*x^C*hjGHMZYJg^GSW6G0mlPPXEq@%3XY7seQYN5Eae94e$P zcM3bxU6{y(5eyYDClbf1*f?&RUW)E;3cE@@*if2_8IKRwrWPU+%j39}gE;%x?Re8g z*W>umAXYlYQAql1<%TOjB}xUmXQ&I)BT+kJ;Mm|WfkPHu zG>QXlvslwTMiAgcoQCw~=@qykv4WLL4WXsE4LY=))zIx4!{4^;z~`R(b-ZrQJ-BUj z39g-z6|?|ZP+j}7x!;jh)eo6;lED&B}!>OelW7y3@!V_ zhz4?qh4Z*=*HS#NYd+rEw*xt@!xx+4%1C$=FrxM}~4X?QrA5?yXqS zK919S4z5I+E>^KM!#X2)ncE)6-ed=Unp}m+vX1;XG@n}Le@0}SAh>8lMQc+_FqMno z^Ft@%9lOrQf9^XGx2JmWhDCQ{xYB`6Zw5p8Hnh_)X~^V*555SW7GOFE&w5$R#1 ziM4NT+lS+PbptD^wSS!t_?s_Xn{LPVrq03U@*M0Vn7t>n7+1wl#HQ>VoZq<}_aqkM z+ToRGk7VsC(va?qccIOd#XUm{aqqr`ST{KjzuI{$dR-ax63`s3B4jMXuA+I31bW8H zVO%@09J7uP0f>fgfKc22#T86IY+BT(9wp0 z*bMGVF2D=sZzO#1U`c2S!^w8)0>1BXAzmU-`4bs*VVQp%&*@zcf24@}D0^E|y_iJ^ zCv*&Hu03VE4WC_q3+3wr1mOdCS=T+-o@YH|+tEj0o2Sg|&W2br&8cZ=5bTuv`_kVc zQ3>ExbJk)Hf&E7(pN2cx{*!E@)&Lr0LsB!ZgTsFTk>|7c=wKUjQ--B6W3C)QZxnaz zTa2|Mi*Qc&ZuklI^6YqxvF)4~-CKV_FH^kCi3AAf7s^n$m=67&kug^1Ka-P;~)RH9r^Uvu&a-C z`dG;^z=irOmFT`Cl1T(<`rpKaKzi%F{-@n4bB#J(4 z8t=hPyO-f7LnmNeW)U8korewU7vYxsSKya}C*Y>cYK#R!D2FRZZ|=ZrHCLo(6s2et z-rhWW+XYONqwsmksAZ^~H-xc!wjIBpI>t66JfnM%edZe8a{tTVnD*dx$KHz1UHk*w zGQAS-*>@R!K6?V%-C2AmF#!M7U&VJu&O*BE!M5pM{Pqv0Qpx5qwxJKn*&qgj35;iB z_~`Cu;{&_Thf_Ns{s}p-VBxQDV<`#8x4wn1?LHN+SaLs&Q36MvUgtnB!QoGLoX9i+ zn9b8TEV&y~2q0by;h*+d}-f>`0(1x@Y9D*!mUHg8|eaP^`C|Q?w8>wgNtzg zzD4k}2miwjr(iZ4WXm}MGNIwUdiVqanlvu&TaPQ|uS1%K<&IPz77R?{@;hFITlOv^ z5DsB`ycZLt7+$&V6}UdJ8kaA70HI(G$Ga)_7Wbd3S%Jp_jdQLAKseotSbO9%HS-xP z>krnQf-m0ibo^-J=@=e!KH{B(ni@1v9vC z!8UYtrJ=*bgT5jLDbKqyQO0{HSaCSZxMgZ7F1YH$SP`2fFT(iwP3PbPH@+60FMP$q zw0WX<<@T50A0D{OR=s_1crh~7+Mj}nKSwO5FIdE`^$T$O^(SIB-iDrN8eXPQZS@C?3i!Y^>az*hWv=veHV z>M-!q7S15PqZ1Eg=UH3%Q`AWiMp^z$|606m`JGt2U;?94G5qAN)A5e$Uy9WJFud#g z@xgV!!4J0Y#`8M2Am?-9{`5Soo0*SaO`nMQl;NMx9E*I-cPJlNso6pqSM53;pL*!o zh?aBs&DAHNtuxC`k%k0Y!}{SU-G%b>+u`)CAy7LwWT;x2Lxa}mN}@B6$E#M|gMr8_ zZkb(*je~Qrg>oJs%=;SKvDT=y8}b zb+8pUG^_NlK&m7yRoBE}%`#uUe7SjDG&Z?%cO{Q&_btJi;2tb=k025E;Il)QAWw5G+wj2XT&$m&i&Q*lLr&>L z5Zl(xM`6Z~*~tjvGhti2Q7RE;4Es8r7`R=0#OT{P651;E4xNEl?p$cHxexMFduH3?@6UWwIN`_YI?~KaP%$ z6e3iv?m`WLUg*j9a2 ziZ0wWv4FDRL%bA#W710ykV8J}!F}4y$*85UETcSG=d5@LK4%I2ZE-~BC9rbN2%f%r zun`FO(lJlR<)Muz>kX@zysS zK7y3y@YbPi#llgKub-YnFxSIh4(y@qhutLvh-Nnq&qIRs;AwHaI-DU?XaBkJ>#;-S zmJa9tG^zBD=sHv!9+M<{DR85S%9^;WOAZBr9N97*`Sj!fJS0^b>r6YvH+PF~PG1o@ zg>!UzvA*c!Zf*GW*Q#T=+5~h2E(C<+-I1q7E4Tg{6Pd*bHLh=b;~VCA(sFf8rvBt7 zKY2s}3AoDm$^MnNZ}TE--a3G(={5|y+wr4yXW;6!Cu3xL4>oO|XTw;Y2@mo^A&l+s zL}h{iWFm;-z7Qh!`Qck1v{h8;0DJA*Xr$8~Ow|H#5ezw}-6#|2RCk3@B3N?m@x#B> zkII|^hW2z(Nk=foKHGzdK8$YaMe^(Ok=xLLs*a#ona4d3Ek}HR3^nS14GCnaB$WsM z`T%-vb0gOdR0=NKylxfN-nRln+o(Xp73`j6K4}QHZdrr}|8Oh{YdbK-Ui`Yz1^D(| z=VD{E7mj;kNZrzl9S_XM`Ue)FXZ{RE5Ypa+7*578&fag~$8&J=$Qo?S&81)+xem9c z`tZrEmttV~IJSAaaLw-3`26>tk9XdCDTU(DNp>~|LW;laV*F8T**SoXcP)c&%#B^6 zJ(!6{FnfOw9{ldHzaIP+om?m4)B-#nD| zhA_={GZio9_Qm19J&N>o0o-}-!6B|hioj=@edN7NCsSWhsMT{vq^cVibZx=!cdW+m z?>`Q=?OBSO?_GnfJLe!yP*E*8@z6tyarONtV&DEQTzB`e*tBf`yD|iAYs$EI7BA=Z{9 zICo)Rx(z#Nj5m$UMa^ABX(E7`yL<7@W!EBqPaBexVI=sjgO&QJ8=h@3AD)*y!SZC4 zV0daSb`JNUnDQY-IqPgc=vi6ac^-Z<+kx074{n-Xiox9BtHAy;WeA|Pzmhrv*zHI1 zu5R3Q`zky*G#Byd2=+hNk5a~iexxz7sRxPCD7KEx!_|Xj>_};Iztbq&ZzF32BU@t%&iW9%V6?u{?NReO%dR6c^A51(SgXNPE5e${anS%(+piUYe7 z9ms5rVL0B2f7KT3^%iiD90AnQUnaJDW&L-pCBJMZ4g&4lw=Bi253I($o0ej1xC4%H zF9Lf!*fHIWnL-#H>~Jum`a2FkYWZK)zdxBsRUpch)ny|m8p(LFknoMLPF2{#@I~W6gVd7id*ir0#wh(g+9W`ugGM!PMtcVcm1={+ z>#n=b_7>1ilB&GF21#H9vb0Z+#+5(xp${4OIwI&IYrHuJ$|W}{YZ*FE=;2fj^Ix_rNIasj0UMcaYZy~}44RBf_aii$Ypgf~+IJHaT& zG=0E<5If`E2{#;Rf?Rf{G#R)u?T2%}56+|uo-*@Nt1uf?q{hQ2kNFWAXMPyAqO*kp zRrYFYDEeH;&jb-1WI1P8jxZJOBo%s~hT$xYN-=n-kyB5(L7LoqUgtKc}rQ$@aWoY${YfeSYSB5J? z-c2yAVZJAncZelANT&x=s15}XVEwuiF7u@5U{9~J3jd^zz0l=ATTdGPY8igk;hx=n zHveKK8OGf-RQ(=B-om>BRG;%SStAH`bT;mhss!k)_iM*iqb-s(2b&}9W(z|9*Rx`9Ti+TwTyAMOmro` zQ+#h^iU27QLXLniq*e4|0c_c@pb>~^y23c2`y>?Qf!QB6p#6wIPtA$b+Qx8fC5}`N zJ107?ZD|%2)^U}c0UjWGt2g@kx%Lkd3UwLL?P?JmBYugbt~RFX+m?g zaA)J!lYms2yks1Y<~m|id<>E7wwwi8rKPz&nx^r+?|sjXcG5g4P2YIbCx$o&<07L_{1l$ZQC~d_{TrSAO7$M zyzhPQ!}Fj2d|Y zLFZt3d}mf(Q-^iMi0T;CmKLria8rI1=aext+JUK5 zi1F9?=y1kRnS7aj7r6rQRZdjN_Kf07hqHjkr=|tN$ zp#M5IIybONX{ahGFUAARM}Gx#_BrvR&)$roky%Ur>GPMuyOH1}QbDDy1K!M`F|{7;ZIBG{G%6P#=YdK96HG3+Cx!z20e(9pVPPY zW5W%r5Z}^{`}Zz{Pgbhc&K*Vt_RjAgdRF5XgLeFoMlFf%UW2k@qGtM&82D0#SiXe z{m!qUGV>ldeW$TNjd)5SN?!pzKFL!?Mz&9K08kvy@;}%yXPVCKsQ2LylihZMDF$?zOfy*7u&229760sXw{xGtlhbZ zYMS02W;+-xAmC>^-%r3pU>n{=8ITSbtg)?7j`xJ{-QkllQf+#iG_4_o>eTa4%img$ z=Se^Ug=%6)bv=wYh%~I!JmB-;rerk3s59MqHCIw;#H01T!afob=#k?YA&JD)=WNDh#jdqP9SLMURT4s>&uAIX!&N?Gn*ptm?nT=Crm4d z{IeB=hl}tftMH`xeW-}ot^ztX=gs@#Pq9ZfQHD23Wj$U*aDqL%u>!*Ti)h$ZvlO`(L(YAI!JS8Xm%x8q)DncbV?^iM?H7Z(_u!N3vvvxk0t4NTuvq}&}P_~|i zb2!VqGL59(tH6_}B9N%TlOr%=IXgBM(R&{a5)D9T4^3W7p1OLYmI*|4U*kJ)V*7cR z+46U|^~R-Ga8D6)uO~kVQe4};c;hc$42QoJ@G@^y@_{8u=9z|NV;&2CHH+T01?G=s z++0FG0bS>2dDNu9X~aEX`KuVXxk3O?M09@vvEd4;Q72N1G&N+}lUExn*q|lE2FNl!m z1i8D?CI{t+hrpG9nX-`W^`RK`pjh(SS#ENGb*j#a6}V}n=FFYO+jZ)zQ~di=QaY=A zI-_cT;||N>p2z=d_#n|-{tsQ~zMH^#I|1}A0>M$r5ZltcyRv8>DO#NhEO=QwZ`z4s zJ9*|~oyy}mBaemL0tD3r+I{!eFmg*D{(bZ`=Cf|71%KdXJRNBiI|$y%S7)9Eb+Ups zmM^)Tku+%Pfd~Q*coEv|f;Y?e9)S~Cl2gb4{+H~6GwEh~VBNKQke)-{bvRJOwZ96YyB+940l%GGf^0Q=fE5CF%cJ9XRqqazm-Bw!i4Z#+-Z+qU`7v1RY6$B= zvQEUrGiXga$%KDkzUuoCi5&7Mrdh{hPV%JAr?wr^F=gr~zCu|DW(dfAdZ$rNfhf6s z4+mFIRFY|VB-g``z=}G`zxvg$@XKHR(&niizB)>PN0W>-Nn0za^r@A~`qV^ib^f(d z?MFZQk=+wm`Nc1OVIA>DN=i#RFF*L;g9d(d{+8yaYGICm(UXCs|EtvL0zH*dnODia zx55dhCNO)*c#p@;9=Ka5sPX90B^h%~u+l-F+FL-&>4Z!r5Z7OS{bP5lZ1y;vnvhCG zR+B>6UOxe7`&em;U5 z4RKX{1bVD2XQl}Ecmk>hFO^exZx+QKKX$)iIm!x8uv7}T5FW|H!F-gWZt{}(natRU zb#qw8zY(PxYH(jt(y`{m+AsP{%44aejun)P7mPAX}o8&mu zz3M^^9t~v?hRaLh&d~UTXsBh4TghF;{++!@-O~-H=Agtpm^m?qGQpp3e**3-g<8jN z&{)eyB&iS3V0aQVgriC7@d|SNKE~}r&)o^MZOsw%Rp5))ujsH20Ck~r69M9MnRUTB za5-tz5AMwT(XYP(Gu|pH1RF)#naOH|caNYAofWJdTZ~{nL*SQ0c5VRah3w%Cr_G)e zI-E3uZbbGGP;M(*Ph4x7bP%nBhSo=L>KOB4YA?~mVZ(e)s#VLlBOk!`<9@80t{?qS zt7$whi+q_qd9rY1iJZZV*!Km=p}Fo zO|l+#7ZI4D5O^JE8|CxXx^(j0G=CQz1R#9II0fv3RVOz7_5o~I+gLrNVLCqnFqO{j ziG!ZMqamf{Bfm2@&WE?i&c(hWBKs>Swn?io+9?86f^&5mDt;&178{JpK{0D*yYYJo z(wZ_?Bg(6#cscR4>636;Xe(Sf@|yXQ>;za|@lD>J?or-sEo+1FI>!rT%rAsd-Q%~m z>tfI#+m_mOVE2^Cq?_{J+0MvBYvbsuE>=vPD1ct%Q-z z`{D2u*>R~KpW#fnaBhUWlyW(YG?}>){{$T2_w#Wd!!R>^N5kwolPtU|%W_rF`A}Y4 z6!AIRSg}SvRtuC$OVoD236{OzQMEJwbno zG%_JCkA}ED{pnBR3t#vGF1qL&qr<{HSx5)(ihot={%WP#aD*PLKbl+i z^l4#T>T-(7N6F~_A5vwi610R)hoWhsl`36GSf5v2b(Jl@d#q8-#a`uT8Eu1Af|Wdb zWmR_gY5WO9+Hcwg-_CJ(2tM2s85-RjZD0kSX?~wfBd}*0p^YPOC9?32r4ZOMh4$MA z;ormF!AusOsT92X;{-z`I3{M{xpzB!4-T@&S3+prFnir4bUu)Vf3m)hi*M&7f6v;< z=>kKZGL6m%!}5M$!w_5qEFLO3-%uQ(2L|CBq~fO#gtty1I7%QhQ$S!a$sTkW?Hl6g zzGVcFE$pR-ya+!qg3yixjS2;X#yBuuWRIRkVRs&F4~!$Yi(rC6<;~Eb(&)%DwNkm|k0({x6m8e;KzD0_4Y`qB(uUy9IQhVQ(D(`f_gyoN{y&Z(N(0_`*A)71pGDst zGX%zY%(*p*1;3w0*PS$inpdKUSVtg-(~YzJdAusRA1Arj+C8WL64u+_5s>E4y{?4* zwFPvnr>smBY1nB1hqD9*1RpbX@1ur_450IV_dRjUy=DSk>yn7=NW)7&+3PgAfvUh;-yKDCZ79M&QM6O{g9L7FCRZf*mzNY%4!kzK z2`9Jf5YYNCfx|UmyBND2ar{l&Ag(JeMA!B#%a})KUk2Vp1>Fx8&^49Di$^cy3kN|- zll-hhb_=kqGllj`#^D^{`=c3_oqQrlu5^YGT|Wgs0m>c%pnv<9-{KEne+O!7XUJD} zP^k0#!*1O2lT-1M9hZSMV*HfnE=ZtryfcgP_7L$F!4BJ&07_?~fH!P>1%ce*L;cj+ zI`*Se*NoT+iI%E)x9Z+8I5+JkFqwgSECCmllQUODr8_Ea zT2EXjUla1fk&)3M(v%H%yVx0{k}1%b33>{RvUW5Vz&1xI@V!Eg+MCYIF)d-&{Uj$dmgFBv~v1IQs;6XJgMaq1zqvB*f-Ln}ucaOl4FT$Oc2Z%jTj|&c_ z;mDWam`TIAV;GJ-V{oLisCoIURAC}aVoJ)>M4r~0Y>799QfTN zRWX@@!W;rB0vzuc>x9YIJj?~xkg1=b7;GRz0 zwPyvhaHY81qajcB-smP zz4`YiSWiql;z2p)V^PSzY>stEpw4=zQWms*g_FDsQcgB*UxHMYid<-0F|#T=c2EZ8 z$)QY`3?(U_l=YC$gCBkM1`BuTo1TWQWs8t#^WoLKd&rD~J>a9FvIieK<2HEL3Dxjo za_XfkT?gwoyqn-VOAtr)dB?NH#|Y);chN-{OwMP;J%DO+<2`wLn13D5@KACt96`px z;*^*-$zM6l_E~e|w7?JpTWuaf%6Yt!$Ie;>$84Qp`(Tu8<7y9*B`51#GU=XR=Y{RL zr;{>5%8bR~BwwSOXAl`J5j@G|PJ^aSW($?eP6Aqjbc(+xRhRF;6cF=LCmhj3#!9H{ zqfVJ+Mh?oVcs!bl8KiQuGvQzzYWPw4^iLPzO|y=e-#fD1Y(9r>vPnFRkKT7h1x=R57b76WN`OH0|6hDJ{w zvm+?~gLDAX(9Tvgk(p(0C1-_-szhZWw_Jsl^WPau{O^$F?dXgxA!P}TkZALItnMdJ zCa>o9v=ac(c*u}VrQlh=8_vzUfdrAXm`m{C&^qU28m{Ritt5L}^c{NzmxnK8V1UF}R0k5uxGzxA5@?-qT)19icQ{)4c`$TSv*G zbe%V|d~Y8C9(nA@&{${52lA~(U?<~PrQx-$7q;(Zxn@vf*{Y!c!!qyb3|z|lUI9b` zQ}J+&MvTv@e7`m}0mt4EfIK`v1R@Udsw;k9mxIUQK?0YK2U#b2 zM|_-`C5W0Z1LR~obClS#+c#zTcFiP>cdl91C&8;gNpvWWp{Nh{(I`FKa8Q=Oy5=M( zPW~U(Rs9?;#D0j2|M3m*4HRq$)xBpJ!8>*!@X#<^lvnTGX}Ip%2+!tya3=&{s|J>x zlqCb^0_6ldu6^Ss3$Fc>2<(o-!#dp^jUexk5@wl++@3kG2XFPShjXw5-#Ft)=gB{| zS<1Fo!*4h0K-3!g7ItIlGmo`ZO+(sPsKsa;4OJ^{oU(Wa^GNxN(_l|(s5nD_L)qLm z2;V3_DVKqbL+}n!mRYCKktD`%@5McF&2t)N9baQ{2?8toZ`%5F{ASY$NE}muZ|exW z+sEL$X9v6^DS}`JHqXjH5I`NCS=L3q*nv)hy!feXrXJR3g&>FNV%t7AhbB#iTr(Mj z*(vz)-(QLGp&5MtH}6849TkClw^n7bE#0|$8Fpn`PSdBHd)hVMs)Dk&YV9q&HI9zK z0=8`K$A)~Df!#w$^Kh8Y%IFd}I)24GH#&(GFW%XE3uaFt=t<<@W(UN-Z^8U;9HH|Nive_%1p zk>=27^g?r2<>5Kwj57?B2oT9bq>XxYT!cI|8vW3IJ4cG+a1!A8?svb7_3PJLy0YWS zkJ8dJfgIUdEez6zg>o=Fv4M}nK#sgTCGxkBXGf5Fw-xv}tL(WHX()S2lbanEX0Ij?V zZW^$#CNYFj%P>xjS@%$}ddc&!JWM_VUxmgVAe z&0DBV&oC{5h&dey+|8cFZlp>oO!Vj?PVmerk1VZ7Ie zLYj@zL{R_L;Ey;^N+nPuKqT@sPZs#D_$VG5$RuE@5foLX3BU+gYQr?%KE@;9sC*O9 zIpRqJo&rv_V9k7-7N2r;_ra!k8rg^z|Q(gXz` zxc6zm+II2)eL#Z0k?9Fkj*w5xmw{UXF$z8$1f5{s>^^14LEu*N@>yG$pfZJ0n+u`6 zylmodOCCs0`E9)g+_e2zREi$5{7_GjdoSD7F2?B+)A=rqZ;jyBH9@|)nTJ>ej_yv> zA_9N}$!P*cfja_lXNm@UlAt!w7`7v?Tw|J-Xp_DW9P`>6fq~C``PJ}j*@X|@^c;pG^ByUYP5YkL2KS6Snh7{rpYkL++GD8s zy%a6hA&rB>&wQ}n1ShGNlQCjl)&dyPfN1hhcRVB?2wa7(tBkB(IdqiL!?siNPwanmifl za@hDMKqap#+&(;a;v4w(7w)jQp3p>gilYyANoP6950}SJb?G-5JDdb`T0J_lS+Z>p zH!P*+nz|t`kG5=4SatAU{pwfSDk~kwq~R^ib=5rAqnYBNIF>D2W_DC_iazzJPvOcd zueA4dX=Sty8r3sRmX@R8Xot-nx76_P6lqs;*|cGs8u`>Dr+$=61w)8JodQ9RHZ@W5 z%{Sj{Zaqx~d;8npZkIM#()l6UJLj=VH4lZ6K*!;y($n}Yfue)PLdvJ2rS<|f1V0Wc zS+~5K!4gsTv5p=lOh}dAN1Ty9cVnx-c=md0XGR#!Oj;>BPVo|0QK!t#yLZh#E z*&*X6m6!}B4V(a2MGBWaZQF7{z>DCZMxa#_;NowA0T~4+K}}V^$7qn_3BF5!rO&;C zs1Q6=M@AVhjUN?cP2geoe$<9&7zuDd11Ce{nzz6VsK6OyUI88A-+f%RQXKZ zqyr@7a8N;r92%P2RrlaPW7y<{=8y_R=$`>44YN$=;0e(J(4ZOsWVwyUYP(WKik5k) zDGw??m5YpVg)$}&hJygfK|o)xrvU4NacC$@!<7VS8Ui$avThu0GGoRTC<_)Fr<FpvZ(ghV0qU z*a=|OdBICVfAWU0?rQ`y*gZ(lLtc@;4(3ntB_3AQyChR<0>lF6l_EmJRU1Cigli*b z3EzES8RLk;StdwKQofjfcB@zic{m40(J>y!2VVRo3tnM9s&l&#ZD%+uiYo0dlN7TI z@tvuDcyk1`0=sG_vvHG8B$=joO3+$U2V{!8r2(%5-AJmOGXl;6M3kFa0nW&~$d40I zifie+7x`X43Udeo#V2)IC=XQvsX4wRw&ivH)|hRv7a zO3!@s4CZX^Ren(nE_O01jxs{j$L*Sk^Du04kVg(@FZIN~vhGsIN;$CHwP7#3!|XJ% zUL3P^@3Lnq1OF6xR&nAOOyb4@fmSt(Uy;XmGKr~@8wX$)Y(dI}{Zkl=PaB#kpG;Gr#7RSEy%zzN5RGe37wd)b$%rs+2Yc-fhN%(ARpl|z zDbh5UH5wlcwP{5|t&Ijn##_ZFV3Ws3UZ~2@D1nr`3x_pYM+=Y;WocwJmx&5NNKR!B zb>$EUDZdQvDByIys_G$2SJLr zf0sQ8<(?XP?)kmak4yr&hzI?P z;<*3x|3HiYt9k%z5G)Z9zWnxAVs9mea)3N=wxK$9YW+Fs=l6dM*}=FCe+nR|j^&Y) zQLbu8kagpbLe>zhj5F)eyomxr4Zx`OUz;R==6kiE4{i5NqHDT}FVD=wRcSw7JarMi z|C963y>S9gAI$^fuE;CNGF9d65vZS<#L)fQEl=74<5NF*2d-Fi8`dU+hk%KPBN?3> zrun6cv)V@y+eWz$P?lJa0&is+7XjqjDC<%6O2APQNb78eYcg*8G{xK{>}H-^?hcek zPqcVf{`;Honm;_3&&qI7?tEo}OoH6%z9G~GhuN#IVe8-=JXGwV@Euf=4#xGH9c%FG zEh}-2YZ1ONa}om0y>`-BRNBI*F6g(mp*F4#NF?IL3)lRE1^K`K`FfOh4O^Sh94?o) ziY=)=+?ZQ}Qy+K-{%|Gh@OzzT8_6QJrvT3^>xm%DlXAdI;G>h}|EyBh(G=Q?$Tx)( zHoXM@xcd|=J9P|+0m?shhB{!%C}{;AinF;lk3KaFr6DfGbF@=Ubee$T7g+j- zfA|Mm4JL=eEw|i)pZ@fx=1h<`NF)I8geUS|Hlae@s=az-S6kIJJ9dqwT~ckA3r9>}b-MP{|40*nAS^+dKvGh{$WhOA`}i z&;@Qxg|K}3E-+A`5wiI)tQgIyaA=5t0_iXSqa9MIJY_7WX9*yZsM1i$aLKbHqb_65 zu4KKg6b~DVBSfRp)q$#jf%0R|XoTb~>0)nCUMCqqrNc*>L~V0q*weM4IpsmW6+h#s zvRAFLID32Q-Xt2B8q?9RUX`FvLo)&u)>~Eq*>IJpv#%HKPy}5rK5vl25r8ZEWeViM z;}fQ_*U~ZIAx{cHiVpS;YPqp`to}0Y`|c^2(k6I5Ml4V$5JO|Gy%=hmv`w{CSM!I-MVzFHz_4~dX#TXj3`*fWM{mC+RpcB8FIhJWO^6sc$N4^7}961|(BkZKCZzCS4VzT04v9`BAB3A{DTqu-Q6Bh^2DD?gRC0JPk?Pz+#s+Z0^a zM$wlbAX5292zDfs0&bEim6tqaO<-jAFmC>7eV5<#-~_I`do|7sllKi0)YpNu&O$}tv||f-MOm(S zf#0k@iQw3ec6rp|%&WX{ssf5_CFDb?(}gLIAH%6bkMNM^$%dquHsN17y{p^3-xs%Z7r_rCW%{QT!X z$7^5vS_3fhx(IwUZJS8*X*6#~?~0_i#?iUigRrifp%R zr{dGRB8{Zz(sy}~^sE)MJ@HAET=&3P=iVx{PG*biB!(PXvH#N~l&g&hRj~p!`hD7I zrD=d?ioQ7=sHodd0Aom!%2=zUYWeylhT9$iGHMiZ4Qm-- zP%ochjonrkRACfGDM_1)L8Dk{cvP&WXsBeg98AaA+YOh7y=1hdSlJ_~7Bw`(G}I_H z#4tl8$L}_zrgY>b(l8EtpPI}pqc3lRjI99zeG1Glk1~cj1FDjY+gu?>lmJX1j=;-~ z%a9?L0MWo`D5=LT4nA$dW(1gPvCmuAQC-U~mfyGHYt z_Ru3ysit0!fS0^atWT2#DtCFhY~nY6%PZy3qR58sF1|Lh$6`&}pF+&{hr z-s5KA+%rKSOXJNBfwQBHTw%*$9@TED8s;6JVxA^wtICKDvEJ{D;p?-fFj6L1-az^K zD2^NG!^(Mmh-}Rvx}Cj1f+Nj)vQ9#XvXw4jY4A)aEA$cGyNWbS^48<|9TYO3CThY?kRRA)P5-!+K!@Qs}m38-6&Mq23QoerF_kadsDsG zRSdHY0PR2P!TWCbJ-+<%e}(6}S!}#&6}A;v);Zfzo=#B?*s+q%@Oa^({02uW=-OSu zE!)=M)pxuGiTk_IzTS!XS7p(4^AvnR53av%BR>85|FFD2;fQ>EBo~`z{d)@ukeqz- z$@tE9zGI^kzyJO3@wKmg%?_}Zw?_N#G>5s=_7z?_TBi*(!Hj-uIP8QIPO!N?8h%>5 zc(I*MAaBvpdU~FsKP5RF+%6A%v=1KYblKS^8R(Hd)_?V8{^*i`j?M;=Am|dfY4z#| z89$Z*k0{m^#`9l$HW4(H7==~TdC1g#e3$WOp0aA{-$8u|utxb-V zf)iM(Q1Q#qsAr%!8vKzr#;GAB8TWB2{^`1>#D*y}FUWq>fs=U*8V#yGl)_#xfs5r& zakGBSv!guex%lqV@R#0UnlylVuJ6uRtZooATtRSPJy^cy3$7Svtmh)|>8CGX#hNms-syKq7$5@}j5Hybz&o^#%ocL^Z5; zdN6lX8wM8OrE&JT$~dWSs4ino;#bB}mmx>9hr>7pXmSLp{@P=JyVnX%mD&m*3i}7DO&cMz+^A7?yX9e4fbFe?zhWV6@!u@R+y=4))A7s(0 z1enU3(4lxmprW=Q5U2TD0(Q=56t(^iltXTK`m(rnbS2ZuT9KSCf?(47|MpqPqzZ^^ z9EUqAaM1vJ1nN$vk-oPZBUL|sk*1uI$9Lwt@!-Az%o!;VkZ8`66Wtpr3mudVfn~Kl zfpC4dHr`l-ptcSddKcEcO!2WeTq6m%N)B{xs-kC88Gh|erTNaOWZl~vPuY;8Q|*di zJTzTKp1^gpe$Xw6yN&Rw`>KKhP$+aO5PS7TK(b|zxaTMMVCB6nn+w$=c_@|@mj5=ty{Dc zvyNgCSZV^Jr|6LrS#7#c$7;DfKDPgcU2c$5On0(3D21X2x{gr4|D&Wd1$1;-`pO`` zH@!WN2P#PMQ>j(8qR4vARP%Cm^R5h-4Ham3h0oMu7OAZK&%T?7L0+Fm?_b);3^c#1 z!sKC*J6scDRf~FN!(Zj63<4Td)H{X?i;UQjqa?CGzKw_|6jgYj0eE9*kG5FnSyACG~^X0DAI6?_GZvfjzFkDsrcdb%Qn}`Dn*ng2$-0(;U2J27>HtS zs^pK82HowA(f;U8o!0y~>{PC#d%M3qh1F|ccZh9Hce0+0gVuFiJK zoX3EWwSU#4Kww7{-art!>pM`rJ7(vu)k*}K1nG*SDVLhWFK?oFFHq+~1T&*#N`su8 zJ`{+1jg)+`; zmD~I*FXdTY+TH?g7+QswZMl@qkf49{E-Jc^6*apk^K&IY_AYZH#!6qlw74S4klbE%;vo5{YoDcLA z{WpnqC7-u2g-6~^b&^{ukk9y#hQvh!sz&M5{xFXs$?(fgx zj0!;od-euc1UQN`8X9Jj;98?GQ%6pduj+x5>OC*sRrz(Fyw|=wGElaBz45+Hc-6&* zQcEWrap{A7J^>UN@WwEW0G5ncjmq1GzLp}HvWpQdLy$rR$ zgeFZZ?WS=ipA4u8(X$NlwwWh_O2k%DnX*x9;CBsSXxVb)$J2W5GtU&9IyNLl<3V0)Df&a&379-o9!NISC|)tY)QaYT zGtZdvBk!J-rD|ZVCIFYn&=5`{(Z>9gnP0V4cMZ{-g7D{js71YI)GL7+MpF?4#e>B2 zEUh_8fl@%b}&@G-P~2W1p$lQ!dM1Kl3D6p-~i>jPRL(U>fx@ z0j7AQv)bCWJJ5S~5*6~fnxNg!PDwO zt?VQNY8mN;0(`|3-ubHc*?ggVdJ_IU(`eh2vQ16BX&O_>G|Q)XWtI4>c?u;@+P6u& zzUyTFO4*HUiS1g)xx12h#g1p;)~V%qXu|?bZtj6M&yK)SFW&YX?e@z$rhJ8lO7It0 zKe4ds6_W)4T=i>h}5K((y^ub+PBcBXOgjJGEaQIApP zkM^?O(o^*KA?ZHqMHf4HbzCF;bdb!`QwKebQ`QN5%t}5=q@5;pAleIG_(DAIdC$Y- zs{|MQ1n=*cYoz?&_Ttn>4dhCpc;q_8I_BazWA!kjGp)@ zkRdQ*#(|##Dy$3{7*j~V4 z@gl&`(1W}$HhGwa+Kg7?Isa!ojFVu%$3KsD$8L~|ackqpj!hYiA%a}Zjp1AmepWdi z0iAX&z@&O*EXt2SnE|s#T{XQ42F4m?u)GmeR0TE!WSMt&+KILYnQsBO2053<;TvLI z%%%|AoP#IrKxEQ|=iT#sd}{EyjZi>pmWEN4$+Fm9O-#?qt)x|vqJ z3<1i-mUuUA*uMfVZ`+Q*Hm^-uFFq8(a?dQ@zWowBciU^wb2IOc6%pN=M_`)yAD?30 zl@58S;b8I8WSjZdZ-HCJui-k|W z@2I?w^-1~Uqdu8G145xFLg>NV#oc)I8=i&q{{1NQ1_@|%tjsLaqAZA?T0zOqgS=;2 zprHCHv{B|OPWZD`Y#;8y-|e{s?;E-h^CD@qv9sV|!2_%l|C9rr>t^Af8D+i-@NO9+ zFe}5EBrsDwvRxWrBaqRK+zA4t$et2P#Aw+$4n%im;A$?tXL)Qm+~*~Gop!F-6OJUZ zcCo!5%~jV5PtoIqtj4G>wDP%*X=I~Ybg3Sy_oYKe-5NfSaWOUWKTmQ6u2``GU;p~o z@!8LQ7XR`u|6=2z+E3tL|Mg$((qt~3Px6>NhT<@~_%-L#)KO{5SQ0GCw3*SDaSO6% zEw?!hs)jnuGr~&-+KizArMefuszY(eASw)dYBEeRA@$!h!g5i|urL|}AS6pyLtF~1 z-+EtRW$^i1b*aN78LA$?@?*+RMx92N&jlI;z!ZZia2j6&Hxw8HOnj~}egk3@AWh6Q zFvs@|U=TpqZz&NS!686F#UG~88c59I8-r)?K^arTKFKqvR0j{9wl0cxg;CY!U)oS{ zc9sTm1W%!tY>o;E=d-xf2- z->T)Us;vfe&)lAMrCy_9RXHl+vv?!0gt`Z=NxvBU5)##6)SM-J{-I~#u0k(%j7P8| zJr^z-GkLxghYce#e$|5jf|260N>$!jCmNQKaZ&v2Noq*M)kb8|7Ga$RG2j`8J5WZE zvM^h6A}H^T=2%67wsZ5q4Mp_c4oq$A#hpL)A(5zq$&;RY3c`y7RO&<4#uMhl=4NT= zE~5A~e95{KKvP{aKPG45o$B1m&Z>{6Y~LhDz6Ad)*(}3IwpI6&2Lb>Luf3Yg<0zRI zfRe!{uPfOMqVVGKC2z90e*D5K@T@a$!S_q^@E`FLu(*pL0WLdPe)~{AHqCS)F&v|z zci5R&Iu>;vI}fdF7&R>9+Ow#Brl2aQSC!~VV)zwPQ2!n58-|P`DXN-xPr1W3zyEql9Xuc z0JR|(^Um^!f0Fl_-(v^;>R?#Uj1zOi3EVWc5I?=+6x{stQ&7CG9TAG0f1--cdkMbU zBdEkW@WT)N5Z}D*!ze$n({@L%h;IV5TCBiyYQ-G7@0_+_w&-3Req4oDha(S87>KpJ zt6rJ^n8$@@z2&Re+VIvrVaVh~+&{YO;FqW9@jy0RhW5+j^})?cUUcc@COPF5aI&%1 zy*-ca@Rk~smh-Jyv&Qxm(53T2R<2xm;I}T#U@uFtJ;v!BUwR#Kkn*C!5>u(IY>0_W z*EqWMex;;aTZ|O5F10)vKiyLpUF1Jiw<#P8A;2Ofq}K>z6pQ9u9Nhng&t*9Ejtng0 z)u(xqlm_FM0WyyP4v~O@dc~G!c>{RW z4LS4em4}LHDSf?Fs}LNe(HEM<;kK@J4=Xu9Wgy zWp7^_6uRR@IB6_R{!|aD{{}A&OiA_`zofv@CAY%PI)D=GA)u(#sEi0M_D*%PysR&G z4XLp(c1-kO{Qh2er<6{vezb-5a0&-07nDbN!UWF6GvhJystQy4u=4P;A;&J^BlSIU zHFOSE5lENOop<5OAHB-*A=1FA$f8iaDBd8IB;O5ha${ns4au4x`2`Fiu%{iL1v(Q+ zwhsa%@zh7Ysm>J<`JwF&ln2Y3@}y6;v1&Gsuui@uO}adGwwa4%bdM%19!;>9ZZvNj zfrsWsVU|FvSVLl&8`btIc5R=7e3_loI03MRMME{Xi7(ssR1n%Y4p)|S)7QxYIdQ^q z11Mz)Vj68y^&{SC4=X*l9hwQoya^p7Onw!Z2ek!1J4M>VDH<_Q>>Ej-&+Ws%UwND5 z{fR<#FAp!OhoiloqQ?ud4N{-l&=xyka^%#_nzd3RO1~x&^U`EyQzQo;J{qLPEsxKi zyB-gKN0d(y4A_)b8a1&^#!lW3DikwhD-b_RJPp9i%9x6s#m6oC*5Xhs_b_!_F5IWhHerRJq zwj_J_yM_}AqCF2u#vmKztGxAG$ zv>`ObEnd25_!w4zP4_gcq`ifz;}f={aWTMlkci;}yN^L{AdPSBeI{1@W&{--7Ms>G zbJhW)DrnL!i#l&p8iQ*G8@UA5oVtimoOPu7$)@XdCJz^X%adhw>XK*1W8MfmI)r&u zx$V3*e%I1(4e>dqXKW}YuyY!oNdh=cd>7E6ESY!2;w_*utsTK>s3jxfH)Yo8CO8cc z#7@^Ium9lGALF*+D1P;aGqCc;H0J+m99<8V5Z&uQaIXj6at&RZm_LHLnveAt3K+<6 zxCqQBlj@vVyJB3GOuDfO$<2J$I|;-btb27F2-0#@Wac`NUQ&fGL!DF2!<8CFd@^Zy zIcCuU-ecLx6Un*N{r*vSQU$onI*r_cu3OybUYmrIb*oK51psXbO7f%OK>=~fl(q$M z212YC-d8;QPaamAD!_0qcL2$mEU`@mx8D0v#08#v!vvfx=WK#yVV!Djl1f3~=(Nev zVH7*Oi0vxd8DE|xI}W2kRAN=M@2;S26D7M;Lm}cod1;>wO*uy9=-7(P=){8XEbE#^C&>6UyrwrA ze6V;eJ^p5%EN|o=Q)vLLdRT>%N6Nt-iAtiOlJLFzFz3NCQkf_Xe;E_QJ%cge)SKwPmT>$@XscFGcR=x^UsFg_-B*mDI=DT zdOn-OT;i|Ic_Emr()c+V22@M?ZRx+fJ(?4w@=7jDHdJO_dY}AuvaWKOJihYY?_0h` z(n;(e_rV=z$A;`G&J7b}u-g!;!JVU$k{GCd)oCE;v7sN8L34G?=rUe0sZp+~$|X;k z^3FD(c4hl45$vlyD2>jI4)`XElsX!Ew$*=sbA2NHC$9bgQUr!pM=XyG-}2pxPH<;Z zzG;GtF6OZ}M4%BO7-amKs7#)ihf8IY_fVf|EUH7LuM9RkVRkXRc9z(-b3cCfUpKKy zm5>=7vco_P^r*wxMj4klsC`P#H58Rf!4ub>It6&+E)+T#e3)g+xR9Rbgg;qDc&Lo< zo~(JrbjF%5?8lwAZNS>!uES?;{v=WaZw6?^FU{{$epD~H61+nMen6LE>F?Xkc-N=3t?1B*}9P>iP80*Fjb)ptM1D{Hw~ebx`7Gald{w^DNY$+ zk?KQAN=V_9%eO5lmAGIg_u6v`Hch;H7 zFyl9ms=T1H1ZT+%+IJQRc1j5DOQPaufMiPD6FYHPq~g{AE%|LjtOADY7tG}0n=Qf@ zuc3o>-aCH|BlRJLH+IN~26wS*FM!I}kgGf2V8cySt3wSPl6I`A2|W z?(kdNws_(RP&zO*GzBjKSzDkUmq^=GxOxbl)k)IklOCsmCCA7t-(VP(K@y zSIr44cLvb5um|sa+1D(dCkE9!dI#kGFI|%Hr|9uRYR{}*IdLkizr(A~$;WKJW$M8) zbuJr@jALCDK1F|l0_<76|2ywQ7F3v0RJti{OVP=5V<4bGP0mZRiYzd{ANb81_MMl! zK~y-0+-Lmit=qXyRE`R%D6H4nyc%TB2wZH(UB0UZuGK+igr$t72o=7Wh8bywV;;?j z=$RV3rCV3tS_NV&dK6YbMfVS+*$Ah+3Mlcba@RL9j`KIX86O%v6`o}?i0n+Gm`>n< z8#dTmA`OGEFJ4cBy>VCBji|GLSKM%nJ)8IpMXnapmg*uFO}8uDgLUA zGCVRKQtr&Bd9|9Rbqv^q(D1Q_1kV`$%ygmnt6~HIH-GCADGYgMpjc&Mo}AJN%%g@g%`lt1FsS6f_{YoYUGFk%llZQ`w-dkk z?yb1*)-87H<#W$K?A9Qhn(L&wGE6tJzly*(jrtgYEZ?tc|EEZZk0`g2Re=n}t=|GS zN>BN1@>-yXzikLp9w&zzC1U0Ft>o3#Aq2P2)brvEeiKLxRW=r~&hQJNw(7c_N7p6~Hv3tyyfU`I$-dLwc zle_Z;_)B^G%SXSCOd^YCzWgk#yl4%|GmSU}Ld9=Yg8(1HtJ6{G3KIxwXJ)3uhgxc0 zj5^_Gy|-=4!kuF0$xh2>JJs&Bfrlo}$MAH7cr(RjL0d z`_`^_HA#c_lg)YcjLKODQ+gKLCj8K+Ps=>RIDnGd%-LibU_~viNn6ANnq@iQeJ6Ri7Jkg9*%3 zqX_g;Y0~ge!tk4~U29Q^TvV)8%|FrPYbsq&MU&~-gWb)Zb&|bVopHuKx_Pk-3^IRA zM|o2|ElpjGau{zKWwm_iv+>Nn%cEk?>}mafGxU=CMm!ddmp};r!tD_YDOz;Q0Qy$V z0lNpx4{dBs6G3T=X$*~DBED=0T6;VB3yx*i|TB1go^r;iqOA#m8QH4KMLvV!P zqQW{>d;}mm6HAkPZ2~G^ccgPR4DsVnADpOr(W}o#j&NM58}CHTPm#Vq+B|S)KE0B|Rco^VP=TG5!K)E}BPx!@N(X2u=wYGc>H(nr%Vj z(-QR=-q+H413OGFmnYb!ac@LtJZgY0k;$}xZj+CcNoP*OTQ%h85czb-m@}X9{4wtV zgqiJnKGo5)k_r&0oCE=`bRAR|$^RO=ggTPL&LOk-DbtMKT3@5w)cgIlL#Or+blUwV0v!M{nu2f?m$9(^>QnSMAn8ZRuXUi<9_qqx{~0-}Y-nW)yiO#w zv!bM&o-D8)3acKS z&Xtmq)om)NCJ0cly0@S)$3mABaZ4I9x=r9@Bm<)Fy7*l{s5yCA3fm00Cai|Ehlrw=iFl}}OZ80&l^-eQhLJE{h?;qClK5i3Sxx~efzSGrdN}gqKzMzs zjxW;7MRSA^3;?$ zJ!_^f-W%AImrL=|5M?rOCGzkvjoHl|NM=K5+nqtREsUDZI%8Tj@q@si)I$(IHfw1+ zTp{?QH1Z8vxM~1B!FE(z%d4^~CCQ}8n(9oy8_$gz^~h(MEG{5wGRJ#09Ur4|G{ZMH zz0*4lP*X2|qpXd(ayjSNuw0X#b^bBP>R?tUm6G3WE3G2?atQ7x7}qK(O{ASk*nAYl zE19l?4wCY$G%O!Vi+SO1O};m8iHGrZMFw)e{NpJDVgilz`DbkRx|juvLmf9~z>awFhx~|nqIK_$>W}|vS-y@7QN3sqdMzOU zRG*A)%k9Z$Yv-~Bj8vX2_edOFg(_Zn#y?x$pAgg#+oQS~qW2U%KFGkTKB*hbN;cG0 zlc*&q*c5d2GEB%>$%ln`+>(r+hU`A`na|jf`=9^(=k37LCaBSKU4Qp?e`kQ`_SQLu$SvH@~ekk;0SVv;2^hzP`&q)bAYlEz&)U)6$etW_aG! zVWbBpYFYyP){H}8EDomAP~i3XAAE142iFu9z= zR8XM-s`x|DDcA=Ls)%tnCuAOxbYFRI@~sK_MEc#zZ&5Rx!Zh!Rn(wHDdfrMbn_D~b zvQY)5SSQs6KyC8N@=!O{#tXh*2R$s`fp|&Hv|GzZ67VcVneRXql`w7KEPM0vN;Kvx zIl|;+CWlgp^`X^y+9a>S&qgm@wEE2DSboxCzQ%kiPtCNH(zWu=PI4U6mf&zh2 zSzw$pE)c^q8VFImB-_)-;%vmKFd7y#o|0(%#b4W9J4rC0GBQ8TJlhJx+R!6Ggvze= z-a0vbIxW!1wxYRaDjVxo%eTGpvYp|jENJ&`rDDt&A z1)b*R301jLwi>$n+~+=r4I4J#%rnnyJgJk0yT19&Z(8}Uz4lr=G57rQ&o^+SoueNK zt?65VQnko$b!BLV&y0(4y#8B?Mao9Cz%-4ThT{O~eZ8amjkrYot@5Z>?~3V^>H0Gn z7)@9<151*(#P$cGQq+NrI%>d-s?x7ZLS4}*F7@bS;FK3Ww`IoKn?;IGVBr8bbfGda zR-YrJo-W_D`3t(#3s)dhyi8Zhm*4eHsoR6;Y8W@&y%M#s7x~o-;D!%lgHy)yCYjQA z6Pz(GIy6%6YLmFGdkA;}%%AdM{9w}Tm1pt^lo9n5r7-u8L zb!w*9{I1OzhsMypISX&G0`ClskLpqv{0AGUQ8cqfIQ%g<=kz0T|1ctV@1g#2pwLaj+>~c6+a}Of8?vD%c_H|& zfdK&^ff#vGY`CaulkclKnnGZE->99BC6HK|-veiiAg3__TY2_S3deTWH{83ubTwx4 zW9HSPwm@NN7jzQ2E_pC@K3jR;KFgOj&#Yz$BGm>&&2ozm`l(?-6}`i_%wt7hTZ@EHm>YvDov(YuXbj# zt3DaG>doXtvZ(o01X8|u91l_6KlaA|QYjzbr21i5t+Rg=7yoNi?o;%5Ayt>ESvKl$ zQY&kGRX`cm#*Zfu$-vK2VHE@hT1fMl9(w2@JmVS9u;+0$?DNh$&j8XRr4Rk&-N>}= zL1PU|hLa3!^0ZzH2fw#|io|>itN&WRlhg~70ifZjBobCvcALsh#z?(Y#ihHt>dTZF zUP{!ABJW8d%P32^%FyX%OP(w)O<2@B2lCDTEZ#==Mvu}IGsDUKU4Od~oTT5?d`6~- zak}8!>qBsu%H2gHPIY|ajrZdI>o?W|lag8H--d!n)e>U6OK=t)HYdaKqlv7F)$+l3 zc+Yy;Du+nlMP~o>AE|kd)C7cfujRf`>%9ga4iDpz@^2wmwrq1hwB)sSIO}R%yLr0=!8qH6YQvkg2-8_i;ZSgenOtMap!fJxAz=Tb}X8Gj7Xdw;jHCMu! zT*&)CgKCoqH8+fM+m&f)8zk#w$z$OrEbWNWh?mG$#xDb-cW2{vw1nbR`IIYNHk_n( z+yu7`Io5EDz?RasFnWjgw9~N3kIF94PYUtx!_WJSeNRj#t(=y3f-HBcWP1d;^70h1 z%-vlC;t>Ob2V~v&bdbait4r}pKuq5iMs=llC4WxxnPm;dVz}jSTVV)`0KcjVO$X0DelfjuM^U^mwV|E^z(kF%5>cgFB zJN1_>xPw4aL+r|%zzlW9fp%xFkY|(w+dQ*bpA4(I(vc+LN)bQ%=Fc!QM&R@~CaE^@ zzRuF8=y5`70tc$i8tp-13t**6aoDBrhxJ4s!z6{Q$;UzV43Bg*hp0>;9Y%Ur zb9ttwrZ9j0e712Kd^YfCG>WvHgk2AFw3JIwQ8kn&Uu^m0ZRNuZV@o~`&y$5`nC3gW z?0X{*(ssP`OAXPUDNYMR#iZVF^Pa-!d-Ic*qLbId45SpAl$#8lzUy9tY$(KjQ%UMQ zx4={bT!<8(da(R#dNE{p)Jv9YT+7_4%BkQz@K5Iv8m4j%l@Z;Wu^oMxFxdZQHV?-6 zi``#DJiXtdmfPJuG6`4F3AccS=7Jb+7_h-JD^s%^OxyCOdy10jHv-vZD`<4J+&jQ~ zi&yV8-q-Kuv&L^i3EX?IIZ`sT6%!h4Er+7s6E-!sH;}w+! zl=vd=85pHp*u>Z7bA7TdUC|f<`_u5GYl!SkBlOS&4Y}lt#P9+GP8qo}>r=xgyaadF zKkyKK_PK-m_2ipCL-MD%oB3&}?*qi=&EYZSMxGysFNn(IB#}WHt{4r!oqZ)aZoF^x z&ah&i>R$I$uKL}2`4sQ|QFvGM;r)OAV}-DGRw`zo3D_!sr8C6$XxL{`1QuE)Nd6LR zXnu+f&x#Ze(=abzlV`2vst19qzZcG)P67^jE}1ccHFXr~dA1xXXK=df?}&=(tSBsv zz4oxt5R%TVa?LW20y{~93)QXWY&H3(PZnIj&Q4V)zYf#(y6`JyGo1vbq2%CGkK$PzBC*qk4~-trnUVjCHR3JAJ&*EC7%|Z@-va^1C(-wPPvL z8QbDQCDWD(VQ1HYLu4Pfr0P?F9_jTIJ#I+-GTYij?ThuTHr6ECH7Xmql-UUD6I|7V z9{Z$x%Tx31Z+{z~_{1mh=}&+9kn1BK`3Ua6|NaBO=Wx>dYT#19trMG@_YYTKqCYp} zW$%cwdQX=WUX#(r^_KV!JSQDcpuDtlt~H!l`UbVeYhn3aij;8+c<3z)eaQQy#&4C& zhG3MQe)BQ~XTM0zcpKksE{8~Y*KmlanQjv-HOb1r`!WpX-Ks14+O9za#P&``i1~Is62L3G*cF#O*jVO$o( zj91jigX*LXd>VNYU=)~Qws% zz3hXR)11?wH$k7J+sK#7+bE+x^-XW;)7pUQPiau*&BG)^si7~0X!4L@O!nlN5sww0 z;?;ANU;i|w&N!StH;N6T+|}2Hv(8$H{O}lg!W%P5xTX^IRY;)#4Q;wU9K$$e{0&(1 zYI-8=w@Bq`eisj!uJTX`_)wY?Majeb=~x8;C*`e?Z!cx=-u3J8t1tZl9sTWi+G*z? zuU*DjMyKYv$OGjg=wlnOm5$ht*XR^h_SPb286gUtgZzOvJ1axE|x^ucBO_K-)KTNUOrwKJw8xznllngGui49I8) za;2>e8Grc6pX0(8o{s(~0jx5t;W_2SWQJv+4mFRQ0Izu11d0MX3}c(E3J__pDwaDK z@#3u)e7v5|N0A=MoXST`R&V@x1eewIQ}no?`ut>e2sDJtOD3X~oZ2egOQqoT`r!6> zd4mm=mHc?25PKx@&K!QlVzIvnQnZXc91deUh`7Rl+tU)Cu)7? zkg)vFe@de@9m_wTG|FK{ss5$@VgDaSd}fABO0`)Ai>47zGmb`__PhBG6{nus5Qpy5 zNLIs?sUp8q`P+`O&{cHcw<&7avzWtOGq4Ad=*&Y|VT$sgeF6 zR|}a3)4uS3#nA+7&9dmTwN*&jHp5zcOqPFIvDKtYE-Fu2hStGp8URi|g+noPhG*MwOoD&(OZVA}vrX2fNPG@&^ZB;Oey<77;< zg$MI_;mc^ubvB%pgO}1ZnQD;o!mBCg1|}Lju^~}@YE_hZ%MO6x#wV%yP3h`7K#GH9 zv3VvksstX|M6cLc_u6><9-RKH zd~O>;5}=sJO2ep1fo(&)lHAx*dI1!@qaj5B7X!Z}rWu4E-~Gr>(cT-wlH(VmA|R%` zi4T-T`%YdcUF!g;0Ai_zy`($&-GDDITUn+uu`Z)a1}usHNxJ5mYw(I!yux&=bnLoy z>;A0%{{JHF&`xcdpU!3uP0C5_MLhmVHdx!vH_On9z1$S-vx3sky(eG-g3(= zh(sa=pfsOn$&w|FR1T8jS-pC-oe=+@|M{Qz!4H0b=RNOvjiZOsh0Vm7w3cS}NpFYCQjQ)EbY{I6NIG+h!Wgu+2|BlOa8v_)H30=QY{M z=?dEml+NqI4Exidz(6ZQSJcov1z!J|HI4qaCCS$eOG?NZDhVtAF8YLPI*0{>m3K}d9eKzwegCtLhp7S#PGK}%K>B-WnAPp^a zcGx@~E$J?H&}i=1k7}}h{+RKAyr}8)_C5RStE!X-=0EI?;$t8BH%tzTXGfrBnHqV} zC4*^0Q>s(lYnH+IK?qME;9}d*yfKq&-DVybs{URxZ0ozqBg^L0gkP<^iUiTIc>;HT z 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�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

ETpR4!&b0fQwNrA#<+^wsZD`elAneHSbvw0cS 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 Ki7GL}fd2ytIH9)y From 43b12929c9db31280058051b84d81aa59a222665 Mon Sep 17 00:00:00 2001 From: Matthew Bowles Date: Thu, 15 Mar 2018 12:17:39 +0000 Subject: [PATCH 241/364] resize images re #22102 --- .../images/{mslice_cut.png => mslice_acut.png} | Bin docs/source/release/v3.12.0/direct_inelastic.rst | 9 ++++++--- 2 files changed, 6 insertions(+), 3 deletions(-) rename docs/source/images/{mslice_cut.png => mslice_acut.png} (100%) diff --git a/docs/source/images/mslice_cut.png b/docs/source/images/mslice_acut.png similarity index 100% rename from docs/source/images/mslice_cut.png rename to docs/source/images/mslice_acut.png diff --git a/docs/source/release/v3.12.0/direct_inelastic.rst b/docs/source/release/v3.12.0/direct_inelastic.rst index 356f73468219..54fb3794e17d 100644 --- a/docs/source/release/v3.12.0/direct_inelastic.rst +++ b/docs/source/release/v3.12.0/direct_inelastic.rst @@ -13,14 +13,17 @@ New features .. figure:: ../../images/mslice_interface.png :class: screenshot :align: center - + :width: 500 px + .. figure:: ../../images/mslice_slice.png :class: screenshot :align: center - -.. figure:: ../../images/mslice_cut.png + :width: 500 px + +.. figure:: ../../images/mslice_acut.png :class: screenshot :align: center + :width: 500 px Similar to the slice viewer, MSlice plots slices and cuts from workspaces. It creates customisable publication quality figures. Cuts can be created interactively by dragging a rectangle across a slice, and information such as recoil lines and bragg peaks can be overplotted. From 024480a0b1cf736db44d43b1f01be61ea4dae27b Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Thu, 15 Mar 2018 12:24:54 +0000 Subject: [PATCH 242/364] Created deprecated section --- docs/source/release/v3.12.0/sans.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/sans.rst b/docs/source/release/v3.12.0/sans.rst index 4c109631c980..76b8f71d33d9 100644 --- a/docs/source/release/v3.12.0/sans.rst +++ b/docs/source/release/v3.12.0/sans.rst @@ -42,7 +42,6 @@ Improvements - Added more prominent instrument selection and process buttons to Isis Gui v2. - Added manage directories button to Isis Gui v2. - Added link to documentation at the bottom left of Isis Gui v2. -- As an advance warning we plan to remove the 1D Analysis tab from the old Gui for the next release. Bug fixes ######### @@ -54,5 +53,9 @@ Bug fixes - Fixed a bug in the old GUI where 2D reductions were being run in 1D if a new user file was specified in a batch file. - Fixed a bug in Isis Gui v2 whereby the sum runs script was not working for ZOOM. +Deprecation +########### +- As an advance warning we plan to remove the 1D Analysis tab from the old Gui for the next release. + :ref:`Release 3.12.0 ` From 1f33bd99dc17ab940dbfff0b42088d385f42f3e8 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 15 Mar 2018 12:41:19 +0000 Subject: [PATCH 243/364] Unwrapped zoom fix #21230 --- .../InstrumentView/UnwrappedDetector.h | 7 +++++-- qt/widgets/instrumentview/src/RotationSurface.cpp | 13 +++++++++---- qt/widgets/instrumentview/src/UnwrappedDetector.cpp | 7 ++++++- qt/widgets/instrumentview/src/UnwrappedSurface.cpp | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h index d2c14e63edba..71e1ad31f862 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h @@ -4,8 +4,9 @@ #include "MantidGeometry/IDTypes.h" #include "MantidKernel/Quat.h" #include "MantidKernel/V3D.h" -#include #include "MantidQtWidgets/InstrumentView/GLColor.h" +#include +#include namespace Mantid { namespace Geometry { @@ -31,6 +32,7 @@ class UnwrappedDetector { UnwrappedDetector(GLColor color, size_t detIndex); UnwrappedDetector(const UnwrappedDetector &other); UnwrappedDetector &operator=(const UnwrappedDetector &other); + bool empty() const; GLColor color; ///< red, green, blue colour components (0 - 255) double u; ///< horizontal "unwrapped" coordinate double v; ///< vertical "unwrapped" coordinate @@ -38,7 +40,8 @@ class UnwrappedDetector { double height; ///< detector height in units of v double uscale; ///< scaling factor in u direction double vscale; ///< scaling factor in v direction - size_t detIndex; ///< Detector Index in ComponentInfo/DetectorInfo. + size_t detIndex = std::numeric_limits::max(); ///< Detector Index in + ///< ComponentInfo/DetectorInfo. }; } // namespace MantidWidgets } // namespace MantidQt diff --git a/qt/widgets/instrumentview/src/RotationSurface.cpp b/qt/widgets/instrumentview/src/RotationSurface.cpp index 28d652a7f1e5..a9288fabceb2 100644 --- a/qt/widgets/instrumentview/src/RotationSurface.cpp +++ b/qt/widgets/instrumentview/src/RotationSurface.cpp @@ -74,6 +74,7 @@ void RotationSurface::init() { m_u_max = DBL_MAX; const auto &detectorInfo = m_instrActor->detectorInfo(); + const auto &detIds = detectorInfo.detectorIDs(); // Set if one of the threads in the following loop // throws an exception bool exceptionThrown = false; @@ -86,7 +87,8 @@ void RotationSurface::init() { try { size_t i = size_t(ii); try { - if (detectorInfo.isMonitor(i)) { + if (detectorInfo.isMonitor(i) || + detIds[i] < 0) { m_unwrappedDetectors[i] = UnwrappedDetector(); } else { // A real detector. @@ -186,7 +188,8 @@ void RotationSurface::findUVBounds() { m_v_max = -DBL_MAX; for (size_t i = 0; i < m_unwrappedDetectors.size(); ++i) { const UnwrappedDetector &udet = m_unwrappedDetectors[i]; - if (!m_instrActor->componentInfo().hasValidShape(udet.detIndex)) + if (udet.empty() || + !m_instrActor->componentInfo().hasValidShape(udet.detIndex)) continue; if (udet.u < m_u_min) m_u_min = udet.u; @@ -217,7 +220,8 @@ void RotationSurface::findAndCorrectUGap() { } for (const auto &udet : m_unwrappedDetectors) { - if (!m_instrActor->componentInfo().hasValidShape(udet.detIndex)) + if (udet.empty() || + !m_instrActor->componentInfo().hasValidShape(udet.detIndex)) continue; double u = udet.u; int i = int((u - m_u_min) / bin_width); @@ -254,7 +258,8 @@ void RotationSurface::findAndCorrectUGap() { } for (auto &udet : m_unwrappedDetectors) { - if (!m_instrActor->componentInfo().hasValidShape(udet.detIndex)) + if (udet.empty() || + !m_instrActor->componentInfo().hasValidShape(udet.detIndex)) continue; double &u = udet.u; u = applyUCorrection(u); diff --git a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp index 44db7b3761ec..d3ad0c728158 100644 --- a/qt/widgets/instrumentview/src/UnwrappedDetector.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedDetector.cpp @@ -8,7 +8,7 @@ namespace MantidQt { namespace MantidWidgets { UnwrappedDetector::UnwrappedDetector() - : u(0), v(0), width(0), height(0), uscale(0), vscale(0), detIndex(0) { + : u(0), v(0), width(0), height(0), uscale(0), vscale(0) { color = GLColor(0, 0, 0); } @@ -36,5 +36,10 @@ operator=(const UnwrappedDetector &other) { detIndex = other.detIndex; return *this; } + +bool UnwrappedDetector::empty() const { + return detIndex == std::numeric_limits::max(); +} + } // namespace MantidWidgets } // namespace MantidQt \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 37d58eb8de85..4cef31e6c1be 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -140,7 +140,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { const auto &componentInfo = m_instrActor->componentInfo(); for (const auto &udet : m_unwrappedDetectors) { - if (!componentInfo.hasValidShape(udet.detIndex)) + if (udet.empty() || !componentInfo.hasValidShape(udet.detIndex)) continue; int iw = int(udet.width / dw); From fb0f7d36ada6ef8f972cb1f7358b24fdd4521919 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 15 Mar 2018 12:59:48 +0000 Subject: [PATCH 244/364] clang-format #21230 --- .../InstrumentView/UnwrappedDetector.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h index 71e1ad31f862..f5482189f25d 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/UnwrappedDetector.h @@ -33,13 +33,13 @@ class UnwrappedDetector { UnwrappedDetector(const UnwrappedDetector &other); UnwrappedDetector &operator=(const UnwrappedDetector &other); bool empty() const; - GLColor color; ///< red, green, blue colour components (0 - 255) - double u; ///< horizontal "unwrapped" coordinate - double v; ///< vertical "unwrapped" coordinate - double width; ///< detector width in units of u - double height; ///< detector height in units of v - double uscale; ///< scaling factor in u direction - double vscale; ///< scaling factor in v direction + GLColor color; ///< red, green, blue colour components (0 - 255) + double u; ///< horizontal "unwrapped" coordinate + double v; ///< vertical "unwrapped" coordinate + double width; ///< detector width in units of u + double height; ///< detector height in units of v + double uscale; ///< scaling factor in u direction + double vscale; ///< scaling factor in v direction size_t detIndex = std::numeric_limits::max(); ///< Detector Index in ///< ComponentInfo/DetectorInfo. }; From 30327a6e646b7f1e8b1c6c77654f49cff0e62331 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 13:19:50 +0000 Subject: [PATCH 245/364] Re #20991: Updated RROv2 doctest. --- docs/source/algorithms/ReflectometryReductionOne-v2.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/algorithms/ReflectometryReductionOne-v2.rst b/docs/source/algorithms/ReflectometryReductionOne-v2.rst index aa317703b266..4331a2e78b62 100644 --- a/docs/source/algorithms/ReflectometryReductionOne-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOne-v2.rst @@ -254,10 +254,10 @@ Output: .. testoutput:: ExReflRedOneTrans - 0.4592 + 0.4597 0.4654 - 0.7278 - 1.0305 + 0.7204 + 1.0509 .. categories:: From 287d9c68422c6e2b7d68c51c9c0156f6241bd85c Mon Sep 17 00:00:00 2001 From: Matthew Bowles Date: Thu, 15 Mar 2018 13:20:54 +0000 Subject: [PATCH 246/364] fix cut image re #22102 --- docs/source/release/v3.12.0/direct_inelastic.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/direct_inelastic.rst b/docs/source/release/v3.12.0/direct_inelastic.rst index 54fb3794e17d..c5f483b13b0b 100644 --- a/docs/source/release/v3.12.0/direct_inelastic.rst +++ b/docs/source/release/v3.12.0/direct_inelastic.rst @@ -21,11 +21,13 @@ New features :width: 500 px .. figure:: ../../images/mslice_acut.png + :class: screenshot :align: center :width: 500 px + - Similar to the slice viewer, MSlice plots slices and cuts from workspaces. It creates customisable publication quality figures. Cuts can be created interactively by dragging a rectangle across a slice, and information such as recoil lines and bragg peaks can be overplotted. +Similar to the slice viewer, MSlice plots slices and cuts from workspaces. It creates customisable publication quality figures. Cuts can be created interactively by dragging a rectangle across a slice, and information such as recoil lines and bragg peaks can be overplotted. - The algorithms :ref:`algm-SofQWCentre`, :ref:`algm-SofQWPolygon` and :ref:`algm-SofQWNormalisedPolygon`, which rebin an inelastic workspace (has a `DeltaE` axis) from spectrum numbers (angle) to `MomentumTransfer` may now rebin the energy (`DeltaE`) axis as well as the :math:`|Q|` (`MomentumTransfer`) axes. - :ref:`algm-SofQWNormalisedPolygon` now has uses a faster method for calculating the polygon intersections. From 2ec51f10012d20a678691c697a2b0d009fa4031a Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Thu, 15 Mar 2018 13:53:29 +0000 Subject: [PATCH 247/364] Moved Communication page. Re #22082 --- dev-docs/source/Communication.rst | 45 ++++++++++ dev-docs/source/DevelopmentTeam.rst | 116 +++++++++++++++++++++++++ dev-docs/source/images/ASavici.jpg | Bin 0 -> 4011 bytes dev-docs/source/images/ERantsiou.png | Bin 0 -> 28033 bytes dev-docs/source/images/GGuest.png | Bin 0 -> 16777 bytes dev-docs/source/images/JBilheaux.jpg | Bin 0 -> 7162 bytes dev-docs/source/images/JBorreguero.jpg | Bin 0 -> 3185 bytes dev-docs/source/images/LMoore.jpg | Bin 0 -> 5361 bytes dev-docs/source/images/MDoucet.jpg | Bin 0 -> 7639 bytes dev-docs/source/images/MGigg.jpg | Bin 0 -> 45526 bytes dev-docs/source/images/NDraper.jpg | Bin 0 -> 89010 bytes dev-docs/source/images/OArnold.jpg | Bin 0 -> 5204 bytes dev-docs/source/images/PPeterson.jpg | Bin 0 -> 6721 bytes dev-docs/source/images/RFerrazLeal.jpg | Bin 0 -> 5583 bytes dev-docs/source/images/RTolchenov.jpg | Bin 0 -> 6420 bytes dev-docs/source/images/VLynch.jpg | Bin 0 -> 3740 bytes dev-docs/source/images/WZhou.jpg | Bin 0 -> 3448 bytes dev-docs/source/index.rst | 5 ++ 18 files changed, 166 insertions(+) create mode 100644 dev-docs/source/Communication.rst create mode 100644 dev-docs/source/DevelopmentTeam.rst create mode 100644 dev-docs/source/images/ASavici.jpg create mode 100644 dev-docs/source/images/ERantsiou.png create mode 100644 dev-docs/source/images/GGuest.png create mode 100644 dev-docs/source/images/JBilheaux.jpg create mode 100644 dev-docs/source/images/JBorreguero.jpg create mode 100644 dev-docs/source/images/LMoore.jpg create mode 100644 dev-docs/source/images/MDoucet.jpg create mode 100644 dev-docs/source/images/MGigg.jpg create mode 100644 dev-docs/source/images/NDraper.jpg create mode 100644 dev-docs/source/images/OArnold.jpg create mode 100644 dev-docs/source/images/PPeterson.jpg create mode 100644 dev-docs/source/images/RFerrazLeal.jpg create mode 100644 dev-docs/source/images/RTolchenov.jpg create mode 100644 dev-docs/source/images/VLynch.jpg create mode 100644 dev-docs/source/images/WZhou.jpg diff --git a/dev-docs/source/Communication.rst b/dev-docs/source/Communication.rst new file mode 100644 index 000000000000..a3546c73e62c --- /dev/null +++ b/dev-docs/source/Communication.rst @@ -0,0 +1,45 @@ +.. _Communication: + +.. toctree:: + :hidden: + + DevelopmentTeam + +Communication +============== + +How to contact people in the development team +--------------------------------------------- + +* :ref:`Development Team ` Contact Details +* For one to one with local people - go and talk to them +* Developer email list (closed list for developers only) mantid-developers@mantidproject.org +* Voice and Video calls - Skype +* Telephone + +Support +------- + +* Email Mantid-help@mantidproject.org goes to a short list of developers, who create tickets and assign to others. +* `Forum `__ with discussions for general and technique help requests + +Meetings & other information +---------------------------- + +Text +^^^^ + +* Informal discussions, and daily status - `Slack `__ +* Weekly code progress - `Developer news `__ +* Set your picture on `Gravatar `__ to get it to appear in github/slack/etc + +Video conference +^^^^^^^^^^^^^^^^ + +* Mantid Review - Every fortnight update on significant changes & plans + +Face to Face +^^^^^^^^^^^^ + +* Annual Developer Workshop + diff --git a/dev-docs/source/DevelopmentTeam.rst b/dev-docs/source/DevelopmentTeam.rst new file mode 100644 index 000000000000..95bd49217518 --- /dev/null +++ b/dev-docs/source/DevelopmentTeam.rst @@ -0,0 +1,116 @@ +.. _DevelopmentTeam: + +Development Team +================ + ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Name | Location | Areas of | Contact | +| | | Knowledge | details | ++============================+=============+================================================================+=========================================+ +| Nick Draper(PM) | RAL, UK | Project management, | | email: nick.draper@stfc.ac.uk | +| | | User Requirements, | | skype: nicholas_draper | +| .. image:: | | Architectural design, | | phone: +44(0)1235 567212 | +| images/NDraper.jpg | | Geometry design, | | +| :width: 100px | | dispute resolution | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Peter Peterson | ORNL, US | | | email: petersonpf@ornl.gov | +| | | | | skype: peterfpeterson | +| .. image:: | | | | +| images/PPeterson.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Mathieu Doucet | ORNL, US | Small angle | | email: doucetm@ornl.gov | +| | | neutron | | skype: mathieu.doucet | +| .. image:: | | scattering | | +| images/MDoucet.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Martyn Gigg | RAL, UK | | | email: martyn.gigg@stfc.ac.uk | +| | | | | phone: +44(0)1235 445228 | +| .. image:: | | | | +| images/MGigg.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Roman Tolchenov | RAL, UK | Curve fitting and optimisation, MantidPlot user interface | | email: roman.tolchenov@stfc.ac.uk | +| | | | | phone: +44(0)1235 445852 | +| .. image:: | | | | +| images/RTolchenov.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Anders | RAL, UK | Instrument and Parameter definitions, Curve fitting and | | email: anders.markvardsen@stfc.ac.uk | +| Markvardsen | | optimisation, Muon data reduction and user interface | | skype: thomas_heldig | +| | | | | phone: +44(0)1235 445137 | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Karl Palmen | RAL, UK | | | email: karl.palmen@stfc.ac.uk | +| | | | | slack: karl_palmen | +| | | | | phone: +44(0)1235 445794 | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Owen Arnold | RAL, UK | Project Manager for ESS In-Kind team at ISIS. Live Data | | email: owen.arnold@stfc.ac.uk | +| | | Reduction, Visualisation and Instrument Control | | skype: owen_arnold | +| .. image:: | | | | phone: +44(0)1235 565253 | +| images/OArnold.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Michael Hart | RAL, UK | ESS In-Kind team at ISIS. Live Data Reduction, Visualisation | | email: michael.hart@stfc.ac.uk | +| | | and Instrument Control | | phone: +44(0)1235 445253 | +| | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Lamar Moore | RAL, UK | ESS In-Kind team at ISIS. Live Data Reduction, Visualisation | | email: lamar.moore@stfc.ac.uk | +| | | and Instrument Control | | skype: lamar.mantid | +| .. image:: | | | | phone: +44(0)1235 565253 | +| images/LMoore.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Jean Bilheaux | ORNL, US | | | email: bilheuxjm@ornl.gov | +| | | | | skype: jeanbilheux | +| .. image:: | | | | phone: +1 865-241-6969 | +| images/JBilheaux.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Andrei Savici | ORNL, US | Triple Axis, Inelastic Resolution and Fitting, Single Crystal | | email: saviciat@ornl.gov | +| | | Diffraction and Inelastic | | skype: a_savici | +| .. image:: | | | | phone: +1 917-543-5535 | +| images/ASavici.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Jose Borreguero | ORNL, US | Quasielastic model fitting, MD simulations | | email: borreguerojm@ornl.gov | +| | | | | skype: jmborr | +| .. image:: | | | | phone: +1 678 793 6463 | +| images/JBorreguero.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Vickie Lynch | ORNL, US | | | email: lynchve@ornl.gov | +| | | | | skype: ornlmantid_vickie | +| .. image:: | | | | phone: +1 865-574-0623 | +| images/VLynch.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Wenduo Zhou | ORNL, US | | | email: zhouw@ornl.gov | +| | | | | skype: wenduozhou | +| .. image:: | | | | +| images/WZhou.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Ricardo Ferraz Leal | ORNL, US | Data reduction for HFIR SANS (BioSANS and GPSANS) | | email: ferrazlealrm@ornl.gov | +| | | | | skype: ricferrazleal | +| .. image:: | | | | +| images/RFerrazLeal.jpg | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Ross Whitfield | ORNL, US | | email: whitfieldre@ornl.gov | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Emmanouela Rantsiou | PSI, CH | | | email: emmanouela.rantsiou@psi.ch | +| | | | | skype: emmarant | +| .. image:: | | | | phone: +41 56310 4631 | +| images/ERantsiou.png | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Gagik Vardanyan | ILL, FR | | | email: vardanyan@ill.fr | +| | | | | skype: vardanyan_ILL | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ +| Gemma Guest | RAL, UK | Large scale structures at ISIS (reflectometry and small angle | | email: gemma.guest@stfc.ac.uk | +| | | neutron scattering) | | skype: live:gemmabguest | +| .. image:: | | | | phone: +44(0)1235 394011 | +| images/GGuest.png | | | | +| :width: 100px | | | | ++----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ diff --git a/dev-docs/source/images/ASavici.jpg b/dev-docs/source/images/ASavici.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4f52c7a4ad9ef82c313d1c2eed0dc14486318146 GIT binary patch literal 4011 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/ERantsiou.png b/dev-docs/source/images/ERantsiou.png new file mode 100644 index 0000000000000000000000000000000000000000..e819a02203f5a3646b979b66aefc90eb24f60685 GIT binary patch literal 28033 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/JBilheaux.jpg b/dev-docs/source/images/JBilheaux.jpg new file mode 100644 index 0000000000000000000000000000000000000000..97854cc92f4e2ca4d24e845a28174438a4e65cf5 GIT binary patch literal 7162 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 vfkc)rrywIXRDvPcD(bRtc3H_i) literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/LMoore.jpg b/dev-docs/source/images/LMoore.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3734e6f2d1c09eecce2041b534303e5ed696f145 GIT binary patch literal 5361 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/MDoucet.jpg b/dev-docs/source/images/MDoucet.jpg new file mode 100644 index 0000000000000000000000000000000000000000..58057ed6ec3288ba80ee138d773d10bccc89e888 GIT binary patch literal 7639 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

N zFlXkHJeHNJU~xvu>aO{XK`nOwZ}xZFKi|nJZVum4blSIgpOkc2X07=(35ZZUTj)F* zeiH5+&q}nITNgl{9V7~fTJ?&Zob05;H`QM@S2#EMA}x;jG5Fq$2^qLb(A%d(!{?b( z+;ee#!N(EG+z+K6TuIdb4>SsN+)p5v-%Z}&M!dW_J#+hne0f@atK2J`_CQ~SnY1BQfKd~y>yW{j`XYR?60J;g~9C!3c zEp{T%N;87_y?Q0Nhdj%>a+mVs+LPbBG|zXE064+lf6r!kU4-eRO;#@?;6&TYH7Qk( zZ-+e9Rj;|mFUlr0-g&vjM|IP;UlRT%u{GwCMSaSfl^fWC2Opo+M}~ZIzKeT9xV#&@ z>Aiy*w)bFm9Ph{Z7sKxn#h&Zr-Q9|L-KwYap~zFOHRk-VNqjVOr7{=cHVJ^XR}pe- z`In0Lha1XsdEZ}nrqYx2$^%B8Sul5;APBo1?l=%_8bq1n;jta>@?+&8>O)9Ze1?pE zaZW?7G5So8VA*L?de>GOi6E5N$M3DieyhP4H*m)}uHr)m6%DX&*~3pe*IfFX)!Cy| z)^1Z`;|JZ$_vZyy{FYN<`0NvKK?vkZbJ2?}51Cxq#O!o=t6^#`Dki7Kol<3duiH5L zb?EyZXX(oyt0kKL){nQE6P6kdvVO$7&ON+CRAH(RE%V}g+f>ur;Yx=nj*(SN=}YsG z>wUQ*EQt3zcp?@OPQSQakk=CsAbTTSuqTn|Q%`h$)>OEAeoJJ!DDvFajWo_)3|HRF z%fz*0ckFzNm<$!mB=_$7<8L)6-%ev6XLf0Cx+e_VKa|6~dls`$R9Zj19(H|*IlrE% zyQmbi`U2g-(_kQUJ<#Z5l=toRJ}w4nsvn*d6NRY^G3W9hFf!kTf*ae=`B`;}ZdUln zvgGhC9G`a3jKD^BD%oGb-Yw5X9gi-!Mq?W=Vvj#UN=^Z;ueFe SQG@B8h+SSrhp*wJv3~>S{UWFU literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/MGigg.jpg b/dev-docs/source/images/MGigg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..28274291b3ca109fd1820cd3700816c6014c41a1 GIT binary patch literal 45526 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 GBmdbw*UWwZ literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/NDraper.jpg b/dev-docs/source/images/NDraper.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7b1fa3d88134cc1b4bb625cc0c47a9248182ea8c GIT binary patch literal 89010 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

B>HveYa6E`uF=5w-{O{|x@!}4=Audh8BXoP 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�xMRytic0__}<1=^=z$5Y;{x)CRuha|2ztk~{e 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 Mo|_0$vs}Xz zmsvGcX5FQKIdIf>@*}JJ8;+{eCTUlUZM>M-(lR6Uwh@gAUM=&M5Fc7YTtre;OcbH> zZrS|J`4C~Zq!}`EVtdeo+W7QEC{Lwqqs$>P{auXmpHK~PzPGOoJZf64`Q7}X_uE18 zzr(93^G^S0XG^RSWRtc>W~{A9$Zb!T>}bFzZ{d3^{?#kfh0?{}upKgGS2W;MLw`W) zJ&{=u62B(O-P%2Fd4n2czt? z_4vo$za8=prD%n6hN)>n5ARKD$mM0b&mB*58KEbNZ zJH=7nE$1Zc*&)l4*TsL-1DnHVCWX6tvV)?5mk<5Nb<4Px@tm4B&uKG#$@kBsO>Bzo z?FnheCIq;d+2`yh>53nYqcq0wUorEx!=`7MP9eXEx+xGef~K&_nbQIk?>7%E&i*{0 zNbKth_dDZd*?8i@Ig9AFtY9J)K%3un^#Xp0*ykgA*OJQ9qW!rx6Lqz=4S0DcY%i1Q z@lL%{Y2B(1Wt_8YaKEjLSYFK&>_s#2B^xAyB3OWA+hrqASw}dDg9jB`kb38-i(H@R z-~QZio*(0*#otzIHXr=A;C%XA>7l(aZ?u=@cF>-s zEmNDoI-~|1ErlrQlMlb;{7a`>KRk$yF-C2nc<`z+p zSnk{t=Wzrfw<1xU{nrK3dXxwLsF+n-hU#-}Ft!rS zf0XM|Ui_g9(@m$LP-Io8v< zl1FZ=HhldDdSbmKMCBT7v9=XvyO{V4#J0f+xkL_2I=%qY#*3AAENC<+-}5CKk>kpL zE}5rcCx5j`R$ml4`i&|eK@ zSmlk@ONO`TPiEt@4iDC(Y1#5Wkna!OpMZZ88{r3x?&Oog+VrLLd$~GV%FUG->D`(=ZyCm$MUXw;J1x$J}`JCycMckHNT9!CO^^MX2Z`Kk}!WPA5IMedT;YC{?gtK zxA88UrF?(zouq?P(I-!~ECc6@YYgOL_)bCgHOPM1e+e}2+5`4^i{eLy>>f+Y7?$qa zX&c0U^3i><{VUb2{7q@5%APH}wymo_H$fKHnpZ&mDwlX6GSjM zBlwpeopisj=f+Jt<43`5N8qoDfsXG-g{@g0Kv>(jAsarb+**-SCGA#kmXqNQv=;{KML}{6KU!DBmUc#n#^!Lmxp{;KF1;Opvu@{2Vk-s{S674 zD>Qqr?4RP~H`?#)&*RCrO=&cy)G<4T4jEMT?8EC_$Ao-SHO9TFdFz#j>iVNZxZ;2PS!jb zr2f#}6|`rDTS(;9pto#3!^0jwi4I5MRyBK_D)Qq@@oXBLXu6yu`zv0JL0R_?`1hY2 zbI>1eYGkCDR!Mw0rRvRXaGz-KPmdRJv0swL@swq8{2_?XY#+j^csEnD@cyTH`z(BC zkL`As5TEQFLg7hExEqlkPw_5r4`MOfCd^UjQ2nRj*NH6t$E9lXGDeu=Prc4~Zh=YV zNHqqx;JLmm_+np%o-4c--ZSvKiFAAR`C8^N_a#%@5C9}}KaERDM9C!V&ja|0rg)R~ zH~5DBAJwOO-v(=vlWi#lmLPlM2j(5eanEY_1O5sz`ww`t!k-eO{ii+&czS!U4Qi8P zUXI#4tV;OH5IU*J?bg3sd_QsF@7im?cfSVyGHJ_i;yo~!aKCnorr&!+sFI)jwt}cTH1eEV62z1G|@i%l`l^Y{PdX6UW!kXUcp- z`z2|f4A$(vI{Y@#nRVX=T*v*fY9qnE(_Mm)Jy`~F4>%u6+BIai7c69a1^Yez!a9$} z?}W?o55w9?{{V#J!52ByG^ZO) zLOeQ19Qxzbylvq&{gJL1 z_%7-3>)|%D`#pS8Lk78`e&J-C{`Ge7l5^dD>BnR5Qq_SwU5oKjD1HNcT+@Cycz)hF zd@tghTlk3==1-rbpbt^c=j&ZJjC>8EYEh?#8sNocc;frRTEu*tDf+7^>x0J~!LC=} z4g5YV@P@bhC;U?-FSNyYER3y|c$cFgKixPZ*wv4Mw>}`f(e*Fc)5eo|I`@Yi-$I&4 z!I~g`QO{M!et2(crLZj#k?~K%9w_*$pXdB{B(SwSPW zQQTC26K-Vqt>8Ti_PF>*ZyY`$@cOCNti$2Tt~|(J-Ff>v~Pm{01&LcEO=<2_*dRN+PcNL8A~gd7~EI*K{*G| z$j*2^g?Z~%v|S@l{hod{UwkaqPnqC9AH>q>249*e zXK{vz9)mgjike@B`UD;X@lL<{Abdh%`X;X&w_X>yow6AmoW`frb;n{4OwzukUh6|z z(?^rS-Xc!}Y1)`%oerts9ZAS5JY;4|Ha+_AJqY%o{{X@bg$5;zdmgYs7=% z7lHQN>35wMSF#`;8yH|za=nf-*0VLeR?AB92ABI;_!7hY0{i|Yo<7o*erS2aO3FFP zwgEWlgWol&C8o8i%O8fVZ;$*Y9uJG{z82KpOs=n|KPEhZ^ZcU(dgI=mXW~5q(5J+k zI~@2+#W}O_ewYS+!Fb;SgKmbM z;~PM5(_0^wLf+URv(vw7SFjd*5Aklp#9j{2Jb5%}X9l-8vDD$6L5VK$w8bbq1!Iwu zjAp9%kM>yjI+|X&E}!t$%Tm&2Ek3p3$kZ*(i{s~#0y>Ox0Q@R=dF_qEz^YH6X@PF)m`+E2@L-6N{Cb{s&p{)M^#G>lyPUN+_%xwuh+BYB{ zt$i!|S6<%g9t!xs;VVnYU&a3ttG2$xeS<?$l$YD|$JoUh~pbk zSy-?9^aqv482YbFcNJ#+WowfJ5v$1xWg}C>s(B;m-9hyg1-TOAVt}#`R!!Lq4+_}t z=xG{S#nAzoe5UKPfI#FC+w196Wr9coyqGKf;nyeE)F0BPTZpZ$Lix^FTL&M&pncQs zy>aP^xXB4Zs23RI4$OJTK8!khiU7(M{%&7z8`tl1mFy3{q4cGNp$hhrFwWt>>ray6 z8%x6!t%a3A3`YzM&iaH9DlT)bHOw+oJPrw8d(t}dk)Hy7H333G83s>R|6AzY10$d8ilJau*8liL*U z*n@k+*Ux{a;&_5wMCC3b&-%CYtp$ybZ`QdjA5fP?y0BTSdZRB_>b!Mke`)27H))(dR%Qh9P!Oa5rikG#SFVoE6yq4 zbC9&;3{K`8`cMQ#S2x)$d{R;P2U z{h_~Uli;0b{1o_G2if%ql_9#hShlUU;e|-Sz$f3Jtya>ZES{vdpH@SnrajEmzh1J5M4A|JBqXwWjncA)LYI6Ht) zHxbxZeSLAJ_@BXX{?VTY%$7GQhHXZ{{#fo+bLJzj0G_`v{3xQD38b|%biH@OUk`ju zqx^C3!c88F;~2tfwp`*lSn(hocsb)0KgTPJKZ4&BG_Q;ntben$wiY_&w5mvO#0xTU&24 zLGf%U4xw!8k1j`3wZi)K2kDy2({%k@#W%z2$_4s`KqTfF%H>Vg}8Yre@ z_Aq~G%{Ffk_(Q|r9y}x#3)>muGZs5fU%T(~0zQVYe{KH&hh7`_#rr+ld`-5pU$j`m z72TwyZDm&jBif28WK=y-rU)1yp1jdTPg@FK4a~oax@?{{@RphTQhYamv1?jN@6@3CqENg#5^9%x1Y3U!MP{8Z?gEq z!B-+{OQk>Z+B75`-3Vm_5$Y;^1H^D%*=gSutu){vyR>!HEXe>!pLTS|Lxv%T=|vR< z#cI(n!~Gjf@b8KBpV_m-jMsi0@g<~}o*mpb7^8J1qdnIgk)Ka`sqnYMx7xmo;vd;h z$JgyF`cLmPJLEja7;Vv=!=Y1;P6-rIRK6k_u;Z$0*ZLp)ELdd&#vc!*7M>yJ&?1%~`jmA12{k!%wQBGR~cSFBv?HuT* zK>e!z8%?s}2_ZL1#Gtr|xB-V=gsJ>JDqq?NthyhCziYpT(FpEsV~Sg(knQuJara2? zjFqB_V^3pW#`@isl-f7#1L4r=qIi-RW7jQ6!y_;OCIh)&x9HcsRngJV2&B8n&))-30APY7yX7JLKZ5802$cUkc_g5?tEnz}Z3 z$M>Oa-Hr$Z9>jW9R;3=P@zdY}c+oDt$>UFlcZFuUR={?M0!HD%+_*e%Yyzou8k*@f3?9}4U-#HbrEM%N+0OXHmHG9OG?}w$k(7rQRX{jfLej{40 zpW-_QPxW&+J0%Kwoa7u1+3%Vtt6G$XTljy(_I9_v0b9)YpW)<#QSkntTo1Kr@BaWS zS-X6{E)SsXn$nY4&|%l~zZXLQZwh=%hwPfQi>b^P+ei`x$9_S_*V2k9leqm)!}{g# zg|ECL4DtT}!ddX{VRxY4IsX7zYE4Pc>JnNWjp9!R_)o{47S(;WOaI`sbl z6KUG={?XHGw$MjyYvSJxCbOa{xNqO0FPj^V!PJhtWc8woO<5IU{kEkZqhk&3nU(V3 zH+H+a`31gsiS6$Php5@6}}$P+8IUN>&L zNgy%xAmvY}t9Hb(j@S~d<;c+y(SrW~tcd+MApR6lK*;r5b1ZRB2?Yq>03)FwasKNL zqtsPfge@A}!g&!1032?MAQANk^Au4)54Me#WMuDCttGmT?HX}kIRPu?4hX@@{vxn#EU)C6*G$r` zF{s*xpF??h5+MHoTWaU~o`lgwDDF&**d|-6IG;mOmiH?p`gAfLE#x2TZI7y+aC%o` z;SEu5^psq&+@a$vIof+4%8DqS#G3&-j8Mv>nkcM*L699n#0Ce5} z@)@A0{#ZlR2=-Wk&&gig^|^x+-)m_JDZU%8;4Yp{d^);Xe7cV`wD?}jONrd%^L}OP z?()))Pnqwo93A;Lpbk)g{@Pzp@z*H9e?1i?C76<$ikkZ0PIG~ln&tuxH8m|g?FG8O zc0RgDPj~U}*-AkL22;_|P}BSy^1pKA7J!KsZ~*MVAbx;?2?S;Wkvjm$IV9D; z^3F;BV;~AJB^5QzxeWUAfa=TV^1YiML_Vrurp z+|J&?(aG7x75?(oYad@f|FH0g$f)R;*!RgPscGpSGBR`X^1l`o79qb?R9030sHv^1 zZ)@*BcVfD_dxnNbM#sh{Cb4rk{QSb=((=kGaeHTXZ~uUFc=VSG1c3j8b?*OLE~axX zioZFa`O5{O@Hy{bCQ7Pn($vhV1~j(bEc`N|v{%%UzLd9K5RiRLV14#tkd968*4%aC zU$lS8{%2r_{}b8&1N;A6Sl}WUbe=pg695HfQ!LnireAL|4z?x(mQQ|U%QtJcSnLbX zkb$x%gVUNAAnOQZ7<2s<2vG!`UTolZbZhl#L3{a%;k05JL1nEt7_Hlm+05@B&oZYF z?FcC&1P6QoA(j}oAi!LixOo@9O9s})uM^wx*HLXD^qA)jeA(M-@9NF~Y8{T%0K-o( z2L^{aQKikFM;|*-gr{4~ClmvFZzVfSlF5L(<;vLpSi5S5haJBdoUXCJI3<6;re1{NOw+JxGH}@fU9f_6-{}|gh~)Ck`1Fwn;9is_1B3{4>uJ#q_%tcj4WFybXw*K(5st` z$^=HVf4f(jVt_qWx}I?5&~(ldbD=7``nR>;|Jl;E0*Y{xl)E{F!3$?tKG_o8aD zt`^h~L*~dp#OJ0A{*lec?DyU6GkzeXXBN>xTSdWrR^sKA3JD+Q|FqR!9H@xrg{O6^ z4$QJ$^v*Jk^4*ygj%vPsHZa5Z%FHgMgQ;=lS+!)zeUoUOT0X(y!F;bU&sEBNPUu7S3Y2zl9SGXtGWf9#LV%Am07JR z6qMNUWc~U?>}z=j$U(qVp)lpMBGOaA1|09iQ{4TP-TZmD!)r32z9nK?XDhtE(Mwvl z50pPmAOnt)vGt?X@zUngJ#mev?+KbDo-@N_Y-8B0b=WN!MM$ebsS3mw_Q1_jR%7%k zPETDzX<~?HgTwKnRBuw3ym;2tEtGxPgcoM|60v)Jemz4`)N1Ew^8J(ejx;QRbJS;$ipA@BS}&Pl5#939AZF^(8p>tyN(a zE6eF-y}jk2h5VC1l5L(d(M&QTaP7LW*;!AqSJA{BkJ8$w;a$)>jFFCZgJSAvR8@0a z>7+_}u~Pa$np1ER&hj=3RhLaW=)k>o^*3UtMbv-1-8>OP2BHs$hyGR(cFu(bdoCQo z_KZVyr`DZ0Y>QQN;oZ})k{nl~70Voi9o;k92xgtVe2 zBbA@^w$%sTc0}(6UBzOjC1tR8Ub)p6w@yEOd&ryGfm9fBUGdMv1VFS=8?>drtF{o+ zqP1}(hqP(hxR4gBdov$$o5jgM)KfChdhf)Dx(*M+%FUv3GOmSOwziOARO`9DR0bB9 zj?F0^vfd^J{lsD_VE7UNttEpoaSzfgOaXb)FxsTJj~K4{5IuCF^`eVwF?N#6jhB%x zo_BODnDI2Tijh)7yxo^!x=s5t^H%04n_-$UCx>uWHXPfSh_+^6Hy~Qo6n#Z87C)4S z{P92y)h{CzvdZ)s9P@-7jfl_hmSnhZ4Z9C$Fdx0yL?gQm2* zq!nJgJhtWqW{X-soZ+(Ls(?MPf63$Op*4rs8Ui00QxaIT*K@`5iB;gf0J>#l)LU~; zMr0{(aoeczwLC2!d_PvQ-P|-v+|z2?G<2lssUuzgHH-M<0S1|%wWVU{TQa~T{)*O& zlxX%Tx9Lg#c3Ek7{FiR*Pxd7XW?CDg#Lvi&IBgOaQ384)5H@U=*_!Y2@_3R(l$i9k z4#OZtQy8K<8ij+l=qR~Q3xrvWD7DSTIn-;t^qHW71WX*HF4E%J#Nlgu< z>$731PE<~jxnX(%B@~;!?lo_^;k}*SS>P#NOzh^f#!(d^mqAk4qe{d5jKERvUYQ8m zI+fNCLuLbTQfnqPts} zd;c>}*mgc@D9L@^CNEsjd&82&YE9|J)C$T$v1`4V9=lSi>K4!&(HUg#cvd~tnGB}s2>COfP3O(%3ERo!ZX&}=^%DCdvyn|u|za5}dghT(4% zD^8_y^gA&>i*TWUTz)FoIK*zBfEBKNjL^L2lZzL2!58H=>FE>72PlbJtRp!twQi9+ zPd>W1KbOIP6T%Xli(F>ZeXG)nkB$?BafM;{;YQl}3Agg=JL<>9m54Vd6QU}X?cB3; zhxNVfW8>b_Qwo>*krw3#r)#FeQ1)N}U#|`}pKQoKM7ggEeHlnJTOK7dVk~h%*8Lp= z>pv|xluGlhV63@UsL5JeFjGoU5llMm(2m(%T!1?_CuMIHzFUfAz2eRMVjbQyXsWDd zO*s2x%T(KxDQ^c(Pep_tj=w$eCG8M)W|!XVC9>a}@yc!+XcW2J;UR*%B|LTXn!5QV zF}-t(Y0W=|NL@`dG#%lmteN2X>2d9BQ*BOb&We%Pix26L(x_N$t4im#Xa ziDj2RT|?Ip{}oH*H7O>ioL5c=wE%IQJxMtK43ADM-iDJ!gF@M@MY~Q`b^vns!9rAoPCP*#5nY!2p6*03o)$ z)yB(53d@b2(Jvp~9WjW|5Lkdj`1d11Twu}DT*DtVa&VXLr(8xt`iM*QEVUv>2<30W zkMB%$eliWvJ{q61s@gAim5OS)6Y=H*I7{92S+6V=?@TSz5KKyo)aLg4?!Dv1Q@1Wg z9LJk>dSPegB2)eF))axpb*O>C)UC#kW)bKQcJ111O04}{op+T&twIQxGrHbm=aXCG zs468%;*qCB&3C{W<;MPMWlCqTIKqK7mbBvRFwUo1cIxNvil8O0d~sRJ+35 zP8ES8r=pH4UbtE6Mcu0WJW}pDCb3}H-L|0$_&Fe|RqJFc-;d8(uo}0`Cj)J(BpSCl zD2JtIW`K#AXBOih-TcEB-2U87JepemSfdeq_o&zj87O!)TQ1u=_V`#bWUcEof(#(8 z`<9s!olaO}=e~Bpu{9GVlI}6-iczTn3Pnm}z{i7?uyw+mgP*}9M$S~!oQS<;N5fqP zovnnLs{^FJDotDDG`!|YW9P9TW{P!X9Xbxj9Ve_C-`UHkuAV$Jea>Y<*!s*wdv*iI_=v#_SSly;z@K1hp2U>+P4-JeT|x3392GPzxj zw5;xS?wn|80ZbegzXt6KCER`eUb^86t9QCO4O`!jo=vqOF@=`^5;M;FBw}L3Q>Z#x z<};WwfNl;?G-)an0DK}sEEWp}&u*@=ndiqKCvx+{xs$?%IZwszZxl6UC29}Lt?AY3 zH|;fdS~VfZO^_~pBUK{|`Og+vx{?_D1IDNlstep$B)&MV(r+8y%1n=Y*(9o&@Y_&x zX)!KXEpse$(O$kGdCE80a?tU8@57M{y3%96@=skMCC{hjiMK0Det)#IS{12SiMkI; z;O2((l&x9as;&j)TBHcO7!G4=C0R(>9_q%3k)A8mH~pX0AN%UjU2(`F?x@{Dkz!ZD1S_-9@zui!%e(itlbda2~I_Q`y5F!cylHs`$1 zoqy`fya?GjqANJFk_l?gzG)37wQq=2oj}C52JM5g$tCpFnFu8&ZSZbld~7AyAiX=WvMnphA4@ubi8J2DnGcrWN+wB!lTMnzmP zv}V>+*7SYd(;@46kk;l6OnLliHa!}XC@WM&c2&q^74?OQ9&^UGx=G6LvG*Q-r?`w@2rf7eD&c zvqD>`%Ri6E7HhzLfDcX=<2xK<#po(L1f28zU&rB;VeJ*FMa%Gye*6%jsms&~HUtfS z;qwdWjN-Jk#5f?$fA@X={qTxJ$Tbbta4wd3*vlcW?5DJgM)XbUHaqceoO5IMY+1V! JOzX&#{{LWEwbiSw~+7fIuK500{s9C$pp% z^))r^jA2GP`d78V0059m+IxGu6Y&6mho>J3rmMkYdEJT!Isy;@YycI&4p7-U`g&h7 zHogib00>;d{h!dBH>>79%05xIYzS@6dNQ9HU))lZ{9Mrq)1lQ6Au^5O8oRK>E zAQl3@3nj{*75Z9Sn^?4CaTBc>8I<{>Bl$0oMpQfAqWB zUp59YJIH~#d0ioJm_a=kLtIQPeqxAwh>ND--?$&;4x|yZ_iPP#aMPa2;?5 z-~bZv1h1X|4*&yn0S(|h;0>SvFTfd$AVCHa>?OqEU@sEz1>F8E(;YDWHOd`i=mJaN zn57?Md;ouNG$Fq^pkW9^i2cgIBRM3wCOIJaOfpw;{q3k&vID>1TdNQ0*l!>JA{lUJvm5)06Kn{`o)EIeR`}{}tgO%mI%v-2KBP{EwN= z0}fz5f@^~N01&%_Pw*e}{pW1|)#`!VPILq7@3{s@YHa$bJJElt0k!|DtDh@PaP{ZP zJO07@bFJYdTqIH?`XmY@iU1FZI>|*6H4-iGNtxv8uMuY8S|NczP&W!xZx4F#1cJfn z@16d=w!qJ`2EH-iInsrD!cj;^9>V!IMtM0S-Qhn1KQI47_z&iP2MKlMXWYsk0E&G9 zfJOFq-*?!L8UkVN`Q7Jd0064%U_JQ!yH5x_4@}trP;H;plcO9^!#DuEbw8N_ZfOT0odLkW01yF3kprX<27nku z5Q2UPJ3#sa1Hfen$1es0=0)QCgk75k60kFOi8lf~1M*n>$dP?+*;q;XF7Y-xP zPR0ODfCvI1e2Bmg*oaAq35|?|gqRdc28BY&$jG4NR1{EhN^&wX3K|MZDk^GfYA6K_ zEe$m-2&o832xEzVj3uQaCnKl&Kev;&06jSn1~?Hz&H+U95Mp}BNgKcoIw1vrall59 zOK1=xViHnN5vT(sRGtFm6B84GVo6Cr$B-~E4v^53GMtsVM8;@h4?X8|TKe|GXXLyZ zW$&0^U$A^K4yXtUN@f;THg4+ScCD z+4cTIZ(skw;Lz~M=*;Zg*KhL+i%ZL!Ti>^LcK2}m2LxXbfcU4aU(Wu;7d_~U2;2h_ zD8UzmD3D;Bo`m$Q6dA)M6R5op<2mWu05vfL+&p4>Kpi-;O*j=Wot5!YrGfje%+tXLC~Lby7b|*T#1rm^ zLFe<=kYBQogq>U1@QIE80Hq8nRmUwI>f*wu1*4t&(LRdzm<+r6Bl$YH{aF+puQxJH zws$ZT?mN8dJ~Zh+*LPF;MqMuQy_nm=RH7aBntId;0Fh&Py~$N1kW-+A33UVbTzYaC zylK#phsNRWu2lAn(!TSfyXC#i?uZgcBuTz1@a^(fvVQg1t6mR$vJbx7@ zZe{LZjl0()n6~N=QCCVCOEme3psXd6B^+ zi*tIWerVA!h|Y7H{FYg)nYWqh6NC37YS(Hq<69GIUp`u} zDb14(eBa|v`9*Zyx8^Vx2`pr7!#YLczwSM6st1}!W)_1K5@)5w99i)$57so05$;c+ z#IZVP0re7eGk;yy>~KlZ3jN{%x>~-Md?xBjeR2yRZGh3ojGq9kauTB)v$=Cu>mOV< z;CnsX!Ex8)OH~H6o<2J~4-3{f)hWwIuyg4*7zmcS78Vcf)!Xr6S2wPJzv2O>DY3OJ!r09RaV6 zJL{`os;(?H6XVqSwBP7FIM;QDD|=|OR0?Zbo$nH0a(<^xO7CM*@$g*#fkh6^>CFvt8&qx#j+Vepcj^w5RHUGtdqK`ugp7+jeSdN4@NcDK8PS1ajX&ov% zkRZER#u#5THtr$1|0FQF8L7%R)8J&gSUvRFI@j4OX~GI+xz-kya5}AvSQXfLRe{#) z-3|_)5yl~Nm)TEipKEeKe=oPpUavdr@RV^eoN`Hx9nDde-2P=beK5r1D0Owk*O#f6 zY&ekYFh9m7eywZ!RsAugdf0UHY1?I%DXQ%n*(YjSlM@25%1%{!3#LH1&YeOcosgj( z%(7J@+d(mJe4d$h=M~jZwRFWqHcY=&(GokKdD@=OIPUgk*%5sPG8H_|Jv#-#o8V)6 zW6tPqCiITKYcia#ebf${n}%DecRok{28zQeVN(nwlIO+4*k^)l{k*OHrDMvLe3N4 z7QWfqn7({A7W>F0=y$XW|n^!P8&3IWpm5g64z{*L^V*sP+WdK^C@w#QL3df z!?l7gxivT{GT;AZ&5OjYOYdj*Zfu|zgmF`0qm%i&g0{1baMx!LRA zf=kmO=3MDdcy<`nPyY`#fvFuwkZ|P)}STt%)4=ADF7)XqExar{!L8<$%q@|@DON0T;It^dw(O?;~%XLR4;xC z^Ewo8t@Dahcc+op>2r(~Z9avRx#H#emjr39q>in#s-CopTTeh~yc!=aYm$!DrQ>+h z@6b9lS-Gdbwd{JFqY75ZVsHwp>lI^>&6wSm&5id!$~EH!=wIER#tC)>`RN&AKAR>H z+g!fBC6z)S?_)b?9hGYJ@X?4X=0^L-fEX>5k!At*W#1n$@vLiQYVxsNJf;!?hjYf$ zKJHEQ)DDA9E=;f0y2cr+e+b@K(Ka(T6XTrA6kU;&IROwc&t_&VHrR~20}_HeY(9q4u-RLhTfJgH^d0T!gJS)#FcVwjf#aKIr$=Q)D05O^yMQwAFD`>t(Mn%hB zyR)clSA{!usLj#d?9!I#ipPa@I9d(&67dqJCi+BaVeio;Wh1pYrV*S>XUP4Die_wr zCdbsoh4v)viPwP&>)vh)M(lY00knL`P&Qqr<)BT&CeMd#bbuUUrnK{XXbbESaxJGm zO<-w0_?k`_SR6Y|Tc#%C)O}i=QO{icne%)12D$jK)CQ_w95%vAc7)m@vI8JD9&6nkN#r`^DOBT~Te*?@q zGgYJ3Z7s-M-i6ke?`Y!ZvfOs3TAI$3VG%LKe%TbGm-3fF;B{73)*8f6HEVCi>#l4zBQCiuUEr`SFd#AGJY1#IWjWY{;Xw{>62;fdL&+&XOXAymMwdL}EBKWGXyy|tk%ZK%`Zar}x7xTH!j+citzQJO zl-XlYSA0J)-GGaZANyJKP5ZaD+Q!_wYu5l5cBbFqq4s|zGbh*?PL3!4!eWf8Ekz#i zH_SA3ziHm^jE#SIIy^)}T7jsE3b%OzkiHp`<9M_paSOx#x_33>s<*4v8`+`As!h-Q zkJlEd2{;p^m1#~w*CB5kK$IMGt$p@UBp;+5`Vi0twh7!KRjl7 z`U+E@g1sPds=o~LHS|3EV0gP{EPppXeYfiOgZ<=wAAyyQ`n8eNqX~gy_otapOcw}ti^CEE) z-z>rEzEeWcjNqmUIy${FD9rhu?K{8D@VjQ(ORrk>utiHl_Ynalbz;C9iLGDcz7~;CvA20o)pznCA}1RdccZWd9YsEH_b=5O{N|nt zBIK&B&rIx42n~_**;05KTZ}o!5r5P~@m+b(b2OJ}`}e?=s^X4rXu!nojRzcV#_tqcl9V&MG;Xn z^5XPz9nYcal)~Apk?zjv@0GWAORJh7$HP;!%}4_U18h!PRk}Q-k9fBKaa9==HC zY`UAkF_D? z%b(P-joFXImrQo8U1#y9$^<*1eW{oNttsB?;pmIZSEV}Hmupm^mYtdCPI5i`8xlp=MHWRTT z@z!p%x}}-Jzlf@;dG|}}?cNhEtiAc6-4|JQc8&$HqFlk{~;@?sjP5hZE z+iYzY`+gTBRuCh0Hx(d9j$BWntucPwJpcDyGc8ZwZW=41P8P&$_e0Q$Z z4)f7})L7Ko4~K|{$2L;!W*(KQ$Q&vzN!~X%S~Gxc@$xZW=sSB>YU@33a^e516z-VK>yrgXHR4pH$WQU~DUb!OI zY>{fO@csmoE^3ZxJYD=AyJlK$?Sm%16F?_a9(Lu5r_2sacdK19-*szvQq#wEjq|mn zORk2wUQeOIe#&8li25m4@5vF%yxi9x9CT^Qsy#j;puOd7!+Z#AiNomdT$_e;vhFbW zm$Z4hG@QBV4DP}ik@XY6aFey#fwyj8`ui(0Ng%#%&YN|*%19+y8y$LPA?+`B;tlOk zKc9g)^1KUZbHSMM!c@5Mm-}O@dil4kYjVA5br(!n)L_2-CJPL>9l7a=Y}W^S+O{0G zL!u#XPXN*{%H&VjV!MF}&nG8Tk(mia@Ub literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/RFerrazLeal.jpg b/dev-docs/source/images/RFerrazLeal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b6e8097a1b3e6fc0a93dc89971772d567ed43877 GIT binary patch literal 5583 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 X+Sx+C4d+T7)w5Qkhwv+mUj6zn)g`sC literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/RTolchenov.jpg b/dev-docs/source/images/RTolchenov.jpg new file mode 100644 index 0000000000000000000000000000000000000000..85259769e2b07d0120b40268ac6ea6dfc7950173 GIT binary patch literal 6420 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/WZhou.jpg b/dev-docs/source/images/WZhou.jpg new file mode 100644 index 0000000000000000000000000000000000000000..98f98d99f0008f1d78b7df60db4b09cea2844687 GIT binary patch literal 3448 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst index ebf236f4ac0c..35ed5727e427 100644 --- a/dev-docs/source/index.rst +++ b/dev-docs/source/index.rst @@ -25,6 +25,11 @@ Guides :doc:`GettingStarted` Describes the process of obtaining and building the mantid code base +.. toctree:: + :maxdepth: 1 + + Communication + =================== Component Overviews =================== From 487619ee3e03fcd3a11556a062da1ae0caacaef4 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Thu, 15 Mar 2018 14:05:41 +0000 Subject: [PATCH 248/364] Added Dependencies.rst. Re #22082 --- dev-docs/source/Dependencies.rst | 41 ++++++++++++++++++++++++++++++++ dev-docs/source/index.rst | 1 + 2 files changed, 42 insertions(+) create mode 100644 dev-docs/source/Dependencies.rst diff --git a/dev-docs/source/Dependencies.rst b/dev-docs/source/Dependencies.rst new file mode 100644 index 000000000000..d66367cb665d --- /dev/null +++ b/dev-docs/source/Dependencies.rst @@ -0,0 +1,41 @@ +============ +Dependencies +============ + +The large external libraries that we use in Mantid (boost, Poco & Qt) +have overlapping functionality in certain areas. In this situation we +want to be consistent in only using one\ :sup:`\*` library for a +particular piece of functionality. The table below sets out what we use +in various areas. + ++-------------------------+-------+-------+----+-------------+ +| Functionality | Boost | Poco | Qt | Other | ++=========================+=======+=======+====+=============+ +| File / directories | | **X** | | | ++-------------------------+-------+-------+----+-------------+ +| Notifications / signals | | **X** | | | ++-------------------------+-------+-------+----+-------------+ +| Threads / threadpools | | **X** | X | | ++-------------------------+-------+-------+----+-------------+ +| Regular expressions | **X** | | | | ++-------------------------+-------+-------+----+-------------+ +| DateTime | **X** | | | | ++-------------------------+-------+-------+----+-------------+ +| Setting & Properties | | **X** | X | | ++-------------------------+-------+-------+----+-------------+ +| Logging | | **X** | | | ++-------------------------+-------+-------+----+-------------+ +| XML | | X | ?X | | ++-------------------------+-------+-------+----+-------------+ +| Triangulation | | | | OpenCascade | ++-------------------------+-------+-------+----+-------------+ +| Python | X | | | SIP | ++-------------------------+-------+-------+----+-------------+ + +:sup:`\*` In some (rare) cases we may want to use Qt for something up at +the graphical layer, and something different in the framework where Qt +is not available. + +Also noteworthy is the `Compiler +Support `__ for +various "advanced" language features. diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst index 35ed5727e427..5e88a61b2272 100644 --- a/dev-docs/source/index.rst +++ b/dev-docs/source/index.rst @@ -29,6 +29,7 @@ Guides :maxdepth: 1 Communication + Dependencies =================== Component Overviews From a79528747cf45529626c092021e68380a1de432b Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Thu, 15 Mar 2018 14:14:51 +0000 Subject: [PATCH 249/364] Added HandlingXML page. Re #22082 --- dev-docs/source/HandlingXML.rst | 85 +++++++++++++++++++++++++++++++++ dev-docs/source/index.rst | 1 + 2 files changed, 86 insertions(+) create mode 100644 dev-docs/source/HandlingXML.rst diff --git a/dev-docs/source/HandlingXML.rst b/dev-docs/source/HandlingXML.rst new file mode 100644 index 000000000000..9c58094c93d1 --- /dev/null +++ b/dev-docs/source/HandlingXML.rst @@ -0,0 +1,85 @@ +Handling XML +============ + +This page provides an introduction into reading/writing XML effectively +within Mantid. In Mantid, we use Poco to handling XML serialisation. A +useful introductory presentation can be found `here. `__ + +**This page is a work in progress.** + +Examples +-------- + +Parsing +~~~~~~~ + +.. code:: cpp + + + #include + #include + #include + + Poco::XML::DOMParser pParser; + Poco::AutoPtr pDoc; + try { + pDoc = pParser.parseString(cuboidStr); + } catch (...) { + // Handle the failure as appropriate + } + // Get pointer to root element + Poco::XML::Element *pRootElem = pDoc->documentElement(); + +Iterating over an element's children +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: cpp + + Poco::XML::Element *pRootElem = pDoc->documentElement(); + //Iterate over every child node (non-recursively) + for (Node *pNode = pRootElem->firstChild(); pNode != 0; pNode = pNode->nextSibling()) { + auto pElem = dynamic_cast(pNode); + if(pElem) { + //We can now do something with this element safely + } + } + +Inspecting an element +~~~~~~~~~~~~~~~~~~~~~ + +.. code:: cpp + + Poco::XML::Element *pElem; + + //Reasonably quick operations + const std::string tag = pElem->tagName(); //for bar the tag is 'foo' + const std::string value = pElem->innerText(); //for the above example: 'bar' + Poco::XML::Node *pNext = pElem->nextSibling(); + Poco::XML::Node *pPrev = pElem->previousSibling(); + Poco::XML::Node *pChild = pElem->firstChild(); //avoid lastChild, it's expensive + +Avoid NodeList +-------------- + +There are numerous functions that return a ``Poco::XML::NodeList``. You +should avoid using them and the list they return as best you can. + +NodeList is a very inefficient container. Its ``item`` method has a cost +equivalent to the value of ``i`` given to it, and its ``length`` method +a cost of ``n``, where ``n`` is the number of nodes in the list. + +This means that running the following is horrendously slow: + +.. code:: cpp + + // NEVER DO THIS + Poco::AutoPtr pElems = pElem->getElementsByTagName("foo"); + for(int i = 0; i < pElems->length(); ++i) { // length costs N, and is called N times (N² cost) + Poco::XML::Node* pNode = pElems->item(i); // item costs at least i and is called N times, with i from 0 -> N-1 (N² + N cost) + } + // NEVER DO THIS + +Even if the compiler is smart enough to optimise ``pElems->length()`` to +a single call, we still have N² + N performance at best. Instead, we +should **always** use the iteration example given earlier, as that runs +in N time, instead of N². diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst index 5e88a61b2272..dae7838b6abb 100644 --- a/dev-docs/source/index.rst +++ b/dev-docs/source/index.rst @@ -30,6 +30,7 @@ Guides Communication Dependencies + HandlingXML =================== Component Overviews From f9b677ca72a2da9373a3c169ac3c871ab7b83d68 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 14:14:59 +0000 Subject: [PATCH 250/364] Re #22048: Applied manual fixes. These fixes were not applied by clang-tidy because they are either inside a macro, not included by any source files or conditionally compiled on a condition which is false on my OS. They were found using grep -rnI '^[^/#*]*typedef' Framework/ --- Framework/API/inc/MantidAPI/ICatalogInfoService.h | 5 ++--- Framework/API/inc/MantidAPI/SingleValueParameter.h | 2 +- Framework/API/inc/MantidAPI/SingleValueParameterParser.h | 4 ++-- Framework/API/inc/MantidAPI/VectorParameter.h | 2 +- Framework/DataObjects/test/WorkspaceIteratorTest.h | 8 ++++---- Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h | 8 ++++---- Framework/Kernel/src/NetworkProxyOSX.cpp | 2 +- .../inc/MantidMDAlgorithms/Vector3DParameter.h | 2 +- .../kernel/Converters/CArrayToNDArray.h | 2 +- .../mantid/api/src/Exports/ProductFunction.cpp | 9 +++++---- .../inc/MantidTestHelpers/MDEventsTestHelper.h | 2 +- 11 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Framework/API/inc/MantidAPI/ICatalogInfoService.h b/Framework/API/inc/MantidAPI/ICatalogInfoService.h index dea2b3bdbe46..fef462a41a2d 100644 --- a/Framework/API/inc/MantidAPI/ICatalogInfoService.h +++ b/Framework/API/inc/MantidAPI/ICatalogInfoService.h @@ -52,9 +52,8 @@ class DLLExport ICatalogInfoService { virtual ITableWorkspace_sptr getPublishInvestigations() = 0; }; -typedef boost::shared_ptr ICatalogInfoService_sptr; -typedef boost::shared_ptr - ICatalogInfoService_const_sptr; +using ICatalogInfoService_sptr = boost::shared_ptr; +using ICatalogInfoService_const_sptr = boost::shared_ptr; } } diff --git a/Framework/API/inc/MantidAPI/SingleValueParameter.h b/Framework/API/inc/MantidAPI/SingleValueParameter.h index b7a024450eb8..6f671927cf76 100644 --- a/Framework/API/inc/MantidAPI/SingleValueParameter.h +++ b/Framework/API/inc/MantidAPI/SingleValueParameter.h @@ -159,7 +159,7 @@ std::string SingleValueParameter::toXMLString() const { class classname \ : public Mantid::API::SingleValueParameter { \ public: \ - typedef Mantid::API::SingleValueParameter SuperType; \ + using SuperType = Mantid::API::SingleValueParameter \ static std::string parameterName() { return #classname; } \ classname(type_ value) : SuperType(value) {} \ classname() : SuperType() {} \ diff --git a/Framework/API/inc/MantidAPI/SingleValueParameterParser.h b/Framework/API/inc/MantidAPI/SingleValueParameterParser.h index 78f562d22488..a0ec788a261d 100644 --- a/Framework/API/inc/MantidAPI/SingleValueParameterParser.h +++ b/Framework/API/inc/MantidAPI/SingleValueParameterParser.h @@ -79,7 +79,7 @@ template Mantid::API::ImplicitFunctionParameter * SingleValueParameterParser::createParameter( Poco::XML::Element *parameterElement) { - typedef typename SingleValueParameterType::ValueType ValType; + using ValType = typename SingleValueParameterType::ValueType; std::string typeName = parameterElement->getChildElement("Type")->innerText(); if (SingleValueParameterType::parameterName() != typeName) { return m_successor->createParameter(parameterElement); @@ -101,7 +101,7 @@ template SingleValueParameterType * SingleValueParameterParser::createWithoutDelegation( Poco::XML::Element *parameterElement) { - typedef typename SingleValueParameterType::ValueType ValType; + using ValType = typename SingleValueParameterType::ValueType; std::string typeName = parameterElement->getChildElement("Type")->innerText(); if (SingleValueParameterType::parameterName() != typeName) { throw std::runtime_error("The attempted ::createWithoutDelegation failed. " diff --git a/Framework/API/inc/MantidAPI/VectorParameter.h b/Framework/API/inc/MantidAPI/VectorParameter.h index df8419c2fa91..efc256f68eee 100644 --- a/Framework/API/inc/MantidAPI/VectorParameter.h +++ b/Framework/API/inc/MantidAPI/VectorParameter.h @@ -245,7 +245,7 @@ ElemType &VectorParameter::at(size_t index) { #define DECLARE_VECTOR_PARAMETER(classname, type_) \ class classname : public Mantid::API::VectorParameter { \ public: \ - typedef Mantid::API::VectorParameter SuperType; \ + using SuperType = Mantid::API::VectorParameter; \ static std::string parameterName() { return #classname; } \ classname() : SuperType() {} \ classname(size_t index) : SuperType(index) {} \ diff --git a/Framework/DataObjects/test/WorkspaceIteratorTest.h b/Framework/DataObjects/test/WorkspaceIteratorTest.h index c218a9078cf5..291ba9adfa00 100644 --- a/Framework/DataObjects/test/WorkspaceIteratorTest.h +++ b/Framework/DataObjects/test/WorkspaceIteratorTest.h @@ -33,10 +33,10 @@ template class FibSeries { class WorkspaceIteratorTest : public CxxTest::TestSuite { private: - typedef boost::shared_ptr parray; - typedef boost::shared_ptr W2D; - typedef boost::shared_ptr WSV; - typedef boost::shared_ptr Wbase; + using parray = boost::shared_ptr; + using W2D = boost::shared_ptr; + using WSV = boost::shared_ptr; + using Wbase = boost::shared_ptr; public: void testIteratorWorkspace2DAsBase() { diff --git a/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h b/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h index 46d8aca20705..aa4b53686454 100644 --- a/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h +++ b/Framework/Geometry/inc/MantidGeometry/IDetector_fwd.h @@ -34,13 +34,13 @@ namespace Geometry { class IDetector; /// Shared pointer to an IDetector object -typedef boost::shared_ptr IDetector_sptr; +using IDetector_sptr = boost::shared_ptr; /// Shared pointer to an const IDetector object -typedef boost::shared_ptr IDetector_const_sptr; +using IDetector_const_sptr = boost::shared_ptr; /// unique pointer to an IDetector -typedef std::unique_ptr IDetector_uptr; +using IDetector_uptr = std::unique_ptr; /// unique pointer to an IDetector (const version) -typedef std::unique_ptr IDetector_const_uptr; +using IDetector_const_uptr = std::unique_ptr; } // namespace Geometry } // namespace Mantid diff --git a/Framework/Kernel/src/NetworkProxyOSX.cpp b/Framework/Kernel/src/NetworkProxyOSX.cpp index ed8e08590703..1692e4647a50 100644 --- a/Framework/Kernel/src/NetworkProxyOSX.cpp +++ b/Framework/Kernel/src/NetworkProxyOSX.cpp @@ -43,7 +43,7 @@ enum ProxyType { }; /// Typedef Collection of proxy information. -typedef std::vector ProxyInfoVec; +using ProxyInfoVec = std::vector; /** * Extract proxy information from a CFDistionaryRef diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h index 61f405f65fe3..4846bb102e10 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Vector3DParameter.h @@ -152,7 +152,7 @@ ElemType &Vector3DParameter::operator[](int index) { class classname \ : public Mantid::MDAlgorithms::Vector3DParameter { \ public: \ - typedef Vector3DParameter SuperType; \ + using SuperType = Vector3DParameter SuperType; \ static std::string parameterName() { return #classname; } \ classname(type_ a, type_ b, type_ c) : SuperType(a, b, c) {} \ classname() : SuperType() {} \ diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h index 268e6219ecbe..db0adf440ddd 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Converters/CArrayToNDArray.h @@ -45,7 +45,7 @@ struct CArrayToNDArray { // Round about way of calling the wrapNDArray template function that is // defined // in the cpp file - typedef typename ConversionPolicy::template apply policy; + using policy = typename ConversionPolicy::template apply; return policy::createFromArray(carray, ndims, dims); } }; diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp index d2ef62e9d764..586c963c4f6b 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp @@ -8,11 +8,12 @@ using namespace boost::python; namespace { -typedef double (ProductFunction::*getParameterType1)(size_t) const; -typedef double (ProductFunction::*getParameterType2)(const std::string &) const; +using getParameterType1 = double (ProductFunction::*)(size_t) const; +using getParameterType2 = double (ProductFunction::*)(const std::string &) const; + +using setParameterType2 = void (ProductFunction::*)(const std::string &, + const double &, bool); -typedef void (ProductFunction::*setParameterType2)(const std::string &, - const double &, bool); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setParameterType2_Overloads, setParameter, 2, 3) } diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h index 93b7fab66f12..46de8bd791d3 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h @@ -436,7 +436,7 @@ static void feedMDBox(MDBoxBase, nd> *box, size_t repeat = 1, template static void recurseSplit(MDGridBox, nd> *box, size_t atRecurseLevel, size_t recurseLimit) { - typedef std::vector, nd> *> boxVector; + using boxVector = std::vector, nd> *>; if (atRecurseLevel >= recurseLimit) return; From 742c36c709b1e1427630ebad88838ce6cabb4f76 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 14:21:12 +0000 Subject: [PATCH 251/364] Re #22048: Moved squashed comments causing clang-format failure. --- .../DataObjects/inc/MantidDataObjects/TableWorkspace.h | 9 +++++---- .../inc/MantidGeometry/Surfaces/SurfaceFactory.h | 9 ++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h index 7fbc3e0790b5..3986f16cbd41 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h @@ -412,10 +412,11 @@ class MANTID_DATAOBJECTS_DLL TableWorkspace : public API::ITableWorkspace { using column_it = std::vector< boost::shared_ptr>::iterator; ///< Column iterator + + ///< Column const iterator using column_const_it = - std::vector>::const_iterator; ///< Column - ///const - ///iterator + std::vector>::const_iterator; + /// Shared pointers to the columns. std::vector> m_columns; /// row count @@ -432,5 +433,5 @@ using TableWorkspace_sptr = boost::shared_ptr; using TableWorkspace_const_sptr = boost::shared_ptr; } // namespace DataObjects -} // Namespace Mantid + #endif /*MANTID_DATAOBJECTS_TABLEWORKSPACE_H_*/ diff --git a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h index a017602c9869..b8f981f5a70b 100644 --- a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h @@ -42,12 +42,11 @@ class MANTID_GEOMETRY_DLL SurfaceFactory { private: // workaround because gcc 4.4 cannot have std::unique_ptr inside a std::map. // http://stackoverflow.com/questions/7342703/gcc-4-4-4-5-unique-ptr-not-work-for-unordered-set-unordered-map + + ///< Storage of surface pointers. using MapType = - std::vector>>; ///< - ///Storage - ///of - ///surface - ///pointers + std::vector>>; + static SurfaceFactory *FOBJ; ///< Effective "this" MapType SGrid; ///< The tally stack From 2643196acee1644c9f318d4863015c98c224c2d1 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 15 Mar 2018 14:22:24 +0000 Subject: [PATCH 252/364] fix single crystal peaks error in peak tab #21230 --- .../InstrumentView/InstrumentWidgetPickTab.h | 2 +- .../src/InstrumentWidgetPickTab.cpp | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h index 93a5df79fa5e..03017d31ca21 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h @@ -280,7 +280,7 @@ private slots: bool m_enabled; TubeXUnits m_tubeXUnits; ///< quantity the time bin integrals to be plotted against - int m_currentDetID; + int m_currentPickID; }; } // MantidWidgets diff --git a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp index c098389b9b8f..5b38aa26b77d 100644 --- a/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp +++ b/qt/widgets/instrumentview/src/InstrumentWidgetPickTab.cpp @@ -816,7 +816,8 @@ ComponentInfoController::ComponentInfoController( QTextEdit *infoDisplay) : QObject(tab), m_tab(tab), m_instrWidget(instrWidget), m_selectionInfoDisplay(infoDisplay), m_freezePlot(false), - m_instrWidgetBlocked(false), m_currentPickID(-1) {} + m_instrWidgetBlocked(false), + m_currentPickID(std::numeric_limits::max()) {} /** * Display info on a component refered to by a pick ID. @@ -1077,7 +1078,7 @@ DetectorPlotController::DetectorPlotController(InstrumentWidgetPickTab *tab, OneCurvePlot *plot) : QObject(tab), m_tab(tab), m_instrWidget(instrWidget), m_plot(plot), m_plotType(Single), m_enabled(true), m_tubeXUnits(DETECTOR_ID), - m_currentDetID(-1) { + m_currentPickID(std::numeric_limits::max()) { connect(m_plot, SIGNAL(clickedAt(double, double)), this, SLOT(addPeak(double, double))); } @@ -1088,7 +1089,7 @@ DetectorPlotController::DetectorPlotController(InstrumentWidgetPickTab *tab, * @param pickID :: A pick ID of an instrument component. */ void DetectorPlotController::setPlotData(size_t pickID) { - m_currentDetID = -1; + m_currentPickID = std::numeric_limits::max(); if (m_plotType == DetectorSum) { m_plotType = Single; @@ -1103,7 +1104,7 @@ void DetectorPlotController::setPlotData(size_t pickID) { const auto &componentInfo = actor.componentInfo(); if (componentInfo.isDetector(pickID)) { if (m_plotType == Single) { - m_currentDetID = actor.getDetID(pickID); + m_currentPickID = pickID; plotSingle(pickID); } else if (m_plotType == TubeSum || m_plotType == TubeIntegral) { plotTube(pickID); @@ -1686,7 +1687,7 @@ QString DetectorPlotController::getPlotCaption() const { * @param y :: Peak height (counts) */ void DetectorPlotController::addPeak(double x, double y) { - if (m_currentDetID < 0) + if (m_currentPickID == std::numeric_limits::max()) return; try { @@ -1737,11 +1738,13 @@ void DetectorPlotController::addPeak(double x, double y) { // Run the AddPeak algorithm auto alg = Mantid::API::FrameworkManager::Instance().createAlgorithm("AddPeak"); + const auto &detIDs = + m_instrWidget->getInstrumentActor().detectorInfo().detectorIDs(); alg->setPropertyValue("RunWorkspace", ws->getName()); alg->setPropertyValue("PeaksWorkspace", peakTableName); - alg->setProperty("DetectorID", m_currentDetID); + alg->setProperty("DetectorID", detIDs[m_currentPickID]); alg->setProperty("TOF", x); - alg->setProperty("Height", actor.getIntegratedCounts(m_currentDetID)); + alg->setProperty("Height", actor.getIntegratedCounts(m_currentPickID)); alg->setProperty("BinCount", y); alg->execute(); From 83a32842a81ba12985bdc903326f44c1edf22b88 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Thu, 15 Mar 2018 14:36:51 +0000 Subject: [PATCH 253/364] fix type issue #21230 --- .../MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h index 03017d31ca21..83ce8c02bc5a 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h @@ -280,7 +280,7 @@ private slots: bool m_enabled; TubeXUnits m_tubeXUnits; ///< quantity the time bin integrals to be plotted against - int m_currentPickID; + size_t m_currentPickID; }; } // MantidWidgets From 756a4b0638516d517fb45a18bd21e58ccc3bb1f2 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 14:44:23 +0000 Subject: [PATCH 254/364] Re #22048: Applied some manual fixes for Vates. --- .../VatesAPI/test/FilteringUpdateProgressActionTest.h | 5 ++--- qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h | 2 +- .../inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h | 2 +- .../pqCameraReactionNonOrthogonalAxes.h | 2 +- .../pqCameraToolbarNonOrthogonalAxes.h | 2 +- .../MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h | 4 ++-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h b/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h index de0a70e39716..55eae5f2f3a8 100644 --- a/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h +++ b/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h @@ -18,8 +18,7 @@ class FilteringUpdateProgressActionTest : public CxxTest::TestSuite { } }; - typedef Mantid::VATES::FilterUpdateProgressAction - ProgressActionType; + using ProgressActionType = Mantid::VATES::FilterUpdateProgressAction; public: void testCallsView() { @@ -49,4 +48,4 @@ class FilteringUpdateProgressActionTest : public CxxTest::TestSuite { "message", view.Message); } }; -#endif \ No newline at end of file +#endif diff --git a/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h b/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h index 02984a1716ae..ff24c106df62 100644 --- a/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h +++ b/qt/paraview_ext/VatesAPI/test/MDEWLoadingPresenterTest.h @@ -33,7 +33,7 @@ class MDEWLoadingPresenterTest : public CxxTest::TestSuite { */ class ConcreteMDEWLoadingPresenter : public MDEWLoadingPresenter { private: - typedef MDEWLoadingPresenter BaseClass; + using BaseClass = MDEWLoadingPresenter; public: void diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h index 5fce01503429..8617dca811dd 100644 --- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h +++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/VsiApplyBehaviour.h @@ -13,7 +13,7 @@ namespace SimpleGui { class VsiApplyBehaviour : public pqApplyBehavior { public: Q_OBJECT - typedef QObject Superclass; + using Superclass = QObject; public: VsiApplyBehaviour(Mantid::VATES::ColorScaleLock *lock, diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h index dbe74aa098fe..01d4601507b2 100644 --- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h +++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraReactionNonOrthogonalAxes.h @@ -71,7 +71,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS pqCameraReactionNonOrthogonalAxes : public pqReaction { Q_OBJECT - typedef pqReaction Superclass; + using Superclass = pqReaction; public: enum Mode { diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h index 5dd075d442be..ddb661045784 100644 --- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h +++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/pqCameraToolbarNonOrthogonalAxes.h @@ -72,7 +72,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS pqCameraToolbarNonOrthogonalAxes : public QToolBar { Q_OBJECT - typedef QToolBar Superclass; + using Superclass = QToolBar; public: pqCameraToolbarNonOrthogonalAxes(const QString &title, diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h index 6042efc4cff8..1982ab9b1402 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/FirstExperimentInfoQuery.h @@ -27,7 +27,7 @@ template class DLLExport FirstExperimentInfoQueryAdapter : public FirstExperimentInfoQuery { public: - typedef boost::shared_ptr Adaptee_sptr; + using Adaptee_sptr = boost::shared_ptr; private: Adaptee_sptr m_ws; @@ -70,4 +70,4 @@ class DLLExport FirstExperimentInfoQueryAdapter } } -#endif /* MANTID_SLICEVIEWER_FIRSTEXPERIMENTINFOQUERY_H_ */ \ No newline at end of file +#endif /* MANTID_SLICEVIEWER_FIRSTEXPERIMENTINFOQUERY_H_ */ From 4e320392c3aa0198a52513eda1208eb430eb204b Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 14:45:21 +0000 Subject: [PATCH 255/364] Re #22048: Applied clang format patch for manual fixes. --- Framework/API/inc/MantidAPI/ICatalogInfoService.h | 3 ++- Framework/API/inc/MantidAPI/SingleValueParameter.h | 7 +++++-- .../DataObjects/inc/MantidDataObjects/TableWorkspace.h | 2 +- .../Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h | 5 ++--- .../mantid/api/src/Exports/ProductFunction.cpp | 3 ++- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Framework/API/inc/MantidAPI/ICatalogInfoService.h b/Framework/API/inc/MantidAPI/ICatalogInfoService.h index fef462a41a2d..bc247f862d72 100644 --- a/Framework/API/inc/MantidAPI/ICatalogInfoService.h +++ b/Framework/API/inc/MantidAPI/ICatalogInfoService.h @@ -53,7 +53,8 @@ class DLLExport ICatalogInfoService { }; using ICatalogInfoService_sptr = boost::shared_ptr; -using ICatalogInfoService_const_sptr = boost::shared_ptr; +using ICatalogInfoService_const_sptr = + boost::shared_ptr; } } diff --git a/Framework/API/inc/MantidAPI/SingleValueParameter.h b/Framework/API/inc/MantidAPI/SingleValueParameter.h index 6f671927cf76..a346d7107385 100644 --- a/Framework/API/inc/MantidAPI/SingleValueParameter.h +++ b/Framework/API/inc/MantidAPI/SingleValueParameter.h @@ -159,8 +159,11 @@ std::string SingleValueParameter::toXMLString() const { class classname \ : public Mantid::API::SingleValueParameter { \ public: \ - using SuperType = Mantid::API::SingleValueParameter \ - static std::string parameterName() { return #classname; } \ + using SuperType = \ + Mantid::API::SingleValueParameter static std::string \ + parameterName() { \ + return #classname; \ + } \ classname(type_ value) : SuperType(value) {} \ classname() : SuperType() {} \ std::string getName() const override { return #classname; } \ diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h index 3986f16cbd41..c3874fdb65bf 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h @@ -416,7 +416,7 @@ class MANTID_DATAOBJECTS_DLL TableWorkspace : public API::ITableWorkspace { ///< Column const iterator using column_const_it = std::vector>::const_iterator; - + /// Shared pointers to the columns. std::vector> m_columns; /// row count diff --git a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h index b8f981f5a70b..6a2226f1dc0a 100644 --- a/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h +++ b/Framework/Geometry/inc/MantidGeometry/Surfaces/SurfaceFactory.h @@ -42,10 +42,9 @@ class MANTID_GEOMETRY_DLL SurfaceFactory { private: // workaround because gcc 4.4 cannot have std::unique_ptr inside a std::map. // http://stackoverflow.com/questions/7342703/gcc-4-4-4-5-unique-ptr-not-work-for-unordered-set-unordered-map - + ///< Storage of surface pointers. - using MapType = - std::vector>>; + using MapType = std::vector>>; static SurfaceFactory *FOBJ; ///< Effective "this" diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp index 586c963c4f6b..d1e71ee12ce9 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/ProductFunction.cpp @@ -9,7 +9,8 @@ using namespace boost::python; namespace { using getParameterType1 = double (ProductFunction::*)(size_t) const; -using getParameterType2 = double (ProductFunction::*)(const std::string &) const; +using getParameterType2 = + double (ProductFunction::*)(const std::string &) const; using setParameterType2 = void (ProductFunction::*)(const std::string &, const double &, bool); From c73914c44868f6a33d9bd738cf53c03c5209725d Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Thu, 15 Mar 2018 15:11:03 +0000 Subject: [PATCH 256/364] Changed Segfault to other example --- docs/source/release/v3.12.0/framework.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/source/release/v3.12.0/framework.rst b/docs/source/release/v3.12.0/framework.rst index 4e95502b10e9..4c17faf5adb1 100644 --- a/docs/source/release/v3.12.0/framework.rst +++ b/docs/source/release/v3.12.0/framework.rst @@ -141,10 +141,12 @@ Improved .. code-block:: python - from mantid.simpleapi import Segfault + from mantid.simpleapi import * import json - props = json.loads('{"DryRun":true}') - Segfault(**props) + source = json.loads('{"Filename":"CNCS_7860_event.nxs"}') + props = json.loads('{"InputWorkspace":"eventWS", "Params":"1000"}') + eventWS = Load(**source) + rebinned = Rebin(**props) Deprecated ########## From 1f9bf6182f590e6f2df7b60f4196ed195071e604 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Thu, 15 Mar 2018 15:14:10 +0000 Subject: [PATCH 257/364] Adde Useful Tools and Profiling pages. Re #22082 --- dev-docs/source/ProfilingWithValgrind.rst | 173 ++++++++++++++++++ dev-docs/source/UsefulTools.rst | 156 ++++++++++++++++ .../source/images/KCachegrind_MantidPlot.png | Bin 0 -> 513544 bytes dev-docs/source/index.rst | 2 + 4 files changed, 331 insertions(+) create mode 100644 dev-docs/source/ProfilingWithValgrind.rst create mode 100644 dev-docs/source/UsefulTools.rst create mode 100644 dev-docs/source/images/KCachegrind_MantidPlot.png diff --git a/dev-docs/source/ProfilingWithValgrind.rst b/dev-docs/source/ProfilingWithValgrind.rst new file mode 100644 index 000000000000..d5e66f6621a9 --- /dev/null +++ b/dev-docs/source/ProfilingWithValgrind.rst @@ -0,0 +1,173 @@ +.. _ProfilingWithValgrind: + +Profiling with Valgrind +======================= + +Summary +------- + +Describes how to use the +`callgrind `__ plugin to +the `valgrind `__ tool set to profile your code. + +*Note: Valgrind is a Linux only tool* + +Installation +------------ + +You will need to install both *valgrind* & the visualizer tool +*kcachegrind* - both of which should be available in your distribution's +repositories. + +Ubuntu +~~~~~~ + +:: + + >> apt-get install valgrind kcachegrind + +Red Hat/Fedora +~~~~~~~~~~~~~~ + +:: + + >> yum install valgrind kcachegrind + +Preparation +----------- + +To be most effective valgrind requires that debugging information be +present in the binaries that are being instrumented, although a full +debug build is not required. On gcc this means compiling with the *-g* +flag. For Mantid the recommended setup is to use a separate build with +the *CMAKE_BUILD_TYPE* set to *RelWithDebInfo*. This provides a good +balance between performance and availability of debugging information. + +Running the Profiler +-------------------- + +The profiler can instrument the code in a number of different ways. Some +of these will be described here. For more detail information see the +`callgrind manual `__. + +During execution the callgrind tool creates many output file named +*callgrind.output.pid.X*. For this reason it is recommended that each +profile run be executed from within a separate directory, named with a +description of the activity. This allows the separate profiled runs to +be found more easily in the future. + +**Beware**: The code will execute many times (factors of 10) slower than +when not profiling - this is just a consequence of how valgrind +instruments the code. + +Profile a Whole Program Run +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the simplest mode of operation. Simply pass the program +executable, along with any arguments to the valgrind executable: + +:: + + >> valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes [args...] + +Profile Selected Portions of the Code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For larger pieces of code it can be quite likely that you wish to +profile only a selected portion of it. This is possible if you have a +access to recompile the source code of the binaries to be instrumented +as valgrind has a C api that can be used talk to the profiler. It uses a +set of +`macros `__ +to instruct the profiler what to do when it hits certain points of the +code. + +As an example take a simple main function composed of several function +calls: + +.. code:: cpp + + int main() + { + foo1(); + bar1(); + foo2(); + foo3(); + } + +To profile only the call to ``bar1()`` then you would do the following +to the code: + +.. code:: cpp + + #include + + int main() + { + foo1(); + CALLGRIND_START_INSTRUMENTATION; + CALLGRIND_TOGGLE_COLLECT; + bar1(); + CALLGRIND_TOGGLE_COLLECT; + CALLGRIND_STOP_INSTRUMENTATION; + foo2(); + foo3(); + } + +After recompiling the code you would then run the profiler again but +this time adding the *--instr-atstart=no --collect-atstart=no* flags, +like so + +:: + + >> valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes --collect-jumps=yes --collect-atstart=no --instr-atstart=no [args...] + +The *--instru-at-start=no* is not strictly necessary but it will speed +up the code up until the profiling point at the cost of the less +accuracy about the cache usage. See +`here `__ +more details. + +Visualisation +------------- + +Callgrind produces a large amount of data about the program's execution. +It is most easily understood using the *kcachegrind* GUI tool. This +reads the information produced by callgrind and creates a list of +function calls along with information on timings of each of the calls +during the profiled run. If the source code is available it can also +show the lines of code that relate to the functions being inspected. + +.. figure:: images/KCachegrind_MantidPlot.png + :alt: Example of KCachegrind display a profile of MantidPlot starting up and closing down + + Example of KCachegrind display a profile of MantidPlot starting up + and closing down + +By default KCachegrind shows the number of instructions fetched within +its displays. This can be changed using the drop-down box at the top +right of the screen. The *Instruction Fetch* and *Cycle Estimation* are +generally the most widely used and roughly correlate to the amount of +time spent performing the displayed functions. + +Some of the key features display are: + +Flat Profile View +~~~~~~~~~~~~~~~~~ + +- Incl. - Sum of itself + all child calls as a percentage of the whole. + Programs with little static allocation should have main() at 100%. + Units are those selected by the to-right drop-down +- Self - Exclusive count spent in the selected function. Units are + those selected by the to-right drop-down +- Called - Number of times the function was called. + +Function Call Detail +~~~~~~~~~~~~~~~~~~~~ + +Click on function in flat view to get more detail on the right. + +Displays details about the selected function call plus details about all +child calls it made. The *call graph* tab at the bottom gives a nice +graphical overview of the relative function cost. + diff --git a/dev-docs/source/UsefulTools.rst b/dev-docs/source/UsefulTools.rst new file mode 100644 index 000000000000..1849b6fe63fc --- /dev/null +++ b/dev-docs/source/UsefulTools.rst @@ -0,0 +1,156 @@ +Useful Tools for Developers +=========================== + +Creating classes: class_maker.py +-------------------------------- + +**To make it faster to create a new class**. This is a small python +script located in /buildconfig/. It generates the .cpp, .h and test +files for a class along with some code stubs. It can also flesh out more +methods for new Algorithms, using the "--alg" option. + +| ``usage: class_maker.py [-h] [--force] [--test] [--alg] SUBPROJECT CLASSNAME`` +| ``Utility to create Mantid class files: header, source and test.`` +| ``positional arguments:`` +| `` SUBPROJECT  The subproject under Framework/; e.g. Kernel`` +| `` CLASSNAME   Name of the class to create`` +| ``optional arguments:`` +| `` -h, --help  show this help message and exit`` +| `` --force     Force overwriting existing files. Use with caution!`` +| `` --test      Create only the test file.`` +| `` --alg       Create an Algorithm stub. This adds some methods common to`` +| ``             algorithms.`` + +Moving/Renaming classes: move_class.py +-------------------------------------- + +This python script is located in in /buidconfig/. It will move a class +from one subproject to another and/or rename the class. Namespaces and +cmakelists are adjusted. For details, run: + +``Build/move_class.py --help`` + +Deleting a class: delete_class.py +--------------------------------- + +This python script is located in in /buildconfig/. It will delete a +class from one subproject. CMakeList.txt is adjusted. For details, run: + +``Build/delete_class.py --help`` + +Leak checking etc +----------------- + +Linux +~~~~~ + +`Memcheck `__ + +- Keeps track of allocs/deallocs and reports anything missing at exit. +- Slow but thorough +- Useful options to run with + +``valgrind --tool=memcheck --leak-check=full --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes --freelist-vol=500000000 ``\ \ `` [args...]`` + +Windows +~~~~~~~ + +`Visual Leak Detector `__ + +#. Setup the additional paths as defined in the readme file +#. Adjust the configuration file, "C:\Program Files\Visual Leak + Detector\vld.ini" to output to both File and debugger by changing the + ``ReportTo`` to + +``ReportTo = both`` + +#. Add #include to the system.h file in Kernel +#. Compile everything in debug +#. Running unit tests should now create a file memory_leak_report.txt in + the test directory. +#. IMPORTANT remove the #include before checking in. + +Thread checking +--------------- + +`Helgrind `__ or `drd `__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Identifies race conditions & dead-locks +- Slow but accurate +- A pain to get working with OpenMP. GCC must be recompiled to use a different call to create OMP threads or helgrind/drd cannot "see" the thread calls. Use this `script `__ to recompile the same version off gcc that is onyour system. The script will need editing to change the appropriate variables. + +Profiling +--------- + +.. _linux-1: + +Linux +~~~~~ + +`Callgrind/KCachegrind `__ + +- KCachegrind visualizes callgrind output. +- See :ref:`Profiling With Valgrind ` for help on + running callgrind + +`gperftools `__ + +- Takes snapshot of run and prints percentage of calls in functions + +See here for a list of other tools: +http://www.pixelbeat.org/programming/profiling/ + +.. _windows-1: + +Windows +~~~~~~~ + +`Very Sleepy `__ (Windows): + +- Start/stop recording of program using a button +- Not as detailed or flexible as callgrind + +IWYU +---- + +`include what you +use `__ (iwyu) is a +clang-based tool for determining what include statements are needed in +C/C++ files. Below are instructions for getting it to run with mantid on +linux which is a filled in version of `this +bug `__. + +#. Install the software. The version available from system installs + should be fine (e.g. yum or apt-get). +#. Get a copy of + `iwyu_tool.py `__ + which is in the project's repository, but may not be installed if you + got it from your operating system locations (e.g. yum). +#. Run ``cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE``. This will + generate an extra file, ``compile_commands.json``, in your build area + which has instructions on compiling every file in mantid. +#. Run :literal:`iwyu_tool.py -p `pwd` 2> iwyu.log` to generate the + report of changes redirecting into the file ``iwyu.log``. This will + take a long time since it is going through the whole repository. If + you want it for a single file, then supply that as an additional + argument with full path. Only one file can be supplied at a time. +#. Run ``fix_includes < iwyu.log`` and compile the results. Depending on + how you installed iwyu, the program may be called + ``fix_includes.py``. If it doesn't compile, the most likely suspect + is that iwyu included a private header. See `iwyu instructions for + users `__ + for ways to handle this. Generally, they suggest deleting the + offending lines. +#. Check that your build path didn't make it into source files. Since + ``compile_commands.json`` has full paths, iwyu will put full paths in + the include statements. This will not produce an error on your + system, but it will on the build servers. The easiest way to check is + to use `the silver + searcher `__ to check + for your username in your source tree. +#. Enjoy your success. + +**Note:** ``iwyu`` outputs to ``stderr`` and always returns a failure +status code since it generates no output. The output stream also affects +``iwyu_tool.py`` diff --git a/dev-docs/source/images/KCachegrind_MantidPlot.png b/dev-docs/source/images/KCachegrind_MantidPlot.png new file mode 100644 index 0000000000000000000000000000000000000000..ea1be216a8e931906e2e32bc54c531696313876d GIT binary patch literal 513544 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�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%0Aj9_J@1zJF?|aQU#WC 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst index dae7838b6abb..e84c56cb7fb1 100644 --- a/dev-docs/source/index.rst +++ b/dev-docs/source/index.rst @@ -31,6 +31,8 @@ Guides Communication Dependencies HandlingXML + UsefulTools + ProfilingWithValgrind =================== Component Overviews From 684c26e69278667f26c01a9d5c6797ea8234352f Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Thu, 15 Mar 2018 15:19:02 +0000 Subject: [PATCH 258/364] Added Visual Studio Build Impact page. Re #22082 --- dev-docs/source/VisualStudioBuildImpact.rst | 76 +++++++++++++++++++++ dev-docs/source/index.rst | 1 + 2 files changed, 77 insertions(+) create mode 100644 dev-docs/source/VisualStudioBuildImpact.rst diff --git a/dev-docs/source/VisualStudioBuildImpact.rst b/dev-docs/source/VisualStudioBuildImpact.rst new file mode 100644 index 000000000000..967fcbb315ef --- /dev/null +++ b/dev-docs/source/VisualStudioBuildImpact.rst @@ -0,0 +1,76 @@ +Visual Studio Build Impact +========================== + +Building Mantid on Visual Studio can take a while, and really tie up the +computer. This is because Visual Studio starts all of the compilation +processes at normal priority, so they compete as equals with everything +you are doing. + +So you might think that you can open task manage and reduce the priority +of all the cl.exe processes, well there can be quite a few, and no it +won't work for long as these processes are replaced for every file it +compiles. + +What you want to do it hunt down the MSBuild.exe processes and reduce +the priority of them, there should be the same number as you have +logical processors. The MSBuild processes spawn all of the compiler and +linker tasks, an they inherit the priority of the MSBuild process. + +Script +------ + +Of course if you don't want to do this yourself then you can use this +script. + +.. raw:: html + +

+ +Save it as Reduce_Build_Impact.vbs, and use when things are running like +a dog! + +Monitoring Script +----------------- + +If you don't want to keep running the script for each build, here's one +that keeps a watch on your system every 5 seconds. + +.. raw:: html + +
+ +.. code:: python + + Const BELOW_NORMAL = 16384 + + strComputer = "." + Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") + Do While true + Set colProcesses = objWMIService.ExecQuery _ + ("Select * from Win32_Process Where Name = 'MSBuild.exe'") + For Each objProcess in colProcesses + objProcess.SetPriority(BELOW_NORMAL) + Next + WScript.Sleep 5000 + loop + +.. raw:: html + +
diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst index e84c56cb7fb1..2ec6983f8e16 100644 --- a/dev-docs/source/index.rst +++ b/dev-docs/source/index.rst @@ -33,6 +33,7 @@ Guides HandlingXML UsefulTools ProfilingWithValgrind + VisualStudioBuildImpact =================== Component Overviews From 75837e771d84727e7931fbd72909524aced3ec0b Mon Sep 17 00:00:00 2001 From: Ross Miller Date: Thu, 15 Mar 2018 11:25:20 -0400 Subject: [PATCH 259/364] Set the run_end property when the run actually ends When we receive a RunStatusPkt packet with the status field set to END_RUN, add a property called "run_end" to the workspace (using the time from the run status packet's header). Refs #22112 --- Framework/LiveData/src/SNSLiveEventDataListener.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Framework/LiveData/src/SNSLiveEventDataListener.cpp index a5d5c7967d0a..d450d3e17b4d 100644 --- a/Framework/LiveData/src/SNSLiveEventDataListener.cpp +++ b/Framework/LiveData/src/SNSLiveEventDataListener.cpp @@ -740,9 +740,8 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::RunStatusPkt &pkt) { } } else if (pkt.status() == ADARA::RunStatus::END_RUN) { - // Run has ended: update m_status and set the flag to stop parsing network - // packets. (see comments below for why) - + // Run has ended: update m_status, set the end time and set the flag + // to stop parsing network packets. (see comments below for why) if ((m_status != Running) && (m_status != BeginRun)) { // Previous status should have been Running or BeginRun. Spit out a // warning if it's not. (If it's BeginRun, that's fine. It just means @@ -752,6 +751,10 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::RunStatusPkt &pkt) { } m_status = EndRun; + // Add the run_end property + m_eventBuffer->mutableRun().addProperty( + "run_end", timeFromPacket(pkt).toISO8601String()); + // Set the flag to make us stop reading from the network. // Stopping network reads solves a number of problems: // 1) We don't need to manage a second buffer in order to keep the events From ef79c4e779f870be669e3447c40994935335d2bc Mon Sep 17 00:00:00 2001 From: Ross Miller Date: Thu, 15 Mar 2018 11:34:29 -0400 Subject: [PATCH 260/364] Comment cleanups - no code changes Cleaning up some wonky comments left over from the last time someone used an automated tool to limit lines to 80 characters. No code changes. Refs #22112 --- .../LiveData/src/SNSLiveEventDataListener.cpp | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Framework/LiveData/src/SNSLiveEventDataListener.cpp index d450d3e17b4d..8942b9873ef4 100644 --- a/Framework/LiveData/src/SNSLiveEventDataListener.cpp +++ b/Framework/LiveData/src/SNSLiveEventDataListener.cpp @@ -1102,18 +1102,15 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::DeviceDescriptorPkt &pkt) { prop->setUnits(pvUnits); } { - // Note: it's possible for us receive device descriptor packets in - // the middle - // of a run (after the call to initWorkspacePart2), so we really - // do need to - // the lock the mutex here. + // Note: it's possible for us receive device descriptor packets + // in the middle of a run (after the call to initWorkspacePart2), + // so we really do need to the lock the mutex here. std::lock_guard scopedLock(m_mutex); m_eventBuffer->mutableRun().addLogData(prop); } // Add the pv id, device id and pv name to the name map so we can - // find the - // name when we process the variable value packets + // find the name when we process the variable value packets m_nameMap[std::make_pair(pkt.devId(), pvIdNum)] = pvName; } } @@ -1207,10 +1204,8 @@ void SNSLiveEventDataListener::initWorkspacePart1() { // down in initWorkspacePart2() when we load the instrument definition. // We also know we'll need 3 time series properties on the workspace. Create - // them - // now. (We may end up adding values to the pause and scan properties before - // we - // can call initWorkspacePart2().) + // them now. (We may end up adding values to the pause and scan properties + // before we can call initWorkspacePart2().) Property *prop = new TimeSeriesProperty(PAUSE_PROPERTY); m_eventBuffer->mutableRun().addLogData(prop); prop = new TimeSeriesProperty(SCAN_PROPERTY); @@ -1239,8 +1234,8 @@ void SNSLiveEventDataListener::initWorkspacePart2() { loadInst->execute(); - m_requiredLogs.clear(); // Clear the list. If we have to initialize the - // workspace again, + m_requiredLogs.clear(); + // Clear the list. If we have to initialize the workspace again, // (at the start of another run, for example), the list will be // repopulated when we receive the next geometry packet. @@ -1261,10 +1256,9 @@ void SNSLiveEventDataListener::initWorkspacePart2() { true /* bool throwIfMultipleDets */); // We always want to have at least one value for the the scan index time - // series. We may have - // already gotten a scan start packet by the time we get here and therefor - // don't need to do - // anything. If not, we need to put a 0 into the time series. + // series. We may have already gotten a scan start packet by the time we + // get here and therefor don't need to do anything. If not, we need to put + // a 0 into the time series. if (m_eventBuffer->mutableRun() .getTimeSeriesProperty(SCAN_PROPERTY) ->size() == 0) { @@ -1300,8 +1294,7 @@ void SNSLiveEventDataListener::initMonitorWorkspace() { // NOTE: This function does not lock the mutex! The calling function must // ensure that m_eventBuffer won't change while the function runs (either by // locking the mutex, or by the simple fact of never calling it once the -// workspace -// has been initialized...) +// workspace has been initialized...) bool SNSLiveEventDataListener::haveRequiredLogs() { bool allFound = true; Run &run = m_eventBuffer->mutableRun(); From f04c68408dd8548cc4b51db7ddce74e2bb98b484 Mon Sep 17 00:00:00 2001 From: Joseph Ramsay Date: Thu, 15 Mar 2018 17:07:34 +0000 Subject: [PATCH 261/364] Re #22082 Move MVP description and GUI guidelines to dev-docs --- dev-docs/source/GUIDesignGuidelines.rst | 284 ++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 dev-docs/source/GUIDesignGuidelines.rst diff --git a/dev-docs/source/GUIDesignGuidelines.rst b/dev-docs/source/GUIDesignGuidelines.rst new file mode 100644 index 000000000000..2be10eb0e696 --- /dev/null +++ b/dev-docs/source/GUIDesignGuidelines.rst @@ -0,0 +1,284 @@ +===================== +GUI Design Guidelines +===================== + +.. contents:: + :local: + +Summary +####### + +This page describes guidelines that show be followed when implementing +an interface in MantidPlot. The aim is to encourage a consistent +approach to developing interfaces. + +MVP (Model View Presenter) +########################## + +Mantid GUIs aim to use the MVP pattern. The MVP pattern is a generic +concept for how to structure GUI code. MVP allows components of the +GUI to be tested separately and automatically. It also allows for +greater flexibility. Decoupling the model and view mean that if the +developer wants to experiment with, for example, a different GUI +toolkit, or a different method of doing their calculations, then it is +easy and safe to swap out components. A description of each component +is given below. + +To illustrate MVP, a simple example of a calculator GUI has been +created using Python (the concepts of MVP can be applied to any +programming language). This example can be found in +``scripts/MVPExample``, and you can run it with ``python +Calculator.py``. + +It is good practice to have model, view or presenter (as appropriate) +at the end of the name for each file (e.g. FFTView, FFTModel, +FFTPresenter), and each component should be a class in its own +right. Within the MVP pattern the model and view never exchange any +information directly. + +Model +----- + +The model is where the 'hard sums' take place within GUI. Any Mantid +algorithms should be run in the model, as well any other calculations +that may need to be performed. + +It is possible that a presenter may have multiple models. For example +if two GUIs require the same calculation (e.g. mean) but not all +of the model (one GUI may need standard deviation and the other the +median), then it would be sensible for there to be three models (with +the mean model being shared). This prevents code duplication and makes +maintenance easier. + +It is important to note that the values used in the calculations +should be received from the presenter (more of which below). + +View +---- + +The view determines the look of the GUI. In passive-view MVP, there +will generally be very little logic in the view. A view should define +the following sections: + +* The look of the GUI (often this will be defined in a Qt ``.ui`` file + instead) +* **Get** methods to return values from the widgets (text input, + button etc) +* **Set** methods to update the output from the GUI (eg. plot some + data, fill in some text boxes) + +A view will probably also contain **connections**. A detailed +explanation of signals and slots can be foud `here +`_. Briefly, a +widget may emit **signals**. For example QPushButton emits the signal +``clicked`` when it is clicked. In order to handle the button being +clicked, the view will implement a **slot** method (in Qt just a +normal method, but specified as a slot with the Qt `slot` +keyword). This method does whatever we need for a button click. To +ensure that this method is called whenever the button is clicked, we +connect the ``clicked`` signal of our button to the +``handleButtonClick`` slot of our view. + +The view should have a parent - this will be the widget containing +it. An example of a parent would be a main window containing tabs - +the children of the main window would be the tabs, and the children of +the tabs would be the widgets contained within the tabs. + +Presenter +--------- + +The presenter acts as a 'go-between'. It receives data from the view, +passes it to the model for processing, receives it back from the model +and passes it to the view to be displayed to the user. The presenter +generally should contain relatively simple logic (though it will be +more complex than the view). + +The model and the view are stored as members of the presenter +class. These should be passed into the presenter at initialisation. + +It is important to note that the model and view should have as little +access as possible to the presenter. Presenter-model communication is +simple - the presenter generally just calls methods on the +presenter. Presenter-view communication is slightly more +involved. There are two ways of doing it: + +* **Connections** - the presenter may also contain connections. You + may choose to define custom signals in your view, such as a + ``plotRequested`` signal to announce that the user has asked to plot + some data, probably by clicking a button. The presenter will need to + implement a slot (let's call it ``handlePlotRequested``) to handle + this, which gets the relevant data from the model and passes it to + the view, and connect the signal to the slot in its constructor. It + is also possible for a signal emitted by a view to be caught in the + presenter of a parent view. In order to communicate by connections + using Qt in C++ the presenter must inherit from ``QObject``. It's + generally considered good practice to avoid having Qt in the + presenter, so this method works best for GUIs written in Python (or + another language with a more relaxed type system). + - Note that is good practice to handle all signals in the presenter + if you can, even if it is possible to just handle them in the + view. This is because by going through the presenter we can unit + test the handling of the signals. +* **Notify** - the presenter may instead allow the view to 'notify' + it. This can be achieved by implementing a set of possible + notifications (in C++ an enum class works well) and a method + ``notify(notification)`` on the presenter. In the above example, + ``handlePlotRequested`` is still needed, but now ``notify`` invokes + it whenever it is passed a ``plotRequested`` notification. This + method requires the view to have a pointer to the presenter, which + introduces a circular dependency and leaks information about the + presenter to the view. The leak can be resolved by having the + presenter implement an interface which exposes **only** the + ``notify`` method, and having the view keep a pointer to + this. + +Doing presenter-view communication with connections is the cleaner of +the two, so this method should be used unless writing a GUI in +C++. You'll notice that, in both cases, the view never passes data +(for example, the input from a text box) directly to the presenter, +instead it justs tells the presenter that something needs to be +done. In passive-view MVP the presenter, in handling this, gets any +data it needs from the view using the view's **get** methods. + +Testing MVP Components +---------------------- + +MVP allows us to write automated tests for a large amount of the +GUI. We can write independent tests for the presenter and model, but +usually not the view (for this reason, the view should be as simple as +possible, ideally containing no logic at all). + +**Mocking** is very useful tool for testing the presenter. Mocking +allows us to return a predefined result from a method of either the +view or the model. + +It is useful to mock out the model because, providing that we've +written adequate tests for the it, we don't care what the output is in +the tests for the presenter - we just care that the presenter passes +the output to the view correctly. The model may perform time-consuming +calculations, such as fitting, so by returning a dummy value from the +fitting method we cut down the time our tests take to run. We can also +potentially change how the model works - if the GUI uses an algorithm +which undergoes some changes, such as applying a different set of +corrections, the tests for the presenter will be unaffected. + +It's useful to mock out the view because we don't want to have to +manually input data every time the unit tests are run - instead we can +mock the **get** methods to simulate the user entering data. + +Using `GMock +`_ +in C++, or `unittest.mock +`_ in Python, we +can set expectations in the unit tests for certain methods to be +called, and with certain arguments. + +Qt Designer +########### + +The layout of all interfaces and reusable widgets should be done by +using the Qt's `Designer +`_ tool. This +has several advantages: + +* immediate visual feedback of what the widget/interface will look + like +* far easier to maintain, e.g. moving a control is a simple drag and + drop +* reduces the amount of hand-written code required + +If it is felt that the design must be hand coded then this should be +discussed with a senior developer. + +Reusable Widget +############### + +Many interfaces will require similar functionality. For example, the +ability to enter a filename string to search for a file along with a +'Browse' button to select a file from the filesystem. This type of +behaviour should be captured in a new composite widget that can be +reused by other components. + +The new widget should be placed in the MantidWidgets plugin and a +wrapper created in the DesignerPlugins plugin so that the new widget +type can be used from within the Qt Designer. + +The current set of reusable items are: + ++-------------------------+---------------+----------+ +| Class Name | Parent Class | Abiltity | ++=========================+===============+==========+ +| AlgorithmSelectorWidget | QWidget | A text box and tree widget to select an algorithm | ++-------------------------+---------------+----------+ +| CatalogSearch | QWidget | An interface interface to the catalog system | ++-------------------------+---------------+----------+ +| CatalogSelector | QWidget | Displays the available catalog services | ++-------------------------+---------------+----------+ +| CheckBoxHeader | QHeaderView | Enables checkboxes to exist in the table header | ++-------------------------+---------------+----------+ +| `ColorBarWidget `_ | QWidget | Show a color bar that can accompany a colored bidimensional plot | ++-------------------------+---------------+----------+ +| DataSelector | MantidWidget | A box to select if input is from a file or workspace along with the appropriate widget to choose a workspace or file. | ++-------------------------+---------------+----------+ +| DisplayCurveFit | MantidWidget | A plot to display the results of a curve fitting process | ++-------------------------+---------------+----------+ +| FindReplaceDialog | QDialog | A dialog box to find/replace text within a ScriptEditor | ++-------------------------+---------------+----------+ +| FitPropertyBrowser | QDockWidget | Specialisation of QPropertyBrowser for defining fitting functions | ++-------------------------+---------------+----------+ +| FunctionBrowser | QWidget | Provides a wiget to alter the parameters of a function | ++-------------------------+---------------+----------+ +| InstrumentSelector | QCombobox | A selection box populated with a list of instruments for the current facility | ++-------------------------+---------------+----------+ +| LineEditWithClear | QLineEdit | A QLineEdit with a button to clear the text | ++-------------------------+---------------+----------+ +| MessageDisplay | QWidget | Display messages from the logging system | ++-------------------------+---------------+----------+ +| MWRunFiles | MantidWidget | Provides a line edit to enter filenames and a browse button to browse the file system | ++-------------------------+---------------+----------+ +| `MWView `_ | QWidget | A colored, bidimensional plot of a matrix workspace | ++-------------------------+---------------+----------+ +| ProcessingAlgoWidget | QWidget | A composite widget that allows a user to select if a processing step is achieved using an algorithm or a Python script. It also provides a script editor. | ++-------------------------+---------------+----------+ +| ScriptEditor | QsciScintilla | The main script editor widget behind the ScriptWindow | ++-------------------------+---------------+----------+ +| WorkspaceSelector | QComboBox | A selection box showing the workspaces currently in Mantid. It can be restricted by type.| ++-------------------------+---------------+----------+ + +Python +###### + +Interfaces can also be created in Python using the `PyQt4 +`_ package. The code for the +interface should be placed in a Python `package +`_ under the +``Code/Mantid/scripts`` directory. It should be named after the interface +name (without spaces). The code within the package should be +structured to avoid placing all of the code in a single file, +i.e. separate files for different classes etc. Sub packages are +recommended for grouping together logical sets of files. + +For the interface to appear from within MantidPlot create a startup +python file under the ``Code/Mantid/scripts`` directory. Assuming the code +for the interface is in a directory called foo_app then the startup +file would look like: + +.. code-block:: python + + from foo_app import FooGUI + + app = FooGUI() + app.show() + +where ``FooGUI`` is the ``MainWindow`` for the interface. + +Designer +^^^^^^^^ + +As with the C++ GUI the Qt Designer should be used for layouts of all +widgets and the main interface. It is recommended that the ``.ui`` +files be placed in a ``ui`` subdirectory of the interface package. To +generate PyQt code from the UI xml you will need to run the ``pyuic4`` +program that ships with PyQt4. It is also recommended that the output +file is named, using the ``-o`` argument, ``ui_[widgetname].py`` and +placed in the ``ui`` subdirectory. From e22928c8db80e1b276cb334e6af4ecba0570f171 Mon Sep 17 00:00:00 2001 From: Joseph Ramsay Date: Thu, 15 Mar 2018 17:07:56 +0000 Subject: [PATCH 262/364] Re #22082 Add MVP example code to scripts directory --- scripts/MVPExample/Calculator.py | 37 +++++++++++++ scripts/MVPExample/Model.py | 10 ++++ scripts/MVPExample/Presenter.py | 43 +++++++++++++++ scripts/MVPExample/View.py | 91 ++++++++++++++++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 scripts/MVPExample/Calculator.py create mode 100644 scripts/MVPExample/Model.py create mode 100644 scripts/MVPExample/Presenter.py create mode 100644 scripts/MVPExample/View.py diff --git a/scripts/MVPExample/Calculator.py b/scripts/MVPExample/Calculator.py new file mode 100644 index 000000000000..143b51351daa --- /dev/null +++ b/scripts/MVPExample/Calculator.py @@ -0,0 +1,37 @@ +from Presenter import Presenter +from Model import Model +from View import View + +import PyQt4.QtGui as QtGui + +import sys + + +class Demo(QtGui.QMainWindow): + """ Wrapper class for setting the main window""" + def __init__(self, parent=None): + super(Demo, self).__init__(parent) + + self.window = QtGui.QMainWindow() + demo_view = View() + demo_model = Model() + # create presenter + self.presenter = Presenter(demo_view, demo_model) + # set the view for the main window + self.setCentralWidget(demo_view) + self.setWindowTitle("MVP Demo") + + +def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + + +if __name__ == "__main__": + app = qapp() + window = Demo() + window.show() + app.exec_() diff --git a/scripts/MVPExample/Model.py b/scripts/MVPExample/Model.py new file mode 100644 index 000000000000..c9c883a022d5 --- /dev/null +++ b/scripts/MVPExample/Model.py @@ -0,0 +1,10 @@ +class Model(object): + def __init__(self): + self.result = 0 + + def calc(self, value1, operation, value2): + if operation == "+": + self.result = value1 + value2 + elif operation == "-": + self.result = value1 - value2 + return self.result diff --git a/scripts/MVPExample/Presenter.py b/scripts/MVPExample/Presenter.py new file mode 100644 index 000000000000..9cff214bf10a --- /dev/null +++ b/scripts/MVPExample/Presenter.py @@ -0,0 +1,43 @@ +class Presenter(object): + # Pass the view and model into the presenter + def __init__(self, demo_view, demo_model): + self.model = demo_model + self.view = demo_view + + # Define the initial view + # Note that, in the view, the drop-down could be replaced with a set of + # tick boxes and this line would remain unchanged - an advantage of + # decoupling the presenter and view + self.view.set_options('operations', ['+', '-']) + self.view.set_options('display', ['print', 'update', 'print and update']) + self.printToScreen = True + self.view.hide_display() + + # Connect to the view's custom signals + self.view.btnSignal.connect(self.handle_button) + self.view.displaySignal.connect(self.display_update) + + # The final two methods handle the signals + def display_update(self): + display = self.view.get_display() + if display == 'update': + self.printToScreen = False + self.view.show_display() + elif display == 'print': + self.printToScreen = True + self.view.hide_display() + else: + self.printToScreen = True + self.view.show_display() + + def handle_button(self): + # Get the values from view + value1 = self.view.get_value(0) + operation = self.view.get_operation() + value2 = self.view.get_value(2) + # The model does the hard work for us + result = self.model.calc(value1, operation, value2) + + if self.printToScreen: + print result + self.view.setResult(result) diff --git a/scripts/MVPExample/View.py b/scripts/MVPExample/View.py new file mode 100644 index 000000000000..1ffd2c4288c1 --- /dev/null +++ b/scripts/MVPExample/View.py @@ -0,0 +1,91 @@ +import PyQt4.QtGui as QtGui +import PyQt4.QtCore as QtCore + + +class View(QtGui.QDialog): + # In PyQt signals are the first thing to be defined in a class: + displaySignal = QtCore.pyqtSignal() + btnSignal = QtCore.pyqtSignal() + + def __init__(self, parent=None): + # Call QDialog's constructor + super(View, self).__init__(parent) + + # Initialise the widgets for the view (this can also be done from Qt Creator + self.table = QtGui.QTableWidget() + self.table.setWindowTitle("MVP Demo") + self.table.resize(400, 250) + self.table.setRowCount(5) + self.table.setColumnCount(2) + self.table.setHorizontalHeaderLabels(QtCore.QString("name;value;").split(";")) + + # Set display values in the widgets + keys = ['value 1', 'operation', 'value 2', 'display', 'result'] + self.combo = {} + self.create_combo_table(1, 1, 'operations') + self.create_combo_table(3, 1, 'display') + for row in range(len(keys)): + self.set_names(keys[row], row) + + # Initialise layout of the widget and add child widgets to it + grid = QtGui.QGridLayout() + grid.addWidget(self.table) + + self.button = QtGui.QPushButton('Calculate', self) + self.button.setStyleSheet("background-color:lightgrey") + grid.addWidget(self.button) + + # Connect button click handler method to the button's 'clicked' signal + self.button.clicked.connect(self.btn_click) + # connect method to handle combo box selection changing to the corresponding signal + self.combo['display'].currentIndexChanged.connect(self.display_changed) + + # Set the layout for the view widget + self.setLayout(grid) + + # The next two methods handle the signals connected to in the presenter + # They emit custom signals that can be caught by a presenter + def btn_click(self): + self.btnSignal.emit() + + def display_changed(self): + self.displaySignal.emit() + + # Populate view + def create_combo_table(self, row, col, key): + self.combo[key] = QtGui.QComboBox() + options = ['test'] + self.combo[key].addItems(options) + self.table.setCellWidget(row, col, self.combo[key]) + + # The next 5 methods update the appearance of the view. + + def set_options(self, key, options): + self.combo[key].clear() + self.combo[key].addItems(options) + + def set_names(self, name, row): + text = QtGui.QTableWidgetItem(name) + text.setFlags(QtCore.Qt.ItemIsEnabled) + self.table.setItem(row, 0, text) + + # Update the view with the result of a calculation + def setResult(self, value): + self.table.setItem(4, 1, QtGui.QTableWidgetItem(str(value))) + + def hide_display(self): + self.table.setRowHidden(4, True) + + def show_display(self): + self.table.setRowHidden(4, False) + + # Finally, we have the get methods to allow the presenter to read the user's input + + def get_value(self, row): + return float(self.table.item(row, 1).text()) + + def get_operation(self): + return self.combo['operations'].currentText() + + def get_display(self): + return self.combo["display"].currentText() From 2c9e0e498548414fc548fdb8ead209412c01a4a5 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Thu, 15 Mar 2018 17:11:22 +0000 Subject: [PATCH 263/364] Updating version number --- buildconfig/CMake/VersionNumber.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildconfig/CMake/VersionNumber.cmake b/buildconfig/CMake/VersionNumber.cmake index 62ba3492a4a8..0ef41816a34b 100644 --- a/buildconfig/CMake/VersionNumber.cmake +++ b/buildconfig/CMake/VersionNumber.cmake @@ -1,9 +1,9 @@ # Set the version number here for MantidVersion and the package filenames set ( VERSION_MAJOR 3 ) -set ( VERSION_MINOR 11 ) +set ( VERSION_MINOR 12 ) # UNCOMMENT the next 'set' line to 'force' the patch version number to # a value (instead of using the count coming out of 'git describe') # DO NOT COMMIT THIS TO MASTER UNCOMMENTED, ONLY TO A RELEASE BRANCH -# set ( VERSION_PATCH 0 ) +set ( VERSION_PATCH 0 ) From cb4f316d8733ec732380482a7a334da478564789 Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Thu, 15 Mar 2018 17:32:23 +0000 Subject: [PATCH 264/364] Re #22082 Fix typos in gui guidelines page --- dev-docs/source/GUIDesignGuidelines.rst | 156 ++++++++++++------------ 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/dev-docs/source/GUIDesignGuidelines.rst b/dev-docs/source/GUIDesignGuidelines.rst index 2be10eb0e696..523f82f4b94c 100644 --- a/dev-docs/source/GUIDesignGuidelines.rst +++ b/dev-docs/source/GUIDesignGuidelines.rst @@ -8,18 +8,18 @@ GUI Design Guidelines Summary ####### -This page describes guidelines that show be followed when implementing -an interface in MantidPlot. The aim is to encourage a consistent -approach to developing interfaces. +This page describes guidelines that should be followed when +implementing an interface in MantidPlot. The aim is to encourage a +consistent approach to developing interfaces. MVP (Model View Presenter) ########################## -Mantid GUIs aim to use the MVP pattern. The MVP pattern is a generic -concept for how to structure GUI code. MVP allows components of the -GUI to be tested separately and automatically. It also allows for -greater flexibility. Decoupling the model and view mean that if the -developer wants to experiment with, for example, a different GUI +GUIs in Mantid aim to use the MVP pattern. The MVP pattern is a +generic concept for how to structure GUI code. MVP allows components +of the GUI to be tested separately and automatically. It also allows +for greater flexibility. Decoupling the model and view means that if +the developer wants to experiment with, for example, a different GUI toolkit, or a different method of doing their calculations, then it is easy and safe to swap out components. A description of each component is given below. @@ -63,7 +63,7 @@ the following sections: * The look of the GUI (often this will be defined in a Qt ``.ui`` file instead) * **Get** methods to return values from the widgets (text input, - button etc) + checkbox etc) * **Set** methods to update the output from the GUI (eg. plot some data, fill in some text boxes) @@ -72,12 +72,10 @@ explanation of signals and slots can be foud `here `_. Briefly, a widget may emit **signals**. For example QPushButton emits the signal ``clicked`` when it is clicked. In order to handle the button being -clicked, the view will implement a **slot** method (in Qt just a -normal method, but specified as a slot with the Qt `slot` -keyword). This method does whatever we need for a button click. To -ensure that this method is called whenever the button is clicked, we -connect the ``clicked`` signal of our button to the -``handleButtonClick`` slot of our view. +clicked, the view will implement a **slot** method. This method does +whatever we need for a button click. To ensure that this method is +called whenever the button is clicked, we connect the ``clicked`` +signal of our button to the ``handleButtonClick`` slot of our view. The view should have a parent - this will be the widget containing it. An example of a parent would be a main window containing tabs - @@ -102,19 +100,21 @@ simple - the presenter generally just calls methods on the presenter. Presenter-view communication is slightly more involved. There are two ways of doing it: -* **Connections** - the presenter may also contain connections. You - may choose to define custom signals in your view, such as a - ``plotRequested`` signal to announce that the user has asked to plot - some data, probably by clicking a button. The presenter will need to - implement a slot (let's call it ``handlePlotRequested``) to handle - this, which gets the relevant data from the model and passes it to - the view, and connect the signal to the slot in its constructor. It - is also possible for a signal emitted by a view to be caught in the - presenter of a parent view. In order to communicate by connections - using Qt in C++ the presenter must inherit from ``QObject``. It's - generally considered good practice to avoid having Qt in the - presenter, so this method works best for GUIs written in Python (or - another language with a more relaxed type system). +* **Connections** - the presenter may contain connections as well as + the view. You may choose to define custom signals in your view, such + as a ``plotRequested`` signal to announce that the user has asked to + plot some data, probably by clicking a button. The presenter will + need to implement a slot (let's call it ``handlePlotRequested``) to + handle this, which gets the relevant data from the model and passes + it to the view. We then need to connect the signal to the slot in + the presenter's constructor. It is also possible for a signal + emitted by a view to be caught in the presenter of a parent view. In + order to communicate by connections using Qt in C++ the presenter + must inherit from ``QObject``. It's generally considered good + practice to avoid having Qt in the presenter, so this method works + best for GUIs written in Python (or another language with a more + relaxed type system). + - Note that is good practice to handle all signals in the presenter if you can, even if it is possible to just handle them in the view. This is because by going through the presenter we can unit @@ -153,14 +153,14 @@ allows us to return a predefined result from a method of either the view or the model. It is useful to mock out the model because, providing that we've -written adequate tests for the it, we don't care what the output is in -the tests for the presenter - we just care that the presenter passes -the output to the view correctly. The model may perform time-consuming -calculations, such as fitting, so by returning a dummy value from the -fitting method we cut down the time our tests take to run. We can also -potentially change how the model works - if the GUI uses an algorithm -which undergoes some changes, such as applying a different set of -corrections, the tests for the presenter will be unaffected. +written adequate tests for it, we don't care what the output is in the +tests for the presenter - we just care that the presenter handles it +correctly. The model may perform time-consuming calculations, such as +fitting, so by returning a dummy value from the fitting method we cut +down the time our tests take to run. We can also potentially change +how the model works - if the GUI uses an algorithm which undergoes +some changes, such as applying a different set of corrections, the +tests for the presenter will be unaffected. It's useful to mock out the view because we don't want to have to manually input data every time the unit tests are run - instead we can @@ -190,8 +190,8 @@ has several advantages: If it is felt that the design must be hand coded then this should be discussed with a senior developer. -Reusable Widget -############### +Reusable Widgets +################ Many interfaces will require similar functionality. For example, the ability to enter a filename string to search for a file along with a @@ -205,45 +205,45 @@ type can be used from within the Qt Designer. The current set of reusable items are: -+-------------------------+---------------+----------+ -| Class Name | Parent Class | Abiltity | -+=========================+===============+==========+ -| AlgorithmSelectorWidget | QWidget | A text box and tree widget to select an algorithm | -+-------------------------+---------------+----------+ -| CatalogSearch | QWidget | An interface interface to the catalog system | -+-------------------------+---------------+----------+ -| CatalogSelector | QWidget | Displays the available catalog services | -+-------------------------+---------------+----------+ -| CheckBoxHeader | QHeaderView | Enables checkboxes to exist in the table header | -+-------------------------+---------------+----------+ -| `ColorBarWidget `_ | QWidget | Show a color bar that can accompany a colored bidimensional plot | -+-------------------------+---------------+----------+ -| DataSelector | MantidWidget | A box to select if input is from a file or workspace along with the appropriate widget to choose a workspace or file. | -+-------------------------+---------------+----------+ -| DisplayCurveFit | MantidWidget | A plot to display the results of a curve fitting process | -+-------------------------+---------------+----------+ -| FindReplaceDialog | QDialog | A dialog box to find/replace text within a ScriptEditor | -+-------------------------+---------------+----------+ -| FitPropertyBrowser | QDockWidget | Specialisation of QPropertyBrowser for defining fitting functions | -+-------------------------+---------------+----------+ -| FunctionBrowser | QWidget | Provides a wiget to alter the parameters of a function | -+-------------------------+---------------+----------+ -| InstrumentSelector | QCombobox | A selection box populated with a list of instruments for the current facility | -+-------------------------+---------------+----------+ -| LineEditWithClear | QLineEdit | A QLineEdit with a button to clear the text | -+-------------------------+---------------+----------+ -| MessageDisplay | QWidget | Display messages from the logging system | -+-------------------------+---------------+----------+ -| MWRunFiles | MantidWidget | Provides a line edit to enter filenames and a browse button to browse the file system | -+-------------------------+---------------+----------+ -| `MWView `_ | QWidget | A colored, bidimensional plot of a matrix workspace | -+-------------------------+---------------+----------+ -| ProcessingAlgoWidget | QWidget | A composite widget that allows a user to select if a processing step is achieved using an algorithm or a Python script. It also provides a script editor. | -+-------------------------+---------------+----------+ -| ScriptEditor | QsciScintilla | The main script editor widget behind the ScriptWindow | -+-------------------------+---------------+----------+ -| WorkspaceSelector | QComboBox | A selection box showing the workspaces currently in Mantid. It can be restricted by type.| -+-------------------------+---------------+----------+ ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Class Name | Parent Class | Abiltity | ++=========================+===============+==============================================================================================================================================================+ +| AlgorithmSelectorWidget | QWidget | A text box and tree widget to select an algorithm | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| CatalogSearch | QWidget | An interface interface to the catalog system | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| CatalogSelector | QWidget | Displays the available catalog services | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| CheckBoxHeader | QHeaderView | Enables checkboxes to exist in the table header | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ColorBarWidget | QWidget | Show a color bar that can accompany a colored bidimensional plot | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DataSelector | MantidWidget | A box to select if input is from a file or workspace along with the appropriate widget to choose a workspace or file. | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| DisplayCurveFit | MantidWidget | A plot to display the results of a curve fitting process | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| FindReplaceDialog | QDialog | A dialog box to find/replace text within a ScriptEditor | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| FitPropertyBrowser | QDockWidget | Specialisation of QPropertyBrowser for defining fitting functions | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| FunctionBrowser | QWidget | Provides a wiget to alter the parameters of a function | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| InstrumentSelector | QCombobox | A selection box populated with a list of instruments for the current facility | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| LineEditWithClear | QLineEdit | A QLineEdit with a button to clear the text | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| MessageDisplay | QWidget | Display messages from the logging system | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| MWRunFiles | MantidWidget | Provides a line edit to enter filenames and a browse button to browse the file system | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| MWView | QWidget | A colored, bidimensional plot of a matrix workspace | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ProcessingAlgoWidget | QWidget | A composite widget that allows a user to select if a processing step is achieved using an algorithm or a Python script. It also provides a script editor. | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ScriptEditor | QsciScintilla | The main script editor widget behind the ScriptWindow | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| WorkspaceSelector | QComboBox | A selection box showing the workspaces currently in Mantid. It can be restricted by type. | ++-------------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ Python ###### @@ -273,7 +273,7 @@ file would look like: where ``FooGUI`` is the ``MainWindow`` for the interface. Designer -^^^^^^^^ +-------- As with the C++ GUI the Qt Designer should be used for layouts of all widgets and the main interface. It is recommended that the ``.ui`` From c8ba192f751c444a0594d79c44673cb1b4487064 Mon Sep 17 00:00:00 2001 From: Gemma Guest Date: Thu, 15 Mar 2018 17:51:55 +0000 Subject: [PATCH 265/364] Revert "Re #20991: Updated RROv2 doctest." This reverts commit 30327a6e646b7f1e8b1c6c77654f49cff0e62331. --- docs/source/algorithms/ReflectometryReductionOne-v2.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/algorithms/ReflectometryReductionOne-v2.rst b/docs/source/algorithms/ReflectometryReductionOne-v2.rst index 4331a2e78b62..aa317703b266 100644 --- a/docs/source/algorithms/ReflectometryReductionOne-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOne-v2.rst @@ -254,10 +254,10 @@ Output: .. testoutput:: ExReflRedOneTrans - 0.4597 + 0.4592 0.4654 - 0.7204 - 1.0509 + 0.7278 + 1.0305 .. categories:: From 5812e2cc41d364621e48af2ce65184b45625db72 Mon Sep 17 00:00:00 2001 From: Duc Le Date: Thu, 15 Mar 2018 15:56:33 +0000 Subject: [PATCH 266/364] Re #22114 - Reinstate checks for when to apply binwidth normalisation --- Framework/DataObjects/src/FractionalRebinning.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Framework/DataObjects/src/FractionalRebinning.cpp b/Framework/DataObjects/src/FractionalRebinning.cpp index 4bad6f9ee087..fea485fb2220 100644 --- a/Framework/DataObjects/src/FractionalRebinning.cpp +++ b/Framework/DataObjects/src/FractionalRebinning.cpp @@ -478,6 +478,8 @@ void calcGeneralIntersections( void normaliseOutput(MatrixWorkspace_sptr outputWS, MatrixWorkspace_const_sptr inputWS, boost::shared_ptr progress) { + const bool removeBinWidth(inputWS->isDistribution() && + inputWS->id() != "RebinnedOutput"); for (int64_t i = 0; i < static_cast(outputWS->getNumberHistograms()); ++i) { const auto &outputX = outputWS->x(i); @@ -487,7 +489,7 @@ void normaliseOutput(MatrixWorkspace_sptr outputWS, if (progress) progress->report("Calculating errors"); double eValue = std::sqrt(outputE[j]); - if (inputWS->isDistribution()) { + if (removeBinWidth) { const double binWidth = outputX[j + 1] - outputX[j]; outputY[j] /= binWidth; eValue /= binWidth; @@ -599,8 +601,10 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ, // If the input workspace was normalized by the bin width, we need to // recover the original Y value, we do it by 'removing' the bin width + // Don't do the overlap removal if already RebinnedOutput. + // This wreaks havoc on the data. double error = inE[j]; - if (inputWS->isDistribution()) { + if (inputWS->isDistribution() && inputWS->id() != "RebinnedOutput") { const double overlapWidth = inX[j + 1] - inX[j]; signal *= overlapWidth; error *= overlapWidth; From a16dc526cf38db3d26dd031c2204451f74f53326 Mon Sep 17 00:00:00 2001 From: Duc Le Date: Thu, 15 Mar 2018 17:06:13 +0000 Subject: [PATCH 267/364] Re #22114 - Slight mods for RB output (inc binwidth in weight) --- Framework/DataObjects/src/FractionalRebinning.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Framework/DataObjects/src/FractionalRebinning.cpp b/Framework/DataObjects/src/FractionalRebinning.cpp index fea485fb2220..ff317cc6cce6 100644 --- a/Framework/DataObjects/src/FractionalRebinning.cpp +++ b/Framework/DataObjects/src/FractionalRebinning.cpp @@ -479,7 +479,7 @@ void normaliseOutput(MatrixWorkspace_sptr outputWS, MatrixWorkspace_const_sptr inputWS, boost::shared_ptr progress) { const bool removeBinWidth(inputWS->isDistribution() && - inputWS->id() != "RebinnedOutput"); + outputWS->id() != "RebinnedOutput"); for (int64_t i = 0; i < static_cast(outputWS->getNumberHistograms()); ++i) { const auto &outputX = outputWS->x(i); @@ -604,10 +604,12 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ, // Don't do the overlap removal if already RebinnedOutput. // This wreaks havoc on the data. double error = inE[j]; - if (inputWS->isDistribution() && inputWS->id() != "RebinnedOutput") { + double inputWeight = 1.; + if (inputWS->isDistribution() && !inputRB) { const double overlapWidth = inX[j + 1] - inX[j]; signal *= overlapWidth; error *= overlapWidth; + inputWeight = overlapWidth; } // The intersection overlap algorithm is relatively costly. The outputQ is @@ -630,7 +632,6 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ, // If the input is a RebinnedOutput workspace with frac. area we need // to account for the weight of the input bin in the output bin weights - double inputWeight = 1.; if (inputRB) { const auto &inF = inputRB->dataF(i); inputWeight = inF[j]; From 3ee66caacd6f3b073de85c92e586033a18b9f014 Mon Sep 17 00:00:00 2001 From: Duc Le Date: Thu, 15 Mar 2018 17:07:01 +0000 Subject: [PATCH 268/364] Re #22114 - Fixed unit test --- Framework/Algorithms/test/SofQWCutTest.h | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Framework/Algorithms/test/SofQWCutTest.h b/Framework/Algorithms/test/SofQWCutTest.h index 93f98324fcaa..ea13b7476613 100644 --- a/Framework/Algorithms/test/SofQWCutTest.h +++ b/Framework/Algorithms/test/SofQWCutTest.h @@ -188,16 +188,16 @@ class SofQWCutTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS((*(ws_q->getAxis(1)))(0), 0.0); TS_ASSERT_DELTA((*(ws_q->getAxis(1)))(400), 5.0, delta); TS_ASSERT_EQUALS((*(ws_q->getAxis(1)))(800), 10.); - TS_ASSERT_DELTA(ws_q->readY(64)[0], 0.144715421, delta); - TS_ASSERT_DELTA(ws_q->readE(64)[0], 0.007981350, delta); - TS_ASSERT_DELTA(ws_q->readY(345)[0], 0.658678386, delta); - TS_ASSERT_DELTA(ws_q->readE(345)[0], 0.029371568, delta); - TS_ASSERT_DELTA(ws_q->readY(595)[0], 0.159563545, delta); - TS_ASSERT_DELTA(ws_q->readE(595)[0], 0.012046158, delta); - TS_ASSERT_DELTA(ws_q->readY(683)[0], 0.178108225, delta); - TS_ASSERT_DELTA(ws_q->readE(683)[0], 0.019119298, delta); - TS_ASSERT_DELTA(ws_q->readY(745)[0], 2.086237760, delta); - TS_ASSERT_DELTA(ws_q->readE(745)[0], 0.048837503, delta); + TS_ASSERT_DELTA(ws_q->readY(64)[0], 1.447154208, delta); + TS_ASSERT_DELTA(ws_q->readE(64)[0], 0.079813500, delta); + TS_ASSERT_DELTA(ws_q->readY(345)[0], 6.586783859, delta); + TS_ASSERT_DELTA(ws_q->readE(345)[0], 0.293715678, delta); + TS_ASSERT_DELTA(ws_q->readY(595)[0], 1.595635453, delta); + TS_ASSERT_DELTA(ws_q->readE(595)[0], 0.120461583, delta); + TS_ASSERT_DELTA(ws_q->readY(683)[0], 1.781082246, delta); + TS_ASSERT_DELTA(ws_q->readE(683)[0], 0.191192978, delta); + TS_ASSERT_DELTA(ws_q->readY(745)[0], 20.862377605, delta); + TS_ASSERT_DELTA(ws_q->readE(745)[0], 0.488375031, delta); auto ws_e = boost::dynamic_pointer_cast(result->getItem(1)); @@ -210,16 +210,16 @@ class SofQWCutTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(ws_e->getAxis(1)->unit()->unitID(), "MomentumTransfer"); TS_ASSERT_EQUALS((*(ws_e->getAxis(1)))(0), 5.); TS_ASSERT_EQUALS((*(ws_e->getAxis(1)))(1), 10.); - TS_ASSERT_DELTA(ws_e->readY(0)[3], 2.003485282, delta); - TS_ASSERT_DELTA(ws_e->readE(0)[3], 0.013726709, delta); - TS_ASSERT_DELTA(ws_e->readY(0)[20], 0.136945077, delta); - TS_ASSERT_DELTA(ws_e->readE(0)[20], 0.003767914, delta); - TS_ASSERT_DELTA(ws_e->readY(0)[27], 0.158356991, delta); - TS_ASSERT_DELTA(ws_e->readE(0)[27], 0.004113822, delta); - TS_ASSERT_DELTA(ws_e->readY(0)[78], 0.197240860, delta); - TS_ASSERT_DELTA(ws_e->readE(0)[78], 0.005446083, delta); - TS_ASSERT_DELTA(ws_e->readY(0)[119], 0.027223857, delta); - TS_ASSERT_DELTA(ws_e->readE(0)[119], 0.003277629, delta); + TS_ASSERT_DELTA(ws_e->readY(0)[3], 3.339142136, delta); + TS_ASSERT_DELTA(ws_e->readE(0)[3], 0.022877849, delta); + TS_ASSERT_DELTA(ws_e->readY(0)[20], 0.228241794, delta); + TS_ASSERT_DELTA(ws_e->readE(0)[20], 0.006279856, delta); + TS_ASSERT_DELTA(ws_e->readY(0)[27], 0.263928319, delta); + TS_ASSERT_DELTA(ws_e->readE(0)[27], 0.006856371, delta); + TS_ASSERT_DELTA(ws_e->readY(0)[78], 0.328734767, delta); + TS_ASSERT_DELTA(ws_e->readE(0)[78], 0.009076805, delta); + TS_ASSERT_DELTA(ws_e->readY(0)[119], 0.045373095, delta); + TS_ASSERT_DELTA(ws_e->readE(0)[119], 0.005462714, delta); } }; From 0037878df9f37d4401d94ffbe8aee424e65c1c95 Mon Sep 17 00:00:00 2001 From: Gemma Guest Date: Thu, 15 Mar 2018 17:56:18 +0000 Subject: [PATCH 269/364] Add additional fix to INTER IDF requested by scientists Re #20991 --- instrument/INTER_Definition.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrument/INTER_Definition.xml b/instrument/INTER_Definition.xml index d2a4f82f07d0..fa286b8d69cd 100644 --- a/instrument/INTER_Definition.xml +++ b/instrument/INTER_Definition.xml @@ -113,8 +113,8 @@ - - + + From 673a59218d4e639e27751b49242924d64b9bbc24 Mon Sep 17 00:00:00 2001 From: Gemma Guest Date: Thu, 15 Mar 2018 18:00:36 +0000 Subject: [PATCH 270/364] Update SURF IDF with latest position changes from scientists Re #20991 --- instrument/SURF_Definition.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/instrument/SURF_Definition.xml b/instrument/SURF_Definition.xml index 227ebacc475e..d39c3fec1188 100644 --- a/instrument/SURF_Definition.xml +++ b/instrument/SURF_Definition.xml @@ -17,7 +17,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -133,7 +133,7 @@ - + @@ -141,7 +141,7 @@ - + @@ -151,7 +151,7 @@ - + @@ -182,7 +182,7 @@ - + From 6880685091b7612259eaeba771a4e5dabd800115 Mon Sep 17 00:00:00 2001 From: Gemma Guest Date: Thu, 15 Mar 2018 18:10:35 +0000 Subject: [PATCH 271/364] Add new SURF IDF version for slit log name change Re #20991 --- instrument/SURF_Definition.xml | 4 +- instrument/SURF_Definition_2017.xml | 205 ++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 instrument/SURF_Definition_2017.xml diff --git a/instrument/SURF_Definition.xml b/instrument/SURF_Definition.xml index d39c3fec1188..382c01e0c025 100644 --- a/instrument/SURF_Definition.xml +++ b/instrument/SURF_Definition.xml @@ -6,8 +6,8 @@ xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd" name="SURF" valid-from="2010-01-10 23:59:59" - valid-to="2100-01-30 23:59:59" - last-modified="2018-02-22 00:00:00"> + valid-to="2017-02-13 23:59:59" + last-modified="2018-03-15 00:00:00"> diff --git a/instrument/SURF_Definition_2017.xml b/instrument/SURF_Definition_2017.xml new file mode 100644 index 000000000000..4bec930ff53a --- /dev/null +++ b/instrument/SURF_Definition_2017.xml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + 40mm(H) x 60mm(W) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b76033304e2312c07fd196ada0747b2b6baec9f1 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Thu, 15 Mar 2018 18:25:16 +0000 Subject: [PATCH 272/364] Update MSlice to version 1.0.0 --- scripts/ExternalInterfaces/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ExternalInterfaces/CMakeLists.txt b/scripts/ExternalInterfaces/CMakeLists.txt index 2d2e986408d0..49b608f4bbdb 100644 --- a/scripts/ExternalInterfaces/CMakeLists.txt +++ b/scripts/ExternalInterfaces/CMakeLists.txt @@ -6,7 +6,7 @@ set ( _mslice_external_root ${CMAKE_CURRENT_BINARY_DIR}/mslice ) ExternalProject_Add ( mslice PREFIX ${_mslice_external_root} GIT_REPOSITORY "https://github.com/mantidproject/mslice.git" - GIT_TAG d8932699da4a76dfd88eb1d3d6dcde580debafce + GIT_TAG 560cc9351596b0078b201b9e1785e3c5a745f375 EXCLUDE_FROM_ALL 1 CONFIGURE_COMMAND "" From 6e15fd3572e797a7e0a514e9ebfa7009b7360ebb Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Thu, 15 Mar 2018 18:30:54 +0000 Subject: [PATCH 273/364] Fix Sphinx warning in direct inelastic docs --- docs/source/release/v3.12.0/direct_inelastic.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/release/v3.12.0/direct_inelastic.rst b/docs/source/release/v3.12.0/direct_inelastic.rst index 8a67b93babb8..7a4903d60b7d 100644 --- a/docs/source/release/v3.12.0/direct_inelastic.rst +++ b/docs/source/release/v3.12.0/direct_inelastic.rst @@ -24,7 +24,6 @@ New features :width: 500 px .. figure:: ../../images/mslice_acut.png - :class: screenshot :align: center :width: 500 px From ee7920c00a7b3cea973099262af1b32bf4740b6b Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Fri, 16 Mar 2018 08:44:26 +0000 Subject: [PATCH 274/364] Fix RPATH for Vates widgets library libMantidVatesSimpleGuiViewWidgetsQt4.so is dependant on libMantidVatesSimpleGuiQtWidgetsQt4.so which was previously not being found due to the RPATH not searcing in the same directory. Without this change the Vates Simple Interface is not available. --- qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt index fd315f848220..68d604c13eb6 100644 --- a/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt +++ b/qt/paraview_ext/VatesSimpleGui/ViewWidgets/CMakeLists.txt @@ -136,7 +136,7 @@ mtd_add_qt_library (TARGET_NAME VatesSimpleGuiViewWidgets @loader_path/../../Contents/MacOS @loader_path/../../Contents/Libraries LINUX_INSTALL_RPATH - "\$ORIGIN/../../${LIB_DIR}" + "\$ORIGIN/../../${LIB_DIR};\$ORIGIN" ) # Set the name of the generated library From e7481a9c2ab4203b83f1e57cef1c6244fd8f5463 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Fri, 16 Mar 2018 10:39:58 +0000 Subject: [PATCH 275/364] Re #22119 Added events to change status of middle button --- scripts/ErrorReporter/errorreport.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/ErrorReporter/errorreport.py b/scripts/ErrorReporter/errorreport.py index 267d962ca7cf..5f2ead585956 100644 --- a/scripts/ErrorReporter/errorreport.py +++ b/scripts/ErrorReporter/errorreport.py @@ -19,6 +19,9 @@ def __init__(self, parent=None): self.requestTextBrowser.anchorClicked.connect(MantidQt.API.MantidDesktopServices.openUrl) + self.input_name_line_edit.textChanged.connect(self.set_button_status) + self.input_email_line_edit.textChanged.connect(self.set_button_status) + # The options on what to do after closing the window (exit/continue) self.radioButtonContinue.setChecked(True) # Set continue to be checked by default @@ -47,6 +50,12 @@ def get_simple_line_edit_field(self, expected_type, line_edit): value_as_string = gui_element.text() return expected_type(value_as_string) if value_as_string else None + def set_button_status(self): + if not self.input_name and not self.input_email: + self.nonIDShareButton.setEnabled(True) + else: + self.nonIDShareButton.setEnabled(False) + @property def input_name(self): return self.get_simple_line_edit_field(line_edit="input_name_line_edit", expected_type=str) From a8314a4967d96031c1b6a2a0f266b73c1572de5e Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Fri, 16 Mar 2018 11:03:24 +0000 Subject: [PATCH 276/364] Add dev-docs to check_for_changes script Changes to dev-docs are now identified as doc changes so builds can be skipped if necessary. --- buildconfig/Jenkins/check_for_changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildconfig/Jenkins/check_for_changes b/buildconfig/Jenkins/check_for_changes index f46e26b59c1d..27e070d4afec 100755 --- a/buildconfig/Jenkins/check_for_changes +++ b/buildconfig/Jenkins/check_for_changes @@ -40,7 +40,7 @@ case "$TYPE" in # FOUND=1 iff changes are limited to docs or GUI only # Find all changed files and grep for required type. -v inverts match so grep=0 means # there are other changes besides this - if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/|^qt/|^MantidPlot/'; then + if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/|^dev-docs/|^qt/|^MantidPlot/'; then exit $FOUND else exit $NOTFOUND From bbef4238011159a6967c037d02bfdfd3595b3e23 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Fri, 16 Mar 2018 11:16:19 +0000 Subject: [PATCH 277/364] Frequency domain analysis produces warning if no data --- docs/source/release/v3.12.0/muon.rst | 1 + scripts/Frequency_Domain_Analysis.py | 13 +++++++++---- scripts/Muon/load_utils.py | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 288c2d8f1f22..45740fd7982b 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -32,6 +32,7 @@ Improvements - The period summation/subtraction can now be used in multiple fitting. - Muon analysis now handles the "auto background" gracefully in single and multiple fitting modes. - We have disabled some non functional graph right click context menu items or adding functions when in multi data fitting mode, in the Data Analysis tab of the Muon Analysis Interface. +- Frequency domain analysis will produce a warning if there is no data to load. Bug fixes ######### diff --git a/scripts/Frequency_Domain_Analysis.py b/scripts/Frequency_Domain_Analysis.py index be4a39c69495..a7a1d58180e2 100644 --- a/scripts/Frequency_Domain_Analysis.py +++ b/scripts/Frequency_Domain_Analysis.py @@ -37,7 +37,12 @@ def qapp(): app = qapp() -ex= FrequencyDomainAnalysisGui() -ex.resize(700,700) -ex.show() -app.exec_() +try: + ex= FrequencyDomainAnalysisGui() + ex.resize(700,700) + ex.show() + app.exec_() +except RuntimeError as error: + ex = QtGui.QWidget() + QtGui.QMessageBox.warning(ex,"Frequency Domain Analysis",str(error)) + diff --git a/scripts/Muon/load_utils.py b/scripts/Muon/load_utils.py index 6a4b9718a50e..26a9a4ad8bee 100644 --- a/scripts/Muon/load_utils.py +++ b/scripts/Muon/load_utils.py @@ -13,7 +13,7 @@ def __init__(self, parent=None): if exists: self.setUp(tmpWS) else: - mantid.logger.error("Muon Analysis workspace does not exist - no data loaded") + raise RuntimeError("No data loaded. \n Please load data using Muon Analysis") def setUp(self,tmpWS): # get everything from the ADS From d4d8badac38c6b96ca93df9b779ad671d1d683db Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 15 Mar 2018 13:30:17 +0000 Subject: [PATCH 278/364] Re #22109: Added rst version of wiki page with minor edits + updates. --- dev-docs/source/Python3.rst | 118 ++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 dev-docs/source/Python3.rst diff --git a/dev-docs/source/Python3.rst b/dev-docs/source/Python3.rst new file mode 100644 index 000000000000..55fc190b9997 --- /dev/null +++ b/dev-docs/source/Python3.rst @@ -0,0 +1,118 @@ +======== +Python 3 +======== + +Python 2 has an `end-of-life date set for 2020 `_ +and now that most third-party packages support both 2 and 3 we are starting to think about a +migration strategy for Mantid. + +.. contents:: + :local: + +Building Against Python 3 +######################### + +This is currently only possible on a Linux system with a pre-installed version of python 3. You need +to install some additional packages as shown below: + +.. code-block:: sh + + apt-get install python3-sip-dev python3-pyqt4 python3-numpy python3-scipy python3-sphinx \ + python3-sphinx-bootstrap-theme python3-dateutil python3-matplotlib ipython3-qtconsole \ + python3-h5py python3-yaml + +or on fedora, with slightly different package names + +.. code-block:: sh + + dnf install python3-sip-devel python3-PyQt4-devel python3-numpy python3-scipy python3-sphinx \ + python3-sphinx-theme-bootstrap python3-dateutil python3-matplotlib python3-ipython-gui \ + boost-python3-devel python3-h5py python3-yaml + +then set ``-DPYTHON_EXECUTABLE=/usr/bin/python3`` when running cmake before building. + +.. warning:: + If any of these packages are installed via pip, this could cause conflicts. + Install as described here only. + +Supporting Python 2 and 3 +######################### + +Python 3 introduces many exciting new features. For a full description see the official Python 3 +changes document. For a shorter overview see +`here `__ or +`here `__. + +Some features of Python 3 have been backported to Python 2.x within the +`__future__ `_ +module. These make it easier to write code that is compatible with both versions. + +This cheat sheet provides helpful examples of how to write code in a 2/3 compatible manner. Where an +option is given to use either the `six `_ or +`future `_ (not to be confused with ``__future__``!) modules +then ``six`` is used. + +All new code should be written to be compatible with Python 2 & 3 and as a minimum the first import +line of the module should be: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + +It is quite common to also see ``unicode_literals`` in the above import list, however, when running +under Python 2 ``Boost.Python`` will not automatically convert a Python ``str`` to C++ ``std::string`` +automatically if the string is unicode. When running with Python 3 ``Boost.Python`` will do this +conversion automatically for unicode strings so this is in fact not a huge issue going forward. + +Migrating From Python 2 to 3 +############################ + +One way to migrate a file from python 2 to 3 is as follows... + +.. warning:: + | To perform the following procedure on windows: + | 1. Git Bash or similar will be required. + | 2. To run the ``2to3`` script you will need to start the command-prompt.bat in the build directory and run ``%PYTHONHOME%\Scripts\2to3`` + +Run the following script to run the python 2 to 3 translation tool and rename the file to ``filename.py.bak`` + +.. code-block:: sh + + 2to3 --no-diffs -w filename.py + mv filename.py{,.bak}; + + +Run **one** of the following commands to append the import statement listed above. + +.. code-block:: sh + + awk '/(from|import)/ && !x {print "from __future__ import (absolute_import, division, print_function)\n"; x=1} 1' \ + filename.py.bak > filename.py + +**or** + +.. code-block:: sh + + sed -i '0,/^import\|from.*/s/^import\|from.*/from __future__ import (absolute_import, division, print_function)\n&/' filename.py + +Check each changed block, + +- If any change has replaced ``xrange`` with ``range`` then add ``from six.moves import range`` + to the imports list +- If any change has replaced ``ifilterfalse`` with ``filterfalse`` from ``itertools`` then replace a + statement like ``from itertools import filterfalse`` with ``from six.moves import filterfalse`` in the + imports list. There are more cases like this documented `here `_. +- If any change has replaced ``for k, v in knights.iteritems()`` with ``for k, v in knights.items()`` + then add ``from six import iteritems`` to the import list and update the replacement to + ``for k, v in iteritems(knights)``. + +In some cases like ``range``, pylint will complain about `Replacing builtin 'range'` or similar. +Make sure to put the proper ignore statement on that line using ``#pylint: disable=redefined-builtin``. + +Check the code still runs as expected in Python 2. + +.. note:: + ``2to3`` will try to keep the type of the objects the same. So, for example ``range(5)`` will + become ``list(range(5))``. This is not necessary if you use it just for iteration. Things like + ``for i in range(5)`` will work in both versions of Python, you don't need to transform it into a + list. From 66e8c864e10134f4ed6722c5accca6fbc3a88c21 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Fri, 16 Mar 2018 11:26:09 +0000 Subject: [PATCH 279/364] Fix all parameters from top-level function. Re #22115 --- qt/widgets/common/src/FunctionBrowser.cpp | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/qt/widgets/common/src/FunctionBrowser.cpp b/qt/widgets/common/src/FunctionBrowser.cpp index a56c11eb07b5..e4bf7c95b779 100644 --- a/qt/widgets/common/src/FunctionBrowser.cpp +++ b/qt/widgets/common/src/FunctionBrowser.cpp @@ -932,26 +932,7 @@ void FunctionBrowser::addTieProperty(QtProperty *prop, QString tie) { if (!isParameter(prop)) return; - Mantid::API::Expression expr; - expr.parse(tie.toStdString()); - // Do parameter names include composite function index - bool isComposite = false; - auto vars = expr.getVariables(); - for (auto var = vars.begin(); var != vars.end(); ++var) { - // nesting level of a particular variable - int n = static_cast(std::count(var->begin(), var->end(), '.')); - if (n != 0) { - isComposite = true; - } - } - - // Find the property of the function that this tie will be set to: - // If the tie has variables that contain function indices (f0.f1. ...) - // then it will be set to the topmost composite function. - // If the tie is a number or has only simple variable names then it belongs - // to the local function (the one that has the tied parameter) - QtProperty *funProp = - isComposite ? getFunctionProperty().prop : m_properties[prop].parent; + QtProperty *funProp = getFunctionProperty().prop; // Create and add a QtProperty for the tie. m_tieManager->blockSignals(true); From 62a3d9351e0bbfde81cc66a45a2204c22e355ec3 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Fri, 16 Mar 2018 11:36:46 +0000 Subject: [PATCH 280/364] Frequency domain analysis blank line rm# --- scripts/Frequency_Domain_Analysis.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/Frequency_Domain_Analysis.py b/scripts/Frequency_Domain_Analysis.py index a7a1d58180e2..c8eefe082472 100644 --- a/scripts/Frequency_Domain_Analysis.py +++ b/scripts/Frequency_Domain_Analysis.py @@ -45,4 +45,3 @@ def qapp(): except RuntimeError as error: ex = QtGui.QWidget() QtGui.QMessageBox.warning(ex,"Frequency Domain Analysis",str(error)) - From 104ac5f40ad87a5ede8d42598aa866f28c935d12 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Fri, 16 Mar 2018 12:03:49 +0000 Subject: [PATCH 281/364] Re #22124 Fixed find direction --- .../WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py | 3 ++- scripts/Interface/ui/sans_isis/beam_centre.py | 2 +- scripts/SANS/sans/gui_logic/models/beam_centre_model.py | 9 +++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py index f0ab4f123599..c34e32999258 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py @@ -203,7 +203,8 @@ def PyExec(self): logger.notice("Itr " + str(j) + ": (" + str(self.scale_1 * centre1) + ", " + str(self.scale_2 * centre2) + ") SX=" + str(residueLR[j]) + " SY=" + str(residueTB[j])) - if (residueLR[j]+residueTB[j]) < (residueLR[j-1]+residueTB[j-1]) or state.compatibility.use_compatibility_mode: + combined_residual = [sum(x) for x in zip(residueLR, residueTB)] + if combined_residual[j] is min(combined_residual) or state.compatibility.use_compatibility_mode: centre_1_hold = centre1 centre_2_hold = centre2 diff --git a/scripts/Interface/ui/sans_isis/beam_centre.py b/scripts/Interface/ui/sans_isis/beam_centre.py index 55053098c225..0ded1c83bd4c 100644 --- a/scripts/Interface/ui/sans_isis/beam_centre.py +++ b/scripts/Interface/ui/sans_isis/beam_centre.py @@ -176,7 +176,7 @@ def left_right(self, value): @property def up_down(self): - return self.left_right_check_box.isChecked() + return self.up_down_check_box.isChecked() @up_down.setter def up_down(self, value): diff --git a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py index d9278e7d46d0..74b29cdb2367 100644 --- a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py +++ b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py @@ -1,4 +1,5 @@ from sans.common.enums import (SANSInstrument, FindDirectionEnum) +from mantid.kernel import (Logger) class BeamCentreModel(object): @@ -53,9 +54,13 @@ def find_beam_centre(self, state): if self.up_down and self.left_right: find_direction = FindDirectionEnum.All elif self.up_down: - find_direction = FindDirectionEnum.Left_Right - elif self.left_right: find_direction = FindDirectionEnum.Up_Down + elif self.left_right: + find_direction = FindDirectionEnum.Left_Right + else: + logger = Logger("CentreFinder") + logger.notice("Have chosen no find direction exiting early") + return {"pos1": self.lab_pos_1, "pos2": self.lab_pos_2} if self.q_min: state.convert_to_q.q_min = self.q_min From ee7a0d5361d99cf95a7ac97c9b062da6fedcbd1f Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Fri, 16 Mar 2018 13:49:45 +0000 Subject: [PATCH 282/364] Revert "SANS beam centre crashes with no find direction" --- .../WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py | 3 +-- scripts/Interface/ui/sans_isis/beam_centre.py | 2 +- scripts/SANS/sans/gui_logic/models/beam_centre_model.py | 9 ++------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py index c34e32999258..f0ab4f123599 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py @@ -203,8 +203,7 @@ def PyExec(self): logger.notice("Itr " + str(j) + ": (" + str(self.scale_1 * centre1) + ", " + str(self.scale_2 * centre2) + ") SX=" + str(residueLR[j]) + " SY=" + str(residueTB[j])) - combined_residual = [sum(x) for x in zip(residueLR, residueTB)] - if combined_residual[j] is min(combined_residual) or state.compatibility.use_compatibility_mode: + if (residueLR[j]+residueTB[j]) < (residueLR[j-1]+residueTB[j-1]) or state.compatibility.use_compatibility_mode: centre_1_hold = centre1 centre_2_hold = centre2 diff --git a/scripts/Interface/ui/sans_isis/beam_centre.py b/scripts/Interface/ui/sans_isis/beam_centre.py index 0ded1c83bd4c..55053098c225 100644 --- a/scripts/Interface/ui/sans_isis/beam_centre.py +++ b/scripts/Interface/ui/sans_isis/beam_centre.py @@ -176,7 +176,7 @@ def left_right(self, value): @property def up_down(self): - return self.up_down_check_box.isChecked() + return self.left_right_check_box.isChecked() @up_down.setter def up_down(self, value): diff --git a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py index 74b29cdb2367..d9278e7d46d0 100644 --- a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py +++ b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py @@ -1,5 +1,4 @@ from sans.common.enums import (SANSInstrument, FindDirectionEnum) -from mantid.kernel import (Logger) class BeamCentreModel(object): @@ -54,13 +53,9 @@ def find_beam_centre(self, state): if self.up_down and self.left_right: find_direction = FindDirectionEnum.All elif self.up_down: - find_direction = FindDirectionEnum.Up_Down - elif self.left_right: find_direction = FindDirectionEnum.Left_Right - else: - logger = Logger("CentreFinder") - logger.notice("Have chosen no find direction exiting early") - return {"pos1": self.lab_pos_1, "pos2": self.lab_pos_2} + elif self.left_right: + find_direction = FindDirectionEnum.Up_Down if self.q_min: state.convert_to_q.q_min = self.q_min From d1927a8ef3da48987b194f238ff239fe8aca0642 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Fri, 16 Mar 2018 14:01:30 +0000 Subject: [PATCH 283/364] Re #22124 Removed change that failed system tests --- .../algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py index c34e32999258..f0ab4f123599 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANS/SANSBeamCentreFinder.py @@ -203,8 +203,7 @@ def PyExec(self): logger.notice("Itr " + str(j) + ": (" + str(self.scale_1 * centre1) + ", " + str(self.scale_2 * centre2) + ") SX=" + str(residueLR[j]) + " SY=" + str(residueTB[j])) - combined_residual = [sum(x) for x in zip(residueLR, residueTB)] - if combined_residual[j] is min(combined_residual) or state.compatibility.use_compatibility_mode: + if (residueLR[j]+residueTB[j]) < (residueLR[j-1]+residueTB[j-1]) or state.compatibility.use_compatibility_mode: centre_1_hold = centre1 centre_2_hold = centre2 From 06ed4acfce7e21df9568856790867ee878f2ce95 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Fri, 16 Mar 2018 15:18:34 +0000 Subject: [PATCH 284/364] Re #22124 Fixed find direction --- scripts/Interface/ui/sans_isis/beam_centre.py | 2 +- scripts/SANS/sans/gui_logic/models/beam_centre_model.py | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/Interface/ui/sans_isis/beam_centre.py b/scripts/Interface/ui/sans_isis/beam_centre.py index 55053098c225..0ded1c83bd4c 100644 --- a/scripts/Interface/ui/sans_isis/beam_centre.py +++ b/scripts/Interface/ui/sans_isis/beam_centre.py @@ -176,7 +176,7 @@ def left_right(self, value): @property def up_down(self): - return self.left_right_check_box.isChecked() + return self.up_down_check_box.isChecked() @up_down.setter def up_down(self, value): diff --git a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py index d9278e7d46d0..74b29cdb2367 100644 --- a/scripts/SANS/sans/gui_logic/models/beam_centre_model.py +++ b/scripts/SANS/sans/gui_logic/models/beam_centre_model.py @@ -1,4 +1,5 @@ from sans.common.enums import (SANSInstrument, FindDirectionEnum) +from mantid.kernel import (Logger) class BeamCentreModel(object): @@ -53,9 +54,13 @@ def find_beam_centre(self, state): if self.up_down and self.left_right: find_direction = FindDirectionEnum.All elif self.up_down: - find_direction = FindDirectionEnum.Left_Right - elif self.left_right: find_direction = FindDirectionEnum.Up_Down + elif self.left_right: + find_direction = FindDirectionEnum.Left_Right + else: + logger = Logger("CentreFinder") + logger.notice("Have chosen no find direction exiting early") + return {"pos1": self.lab_pos_1, "pos2": self.lab_pos_2} if self.q_min: state.convert_to_q.q_min = self.q_min From b82f6bfaddde1a8d547d5939083bd5c08551bd5e Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Fri, 16 Mar 2018 16:26:17 +0100 Subject: [PATCH 285/364] Extend directtools docs, append some non-public methods with '_'. Re #21901 --- .../techniques/Directtools Python module.rst | 24 +- scripts/directtools/__init__.py | 235 ++++++++++++++++-- 2 files changed, 232 insertions(+), 27 deletions(-) diff --git a/docs/source/techniques/Directtools Python module.rst b/docs/source/techniques/Directtools Python module.rst index 6dcf5a66b884..45bd9feacb69 100644 --- a/docs/source/techniques/Directtools Python module.rst +++ b/docs/source/techniques/Directtools Python module.rst @@ -6,14 +6,34 @@ :literal:`directtools` is a Python module for quickly plotting standardized :math:`S(Q,E)` color fill plots as well as line profiles (cuts) in constant :math:`Q` and :math:`E`. The module also provides a few utility functions for inspecting and manipulating the :math:`S(Q,E)` workspace. +For a general introduction on using :mod:`matplotlib` with Mantid, see :ref:`this introduction ` + +.. plot:: + :include-source: + + import directtools as dt + from mantid.simpleapi import * + + DirectILLCollectData(Run='ILL/IN4/084447', OutputWorkspace='data') + DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW') + + fig, ax = dt.plotSofQW('SofQW') + #fig.show() + Reference ========= +Classes +####### + .. autoclass:: directtools.SampleLogs :members: __init__ +Functions +######### + .. automodule:: directtools - :members: dynamicsusceptibility, nanminmax, plotcuts, plotprofiles, plotconstE, - plotconstQ, plotSofQW, subplots, validQ, wsreport + :members: box2D, defaultrcParams, dynamicsusceptibility, nanminmax, plotconstE, + plotconstQ, plotcuts, plotprofiles, plotSofQW, subplots, validQ, wsreport .. categories:: Techniques diff --git a/scripts/directtools/__init__.py b/scripts/directtools/__init__.py index 6aea8a736947..fb40a60ab2ba 100644 --- a/scripts/directtools/__init__.py +++ b/scripts/directtools/__init__.py @@ -33,6 +33,11 @@ def _clearlatex(s): return s +def _configurematplotlib(params): + """Set matplotlib rc parameters from the params dictionary.""" + matplotlib.rcParams.update(params) + + def _finalizeprofileE(axes): """Set axes for const E axes.""" axes.set_xlim(xmin=0.) @@ -111,6 +116,11 @@ def _binCentres(edges): return (edges[:-1] + edges[1:]) / 2 +def _mantidsubplotsetup(): + """Return the Mantid projection setup.""" + return {'projection': 'mantid'} + + def _profiletitle(workspaces, scan, units, cuts, widths, figure): """Add title to line profile figure.""" workspaces = _normwslist(workspaces) @@ -180,7 +190,22 @@ def _SofQWtitle(workspace, figure): def box2D(xs, vertAxis, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf, vertMax=numpy.inf): - """Return slicing for a 2D numpy array limited by given min and max values.""" + """Return slicing for a 2D numpy array limited by given min and max values. + + :param xs: the 2D X data of a workspace from :func:`mantid.api.MatrixWorkspace.extractX` + :type xs: a 2D :class:`numpy.ndarray` + :param vertAxis: the vertical axis values of a workspace + :type vertAxis: a 1D :class:`numpy.ndarray` + :param horMin: the left edge of the box + :type horMin: float + :param horMax: the right edge of the box + :type horMax: float + :param vertMin: the bottom edge of the box + :type vertMin: float + :param vertMax: the top edge of the box + :type vertMax: float + :returns: a tuple of two :class:`slice` objects, the first one for vertical dimension, the second for horizontal. + """ if len(vertAxis) > xs.shape[0]: vertAxis = _binCentres(vertAxis) horBegin = numpy.argwhere(xs[0, :] >= horMin)[0][0] @@ -190,13 +215,11 @@ def box2D(xs, vertAxis, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf, return slice(vertBegin, vertEnd), slice(horBegin, horEnd) -def configurematplotlib(params): - """Set matplotlib rc parameters from the params dictionary.""" - matplotlib.rcParams.update(params) - - def defaultrcParams(): - """Return a dictionary of directtools default matplotlib rc parameters.""" + """Return a dictionary of directtools default matplotlib rc parameters. + + :returns: a :class:`dict` of default :mod:`matplotlib` rc parameters needed by :mod:`directtools` + """ params = { 'legend.numpoints': 1, 'text.usetex': True, @@ -205,7 +228,23 @@ def defaultrcParams(): def dynamicsusceptibility(workspace, temperature, outputName=None, zeroEnergyEpsilon=1e-6): - """Convert :math:`S(Q,E)` to susceptibility :math:`\chi''(Q,E)`.""" + """Convert :math:`S(Q,E)` to susceptibility :math:`\chi''(Q,E)`. + + #. If the X units are not in DeltaE, the workspace is transposed + #. The Y data in *workspace* is multiplied by :math:`1 - e^{\Delta E / (kT)}` + #. Y data in the bin closest to 0 meV and within -*zeroEnergyEpsilon* < :math:`\Delta E` < *zeroEnergyEpsilon* is set to 0 + #. If the input was transposed, transpose the output as well + + :param workspace: a :math:`S(Q,E)` workspace to convert + :type workspace: :class:`mantid.api.MatrixWorkspace` + :param temperature: temperature in Kelvin + :type temperature: float + :param outputName: name of the output workspace. If :class:`None`, the output will be given some generated name. + :type outputName: str or None + :param zeroEnergyEpsilon: if a bin center is within this value from 0, the bin's value is set to zero. + :type zeroEnergyEpsilon: float + :returns: a :class:`mantid.api.MatrixWorkspace` containing :math:`\chi''(Q,E)` + """ workspace = _normws(workspace) horAxis = workspace.getAxis(0) horUnit = horAxis.getUnit().unitID() @@ -224,13 +263,24 @@ def dynamicsusceptibility(workspace, temperature, outputName=None, zeroEnergyEps return outWS -def mantidsubplotsetup(): - """Return a dict for the matplotlib.pyplot.subplots().""" - return {'projection': 'mantid'} - - def nanminmax(workspace, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf, vertMax=numpy.inf): - """Return min and max intensities of a workspace.""" + """Return min and max intensities of a workspace ignoring NaNs. + + The search region can be limited by *horMin*, *horMax*, *vertMin* and *vertMax*. + + :param workspace: a workspace + :type workspace: :class:`mantid.api.MatrixWorkspace` + :param horMin: the left edge of the search region + :type horMin: float + :param horMax: the right edge of the search region + :type horMax: float + :param vertMin: the bottom edge of the search region + :type vertMin: float + :param vertMax: the top edge of the search region + :type vertMax: float + + :returns: a tuple containing the minimum and maximum + """ workspace = _normws(workspace) xs = workspace.extractX() ys = workspace.extractY() @@ -245,7 +295,26 @@ def nanminmax(workspace, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf def plotconstE(workspaces, E, dE, style='l', keepCutWorkspaces=True): - """Plot line profiles at constant energy.""" + """Plot line profiles at constant energy transfer from :math:`S(Q,E)` workspace. + + Creates cut workspaces using :ref:`algm-LineProfile`, then plots the cuts. A list of workspaces, + constant energy transfers, or cut widths, or any combination thereof can be given as parameters. + + The last entry in the returned tuple is a list of cut workspace names. This will be an empty list + is *keeCutWorkspaces* is set to `False` as the workspaces will not appear in the ADS. + + :param workspaces: a single :math:`S(Q,E)` workspace or list of workspaces to cut + :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a list thereof + :param E: a constant energy transfer or a :class:`list` thereof + :type E: float or :class:`list` of floats + :param dE: width of the cut or a list of widths + :type dE: float or :class:`list` of floats + :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both + :type style: str + :param keepCutWorkspaces: whether or not keep the cut workspaces in the ADS + :type keepCutWorkspaces: bool + :returns: A tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`, a :class:`list` of names) + """ figure, axes, cutWSList = plotcuts('Horizontal', workspaces, E, dE, '$E$', 'meV', style, keepCutWorkspaces) _profiletitle(workspaces, '$E$', 'meV', E, dE, figure) axes.legend() @@ -258,7 +327,26 @@ def plotconstE(workspaces, E, dE, style='l', keepCutWorkspaces=True): def plotconstQ(workspaces, Q, dQ, style='l', keepCutWorkspaces=True): - """Plot line profiles at constant momentum transfer.""" + """Plot line profiles at constant momentum transfer from :math:`S(Q,E)` workspace. + + Creates cut workspaces using :ref:`algm-LineProfile`, then plots the cuts. A list of workspaces, + constant momentum transfers, or cut widths, or any combination thereof can be given as parameters. + + The last entry in the returned tuple is a list of cut workspace names. This will be an empty list + is *keeCutWorkspaces* is set to `False` as the workspaces will not appear in the ADS. + + :param workspaces: a single :math:`S(Q,E)` workspace or list of workspaces to cut + :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a list thereof + :param Q: a constant momentum transfer or a :class:`list` thereof + :type Q: float or :class:`list` of floats + :param dQ: width of the cut or a list of widths + :type dQ: float or :class:`list` of floats + :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both + :type style: str + :param keepCutWorkspaces: whether or not keep the cut workspaces in the ADS + :type keepCutWorkspaces: bool + :returns: A tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`, a :class:`list` of names) + """ figure, axes, cutWSList = plotcuts('Vertical', workspaces, Q, dQ, '$Q$', '\\AA$^{-1}$', style, keepCutWorkspaces) _profiletitle(workspaces, '$Q$', '\\AA$^{-1}$', Q, dQ, figure) axes.legend() @@ -272,7 +360,32 @@ def plotconstQ(workspaces, Q, dQ, style='l', keepCutWorkspaces=True): def plotcuts(direction, workspaces, cuts, widths, quantity, unit, style='l', keepCutWorkspaces=True): - """Cut and plot multiple line profiles.""" + """Cut and plot multiple line profiles. + + Creates cut workspaces using :ref:`algm-LineProfile`, then plots the cuts. A list of workspaces, + cut centres, or cut widths, or any combination thereof can be given as parameters. + + The last entry in the returned tuple is a list of cut workspace names. This will be an empty list + is *keeCutWorkspaces* is set to `False` as the workspaces will not appear in the ADS. + + :param direction: Cut direction. Only ``'Horizontal'`` and ``'Vertical'`` are accepted + :type direction: str + :param workspaces: a single workspace or a list thereof + :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a :class:`list` thereof + :param cuts: the center of the cut or a list of centers + :type cuts: float or a :class:`list` thereof + :param widths: the width of the cut or a list of widths + :type widths: float or a :class:`list` thereof + :param quantity: name of the physical quantity along which the cut is made, used for legend label + :type quantity: str + :param unit: unit of *quantity* + :type unit: str + :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both + :type style: str + :param keepCutWorkspaces: whether or not keep the cut workspaces in the ADS + :type keepCutWorkspaces: bool + :returns: A tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`, a :class:`list` of names) + """ workspaces = _normwslist(workspaces) if not isinstance(cuts, collections.Iterable): cuts = [cuts] @@ -308,7 +421,18 @@ def plotcuts(direction, workspaces, cuts, widths, quantity, unit, style='l', kee def plotprofiles(workspaces, labels=None, style='l'): - """Plot given line profile workspaces.""" + """Plot line profile workspaces. + + Plots the first histograms from given workspaces. + + :param workspaces: a single workspace or a list thereof + :type workspaces: str, :class:`mantid.api.MatrixWorkspace` or a :class:`list` thereof + :param labels: a list of cut labels for the plot legend + :type labels: str, a :class:`list` of strings or None + :param style: plot style: 'l' for lines, 'm' for markers, 'lm' for both + :type style: str + :returns: a tuple of (:mod:`matplotlib.Figure`, :mod:`matplotlib.Axes`) + """ workspaces = _normwslist(workspaces) if not isinstance(labels, collections.Iterable) or isinstance(labels, str): if labels is None: @@ -336,7 +460,26 @@ def plotprofiles(workspaces, labels=None, style='l'): def plotSofQW(workspace, QMin=0., QMax=None, EMin=None, EMax=None, VMin=0., VMax=None, colormap='jet'): - """Plot a 2D plot with given axis limits and return the plotting layer.""" + """Plot a 2D :math:`S(Q,E)` workspace. + + :param workspace: a workspace to plot + :type workspace: str or :class:`mantid.api.MatrixWorkspace` + :param QMin: minimum :math:`Q` to include in the plot + :type QMin: float or None + :param QMax: maximum :math:`Q` to include in the plot + :type QMax: float or None + :param EMin: minimum energy transfer to include in the plot + :type EMin: float or None + :param EMax: maximum energy transfer to include in the plot + :type EMax: float or None + :param VMin: minimum intensity to show on the color bar + :type VMin: float or None + :param VMax: maximum intensity to show on the color bar + :type VMax: float or None + :param colormap: name of the colormap + :type colormap: str + :returns: a tuple of (:mod:`matplotlib.Figure`, :mod:`matplotlib.Axes`) + """ # Accept both workspace names and actual workspaces. workspace = _normws(workspace) isSusceptibility = workspace.YUnit() == 'Dynamic susceptibility' @@ -378,12 +521,28 @@ def plotSofQW(workspace, QMin=0., QMax=None, EMin=None, EMax=None, VMin=0., VMax def subplots(**kwargs): - """Return matplotlib figure and axes.""" - return pyplot.subplots(subplot_kw=mantidsubplotsetup(), **kwargs) + """Return matplotlib figure and axes with Mantid projection. + + The returned figure and axes have the proper projection to plot Mantid workspaces directly. + + :param kwargs: keyword arguments that are directly passed to :func:`matplotlib.pyplot.subplots`. + :type kwargs: dict + :returns: a tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`) + """ + return pyplot.subplots(subplot_kw=_mantidsubplotsetup(), **kwargs) def validQ(workspace, E=0.0): - """Return a :math:`Q` range at given energy transfer where :math:`S(Q,E)` is defined.""" + """Return a :math:`Q` range at given energy transfer where :math:`S(Q,E)` is defined. + + :math:`S(Q,E)` is undefined when Y = NaN + + :param workspace: A :math:`S(Q,E)` workspace to investigate + :type workspace: str or :class:`mantid.api.MatrixWorkspace` + :param E: energy transfer at which to evaluate the range + :type E: float + :returns: a tuple of (:math:`Q_{min}`, :math:`Q_{max}`) + """ workspace = _normws(workspace) vertBins = workspace.getAxis(1).extractValues() if len(vertBins) > workspace.getNumberHistograms(): @@ -401,7 +560,14 @@ def validQ(workspace, E=0.0): def wsreport(workspace): - """Print some useful information from sample logs.""" + """Print some useful information from sample logs. + + The logs are expected to contain some ILL specific fields. + + :param workspace: a workspace from which to extract the logs + :type workspace: str or :class:`mantid.api.MatrixWorkspace` + :returns: None + """ workspace = _normws(workspace) print(str(workspace)) logs = SampleLogs(workspace) @@ -420,8 +586,27 @@ def wsreport(workspace): class SampleLogs: + """A convenience class to access the sample logs of :class:`mantid.api.MatrixWorkspace`. + + Upon initialization, this class adds the sample logs as data attributes to itself. The + attributes get their names from the logs. Log names containing dots result in nested + log objects. Thus, if a workspace contains logs ``'a'`` and ``'b.c'``: + + .. code:: + + logs = SampleLogs(workspace) + # This is equivalent of calling workspace.run().getProperty('a').value + logs.a + # This is equivalent of calling workspace.run().getProperty('b.c').value + logs.b.c + """ def __init__(self, workspace): - """Transform sample log entries from workspace into attributes of this object.""" + """Initialize a `SampleLogs` object. + Transform sample log entries from workspace into attributes of this object. + + :param workspace: the workspace from which to extract the sample logs + :type workspace: :class:`mantid.api.MatrixWorkspace` + """ class Log: pass workspace = _normws(workspace) @@ -442,4 +627,4 @@ class Log: # Set default matplotlib rc parameters. -configurematplotlib(defaultrcParams()) +_configurematplotlib(defaultrcParams()) From 937f062dd54e26877acebea3957099fc7ca560d4 Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Fri, 16 Mar 2018 17:54:30 +0100 Subject: [PATCH 286/364] Rename directtools .rst file to enable usage of the plot directive. Re #21901 --- ...{Directtools Python module.rst => DirecttoolsPythonModule.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/source/techniques/{Directtools Python module.rst => DirecttoolsPythonModule.rst} (100%) diff --git a/docs/source/techniques/Directtools Python module.rst b/docs/source/techniques/DirecttoolsPythonModule.rst similarity index 100% rename from docs/source/techniques/Directtools Python module.rst rename to docs/source/techniques/DirecttoolsPythonModule.rst From 8d0f7eb194ce93e523e445ba050a5bab8052adc8 Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Fri, 16 Mar 2018 17:55:04 +0100 Subject: [PATCH 287/364] Add usage examples to directtools sphinx docs. Re #21901 --- .../techniques/DirecttoolsPythonModule.rst | 112 +++++++++++++++++- 1 file changed, 110 insertions(+), 2 deletions(-) diff --git a/docs/source/techniques/DirecttoolsPythonModule.rst b/docs/source/techniques/DirecttoolsPythonModule.rst index 45bd9feacb69..70dd3e6fab3c 100644 --- a/docs/source/techniques/DirecttoolsPythonModule.rst +++ b/docs/source/techniques/DirecttoolsPythonModule.rst @@ -4,22 +4,130 @@ :mod:`directtools` ================== -:literal:`directtools` is a Python module for quickly plotting standardized :math:`S(Q,E)` color fill plots as well as line profiles (cuts) in constant :math:`Q` and :math:`E`. The module also provides a few utility functions for inspecting and manipulating the :math:`S(Q,E)` workspace. +:mod:`directtools` is a Python module for quickly plotting standardized :math:`S(Q,E)` color fill plots as well as line profiles (cuts) in constant :math:`Q` and :math:`E`. The module also provides a few utility functions for inspecting and manipulating the :math:`S(Q,E)` workspace. For a general introduction on using :mod:`matplotlib` with Mantid, see :ref:`this introduction ` +The input workspaces are expected to have some specific sample logs, namely ``instrument.name``, ``Ei``, ``run_number``, ``start_time``, ``sample.temperature``. + +Examples +######## + +The default parameters for :func:`directtools.plotSofQW` give a view of the :math:`S(Q,E)` workspace around the elastic peak with sensible limits for the axes and intensity: + .. plot:: :include-source: import directtools as dt from mantid.simpleapi import * - DirectILLCollectData(Run='ILL/IN4/084447', OutputWorkspace='data') + DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data') DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW') fig, ax = dt.plotSofQW('SofQW') #fig.show() +The :math:`Q`, :math:`E` and intensity limits can be changed using the optional parameters. The utility functions :func:`directtools.validQ` and :func:`directtools.nanminmax` might be helpful when determining suitable ranges: + +.. plot:: + :include-source: + + import directtools as dt + from mantid.simpleapi import * + + DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data') + DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW') + + EMin = -20. + QMax = dt.validQ('SofQW', EMin)[1] + VMax = 0.5 * dt.nanminmax('SofQW')[1] + + fig, axes = dt.plotSofQW('SofQW', QMax=QMax, EMin=EMin, VMax=VMax) + #fig.show() + +An important aspect of examining the :math:`S(Q,E)` workspace is to plot cuts at constant :math:`Q` and :math:`E`. This can be done by :func:`directtools.plotconstQ` and :func:`directtools.plotconstE`: + +.. plot:: + :include-source: + + import directtools as dt + from mantid.simpleapi import * + + DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data') + DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW') + + Q = 2. + dQ = 0.2 + fig, axes, cuts = dt.plotconstQ('SofQW', Q, dQ) + #fig.show() + +Any of the workspace, cut centre or cut width arguments can be a :class:`list` instead. This enables data comparison: + +.. plot:: + :include-source: + + import directtools as dt + from mantid.simpleapi import * + + DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data') + DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW') + + Q1 = 2. + Q2 = 3. + dQ = 0.2 + fig, axes, cuts = dt.plotconstQ('SofQW', [Q1, Q2], dQ) + #fig.show() + +The :func:`directtools.plotconstQ` and :func:`directtools.plotconstE` functions use :func:`directtool.plotcuts` to do the actual line profiles and plotting. The profiles are made by the :ref:`algm-LineProfile` algorithm, and all three plotting functions return a list of the produced line profile workspace names. + +If a line profile already exists, it can be plotted using :func:`directtools.plotprofiles`. This also accepts either a single line profile workspace or a list of workspaces enabling comparison: + +.. plot:: + :include-source: + + import directtools as dt + from mantid.simpleapi import * + + DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data') + DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW') + + E1 = 8. + dE = 2. + cut1 = LineProfile('SofQW', E1, dE, 'Horizontal') + label1 = 'At E = {} meV'.format(E1) + E2 = E1 - 4. + cut2 = LineProfile('SofQW', E2, dE, 'Horizontal') + label2 = 'At E = {} meV'.format(E2) + fig, axes = dt.plotprofiles([cut1, cut2], [label1, label2], style='m') + axes.legend() + #fig.show() + +:class:`directtools.SampleLogs` is a convenience class to import the sample logs of a workspace into a 'struct' like object in Python: + +.. testcode:: SampleLogsEx + + import directtools as dt + from mantid.simpleapi import * + + DirectILLCollectData(Run='ILL/IN4/084447.nxs', OutputWorkspace='data') + DirectILLReduction(InputWorkspace='data', OutputWorkspace='SofQW') + + # Works on any workspace, not just S(Q,E). + logs = dt.SampleLogs('SofQW') + print(logs.instrument.name) + print(logs.run_number) + +.. testcleanup:: SampleLogsEx + + mtd.clear() + +Output: + +.. testoutput:: SampleLogsEx + + IN4 + 84447 + Reference ========= From 90565bb392ea4ad8291ea625af2c2dc751c6889f Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Fri, 16 Mar 2018 17:02:03 +0000 Subject: [PATCH 288/364] muon analysis does not crash if cant find data --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 43d1fcd59fd0..a17be9e06467 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1549,6 +1549,10 @@ void MuonFitPropertyBrowser::updatePeriods() { void MuonFitPropertyBrowser::updatePeriods(const int j) { // this is for switching but has a bug at the moment // const QStringList &selected) { + if(m_periodsToFitOptions.size() ==0){ + + return; + } m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); m_enumManager->setValue(m_periodsToFit, j); if (m_periodsToFitOptions[j] == CUSTOM_LABEL) { From e517a2ff58f070c7974e104c3685d06211c92803 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Fri, 16 Mar 2018 17:11:40 +0000 Subject: [PATCH 289/364] muon analysis gives warning if no data --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index a17be9e06467..b5b177341c87 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -57,6 +57,7 @@ #include #include #include +#include namespace { Mantid::Kernel::Logger g_log("MuonFitPropertyBrowser"); @@ -1550,7 +1551,7 @@ void MuonFitPropertyBrowser::updatePeriods(const int j) { // this is for switching but has a bug at the moment // const QStringList &selected) { if(m_periodsToFitOptions.size() ==0){ - + QMessageBox::warning(this,"Muon Analysis","Data not found. Please turn on the data archhive"); return; } m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); From 2688291b3255d7f57c91c0eaa7e01dbebd099416 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Fri, 16 Mar 2018 17:13:34 +0000 Subject: [PATCH 290/364] muon analysis gives warning if no data clang --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index b5b177341c87..ac0639876232 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -57,7 +57,7 @@ #include #include #include -#include +#include namespace { Mantid::Kernel::Logger g_log("MuonFitPropertyBrowser"); @@ -1550,9 +1550,10 @@ void MuonFitPropertyBrowser::updatePeriods() { void MuonFitPropertyBrowser::updatePeriods(const int j) { // this is for switching but has a bug at the moment // const QStringList &selected) { - if(m_periodsToFitOptions.size() ==0){ - QMessageBox::warning(this,"Muon Analysis","Data not found. Please turn on the data archhive"); - return; + if (m_periodsToFitOptions.size() == 0) { + QMessageBox::warning(this, "Muon Analysis", + "Data not found. Please turn on the data archhive"); + return; } m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); m_enumManager->setValue(m_periodsToFit, j); From ad0be174b2275f19cbfd2d63bb3ecea975432d87 Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Fri, 16 Mar 2018 17:23:21 +0000 Subject: [PATCH 291/364] better error message and less h's re #22133 --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index ac0639876232..314d6cd845b5 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1552,7 +1552,7 @@ void MuonFitPropertyBrowser::updatePeriods(const int j) { // const QStringList &selected) { if (m_periodsToFitOptions.size() == 0) { QMessageBox::warning(this, "Muon Analysis", - "Data not found. Please turn on the data archhive"); + "Data not found. Please turn on the data archive, using the Manage Directories button."); return; } m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); From ba8bd452b234adce56a609041630f81bbe0dc49e Mon Sep 17 00:00:00 2001 From: Nick Draper Date: Fri, 16 Mar 2018 17:26:23 +0000 Subject: [PATCH 292/364] clang format re #21643 --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 314d6cd845b5..52fb3e30fa33 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1552,7 +1552,8 @@ void MuonFitPropertyBrowser::updatePeriods(const int j) { // const QStringList &selected) { if (m_periodsToFitOptions.size() == 0) { QMessageBox::warning(this, "Muon Analysis", - "Data not found. Please turn on the data archive, using the Manage Directories button."); + "Data not found. Please turn on the data archive, " + "using the Manage Directories button."); return; } m_enumManager->setEnumNames(m_periodsToFit, m_periodsToFitOptions); From 08d38f772d80eee56508cf2d7ac856a07f9d78f8 Mon Sep 17 00:00:00 2001 From: Andrei Savici Date: Fri, 16 Mar 2018 15:01:24 -0400 Subject: [PATCH 293/364] Re #22134. Fix the numerical error --- Framework/Geometry/src/Crystal/UnitCell.cpp | 8 +++++++- Framework/Geometry/test/UnitCellTest.h | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Framework/Geometry/src/Crystal/UnitCell.cpp b/Framework/Geometry/src/Crystal/UnitCell.cpp index 2e273816e2cf..57bbec2330fd 100644 --- a/Framework/Geometry/src/Crystal/UnitCell.cpp +++ b/Framework/Geometry/src/Crystal/UnitCell.cpp @@ -452,7 +452,13 @@ double UnitCell::recAngle(double h1, double k1, double l1, double h2, double k2, double E, ang; Q1 = Gstar * Q1; E = Q1.scalar_prod(Q2); - ang = acos(E / dstar(h1, k1, l1) / dstar(h2, k2, l2)); + double temp = E / dstar(h1, k1, l1) / dstar(h2, k2, l2); + if (temp>1) + ang = 0.; + else if (temp<-1) + ang = M_PI; + else + ang = acos(temp); if (angleunit == angDegrees) return rad2deg * ang; else diff --git a/Framework/Geometry/test/UnitCellTest.h b/Framework/Geometry/test/UnitCellTest.h index 950decf36f63..4b512ff034d8 100644 --- a/Framework/Geometry/test/UnitCellTest.h +++ b/Framework/Geometry/test/UnitCellTest.h @@ -142,6 +142,12 @@ class UnitCellTest : public CxxTest::TestSuite { } } + void testReciprocalAngle0() { + UnitCell cell(5.45, 5.45, 5.45); + TS_ASSERT_EQUALS(cell.recAngle(0., 4., 0., 0., 4., 0.), 0.); + TS_ASSERT_EQUALS(cell.recAngle(0., -4., 0., 0., 4., 0.), 180.); + } + void testStrToUnitCell() { UnitCell cell(2.0, 4.0, 5.0, 90.0, 100.0, 102.0); std::string cellString = unitCellToStr(cell); From 09eeb9693c67e14f7cff613a737299c3ad5a91e0 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Wed, 14 Mar 2018 17:10:36 -0400 Subject: [PATCH 294/364] Extend MaskAngle for phi angles This will allow masking angles to be based on TwoTheta or Phi. This code also now runs faster. --- .../plugins/algorithms/MaskAngle.py | 41 ++++++++++++------ .../plugins/algorithms/MaskAngleTest.py | 12 +++++ docs/source/algorithms/MaskAngle-v1.rst | 40 +++++++++++++++++ docs/source/images/MaskAngle_phi.png | Bin 0 -> 51087 bytes 4 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 docs/source/images/MaskAngle_phi.png diff --git a/Framework/PythonInterface/plugins/algorithms/MaskAngle.py b/Framework/PythonInterface/plugins/algorithms/MaskAngle.py index 6fe7e7f90ad2..772db73daecb 100644 --- a/Framework/PythonInterface/plugins/algorithms/MaskAngle.py +++ b/Framework/PythonInterface/plugins/algorithms/MaskAngle.py @@ -32,9 +32,12 @@ def PyInit(self): angleValidator=mantid.kernel.FloatBoundedValidator() angleValidator.setBounds(0.,180.) self.declareProperty(name="MinAngle", defaultValue=0.0, validator=angleValidator, - direction=mantid.kernel.Direction.Input, doc="Angles above StartAngle are going to be masked") - self.declareProperty(name="MaxAngle", defaultValue=0.0, validator=angleValidator, - direction=mantid.kernel.Direction.Input, doc="Angles above StartAngle are going to be masked") + direction=mantid.kernel.Direction.Input, doc="Angles above MinAngle are going to be masked") + self.declareProperty(name="MaxAngle", defaultValue=180.0, validator=angleValidator, + direction=mantid.kernel.Direction.Input, doc="Angles below MaxAngle are going to be masked") + self.declareProperty('Angle', 'TwoTheta', + mantid.kernel.StringListValidator(['TwoTheta', 'Phi']), + 'Which angle to use') self.declareProperty(mantid.kernel.IntArrayProperty(name="MaskedDetectors", direction=mantid.kernel.Direction.Output), doc="List of detector masked, with scatterin angles between MinAngle and MaxAngle") @@ -56,23 +59,35 @@ def validateInputs(self): def PyExec(self): ws = self.getProperty("Workspace").value - ttmin = self.getProperty("MinAngle").value - ttmax = self.getProperty("MaxAngle").value + ttmin = numpy.radians(self.getProperty("MinAngle").value) + ttmax = numpy.radians(self.getProperty("MaxAngle").value) if ttmin > ttmax : raise ValueError("MinAngle > MaxAngle, please check angle range for masking") + angle = self.getProperty('Angle').value + detlist=[] numspec = ws.getNumberHistograms() - source=ws.getInstrument().getSource().getPos() - sample=ws.getInstrument().getSample().getPos() spectrumInfo = ws.spectrumInfo() - for i in range(numspec): - if not spectrumInfo.isMonitor(i): - det = ws.getDetector(i) - tt=numpy.degrees(det.getTwoTheta(sample,sample-source)) - if tt>= ttmin and tt<= ttmax: - detlist.append(det.getID()) + + if angle == 'Phi': + for i in range(numspec): + if not spectrumInfo.isMonitor(i): + det = ws.getDetector(i) + phi=abs(det.getPhi()) + if phi>= ttmin and phi<= ttmax: + detlist.append(det.getID()) + else: + source=ws.getInstrument().getSource().getPos() + sample=ws.getInstrument().getSample().getPos() + beam = sample-source + for i in range(numspec): + if not spectrumInfo.isMonitor(i): + det = ws.getDetector(i) + tt=det.getTwoTheta(sample,beam) + if tt>= ttmin and tt<= ttmax: + detlist.append(det.getID()) if len(detlist)> 0: mantid.simpleapi.MaskDetectors(Workspace=ws,DetectorList=detlist) diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py index 8056afe9f189..e4ac2e594b62 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py @@ -21,6 +21,18 @@ def testMaskAngle(self): DeleteWorkspace(w) self.assertTrue(array_equal(masklist,arange(10)+10)) + def testMaskAnglePhi(self): + w=WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(30,5,False,False) + AnalysisDataService.add('w',w) + masklist = MaskAngle(w,0,45,Angle='Phi') + detInfo = w.detectorInfo() + for i in arange(w.getNumberHistograms()): + if i==0: + self.assertTrue(detInfo.isMasked(int(i))) + else: + self.assertFalse(detInfo.isMasked(int(i))) + DeleteWorkspace(w) + def testGroupMaskAngle(self): ws1=WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(30,5,False,False) AnalysisDataService.add('ws1',ws1) diff --git a/docs/source/algorithms/MaskAngle-v1.rst b/docs/source/algorithms/MaskAngle-v1.rst index 5f9590342acb..0384c1e1da68 100644 --- a/docs/source/algorithms/MaskAngle-v1.rst +++ b/docs/source/algorithms/MaskAngle-v1.rst @@ -14,11 +14,15 @@ Algorithm to mask detectors with scattering angles in a given interval set, all detectors are going to be masked Returns a list of detectors that were masked +When masking the phi angle the absolute value of phi is used. + Usage ----- .. include:: ../usagedata-note.txt +**Two theta example** + .. testcode:: MaskAngle #Load a workspace @@ -53,6 +57,42 @@ The instrument view would look like: .. figure:: /images/MaskAngle.png :alt: MaskAngle.png +**Phi example** + +.. testcode:: MaskAngle_phi + + #Load a workspace + ws = Load("CNCS_7860") + + #Do the masking for direct beam + mask = MaskAngle(ws, MinAngle=30, MaxAngle=150, Angle='Phi') + print("The algorithm has masked {} detectors".format(mask.size)) + + #to test check a couple of detectors + inst = ws.getInstrument() + print("Is the minimum element in the mask list (detector {}) masked? {}".format(mask.min(), inst.getDetector(int(mask.min())).isMasked())) + print("Is the maximum element in the mask list (detector {}) masked? {}".format(mask.max(), inst.getDetector(int(mask.max())).isMasked())) + print("Is a detector outside the list masked (for example detector 100)? {}".format(inst.getDetector(100).isMasked() )) + +.. testcleanup:: MaskAngle_phi + + DeleteWorkspace(ws) + +Output: + +.. testoutput:: MaskAngle_phi + + The algorithm has masked 6348 detectors + Is the minimum element in the mask list (detector 29568) masked? True + Is the maximum element in the mask list (detector 44287) masked? True + Is a detector outside the list masked (for example detector 100)? False + + +The instrument view would look like: + +.. figure:: /images/MaskAngle_phi.png + :alt: MaskAngle_phi.png + .. categories:: .. sourcelink:: diff --git a/docs/source/images/MaskAngle_phi.png b/docs/source/images/MaskAngle_phi.png new file mode 100644 index 0000000000000000000000000000000000000000..aba5f84d5474cfee2e2d514d0d8cc25394a71c58 GIT binary patch literal 51087 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

+jU{H;AeiX2D7ql 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

  • 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 I#f-oG9~99MC;$Ke literal 0 HcmV?d00001 From 4e41c9068701aff5d1006c1ff19f6dfb696bc2c8 Mon Sep 17 00:00:00 2001 From: Andrei Savici Date: Fri, 16 Mar 2018 15:29:02 -0400 Subject: [PATCH 295/364] Re #22134. Clang format --- Framework/Geometry/src/Crystal/UnitCell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Geometry/src/Crystal/UnitCell.cpp b/Framework/Geometry/src/Crystal/UnitCell.cpp index 57bbec2330fd..08077755d176 100644 --- a/Framework/Geometry/src/Crystal/UnitCell.cpp +++ b/Framework/Geometry/src/Crystal/UnitCell.cpp @@ -453,9 +453,9 @@ double UnitCell::recAngle(double h1, double k1, double l1, double h2, double k2, Q1 = Gstar * Q1; E = Q1.scalar_prod(Q2); double temp = E / dstar(h1, k1, l1) / dstar(h2, k2, l2); - if (temp>1) + if (temp > 1) ang = 0.; - else if (temp<-1) + else if (temp < -1) ang = M_PI; else ang = acos(temp); From 58521414361732550dacf201a4d9aaf7505c140b Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Mon, 19 Mar 2018 09:00:10 +0100 Subject: [PATCH 296/364] Code beautification. Re #22075 --- Framework/Algorithms/test/ConvertToHistogramTest.h | 4 ++-- Framework/Algorithms/test/ConvertToPointDataTest.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Framework/Algorithms/test/ConvertToHistogramTest.h b/Framework/Algorithms/test/ConvertToHistogramTest.h index 6468d1989ef3..5ac8871d696e 100644 --- a/Framework/Algorithms/test/ConvertToHistogramTest.h +++ b/Framework/Algorithms/test/ConvertToHistogramTest.h @@ -21,7 +21,6 @@ using Mantid::Kernel::make_cow; class ConvertToHistogramTest : public CxxTest::TestSuite { public: - void tearDown() override { Mantid::API::AnalysisDataService::Instance().clear(); } @@ -82,7 +81,8 @@ class ConvertToHistogramTest : public CxxTest::TestSuite { constexpr int numSpectra{2}; Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspace123( numSpectra, numYPoints, false); - double xErrors[numYPoints] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + double xErrors[numYPoints] = {0.1, 0.2, 0.3, 0.4, 0.5, + 0.6, 0.7, 0.8, 0.9, 1.0}; auto dxs = make_cow(xErrors, xErrors + numYPoints); // Reset the X data to something reasonable, set Dx. Points x(numYPoints, LinearGenerator(0.0, 1.0)); diff --git a/Framework/Algorithms/test/ConvertToPointDataTest.h b/Framework/Algorithms/test/ConvertToPointDataTest.h index 410bc4d73b1e..d9f2963fa683 100644 --- a/Framework/Algorithms/test/ConvertToPointDataTest.h +++ b/Framework/Algorithms/test/ConvertToPointDataTest.h @@ -19,7 +19,6 @@ using Mantid::Kernel::make_cow; class ConvertToPointDataTest : public CxxTest::TestSuite { public: - void tearDown() override { Mantid::API::AnalysisDataService::Instance().clear(); } @@ -146,12 +145,13 @@ class ConvertToPointDataTest : public CxxTest::TestSuite { void test_Dx_Data_Is_Handled_Correctly() { constexpr size_t numBins{11}; double xBoundaries[numBins] = {0.0, 1.0, 3.0, 5.0, 6.0, 7.0, - 10.0, 13.0, 16.0, 17.0, 17.5}; + 10.0, 13.0, 16.0, 17.0, 17.5}; constexpr int numSpectra{2}; Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspaceBinned( numSpectra, numBins, xBoundaries); TS_ASSERT(testWS->isHistogramData()) - double xErrors[numBins - 1] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + double xErrors[numBins - 1] = {0.1, 0.2, 0.3, 0.4, 0.5, + 0.6, 0.7, 0.8, 0.9, 1.0}; auto dxs = make_cow(xErrors, xErrors + numBins - 1); testWS->setSharedDx(0, dxs); testWS->setSharedDx(1, dxs); From 6c9e5619ea23132b4f9b2508122716c8f3702413 Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Mon, 19 Mar 2018 09:12:33 +0100 Subject: [PATCH 297/364] Code beautification. Re #21901 --- scripts/directtools/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/directtools/__init__.py b/scripts/directtools/__init__.py index fb40a60ab2ba..bc91cfe55510 100644 --- a/scripts/directtools/__init__.py +++ b/scripts/directtools/__init__.py @@ -191,7 +191,7 @@ def _SofQWtitle(workspace, figure): def box2D(xs, vertAxis, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf, vertMax=numpy.inf): """Return slicing for a 2D numpy array limited by given min and max values. - + :param xs: the 2D X data of a workspace from :func:`mantid.api.MatrixWorkspace.extractX` :type xs: a 2D :class:`numpy.ndarray` :param vertAxis: the vertical axis values of a workspace @@ -217,7 +217,7 @@ def box2D(xs, vertAxis, horMin=-numpy.inf, horMax=numpy.inf, vertMin=-numpy.inf, def defaultrcParams(): """Return a dictionary of directtools default matplotlib rc parameters. - + :returns: a :class:`dict` of default :mod:`matplotlib` rc parameters needed by :mod:`directtools` """ params = { @@ -522,9 +522,9 @@ def plotSofQW(workspace, QMin=0., QMax=None, EMin=None, EMax=None, VMin=0., VMax def subplots(**kwargs): """Return matplotlib figure and axes with Mantid projection. - + The returned figure and axes have the proper projection to plot Mantid workspaces directly. - + :param kwargs: keyword arguments that are directly passed to :func:`matplotlib.pyplot.subplots`. :type kwargs: dict :returns: a tuple of (:class:`matplotlib.Figure`, :class:`matplotlib.Axes`) @@ -603,7 +603,7 @@ class SampleLogs: def __init__(self, workspace): """Initialize a `SampleLogs` object. Transform sample log entries from workspace into attributes of this object. - + :param workspace: the workspace from which to extract the sample logs :type workspace: :class:`mantid.api.MatrixWorkspace` """ From fcef8653964d73cfe76c01c9f0751454238b2a31 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 19 Mar 2018 08:25:28 +0000 Subject: [PATCH 298/364] Re #22048: Added manual fixes for paraview. --- .../VatesAPI/inc/MantidVatesAPI/Common.h | 8 +++----- .../inc/MantidVatesAPI/Normalization.h | 4 ++-- .../inc/MantidVatesAPI/PeaksPresenterVsi.h | 6 +++--- .../VatesAPI/inc/MantidVatesAPI/ViewFrustum.h | 19 +++++++++---------- .../inc/MantidVatesAPI/vtkDataSetFactory.h | 4 ++-- .../MantidVatesAPI/vtkMDHistoHex4DFactory.h | 8 +++----- .../MantidVatesAPI/vtkMDHistoLineFactory.h | 2 +- .../MantidVatesAPI/vtkMDHistoQuadFactory.h | 4 ++-- .../MantidVatesAPI/vtkSplatterPlotFactory.h | 3 +-- .../VatesAPI/test/MDHWLoadingPresenterTest.h | 2 +- 10 files changed, 27 insertions(+), 33 deletions(-) diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h index 54c25aa86e65..735266d4e39e 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h @@ -14,16 +14,14 @@ class IMDDimension; namespace VATES { /// Vector of IMDDimension shared pointers. -typedef std::vector> - DimensionVec; +using DimensionVec = std::vector>; /// IMDDimension as shared pointer. -typedef boost::shared_ptr Dimension_sptr; +using Dimension_sptr = boost::shared_ptr; /// IMDDimension as const shared pointer. Note that IMDDimension is pure /// virtual. -typedef boost::shared_ptr - Dimension_const_sptr; +using Dimension_const_sptr = boost::shared_ptr; std::string makeAxisTitle(const Mantid::Geometry::IMDDimension &dim); diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h index fe5a61c39123..e85e8c1a0b30 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h @@ -37,7 +37,7 @@ enum VisualNormalization { }; // Helper typedef -typedef Mantid::signal_t (Mantid::API::IMDNode::*NormFuncIMDNodePtr)() const; +using NormFuncIMDNodePtr = Mantid::signal_t (Mantid::API::IMDNode::*)() const; /** Determine which normalization function will be called on an IMDNode @@ -56,4 +56,4 @@ createIteratorWithNormalization(const VisualNormalization normalizationOption, } } -#endif /*MANTID_VATES_NORMALIZATION_H_*/ \ No newline at end of file +#endif /*MANTID_VATES_NORMALIZATION_H_*/ diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h index 49875440b54b..498d9a535458 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h @@ -29,8 +29,8 @@ class DLLExport PeaksPresenterVsi { const bool ascending) = 0; }; -typedef boost::shared_ptr PeaksPresenterVsi_sptr; -typedef boost::shared_ptr PeaksPresenterVsi_const_sptr; +using PeaksPresenterVsi_sptr = boost::shared_ptr; +using PeaksPresenterVsi_const_sptr = boost::shared_ptr; } } -#endif \ No newline at end of file +#endif diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h index 7c1cbb085de4..314e52a504d0 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h @@ -47,12 +47,12 @@ template class DLLExport FrustumPlane { enum { m_location = I }; }; -typedef FrustumPlane LeftPlane; -typedef FrustumPlane RightPlane; -typedef FrustumPlane BottomPlane; -typedef FrustumPlane TopPlane; -typedef FrustumPlane FarPlane; -typedef FrustumPlane NearPlane; +using LeftPlane = FrustumPlane ; +using RightPlane = FrustumPlane ; +using BottomPlane = FrustumPlane ; +using TopPlane = FrustumPlane ; +using FarPlane = FrustumPlane ; +using NearPlane = FrustumPlane ; class DLLExport ViewFrustum { public: @@ -156,9 +156,8 @@ void ViewFrustum::initializeMatrix(Mantid::Kernel::Matrix &matrix, } /// shared pointer to the view frustum -typedef boost::shared_ptr ViewFrustum_sptr; -typedef boost::shared_ptr - ViewFrustum_const_sptr; +using ViewFrustum_sptr = boost::shared_ptr; +using ViewFrustum_const_sptr = boost::shared_ptr; } } -#endif \ No newline at end of file +#endif diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h index de95431d72b3..4ef75133b75c 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkDataSetFactory.h @@ -247,8 +247,8 @@ class DLLExport vtkDataSetFactory bool m_bCheckDimensionality; }; -typedef boost::shared_ptr vtkDataSetFactory_sptr; -typedef std::unique_ptr vtkDataSetFactory_uptr; +using vtkDataSetFactory_sptr = boost::shared_ptr; +using vtkDataSetFactory_uptr = std::unique_ptr; } } diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h index 0ed83ee2ced6..56770476a3d3 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h @@ -74,11 +74,9 @@ class DLLExport vtkMDHistoHex4DFactory : public vtkMDHistoHexFactory { void validate() const override; private: - typedef std::vector>> PointMap; - - typedef std::vector> Plane; - - typedef std::vector Column; + using PointMap = std::vector>>; + using Plane = std::vector>; + using Column = std::vector; /// timestep obtained from framework. double m_timestep; diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h index 3223b13f86e0..3560e0d06aa3 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h @@ -59,7 +59,7 @@ class DLLExport vtkMDHistoLineFactory : public vtkDataSetFactory { void initialize(const Mantid::API::Workspace_sptr &workspace) override; - typedef std::vector Column; + using Column = std::vector ; std::string getFactoryTypeName() const override { return "vtkMDHistoLineFactory"; diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h index 8f8a643de51a..5aec1739e190 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h @@ -62,9 +62,9 @@ class DLLExport vtkMDHistoQuadFactory : public vtkDataSetFactory { void initialize(const Mantid::API::Workspace_sptr &workspace) override; - typedef std::vector> Plane; + using Plane = std::vector>; - typedef std::vector Column; + using Column = std::vector; std::string getFactoryTypeName() const override { return "vtkMDHistoQuadFactory"; diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h index ecb8b0c95701..e6fd9c757d19 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h @@ -18,8 +18,7 @@ namespace Mantid { namespace VATES { -// Helper typedef -typedef Mantid::signal_t (Mantid::API::IMDNode::*SigFuncIMDNodePtr)() const; +using SigFuncIMDNodePtr = Mantid::signal_t (Mantid::API::IMDNode::*)() const; /** * Factory that creates a simple "splatter plot" data set composed of points diff --git a/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h b/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h index 0a249d713b61..bf4ae0aee056 100644 --- a/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h +++ b/qt/paraview_ext/VatesAPI/test/MDHWLoadingPresenterTest.h @@ -31,7 +31,7 @@ class MDHWLoadingPresenterTest : public CxxTest::TestSuite { */ class ConcreteMDHWLoadingPresenter : public MDHWLoadingPresenter { private: - typedef MDHWLoadingPresenter BaseClass; + using BaseClass = MDHWLoadingPresenter; public: ConcreteMDHWLoadingPresenter(std::unique_ptr view) From 1730c5c2ccab308bffe799d4cd7cd0fc3bfc87dc Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 19 Mar 2018 08:07:34 +0000 Subject: [PATCH 299/364] Re #22048: Fixed SINGLE_PARAMETER_VALUE macro. --- Framework/API/inc/MantidAPI/SingleValueParameter.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Framework/API/inc/MantidAPI/SingleValueParameter.h b/Framework/API/inc/MantidAPI/SingleValueParameter.h index a346d7107385..8736075130a5 100644 --- a/Framework/API/inc/MantidAPI/SingleValueParameter.h +++ b/Framework/API/inc/MantidAPI/SingleValueParameter.h @@ -159,11 +159,8 @@ std::string SingleValueParameter::toXMLString() const { class classname \ : public Mantid::API::SingleValueParameter { \ public: \ - using SuperType = \ - Mantid::API::SingleValueParameter static std::string \ - parameterName() { \ - return #classname; \ - } \ + using SuperType = Mantid::API::SingleValueParameter; \ + static std::string parameterName() { return #classname; } \ classname(type_ value) : SuperType(value) {} \ classname() : SuperType() {} \ std::string getName() const override { return #classname; } \ From 9d404cee4f9b53739aa6ca054a41f45973ba08d4 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 19 Mar 2018 09:01:27 +0000 Subject: [PATCH 300/364] Re #22048: Applied clang-format patch. --- .../VatesAPI/inc/MantidVatesAPI/Common.h | 6 ++++-- .../VatesAPI/inc/MantidVatesAPI/ViewFrustum.h | 15 ++++++++------- .../inc/MantidVatesAPI/vtkMDHistoLineFactory.h | 2 +- .../test/FilteringUpdateProgressActionTest.h | 3 ++- .../ReflMeasureTransferStrategy.cpp | 3 ++- .../ISISSANS/SANSRunWindow.cpp | 3 ++- qt/scientific_interfaces/ISISSANS/SANSRunWindow.h | 5 +++-- .../Muon/MuonAnalysisFitDataPresenter.cpp | 3 ++- .../Muon/MuonAnalysisFitDataPresenter.h | 4 +++- .../Muon/MuonAnalysisHelper.cpp | 2 +- .../Muon/MuonAnalysisResultTableCreator.h | 4 ++-- .../Muon/MuonAnalysisResultTableTab.h | 2 +- .../Common/AlgorithmInputHistory.h | 3 ++- .../MantidQtWidgets/Common/BatchAlgorithmRunner.h | 3 ++- .../Common/FindFilesThreadPoolManager.h | 3 ++- .../inc/MantidQtWidgets/Common/InterfaceFactory.h | 6 ++++-- .../Common/SelectionNotificationService.h | 3 ++- .../src/QtPropertyBrowser/qtpropertybrowser.cpp | 8 ++++++-- .../algorithm_dialogs/src/StartLiveDataDialog.cpp | 6 ++++-- .../SliceViewer/ConcretePeaksPresenter.h | 2 +- .../MantidQtWidgets/SliceViewer/PeaksPresenter.h | 3 ++- .../sliceviewer/test/ConcretePeaksPresenterTest.h | 3 ++- .../test/PeakRepresentationCrossTest.h | 6 ++++-- .../test/PeakRepresentationSphereTest.h | 6 ++++-- .../SpectrumViewer/MatrixWSDataSource.h | 3 ++- .../SpectrumViewer/SpectrumDataSource.h | 3 ++- 26 files changed, 70 insertions(+), 40 deletions(-) diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h index 735266d4e39e..dd59f7d9ba4b 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Common.h @@ -14,14 +14,16 @@ class IMDDimension; namespace VATES { /// Vector of IMDDimension shared pointers. -using DimensionVec = std::vector>; +using DimensionVec = + std::vector>; /// IMDDimension as shared pointer. using Dimension_sptr = boost::shared_ptr; /// IMDDimension as const shared pointer. Note that IMDDimension is pure /// virtual. -using Dimension_const_sptr = boost::shared_ptr; +using Dimension_const_sptr = + boost::shared_ptr; std::string makeAxisTitle(const Mantid::Geometry::IMDDimension &dim); diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h index 314e52a504d0..ff56b7e46e1c 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h @@ -47,12 +47,12 @@ template class DLLExport FrustumPlane { enum { m_location = I }; }; -using LeftPlane = FrustumPlane ; -using RightPlane = FrustumPlane ; -using BottomPlane = FrustumPlane ; -using TopPlane = FrustumPlane ; -using FarPlane = FrustumPlane ; -using NearPlane = FrustumPlane ; +using LeftPlane = FrustumPlane; +using RightPlane = FrustumPlane; +using BottomPlane = FrustumPlane; +using TopPlane = FrustumPlane; +using FarPlane = FrustumPlane; +using NearPlane = FrustumPlane; class DLLExport ViewFrustum { public: @@ -157,7 +157,8 @@ void ViewFrustum::initializeMatrix(Mantid::Kernel::Matrix &matrix, /// shared pointer to the view frustum using ViewFrustum_sptr = boost::shared_ptr; -using ViewFrustum_const_sptr = boost::shared_ptr; +using ViewFrustum_const_sptr = + boost::shared_ptr; } } #endif diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h index 3560e0d06aa3..f3d3b2916ba5 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h @@ -59,7 +59,7 @@ class DLLExport vtkMDHistoLineFactory : public vtkDataSetFactory { void initialize(const Mantid::API::Workspace_sptr &workspace) override; - using Column = std::vector ; + using Column = std::vector; std::string getFactoryTypeName() const override { return "vtkMDHistoLineFactory"; diff --git a/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h b/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h index 55eae5f2f3a8..fade140c7764 100644 --- a/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h +++ b/qt/paraview_ext/VatesAPI/test/FilteringUpdateProgressActionTest.h @@ -18,7 +18,8 @@ class FilteringUpdateProgressActionTest : public CxxTest::TestSuite { } }; - using ProgressActionType = Mantid::VATES::FilterUpdateProgressAction; + using ProgressActionType = + Mantid::VATES::FilterUpdateProgressAction; public: void testCallsView() { diff --git a/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp b/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp index 334aef8c297d..f56491e7a629 100644 --- a/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp +++ b/qt/scientific_interfaces/ISISReflectometry/ReflMeasureTransferStrategy.cpp @@ -44,7 +44,8 @@ MantidQt::CustomInterfaces::ReflMeasureTransferStrategy::transferRuns( SearchResultMap &searchResults, Mantid::Kernel::ProgressBase &progress) { using VecSameMeasurement = std::vector; - using MapGroupedMeasurement = std::map; + using MapGroupedMeasurement = + std::map; // table-like output for successful runs std::vector> runs; diff --git a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp index ed12722f9fcf..31b6f24dd8ef 100644 --- a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp +++ b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.cpp @@ -2145,7 +2145,8 @@ bool SANSRunWindow::handleLoadButtonClick() { m_uiForm.sample_geomid->setCurrentIndex(geomId - 1); using namespace boost; - using GeomSampleInfo = tuple, std::string>; + using GeomSampleInfo = + tuple, std::string>; std::vector sampleInfoList; sampleInfoList.push_back(make_tuple(m_uiForm.sample_thick, diff --git a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h index 549e2b2a6086..9a0db62bb67f 100644 --- a/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h +++ b/qt/scientific_interfaces/ISISSANS/SANSRunWindow.h @@ -330,7 +330,7 @@ private slots: enum TransSettings { M3, M4, RADIUS, ROI }; /// holds pointer to validators and their locations - using ValMap = std::map >; + using ValMap = std::map>; /// The form generated by Qt Designer Ui::SANSRunWindow m_uiForm; /// this object holds the functionality in the Add Files tab @@ -383,7 +383,8 @@ private slots: /// Holds pointers to the check box for each supported save format with the /// name of its save algorithm QHash m_savFormats; - using SavFormatsConstIt = QHash::const_iterator; + using SavFormatsConstIt = + QHash::const_iterator; /// Get notified when the system input directories have changed Poco::NObserver m_newInDir; diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp index 95d636cc1fd5..866782134b55 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.cpp @@ -23,7 +23,8 @@ using Mantid::API::ITableWorkspace; using Mantid::API::MatrixWorkspace; using Mantid::API::TableRow; using Mantid::API::WorkspaceGroup; -using RebinType = MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType; +using RebinType = + MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType; namespace { /// static logger diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h index 091b69d5d557..40a92514a7f3 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysisFitDataPresenter.h @@ -11,7 +11,9 @@ #include /// Save some typing -using RebinOptions = std::pair; +using RebinOptions = std::pair< + MantidQt::CustomInterfaces::Muon::MuonAnalysisOptionTab::RebinType, + std::string>; namespace Mantid { namespace API { diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp index 9d7e86183bae..52df489c0b30 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysisHelper.cpp @@ -1102,7 +1102,7 @@ getWorkspaceColors(const std::vector &workspaces) { QMap colors; // position, color // Vector of pairs - using FitProp = std::pair >; + using FitProp = std::pair>; std::vector fitProperties; // Get fit properties for each input workspace diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h index d4c4f8c58ee8..4e4a2303fab2 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableCreator.h @@ -9,8 +9,8 @@ namespace MantidQt { namespace CustomInterfaces { -using WSParameterList = QMap >; -using LogValuesMap = QMap >; +using WSParameterList = QMap>; +using LogValuesMap = QMap>; /** MuonAnalysisResultTableCreator : Creates table of muon fit results Used in the "result table" tab of Muon Analysis interface diff --git a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h index 6f4ae326f7af..a59f0e29be4f 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h +++ b/qt/scientific_interfaces/Muon/MuonAnalysisResultTableTab.h @@ -16,7 +16,7 @@ class MuonAnalysis; namespace MantidQt { namespace CustomInterfaces { namespace Muon { -using WSParameterList = QMap >; +using WSParameterList = QMap>; /** This is a Helper class for MuonAnalysis. In particular this helper class deals diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h index 53706682c1b2..25c13f5492a9 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/AlgorithmInputHistory.h @@ -96,7 +96,8 @@ class EXPORT_OPT_MANTIDQT_COMMON AlgorithmInputHistoryImpl friend struct Mantid::Kernel::CreateUsingNew; }; -using AlgorithmInputHistory = Mantid::Kernel::SingletonHolder; +using AlgorithmInputHistory = + Mantid::Kernel::SingletonHolder; } } diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h b/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h index 1e976435e309..117cb8d41a52 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/BatchAlgorithmRunner.h @@ -60,7 +60,8 @@ class EXPORT_OPT_MANTIDQT_COMMON BatchAlgorithmRunner : public QObject { public: using AlgorithmRuntimeProps = std::map; - using ConfiguredAlgorithm = std::pair; + using ConfiguredAlgorithm = + std::pair; explicit BatchAlgorithmRunner(QObject *parent = nullptr); ~BatchAlgorithmRunner() override; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h index 4e4d57dd03aa..7252ac0cbbb6 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManager.h @@ -21,7 +21,8 @@ namespace API { */ class EXPORT_OPT_MANTIDQT_COMMON FindFilesThreadPoolManager : public QObject { Q_OBJECT - using ThreadAllocator = std::function; + using ThreadAllocator = + std::function; public: /// Create a new thread pool manager for finding files diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h b/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h index 1141964429b3..48209257627c 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/InterfaceFactory.h @@ -70,7 +70,8 @@ class EXPORT_OPT_MANTIDQT_COMMON AlgorithmDialogFactoryImpl }; /// The specific instantiation of the templated type -using AlgorithmDialogFactory = Mantid::Kernel::SingletonHolder; +using AlgorithmDialogFactory = + Mantid::Kernel::SingletonHolder; /** The UserSubWindowFactory is responsible for creating concrete instances of @@ -179,7 +180,8 @@ void UserSubWindowFactoryImpl::saveAliasNames(const std::string &realName) { } /// The specific instantiation of the templated type -using UserSubWindowFactory = Mantid::Kernel::SingletonHolder; +using UserSubWindowFactory = + Mantid::Kernel::SingletonHolder; } } diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h b/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h index c1b5adfc1f7a..0c73de84869c 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/SelectionNotificationService.h @@ -63,7 +63,8 @@ class EXPORT_OPT_MANTIDQT_COMMON SelectionNotificationServiceImpl SelectionNotificationServiceImpl>; }; -using SelectionNotificationService = Mantid::Kernel::SingletonHolder; +using SelectionNotificationService = + Mantid::Kernel::SingletonHolder; } } namespace Mantid { diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp index 18d98aa5fe6f..1a4b46554825 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp @@ -1172,8 +1172,12 @@ QtBrowserItem::~QtBrowserItem() { delete d_ptr; } //////////////////////////////////// -using Map1 = QMap >; -using Map2 = QMap > >; +using Map1 = + QMap>; +using Map2 = + QMap>>; Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory) Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews) diff --git a/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp b/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp index 718bde630b71..d012208585e5 100644 --- a/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp +++ b/qt/widgets/plugins/algorithm_dialogs/src/StartLiveDataDialog.cpp @@ -40,7 +40,8 @@ class LiveDataAlgInputHistoryImpl : public AbstractAlgorithmInputHistory { template class Mantid::Kernel::SingletonHolder; #endif /* _WIN32 */ /// The specific instantiation of the templated type -using LiveDataAlgInputHistory = Mantid::Kernel::SingletonHolder; +using LiveDataAlgInputHistory = + Mantid::Kernel::SingletonHolder; class LiveDataPostProcessingAlgInputHistoryImpl : public AbstractAlgorithmInputHistory { @@ -60,7 +61,8 @@ template class Mantid::Kernel::SingletonHolder< LiveDataPostProcessingAlgInputHistoryImpl>; #endif /* _WIN32 */ /// The specific instantiation of the templated type -using LiveDataPostProcessingAlgInputHistory = Mantid::Kernel::SingletonHolder; +using LiveDataPostProcessingAlgInputHistory = + Mantid::Kernel::SingletonHolder; } // Add this class to the list of specialised dialogs in this namespace diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h index 273a122d19af..1db7c3294635 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/ConcretePeaksPresenter.h @@ -14,7 +14,7 @@ namespace MantidQt { namespace SliceViewer { /// Alias for Vector of Peak Overlay Views -using VecPeakOverlayView = std::vector >; +using VecPeakOverlayView = std::vector>; /// Coordinate System Enum to String. std::string DLLExport diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h index ecb866c7734b..27bac238237a 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/PeaksPresenter.h @@ -35,7 +35,8 @@ class PeakOverlayView; class UpdateableOnDemand; // Alias -using SetPeaksWorkspaces = std::set >; +using SetPeaksWorkspaces = + std::set>; /*--------------------------------------------------------- Abstract PeaksPresenter. diff --git a/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h b/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h index 3fee2f048849..a73b280ba0ec 100644 --- a/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h +++ b/qt/widgets/sliceviewer/test/ConcretePeaksPresenterTest.h @@ -30,7 +30,8 @@ using MDGeometry_sptr = boost::shared_ptr; class ConcretePeaksPresenterTest : public CxxTest::TestSuite { /// Alias. - using ConcretePeaksPresenter_sptr = boost::shared_ptr; + using ConcretePeaksPresenter_sptr = + boost::shared_ptr; /// Helper method to create a good 'Integrated' peaks workspace Mantid::API::IPeaksWorkspace_sptr diff --git a/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h b/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h index 9bb481526a66..1c90d4c47f1c 100644 --- a/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h +++ b/qt/widgets/sliceviewer/test/PeakRepresentationCrossTest.h @@ -182,9 +182,11 @@ class PeakRepresentationCrossTest : public CxxTest::TestSuite { class PeakRepresentationCrossTestPerformance : public CxxTest::TestSuite { private: - using VecPeakRepCross = std::vector >; + using VecPeakRepCross = + std::vector>; - using VecPeakRepCrossWrapped = std::vector >; + using VecPeakRepCrossWrapped = std::vector< + boost::shared_ptr>; /// Collection to store a large number of PeakRepresentationCross. VecPeakRepCross m_peaks; diff --git a/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h b/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h index ad8be837c9ce..a1a589a3f165 100644 --- a/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h +++ b/qt/widgets/sliceviewer/test/PeakRepresentationSphereTest.h @@ -316,8 +316,10 @@ class PeakRepresentationSphereTestPerformance : public CxxTest::TestSuite { } private: - using PeaksRepresentationSphere_sptr = boost::shared_ptr; - using VecPeaksRepresentationSphere = std::vector; + using PeaksRepresentationSphere_sptr = + boost::shared_ptr; + using VecPeaksRepresentationSphere = + std::vector; /// Collection to store a large number of physicalPeaks. VecPeaksRepresentationSphere m_peaks; diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h index 390f92a2041e..58aec195aaed 100644 --- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h +++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/MatrixWSDataSource.h @@ -104,7 +104,8 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER MatrixWSDataSource }; using MatrixWSDataSource_sptr = boost::shared_ptr; -using MatrixWSDataSource_const_sptr = boost::shared_ptr; +using MatrixWSDataSource_const_sptr = + boost::shared_ptr; } // namespace SpectrumView } // namespace MantidQt diff --git a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h index d78b385e57d2..d084570ac5c2 100644 --- a/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h +++ b/qt/widgets/spectrumviewer/inc/MantidQtWidgets/SpectrumViewer/SpectrumDataSource.h @@ -107,7 +107,8 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumDataSource { }; using SpectrumDataSource_sptr = boost::shared_ptr; -using SpectrumDataSource_const_sptr = boost::shared_ptr; +using SpectrumDataSource_const_sptr = + boost::shared_ptr; } // namespace SpectrumView } // namespace MantidQt From 69767ca2013071aba766d63e22f97c8ed7d24b34 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Mon, 19 Mar 2018 09:18:26 +0000 Subject: [PATCH 301/364] Remove pyplot docs. Re #22101 --- docs/source/api/python/mantidplot/index.rst | 8 -------- .../source/api/python/mantidplot/pyplot/index.rst | 15 --------------- 2 files changed, 23 deletions(-) delete mode 100644 docs/source/api/python/mantidplot/pyplot/index.rst diff --git a/docs/source/api/python/mantidplot/index.rst b/docs/source/api/python/mantidplot/index.rst index a2be3b03524f..aa3cc26dc83e 100644 --- a/docs/source/api/python/mantidplot/index.rst +++ b/docs/source/api/python/mantidplot/index.rst @@ -72,11 +72,3 @@ This package defines the Python interface to the MantidPlot application. For fra waterfallPlot.rst windows.rst workspace.rst - -Submodules -########## - -.. toctree:: - :maxdepth: 1 - - pyplot/index diff --git a/docs/source/api/python/mantidplot/pyplot/index.rst b/docs/source/api/python/mantidplot/pyplot/index.rst deleted file mode 100644 index 824d782aa05e..000000000000 --- a/docs/source/api/python/mantidplot/pyplot/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -=================================================== - :mod:`pyplot` --- Matplotlib-like plotting package -=================================================== - -New plotting interface ----------------------- - -This package provides a simple command line interface to the Mantid -plotting functionality, resembling matplotlib and its pyplot package -(http://matplotlib.org). The module is subject to changes and feedback -is very much welcome! - -.. automodule:: pymantidplot.pyplot - :members: - :show-inheritance: From 328f0b7182b747e1d1bebbcfa3999270b9b1786d Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 19 Mar 2018 10:03:00 +0000 Subject: [PATCH 302/364] infinite geometry fix #21230 --- .../inc/MantidBeamline/ComponentType.h | 1 + .../Instrument/ComponentVisitor.h | 4 ++ .../Instrument/InstrumentVisitor.h | 6 +++ .../inc/MantidGeometry/Objects/CSGObject.h | 7 ++++ .../inc/MantidGeometry/Objects/IObject.h | 2 + .../Geometry/src/Instrument/ComponentInfo.cpp | 6 ++- .../src/Instrument/InstrumentVisitor.cpp | 41 +++++++++++++++++++ .../Geometry/src/Instrument/ObjComponent.cpp | 13 +++--- .../Geometry/src/Objects/ShapeFactory.cpp | 3 ++ .../instrumentview/src/InstrumentActor.cpp | 4 +- 10 files changed, 79 insertions(+), 8 deletions(-) diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentType.h b/Framework/Beamline/inc/MantidBeamline/ComponentType.h index 9548fac56244..c5e33293a069 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentType.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentType.h @@ -6,6 +6,7 @@ namespace Mantid { namespace Beamline { enum class ComponentType { Generic, + Infinite, Rectangular, Structured, Unstructured, diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h index 1ee03f9ba9eb..caa2b19eb069 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h @@ -43,7 +43,11 @@ class ComponentVisitor { virtual size_t registerComponentAssembly(const ICompAssembly &assembly) = 0; virtual size_t registerGenericComponent(const IComponent &component) = 0; virtual size_t + registerInfiniteComponent(const Mantid::Geometry::IComponent &component) = 0; + virtual size_t registerGenericObjComponent(const IObjComponent &objComponent) = 0; + virtual size_t + registerInfiniteObjComponent(const IObjComponent &component) = 0; virtual size_t registerDetector(const IDetector &detector) = 0; virtual size_t registerStructuredBank(const ICompAssembly &bank) = 0; virtual size_t registerObjComponentAssembly(const ObjCompAssembly &obj) = 0; diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h index f228a8b30797..a6a365bbc84a 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h @@ -168,9 +168,15 @@ class MANTID_GEOMETRY_DLL InstrumentVisitor virtual size_t registerGenericComponent( const Mantid::Geometry::IComponent &component) override; + virtual size_t registerInfiniteComponent( + const Mantid::Geometry::IComponent &component) override; + virtual size_t registerGenericObjComponent( const Mantid::Geometry::IObjComponent &objComponent) override; + virtual size_t + registerInfiniteObjComponent(const IObjComponent &objComponent) override; + virtual size_t registerStructuredBank(const Mantid::Geometry::ICompAssembly &bank) override; diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index e6b344189554..a8ea0b2ae7d5 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -83,6 +83,11 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { return obj; } + bool isFiniteGeometry() const override { return m_isFiniteGeometry; } + void setFiniteGeometryFlag(bool isFinite) override { + m_isFiniteGeometry = isFinite; + } + /// Return the top rule const Rule *topRule() const { return TopRule.get(); } void setID(const std::string &id) { m_id = id; } @@ -272,6 +277,8 @@ class MANTID_GEOMETRY_DLL CSGObject : public IObject { std::string m_id; /// material composition std::unique_ptr m_material; + /// Whether or not the object geometry is finite + bool m_isFiniteGeometry = true; protected: std::vector m_SurList; ///< Full surfaces (make a map diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h index 3fc6c456a075..3567f7bb27c5 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h @@ -59,6 +59,8 @@ class MANTID_GEOMETRY_DLL IObject { virtual bool isOnSide(const Kernel::V3D &) const = 0; virtual int calcValidType(const Kernel::V3D &Pt, const Kernel::V3D &uVec) const = 0; + virtual bool isFiniteGeometry() const { return true; } + virtual void setFiniteGeometryFlag(bool) {} virtual bool hasValidShape() const = 0; virtual IObject *clone() const = 0; virtual IObject * diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index 8e6c0dbe9a47..ad76cbcca0fd 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -392,7 +392,8 @@ BoundingBox ComponentInfo::componentBoundingBox(const size_t index, const BoundingBox *reference) const { // Check that we have a valid shape here - if (!hasValidShape(index)) { + if (!hasValidShape(index) || + componentType(index) == Beamline::ComponentType::Infinite) { return BoundingBox(); // Return null bounding box } const auto &s = this->shape(index); @@ -445,7 +446,8 @@ ComponentInfo::componentBoundingBox(const size_t index, */ BoundingBox ComponentInfo::boundingBox(const size_t componentIndex, const BoundingBox *reference) const { - if (isDetector(componentIndex)) { + if (isDetector(componentIndex) || + componentType(componentIndex) == Beamline::ComponentType::Infinite) { return componentBoundingBox(componentIndex, reference); } BoundingBox absoluteBB; diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index 48475106c4da..d8bc94059ff6 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -212,6 +212,35 @@ InstrumentVisitor::registerGenericComponent(const IComponent &component) { return componentIndex; } +/** +* @brief InstrumentVisitor::registerInfiniteComponent +* @param component : IComponent being visited +* @return Component index of this component +*/ +size_t InstrumentVisitor::registerInfiniteComponent( + const Mantid::Geometry::IComponent &component) { + /* + * For a generic leaf component we extend the component ids list, but + * the detector indexes entries will of course be empty + */ + m_detectorRanges->emplace_back( + std::make_pair(0, 0)); // Represents an empty range + // Record the ID -> index mapping + const size_t componentIndex = commonRegistration(component); + m_componentType->push_back(Beamline::ComponentType::Infinite); + + const size_t componentStart = m_assemblySortedComponentIndices->size(); + m_componentRanges->emplace_back( + std::make_pair(componentStart, componentStart + 1)); + m_assemblySortedComponentIndices->push_back(componentIndex); + // Unless this is the root component this parent is not correct and will be + // updated later in the register call of the parent. + m_parentComponentIndices->push_back(componentIndex); + // Generic components are not assemblies and do not therefore have children. + m_children->emplace_back(std::vector()); + return componentIndex; +} + /** * @brief InstrumentVisitor::registerGenericObjComponent * @param objComponent : IObjComponent being visited @@ -224,6 +253,18 @@ size_t InstrumentVisitor::registerGenericObjComponent( return index; } +/** +* @brief InstrumentVisitor::registerInfiniteObjComponent +* @param objComponent : IObjComponent being visited +* @return Component index of this component +*/ +size_t InstrumentVisitor::registerInfiniteObjComponent( + const IObjComponent &objComponent) { + auto index = registerInfiniteComponent(objComponent); + (*m_shapes)[index] = objComponent.shape(); + return index; +} + /** * Register a structured bank * @param bank : Rectangular Detector diff --git a/Framework/Geometry/src/Instrument/ObjComponent.cpp b/Framework/Geometry/src/Instrument/ObjComponent.cpp index 24f04ae61136..3b6691319239 100644 --- a/Framework/Geometry/src/Instrument/ObjComponent.cpp +++ b/Framework/Geometry/src/Instrument/ObjComponent.cpp @@ -1,12 +1,13 @@ #include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidGeometry/Instrument/ComponentVisitor.h" #include "MantidGeometry/Instrument/ComponentInfo.h" -#include "MantidGeometry/Objects/IObject.h" +#include "MantidGeometry/Instrument/ComponentVisitor.h" #include "MantidGeometry/Objects/BoundingBox.h" +#include "MantidGeometry/Objects/CSGObject.h" +#include "MantidGeometry/Objects/IObject.h" #include "MantidGeometry/Objects/Track.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidKernel/Exception.h" #include "MantidKernel/Material.h" -#include "MantidGeometry/Rendering/GeometryHandler.h" #include namespace Mantid { @@ -342,8 +343,10 @@ void ObjComponent::initDraw() const { */ size_t ObjComponent::registerContents(class ComponentVisitor &componentVisitor) const { - - return componentVisitor.registerGenericObjComponent(*this); + if (this->shape()->isFiniteGeometry()) + return componentVisitor.registerGenericObjComponent(*this); + else + return componentVisitor.registerInfiniteObjComponent(*this); } } // namespace Geometry diff --git a/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Framework/Geometry/src/Objects/ShapeFactory.cpp index c34fd7128867..439fb17c8956 100644 --- a/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -152,10 +152,12 @@ ShapeFactory::createShape(Poco::XML::Element *pElem) { numPrimitives++; } else if (primitiveName == "infinite-plane") { idMatching[idFromUser] = parseInfinitePlane(pE, primitives, l_id); + retVal->setFiniteGeometryFlag(false); numPrimitives++; } else if (primitiveName == "infinite-cylinder") { idMatching[idFromUser] = parseInfiniteCylinder(pE, primitives, l_id); + retVal->setFiniteGeometryFlag(false); numPrimitives++; } else if (primitiveName == "cylinder") { lastElement = pE; @@ -175,6 +177,7 @@ ShapeFactory::createShape(Poco::XML::Element *pElem) { numPrimitives++; } else if (primitiveName == "infinite-cone") { idMatching[idFromUser] = parseInfiniteCone(pE, primitives, l_id); + retVal->setFiniteGeometryFlag(false); numPrimitives++; } else if (primitiveName == "cone") { lastElement = pE; diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index 59422c7bb561..e304b6b59e9b 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -728,8 +728,10 @@ void InstrumentActor::draw(bool picking) const { void InstrumentActor::doDraw(bool picking) const { const auto &compInfo = componentInfo(); for (size_t i = 0; i < compInfo.size(); ++i) { + auto type = compInfo.componentType(i); if ((!compInfo.isDetector(i) && !m_showGuides) || - compInfo.componentType(i) == Beamline::ComponentType::OutlineComposite) + type == Beamline::ComponentType::OutlineComposite || + type == Beamline::ComponentType::Infinite) continue; if (compInfo.hasValidShape(i)) { From a143437048b9937d23554cd17bc4beaf122ad35c Mon Sep 17 00:00:00 2001 From: Gagik Vardanyan Date: Mon, 19 Mar 2018 11:07:22 +0100 Subject: [PATCH 303/364] Re #22082 dev docs: python vs c++ algorithms --- dev-docs/source/PythonVSCppAlgorithms.rst | 79 +++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 dev-docs/source/PythonVSCppAlgorithms.rst diff --git a/dev-docs/source/PythonVSCppAlgorithms.rst b/dev-docs/source/PythonVSCppAlgorithms.rst new file mode 100644 index 000000000000..b9de48c95407 --- /dev/null +++ b/dev-docs/source/PythonVSCppAlgorithms.rst @@ -0,0 +1,79 @@ +.. _PythonVSCppAlgorithms: + +======================== +Python vs C++ Algorithms +======================== + +.. contents:: + :local: + +Overview +-------- + +Mantid can be extended both with python and C++ algorithms as plug-ins. There are a number of considerations to take into account when deciding which language to choose. +These are summarised in the table and discussed below. Generally, it is recommended to implement **atomic** operations in C++, and **workflows** in python. + +Algorithm Language Comparison +----------------------------- + ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| Consideration | C++ | Python | ++===================+===================================================================================================================+============================================================================+ +| Execution Speed | Generally much faster (order of magnitude, and beyond), since compiled. Lots of optimisations can be made. | Generally slower. Numpy should be used wherever possible. | +| | OpenMP parallelisation for trivial loops (e.g. loops over spectra). | Large loops should be avoided, especially the nested ones. | +| | | Provides no means for trivial parallelisation. | ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| Creation | Generally slower and more complicated, but you do get the advantage of compile-time type checking. | Generally easier and faster. | ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| Workflow | Large overhead when setting and getting the properties of child algorithms. Can quickly grow cumbersome, if many | Very convenient and concise for workflows thanks to the python SimpleAPI. | +| | child algorithms have to be run. | | ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| Testability | Easy in C++ | Easy in python | ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| API Accessibility | Full | Some of the framework functionality is not exposed to python. | ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| User Readability | Users are not generally expected to understand C++ code. | Better readability. Power users are expected to understand python code. | ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| User Modifiability| Users can not change C++ algorithms, since they are shipped in the compiled form. | Users can play with python algorithms, since they are shipped as source. | +| | | It is not advised, of course, do to so, but in case of a spurious result, | +| | | they have the opportunity to play with the algorithm before contacting us. | ++-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ + +Multiple Possibilities in Mantid +-------------------------------- + +There are many ways to extend Mantid to add new features not present out-of-the-box. + +The easiest way to extend Mantid, and possibly the best starting place for any improvements, is a python script. Mantid provides a very high level of scriptable control, including plotting and visualisation as well as the execution of core routines. The scripting manual for Mantid provides an overview of the possibilities offered for scripting, including automatic generation via the graphical user interface for Mantid. + +Algorithms and Workspaces are core concepts in Mantid. Generally, an Algorithm does something based on input workspaces, either to create a new one from the results, or to modify the input in-place. One reason to create an Algorithm, is because you have a script containing a well-defined and useful procedure, that you would like to share with a wider audience. It usually requires a low amount of effort to adapt a python script into one or more Python Algorithms. + +Core Mantid Algorithms as well as some user defined Algorithms, are generally written in C++. There are a number of advantages to doing this (which are covered later), but also some serious disadvantages. When thinking about writing new functionality against Mantid, C++ does not need to be the default option. + +Should I Write a C++ Algorithm? +------------------------------- +The main reason to write algorithms in C++ is that you can often significantly reduce the run-time processing time over code written in Python. Looping over large volumes of data tends to be fastest in C++. Mantid also has facilities for running your Algorithm in a multi-threaded context when assembled in C++. + +Writing an algorithm in C++ gives you all the advantages associated with a compiled language including compile-time type checking. Some developers find this advantage significant enough to make writing C++ algorithms faster than Python equivalents. + +Writing clean Mantid Algorithm code in C++ is sometimes not a good idea. Here are some brief reasons why: + +For workflow Algorithms consisting mainly of child-algorithms execution, child-algorithm set-up in C++ can be long-winded and more fragile than Python. +There are many different ways to do the same thing in C++, and therefore more ways to get it wrong. +You are responsible for all the heap-allocated memory, as well as other resources you create. +Our target platforms have different compilers, with different interpretations of the same C++ standard, this can make writing cross-platform code tricky. +Compiler and linker outputs can be verbose, particularly in the presence of templated code. + +Should I Write a Python Algorithm? +---------------------------------- +Python algorithms are generally easier to put together than those assembled in C++. Because python has a limited dictionary, the barriers to writing effective code are much lower. Furthermore, not all algorithms need to run at the speed of light. For Algorithms that are only fed small volumes of data from small instruments, the user will not notice the difference between it running in half a second in Python or a tenth of a second in C++. + +It's more natural to convert a python script into a python Algorithm than directly into a C++ algorithm. In many cases, the algorithm functionality is best assembled by procedural execution of existing algorithms. For this, the python API provides the best means of executing an algorithm in a single line, using well defined, named variables. An algorithm of this nature will take up only a few lines in Python and therefore be very easy to read and maintain. + +Python algorithms also benefit from automatic GUI creation when they are registered with Mantid, so they can be used equally well through the command line, or through MantidPlot graphically. + +Python algorithms are great for editing and re-registering. Users can tweak existing Python algorithms or generate their own, without the complication of setting up a build environment. They can also more easily be re-issued to fix particular issues than C++ algorithms. + +Note for Mantid Developers +-------------------------- +Developers creating new algorithms in python must still generate unit tests for them. When an algorithm breaks, users do not care what language they are written in. The developer test suites allow you to create the same level of test coverage in python as you would in C++. Developers should also take care to ensure that the test exercises all of the code, as Python provides no compile-time type checking. From 46cc56b2f3efe9107fc94966b465bdd1bc392142 Mon Sep 17 00:00:00 2001 From: Gagik Vardanyan Date: Mon, 19 Mar 2018 11:22:28 +0100 Subject: [PATCH 304/364] Re #22082 table row headins bold --- dev-docs/source/PythonVSCppAlgorithms.rst | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/dev-docs/source/PythonVSCppAlgorithms.rst b/dev-docs/source/PythonVSCppAlgorithms.rst index b9de48c95407..80993461f751 100644 --- a/dev-docs/source/PythonVSCppAlgorithms.rst +++ b/dev-docs/source/PythonVSCppAlgorithms.rst @@ -16,28 +16,28 @@ These are summarised in the table and discussed below. Generally, it is recommen Algorithm Language Comparison ----------------------------- -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ -| Consideration | C++ | Python | -+===================+===================================================================================================================+============================================================================+ -| Execution Speed | Generally much faster (order of magnitude, and beyond), since compiled. Lots of optimisations can be made. | Generally slower. Numpy should be used wherever possible. | -| | OpenMP parallelisation for trivial loops (e.g. loops over spectra). | Large loops should be avoided, especially the nested ones. | -| | | Provides no means for trivial parallelisation. | -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ -| Creation | Generally slower and more complicated, but you do get the advantage of compile-time type checking. | Generally easier and faster. | -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ -| Workflow | Large overhead when setting and getting the properties of child algorithms. Can quickly grow cumbersome, if many | Very convenient and concise for workflows thanks to the python SimpleAPI. | -| | child algorithms have to be run. | | -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ -| Testability | Easy in C++ | Easy in python | -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ -| API Accessibility | Full | Some of the framework functionality is not exposed to python. | -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ -| User Readability | Users are not generally expected to understand C++ code. | Better readability. Power users are expected to understand python code. | -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ -| User Modifiability| Users can not change C++ algorithms, since they are shipped in the compiled form. | Users can play with python algorithms, since they are shipped as source. | -| | | It is not advised, of course, do to so, but in case of a spurious result, | -| | | they have the opportunity to play with the algorithm before contacting us. | -+-------------------+-------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| Consideration | C++ | Python | ++=======================+========================================================================================================+============================================================================+ +| **Execution Speed** | Generally much faster (order of magnitude, and beyond), since compiled. | Generally slower. Numpy should be used wherever possible. | +| | Lots of optimisations can be made. OpenMP parallelisation for trivial loops (e.g. loops over spectra). | Large loops should be avoided, especially the nested ones. | +| | | Provides no means for trivial parallelisation. | ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| **Creation** | Generally slower and more complicated, but you do get the advantage of compile-time type checking. | Generally easier and faster. | ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| **Workflow** | Large overhead when setting and getting the properties of child algorithms. | Very convenient and concise for workflows thanks to the python SimpleAPI. | +| | Can quickly grow cumbersome, if many child algorithms have to be run. | | ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| **Testability** | Easy in C++ | Easy in python | ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| **API Accessibility** | Full | Some of the framework functionality is not exposed to python. | ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| **User Readability** | Users are not generally expected to understand C++ code. | Better readability. Power users are expected to understand python code. | ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ +| **User Modifiability**| Users can not change C++ algorithms, since they are shipped in the compiled form. | Users can play with python algorithms, since they are shipped as source. | +| | | It is not advised, of course, do to so, but in case of a spurious result, | +| | | they have the opportunity to play with the algorithm before contacting us. | ++-----------------------+--------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------+ Multiple Possibilities in Mantid -------------------------------- @@ -46,7 +46,7 @@ There are many ways to extend Mantid to add new features not present out-of-the- The easiest way to extend Mantid, and possibly the best starting place for any improvements, is a python script. Mantid provides a very high level of scriptable control, including plotting and visualisation as well as the execution of core routines. The scripting manual for Mantid provides an overview of the possibilities offered for scripting, including automatic generation via the graphical user interface for Mantid. -Algorithms and Workspaces are core concepts in Mantid. Generally, an Algorithm does something based on input workspaces, either to create a new one from the results, or to modify the input in-place. One reason to create an Algorithm, is because you have a script containing a well-defined and useful procedure, that you would like to share with a wider audience. It usually requires a low amount of effort to adapt a python script into one or more Python Algorithms. +:ref:`Algorithms ` and :ref:`workspaces ` are core concepts in Mantid. Generally, an Algorithm does something based on input workspaces, either to create a new one from the results, or to modify the input in-place. One reason to create an Algorithm, is because you have a script containing a well-defined and useful procedure, that you would like to share with a wider audience. It usually requires a low amount of effort to adapt a python script into one or more Python Algorithms. Core Mantid Algorithms as well as some user defined Algorithms, are generally written in C++. There are a number of advantages to doing this (which are covered later), but also some serious disadvantages. When thinking about writing new functionality against Mantid, C++ does not need to be the default option. From e07b2bf50bc7eaeb32967b712b3665c1ffc8a2c4 Mon Sep 17 00:00:00 2001 From: Matthew Andrew Date: Mon, 19 Mar 2018 10:24:15 +0000 Subject: [PATCH 305/364] Update index.rst --- docs/source/release/v3.12.0/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/release/v3.12.0/index.rst b/docs/source/release/v3.12.0/index.rst index 986c57b3595e..6e4e7479a0d6 100644 --- a/docs/source/release/v3.12.0/index.rst +++ b/docs/source/release/v3.12.0/index.rst @@ -40,7 +40,7 @@ access the source code on `GitHub release page`_. Citation -------- -Please cite any usage of Mantid as follows: **TODO update with current version doi** +Please cite any usage of Mantid as follows: - *Mantid 3.12.0: Manipulation and Analysis Toolkit for Instrument Data.; Mantid Project*. `doi: 10.5286/SOFTWARE/MANTID3.12.0 `_ From 4e92cf984096d688f8f5287725879aa68682cbfe Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 19 Mar 2018 10:41:30 +0000 Subject: [PATCH 306/364] Re #22048: Fixed broken brace in TableWorkspace.h. --- Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h index c3874fdb65bf..d893a30fab61 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableWorkspace.h @@ -433,5 +433,6 @@ using TableWorkspace_sptr = boost::shared_ptr; using TableWorkspace_const_sptr = boost::shared_ptr; } // namespace DataObjects +} // namespace Mantid #endif /*MANTID_DATAOBJECTS_TABLEWORKSPACE_H_*/ From 108a2150afbc580ebd9dc84c91f7ef762ebea82a Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Mon, 19 Mar 2018 11:04:23 +0000 Subject: [PATCH 307/364] Fix shape check #21230 --- Framework/Geometry/src/Instrument/ObjComponent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Geometry/src/Instrument/ObjComponent.cpp b/Framework/Geometry/src/Instrument/ObjComponent.cpp index 3b6691319239..5dcd1e54cf1a 100644 --- a/Framework/Geometry/src/Instrument/ObjComponent.cpp +++ b/Framework/Geometry/src/Instrument/ObjComponent.cpp @@ -343,7 +343,7 @@ void ObjComponent::initDraw() const { */ size_t ObjComponent::registerContents(class ComponentVisitor &componentVisitor) const { - if (this->shape()->isFiniteGeometry()) + if (this->shape() != nullptr && this->shape()->isFiniteGeometry()) return componentVisitor.registerGenericObjComponent(*this); else return componentVisitor.registerInfiniteObjComponent(*this); From 9f5422aa39e916a3285d3a682fb2605bf21f2d7d Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Mon, 19 Mar 2018 14:18:17 +0000 Subject: [PATCH 308/364] Removed pyplot code. Re #22101 --- MantidPlot/CMakeLists.txt | 2 - MantidPlot/pymantidplot/pyplot.py | 1598 ----------------------------- 2 files changed, 1600 deletions(-) delete mode 100644 MantidPlot/pymantidplot/pyplot.py diff --git a/MantidPlot/CMakeLists.txt b/MantidPlot/CMakeLists.txt index 14147fcf7c18..60cfcede8427 100644 --- a/MantidPlot/CMakeLists.txt +++ b/MantidPlot/CMakeLists.txt @@ -740,7 +740,6 @@ copy_files_to_dir ( "${PY_FILES}" set( MTDPLOTPY_FILES __init__.py proxies.py - pyplot.py qtiplot.py ) copy_files_to_dir ( "${MTDPLOTPY_FILES}" @@ -893,7 +892,6 @@ set ( MANTIDPLOT_TEST_PY_FILES MantidPlotMdiSubWindowTest.py MantidPlotTiledWindowTest.py MantidPlotInputArgsCheck.py - MantidPlotPyplotGeneralTest.py ) if ( MAKE_VATES ) diff --git a/MantidPlot/pymantidplot/pyplot.py b/MantidPlot/pymantidplot/pyplot.py deleted file mode 100644 index 00d2763ca14f..000000000000 --- a/MantidPlot/pymantidplot/pyplot.py +++ /dev/null @@ -1,1598 +0,0 @@ -"""============================================================================ -New Python command line interface for plotting in Mantid (a la matplotlib) -============================================================================ - -The idea behind this new module is to provide a simpler, more -homogeneous command line interface (CLI) to the Mantid plotting -functionality. This new interface is meant to resemble matplotlib as -far as possible, and to provide a more manageable, limited number of -plot options. - -The module is at a very early stage of development and provides -limited functionality. This is very much work in progress at the -moment. The module is subject to changes and feedback is very much -welcome! - -Simple plots can be created and manipulated with a handul of -commands. See the following examples. - -Plot an array (python list) ---------------------------- - -.. code-block:: python - - # plot array - plot([0.1, 0.3, 0.2, 4]) - # plot x-y - plot([0.1, 0.2, 0.3, 0.4], [1.2, 1.3, 0.2, 0.8]) - -Plot an array with a different style ------------------------------------- - -The plot commands that are described here accept a list of options -(kwargs) as parameters passed by name. With these options you can -modify plot properties, such as line styles, colors, axis scale, -etc. The following example illustrates the use of a few options. You -can refer to the list of options provided further down in this -document. In principle, any combination of options is supported, as -long as it makes sense! - -.. code-block:: python - - a = [0.1, 0.3, 0.2, 4] - plot(a) - import numpy as np - y = np.sin(np.linspace(-2.28, 2.28, 1000)) - plot(y, linestyle='-.', marker='o', color='red') - -If you have used the traditional Mantid command line interface in -Python you will probably remember the plotSpectrum, plotBin and plotMD -functions. These are supported in this new interface as shown in the -following examples. - -Plot a Mantid workspace ------------------------ - -You can pass one or more workspaces to the plot function. By default -it will plot the spectra of the workspace(s), selecting them by the -indices specified in the second argument. This behavior is similar to -the plotSpectrum function of the traditional mantidplot module. This is -a simple example that produces plots of spectra: - -.. code-block:: python - - # first, load a workspace. You can do this with a Load command or just from the GUI menus - ws = Load("/path/to/MAR11060.raw", OutputWorkspace="foo") - # 1 spectrum plot - plot(ws, 100) - # 3 spectra plot - plot(ws, [100, 101, 102]) - -======================== -Different types of plots -======================== - -The plot() function provides a unified interface to different types of -plots, including specific graphs of spectra, bins, multidimensional -workspaces, etc. These specific types of plots are explained in the -next sections. plot() makes a guess as to what tool to use to plot a -workspace. For example, if you pass an MD workspace it will make an MD -plot. But you can request a specific type of plot by specifying a -keyword argument ('tool'). The following tools (or different types of -plots) are supported: - -+------------------------+------------------------------------------------------------+-----------------------+ -| Tool | tool= parameter values (all are equivalent aliases) | Old similar function | -+========================+============================================================+=======================+ -| plot spectra (default) | 'plot_spectrum', 'spectrum', 'plot_sp', 'sp' | plotSpectrum | -+------------------------+------------------------------------------------------------+-----------------------+ -| plot bins | 'plot_bin', 'bin' | plotBin | -+------------------------+------------------------------------------------------------+-----------------------+ -| plot MD | 'plot_md', 'md' | plotMD | -+------------------------+------------------------------------------------------------+-----------------------+ - -The last column of the table lists the functions that produce similar -plots in the traditional MantidPlot Python plotting interface. For the -time being this module only supports these types of specific -plots. Note that the traditional plotting interface of MantidPlot -provides support for many more specific types of plots. These or -similar ones will be added in this module in future releases: - -* plot2D -* plot3D -* plotSlice -* instrumentWindow -* waterFallPlot -* mergePlots -* stemPlot - -Plot spectra using workspace objects and workspace names --------------------------------------------------------- - -It is also possible to pass workspace names to plot, as in the -following example where we plot a few spectra: - -.. code-block:: python - - # please make sure that you use the right path and file name - mar = Load('/path/to/MAR11060.raw', OutputWorkspace="MAR11060") - plot('MAR11060', [10,100,500]) - plot(mar,[3, 500, 800]) - -Let's load one more workspace so we can see some examples with list of -workspaces - -.. code-block:: python - - loq=Load('/path/to/LOQ48097.raw', OutputWorkspace="LOQ48097") - -The next lines are all equivalent, you can use workspace objects or -names in the list passed to plot: - -.. code-block:: python - - plot([mar, 'LOQ48097'], [800, 900]) - plot([mar, loq], [800, 900]) - plot(['MAR11060', loq], [800, 900]) - -Here, the plot function is making a guess and plotting the spectra of -these workspaces (instead of the bins or anything else). You can make -that choice more explicit by specifying the 'tool' argument. In this -case we use 'plot_spectrum' (which also has shorter aliases: -'spectrum', or simply 'sp' as listed in the table above): - -.. code-block:: python - - plot(['MAR11060', loq], [800, 900], tool='plot_spectrum') - plot(['MAR11060', loq], [801, 901], tool='sp') - -Alternatively, you can use the plot_spectrum command, which is -equivalent to the plot command with the keyword argument -tool='plot_spectrum': - -.. code-block:: python - - plot_spectrum(['MAR11060', loq], [800, 900]) - -Plotting bins -------------- - -To plot workspace bins you can use the keyword 'tool' with the value -'plot_bin' (or equivalent 'bin'), like this: - -.. code-block:: python - - ws = Load('/path/to/HRP39182.RAW', OutputWorkspace="HRP39182") - plot(ws, [1, 5, 7, 100], tool='plot_bin') - -or, alternatively, you can use the plot_bin command: - -.. code-block:: python - - plot_bin(ws, [1, 5, 7, 100], linewidth=4, linestyle=':') - -Plotting MD workspaces ----------------------- - -Similarly, to plot MD workspaces you can use the keyword 'tool' with -the value 'plot_md' (or 'md' as a short alias), like this: - -.. code-block:: python - - simple_md_ws = CreateMDWorkspace(Dimensions='3',Extents='0,10,0,10,0,10',Names='x,y,z',Units='m,m,m',SplitInto='5',MaxRecursionDepth='20',OutputWorkspace=MDWWorkspaceName) - plot(simple_md_ws, tool='plot_md') - -or a specific plot_md command: - -.. code-block:: python - - plot_md(simple_md_wsws) - -For simplicity, these examples use a dummy MD workspace. Please refer -to the Mantid (http://www.mantidproject.org/MBC_MDWorkspaces) for a -more real example, which necessarily gets more complicated and data -intensive. - -========================= -Changing style properties -========================= - -You can modify the style of your plots. For example like this (for a -full list of options currently supported, see below). - -.. code-block:: python - - lines = plot(loq, [100, 104], tool='plot_spectrum', linestyle='-.', marker='*', color='red') - -Notice that the plot function returns a list of lines, which -correspond to the spectra lines. At present the lines have limited -functionality. Essentially, the data underlying these lines can be -retrieved as follows: - -.. code-block:: python - - lines[0].get_xdata() - lines[0].get_ydata() - -If you use plot_spectrum, the number of elements in the output lines -should be equal to the number of bins in the corresponding -workspace. Conversely, if you use plot_bin, the number of elements in -the output lines should be equal to the number of spectra in the -workspace. - -To modify the figure, you first need to obtain the figure object -that represents the figure where the lines are displayed. Once you do -so you can for example set the title of the figure like this: - -.. code-block:: python - - fig = lines[0].figure() - fig.suptitle('Example figure title') - -Other properties can be modified using different functions, as in -matplotlib's pyplot. For example: - -.. code-block:: python - - title('Test plot of LOQ') - xlabel('ToF') - ylabel('Counts') - ylim(0, 8) - xlim(1e3, 4e4) - xscale('log') - grid('on') - -By default, these functions manipulate the current figure (the last or -most recently shown figure). You can also save the current figure into -a file like this: - -.. code-block:: python - - savefig('example_saved_figure.png') - -where the file format is guessed from the file extension. The same -extensions as in the MantidPlot figure export dialog are supported, -including jpg, png, tif, ps, and svg. - -The usage of these functions very similar to the matlab and/or -pyplot functions with the same names. The list of functions -currently supported is provided further below. - -Additional options supported as keyword arguments (kwargs): ------------------------------------------------------------ - -There is a couple of important plot options that are set as keyword -arguments: - - -+------------+------------------------+ -|Option name | Values supported | -+============+========================+ -|error_bars | True, False (default) | -+------------+------------------------+ -|hold | on, off | -+------------+------------------------+ - -error_bars has the same meaning as in the traditional mantidplot plot -functions: it defines whether error bars should be added to the -plots. hold has the same behavior as in matplotlib and pyplot. If the -value of hold is 'on' in a plot command, the new plot will be drawn on -top of the current plot window, without clearing it. This makes it -possible to make plots incrementally. - -For example, one can add two spectra from a workspace using the -following command: - -.. code-block:: python - - lines = plot(loq, [100, 102], linestyle='-.', color='red') - -But similar results can be obtained by plotting one of the spectra by -a first command, and then plotting the second spectra in a subsequent -command with the hold parameter enabled: - -.. code-block:: python - - lines = plot(loq, 100, linestyle='-.', color='red') - lines = plot(loq, 102, linestyle='-.', color='blue', hold='on') - -After the two commands above, any subsequent plot command that passes -hold='on' as a parameter would add new spectra into the same plot. An -alternative way of doing this is explained next. Note however that -using the hold property to combine different types of plots -(plot_spectrum, plot_bin, etc.) will most likely produce useless -results. - -Multi-plot commands -------------------- - -In this version of pyplot there is limited support for multi-plot -commands (as in pyplot and matlab). For example, you can type commands -like the following: - -.. code-block:: python - - plot(ws, [100, 101], 'r', ws, [200, 201], 'b', tool='plot_spectrum') - -This command will plot spectra 100 and 101 in red and spectra 200 and -201 in blue on the same figure. You can also combine different -workspaces, for example: - -.. code-block:: python - - plot(ws, [100, 101], 'r', mar, [50, 41], 'b', tool='plot_spectrum') - - -Style options supported as keyword arguments --------------------------------------------- - -Unless otherwise stated, these options are in principle supported in -all the plot variants. These options have the same (or as closed as -possible) meaning as in matplotlib. - -+------------+---------------------------------------------------------+ -|Option name | Values supported | -+============+=========================================================+ -|linewidth | real values | -+------------+---------------------------------------------------------+ -|linestyle | '-', '--', '-.' '.' | -+------------+---------------------------------------------------------+ -|marker | None/"None" 'o', 'v', '^', '<', '>', 's', '*', | -| | 'h', '|', '_' | -+------------+---------------------------------------------------------+ -|color | color character or string ('b', 'blue', 'g', 'green', | -| | 'k', 'black', 'y', 'yellow', 'c', 'cyan', 'r', 'red'. | -| | 'm', 'magenta', etc.). RGB colors are not supported at | -| | the moment. | -+------------+---------------------------------------------------------+ - -Modifying the plot axes ------------------------ - -You can modify different properties of the plot axes via functions, as -seen before. This includes the x and y axis titles, limits and scale -(linear or logarithmic). For example: - -.. code-block:: python - - ylabel('Counts') - ylim(0, 8) - yscale('log') - -An alternative is to use equivalent methods provided by the Figure and -Axes objects. For this you first need to retrieve the figure and axes -where a plot (or line) has been shown. - -.. code-block:: python - - lines = plot(mar,[3, 500, 800]) - fig = lines[0].figure() - all_ax = fig.axes() # fig.axes() returns in principle a list - ax = all_ax[0] # but we only use one axes - ax.set_ylabel('Counts') - ax.set_xlabel('ToF') - ax.set_ylim(0, 8) - ax.set_xlim(1e2, 4e4) - ax.set_xscale('log') - -Functions that modify plot properties -------------------------------------- - -Here is a list of the functions supported at the moment. They offer -the same functionality as their counterparts in matplotlib's -pyplot. - -- title -- xlabel -- ylabel -- ylim -- xlim -- axis -- xscale -- yscale -- grid -- savefig - -This is a limited list of functions that should be sufficient for -basic plots. These functions are presently provided as an example of -this type of interface, and some of them provide functionality similar -or equivalent to several of the keyword arguments for plot commands -detailed in this documentation. Some others produce results equivalent -to the more object oriented methods described above. For example, the -function xlabel is equivalent to the method set_xlabel applied on the -Axes object for the current figure. - -This module is by default imported into the standard MantidPlot -namespace. You can use the functions and classes included here without -any prefix or adding this module name prefix (pymantidplot.pyplot), as -in the following example: - -.. code-block:: python - - # Two equivalent lines: - pymantidplot.pyplot.plot([1, 3, 2]) - plot([1, 3, 2]) - -Note that the plot() function of this module has replaced the -traditional plot() function of MantidPlot which has been moved into a -package called qtiplot. To use it you can do as follows: - -.. code-block:: python - - pymantidplot.qtiplot.plot('MAR11060', [800, 801]) - # or if you prefer shorter prefixes: - import pymantidplot.qtiplot as qtiplt - qtiplt.plot('MAR11060', [800, 801]) - - -Below is the reference documentation of the classes and functions -included in this module. - -""" -# Copyright © 2014-2015 ISIS Rutherford Appleton Laboratory, NScD -# Oak Ridge National Laboratory & European Spallation Source -# -# This file is part of Mantid. -# Mantid is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# Mantid is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# File change history is stored at: . -# Code Documentation is available at: -from __future__ import (absolute_import, division, - print_function) - -try: - import _qti -except ImportError: - raise ImportError('The \'mantidplot\' and \'pymantidplot.pyplot\' modules can only be used from within MantidPlot.') - -import numpy as np -from PyQt4 import Qt, QtGui, QtCore -from mantid.api import (IMDWorkspace as IMDWorkspace, MatrixWorkspace as MatrixWorkspace, AlgorithmManager as AlgorithmManager, AnalysisDataService as ADS) -from mantid.api import mtd -# return __is_workspace(arg) or (mantid.api.mtd.doesExist(arg) and isinstance(mantid.api.mtd[arg], mantid.api.IMDWorkspace)) -try: - from mantid.simpleapi import CreateWorkspace -except ImportError: - def CreateWorkspace(*args, **kwargs): - raise RuntimeError("CreateWorkspace function not available") - -import mantidplot -import mantidqtpython -from six import string_types - -class Line2D(): - """ - A very minimal replica of matplotlib.Line.Line2D. The true Line2D - is a sublcass of matplotlib.artist and provides tons of - functionality. At the moment this just provides get_xdata(), - get_ydata(), and figure() methods. It also holds its Graph - object and through it it would be possible to provide - additional selected functionality. Keep in mind that providing - GUI line/plot manipulation functionality would require a proxy - for this class. - """ - - def __init__(self, graph, index, x_data, y_data, fig=None): - self._graph = graph - self._index = index # will (may) be needed to change properties of this line - self._xdata = x_data - self._ydata = y_data - self._fig = fig - - def get_xdata(self): - return self._xdata - - def get_ydata(self): - return self._ydata - - def figure(self): - return self._fig - -class Axes(): - """ - A very minimal replica of matplotlib.axes.Axes. The true Axes is a - sublcass of matplotlib.artist and provides tons of functionality. - At the moment this just provides a few set methods for properties - such as labels and axis limits. - """ - - """Many plot manipulation functions that are provided in - matplolib through Axes objects, for example to manipulate the x/y - ticks, are not currently supported. Objects of this class hold - their Figure object. Presently every figure has a single Axes - object, and there is no support for multiple axes (as in - fig.add_axes() or fix.axes()). - """ - - def __init__(self, fig, xscale='linear', yscale='linear'): - self._fig = fig - # state of x and y scale kept here. C++ Graph.isLog() not yet exposed - self._xscale = xscale - self._yscale = yscale - - def axis(self, lims): - """ - Set the boundaries or limits of the x and y axes - - @param lims :: list or vector specifying min x, max x, min y, max y - """ - l = __last_fig()._graph.activeLayer() - if 4 != len(lims): - raise ValueError("Error: 4 real values are required for the x and y axes limits") - l.setScale(*lims) - - def set_xlabel(self, lbl): - """ - Set the label or title of the x axis - - @param lbl :: x axis lbl - """ - l = self.get_figure()._graph.activeLayer() - l.setXTitle(lbl) - - def set_ylabel(self, lbl): - """ - Set the label or title of the y axis - - @param lbl :: y axis lbl - """ - l = self.get_figure()._graph.activeLayer() - l.setYTitle(lbl) - - def set_xlim(self, xmin, xmax): - """ - Set the boundaries of the x axis - - @param xmin :: minimum value - @param xmax :: maximum value - """ - l = self.get_figure()._graph.activeLayer() - l.setAxisScale(2, xmin, xmax) - - def set_ylim(self, ymin, ymax): - """ - Set the boundaries of the y axis - - @param ymin :: minimum value - @param ymax :: maximum value - """ - l = self.get_figure()._graph.activeLayer() - l.setAxisScale(0, ymin, ymax) - - def set_xscale(self, scale_str): - """ - Set the type of scale of the x axis - - @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale - """ - if 'log' != scale_str and 'linear' != scale_str: - raise ValueError("You need to specify either 'log' or 'linear' type of scale for the x axis." ) - - l = self.get_figure()._graph.activeLayer() - if scale_str == 'log': - if 'log' == self._yscale: - l.logLogAxes() - else: - l.logXLinY() - elif scale_str == 'linear': - if 'log' == self._yscale: - l.logYlinX() - else: - l.linearAxes() - self._xscale = scale_str - - def set_yscale(self, scale_str): - """ - Set the type of scale of the y axis - - @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale - """ - if 'log' != scale_str and 'linear' != scale_str: - raise ValueError("You need to specify either 'log' or 'linear' type of scale for the y axis." ) - - l = self.get_figure()._graph.activeLayer() - if scale_str == 'log': - if 'log' == self._xscale: - l.logLogAxes() - else: - l.logYlinX() - elif scale_str == 'linear': - if 'log' == self._xscale: - l.logXLinY() - else: - l.linearAxes() - self._yscale = scale_str - - def get_figure(self, ): - """ - Get the figure where this Axes object is included - - Returns :: figure object for the figure that contains this Axes - """ - return self._fig - - -class Figure(): - """ - A very minimal replica of matplotlib.figure.Figure. This class is - here to support manipulation of multiple figures from the command - line. - """ - - """For the moment this is just a very crude wrapper for Graph - (proxy to qti Multilayer), and it is here just to hide (the rather - obscure) Graph from users. - """ - # Holds the set of figure ids (integers) as they're being created and/or destroyed - __figures = {} - # Always increasing seq number, not necessarily the number of figures in the dict - __figures_seq = 0 - - def __init__(self, num): - if isinstance(num, int): - # normal matplotlib use, like figure(2) - missing = -1 - fig = Figure.__figures.get(num, missing) - if missing == fig: - self._graph = Figure.__empty_graph() - Figure.__figures[num] = self - if num > Figure.__figures_seq: - Figure.__figures_seq = num - self._axes = Axes(self) - else: - if None == fig._graph._getHeldObject(): - # has been destroyed! - self._graph = Figure.__empty_graph() - self._axes = Axes(self) - else: - self._graph = fig._graph - self._axes = fig._axes - elif isinstance(num, mantidplot.proxies.Graph): - if None == num._getHeldObject(): - # deleted Graph! - self._graph = Figure.__empty_graph() - else: - self._graph = num - num = Figure.__make_new_fig_number() - Figure.__figures[num] = self - self._axes = Axes(self) - else: - raise ValueError("To create a Figure you need to specify a figure number or a Graph object." ) - - def suptitle(self, title): - """ - Set a title for the figure - - @param title :: title string - """ - l = self._graph.activeLayer() - l.setTitle(title) - - def axes(self): - """ - Obtain the list of axes in this figure. - - Returns :: list of axes. Presently only one Axes object is supported - and this method returns a single object list - """ - return [self._axes] - - def savefig(self, name): - """ - Save current plot into a file. The format is guessed from the file extension (.eps, .png, .jpg, etc.) - - @param name :: file name - """ - if not name: - raise ValueError("Error: you need to specify a non-empty file name") - l = self._graph.activeLayer() - l.export(name); - - @classmethod - def fig_seq(cls): - """ Helper method, returns the current sequence number for figures""" - return cls.__figures_seq - - @classmethod - def __make_new_fig_number(cls): - """ Helper method, creates and return a new figure number""" - num = cls.__figures_seq - avail = False - while not avail: - missing = -1 - fig = cls.__figures.get(num, missing) - if missing == fig: - avail = True # break - else: - num += 1 - cls.__figures_seq = num - return num - - @staticmethod - def __empty_graph(): - """Helper method, just create a new Graph with an 'empty' plot""" - lines = plot([0]) - return lines._graph - - -def __empty_fig(): - """Helper function, for the functional interface. Makes a blank/empty figure""" - lines = plot([0]) # for the very first figure, this would generate infinite recursion! - return Figure(lines[0]._graph) - -# TODO/TOTHINK: no 'hold' function support for now. How to handle multi-plots with different types/tools? Does it make sense at all? -__hold_status = False - -__last_shown_fig = None - -def __last_fig(): - """ - Helper function, especially for the functional interface. - Avoid using it inside the plot_spectrum, plot_bin, etc. as there's risk of infinite recursion - Returns :: last figure, creating new one if there was none - """ - global __last_shown_fig - if not __last_shown_fig: - f = __empty_fig() - __last_shown_fig = f - return __last_shown_fig - -def __update_last_shown_fig(g): - """ - Helper function, especially for the functional interface. - @param g :: graph object - Returns :: new last fig - """ - global __last_shown_fig - __last_shown_fig = Figure(g) - return __last_shown_fig - -def __is_array(arg): - """ - Is the argument a python or numpy list? - @param arg :: argument - - Returns :: True if the argument is a python or numpy list - """ - return isinstance(arg, list) or isinstance(arg, np.ndarray) - -def __is_array_or_int(arg): - """ - Is the argument a valid workspace index/indices, which is to say: - Is the argument an int, or python or numpy list? - @param arg :: argument - - Returns :: True if the argument is an integer, or a python or numpy list - """ - return isinstance(arg, int) or __is_array(arg) - - -def __is_registered_workspace_name(arg): - """" - Check whether the argument passed is the name of a registered workspace - - @param arg :: argument (supposedly a workspace name) - - Returns :: True if arg is a correct workspace name - """ - return (isinstance(arg, string_types) and mtd.doesExist(arg) and isinstance(mtd[arg], IMDWorkspace)) - -def __is_valid_single_workspace_arg(arg): - """" - Check whether the argument passed can be used as a workspace input. Note that this differs from - __is_workspace() in that workspace names are also accepted. Throws ValueError with informative - message if arg is not a valid workspace object or name. - - @param arg :: argument (supposedly one workspace, possibly given by name) - - Returns :: True if arg can be accepted as a workspace - """ - if __is_workspace(arg) or __is_registered_workspace_name(arg): - return True - else: - return False - -def __is_valid_workspaces_arg(arg): - """" - Check whether the argument passed can be used as a workspace(s) input. Note that this differs from - __is_workspace() in that lists of workspaces and workspace names are also accepted. - - @param arg :: argument (supposedly one or more workspaces, possibly given by name) - - Returns :: True if arg can be accepted as a workspace or a list of workspaces - """ - if __is_valid_single_workspace_arg(arg): - return True - else: - if 0 == len(arg): - return False - for name in arg: - # name can be a workspace name or a workspace object - try: - __is_valid_single_workspace_arg(name) - except: - raise ValueError("This parameter passed in a list of workspaces is not a valid workspace: " + str(name)) - return True - -def __is_data_pair(a, b): - """ - Are the two arguments passed (a and b) a valid data pair for plotting, like in plot(x, y) or - plot(ws, [0, 1, 2])? - @param a :: first argument passed (supposedly array or workspace(s)) - @param b :: second argument (supposedly an array of values, or indices) - - Returns :: True if the arguments can be used to plot something is an integer, or a python or numpy list - """ - res = (__is_array(a) and __is_array(b)) or (__is_valid_workspaces_arg(a) and __is_array_or_int(b)) - return res - -def __is_workspace(arg): - """ - Is the argument a Mantid MatrixWorkspace? - @param arg :: argument - - Returns :: True if the argument a MatrixWorkspace - """ - return isinstance(arg, MatrixWorkspace) - -def __is_array_of_workspaces(arg): - """ - Is the argument a sequence of Mantid MatrixWorkspaces? - @param arg :: argument - - Returns :: True if the argument is a sequence of MatrixWorkspace - """ - return __is_array(arg) and len(arg) > 0 and __is_workspace(arg[0]) - - -def __create_workspace(x, y, name="__array_dummy_workspace"): - """ - Create a workspace. Also puts it in the ADS with __ name - @param x :: x array - @param y :: y array - @param name :: workspace name - - Returns :: Workspace - """ - alg = AlgorithmManager.create("CreateWorkspace") - alg.setChild(True) - alg.initialize() - # fake empty workspace (when doing plot([]), cause setProperty needs non-empty data) - if [] == x: - x = [0] - if [] == y: - y = [0] - alg.setProperty("DataX", x) - alg.setProperty("DataY", y) - name = name + "_" + str(Figure.fig_seq()) - alg.setPropertyValue("OutputWorkspace", name) - alg.execute() - ws = alg.getProperty("OutputWorkspace").value - ADS.addOrReplace(name, ws) # Cannot plot a workspace that is not in the ADS - return ws - - -def __list_of_lines_from_graph(g, first_line=0): - """ - Produces a python list of line objects, with one object per line plotted on the passed graph - Note: at the moment these objects are of class Line2D which is much simpler than matplotlib.lines.Line2D - This function should always be part of the process of creating a new figure/graph, and it guarantees - that this figure being created is registered as the last shown figure. - - @param g :: graph (with several plot layers = qti Multilayer) - @param first_line :: index to start from (useful for hold='on', multi-plots, etc.) - - Returns :: List of line objects - """ - if None == g: - raise ValueError("Got empty Graph object, cannot get its lines." ) - # assume we use a single layer - active = g.activeLayer() - res = [] - for i in range(first_line, active.numCurves()): - x_data = [] - y_data = [] - d = active.curve(i).data() - for i in range(0, active.curve(i).data().size()): - x_data.append(d.x(i)) - y_data.append(d.y(i)) - res.append(Line2D(g, i, x_data, y_data)) - - fig = __update_last_shown_fig(g) - for lines in res: - lines._fig = fig - - return res; - -def __matplotlib_defaults(l): - """ - Tries to (approximately) mimic the default plot properties of a pylab.plot() - @param l :: layer (plot) from a mantidplot Graph object - - Returns :: nothing, just modifies properties of the layer passed - """ - if None == l: - raise ValueError("Got empty Layer object, cannot modify its properties." ) - l.removeLegend() - for i in range(0, l.numCurves()): - l.setCurveLineColor(i, __color_char_to_color_idx['b']) - l.setTitle(' ') - l.setXTitle(' ') - l.setYTitle(' ') - -__marker_to_plotsymbol = { - None: _qti.PlotSymbol.NoSymbol, "None": _qti.PlotSymbol.NoSymbol, - 'o': _qti.PlotSymbol.Ellipse, 'v': _qti.PlotSymbol.DTriangle, '^': _qti.PlotSymbol.UTriangle, - '<': _qti.PlotSymbol.LTriangle, '>': _qti.PlotSymbol.RTriangle, 's': _qti.PlotSymbol.Rect, - '*': _qti.PlotSymbol.Star1, 'h': _qti.PlotSymbol.Hexagon, '|': _qti.PlotSymbol.VLine, - '_': _qti.PlotSymbol.HLine -} - -"""Contains all the supported line styles""" -__linestyle_to_qt_penstyle = { - '-': QtCore.Qt.SolidLine, '--': QtCore.Qt.DashLine, - '-.': QtCore.Qt.DashDotLine, ':': QtCore.Qt.DotLine -} # other available: Qt.DashDotDotLine, Qt.CustomDashLine - -def __apply_linestyle(graph, linestyle, first_line=0): - """ - Sets the linestyle of lines/curves of the active layer of the graph passed - - @param graph :: mantidplot graph (figure) - @param linestyle :: linestyle string - @param first_line :: index of first line to which the linestyle will apply - (useful when in hold mode / adding lines) - - Returns :: nothing, just modifies the line styles of the active layer of the graph passed - """ - global __linestyle_to_qt_penstyle - wrong = 'inexistent' - penstyle = __linestyle_to_qt_penstyle.get(linestyle, wrong) - if wrong == penstyle: - raise ValueError("Wrong linestyle given, unrecognized: " + linestyle) - l = graph.activeLayer() - for i in range(first_line, l.numCurves()): - l.setCurveLineStyle(i, penstyle) - -# beware this is not Qt.Qt.color_name (black, etc.) -__color_char_to_color_idx = { - 'k': 0, 'r': 1, 'g': 2, 'b': 3, 'c': 4, 'm': 5, 'y': 18, - 'black': 0, 'red': 1, 'green': 2, 'blue': 3, 'cyan': 4, 'magenta': 5, 'orange': 6, - 'purple': 7, 'darkGreen': 8, 'darkBlue': 9, 'brown': 10, 'gray': 17, 'yellow': 18 -} - -def __apply_line_color(graph, c, first_line=0): - """ - Sets the color of curves of the active layer of the graph passed - - @param graph :: mantidplot graph (figure) - @param c :: color string - @param first_line :: index of first line to which the color will apply - (useful when in hold mode / adding lines) - - Returns :: nothing, just modifies the line styles of the active layer of the graph passed - """ - inex = 'inexistent' - col_idx = __color_char_to_color_idx.get(c, inex) - if inex == col_idx: - col_idx = QtGui.QColor(c) - l = graph.activeLayer() - for i in range(first_line, l.numCurves()): - l.setCurveLineColor(i, col_idx) # beware this is not Qt.Qt.black, but could be faked with QtGui.QColor("orange") - -def __apply_marker(graph, marker, first_line=0): - """ - Sets the marker of curves of the active layer of the graph passed - - @param graph :: mantidplot graph (figure) - @param marker :: line marker character - @param first_line :: index of first line to which the color will apply - (useful when in hold mode / adding lines) - - Returns :: nothing - """ - wrong = 'inexistent' - sym_code = __marker_to_plotsymbol.get(marker, wrong) - if wrong == sym_code: - raise ValueError("Warning: unrecognized marker: " + str(marker)) - sym = _qti.PlotSymbol(sym_code, QtGui.QBrush(), QtGui.QPen(), QtCore.QSize(5,5)) - l = graph.activeLayer() - for idx in range(first_line, l.numCurves()): - l.setCurveSymbol(idx, sym) - -def __is_marker(char): - """ Is it a marker character - @param char :: suspected marker character coming from a linestyle string - Returns :: True if it's a marker character - """ - inex = 'inexistent' - m = __marker_to_plotsymbol.get(char, inex) - return m != inex - -__linestyle_to_qt_penstyle = { - '-': QtCore.Qt.SolidLine, '--': QtCore.Qt.DashLine, - '-.': QtCore.Qt.DashDotLine, ':': QtCore.Qt.DotLine -} # other available: Qt.DashDotDotLine, Qt.CustomDashLine - -def __is_linestyle(stl, i): - """ - Check if we have a linestyle string in string s at position i - @param stl :: input (style) string, for example: '-.g', 'r', ':b' - @param i :: index where to start checking in string s - - Returns :: 0 if no linestyle string is identified, length of the string (1 or 2) otherwise - """ - global __linestyle_to_qt_penstyle - - if len(stl) <= i: - return 0 - - if len(stl) > i+1: - if '-' == stl[i+1] or '.' == stl[i+1]: - # can check 2 chars - wrong = 'inexistent' - penstyle = __linestyle_to_qt_penstyle.get(stl[i:i+2], wrong) - if wrong != penstyle: - return 2 - - if '-'==stl[i] or ':'==stl[i]: - return 1 - else: - return 0 - -def __apply_plot_args(graph, first_line, *args): - """ - Applies args, like '-r' etc. - @param graph :: a graph (or figure) that can contain multiple layers - @param first_line :: first line to which the options will apply (useful when in hold mode / adding lines) - @param args :: plot arguments - - Returns :: nothing, just uses kwargs to modify properties of the layer passed - """ - if None==graph or len(args) < 1 or ((),) == args: - return - - for a in args: - if isinstance(a, string_types): - # this will eat characters as they come, without minding much the past/previous characters - # users can chain as many modifiers as they wish. It could be modified to be more strict/picky - i = 0 - while i < len(a): - linestyle_len = __is_linestyle(a,i) - if linestyle_len > 0: - __apply_linestyle(graph, a[i:i+linestyle_len], first_line) - i += linestyle_len - elif __is_marker(a[i]): - __apply_marker(graph, a[i:], first_line) - i += 1 - elif a[i].isalpha(): - __apply_line_color(graph, a[i], first_line) - i += 1 - else: - # TOTHINK - error here? like this? sure? or just a warning? - raise ValueError("Unrecognized character in input string: " + str(a[i])) - else: - raise ValueError("Expecting style string, but got an unrecognized input parameter: " + str(a) + ", of type: " + str(type(a))) - -def __apply_plot_kwargs(graph, first_line=0, **kwargs): - """ - Applies kwargs - @param graph :: a graph (or figure) that can contain multiple layers - - Returns :: nothing, just uses kwargs to modify properties of the layer passed - """ - if None==graph or None==kwargs or ((),) == kwargs: - return - - for key in kwargs: - if 'linestyle' == key: - __apply_linestyle(graph, kwargs[key]) - - elif 'linewidth' == key: - l = graph.activeLayer() - for i in range(first_line, l.numCurves()): - l.setCurveLineWidth(i, kwargs[key]) - - elif 'color' == key: - __apply_line_color(graph, kwargs[key], first_line) - - elif 'marker' == key: - __apply_marker(graph, kwargs[key], first_line) - -def __is_multiplot_command(*args, **kwargs): - """ - Finds out if the passed *args make a valid multi-plot command. At the same time, splits the - multi-plot command line into individual plot commands. - - @param args :: curve data and options. - @param kwargs :: plot keyword options - - Returns :: tuple: (boolean: whether it is a multiplot command, list of single plot commands as tuples) - """ - # A minimum multi-plot command would be plot(x, y, z, w) or plot(ws1, idx1, ws2, idx2) - nargs = len(args) - # this will be a list with the sequence of individual plots (a tuples, each describing a single plot) - plots_seq = [] - if nargs < 4: - return (False, []) - i = 0 - while i < nargs: - a = [] - b = [] - style = '' - if (nargs-i) >= 3: - if __is_data_pair(args[i], args[i+1]): - a = args[i] - b = args[i+1] - i += 2 - else: - return (False, []); - # can have style string, but don't get confused with single workspace name strings! - if (not __is_registered_workspace_name(args[i])) and isinstance(args[i], string_types): - style = args[i] - i += 1 - plots_seq.append((a,b,style)) - - elif (nargs-i) >= 2: - if __is_data_pair(args[i], args[i+1]): - a = args[i] - b = args[i+1] - i += 2 - else: - return (False, []) - plots_seq.append((a, b, '')) - - elif (nargs-i) > 0: - raise ValueError("Not plottable. I do not know what to do with this last parameter: " + args[i] + ", of type " + str(type(args))) - - return (i == nargs, plots_seq) - -def __process_multiplot_command(plots_seq, **kwargs): - """ - Make one plot at a time when given a multi-plot command. - - @param plots_seq :: list of individual plot parameters - @param kwargs :: plot style options - - Returns :: the list of curves included in the plot - """ - lines = [] - if len(plots_seq) >= 1: - if not 'hold' in kwargs: - kwargs['hold'] = 'off' - lines = plot(*(plots_seq[0]), **kwargs) - for i in range(1, len(plots_seq)): - kwargs['hold'] = 'on' - lines.extend(plot(*(plots_seq[i]), **kwargs)) - return lines - -def __translate_hold_kwarg(**kwargs): - """ - Helper function to translate from hold='on'/'off' kwarg to a True/False value for the - mantidplot window and window error_bars - - @param kwargs :: keyword arguments passed to a plot function, this function only cares about hold. Any - value different from 'on' will be considered as 'off' - - Returns :: tuple with a couple of values: True/False value for window, and True/False for clearWindow, - to be used with plotSpectrum, plotBin, etc. - """ - # window and clearWindow - window_val = None - clearWindow_val = False - hold_name = 'hold' - missing_off = -1 - str_val = kwargs.get(hold_name, missing_off) - if str_val != missing_off and str_val == 'on': - if None == __last_shown_fig: - window_val = None - else: - window_val = __last_fig()._graph - clearWindow_val = False - - return window_val, clearWindow_val - -def __translate_error_bars_kwarg(**kwargs): - """ - Helper function to translate from error_bars=True/False kwarg to a True/False value for the - mantidplot error_bars argument - - @param kwargs :: keyword arguments passed to a plot function. This function only cares about 'error_bars'. - Any value different from 'True' will be considered as 'False' - - Returns :: True/False value for error_bars, to be used with plotSpectrum, plotBin, etc. - - """ - # error_bars param - bars_val = False - bars_name = 'error_bars' - missing_off = -1 - str_val = kwargs.get(bars_name, missing_off) - if str_val != missing_off and str_val == 'True': - bars_val = True - - return bars_val - -def __translate_distribution_kwarg(**kwargs): - """ - Helper function to translate from distribution=DistributionDefault/DistributionTrue/DistributionFalse kwarg to a - mantidplot distribution argument - - @param kwargs :: keyword arguments passed to a plot function. This function only cares about 'distribution'. - - Returns :: DistributionDefault/DistributionTrue/DistributionFalse value for distribution, to be used with plotSpectrum, plotBin, etc. - - """ - # distribution param - distr_val = False - distr_name = 'distribution' - missing_off = mantidqtpython.MantidQt.DistributionDefault - str_val = kwargs.get(distr_name, missing_off) - if str_val != missing_off and str_val == 'DistributionTrue': - distr_val = mantidqtpython.DistributionTrue - elif str_val != missing_off and str_val == 'DistributionFalse': - distr_val = mantidqtpython.DistributionFalse - - return distr_val - -def __plot_as_workspace(*args, **kwargs): - """ - plot spectrum via qti plotting framework to plot a workspace. - - @param args :: curve data and options. - @param kwargs :: plot line options - - Returns :: List of line objects - """ - return plot_spectrum(*args, **kwargs) - -def __plot_as_workspaces_list(*args, **kwargs): - """ - Plot a series of workspaces - @param args :: curve data and options. - @param kwargs :: plot line options - - Returns :: List of line objects - """ - # mantidplot.plotSpectrum can already handle 1 or more input workspaces. - return __plot_as_workspace(*args, **kwargs) - - -def __plot_as_array(*args, **kwargs): - """ - Plot from an array - @param args :: curve data and options. - @param kwargs :: plot line options - - Returns :: the list of curves (1) included in the plot - """ - y = args[0] - idx_style = len(args) # have to guess if we get plot(x,'r'), or plot(x, y, 'r') or no style string - if len(args) > 1: - if __is_array(args[1]): - ws = __create_workspace(y, args[1]) - idx_style = 2 - elif isinstance(args[1], string_types): - x = list(range(0, len(y), 1)) # 0 to n, incremented by 1. - ws = __create_workspace(x, y) - # have to assume that args[1] is a style string - idx_style = 1 - else: - raise ValueError("Inputs are of type: " + str(type(args)) + ". Not plottable." ) - else: - x = list(range(0, len(y), 1)) - ws = __create_workspace(x, y) - - lines = __plot_as_workspace(ws, [0], *args[idx_style:], **kwargs) - graph = None - if len(lines) > 0: - graph = lines[0]._graph - else: - raise Exception("Could not plot a workspace: " + ws) - # something to improve: if the C++ Graph class provided a plot1D that doesn't do show(), so that - # we could modify properties behind the scene and at the end do the show(). Con: do we really need - # to load the qti layer with more methods because of outer layers like here? - if 0 == len(kwargs): - __matplotlib_defaults(graph.activeLayer()) - return __list_of_lines_from_graph(graph) - -def __plot_with_tool(tool, *args, **kwargs): - bin_tool_names = ['plot_bin', 'bin'] - spectrum_tool_names = ['plot_spectrum', 'plot_sp', 'spectrum', 'sp'] - md_tool_names = ['plot_md', 'md'] - - if len(args) < 2: - if tool in bin_tool_names: - raise ValueError("To plot bins (using '%s' as tool) you need to give at least two parameters, where the second parameter selects the bins"%tool) - elif tool in spectrum_tool_names: - raise ValueError("To plot spectra (using '%s' as tool) you need to give at least two parameters, where the second parameter selects the spectrum(a)"%tool) - - if tool in bin_tool_names: - return plot_bin(args[0], args[1], *args[2:], **kwargs) - elif tool in md_tool_names: - return plot_md(args[0], *args[1:], **kwargs) - elif tool in spectrum_tool_names: - return plot_spectrum(args[0], args[1], *args[2:], **kwargs) - # here you would add slice/spectrum/instrument viewer, etc. and maybe you'll want to put them in a dict - else: - raise ValueError("Unrecognized tool specified: '" + tool + ";. Cannot plot this. ") - -def __plot_with_best_guess(*args, **kwargs): - y = args[0] - if __is_array(y): - if __is_array_of_workspaces(y): - return __plot_as_workspaces_list(*args, **kwargs) - else: - return __plot_as_array(*args, **kwargs) - else: - # mantidplot.plotSpectrum can handle workspace names (strings) - return __plot_as_workspace(*args, **kwargs) - -def plot_bin(workspaces, indices, *args, **kwargs): - """ - X-Y plot of the bin counts in a workspace. - - Plots one or more bin, selected by indices, using spectra numbers as x-axis and bin counts for - each spectrum as y-axis. - - @param workspaces :: workspace or list of workspaces (both workspace objects and names accepted) - @param indices :: indices of the bin(s) to plot - - Returns :: the list of curves included in the plot - """ - # Find optional params to plotBin - bars_val = __translate_error_bars_kwarg(**kwargs) - window_val, clearWindow_val = __translate_hold_kwarg(**kwargs) - - # to change properties on the new lines being added - first_line = 0 - if None != window_val: - first_line = window_val.activeLayer().numCurves() - - graph = mantidplot.plotBin(workspaces, indices, error_bars=bars_val, type=-1, window=window_val, clearWindow=clearWindow_val) - - __apply_plot_args(graph, first_line, *args) - __apply_plot_kwargs(graph, first_line, **kwargs) - - return __list_of_lines_from_graph(graph, first_line) - - -def plot_md(workspaces, *args, **kwargs): - """ - X-Y plot of an MDWorkspace. - - @param workspaces :: workspace or list of workspaces (both workspace objects and names accepted) - - Returns :: the list of curves included in the plot - """ - # Find optional params to plotBin - bars_val = __translate_error_bars_kwarg(**kwargs) - window_val, clearWindow_val = __translate_hold_kwarg(**kwargs) - - # to change properties on the new lines being added - first_line = 0 - if None != window_val: - first_line = window_val.activeLayer().numCurves() - - graph = mantidplot.plotMD(workspaces, normalization=mantidplot.DEFAULT_MD_NORMALIZATION, error_bars=bars_val, window=window_val, clearWindow=clearWindow_val) - - __apply_plot_args(graph, first_line, *args) - __apply_plot_kwargs(graph, first_line, **kwargs) - - return __list_of_lines_from_graph(graph, first_line) - - -def plot_spectrum(workspaces, indices, *args, **kwargs): - """X-Y Plot of spectra in a workspace. - - Plots one or more spectra, selected by indices, using bin boundaries as x-axis - and the spectra values in each bin as y-axis. - - @param workspaces :: workspace or list of workspaces (both workspace objects and names accepted) - @param indices :: indices of the spectra to plot, given as a single integer or a list of integers - - Returns :: the list of curves included in the plot - - """ - # Find optional params to plotSpectrum - bars_val = __translate_error_bars_kwarg(**kwargs) - distr_val = __translate_distribution_kwarg(**kwargs) - window_val, clearWindow_val = __translate_hold_kwarg(**kwargs) - - # to change properties on the new lines being added - first_line = 0 - if None != window_val: - first_line = window_val.activeLayer().numCurves() - - graph = mantidplot.plotSpectrum(workspaces, indices, error_bars=bars_val, type=-1, window=window_val, clearWindow=clearWindow_val) - - __apply_plot_args(graph, first_line, *args) - __apply_plot_kwargs(graph, first_line, **kwargs) - - return __list_of_lines_from_graph(graph, first_line) - - -def plot(*args, **kwargs): - """ - Plot the data in various forms depending on what arguments are passed. Currently supported - inputs: arrays (as Python lists or numpy arrays) and workspaces (by name or workspace objects). - - @param args :: curve data and options - @param kwargs :: plot line options - - Returns :: the list of curves included in the plot - - args can take different forms depending on what you plot. You can plot: - - * a python list or array (x) for example like this: plot(x) - - * a workspace (ws) for example like this: plot(ws, [100,101]) # this will plot spectra 100 and 101 - - * a list of workspaces (ws, ws2, ws3, etc.) for example like this: plot([ws, ws2, ws3], [100,101]) - - * workspaces identified by their names: plot(['HRP39182', 'MAR11060.nxs'], [100,101]) - - You can also pass matplotlib/pyplot style strings as arguments, for example: plot(x, '-.') - - As keyword arguments (kwargs) you can specify multiple - parameters, for example: linewidth, linestyle, marker, color. - - An important keyword argument is tool. At the moment the - following values are supported (they have long and short aliases): - - * To plot spectra: 'plot_spectrum' OR 'spectrum' OR 'plot_sp' OR 'sp' (default for workspaces). - * To plot bins: 'plot_bin' OR 'bin' - * To do an MD plot: 'plot_md' OR 'md' - - Please see the documentation of this module (use help()) for more details. - - """ - nargs = len(args) - if nargs < 1: - raise ValueError("You did not pass any argument. You must provide data to plot.") - - # TOTHINK: should there be an exception if it's plot_md (tool='plot_md') - (is_it, plots_seq) = __is_multiplot_command(*args, **kwargs) - if is_it: - return __process_multiplot_command(plots_seq, **kwargs) - elif len(args) > 3: - raise ValueError("Could not interpret the arguments passed. You passed more than 3 positional arguments but this does not seem to be a correct multi-plot command. Please check your command and make sure that the workspaces given are correct.") - - # normally guess; exception if e.g. a parameter tool='plot_bin' is given - try: - tool_val = kwargs['tool'] - del kwargs['tool'] - return __plot_with_tool(tool_val, *args, **kwargs) - except KeyError: - return __plot_with_best_guess(*args, **kwargs) - - -#============================================================================= -# Functions, for pyplot / old matlab style manipulation of figures -#============================================================================= - -def xlim(xmin, xmax): - """ - Set the boundaries of the x axis - - @param xmin :: minimum value - @param xmax :: maximum value - """ - l = __last_fig()._graph.activeLayer() - l.setAxisScale(2, xmin, xmax) - -def ylim(ymin, ymax): - """ - Set the boundaries of the y axis - - @param ymin :: minimum value - @param ymax :: maximum value - """ - l = __last_fig()._graph.activeLayer() - l.setAxisScale(0, ymin, ymax) - -def xlabel(lbl): - """ - Set the label or title of the x axis - - @param lbl :: x axis lbl - """ - l = __last_fig()._graph.activeLayer() - l.setXTitle(lbl) - -def ylabel(lbl): - """ - Set the label or title of the y axis - - @param lbl :: y axis lbl - """ - l = __last_fig()._graph.activeLayer() - l.setYTitle(lbl) - -def title(title): - """ - Set title of the active plot - - @param title :: title string - """ - l = __last_fig()._graph.activeLayer() - l.setTitle(title) - -def axis(lims): - """ - Set the boundaries or limits of the x and y axes - - @param lims :: list or vector specifying min x, max x, min y, max y - """ - l = __last_fig()._graph.activeLayer() - if 4 != len(lims): - raise ValueError("Error: 4 real values are required for the x and y axes limits") - l.setScale(*lims) - -def yscale(scale_str): - """ - Set the type of scale of the y axis - - @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale - """ - ax = __last_fig()._axes - ax.set_yscale(scale_str) - -def xscale(scale_str): - """ - Set the type of scale of the x axis - - @param scale_str :: either 'linear' for linear scale or 'log' for logarithmic scale - """ - ax = __last_fig()._axes - ax.set_xscale(scale_str) - -def grid(opt='on'): - """ - Enable a grid on the active plot (horizontal and vertical) - - @param title :: 'on' to enable - """ - l = __last_fig()._graph.activeLayer() - if None == opt or 'on' == opt: - l.showGrid() - elif 'off' == opt: - # TODO is there support for a 'hideGrid' in qti? Apparently not. - print("Sorry, hiding/disabling grids is currenlty not supported") - -def figure(num=None): - """ - Return Figure object for a new figure or an existing one (if there is any - with the number passed as parameter). - - @param num :: figure number (optional). If empty, a new figure is created. - """ - if not num: - return __empty_fig() - else: - if num < 0: - raise ValueError("The figure number must be >= 0") - - return Figure(num) - -def savefig(name): - """ - Save current plot into a file. The format is guessed from the file extension (.eps, .png, .jpg, etc.) - - @param name :: file name - """ - if not name: - raise ValueError("Error: you need to specify a non-empty file name") - l = __last_fig()._graph.activeLayer() - l.export(name); From 74392f207f0c26942fc35b50927437107d41b10c Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Mon, 19 Mar 2018 15:36:12 +0000 Subject: [PATCH 309/364] Mention it in the release notes. Re #22101 --- docs/source/release/v3.13.0/ui.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/source/release/v3.13.0/ui.rst b/docs/source/release/v3.13.0/ui.rst index 95ee154539c6..57924a014242 100644 --- a/docs/source/release/v3.13.0/ui.rst +++ b/docs/source/release/v3.13.0/ui.rst @@ -10,3 +10,9 @@ UI & Usability Changes improvements, followed by bug fixes. :ref:`Release 3.13.0 ` + + +MantidPlot +---------- + +- MantidPlot's pyplot API has been removed. From 16ba8fb4f67a194d7aeebc300bb966199b1c1c2b Mon Sep 17 00:00:00 2001 From: Ross Miller Date: Mon, 19 Mar 2018 13:07:07 -0400 Subject: [PATCH 310/364] Make clang-format happy Literally just deleting some trailing whitespace from one line Refs #22112 --- Framework/LiveData/src/SNSLiveEventDataListener.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Framework/LiveData/src/SNSLiveEventDataListener.cpp index 8942b9873ef4..fb5f61f9406c 100644 --- a/Framework/LiveData/src/SNSLiveEventDataListener.cpp +++ b/Framework/LiveData/src/SNSLiveEventDataListener.cpp @@ -754,7 +754,7 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::RunStatusPkt &pkt) { // Add the run_end property m_eventBuffer->mutableRun().addProperty( "run_end", timeFromPacket(pkt).toISO8601String()); - + // Set the flag to make us stop reading from the network. // Stopping network reads solves a number of problems: // 1) We don't need to manage a second buffer in order to keep the events From 56ca4e04536855f6e639acd7c2ec92c6b91c8abc Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Tue, 20 Mar 2018 08:58:26 +0100 Subject: [PATCH 311/364] Fix directtools unit tests. Re #21901 --- scripts/test/directtools/DirectToolsTest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/test/directtools/DirectToolsTest.py b/scripts/test/directtools/DirectToolsTest.py index 82b22d58bd88..a1877a98dcc3 100644 --- a/scripts/test/directtools/DirectToolsTest.py +++ b/scripts/test/directtools/DirectToolsTest.py @@ -56,7 +56,7 @@ def test_box2D_vertMax(self): def test_configurematplotlib(self): defaultParams = directtools.defaultrcParams() - directtools.configurematplotlib(defaultParams) + directtools._configurematplotlib(defaultParams) for key in defaultParams: self.assertTrue(key in matplotlib.rcParams) self.assertEqual(matplotlib.rcParams[key], defaultParams[key]) @@ -98,7 +98,7 @@ def test_dynamicsusceptibility_removesingularity(self): self.assertEqual(outEs[2], 0.) def test_mantidsubplotsetup(self): - result = directtools.mantidsubplotsetup() + result = directtools._mantidsubplotsetup() self.assertEqual(result, {'projection': 'mantid'}) def _nanminmaxSetup(self): From 09ea6dece85e4c6b10361b1d665d109a8769ed96 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Tue, 20 Mar 2018 09:40:03 +0000 Subject: [PATCH 312/364] Remove pyplot imports. Re #22101 --- MantidPlot/mantidplot.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/MantidPlot/mantidplot.py b/MantidPlot/mantidplot.py index af726851aca8..c038cd11e64a 100644 --- a/MantidPlot/mantidplot.py +++ b/MantidPlot/mantidplot.py @@ -10,8 +10,5 @@ import pymantidplot from pymantidplot import * -# import pyplot and also bring it into the standard MantidPlot namespace -import pymantidplot.pyplot -from pymantidplot.pyplot import * # and the old qtiplot stuff import pymantidplot.qtiplot From eaefa1e699fb17dfc9b03ae2bc727cd78089e61b Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 20 Mar 2018 10:12:19 +0000 Subject: [PATCH 313/364] Update DOI authors list --- tools/DOI/authors.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/DOI/authors.py b/tools/DOI/authors.py index 6f8b1f5613f2..1f2f42c7cf85 100644 --- a/tools/DOI/authors.py +++ b/tools/DOI/authors.py @@ -113,6 +113,7 @@ 'Matthew D Jones' : 'Jones, Matthew D.', 'Matt King' : 'King, Matt', 'Jiao Lin' : 'Lin, Jiao', + 'Jiao' : 'Lin, Jiao', 'Simon Heybrock' : 'Heybrock, Simon', 'Elliot Oram' : 'Oram, Elliot', 'Dominic Oram' : 'Oram, Dominic', @@ -141,9 +142,12 @@ 'reimundILL' : 'Reimund, Verena', 'Krzysztof Dymkowski' : 'Dymkowski, Krzysztof', 'dymkowsk' : 'Dymkowski, Krzysztof', + 'krzych' : 'Dymkowski, Krzysztof', 'Gemma Guest' : 'Guest, Gemma', 'Anthony Lim' : 'Lim, Anthony', + 'Anthony Lim' : 'Lim, Anthony', 'AnthonyLim23' : 'Lim, Anthony', + 'Anthony' : 'Lim, Anthony', 'CipPruteanu' : 'Ciprian Pruteanu', 'Tasev' : 'Tasev, Dimitar', 'Mayer Alexandra' : 'Mayer, Alexandra', @@ -154,11 +158,18 @@ 'Thomas Lohnert' : 'Lohnert, Thomas', 'James Tricker' : 'Tricker, James', 'Matthew Bowles' : 'Bowles, Matthew', + 'MatthewBowles' : 'Bowles, Matthew', 'josephframsay' : 'Ramsay, Joseph F.', 'Joseph Ramsay' : 'Ramsay, Joseph F.', + '=' : 'Ramsay, Joseph F.', + 'Joe Ramsay' : 'Ramsay, Joseph F.', 'Adam Washington' : 'Wahington, Adam', 'Edward Brown' : 'Brown, Edward', - 'Matthew Andrew' : 'Andrew, Matthew' + 'Matthew Andrew' : 'Andrew, Matthew', + 'Mantid-Matthew' : 'Andrew, Matthew', + 'Keith Butler' : 'Butler, Keith T.', + 'fodblog' : 'Butler, Keith T.', + 'Marshall McDonnell' : 'Mcdonnell, Marshall' } # Used to ensure a Git author does not appear in any of the DOIs. This is NOT @@ -172,6 +183,10 @@ 'Chris Kerr', 'Thomas Brooks', 'mantid-builder', + 'Erik B Knudsen', + 'Bartomeu Llopis', + 'dpaj', + 'Daniel Pajerowski', ] # The whitelist is used for sponsors / contributors who should be included, From 6e03cdcdeca4e424ea42e46069f449bcabb4ea55 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 20 Mar 2018 10:21:47 +0000 Subject: [PATCH 314/364] Unfix patch number for master --- buildconfig/CMake/VersionNumber.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildconfig/CMake/VersionNumber.cmake b/buildconfig/CMake/VersionNumber.cmake index 0ef41816a34b..ad429218ae4c 100644 --- a/buildconfig/CMake/VersionNumber.cmake +++ b/buildconfig/CMake/VersionNumber.cmake @@ -6,4 +6,4 @@ set ( VERSION_MINOR 12 ) # UNCOMMENT the next 'set' line to 'force' the patch version number to # a value (instead of using the count coming out of 'git describe') # DO NOT COMMIT THIS TO MASTER UNCOMMENTED, ONLY TO A RELEASE BRANCH -set ( VERSION_PATCH 0 ) +#set ( VERSION_PATCH 0 ) From 4e2863cc74457048dcb6c096be0613cc27d8c67d Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Tue, 20 Mar 2018 10:55:02 +0000 Subject: [PATCH 315/364] Remove pyplot docs reference. Re #22101 --- docs/source/api/python/index.rst | 8 -------- docs/source/api/python/mantidplot/plot.rst | 8 -------- 2 files changed, 16 deletions(-) delete mode 100644 docs/source/api/python/mantidplot/plot.rst diff --git a/docs/source/api/python/index.rst b/docs/source/api/python/index.rst index 3490c7c58bb7..916a08dcbca6 100644 --- a/docs/source/api/python/index.rst +++ b/docs/source/api/python/index.rst @@ -11,14 +11,6 @@ If you are new to Python in Mantid then we advise first looking at our `Mantid t For tutorials on how to use python in MantidPlot please see `MantidPlot: Python Scripting `_. -Matplotlib-like plotting interface ----------------------------------- - -.. toctree:: - :maxdepth: 1 - - mantidplot.pyplot - Reference --------- .. toctree:: diff --git a/docs/source/api/python/mantidplot/plot.rst b/docs/source/api/python/mantidplot/plot.rst deleted file mode 100644 index bd58de32ef17..000000000000 --- a/docs/source/api/python/mantidplot/plot.rst +++ /dev/null @@ -1,8 +0,0 @@ -====== - plot -====== - -.. module:`mantidplot` - -.. autofunction:: mantidplot.plot - From e88c9ec50036b26459e5f069b28956a93ef1ffc2 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Tue, 20 Mar 2018 11:40:55 +0000 Subject: [PATCH 316/364] Another reference removed. Re #22101 --- docs/source/api/python/mantidplot/index.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/api/python/mantidplot/index.rst b/docs/source/api/python/mantidplot/index.rst index aa3cc26dc83e..ade8a9d5a160 100644 --- a/docs/source/api/python/mantidplot/index.rst +++ b/docs/source/api/python/mantidplot/index.rst @@ -49,7 +49,6 @@ This package defines the Python interface to the MantidPlot application. For fra newTable.rst new_proxy.rst note.rst - plot.rst plot2D.rst plot3D.rst plotBin.rst From 722870c193c282ace18cd3aa746da70015d6da94 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 20 Mar 2018 12:06:35 +0000 Subject: [PATCH 317/364] Re #20991: Updated reference files following INTER IDF changes. --- .../tests/analysis/reference/L2QReferenceResult.nxs.md5 | 2 +- .../tests/analysis/reference/QuickReferenceResult.nxs.md5 | 2 +- .../analysis/reference/QuickStitchedReferenceResult.nxs.md5 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 index c8a896ea2aab..e2e298fb93f0 100644 --- a/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 @@ -1 +1 @@ -ab91c31c3afe4344448163c936a6aabb +1445797a969c8f96e9ffe402af0dded7 diff --git a/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 index ddecb58026e8..15dd6430cabd 100644 --- a/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 @@ -1 +1 @@ -db61a5ead517dff760aefd84be6d3489 +0e367a48dd764b901c9176d37f5bf713 diff --git a/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 index 5e2740f55973..4a3b6c8a4078 100644 --- a/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 +++ b/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 @@ -1 +1 @@ -af5615a686637e41b40acac5dcfbd1c2 +f19753635948066d7ce6a45e58640f6f From 109be37ac450d3dea0b79c605cc1bdbf0cbee7c7 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Tue, 20 Mar 2018 14:02:56 +0000 Subject: [PATCH 318/364] Remove, update, format. Re #22082 --- dev-docs/source/Communication.rst | 5 +--- dev-docs/source/Dependencies.rst | 2 +- dev-docs/source/DevelopmentTeam.rst | 6 ----- dev-docs/source/HandlingXML.rst | 8 +++--- dev-docs/source/UsefulTools.rst | 28 +++++++++++--------- dev-docs/source/VisualStudioBuildImpact.rst | 20 ++------------ dev-docs/source/images/ERantsiou.png | Bin 28033 -> 0 bytes dev-docs/source/index.rst | 10 ------- 8 files changed, 23 insertions(+), 56 deletions(-) delete mode 100644 dev-docs/source/images/ERantsiou.png diff --git a/dev-docs/source/Communication.rst b/dev-docs/source/Communication.rst index a3546c73e62c..4344a5157a06 100644 --- a/dev-docs/source/Communication.rst +++ b/dev-docs/source/Communication.rst @@ -12,10 +12,8 @@ How to contact people in the development team --------------------------------------------- * :ref:`Development Team ` Contact Details -* For one to one with local people - go and talk to them * Developer email list (closed list for developers only) mantid-developers@mantidproject.org -* Voice and Video calls - Skype -* Telephone +* `Slack `__: instant messaging and calls Support ------- @@ -30,7 +28,6 @@ Text ^^^^ * Informal discussions, and daily status - `Slack `__ -* Weekly code progress - `Developer news `__ * Set your picture on `Gravatar `__ to get it to appear in github/slack/etc Video conference diff --git a/dev-docs/source/Dependencies.rst b/dev-docs/source/Dependencies.rst index d66367cb665d..cb9da7b2d910 100644 --- a/dev-docs/source/Dependencies.rst +++ b/dev-docs/source/Dependencies.rst @@ -37,5 +37,5 @@ the graphical layer, and something different in the framework where Qt is not available. Also noteworthy is the `Compiler -Support `__ for +Support `__ for various "advanced" language features. diff --git a/dev-docs/source/DevelopmentTeam.rst b/dev-docs/source/DevelopmentTeam.rst index 95bd49217518..af0cb984ac13 100644 --- a/dev-docs/source/DevelopmentTeam.rst +++ b/dev-docs/source/DevelopmentTeam.rst @@ -99,12 +99,6 @@ Development Team +----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ | Ross Whitfield | ORNL, US | | email: whitfieldre@ornl.gov | +----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ -| Emmanouela Rantsiou | PSI, CH | | | email: emmanouela.rantsiou@psi.ch | -| | | | | skype: emmarant | -| .. image:: | | | | phone: +41 56310 4631 | -| images/ERantsiou.png | | | | -| :width: 100px | | | | -+----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ | Gagik Vardanyan | ILL, FR | | | email: vardanyan@ill.fr | | | | | | skype: vardanyan_ILL | +----------------------------+-------------+----------------------------------------------------------------+-----------------------------------------+ diff --git a/dev-docs/source/HandlingXML.rst b/dev-docs/source/HandlingXML.rst index 9c58094c93d1..1f7ad335fe10 100644 --- a/dev-docs/source/HandlingXML.rst +++ b/dev-docs/source/HandlingXML.rst @@ -13,7 +13,7 @@ Examples Parsing ~~~~~~~ -.. code:: cpp +.. code-block:: cpp #include @@ -33,7 +33,7 @@ Parsing Iterating over an element's children ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. code:: cpp +.. code-block:: cpp Poco::XML::Element *pRootElem = pDoc->documentElement(); //Iterate over every child node (non-recursively) @@ -47,7 +47,7 @@ Iterating over an element's children Inspecting an element ~~~~~~~~~~~~~~~~~~~~~ -.. code:: cpp +.. code-block:: cpp Poco::XML::Element *pElem; @@ -70,7 +70,7 @@ a cost of ``n``, where ``n`` is the number of nodes in the list. This means that running the following is horrendously slow: -.. code:: cpp +.. code-block:: cpp // NEVER DO THIS Poco::AutoPtr pElems = pElem->getElementsByTagName("foo"); diff --git a/dev-docs/source/UsefulTools.rst b/dev-docs/source/UsefulTools.rst index 1849b6fe63fc..e2c6e3c22f2c 100644 --- a/dev-docs/source/UsefulTools.rst +++ b/dev-docs/source/UsefulTools.rst @@ -9,17 +9,19 @@ script located in /buildconfig/. It generates the .cpp, .h and test files for a class along with some code stubs. It can also flesh out more methods for new Algorithms, using the "--alg" option. -| ``usage: class_maker.py [-h] [--force] [--test] [--alg] SUBPROJECT CLASSNAME`` -| ``Utility to create Mantid class files: header, source and test.`` -| ``positional arguments:`` -| `` SUBPROJECT  The subproject under Framework/; e.g. Kernel`` -| `` CLASSNAME   Name of the class to create`` -| ``optional arguments:`` -| `` -h, --help  show this help message and exit`` -| `` --force     Force overwriting existing files. Use with caution!`` -| `` --test      Create only the test file.`` -| `` --alg       Create an Algorithm stub. This adds some methods common to`` -| ``             algorithms.`` +:: + + usage: class_maker.py [-h] [--force] [--test] [--alg] SUBPROJECT CLASSNAME + Utility to create Mantid class files: header, source and test. + positional arguments: +  SUBPROJECT  The subproject under Framework/; e.g. Kernel +  CLASSNAME   Name of the class to create + optional arguments: +  -h, --help  show this help message and exit +  --force     Force overwriting existing files. Use with caution! +  --test      Create only the test file. +  --alg       Create an Algorithm stub. This adds some methods common to +              algorithms. Moving/Renaming classes: move_class.py -------------------------------------- @@ -28,7 +30,7 @@ This python script is located in in /buidconfig/. It will move a class from one subproject to another and/or rename the class. Namespaces and cmakelists are adjusted. For details, run: -``Build/move_class.py --help`` +``buildconfig/move_class.py --help`` Deleting a class: delete_class.py --------------------------------- @@ -36,7 +38,7 @@ Deleting a class: delete_class.py This python script is located in in /buildconfig/. It will delete a class from one subproject. CMakeList.txt is adjusted. For details, run: -``Build/delete_class.py --help`` +``buildconfig/delete_class.py --help`` Leak checking etc ----------------- diff --git a/dev-docs/source/VisualStudioBuildImpact.rst b/dev-docs/source/VisualStudioBuildImpact.rst index 967fcbb315ef..2d8f5cb11ba7 100644 --- a/dev-docs/source/VisualStudioBuildImpact.rst +++ b/dev-docs/source/VisualStudioBuildImpact.rst @@ -22,11 +22,7 @@ Script Of course if you don't want to do this yourself then you can use this script. -.. raw:: html - -
    - -.. code:: python +:: Const BELOW_NORMAL = 16384 @@ -39,10 +35,6 @@ script. objProcess.SetPriority(BELOW_NORMAL) Next -.. raw:: html - -
    - Save it as Reduce_Build_Impact.vbs, and use when things are running like a dog! @@ -52,11 +44,7 @@ Monitoring Script If you don't want to keep running the script for each build, here's one that keeps a watch on your system every 5 seconds. -.. raw:: html - -
    - -.. code:: python +:: Const BELOW_NORMAL = 16384 @@ -70,7 +58,3 @@ that keeps a watch on your system every 5 seconds. Next WScript.Sleep 5000 loop - -.. raw:: html - -
    diff --git a/dev-docs/source/images/ERantsiou.png b/dev-docs/source/images/ERantsiou.png deleted file mode 100644 index e819a02203f5a3646b979b66aefc90eb24f60685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28033 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 Date: Tue, 20 Mar 2018 14:21:58 +0000 Subject: [PATCH 319/364] Add Python GUI docs --- dev-docs/source/GUIDesignGuidelines.rst | 4 + dev-docs/source/MVPPythonViews.rst | 227 ++++++++++++++++++ .../MVPPythonViews/AdjustWidgetLayout.png | Bin 0 -> 120121 bytes .../images/MVPPythonViews/CompletePromote.png | Bin 0 -> 34043 bytes .../images/MVPPythonViews/CopyFromMainUI.png | Bin 0 -> 148409 bytes .../images/MVPPythonViews/NewFileName.png | Bin 0 -> 20274 bytes .../source/images/MVPPythonViews/NewForm.png | Bin 0 -> 65819 bytes .../images/MVPPythonViews/PasteIntoWidget.png | Bin 0 -> 81569 bytes .../MVPPythonViews/PostReplacedWidget.png | Bin 0 -> 96453 bytes .../MVPPythonViews/PreReplacedWidget.png | Bin 0 -> 97205 bytes .../images/MVPPythonViews/PromoteWidget.png | Bin 0 -> 30851 bytes .../images/MVPPythonViews/SelectFile.png | Bin 0 -> 61774 bytes .../images/MVPPythonViews/SelectTemplate.png | Bin 0 -> 41568 bytes 13 files changed, 231 insertions(+) create mode 100644 dev-docs/source/MVPPythonViews.rst create mode 100644 dev-docs/source/images/MVPPythonViews/AdjustWidgetLayout.png create mode 100644 dev-docs/source/images/MVPPythonViews/CompletePromote.png create mode 100644 dev-docs/source/images/MVPPythonViews/CopyFromMainUI.png create mode 100644 dev-docs/source/images/MVPPythonViews/NewFileName.png create mode 100644 dev-docs/source/images/MVPPythonViews/NewForm.png create mode 100644 dev-docs/source/images/MVPPythonViews/PasteIntoWidget.png create mode 100644 dev-docs/source/images/MVPPythonViews/PostReplacedWidget.png create mode 100644 dev-docs/source/images/MVPPythonViews/PreReplacedWidget.png create mode 100644 dev-docs/source/images/MVPPythonViews/PromoteWidget.png create mode 100644 dev-docs/source/images/MVPPythonViews/SelectFile.png create mode 100644 dev-docs/source/images/MVPPythonViews/SelectTemplate.png diff --git a/dev-docs/source/GUIDesignGuidelines.rst b/dev-docs/source/GUIDesignGuidelines.rst index 523f82f4b94c..5500cdc6c950 100644 --- a/dev-docs/source/GUIDesignGuidelines.rst +++ b/dev-docs/source/GUIDesignGuidelines.rst @@ -12,6 +12,8 @@ This page describes guidelines that should be followed when implementing an interface in MantidPlot. The aim is to encourage a consistent approach to developing interfaces. +.. _dev-docs-mvp-intro: + MVP (Model View Presenter) ########################## @@ -53,6 +55,8 @@ maintenance easier. It is important to note that the values used in the calculations should be received from the presenter (more of which below). +.. _dev-docs-mvp-view: + View ---- diff --git a/dev-docs/source/MVPPythonViews.rst b/dev-docs/source/MVPPythonViews.rst new file mode 100644 index 000000000000..1709ef6efb01 --- /dev/null +++ b/dev-docs/source/MVPPythonViews.rst @@ -0,0 +1,227 @@ +Using QtCreator to Generate Python GUI Layouts +============================================== + +Motivation +---------- + +Code for setting up individual widgets and the layout of a view can +become large and difficult to maintain by hand. It usually easier to +edit such code using a drag and drop WYSIWYG (What You See Is What You +Get) editor such as Qt Creator. However, doing so requires some +additional actions at build time. + +Implementation +-------------- + +Qt Creator was not originally designed to work with Python, and it is +therefore not possible to directly save or export the layout as a +Python script. Instead you must first save the layout in a ``.ui`` +file and use the ``pyuic4`` tool to convert it to a python script. + +Integration With CMake +---------------------- + +Running this tool manually for each ui file in the project would +quickly become infeasible. Fortunately it is easy to integrate this +with the cmake build using the ``UiToPy`` function defined in +``buildconfig/CMake/UiToPy.cmake``. This function takes a list of ui +files and a name to be used for a cmake target. It will produce a +target with the specified name, which, when built runs the ``pyuic4`` +command on each of the ``.ui`` files to generate a ``.py`` file with a +``ui_`` prefix in the same directory. + +For example the following CMakeLists.txt: + +.. code:: cmake + + include(UiToPy) + set(UI_FILES + sans_data_processor_window.ui + settings_diagnostic_tab.ui + masking_table.ui + ) + + UiToPy(UI_FILES CompileUISANSDataProcessorInterface) + +Produces a cmake target ``CompileUISANSDataProcessorInterface`` which +when built runs + +| ``pyuic4 sans_data_processor_window.ui -o ui_sans_data_processor_window.py`` +| ``pyuic4 settings_diagnostic_tab.ui -o ui_settings_diagnostic_tab.py`` +| ``pyuic4 masking_table.ui -o ui_masking_table.py`` + +The generated target also runs a script wrap_pyui.py which prepends +``#pylint: skip-file`` to the top of the generated file. + +It is worth noting that for the main Mantid repository, in most cases +``include(UiToPy)`` can be omitted since the majority of Python GUIs +have their ``.ui`` files under the ``scripts/Interface/ui`` directory +and so ``scripts/Interface/ui/CMakeLists.txt`` performs this include. + +Using the Generated Script +-------------------------- + +When following the MVP design pattern as described at +:ref:`dev-docs-mvp-intro`, the generated file alone is not sufficient +as a :ref:`dev-docs-mvp-view`. Directly accessing the widgets and the +signals defined on the view from the presenter moves the view +implementation details into the presenter, which makes it harder to +change the names and types of widgets used to display the +information. Instead it is best to create a separate Python file which +imports the generated one and adds a separate view class which +inherits from the generated one. + +.. code:: python + + import ui_add_runs_page # This imports the file generated by pyuic. + + class AddRunsPage(QtGui.QWidget, ui_add_runs_page.Ui_AddRunsPage): + pass + +You can then add separate methods to the view for accessing and mutating +the content of the widgets as well as add any necessary signals which +form the interface to the view. + +.. code:: python + + import ui_add_runs_page # This imports the file generated by pyuic. + + class AddRunsPage(QtGui.QWidget, ui_add_runs_page.Ui_AddRunsPage): + outFileChanged = pyqtSignal() + + def __init__(self, parent=None): + super(AddRunsPage, self).__init__(parent) + self.setupUi(self) + self._connect_signals() + + def _connect_signals(self): + self.fileNameEdit.editingFinished.connect(self.outFileChanged) + + def out_file_name(self): + return self.fileNameEdit.text().encode('utf-8') + +Keeping GUIs modular using Widgets +################################## + +.. _motivation-1: + +Motivation +---------- + +When designing a GUI in QtCreator it is often too easy to end up with +the entire interface in a single UI file. This can then lead to having a +single presenter for the entire GUI and sometimes even a single model. +This makes the UI harder to maintain as a whole and difficult to re-use, +move and separate out individual sections. + +Instead when building a GUI it is sometimes better to separate parts of +the interface into smaller views and presenters which form a hierarchy +of widgets. For example the new SANS Run Summation page is in it's own +UI file and uses two separate widgets - a ``RunSelectorWidget`` and a +``SummationSettingsWidget``. Although these widgets are not currently +used in any other interface, they are still isolated from the Run +Summation tab and could easily be used in another interface should the +need arise. The code is also better organised and more modular as a +result of this clean separation. + +.. _implementation-1: + +Implementation +-------------- + +Assuming we start with QtCreator with .ui file open which contains a +section of an interface which we wish to move to its own widget. We must +start by creating a new .ui file + +1. Go to *File* > *New File Or Project* and select *Qt Designer Form* +from the list of templates. + +.. image:: images/MVPPythonViews/NewForm.png + +2. Then select *Widget* from the list of form templates. + +.. image:: images/MVPPythonViews/SelectTemplate.png + +3. Enter the name for the file and save it to the location containing +the corresponding CMakeLists.txt + +.. image:: images/MVPPythonViews/NewFileName.png + +4. Click *Next* and adjust any project management settings as you wish +before clicking *Finish*. + +At this point you should have an empty Widget in the design area. + +.. image:: images/MVPPythonViews/SelectFile.png + +You can switch between the two ``.ui`` files using the menu in the top left. + +5. Next, copy the components you wish to move into the new widget and +paste them into the new file. + +.. image:: images/MVPPythonViews/CopyFromMainUI.png + +.. image:: images/MVPPythonViews/PasteIntoWidget.png + +6. Make adjustments to the layout and resize behaviour of the widget as +you see fit. + +.. image:: images/MVPPythonViews/AdjustWidgetLayout.png + +7. Add the following CMake snippet to your CMakeLists.txt, note that +you may already have a target for generating the Python files in which +case you can simply add your new ``.ui`` file to the list of existing +``.ui`` files. + +.. code:: cmake + + set(UI_FILES + my_widget.ui + ) + + UiToPy(UI_FILES CompileUIMyWidget) + +Test that this has worked by saving your ``.ui`` file and re-running +the build, the output should contain a line similar to the following: + +``[1/1] Generating scripts/Interface/ui/sans/ui_my_widget.py`` + +8. Add a separate python file containing the `View +`__ class which extends the generated one. + +.. code:: python + + # my_widget.py + import ui_my_widget + + class MyWidget(QtGui.QWidget, ui_add_runs_page.Ui_MyWidget): + pass + +9. Return to the original interface file, delete the components you +copied across and replace them with a single *Widget* component found in +the containers section. + +.. image:: images/MVPPythonViews/PreReplacedWidget.png + +.. image:: images/MVPPythonViews/PostReplacedWidget.png + +10. Right click on the newly created widget container and select +*Promote To...* + +.. image:: images/MVPPythonViews/PromoteWidget.png + +11. For the *Promoted Class Name* field enter the name of the view +class. If you are taking the advice given above, this should be the name +of the class which inherits from the generated +``ui_my_widget.Ui_MyWidget`` class. + +12. For the *Header File* field enter the fully qualified path of the +python module which contains the class mentioned above. + +13. You can leave the *Global Include* box un-ticked. Finish the +promotion by pressing *Add* and then *Promote*. + +.. image:: images/MVPPythonViews/CompletePromote.png + +14. Save your ui files, re-run and launch the build to see the finished +result. diff --git a/dev-docs/source/images/MVPPythonViews/AdjustWidgetLayout.png b/dev-docs/source/images/MVPPythonViews/AdjustWidgetLayout.png new file mode 100644 index 0000000000000000000000000000000000000000..f8862eabe08ad4b2cc906c6e29a6a80146ed3d03 GIT binary patch literal 120121 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 z≀jCDDpmz1V3U-=5jpYTkJw*t2T)^JF)JIh5&}eCSkP-&aNY@3;;NcYsgDdIyau zvI-p{J;A4Go>Hpdy5~tVpTgef&JWc!9kwzB8r07!jB<<8VT{+*)`WKiTq4u2Tr4$I z981F`Ig+H1vA#P-+bSElDC-dU|^H-Mq@$BN3I9>L@7(l744C-oSkL;z#2? zCJDEf4l;{ASgw!an^ir>KHBc~ygZLBey0F&w5vTeZiVx3Dl~q1O+#I3D*ya_D0iHG;;{Ke9ACj?VY9d>nrJg!G~e-i?4wY8DR zJg&GPAO-9pu7Zkz?b!cQ6cS=G7&^=?-(tSQj!>$s#jK1CVKKrKxRS4f0JL~wB* zwAgm@T0E36w`iBTdXvBt8Xr&JWiWv?mh5a>qq#%B%=o6aNR4COL5+ljn8W;UA3p8h zzkh$YU!IYZYAKsS2r+snP8)-Yn%ey0swm(i@!XNFzL~X&;ClM#S>1GPM^m1a1Ctpv zQ;t!8O2lYX`3tfqySgpFANoNn=Rf)c9Wn664G;GOb3tG}*sV<`O3_|z&lor{%Yh`1h|Ok^sJvQ4r>L*o59=*a=HM7I&qsP;~W|9 zulb=m0_?_9*CBKBpB9-)`3z8hY>az+Y$0>O17Bx^e7B(i4HL6&xFv%*LGH;%;)Drq zn}s_fArG^*EWfpvrw`FTFAaz!A24R6D7mzXtd8e{D5~14DPadic1r2Qxw@nmWB5O9 zkxwytt)_kXVxW9Bdn^ zzaif>tElX&&_g9)xFYpTMo_MRhbpN{3SJZ4hF!^#IkXTd(%9IDlNfD0F zF^oab1G%_2}F!XO1HSGkM#BmRz%_$uS!bgUuv zp`Vwh4?eFC)whgSRaPOS9Yp_1J7~b8)OvG_4NL*Rn>*cpeF&nkmO5kV{dZn4yb+ln z%*3$ZwgdP02TH`*D4AiDUzTs~>PR*W#{MQoSdg2508_U&2o1+H*TBO^+J>z!Mz)JkX;1AfQT z&Ljwb0)X&a+vU@D#+$Kzf(5#|MjRU2T?$%S3|O_APD>`R-*-soDDMAKcz!=3Q<$=B zi@+2s^RO&(L@p(j|smJgU&~+FiBG{1teOl}9>v63#ELH-x3kg0v9@ zlv|{3PB$k(QdXn^Qij)SgU@KVE0rCpbzVshms+Ssaiy&FijeBeItE6w9gD|3d}K2D z3)xa=iy!bkaz@^BOcHiW{lo6so&xtf1O!XXm%ti#y|_BRDF1-ZveZ%E))#;zAb{Sj zoFVn-gWYDE70Gqo^zZ{zR8#~&-pE%sIEWAD5rO+PADVxZ$z(FucFk$CMZ_-nUCKJ^ z$ARhx!1u)5++1s)D(GYo{_S9s4V`G@%!*q{3qLOTEmrYb9A#cf^V zaEgu?rj!YGuX2^I6WO=3)#3^b)UDPDK+iL{f@(Za@Fdawz=NEW#c8Ha*G%!VF@XgLQx7KoguOl1@ECJY zaQtR95c9w6$s9Bo+Cb#2Iqn_o%(S+KXIGKH&n)(2{vRm)%_(%;-0^q+F@tXE>%%cJ zGD5^;qzDJUh3o-v2gSz5hG`fi-)4TZ9UJ*ptsi{PktNsH*U0`jNmxu=GFL_&R-Fo$ z5@#u;2TG)>n;X00><87gKeZ1=)8+6xM&w@ExDINHOUi}u+(kM-xdjzrd1bkxb?86D zjQ{+WY-&<6yc`1@Aec5l^hW)kKcAr=hCmMJJMphB6#UNPJ0Rl%ge(B<@#m(J;OGAQ zDS=XPE~@&0o5iR*3EGqL!R)4_24BeDqhKu-wRe=fBP$rK$j^3bPdt=>;Tz3ApY=vE zB0Bo5zW#FotxwaK> z&oS+sC0tGv$bcXpfDPjd3=V;8-X@TVr}$6eHuxI6^XL2R0zbp&^+CP<$Xtk)nBQJ+ zP|KI(P>BMgPvSCTi@g(Q-WN#$+VKQaDg^Nh?a9aQ*OlMOU3l`|=VHmSOk{0)Ha5P2 z$rvI~y1RQ@u~PL}oPb9HnBw0&UEh4ybpBP%xfbeAI7-8xmsxr$<}`sFIXo!P1|b|? zb4y{T*&6501VA5?jN5Bg&{x4x$?M*6bimb9dTSg%WOp7?9NW&p2KwG>1zJ(dNtAy&IeaML zV2lF^WtJ86K=Tn!sj&Jt{4044g#O_C0qIEcr}eKVnqW2o?V@QKn4o@t<1_lQ1-cmqZa$rzzGAj(_ z2C(y#EOjxor#SYxY>((d1-S1+BGG5>>9EMiE!AVCC+L8IUO=90<)it^{9|D*4laIv&sQdC!eC>0XYJnu1G5JqHM%es}nIQIwI zdjG&cJ)qNf#P4#|AFkclf&Qc8Vvm-TR3N18BNDv2T~Z;pQEpEtCc=||LiZ-(^Ffc2 zGV(C#)$qRla$2&SC;CfdQ?^Wn1uJ>aG+OV$FG2E&CShy2B|Hu$6mw_lAAgG z51H#YL{0L!vy;<3_l@Y?lb#-mi)oi_q@Cf?O~_@vEhJlxhl^3iBCkm|)C|tM!7R7% zg}$mH)gLHCx(lw{Gz&6GhSG z+Ci_cWn~Z6hpxq7Qv}B5fP-U3X%!C=@Uz$`%IN4iZa7_Ua##a9*91ta4A&O{H>v*3 z=W66j8VgqoNG7aRpo!RBxBLQb`wp5k6=w_UEF}TYOM^TJI%bk*F7>>c6v7>B9_qAA zO~&zZ#ez5PTZD_S>5rp?O_QOsh_x-Bd-!_+uKDOXum9%~i@K`^OG7IZh1{|-9W2HQ z>`ujo^3G!lA({SimfQQ+5eD}C(@x>mxMT)v#U`#rGiuOUvosTaYpcRFyR@oh zvYbna=p(2LAoBpFoxIq@aUX5|-V`cX%Dxk2sIL*K_kV^7%srcJjNn9-QV6E8C~jbv$1=xz0mWdBbp^@lgHux z-U4;$_DKCNeA*xj=)tT{{@y>@6sY^;iE33LJ-B=E&zhac95b|BJ^TQYWMLq{FcD%> zp@T&Qv*iWn)z}%Oht;@`szz=_8M>^so5Rqj?P5Z!WVyxd@!y>v#pGqa7tGj9*$3&A zeL%%cnX50fzY=z1khx;y5s#vu&j&4YZwbcb*#X7=7#qUP1Gr~5uCBnEZ+B&Z(rNc} z*#rW9_5lA4(t?CsU-LpV zg?&A@;XCS$9UcCQ1^K1U1cRR%3|{3$AW{6^TPQWRmCdQ9Hg3w5-}ugBVsql7s=#xv z{N;|NC@l}Yeei!^I>W(wz19oJ8I%+z<}Mr2y`bLxbrf~@Myt{*F`v;wwS;wxj7^u5 z#jtyJ9T@`%T3k>@!QGQ_>jo#D3CXjg%|M7ogZBAPOLUA05!>1m6ih-HZ$8|)EhTzj zX39cEoh%;3u&}te80Dt;DO+2oKX0L*9&30^N^_KYwZFSB3u3{Z-7{1*d(39 zX}c7(E9n5Hgi)}`j-{fx9Brj_-@+!GZwMu8X&NPhTL~PrmC+OzdwUJU8HCt$s0KF` zm8|XT7NAUPGgnJd?5_n<8JOG7T~*qzy|C)q5L*YDuU`O{+Zk(2ObmX=@TwgLK4atM zS_mBNt_`XEtA2rj^ZP(VUip&bbbj(N`A4RLdQfE@BgA2FG2Q1;a-qa+`AESUE6VuWdm zo@)L0^rs3EFWag$jBqn1rk$#a`D!h({aR@-vVBfTS+tk&?jg4;p@<0T8Glc#)FU3k>v)9u`dWz@ zkWp`Tz7`aHD?xX72F3(nD*X(uLCrLP*|uIpuoHCnuLTH=_+%uNwmIzkn%T zvRsz(^|%#K07p-R`5=`DOic>c6FuG+I6f}dtkzu~haCkx8_6M1;L8lChV@_^stt*M zNO8e_+JoQO;{5%d*L6n$|5>(7>e0|ojTQh+ZaD2#EZ;bp3lH5r+M_ufgGc7K272hf z6}HQ7MMblqvXCW*W8lu6J6}`|=klIInGjZpNH~%F3V9@p?NLC|qGB_wLri2i@4+Dr zFF7zQS|sD=Wt0g~?>?FvSY;Wou}=f$JR%+5EIvQEy4T zOMn0+?;qT+4%~lmOuO!5L7E-!#ouRy2Or$e50&_@PM$%hClr;ZF0k4Wg z+zFLwM8Gxy{Zlq_Z_#kd{g!meI6m8SVe)c?>~(U~SUyetC4!H{HPJuVDeBOxa+T1R zO>T%KtR@;DM7JB6Vc@V41PB9+`7GtqyQjNDIW*n8j|I-6d!GsSlv_UovL~=uAX-v$-@2X!((=L)gqte1or?R zEaETm;SFlr)gs{b-OYE2*V@|Jp|(SBxMWyt)(`#&%2OYg_R06-o z+M&sS=~$UbdxG0J5f8TqfPM`k#*@FuUw!%n7XvYrQXmup=}10>45+3#o} zsV%#T=d}XDWGdt#*UiUdrh!!fLA?<<=^@C>;$RoCCEe8}#cDe6<>ybcrXwOuNV?$d z%#zQ@)T-r23JVLvXVA%{LZ|gO^PjxF5*hA_CuDbe0iMebIi38f;l>`|O3RE-P7;zm zAnR6|?r7=g2!a7+Ka4Z-o|7Zq8I%5O`$hHl_{2P>&tbWM(~k9w3}I2t+1KMKS6rT| zHt9D1s)k3RmXCOdLwsE<5}b6IOC21dO*$cB-d8v@-E27Tr%IKNG}vsTU=i;Psaefx zjz98z^(yT%#At?n{}A!aH}pN=e6|>Y*;{*(vL@(;23a#bWy406_!Pgcu77RXv$YwMTh^RJvi6P50sNxZ(IKRo;H;Lr7~9BMHWrM zZd^B1d(Gbb^Yql{?0B`a?gsWvKxSy~dV3QcTa6r`f+AfX@a>oGr#_H09DIp-x35-9 zOOO7&fYvneAqE@?cVxc;MX}X4eJ)`crli0;7_D;5|1E&)h)GZ| zFngtz(m^2=Q(K_#u&aMJy8PwZGd!Hovm+*B_U%C*s9?HuznV>L1r$@2-h6 z&b>=bR*33~SNUZ}EkLK%EH0l8X-K{6hjf~Ix4>yp(-!>$n_a zlxVQ_EsJ-*gJlKl!yfvtei|Wfh@RqSNSNlh2q`I%40cJ%s;F5SihP8khm-R@R#oE* zlDvkr(<1e$*2}Qe$Rw{Jae|rc?gNv4PH+V$0Sew)v67Q%-#kJ~HlUZxpsBw3m6 zxGQ2o9|@*`tsNcD!H!e5!8hWAIS?=tJL9~Qsl2>ylay%%)x6QvB%LRXF~-^6QpEUJ zglM_$vQw1OJT2GMfTs-ZIE@Vro{;~yHq};KPEv3san!UcF=duY z%*;p1!=BByK;#TS6tng2h^ThtnLw2yczx#fBA&zX90&tnltYg%#X)vgQ#J7;Bb>wo z*gA~`IzWCR8K3-hD9s=&5+3*Ub$D|ym~?&Fwbk&fuY=*|iPg3yPQLmRs=7qf^Fx*_ zWrviB33Vix90ZTInNsdeaPePVV2}a;17_woAkdwkz`fSXL_Q;00_VPCC`}>=e-@4G z6|ygoW%jii#Ogh0WT>f7kUd|8YUYc`2Iv>c%E*AHNl-M3!vOYg3iGNDpwtmkS}n5JipvCH{TO~?&IZ!c#6Q^0pF*4 z^Q6S@bVM+YotYP$)n&IaR=o z>Zy@J9p{$xwUF|cy@!LT!4T+@;i3W%4vLp$R>Sg!206jl<6Au;R%5e1IdH$cPowu(J> zv{a8Wu{$9+F%+Ax(jGY?AVMH_4*DP>6@6wQ5Nbf=be)7*^R~xDJwz@zU&R<9oj70S zZ;Vt2&U&KGgLh!9%hAp(W#Zn^dj70pPGn(lc!u=+Ju)CFqeI!80xTvc0)=6k{CFe} z4=54?-vL<`2M1w9(GCY2fAt43-E{`VwAS1|`rm|8npKS?={Y!L@bJ*1(rA=j#gI{| z6aFX!GR?~E7{Ncl1Pf+Dt0-Vfs?NseMqj$>Mo4Ve@$jr!d8!nC14vg%d1yC1yyj zE0QP319Ey%)D0O+%@~Z*dI(!AsOO;Mmy_>*Z)4Zk+gmtd{RuIn`he$|JTb753-*Bf zho7yuJe~w3OjZ(=jgO7=ljV7%_Y|AnL9T z6zcg~0IF+!Fv4{6;<8;Ln|NW1=f8_%@k3rh#0T@`%PUCmT_0+e-S`Sw%VS0d1aoZM=A9}XM=E_ znPGOeh0_`$a>fNwu>VYUVj%%pg+HDv90+GI%t3W+J?rqo*`J`MoA$^d|8dW7cNA_*C>+6N9hiB5uI+a5oO8NgIC;;FbG@>1 z{L4ly9*ydw-eZLH&Dp{~ijf8C3IK=EJOn)KxM{nD-xOROV@VM5AO@MY0Rv9U5z!v}0R?f#)$x(iE4 z+$ot?9byZ4$fvrsKk)yFVzJ!y|K>}mkHFTs)3sXr#-s5vk^Es>=!8MUFta|dC-GuyqypE9k#X%dvMBZa z|1K%=uZTlvz`X2hadzfJoH_%=I+J5LKZgJ3Y)|xI0Xz=@ZL55xU`D=FTRuRTft#vE{0zl|Cmq=|EKaTDXJAps^^Udf5;M(qUD6Q zd;QkB))k4(7R2Sd%)q^YvIR^-WyrkW#eOlBIjBKK3pvTQz#wq2A5-E!S+hb(uG-Vi zLHC>4kg=sH9ZjS}^&?qF>8wAR9M&L)M3f&7_(znlEw zXlvT(^8D}&Vw1#TIK$Ti9sg9)B)L?mpz*Em>YFX!rI1XD{oFVE-ST^>&F)|%m0xrw zO(40%96+rDXJ-t%Rj2;HeQ?4LX5@52hHJ;7kWpj{qw&~q--uStlQdr#g9wksKX&l4 zrB=WvRedzNl$W=`7F+~786?H@8ne`$j+#?UK-#jiV=21EAIn{lQ;?(8Kf+|dgg@bQ z&UE$cOzEr+&57QT8A9Z0dup$un48mSL>|1l1)gc}PPTVXH1FJd;Tn+wt6-A-6(s*T zJ0PIB^4pEO*9%R1OWWQ|B?NHt1q%8h`!&6ea8YPPni&TaXjFG<^E$USW4N65h8G{- zp`SmwlmtmbELD2t?VP}Y4i{S zgA564F2bXzKmVOvMf+@H!XE+Eq@s!$Hs%g_rz7UvH78w)JbiEyd`#&!SBJJ|%TF32 z#iGuxQ@fmPCkN1-0GMca^BzIX-=)>_Cc1F>1B-vSS^c<(G$yn=xA$dk=NG?mI~F)A zkUlc%m`z~!2qn3ScCI|OD>2(4u=Zl7slEAmkvc5=;1uxmWE4mFOYwB8v0D&clNhQPI{h!CQU_8Q}m)--d#oAAy6DO-TV2?zhShL6Q!trrE`7mAdv=c4hX%_ zApskPd+IU7RRp9n!6Le9DnerwY1RuN07;A&g;rf&_>hZ7yxi{gVzJ{qp8W28^)8M} z>-3+xrHo8tIl=zH!BCiw5gA;Je8)bXvThU8Ye6ln+O1_2L=DI7e1eO!NbLo$4~OY5 zKvHxIC)0%hCtK3W%`}gl*ju-9j+pl|7A`Oz4Y4&H#Wps6eR%jW792~+T!-I!6<0l+XGtrA2`?A{8=386VQ-G4y$+`bDkjSy` z=zM4EXq&tdnWA9?!X=h;aKK+7{SpnhHJy04j5ZIW5mO+st8a4vkHWMuI-eYE0I5yz zGk{Jv24=n%6Zh{8Ce@FRTIilvQf!p3oE;Mo;57CrYRm`Yq;!=l=b;h?Mn|`w5Zu5=h?RbJ3m>`;ZM-M?L*z9{7wVbMe|)s1txG6w|)Vz^XtBQ@Fo!2__j z!gT{O*KocK^{R_<=TJ9VxY!>`F(ZeM_8*=-_iBZdg_$VL+Lz$Vj(op9FK^h{oD`;n z!U?jJ{+tf=VmGTAHY|bZx#iyLgPE#&9Lspi?vgjn%nDjep^EO-?acSxM%}zhLrBr`@fl3c$CGm2Ql#QyrL^A=<`%$VcmpK zPvG7e%ezKx^J70>zG;hzvSjc)0cQnAi8I zDfH2bRBk*`t?-T(8O-MilwThP3jxzXKS@AGNAW!Y=7r?*BiYz!e{Q;%wY3b?f-#7S zLO{A(u}&fZS?XJRdrvv2edgvcQ2<@^^z;OnjSEI23<}@Hbn}JXWnVnVIloE)tZYCP zj1PG@&*w0p<9rBB4EBpN{|o0+NT@$P5AZws=-8Y1MA$YR*b~CNT~c7)q*P%>2tKHF zc~i;XHq_bkW*TF=7U!p7P>rcLEq0nm zQ9x1>?{(E@zd)c_>p*7i#(;W8%THDJJHKm}ori~&!4e_@;@)Li z&_cQdYc4xu+9iF%BL}1Q3sDUVRG`2t4P+ARN<@>sc#*-^*bh(U1RAFsgarZ30QQ=3 zz01J%k{{E#@;xM`qixt~X`}?htiZ@(X-f<2)9>6jl^IvZKyY5GgO_3fD;x^rbgYx7mp9NmWl9iTboSAKxh6^cO)I9{NSJrg_Bu}(+{8d z-S~+n8xScW-!b1{BFIC~zrJQ7Cc4aS_wQOshFUJJ&*%AT3KvHhWtXFMQFyU9!g|ji z1M7Tn(izPSjpzKH8xBBc9ntIx=Yil+c=!@lkRnO(S)xRPxwP6+&=0z6qTc*M^ku?r z;+K$lmrk5Cq?KlMiQj~^`nFEvLv-}EIDW0Qvqj=H)AiqqMGw#b+U`&6oXB^U0XP z9UeFsa`UW?Hcp?RBjd< zhCUc&z>u>CcsV-HvT{cNx&uFseb8N92me(R$ckz`nPlnu!+XuCyu$qWeHnPF?x?F){qaK zNr@P_q(wH{HP%is=O0Ov&OZ9QgzMh+wk>k_Oa|47jYKpIkk=RdsZK~+$F#lY@1&Nw zzJ9JIRF<`%)F@V)h-|&~Cr??!fKW3%vt}ZL3buYm5vLBoP>~Dx$xZxcVA(*9=PST2 zl-_)hd}m&HN(4kC`-|`tu;tV1C^vuEYjnr7=j&ifMLj&k4OWueyzkt20J(dw-Wo6Q z?g@-?0@9e+mw$qEsTFqm=7bw;I>q&LvCbx~lS4iSWTS0XZsVI*U6P;$5Q-<}Ub~3` zF64xI&Ig9!=Ys}}h%Hadcv)z16|5Bgc39-C!ya`pU710=aDRPVRnK&MenW{@7^+X{ z;gSSU!`Y+d-FsET!v~i}GN~W^cm!sE3Wmhy!GZ~pxGoJIPT+0R)ZEOQJs28}xY>fv zHKBJICi>d8wtK-M@?;qHhorC=`-VnXyA{WuRz?kH(`*t*Q(Ea(@p#NKnh#tr&O}SgYi?zc z1THQvDD^md;$V4^+1%QjAZ`4i;KmmRg^Mti#K#$NOOyM9uVcj(BnI|-a*9%O2lX-I z$xFzPt(g7Fa>~%w>CFd3oYlXj(Yo`M8CoK0lKB3{@p~LCHwNb$bpHg8y4~YN&Az6& z0Fk5?P1THd>lwA~D6JfVnF=^s*OQ8Gv9Waa~4~mF-dxt*SeS6?cOhR0w z`J_vSkoug6Wo|R!Nm05(uU_x~f`J9VR*ku zVtxTdk~Vhgp7_}iE$Obj2npVmF)RV~t)cLAzR)Q5{NnN8m1Q3#&=67M(jxp;Hzc=zn6m#Q`(_6Y|^B(UGMn~v_V zLWY;lw+Hx5-mwbXvuXXDr+czDOwGt>Nn(&aNN94Ep0D%ny4}{+KlT3m;yCDJ#eJoO0GKlDI6u3(0u8Xv~^Q! z{-Yz$3(bycG9f&A>)Rkneawm3uo=l5S&u^}s`Q~er-YytQ^S0+xmj8dA>EnU&j%}} zmEGkV%iCy*Pz4Y&{6|b67&YM#-rG6eu7E* z7ZJbcXfCM3RstkUH0lEhaQ|5hGO(~9yc=Hvu85%Y=jFQ>9>_{fKj18)YZStcfHcQ> z+K2HKgl|Hzoz?xr;X>rT$VZuRW{7opS{0!5a+6vo5)4j(_DZ*~pog3-7P0l)Rd$nC z-YsUSmmj(k(=Y$gxhnt_a@fTI8vWmL)_HeQXXeFj z4~m!PnRd7kH;u3n;b9>6#WPj&EMUZ;Q=frP`JU4s9)*yQw#yBU$_qVi^U4dA@J2A2 zuqhdAT+Yqf?7lM_w%@P#mD$j@#Qlb5TSQ&`w$8JhXK$WSKIeU}YuJ1^*}<~0IhcY5 ztNrKu_I4~R3N)uRi51&A4b@?*79=$_z77VM-tk?Prm7=FrpD+z+Cx$his&6r2_Eke z`T9CKvKh`uSK=9w){=scl|^S04P%U-LOKbZWG8HsSYh3ajU94!w%ZA(b{owLpWv0i zTxWRPH*T~?hKJZ1c4s`NkceS)F)-3MuG7KT747c3gQ^X6z`<#Ttl>O0H5DSIQefXp zFdBBWbshTXD<5oZ=9h7j(H%A(0}BDNC!(b5zU_4V{(+KjHtv0Su+BgPI?9^r&+Zym z!1TEVZu#Ar`{!mr^@M%Ml!tCBFy6>HC_FCCPr%PtW`hY0kFjg0s>y0mDc9)+@Dd7C z)PJOi!7usS(K(8C^#tm5OUL--OXH1Dph1Cy2)*{upGap^_lM8EzyE=B%x~sP$zrL% z*fx+3dIAMwM3=!H%>@5}tM$;xNc_K39^@2(I>_aU2L_dqwVKLD6|Yg*-X5hwryHFT z;Vs{PBplgoa_8peiTW1grFA}iv$@{Sgjg#5- zMbi8s;3Iijv&7{W1Eao=Is6@VtDbR@RVbCKWG(>7;K=Iq!2*p^6WMH|w!X3PSS%QE zYrC332ierp(eUnN5T0W1rSoPmE6Ik?d<8dZiJ>w~}b^)PSLw90C{yR6|inJkD5O)iJ1vA^P6uIP$|wXs$4 zdd0Gnw;=fIy`G*zu_lu;9HPw3$E~7Gr#Q%cBbQ>N{B)%OPnjyX#U7`3JgCWtb${~J zApxq90!{^wsK5nNT5EB~7Tt(~#4RZPL<`f?(h0yNH1RR*UELRRSk?tG{J-hXX5fWN zZlX-5YAc|GuqD*o(lQpdLmkC_nv6^e&bJ-_q^KmwK9r}w$*pjCX60qdVmKDI5zX-k z>mO@BV$I6NCR6GXmP*u^|Gg%<72Mwby#ZW1TjGAbSX|~>q#5}ZCk+?D%o2|F_TM8S zjL=nkSk==NGSRa)8)Et07Yp*+vg5U+F!P@Uxo0oWs)z^V70_Hc~e;% z>Gpt_TMS%>m<|^PAh*36=vklCz%4M6Nr`<^Hj(H3#FDUFnWR zqwIqX;*mgfrvbI56W66G$cDYL1JF<~8vGaPB)RLx$Nd24MJFbf1pJTDs0#%ix7cj7 zQCpb#8$G^$edD53I8%5+3YX01)FR6EPZ8bjiOXd155Saj4K7&TYqZX7Q^e|x(^WN< zs`ANQ1w8TN-jekAIJ~KUYxBEBG&^I*A{G8EW|Frp^xs;hqhpe1^%*gN?Ri6eaLv0X zq@?kE=P1(BIKq;2m4(8>8XxE70e7`u-5(Sy%s$!{8o0=f!HaeItXRX>|Gny>S+=vP zIsr|x8Vv5fc+`e*E^niYk`kfborQO#JF%t=W5C!LhScX;OJCh!O%UTd4rjSu>I_z0 zhMPq04^uep)SNo)uJaXcj)*TlAjCa;=laS_=l)G#(Pyc*&RlZCOtzt3_VQ!j+t~{< z^|GI^sDb4iZ+d@Mt}+830Sog+Ecd!@WlWV@(ZngSI01`Z{U4GSO8G}2r!c|&=SqF} zK)HVcbl~Hi)nnL08;*_dijGORn2=67oe}~bLh+>fG9(tF-;jFu^|uKy%b$A3Pc1Hj z{Gz~O6fAk0nu;%cw){?^Koo;Pv3nNEF;73Z*mRtR>W{ojHi#&;+v5dOnEbHbxH!9@hi?ISjzz`%E- zh;<}#L#hWvE1>eEAa}^W+vGoAo~7>1DU=NbyK!MO(X#+nSTBUa5c#cf?k`b22f_WEjpKTxD}ScmW493WzK|f4)j>9hxkd znd}@{2nkZLISE1#WO19r=_}0e=$N>k5-GEQ0VC`QaI^j?D`PPB+akwyXJ-ejH_*D3 zmFeLifHU^!kf(S5W})e1N0ARUgWlZRvGH+Mf=9x0RhRH8D6g&eo+0b0Z}*AXz)p2; zXd9#ayy`G~ySdSNqwkTZ=v{0&^#*D>iND?5KUA`^SPm1B+@=5V)`Nbv=$V<06+e=C zgp1n*rBb;>`SedasmYh zCP>92HTYPE{}^IeY;QxQ__I01n+%c_&@UBcs#r`-@j{4aD_BK#8!!Uso1#Pj96F#U z*TJ(ht@4K`BrpMpGT#VvkX^$0>7L${+pQ}G<7rs%W4@;>CMRDYZ~RsHyY^2&72Iky zugbZs<^}Gc58zWME|rzJ3;)xsat7kY9`ORz0ov!L%P5eKM!LEEXAAHC5KB?l*o<(< z^*dOg@0`#4RV&98fR7!;U_6;AyZnR-$Sf%~kpm4!UCHhC=YE6XuWYC)U0kl;ys=Z` zLHr-_3kI>%(UrKkI3&eeZw+_i<0?&z^9I|5%Oc@Q-}9L2lHMKt_X05V-JPQ-|NQwg zP{kM;K)3K|Z|~l$4jhJn1DmgK0#!V|--yj&=P8hx-s|hj7EPT*GTont)E5Aw$U%V? z;m*vfuPdM72LK;DK6n_aEGpfmaE%Ki&~n z4?qx^urORN{wJpYHzNQ{gv;8ICW`6Y=DEe8tr|G(xX;u_O9K`2DOd?_AcBszh;25< z!46WR#+kEh)5)F5+@hm}Nb|QMB7D+8D;voV?V>qy5i0yuP;dPmZ1lKt?dBijMcRBl zJrfM=SZJfPKZ8mz`;aJSs4&VU<2hfSt=;E)I(Qs9O zMTJLv>-v$7{L>sv0s=@E`njD0Zg?GV5l#sSvw3L!K#v4sHj1^TN654C5dAY?Qz#@P zB(R*cIIF*NK+IlW>>(IDBp9O+P$Sjgru;ID>IOrXi1vRJreMm`_1;lS69(Nhtd56> zsc5lk0LF}qT(4#*x}ACB@W_Y)r34}pKNWy@shJHHorZg0S^W3!-9@%J?S{RShOS-~ z40#Fs!L@t$qN=csMHz11C;XI>vPjcDHIipX49k4P&l6#}!=bUaI(jRTG>{5dPTR=# zf4&W`FHJtZ)>L0tpJC&N7w2w020WqL$)_QKk*#5O(02P08<$6tTE&U!-YBP;EGUo! zi@2wx+}gIVus=OP>59|21w7tnq*F=HW!8XW^`dQf9Kxqmo6paFIn;D zvi{HMi&U9<=cRftj10AspEYRQ)gh9CQk~B|jJF$`gxMrx+!-b%*K1R&u<2bdoWR9P zTWuqm^qzMuEC|E*=R;Z9*j~YLf#kY?hjREu1Hqfg`o(s>F+b$;O`0g5Ri|KkAq9ANFgy)5(**o zhJD$@+PT^CJ`2#AgpHV)72`a8VBQz6%m8k0VH}&ri1|eLfG;o-jnQ|zJg0$Jf(^JZ zNQX$t$wQ7voBvEye9X1j)vMI_;|82O0QK4Mi6j~y5N_>n(|4$h=2%foXlTHMS=-#4 zT002qivN~tyF828hIz>isV6KnM4@fhG5LuM^$LpDdI*FR(F7kb{#hIn#(tqx{q+vU zZ&0$hb5mbzR$U%hjWSRIUP7YQP zrj4hhr+&BH-I9k`H>yweSC{)zF$g(qk!*8d8C-j3Y~1KMO$I-tv%gZHCLsn#(Lq
    uyga@bBl$5Us2)yRn-2MKCL4R|MP+vck&8ia;142%Rt>o873NVa~sUc5W zNW^GmcjZDB(#3%wsqDr$olNbmnIu98+v=3s|&6KLH`_+ zrTKsZ1<_GIJGHlae8BU#rzbbDjHDjphn01Apw%a6oO;OF*&~{oo{H_u3Nu+gnaCtK z(6IUQC%=AdB6!C(PbtTSqcsG#tH9A5m}A7@L4eY>#jwQMW~#0}EkproAy=vGd_`Ox ztIN#wDCOEuYo!ZoN-{2~JL>#+ykBb%`vMlWFi;Xcv;L%Yl*&$9%HGHk$&;VX} zppedArPHj8SHDce+oNl6j@h(Kd8MoL%2gv~etons2@JPK8e#PzcBXw5kQ7|p_s=o` z5lP;S8euY)DTBn`*|=Dzv|dTrasb8=Va~I+zi00V+KU;J_69$iWcQ`E&s^a9N zCT)y&r~*)lC?uk)>*^8`%Siuo>3{y`(m#dG14s(hS`_C3{6rn{bai`L?CL5lo#9B9 zro^PoP@_Lsf0KuKpTO2+sz`HVr{g;si1jG9A}k;&=rBHhD^-ncavw@6>&Pg^$Mq4N zKvnXFhOqF|<-rt|hK2@{k#cw8$;;|&p36i(FMq!{v-J^1)3GpDyN&m2U+Kcwk8i=8 z#$mgz-LS^Cw|UBLTUZD)W^i`Zx&Ni}{(SEyD+%g!iQm{qjkUFPVB^o|*|S2IRsXl% z^3d$UN(c)FLJUBDB1J{K)&T){8 zNeJqZOLupJkr>w^5u(G1|2^NP|8c2{B-(+`-98+N$eErdvGerC@sCRI35i0&r#St- zlL_6$QsjC$ z?|`;ugF7sf-Ul8L6+dgzO-9b_SO!KRo)6_n_rs@7=vE-KSAJ7XrhE ze42cM)@;KY!8b3>FRlU&Ni<&)430bUUcB7u)=VTWs!T*E5WPXEj7Cz#w;Ub)qgi=j z2PvPf@O(K7xfV0e0r)ba`vqMwrTW}s#8MzAgF;*dD+G)gz?chq*{-xjN2kk1Vrx%) z{;DFLhOz!z?lIi|5`^4K(s{lSUNq`o+UQSvr$VkvuST#l@+)1)~T7Ow|_*pH#4#79LE4A#|p`UFr=u}2K=E;2Y? zI7Ju#{%s&^=C!!uE@~FdV;8f#*b!>YlJDfP-kJA8Hlg{Xx$hS*|3Hum{_9VCS5PsR zmY;XYzCRBVgkKJp&&;O7Es*a_sX5@+DdY$H)5=6divQo!BndHjgdn?X*RFxE%?FHc zvo&3RWz6z0F6|J7NMN~T80S1c)EO$UrM0q~tSwNv3u0PSlR+Tp-Mwo?t5)tAo1JZY zoT&;8V%ercg`GJccp%Dp3=)kt0+t1RdhhaR8IB(Ta6dZlG3g!5zZLe?sRIy^!<^Qi`+llM9uXvb-6%|# zqO`Bjr@M$?3shk;o>`l_{@(BA;noNJ9yFeJ#yb4(s%M1~3ArEhy$+^=#q47@phs}N z;-0>6t~DF`C6Jeli;q9EG9zYbiB7cPAmo*#7jV&ne@61A`yXq}6Gz70o>gL4bHba< zY_q+>gpJh;TwmMTP_qo9`DdPHCC(%h$7-aVLQ?kf*|3?XpU0F8NV`}PP>N3#Lhy_vzcORVX z{q1h<#l7%6C3g>FVjx}2PQB}FpiyPBT*D2=!^=>~BkwG<-5mD;hbmO}&o%_i+J;)Z z(JIQI8^_SYx#csVM1CZ>6?&w!IacA!0z(l+&>+tVVr z;mUuZo_d%||LwQP;(zV;$lXZP^CvT(zdVU`lOtacxg}>v6vg;q0|)t!H`}h8|Loe1 z!@|N4$uxwe05aS6Tl!j(OtZPH>)hD#tXi4HHJqw%eHo+Qb9Gy1R#w0quAOYOZ?JbZ zn)l1^nZ?E$eve_u+*ZI2IXbatm>ahnDm5iw(CgIesrMRLJUdv7WjB>O*n2i3GILo(C5TjAYb5VW$_s0Kw-+C@KfcgY(2NZZMp#3Gn zYyrx7P`$n2bdK!#rKK}AHb$vg$qDZk_kE}SJ|$fCkpd&>GKGm{tBPMJ zfa^Y}!uTL74!rRp?Fsh51`zfH01cp%I>5~VIuY_);NxRAGxr=FK#YVhCU zQE!zf$6bt>Ek*f~k+FVY0Gpqm9|j5-A8Xp$GNi~LQx;NV$>F){Od1EV6;G%w679OZ z;tjEm5N8YTJ;++|t353=OBQx^jROOP|4!;aXp(;XJE?I5It*wrFam#q;Q-xJVKc5T zkoOjBjq~q!AfkTt>gQ;YImB!F78KYB+X;Ctl2TE51FCzqNx*cQ4{5gko%k?=r1Sn% z?R@g=nZV-qQuF~zR7@1pr`XLu=k6alb9n1_H#3lusG$rd2*HpplB5sB!Kx}Aj|YT5 z?~cs4lP)gBKU@4yfQsT5h>qn2?+PL@&)pczDg-I*ksenY>HSF&##DY|mIPPY*a;B6qBQoN2{FT+{2y zQDiHvp#Ya1i5@|R9wsRx(tf&$t#qlmj;!08HvFmU{$hYqK7~pBxWK;qOSl2Ty%0j&4ka2T8wqtn=GmGq}O46 zjJ~6$Y3>4_+ji=jKvQ=Dduu{`d@(*gxZFQR4(Qd6C=L%eJ>lbeMoSyR@yHG${9c4y zzULU@k_#%t9Y0}(B@Xx*JDC+13qU!S1<#&qZZWaVQ5Z zH+Q9!MZA5`!7PFYz%PnQu6rl8rf&Yav&Z`4-kb_$@Co?#{|FCH6@L$3pm$76OoUa7 zw@i3&+csWlfZf<#&5)NoVCrqX+~<{fxq)~eB1|zi)gtpe`(_!5ST3lqST;ueiQ?%B zl)=iEYk1+|&_5y)Zi~YSt}`bmgYI&?U@C<^LmqJdH+Kzd0|(}CRxPKPpLhU!p{Nzx z|M<1ie}&az1(WIXmk)pP^ud@25(KZfjoNK|pri6mlRvwnRAEa)z-+oulq!qj>F=*M zQR^PXX%iuWMFoW*J}(m%E7&v|h(&!)VQy`n%rmf7Z&WpZ&}HU$7{g^UQW^{|Ce=R~ z3+#O@9i6&GjLNAo_q!<8>-_{!Ko-t+4;j`SN!~Prm>-F%D%SVKn30zonG8igv_z(9 zEGh}ifF76fw^0vg96Y_f;fTldigzKTYjt@vBTq^O4;3$2R^Lj-8wG7`bod{j_`os< z?whCF+*jO5sc$~vPjHy|p?VBcpS^rq{r;*J%2=6QfTW;5-&+(c)R$7 zzR-fu5MRP$JhQB3mFtxK_`0hzz>rOSD-?KwNV+eWxs+S=OTzL^1=R8~f_HsFtJ z?H_a;`v28w46tJ0j53sUY3LZhMlq(QmWXN*i4d5mX!Qp}JnJE;bxIl@O`ePK0@2Zi z&jLQnJ#p6{px{>S!M&DUH4}FmUrIJC$A6`EMVHd>51<6FioipI->hi%h0zAMJt66ofm->pmRPNTr`KglXmqic9F6z&7@c57}(yIN^AIy5K@L4>r%TM|}ofPHX&I@YD z;94Il&_|U}R7x4u5P=-9`?!ff-m^A`F=-WCHMR5LVm8xm_FM;xq+Un^Lq{<1|CP3Zn(xo-r? zJfJ0gfP%$2#%8g?h*u)Qeqpyy1w##vJ_RK2pxiFANT{|wcX9%A0*>?3%8rQrRj~5^ z_$fyu=_fmr@gIj(1vrEPB(tuE=qHIl4mN|%0rpkpnnTcAFNMmK0Svdw=rhZ3BCmE%zU2A5xaLo6tR|5Q#C&~MlkN) zEvpH|xD>Ls?v{IQKd@_OhVPfG1aaC$(H=ar|NGk0#mdlIwvLTGzJVtA5GW6G1p3-W zBH9P#@<}yyWJOtGSxM*P@G(Rdi~Q$c1=A%sSZ4|>7G2Z6jP6hnl-MjvT!%2sTT>h3 zj*r=FeSzS&J^h_z|sl~Lv)z0h;xfkb*Jx&pC% zj9}?fLWKP-q2k)bh0E&!Cq=ll_%$_f8!=cNJZ|tO0^)=B0aU6e(U->uy?1c5=SOUsps-*?KWDy;I7LII*r3N<@ZL6%DWcP zoT8WbHQ0z? z2JaIvzq0C3o50&6|MpF=ErKHyVoB*?La?6E>xdQtRQXSbO`Q-h0$e+z-bh zpn(|a?%rOoxA2%1mPJppF8cLno`VzgsAYKo;JwZSP^UwC zqfGo5vz~(ABiFX>V@RfodvxagV92PFkPu8#kj<7L^e5u!n9S3YF8N6zf0hnqRpT8P zCCw1?cW&a2qx>`X>9S#CTT9Pn^MTOy9G(no- zp{0&}FpdmdWRsNf{s6P3yT6Tv#lma=H`Rv9(g0pqB$W#;tyn+BiLc;K)zt^Dyrf&-8PgiAG|Cm(C9nE2r z2(Ah!Z-j*M95=b69qRwhdRsM7nkBHRrgv!z6RLaw5SB=zWYp8=Y|0!|*wuC8gtr_y z9uPi=t217|@{)yNw*BH9_i+A=N|BKlG(ONfoH6Nu=+}C7qJlCyR~Gs%a1{xs87;H| zpX;=v)9w^S$rjzor9algmb4m`zIn2E2OB)Et*!4tXB7wReQ48io#sVCvenv&dtKth z8#_>B3IjM@>!BbkJXWuK|eVbq^-r8=BJKb%t+m4Ct^ z5=j7~h=t*=}4_qPH zrlE6?qSIw8#|p=IAd_sZLELEIHX_YLe17{cD;H{$TE#AHr~pR-@2{h++36q)>$%2#D{!ye_pacs+EM}#L4!kxl)-K7l}{+y+y6PlT-PfDjT1YU7QbdL-cDVrV#6U zWqq`upS&4SYgAc~jTUZB+13+&zIxSQw3I0(CfMz)Q1C7c9x>VG#Rao#!4Ujz_oT0Ypk_5&Y5Ec2=pbpi+E?#QrI2g?(QYWI-NzZo@nI14;};mXkMspGwT9-xC%7?D<^i9eLZ-S$LIoGFv9Xs|&#)(WhQsM;{dz_BFUtrQ!_CIU!*h zO!(0u{0VXU2XOGiY6l^l$Xk?}F*o;DW)>C{dd4wkN~p1z@QH|$ZU7$VA&ZBc_RnRL z@BI?`2stizcz-8ru0m_KeD+!)m&&8F%h}#JU-5Kkw~mWFz)E}9cu_tyaOh*y(NP9^ z03?id=5g?O%20B0mdiE%)erqu;k?KU?fy$h*UOTn#FT@78wQ)De8qG;&eqlqb8pebEUr+C_uXnAHg=5`se%>noPRj{RtNDUQ^lT($hkb(`^|U3%+u1qL^4JplynV(pjyvDUXd4 zk0ml|wABvM)|hh`g%ILO5qfD=IGj3>IDi+{c(84d8yfLkkw*?NsAgQV-EBzh;v=3;86A zAD#Hzf#6kaP#{d5axOY?tn^C$DazBCTb#{b95w89)o(pmFFzLKVb3=ga^k!C=!e~> z&z%GucI!y1?sPQqE`rghsVLBO21$_dz1*QDCEMI-{u6iaa)}?FV}M8&&TGCHs#Os^ zIIulCUX^n>*-$lg^a-I^td6TI-#%GIq!t{H9tE5oiomc3&)nC?TwwZij(2vT3SvSX zJ-vq0FSmNLY(%5iInUUk9^jrI+w=JoArZjkz;KQ#`|t_v+k@WY(ez(~VC&ogc{$2? zF4w-?EU&=lEqp6QrpjV3~KK(zySO+fp=6%3#ylDJ)ebbC;EtxsbI~ z&Hyc-xRf*V5sF~1^{j6)&q)qtIiO-Wht)2hzkGhlM6U&+p&%QZzy1Ai?va0`)MJ}J z6EThoXE%OO5478L_x3R{F>z4$3>ZpkYQ{qBsC?s@J~YH|VHiXy`Q}CvI&t zaAWxQZ%VyR)#~DIvVsI{XJ;o?#|ut`!==)nhVr{Vd2j9F-QH^HeFC7Hy#SxAn%W+| zvUb=C0`33|4!;idCD)EH-p~ix-FZTGC}&R2UjAMS0af}-z72#7D-4`)6PEBqFq*xY z{dWHftl{2``bU4AEQOlM)~b*-LNp>h=}s2T>9^%Bu7heZYT~|{Lb$LQx}KQ zbr|VYbFyJfv_e_EteMBBah8kgqq+S<+6(b znukH>`j!4P!y-se^2v#l{*>?=^!6=Yy(!^5#y52z6Bcx?UVP+%%*D4Ar8dOJ?5YI@ zyh=m&sY=UaL6L-sDo~k3efRwQiKG8}Y4)IlPD3vYXstArlyC`{O<-&&Q&Lq0_7t(0 znAlD6qy5>csg&fWU`H>1uY!sbPgnlTWZeW&wJwD0(uxuH9H%;){H+LfjB-iEpKHEnCGsOJ9 z?aa5%gU%PHF_YtwSU7X^^Iq%C2PHT*Xo$N*Plg5AMHIac)O|xbIaHGR1gG=A_7Haj z<3r=fh_|I~YrGU?enOP5ub=fyXAFm=-_(<6f?X>47Ah8dXuIS@u;3TnIDUFcY)5VSTi-h4szsrr~Xg#0`;(%a>CH{MDet(Erj!HL1S~39r<2rtagoJ~c3S~yR zBEN-&We=p@8@tR{W@V|}uL#-H7u*=U(^V*LEEo`5z0}#*U1&oMbp*AXR~DIFNQ;^v z(D>(1@Q0oCXbyy8M|OUCfH)RIix4lDin}GqbFem zY}ZEG|F(wWo(-tVr77k7w#&Bv8$86a6IBn(-eVn|+1Xi8_fpy@FZRfhZp%;0CEvSt zdPuiy2GWT*Hg;B|WkGfvuUbl_(z*?f=oo`m`mgQQL(nj&FB?I6D!EBCE)}^zxbH4V z5VcqWcbdS+rAJCe%kj?)#Wz;U^G+eydwAwy(X5VkQ<2x@($n%fz@K`QB5$qRLL^vb zVHlkcQ)IuonnFa%fH9(cv3~7x_4!`c``D;mj$2$CYRPg`$4+~cV3=1IVmfL+n_0Bn zpGoa}x>wUN5K@&asdM@13vx9lFHbxk5u+tZtdF?6=5Vrh>S0e$$^qjs*|t3bTAXP5 z*{bT%*1%3~Jby!%SanI^ge&Jx8z!`SyWMlA=5ULmj+^yU$t%5d#J=1Zs%c}hI(A%m z!A;EcGk17b?H`8}^C<%Z2Kev+ErMx<`Im6ItuOH*-aY|S++cN$(`EY`LEpy$`zkhu zy#*Ajp)^kc!2bI6t567o!t-E6_WO)l;RDY$_x@^sZ%H_X(9-@Y1oQO#=Dh}hzEYtj z7CvLXS-5;$_0Uk5LVKi+mRZeT(aNw(ea?^q}B=MhpTy_Ok93#ZDQ-2`csHiD`Ya1ONb;)X%rPgoOiMuoXD%tH9o%9>$nd)v^Z# zM%W+hB7v6ijILAUF{^dhr)#hBSNrTcXvFSU3F}@k}VlEW@%%=D;Y<*<#d`4SJok6b2Z;^ z+}o@|bMeF5+xH0=QJz#hWVx1>yEx+K@6};f5t&Y{H9ZZ%5MUAW!@Mn_P!>E~v{=m1 zA3chzcs{dH;iz`^Zg05Gxs9G-?%q~( znj2oD5|WaTMCE?X(bi&bi?>U*=QqD($cw1Xn&?r3?i>Opf}*L`0FQU3hP*~bRAB0s z$g>b(-%IY7s+4mTa17luMT|SYRoubEVJb-d3JL;DXbj8VpWD-IKe^9n+;bhE#)P#^ zQxu43%}^@~0dr&MOFlAWVF9Ui zbtEJJ>cfPO*qJr>#=1ee*F-S2)$-1>1xQY0(RALH8*K`xsNh;xDSF?MZ)m`XZ(^Fk z=6sMLA$D1r&7fBs3Vfv0wRr(2HE73(-b160c(mK`T)fFPQ^(s|K+&F^Ilf4VJ$5`{ zG-aa&ObrC;oLUNM5%Pz=IlWL<#%?6}`Yo>yvZ@28o3-T=T?eQj-&@nE)W zL-&s~`83WQwUD1bYr*z+>u{GpNycLB=nf>xy@U|UT6dqQst+-!L|EX8Ge46gDz|07 z$LVnlvwNIkQP#+ACJ=alXzrNo{K|EjuO*Z^0G1PwM}M=rgLyUiE`TJp=HuF(6BRJ= zt+w5W>!mX`ZYe3vHLDZ!z2{f#xJd+*+x{%H2Wb*)EQ&5i%lhngYi?I>=yyaX7zQ@L zv%qc3!P|cgC{&PmZjLZfU>Db>`sbl0@#a~M8s)()Dn>SDUuU$K`8p(DLyo;#-);32Q zjj>1bMU%+D4qzCdFg0)^)$9bPhgI3rPsGHWy<9d@8Jq%Do--9j<1U~~K8!GDBQ zm$_LjnRuz&((fTE?Ra)jGmOENTT|=|pCaYeo?`_|rb>QSLpjryI1FduZ2AxEHU*~F zmAxbg*--+xLm^1^Ar@A9pQh`qnH;9ezg%x70CND5W3`=mx(mXgz|=TBzb7XL8|QM_ zahj8Zuo^sLu)=2>%;6Yn9Bi?Dz;+qZRt1u5tjP&KmnI!_TF#YF*jG1%#^fjI+8_N9fR4oGBQ0n zLZ)1Z50OjuVNGA(*T1cbz+i26nzf`VgbK0o=FQfA(PZ~84X#qVW#70@B$FT+w0&Rm ztmq0e;fbiIP~6RHlGlSWHv=nDz!Ge za|ldI4I=eY>nra7E@w2Kh)NcZwA@?j=Hp_ap;`Y?kP>@qRygo2K7G7W(Q%qE1Qt9g z;|#X{82CU!`_27v9h=>ScKGpxuOFYj*;Xn3K++z`b412bb@;Uj9de}>V=BV;`a?&0 zN@k9KT3K&D_qM7@sJv{ptE+X0IL9O+^3TrRv|9P`Fgpaq8ii)#X;#j8`RZSs@h{cy z)AamM5E$1m1I9l>CI?*uaBW1!H?F~2Z@%xFJ7o~n3ffT+S-PH1##@TIu`3j}I984o z-i;QT=9>)vgm?s;A={0T3M-SLd@mrr?$ohN{;@f=9WWiM4~(}bF=F70i@tK6jnfZb%$no)6%2Z z1!1?O|8$xT36jL&uU>O1{(WV+3fCGd(e?7;+4v2BzYH<$EJcD`eh$IZG84S3Y@(y1 zUd#0#Xv`rgIr%3Lp7Ip2e)djJq&hF*rEVMd`mB<0yli<(+T8WiQbWF}+$CaeZmv;- zt_lb1?@=~6@MG@-w+k4Aq<>*p5rXeclNt zdUj&j6DU~aGKh9EYuxd-dLDVQku0Fa?utp?H#(A#zr9ToBM#dZpjv_r--pE$tSD0& zd)KY9wJ}%E@zcVsW>x2$oaGL?Uj6TnY_Wx?{})wn9aUBS{SSiy5{gPmi!>-mNrQ@r zbT^2KbV)a;fHbI-w1AX!cS!f8ySuydx34qv`96kc~R!muzQ8s2%#v+R4p7ODgb4WI zDatH{FW0b58C2AT#sfc{hx0}jZ8t|kJ2Z;&jMjPKjIgk>i8q{We5$--+?NuU1KR{F zbhuQ)!f>I#`k=nBU<{iJ^NjH9oF!z5;+5!~tKx;*n>wstg=G7`Lw%8NYe+w1fChU&fuY=Ji#k z(7nyU;+lOaV$KAy#FryYrHjEz450;v{oet@TsYMP3~s`~Shi}_^-_0*>Xhb%9DUfF zvZXj%VwUSa;~|` z3^}rgS}~fQJn7v28?tA0`#KsL8~8aA5)!(4d+R_M1_}{uZ0yIJoc)bz8XCb6oYF+$ z23b!ouU@@^;lAXW6Z4B@m4_{vpy$#t3=K654D_X?qDtg`qA`cbZYlB7u2K_u1PkRa z8d2~KjowksWCWD}UFwOuSTS7ih_hWh00q75=35a39njp#rgNY<@KF0ia(#|~j7&I% zT!3ij;64O;{>tB|4Eh3dY72CV7wp@k9&C&@{lL)P87$ED@%EqUn!Y_j!Nxr)Zz&3( z-chsM!&t7AS1T(<9K;;N0U??H#Ty|9y@z1W$;^BNr7v(2!)gHF#Bt-w@-h;Kk6_b< zgfHQ=hhY+j&nt3#=gGdu#&(W3mpA05EkY+s_Whfn|JWMd3PME&+QZ%J%sR*0MK%JykkW~$A+=A{EAvf3|E{fj3u*($+*%-@C*DyJwp4@ zXE@_vQH7dPe8$&lisJGT-p{|=wc<9rbYHl>dl&0>q^D;zgL~IHi~$c*QcBV{$t_{Y zun zs_){G_yKZkITJH9%HvGSX0%M-~vG{t!% zOe5Fg{`d33E7W&vaM#102vlPjb5&ig^Q~?fn)wU4h~=&{B%T*n%QNLok=vR zGT?3FX0L^fP4~fi;&j|?O#x*5&(hxTB!c4O?ji!06z>|cF5W;k`xg9xMO;fGZ)+e^ zW30@@%Sb6b9!ls-jW_}F)jODUL%mH#){((u#p65&0A{G1{@{&HqS8>9x6eGWhO2Z4 zZEcHyWYJqaAOrmSw$U|x(^CMa+BHhN*%v#fm2w|I0%ko3bYA)scYK?rLow+2ebYz* zSD9H&5=8J4;n{Ci57x(IBQ8rm3K(K^q{mJU!uO1s;T!9!gPw>qvhY^tSI;)a60lwC&j}UkjGC#An_5y}_ zcyVAn1)(aR-DbQ|D5K*3;UX-=W2IK;AHh0~I;AztB*O>mpz{;GhlA#0Q{%;Gcj20s z+u5`QN?*>(6q!x_`RJMrT7@EN>M^I1VdkEJh9PmJRVbP3(zP217 zaDbF0%1EB`-{BD@6yPEJOX^pgy`LMvwYT4s?rhlaHy&Kh0LBRj4m2SO3WoH9+BV{{ z(8=mVPfwn2ha2CbqrV%IGv0(>Me|~l(f#DGH;jF6cfUhDYFt|O4N9e>HTr#SdT%gF z=ED2P*~PhQ4sX6KFjG16cc<;ubmeJ?S^;CX_rRmb{I|P$ytei?fyxINH1KPIfH^LV zF21};ob$F<5AD_xqQ6V_-OS8Zh9U+#yA|pBI*-K;UPt7J)!7_|(KR%PKF@!tGe3d@ zhv0l`zw81c@)Lx8q9`j5tnpdj1H=cK8jYWrK&UOEkgERd+*z&C^(s#i+F*v3XvfbL z>(!C#AI0&R*vz}%-6G?agqi_}*#6Vpd>iKwUH5LC*%(rn3EG0^@v>7|rFor#$O5{@ zc6N3U@9zW3+kt@rnsGA9SU^Mg94IfxX}l`?Dnd8{zXE!=xk5VHLU!riswVq(tJCJMCo zif#r|_ut}%{;Rs5rC?R39$kyN16LM;ZY43G-fFQ9%Icu<420ZBv&7%q@c%B=TiW%^mBLl(-2I+zsm?iDfTx@*D#)pSHOD4OB*rUv-Riq>OYgM$lI^0+2iWF! zM>+97B7eN6%jV!U)qDT`XG%(nl*zmaI~99ykf?us!>~{6c)5;|QSDmkZh;Sl9gdx5 zObn0x(rx%8m;fRBO|Ck%y*RxQSQ-%teQg#~U6e383f!YqPGZCgXI^X{&VSL=II|kO z%H7$Y0uiAgbhIhj{;-BpOVIy0p32v{rrj z{@=lrD1Y&>V?7;MZv<8-WC5vtqM@O&ejV8&mgEY=i4g~3lWi`Px~3wf~*SfK%o=hmp~u}tb9UMJlLs)*!QR-Ih0Hd z4*l7MN05^mXLR8T*_U`njz9(=MFqxOCimxtES&RjbKwRP4`ob{XN1cr+ z#uOQz?2i71P@p>?i^Y1R(?JT5dKfmIXKS_TyD0lZvt{wdSUiZRAneE3ZEbz6;8cK$ zN-IQ(d~$MTWJvA5{~bPWXlQB*Z?=Uv)7Qx`y1^@! z{_{5t$Z@(yLWKG?_S>`P&-uT7v%_+k?t$_{7^vZ#)LJqnzIX4Po}M_UKwveJ>EBG* zE*X5EMP~EhH8Jr`AF&ov0bA0K9v=3c+9l09{l-hfh3pfHiZJCEGY;mshVUS+w2^UT$6q$e;1N|6HL^&uoW4L%toax<=GZl zG~XaDu5uX4YCC0IM^{=rbklq6baCa2+tDALpg%PqjR4)dg{z|ja8gPD7ii30udADk zmin2+@cz6%$Qoxnr}XA2XLK9)&TOAHvV)#6$#>l8U}23JR->hXG^$?LOLqWlK`jV4 z!;8*aB8lByAm$GPD|o?jwLaLvZ`*v<@A+|Op4if+1f-U zI-HRaY=JLCn?BGz_>N|?+Um4{zc4pP{ol2R4*@PeT)xo%|K(4}^8n{$ef`Ts#oswa zd9(ro?y0G%uz=IhT=$%5LHi0*-5VWKVNFfvG;uSZ@F29C;7Il-<|0SoBO&>Hbj;?u zNB`OVw{egU`lS~VX;4s5%Q0XDbarN8rq=r{g&a?c2PJV|veA>FNLQc#v;bxkwWU~u zscULJo3ySX@ChMf8nV=a!=z+(XZzCpDcB=fngZtIBJz>>C^p7}38v`;)HJk)#cIit zL}xA)JT?cUz%2?MaPRNzy#U&{tk5_Po&mv1$Al-Gx(5{wzkVglHw+#=<0HOVRP;phc-o18S-pL5 z^890(4=X;CVpk)CNO;wW25zlxy3K6PBK;afM9U__7c7@rmA)`z0y6pw(&~4r@EY{~ z@nWSRO}IKzLV}gBmcB@Pu!$iT*}Sc48LKzRRbCqYak1-f+S85gHDBt|(6F$VU}u22 zSXEv1XWwAcNGqll78ag??9wtWF|luE=1n~#D~?D>$f5zt`dQ`^5p5YUNl6YE)L~Ui zeELjrPXO|>SlQTWJ39%egsFOZ*}W^A2qDZJ1@28zc}uoCckX}yS;xQtCLG#gv&jdL zQAGbb@>Z$$#maJbCJBU8w%KWI%sxv~%rk3XTc3qE=B{%6pewU&;Vf;SL|81J0G#{K z3wz<55@$f>f_d}${@8kHI7?8H=XC-Cf*=8DDM?AyN^6VQCnziZnG!(j?q(Q6{TX1r z-ON@Wau!#!tH2P84+cP#GQ0KPF0t^M{5OU9uh`6R)D{oZv*;$Mu)g4sL~gF;7393B zUDUA&<1*>`2+c(NmO?kS`TsR`AqOH%T@TXq=SyD?J?N$8>>u*Tlx+ssNj_NS+5e~2 zfj{bjm{~+*q=BdwMB&|rjbNk??`o(o2rp7Y#9@+xdR6KN53ay^1!ZRpX=x)*z%d0% z5ISC7G|$*8d>T%`H(JH?-ZI@kAovVe6M{Ywm}>E~7j?nN2=2uTWkGib;6VW4qHxh?il_;0H&#KrYwZ z54>z*2O0047lBRRcS~H5gax2unj*?!j~RJ=;aznX7dM|EG7{uIB+#0Yj|RdyyV%ezPcsh73=Y#p*KTbXf1*yEnC@3gsB~ zm^`AJxWRWGB)oc$C|6Q!>iw43ge;v!3>Np1Ceq2oyqmnZdJX;hTX@|@7Oti)O$Ykr zTcs^0-j*>s*5wt5!-4&TSeKvFW+D#)Wb;g#eIcB_N~3svWPSe=iWNvN8B*^B(o zZCAT?+C=2YALiQp>TjEZcTZ|_>s_b@6<`CoDiH~Z!o&6s*l1Bej0y|wFD;x8U`P2L ztRR~ff;5SNLkg}c6jFj&2UbHU^^VkU1Awxi!20R4zDg&!>~L#;4~fo@`i)OhO3&i^ z`3t(00=_3`3%d*Cgu$jD(ZOnDtm7`9_P+D%7^!N3@tWwkWsBd+8Dsl_L&^%@o>Srn zLN4sEhu`=-MRFaE?4ztd+;uYF(6veFzutIbn=Said(3nAFi6K)wDs;^UNS^k1ft3O zVR#G?rvdZ@V%=cn7XxDnl+!*{PGEY#c7;j8I3sgUOiXGT; zKUswF_TI{~X=x}ANeVFg?R=JpM=a`jBqM%iB z&y$!Sgy~8E+{G3;;sxqOCgZIGrlVr7#B00%#QyyF6xz!Iv(KDy4?mGeo55J1QZDdF zAf{k%Pka=>YGeT%sp_=49UN3dM4|ecP&s=$PImv^HU@^$NS3)qkxAO24)7-D@1Q!h zxEyQ$#NVNq=Xv+VnlMi&;wO`9<7Y3FdO)3%(T7` zx0%~l6*A&GoL?+wz7#@|FabTw)+Z!YFw8K9{%%wiVaPmy20(z$;IZkuce+~ZX);{p z4pIDF)#emCJG(wZ`QcC#C1xoxMrbzNp1A@a8^@O~c=-6^oo0Q*Aq)y;cHkbIiT$Rf zjYW+~`P(}nfQFj-8U*t8WS1Pj@^<>SVGH=2sU`cuy?-Nx_F0&j1M!)Zk>0N0VBFqh zsX7qaL;NC*vK-zMlcAbVSJAy;Z)pF)YP~j;J7VkS>!((2$gV&u{Zl1~{A3+^E}qhb z2G_gH6www#23yxXgOVQ(+qSl|Wyeo$i9lJ6(EZy+(j|jF(kWEjHF2eJRd!aqbdXwI z0@Y|>BSZ$yXWg;@r7yfi#D5czp|Wh?46fPR+@#%J=)pEFq;Dr;()ZS2e(eru&g8Z2plOeUWUajvea}ndq?01 z)d!OCsg{{sPo{k-8NnZMd2t$a75!G-Ham&kLrEo%0DE5@{a&+@N`H1^@S(#8eIYxD^B1{P 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 P`3%spA!+}PE literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/MVPPythonViews/CompletePromote.png b/dev-docs/source/images/MVPPythonViews/CompletePromote.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d39047ed84736572fbea976b782d68b8e649b1 GIT binary patch literal 34043 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 b&bvjh8}FU{iPDUzxR literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/MVPPythonViews/CopyFromMainUI.png b/dev-docs/source/images/MVPPythonViews/CopyFromMainUI.png new file mode 100644 index 0000000000000000000000000000000000000000..98d3fadd4a79222fc6a8f99b5158b9521d671522 GIT binary patch literal 148409 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 P!OuNu1*z=Yy3hXy`qKLg literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/MVPPythonViews/NewFileName.png b/dev-docs/source/images/MVPPythonViews/NewFileName.png new file mode 100644 index 0000000000000000000000000000000000000000..bec43e4033a4b72563df623c03260550623a0213 GIT binary patch literal 20274 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 W7budkTRA`xJdmZC4YC^H_2l0i*_%E9 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/MVPPythonViews/NewForm.png b/dev-docs/source/images/MVPPythonViews/NewForm.png new file mode 100644 index 0000000000000000000000000000000000000000..fd2794af39b9d32259060204cd346c5afcdf60c0 GIT binary patch literal 65819 zcmb?@bySt@w(mkvLPDh*rCYi|LFtfgP`bNQX^@a^5D;+D-6`GO-QC^y!Ef(2!sS8_TjyP zQ_}97y^6vVe$&yxC%It~8ias=kdX8@6kcF)?7H z6BdY@M3E6_YVr;?oShu1toN%84UQUY`<=tyaB`{yz7Rxs?ejt~z>_Z|RTJj%e;;2% zNnw)y^&PzzubL45dH=(+*Z;rYRuiaw^3NH#>$> zqJa<5s&_dn%_aSigM*JBNvq6Ipxwyuuj{z9uX8?mMoLN=CB8OL5cI-WM^CRck;8J> zE)>q{?|HpxiCmPrr6K!@{`Vzr3Y^ul^6MUizh{H+8r%}T|NI~k=TYvDf1jw+tEND0 z-~aj)i1aOu9_oMHRqZiY$FYGhZ+}$V{XZXBSy?+HX98)WX=Ll1nEX)jL!nS=cbBu< zdHcJqC~#A&pc-K3mvc{CA2srhq=Dp}4*D?sBFC@~tf=EjDATUqt%~-o|!Q@DS>njKS{m;*$vLF`cb&bZuKefCT z>7{R9yIeeZ6342Kw85w)sI44^)tB(8Sn%oCy+kZysr86K!Cal#zDD(L%~Fa?iRzs5 zM$d;7`-dB1O6g>ZH*X^3$R!5zjM0Nbf+0@#%TH;Q3)fenESpP9CAd@gw}9aAi+mH4AX9E)fgWti1Q^ zRWHN&D%|G|QK_)v=Q1;QKHJ9ZQ7%|sjb~9&Q~6ZsKu;6J7$%tZxusodw$2@2;`#GX zLV<4$4Mb-*^ZG?%G@Z zkf=mo+!IbJb@4+k`Czubr+duwu-3!7t~&Y9c%Hy;V-`ZER_BAwsLlM-QvhSQoZ+#6 zJbZnQ&7fm!A>DF)Hd$xR6U(5TWs@1SYmL_m0CJReL@QDIW(dEKk(ushvG_~448&;Cp2>UgwJIo7knLVu_P6LMK* ziq_;c#Zp{cyfn5mk*8G}!?H1;`^7*yA8*XskI zcL@2C(NSdAyddV48H7puGdH`ZOw~5-tqYk!R+e6I$?{0H%;}cE*E;7UT;4@TFK?l^ zx6Vl1)7(+?E6&hJj<1{ zbCtsRek}-dQ)`#woS5_70RNpzg;N?$fK(qJnexWZpZ<1RL*E_p)rNn2xEEYr4P|Hx z#PmNT=Bbt*Z=ab8YSjxu6~rNwkLwBfb!G}#<||YJe#wt$j*^m+R`gm?84V2zIV$hV z1qyM;4_kkA+}D48?Ra-ERG}!rih)O`)sVztxiH*djt|OaSPJjj_}&bw#i!IF zG~zgBT`c_jDZ%d)AzQ=6u!aN4hNG8(boZ_d6vf|~0wc4bpXQSp2&Zii4_{uR5wzY; zmA++W7MC+LH>cDdl zU+>LSJZ+*@W>6~76!EVxSI{k7sB>=FM2vI-HOtS>4>Fps7}*`IbB;~DD_Gwy#pTc& zi#Jv;?~aDa+nt+#0v;N*W(geFh)qg_K%_*~mV`CQ|fzYz3S>!t|Q z=Q=ar96T*E8`5B#Emn=B(Cdl8{0f?7ByB8d2;L}s)9`QvJ&(hy7cag_qzOVs56{!R zM4TZ=m~^70BV@4N)h)7yR1*h`hdSxU})l2vB!B3+k zBDkOU-CV#Hb;U?w*1@Q#s(!IF?YaB4LqH2_%5|87o7s!p>JK#y zyR>~KB`FCL5D={38VVl!)iI~7z&rO}spGCy&Nu8H6PBNvM`)YR4F|M;YyIm%1(RjM zuRq6Td~&!y$HSmi^FdD!0}{)inWghI%;_7Bb`os%euDU`XI5dUyf8lpzJ3$ycP7NU z=9&z0Oewd=O3z4FXvEj=M{eaEf!2nGhN3zrB~=mQ{I2M?TxihW*yl^CwfaUWlX}d3 zilV4sv&1@9~~+%FD}_81{853J3&YP~S>nOA+9=K7Edd^i+KG;+6^n ziB)%FiY-r@xKb{2(s7YQ$S;gco5=8fb3x|J{C({C9#z8cP^IEXsTJ4TRm9}lv!4J= z-Ht=iYii;*$7?MU_CLzVph?);wucg=e6C%0yniPmES#2>7O!_RF)L&sBt)Zp_|tlq zgEwcd*puonD!-RNCE|b51oqG?vkN|JuOLj`hMTkH6fu7kynyO>V=wo1Vc|NbBf&Xi zV=P?UOc(x8Mu4;g{BFh0%~Xwti(sy=uk+MO+1pA^?atnEu;@?z^m(71Wzc(KnCA6V zmDLhe#NA!B+<~x1IsePMM*gn;=9@y>5JJQ%yEbu%T7^-;bj-XQp+30$8i)PPB3WH4 zTFoGhY8&#&)P&cL;L}&jDq9Yw*}AK$p%vPV*698OT%Ac=EDl_|2rj1q8w07iUInqu z&2Z12hO=aQZzt_em5$V8qK(zp8;#ETmu~bg$u{s-+j6}+UlNMAhT5Lx5D#@5sa2l7 zmzQT5i)W2K3hnt~Dq$sxu)e+?mynQUH9qnD`SX?WWF9BwlUoh{$xi$iHXRLq9#WR@wsb?zrI0CSC$OBj}wm!pri4G()A z9wIm#%t@S^O>w%d8U@)alZ$h?;nWgvS@kC;rhg3j(ZR)$(Gij@mf^R#v$f)RK-AtY z9OdXJBXL4uwb?04M@Kg}IQV&|VlOT+Ubestmn4hh^n9*XqrqnF`^C?Ke(>N`8?9Mb z3r;inp`tjOCE= z(hX|ue_89ch6ElnB#FlpMpKgy83h^f=I|T%M7g4OFp4SOs|E3#lPpY3Y44NOdXsp< zD(KydN=lZmPBwU5ZsXcf@N@WNa7*7yK`yS&WEWQA;^V7Gp3bjveuby{TSKry#F216b&7(Th-FT8k z{Z*a{qs(|L;tzu_r`;vO2{t_pi6xO?PP;lX6FHz7%pRwr?02QU0LVrTOvQJhw?iq^ zOpJ}0JbI0k3RQc8r)-Bt2Y;Hy53?GNB1lO|y?OHnRPfJj+hbtUeMu#S7kao%zP&nu zVS2wl`Lbo|bU=Vky*j~6HQ$ z%2-e?U(X<;=-xv_(f)E~=Ac!gpJ>E2_^COASFup>^Yv~uG9l;JS!rqQDudzqnye6ffYQ3h_jsHxFA*KM%oOWcQ)MKa zQfi2*F7-`KOiJ9=Xi^%T#ER2>aanA9wj0E&V4c-PU4q}mn(2`RU+SQ zfd|;Knt%{0+ZQRNUb(ayhmO7?92XaNxUu-nY_cryqeLvIVX&wU4xlc5fGWJg#cXR9 z@~_5z5l}2^P?zhxj9Dvls}i)h_}Tc(GrY=v@!7+?OtkOcLM2FMc`#oeMWeWFs7yNd z;lqc)pQ_JY91nszID!vfJxFIuC#Rc?5c?m=;f4{O zeS5v-f4UF&CI(M|EduQaq;h~4}O#|NtcSEe=+;xHxUP-@-? zP1I3iXa_;~kZ(7?bzpo&5;KwB2{i=0pic}S(>!F*v(@C(6T!ecp#^0SRs zL2%ZB0jIK+Kdu+05MJM#56{9*R9UZ_{`P;dj9qClSEE2!nPIqZR}lDOSy|rwdM{P; zDG+nYS>dh3Gnx6e{}DEPUMxTVx8?*cO7IEizuxa8`5$k$dIrfsf4QcHZ+RrsDPf&% zP9y1(w%9esJU*-sNtQ^9sD%8z>H0m2jo?1(f)X%RpCenRQe0Rt+7U*4<=QM*SD&*K zMLVG!i{99P>1i+GH-vswjva;{SAKM}yA4przrlzH9ic=CFe)aAN{*Y!REw=`Dl#a|Lh zygaks)Yc$PK!A&fbGX09!|!n`+EFmKxloG@k4m`yS1lWl24~LeejeQSV7AnruO1hN zv!a$xmZC_Lk(t>xQ)#(1UW+!z?U?@IXc>~k=^W(kk9M+qWs8K>DRWn2&&0t3`zUGM z!K2w6pBf7aYK1e(5YZ^+HI?s7OqJ==Lh3zc@H^bxryLJS22vYITr12J z3RJ>}Gc_6uFnwP%k|8ety~i2uv9F`7VKnUQSYf_>n|+S((g-abUPLx{V(dv}xrseG1Xp6Y{ui^ClXIy!o9 zUtg8e7Bi5HGE`TDC#Tj)E)@~f)Dnh;D1Ag({&l*fkEgrG?I>m?2{bV)Ms+27vz2FO zP=z!vlZT2u9w3vX3)NQSq{U88Pxr<*LM&xu?CkAV7#{h~ia;WCZBGifau~9?wax6- ztMcRt>|P+`L5WSzcH%fG~8MR?qNHtr`wp;rB)C_)u2ZnIh>#RT~-&|7Nt1^b+6 za-fq*7plUZ&$Wm4h=*keYlMT zH-5?W77qVmN-!6zkNOBjf*1fHP+-8{qLvGjuoupWHS>i7wo|Y6D=T}N$4n;zgMxs7 z4*T_M(>n~Lr>gn+0;$;w=^6P_6?x-sx0f$@cxuTeib~4h7MC(Q0EEtg3iWzsq-UUy zzL${r9?|w)zQoCTyg++kyL^XAtIP;b4IC^Yg5397D~|6Hb6ZnGaAQW zVPTo=sVX+ObNSP<^MkAOHNfTV-NO+8(x&GoB7Tj`mJX*kRkGpcd_nN)Prd6!acR$c zAOZr4`UAWl4|>rh!!o>e=|=wN!2`_(w}`*hj^Tl@K3nONA`x`x8hhy`?vKEKQGLz$|z z6i~0Q+}N9`TrDb3vuO(g%Ya~ak6OKk^#+aT4_H-?p23i~#e7X$%H54@I+{p+*A`G(2CyZ-Qx} zvB!<=L%IzF+-`A^*#nE8Eky!#+KeWD^2f6nN?U1|Y|q!Y!!u|#q+jy^q8WrqEqLc* zZ(UURz;Kq_X!TMl25S_mc~cv8QEzr{_#7}eL3Q=S1#bJ+47aOPC2acx#RHE!P^xr0 ze|}rYmkb}|cxt8J6P0Eb&n#BaF*G#vWxf~JCBc=$kBTB3 zSyno2$r<$D;iqOvUFO@0fSpn8bj6%4ohnudDKPJl#;~?dGrX|alJijeAR@xzzD_r8 zJ}C;8`sPF}~{eovLVZG9@QvzK3cBW=K=&fL-woauRxg3%e9YBp7JH+t=MFrcb7 z|DZipdDfJPuDBeo=W_lJzVQN!kI8l3ErwC;UGtNt3N!Vfu_wCiHEte;XXMQkg)2(L zE^fxjm)A@0sRgHU1{SYSzI7azRMherEh#T<&OhCNR9Wmz_a?B!rjZI4>90Hses#8+ zIaZV=)Ub7XdU&`b1lb;gdN(xO%M^rMst%ufBBgrgoL)PhtfK(O0j{a3iDa&jQs9_W z;31Uwwa+DE0;@hvzPlP3!u)dUQ@T0VGlQ9PLdjIFNE0@bVwXNO2xtem9ADmOm79!! zb#lHtmwWB%Jh70P)*|w$)WSW-N!hTs>d42(=kWf{RYSbW=I9s`i&6WV1fsHV7$N*S z-~&j+&}UemV2zrN#{%Bo#D{8n=stY&HaVbXWsQQ47!FoB zKcA&l%rZ=En5}VF-zx_Doq8mDq`PTms)kt*BWd0QY?N{|m3m7IL zm~6?!0-BAfQo~y=9XQ3h+>u&sPlMis5ODgBz6HQB*3?Vg?R|+`9G@YWe7QqeLLvnk z^*P)EndgmwA)+L*u7LBfyUwTGkES`fzq^6ExEL7EKPARMSBPQIhKYRzlj{_!lJ5%2QtyA0}S9ZA2s*h)JBoewO5C-REw?7>Mj3C?9P1&0BO)>CJFcD8E zhvht(@lF)KA;fY2nnh>SsLo_8>-`GF?tH0o`N1ZWcFo1M6!_d62cVrvp4}{D33b3t zJmIuGr~9ZOadLgO!&uRgQtt{bBw?{s!1CU0o6RI?Rqa9P0T2|RFP55bFwi(V{pcBz zCE9&ls^PDFeS8)@1-`=EU3(l&z9to39w}q;ez+tA6#epa3!Sj$R=D}e6)ukr9HVxF z-e!R8UwYI6J0}@W6(=BIZ#of#7?CAqcs}cle60)FQD!jgEPA#>Kn%)*kcbGS7(N`Ii)8p8-?5nJv1vRJSDyXZYKb}Sa#c=8b|5=v zdKRWcQE4Gd(B`t1SIe&VM$u^@dp@{Aw9Ps)dtyqRci24+X7FuoZ7mk6y&ckB18B45 zCoJ>^VnUi>pB-|avcaPfO54nWI;xPf_}<&)Y_i6jr~dlPutOkmXk#L!9 z8EuL%Vv#j*OnExjnF38#(@_LVMn-mvdCA;!LTasFZ~GG2VK9P|-@XLB!NqPT;U@#2 z&s`q<5HBGws7e~IB8~F$qsNKEi~&3}&dHgKj0|r_HW}_R)1F-A!p)lwk`lcxLFWq_ zsLR97XkJ$wBKp=`ssA=V5FS2+n55)5uI2wb3joOGuN*$+8c$7#a-Px4AWZt>mV&mqmO=tBH$ZhIT4{&cX#TXJ?B@m} zj!#+0kroyw`-+bK#)F)`o(IA3)eI^@kd0BSkr+{p6shez^#5-aFC8siK+i+yIfoj=s+jf(CkAW$YH7%RZ~;joh*$N2_s6&E=<+A>A)2*D9b^4#lpta zJk9+a63S(pvv1hG%XP_WE}5v5522E)di(nIYspkLp7%}Z1!fn_`iI6t1Od*(7sTAX zKi*=`uzFK5nH+rq=Ux<2XyR(Xl0 zVqks9&dty&9(V#E>xP83v0HuO6y-=sM+b1Y<6Gm|IM#9z;q$`hkEGe{yuP#oljhS` z{(6_J>!bto=Jb!f2^^{Xd^ON}>#&2kLdH3li%cD7$E-i-HAN) zj$P-IBR;#u+(JqpZY->INX{2cYO&cF8-Yds)ITlO^s#SSer9;{L4cTMHq($SBob<~ zb5592@AR!g={U^Z+BQ3((jrlBVP~R{S~&|Dc++Y2H>f~x3=of|$>Q|i9o-t)oi6o1 z!DcwVZIgh!dGjZd!0-#v$g^#~rH{hG>6w{;a3frutVx}#8J{t8#_bk&@imNwp6!ff z8ZO+Q?vBJ>+wUx{uV+;d9xR}dn8wiMEYh>}>cCzAMc%7%@ZNgat7O#W;ht~8az0(R z)@KciS|g5}Rw)x|#!?!0O|#P1S5{K8dKX{BI!0YwwRks@9XB8Xgjjrbi{;5cbY29c zH=L`O_NL>a_Rd&XSWZego%gWthg1jsSI@D5W{W|qL?^Wu9uBe$wGMk~E~7$#3G;46 zm(w?-#%EgW-})+C9E%^m#dwJeDDH`elctX-BT$rAi;9F^JQgaT@nd2cTZN^Zf~~n*A1kwKkfPOJ|Hj0UzAb!iCKarQFbu;l!r&1 zyUg4h>_Xdzl+<;b9A}qd&qb2!i@lZxSoq({wG`JbE;-KLxS4znN(r!4U|nR2@cF!G ztSUE+^gO)8%v2t)@PyUP=v9eJEOptdforirCEyHrxPu_A_MM=cQnp@Xe4^T1$i{Ym zhWx9}wVF)m50Fty_!iF{9C$r(gF#_gFRoXy26%9)&Yrfu#y&%?E$;OfaG5f4!nbs> zpwWu}5`%)$r{|xw1tdMF&PPC~J5S?Faag{jPeb-QhjbO_4y5O}nRYVf>YQoY*f&Q? z;WOH$egdD)rq$y}PhbBd=zUwm8Q5H}^dluTE=J{OqVv@1p8;JmMHc>(>t9jh)yc2Q~n01`uT<7Y3CB>MnB5ez=Wl8ZJLpCJw(7nr^*e{cpUb= zG$&2H+n#4J2~EfqiSS ziU1@Ua`k&4s#u={IB$OMAsH{SAoN4V69vEx$oyX}=G}o%_^G7_H15Qoxw$=Sw91#Z zm!b)*CY|TWJity1iZxW+9?fY3Ac@Oq6T#)$1^7{ul8P5n_J9QHKzl0 z+F^x)XssK%-q?zWifVBG=OY21M-rWq(xaV`qnOhvSo~%#npQo=A>YktJO{;Gt%4-X zmgtccxUDgRopZW7ues-3KrSKoR-6AB%3Y)qKR*u6rtM8Xp`?`LZw=@xP|ZsYnqUYB zcAc+xaZj+xH5`XWTYXqI`mL8&0Wie?{%WQsEwOMYu0(1IUuO(GEzq=IAHF9coGxFP zKHJf#bsz-I*T>)Ac4b}axRw7irGai_vZCpPHE8+i>FFvBHi|*!AlN_-j7rIon0(`z zVR(^_Bp+Y*#jR4qcfCJE8cipt)P5m=J_=+6E07fcY6g%jV#s(+^-u62a zD{3WVFfiW;xNS~(D#WjQoV4eVUblK`sFhT#IoRkd&Bj?0-CS&UT}Ss&E7GiazFR5r zUvseg6;p`~pklUtZp=H$m>Q5^8_9L$cy_we)8Gw{j%Z)@6&f1 zp@haG!~Tk<{wz@hT zUNg=frMzDbeRxKuxdSSQOo)unP7gYMfAM?;_S6c6v`$}*{c2yNKi^EnV0-pcKt)O4 zFh@wnGc&mzl1L|WwJbcxw!SFvELkJsbn^+-tQ~=>J1XUC`hyi>8p9~@HtJSl4+j&o zPe8qLxZKb(t1s!}h%k!rD9P5sYkGQm1L;ITRCRSfWc+@gMv81_QGM~f2m0BbX#Mjt zXcE6|jMm+??eZu!R&RXtFJ%_K-#1B_t-YgB)hyYzSKXNRIJ{ASp$?V}ZJbN@+z?On zs5MIO!JS|=juK6k>g#T|A|`R#C%nw)0M4Xl9Uos~1)>KM01Q?+r4hSxwXqaZ3BL^8 zK{NSXZaN{y#%>$Soyg!{d?k*<vKtN)mstSzj^`=5b=7cJ+roE z@j*DVH5(IuJns*Pmy~y$?oSX)Jhy#zcO;Ut(L^q-GhE~D4`;hb#OD$0xL1Q%^6Rct z|2b$3i>pH|vsKQKF?-xa<|EH+Ca0ea{_;h;I$77>T#SRSZ)$pH!e-REYb;N#-cBz@ zh()K?3cRAJ3g--(v6I^=mMh)PPtz4vQX$nNvBvilx{=O*lO7*Gg;p?B_z|jb4D3=%EvFli6Fv{Gf_fKQqXCAi;9EFQ z)tYl12*>kPq*HhoELFA#FkV@niiztXWWEr*?YRxkGe2CTv)`Va)}y4M5kIR1*yKg& z=e^j+0;v$Vd^?_jEi4?bcw)Tl`U2wvkeZ(!Z^)aEjE?@2+!_Xa9T5V`95oOCOHN=K zqkN?ij%=whf{?N6VCp>Xf+V@QsTsmah6k9mwFwA!yOP!KN}fOHKPH7+8+*h0r?DvO zOMj7PeWC)o4<%S_?`zrf-v(DAFF@$!3A0m5MI8y*qa!3>S--(`_CP<_dN_2soI|JJ=_Z^ z02%IMi$Nb^(B1jvX*^5soh$#)LX|)_y?F`KPYwFf7@`xtg? zXS8r{sJs)qy0PI8Aku74%-xjY6}3m_L>N#^K!yrt(RJC!WcZ5blfo}Cc1QvQA+^6?w#)!}gPWH}XS`5@nb9Fd^5)GG zT3T8l{)jYrlZ**2*qcn~Ty3*S#QWTTHV>Fhuat#f@y0RjiLRviui zd;)7)zAqjuK7PkaGa7m$P>c5jM8jUh4y4>qja?dhh@#DU|0E$2a2FpFkFN4Kp#Xw{ zG;bY(pYq{VkvPB}3R62*;^5VUKo} z$=wgSsKiRMFCg?INxoY_|#HBx(5}cD$Lm-5!7*jg5 z(ynV^;1@1y(4WL7vfk@Anx_Rj5y7eRa+syrQf=McL4XRM?+G-?YHI^eOn82_pVjOWaqXlp4F?Fs*56zd_v`dkKgV`D zIY(KWoi&>Ng&03ijWQ0d0x=mQe5JVtZF)){qLGl&!;sD_H!Fh`xejg;`c->9|DvH0i z*2K^?d$ma*prW?(vMaKG1?ZK=$qBN!EEnLA%x!zSDpse1J#Gs^3lt%EFrP|3AQJJr zbQa9HDwtxDZ~XCn4g!{X`@vf|JD3jEvU`PC2l$?@JUmK;+A{CnK>+Lxr&nhmbNK!N zcZ!5Ue7?k;htFe25V%T^&R9lb$J@K9VpHtBnRd6E!t87jkZD%f*b{L20rbcf&3rW) zwNHwTW$H~^Hu5#Wu z$1Z#zp+b;&{vEDaXZa4KF4KT|TDCL$^y}ea0AtMaM>py*S+GL>d=SJqtkMK$rN5vC zfwT??mWq$D{XJqs<%nVbqTHY8$2`>>F&ss1=P|UHq(e*)3FM^lrd8>>XXB8(yAz{wevk5 z0zQXeYjg?<*AT{XYc=;R4~TdSwLdt>n9QCFN*uR)JBOhRh`jTABIDg^mK0^L^DpD` z+bDRsir=!hty10I-h$5;fA{X^H1iW!*el(^&p@6YQJ4Tti+Oe6i^kcB#EA12{haG! z==JrJxBBh9a5FMVydN`>FeCUFX=sp8`c_wZe*ZRN#n28Fh!zL3|L?hr)h+pZ9Oft! zMViOVSWUd$mF?(n#+a+>-8ccYKnZ0kohN^%0s+nkTyZcsYeBhXQsuTnv=83 zD~!`0SKqO$M<-&#Tkcz%njl|U3YJ5DdzC`RY5N#7U%mFJuUXx(Z ztVe2^t97(?a8TN-wK{qgv%b#By}r7hp9q#L6~)dKn$x~|l@n9#`L6!RwLLY_MAdsf z-r1fE1z~i&Yd>I=y|`S2k$*_=5lp*}zm)j%hyTUlVzcAcSJ6H9R^!xg$e#UMm6d7VxF-R&O}?C>0fnv-MahuOZmUT(fb^CAKp zQacFyrVeMXf{;h0!GsNHTsS%LEiWfJqiLMT)X(#0Dyid~E`KF3els&KIRV;^pwPl+ zGqb4Apb|^~n8j*2jUgq~r`L!gYQa}+rds;MYGQ%7XY$H=NSs``P*Xzfaif9^fD{(J zs`#Wo8l7ep1dP{=ohPv6oIHYH)kTsfFgwg{0;Bo@Rt@A7CE*B3w2%4k!&U= zrlmh^-!*Ejy^k_7PpHZMX2=(>l z3J(w8<+1t-?%J~J?FTR0Go6Vi+%CH~psgVCQ$YZo8$HZv_ac`F3=RfKh$J9)I-lP@ zg}rh0G(CA7uX^MCJt$~7m0o?a+>jB()|>mrqFwBFeh6suhZ3EvdE#@}?6spv28TeG z)_lWco&&XYb3T{j>G2vVC)uNA2!uH?Q(|J12|41ovu78EAW8g~rUT4qS+;;cliOZF ze-Iha^7-4Rmnpnr;ex(zd(Gk&Z$Vxorck9Tbgs6zr0kbyof}M`W|dPoJ0TD3V1}h9 zq&zB4Na(V9IEHASIr}$ve)l zq@QqlR|ItiE2;>m&%9_SsjEX^aYSr{Dt)h$5}> z8}*7jvxQ>x)X85CzzwF@9MT2s816G5L?B<5VxGv6l@lW1e*J6Py`(?F7bN5+8*Dj* zo}qqPlbfvc6u@UUryzOz;-W-_+3_rh! z)I4)n!3itS_;NaVbb2t8_)#LpW@Vh-!F zMY&)1#>3UeFD)&B46Was>jk(C?@<^T6WGkX3M_g{SO7}V1=I` zS~V^1GD zl*Q01qK^D1T9+Eci5J}|^!VpoHddfdDnhcM(5`MaQzzV4f*{F<%jc%zb%K0)HsyIp z;&^)yPHQObhlU&MUC##r%azq~I4+;ZAwrB&-pkb3)RaYM^V4G)-E^*5Yh6?-f76luvD5%0KOc=NK`q}; zZ?!!rLhx_K7OWn7=W?U&{O#4FN~*&|Ddi&9DYJR9@!@e!6Xg?hnnkS5Wm@tiLv77K`gX zuOBMWhYxyWjc1!;AW(gMvESy8Mm*_A@`ZgDx746i_rk)({y-Rft3QP&b(ilS$z!VQ zU^x1|-bF6miHR;h4~*udD=&DsU7rSmL7Q|awE6bq_pQ-#eA*Z~r9^V}OczRr2M-A3 zYWb|QHC8~|<4s1o(~C<8qm0by=_wE^U)g5KwEdYSFx~lOdbwUy-bS4b3szW$87>D< znHZWNMlm%Xy z6h8UAg?dBA6^gsIru#dfPx^*D+zO@M->KGp=5M^%>Dgv8J>qkYFpi{17j0vG6QC-- z)70z@;x#(pE*EMyu2(b)tWe&4tR2rc8vn)g?Afy>;_Nx2>#b_XM| zT`L{XnERlELa2PT^$JCOjiV6Ijf`0gUtX`H)VrQP#=k7;T{1GEVqqW;HZ-&j1U4L8 zT=z5gUrL*am5->;-JOp@Cb>V!*^}~$?kPO{NQFFh0-K2_kSVWDsgvN}qsg(=*=?1q zna$UPEZm&8gW5Rbxc~DGy@WX16vAOWJE?aeg(rX-pbC%rv&>XX5lh^D*JkzSjHPD8 zoOZSnJ2GiM6Gp-R?QwCQ(;lHu zi-VNJ@1BrYc~Indqg0|7h^PZHkeqg>Dw2G_jsr=A=BG2(gkAHMDxl2ur_U;}oSn#?Ol5%$i*||McvZS3+Teg%PmrNOo2d|qz zIQh_cI*vVG4TdRo5L7x<(M6Y;Ex)PRw3H$4aWnRYju@F z>{@B5D8)ph`o>_-0N(XRVWDHfXriV(Cw6S$057q^OzK$GqTAR-U7v=!1Dl0v>BG`1kMO{OcYENln7~ z9(j$rI?(iH^zM40imH3$_yQa zRXqdy*EhPBrnyM-ki7hSYrCQiFmF{3qal7K-3usT=WnX{M$c5TfbYSpsc@Y-K&OW9`I&lf@z2(QpdEHAHB1h-PIuB_rAP*;Nj;n350!9#FehY_@ zW8vX-w{*zhfXV?hUg@HPwVqhxn$#*X3dr@f%VaL@$1Hrys2M;>t36Jz2xrKXcvOB_ zeTm6aX#@5j`g~7|KZMmX*{)y-ysUOS;CHBC&sp3vEG{Zr3`tleT{Cm8fvul>tYg+2ovX~by_1`8@pKUg+uvjI z7eU(W@qvnlzcJ~#l*8}PX9$zd3R!XKxIW(vH8rzTBrrAIVV#p%CZm8xJ0X0TJqTnm zYnQT4;4?>x3Cu!{kBj@MK;tQ@)L)pHpV{VPty}GOg#?_Obc+m%GSe}+J%XxMfMx!7 zJ5J#DIn#Z8KJDY03;)*Up6e+%3d;rJ1?TaPiGT?SQF*4A_jRv&(N_>vhE{C!B>GocE->4*QsGS$CjP?S zl`su8HZ_)Q>4|(WpY=KDl1KEb2BX@<=JfRU3Cx&@W~yKuLtfp_Td3RI%+S!^&ri6- zJTEs_qJg*H$JcjhcQ%?gP>oX`W^9Zb<9 zg26>fFp0C;8y^W|OJIt7qeb&ufzhHHRHAf)-P_7CFr?B1CNR&zw19WZ!&L1-Rl>c% z*OfxoL>ihgdJJ+wVZ9#Ysl?9tL^F@`dA);hLhTh(;RaD9ecxSKq`ig;*8RJ?mlwI3 zqU{@3PHx0u2Yeg00vqnqBFPt5bhd&me^e^1BW*m(a}*yFcwk)lbaNb&jg9U8O2_Ll zXG@@7sk86pONC(*92{I_ePU44F*-W>fhO8!`h*Td5Wp`xh|N*V{Vbn@fleWlCR3>O z`?u&+)fA?BBJ-p>Q>l}|inLT?gF6n(z9-n3VM_D~@+6)fe_BYLZq5lI92QsTcvyac z#Z1#`fu)Qohn#_cvW%09|KjS>04FuIUja{OzDK6pVzbu$(c8tI%dR(BYpy11sw8TN zjh&hGmvSY;gQl*KkeeGLB~%OR}@GLvXoI z8ZqPz3=7KuAF`02X$mrjoMCt&pttFR@zeSG8#Al9?rw4h>TWz7oWWdmY|sh%5H`|Q z2U5eZ83mp2PNP6LLN?z7lkU0tTibI20EWZh5IHR8(ycT6I`v8v239T+(SYyqeaG)? zivQ&zm}s1=?mv8bp5N$%l_0k9f&^o}r$VvdxbM zU~#^G0r&oej~TPw;b$-})xK@NgTrrvoT8=Gxn^^`y;JIPC1){P*HwiW2>@?XSFw3J zX4aSWGAKyAFzNKF@bV1|pN))O{Fvmk96QczZEG8H9DK1(ui;Z{JuJrOhi04QQl1lx z$C2_Nl_aU4!0Ov4Z)tw5u`!Cca&&&C58|@CE~hwbii%2f>VomZnQ@g?uTQY(en~>* z=xkMkgM!3kz*E(7cUNLi7YCWhqoexXC|njU`*mb#LV~M}$(P6Raf=l^*55W?k&6#P z>q!e{Do-XF?!czZRxOl@Xa1e@d-2l*5gS`M*^P;UOp@I%xsrmAu0j#vi7L;92F`NJ z4lvq}!(shuK)X)VA!(b=QML7>rR6g&G~KgldoYN8ywm~@A=n;kDG&$wD3z}ps*GCo z9?ARV-9do#m)ZnA=WmF`WjA5Pew^eo`Iw-|baSyM0pQ?daZkuMq2#GjN5%xaKuy}Q zu`v*LG#7VbFVLtbR(t^N^2ervC+}J6=G)}&BxDIS2-W)`9_}< z)B3()>B9kR61S}%@Iccuqg^<3mpWb{CXpaCVuBli6ifZDW0HL_Fz62W($7UG9K(f% z>vi(uHTcfqQ>K4k1_{C+MnN*G$1D2#)fiwVv)C>j*W}liC_lHc0%%A1&JS9Q*=pBV z2ST2sH&Y2X|M_9TbOQ5lu6NfcUzWaft{o>K3;jK9aOO*~KQa(CK$JP2+xS(Ez~?dh zf41d9m%V_1%h{etOIDw1rH7E;nj?s!o^jic%r;uI2;cKN9p>%~h=E`7GO3U!`FU}K z*g=w5Tic9AiGr7xw`ZYm)9@(U`TCT4rCo-EhK8o4#HO0Jt;VkFU~WM(v|rG9v-9Pw zj8l=z74upJ2*$lUWc>jIM;aw68Ng!y4_{vyRCU|EiwY_VqJ%Vv($d|iD2Sw_v~+hj zA|cY`1|e`H7|M~&{P*TQ5X%E@-?1|nT!$|ul4tD#j(I85+0`!@~2Ny zj*l>Z?^7_e_OAf7<^gE0Z3$6 zIs%%=axRQBexyK%A=-L%S2L)Zl!}S^%h&SqzuRMkf^JWp>tauIFopkPOhUpA;J3K8EyF4+x#BpC zUW;TrFfcOOUmtqTQDydPVkA1GSGs*{l&R2N@T-y%jXQ}kSb#3l!~mV66wO)mk%&Jr zo^cBzxgeC6mtSJf9{BdiSdk92R$pnf0s;edo3iB{k`Ct~c%{^2Isiny-_z5hmaE?V zkl7?;(;9EwV>2HXS5l1L<}ajI44Uf}8mKiV4~w9eTT>eV9-c+_46WK`y>$>_e@QnvyJ-sccKnn=ly3rod{smU7$)!dvbH zH4~y$f!LCSz5S=OJaKw~gaZXq=8&L-boc&!?WH(&)&0G+h%)xa%gZK{#gVexBFt=T z;)j!Nl!AvWH`7t>A?-dTe_bU3o^sJxFE3OLqC3AG6BJDljOaH9%j@Rp^Y1zCI$gBdrt`dv^HuuL0oy z+fd&)E*Oefv_}~IY zr)o!P<8Y_@da5pbn0{VlpKr4`G$0L|jC!@Sx%cxcy7KcA3>CCk28Xvhd3t(6D#QaI zqTe0YoyHjx?6Q4n2~M6JEk`d&mzdiNM|#Yt6t~PSwQ;uGmKaZiMP;!X!>iB755=SY zQLW=>R9Onhj6~NFIGld{4cLqG#UBN3oga%RN<~BTK#~5rLM|P>;dJFA=W_G3^NeI; ztCnkSZ|F2`ogZp@9Y`aj$f2nspBmj&E^nh#($dDEYPZPb=%Ir`Bw?BRGQh3+aV4W` zQXG`HE+X#f{Pr zy)?q%>TdnAHs(g89ZM#3$5x0l7!UX9-QOc{oOs5?5d;#l%RSgQ*_=GR4{9aPM3o9^ z4fW(ho|gCa_K<@l@yiqC1`|8Ge7S)uBUJja+4V0k&(H`s5`ZO#Jz8ab%+RCm^--~m z7AS_?u}VLb5`7vK?2hqKi-DQsDfcbi#a&IMppL;oZ14d_CKGZRwJy_7#6$?6PV(^3 zC2-=hmo@%4IrYcgoUTbG&X1>-FD6HVcot1a{y-z>CAGD+1!O4yqE3}zrD5(F6psgN zt2DM28?hc(b3ZvF{q>Ul;}t1lPP>M3j6ObybN_o=8D7$TJ6mTePvuwoyjy^Cr*$W^R9?ix`Yc(6rG zW1x4t0dC(9HJVsfRYX~AhP=|kBNcE!*;pF&1aMm$!cJE#I4>G8%_wf#FKKOkJ3l|4 zsjuP7lANy#oeL7RLN4Ao&o~|dflTg)BDsR+FOnvCM8j%sxsx{TEYpvdngvz_W89GX zJX)w%R$L~bN4~Imdf#yPxa2eotMc3IN2E@HDYmvYoO|6#f>K~%*vys}+fV!(QC0-k zu+>p6?sQ#rESK5l@qOioUV^VaIFLVAFxOrEX0|xo*S%(e{PF~4sIWx)yj#s?XX*}> zh{*bI8I{!bBoe4Vc9}V%+S!dLPJ`0CPlGYo&~e%)!l0moa|2*j&k}X@!5mpaa0}$C z)d#6EWXOpc>pJ4#;B00q0617*z@z@^)lJ`EqPb2b#%)1|w;x_38)X{`wrA($(1dfo z7~3Doa_+&_)u?mvgUfHC<<2n{Ri)Dw&)lO>BflU_I5pG|k=k|O3Y9osNLy;5x zt+T@gNDoNZ;}J?gouzDG3iVPoAJ08r~>-Zb;ac5&J|<{^RK{!>{z2dnA4gRa&|+V7|+woK#TgUmjg?cPs5=tR`J zS&Gvm?a7R!JJa>Io;-OH;?mq)|5~xF^dbbAfsQU=!%g(M$c-dCYO+l>BU7&EDI&{d zBZye8KsnM=Pp{GCBIbLp+*2}l0W1b5XKf>85BTLJwHExw}aDu zy{If6*l@by*vP;>g({2XY(w5i6%rD1RoyhSwHd>0FTiOwO-@ek<(ZxyLA__&6SJ0> zQ(n$NAJ0D5*cLt-LDSVWVIRZ9VEMZ~cbap?NuoZY?+`^=UjB{P^XUC++0^vx_FC=| z1X3?DHD$Oo`U#rv{tBrbxt2ZM$eSp8dwVmgQj%w6^(Yr+)37p*=ZaQU%7%JBSZA!A{;3}pGMRUe+6s^x1N5>Z(@E7wM|5g+o=OMHvNa0yo%eB` z^0C|lA_3CLSZr%mtJqLo2qMg4|N5l41Xdr}juvZEfktHUFup=ATMqT@X51Y_D5SVR znR45bm5YmO)iRzkeru$)pBACSoOARR9aiXk32bFTNCspyR6v1$x<18C_w$ z?xDIM{>$4KDbl~{sZG@HKF|4%q*QIr;w-`XJayxKA=o9pUti+34ClqLo8MS6HEjb8 z;8!cS3X643sa1x3*6oJyc&ti`jn`I2>lL8#X1!3l+AQX`j^#8~h&xAkNe4-W?< zv&EXJRe#INYXb9n-^c(UGlRGu3~Jff@fBOM4KsJ3M4G*VAjR7#vXFF$WOJ|z(nH?b z?!=5&-unhi?T1|}AF_2s#Sd1rhig$v4f|BbP~<3CzuO<1btbR|Lxl>vi;7PY6AwF} z<2Op|*JCl6EbNZo-rSDs*kDwFwzSA>fpW=>II(d-9sGc%d4n}&g#RD-M-#R@u~|*k z;uh@Un<^F8$7o7?^XN6xYg1)`!d6a%vw?b zXRu%L+E-~Bt2_W8i$SBxQz2iqU4ah@8kYjqxp@lnA2O(5;_8-3fIoky%h4?L$jHk_ zYHx3AxK4A=Wh8mC@SdtydHNM?)?i%VAkX!L@%cF)o|#JelHdI;_3F(VZxrk0hoq!E zCvCD^TaJ&<$IGPUMK@njM|V`Y9NyDzkMwwa9N=uU=WXFg z)_WwL^aO2lCb;gWQ?Y9Xq4pJL5;T@2&Mh2E*njbx;wL)|W&4JQwHjlJ9GsHUj8`Pv zU6+@=@mRI+@>MDpY`0b8Y=I?51PvByM-$%i$>ch00!nW2!1W<`UwZ9cs18ZI1qsCaB^aav4{?Z_ zYEkYZGnp+?Zi@qc zk;J_Iyp;pGh%x@#3{|SiaV`#|&-5~|y)>l5(=ZI=h5d&)l(V*_OcR;s1VLb_*B+pB zvEatmWF=Lf3e5oR2$q;+iga(W1TVy9y^SBvbGOj>J;LKY_w=(5`bsD2G128Q32~yG z{RZP@D80q;j^GnEI=-PdI4Cb4*7+E~i8?1`yLo~-UT(A}LT>&du8puEk=Gs-?SVpf z5W@w5dff#sx~(m^5UhD3#802;?@+)0?hvQF0B1&B6do4U-QUTSaI?5~I~3b4oFzP1 z%CMOH^Eu9Lh>4lGZB5$C26PwUl_y;7V-XY_3{k-T_h)^6MoX)~DYPDZBvRgh>iI+m zw+|EXLW`vtRHp~A)VO9>;o!>;`g!LnT{KmgoA_(UjSWnSyDn!DGz0of#@&3I#v|XQ zcBZ+B719wO3;Or5wGMK#r8v_7Qr0IKLYT-eTOTJTB&;qjMhs|PU_b=ECujeh;~~LiZpDT94|w86^&LeLfUo=Hn5d~fhwX)`$|dsm{=o=b z?)TlK`VUIwx$FNBfp-0iMExHK7WYT!>^l?qSA0oWDJgwGdeQeyRQ3#mpflXVV@ILl zRmuy7XsWSt<72bzk*xEnAZEjMIZBDxI4x%v7d{T0=hi2!?~&j-D$4p08`9e=w=o7u zVn^r%ZWWbvi?-WD*2`T|mh@Kr$5-4?UNKqjW1F3xyI1gdcVcP(2e!L<=o>@?O4j-h zO!|)@8w0yF`MPH4r{(}90-18}+1^oDDOd%(0U8IQD%BvlGw1S1sO$FFsK0>ZY0-w- z{Re4O!|927bIVAyN`-lNPor1Z@G#WhcM)*@(&9Z7OiZeKNM8c|Q)Mf*(KaW1dCH9S z#Z06=d*ZQgySMjX`XNL8H<#@XeCuWkh1I2FB5x1A zloZ41iI%4Nm#<451No+eR*=p6BSDox>F&GzYg6L~o& zR5@2{@Z56&nS_rXuU28vJ`moFPP95+g;k(lHy;*^vBIeSaWnIM%wuY#h7C^h)u95x zXNiefGF38mzEQ9AGakVIc&IW^f$WC3=J-i;2Y_RziX-@s9{KtBG;_8@4U7ms^dc2w zh%T`?y$9)NA{E`l`0SIhtE=van@(hM%2KJ);}y#No4bJ17!6y09Q%%fFAy;XWk?N& zDG~}8+^au8~phuo`W0v9UvlSHmYD zbFc^qny>0H`oGl)N%~T`+yRO6h3oDUXu=#wFkh9mM;cCLQ&8mPg-1Ys7-BQaCMEHq z-u)I5i$7Ikmy!?4o)k?@lgU#29_y9f;r{QCkqcJ>286yK5-gVKRjQmWc|eYrrKvA6 zBk)tUwl@|M2YiF7Zhe$3VnK>#Ob~(tRmc~^dhn9#)617~rDbXMJtWu+s(5c*@QLB+ z#AeYrA8kDYWjviyDU;~bt=kxL--8Q^x1kG75VXGM0Y!;IuCg~U2-CH$Vjas}t5YRZ zMn*f28N*YK!U!$tXt5K zuaQvwbd9wHMBZ-GY5~%LKHxG2X-||7=Dt^}5(I;9r17vtTT8Ue@G!y-Y1yG5Sw%_# zLLRx&oKGDWj-w-4=;U@PQ)SK=R~0)Sp*#dt-@J7F^zmg1Y6HgG+1j5!xtG@364nN& z7hI2J~{*{JIQGoOb$uQWCA+H;s z!{#n!b2FdI3H6)%Jmg3Dp!iAAugFIvu?yA{2H>3wUQI9ffDs8y4MI{TLnPoCKxuM8f5%JQXa!1Oau$Qh8w!Qs#OK7^*QFf4DZ}6?%w$%c_o^(n~q<)L_ zGZL12dvD1x!5!JUF=8IWWy*unb*~?C=O9?@UB)&)9?LgD&_m9j*$O)SU2FNoZ-#yH z*Hf_OZJLaL%NNa$*LAP2&l&GOX1vjmC3KEfzfrCG9KxdXI$P)P@bGqL=Y$3ahh*sq z|2LLZWwoTWwjW8SUK~+XqJN{Xx5*pw=$TDgKmL%R5sNCAg=c_fPZGCnS&S)U6w{Nr$1rlt&kn2qY5}0qD70;njAJ)TAb0%SsDTH@M{V#Z zo=jDKs;=f4(CfPWv9CW32`+;>yu7?f`RX;@-eS=Xf60*sE>2gc)1JTi`r)SE6deW$ zPa`0lICU;z5ppKhsE*(Czt+CCoft4M-yNrKnzH}Y2%oK%sD z{C{Ew>W{V-<`$^1IT*cQi+yknWm7*sSjep5mAaX%CI92@P_`VIx%#DCfrOnc4GuDy zKBCcQRC`yjtrkvhjs$4b-?b_KW_sm0=TjEMzg8zmJz(hq0)NIvz}Y@I>jL@G$7X6{ zKkZ4Wu1|dtTBNo5M^ZTyFH}@`n+TO)A)AaBd*8tzeP8s-QSOJ#_H=#EHt_`Op&k#c zV8}t3x1GD$%z`f&v}FMZm*4BKEQL>3#*~r9gIW-Y2=GXdGX{xtnGD6* z(OMUUxp`1k@)KH~uXcGVkg>TUhqVRXZHum*+b!u55`D7I@)|FOauiLhraUVO7~zhH zC@F%K=!RWVe6!(yqBU42sdR!7$?BD6x^Tk`W+sgmL&WA7TStY_*sIg)H+1w$g*r5l znE3tUFV9KW-HaG={FJN#)v3&vyM0i`5AelGVm)p~bYSZjO=_0PL+g!i)Wb;(a%N`~w2s zib%Gvtg`HwNd~3o-bkG*lopBG$w}d$gi@*>i-Zv1xzT*nxRG_|-jM-`{qOuo+H@Nn zrr%BDhwno(N=SnWr$Rmy_k2!CnoOd$9bNmI6`7hN_sQt zc9CY65gI!BjS&1cF6XOPafgSiuFb0yNX9~CpG#Q%g$8BsYKHVUzbx3={F zt-Ypv25$|L(f|phLjr+nEU)$LrS>Sf=w6jeEN1c*_08O=%FxOa zhqJ$%FTL+AiN1Xc-u|k|+9fHdO90M~1f4aj;~AQ+iH6hBCO1~Pc-j};N5H3~$H+6M zcgBdWX5fcG+xmOb+rN{wg}pggktr9)M;w?3D?M1j ztae0DQi#X1g@R1GD1C8*^2(g9$zRFxynE`0Zk+=wzwtOW zi6H97y|6}Hc~U{Q9}x2lG??bmUqggAlZI7q&haRB{~XSDi|yYiaK5LyypM|0?@3-* z*oa@O?}7OAFCF`lrAB?8Rjm5o($c)OSMvFskLdm^5D7Yl-9Fr41(EcH`AiC^s`(st zL+XAy_vKmZt19F!UU(0ZIshahwkAUXaw19A?Zwj4vc93NKOj2ERjx*c7T+h3K*Gd? z4i0Bf;@$(GPOqv%3p~t$)lTz&?3~WMHnE5<(5h6Ee%MPn-Moppb8Sb=BU7QNjU?a} z@CI6Y&Cj=sE!tR?yEQznaapf%%1eK|RC7)c3DjFi?`n6?h{eGs3P7N|ZP(Rw*_oLL zOrO*I(w@lHwu~*jBA11g{)Mu5>vh=zb<_HQeD}d2%97+S1z)g2BuTQkJEiSjj18 z+JavZu_b;|Z)c&OSR+|6)<*c1?6;>fYV%CPwqPw&td6lF*8PhYPfh~@BimGj52xHu z-o|>|8)H;anFT!WMr$I~76Ug+?4y(vO;EvTYld=>kOBJq!Oe*k`<&)cw!VhQ*gUz^ z+mBaTxKE!x3w@Uc9G%wkAWb`G$lTl`lksZ#)5l03PkK|Z%ip@!{yEVZ=wBWh(Qj?I zp2m~Uk_!clf<{mSwD7)QDF9B5GWiNA9^jBxN4&b|f{%)MMqy_lhL((#Ni#TJ>k5+Z z`%c7X#uD3l`d zPW1HBV@b|K5;|MIKu>`5<6O8_Vne~O9J#T%nKJ7Dl>68fwC$^*&w#mQXiFgUut#5JJwEQ*p zif&OIOGIGsE-bWwDFWZp(}fp=(Pe8h#m$pLT(Oh;?-^23k~$wu&-}ThVnJQTkqv70N%=Y%MriBp7A^}}Qyh3L@Ydj&RnbqJ_qCyby>QJ6>w)SlQ zU6%L7#n1=J4;4uHusjFqg3WZ)BVU8B z8R8GabENC|S{{(h0zRFqUXg^8Gt6Y(or{*t9^P@dW3 zIppH%a> z8yl@KF3a^&>?QSjr?d>Uxj`B60mrAeq4JOHARTS9vAc{EBXc@CrJAc zzlD81zpwzf5d~0$VZ&L+W+w!p@87qtHD2yaE}aF&w~IayxQ~i1(U19%=mG&bzNZbu zr-Jz?VoLEWN@uB8OYv(S4M+mb%`#QOdE~lu^qrB{$zuwi%o2Hk7`OhqwN@seTC*LU zwtz=~Pr2qw7W$UjKu@@{B{(aJla*D%Dxh=!Xz$l$BPtYSk`AxQkt{8X2LE4jNioRq zpH(0bJa_Ldnw;Hz$?bzbJBJ%?u-75O1zbe$vW>ssu(75BO9NXW>`WrAulE~i7ol#KKBXU z(ap`xWjU-tT)1#YAyRlLxa%Py=zB{3l>}oIDW8i+XY0e*&bMQEr!&!vKX>Om?3T*EEJMzuBIGNOrj9T#t@nwFdQ8dkEDGk9=+v}x z(rtykdQdKa&8UC~g~G(a@&5F3SsDF*Vuvzr`TfDP+ZpYyI#}VhS)^v@h-P)&CkNCw za$A7xJO+<&pec+0;4y>NXb2gkYwj(IBB9({%y@OWkGI&>0Za|hfCSJy!D6&p-F?*A zDZY2Il1y%E3hsZX8TOZlRzQV`gh$xn@IQgxFsewGRyelv%k)$YvvoHgkgg$ZItja6 zq93K181Cchthw0!pE}QuK^EdXl`@@;phOTFKZKa+ z{oDM`i1-&!>4g6!;hLNK^y)@>Itqva<{jVOg^pSOY&04F|HCDuIVa>cev220uGpEL zv)$&yp^ec0zeK5$M8})ek&$AmNSQKKm>g;Em?4Z3+MKW1*|aT_Qv-a#FE7toE!Wv} zgjwk5?_-gWbc1Hz5GwDM$>0*BEoD{C+#b1TaWd_(xCS61tGR4-KIc4#&n;T~LC59Q z%^I*D{jQb%YDr@CX8C$HJ_heuC^@CLV6|~dY!?39qeosMub;58+{C;y>FeX05f`Bx z6K}n7WO`5K!;iQV{0<%9lhbR&Unu-@sZoM>4@#HL7}j7w^xp3dSlwWW4d_pM$MSKN z>0UZZj+T-6ChK=;>d_)=TmZcX3!+a7BV#$|v&xVM^CSOu8H3ZA%X)Yt2e*WsQSQrb zD>W3wC4Z%(aAs-_$pE*?d};aoIl}h^S73PQE(NG3s-92(%co@}Y|bBizR-sbYp|>$ z1K=ewxSWS;Put1qf4aUp!sl^dg10lYF$|^*QK-2rjdt$7fVL}^U7ulrN@BS|!#Re{ zj1IJCZE3OokGtY!vRvlxCqU_}rL7GU0iGfHJwwf3wXv*)G_pRsyB7aZh0cYBA{wL1 z^+-ra(&1_Tba}2x7hVLkMv7(%Vz9y#Z+Y67QOsjsr^8Ax=~_Rg`}RGL9_P72=PoaR z7n|ed-sps!%yz$D+mx2k=$a8w%~z;5LLMk2hbI4e5jTa zb#Y}Z(HbIv@VlNL*MVuG3ynp-ke1P+d&LI|* z`05sji02kZAGDNfjQD56VGNg35fCUhq;3__%6KU!SF2^%!?OISk-=fAQvR_$03Yz>CYBlyHh8+s+5wuNb^3OBjrbUA7K&Me0Gh{r%Y}qacu{g}ve=Dfj57)=3 zC~Ms>n||KGD5BNMx`+px8YpVFIRmAz!`hE@k+T&m7P^1dKr~?}h^0X3*^KaeEN%%o zyhdIS4wkuk!Oq48m&3`)$@i4dlRq5iYz$B7fzbvBR|xwCXK$LeNI;-2LK*_V!xCfb zrp$CX(PQs>bD%g3GM#u5`EIP{8YwFIjDl*UH$`BZgd|s~K8e824vGZ}Xa@fyL_`D~ zg3F1SsZ|UHj(`((9s+hj5}3SR_DFjUdG1)gz)UUwe5xVK*xt!*%QH<^bGrWeg~12B zkkO^S>myU>w1glL91aA-p2owkpwG%7!b+H2Y2(Ab2UENjF1-DLD(dm%E{V|IW^sC! zq#*XfDo?pgXM%wfghpQhVX1XIkFqxG{1_G24zu=P7QKQ}UF9BMP?v`-=hBkZA!j=d7HZfii1-AcGRLk_|uI z%vCQ^g%qv$VNtyoo0CPU`_~8!^>v-A>>w0Qc!FlC=?kYbqs%nrS(%x$i1xWez;1h# zS(MI@nThFRQ$K}hId_?PuT<5|fmb4Hv~~W;OinuvBg&pYx-p_AAT)T4)Z?n~Z7159-mV{Bqvr4%d5T zPEH0F<2g@RBH<8L)A4He_D^S2bd1!OKhN+fEszp{X6yn%>mqMC9u(PGt?PUejR#;9)v{6s-% zP;NR7W10vpNZ8{b)BHPRu;<7%AEgPyN5BzN8(my)e}#(+CTo!*seu`HshOO^Ib#UC zEHpi!gg}=LLn*0?oyn9!Zxr;65fL@DM3>WjX1zux7_8@$?n6nOm;i&d*Z~q~>i_K- z)fI2KHQ@EYsw$yFv7iu+5$t>1>^X`VJsEx#{S!crh2S%4T>1M{J5^(upbGjRc+rI{ zJAu9bs_1*nsZM!-vis59)rIaWRdSl9cO7_4RC$_|+Pzjm0P##d0Wm?Kod03nV;;1z zJyip#%J|Q7v|?~sS_H!B1tH`AjTk3XxF6~q_BmTZl`qYw>n@ilzkeumLdRuL(`p%} z2hQ*bHM`Q8hk|aYfob>|T4ENxD*fI1nk|^Tg-a^J9beqo+*I7Fi)tsIGs~y*R?_!q z;*5`5Te$cq%C=N=Y?cAa%M-_wQ?-@xGULCSv7tGjJ0{B0c@o!Lf&m3L(IcNbp7F z`v&Rm)}yhOcxGl@a>joj87m1O;P+wG?_T^USDz0#kkTo&^l$vJm)^AApX8SW5oSQb z12Isww|eB6axd{D|L%Fysgx}7`_CVxD#&SS@~6S|1x3J$Oo|KllCrTs47r>*#{}g` z^S}XH$mqnUgD4b;aLqUoeuAnYtW%;$(Q1xh)WdFs6@5C z{STk|JD3VK$-^rHLwYy*=nn4f?VvK-Hth2{z4u1{D%y8m@_B>fp@mky8k^JXWDioa zehbitTq;TT%7Wz`CcE^ctRmj@%ZDw~Y_qTs{H=Sg)sji%#)M0jR@ys|Oy9OWypF;;sbwH~5lJhbC6l&};rAZ#vdD8{ zPd{NHzkK^0s7@THPi+$l#A8=^iRTXnU-6OK(Z}2 zOKMw*tzPf=r*q7j%WfW7;Z5G^SlM%LdOAo!H(#dz&^zZg`;)$0-dRNjPxZCS_x)D+dOoHZ?(b0nZ1=b3F_c=bTM$VCE|E0ov z=6uDqwA2fq{OU=zUL0kHsL{)34`P2O{dD#_#rv~~KhSp2w1^A{F%yjUctFhk3Q`d1 zhGG?^g7?eI+k1v7z7E*;egs+K3((5f(ROPoC{)tLT+7ek{QCvNb$%p-S*g{On<3p=4p&UsI1~0)OD>#?JuM>W6TsXe^^M_hfKETd&LK=(;NT6wI4fjA250I#|+9H6F zf$73!MqIY59?iG|u2i@LkDL9%ubJFBSIOH5Jz!KJ)EmZ5Co{E4QZZH+ZCU zBhe)ZVz9~%p!L8k0xX2>(Gq;h!}&8Wf&uw=o<(~3tLH2!9g| zZ$?042g4wS;JqzMyHJdXB5BEzwb_|Og|@TXDN%dV%dfICS)|V86bS+EL0sk!p&C1v zlieiwjp1kEZJ-&~jB9!D;KA*027TYNwizLv1Rm`QW0EY$n;|>R0>TxFo{2z^Q*dW1 z^`8TOfB%KB3JfGDUa1%al5kT}Ol)k^bPtvdj13W^PJpF~t@%h6WU4#>9}&LV*54Fj z79?yT>vm8AOch#U!8{TGwI5}@{#_2CqUT5SKb>r-1js%?GG^*i`IHjbJK$S%fJB-q z>y>n=o+JS0V&W?17TE38p`V0+qcyY~vw)!LU9lh!Puypb zASRnxB;BXlrlwtgT7tRPw%=4f4{17Z^>61EHIWrkn{+RG~~tU_)ctNqpCvvsb5`Hq6!KM-n^Myj94aUXh_t?+P6GnV`*+XqC@^rOR>cqThGgfZk!+t#9@%N;z9fO zj5OI3!rf<3ET@CvaXJH0^k6BVZL7m2BZEsdSAc>RiB^UN1~a_3LlF-QO?gBr;DXe! zvaf5mJsqxdUEUQB%`-?-4zB+AVvDLmV@Wzq<)$Ge#VEF-t!XBCUhd}yu4)2csG6Ib zMcWPB*4OXuUj4ZP)s7VNgWhT{_H7a>S#dY0Q*SmjW(~*?ogd~Xg5p41#~@SuU$+l@ zPbWVwdyyY}6U&f9cmwJ&NM6&*zc*8)#zrFFS)~dM(fNA)7XihCH{r*qnVvF|2bENk zboHRSUn;;wK}5X5(8t`Mmj3oaL6V}0oD%=t3egSnwr*M3XO`kqF^~SVfnzhw6*5$* zv7bbK%@6(ewD;W2IGMZe*bxu_7QdEX&qS)0b_ynwt_Sccfc$t~0Xl87sX7VfoWYiS zU4^TQ)1m@-|0(EwY8a#LQ!6)y9g|L%fXvWnB=^(%;_a|~Db$f;L}axa78cO0&$CcbqhR3Ftjsj-S#i5+iX!^HrL)=HK|FdS1$yP3Q z;emYmd<%BZ${cQ697M&yI?}n+Q|wL@>`4R%SiR;m&ACTxrjsY}!7%2P->S+Jx(jQt znt@Pg?`Uu7k8fky8c2Ax!)*(QUgXox5gb3?(*0tfgX7lP>dP@TP%8WV}CIAf`xuAs$LLWDyLxi zS%T>3apl*-Z!GuvDL}({zKxpoUlEkxFviX+)NlFe!aF2Wu{_oaVOxp3c8yO8ZukaQ zVO^TDrR9kgf9&40p~7sVtsc! z5E#^#8eSlgVwQWPy!ZX4IEDrXV>k>k&76-4t-6%unugmm?hE{P%<819>%rVu@vo3Ct4HDTr}{i7$$n6k{JgUIfwHat zW3S01lv|Xnn)_dY8I;dHMEJL;er&&adl$}s%#qxI;eWgU{~Ykis#Wds2wB*@q3nSl zy2g*`?B-x*^O#jG&=i_L>A>~FLgx%a->(F0xK!p(2K*jZCbxpH1-QHRkQ((5{xH=(~D%YmL3t{UhIt$1q19SN{s180TO)mc|H5(bHbNU9Ex z=Ij2e1*o%lU~79weqO#a*>*EJt-S|`ogzAum#McOz=UiJ5Nd+KCTdF2i%s=nzO>ukhCejwd*nSt*r;QO9}}d?UCf`RQ)H&ti_hh#3kUVF=Gip3036T>6jU zJ`#p`NTBSt>bU066MXXMOkN_9>l37F|8ttcxD_THY8YFdq8LmvbI5f}$~Qaa|Bzs? zO#f<IZRxYe5*P)0#6BF(SWCNwL#2v zA-zh}mFxMg`_VQp!}=M2>g1VOXq?WPbS~{_@50)DFh%U!A+OPtM!~NRBGc-2{(MYXyDhe(sdCJ3HOny}Bb* zNH2d+5f^52alH`lbS0>JpG@}o4y5;^yl`^jalbm`1Yy{d)n*A7*X;fZMRONdSELWM zI;iz|Dm^3D=LwNH?i3&b4fa9P99+2`XdbT<<3xgpkYB6sQ<1nVcAr2z&EkAohum>q z^S4j8$}H0|GD^(;+=hMClsEfveJEe;+i_3hC?3oMF*-RbwC+&{ys|h_^xZqHX-{ut z7>eGSD9txHxjI@$Ow3zK#m`S%e`dajS05gZC7a%Z{PBF7-=s&J?ePUyJjlZyLPU5m z&T~{QH=^faVlbWKZL&Il**SJC>#i$wDE<`{xb@e2RLgqH0i@^b+En6=jiWID#~_S@ z+bzxgMQXf!{QRTEri9@5OR4p}^T*fqHH>|~aTon(2S~t1Yup913=JU{sJ}*EilDB~ z19%2&Mn2Cy?Rub?7dKp=@67%BCFCnACMJ|7V|lizblaUPzz2Pu)wNv*F5s?&)BA-* z<>_J>K`)xw272mF!r&TU)*Gb$uB|l+!?Qr3$W3XHm6a86VS?s|>UU9V@yV`wIoEI| zJS?vLBKh$nY@5$(vaFceu0yGb)2ZK6@h|3>`1mJd&!)&E%1CcY2u7Uu*-&Ven$Y;r8j{@N~(A z#7{c|74YFWjl7~2Pj8N3!5lGA-S08%_-U{8Z=TsRLW+)dM{;~&dHL;+9YKjO;mhbm z?iq;x$_U+7AZh)A&7A~bjMx&rJy0TY@p8YPsvrPiknT#-Pr4J!$A{~~D4^)^fw1e@ z59w^o%*WuN_~E=F2}Zl<)tK{AqhV|qPF&j#$z>4F-t2P7u1-QSn7a)z>Auj@J&cD* zJs`n~qEqRvO@6FtqT?ksL<{ll)HALMIYW(9TYCDQNLf zq=iK;M<&)|feP<GIfe@Eq2Mm=vCJ6K`v5x03j%-@`n+Olh5O+o&b z;ovd-?Qf+&iQ#t>q4P=Z#`K(?9|sz+5u9NVy#Jmd#RJ1ehh+iRAg9+r& zMbH5XyYZpPhKq=Rla&V$8_`zRzVVN(FklXxF=+U9Je>-;At>3#^P}blGx_vLGZKmIu23Hg;m~K!>?)Ui$l^M6n$jHR-neqTX0r);1G_B<(Q_a_P z_#OHD&a0y-w*(ngg5F65qZ_+5Wtk|+$jWBP7yObvKO3stb742D?JmQ(gV7&EDS*)a z9gS!(v9R2n1w_ndYY0(G_SdPY)Sb<{b2no^+-K*fKO&j36B_zL5s>j3mJs%P&=1Q1 z}G5pq$D|h=xMn-sC+`R@)4OgXai}V}(p8^)L z294MePUPK&W1HdQp>nS<&--|R5gBIp( zy<$-Rg8GX;j6_^o%aWKzT0c22vDoWTt#Knx&XzA5c`l#(?chV60v5K75GG=vMvrh9 z7ujod=)S>!++3hQf5mGLhI)ILS>gm&MQib!`&sXQI@N8kFgdWH-@P*cYFGoK7TYLrB%Aav_qj-Q4TRZGDrB=)PUS&=7Lz{!g5EeSl1JfuDY=6A} z@FB*o=FBNDetq)(gE|SF*T`)&G=qo7f8aYq+B!?mc)zx$X=LQ79m^t@Esdxo3`9_^ zVVsCAfVl5w{jetQ2P3fr={qTi+`4rmQ-d*80t9(+oW{*FDixMX?edAp-DK8OeN^_? z?A_wjYHF%Cq%(3LxD`$=IApA#=$|KTTv(DPnaP&tzMOHlS?v!jH!n}O&IlSmMx&PA zzm1=&1QV-a_#$+FZzUvje|>MFQ!bWMq1@P<1DQ-hN93QJTB;d$PCv-fI`~x>46j~0 zmQA5?y>nnv<2_x41@f@SQ_E?-3*({JQc?vk_V~X9xBQl|S5DVmJ~%mXNZim1zU1$8 zBDx%%85s#Bw}8CZ1acVb$`_cFL{cXpaB_Acoo0oDI1Ou#H&Y;cZhXzisEl&vFg8vP z21@t#T-pb|S&rj{j>q)ovCh+P(cDiD=y(|kbj(_I;GA`Js!Ox(foHnqd*(?=x@&+H zUTe_mP>-0|{_GpE5di4E+3;Mb#|p zy#|9ooR=8<;&?&|4KEVNmoh41AZjDWPxJuu8yt?|k6zYjzh5aKB^StqlX zpV-XD$yLT!(!`8ODNwOYNih#e+Q&J5=Q0Xns! zu;Ur}(PfrpJ-x{)tZZv~4vq&%@FgT}Fdy&8j{myx;@taFne9>N=!j_B1eN?^H03I zh&IH;#0G|)|Bf;v@$pUCw*SzN5|xx(Zb9VUhC{H8`q~}t@Ky5gL?K_-LT+k8I}gkYOxmjR_NHLy?ncAs`;zRY{{6BhN7grs1_KMrI-m%4C+Lg= z0WCEyAV$CYLPLX83Iijt_{OJ}vfx|6$uF|x=C{|Q>Nyv1D4rqKr)TTigopE%oMw}~ z+g5k+Nq-C(u_JX$N|qXhT0WR0JlrU`?$z{h;UmJ}RLq~LjMa99v^_nTh4}i72$sV> zHcoB(f$*)VLmg5Vwg6>zBSb=gr`hy(je;aD9zBz%eHHo`Zb~IV)8@w+-zzHYghKmL zh4qX#L?dYxW_$az(Fpet5kkLOdqZ|8B|mm%z7IINaJShSi|27G`%>ke+z_7efzO=* zTrWC}BBXm=UVeYKuOD2o8(W>WM|#!;j&Vgl_k{}r&hAtj!#k>Ksz@i6(=Gto{*Gn6 zUgEu)L|eV)h_5hRDPgQnKh0Nr{aV;^y;Es@=x9VT$K}15uh;JMEJmh!9sz{htJb>U zzo?l@eRUzz7{sFL`nRw= zP6g@vkIsD|B4E0d#?G!B#Wh}o#yhDY@N{1c+5(ncl;nxMro*oy+C_0X}pDHp#! zSB1r3uZRmow6FUzCu`5VrVJ)zZhdo|D0gsnd)*fbMM7wrT$YT>c}cop_T_*Rk$SGkhqP6cQIX)aLMS5DU%~?3n8#~ zYwUyT_?>sJoOg6p;^qE~L_;&Ft)tVp`sk12Mjpwy^D|$Jmad^d$mO=C+vTz~KHsyO zsRQrRQkLu5L=9(AktGqAO$=xswt@n|=(LnkW&NSVjQA6k)IUO8o3-4)9HDbNXu^su z2PlJ(k)>OD5NeQ;^$PZ$qx72`930~D7sUQibea=Ei5KNY6wd_DLJ)B^Fe)jI-O%&> zGC_GpQ!=5xzW(rac^r7)9zArpIU&P=M#|%*&ObxD>r{~OJ|kx@PazT}5kJDm3G}z- z_Q4>2wWH2|gNc>3g^!H6r^itRd@V4K0R|clz^ugE^~d?$1kLMp0(5bL(T?}sv^t|T z;PBl2yZcS{+-{sDiG*Zx@~3axKze9M$QNsFDv*kcr9fc zu|Y#$A6m${4s26cwoL_*Q2TMrW)Ly&Dk!)<5jZGe!TE;aV7_}NfIuLDr|i<2E|#3zbg zW!dTanAOjOC;mVVO^twPdyDa}^=wjeL$61~B6h!A`s>K{%Ly^E#*P$gcC6}?m_>)4 z=H~P-seNTOr&fABDh#!`hu6r0JR1{D_L>e|BDbgXSh#*KvNOw2VUD5)g(k(4g(%ndhv~+iO!#gkc zeSgpM``*~cvH$Smy3SbVI@g+W%rVDUT<;Y$gyzBcD#tHd3A{x*hbBnyIPTW}ezCo7 zb|((chRudl&%%nwVvcHUB)4<(^EkkV!S2=04J|FPR$;X+OYXPH(WQ_F4HeVk$J6pGm%u`Ap*n-yTor43dw)5@z?d?{@ zB*U(x&B;_WIclkImD>Zo+A`Tg1iYNEbD1s$?jQ*=DhrvY5N_A;da9I|Eb(SMAt!e@ zvEC?ibavcZ4VZ;RhYh$$jg5^+xB1-Tp*Ia-btiK78vj}aYSvs$-9v{lXXHMP&uZpv zrOuakm-kMFoSq<_t4f(!LrlGHe)mE92ii!w@S167jMgr7g!QIhRW^gA-S#a{?*x9{ zV!$c${mA5pW3igEn%w>Blrk>KI02rYg`eukyr*2G z&s~SsH1~s7+vPUP%%(+3=-;hOm0%!gEOzcM3tqp!XcikQF>hk3%T1QdRZ&tNiG>%q(67BZgyF=9PmG6uf zwT(3kXUXfBn}-Ay74u<}E7q-PReIad;@=`xhs9u({To7N7c~; zDWR4+U&(HUv=26ikGYqCTV!gF9mINtrMKN=+^~gi%T!Z2fm!`7pST{11L#!#P{_md z%=G7ljEG!4SA=Q*bKN&0E-)_Rj<9nzQ8x)W%hE^x@r|XTqH=Hgbicf+V)5i|ENHcZ zTu9e`v}farKUT`h!clUqq8-BpfA{-RjyZQ7!WY{2m7QrnR_z+|EXs?&9`U3O_10FX zT^FIVaogNKzhgY{NkV5J5dYJp`^kjcPfl6ZT3zLl4t%DAVFFMMgy+erfrFjMd0WQSdE{rx#~?bnE6myVJE_7=5`rJ^kdP3JRkM35Oj5i{X#K2u zFJ)d%*<(p2B_lsr$85a+Ajh)RYyFOo!0XQWA*U*$B$4UIT#2WLzN_u-cr*lVf9D~n zF3X%=jd-+vB01O?En=Q;H-Pv+Nm*sD?>G6YF$?XERbp;(4F}MrPuA~@teCpKl%R;~ zSz3N;cK6=#k+;x`3Qdrs$khCU7-}V6J`a4#?t7iK?M29~AdSxrK2xiFwQGu@k$v}Bty-l$IwDj0mv)zl%M#M{^2HA>Ku z-WKfrn?L99^jjdm#l03P>dc~T*C%gKQ~HdwY}s6LB;QR0NhW`ax_O^8gKZ^B^>oYO zkz4wQhQl{9olTe+IJn7u?HA76vT@wYgFVrA%TD!w(p2@fyse0*<6NQ_O8Khn^v?&b z>aMIU1HS^VuQ)GuC8lxn!i+i}c0|c7n^4>Cvb66ehJ;9Bi&FYHlDrZ%ye{LVDP$92 z`TcN*$cDT*dwbWWkuT?vg=KJlW7CJYGZ90Y`bwLS^hkubE}?Bsoj`1=cK;U6ac zI1`0BJ0bm=lAeWMwWg$#fGtg*Kxb}1$%E>{xJ)}dfR%6-w*IE9aPsq~&4o*Exj7B! z{Yq%>dZs6T6`M?8c}u5MdrW$rSS2lbEqjn_obFZ=8b=V(8B@3@&mM=8YQ33S67%ut zJ4V|pz0;Hu)b4C$n-go|&f_V{$C6FgJQ1nRF``v?%fp{Svk7QEkp8@SO?5Bwmg{(T zjCDHZ>9QWX|I=T6-%=h=x-nwx&4Zpc`JOyQ#@kwP9o>2ENAEF_Fl_d9K8f7kWwkEt zd2OA7Q%LhlSqG=TplFchi9iBQ8IBWKIZi_3)VGUZSp&Rd=DQ37!5$AP2Mfum=mXn% zw~&7xJEPcDKQWSR_z;BsMJaa8W@*W7SYJx);#^3i(a7T4d4iUUCIcMv)TbUgu%1zav4+!Y z6vbvlP1+KuyUFIN^zu1xCuRXvcmPc0Ivc@xVhPi*jW{p-tcO(T#>_18*1T(@Bia1z z6H1}ycL)xjjp567s3mnb)!24~vnqax&zr6HJ!k)+<6Dz1z}x$)kTQydrgIGc!Gj3l z7t|!pRB6eX^510XX%#!L(uEqBy!q`q_#97Y3*MQsO9N2XGZoxxg`QsKjg9`#&Twio z*JJgj!=L`#eS5{$kJ`_iQck}7eGqq>a%fCn(G2Yc_ zsIQG=t4?UcU9ckVf-pfy_G4^^zU0YzW9sVXp-%i=WnNLvo5I@WdA;2M@eZSmv@UY| z9ZE#jEL6HT=%2ll{9WU3hWR_;D}KZ?ij&K{_x73rsR{YGWb90mcy$k3uB`lf>d z(nj>Um%o?&5u5gq!=`kdS|e+f$%4>%xScVUxJR>X{q-%lx|H(jgFEpMu~-Ze{;_6_ zz2~0(-HtqRKBo1iT8ISs6Kdb95R%stQp=%5Ry_G~0!=>*(oqDAjQmAV>ykR6m+%M^ zg5$hd&Mm2yc%1Di*aLBrwdH?uXo-+1jwuvqUD8delX_Er-L+;HN%tu>ys@$*W4ju(7r<4p`L-$lP(X6jcmuGM-_z5|Z{zbdr%(UM> z%>LB+HaUky6Wl0gO1LdVsC0F{H8)btkCZ0Yer-w2xUktpwrV$F_e`pKCPrt{NS0Qx zEz)B;TgbWp7U^Eha(zS*hhBHXZHrcYiDWe*tnTo{rxKfLk#2bNZ|QJPDx-hSt3C1e zCfj?(fM(%CgM*tS{z_CAX=|!CQ7iX;@KRM-e9WJQFYt9R{%gvX=&8C`Ty z=b01my&)Pf6nkssPvLX#8Jg5>nTb7@dum>yGuA3Aj6PWTg_^Cs*#G4M;4(xG6zI}G zBUhrv2?4IHc!J2wz&BG!Pb3ZkJ~71~nmzXY&$v=~;Rpp}epk=Dmyu!MJJynYmh9f6 zx>!zp_PJC0zEvS-eQGhw`aRKy4oV11#=ysj7eSB5YVQUhI|IeWY|tvIRAK#$QuLD! zq!HDZ_Nzi{=C_gdzFWm z$P9XAU?5hCV>>mqP{5pmUR<=1=Z^>mgbG%|`eJ;1KuE~^RE-N24UMU0=8OIQ&^cq> zp#{=)V7x2u3{U{8{Pnz_rIwCPBS4>^B!h@}`JB~B?O*@|Oir&6K_?bd0UoojtanWU z31H`=9g+0!KDOh~@E!4V>xOD-DEBQ!*1r-JW%HPoMl_pqsh0F>;=_ZX`^rG^S15;3>q=LDA{EK<@J%A%s+jwe3JQ&LodL+lz? z$7Q*67V?j*tX!5tIy!%)T~kN@*Edm2MUJbiprzRGMYpw_=#gJp6yBxtalce(H8=>a zb6P-ic93Ivm9~yq%BHE*A=|i$_cx~v)EPixVQA9;JJJcIymE zgngh6%}#i?E?2!3bZiLtcKClk2e-|#mqJFv#dk#f{J_!n%e%U(j-5~e3P#2d$o;j< z^n~+CC&k32sQ=kDr;-qTQ;l9&2}@eb{SV!!|ifDzmD7S9LY^*u6RAXu6s0pSJayINgFv@ z6DEuBqToU6TSJrR$y`xi`0>FF)&~umBYE?=Ta)1D`y2|P(1@>VrWbB{jxcuxilESW zwUoI>>E=XCpM?Qtu1e`QFc?OfK)+|uS-J^@4De*_oczh0A$=vqOJS&Q+zypw8@2pQ zg>2Bi&Ev%GJaltT*>?IBt*H5O+izCB^vRXGJCdVQ#K_cmfhku6z5F-bb9*Eh@dCSZ zd#MDTkSIl`{(*tr{C60@$3SxZ@h)sZ67hhA0v>Gm=6IR*e+uXq9 zBao!$>rVZ`GNo;Hert1H?b2MHA2s9~benBnR2ncsCkBF349Z0|OB>2i6!laY-Urz!i8++{__?_`)|;ll{Ep@^rV#x^sz0FV zQM4N>h|g+-C8gh~qhls&Q zKxEg+8eK1@DspfK@=#sOZb&7Z{^=Qh_;GSK0m@? zn)NPKq|{mz1!ZNTmLL9v{C-(#B~>XYV79%SxHBBOm%TtRcJraQq*T6>1gPJh7+l;q z+8P%H#(d$g)VH+7=HJ=E#`$!8_|BozOMKs;+i2oDHgHGuN4EG6wnw6@r54L=Pg#3< zdPct%<~Y~XRPP+^H3EqC=&IW13{;$EW;~Ftfi}tw zf1mfWbFb(XzCSN&2~n;%Q>=VUtz&BXMo*8*p=qnHLKh7IJw3EV#ltg%s(uA7aWE8z zD{{PwD0dd_bcE9ZmJOyrmLt>=p*oIcD)YKl@3Iwefz$zYkr$x)@HR{S2J!vDz;iLs z?UacsynHP!y$tk>!K}^Dk`j(_hmHF2PK*fgU%o+j z(8$pWJ;lQff7goJGD0<Ff|uvS;{@DVNB{vF&dw$69=y+Vns2$N(GS`p zEN>0#YMtv>%))ik%jZhhr7 zxY!`JE{T|aTZ`#L*s{J^eoHb8b~@zX=T892{{!dary0~4;K!T<72j`tMn4M*W`lY~ z_D2Ncl#6W%V1b5;DN2Z6n*aSk*vUsq)*Z3PLbHq5po(%EY){4he>3-A1ckj$xAmS1 zUuoD}HZ|yZS8+<;mMOO1nh@)ZWVETdK93RROpxpnl|&Q?JgmIbtvTFOz*$l=@c_Sp zH^&PRu>EI!6Z%Vh`1>*W|N1zk{tk#9FJn;N`*#WP!IGAlxsj(_WZ;YKk2S|pX3!n$ z8Zpi{k^PwxLQadZo?6)na)`%j>4JEX{`;F#N<^gh_e|kfi1gy`RSDlA|6d>9oN5+^ zCCY#>#7{dZnCZZtc*Fekr0GgYB^uXR_3w|BKR)r|b-3aKqTpQJ{xVPu0Q>6yF7whv zAzwot&f1ItT(qwh7z%s4{+D2w#Q1N>vKveL^@hcy-(9mm2WY?*n$NYEg!-{swQb-) zX756DeHIk^JcW|mil#0iafGVff%uW?S9jjHK4iq+6S`z>v0q*V# z-NB8m<}5k0i+Sl5k9`i@>Y9>~ICcvkmDF|xfyW#X0+-X;8&R4-SXks+zq06%r+0Qi zs5jw}mSG7kENbgKXrUGX+Qvew69aS>7fKK!_?LO9pSXxvA@K0f zo~x)3A}Qu+Jm%oQZBy!;Tc3aF=*aCL^s*#BC?sSNUUVpu3~TJ~?KKWIFZdpTli?o4 z0G%&9FBy3_TTwyjt$&_wy+~XH)W4_J8_h27vecsHs6ae@t}FsNmu6A+@fe5c9N4&{ zQT^|mCP^o;637`YFW*&%5{vMEF3nd+at4%~3K-vg1SO}LbvecnYqGl}jiN98k(?}b zKx0iemfa%9O#q5Wqc9P6`#(b=74FJ6_w7hMs2xqMjzraQTFyGZeOr1SOKcCBT)0x74Uje1zIj|X-g|MI{Nv!f*hIB& zHpC$0zev9R-4wB*_6sLCJKB;QqJIaZO|0yZoSXGclOf;_uFsG!PixdyeCN@lN7A`f zCJ`Os_OzFcx{rhcmJgX(?s!&dWB(!!{Cl9sa3Fmka@>|yW*=H2Z;$n;~Oa;#^U_>mLYytAFzmt6K*Jnf~^Y>rkxBt6V zV5Ru{ua5&L#t|=zaKonH`_CT7TZ?T4NE2%6JK4%%Ta%SK78ZGOunWUZ1=WCx;lrN# zWAJ{;IdZBf`~*D)(GJtAp%D@9k`HI~3mn@YEIm~V-*lc%l>Rs*Buzb&Ri}pQ3hvPY zcM&u?Xva7HQ~g-5Ct3tJG5a}X#;Ja`+he#PBHi9-yE#{zT(wt6)J29p&$C<)Y4pPj z3k>GUrq|SpfRO765_l={ONmH`l#K}$F$Qywiyfxjhb{iJtu1y!WqU+pd$0git~RN~ zK`x_EYbzdwMjbMz?}}xgj+~6q(9Y@v1E7~CK0aPU>4J$t4o5EGO3-3sL=)GF9r3a? z)SPLSp_2>WNrflz%!PBiX1`Qw@0OO9R{c5ZH04aQ7zzq1LYDJxT-lA8d70GR-R$nj z-0{81$btfFBr!1pv{2DkuUMScj;lwLDYr3Qlc4t$HUp&Bz?xZ3f3rH6%L~=B*#Q>a za@W(s(!6;ZDdxR_K6dk=*igSvEg*r6xgfU2*8I{^5>MZtM}6t7sz{JRM1o`m4i$mSC^9}l`tl4{xY=>3oK>GJT5~VoTSy%)DZW0N&XVj zjk&7b`IUivM(}fLo^m@!QmWN?Oyqv;9V$rN5xkxGc6^%54HXp$I#N1Z$S~7YhUmMZ zd2V{tsbHS#J*=|dZg;55SF7s@Hy(f(krAiG-5aDD(e9Jzth7>oSFYh1$dt&CY4U@9 zW~BG)!;ELuY@YNH^lbCzbSDbgEuP0{HXtUeHvamx#EjB&&z>X@BFJnh1=1|F)M;W5 z2`{T%Kh@W-VW)ZrM!=Qan-qj0n0xh^E*x;6uXjS*@J9=Zi@QoBK!>rM#F_}|ZPgu7 zz12%TWn~VDcKJ$|3=9g_Kio8?CPP-`GE?&Nd!fbib_GsHK7*o`UN{SDndLPyr{$!0 zSW8HS)A}RW2oSRW;FgqRGE{tc!EGsU>0I;6^Xd}$`_}p!h{`};6O?B&PPfj(#c)b4 z+kZIJkGrjoKyw{L++!~5To!44M0XuCug8%<#y;>DSUZCbi?i)^r0%6m9}DK$`{ZR%M0oOd-`m`TM&};T zuZf*a3Qhry@4;-v`)&~*L5=aLT4fgyUx%F3?KCwbb5*)QAZedOQ(^8l*b~$*W{=?W zIKKU)->Y8Umc?ecyE{N)1yq1Y(@UU8UDO!s*3NqcOX>&-ZL>O!VM4~4Y{SILTKL=! zv8MOF`FEcF85@%woB9NgS*}Rr?&cwwzlyk@5dZ~dz77M=@i^h?W*)C84h~Ey1SxEpqo0`D zoUd}KR1I=#Iya4OfCj=?iN&w+m{gmw^%%J)nh&9`5=rDPnTWZdV1f(0c<#yOh>Mh# zTQQw!aXozu!#)df(z7Yef;GI#x=z~%_ph_teW~@S=tC^LwYSPWzdqNtmbS+ zUJJW5jjvDxO_QL(ZsFn$G&Ixv@$qrF5^;T?i=ohnwwhJZ{TNzvEklq8%?4?p9Wp$j zik0)Gm7Nti*dVB?s)GD$i3cA)UvYj>ad8@m7UrnbVp3ARM9AI2O9TYHcmW%c%#iDz zgw*OPBG|yjsAw~gQmqUO3?Oa-tGFTJZN;4<>IErU4Gj&R-AE8|m^NQ{%;3e&%9!O?Bd!2xNx%zw_@yb3^^~bkf+>6$tGHGSy!BU0t353APdVr3IyhDIne)!z=qC zOimdS>yQ6Sf~!>{Gjnr@j_9MFsxJY`62rBQhSU+o6e^pgw^?a7cy#=i zq+exuEvI|2<9+{RZQSb5_~`uXtQ15>R#sNFYk$6guw#MsVZKBHXF?=nY*=Dq&n^y) z(NN0Gt*tHTTwbQgN0Gp@|9M^i!er=2`|k#C{M}VUrD)Z+B__DA_aPk8Qw2|NxVc>} zo4kSToHl@B)VF_VGzMO9EXRxTp2KOb%NG@e`Zfuqau2&CBx5-BS%IhL=&TK2rf_z4 z4koyyg9Wjvdq#`eLoj4|I4>Otie}g6(zg!QJA=s#zQjiQfidQ^`{_+lRFsp|<;QAO z_WaYEm@Cs{{OP1Y9vUCS({;8s$i6Ez#H|Wm)Ei!(e*jvyww@m5bLYxf!K<^N`~IPN zAQgE4BKV|}tehCeCnBgz-Dh69$X>xGw(J0!>F-`tjL9?>e)@E=b18q1jK8HkaN6o{ zjAN|WHG zXMlP@G(y%4I_JUS$uac>>e2BRLQvn!S@YD=95VUUaT-~rC5 z8<5+Q_+A12QY$dD(pQq*Q|Wh!cJHU#@>6Jz+C9$x<@M4(Yje5Pvum;qIHNshAw(6< z{I`MU2VH0xlcQ$;Q_qH;lK#wV-eBS*Y-r!mA4u|eU^{;+okZN`VnJ+RTi|-t$uVh~v_O4{(Lm`lF%@X@=h}P^H!Dj^!ve8)Y3iuS*is8yFSl zyx;4hCzjgByb-nwt-K<4J-B)ceGwn%9?3!~Vq@SgM|&uUpi56&_>M3(uV-v-Fxci9 z2;q^15pR$G`SZ|97@|lS&?l_zz#V<|o@Bg?hL82@B^uj3dvzcXOld4;?KVFX1;V{V zET3=Dbwa9TejsONN$EGgx!C>Z4$hrUUBklGn~B_k(8|hR<&deFuVFS?>pkhh+QVAu#_O{?E!omA zmH1-2CMYhB0f1J%Ya$4BZ+?4A`8+lg;m9NNv7PZsJIM4OIL=W4FG9a` zH4HM6rM1KLu2XI5bP{6EVD$l*TOT~@=b`y9>agxw3R0xisS*Yx_YxB;;9;4Q0Pi6c zR01Hvyor>*w|KgrSU4w{mf${C>vu%{+&_zzccJi?Kelg<&;Hl-F3YW zKoJ>%sybRC_i44|mw!WWp@pp1q1Z+vOOmB#(>=#*9`$7^CB*jyYwQ^Cc~w=-Ax^Y3 z6g5V3`Cy4AcbUut$<*ptmTumr+I@5iXcntH9-dU;nIq_3FDNP*$g?STr@Xzrw-{tM znTR#_3ux5_R~HoA}^Gqf)(=dEsq1Lwd zza%0Vu6BrNT!2B1GWc1;Gq=(gi>Zt;?)pV)-%q36-gs`S4>c~=H~(3keR&{HANf?Z zp~hwQ;%wZ+peNo}CE-(g`a2d;L~0T+^6pEnS0|z+;g4@L`QWxgoBh>|}eQ0;P52$14nq)Kp~iz>>5>zugY@vPy+!&ombKPtSs` z!Q2xKA&|7XKdhQFdBO`D+CR)Y+_;(2J;|<(v2->- zmbwzTLeo$ZXLT(td($jiLGSO^U<}*oJ`g=QS)FAj@q`{0I3E)Iw4By}ou&fk!B^cF z`iShE?K&4$15}^M$8!Y)C~$!g>}UNRsh3P(U(M22U{p`ppXlleMg}!HNQa3#86Kj8 zIdcA_3@bx{3mD=_x$;=+eadH&t7M;V72t_7zRb@q3FURzh&JDx*wH3i<#VvJTiovz z5&Y_G}_+Q#v5BHgf!<>&8m#1Cr@MELNTU7KI~h2pmlWhj+tTTw!b?B_+ya&jOPDFgni=0x&;5GW0+ul2Z}Ws|=t4`hIKS#kMG zz_7GH=hpD-AO>+&a6aKYjY@Uezo&+SFGwK5(!a|DEjc=$Zy~J2{~}=^P*YC%_YaPz z?S$Oq%?yYY+->-4CLUt8_|U%4Lr?$vcPycBELId6AIEf9?U$~YOUs-7J>Wycr~iKC zu@53_|9d7Gp@*XnJ2ZxJcaGVcMu!8=1C4L^^6RZ8({8n7uHH)XvAt`={t7qdzsJV( z6+p?9ZFC?ZULC6c^v8$&N&x#;h3cJfCf%<4HR?MIrfH0-Jwm^dnyOdSCx85GLTt2f z+JFa{zeQ*M53<ec5Y~3GO3{@ z&4S~#nj`D({ehjITyrOz!jHDmQMIN|&n3=zeG>4<{{MexW{&jSR>(O||No%rApgtK z5w@6+X6)Me&oHJ4(+%F(k}^OsFi(lvO#C8_>=~H+6-bPuTL^3caXG)=eUFP)3y~tH zdnLJ8NPS^9+h^OhrXPHglRz1VlJb*tWZ6L2TH6n1E~0nQ&yBVA_qf&1vc>uP=eow) z3M+pz0UA8K25-mXPv3oiWiv*JhzRu-vF`TClz1CdwoVCuVvIx%VVE zo^5@I;0x$=3du)Ygs?X4f$j|jlF(!!W!>5>wNLe?RujRmTbiE-`ihAR_??Lpy2S4F z{z7YhoZW}yzO_V^{{4=}=ayQcKwpv+fOXT}(&BSmOyX(ei==9|Y^3AI;ahP%`JikQ z*$EvgaE6Z($)R@XX{IM;10^XX3Mz*X;m-a#PBc#8x6G>X=Zx*zh zl*R`%whw=XM=O&Y{P8IJ{eQUteFH==QFL|y`9ff#zM^~c)wm$F^`AG&b~iiW zZMT1_-lCI>Q~w8Jm7zaE0Ab=hVsnTmB_scrUV!)fKZxSZzp&8FFaLoFCI6<2UjM;T zwf}bbYW!>sD|fpi z^vQ8MYY~dEYz9n>9|929vCH!Xfgb$l)qMT`{Ko#TkA=TLhP^jP_vz*hL=_9b2uR^F zpk)yDxqvUplk&M@@gM)whI2k zLl}q$|F5VYqs^0lpp)%h>WfL9t^|GzU!i0p9S-JCZyuyZbzK<4?DVIb2-2sA35pR*y7g?@n4&kS{`^Jwh zt8cjQs`A)vL>q#-PY>?OrI>`oLcYh+^s*u3k|e&^cI#%Nj6 zk|g24QTH&FfNNWU=W}RbhUkM~0_Kr0wp{j5S0YnF zZkmPmgbKM-5x=8XZz8{b{km7rAsM@KYiepLqu1V^3#BK5K{0^aB@zn6XaX&aopo1! z&>6W`Rf&SY-?H;-dQRJ3gR*=#TX(G0lEe+oo|vW#MpZ}CMk46+M#3s}yF5{fJPL^xz)OB3Gy@IFQO;6-r z`=YyEtQtbc(oNnfqUkB=1cC0x^v>J4N?-WTkNDq8Laj16AXGZzXgF7;uku|s8sWM9 zGB`_=+Y*q~2{s*AHpe^di&Z*DoN9KrOioS?mc8qIgh{{|50-Wdj*sZMTH|-lOrP=C z+n0b_DjX!{D$(29dvw27(Dk}06yO#)&MxJm41hh5%%IU37CklC@ zRvBKJt73p|`Mk7|s6JN%8meMSNA+wlv9V3H*$JIImL$MsAc4FZnVXxN*=Po-(SD1< z?EDCGT!VOz7#jU&L+=tvm_t8ErnS*+lCd%l)tXL)oNw={?m0}j@63>k)LpQKBw6$X z$fS;X%+#y5p6_NR(JpR_=EiavJm^j2ZT;~0jg$M%H_R6p_2c7l%eU?>>@(HP0psY2 zQgNGYm0{SU+}l|S-k`~$&m$t$a>Mb*=)e<=%E7^9_>PZ!c0-F~91{LBXH00e8z{a! zh+&g(TxU$Q7>zabuda`;*e{Gvo+z-Pi7*+|+5MUxQ;G}`ntmnjAft!-Q?=^bo;5Z6 zQ1937x$p&0fw7ZCSa_jNXBf$Wj@s|fA8wS6NVjiR8=IS}qa_%c`D*Q8tQW}b!Wl*X z5ZmcQt&RV}vin0|$KppR1#OuLwwa9|x%DInPt5JlKVb7rAYg*YUul~mdTcRD$jid=rQ74`6>xbZ%t6tG znw;g!OaJ@J&zIz=JN=Ry!0!^PS*!$B(dokVoYM6bT?bar2avpWZ;o#%9 zeYC9AUWhIj{GpK`MZ){GTB%@yNlm!XnJxSMR&hg zr768Q^GHtsx$Rc;mpqTf5rA4P|#-9260U zC>9Fe(IDZCgo(PhpKt19ywQnhz4g0GxL`0!LGkF_%#zN-vRa3!r%;{*NedmFr!oSx z`x`Q#^^VW?jSQdw8V<$~SWFCfi6=UlOce}IF()Q{$WEd_pp`sLrN#GMkEn>js37N2 z3)2;!1x7w-CsM#qz&lUEivf1M<}@lKfEEkYqn@=?KX$!F{_!r?dgL9mCO*ppPw36l zvb0Rfg&y9q=H;R~orVo%g2tK#t@<)0D|it;&#Sx=Za$0VsCRO91~KzSKml*xx!0n_ z933ej^;)8O+v@W2(&=in0rp8|%RZg8k^Cgp$3X!~YH$ZTbn>5fb}lovV~{}4I+&P0 z@=KF{At*vX-7IYJ3JjL!Gm|_(dlp@uR#PCqqvtCuxy7!P1T`*4ZGX0wBK5Bq;|oO?=INPC7dv49JudTJksB)%BG1;Qq7+64={GB!Q>o&e4$p zytRCXdT!z;QT3yvh^D38%TU3-Ov6x2Ce?0}Yq&21fj8J+CWgvoDDAgL-;_KM{xltLXIiI=ALFm~Pyjxms-)ysTBzSKv%2auty@_+bz2MMh46rQ zT5LHI>H7xc&BknFIgKTtT+eI2m8Kj<9sWd_b>J#7F_D}188)_6;dT!rjoS=q0nB`&=r`7iwKHV=A{>_cH9VBbA@3gaKgnN3k_5{;NcgVdCscfo^@sXU$4^x|tRx?oeW0scVW? z+eeC&6cnMii_o~CP$6=UtVPqqa&g;S_0;@w8(x&RrM3jr!DLaZM~S_Ly*)e6nE&zI z&9Cm7xw;&E^r!{IODdc<>C@jt>TP_F`o5P$rcpR{oqNYJdU-)uxT|@1I5Mg=IK#Qb zP5CzYI9(2oKvesi$cdZsQGFFeR_;Z1lv%5qfuBYo)>ZIwu`y9DvdOEa# zDMV}P!z=D3n>1bjqbI7xp7~2%i;KJYvukrgzTf^SZ?bU$l{a>aKb}z1{arhGU3XUB zIS?i-7~B5i`ZCm9dwjIYk_?P*(p5)#*iHU?c9@E5+{0zSXEDR~^71-Z>5l;>q8vGG z0PNcxto4g}T`y42!otIwn;oVarh7v(S5_#V!ba}eP4EaySJHs%ent&%}8{>FG4 z66aXUPs&^-TXi@oD4yA^_NSX2vaPedhZTtQmiO!zOiLuYwZY`@I_xxz#KHdJ{}Fi2-nR}68|Kn8M$lgmUzMG?eCR}z zNp-e+6GZ_7(Y(=H9~i&~4bUmktcUzP@dA=onwlnq-@$S=#ObocDx6m4Yp&{bhUPUg zF_`xqt`GNl)ISI9zl%NNcDK7k?7$v8{FG1hnFt|ck(x<3b(mm7L9u5fYI`TY<_KW%p71B{Iu2^Z92^`_P&%v* z*Fx|pN3s>kphyN8O<-tHksfTGFc<^;cocg|m4{y!tAN6$)po+z-y>DG4>}vzoqvz} zH8quz-}z{+SFj8V53hB!2zzvDq`f^b`VC83T3U305Pb7X*TWg%g#r%OliS02ml03Z zc?$WTJQ+XdKh;AW&OHx7JwJ{s;Q9MSTfxr(e5L4*o-_v&kRkmv=ss4famKZ@v>d+J z!FjJ6xz*gxmT_gX)Wdb@G@LW)q>>HX-rGjEq(Ea;Sh(4Q7M=;>Kczd9LUa@;#U?{z z{f`kJOvokPELR7G9Y!-=DF4rm9j>38pUOTfejqKNOa`m;-j852UdI)zd}-I9<4mb! z#{!+mr=tHJ_5vBSSrRHR9{t=p7Bm_z$A*odacU|tpvX}9_`(o~-?Ib+@IB}v zohiLIr6J-pH|R(!+uh&q{Fw`4rTCb)Y@+^wL4{#`&1~xVhKmr=4LWnxlCFnSo)WX0 zu+Sl5FVRmVnQ3)oAbgo-7Q>1p5r1$m{Y}K2_y%s{F-Ny=u8xRiudg~gQ#Be#M`O0H%3`4m2D(ZT>7TIx z;P>j+pK;B zYs0e;S;Eof!Iv*zG6cpO8+RBr;=L}W2{&Hy~k1#oKu(I56>CLhEj z3wZsMc^z{if}sEjmUI*@gN4e2m6+t-pLl+6^QB1K&kpfEFvx$C^FKlgXO#0Bf&%2H zges%alxIj@iyeIcvm>FPpeU7`xqM3Eez7W>u2ec_%2R6o#{29L`MtIE94yIJdkbKq z;fB02kctNG0xTrszkc~fGJcE}7y;duZI6p~;wT~Ey?_R-nXvoR|BeuL5j;Miv)%aT z>C<~is5>1iGDt8>BVv-=4c1&XPORW`VqoUU8f-N?_v=Zky`5D}Wa9hAzh92&tU7IG;-ytGYCU9M@K{GBj5A_jNg!#<5r zTf1n!BlN+W1s_vBOO3$Or@0x^O+8-yyG$v1Zo*hb_72I;G?D=r9u-AYf0n5nXXu?TYRP&!I8>^x0ce-6|UpB4`nILP>J>{C7`P}OT z`_rUV681~~xrGIIiwp~a8>AwzA8f3;tMdzL!WgFRXECs)lPx^>dldl-=r1KCBuXtG zAo5=IDtit?epqN#YF(c}D^Jb*(L0y0ldU8wcVhSLk*@&(3&Q`$4(H^wX!VL>kGs-# zRkrjj#_c~VpRlz*O8mdak3ei-i2n*67-;&+3R5u=goyan9z>3Y%9X!G_N)1g=1}HR zmyLKnRAq>zb3s7(mF7ZNFW!Ts&qk|=&lgxy2)MDGs9;Kn+}%!EpC=3vG3bg93M-;q zrexZgZQbXj=KT5FjNdl{jnJ@$< zVE_PjtOvg2kvzD6AKn)}?E)l4063bKzu7Hv+b%FmbC^8`>iB4}6Wiu^X@eH?&d9WC zmRu1vs7(Q~2m&|Q1MZ+eGJ8(u(Xqbw>hJ5f7yk=I4Q$~BFZVF2jyA~88eak5@4IUD zBP5O=ip!arBi0cAfVLgj&NAhHBDjlS^R5qHOa1vo0_+|?kT?de3!@z&Vl?4-Q}?2% zIXhR<8KtLZ?vMF!?e5Y^WFBq8n`SWjF<;URwIlLZ(_{in>-p8iK!^>X)`g~Z)%fZH z3`<~7tA`wpgx6tjz4FlMzXyF3W|;j}qx?Ox;Pf04T=n~>tY3Rbcx6k(aX+A-wkJ&w z4UWLRmr2Oi-omK*XKz`P{kvkQ>%DtvL?LDqg}#Qd9I4>T3K?#q5SWt=(ZQ6ekc=y1 z-rW@An=It$t>X@_*k8gSBTLHCguF~7l|{})TpWEmPwm%AlxBw5{-f%PHEsouI=|xL zV&b9QMMayF>9wKb4QMEmdR;;o&*wz1I$tX=E2)vRV~}wKT}nbfhP1lx3!?mFd=mWG zgoB%mAZC%ftn~VLeKj(dZ76Ag5XPUB+91Izu1t&kCc2|H_Hf>H0u(WkX110-fyP4J zb%EFVNS+Ni`v64za+8ol;#?tLA>>_l-SS3-O|hxXJed}ew^zz5*Avrqg^#!{AHbQT zke*2JErd652M4wW?iY6$YSqP(5+@1xt+^3oq_V^H)7j;uQ>`=h3s*N}=<`c=pU-e* z*Cmu5&bK6_1iK$aO_zlIFJJzmw6PrXT`{+7WaqP(TO-%__ zx~)G!rU*8&Zz3f>Abau57E_cwk9s2Wfx;If%yyF=85ud_2o_9M%LbGT5ALvfPb63{ zG2vE>^9Hc63j)9ft6*+C;z^8PDD*?dj*XWZce}`CvYgh?xn8w{Z^Xo@$j4{`%ay4Kr!JM`ln?c97=)}+cB9yWFbUeQf%G#8gd zBEFSR;|vPl>x+-4YUb?$fDk3CPRg3he6J0766Z_R@!{O=;4V{VK|fECHG55R7m!hDqf%x zTy}7Sw46Uk1W9wafJT|~K#_|B(o^+XiKYzcIDtUEl8(IV;cHE_`=oQ(PBx=O4rI6;Xka$% z(Sdez(JBJo*5gP+M2_HgNMJ#@y#5O#OS$M4ja2-N ze`uMRJ6Sr=A`rmXK&I4kd2QQwT8O<~LAXXO8UMWOsXE+P2Ro7D!itPvDB;V{rwOZl zHL9ONZ3OK%$GS^@G7pSEA!fUxH%l&arLT+(_d^Gp?wX6wEwlm4-$n8KE}Zx2A7Nv+ z69m{aBiX%^sk9W#h zj!wV77P`|e;|4FVn3#v41_AHUr?U4V(5;u|Fr8}Oy@pA4Mse%q6rTs@mLNuogsa;H z|91b0!J>F#j$%};n=>lb!-vfqPWz{j@vcr}rB;Z;qFcd)4tv@C7!)qN*?^#+&SJ*@ zjTo+va(Ke(0+cur9UYwvtf<&naUIzQNK+ab&+?f53;Hc@Yy1!B=h5m8u|^uSDw}Xk zmGaYo&>l~x;mj8GMSb1I)cJk#Arn2Lx`B^~bTTpxiH2hDGmvbM1bopSkk%%FKzH02 zfE<9aKLIkT{L}=;dHHCyV7ig2qB2JQ$!EZ%VI@~>=1+~i5gvkr9_VsqPHkfLP*1o zh>{h(TS_EE5WUx>M3*QF>l>5o_kGW~&Udc!{X6rQ%PMotXFl_J#<=f$++(^;a4oLQ z`g{HutMS(OgjSM_7qR(!n!}nlIV?$5{RsnutN5&`&eoYBta78PxHy(wAA*9cb;{I` zPYQrRE_W>71+@tDwIC9i3gP;Z*5hgHV*b!5N)!5YQ4+v!I%V(2zp*yZoCp^F?{Hg* zpu_okh@w8}c*{MS+O!&};v126`|>6fBlN-;eLaz{7LTo}Fsr7R`hvA0^ULF=xO3cW@br zK}6`;heRJ9-R#G(CqW_PPSxG>QBhIu9v(CrMSN{1*y?+AjWUR%RyIAEq6mKXVEq_u zl!toD1yW)1KcryDv|s4Y0aoDiQ=XXE*cMP}FY4+4&!DZ(nxG!a)_vRZ;;evRK8C%b z^0>qDH#y7JB0-cqOtK1;r3gmdJpe+SHAuBU7VKZ+G_~o{dT;yZTyq4q>;)(p zg6Mr^dehMseDu3@oh3Zi8A*)N(jIQNt0IhFQT_sw*3A<)1MCf@v5Q&kuxjD}bs}LD zd4Vpx-)%B3y#y_7dLV74xdX{@A+#=xun0fxF#i3oph}T2bu=**O5}idDOB}VP>`R2 zHbYug73xk-P6>F)wOytM_eP?OyZ0LP<2aosXD(+}t%(5)-O|9jO@ukkNa!G&7SN9B z&G<(PV9=7;nzF)ekOU_=$jd^?3uwyA1w5D zrT&DV^WN6#l!#sbdengK!j18A-`Gt@_rCHdGm$e)+a3ClhhL>?8&=77#toJ_FK?{j z-(HPWb!kbGWPm-OX{kD9zDf8@Bxr9(6VOEOXh-0YY;A2F92`D1d{)d+|6ihUz?;zj z!kaqbsX-Mb@Eg_@+35oe;|)m~HQg`?U`_PH@N;t_(jEa4qcg>$4UU6Q$OrTMTwf+U z_|bvc+B_=+c4kLs=ZW2oEUj`^))OoeSHRYc>wz=JRloV3ytO{7^ku^K&s*6B$#33V zF!FXm;4(k5K9Bap1ydLJ3`uQMGhPcm;n{~pLTf4n260MB_t`;`{6uW^ zE6<-q-vVdg?B5T3yt|%MKHWXjqKJR-GLZfI1_ociGQs;rm}%I<36C zysmE(+RH3dvUT4jyuaKLd6ja|efY>IbRVjaUEv>2mkJzj2upr#OXCr-ySrh${-Z19 zoKhI=$tRzJsC*&jSya1nMKagu#^D!6mD|0&yujgocKu&J1PsqCmU003M~un{I^g+@;1OAAExcRZzr;*aCC|DMPOG zIclpJ9I`+6_Vpju0F>_60yUE59z8}n-7u!4__s#EVQ7i_5ap@&Sr_(4$kgJ2~P znIe+m`n=3`u;dVtmP3M>CT3v;Q2LNkIt2(30h}&1tb(s6GkK|`x>`PsbQGF0_H8Xg z?~R75%U(WK0i8ifWzmlTe!;F!AGfq>NhPm&QX9af`G$-HP2A>fiel#!;(7Ljf*z^M zPfHWmiBnO%ZrbHGQef6&4{1Lc6?vv}@QISr(nErd9n$faw8MA{bjg4+0B9Sm^yE4l zBiFVy0mx&LeR$#2Na_{qjO!&MJ4Oy)0%xr2>WbP+{?d9Tj;Y0`dtVR!Wd~eHO|#_u zhWu_%oVu9Fcs)6wBMDEwX*j3)!x(8If+&;{TPXJB?RVy^2?{x9YG3Q&-q@w{*&?vk0 zwxZ&~xmaZ$?d%q!PG0jj9jqmPXFBh#95TOvfFn5N2=mR57#2yV$G5SvO~6x&qIZrC zy1Vs<##yNnT9c(m*6~m&nzBNPBs;5IH7@gA(l|T>lxd!G+$?KTuiXncdrzOXq;N4n+?GdllR0@rM0srlcD_{zW{F&ynniSoha_C)M2;P&6AToGMqkIr zwMtHcc|+!jLZO8vP`g5=z}?(T?T~;h7U#}QKgEY9?dXDmA!0p8+#?9Iw=-~!F5G}# z>PrN@s}Y$F?$Sp{ZEe^4rD>Y0ge*P_dT$dFE-AqH)Yp&C8#D0S3Zamb+o^P6rm;E? zp@CfHi>LN2!yO|e4dL{h+jYl)K7OH5>rVpw=1C^j$m(?C-0n;JCy!0!V;dzo^F6PP z)A-?`n$br`ZY;oBi!%|-x6@}t{=yCIrkQEKH3+5k@p&k?c3#TuhhJnQ)kyAklqTG8 z$mp=o17H%uQ7S`sDAy@N0~soQ9mD2o{2jo09?LzekymPxeS6 za53yDVr%BRo(Y!@GV#fmmMcsWU}&4rl5RDN^aO*0&GU5nqXV=i<_F;Z`>B5cEfR<# zhmJg88pu(9{olYgfF=6}?@QP@ki(RNZ;uTSltJ@@9nKQ1HYR_J@s~XN;E+M94TX+ITE$Ke3=hJHyuGS|DtI zcgpDCvmOzXeUyW#TgQ|3j3i+%!w#lF>ca*dQo<@hWV8EfY+SZyx-kJf6nhmR#e zB`P2T`UKmN!sEb$Y;Vlo$arD`$#LRFrh1lq;40_}k|6cBY}w%&m z@JRyf(81?!8=9EUZ|ha`3jmQ!b*LGCcjqbeAtU)#>CEs<%w82dO>MrvIE%=`KR@N2 z<}*~B%-x5yF62$ldX4e~2Enz8PG8cyVydYb^{aJhniTrPl)Y`m;aL6RW-6GoN*W2{%b&8bg9N!L-%*c=J12 z)5M@0MQ6{D0Qjd@f{;HR@kzTf4qC$=oL_#e%E>*%J_wz~f)z+m8=%lH4O7HGZ&p;q zRD_FEy16%S@tmm|X~3iQ^Q42=^n+>Qp%DX57)p%xzq2R}(2JnA8ng)bxpALSaP#(@n5|;5QDw4}H)(J*OS2QPw^t9|^J#S+JR?)3 zT*7o4BRQdm&g7&y{CgDi5Y6v8;qJ$<2oZSV0gLpKC77Nb@!4QClyZHcpLprQ#fz(i zASxDVpH$$}2OXqS8xqeq__OeSSIZz9%c#8nI5FN+c>nU5$PE|dS@v*v21`Z(El|i2 zY?7&NnX2c-E=3jD-I>78r@Z&3W|Mjx9*&*GmZwNheLgnmk`BS6@XXd(u-Z#&#@v_$ zRS<-1c0l=B_r9nNNDYHa806f)gpN`(W%&SwO{cHA9~ZxccDJVA1sTL9fiUD!ecO4u zE|o|eEZY*UkXdOhU&MNRNeB5wQ%B%&hX)UinoMN2?rg5L?XO*@U%|aJwfLOCk6Y)~ zf>eWRB*#E0MeVuA#`{na-|1QD#kJb++^DX6xu_`T@k#PrPEM`Y!*NXgDo>Z&JlbJG z#PaS##HKKWh-|eK+8TCLY_IA8R_Tt}e(+4x&j0;;yIj_RzCNaO`D0r%yG%^|b_?t3 z!EikpGsbrTx#`_ni@8NcA>yre{W?%!k_znNZsL?dgZgoE-RC%8;^mb`huyur z@co-`QYYg6Nri;bdq>mj0xz4I&xYkOiJCH!K)CpEsUuQtVSpAAMksV;+1xM&!mF*M z;5EDZuhy?$PY9?}12Z9KQc7~~R-RhJi$5DH_ei}xf7UfLB*P{$Iy)u@1}{z%w_roK z5WIh)bIr}oKm$Yqogdd$`w0IB^&7BsMjV5L@9s!If0jp)DaB8oBwf4KK=E*OjPN}> zd5aYzX<=rDi+8)YGW>BC5uCb>B-e8aqfHifwp59uN1&>boJ&6eAXM4q0(goh_mIs4 zr3iQ2-J`|Yh)r0kQ%o5wvOo;dc`*_zlU80X?Ny8^pZEo`8}nYH$~&Su-j#LheXXsL zG`OJ4roH*L>{{?mEy@C`r)f%CdoRBZiHZV^1@hqD1|FEE^ai9XKr9vi=l@#QXSJa2 znIcOq%^bqekJfu4;iviYAKXSh<_F0TO>;*qNBG~G89WL>70^agm(MT??jG3-ARl7* zo*t(hk4F38J2Du-aK>zZT~Z`zg=;Z?3*F~HWVu$oR5igsNN18YeUky37Y$825MZ{T)+$p;NFVgIP)?y>qkk6=s><<95DutN>YE5Qik;MkNAs;#l zw5+6D=WGu)XrXWXut116G&aU2C0(g{c;a9)zo3Fla&VXy3tSxX8Xp_8*(XgDKfKZB zQc|>kCSvm;Lj{_A(v>83S~~ zf5sLF@qrws9LUc-c;D~%^I(lcF7tmLK>YvqWp@)hSwU1{A0-9%B%`4PmvBiAF1Fs( ziEi|nnBBcx`2XTt!+h+)I2UjMr54fNp|n5NA)hK|VFK+R{}Ckpzg^?GCS;1k;lXH7 z;_zsqDH?pT?$2uGJcEaXLnYyjNv(h1obPN0hg!Pq4N$rz^Ll+OEiE0JpASz=)Q$Ru zuv~Dwa~`WZ1~-a~lCpkeWTazCuMi}PPU|x_{k(!oRG?=8J-reLx*$zx314Nq4ek7< zYaSgTk)&`ui2h7nU>0B1&^QV8zy?(h``{ZyL9PMhdF!Jie=IVMBImcZ=7N`@l@b1C zVDv>q&2i)iv=WFum=dUd5EME%JMTXL@yh-wDf&hBp%LNXI2`UgHIF9>NUh0Dom&S} zv*0=fCgJ70{q5i9e@b_OPoZb%!|!psFhDoTr*aUF=EV9xMnxUGP|w3%b2})v+=BaH zs%vXL$)_}QL)0P2IK+weM+t&ka`N13;G4yL^VLx^V^#!L z&x>F+o7H5$_s@@Sp&y0!HhY0>Jw%WF#da!tJGm^?%FfLB@Jut!}=!a!AVy z+8e+-o2*4lMV!`%6b^2$4>fdCJ|S76fgTDZ+B|_Bxpw*$ zD49dOP_PI@ATJF_rz`K#m$@zYgA2v5fuHRso0_nwD9gpVK-FXsatvlkmB36%sx?q> ziZcmiK>>QfI?(h~ReE*+#Huv{IvTJJ?4MKD#<)ySFBQ zbOJNPl0wNcFn&X~zW6JJ_pSDfNJvZHloW{vwHg$|%Q-m-8T+pB&-)Oc$A7;CeLqz3 zYR?^75|?}gp5E@&D?>D`kX||7FS;mR4f;y0JXgD1pcb2CLBVv3f@-X_2N1!5QIY0ppEaZT5xI0dA0Ryx8H3g%Y;l$Ax!Q95qES8kJ0GdXc zBJV%isL#|dGZ=$Ei!al!4zAd^IEd^be9aEuY;UiSauqRCu2h6{1oSC&)*`FzoarAN z*DTX~T?NkvRecJIOxe8m)c|X_M0jrZ9kvf-Ysna_>O%BMU>(+xsjUKre@nf2A<@(j z-vIe=c=-YLBA>wr5ghd-A}RuD7$muA_T7*3ruqMbk3BDU1rqXZcg{{X9g9D&&Y!Zf zY=9NkaeQ%iz2XZNe=0C=P<)xW;U||W;Xx~{KfsKSbQ!V)!?wW4$V0_DTT6Y#U|fXM zM*D&G8*9?68O0_Ol%6Mmwe(d2!R<_6r8Eg(NTnc#P50fRr%HPm3)07YLb~_E@&}id z!srgwwDm;)GAv&~IBoqbxJhhgpGM^n7YDy@Pfn72O-Hw7FZBo#u`?hOUGkpYwahE5? z#{st$d0s3kb3`}aPMOamg*I(9lrCO9OP@mJ&V=4Pkt@ zSEzJz4aPQCP9e%^Sy|akV0h@?JkAqnQfJBXsVqZ@JCLyZ?j3{2vLnall$Kt&gx6_5 zIR&GZTRjjHap~ooM1Ac`{k;y`XKQlD=d()NbY|0&2AusOd;B!NCFGrgfBT{-+!;pm z-upr&leinpnog1+BPF9PC9EV#mP_{d$;qQNz%yvPzt=@MV37J;5{d(S)OmHML~6DO zTZfjHY6FtL@^pA26upd!(MP&VZozxfty9ChX;4t&uoo^gpQx4d(Vusj# zmtoyRlPPpFw56e$dLoj~`@|Tq;N}VT}G;noo?I zIku#^4r6ueKRS{Hs-LO6)y#m~@<}AE)}$ondxW{i5H$JYnq6u`6YAb-l^5BJfF*-Q zT^ob0t}aNuBv~C3fYE{V5R@1b-`{qoqP(908kyAS^~(C@_RrZHK%0GgsZV_-Fp!3p zB_gsG5UfWX8P_d5zGg}h^*2~$Q^Nmsb&nYV(HTybc(iir;s*@TM;_|IKv||*&*Zu= zj01v8Gh30oJ6As#boT}&?lFNXiF>{>nL7!R=Aa)z^8L>v>A;-$g9nINO-(H>*cvt- zsMn&L8;QO=VT1$WgWm^>Q0PiYhEB z2!b`M3?wh!@BtcE>Kj00KAS7bpX2##o^9zvkvhlq_?pg699_k6SS=G18Dz>_@Aebe zg(mytzzpdm6H{|?2$|=`kLH4jCMIcnU?sLGUYQ)JKTe41~vGnsvSVXA?^{`CTY zix;bRPm7678**y?6G=!OHh_KLY;7%{p+q`HH+LLw+(YYf_8Dv}Ak$%m2eU%fhlSmD zn`uccT@DZ#=tA3=g{^84${*T^n{|c{vwI5$fE-|L#md+OJS-g=R^Mb~3>kcTbB*2RQS`Vl87v8&Bq{?*3xGDl%fqUZOZi7QW*4Nb9k)A|xBk#af zIdPq)9|PqKz$JqMlpbckM)qT%+`3=~FtxfL4qKF~t1GP9EG(;IX=t>VIHvD`qhsyV zv~c8f8mlNEwJ4PM10<0TF~>oBONI_&zLy9B0oSf(jTE3Iz@G zI5{{1VS_U;G?euE#iypG22`jcgshz%M6hFQg3J#JDU%DJCteCnThA>@82?Aq>eSvYPk-yLmS3-u^i_qG2}^@)2wtvl^J zPft!w=;1H69D~T9ui6(4YVucLo&a`gAYg(HG}{U{ty~el8xHvGEk|X-a>mL=j3(YM zyWYQO-%3Co+;Z*LrU1S7+dHj7TXOpezfUi6t<)Upo)%L^C%~0 zR ze72?-fcO=*g?8^#-(D&}f#6*zm9lcVc;UhmwC^6v!tc0P2fR{+Aa)?^SL8Kudpug_$gXi z`C9*D*e*1{h)4c7f%@LF3r`s(vlwMS?Um+Oj;)DkG~`*YK_CHkVjsK-u2q}k$5*Gm z1Va~X5|A4Jf`#wnkB30#tf1gY0f9W0g@4e_=y)(XgMA5TI}=Zp~Y!1JHZl^}ei$Uq)+Kn}$0`s<<5n`&D%6_e0WKy;>CQ!i^>LG>T6BZzKugwE#Ufmv%NCP(@gWhQ5Cf!2l+-!aJzdS|k>_ z7sGUcA(N2)X^QXi;XQJRZ%pD0O>Am5bDR7~tZbg0Pj ef2T}Ve68(NZYT+zriCvi`AbPnF<0Ki|Gxm(`gKtN literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/MVPPythonViews/PasteIntoWidget.png b/dev-docs/source/images/MVPPythonViews/PasteIntoWidget.png new file mode 100644 index 0000000000000000000000000000000000000000..06ce203faa1aba7bbc1923372d0520d8a752fb10 GIT binary patch literal 81569 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

    kF7mXsnDBB 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 DWA-sL literal 0 HcmV?d00001 From 36b9994f0aef0c76001df2755a027bb426bfcf29 Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Tue, 20 Mar 2018 14:28:09 +0000 Subject: [PATCH 320/364] Reference Python page from MVP tutorial --- dev-docs/source/GUIDesignGuidelines.rst | 4 +++- dev-docs/source/MVPPythonViews.rst | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dev-docs/source/GUIDesignGuidelines.rst b/dev-docs/source/GUIDesignGuidelines.rst index 5500cdc6c950..b004ce72a65e 100644 --- a/dev-docs/source/GUIDesignGuidelines.rst +++ b/dev-docs/source/GUIDesignGuidelines.rst @@ -274,7 +274,9 @@ file would look like: app = FooGUI() app.show() -where ``FooGUI`` is the ``MainWindow`` for the interface. +where ``FooGUI`` is the ``MainWindow`` for the interface. Some more +detailed documentation on creating GUIs in Python can be found at +:ref:`dev-docs-mvp-python-views`. Designer -------- diff --git a/dev-docs/source/MVPPythonViews.rst b/dev-docs/source/MVPPythonViews.rst index 1709ef6efb01..40cc1adb4770 100644 --- a/dev-docs/source/MVPPythonViews.rst +++ b/dev-docs/source/MVPPythonViews.rst @@ -1,3 +1,5 @@ +.. _dev-docs-mvp-python-views: + Using QtCreator to Generate Python GUI Layouts ============================================== From 9bf5843b837d01004c8526e410a14a4c3049e042 Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Tue, 20 Mar 2018 14:35:22 +0000 Subject: [PATCH 321/364] Move example code to dev-docs directory --- {scripts => dev-docs/source}/MVPExample/Calculator.py | 0 {scripts => dev-docs/source}/MVPExample/Model.py | 0 {scripts => dev-docs/source}/MVPExample/Presenter.py | 0 {scripts => dev-docs/source}/MVPExample/View.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {scripts => dev-docs/source}/MVPExample/Calculator.py (100%) rename {scripts => dev-docs/source}/MVPExample/Model.py (100%) rename {scripts => dev-docs/source}/MVPExample/Presenter.py (100%) rename {scripts => dev-docs/source}/MVPExample/View.py (100%) diff --git a/scripts/MVPExample/Calculator.py b/dev-docs/source/MVPExample/Calculator.py similarity index 100% rename from scripts/MVPExample/Calculator.py rename to dev-docs/source/MVPExample/Calculator.py diff --git a/scripts/MVPExample/Model.py b/dev-docs/source/MVPExample/Model.py similarity index 100% rename from scripts/MVPExample/Model.py rename to dev-docs/source/MVPExample/Model.py diff --git a/scripts/MVPExample/Presenter.py b/dev-docs/source/MVPExample/Presenter.py similarity index 100% rename from scripts/MVPExample/Presenter.py rename to dev-docs/source/MVPExample/Presenter.py diff --git a/scripts/MVPExample/View.py b/dev-docs/source/MVPExample/View.py similarity index 100% rename from scripts/MVPExample/View.py rename to dev-docs/source/MVPExample/View.py From b43dcaffd65304b389287ab738ec4075d5f5581e Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Tue, 20 Mar 2018 14:36:06 +0000 Subject: [PATCH 322/364] Revert "Move example code to dev-docs directory" This reverts commit 9bf5843b837d01004c8526e410a14a4c3049e042. --- {dev-docs/source => scripts}/MVPExample/Calculator.py | 0 {dev-docs/source => scripts}/MVPExample/Model.py | 0 {dev-docs/source => scripts}/MVPExample/Presenter.py | 0 {dev-docs/source => scripts}/MVPExample/View.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {dev-docs/source => scripts}/MVPExample/Calculator.py (100%) rename {dev-docs/source => scripts}/MVPExample/Model.py (100%) rename {dev-docs/source => scripts}/MVPExample/Presenter.py (100%) rename {dev-docs/source => scripts}/MVPExample/View.py (100%) diff --git a/dev-docs/source/MVPExample/Calculator.py b/scripts/MVPExample/Calculator.py similarity index 100% rename from dev-docs/source/MVPExample/Calculator.py rename to scripts/MVPExample/Calculator.py diff --git a/dev-docs/source/MVPExample/Model.py b/scripts/MVPExample/Model.py similarity index 100% rename from dev-docs/source/MVPExample/Model.py rename to scripts/MVPExample/Model.py diff --git a/dev-docs/source/MVPExample/Presenter.py b/scripts/MVPExample/Presenter.py similarity index 100% rename from dev-docs/source/MVPExample/Presenter.py rename to scripts/MVPExample/Presenter.py diff --git a/dev-docs/source/MVPExample/View.py b/scripts/MVPExample/View.py similarity index 100% rename from dev-docs/source/MVPExample/View.py rename to scripts/MVPExample/View.py From cbc85b74b0ee09515ef8bd70c491664d8a07ff50 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 20 Mar 2018 14:04:33 +0000 Subject: [PATCH 323/364] Re #20991: Fixed doctest. --- docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst index 2bb6d6488005..a923be6b6548 100644 --- a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst @@ -43,7 +43,7 @@ The rest of the input properties are not inferred from the parameter file, and m property that allows users to specify a region of direct beam that will be used to normalize the detector signal. The region of direct beam is specified by workspace indices. For instance, :literal:`RegionOfDirectBeam='2-3'` means that spectra with workspace indices :literal:`2` and :literal:`3` will be summed and the resulting -workspace will be used as the direct beam workspace. +workspace will be used as the direct beam workspace. Transmission corrections can be optionally applied by providing either one or two transmission runs or polynomial corrections. Polynomial correction is enabled by setting the From 84b20dfb7a5537cf297da996de5b74c775c171e3 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 20 Mar 2018 15:22:06 +0000 Subject: [PATCH 324/364] Re #22154: Applied fixes to Framework/*. --- Framework/API/src/MultipleFileProperty.cpp | 10 +- Framework/API/src/ParameterTie.cpp | 2 +- Framework/API/test/AlgorithmTest.h | 2 +- Framework/API/test/NotebookBuilderTest.h | 4 +- .../Algorithms/src/CylinderAbsorption.cpp | 2 +- .../Algorithms/src/PDFFourierTransform.cpp | 2 +- .../Algorithms/src/PerformIndexOperations.cpp | 8 +- Framework/Algorithms/src/RealFFT.cpp | 2 +- .../Algorithms/test/AnyShapeAbsorptionTest.h | 4 +- .../test/DetectorEfficiencyCorTest.h | 4 +- .../test/GenerateIPythonNotebookTest.h | 2 +- Framework/Crystal/inc/MantidCrystal/SortHKL.h | 2 +- Framework/Crystal/src/SCDCalibratePanels.cpp | 4 +- .../src/Algorithms/EstimateFitParameters.cpp | 2 +- .../inc/MantidDataHandling/LoadCalFile.h | 2 +- .../inc/MantidDataHandling/LoadNXSPE.h | 2 +- .../inc/MantidDataHandling/SaveCalFile.h | 2 +- .../inc/MantidDataHandling/SaveNXSPE.h | 2 +- .../src/GenerateGroupingPowder.cpp | 2 +- .../DataHandling/src/GroupDetectors2.cpp | 2 +- Framework/DataHandling/src/LoadISISNexus2.cpp | 4 +- Framework/DataHandling/src/LoadRKH.cpp | 2 +- Framework/DataHandling/src/LoadSESANS.cpp | 4 +- Framework/DataHandling/src/LoadSpice2D.cpp | 2 +- Framework/DataHandling/src/SetSample.cpp | 6 +- .../test/FindDetectorsInShapeTest.h | 24 ++-- .../test/MaskDetectorsInShapeTest.h | 12 +- .../Geometry/test/CrystalStructureTest.h | 2 +- .../test/InstrumentDefinitionParserTest.h | 18 +-- .../Geometry/test/MDGeometryXMLParserTest.h | 2 +- Framework/Geometry/test/ObjCompAssemblyTest.h | 8 +- .../Geometry/test/ParObjCompAssemblyTest.h | 4 +- Framework/Geometry/test/ShapeFactoryTest.h | 120 +++++++++--------- .../StructureFactorCalculatorSummationTest.h | 2 +- Framework/ICat/src/GSoap/stdsoap2.cpp | 2 +- Framework/Kernel/test/CatalogInfoTest.h | 2 +- .../Kernel/test/ComputeResourceInfoTest.h | 2 +- Framework/Kernel/test/MaterialXMLParserTest.h | 4 +- Framework/Kernel/test/PropertyManagerTest.h | 6 +- .../inc/MantidMDAlgorithms/CloneMDWorkspace.h | 2 +- .../MDAlgorithms/src/CreateMDWorkspace.cpp | 2 +- Framework/MDAlgorithms/src/MaskMD.cpp | 2 +- .../RemoteAlgorithms/test/SimpleJSONTest.h | 8 +- .../test/MantidWebServiceAPIJobManagerTest.h | 3 +- .../PoldiMockInstrumentHelpers.h | 2 +- Framework/SINQ/test/PoldiPeakCollectionTest.h | 4 +- .../src/WorkspaceCreationHelper.cpp | 2 +- .../WorkflowAlgorithms/src/EQSANSLoad.cpp | 2 +- 48 files changed, 157 insertions(+), 158 deletions(-) diff --git a/Framework/API/src/MultipleFileProperty.cpp b/Framework/API/src/MultipleFileProperty.cpp index 6f92bac63f3e..7d0d7ac5b540 100644 --- a/Framework/API/src/MultipleFileProperty.cpp +++ b/Framework/API/src/MultipleFileProperty.cpp @@ -37,18 +37,18 @@ bool doesNotContainWildCard(const std::string &ext) { static const std::string SUCCESS(""); // Regular expressions for any adjacent + or , operators -const std::string INVALID = "\\+\\+|,,|\\+,|,\\+"; +const std::string INVALID = R"(\+\+|,,|\+,|,\+)"; static const boost::regex REGEX_INVALID(INVALID); // Regular expressions that represent the allowed instances of , operators -const std::string NUM_COMMA_ALPHA("(?<=\\d)\\s*,\\s*(?=\\D)"); -const std::string ALPHA_COMMA_ALPHA("(?<=\\D)\\s*,\\s*(?=\\D)"); +const std::string NUM_COMMA_ALPHA(R"((?<=\d)\s*,\s*(?=\D))"); +const std::string ALPHA_COMMA_ALPHA(R"((?<=\D)\s*,\s*(?=\D))"); const std::string COMMA_OPERATORS = NUM_COMMA_ALPHA + "|" + ALPHA_COMMA_ALPHA; static const boost::regex REGEX_COMMA_OPERATORS(COMMA_OPERATORS); // Regular expressions that represent the allowed instances of + operators -const std::string NUM_PLUS_ALPHA("(?<=\\d)\\s*\\+\\s*(?=\\D)"); -const std::string ALPHA_PLUS_ALPHA("(?<=\\D)\\s*\\+\\s*(?=\\D)"); +const std::string NUM_PLUS_ALPHA(R"((?<=\d)\s*\+\s*(?=\D))"); +const std::string ALPHA_PLUS_ALPHA(R"((?<=\D)\s*\+\s*(?=\D))"); const std::string PLUS_OPERATORS = NUM_PLUS_ALPHA + "|" + ALPHA_PLUS_ALPHA; static const boost::regex REGEX_PLUS_OPERATORS(PLUS_OPERATORS, boost::regex_constants::perl); diff --git a/Framework/API/src/ParameterTie.cpp b/Framework/API/src/ParameterTie.cpp index 56b2bfb5dd7a..1716b93639f3 100644 --- a/Framework/API/src/ParameterTie.cpp +++ b/Framework/API/src/ParameterTie.cpp @@ -81,7 +81,7 @@ void ParameterTie::set(const std::string &expr) { } // Create the template m_expression - boost::regex rx("\\b(([[:alpha:]]|_)([[:alnum:]]|_|\\.)*)\\b(?!(\\s*\\())"); + boost::regex rx(R"(\b(([[:alpha:]]|_)([[:alnum:]]|_|\.)*)\b(?!(\s*\()))"); std::string input = expr; boost::smatch res; std::string::const_iterator start = input.begin(); diff --git a/Framework/API/test/AlgorithmTest.h b/Framework/API/test/AlgorithmTest.h index 92f3c17252ce..7d347d05653f 100644 --- a/Framework/API/test/AlgorithmTest.h +++ b/Framework/API/test/AlgorithmTest.h @@ -361,7 +361,7 @@ class AlgorithmTest : public CxxTest::TestSuite { } void test_Construction_Via_Valid_String_With_No_Properties() { - IAlgorithm_sptr testAlg = runFromString("{\"name\":\"ToyAlgorithm\"}"); + IAlgorithm_sptr testAlg = runFromString(R"({"name":"ToyAlgorithm"})"); TS_ASSERT_EQUALS(testAlg->name(), "ToyAlgorithm"); TS_ASSERT_EQUALS(testAlg->version(), 2); } diff --git a/Framework/API/test/NotebookBuilderTest.h b/Framework/API/test/NotebookBuilderTest.h index 4de0ec170fd4..7ae7f7ecff6c 100644 --- a/Framework/API/test/NotebookBuilderTest.h +++ b/Framework/API/test/NotebookBuilderTest.h @@ -211,7 +211,7 @@ class NotebookBuilderTest : public CxxTest::TestSuite { void test_Build_Unrolled() { std::string result_markdown = - " \"source\" : \"Child algorithms of TopLevelAlgorithm\""; + R"( "source" : "Child algorithms of TopLevelAlgorithm")"; std::string result_code = " \"input\" : \"BasicAlgorithm(PropertyA='FirstOne')\","; @@ -254,7 +254,7 @@ class NotebookBuilderTest : public CxxTest::TestSuite { void test_Partially_Unrolled() { std::string result_markdown = - " \"source\" : \"Child algorithms of TopLevelAlgorithm\""; + R"( "source" : "Child algorithms of TopLevelAlgorithm")"; std::string result_code = " \"input\" : \"BasicAlgorithm(PropertyA='FirstOne')\","; diff --git a/Framework/Algorithms/src/CylinderAbsorption.cpp b/Framework/Algorithms/src/CylinderAbsorption.cpp index b8653ecc69e9..731b7fc4ff8d 100644 --- a/Framework/Algorithms/src/CylinderAbsorption.cpp +++ b/Framework/Algorithms/src/CylinderAbsorption.cpp @@ -82,7 +82,7 @@ std::string CylinderAbsorption::sampleXML() { xmlShapeStream << " " << " " - << " " + << R"( )" << " " << " " << ""; diff --git a/Framework/Algorithms/src/PDFFourierTransform.cpp b/Framework/Algorithms/src/PDFFourierTransform.cpp index efd92caa5d60..58d8c50d4823 100644 --- a/Framework/Algorithms/src/PDFFourierTransform.cpp +++ b/Framework/Algorithms/src/PDFFourierTransform.cpp @@ -257,7 +257,7 @@ void PDFFourierTransform::exec() { } else { std::stringstream msg; msg << "Input data x-axis with unit \"" << inputXunit - << "\" is not supported (use \"MomentumTransfer\" or \"dSpacing\")"; + << R"(" is not supported (use "MomentumTransfer" or "dSpacing"))"; throw std::invalid_argument(msg.str()); } g_log.debug() << "Input unit is " << inputXunit << "\n"; diff --git a/Framework/Algorithms/src/PerformIndexOperations.cpp b/Framework/Algorithms/src/PerformIndexOperations.cpp index b00698a069e3..22ed20a842f0 100644 --- a/Framework/Algorithms/src/PerformIndexOperations.cpp +++ b/Framework/Algorithms/src/PerformIndexOperations.cpp @@ -172,7 +172,7 @@ class AdditionParserRange : public CommandParserBase { public: private: boost::regex getRegex() const override { - return boost::regex("^\\s*[0-9]+\\s*\\-\\s*[0-9]+\\s*$"); + return boost::regex(R"(^\s*[0-9]+\s*\-\s*[0-9]+\s*$)"); } std::string getSeparator() const override { return "-"; } }; @@ -184,7 +184,7 @@ class AdditionParser : public CommandParser { public: Command *interpret(const std::string &instruction) const override { Command *command = nullptr; - boost::regex ex("^\\s*[0-9]+\\s*\\+\\s*[0-9]+\\s*$"); + boost::regex ex(R"(^\s*[0-9]+\s*\+\s*[0-9]+\s*$)"); if (boost::regex_match(instruction, ex)) { std::vector arguments; boost::split(arguments, instruction, boost::is_any_of("+")); @@ -210,7 +210,7 @@ class CropParserRange : public CommandParserBase { public: private: boost::regex getRegex() const override { - return boost::regex("^\\s*[0-9]+\\s*:\\s*[0-9]+\\s*$"); + return boost::regex(R"(^\s*[0-9]+\s*:\s*[0-9]+\s*$)"); } std::string getSeparator() const override { return ":"; } }; @@ -319,7 +319,7 @@ void PerformIndexOperations::exec() { this->getProperty("ProcessingInstructions"); boost::regex re( - "^\\s*[0-9]+\\s*$|^(\\s*,*[0-9]+(\\s*(,|:|\\+|\\-)\\s*)*[0-9]*)*$"); + R"(^\s*[0-9]+\s*$|^(\s*,*[0-9]+(\s*(,|:|\+|\-)\s*)*[0-9]*)*$)"); if (!boost::regex_match(processingInstructions, re)) { throw std::invalid_argument("ProcessingInstructions are not well formed: " + processingInstructions); diff --git a/Framework/Algorithms/src/RealFFT.cpp b/Framework/Algorithms/src/RealFFT.cpp index 4c8d099ca5f9..43df23eaba29 100644 --- a/Framework/Algorithms/src/RealFFT.cpp +++ b/Framework/Algorithms/src/RealFFT.cpp @@ -52,7 +52,7 @@ void RealFFT::init() { std::vector fft_dir{"Forward", "Backward"}; declareProperty( "Transform", "Forward", boost::make_shared(fft_dir), - "The direction of the transform: \"Forward\" or \"Backward\"."); + R"(The direction of the transform: "Forward" or "Backward".)"); declareProperty( "IgnoreXBins", false, "Ignores the requirement that X bins be linear and of the same size. " diff --git a/Framework/Algorithms/test/AnyShapeAbsorptionTest.h b/Framework/Algorithms/test/AnyShapeAbsorptionTest.h index 04f3c54d9930..4cfbbc0ed295 100644 --- a/Framework/Algorithms/test/AnyShapeAbsorptionTest.h +++ b/Framework/Algorithms/test/AnyShapeAbsorptionTest.h @@ -157,8 +157,8 @@ class AnyShapeAbsorptionTest : public CxxTest::TestSuite { // Now test with a gauge volume used. // Create a small cylinder to be the gauge volume std::string cylinder = " "; - cylinder += " "; - cylinder += " "; + cylinder += R"( )"; + cylinder += R"( )"; cylinder += " "; cylinder += " "; cylinder += ""; diff --git a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h index 419b32dd424a..e72f802207da 100644 --- a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h +++ b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h @@ -113,8 +113,8 @@ class DetectorEfficiencyCorTest : public CxxTest::TestSuite { using namespace Mantid::DataObjects; std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; diff --git a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h index 161da6b66676..365d57e52f15 100644 --- a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h +++ b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h @@ -65,7 +65,7 @@ class GenerateIPythonNotebookTest : public CxxTest::TestSuite { create_test_workspace(workspaceName); std::string result[] = { - "{", " \"metadata\" : {", " \"name\" : \"Mantid Notebook\"", + "{", " \"metadata\" : {", R"( "name" : "Mantid Notebook")", " },", " \"nbformat\" : 3,", " \"nbformat_minor\" : 0,", " \"worksheets\" : [", " {"}; diff --git a/Framework/Crystal/inc/MantidCrystal/SortHKL.h b/Framework/Crystal/inc/MantidCrystal/SortHKL.h index f2a72e51f2a6..44a384ad92fe 100644 --- a/Framework/Crystal/inc/MantidCrystal/SortHKL.h +++ b/Framework/Crystal/inc/MantidCrystal/SortHKL.h @@ -43,7 +43,7 @@ class DLLExport SortHKL : public API::Algorithm { int version() const override { return 1; }; /// Algorithm's category for identification const std::string category() const override { - return "Crystal\\Peaks;DataHandling\\Text;Utility\\Sorting"; + return R"(Crystal\Peaks;DataHandling\Text;Utility\Sorting)"; } private: diff --git a/Framework/Crystal/src/SCDCalibratePanels.cpp b/Framework/Crystal/src/SCDCalibratePanels.cpp index 7ec8c15ed7bb..2fed712d7f9c 100644 --- a/Framework/Crystal/src/SCDCalibratePanels.cpp +++ b/Framework/Crystal/src/SCDCalibratePanels.cpp @@ -601,9 +601,9 @@ void SCDCalibratePanels::saveXmlFile( else scaley = 1.; - oss3 << " \n"; - oss3 << " \n"; oss3 << "\n"; } // for each bank in the group diff --git a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp index 2485a0cc1882..1faee75ccd85 100644 --- a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp +++ b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp @@ -324,7 +324,7 @@ void EstimateFitParameters::initConcrete() { "Additional constraints on tied parameters."); declareProperty( "Type", "Monte Carlo", - "Type of the algorithm: \"Monte Carlo\" or \"Cross Entropy\""); + R"(Type of the algorithm: "Monte Carlo" or "Cross Entropy")"); declareProperty("NOutputs", 10, "Number of parameter sets to output to " "OutputWorkspace. Unused if OutputWorkspace " "isn't set. (Monte Carlo only)"); diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h index c303d3859e2a..bb334703fc22 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h @@ -33,7 +33,7 @@ class DLLExport LoadCalFile : public API::Algorithm { int version() const override { return 1; }; /// Algorithm's category for identification const std::string category() const override { - return "DataHandling\\Text;Diffraction\\DataHandling\\CalFiles"; + return R"(DataHandling\Text;Diffraction\DataHandling\CalFiles)"; } static void getInstrument3WaysInit(Mantid::API::Algorithm *alg); diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h index 0b8fcb6276e8..a3bb7fbe5c79 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h @@ -54,7 +54,7 @@ class DLLExport LoadNXSPE : public API::IFileLoader { int version() const override { return 1; }; /// Algorithm's category for identification const std::string category() const override { - return "DataHandling\\Nexus;DataHandling\\SPE;Inelastic\\DataHandling"; + return R"(DataHandling\Nexus;DataHandling\SPE;Inelastic\DataHandling)"; } /// Returns a confidence value that this algorithm can load a file diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h index 1d99257bd0a9..e42f8268571d 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h @@ -31,7 +31,7 @@ class DLLExport SaveCalFile : public API::Algorithm { int version() const override { return 1; }; /// Algorithm's category for identification const std::string category() const override { - return "DataHandling\\Text;Diffraction\\DataHandling\\CalFiles"; + return R"(DataHandling\Text;Diffraction\DataHandling\CalFiles)"; } void saveCalFile(const std::string &calFileName, diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h index 4725bcbaa398..d0864a389faf 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h @@ -47,7 +47,7 @@ class DLLExport SaveNXSPE : public API::Algorithm { int version() const override { return (1); } /// Algorithm's category for identification const std::string category() const override { - return "DataHandling\\Nexus;DataHandling\\SPE;Inelastic\\DataHandling"; + return R"(DataHandling\Nexus;DataHandling\SPE;Inelastic\DataHandling)"; } private: diff --git a/Framework/DataHandling/src/GenerateGroupingPowder.cpp b/Framework/DataHandling/src/GenerateGroupingPowder.cpp index 1f421d452bf1..b5a0f7b0b655 100644 --- a/Framework/DataHandling/src/GenerateGroupingPowder.cpp +++ b/Framework/DataHandling/src/GenerateGroupingPowder.cpp @@ -37,7 +37,7 @@ int GenerateGroupingPowder::version() const { return 1; } /// Algorithm's category for identification. @see Algorithm::category const std::string GenerateGroupingPowder::category() const { - return "DataHandling\\Grouping;Transforms\\Grouping;Diffraction\\Utility"; + return R"(DataHandling\Grouping;Transforms\Grouping;Diffraction\Utility)"; } /** Initialize the algorithm's properties. diff --git a/Framework/DataHandling/src/GroupDetectors2.cpp b/Framework/DataHandling/src/GroupDetectors2.cpp index ffde59f3348e..d4fa1c0b7f88 100644 --- a/Framework/DataHandling/src/GroupDetectors2.cpp +++ b/Framework/DataHandling/src/GroupDetectors2.cpp @@ -1337,7 +1337,7 @@ std::map GroupDetectors2::validateInputs() { const std::string pattern = getPropertyValue("GroupingPattern"); boost::regex re( - "^\\s*[0-9]+\\s*$|^(\\s*,*[0-9]+(\\s*(,|:|\\+|\\-)\\s*)*[0-9]*)*$"); + R"(^\s*[0-9]+\s*$|^(\s*,*[0-9]+(\s*(,|:|\+|\-)\s*)*[0-9]*)*$)"); try { if (!pattern.empty() && !boost::regex_match(pattern, re)) { diff --git a/Framework/DataHandling/src/LoadISISNexus2.cpp b/Framework/DataHandling/src/LoadISISNexus2.cpp index 9f3a54baf0b8..8aabbd7aa3d6 100644 --- a/Framework/DataHandling/src/LoadISISNexus2.cpp +++ b/Framework/DataHandling/src/LoadISISNexus2.cpp @@ -1090,8 +1090,8 @@ void LoadISISNexus2::parseISODateTime(const std::string &datetime_iso, time = Poco::DateTimeFormatter::format(datetime_output, "%H:%M:%S", timezone_diff); } catch (Poco::SyntaxException &) { - date = "\?\?-\?\?-\?\?\?\?"; - time = "\?\?:\?\?:\?\?"; + date = R"(??-??-????)"; + time = R"(??:??:??)"; g_log.warning() << "Cannot parse end time from entry in Nexus file.\n"; } } diff --git a/Framework/DataHandling/src/LoadRKH.cpp b/Framework/DataHandling/src/LoadRKH.cpp index 870343459d7e..8a235dfba8bf 100644 --- a/Framework/DataHandling/src/LoadRKH.cpp +++ b/Framework/DataHandling/src/LoadRKH.cpp @@ -34,7 +34,7 @@ bool isUnit(const Mantid::Kernel::StringTokenizer &codes) { // 5. Close bracket std::string input = std::accumulate(codes.begin(), codes.end(), std::string("")); - std::string reg("^[06][\\w]+\\([/ \\w\\^-]+\\)$"); + std::string reg(R"(^[06][\w]+\([/ \w\^-]+\)$)"); boost::regex baseRegex(reg); return boost::regex_match(input, baseRegex); } diff --git a/Framework/DataHandling/src/LoadSESANS.cpp b/Framework/DataHandling/src/LoadSESANS.cpp index 05a971645273..3c1927e52754 100644 --- a/Framework/DataHandling/src/LoadSESANS.cpp +++ b/Framework/DataHandling/src/LoadSESANS.cpp @@ -103,7 +103,7 @@ int LoadSESANS::confidence(Kernel::FileDescriptor &descriptor) const { bool ffvFound = boost::starts_with(line, "FileFormatVersion"); // Next few lines should be key-value pairs - boost::regex kvPair("[\\w_]+\\s+[\\w\\d\\.\\-]+(\\s+[\\w\\d\\.\\-\\$]+)*"); + boost::regex kvPair(R"([\w_]+\s+[\w\d\.\-]+(\s+[\w\d\.\-\$]+)*)"); int kvPairsFound = 0; for (int i = 0; i < 3 && !line.empty(); i++) { @@ -246,7 +246,7 @@ ColumnMap LoadSESANS::consumeData(std::ifstream &infile, std::string &line, header + "\"", lineNum); - std::string numberRegex = "(-?\\d+(\\.\\d+)?([Ee][-\\+]?\\d+)?)"; + std::string numberRegex = R"((-?\d+(\.\d+)?([Ee][-\+]?\d+)?))"; // static_cast is safe as realistically our file is never going to have enough // columns to overflow std::string rawRegex = "^\\s*" + diff --git a/Framework/DataHandling/src/LoadSpice2D.cpp b/Framework/DataHandling/src/LoadSpice2D.cpp index d109f4cdc8b8..56fd40b1e19a 100644 --- a/Framework/DataHandling/src/LoadSpice2D.cpp +++ b/Framework/DataHandling/src/LoadSpice2D.cpp @@ -218,7 +218,7 @@ LoadSpice2D::parseDetectorDimensions(const std::string &dims_str) { std::pair dims = std::make_pair(0, 0); - boost::regex b_re_sig("INT\\d+\\[(\\d+),(\\d+)\\]"); + boost::regex b_re_sig(R"(INT\d+\[(\d+),(\d+)\])"); if (boost::regex_match(dims_str, b_re_sig)) { boost::match_results match; boost::regex_search(dims_str, match, b_re_sig); diff --git a/Framework/DataHandling/src/SetSample.cpp b/Framework/DataHandling/src/SetSample.cpp index ac802e9549be..1516b5b66dd6 100644 --- a/Framework/DataHandling/src/SetSample.cpp +++ b/Framework/DataHandling/src/SetSample.cpp @@ -111,11 +111,11 @@ V3D cylBaseCentre(const std::vector &cylCentre, double height, std::string axisXML(unsigned axisIdx) { switch (axisIdx) { case 0: - return ""; + return R"()"; case 1: - return ""; + return R"()"; case 2: - return ""; + return R"()"; default: return ""; } diff --git a/Framework/DataHandling/test/FindDetectorsInShapeTest.h b/Framework/DataHandling/test/FindDetectorsInShapeTest.h index e8918c444a31..9334ce32b75d 100644 --- a/Framework/DataHandling/test/FindDetectorsInShapeTest.h +++ b/Framework/DataHandling/test/FindDetectorsInShapeTest.h @@ -22,13 +22,13 @@ class FindDetectorsInShapeTest : public CxxTest::TestSuite { void testCuboidMiss() { std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += " "; xmlShape += " "; @@ -55,7 +55,7 @@ class FindDetectorsInShapeTest : public CxxTest::TestSuite { void testSphereMiss() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; @@ -66,7 +66,7 @@ class FindDetectorsInShapeTest : public CxxTest::TestSuite { void testSphereHit() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; @@ -77,8 +77,8 @@ class FindDetectorsInShapeTest : public CxxTest::TestSuite { void testCylinderHit() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -90,8 +90,8 @@ class FindDetectorsInShapeTest : public CxxTest::TestSuite { void testInfiniteCylinderHit() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; @@ -102,8 +102,8 @@ class FindDetectorsInShapeTest : public CxxTest::TestSuite { void testConeHitNoMonitors() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; diff --git a/Framework/DataHandling/test/MaskDetectorsInShapeTest.h b/Framework/DataHandling/test/MaskDetectorsInShapeTest.h index 91b4f68969c1..8e7b8951df5c 100644 --- a/Framework/DataHandling/test/MaskDetectorsInShapeTest.h +++ b/Framework/DataHandling/test/MaskDetectorsInShapeTest.h @@ -28,13 +28,13 @@ class MaskDetectorsInShapeTest : public CxxTest::TestSuite { void testCuboidMiss() { std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += " "; xmlShape += " "; @@ -44,8 +44,8 @@ class MaskDetectorsInShapeTest : public CxxTest::TestSuite { void testConeHitNoMonitors() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; diff --git a/Framework/Geometry/test/CrystalStructureTest.h b/Framework/Geometry/test/CrystalStructureTest.h index 0675a65b7994..ccd22be23818 100644 --- a/Framework/Geometry/test/CrystalStructureTest.h +++ b/Framework/Geometry/test/CrystalStructureTest.h @@ -29,7 +29,7 @@ class CrystalStructureTest : public CxxTest::TestSuite { m_scatterers->addScatterer( BraggScattererFactory::Instance().createScatterer( "IsotropicAtomBraggScatterer", - "{\"Element\":\"Si\",\"Position\":\"0,0,0\"}")); + R"({"Element":"Si","Position":"0,0,0"})")); } void testConstructionSpaceGroup() { diff --git a/Framework/Geometry/test/InstrumentDefinitionParserTest.h b/Framework/Geometry/test/InstrumentDefinitionParserTest.h index 45a1802fc948..ea47421b1f6a 100644 --- a/Framework/Geometry/test/InstrumentDefinitionParserTest.h +++ b/Framework/Geometry/test/InstrumentDefinitionParserTest.h @@ -891,7 +891,7 @@ class InstrumentDefinitionParserTest : public CxxTest::TestSuite { void testLocationsNaming() { std::string locations = - ""; + R"()"; detid_t numDetectors = 5; Instrument_sptr instr = loadInstrLocations(locations, numDetectors); @@ -903,7 +903,7 @@ class InstrumentDefinitionParserTest : public CxxTest::TestSuite { void testLocationsStaticValues() { std::string locations = - ""; + R"()"; detid_t numDetectors = 5; Instrument_sptr instr = loadInstrLocations(locations, numDetectors); @@ -986,13 +986,13 @@ class InstrumentDefinitionParserTest : public CxxTest::TestSuite { void testLocationsInvalidNoElements() { std::string locations = - ""; + R"()"; detid_t numDetectors = 2; TS_ASSERT_THROWS(loadInstrLocations(locations, numDetectors, true), Exception::InstrumentDefinitionError); - locations = ""; + locations = R"()"; TS_ASSERT_THROWS(loadInstrLocations(locations, numDetectors, true), Exception::InstrumentDefinitionError); @@ -1000,28 +1000,28 @@ class InstrumentDefinitionParserTest : public CxxTest::TestSuite { void testLocationsNotANumber() { std::string locations = - ""; + R"()"; detid_t numDetectors = 2; TS_ASSERT_THROWS_ANYTHING( loadInstrLocations(locations, numDetectors, true)); - locations = ""; + locations = R"()"; TS_ASSERT_THROWS_ANYTHING( loadInstrLocations(locations, numDetectors, true)); - locations = ""; + locations = R"()"; TS_ASSERT_THROWS_ANYTHING( loadInstrLocations(locations, numDetectors, true)); - locations = ""; + locations = R"()"; TS_ASSERT_THROWS_ANYTHING( loadInstrLocations(locations, numDetectors, true)); } void testLocationsNoCorrespondingStartAttr() { - std::string locations = ""; + std::string locations = R"()"; detid_t numDetectors = 2; TS_ASSERT_THROWS(loadInstrLocations(locations, numDetectors, true), diff --git a/Framework/Geometry/test/MDGeometryXMLParserTest.h b/Framework/Geometry/test/MDGeometryXMLParserTest.h index 00c7187b4343..4137571754c4 100644 --- a/Framework/Geometry/test/MDGeometryXMLParserTest.h +++ b/Framework/Geometry/test/MDGeometryXMLParserTest.h @@ -12,7 +12,7 @@ class MDGeometryXMLParserTest : public CxxTest::TestSuite { const std::string &yDimensionIdMapping, const std::string &zDimensionIdMapping, const std::string &tDimensionIdMapping) { - return std::string("") + + return std::string(R"()") + "" + "" + "Energy" + "150" + "0" + "1" + "" + diff --git a/Framework/Geometry/test/ObjCompAssemblyTest.h b/Framework/Geometry/test/ObjCompAssemblyTest.h index 4956b67a238a..06e893180228 100644 --- a/Framework/Geometry/test/ObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ObjCompAssemblyTest.h @@ -337,8 +337,8 @@ class ObjCompAssemblyTest : public CxxTest::TestSuite { std::stringstream obj_str; obj_str << ""; obj_str << ""; - obj_str << " "; + obj_str << R"(x="0" y="0" z="0" />)"; + obj_str << R"( )"; obj_str << ""; obj_str << ""; obj_str << ""; @@ -373,8 +373,8 @@ class ObjCompAssemblyTest : public CxxTest::TestSuite { std::stringstream obj_str; obj_str << ""; obj_str << ""; - obj_str << " "; + obj_str << R"(x="0" y="0" z="0" />)"; + obj_str << R"( )"; obj_str << ""; obj_str << ""; obj_str << ""; diff --git a/Framework/Geometry/test/ParObjCompAssemblyTest.h b/Framework/Geometry/test/ParObjCompAssemblyTest.h index 7710e6233bbc..1b119a3615ac 100644 --- a/Framework/Geometry/test/ParObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ParObjCompAssemblyTest.h @@ -112,8 +112,8 @@ class ParObjCompAssemblyTest : public CxxTest::TestSuite { std::stringstream obj_str; obj_str << ""; obj_str << ""; - obj_str << " "; + obj_str << R"(x="0" y="0" z="0" />)"; + obj_str << R"( )"; obj_str << ""; obj_str << ""; obj_str << ""; diff --git a/Framework/Geometry/test/ShapeFactoryTest.h b/Framework/Geometry/test/ShapeFactoryTest.h index b6335b198e54..3cef5552e508 100644 --- a/Framework/Geometry/test/ShapeFactoryTest.h +++ b/Framework/Geometry/test/ShapeFactoryTest.h @@ -23,13 +23,13 @@ class ShapeFactoryTest : public CxxTest::TestSuite { public: void testCuboid() { std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += " "; xmlShape += " "; @@ -48,8 +48,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { xmlShape += ""; xmlShape += ""; xmlShape += ""; - xmlShape += ""; - xmlShape += ""; // Note non-default axis. + xmlShape += R"()"; + xmlShape += R"()"; // Note non-default axis. xmlShape += ""; xmlShape += ""; @@ -80,7 +80,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite { xmlShape += ""; xmlShape += ""; xmlShape += ""; - xmlShape += ""; + xmlShape += R"()"; xmlShape += ""; xmlShape += ""; @@ -111,7 +111,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite { xmlShape += ""; xmlShape += ""; xmlShape += ""; - xmlShape += ""; + xmlShape += R"()"; xmlShape += ""; xmlShape += ""; @@ -139,10 +139,10 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testRelayShapeXML() { // Create a cuboid. std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; @@ -157,14 +157,14 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testHexahedron() { std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; @@ -180,21 +180,21 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testHexahedron2() { std::string xmlShape = " "; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += - " "; + R"( )"; xmlShape += " "; xmlShape += " "; @@ -209,9 +209,9 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testTaperedGuideDefaults() { std::string xmlShape = ""; - xmlShape += ""; + xmlShape += R"()"; xmlShape += ""; - xmlShape += ""; + xmlShape += R"()"; xmlShape += ""; xmlShape += ""; @@ -242,11 +242,11 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testTaperedGuideDifferentAxisAndCentre() { std::string xmlShape = ""; - xmlShape += ""; + xmlShape += R"()"; xmlShape += ""; - xmlShape += ""; - xmlShape += ""; - xmlShape += ""; + xmlShape += R"()"; + xmlShape += R"()"; + xmlShape += R"()"; xmlShape += ""; xmlShape += ""; @@ -278,7 +278,7 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testSphere() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; @@ -295,11 +295,11 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testTwoSpheres() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; @@ -318,11 +318,11 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testTwoSpheresNoAlgebraString() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; @@ -363,8 +363,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testCylinder() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -382,8 +382,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testCylinderNoAlgebraString() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -400,8 +400,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testCylinderTwoAlgebraStrings() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -506,8 +506,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testInfiniteCylinder() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; @@ -524,8 +524,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testCone() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -543,8 +543,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testConeUseDirectStringArgument() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -562,13 +562,13 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testComplement() { std::string xmlShape = " "; - xmlShape += ""; - xmlShape += ""; + xmlShape += R"()"; + xmlShape += R"()"; xmlShape += ""; xmlShape += ""; xmlShape += ""; xmlShape += ""; - xmlShape += ""; + xmlShape += R"()"; xmlShape += ""; xmlShape += ""; xmlShape += ""; @@ -589,8 +589,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testNoneExistingShape() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -604,8 +604,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testTypingErrorInSubElement() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; @@ -619,8 +619,8 @@ class ShapeFactoryTest : public CxxTest::TestSuite { void testTypingErrorInAttribute() { // algebra line is essential std::string xmlShape = " "; - xmlShape += " "; - xmlShape += " "; + xmlShape += R"( )"; + xmlShape += R"( )"; xmlShape += " "; xmlShape += " "; xmlShape += ""; diff --git a/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h b/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h index 80b53703646a..6880e34e3dbd 100644 --- a/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h +++ b/Framework/Geometry/test/StructureFactorCalculatorSummationTest.h @@ -63,7 +63,7 @@ class StructureFactorCalculatorSummationTest : public CxxTest::TestSuite { CompositeBraggScatterer_sptr scatterers = CompositeBraggScatterer::create(); scatterers->addScatterer(BraggScattererFactory::Instance().createScatterer( "IsotropicAtomBraggScatterer", - "{\"Element\":\"Si\",\"Position\":\"0,0,0\",\"U\":\"0.05\"}")); + R"({"Element":"Si","Position":"0,0,0","U":"0.05"})")); CrystalStructure si( UnitCell(5.43, 5.43, 5.43), diff --git a/Framework/ICat/src/GSoap/stdsoap2.cpp b/Framework/ICat/src/GSoap/stdsoap2.cpp index 140a634526da..fc03059c4637 100644 --- a/Framework/ICat/src/GSoap/stdsoap2.cpp +++ b/Framework/ICat/src/GSoap/stdsoap2.cpp @@ -16101,7 +16101,7 @@ int SOAP_FMAC2 soap_puthttphdr(struct soap *soap, int status, size_t count) { sizeof(soap->tmpbuf) - 80) { const char *t = strchr(s, ';'); sprintf(soap->tmpbuf, - "multipart/related; charset=utf-8; boundary=\"%s\"; type=\"", + R"(multipart/related; charset=utf-8; boundary="%s"; type=")", soap->mime.boundary); if (t) { strncat(soap->tmpbuf, s, t - s); diff --git a/Framework/Kernel/test/CatalogInfoTest.h b/Framework/Kernel/test/CatalogInfoTest.h index 0eaa2692f5d9..9f8e742c4b0c 100644 --- a/Framework/Kernel/test/CatalogInfoTest.h +++ b/Framework/Kernel/test/CatalogInfoTest.h @@ -86,7 +86,7 @@ class CatalogInfoTest : public CxxTest::TestSuite { std::string macPrefixPath = "/archive/NDXSANDALS/Instrument/data/cycle_05_3/ALF06716.LOG"; std::string winPrefixPath = - "\\NDXSANDALS\\Instrument\\data\\cycle_05_3\\ALF06716.LOG"; + R"(\NDXSANDALS\Instrument\data\cycle_05_3\ALF06716.LOG)"; std::string winDefaultPath = "\\\\isis\\inst$\\Instruments$" "\\NDXSANDALS\\Instrument\\data\\cycle_05_" "3\\ALF06716.LOG"; diff --git a/Framework/Kernel/test/ComputeResourceInfoTest.h b/Framework/Kernel/test/ComputeResourceInfoTest.h index 9e830ad03b03..89f745063222 100644 --- a/Framework/Kernel/test/ComputeResourceInfoTest.h +++ b/Framework/Kernel/test/ComputeResourceInfoTest.h @@ -211,7 +211,7 @@ class ComputeResourceInfoTest : public CxxTest::TestSuite { "" " " + simpleInstStr + + R"(" FileExtensions=".xyz">)" + simpleInstStr + crStr + " " ""; diff --git a/Framework/Kernel/test/MaterialXMLParserTest.h b/Framework/Kernel/test/MaterialXMLParserTest.h index 4391ccfd8060..f9fc269958bc 100644 --- a/Framework/Kernel/test/MaterialXMLParserTest.h +++ b/Framework/Kernel/test/MaterialXMLParserTest.h @@ -30,7 +30,7 @@ class MaterialXMLParserTest : public CxxTest::TestSuite { // all of the attributes are handled. //---------------------------------------------------------------------------- void test_Formula_Attribute() { - auto mat = parseMaterial(""); + auto mat = parseMaterial(R"()"); TS_ASSERT_EQUALS("vanadium", mat.name()); TS_ASSERT_DELTA(0.07223047, mat.numberDensity(), 1e-8); @@ -38,7 +38,7 @@ class MaterialXMLParserTest : public CxxTest::TestSuite { void test_AtomicNumber_Attribute() { auto mat = parseMaterial( - ""); + R"()"); TS_ASSERT_DELTA(mat.totalScatterXSection(), 18.5, 0.0001); TS_ASSERT_DELTA(mat.absorbXSection(), 4.49, 0.0001); diff --git a/Framework/Kernel/test/PropertyManagerTest.h b/Framework/Kernel/test/PropertyManagerTest.h index 926c339d2842..b8b496e8293a 100644 --- a/Framework/Kernel/test/PropertyManagerTest.h +++ b/Framework/Kernel/test/PropertyManagerTest.h @@ -248,7 +248,7 @@ class PropertyManagerTest : public CxxTest::TestSuite { mgr.declareProperty( Mantid::Kernel::make_unique>("ArrayProp")); - std::string jsonString = "{\"ArrayProp\":\"10,12,23\"}"; + std::string jsonString = R"({"ArrayProp":"10,12,23"})"; TS_ASSERT_THROWS_NOTHING(mgr.setProperties(jsonString)); TS_ASSERT_EQUALS(mgr.getPropertyValue("ArrayProp"), "10,12,23"); } @@ -581,13 +581,13 @@ class PropertyManagerTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(d, 23.4); TS_ASSERT_EQUALS(i, 22); - mgr.setPropertiesWithString("{\"double\": 14.0, \"int\":33}"); + mgr.setPropertiesWithString(R"({"double": 14.0, "int":33})"); d = mgr.getProperty("double"); i = mgr.getProperty("int"); TS_ASSERT_EQUALS(d, 14.0); TS_ASSERT_EQUALS(i, 33); - mgr.setPropertiesWithString("{\"double\": 12.3 ,\"int\":11}", {"int"}); + mgr.setPropertiesWithString(R"({"double": 12.3 ,"int":11})", {"int"}); d = mgr.getProperty("double"); i = mgr.getProperty("int"); TS_ASSERT_EQUALS(d, 12.3); diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h index b6de872d91f8..7e39035ac96b 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CloneMDWorkspace.h @@ -49,7 +49,7 @@ class DLLExport CloneMDWorkspace : public API::Algorithm { int version() const override { return 1; }; /// Algorithm's category for identification const std::string category() const override { - return "MDAlgorithms\\Utility\\Workspaces;MDAlgorithms\\Creation"; + return R"(MDAlgorithms\Utility\Workspaces;MDAlgorithms\Creation)"; } private: diff --git a/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp b/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp index 7a23dca48eab..fd7750cbc9bc 100644 --- a/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp +++ b/Framework/MDAlgorithms/src/CreateMDWorkspace.cpp @@ -41,7 +41,7 @@ std::vector parseNames(const std::string &names_string) { // The second part matches anything that doesn't contain a comma // NB, the order of the two parts matters - regex expression("\\[([^\\[]*)\\]|[^,]+"); + regex expression(R"(\[([^\[]*)\]|[^,]+)"); boost::sregex_token_iterator iter(names_string.begin(), names_string.end(), expression, 0); diff --git a/Framework/MDAlgorithms/src/MaskMD.cpp b/Framework/MDAlgorithms/src/MaskMD.cpp index 72970550e372..0487f4e75d77 100644 --- a/Framework/MDAlgorithms/src/MaskMD.cpp +++ b/Framework/MDAlgorithms/src/MaskMD.cpp @@ -28,7 +28,7 @@ std::vector parseDimensionNames(const std::string &names_string) { // unless they contain square brackets (so that it only matches inner pairs) // The second part matches anything that doesn't contain a comma // NB, the order of the two parts matters - regex expression("\\[([^\\[]*)\\]|[^,]+"); + regex expression(R"(\[([^\[]*)\]|[^,]+)"); boost::sregex_token_iterator iter(names_string.begin(), names_string.end(), expression, 0); diff --git a/Framework/RemoteAlgorithms/test/SimpleJSONTest.h b/Framework/RemoteAlgorithms/test/SimpleJSONTest.h index dc3b312fad0a..749a4f3d640a 100644 --- a/Framework/RemoteAlgorithms/test/SimpleJSONTest.h +++ b/Framework/RemoteAlgorithms/test/SimpleJSONTest.h @@ -143,7 +143,7 @@ class SimpleJSONTest : public CxxTest::TestSuite { void test_JSONObjectExampleServerResponseLonger() { const std::string longerJsonStr = - "{\"v1\": \"[1, a, 3]\",\"" + errName + "\":\"" + errVal + "\"}"; + R"({"v1": "[1, a, 3]",")" + errName + "\":\"" + errVal + "\"}"; std::istringstream inputLong(longerJsonStr); std::string res; @@ -156,7 +156,7 @@ class SimpleJSONTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(true, ol[errName].getValue(res)); TS_ASSERT_EQUALS(res, errVal); - const std::string l2JsonStr = "{\"v1\": \"[1, a, 3]\",\"" + errName + + const std::string l2JsonStr = R"({"v1": "[1, a, 3]",")" + errName + "\":\"" + errVal + "\", \"" + versName + "\": \"" + versVal + "\" }" "\"}"; @@ -173,7 +173,7 @@ class SimpleJSONTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(res, versVal); const std::string l3JsonStr = "{ \"" + impName + "\": \"" + impVal + - "\", \"v1\": \"[1, a, longer str, a4]\",\"" + + R"(", "v1": "[1, a, longer str, a4]",")" + errName + "\":\"" + errVal + "\", \"" + versName + "\": \"" + versVal + "\" }" "\"}"; @@ -201,7 +201,7 @@ class SimpleJSONTest : public CxxTest::TestSuite { TS_ASSERT_THROWS(initFromStream(jo, istr), JSONParseException); TS_ASSERT_THROWS_NOTHING(prettyPrint(jo, out, 0)); - std::string strOK = "{ \"key1\": \"val1\"}"; + std::string strOK = R"({ "key1": "val1"})"; std::istringstream istrOK(strOK); JSONObject j2; TS_ASSERT_THROWS_NOTHING(initFromStream(j2, istrOK)); diff --git a/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h b/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h index ca1f9a7dca37..0ac25091d436 100644 --- a/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h +++ b/Framework/RemoteJobManagers/test/MantidWebServiceAPIJobManagerTest.h @@ -54,8 +54,7 @@ class MockMantidAPIStatusNotFoundWithErrMsg : public MantidWebServiceAPIJobManager { public: MockMantidAPIStatusNotFoundWithErrMsg() : MantidWebServiceAPIJobManager() { - is.str("{\"foo\": \"err_msg\", \"Err_Msg\"=\"fake error\", \"param\": " - "\"1\", }"); + is.str(R"({"foo": "err_msg", "Err_Msg"="fake error", "param": "1", })"); } protected: diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h index 3af9624cf8bf..eb0672a6c575 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h @@ -534,7 +534,7 @@ class PoldiPeakCollectionHelpers { BraggScatterer_sptr atomSi = BraggScattererFactory::Instance().createScatterer( "IsotropicAtomBraggScatterer", - "{\"Element\":\"Si\",\"Position\":\"0,0,0\",\"U\":\"0.005\"}"); + R"({"Element":"Si","Position":"0,0,0","U":"0.005"})"); CompositeBraggScatterer_sptr atoms = CompositeBraggScatterer::create(); atoms->addScatterer(atomSi); diff --git a/Framework/SINQ/test/PoldiPeakCollectionTest.h b/Framework/SINQ/test/PoldiPeakCollectionTest.h index 5f91b3dd074c..89d64a02f269 100644 --- a/Framework/SINQ/test/PoldiPeakCollectionTest.h +++ b/Framework/SINQ/test/PoldiPeakCollectionTest.h @@ -390,10 +390,10 @@ class PoldiPeakCollectionTest : public CxxTest::TestSuite { BraggScatterer_sptr cs = BraggScattererFactory::Instance().createScatterer( "IsotropicAtomBraggScatterer", - "{\"Element\":\"Cs\",\"Position\":\"0.5,0.5,0.5\",\"U\":\"0.005\"}"); + R"({"Element":"Cs","Position":"0.5,0.5,0.5","U":"0.005"})"); BraggScatterer_sptr cl = BraggScattererFactory::Instance().createScatterer( "IsotropicAtomBraggScatterer", - "{\"Element\":\"Cl\",\"Position\":\"0,0,0\",\"U\":\"0.005\"}"); + R"({"Element":"Cl","Position":"0,0,0","U":"0.005"})"); CompositeBraggScatterer_sptr atoms = CompositeBraggScatterer::create(); atoms->addScatterer(cs); diff --git a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp index 4eeb696bb68a..efa55cce5002 100644 --- a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp +++ b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp @@ -252,7 +252,7 @@ Workspace2D_sptr maskSpectra(Workspace2D_sptr workspace, workspace->setInstrument(instrument); std::string xmlShape = " "; - xmlShape += " "; + xmlShape += R"( )"; xmlShape += " "; xmlShape += ""; xmlShape += " "; diff --git a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp index ca1966529fef..e5eda43ad15f 100644 --- a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp +++ b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp @@ -231,7 +231,7 @@ void EQSANSLoad::readModeratorPosition(const std::string &line) { void EQSANSLoad::readSourceSlitSize(const std::string &line) { boost::regex re_key("wheel", boost::regex::icase); if (boost::regex_search(line, re_key)) { - boost::regex re_sig("([1-8]) wheel[ ]*([1-3])[ \\t]*=[ \\t]*(\\w+)"); + boost::regex re_sig(R"(([1-8]) wheel[ ]*([1-3])[ \t]*=[ \t]*(\w+))"); boost::smatch posVec; if (boost::regex_search(line, posVec, re_sig)) { if (posVec.size() == 4) { From c21a761f4afa45d3a4999109088247e66da325f9 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Tue, 20 Mar 2018 15:49:10 +0000 Subject: [PATCH 325/364] Re #22154: Applied clang-format patch. --- .../CurveFitting/src/Algorithms/EstimateFitParameters.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp index 1faee75ccd85..763a15975a2c 100644 --- a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp +++ b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp @@ -322,9 +322,8 @@ void EstimateFitParameters::initConcrete() { declareProperty("NSamples", 100, "Number of samples."); declareProperty("Constraints", "", "Additional constraints on tied parameters."); - declareProperty( - "Type", "Monte Carlo", - R"(Type of the algorithm: "Monte Carlo" or "Cross Entropy")"); + declareProperty("Type", "Monte Carlo", + R"(Type of the algorithm: "Monte Carlo" or "Cross Entropy")"); declareProperty("NOutputs", 10, "Number of parameter sets to output to " "OutputWorkspace. Unused if OutputWorkspace " "isn't set. (Monte Carlo only)"); From 86bbc1964e78ddc55fe902b1c1e0fffdc99541f7 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 20 Mar 2018 16:11:28 +0000 Subject: [PATCH 326/364] Use sphinx-build if sphinx.__main__ does not exist Older versions of Sphinx do not ship with Sphinx.__main__ so python -m sphinx does not work as expected. This assumes we are on an old Linux distribution and falls back to sphinx-build --- buildconfig/CMake/FindSphinx.cmake | 14 +++----------- buildconfig/CMake/FindSphinx.py | 3 ++- dev-docs/CMakeLists.txt | 15 +++++++++++++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/buildconfig/CMake/FindSphinx.cmake b/buildconfig/CMake/FindSphinx.cmake index ddffff3e2e56..4db68670cd43 100644 --- a/buildconfig/CMake/FindSphinx.cmake +++ b/buildconfig/CMake/FindSphinx.cmake @@ -11,22 +11,14 @@ # main() #============================================================= - -FIND_FILE(_find_sphinx_py FindSphinx.py PATHS ${CMAKE_MODULE_PATH}) - -if (version_string) # chop out the version number - string (REGEX REPLACE ".*([0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1" SPHINX_VERSION ${version_string}) -endif() - +find_file (_find_sphinx_py FindSphinx.py PATHS ${CMAKE_MODULE_PATH}) # import sphinx-build to attempt to get the version execute_process (COMMAND ${PYTHON_EXECUTABLE} ${_find_sphinx_py} OUTPUT_VARIABLE sphinx_output RESULT_VARIABLE sphinx_result) +string (STRIP "${sphinx_output}" sphinx_output) -if (${sphinx_result} STREQUAL "0")# AND version_string) - if (version_string) - list(GET sphinx_output 0 version_string) - endif() +if (${sphinx_result} STREQUAL "0") list(GET sphinx_output 1 SPHINX_PACKAGE_DIR) else() message(STATUS "failed to run FindSphinx.py returned ${sphinx_result}") diff --git a/buildconfig/CMake/FindSphinx.py b/buildconfig/CMake/FindSphinx.py index 3e2ba70b4e35..ecb75f60f01b 100644 --- a/buildconfig/CMake/FindSphinx.py +++ b/buildconfig/CMake/FindSphinx.py @@ -1,2 +1,3 @@ +import os.path as osp import sphinx -print('{0};{1}'.format(sphinx.__version__, sphinx.package_dir)) +print('{0};{1}'.format(sphinx.__version__, osp.dirname(sphinx.__file__))) diff --git a/dev-docs/CMakeLists.txt b/dev-docs/CMakeLists.txt index 38c441b03ecc..b7e1b6612a40 100644 --- a/dev-docs/CMakeLists.txt +++ b/dev-docs/CMakeLists.txt @@ -6,9 +6,20 @@ set ( BUILDER html ) set ( OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${BUILDER} ) set ( DOCTREE_DIR ${CMAKE_CURRENT_BINARY_DIR}/doctree ) +# We try to execute Sphinx directly through python -m to avoid problems +# with the startup scripts on Windows. They are not always reliable +# as they can have hardcoded paths in them. However, older versions of +# Sphinx dont't allow python -m execution. Assume +# we are running on Linux and `sphinx-build` is available in these cases +if ( EXISTS ${SPHINX_PACKAGE_DIR}/__main__.py ) + set ( SPHINX_BUILD "python -m sphinx" ) +else () + set ( SPHINX_BUILD "sphinx-build" ) +endif () + add_custom_target ( dev-docs-${BUILDER} - COMMAND python -m sphinx -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR} - COMMENT "Building html developer documentation" ) + COMMAND ${SPHINX_BUILD} -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR} + COMMENT "Building html developer documentation" ) # Group within VS and exclude from whole build set_target_properties ( dev-docs-html PROPERTIES FOLDER "Documentation" EXCLUDE_FROM_DEFAULT_BUILD 1 From 598a4f21b8e78ed95f42a73f798f9447b59444fe Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Tue, 20 Mar 2018 17:10:26 +0000 Subject: [PATCH 327/364] Add MVP tutorial to dev-docs --- dev-docs/source/MVPTutorial/AddButton.rst | 98 ++++++++++ dev-docs/source/MVPTutorial/AddComboBox.rst | 21 ++ dev-docs/source/MVPTutorial/AddLabel.rst | 19 ++ dev-docs/source/MVPTutorial/AddLineEdit.rst | 23 +++ dev-docs/source/MVPTutorial/AddSpinBox.rst | 16 ++ dev-docs/source/MVPTutorial/CompleteGUI.rst | 179 ++++++++++++++++++ .../MVPTutorial/ExtractInfoFromView.rst | 67 +++++++ dev-docs/source/MVPTutorial/Introduction.rst | 26 +++ dev-docs/source/MVPTutorial/Layouts.rst | 39 ++++ dev-docs/source/MVPTutorial/MatPlotLib.rst | 73 +++++++ dev-docs/source/MVPTutorial/Mocking.rst | 76 ++++++++ .../source/MVPTutorial/MockingExercise.rst | 11 ++ .../MVPTutorial/MockingExerciseSolution.rst | 44 +++++ dev-docs/source/MVPTutorial/Model.rst | 36 ++++ dev-docs/source/MVPTutorial/ModelExercise.rst | 18 ++ .../MVPTutorial/ModelExerciseSolution.rst | 33 ++++ dev-docs/source/MVPTutorial/MultipleViews.rst | 86 +++++++++ .../source/MVPTutorial/PresenterExercise.rst | 18 ++ .../MVPTutorial/PresenterExerciseSolution.rst | 149 +++++++++++++++ .../MVPTutorial/ReceivingSignalFromView.rst | 123 ++++++++++++ dev-docs/source/MVPTutorial/Tables.rst | 49 +++++ dev-docs/source/MVPTutorial/ViewExercise1.rst | 23 +++ .../MVPTutorial/ViewExercise1Solution.rst | 112 +++++++++++ dev-docs/source/MVPTutorial/index.rst | 38 ++++ 24 files changed, 1377 insertions(+) create mode 100644 dev-docs/source/MVPTutorial/AddButton.rst create mode 100644 dev-docs/source/MVPTutorial/AddComboBox.rst create mode 100644 dev-docs/source/MVPTutorial/AddLabel.rst create mode 100644 dev-docs/source/MVPTutorial/AddLineEdit.rst create mode 100644 dev-docs/source/MVPTutorial/AddSpinBox.rst create mode 100644 dev-docs/source/MVPTutorial/CompleteGUI.rst create mode 100644 dev-docs/source/MVPTutorial/ExtractInfoFromView.rst create mode 100644 dev-docs/source/MVPTutorial/Introduction.rst create mode 100644 dev-docs/source/MVPTutorial/Layouts.rst create mode 100644 dev-docs/source/MVPTutorial/MatPlotLib.rst create mode 100644 dev-docs/source/MVPTutorial/Mocking.rst create mode 100644 dev-docs/source/MVPTutorial/MockingExercise.rst create mode 100644 dev-docs/source/MVPTutorial/MockingExerciseSolution.rst create mode 100644 dev-docs/source/MVPTutorial/Model.rst create mode 100644 dev-docs/source/MVPTutorial/ModelExercise.rst create mode 100644 dev-docs/source/MVPTutorial/ModelExerciseSolution.rst create mode 100644 dev-docs/source/MVPTutorial/MultipleViews.rst create mode 100644 dev-docs/source/MVPTutorial/PresenterExercise.rst create mode 100644 dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst create mode 100644 dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst create mode 100644 dev-docs/source/MVPTutorial/Tables.rst create mode 100644 dev-docs/source/MVPTutorial/ViewExercise1.rst create mode 100644 dev-docs/source/MVPTutorial/ViewExercise1Solution.rst create mode 100644 dev-docs/source/MVPTutorial/index.rst diff --git a/dev-docs/source/MVPTutorial/AddButton.rst b/dev-docs/source/MVPTutorial/AddButton.rst new file mode 100644 index 000000000000..f4a07fbdce9a --- /dev/null +++ b/dev-docs/source/MVPTutorial/AddButton.rst @@ -0,0 +1,98 @@ +=============== +Adding a Button +=============== + +In this task a GUI is created containing a single button. + +The View +######## + +The below code creates a QWidget containing a single button. When the +button is pressed it will print a message to the terminal screen. It +should be noted that in practice this should be avoided and will be +discussed in `this section `_. + +First we need to import the relevant packages, this includes PyQt. + +.. code-block:: python + + from __future__ import (absolute_import,division,print_function) + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + +We then create the View class as a QWidget. Each View will have a +parent. As a result, the View will automatically be destroyed if the +parent is destroyed (unless the View has been removed, via docking, +from the parent). + +.. code-block:: python + + class view(QtGui.QWidget): + + def __init__(self, parent=None): + super(view, self).__init__(parent) + +Next we create a layout and add a button to it + +.. code-block:: python + + grid = QtGui.QGridLayout() + self.button = QtGui.QPushButton('Hi', self) + self.button.setStyleSheet("background-color:lightgrey") + + # connect button to signal + self.button.clicked.connect(self.btn_click) + # add button to layout + grid.addWidget(self.button) + # set the layout for the view widget + self.setLayout(grid) + +The above connect statement means that when the button is pressed, the +function ``btn_click`` is called: + +.. code-block:: python + + def btn_click(self): + print("Hello world") + +The Main +######## + +To run the GUI we need a 'main' module. Assuming that the above has +all been saved in ``view.py``, the ``main.py`` will contain: + +.. code-block:: python + + from __future__ import (absolute_import,division,print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import sys + + import view + + """ + A wrapper class for setting the main window + """ + class demo(QtGui.QMainWindow): + def __init__(self,parent=None): + super(demo,self).__init__(parent) + + self.window=QtGui.QMainWindow() + my_view = view.view() + # set the view for the main window + self.setCentralWidget(my_view) + self.setWindowTitle("view tutorial") + + def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + + app = qapp() + window = demo() + window.show() + app.exec_() diff --git a/dev-docs/source/MVPTutorial/AddComboBox.rst b/dev-docs/source/MVPTutorial/AddComboBox.rst new file mode 100644 index 000000000000..c71624607163 --- /dev/null +++ b/dev-docs/source/MVPTutorial/AddComboBox.rst @@ -0,0 +1,21 @@ +============== +Add a ComboBox +============== + +A ComboBox is useful when there is a finite list of options that the +user can choose from. If a line edit was used instead then a typo +would prevent the GUI from working correctly; a ComboBox prevents this +possibility. + +The following code should be added to the View's ``__init__`` function. + +.. code-block:: python + + self.combo = QtGui.QComboBox() + options = ["one", "two", "three"] + self.combo.addItems(options) + grid.addWidget(self.combo) + +The first line creates a ComboBox widget. The second line defines the +options that will be displayed within the ComboBox and the third line +adds the options to the ComboBox. The last line adds it to the layout. diff --git a/dev-docs/source/MVPTutorial/AddLabel.rst b/dev-docs/source/MVPTutorial/AddLabel.rst new file mode 100644 index 000000000000..da59ee92c3ea --- /dev/null +++ b/dev-docs/source/MVPTutorial/AddLabel.rst @@ -0,0 +1,19 @@ +============== +Adding a Label +============== + +In this section we will add a label to the GUI. A label is a text +display that cannot be edited by the user. + +To add a label we need to add three lines to the View. The first +creates the label widget, the second assigns the label's value (what +it will display) and the last line adds it to the layout of the view. + +.. code-block:: python + + self.label = QtGui.QLabel() + self.label.setText("Button") + grid.addWidget(self.label) + +This code should be added in the View's constructor (ie its +``__init__`` function). diff --git a/dev-docs/source/MVPTutorial/AddLineEdit.rst b/dev-docs/source/MVPTutorial/AddLineEdit.rst new file mode 100644 index 000000000000..b2c4cbfb978d --- /dev/null +++ b/dev-docs/source/MVPTutorial/AddLineEdit.rst @@ -0,0 +1,23 @@ +============== +Add a LineEdit +============== + +Sometimes it is necessary for the user to input some information. The +most versatile way of allowing this is to use a line edit, which +allows a user to enter arbitrary text. Adding the following code to +the ``__init__`` function of the View will add a line edit: + +.. code-block:: python + + self.text = QtGui.QLineEdit() + grid.addWidget(self.text) + +It is possible to have a default value within the line edit. It is +also possible to make it impossible for the user to modify the line +edit (useful for tables). + +Care should be taken before using a line edit as it can give a user +too much freedom. If you know that the input is an integer then a +`spin box `_ is better. If there is a finite list of +possible options then a `combo box `_ would be a +better choice. diff --git a/dev-docs/source/MVPTutorial/AddSpinBox.rst b/dev-docs/source/MVPTutorial/AddSpinBox.rst new file mode 100644 index 000000000000..86a3abb414f4 --- /dev/null +++ b/dev-docs/source/MVPTutorial/AddSpinBox.rst @@ -0,0 +1,16 @@ +============== +Add a Spin Box +============== + +A spin box is a useful way to ensure that the user only selects +integer values. The user can type an integer into the spin box or +increment the value using the arrows. It is also possible to place +constraints on the spin box such as a maximum value. + +.. code-block:: python + + self.spin = QtGui.QSpinBox() + grid.addWidget(self.spin) + +To add a spin box to the GUI the above code needs to be added to the +``__init__`` function of the View. diff --git a/dev-docs/source/MVPTutorial/CompleteGUI.rst b/dev-docs/source/MVPTutorial/CompleteGUI.rst new file mode 100644 index 000000000000..af641f6f3ed3 --- /dev/null +++ b/dev-docs/source/MVPTutorial/CompleteGUI.rst @@ -0,0 +1,179 @@ +=========================== +Complete GUI from Exercises +=========================== + +Main module +########### + +.. code-block:: python + + from __future__ import (absolute_import,division,print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import sys + + import model + import masterView + import masterPresenter + + + """ + A wrapper class for setting the main window + """ + class demo(QtGui.QMainWindow): + def __init__(self, parent=None): + super(demo,self).__init__(parent) + + data_model = model.DataGenerator() + colour_model = model.ColourConvertor() + + self.window = QtGui.QMainWindow() + + my_view = masterView.MasterView(parent=self) + self.master_presenter = masterPresenter.MasterPresenter(my_view, data_model, colour_model) + + # set the view for the main window + self.setCentralWidget(my_view) + self.setWindowTitle("view tutorial") + + def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + + app = qapp() + window = demo() + window.show() + app.exec_() + +which has the addition of the data and colour models being passed to +the Presenter. This makes it easier for us to replace the Model at a +later date. + +Master View +########### + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import view + import plotView + + import numpy as np + + class MasterView(QtGui.QWidget): + + def __init__(self, parent=None): + super(MasterView, self).__init__(parent) + + grid = QtGui.QVBoxLayout(self) + self.plot_view = plotView.PlotView() + self.options_view=view.view() + + grid.addWidget(self.plot_view) + grid.addWidget(self.options_view) + + self.setLayout(grid) + + def getOptionView(self): + return self.options_view + + def getPlotView(self): + return self.plot_view + +Master Presenter +################ + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import model + import presenter + import plotPresenter + + class MasterPresenter(object): + + def __init__(self, view, data_model, colour_model): + self.view = view + + self.data_model = data_model + self.colour_model = colour_model + + colours = self.colour_model.getColourSelection() + + self.presenter = presenter.Presenter(self.view.getOptionView(), colours) + self.plot_presenter = plotPresenter.PlotPresenter(self.view.getPlotView()) + # connect statements + self.view.getOptionView().plotSignal.connect(self.updatePlot) + + # handle signals + def updatePlot(self): + # only care about the colour if the button is pressed + colour, freq,phi = self.presenter.getPlotInfo() + grid_lines = self.presenter.getGridLines() + + self.data_model.genData(freq,phi ) + x_data = self.data_model.getXData() + y_data = self.data_model.getYData() + + self.plot_presenter.plot(x_data, y_data, grid_lines, colour) + +The signal from the View is caught here and the models are used to create the correct plot. + +Plot Presenter +############## + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + class PlotPresenter(object): + + def __init__(self, view): + self.view = view + + def plot(self, x_data, y_data, grid_lines, colour_code): + self.view.addData(x_data, y_data, grid_lines, colour_code, "x") + +PlotView +######## + +Unchanged from `MatPlotLib and MVP `_. + +Presenter +######### + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + + class Presenter(object): + + def __init__(self, view, colours): + self.view = view + self.view.setColours(colours) + + def getPlotInfo(self): + return str(self.view.getColour()), self.view.getFreq(), self.view.getPhase() + + def getGridLines(self): + return self.view.getGridLines() + +View +#### + +Unchanged from `Model Exercise Solution `_. + +Model +##### + +Unchanged from `Model Exercise Solution `_. diff --git a/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst b/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst new file mode 100644 index 000000000000..eed9386f820c --- /dev/null +++ b/dev-docs/source/MVPTutorial/ExtractInfoFromView.rst @@ -0,0 +1,67 @@ +==================================== +Extracting Information from the View +==================================== + +The Presenter will need a way to obtain information from the +View. This can be done by **get** methods, as with normal +classes. Here is a simple example of how a **get** method for the view can +be used. + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + + class view(QtGui.QWidget): + + doSomethingSignal = QtCore.pyqtSignal() + + def __init__(self, parent=None): + super(view, self).__init__(parent) + + self.button = QtGui.QPushButton('Hi', self) + self.button.setStyleSheet("background-color:lightgrey") + # connect button to signal + self.button.clicked.connect(self.btn_click) + + self.label = QtGui.QLabel() + self.label.setText("Button") + + # add widgets to layout + self.sub_layout = QtGui.QHBoxLayout() + self.sub_layout.addWidget(self.label) + self.sub_layout.addWidget(self.button) + + grid = QtGui.QVBoxLayout(self) + grid.addLayout(self.sub_layout) + + self.value = QtGui.QLineEdit() + grid.addWidget(self.value) + + + # set the layout for the view widget + self.setLayout(grid) + + #send signals + def btn_click(self): + print ("hellow from view") + self.doSomethingSignal.emit() + + def getValue(self): + return float(self.value.text()) + +The last function ``getValue`` returns the value of the line +edit. Since ``text()`` returns a string the output is type cast into a +float. + +The Presenter has the following code added to the ``handleButton`` method: + +.. code-block:: python + + value = self.view.getValue() + print("Value is "+str(value)) + +which gets the value from the View and then prints it to the screen. diff --git a/dev-docs/source/MVPTutorial/Introduction.rst b/dev-docs/source/MVPTutorial/Introduction.rst new file mode 100644 index 000000000000..3eff0214525f --- /dev/null +++ b/dev-docs/source/MVPTutorial/Introduction.rst @@ -0,0 +1,26 @@ +================ +MVP Introduction +================ + +The MVP (model, view, presenter) pattern is a set of guidelines for +creating easy to maintain GUIs (graphical user interfaces). In +general: + +- The View contains the 'look' of the GUI +- The Model does the 'hard sums' for the GUI (e.g. runs algorithms) +- The Presenter acts as a go between for the View and Model + +It is important to note that the View should be simple (no logic) and +is usually not tested. The Model can be tested in a similar way to +other Python tests. The Model and View never communicate with each +other directly. The Presenter will extract relevant information from +the View and pass it to the Model. The Presenter may then pass the +result of the Model to the View. The Presenter will contain the GUI +logic and is tested using **mocking**. + +These are guidelines and do not form a set of rules. It is sometimes +open to interpretation if some files are classed as a View or a Model +(this will be discussed in detail later). + +A more thorough explanation of MVP can be found at +:ref:`dev-docs-mvp-intro`. diff --git a/dev-docs/source/MVPTutorial/Layouts.rst b/dev-docs/source/MVPTutorial/Layouts.rst new file mode 100644 index 000000000000..43a1bba04cb2 --- /dev/null +++ b/dev-docs/source/MVPTutorial/Layouts.rst @@ -0,0 +1,39 @@ +======= +Layouts +======= + +In the previous task a label was added to the View. However, the label +appeared below the button. It would be sensible to place the label +next to the button. This is possible by using **layouts**. + +So far we have used the vertical layout (``QtGui.QVBoxLayout``) and we +will now use the horizontal layout. It is possible to add sub-layouts +to a layout, which we will do here by adding a horizontal layout to +the vertical one. The order in which widgets are added to the layout +will determine their location. + +In the View we will replace the ``__init__`` with the following: + +.. code-block:: python + + def __init__(self, parent=None): + super(view, self).__init__(parent) + + self.button = QtGui.QPushButton('Hi', self) + self.button.setStyleSheet("background-color:lightgrey") + + # connect button to signal + self.button.clicked.connect(self.btn_click) + self.label = QtGui.QLabel() + self.label.setText("Button") + + # add widgets to layout + self.sub_layout = QtGui.QHBoxLayout() + self.sub_layout.addWidget(self.label) + self.sub_layout.addWidget(self.button) + + grid = QtGui.QVBoxLayout(self) + grid.addLayout(self.sub_layout) + + # set the layout for the view widget + self.setLayout(grid) diff --git a/dev-docs/source/MVPTutorial/MatPlotLib.rst b/dev-docs/source/MVPTutorial/MatPlotLib.rst new file mode 100644 index 000000000000..1f26eba453cd --- /dev/null +++ b/dev-docs/source/MVPTutorial/MatPlotLib.rst @@ -0,0 +1,73 @@ +================== +MatPlotLib and MVP +================== + +The next step towards the goal of creating a GUI that allows users to +manipulate a sine wave plot, is to produce the plot itself. + +For the purposes of this tutorial it is assumed that the user is +familiar with matplotlib, if not see `MatPlotLib documentation +`_. + +The MatPlotLib functions could be considered to be a Model or a View +and there is no correct answer to which. It could be a Model as it +does something with the data, however it could be considered to be a +view as (in this case) it is used purely as a visual +representation. This ambiguity is why MVP is only a pattern and not a +set of rules. On this occasion it has been decided that it should be a +View. + +This view will exist alongside with the view from the exercise. So we +will need to call it something different, such as PlotView. + +The View has the following imports: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + import matplotlib.pyplot as plt + + from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas + +The fourth line imports MatPlotLib and the last line allows it to +interface with the GUI. + +The main class is shown below and contains methods for adding data to +the plot and creating an empty plot (no data). + +.. code-block:: python + + class PlotView(QtGui.QWidget): + def __init__(self, parent=None): + super(PlotView, self).__init__(parent) + + self.figure = plt.figure() + grid = QtGui.QVBoxLayout(self) + self.draw() + self.canvas = self.getWidget() + grid.addWidget(self.canvas) + self.setLayout(grid) + + def draw(self): + ax = self.figure.add_subplot(111) + ax.clear() + ax.set_xlim([0.0, 10.5]) + ax.set_ylim([-1.05, 1.05]) + ax.set_xlabel("time ($s$)") + ax.set_ylabel("$f(t)$") + return ax + + def getWidget(self): + return FigureCanvas(self.figure) + + def addData(self, xvalues, yvalues, colour, marker): + ax = self.draw() + ax.plot(xvalues, yvalues, color=colour, marker=marker, linestyle="--") + self.canvas.draw() + +The ``draw`` method creates the plot area without any data. The widget +is obtained from the ``getWidget`` function. The final method adds +data to the plot area, the ``self.canvas.draw()`` updates the plot +area so it will contain the data. diff --git a/dev-docs/source/MVPTutorial/Mocking.rst b/dev-docs/source/MVPTutorial/Mocking.rst new file mode 100644 index 000000000000..631779fc777d --- /dev/null +++ b/dev-docs/source/MVPTutorial/Mocking.rst @@ -0,0 +1,76 @@ +===================== +Mocking the Presenter +===================== + +The view should be so simple that it does not require +testing. However, the presenter contains logic and should therefore be +tested. When testing the presenter we do not want to create the actual +GUI, instead we just want to ensure that the correct calls are made, +this is done via mocking see `unittest docs +`_ for +a detailed discussion. Here we will have a brief discussion of the +main points. + +First are the import statements + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import sys + import presenter + import view + + import unittest + if sys.version_info.major == 3: + from unittest import mock + else: + import mock + +A different import is used for ``mock``, depending on whether we're +using Python 2 or 3. + +The test class is then initialised: + +.. code-block:: python + + class presenterTest(unittest.TestCase): + def setUp(self): + self.view = mock.create_autospec(view.view) + + # mock view + self.view.doSomethingSignal = mock.Mock() + self.view.btn_click = mock.Mock() + self.view.getValue = mock.Mock(return_value=3.14) + + self.presenter = presenter.Presenter(self.view) + +``create_autospec`` mocks the class contained within the brackets. We +then need to explicitly mock the methods using ``mock.Mock``. In +addtion, when a return value is needed, this is provided in the call +to ``mock.Mock``. + +A test is shown below: + +.. code-block:: python + + def test_doSomething(self): + self.presenter.handleButton() + assert(self.view.getValue.call_count == 1) + +We call the ``handleButton`` function and then use ``call_count`` to +ensure that the method from the View is called the correct number of +times. This is a more robust method for checking how many times a +function is called. + +There is a ``assert_called_once`` function however this should be +avoided as it can easily lead to errors. This is because it is +expected that the function ``assert_called_twice`` exists but it does +not, however when you run the test it will always pass. + +The last bit of code is to execute the tests: + +.. code-block:: python + + if __name__ == "__main__": + unittest.main() diff --git a/dev-docs/source/MVPTutorial/MockingExercise.rst b/dev-docs/source/MVPTutorial/MockingExercise.rst new file mode 100644 index 000000000000..1770a54c068c --- /dev/null +++ b/dev-docs/source/MVPTutorial/MockingExercise.rst @@ -0,0 +1,11 @@ +================ +Mocking Exercise +================ + +In this exercise you will mock the Presenter from the `Presenter +Exercise `_. All of the methods should be +mocked and the return values should be present only when necessary (on +this occasion the values do not matter). The ``updatePlot`` function +should be tested to make sure that it calls the correct methods. + +See `here `_ for the solution. diff --git a/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst b/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst new file mode 100644 index 000000000000..14f8be65e83f --- /dev/null +++ b/dev-docs/source/MVPTutorial/MockingExerciseSolution.rst @@ -0,0 +1,44 @@ +========================= +Mocking Exercise Solution +========================= + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import sys + import presenter + import view + + import unittest + if sys.version_info.major == 3: + from unittest import mock + else: + import mock + + class presenterTest(unittest.TestCase): + def setUp(self): + self.view = mock.create_autospec(view.view) + + # mock view + self.view.plotSignal = mock.Mock() + self.view.getColour = mock.Mock(return_value="black") + self.view.getGridLines =mock.Mock(return_value=True) + self.view.getFreq =mock.Mock(return_value=3.14) + self.view.getPhase =mock.Mock(return_value=0.56) + self.view.buttonPressed = mock.Mock() + self.view.setTableRow = mock.Mock() + self.view.addWidgetToTable = mock.Mock() + self.view.addITemToTable = mock.Mock() + + self.presenter = presenter.Presenter(self.view) + + def test_updatePlot(self): + self.presenter.updatePlot() + assert(self.view.getColour.call_count == 1) + assert(self.view.getGridLines.call_count == 1) + assert(self.view.getFreq.call_count == 1) + assert(self.view.getPhase.call_count == 1) + + if __name__ == "__main__": + unittest.main() diff --git a/dev-docs/source/MVPTutorial/Model.rst b/dev-docs/source/MVPTutorial/Model.rst new file mode 100644 index 000000000000..ea0df87b65c0 --- /dev/null +++ b/dev-docs/source/MVPTutorial/Model.rst @@ -0,0 +1,36 @@ +============== +A Simple Model +============== + +Models are used to do the 'hard sums' within the GUI. It is possible +to have multiple models within a single presenter, as we will see with +this example. For this example we have kept the models fairly simple, +in reality they will be much more complex. + +The first model generates the data for the user: + +.. code-block:: python + + import numpy as np + + class DataGenerator(object): + + def __init__(self): + self.x_data = np.linspace(0.0, 10.0, 100) + self.y_data = [] + + def genData(self, freq, phi): + self.y_data = np.sin(freq * self.x_data + phi) + + def getXData(self): + return self.x_data + + def getYData(self): + return self.y_data + +The model methods can be split into three types initialisation, a +calculate button and get methods. + +In this case we have a distinct second method. Usually this will be +placed into its own file, however for simplicity we will contain it +within the same file as the above code. diff --git a/dev-docs/source/MVPTutorial/ModelExercise.rst b/dev-docs/source/MVPTutorial/ModelExercise.rst new file mode 100644 index 000000000000..c3559b53d9ea --- /dev/null +++ b/dev-docs/source/MVPTutorial/ModelExercise.rst @@ -0,0 +1,18 @@ +==================== +Model (MVP) Exercise +==================== + +In the previous section we did not need to update the View. However, +the Model contains a dictionary which contains the allowed colour +options. The GUI should show the same allowed values as the the +Model. To achieve this you will need to add: + +1. A method to the Model for getting the allowed colours + +2. A method in the View to update the ComboBox values to match some +input values + +3. In the initialisation of the Presenter get the allowed colours from +the Model and pass them to the View + +See `here `_ for the solution. diff --git a/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst b/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst new file mode 100644 index 000000000000..835bec9e2d27 --- /dev/null +++ b/dev-docs/source/MVPTutorial/ModelExerciseSolution.rst @@ -0,0 +1,33 @@ +======================= +Model Exercise Solution +======================= + +The Model should now contain the following method in the +``ColourConvertor`` class: + +.. code-block:: python + + def getColourSelection(self): + return self.colour_table.keys() + +The View should contain the following method: + +.. code-block:: python + + def setColours(self,options): + self.colours.clear() + self.colours.addItems(options) + +The Presenter initialisation should now be: + +.. code-block:: python + + def __init__(self, view, data_model, colour_model): + self.view = view + self.data_model = data_model + self.colour_model = colour_model + + colours = self.colour_model.getColourSelection() + self.view.setColours(colours) + # connect statements + self.view.plotSignal.connect(self.updatePlot) diff --git a/dev-docs/source/MVPTutorial/MultipleViews.rst b/dev-docs/source/MVPTutorial/MultipleViews.rst new file mode 100644 index 000000000000..115cf9916ace --- /dev/null +++ b/dev-docs/source/MVPTutorial/MultipleViews.rst @@ -0,0 +1,86 @@ +============== +Multiple Views +============== + + +It is possible to have an MVP pattern within other MVP patterns. If +each complete MVP pattern is considered to be a widget then having an +MVP pattern embedded into another MVP is effectively just adding +another widget. This can be very useful for creating small versatile +widgets that may be used in multiple GUIs. + +We will combine the View from the exercise and the PlotView from the +previous section into a single view. To achieve this we will create a +'master' view: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import numpy as np + import plotView + import view + + class MasterView(QtGui.QWidget): + + def __init__(self, parent=None): + super(MasterView, self).__init__(parent) + + grid = QtGui.QVBoxLayout(self) + self.plot_view = plotView.PlotView(parent=self) + x_data = np.linspace(0.0, 10.0, 100) + y_data = np.sin(x_data) + self.plot_view.addData(x_data, y_data, "b", "x") + + grid.addWidget(self.plot_view) + + self.options_view = view.view(parent=self) + + grid.addWidget(self.options_view) + self.setLayout(grid) + +The important thing to note here is that when the PlotView and View +are created the parent is set to be the masterView. + +The main only needs to import the masterView: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import sys + + import masterView + + + """ + A wrapper class for setting the main window + """ + class demo(QtGui.QMainWindow): + def __init__(self, parent=None): + super(demo, self).__init__(parent) + + self.window = QtGui.QMainWindow() + my_view = masterView.MasterView() + # set the view for the main window + self.setCentralWidget(my_view) + self.setWindowTitle("view tutorial") + + def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + + app = qapp() + window = demo() + window.show() + app.exec_() + diff --git a/dev-docs/source/MVPTutorial/PresenterExercise.rst b/dev-docs/source/MVPTutorial/PresenterExercise.rst new file mode 100644 index 000000000000..de947f223703 --- /dev/null +++ b/dev-docs/source/MVPTutorial/PresenterExercise.rst @@ -0,0 +1,18 @@ +================== +Presenter Exercise +================== + +In this exercise you will create a Presenter for View.py. + +Using the View from the previous exercise (the one which contains a +table) create a Presenter to handle the button press. When the button +is pressed the following should be output: + +- The line colour +- If the grid lines are on or off +- The frequency +- The phase + +The ``main`` module will also need updating to handle these changes. + +See `here `_ for the solution. diff --git a/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst b/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst new file mode 100644 index 000000000000..a0cb6caedd2c --- /dev/null +++ b/dev-docs/source/MVPTutorial/PresenterExerciseSolution.rst @@ -0,0 +1,149 @@ +=========================== +Presenter Exercise Solution +=========================== + +View +#### + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + + class view(QtGui.QWidget): + + plotSignal = QtCore.pyqtSignal() + + def __init__(self, parent=None): + super(view, self).__init__(parent) + + grid = QtGui.QVBoxLayout(self) + + self.table = QtGui.QTableWidget(self) + self.table.setRowCount(4) + self.table.setColumnCount(2) + + grid.addWidget(self.table) + + self.colours = QtGui.QComboBox() + options=["Blue", "Green", "Red"] + self.colours.addItems(options) + + self.grid_lines= QtGui.QTableWidgetItem() + self.grid_lines.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + self.grid_lines.setCheckState(QtCore.Qt.Unchecked) + self.addItemToTable("Show grid lines", self.grid_lines, 1) + + self.freq = QtGui.QTableWidgetItem("1.0") + self.phi = QtGui.QTableWidgetItem("0.0") + + self.addWidgetToTable("Colour", self.colours, 0) + self.addItemToTable("Frequency", self.freq, 2) + self.addItemToTable("Phase", self.phi, 3) + + self.plot = QtGui.QPushButton('Add', self) + self.plot.setStyleSheet("background-color:lightgrey") + + grid.addWidget(self.plot) + + self.setLayout(grid) + + self.plot.clicked.connect(self.buttonPressed) + + def getColour(self): + return self.colours.currentText() + + def getGridLines(self): + return self.grid_lines.checkState() == QtCore.Qt.Checked + + def getFreq(self): + return float(self.freq.text()) + + def getPhase(self): + return float(self.phi.text()) + + def buttonPressed(self): + self.plotSignal.emit() + + def setTableRow(self, name, row): + text = QtGui.QTableWidgetItem(name) + text.setFlags(QtCore.Qt.ItemIsEnabled) + col = 0 + self.table.setItem(row, col, text) + + def addWidgetToTable(self, name, widget, row): + self.setTableRow(name, row) + col = 1 + self.table.setCellWidget(row, col, widget) + + def addItemToTable(self, name, widget, row): + self.setTableRow(name, row) + col = 1 + self.table.setItem(row, col, widget) + +Presenter +######### + +.. code-block:: python + + from __future__ import (absolute_import ,division, print_function) + + class Presenter(object): + + # pass the view and model into the presenter + def __init__(self, view): + self.view = view + + self.view.plotSignal.connect(self.updatePlot) + + # handle signals + def updatePlot(self): + print("The table settings are:") + print(" colour : " + str(self.view.getColour())) + print(" Grid lines : " + str(self.view.getGridLines())) + print(" Frequency : " + str(self.view.getFreq())) + print(" Phase : " + str(self.view.getPhase())) + +Main module +########### + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import sys + + import view + import presenter + + + """ + A wrapper class for setting the main window + """ + class demo(QtGui.QMainWindow): + def __init__(self, parent=None): + super(demo,self).__init__(parent) + + self.window = QtGui.QMainWindow() + my_view = view.view() + self.presenter = presenter.Presenter(my_view) + # set the view for the main window + self.setCentralWidget(my_view) + self.setWindowTitle("view tutorial") + + def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + + app = qapp() + window = demo() + window.show() + app.exec_() diff --git a/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst b/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst new file mode 100644 index 000000000000..5a6beb71c3f3 --- /dev/null +++ b/dev-docs/source/MVPTutorial/ReceivingSignalFromView.rst @@ -0,0 +1,123 @@ +================================ +Receiving a signal from the view +================================ + +In the `Add Button `_ section we had the response to a button press +within the View. In practice this is not a good implementation. If the +response was more complicated then it would be difficult to maintain +the View as it would become extremely long. Furthermore creating the +look of the GUI is fairly simple and any logic/responses should be +contained within the Presenter. + +In this section we will make a simple Presenter for when a button is +pressed. First we will start with the View: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + + class view(QtGui.QWidget): + + doSomethingSignal = QtCore.pyqtSignal() + + def __init__(self, parent=None): + super(view, self).__init__(parent) + + self.button = QtGui.QPushButton('Hi', self) + self.button.setStyleSheet("background-color:lightgrey") + # connect button to signal + self.button.clicked.connect(self.btn_click) + + self.label = QtGui.QLabel() + self.label.setText("Button") + + # add widgets to layout + self.sub_layout = QtGui.QHBoxLayout() + self.sub_layout.addWidget(self.label) + self.sub_layout.addWidget(self.button) + + grid = QtGui.QVBoxLayout(self) + grid.addLayout(self.sub_layout) + # set the layout for the view widget + self.setLayout(grid) + + #send signals + def btn_click(self): + print ("hellow from view") + self.doSomethingSignal.emit() + +The above code has two new additions. The first is the creation of a +custom signal on line eight. It is also possible to pass objects with +the signals. The second addition is that ``btn_click`` now emits the +custom signal and will be caught by the Presenter. + +The Presenter is initialised with the View and must be a member of the +Presenter class. It is therefore possible to change the View by +passing a different one to the presenter. For example you may want to +have the widgets in a grid or in a table. The Presenter connects the +custom signal from the View to its own function (``handleButton``). + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + class Presenter(object): + + # pass the view and model into the presenter + def __init__(self, view): + self.view = view + + self.view.doSomethingSignal.connect(self.handleButton) + + # handle signals + def handleButton(self): + print("hello world, from the presenter") + +The main is now: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import sys + import view + import presenter + + + """ + A wrapper class for setting the main window + """ + class demo(QtGui.QMainWindow): + def __init__(self, parent=None): + super(demo, self).__init__(parent) + + self.window = QtGui.QMainWindow() + my_view = view.view(self) + self.my_presenter = presenter.Presenter(my_view) + # set the view for the main window + + self.setCentralWidget(my_view) + self.setWindowTitle("view tutorial") + + def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + + + app = qapp() + window = demo() + window.show() + app.exec_() + +The View and Presenter are both created, but only the Presenter has to +be a member of the demo class. The View is created to be passed to the +Presenter and the View could easily be replaced. diff --git a/dev-docs/source/MVPTutorial/Tables.rst b/dev-docs/source/MVPTutorial/Tables.rst new file mode 100644 index 000000000000..d496434b9753 --- /dev/null +++ b/dev-docs/source/MVPTutorial/Tables.rst @@ -0,0 +1,49 @@ +====== +Tables +====== + +Tables are useful way to display a set of related options to a +user. To add a table widget to a GUI the following lines need to be +added to the ``__init__`` function of the View: + +.. code-block:: python + + self.table = QtGui.QTableWidget(self) + self.table.setRowCount(2) + self.table.setColumnCount(2) + grid.addWidget(self.table) + +The first line creates the widget. The second and third lines +determine the size of the table. The fourth line adds it to the +layout. + +To add (non-editable) labels to the table the following code is needed: + +.. code-block:: python + + text = QtGui.QTableWidgetItem(("test")) + text.setFlags(QtCore.Qt.ItemIsEnabled) + row = 0 + col = 0 + self.table.setItem(row, col, text) + + row = 1 + text2 = QtGui.QTableWidgetItem(("another test")) + text2.setFlags(QtCore.Qt.ItemIsEnabled) + self.table.setItem(row, col, text2) + + row = 0 + col = 1 + self.table.setCellWidget(row, col, self.combo) + row = 1 + self.table.setCellWidget(row, col, self.spin) + +The first line creates a widget with the label ``test`` and the second +flag ensures that a user cannot edit the value. The label is added to +the table with the ``setItem`` function. + +A useful feature of tables is that they can contain a widget within +one of the cells. The last five lines of the above code adds a +ComboBox and spin box to the table. It is important to note that the +widgets will now only appear within the table. + diff --git a/dev-docs/source/MVPTutorial/ViewExercise1.rst b/dev-docs/source/MVPTutorial/ViewExercise1.rst new file mode 100644 index 000000000000..72b33cc53a64 --- /dev/null +++ b/dev-docs/source/MVPTutorial/ViewExercise1.rst @@ -0,0 +1,23 @@ +=============== +View Exercise 1 +=============== + +A GUI should help a user to easily manipulate the behaviour of the +code (by changing variables etc.). For example consider creating a +plot of a sine wave. In this exercise you will create a view which +contains the options for manipulating the plot. + +The GUI should contain a single table and a button for updating the +plot. The table should include options for: + +- Setting the line colour (red, blue, green) +- Setting the grid lines +- Entering a frequency +- Entering a phase shift + +The previous sections are not an exhaustive list of possible widgets. + +The pages `MatPlotLib and MVP `_ and `MultipleView +`_ will be useful for the exercise. + +The solution can be found `here `_. diff --git a/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst b/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst new file mode 100644 index 000000000000..cc17fdfcdf3f --- /dev/null +++ b/dev-docs/source/MVPTutorial/ViewExercise1Solution.rst @@ -0,0 +1,112 @@ +======================== +View Exercise 1 Solution +======================== + +main.py +####### + +.. code-block:: python + + from __future__ import (absolute_import,division,print_function) + + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + import sys + + import view + + """ + A wrapper class for setting the main window + """ + class demo(QtGui.QMainWindow): + def __init__(self,parent=None): + super(demo,self).__init__(parent) + + self.window = QtGui.QMainWindow() + my_view = view.view() + + # set the view for the main window + self.setCentralWidget(my_view) + self.setWindowTitle("view tutorial") + + def qapp(): + if QtGui.QApplication.instance(): + _app = QtGui.QApplication.instance() + else: + _app = QtGui.QApplication(sys.argv) + return _app + + app = qapp() + window = demo() + window.show() + app.exec_() + +view.py +####### + +.. code-block:: python + + from __future__ import (absolute_import,division,print_function) + import PyQt4.QtGui as QtGui + import PyQt4.QtCore as QtCore + + + class view(QtGui.QWidget): + + def __init__(self, parent=None): + super(view, self).__init__(parent) + + grid = QtGui.QVBoxLayout(self) + + self.table = QtGui.QTableWidget(self) + self.table.setRowCount(4) + self.table.setColumnCount(2) + grid.addWidget(self.table) + + self.colours = QtGui.QComboBox() + options = ["Blue", "Green", "Red"] + self.colours.addItems(options) + + self.grid_lines = QtGui.QTableWidgetItem() + self.grid_lines.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) + self.grid_lines.setCheckState(QtCore.Qt.Unchecked) + self.addItemToTable("Show grid lines", self.grid_lines, 1) + + self.freq = QtGui.QTableWidgetItem("1.0") + self.phi = QtGui.QTableWidgetItem("0.0") + + self.addWidgetToTable("Colour", self.colours, 0) + self.addItemToTable("Frequency", self.freq, 2) + self.addItemToTable("Phase", self.phi, 3) + + self.plot = QtGui.QPushButton('Add', self) + self.plot.setStyleSheet("background-color:lightgrey") + + grid.addWidget(self.plot) + + self.setLayout(grid) + + def setTableRow(self, name, row): + text = QtGui.QTableWidgetItem(name) + text.setFlags(QtCore.Qt.ItemIsEnabled) + col = 0 + self.table.setItem(row, col, text) + + def addWidgetToTable(self, name, widget, row): + self.setTableRow(name,row) + col = 1 + self.table.setCellWidget(row, col, widget) + + def addItemToTable(self, name, widget, row): + self.setTableRow(name, row) + col = 1 + self.table.setItem(row, col, widget) + +In the above code the following functions have been added to prevent +repetition of code: + +- ``setTableRow`` sets the label for the table row +- ``addWidgetToTable`` adds a widget to the table +- ``addItemToTable`` adds an item to the table (needed because the + frequency and phase are items and not widgets) diff --git a/dev-docs/source/MVPTutorial/index.rst b/dev-docs/source/MVPTutorial/index.rst new file mode 100644 index 000000000000..318f8ed233b4 --- /dev/null +++ b/dev-docs/source/MVPTutorial/index.rst @@ -0,0 +1,38 @@ +========= +MVP Index +========= + +The following tutorial introduces how to create a Graphical User +Interface (GUI) using PyQt. Some knowledge of Python is assumed. + +The concepts carry over into Qt in C++. + +Duration: 6 hours as a hands-on course with exercises. + +.. toctree:: + :maxdepth: 1 + + Introduction + AddButton + AddLabel + Layouts + AddLineEdit + AddComboBox + AddSpinBox + Tables + ViewExercise1 + MatPlotLib + MultipleViews + ViewExercise1Solution + ReceivingSignalFromView + ExtractInfoFromView + PresenterExercise + PresenterExerciseSolution + Mocking + MockingExercise + MockingExerciseSolution + Model + ModelExercise + ModelExerciseSolution + CompleteGUI + From e3cc3e89319e3e83eb58fbab25a30528866a8dc4 Mon Sep 17 00:00:00 2001 From: Mathieu Doucet Date: Tue, 20 Mar 2018 16:25:13 -0400 Subject: [PATCH 328/364] Make sure not to delete input workspace --- .../PythonInterface/plugins/algorithms/MRFilterCrossSections.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py b/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py index ef7bf24f40c7..b0349b8e336e 100644 --- a/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py +++ b/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py @@ -186,7 +186,6 @@ def filter_cross_sections(self, file_path): api.AddSampleLog(Workspace=ws, LogName='cross_section_id', LogText=pol_state) - AnalysisDataService.remove(ws_raw_name) self.setProperty("CrossSectionWorkspaces", output_wsg) # If we don't have a splitter table, it might be because we don't have analyzer/polarizer @@ -196,7 +195,6 @@ def filter_cross_sections(self, file_path): self.setProperty("CrossSectionWorkspaces", api.GroupWorkspaces([ws_raw])) else: api.logger.error("No events remained after filtering") - AnalysisDataService.remove(ws_raw_name) def load_legacy_cross_Sections(self, file_path): """ From ce8a53e9990f346bc50d32e759c24ec5c112d274 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 21 Mar 2018 08:49:43 +0000 Subject: [PATCH 329/364] added tube handing for side-by-side projection #21230 --- .../InstrumentView/PanelsSurface.h | 3 + .../instrumentview/src/PanelsSurface.cpp | 145 +++++++++++++++++- 2 files changed, 143 insertions(+), 5 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h index 56542a27e0f0..dd740e4eaf72 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h @@ -58,6 +58,9 @@ class PanelsSurface : public UnwrappedSurface { void processStructured(const std::vector &children, size_t rootIndex); + void processTubes(const std::vector &children, size_t rootIndex, + std::vector &visited); + std::pair, Mantid::Kernel::V3D> processUnstructured(const std::vector &children, size_t rootIndex, std::vector &visited); diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index 9f7555bb49d7..cf942a9f5bf3 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -14,6 +14,7 @@ #include using namespace Mantid::Geometry; +using Mantid::Beamline::ComponentType; namespace { @@ -229,6 +230,133 @@ void PanelsSurface::processStructured(const std::vector &children, addDetector(child, corners[0], index, info->rotation); } +size_t findParentBank(const ComponentInfo &componentInfo, size_t rootIndex) { + // Search for parent component which contains tubes + auto parent = componentInfo.parent(rootIndex); + while (componentInfo.children(parent).size() <= 1) + parent = componentInfo.parent(parent); + + return parent; +} + +std::vector findBankTubes(const ComponentInfo &componentInfo, + size_t rootIndex) { + auto comps = componentInfo.componentsInSubtree(rootIndex); + std::vector tubes; + + for (auto comp : comps) { + if (componentInfo.componentType(comp) == ComponentType::OutlineComposite) + tubes.push_back(comp); + } + + return tubes; +} + +bool isBankFlat(const ComponentInfo &componentInfo, size_t bankIndex, + const std::vector &tubes, + const Mantid::Kernel::V3D &normal) { + for (auto tube : tubes) { + const auto &children = componentInfo.children(tube); + auto vector = componentInfo.position(children[0]) - + componentInfo.position(children[1]); + vector.normalize(); + if (fabs(vector.scalar_prod(normal)) > Mantid::Kernel::Tolerance) { + g_log.warning() << "Assembly " << componentInfo.name(bankIndex) + << " isn't flat.\n"; + return false; + } + } + return true; +} + +Mantid::Kernel::V3D calculateBankNormal(const ComponentInfo &componentInfo, + const std::vector &tubes) { + // calculate normal from first two tubes in bank as before + const auto &tube0 = componentInfo.children(tubes[0]); + const auto &tube1 = componentInfo.children(tubes[1]); + auto pos = componentInfo.position(tube0[0]); + auto x = componentInfo.position(tube0[1]) - pos; + x.normalize(); + + auto y = componentInfo.position(tube1[0]) - pos; + y.normalize(); + auto normal = x.cross_prod(y); + + if (normal.nullVector()) { + y = componentInfo.position(tube1[1]) - componentInfo.position(tube1[0]); + y.normalize(); + normal = x.cross_prod(y); + } + + normal.normalize(); + + if (normal.nullVector()) + g_log.warning() << "Colinear Assembly.\n"; + + return normal; +} + +void PanelsSurface::processTubes(const std::vector &children, + size_t rootIndex, std::vector &visited) { + const auto &componentInfo = m_instrActor->componentInfo(); + auto bankIndex = findParentBank(componentInfo, rootIndex); + auto name = componentInfo.name(bankIndex); + auto tubes = findBankTubes(componentInfo, bankIndex); + auto normal = calculateBankNormal(componentInfo, tubes); + + if (normal.nullVector() || + !isBankFlat(componentInfo, bankIndex, tubes, normal)) + return; + + // save bank info + auto index = m_flatBanks.size(); + FlatBankInfo *info = new FlatBankInfo(this); + m_flatBanks << info; + // record the first detector index of the bank + info->startDetectorIndex = componentInfo.children(tubes.front()).front(); + info->endDetectorIndex = componentInfo.children(tubes.back()).back(); + + auto pos0 = + componentInfo.position(componentInfo.children(tubes.front()).front()); + auto pos1 = + componentInfo.position(componentInfo.children(tubes.front()).back()); + + info->rotation = calcBankRotation(pos0, normal); + pos1 -= pos0; + info->rotation.rotate(pos1); + pos1 += pos0; + + QPointF p0(m_xaxis.scalar_prod(pos0), m_yaxis.scalar_prod(pos0)); + QPointF p1(m_xaxis.scalar_prod(pos1), m_yaxis.scalar_prod(pos1)); + QVector vert; + vert << p0 << p1; + info->polygon = QPolygonF(vert); + + for (auto tube : tubes) { + const auto &children = componentInfo.children(tube); + visited[tube] = true; + for (auto child : children) { + if (visited[child]) + continue; + visited[child] = true; + addDetector(child, pos0, index, info->rotation); + } + + auto &udet0 = m_unwrappedDetectors[children.front()]; + auto &udet1 = m_unwrappedDetectors[children.back()]; + QPointF p2(udet0.u, udet0.v); + QPointF p3(udet1.u, udet1.v); + // add a quadrilateral formed by end points of two nearest tubes + // assumption is made here that any two adjacent tubes in an assembly's + // children's list + // are close to each other + vert << p0 << p1 << p3 << p2; + info->polygon = info->polygon.united(QPolygonF(vert)); + p0 = p2; + p1 = p3; + } +} + std::pair, Mantid::Kernel::V3D> PanelsSurface::processUnstructured(const std::vector &children, size_t rootIndex, @@ -285,21 +413,28 @@ PanelsSurface::findFlatPanels(size_t rootIndex, const auto &componentInfo = m_instrActor->componentInfo(); auto parentIndex = componentInfo.parent(rootIndex); auto componentType = componentInfo.componentType(parentIndex); - if (componentType == Mantid::Beamline::ComponentType::Rectangular || - componentType == Mantid::Beamline::ComponentType::Structured) { + if (componentType == ComponentType::Rectangular || + componentType == ComponentType::Structured) { /* Do nothing until the root index of the structured bank. */ return boost::none; } componentType = componentInfo.componentType(rootIndex); - if (componentType == Mantid::Beamline::ComponentType::Rectangular || - componentType == Mantid::Beamline::ComponentType::Structured) { + if (componentType == ComponentType::Rectangular || + componentType == ComponentType::Structured) { processStructured(children, rootIndex); for (auto child : children) visited[child] = true; return boost::none; } + if (componentType == ComponentType::OutlineComposite) { + processTubes(children, rootIndex, visited); + for (auto child : children) + visited[child] = true; + return boost::none; + } + return processUnstructured(children, rootIndex, visited); } @@ -310,7 +445,7 @@ void PanelsSurface::constructFromComponentInfo() { for (size_t i = 0; i < componentInfo.size() - 1; ++i) { auto children = componentInfo.detectorsInSubtree(i); - if (children.size() > 1) { + if (children.size() > 1 && !visited[i]) { auto res = findFlatPanels(i, children, visited); if (res != boost::none) { std::vector detectors; From c4aecc009927b40b62ae392530aafec2ebd87336 Mon Sep 17 00:00:00 2001 From: Joseph Ramsay Date: Wed, 21 Mar 2018 09:30:13 +0000 Subject: [PATCH 330/364] Remove trailing whitespace --- scripts/MVPExample/Presenter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/MVPExample/Presenter.py b/scripts/MVPExample/Presenter.py index 9cff214bf10a..d160d22e3f57 100644 --- a/scripts/MVPExample/Presenter.py +++ b/scripts/MVPExample/Presenter.py @@ -31,7 +31,7 @@ def display_update(self): self.view.show_display() def handle_button(self): - # Get the values from view + # Get the values from view value1 = self.view.get_value(0) operation = self.view.get_operation() value2 = self.view.get_value(2) From ff31c65fbe333d05c7984e8c8da6d38a7bbb5384 Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Wed, 21 Mar 2018 10:37:31 +0100 Subject: [PATCH 331/364] dev-docs: general, algorithm and interface documentation guides. Re #22082 --- dev-docs/source/AlgorithmDocumentation.rst | 194 ++++++++++++++ dev-docs/source/AlgorithmUsageExamples.rst | 224 ++++++++++++++++ dev-docs/source/DocumentationGuideForDevs.rst | 249 ++++++++++++++++++ dev-docs/source/FlowchartCreation.rst | 65 +++++ dev-docs/source/InterfaceDocumentation.rst | 53 ++++ 5 files changed, 785 insertions(+) create mode 100644 dev-docs/source/AlgorithmDocumentation.rst create mode 100644 dev-docs/source/AlgorithmUsageExamples.rst create mode 100644 dev-docs/source/DocumentationGuideForDevs.rst create mode 100644 dev-docs/source/FlowchartCreation.rst create mode 100644 dev-docs/source/InterfaceDocumentation.rst diff --git a/dev-docs/source/AlgorithmDocumentation.rst b/dev-docs/source/AlgorithmDocumentation.rst new file mode 100644 index 000000000000..dc03d48a52c5 --- /dev/null +++ b/dev-docs/source/AlgorithmDocumentation.rst @@ -0,0 +1,194 @@ +.. _AlgorithmDocumentation: + +======================= +Algorithm Documentation +======================= + +.. contents:: + :local: + +Summary +======= + +This page deals with the specifics of how to document an algorithm. For a more general guide to the Mantid documentation system see `Documentation Guide For Devs `__. + +How to Document an Algorithm +============================ + +Algorithm documentation is stored in two places. + +* The code (.cpp / .h / .py) files: For strings that are needed in the GUI for tooltips etc. +* The .rst file: For all other documentation, including the algorithm description and `usage examples `__. + +The Code Files +-------------- + +The code files hold documentation in two important areas. + +The ``summary`` method + The summary method should return a string (in plain text) that describes in a short sentence the purpose of the algorithm. This is used to provide a summary in the algorithm dialog box and in the algorithm documentation web page. + +In C++: (This example uses the .h file, you could of course implement it in the .cpp file) + +.. code-block:: c++ + + /// Algorithm's name for identification overriding a virtual method + const std::string name() const override { return "Rebin";} + + ///Summary of algorithms purpose + const std::string summary() const override {return "Rebins data with new X bin boundaries.";} + +Property Descriptions +--------------------- + +Each property declaration in the init method of the .cpp file should include a description. This is used as a tooltip, and in the 'properties' table on the algorithm's documentation web page. + +.. note:: + + The tooltip may only show the description up to the first dot. Be sure that the first sentence in the description gives enough information to understand the purpose of the property. + +For example: + +.. code-block:: c++ + + declareProperty( + new WorkspaceProperty<>("InputWorkspace", "", Direction::Input), + "Workspace containing the input data"); + declareProperty( + new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), + "The name to give the output workspace"); + declareProperty( + new ArrayProperty("Params", boost::make_shared()), + "A comma separated list of first bin boundary, width, last bin boundary. Optionally " + "this can be followed by a comma and more widths and last boundary pairs. " + "Optionally this can also be a single number, which is the bin width. " + "In this case, the boundary of binning will be determined by minimum and maximum TOF " + "values among all events, or previous binning boundary, in case of event Workspace, or " + "non-event Workspace, respectively. Negative width values indicate logarithmic binning. "); + +Workflow algorithms +=================== + +There should be a flow chart for workflow algorithms. See `here `__ on how to make one. + +Algorithm Directives +==================== + +We have defined several custom directives using the Sphinx extension framework. These are defined to generate the information from an algorithm that is not required to be hand written, i.e the properties table. Each .rst file that is documenting an algorithm should use these directives. + +As the **Description** and **Usage** of an algorithm *cannot* be obtained automatically, it must be manually entered. The structure of an algorithm's .rst is: + +.. code-block:: rest + + .. algorithm:: + + .. summary:: + + .. alias:: + + .. properties:: + + Description + ----------- + + The description of your algorithm here. + + Usage + ----- + + A custom usage example. + + .. categories:: + + .. sourcelink:: + +``.. algorithm ::`` + This directive has several pieces of functionality, which includes: + +* A referable link is created for the algorithm. This allows other documentation pages create references to it (e.g. create links to it). +* Insertion of the page title (which is the name of the algorithm, including the version). +* Insertion of a screenshot of the algorithm's dialog. +* Insertion of the Table Of Contents. + +``.. summary::`` + The content of the summary method declared in your algorithm is output as HTML, for example, the following method is used in Rebin: + +.. code-block:: c++ + + /// Summary of algorithms purpose + const std::string summary() const override { + return "Rebins data with new X bin boundaries. For EventWorkspaces, you can very quickly rebin in-place by keeping the same output name and PreserveEvents=true."; + } + +``.. alias::`` + This directive obtains aliases from the required ``alias`` method in the algorithm, for example, the following method is used in Rebin: + +.. code-block:: c++ + + /// Algorithm's aliases + const std::string alias() const override { return "rebin"; } + +``.. properties::`` + As mentioned above, it is *critical* that you include a description for the properties of your algorithm. This directive obtains all of the algorithm's properties (set inside the algorithm's ``init`` method) and outputs in a table format. + +``.. categories::`` + By default, this directive obtains the categories that were set in the ``categories`` method the algorithm. For example, in Rebin the category method is in the header and contains: + +.. code-block:: c++ + + /// Algorithm's category for identification + const std::string category() const override {return "Transforms\\Rebin";} + +When the HTML is generate a categories list is built that contains: Algorithms, Transforms and Rebin. + +It is possible to add additional categories by passing the directive arguments, for example, the following would output the above categories, and also `Example`: + +.. code-block: rest + + .. categories:: Algorithms, Transforms, Rebin, Example + +``..sourcelink ::`` + This directive adds links to the algorithms source code. + +Description +=========== + +This section must be manually entered. The description is an extension of the summary, and must contain a detailed overview of the algorithm's functionality. + +Referencing Other Algorithms +---------------------------- + +Every algorithm and version has been marked with a tag that can be used to reference it from other documents. If you need to reference the latest version of an algorithm, e.g. DiffractionFocussing, then in Sphinx you type would type + +.. code-block:: rest + + :ref:`DiffractionFocussing ` + +If you need to reference a particular version then you would type + +.. code-block:: rest + + :ref:`DiffractionFocussing version 2 ` + +where the first part outside the angle brackets defines the link text and the part inside the angle brackets references the tag name. + +Usage +===== + +This section *must* be manually entered. The usage is a 'code' example of the algorithm in use. The `testcode` directive must be used to verify the usage code you entered works correctly. See `here `__ for more information on how to write usage examples. + +Building the Documentation +========================== + +One can update the documentation for a particular algorithm after changes have been introduced into the corresponding documentation file. Assuming you are in the build directory and want to update the documentation for Rebin: + +:: + + bin/MantidPlot -xq docs/runsphinx_html.py -R Rebin # builds HTML documentation + bin/MantidPlot -xq docs/runsphinx_qthelp.py -R Rebin # builds Qt-help documentation + +or with vanilla python + +:: + + python docs/runsphinx_html.py -m $PWD/bin -R Rebin diff --git a/dev-docs/source/AlgorithmUsageExamples.rst b/dev-docs/source/AlgorithmUsageExamples.rst new file mode 100644 index 000000000000..3c8ee85ebc37 --- /dev/null +++ b/dev-docs/source/AlgorithmUsageExamples.rst @@ -0,0 +1,224 @@ +.. _AlgorithmUsageExamples: + +======================== +Algorithm Usage Examples +======================== + +.. contents:: + :local: + +Introduction +============ + +A *usage example* is part of the documentation page of an algorithm. + +From a user's point of view, the main purposes of usage examples are: + +* Getting started using the algorithm as part of a Python script +* Understanding the algorithm +* Showing hints/comments etc. that help understand Mantid Python scripting in general + +The usage examples are written in `reStructuredText `__, which can be converted to HTML and the code in the usage examples can be tested. The image below demonstrates an example of converting reStructuredText to HTML. + +Guide +===== + +The example below show the proposed way to format an usage example in reStructuredText. + +.. code-block:: rest + + Usage + ----- + + **Example - simple rebin of a histogram workspace:** + + .. testcode:: ExHistSimple + + # create histogram workspace + dataX = [0,1,2,3,4,5,6,7,8,9] # or use dataX=range(0,10) + dataY = [1,1,1,1,1,1,1,1,1] # or use dataY=[1]*9 + ws = CreateWorkspace(dataX, dataY) + + # rebin from min to max with size bin = 2 + ws = Rebin(ws, 2) + + print "The rebinned X values are: " + str(ws.readX(0)) + print "The rebinned Y values are: " + str(ws.readY(0)) + + + Output: + + .. testoutput:: ExHistSimple + + The rebinned X values are: [ 0. 2. 4. 6. 8. 9.] + The rebinned Y values are: [ 2. 2. 2. 2. 1.] + +What is required is: + +* Short description explaining the example, formatted as shown above, i.e. using ``**`` to embolden the text. +* A ``.. testcode::`` section, with a unique 'namespace' name, here ``ExHistSimple``. This 'namespace' is not shown when converted to HTML, but is used in testing the code. This section contains the actual Python code demonstrating a usage of the algorithm. This code block contains commented code, finishing with one or more Python ``print`` lines as shown +* A ``.. testoutput::`` section. This section must have a matching 'namespace' name to the ``..testcode::`` section. It simply contains a copy of the text that is printed out in the ``..testcode::`` section. +* Include the "Output:" string above the ``..testoutput::`` directive. + +What is optional: + +* A ``..testcleanup::`` section. This section must have a matching 'namespace' name to the ``..testcode::`` section. Here, add Python code to do any cleanup of files etc. that were created by the tests. See the notes below for things that are cleaned automatically. + +Notes: + +* The configuration has a global "testcleanup" implemented which calls ``FrameworkManager::clear()`` to clear algorithms, workspaces & instruments so these are dealt with automatically. +* There must be a clear blank line before the ``.. testcode::`` and ``.. testoutput`` directives or the test is ignored. As with unit tests you should write a failing test first to ensure it is running. + +What is worth keeping in mind is: + +* *Assume the user is new to Python*. Consider giving hints to more advanced Python in comments, or introduce a simple example first. +* Use comments. +* Use Python ``print`` to output results, which, where possible, helps to understand the algorithm. + +A Jenkins job tests that the usage examples are not broken, i.e. that they continue to provide a working demonstration against the current build. It is vital to stress that the purpose of usage testing is *not to replace unit testing* (or system testing). The purpose of usage testing (better described as demonstration examples), is to provide some happy-path examples, which, where this is possible, can assist the user understanding of the Python code. This is very different from the purposes of testing in general, see `here `__. + +Additional benefits of usage examples: + +* Quick look-up for developers on how to use a certain algorithm in Python scripting +* Allow the user to test that scripts return expected output in their installed Mantid versions +* Additional test coverage of Mantid Python API + +Using CreateSampleWorkspace and CreateWorkspace +----------------------------------------------- + +There are many ways to create sample workspaces. For example :ref:`CreateMDHistoWorkspace `, :ref:`CreateSampleWorkspace ` and :ref:`CreateWorkspace `. CreateSampleWorkspace creates a fully defined workspace (either event or histogram) but for creating simple histogram workspace CreateWorkspace may be a better option. Above is shown an example where CreateWorkspace is used. Below is a more complex use of CreateSampleWorkspace: + +.. code-block:: rest + + Usage + ----- + + **Example - Fit a Gaussian to a peak in a spectrum:** + + .. testcode:: ExFitPeak + + # create a workspace with a gaussian peak sitting on top of a linear (here flat) background + ws = CreateSampleWorkspace(Function="User Defined", UserDefinedFunction="name=LinearBackground, \ + A0=0.3;name=Gaussian, PeakCentre=5, Height=10, Sigma=0.7", NumBanks=1, BankPixelWidth=1, XMin=0, XMax=10, BinWidth=0.1) + + # Setup the data to fit: + workspaceIndex = 0 # the spectrum with which WorkspaceIndex to fit + startX = 1 # specify fitting region + endX = 9 # + + # Setup the model, here a Gaussian, to fit to data + tryCentre = '4' # A start guess on peak centre + sigma = '1' # A start guess on peak width + height = '8' # A start guess on peak height + myFunc = 'name=Gaussian, Height='+height+', PeakCentre='+tryCentre+', Sigma='+sigma + # here purposely haven't included a linear background which mean fit will not be spot on + # to include a linear background uncomment the line below + #myFunc = 'name=LinearBackground, A0=0.3;name=Gaussian, Height='+height+', PeakCentre='+tryCentre+', Sigma='+sigma + + # Do the fitting + fitStatus, chiSq, covarianceTable, paramTable, fitWorkspace = Fit(InputWorkspace='ws', \ + WorkspaceIndex=0, StartX = startX, EndX=endX, Output='fit', Function=myFunc) + + print "The fit was: " + fitStatus + print("chi-squared of fit is: %.2f" % chiSq) + print("Fitted Height value is: %.2f" % paramTable.column(1)[0]) + print("Fitted centre value is: %.2f" % paramTable.column(1)[1]) + print("Fitted sigma value is: %.2f" % paramTable.column(1)[2]) + # fitWorkspace contains the data, the calculated and the difference patterns + print "Number of spectra in fitWorkspace is: " + str(fitWorkspace.getNumberHistograms()) + print("The 20th y-value of the calculated pattern: %.4f" % fitWorkspace.readY(1)[19]) + + .. testcleanup:: ExFitPeak + + DeleteWorkspace(ws) + + Output: + + .. testoutput:: ExFitPeak + + The fit was: success + chi-squared of fit is: 0.14 + Fitted Height value is: 9.79 + Fitted centre value is: 5.05 + Fitted sigma value is: 0.77 + Number of spectra in fitWorkspace is: 3 + The 20th y-value of the calculated pattern: 0.2361 + +For a more simple use of CreateSampleWorkspace see example below (note if no arguments are given then a histogram workspace is created): + +.. code-block:: rest + + Usage + ----- + + **Example - use option PreserveEvents:** + + .. testcode:: ExEventRebin + + # create some event workspace + ws = CreateSampleWorkspace(WorkspaceType="Event") + + print "What type is the workspace before 1st rebin: " + str(type(ws)) + # rebin from min to max with size bin = 2 preserving event workspace (default behaviour) + ws = Rebin(ws, 2) + print "What type is the workspace after 1st rebin: " + str(type(ws)) + ws = Rebin(ws, 2, PreserveEvents=False) + print "What type is the workspace after 2nd rebin: " + str(type(ws)) + # note you can also check the type of a workspace using: print isinstance(ws, IEventWorkspace) + + .. testcleanup:: ExEventRebin + + DeleteWorkspace(ws) + + Output: + + .. testoutput:: ExEventRebin + + What type is the workspace before 1st rebin: + What type is the workspace after 1st rebin: + What type is the workspace after 2nd rebin: + +When needing to load a data file +-------------------------------- + +Instructions to add a new data file to the repository are available `here `__. Files from the repository will be bundled up into a .zip file, and this .zip made available for download from the Mantid download page. + +If you use files you must add the line + +.. code-block:: rest + + .. include:: ../usagedata-note.txt + +as shown in the example below. This will generate a note to the user explaining how to download the UsageData. + +.. code-block:: rest + + Usage + ----- + + .. include:: ../usagedata-note.txt + + **Example - Load ISIS histogram Nexus file:** + (see :ref:`LoadISISNexus ` for more options) + + .. testcode:: ExLoadISISnexusHist + + # Load ISIS LOQ histogram dataset + ws = Load('LOQ49886.nxs') + + print "The 1st x-value of the first spectrum is: " + str(ws.readX(0)[0]) + + .. testcleanup:: ExLoadISISnexusHist + + DeleteWorkspace(ws) + + Output: + + .. testoutput:: ExLoadISISnexusHist + + The 1st x-value of the first spectrum is: 5.0 + +Running the Tests +================= + +See `here `__ for how to run and test the usage examples locally. diff --git a/dev-docs/source/DocumentationGuideForDevs.rst b/dev-docs/source/DocumentationGuideForDevs.rst new file mode 100644 index 000000000000..a022439e8558 --- /dev/null +++ b/dev-docs/source/DocumentationGuideForDevs.rst @@ -0,0 +1,249 @@ +.. _DocumentationGuideForDevs: + +============================ +Documentation Guide for Devs +============================ + +.. contents:: + :local: + +Rationale +========= + +The algorithm documentation approach aims to: + +#. Keep .cpp files clean and easy to maintain. +#. Make the documentation files easier to edit, supporting the use of external editors. +#. Simplify the Mantid documentation workflow. + +To do this we have harmonised most of our documentation workflow to use sphinx, extended a bit by some Mantid custom tag extensions. + +Prerequisites +============= + +The documentation build requires: + +Sphinx +------ + +* `Sphinx `__ +* `Sphinx bootstrap theme `__ + +These are bundled with the Python distrbution on Windows but other platforms will need to install them following the installation instructions `here `__. It is recommended that ``pip`` is used over ``easy_install``. + +LaTeX +----- + +To view the equations built with the documentation you will need an installation of LaTeX on your system. + +Linux +##### + +If you have installed the mantid-develop package then you should have a working latex distribution. If not, use your package manager and search for a suitable candidate, most likely named something like ``texlive``. + +MacOS +##### + +See `here `__ for instructions on installing ``MacTeX``. + +Windows +####### + +Download and install ``MikTeX`` from `here `__. + +During installation there will be a question with a drop-down box relating to installing packages on demand - make sure "Ask first" is selected. + +The first build of one of the ``docs-*`` targets after ``MikTeX`` has installed will raise a dialog, similar to this asking you if it is okay to install a package. For developers behind a proxy you will need to click on the "Change" button and enter the proxy information and select a new download location on the set of dialogs that appear before returning back to the main dialog. Check the box saying don't ask again and click install. + +reST editors/IDE plugins +======================== + +Several free & proprietary editors support syntax-highlighting reST. A list of the most notable ones can be found `here `__. + +Restview +-------- + +A really handy tool whilst writing out .rst files is `restview `__ which can be easily installed using ``pip``. It opens a webpage with the rst file processed and refreshes the page automatically whenever the .rst file is saved. This can help you quickly track down that unexpected space or missing newline without having to rebuild the documentation each time. It does not support sphinx directives so links will produce errors on the page which need to be checked by building the documentation using Mantid. The syntax to use it is: + +``restview path/to/file.rst`` + +The reStructuredText File +========================= + +`reStructuredText `__ is a markup format and is converted into themed html pages using Sphinx. A primer on reStructuredText can be found here along with a single-page cheat sheet. + +The source files are .rst files which are located in the ``docs/source`` directory in the repository. There are various subdirectories based on the type of object being documented, i.e. ``docs/source/algorithms``, ``docs/source/functions``. + +The documentation pages is aimed at *users*, not developers, and all information should be targeted for the users. Information for developers should go into doxygen/code-comments in the code or into ``dev-docs``. + +Directives +---------- + +Sphinx is built on the ``docutils`` package that allows for directives to be inserted in to reST comments. For example: + +.. code-block:: rest + + .. warning:: + This text will show up surrounded by a coloured box. + +tells sphinx to treat the the given text differently and flag it so that a user will see it as a warning. The name of the directive is ``warning`` and the ``..`` is a reST comment syntax. The directive name must be followed by ``::`` so that Sphinx process knows it has a directive command and not just plain text. For a list of directives known to Sphinx, see `here `__. + +Comments +-------- + +If you wish to place comments in the reST file that will not be rendered anywhere then start the line/block with ``..``. See `here `__ for more details. + +Algorithms +---------- + +The algorithm documentation has a slightly more rigid structure and is described in more detail `here `__ and `here `__. + +Interfaces +---------- + +For documenting custom interfaces, it is recommended that you consult `this `__ page, which explains how to document them, and which directives may be used in more detail. + +How to define titles, sections etc. +----------------------------------- + +The syntax for headers in restructuredText is the header followed by a line containing symbols such as hyphens. It is possible to use different punctuation to create headers but within the Mantid .rst files we standardize on the characters used as follows: + +The title of the page + Should be the first header of your .rst file, and generally only occur once. (This is done for you in an algorithm with the ``.. algorithm::`` directive) + +.. code-block:: rest + + ============================================= + Page title (e.g. Workspace) - This outputs H1 + ============================================= + +Section headings + Sections, such as the description of an algorithm, can be created with the following syntax + +.. code-block:: rest + + # Description - This outputs H2 + ------------------------------- + +Sub-sections + The following is used to create a sub-section of the above section. This must follow after the above to be parsed correctly. + +.. code-block:: rest + + Sub-heading - This outputs h3 + ############################# + +Sub-sub-sections + The following is used to create a sub-header for the sub-heading above. This must also follow after the above header to be parsed correctly. + +.. code-block:: rest + + Sub-sub-heading - Outputs h4 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Things to Avoid +=============== + +If you have weird messages about sphinx warnings that happen on “Console output”, those are coming either from summary functions in algorithms or from parameter descriptions. In these + +* *Do not* use ``*`` in parameter names or summary. This yields “Inline emphasis start-string without end-string” warnings. +* *Do not* use things like ``|Q|``. This yields sphinx error “Undefined substitution referenced”. +* When using hyperlinks with a label, try to use anonymous hyperlinks (two underscores instead of one) to avoid name clashes. + * ```MD `__`` and ```MD `__`` instead of ```MD `_`` and ```MD `_``. The second on will result in a warning. + +Common Warnings and Fixes +------------------------- + +While building the final output, Sphinx will emit warning messages if it things the input restructured text is malformed. This section lists some more common warnings along with suggestions for fixes. + +Explicit markup ends without a blank line; unexpected unindent. +############################################################### + +This is caused by the lack of a blank line between an indented explicit markup block and more unindented text, e.g. + +.. code-block:: rest + + .. testcode:: ExHist + + print "This is a test" + Output: <------------- There should be a blank line above this + + .. testoutput:: ExHist + +It can be fixed by having a blank line between the indented block and the unindented text. + +Inline interpreted text or phrase reference start-string without end-string +########################################################################### + +This is caused by using one of the `inline markup tags `__, where the text being wrapped splits over multiple lines. In these cases the directive variant of the inline markup should be used. One example is the ``:math:`` tag being spread over multiple lines. The tag ``:math:`` must only be used for inline markup, i.e. when there is no newline in the math string. For multi-line maths markup you must use the ``.. math::`` directive instead. + +.. code-block:: rest + + :math:`\rm U \rm B \left( + \begin{array}{c} + h_i \\ + k_i \\ + l_i \\ + \end{array} + \right) = \rm Q_{gon,i}` (1) + +should be written + +.. code-block:: rest + + .. math:: + <------------------ intentional blank line + \rm U \rm B \left( + \begin{array}{c} + h_i \\ + k_i \\ + l_i \\ + \end{array} + \right) = \rm Q_{gon,i} (1) + <------------------ intentional blank line + +where there is an explicit blank line after the final line of latex. See `here `__ for more information. + +image file not readable +####################### + +This indicates the that image referenced by ``.. image::`` or ``.. figure::`` cannot be accessed. Either the image is not there or the reference is incorrect. + +Image links in Sphinx are either relative, in which case it is relative to the current document or absolute in which case the path is assumed relative to the root of the source tree (the directory containing the conf.py) + +Unknown directive type "foo" +############################ + +Sphinx has encountered a line starting with ``.. foo::``, where ``foo`` is expected to be a known directive. + +The fix is to correct the name of the directive. + +Warnings on console (in the build servers) +########################################## + +These type of errors occur in the summary function and/or in documentation of parameters in the init function. See `Things to Avoid`_. + +Running documentation tests locally +=================================== + +The usage tests are executed using a driver script, ``runsphinx_doctest.py``, that is generated by CMake in the ``docs`` directory. A top-level target, ``docs-test``, is created for each generator that invokes the script without any arguments and subsequently executes all of the available usage tests. + +The driver script has been written to accept additional arguments in order to be able to limit the number of tests that are executed. To run a subset of the available tests, the script must be called manually and supplied with the ``-R TESTREGEX`` argument. The regex is applied to the filename of the document and will match anywhere within the name. The script can be called using either a plain Python interpreter or the MantidPlot executable. If using a plain Python interpreter then you will need to either have your ``PYTHONPATH`` set to find the ``mantid`` module or you can provide the ``-m MANTIDPATH`` option to have the script find the module for you. + +It is recommended that the tests are run with MantidPlot as this is the easiest way to be sure that they are being run with the current build copy. As an example, to run any files that have Rebin in the filename you would type (assuming you are in the build directory): + +:: + + bin/MantidPlot -xq docs/runsphinx_doctest.py -R Rebin + +or with vanilla python + +:: + + python docs/runsphinx_doctest.py -m $PWD/bin -R Rebin + +For multi-configuration generators such as Visual Studio or XCode you will need to pick the configuration by choosing the apporiate directory, e.g. for MSVC debug (remembering that the slashes need to be backslash and not forward slash): + +:: + + bin\Debug\MantidPlot -xq docs\runsphinx_doctest.py -R Rebin diff --git a/dev-docs/source/FlowchartCreation.rst b/dev-docs/source/FlowchartCreation.rst new file mode 100644 index 000000000000..8b1db35c64ae --- /dev/null +++ b/dev-docs/source/FlowchartCreation.rst @@ -0,0 +1,65 @@ +.. _FlowchartCreation: + +================== +Flowchart Creation +================== + +.. contents:: + :local: + + +The flowchart diagrams are created by writing ``graphviz`` .dot files that describe the diagram in plain text, and placing them into ``docs/source/diagrams``. These can then be rendered in documentation by using the diagram directive in an .rst file: + +.. code-block:: rest + + .. diagram:: AlgorithmName-v1_wkflw.dot + +Examples of this can be found in `ReflectometryReductionOne1.rst `__ and `ReflectometryReductionOneAuto-v1.rst `__. + +The .dot format is quite simple¸ but very powerful for describing graphs. The approach we use is to describe all the nodes (shapes) we want first, grouping them into their types, and then defining how they're connected. + +To provide a uniform look to all the workflow diagrams, templated keywords are provided which are swapped out with the correct styling options when the documentation is built. They are of the form ``${context}_style``. They're defined by the `diagram directive `__. + +An algorithm that takes one input workspace and scales it by a given parameter/property if it was given, may look like this: + +:: + + digraph DiagramName { + //Comments are inserted in the same way as C++ + label = "MultiplyByParam Workflow Diagram" + $global_style + + subgraph params { + //These keywords beginning with $ are replaced with commands to style all the nodes in the subgraph correctly + $param_style + inputWorkspace [label="InputWorkspace"] + outputWorkspace [label="OutputWorkspace"] + coefficient [label="Coefficient"] + } + + subgraph decisions { + $decision_style + checkCoefficient [label="Was Coefficient\ngiven?"] + } + + subgraph algorithms { + $algorithm_style + scale [label="Scale"] + } + + //Define the connections, labelling some of them + inputWorkspace -> checkCoefficient + coefficient -> scale [label="Factor"] + checkCoefficient -> scale [label="Yes"] + checkCoefficient -> outputWorkspace [label="No"] + scale -> outputWorkspace + } + +While creating the diagrams it's inconvenient to recompile the documentation with each change, so you may want to render the graph manually. This can be achieved on linux or cygwin by running the following command. *You may need to comment out the "$foo_style" lines when manually rendering as they are not valid graphviz syntax* (you can do this on the fly using sed to avoid having to edit the file). + +:: + + dot -Tpng -o output_image.png input_file.dot # render a graph manually + sed 's/\$/\/\/$/g' input_file.dot | dot -Tpng -o output_image.png # excludes $foo_style lines + +You can also render them in a web browser using this `online graph renderer `__. diff --git a/dev-docs/source/InterfaceDocumentation.rst b/dev-docs/source/InterfaceDocumentation.rst new file mode 100644 index 000000000000..1e49cbb60f01 --- /dev/null +++ b/dev-docs/source/InterfaceDocumentation.rst @@ -0,0 +1,53 @@ +.. _InterfaceDocumentation: + +======================= +Interface Documentation +======================= + +.. contents:: + :local: + +Summary +======= + +This page deals with the specifics of how to document Custom Interfaces. For a more general guide to the Mantid documentation system see `Documentation Guide For Devs `__. + +The ``interface`` Directive +=========================== + +This directive allows you to insert a screenshot of the interface into the documentation. It has one required argument: the name of the interface, as given by the interface's ``name()`` method. Several options, detailed below, may also be provided to further control the behaviour of this directive. + +The inserted screenshots are generated automatically when the documentation is being compiled. This is preferable to screenshots taken manually as these will automatically stay up to date. + +Options +------- + +widget + You can give the name of a widget in the interface to only take a screenshot of that widget. If not given, a screenshot of the entire interface will be inserted. + +align + This specifies the alignment to use for the screenshot. Valid settings are *left*, *center*, and *right*. Defaults to *center*. + +Examples +======== + +This inserts a screenshot of the Muon Analysis interface: + +.. code-block:: rest + + .. interface:: Muon Analysis + +This inserts a screenshot of the Muon Analysis interface's Grouping Options tab: + +.. code-block:: rest + + .. interface:: Muon Analysis + :widget: GroupingOptions + +This inserts a screenshot of the main table in the ISIS Reflectometry custom interface, aligned to the right: + +.. code-block:: rest + + .. interface:: ISIS Reflectometry + :widget: viewTable + :align: right From 0cc4f739e244abdc6471d6a8cb7621056bc40b46 Mon Sep 17 00:00:00 2001 From: Lamar Moore Date: Wed, 21 Mar 2018 09:39:12 +0000 Subject: [PATCH 332/364] small refactor #21230 --- .../InstrumentView/PanelsSurface.h | 3 +- .../instrumentview/src/PanelsSurface.cpp | 137 +++++++++--------- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h index dd740e4eaf72..950a7742afd8 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/PanelsSurface.h @@ -58,8 +58,7 @@ class PanelsSurface : public UnwrappedSurface { void processStructured(const std::vector &children, size_t rootIndex); - void processTubes(const std::vector &children, size_t rootIndex, - std::vector &visited); + void processTubes(size_t rootIndex, std::vector &visited); std::pair, Mantid::Kernel::V3D> processUnstructured(const std::vector &children, size_t rootIndex, diff --git a/qt/widgets/instrumentview/src/PanelsSurface.cpp b/qt/widgets/instrumentview/src/PanelsSurface.cpp index cf942a9f5bf3..1542bf49d61e 100644 --- a/qt/widgets/instrumentview/src/PanelsSurface.cpp +++ b/qt/widgets/instrumentview/src/PanelsSurface.cpp @@ -64,6 +64,72 @@ calculatePanelNormal(const std::vector &panelCorners) { normal.normalize(); return normal; } + +size_t findParentBank(const ComponentInfo &componentInfo, size_t rootIndex) { + // Search for parent component which contains tubes + auto parent = componentInfo.parent(rootIndex); + while (componentInfo.children(parent).size() <= 1) + parent = componentInfo.parent(parent); + + return parent; +} + +std::vector findBankTubes(const ComponentInfo &componentInfo, + size_t rootIndex) { + auto comps = componentInfo.componentsInSubtree(rootIndex); + std::vector tubes; + + for (auto comp : comps) { + if (componentInfo.componentType(comp) == ComponentType::OutlineComposite) + tubes.push_back(comp); + } + + return tubes; +} + +bool isBankFlat(const ComponentInfo &componentInfo, size_t bankIndex, + const std::vector &tubes, + const Mantid::Kernel::V3D &normal) { + for (auto tube : tubes) { + const auto &children = componentInfo.children(tube); + auto vector = componentInfo.position(children[0]) - + componentInfo.position(children[1]); + vector.normalize(); + if (fabs(vector.scalar_prod(normal)) > Mantid::Kernel::Tolerance) { + g_log.warning() << "Assembly " << componentInfo.name(bankIndex) + << " isn't flat.\n"; + return false; + } + } + return true; +} + +Mantid::Kernel::V3D calculateBankNormal(const ComponentInfo &componentInfo, + const std::vector &tubes) { + // calculate normal from first two tubes in bank as before + const auto &tube0 = componentInfo.children(tubes[0]); + const auto &tube1 = componentInfo.children(tubes[1]); + auto pos = componentInfo.position(tube0[0]); + auto x = componentInfo.position(tube0[1]) - pos; + x.normalize(); + + auto y = componentInfo.position(tube1[0]) - pos; + y.normalize(); + auto normal = x.cross_prod(y); + + if (normal.nullVector()) { + y = componentInfo.position(tube1[1]) - componentInfo.position(tube1[0]); + y.normalize(); + normal = x.cross_prod(y); + } + + normal.normalize(); + + if (normal.nullVector()) + g_log.warning() << "Colinear Assembly.\n"; + + return normal; +} } // namespace namespace MantidQt { @@ -230,74 +296,7 @@ void PanelsSurface::processStructured(const std::vector &children, addDetector(child, corners[0], index, info->rotation); } -size_t findParentBank(const ComponentInfo &componentInfo, size_t rootIndex) { - // Search for parent component which contains tubes - auto parent = componentInfo.parent(rootIndex); - while (componentInfo.children(parent).size() <= 1) - parent = componentInfo.parent(parent); - - return parent; -} - -std::vector findBankTubes(const ComponentInfo &componentInfo, - size_t rootIndex) { - auto comps = componentInfo.componentsInSubtree(rootIndex); - std::vector tubes; - - for (auto comp : comps) { - if (componentInfo.componentType(comp) == ComponentType::OutlineComposite) - tubes.push_back(comp); - } - - return tubes; -} - -bool isBankFlat(const ComponentInfo &componentInfo, size_t bankIndex, - const std::vector &tubes, - const Mantid::Kernel::V3D &normal) { - for (auto tube : tubes) { - const auto &children = componentInfo.children(tube); - auto vector = componentInfo.position(children[0]) - - componentInfo.position(children[1]); - vector.normalize(); - if (fabs(vector.scalar_prod(normal)) > Mantid::Kernel::Tolerance) { - g_log.warning() << "Assembly " << componentInfo.name(bankIndex) - << " isn't flat.\n"; - return false; - } - } - return true; -} - -Mantid::Kernel::V3D calculateBankNormal(const ComponentInfo &componentInfo, - const std::vector &tubes) { - // calculate normal from first two tubes in bank as before - const auto &tube0 = componentInfo.children(tubes[0]); - const auto &tube1 = componentInfo.children(tubes[1]); - auto pos = componentInfo.position(tube0[0]); - auto x = componentInfo.position(tube0[1]) - pos; - x.normalize(); - - auto y = componentInfo.position(tube1[0]) - pos; - y.normalize(); - auto normal = x.cross_prod(y); - - if (normal.nullVector()) { - y = componentInfo.position(tube1[1]) - componentInfo.position(tube1[0]); - y.normalize(); - normal = x.cross_prod(y); - } - - normal.normalize(); - - if (normal.nullVector()) - g_log.warning() << "Colinear Assembly.\n"; - - return normal; -} - -void PanelsSurface::processTubes(const std::vector &children, - size_t rootIndex, std::vector &visited) { +void PanelsSurface::processTubes(size_t rootIndex, std::vector &visited) { const auto &componentInfo = m_instrActor->componentInfo(); auto bankIndex = findParentBank(componentInfo, rootIndex); auto name = componentInfo.name(bankIndex); @@ -429,7 +428,7 @@ PanelsSurface::findFlatPanels(size_t rootIndex, } if (componentType == ComponentType::OutlineComposite) { - processTubes(children, rootIndex, visited); + processTubes(rootIndex, visited); for (auto child : children) visited[child] = true; return boost::none; From cec769d1450c4ee5151ce5e53fc3565e94b56593 Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Wed, 21 Mar 2018 11:23:29 +0000 Subject: [PATCH 333/364] Remove the test file. Re #22101 --- MantidPlot/pymantidplot/qtiplot.py | 3 - .../test/MantidPlotPyplotGeneralTest.py | 250 ------------------ 2 files changed, 253 deletions(-) delete mode 100644 MantidPlot/test/MantidPlotPyplotGeneralTest.py diff --git a/MantidPlot/pymantidplot/qtiplot.py b/MantidPlot/pymantidplot/qtiplot.py index e3848d12bac5..0c2af7a2968e 100644 --- a/MantidPlot/pymantidplot/qtiplot.py +++ b/MantidPlot/pymantidplot/qtiplot.py @@ -19,9 +19,6 @@ #----------------------------------------------------------------------------- # Intercept qtiplot "plot" command and forward to plotSpectrum for a workspace -# -# This function has been moved inside qtiplot when pymantidplot.pyplot (which -# has another plot() function) was imported into the standard MantidPlot namespace def plot(source, *args, **kwargs): """Create a new plot given a workspace, table or matrix. diff --git a/MantidPlot/test/MantidPlotPyplotGeneralTest.py b/MantidPlot/test/MantidPlotPyplotGeneralTest.py deleted file mode 100644 index 5a89029aa224..000000000000 --- a/MantidPlot/test/MantidPlotPyplotGeneralTest.py +++ /dev/null @@ -1,250 +0,0 @@ -"""General tests for the basic interface of mantidplot.pyplot - -Tests correct creation of output lines from plots (with correct -Figure, Graph, etc. data), and proper handling (exception) of wrong -input parameters. Tests plotting of normal arrays and workspaces with the following tools ('tool' kwarg): plot_spectrum, plot_bin, plot_ - -""" -from __future__ import (absolute_import, division, print_function) -import mantidplottests -from mantidplottests import * -import time -import numpy as np -from PyQt4 import QtGui, QtCore - -# =============== Create fake workspaces to plot ======================= -X1 = np.linspace(0,10, 100) -Y1 = 1000*(np.sin(X1)**2) + X1*10 -X1 = np.append(X1, 10.1) - -X2 = np.linspace(2,12, 100) -Y2 = 500*(np.cos(X2/2.)**2) + 20 -X2 = np.append(X2, 12.10) - -X = np.append(X1, X2) -Y = np.append(Y1, Y2) -E = np.sqrt(Y) - -# this one has 2 spectra -WorkspaceName2D = 'fake ws' -CreateWorkspace(OutputWorkspace=WorkspaceName2D, DataX=list(X), DataY=list(Y), DataE=list(E), NSpec=2, - UnitX="TOF", YUnitLabel="Counts", WorkspaceTitle="Test/faked data Workspace, 2 spectra") - -sec_X3 = np.linspace(2,12, 100) -sec_Y3 = 200*(np.tan(sec_X3/2.4)**2) + 15 -sec_X3 = np.append(sec_X3, 12.10) - -sec_X = np.append(X, sec_X3) -sec_Y = np.append(Y, sec_Y3) -sec_E = np.power(sec_Y, 0.6) - -# this one has 3 spectra -SecondWorkspaceName2D = 'another fake ws' -CreateWorkspace(OutputWorkspace=SecondWorkspaceName2D, DataX=list(sec_X), DataY=list(sec_Y), DataE=list(sec_E), NSpec=3, - UnitX="TOF", YUnitLabel="Counts", WorkspaceTitle="Test/faked data Workspace, 3 spectra") - -# plot_md needs an MD workspace with a single non-integrated dimension -MDWWorkspaceName = 'mdw' -mdSignal = np.sin(list(range(0,100,1))) -errInput = mdSignal/20.5 -CreateMDHistoWorkspace(Dimensionality="1", Names='x', Units='m', Extents='0,10', NumberOfBins=len(mdSignal), SignalInput=mdSignal, ErrorInput=errInput, OutputWorkspace=MDWWorkspaceName) - -class MantidPlotPyplotGeneralTest(unittest.TestCase): - - def setUp(self): - self.g = None - - def tearDown(self): - """Clean up by closing the created window """ - windows = self.g - if not self.g: - return - if type(self.g) != list: - windows = [self.g] - for window in windows: - self.close_win_by_graph(window) - - def close_win_by_graph(self, g): - if None != g: - g.confirmClose(False) - g.close() - QtCore.QCoreApplication.processEvents() - - def test_nothing(self): - return True - - def check_output_lines(self, lines, expected_len): - """ Check that the lines returned by a plot are correctly built """ - self.assertTrue(expected_len==len(lines)) - for i in range(0, len(lines)): - self.assertTrue(isinstance(lines[i], Line2D)) - self.assertTrue(isinstance(lines[i].figure(), Figure)) - self.assertTrue(isinstance(lines[i]._graph, proxies.Graph)) - self.assertTrue(isinstance(lines[i].figure()._graph, proxies.Graph)) - - def close_win(self, lines): - """ - Close a plot window. Use this on your test windows to prevent very likely - segfaults at the end of the tests. - - @param lines :: lines object as returned by the plot function - """ - if len(lines) > 0: - self.close_win_by_graph(lines[0]._graph) - - def test_plot_spectrum_ok(self): - lines_spec = plot_spectrum(WorkspaceName2D, [0, 1]) - self.check_output_lines(lines_spec, 2) - self.close_win(lines_spec) - - tool_names = ['plot_spectrum', 'plot_sp', 'spectrum', 'sp'] - for tname in tool_names: - lines = plot(WorkspaceName2D, [0, 1], tool=tname) - self.check_output_lines(lines, 2) - self.close_win(lines) - - if self.assertTrue(len(lines) == len(lines_spec)): - for i in range(0, len(lines)): - self.assertEqual(lines[i].get_xdata(), lines_spec[i].get_xdata()) - self.assertEqual(lines[i].get_ydata(), lines_spec[i].get_ydata()) - - def test_plot_bin_ok(self): - lines_bin = plot_bin(WorkspaceName2D, [0, 1, 2]) - self.check_output_lines(lines_bin, 3) - self.close_win(lines_bin) - - tool_names = ['plot_bin', 'bin'] - for tname in tool_names: - lines = plot(WorkspaceName2D, [0, 1, 2], tool=tname) - self.check_output_lines(lines, 3) - self.close_win(lines) - - if self.assertTrue(len(lines) == len(lines_bin)): - for i in range(0, len(lines)): - self.assertEqual(lines[i].get_xdata(), lines2_bin[i].get_xdata()) - self.assertEqual(lines[i].get_ydata(), lines2_bin[i].get_ydata()) - - def test_lines_get_data(self): - y = [0.2, 0.5, 0.1, 0.6] - # note this assumes that plot will make a dummy workspace using 0,1,2... as X - x = list(range(0, len(y), 1)) - - lines = plot(y) - self.check_output_lines(lines, 1) - # and here also check the values - if 1==len(lines): - self.assertEqual(lines[0].get_xdata(), x) - self.assertEqual(lines[0].get_ydata(), y) - self.close_win(lines) - - def test_plot_md_ok(self): - lines = plot_md(MDWWorkspaceName) - self.assertEqual(len(lines), 1) - self.close_win(lines) - - tool_names = ['plot_md', 'md'] - for tnames in tool_names: - lines = plot(MDWWorkspaceName, tool='plot_md') - self.assertEqual(len(lines), 1) - self.close_win(lines) - - # now see what happens with non-md workspaces - self.assertRaises(ValueError, plot, WorkspaceName2D, tool='plot_md') - - self.assertRaises(ValueError, plot_md, WorkspaceName2D) - - def test_plot_array_ok(self): - val = [] # empty data, will be replaced with a dummy (0,0) and generate a 'point' line - lines = plot(val) - self.check_output_lines(lines, 1) - self.close_win(lines) - - def test_plot_with_more_functions(self): - lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linewidth=2, linestyle='--', marker='v') - xlim(0, 1) - ylim(0, 1) - xlabel('X foo label') - ylabel('Y bar label') - title('baz title') - axis([0, 1, 0, 1]) - grid('off') - grid('on') - self.check_output_lines(lines, 2) - self.close_win(lines) - - def test_plot_with_style_args(self): - # note that these tests also use various aliases for the tool name 'plot_spectrum' - # Not adding all the possible combinations here, as this suite is becoming time consuming - lines = plot(WorkspaceName2D, [0,1], '--g', tool='plot_spectrum') - self.check_output_lines(lines, 2) - self.close_win(lines) - - lines = plot(WorkspaceName2D, [0,1], 'y:>', tool='plot_sp') - self.check_output_lines(lines, 2) - self.close_win(lines) - - def test_plot_with_style_args_and_kwargs(self): - lines = plot(WorkspaceName2D, [0,1], '-.m', tool='spectrum') - self.check_output_lines(lines, 2) - self.close_win(lines) - - lines = plot(WorkspaceName2D, [0,1], 'r-.>', tool='sp') - self.check_output_lines(lines, 2) - self.close_win(lines) - - def test_plot_with_kwargs(self): - lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linewidth=3, linestyle='-.', marker='v') - self.check_output_lines(lines, 2) - self.close_win(lines) - - lines = plot(WorkspaceName2D, [0,1], tool='plot_sp', linewidth=3, linestyle='-.', marker='v') - self.check_output_lines(lines, 2) - self.close_win(lines) - - lines = plot(SecondWorkspaceName2D, [0,1, 2], tool='sp', linewidth=3, linestyle='-.', marker='v') - self.check_output_lines(lines, 3) - self.close_win(lines) - - def test_plot_with_none_marker(self): - lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linestyle='--', marker=None) - self.check_output_lines(lines, 2) - self.close_win(lines) - - lines = plot(WorkspaceName2D, 0, tool='plot_spectrum', color='y', marker='None') - self.check_output_lines(lines, 1) - self.close_win(lines) - - def test_wrong_kwargs(self): - # funny kwargs should have no big consequences - lines = plot(WorkspaceName2D, [0,1], tool='plot_spectrum', linewidth=3, linestyle='-.', - marker='v', funny_foo='bar', funny_baz='qux') - self.check_output_lines(lines, 2) - self.close_win(lines) - - def test_multi_plot_commands(self): - lines = plot(WorkspaceName2D, [0,1], SecondWorkspaceName2D, [0, 1, 2]) - self.check_output_lines(lines, 5) - self.close_win(lines) - - lines = plot(WorkspaceName2D, [0,1], SecondWorkspaceName2D, [0, 1, 2]) - self.check_output_lines(lines, 5) - self.close_win(lines) - - # this one mixes up positional and kw args - self.assertRaises(ValueError, plot, - WorkspaceName2D, [0,1], WorkspaceName2D, tool='plot_spectrum') - - def test_savefig(self): - # save a minimal figure just to check that the file is written - import os - - lines = plot([0, 0.5, 0.1]) - tmp_figname = 'pyplot_tmp_fig_test.png' - savefig(tmp_figname) - self.close_win(lines) - - self.assertTrue(os.path.exists(tmp_figname)) - os.remove(tmp_figname) - -# Run the unit tests -mantidplottests.runTests(MantidPlotPyplotGeneralTest) From e05089ecab528fa01e5f9a6330c35e27ca4030b5 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 21 Mar 2018 12:18:11 +0000 Subject: [PATCH 334/364] Re #22154: Applied fixes for qt/. --- qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp | 10 +++++----- .../Indirect/AbsorptionCorrections.cpp | 2 +- .../Indirect/CalculatePaalmanPings.cpp | 2 +- .../Indirect/IndirectTransmissionCalc.cpp | 2 +- .../test/MuonAnalysisFitDataPresenterTest.h | 4 ++-- qt/widgets/common/src/FileDialogHandler.cpp | 2 +- .../common/test/DataProcessorUI/GenerateNotebookTest.h | 8 ++++---- qt/widgets/common/test/ParseKeyValueStringTest.h | 4 ++-- qt/widgets/instrumentview/src/DetXMLFile.cpp | 4 ++-- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp b/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp index e2a78dcc7d02..ea6b73f4e77d 100644 --- a/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp +++ b/qt/scientific_interfaces/ISISSANS/SANSPlotSpecial.cpp @@ -423,16 +423,16 @@ void SANSPlotSpecial::setupTable() { m_derivatives["Rg"] = new QTableWidgetItem(); m_derivatives["Rg"]->setToolTip("Radius of gyration"); - m_units["Rg"] = QString::fromUtf8("\xc3\x85"); + m_units["Rg"] = QString::fromUtf8(R"(Å)"); m_derivatives["Rg,xs"] = new QTableWidgetItem(*m_emptyCell); m_derivatives["Rg,xs"]->setToolTip("Cross-sectional radius of gyration"); - m_units["Rg,xs"] = QString::fromUtf8("\xc3\x85"); + m_units["Rg,xs"] = QString::fromUtf8(R"(Å)"); m_derivatives["R"] = new QTableWidgetItem(*m_emptyCell); m_derivatives["R"]->setToolTip("Equivalent spherical radius"); - m_units["R"] = QString::fromUtf8("\xc3\x85"); + m_units["R"] = QString::fromUtf8(R"(Å)"); m_derivatives["T"] = new QTableWidgetItem(*m_emptyCell); m_derivatives["T"]->setToolTip("Thickness"); - m_units["T"] = QString::fromUtf8("\xc3\x85"); + m_units["T"] = QString::fromUtf8(R"(Å)"); m_derivatives["C"] = new QTableWidgetItem(); m_derivatives["C"]->setToolTip("Concentration"); m_units["C"] = "g/cm^3"; @@ -460,7 +460,7 @@ void SANSPlotSpecial::setupTable() { m_units["V"] = "(unitless)"; m_derivatives["Zeta"] = new QTableWidgetItem(*m_emptyCell); m_derivatives["Zeta"]->setToolTip("Characteristic length"); - m_units["Zeta"] = QString::fromUtf8("\xc3\x85"); + m_units["Zeta"] = QString::fromUtf8(R"(Å)"); m_derivatives["(S/V)"] = new QTableWidgetItem(); m_derivatives["(S/V)"]->setToolTip("Surface area-to-volume ratio"); m_units["(S/V)"] = "cm^-1"; diff --git a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp index ed5a8be8ee02..20f2186aaee7 100644 --- a/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/AbsorptionCorrections.cpp @@ -63,7 +63,7 @@ AbsorptionCorrections::AbsorptionCorrections(QWidget *parent) : CorrectionsTab(parent) { m_uiForm.setupUi(parent); - QRegExp regex("[A-Za-z0-9\\-\\(\\)]*"); + QRegExp regex(R"([A-Za-z0-9\-\(\)]*)"); QValidator *formulaValidator = new QRegExpValidator(regex, this); m_uiForm.leSampleChemicalFormula->setValidator(formulaValidator); m_uiForm.leCanChemicalFormula->setValidator(formulaValidator); diff --git a/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp b/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp index ed80f16fc2ca..f16c0812867e 100644 --- a/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp +++ b/qt/scientific_interfaces/Indirect/CalculatePaalmanPings.cpp @@ -33,7 +33,7 @@ CalculatePaalmanPings::CalculatePaalmanPings(QWidget *parent) connect(m_uiForm.dsSample, SIGNAL(dataReady(const QString &)), this, SLOT(fillCorrectionDetails(const QString &))); - QRegExp regex("[A-Za-z0-9\\-\\(\\)]*"); + QRegExp regex(R"([A-Za-z0-9\-\(\)]*)"); QValidator *formulaValidator = new QRegExpValidator(regex, this); m_uiForm.leSampleChemicalFormula->setValidator(formulaValidator); m_uiForm.leCanChemicalFormula->setValidator(formulaValidator); diff --git a/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp b/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp index 55984fe81316..c02192dea4c1 100644 --- a/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectTransmissionCalc.cpp @@ -28,7 +28,7 @@ IndirectTransmissionCalc::IndirectTransmissionCalc(QWidget *parent) * Run any tab setup code. */ void IndirectTransmissionCalc::setup() { - QRegExp chemicalFormulaRegex("[A-Za-z0-9\\-\\(\\)]*"); + QRegExp chemicalFormulaRegex(R"([A-Za-z0-9\-\(\)]*)"); QValidator *chemicalFormulaValidator = new QRegExpValidator(chemicalFormulaRegex, this); m_uiForm.leChemicalFormula->setValidator(chemicalFormulaValidator); diff --git a/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h b/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h index ff0ffe242580..98bfaf225892 100644 --- a/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h +++ b/qt/scientific_interfaces/test/MuonAnalysisFitDataPresenterTest.h @@ -245,7 +245,7 @@ class MuonAnalysisFitDataPresenterTest : public CxxTest::TestSuite { void test_setAssignedFirstRun_loadCurrentRun() { setupGroupPeriodSelections(); const boost::optional currentRunPath{ - "\\\\musr\\data\\MUSRauto_A.tmp"}; + R"(\\musr\data\MUSRauto_A.tmp)"}; const QString wsName("MUSR00061335; Pair; long; Asym; 1; #1"); EXPECT_CALL(*m_dataSelector, setWorkspaceDetails(QString("00061335"), QString("MUSR"), @@ -706,7 +706,7 @@ class MuonAnalysisFitDataPresenterTest : public CxxTest::TestSuite { const QString wsName("MUSR00061335; Group; fwd; Asym; 1; #1"); const QStringList wsNameList{wsName}; const boost::optional currentRunPath{ - "\\\\musr\\data\\MUSRauto_A.tmp"}; + R"(\\musr\data\MUSRauto_A.tmp)"}; // Expect it will update the workspace names EXPECT_CALL(*m_fitBrowser, setWorkspaceNames(wsNameList)).Times(1); diff --git a/qt/widgets/common/src/FileDialogHandler.cpp b/qt/widgets/common/src/FileDialogHandler.cpp index 5c7f51f0b2cf..d19a00267049 100644 --- a/qt/widgets/common/src/FileDialogHandler.cpp +++ b/qt/widgets/common/src/FileDialogHandler.cpp @@ -6,7 +6,7 @@ #include namespace { // anonymous namespace -const boost::regex FILE_EXT_REG_EXP{"^.+\\s+\\((\\S+)\\)$"}; +const boost::regex FILE_EXT_REG_EXP{R"(^.+\s+\((\S+)\)$)"}; const QString ALL_FILES("All Files (*)"); QString getExtensionFromFilter(const QString &selectedFilter) { diff --git a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h index fe471deac852..fda3bd3be5d3 100644 --- a/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h +++ b/qt/widgets/common/test/DataProcessorUI/GenerateNotebookTest.h @@ -152,10 +152,10 @@ class GenerateNotebookTest : public CxxTest::TestSuite { auto notebookLines = splitIntoLines(generatedNotebook); const QString result[] = { - "{", " \"metadata\" : {", " \"name\" : \"Mantid Notebook\"", + "{", " \"metadata\" : {", R"( "name" : "Mantid Notebook")", " },", " \"nbformat\" : 3,", " \"nbformat_minor\" : 0,", " \"worksheets\" : [", " {", " \"cells\" : [", - " {", " \"cell_type\" : \"markdown\",", + " {", R"( "cell_type" : "markdown",)", }; // Check that the first 10 lines are output as expected @@ -841,7 +841,7 @@ class GenerateNotebookTest : public CxxTest::TestSuite { "'IvsLam_TOF_12345', ScaleFactor = '1', ThetaIn = '0.5')\\n\","); TS_ASSERT_EQUALS(notebookLines[48].toStdString(), loadAndReduceString); - auto postProcessString = QString(" \"input\" : \"\","); + auto postProcessString = QString(R"( "input" : "",)"); TS_ASSERT_EQUALS(notebookLines[56], postProcessString); auto groupWorkspacesString = std::string( @@ -876,7 +876,7 @@ class GenerateNotebookTest : public CxxTest::TestSuite { "'IvsLam_TOF_12346', ScaleFactor = '1', ThetaIn = '1.5')\\n\","; TS_ASSERT_EQUALS(notebookLines[77].toStdString(), loadAndReduceString); - postProcessString = " \"input\" : \"\","; + postProcessString = R"( "input" : "",)"; TS_ASSERT_EQUALS(notebookLines[85], postProcessString); groupWorkspacesString = diff --git a/qt/widgets/common/test/ParseKeyValueStringTest.h b/qt/widgets/common/test/ParseKeyValueStringTest.h index ee09cdd2afaf..9b2f84085088 100644 --- a/qt/widgets/common/test/ParseKeyValueStringTest.h +++ b/qt/widgets/common/test/ParseKeyValueStringTest.h @@ -12,7 +12,7 @@ class ParseKeyValueStringTest : public CxxTest::TestSuite { public: void testParseKeyValueString() { std::map kvp = parseKeyValueString( - "a = 1,b=2.0, c=3, d='1,2,3',e=\"4,5,6\",f=1+1=2, g = '\\''"); + R"(a = 1,b=2.0, c=3, d='1,2,3',e="4,5,6",f=1+1=2, g = '\'')"); TS_ASSERT_EQUALS(kvp["a"], "1"); TS_ASSERT_EQUALS(kvp["b"], "2.0"); @@ -33,7 +33,7 @@ class ParseKeyValueStringTest : public CxxTest::TestSuite { void testParseKeyValueQString() { std::map kvp = parseKeyValueQString( - "a = 1,b=2.0, c=3, d='1,2,3',e=\"4,5,6\",f=1+1=2, g = '\\''"); + R"(a = 1,b=2.0, c=3, d='1,2,3',e="4,5,6",f=1+1=2, g = '\'')"); TS_ASSERT_EQUALS(kvp["a"], "1"); TS_ASSERT_EQUALS(kvp["b"], "2.0"); diff --git a/qt/widgets/instrumentview/src/DetXMLFile.cpp b/qt/widgets/instrumentview/src/DetXMLFile.cpp index ec8aefa18163..f4b6ab1853f6 100644 --- a/qt/widgets/instrumentview/src/DetXMLFile.cpp +++ b/qt/widgets/instrumentview/src/DetXMLFile.cpp @@ -21,7 +21,7 @@ DetXMLFile::DetXMLFile(const std::vector &detector_list, m_delete = false; std::ofstream out(m_fileName.toStdString().c_str()); out << " \n \n"; - out << " ::const_iterator idet = detector_list.begin(); for (; idet != detector_list.end(); ++idet) { if (!exclude.contains(*idet)) { @@ -82,7 +82,7 @@ void DetXMLFile::makeListFile(const QList &dets) { void DetXMLFile::makeSumFile(const QList &dets) { std::ofstream out(m_fileName.toStdString().c_str()); out << " \n \n"; - out << " \n\n"; } From 5168a5aa97d514199cf3435b12606153c8fa8f47 Mon Sep 17 00:00:00 2001 From: Mathieu Doucet Date: Wed, 21 Mar 2018 08:41:33 -0400 Subject: [PATCH 335/364] Make deletion conditional --- .../plugins/algorithms/MRFilterCrossSections.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py b/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py index b0349b8e336e..3b0f9d86b24f 100644 --- a/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py +++ b/Framework/PythonInterface/plugins/algorithms/MRFilterCrossSections.py @@ -186,6 +186,8 @@ def filter_cross_sections(self, file_path): api.AddSampleLog(Workspace=ws, LogName='cross_section_id', LogText=pol_state) + if ws_event_data is None: + AnalysisDataService.remove(ws_raw_name) self.setProperty("CrossSectionWorkspaces", output_wsg) # If we don't have a splitter table, it might be because we don't have analyzer/polarizer @@ -195,6 +197,8 @@ def filter_cross_sections(self, file_path): self.setProperty("CrossSectionWorkspaces", api.GroupWorkspaces([ws_raw])) else: api.logger.error("No events remained after filtering") + if ws_event_data is None: + AnalysisDataService.remove(ws_raw_name) def load_legacy_cross_Sections(self, file_path): """ From 9c9df9a5736cb524b9ba80ad0193db770d7c364e Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Wed, 21 Mar 2018 14:28:05 +0000 Subject: [PATCH 336/364] refs #22160 fixed muon bug that disabled fit menu --- docs/source/release/v3.13.0/muon.rst | 25 ++++++++++++++++--- .../common/src/MuonFitPropertyBrowser.cpp | 9 +++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/docs/source/release/v3.13.0/muon.rst b/docs/source/release/v3.13.0/muon.rst index 38a16b54f58a..9fffe7c8a056 100644 --- a/docs/source/release/v3.13.0/muon.rst +++ b/docs/source/release/v3.13.0/muon.rst @@ -4,9 +4,28 @@ MuSR Changes .. contents:: Table of Contents :local: + +Interface +--------- -.. warning:: **Developers:** Sort changes under appropriate heading - putting new features at the top of the section, followed by - improvements, followed by bug fixes. +Improvements +############ + +Bug fixes +######### + +- Fit options are not disabled after changing tabs. + +Algorithms +---------- + +New +### + +Improvements +############ + +Bug fixes +######### :ref:`Release 3.13.0 ` diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 52fb3e30fa33..8812e66448f9 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -336,9 +336,14 @@ void MuonFitPropertyBrowser::setFitEnabled(bool yes) { } void MuonFitPropertyBrowser::checkFitEnabled() { - if (m_reselectGroupBtn->isVisible()) { + if (m_isMultiFittingMode && m_compositeFunction->nFunctions() == 0) { setFitEnabled(false); - } else if (getAutoBackgroundString() != "") { + } + else if (m_isMultiFittingMode){ + setFitEnabled(true); + + } + else if (getAutoBackgroundString() != "") { setFitEnabled(true); } else { setFitEnabled(false); From 7d082a9582b8885f318e1b4204d4c88ca51d56ff Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 21 Mar 2018 14:35:32 +0000 Subject: [PATCH 337/364] Re #22154: Applied fixes for MantidPlot/. --- MantidPlot/src/Mantid/FitParameterTie.cpp | 2 +- MantidPlot/src/importOPJ.cpp | 16 ++++++++-------- MantidPlot/src/lib/src/TextFormatButtons.cpp | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/MantidPlot/src/Mantid/FitParameterTie.cpp b/MantidPlot/src/Mantid/FitParameterTie.cpp index 02352d7bb479..d51c05a2719e 100644 --- a/MantidPlot/src/Mantid/FitParameterTie.cpp +++ b/MantidPlot/src/Mantid/FitParameterTie.cpp @@ -42,7 +42,7 @@ void FitParameterTie::set(const QString &estr) { // rx matches function identifiers in the parameter names and captures the // function index: // for f12.Sigma rx.cap(1).toInt() returns 12 - QRegExp rx("\\bf(\\d+)\\."); + QRegExp rx(R"(\bf(\d+)\.)"); if (rx.indexIn(parName) < 0) { throw std::invalid_argument( diff --git a/MantidPlot/src/importOPJ.cpp b/MantidPlot/src/importOPJ.cpp index a041ae55b1d5..3716e45d9a04 100644 --- a/MantidPlot/src/importOPJ.cpp +++ b/MantidPlot/src/importOPJ.cpp @@ -501,7 +501,7 @@ bool ImportOPJ::importNotes(const OPJFile &opj) { int visible_count = 0; for (int n = 0; n < opj.numNotes(); n++) { QString name = opj.noteName(n); - QRegExp rx("^@\\((\\S+)\\)$"); + QRegExp rx(R"(^@\((\S+)\)$)"); if (rx.indexIn(name) == 0) name = rx.cap(1); @@ -1358,8 +1358,8 @@ QString ImportOPJ::parseOriginText(const QString &str) { QString ImportOPJ::parseOriginTags(const QString &str) { QString line = str; // Lookbehind conditions are not supported - so need to reverse string - QRegExp rx("\\)[^\\)\\(]*\\((?!\\s*[buig\\+\\-]\\s*\\\\)"); - QRegExp rxfont("\\)[^\\)\\(]*\\((?![^\\:]*\\:f\\s*\\\\)"); + QRegExp rx(R"(\)[^\)\(]*\((?!\s*[buig\+\-]\s*\\))"); + QRegExp rxfont(R"(\)[^\)\(]*\((?![^\:]*\:f\s*\\))"); QString linerev = strreverse(line); QString lBracket = strreverse("&lbracket;"); QString rBracket = strreverse("&rbracket;"); @@ -1396,10 +1396,10 @@ QString ImportOPJ::parseOriginTags(const QString &str) { // replace \b(...), \i(...), \u(...), \g(...), \+(...), \-(...), \f:font(...) // tags - QString rxstr[] = {"\\\\\\s*b\\s*\\(", "\\\\\\s*i\\s*\\(", - "\\\\\\s*u\\s*\\(", "\\\\\\s*g\\s*\\(", - "\\\\\\s*\\+\\s*\\(", "\\\\\\s*\\-\\s*\\(", - "\\\\\\s*f\\:[^\\(]*\\("}; + QString rxstr[] = {R"(\\\s*b\s*\()", R"(\\\s*i\s*\()", + R"(\\\s*u\s*\()", R"(\\\s*g\s*\()", + R"(\\\s*\+\s*\()", R"(\\\s*\-\s*\()", + R"(\\\s*f\:[^\(]*\()"}; int postag[] = {0, 0, 0, 0, 0, 0, 0}; QString ltag[] = {"", "", "", "", "", "", ""}; @@ -1407,7 +1407,7 @@ QString ImportOPJ::parseOriginTags(const QString &str) { "", "", ""}; QRegExp rxtags[7]; for (int i = 0; i < 7; ++i) - rxtags[i].setPattern(rxstr[i] + "[^\\(\\)]*\\)"); + rxtags[i].setPattern(rxstr[i] + R"([^\(\)]*\))"); bool flag = true; while (flag) { diff --git a/MantidPlot/src/lib/src/TextFormatButtons.cpp b/MantidPlot/src/lib/src/TextFormatButtons.cpp index 54a29ade87b5..12b6dae42efb 100644 --- a/MantidPlot/src/lib/src/TextFormatButtons.cpp +++ b/MantidPlot/src/lib/src/TextFormatButtons.cpp @@ -457,10 +457,10 @@ void TextFormatButtons::addSymbol(const QString &letter) { else if (letter == QString(QChar(4 + s))) connectedTextEdit->textCursor().insertText("\\int"); else if (letter == QString(QChar(5 + s))) - connectedTextEdit->textCursor().insertText("\\int \\!\\!\\! \\int"); + connectedTextEdit->textCursor().insertText(R"(\int \!\!\! \int)"); else if (letter == QString(QChar(6 + s))) connectedTextEdit->textCursor().insertText( - "\\int \\!\\!\\! \\int \\!\\!\\! \\int"); + R"(\int \!\!\! \int \!\!\! \int)"); else if (letter == QString(QChar(7 + s))) connectedTextEdit->textCursor().insertText("\\oint"); From 7b45260b1c6fde1b580f31a39445fbf8015b1614 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Wed, 21 Mar 2018 15:25:49 +0000 Subject: [PATCH 338/364] Re #22154: Applied clang-format patch. --- MantidPlot/src/importOPJ.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MantidPlot/src/importOPJ.cpp b/MantidPlot/src/importOPJ.cpp index 3716e45d9a04..5c31a9bba3f7 100644 --- a/MantidPlot/src/importOPJ.cpp +++ b/MantidPlot/src/importOPJ.cpp @@ -1396,8 +1396,8 @@ QString ImportOPJ::parseOriginTags(const QString &str) { // replace \b(...), \i(...), \u(...), \g(...), \+(...), \-(...), \f:font(...) // tags - QString rxstr[] = {R"(\\\s*b\s*\()", R"(\\\s*i\s*\()", - R"(\\\s*u\s*\()", R"(\\\s*g\s*\()", + QString rxstr[] = {R"(\\\s*b\s*\()", R"(\\\s*i\s*\()", + R"(\\\s*u\s*\()", R"(\\\s*g\s*\()", R"(\\\s*\+\s*\()", R"(\\\s*\-\s*\()", R"(\\\s*f\:[^\(]*\()"}; int postag[] = {0, 0, 0, 0, 0, 0, 0}; From 7eda500228085cdef9b3b7ebe0be4da3ce655006 Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Wed, 21 Mar 2018 17:09:14 +0000 Subject: [PATCH 339/364] Rename MatPlotLib to MatPlotlib --- dev-docs/source/MVPTutorial/CompleteGUI.rst | 2 +- dev-docs/source/MVPTutorial/MatPlotLib.rst | 4 ++-- dev-docs/source/MVPTutorial/ViewExercise1.rst | 2 +- dev-docs/source/MVPTutorial/index.rst | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dev-docs/source/MVPTutorial/CompleteGUI.rst b/dev-docs/source/MVPTutorial/CompleteGUI.rst index af641f6f3ed3..a84b0a50f457 100644 --- a/dev-docs/source/MVPTutorial/CompleteGUI.rst +++ b/dev-docs/source/MVPTutorial/CompleteGUI.rst @@ -146,7 +146,7 @@ Plot Presenter PlotView ######## -Unchanged from `MatPlotLib and MVP `_. +Unchanged from `MatPlotlib and MVP `_. Presenter ######### diff --git a/dev-docs/source/MVPTutorial/MatPlotLib.rst b/dev-docs/source/MVPTutorial/MatPlotLib.rst index 1f26eba453cd..98a22e767a1b 100644 --- a/dev-docs/source/MVPTutorial/MatPlotLib.rst +++ b/dev-docs/source/MVPTutorial/MatPlotLib.rst @@ -1,12 +1,12 @@ ================== -MatPlotLib and MVP +MatPlotlib and MVP ================== The next step towards the goal of creating a GUI that allows users to manipulate a sine wave plot, is to produce the plot itself. For the purposes of this tutorial it is assumed that the user is -familiar with matplotlib, if not see `MatPlotLib documentation +familiar with MatPlotlib, if not see `MatPlotlib documentation `_. The MatPlotLib functions could be considered to be a Model or a View diff --git a/dev-docs/source/MVPTutorial/ViewExercise1.rst b/dev-docs/source/MVPTutorial/ViewExercise1.rst index 72b33cc53a64..ec679e728b10 100644 --- a/dev-docs/source/MVPTutorial/ViewExercise1.rst +++ b/dev-docs/source/MVPTutorial/ViewExercise1.rst @@ -17,7 +17,7 @@ plot. The table should include options for: The previous sections are not an exhaustive list of possible widgets. -The pages `MatPlotLib and MVP `_ and `MultipleView +The pages `MatPlotlib and MVP `_ and `MultipleView `_ will be useful for the exercise. The solution can be found `here `_. diff --git a/dev-docs/source/MVPTutorial/index.rst b/dev-docs/source/MVPTutorial/index.rst index 318f8ed233b4..f79bb129b618 100644 --- a/dev-docs/source/MVPTutorial/index.rst +++ b/dev-docs/source/MVPTutorial/index.rst @@ -21,7 +21,7 @@ Duration: 6 hours as a hands-on course with exercises. AddSpinBox Tables ViewExercise1 - MatPlotLib + MatPlotlib MultipleViews ViewExercise1Solution ReceivingSignalFromView From ddcb09bceb0b162b6138929af331b0848f9d31d8 Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Wed, 21 Mar 2018 17:10:22 +0000 Subject: [PATCH 340/364] Change MVP tutorial title --- dev-docs/source/MVPTutorial/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-docs/source/MVPTutorial/index.rst b/dev-docs/source/MVPTutorial/index.rst index f79bb129b618..ae45ae2b9bc7 100644 --- a/dev-docs/source/MVPTutorial/index.rst +++ b/dev-docs/source/MVPTutorial/index.rst @@ -1,6 +1,6 @@ -========= -MVP Index -========= +============ +MVP Tutorial +============ The following tutorial introduces how to create a Graphical User Interface (GUI) using PyQt. Some knowledge of Python is assumed. From 7d6d885e33153dc372e630058b57db31711f1187 Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Wed, 21 Mar 2018 17:22:14 +0000 Subject: [PATCH 341/364] Move Calculator example files to dev-docs directory --- dev-docs/source/GUIDesignGuidelines.rst | 4 ++-- .../MVPTutorial/CalculatorExample}/Calculator.py | 0 .../source/MVPTutorial/CalculatorExample}/Model.py | 0 .../MVPTutorial/CalculatorExample}/Presenter.py | 0 .../source/MVPTutorial/CalculatorExample}/View.py | 0 .../source/MVPTutorial/CalculatorExample/index.rst | 12 ++++++++++++ dev-docs/source/MVPTutorial/index.rst | 1 + 7 files changed, 15 insertions(+), 2 deletions(-) rename {scripts/MVPExample => dev-docs/source/MVPTutorial/CalculatorExample}/Calculator.py (100%) rename {scripts/MVPExample => dev-docs/source/MVPTutorial/CalculatorExample}/Model.py (100%) rename {scripts/MVPExample => dev-docs/source/MVPTutorial/CalculatorExample}/Presenter.py (100%) rename {scripts/MVPExample => dev-docs/source/MVPTutorial/CalculatorExample}/View.py (100%) create mode 100644 dev-docs/source/MVPTutorial/CalculatorExample/index.rst diff --git a/dev-docs/source/GUIDesignGuidelines.rst b/dev-docs/source/GUIDesignGuidelines.rst index b004ce72a65e..3f5790757a61 100644 --- a/dev-docs/source/GUIDesignGuidelines.rst +++ b/dev-docs/source/GUIDesignGuidelines.rst @@ -29,8 +29,8 @@ is given below. To illustrate MVP, a simple example of a calculator GUI has been created using Python (the concepts of MVP can be applied to any programming language). This example can be found in -``scripts/MVPExample``, and you can run it with ``python -Calculator.py``. +:ref:`dev-docs-gui-calculator-example`, and you can run it with +``python Calculator.py``. It is good practice to have model, view or presenter (as appropriate) at the end of the name for each file (e.g. FFTView, FFTModel, diff --git a/scripts/MVPExample/Calculator.py b/dev-docs/source/MVPTutorial/CalculatorExample/Calculator.py similarity index 100% rename from scripts/MVPExample/Calculator.py rename to dev-docs/source/MVPTutorial/CalculatorExample/Calculator.py diff --git a/scripts/MVPExample/Model.py b/dev-docs/source/MVPTutorial/CalculatorExample/Model.py similarity index 100% rename from scripts/MVPExample/Model.py rename to dev-docs/source/MVPTutorial/CalculatorExample/Model.py diff --git a/scripts/MVPExample/Presenter.py b/dev-docs/source/MVPTutorial/CalculatorExample/Presenter.py similarity index 100% rename from scripts/MVPExample/Presenter.py rename to dev-docs/source/MVPTutorial/CalculatorExample/Presenter.py diff --git a/scripts/MVPExample/View.py b/dev-docs/source/MVPTutorial/CalculatorExample/View.py similarity index 100% rename from scripts/MVPExample/View.py rename to dev-docs/source/MVPTutorial/CalculatorExample/View.py diff --git a/dev-docs/source/MVPTutorial/CalculatorExample/index.rst b/dev-docs/source/MVPTutorial/CalculatorExample/index.rst new file mode 100644 index 000000000000..87c9c8c32e2c --- /dev/null +++ b/dev-docs/source/MVPTutorial/CalculatorExample/index.rst @@ -0,0 +1,12 @@ +.. _dev-docs-gui-calculator-example: + +========================== +MVP Calculator GUI Example +========================== + +See the following files for the calculator GUI described in :ref:`dev-docs-mvp-intro`. + +- :download:`Main module ` +- :download:`Model.py ` +- :download:`Presenter.py ` +- :download:`View.py ` diff --git a/dev-docs/source/MVPTutorial/index.rst b/dev-docs/source/MVPTutorial/index.rst index ae45ae2b9bc7..f54ab6221113 100644 --- a/dev-docs/source/MVPTutorial/index.rst +++ b/dev-docs/source/MVPTutorial/index.rst @@ -35,4 +35,5 @@ Duration: 6 hours as a hands-on course with exercises. ModelExercise ModelExerciseSolution CompleteGUI + CalculatorExample/index From 98087ac152147f69e729036c10f6a2ae1d62837a Mon Sep 17 00:00:00 2001 From: josephframsay Date: Wed, 21 Mar 2018 17:24:55 +0000 Subject: [PATCH 342/364] Rename MatPlotLib.rst to MatPlotlib.rst --- dev-docs/source/MVPTutorial/{MatPlotLib.rst => MatPlotlib.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dev-docs/source/MVPTutorial/{MatPlotLib.rst => MatPlotlib.rst} (100%) diff --git a/dev-docs/source/MVPTutorial/MatPlotLib.rst b/dev-docs/source/MVPTutorial/MatPlotlib.rst similarity index 100% rename from dev-docs/source/MVPTutorial/MatPlotLib.rst rename to dev-docs/source/MVPTutorial/MatPlotlib.rst From b336d92e11157107620ab8f2ed88402ff8a152a5 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Tue, 27 Feb 2018 10:44:22 +0000 Subject: [PATCH 343/364] Add cacheing of Git commit timestamps in doc build Initially caches the Framework directory and expands as required. Re #21876 --- .../mantiddoc/directives/sourcelink.py | 22 +++----- .../mantiddoc/tools/git_last_modified.py | 53 +++++++++++++++++++ 2 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 docs/sphinxext/mantiddoc/tools/git_last_modified.py diff --git a/docs/sphinxext/mantiddoc/directives/sourcelink.py b/docs/sphinxext/mantiddoc/directives/sourcelink.py index de5b791e15f5..990bfbf99591 100644 --- a/docs/sphinxext/mantiddoc/directives/sourcelink.py +++ b/docs/sphinxext/mantiddoc/directives/sourcelink.py @@ -7,7 +7,7 @@ import mantid from .base import AlgorithmBaseDirective #pylint: disable=unused-import -LAST_MODIFIED_UNKNOWN = 'unknown' +from mantiddoc.tools.git_last_modified import get_file_last_modified_time class SourceLinkError(Exception): @@ -66,6 +66,8 @@ class SourceLinkDirective(AlgorithmBaseDirective): } file_lookup = {} + git_cache = {} + # will be filled in __source_root = None @@ -90,7 +92,8 @@ def execute(self): if file_paths[extension] is None: try: fname = self.find_source_file(file_name, extension) - file_paths[extension] = (fname, self.get_file_last_modified(fname)) \ + file_paths[extension] = ( + fname, get_file_last_modified_time(self.git_cache, self.source_root, fname)) \ if fname is not None else None except SourceLinkError as err: error_string += str(err) + "\n" @@ -103,7 +106,7 @@ def execute(self): else: # prepend the base framework directory fname = os.path.join(self.source_root, file_paths[extension]) - file_paths[extension] = (fname, self.get_file_last_modified(fname)) + file_paths[extension] = (fname, get_file_last_modified_time(self.git_cache, self.source_root, fname)) if not os.path.exists(file_paths[extension][0]): error_string += "Cannot find {} file at {}\n".format( extension, file_paths[extension][0]) @@ -255,19 +258,6 @@ def convert_path_to_github_url(self, file_path): url = "https://github.com/mantidproject/mantid/blob/" + mantid.kernel.revision_full() + url return url - def get_file_last_modified(self, filename): - """ - Gets the commit timestamp of the last commit to modify a given file. - """ - if not filename: - return LAST_MODIFIED_UNKNOWN - - proc = subprocess.Popen( - ['git', 'log', '-n 1', '--pretty=format:%cd', '--date=short', filename], - cwd=self.source_root, - stdout=subprocess.PIPE) - return str(proc.stdout.read().decode('utf-8')) - def setup(app): """ diff --git a/docs/sphinxext/mantiddoc/tools/git_last_modified.py b/docs/sphinxext/mantiddoc/tools/git_last_modified.py new file mode 100644 index 000000000000..d060d5b5be44 --- /dev/null +++ b/docs/sphinxext/mantiddoc/tools/git_last_modified.py @@ -0,0 +1,53 @@ +import os +import re +import subprocess + + +LAST_MODIFIED_UNKNOWN = 'unknown' + + +def cache_subtree(cache, root, path): + proc = subprocess.Popen( + ['git', 'log', '--pretty=format:%cd', '--date=short', '--name-only', path], + cwd=root, + stdout=subprocess.PIPE) + + current_date_str = None + + date_regex = re.compile('\d\d\d\d\-\d\d\-\d\d') + filename_regex = re.compile('[\/\w,\s\-\_]+\.[A-Za-z]+') + + for line in proc.stdout: + line = str(line.decode('utf-8')).strip() + + if date_regex.match(line): + # This line contains the date that the subsequent files were last modified + current_date_str = line + + # Only take the first (most recent) appearence of each file + elif filename_regex.match(line) and line not in cache: + # This line contains a file that was modified on the last mentioned date + cache[line] = current_date_str + + +def get_file_last_modified_time(cache, root, filename): + # If cache is empty then start by caching all of Framework + # Will usually catch all the files you need + if len(cache) == 0: + cache_subtree(cache, root, 'Framework') + + source_filename = filename.replace(root, '') + if source_filename.startswith(os.path.sep): + source_filename = source_filename[1:] + + # Check if details for this file have already been cached + if source_filename not in cache: + # Cache the subtree for this file + subtree_path = os.path.dirname(filename) + cache_subtree(cache, root, subtree_path) + + # Make sure it is cached now + if source_filename not in cache: + return LAST_MODIFIED_UNKNOWN + + return cache[source_filename] From a60365b9741178e2fab40f28e30b83cf24f8e6bb Mon Sep 17 00:00:00 2001 From: Pete Peterson Date: Wed, 21 Mar 2018 15:47:06 -0400 Subject: [PATCH 344/364] Fix call in python -m branch --- dev-docs/CMakeLists.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dev-docs/CMakeLists.txt b/dev-docs/CMakeLists.txt index b7e1b6612a40..a833065f69b1 100644 --- a/dev-docs/CMakeLists.txt +++ b/dev-docs/CMakeLists.txt @@ -12,14 +12,15 @@ set ( DOCTREE_DIR ${CMAKE_CURRENT_BINARY_DIR}/doctree ) # Sphinx dont't allow python -m execution. Assume # we are running on Linux and `sphinx-build` is available in these cases if ( EXISTS ${SPHINX_PACKAGE_DIR}/__main__.py ) - set ( SPHINX_BUILD "python -m sphinx" ) + add_custom_target ( dev-docs-${BUILDER} + COMMAND ${PYTHON_EXECUTABLE} -m sphinx -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR} + COMMENT "Building html developer documentation" ) else () - set ( SPHINX_BUILD "sphinx-build" ) + add_custom_target ( dev-docs-${BUILDER} + COMMAND sphinx-build -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR} + COMMENT "Building html developer documentation" ) endif () -add_custom_target ( dev-docs-${BUILDER} - COMMAND ${SPHINX_BUILD} -b ${BUILDER} -d ${DOCTREE_DIR} ${CMAKE_CURRENT_LIST_DIR}/source ${OUT_DIR} - COMMENT "Building html developer documentation" ) # Group within VS and exclude from whole build set_target_properties ( dev-docs-html PROPERTIES FOLDER "Documentation" EXCLUDE_FROM_DEFAULT_BUILD 1 From 27abe516e90420c9ad33264c9e215bd526b7b8ae Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 08:31:14 +0000 Subject: [PATCH 345/364] Re #20991: Update doctest results. --- docs/source/algorithms/ReflectometryReductionOne-v2.rst | 6 +++--- docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/source/algorithms/ReflectometryReductionOne-v2.rst b/docs/source/algorithms/ReflectometryReductionOne-v2.rst index aa317703b266..3c1db8769062 100644 --- a/docs/source/algorithms/ReflectometryReductionOne-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOne-v2.rst @@ -254,10 +254,10 @@ Output: .. testoutput:: ExReflRedOneTrans - 0.4592 + 0.4597 0.4654 - 0.7278 - 1.0305 + 0.7203 + 1.0512 .. categories:: diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst index a923be6b6548..cfd80f250fdd 100644 --- a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst @@ -198,10 +198,10 @@ Output: 0.00441 0.00462 - 0.64241 - 0.41453 + 0.64231 + 0.41456 0.51029 - 0.52240 + 0.52241 .. categories:: From de5563171989019e5e5538c4f878e8b3a09a93b3 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 09:30:15 +0000 Subject: [PATCH 346/364] Re #22169: Applied fixes to Framework excluding Framwork/ICat. --- Framework/API/test/AlgorithmManagerTest.h | 12 +++--- Framework/API/test/AlgorithmTest.h | 8 ++-- Framework/API/test/ExperimentInfoTest.h | 10 ++--- Framework/API/test/FunctionTest.h | 8 ++-- Framework/API/test/IMDWorkspaceTest.h | 8 ++-- .../API/test/MatrixWorkspaceMDIteratorTest.h | 8 ++-- Framework/API/test/MatrixWorkspaceTest.h | 10 ++--- .../API/test/MultiPeriodGroupAlgorithmTest.h | 4 +- Framework/API/test/WorkspaceGroupTest.h | 16 ++++---- .../Algorithms/test/BinaryOperateMasksTest.h | 6 +-- Framework/Algorithms/test/ConvertUnitsTest.h | 2 +- .../test/CorelliCrossCorrelateTest.h | 2 +- .../test/DetectorEfficiencyCorTest.h | 4 +- .../test/DiffractionFocussing2Test.h | 2 +- .../test/GenerateIPythonNotebookTest.h | 2 +- .../test/GeneratePythonScriptTest.h | 2 +- .../Algorithms/test/LorentzCorrectionTest.h | 2 +- Framework/Algorithms/test/MergeRunsTest.h | 6 +-- .../Algorithms/test/NormaliseByDetectorTest.h | 6 +-- .../Algorithms/test/RebinByTimeBaseTest.h | 2 +- .../test/SANSCollimationLengthEstimatorTest.h | 2 +- .../test/TOFSANSResolutionByPixelTest.h | 2 +- .../test/HardThresholdBackgroundTest.h | 2 +- .../test/Algorithms/ConvertToYSpaceTest.h | 4 +- .../test/Algorithms/NormaliseByPeakAreaTest.h | 16 ++++---- .../VesuvioCalculateGammaBackgroundTest.h | 12 +++--- .../test/Algorithms/VesuvioCalculateMSTest.h | 2 +- .../Functions/ComptonProfileTestHelpers.h | 2 +- .../test/LoadEmptyInstrumentTest.h | 4 +- .../DataHandling/test/LoadISISNexusTest.h | 4 +- .../DataHandling/test/LoadInstrumentTest.h | 2 +- .../test/LoadNexusProcessedTest.h | 8 ++-- .../test/LoadRawSaveNxsLoadNxsTest.h | 4 +- .../inc/MantidDataObjects/MDHistoWorkspace.h | 2 +- Framework/DataObjects/test/EventListTest.h | 2 +- .../DataObjects/test/EventWorkspaceTest.h | 16 ++++---- .../DataObjects/test/GroupingWorkspaceTest.h | 8 ++-- .../DataObjects/test/MDBoxIteratorTest.h | 2 +- .../DataObjects/test/MDBoxSaveableTest.h | 6 +-- Framework/DataObjects/test/MDBoxTest.h | 4 +- .../DataObjects/test/MDEventWorkspaceTest.h | 16 ++++---- Framework/DataObjects/test/MDGridBoxTest.h | 16 ++++---- .../test/MDHistoWorkspaceIteratorTest.h | 2 +- .../DataObjects/test/MDHistoWorkspaceTest.h | 10 ++--- .../DataObjects/test/MaskWorkspaceTest.h | 8 ++-- .../DataObjects/test/OffsetsWorkspaceTest.h | 8 ++-- .../DataObjects/test/PeaksWorkspaceTest.h | 16 ++++---- .../DataObjects/test/SpecialWorkspace2DTest.h | 8 ++-- Framework/DataObjects/test/Workspace2DTest.h | 8 ++-- .../test/WorkspaceSingleValueTest.h | 8 ++-- Framework/Geometry/test/ParameterMapTest.h | 10 ++--- .../ICat/inc/MantidICat/ICat3/ICat3Helper.h | 2 +- .../Kernel/test/DiskBufferISaveableTest.h | 4 +- Framework/Kernel/test/DiskBufferTest.h | 2 +- Framework/MDAlgorithms/test/BinMDTest.h | 2 +- .../test/ConvertToReflectometryQTest.h | 20 +++++----- Framework/MDAlgorithms/test/DivideMDTest.h | 2 +- .../test/ImportMDHistoWorkspaceTest.h | 4 +- Framework/MDAlgorithms/test/LoadMDTest.h | 2 +- Framework/MDAlgorithms/test/MDWSTransfTest.h | 2 +- Framework/MDAlgorithms/test/MultiplyMDTest.h | 2 +- .../MDAlgorithms/test/QueryMDWorkspaceTest.h | 10 ++--- Framework/MDAlgorithms/test/SaveMD2Test.h | 2 +- Framework/MDAlgorithms/test/SaveMDTest.h | 2 +- .../MDAlgorithms/test/SlicingAlgorithmTest.h | 40 +++++++++---------- .../MDAlgorithms/test/WeightedMeanMDTest.h | 4 +- .../SINQ/test/PoldiInstrumentAdapterTest.h | 2 +- .../MantidTestHelpers/MDEventsTestHelper.h | 2 +- Framework/Types/test/DateAndTimeTest.h | 2 +- 69 files changed, 220 insertions(+), 220 deletions(-) diff --git a/Framework/API/test/AlgorithmManagerTest.h b/Framework/API/test/AlgorithmManagerTest.h index fcdbcdcb517c..281451bef434 100644 --- a/Framework/API/test/AlgorithmManagerTest.h +++ b/Framework/API/test/AlgorithmManagerTest.h @@ -139,13 +139,13 @@ class AlgorithmManagerTest : public CxxTest::TestSuite { TS_ASSERT_THROWS_NOTHING( alg = AlgorithmManager::Instance().create("AlgTest", 1)); TS_ASSERT_DIFFERS(dynamic_cast(alg.get()), - static_cast(0)); + static_cast(nullptr)); TS_ASSERT_THROWS_NOTHING( alg = AlgorithmManager::Instance().create("AlgTestSecond", 1)); TS_ASSERT_DIFFERS(dynamic_cast(alg.get()), - static_cast(0)); + static_cast(nullptr)); TS_ASSERT_DIFFERS(dynamic_cast(alg.get()), - static_cast(0)); + static_cast(nullptr)); TS_ASSERT_EQUALS(AlgorithmManager::Instance().size(), 2); // To check that crea is called on local objects } @@ -157,8 +157,8 @@ class AlgorithmManagerTest : public CxxTest::TestSuite { Bptr = AlgorithmManager::Instance().createUnmanaged("AlgTest"); TS_ASSERT_DIFFERS(Aptr, Bptr); TS_ASSERT_EQUALS(AlgorithmManager::Instance().size(), 1); - TS_ASSERT_DIFFERS(Aptr.get(), static_cast(0)); - TS_ASSERT_DIFFERS(Bptr.get(), static_cast(0)); + TS_ASSERT_DIFFERS(Aptr.get(), static_cast(nullptr)); + TS_ASSERT_DIFFERS(Bptr.get(), static_cast(nullptr)); } void testCreateNoProxy() { @@ -169,7 +169,7 @@ class AlgorithmManagerTest : public CxxTest::TestSuite { TSM_ASSERT("Was created as a AlgorithmProxy", dynamic_cast(Aptr.get())); TSM_ASSERT("Was NOT created as a AlgorithmProxy", - dynamic_cast(Bptr.get()) == NULL); + dynamic_cast(Bptr.get()) == nullptr); } // This will be called back when an algo starts diff --git a/Framework/API/test/AlgorithmTest.h b/Framework/API/test/AlgorithmTest.h index 92f3c17252ce..90dc4fc869f4 100644 --- a/Framework/API/test/AlgorithmTest.h +++ b/Framework/API/test/AlgorithmTest.h @@ -808,10 +808,10 @@ class AlgorithmTest : public CxxTest::TestSuite { IAlgorithm_sptr algNonConst; TS_ASSERT_THROWS_NOTHING( algConst = manager.getValue(algName)); - TS_ASSERT(algConst != NULL); + TS_ASSERT(algConst != nullptr); TS_ASSERT_THROWS_NOTHING(algNonConst = manager.getValue(algName)); - TS_ASSERT(algNonConst != NULL); + TS_ASSERT(algNonConst != nullptr); TS_ASSERT_EQUALS(algConst, algNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -819,9 +819,9 @@ class AlgorithmTest : public CxxTest::TestSuite { IAlgorithm_const_sptr algCastConst; IAlgorithm_sptr algCastNonConst; TS_ASSERT_THROWS_NOTHING(algCastConst = (IAlgorithm_const_sptr)val); - TS_ASSERT(algCastConst != NULL); + TS_ASSERT(algCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(algCastNonConst = (IAlgorithm_sptr)val); - TS_ASSERT(algCastNonConst != NULL); + TS_ASSERT(algCastNonConst != nullptr); TS_ASSERT_EQUALS(algCastConst, algCastNonConst); } diff --git a/Framework/API/test/ExperimentInfoTest.h b/Framework/API/test/ExperimentInfoTest.h index 8941eb1eb703..a9a01510235a 100644 --- a/Framework/API/test/ExperimentInfoTest.h +++ b/Framework/API/test/ExperimentInfoTest.h @@ -129,7 +129,7 @@ class ExperimentInfoTest : public CxxTest::TestSuite { void test_Setting_A_New_Chopper_With_NULL_Ptr_Throws() { ExperimentInfo_sptr ws = createTestInfoWithChopperPoints(1); - TS_ASSERT_THROWS(ws->setChopperModel(NULL), std::invalid_argument); + TS_ASSERT_THROWS(ws->setChopperModel(nullptr), std::invalid_argument); } void test_Setting_A_New_Chopper_To_Point_Lower_Point_Succeeds() { @@ -729,10 +729,10 @@ class ExperimentInfoTest : public CxxTest::TestSuite { ExperimentInfo_sptr eiNonConst; TS_ASSERT_THROWS_NOTHING( eiConst = manager.getValue(eiName)); - TS_ASSERT(eiConst != NULL); + TS_ASSERT(eiConst != nullptr); TS_ASSERT_THROWS_NOTHING(eiNonConst = manager.getValue(eiName)); - TS_ASSERT(eiNonConst != NULL); + TS_ASSERT(eiNonConst != nullptr); TS_ASSERT_EQUALS(eiConst, eiNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -740,9 +740,9 @@ class ExperimentInfoTest : public CxxTest::TestSuite { ExperimentInfo_const_sptr eiCastConst; ExperimentInfo_sptr eiCastNonConst; TS_ASSERT_THROWS_NOTHING(eiCastConst = (ExperimentInfo_const_sptr)val); - TS_ASSERT(eiCastConst != NULL); + TS_ASSERT(eiCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(eiCastNonConst = (ExperimentInfo_sptr)val); - TS_ASSERT(eiCastNonConst != NULL); + TS_ASSERT(eiCastNonConst != nullptr); TS_ASSERT_EQUALS(eiCastConst, eiCastNonConst); } diff --git a/Framework/API/test/FunctionTest.h b/Framework/API/test/FunctionTest.h index 5fddb7db7ede..7b770abc5755 100644 --- a/Framework/API/test/FunctionTest.h +++ b/Framework/API/test/FunctionTest.h @@ -411,10 +411,10 @@ class FunctionTest : public CxxTest::TestSuite { IFunction_sptr funcNonConst; TS_ASSERT_THROWS_NOTHING( funcConst = manager.getValue(funcName)); - TS_ASSERT(funcConst != NULL); + TS_ASSERT(funcConst != nullptr); TS_ASSERT_THROWS_NOTHING(funcNonConst = manager.getValue(funcName)); - TS_ASSERT(funcNonConst != NULL); + TS_ASSERT(funcNonConst != nullptr); TS_ASSERT_EQUALS(funcConst, funcNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -422,9 +422,9 @@ class FunctionTest : public CxxTest::TestSuite { IFunction_const_sptr funcCastConst; IFunction_sptr funcCastNonConst; TS_ASSERT_THROWS_NOTHING(funcCastConst = (IFunction_const_sptr)val); - TS_ASSERT(funcCastConst != NULL); + TS_ASSERT(funcCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(funcCastNonConst = (IFunction_sptr)val); - TS_ASSERT(funcCastNonConst != NULL); + TS_ASSERT(funcCastNonConst != nullptr); TS_ASSERT_EQUALS(funcCastConst, funcCastNonConst); } diff --git a/Framework/API/test/IMDWorkspaceTest.h b/Framework/API/test/IMDWorkspaceTest.h index b7476124c4b2..e8b9d8aa3e30 100644 --- a/Framework/API/test/IMDWorkspaceTest.h +++ b/Framework/API/test/IMDWorkspaceTest.h @@ -125,10 +125,10 @@ class IMDWorkspaceTest : public CxxTest::TestSuite { IMDWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -136,9 +136,9 @@ class IMDWorkspaceTest : public CxxTest::TestSuite { IMDWorkspace_const_sptr wsCastConst; IMDWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (IMDWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IMDWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h index 5d1f3979ffd9..13c44fa5e4a7 100644 --- a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h +++ b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h @@ -53,7 +53,7 @@ class MatrixWorkspaceMDIteratorTest : public CxxTest::TestSuite { void test_iterating() { boost::shared_ptr ws = makeFakeWS(); IMDIterator *it = nullptr; - TS_ASSERT_THROWS_NOTHING(it = ws->createIterator(NULL)); + TS_ASSERT_THROWS_NOTHING(it = ws->createIterator(nullptr)); TS_ASSERT_EQUALS(it->getDataSize(), 20); TS_ASSERT_DELTA(it->getSignal(), 0.0, 1e-5); it->next(); @@ -90,13 +90,13 @@ class MatrixWorkspaceMDIteratorTest : public CxxTest::TestSuite { void test_parallel_iterators() { boost::shared_ptr ws = makeFakeWS(); // The number of output cannot be larger than the number of histograms - std::vector it = ws->createIterators(10, NULL); + std::vector it = ws->createIterators(10, nullptr); TS_ASSERT_EQUALS(it.size(), 4); for (size_t i = 0; i < it.size(); ++i) delete it[i]; // Split in 4 iterators - std::vector iterators = ws->createIterators(4, NULL); + std::vector iterators = ws->createIterators(4, nullptr); TS_ASSERT_EQUALS(iterators.size(), 4); for (size_t i = 0; i < iterators.size(); i++) { @@ -122,7 +122,7 @@ class MatrixWorkspaceMDIteratorTest : public CxxTest::TestSuite { void test_get_is_masked() { boost::shared_ptr ws = makeFakeWS(); - IMDIterator *it = ws->createIterator(NULL); + IMDIterator *it = ws->createIterator(nullptr); const auto &spectrumInfo = ws->spectrumInfo(); for (size_t i = 0; i < ws->getNumberHistograms(); ++i) { TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), it->getIsMasked()); diff --git a/Framework/API/test/MatrixWorkspaceTest.h b/Framework/API/test/MatrixWorkspaceTest.h index ae4ccae9b724..15181c264870 100644 --- a/Framework/API/test/MatrixWorkspaceTest.h +++ b/Framework/API/test/MatrixWorkspaceTest.h @@ -1018,7 +1018,7 @@ class MatrixWorkspaceTest : public CxxTest::TestSuite { void test_setMDMasking() { WorkspaceTester ws; TSM_ASSERT_THROWS("Characterisation test. This is not implemented.", - ws.setMDMasking(NULL), std::runtime_error); + ws.setMDMasking(nullptr), std::runtime_error); } void test_clearMDMasking() { @@ -1569,10 +1569,10 @@ class MatrixWorkspaceTest : public CxxTest::TestSuite { MatrixWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -1580,9 +1580,9 @@ class MatrixWorkspaceTest : public CxxTest::TestSuite { MatrixWorkspace_const_sptr wsCastConst; MatrixWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (MatrixWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (MatrixWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } diff --git a/Framework/API/test/MultiPeriodGroupAlgorithmTest.h b/Framework/API/test/MultiPeriodGroupAlgorithmTest.h index 6bd1b7a2ac46..baff00192e95 100644 --- a/Framework/API/test/MultiPeriodGroupAlgorithmTest.h +++ b/Framework/API/test/MultiPeriodGroupAlgorithmTest.h @@ -214,7 +214,7 @@ class MultiPeriodGroupAlgorithmTest : public CxxTest::TestSuite, WorkspaceGroup_sptr wsgroup = Mantid::API::AnalysisDataService::Instance().retrieveWS( "outWS"); - TS_ASSERT(wsgroup != NULL); + TS_ASSERT(wsgroup != nullptr); TS_ASSERT_EQUALS(a->size(), wsgroup->size()); } @@ -241,7 +241,7 @@ class MultiPeriodGroupAlgorithmTest : public CxxTest::TestSuite, WorkspaceGroup_sptr wsgroup = Mantid::API::AnalysisDataService::Instance().retrieveWS( "outWS"); - TS_ASSERT(wsgroup != NULL); + TS_ASSERT(wsgroup != nullptr); TS_ASSERT_EQUALS(a->size(), wsgroup->size()); } }; diff --git a/Framework/API/test/WorkspaceGroupTest.h b/Framework/API/test/WorkspaceGroupTest.h index b04f5dc32c96..c078d3040924 100644 --- a/Framework/API/test/WorkspaceGroupTest.h +++ b/Framework/API/test/WorkspaceGroupTest.h @@ -368,10 +368,10 @@ class WorkspaceGroupTest : public CxxTest::TestSuite { WorkspaceGroup_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -379,9 +379,9 @@ class WorkspaceGroupTest : public CxxTest::TestSuite { WorkspaceGroup_const_sptr wsCastConst; WorkspaceGroup_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (WorkspaceGroup_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (WorkspaceGroup_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } @@ -400,10 +400,10 @@ class WorkspaceGroupTest : public CxxTest::TestSuite { Workspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -411,9 +411,9 @@ class WorkspaceGroupTest : public CxxTest::TestSuite { Workspace_const_sptr wsCastConst; Workspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (Workspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (Workspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/Algorithms/test/BinaryOperateMasksTest.h b/Framework/Algorithms/test/BinaryOperateMasksTest.h index f5fb9d1ad1eb..886f12eef1e7 100644 --- a/Framework/Algorithms/test/BinaryOperateMasksTest.h +++ b/Framework/Algorithms/test/BinaryOperateMasksTest.h @@ -72,7 +72,7 @@ class BinaryOperateMasksTest : public CxxTest::TestSuite { std::cout << "\nTest I Is Completed\n"; - if (ws1 == NULL) { + if (ws1 == nullptr) { std::cout << "\nWorkspace1 is NULL\n"; } @@ -100,13 +100,13 @@ class BinaryOperateMasksTest : public CxxTest::TestSuite { ws4 = AnalysisDataService::Instance() .retrieveWS(ws4name); - if (ws4 == NULL) { + if (ws4 == nullptr) { std::cout << "Workspace4 is NULL\n"; } else { std::cout << "Workspace4 is good at output of NOT. Number Histogram = " << ws4->getNumberHistograms() << '\n'; } - if (ws1 == NULL) { + if (ws1 == nullptr) { std::cout << "Workspace1 is NULL\n"; } else { std::cout << "Workspace1 is good at output of NOT. Number Histogram = " diff --git a/Framework/Algorithms/test/ConvertUnitsTest.h b/Framework/Algorithms/test/ConvertUnitsTest.h index 5340a181e069..67db2df5870f 100644 --- a/Framework/Algorithms/test/ConvertUnitsTest.h +++ b/Framework/Algorithms/test/ConvertUnitsTest.h @@ -714,7 +714,7 @@ class ConvertUnitsTest : public CxxTest::TestSuite { WorkspaceCreationHelper::createEventWorkspaceWithFullInstrument(1, 10, false); ws->getAxis(0)->setUnit("TOF"); - ws->sortAll(sortType, NULL); + ws->sortAll(sortType, nullptr); if (sortType == TOF_SORT) { // Only threadsafe if all the event lists are sorted diff --git a/Framework/Algorithms/test/CorelliCrossCorrelateTest.h b/Framework/Algorithms/test/CorelliCrossCorrelateTest.h index 6647ebd9c676..da7c08c0a750 100644 --- a/Framework/Algorithms/test/CorelliCrossCorrelateTest.h +++ b/Framework/Algorithms/test/CorelliCrossCorrelateTest.h @@ -62,7 +62,7 @@ class CorelliCrossCorrelateTest : public CxxTest::TestSuite { ws->getAxis(0)->setUnit("TOF"); - ws->sortAll(PULSETIME_SORT, NULL); + ws->sortAll(PULSETIME_SORT, nullptr); // Add some chopper TDCs to the workspace. double period = 1 / 293.383; diff --git a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h index 419b32dd424a..c0fb1956a216 100644 --- a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h +++ b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h @@ -128,13 +128,13 @@ class DetectorEfficiencyCorTest : public CxxTest::TestSuite { const int ndets(2); std::vector detectors; for (int i = 0; i < ndets; ++i) { - Detector *detector = new Detector("det", i + 1, shape, NULL); + Detector *detector = new Detector("det", i + 1, shape, nullptr); detector->setPos(i * 0.2, i * 0.2, 5); instrument->add(detector); instrument->markAsDetector(detector); detectors.push_back(detector); } - ObjComponent *sample = new ObjComponent("sample", shape, NULL); + ObjComponent *sample = new ObjComponent("sample", shape, nullptr); sample->setPos(0, 0, 0); instrument->markAsSamplePos(sample); diff --git a/Framework/Algorithms/test/DiffractionFocussing2Test.h b/Framework/Algorithms/test/DiffractionFocussing2Test.h index c0a0e67a7755..c22f2022a26a 100644 --- a/Framework/Algorithms/test/DiffractionFocussing2Test.h +++ b/Framework/Algorithms/test/DiffractionFocussing2Test.h @@ -270,7 +270,7 @@ class DiffractionFocussing2TestPerformance : public CxxTest::TestSuite { alg->execute(); ws = AnalysisDataService::Instance().retrieveWS( "SNAP_empty"); - ws->sortAll(TOF_SORT, NULL); + ws->sortAll(TOF_SORT, nullptr); // Fill a whole bunch of events PARALLEL_FOR_NO_WSP_CHECK() diff --git a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h index 161da6b66676..7f82d223721f 100644 --- a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h +++ b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h @@ -156,7 +156,7 @@ class GenerateIPythonNotebookTest : public CxxTest::TestSuite { history.addHistory(boost::make_shared( API::AlgorithmHistory(pAlg.get()))); - pAlg.reset(NULL); + pAlg.reset(nullptr); } }; diff --git a/Framework/Algorithms/test/GeneratePythonScriptTest.h b/Framework/Algorithms/test/GeneratePythonScriptTest.h index 67ac94d0a325..f88f2d1cfd42 100644 --- a/Framework/Algorithms/test/GeneratePythonScriptTest.h +++ b/Framework/Algorithms/test/GeneratePythonScriptTest.h @@ -159,7 +159,7 @@ class GeneratePythonScriptTest : public CxxTest::TestSuite { history.addHistory(boost::make_shared( API::AlgorithmHistory(pAlg.get()))); - pAlg.reset(NULL); + pAlg.reset(nullptr); } }; diff --git a/Framework/Algorithms/test/LorentzCorrectionTest.h b/Framework/Algorithms/test/LorentzCorrectionTest.h index 0190630e7c05..99cdf9c70503 100644 --- a/Framework/Algorithms/test/LorentzCorrectionTest.h +++ b/Framework/Algorithms/test/LorentzCorrectionTest.h @@ -126,7 +126,7 @@ class LorentzCorrectionTest : public CxxTest::TestSuite { alg.setPropertyValue("OutputWorkspace", "temp"); alg.execute(); MatrixWorkspace_sptr out_ws = alg.getProperty("OutputWorkspace"); - TS_ASSERT(out_ws != NULL); + TS_ASSERT(out_ws != nullptr); const std::string unitID = out_ws->getAxis(0)->unit()->unitID(); TS_ASSERT_EQUALS(unitID, "Wavelength"); diff --git a/Framework/Algorithms/test/MergeRunsTest.h b/Framework/Algorithms/test/MergeRunsTest.h index 24f962ba1f78..bbdde628d2bb 100644 --- a/Framework/Algorithms/test/MergeRunsTest.h +++ b/Framework/Algorithms/test/MergeRunsTest.h @@ -281,7 +281,7 @@ class MergeRunsTest : public CxxTest::TestSuite { TS_ASSERT_THROWS_NOTHING(alg.execute()); MatrixWorkspace_sptr wsOut = Mantid::API::AnalysisDataService::Instance() .retrieveWS("out"); - TS_ASSERT(wsOut != NULL); + TS_ASSERT(wsOut != nullptr); for (size_t j = 0; j < wsOut->getNumberHistograms(); ++j) { using Mantid::MantidVec; auto &xValues = wsOut->x(j); @@ -930,13 +930,13 @@ class MergeRunsTest : public CxxTest::TestSuite { WorkspaceGroup_sptr wsgroup = Mantid::API::AnalysisDataService::Instance().retrieveWS( "outer"); - TS_ASSERT(wsgroup != NULL); + TS_ASSERT(wsgroup != nullptr); TS_ASSERT_EQUALS(input->size(), wsgroup->size()); // Loop through each workspace in the group for (size_t i = 0; i < wsgroup->size(); ++i) { MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast(wsgroup->getItem(i)); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); TS_ASSERT_EQUALS(expectedNumHistograms, ws->getNumberHistograms()); // Loop through each histogram in each workspace for (size_t j = 0; j < ws->getNumberHistograms(); ++j) { diff --git a/Framework/Algorithms/test/NormaliseByDetectorTest.h b/Framework/Algorithms/test/NormaliseByDetectorTest.h index a66f14d5b4a1..63aa2b3f5a85 100644 --- a/Framework/Algorithms/test/NormaliseByDetectorTest.h +++ b/Framework/Algorithms/test/NormaliseByDetectorTest.h @@ -51,7 +51,7 @@ do_test_doesnt_throw_on_execution(MatrixWorkspace_sptr inputWS, TS_ASSERT_THROWS_NOTHING(alg.execute()); MatrixWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS("out"); - TS_ASSERT(outWS != NULL); + TS_ASSERT(outWS != nullptr); return outWS; } @@ -225,7 +225,7 @@ class NormaliseByDetectorTest : public CxxTest::TestSuite { create_workspace_with_incomplete_detector_level_only_fit_functions( MatrixWorkspace_sptr original = boost::shared_ptr()) { MatrixWorkspace_sptr ws = original; - if (original == NULL) { + if (original == nullptr) { // Create a default workspace with no-fitting functions. ws = create_workspace_with_no_fitting_functions(); } @@ -649,7 +649,7 @@ class NormaliseByDetectorTestPerformance : public CxxTest::TestSuite { private: /// Helper method to run common sanity checks. void do_basic_checks(MatrixWorkspace_sptr normalisedWS) { - TS_ASSERT(normalisedWS != NULL); + TS_ASSERT(normalisedWS != nullptr); TS_ASSERT(ws->getNumberHistograms() == normalisedWS->getNumberHistograms()); TS_ASSERT(ws->x(0).size() == normalisedWS->x(0).size()); TS_ASSERT(ws->y(0).size() == normalisedWS->y(0).size()); diff --git a/Framework/Algorithms/test/RebinByTimeBaseTest.h b/Framework/Algorithms/test/RebinByTimeBaseTest.h index c9b8d5f17bed..1f3f4ab0f1fd 100644 --- a/Framework/Algorithms/test/RebinByTimeBaseTest.h +++ b/Framework/Algorithms/test/RebinByTimeBaseTest.h @@ -526,7 +526,7 @@ template class RebinByTimeBaseTestPerformance { // Simple tests. Functionality tests cover this much better. MatrixWorkspace_sptr outWS = AnalysisDataService::Instance().retrieveWS("outWS"); - TS_ASSERT(outWS != NULL); + TS_ASSERT(outWS != nullptr); } }; diff --git a/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h b/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h index 989a5db08afb..f4b89655dea4 100644 --- a/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h +++ b/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h @@ -51,7 +51,7 @@ createTestInstrument(const Mantid::detid_t id, Detector *det0(nullptr); if (!detShapeXML.empty()) { auto shape = ShapeFactory().createShape(detShapeXML); - det0 = new Detector("det0", id, shape, NULL); + det0 = new Detector("det0", id, shape, nullptr); } else { det0 = new Detector("det0", id, nullptr); } diff --git a/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h b/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h index 980b8035bf04..7d7ddbd661f7 100644 --- a/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h +++ b/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h @@ -62,7 +62,7 @@ createTestInstrument(const Mantid::detid_t id, Detector *det0(nullptr); if (!detShapeXML.empty()) { auto shape = ShapeFactory().createShape(detShapeXML); - det0 = new Detector("det0", id, shape, NULL); + det0 = new Detector("det0", id, shape, nullptr); } else { det0 = new Detector("det0", id, nullptr); } diff --git a/Framework/Crystal/test/HardThresholdBackgroundTest.h b/Framework/Crystal/test/HardThresholdBackgroundTest.h index 3ba3c728bd0c..5429cc3c3c72 100644 --- a/Framework/Crystal/test/HardThresholdBackgroundTest.h +++ b/Framework/Crystal/test/HardThresholdBackgroundTest.h @@ -23,7 +23,7 @@ class HardThresholdBackgroundTest : public CxxTest::TestSuite { void test_isBackground() { const double threshold = 1; MDHistoWorkspace_sptr ws = makeFakeMDHistoWorkspace(threshold, 1, 1); - auto iterator = ws->createIterator(NULL); + auto iterator = ws->createIterator(nullptr); HardThresholdBackground strategy(threshold, Mantid::API::NoNormalization); diff --git a/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h b/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h index 17ed511e6d0c..4c85a58beb16 100644 --- a/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h +++ b/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h @@ -57,13 +57,13 @@ class ConvertToYSpaceTest : public CxxTest::TestSuite { // Get the y-Space output workspace MatrixWorkspace_sptr ySpOutputWs = alg->getProperty("OutputWorkspace"); - TS_ASSERT(ySpOutputWs != 0) + TS_ASSERT(ySpOutputWs != nullptr) TS_ASSERT_EQUALS(testWS->getNumberHistograms(), ySpOutputWs->getNumberHistograms()); // Get the q-Space output workspace MatrixWorkspace_sptr qSpOutputWs = alg->getProperty("QWorkspace"); - TS_ASSERT(qSpOutputWs != 0) + TS_ASSERT(qSpOutputWs != nullptr) TS_ASSERT_EQUALS(testWS->getNumberHistograms(), qSpOutputWs->getNumberHistograms()); diff --git a/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h b/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h index ef0f8b8aa540..549553b7dfdb 100644 --- a/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h +++ b/Framework/CurveFitting/test/Algorithms/NormaliseByPeakAreaTest.h @@ -60,10 +60,10 @@ class NormaliseByPeakAreaTest : public CxxTest::TestSuite { MatrixWorkspace_sptr fittedWS = alg->getProperty("FittedWorkspace"); MatrixWorkspace_sptr symmetrisedWS = alg->getProperty("SymmetrisedWorkspace"); - TS_ASSERT(outputWS != 0); - TS_ASSERT(yspaceWS != 0); - TS_ASSERT(fittedWS != 0); - TS_ASSERT(symmetrisedWS != 0); + TS_ASSERT(outputWS != nullptr); + TS_ASSERT(yspaceWS != nullptr); + TS_ASSERT(fittedWS != nullptr); + TS_ASSERT(symmetrisedWS != nullptr); // Dimensions TS_ASSERT_EQUALS(testWS->getNumberHistograms(), @@ -171,10 +171,10 @@ class NormaliseByPeakAreaTest : public CxxTest::TestSuite { MatrixWorkspace_sptr fittedWS = alg->getProperty("FittedWorkspace"); MatrixWorkspace_sptr symmetrisedWS = alg->getProperty("SymmetrisedWorkspace"); - TS_ASSERT(outputWS != 0); - TS_ASSERT(yspaceWS != 0); - TS_ASSERT(fittedWS != 0); - TS_ASSERT(symmetrisedWS != 0); + TS_ASSERT(outputWS != nullptr); + TS_ASSERT(yspaceWS != nullptr); + TS_ASSERT(fittedWS != nullptr); + TS_ASSERT(symmetrisedWS != nullptr); // Dimensions TS_ASSERT_EQUALS(testWS->getNumberHistograms(), diff --git a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h index ddc0df117f8a..a2b7cbb59288 100644 --- a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h +++ b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateGammaBackgroundTest.h @@ -31,8 +31,8 @@ class VesuvioCalculateGammaBackgroundTest : public CxxTest::TestSuite { MatrixWorkspace_sptr backgroundWS = alg->getProperty("BackgroundWorkspace"); MatrixWorkspace_sptr correctedWS = alg->getProperty("CorrectedWorkspace"); - TS_ASSERT(backgroundWS != 0); - TS_ASSERT(correctedWS != 0); + TS_ASSERT(backgroundWS != nullptr); + TS_ASSERT(correctedWS != nullptr); TS_ASSERT(backgroundWS != correctedWS); // Test some values in the range @@ -81,8 +81,8 @@ class VesuvioCalculateGammaBackgroundTest : public CxxTest::TestSuite { MatrixWorkspace_sptr backgroundWS = alg->getProperty("BackgroundWorkspace"); MatrixWorkspace_sptr correctedWS = alg->getProperty("CorrectedWorkspace"); - TS_ASSERT(backgroundWS != 0); - TS_ASSERT(correctedWS != 0); + TS_ASSERT(backgroundWS != nullptr); + TS_ASSERT(correctedWS != nullptr); TS_ASSERT(backgroundWS != correctedWS); // Test some values in the range @@ -125,8 +125,8 @@ class VesuvioCalculateGammaBackgroundTest : public CxxTest::TestSuite { MatrixWorkspace_sptr backgroundWS = alg->getProperty("BackgroundWorkspace"); MatrixWorkspace_sptr correctedWS = alg->getProperty("CorrectedWorkspace"); - TS_ASSERT(backgroundWS != 0); - TS_ASSERT(correctedWS != 0); + TS_ASSERT(backgroundWS != nullptr); + TS_ASSERT(correctedWS != nullptr); TS_ASSERT(backgroundWS != correctedWS); TS_ASSERT_EQUALS(1, backgroundWS->getNumberHistograms()); diff --git a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h index 5e4bb0d4777f..875ed5020e71 100644 --- a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h +++ b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h @@ -78,7 +78,7 @@ createTestWorkspace(const bool detShape = true, if (groupedDets) { // Add another detector in the same position as the first auto shape = ShapeFactory().createShape(shapeXML); - Mantid::Geometry::Detector *det2 = new Detector("det1", 2, shape, NULL); + Mantid::Geometry::Detector *det2 = new Detector("det1", 2, shape, nullptr); // Setting detectors should normally go via DetectorInfo, but here we need // to set a position as we are adding a new detector. In general getPos // should not be called as this tries to set the position of the base diff --git a/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h b/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h index 2022b396ac9a..8ddde99e992a 100644 --- a/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h +++ b/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h @@ -154,7 +154,7 @@ createTestInstrumentWithNoFoilChanger(const Mantid::detid_t id, Detector *det0(nullptr); if (!detShapeXML.empty()) { auto shape = ShapeFactory().createShape(detShapeXML); - det0 = new Detector("det0", id, shape, NULL); + det0 = new Detector("det0", id, shape, nullptr); } else { det0 = new Detector("det0", id, nullptr); } diff --git a/Framework/DataHandling/test/LoadEmptyInstrumentTest.h b/Framework/DataHandling/test/LoadEmptyInstrumentTest.h index 0520c1e4b601..b69047bccc78 100644 --- a/Framework/DataHandling/test/LoadEmptyInstrumentTest.h +++ b/Framework/DataHandling/test/LoadEmptyInstrumentTest.h @@ -180,7 +180,7 @@ class LoadEmptyInstrumentTest : public CxxTest::TestSuite { TS_ASSERT_DELTA(param->value(), 32.0, 0.0001); param = paramMap.get(&det, "boevs"); - TS_ASSERT(param == NULL); + TS_ASSERT(param == nullptr); param = paramMap.getRecursive(&det, "boevs", "double"); TS_ASSERT_DELTA(param->value(), 8.0, 0.0001); @@ -780,7 +780,7 @@ class LoadEmptyInstrumentTest : public CxxTest::TestSuite { // And finally demonstrate that the get() method does not perform recursive // look-up param = paramMap.get(&det1, "tube_pressure2"); - TS_ASSERT(param == NULL); + TS_ASSERT(param == nullptr); AnalysisDataService::Instance().remove(wsName); } diff --git a/Framework/DataHandling/test/LoadISISNexusTest.h b/Framework/DataHandling/test/LoadISISNexusTest.h index bd8897282c52..d5a63f9f7abf 100644 --- a/Framework/DataHandling/test/LoadISISNexusTest.h +++ b/Framework/DataHandling/test/LoadISISNexusTest.h @@ -483,8 +483,8 @@ class LoadISISNexusTest : public CxxTest::TestSuite { boost::dynamic_pointer_cast(grpWs->getItem(0)); MatrixWorkspace_sptr ws2 = boost::dynamic_pointer_cast(grpWs->getItem(1)); - TS_ASSERT(ws1 != NULL); - TS_ASSERT(ws2 != NULL); + TS_ASSERT(ws1 != nullptr); + TS_ASSERT(ws2 != nullptr); // Check that workspace 1 has the correct period data, and no other period // log data checkPeriodLogData(ws1, 1); diff --git a/Framework/DataHandling/test/LoadInstrumentTest.h b/Framework/DataHandling/test/LoadInstrumentTest.h index 5e5c37231351..d8a6a87974f3 100644 --- a/Framework/DataHandling/test/LoadInstrumentTest.h +++ b/Framework/DataHandling/test/LoadInstrumentTest.h @@ -636,7 +636,7 @@ class LoadInstrumentTest : public CxxTest::TestSuite { // IDFs_for_UNIT_TESTING/HRPD_Parameters_Test4.xml Parameter_sptr param = paramMap.getRecursive(&(*comp), par, "fitting"); TS_ASSERT(param); - if (param != 0) { + if (param != nullptr) { const FitParameter &fitParam4 = param->value(); TS_ASSERT(fitParam4.getTie().compare("") == 0); TS_ASSERT(fitParam4.getFunction().compare("BackToBackExponential") == 0); diff --git a/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Framework/DataHandling/test/LoadNexusProcessedTest.h index b28faff22c4c..82ee05ae66f2 100644 --- a/Framework/DataHandling/test/LoadNexusProcessedTest.h +++ b/Framework/DataHandling/test/LoadNexusProcessedTest.h @@ -280,8 +280,8 @@ class LoadNexusProcessedTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(ws->getSpectrum(4).getNumberEvents(), 100); // Do the comparison algo to check that they really are the same - origWS->sortAll(TOF_SORT, NULL); - ws->sortAll(TOF_SORT, NULL); + origWS->sortAll(TOF_SORT, nullptr); + ws->sortAll(TOF_SORT, nullptr); IAlgorithm_sptr alg2 = AlgorithmManager::Instance().createUnmanaged("CompareWorkspaces"); @@ -724,7 +724,7 @@ class LoadNexusProcessedTest : public CxxTest::TestSuite { "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml"); InstrumentDefinitionParser parser(filename, "MINITOPAZ", Strings::loadFile(filename)); - auto instrument = parser.parseXML(NULL); + auto instrument = parser.parseXML(nullptr); peaksTestWS->populateInstrumentParameters(); peaksTestWS->setInstrument(instrument); @@ -769,7 +769,7 @@ class LoadNexusProcessedTest : public CxxTest::TestSuite { "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml"); InstrumentDefinitionParser parser(filename, "MINITOPAZ", Strings::loadFile(filename)); - auto instrument = parser.parseXML(NULL); + auto instrument = parser.parseXML(nullptr); peaksTestWS->populateInstrumentParameters(); peaksTestWS->setInstrument(instrument); diff --git a/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h b/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h index 1f8f61470db0..8184605518f6 100644 --- a/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h +++ b/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h @@ -150,8 +150,8 @@ class LoadRawSaveNxsLoadNxsTest : public CxxTest::TestSuite { // std::cerr << "Count = " << i.use_count(); boost::shared_ptr source = i->getSource(); - TS_ASSERT(source != NULL); - if (source != NULL) { + TS_ASSERT(source != nullptr); + if (source != nullptr) { TS_ASSERT_EQUALS(source->getName(), "source"); TS_ASSERT_DELTA(detectorInfo.sourcePosition().Y(), 0.0, 0.01); diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h index 2b4fcd178c1f..8284af3e4ae0 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h @@ -426,7 +426,7 @@ class DLLExport MDHistoWorkspace : public API::IMDHistoWorkspace { } MDHistoWorkspace *doCloneEmpty() const override { - return new MDHistoWorkspace(0); + return new MDHistoWorkspace(nullptr); } void makeSingleBinWithNaN(std::vector &x, std::vector &y, diff --git a/Framework/DataObjects/test/EventListTest.h b/Framework/DataObjects/test/EventListTest.h index 7d1e65d52deb..23f979ed5c16 100644 --- a/Framework/DataObjects/test/EventListTest.h +++ b/Framework/DataObjects/test/EventListTest.h @@ -1434,7 +1434,7 @@ class EventListTest : public CxxTest::TestSuite { void test_convertUnitsViaTof_failures() { DummyUnit1 fromUnit; DummyUnit2 toUnit; - TS_ASSERT_THROWS_ANYTHING(el.convertUnitsViaTof(NULL, NULL)); + TS_ASSERT_THROWS_ANYTHING(el.convertUnitsViaTof(nullptr, nullptr)); // Not initalized TS_ASSERT_THROWS_ANYTHING(el.convertUnitsViaTof(&fromUnit, &toUnit)); } diff --git a/Framework/DataObjects/test/EventWorkspaceTest.h b/Framework/DataObjects/test/EventWorkspaceTest.h index ff9c4f94fed8..b873a8cbae6d 100644 --- a/Framework/DataObjects/test/EventWorkspaceTest.h +++ b/Framework/DataObjects/test/EventWorkspaceTest.h @@ -691,10 +691,10 @@ class EventWorkspaceTest : public CxxTest::TestSuite { EventWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -702,9 +702,9 @@ class EventWorkspaceTest : public CxxTest::TestSuite { EventWorkspace_const_sptr wsCastConst; EventWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (EventWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (EventWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } @@ -722,10 +722,10 @@ class EventWorkspaceTest : public CxxTest::TestSuite { IEventWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -733,9 +733,9 @@ class EventWorkspaceTest : public CxxTest::TestSuite { IEventWorkspace_const_sptr wsCastConst; IEventWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (IEventWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IEventWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } diff --git a/Framework/DataObjects/test/GroupingWorkspaceTest.h b/Framework/DataObjects/test/GroupingWorkspaceTest.h index a2c232cbcf14..04f7fb02a072 100644 --- a/Framework/DataObjects/test/GroupingWorkspaceTest.h +++ b/Framework/DataObjects/test/GroupingWorkspaceTest.h @@ -109,10 +109,10 @@ class GroupingWorkspaceTest : public CxxTest::TestSuite { GroupingWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -120,9 +120,9 @@ class GroupingWorkspaceTest : public CxxTest::TestSuite { GroupingWorkspace_const_sptr wsCastConst; GroupingWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (GroupingWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (GroupingWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/DataObjects/test/MDBoxIteratorTest.h b/Framework/DataObjects/test/MDBoxIteratorTest.h index 1ee036378ca7..93fc5a6f5896 100644 --- a/Framework/DataObjects/test/MDBoxIteratorTest.h +++ b/Framework/DataObjects/test/MDBoxIteratorTest.h @@ -83,7 +83,7 @@ class MDBoxIteratorTest : public CxxTest::TestSuite { //-------------------------------------------------------------------------------------- void test_ctor_with_null_box_fails() { using boxit_t = MDBoxIterator, 1>; - TS_ASSERT_THROWS_ANYTHING(new boxit_t(NULL, 10, false);); + TS_ASSERT_THROWS_ANYTHING(new boxit_t(nullptr, 10, false);); } //-------------------------------------------------------------------------------------- diff --git a/Framework/DataObjects/test/MDBoxSaveableTest.h b/Framework/DataObjects/test/MDBoxSaveableTest.h index 12c374388df1..8408e0f6802f 100644 --- a/Framework/DataObjects/test/MDBoxSaveableTest.h +++ b/Framework/DataObjects/test/MDBoxSaveableTest.h @@ -254,7 +254,7 @@ class MDBoxSaveableTest : public CxxTest::TestSuite { MDBox, 3> *b = dynamic_cast, 3> *>(gb->getChild(22)); TSM_ASSERT_EQUALS("Child has 8 events", b->getNPoints(), 8); - TSM_ASSERT("The child is also saveabele", b->getISaveable() != NULL); + TSM_ASSERT("The child is also saveabele", b->getISaveable() != nullptr); if (!b->getISaveable()) return; @@ -753,7 +753,7 @@ class MDBoxSaveableTest : public CxxTest::TestSuite { bin.m_max[d] = 4.0; bin.m_signal = 0; } - c.centerpointBin(bin, NULL); + c.centerpointBin(bin, nullptr); TS_ASSERT_DELTA(bin.m_signal, 8.0, 1e-4); TS_ASSERT_DELTA(bin.m_errorSquared, 8.0, 1e-4); } @@ -847,7 +847,7 @@ class MDBoxSaveableTest : public CxxTest::TestSuite { TS_ASSERT(mdbox); auto pIO = mdbox->getISaveable(); - TS_ASSERT(pIO != NULL); + TS_ASSERT(pIO != nullptr); if (!pIO) continue; diff --git a/Framework/DataObjects/test/MDBoxTest.h b/Framework/DataObjects/test/MDBoxTest.h index 0f64cf5f143a..3aa90974421b 100644 --- a/Framework/DataObjects/test/MDBoxTest.h +++ b/Framework/DataObjects/test/MDBoxTest.h @@ -407,7 +407,7 @@ class MDBoxTest : public CxxTest::TestSuite { // First, a bin object that holds everything MDBin, 2> bin; // Perform the centerpoint binning - box.centerpointBin(bin, NULL); + box.centerpointBin(bin, nullptr); // 100 events = 100 weight. TS_ASSERT_DELTA(bin.m_signal, 100.0, 1e-4); TS_ASSERT_DELTA(bin.m_errorSquared, 150.0, 1e-4); @@ -419,7 +419,7 @@ class MDBoxTest : public CxxTest::TestSuite { bin.m_max[0] = 6.0; bin.m_min[1] = 1.0; bin.m_max[1] = 3.0; - box.centerpointBin(bin, NULL); + box.centerpointBin(bin, nullptr); TS_ASSERT_DELTA(bin.m_signal, 4.0, 1e-4); TS_ASSERT_DELTA(bin.m_errorSquared, 6.0, 1e-4); } diff --git a/Framework/DataObjects/test/MDEventWorkspaceTest.h b/Framework/DataObjects/test/MDEventWorkspaceTest.h index 72e27f6bb92a..2c1cecc5183e 100644 --- a/Framework/DataObjects/test/MDEventWorkspaceTest.h +++ b/Framework/DataObjects/test/MDEventWorkspaceTest.h @@ -42,7 +42,7 @@ class MDEventWorkspaceTest : public CxxTest::TestSuite { /// Helper function to return the number of masked bins in a workspace. TODO: /// move helper into test helpers size_t getNumberMasked(Mantid::API::IMDWorkspace_sptr ws) { - Mantid::API::IMDIterator *it = ws->createIterator(NULL); + Mantid::API::IMDIterator *it = ws->createIterator(nullptr); size_t numberMasked = 0; size_t counter = 0; for (; counter < it->getDataSize(); ++counter) { @@ -123,7 +123,7 @@ class MDEventWorkspaceTest : public CxxTest::TestSuite { /*Test that the boxes were deep copied and that their BoxController pointers * have been updated too.*/ - std::vector originalBoxes(0, NULL); + std::vector originalBoxes(0, nullptr); ew3.getBox()->getBoxes(originalBoxes, 10000, false); std::vector copiedBoxes; @@ -379,7 +379,7 @@ class MDEventWorkspaceTest : public CxxTest::TestSuite { for (size_t i = 0; i < 50; i++) { ew->addEvent(ev); } - ew->splitAllIfNeeded(NULL); + ew->splitAllIfNeeded(nullptr); ew->refreshCache(); // Create dimension-aligned line through the workspace @@ -792,10 +792,10 @@ class MDEventWorkspaceTest : public CxxTest::TestSuite { IMDEventWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -803,9 +803,9 @@ class MDEventWorkspaceTest : public CxxTest::TestSuite { IMDEventWorkspace_const_sptr wsCastConst; IMDEventWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (IMDEventWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IMDEventWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; @@ -855,7 +855,7 @@ class MDEventWorkspaceTestPerformance : public CxxTest::TestSuite { std::cout << "Starting Workspace splitting performance test, single " "threaded with " << nBoxes << " events \n"; Kernel::Timer clock; - m_ws->splitAllIfNeeded(NULL); + m_ws->splitAllIfNeeded(nullptr); std::cout << "Finished Workspace splitting performance test, single threaded in " << clock.elapsed() << " sec\n"; diff --git a/Framework/DataObjects/test/MDGridBoxTest.h b/Framework/DataObjects/test/MDGridBoxTest.h index 0ae4ef00585b..91442092b7a6 100644 --- a/Framework/DataObjects/test/MDGridBoxTest.h +++ b/Framework/DataObjects/test/MDGridBoxTest.h @@ -445,7 +445,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { } // You must refresh the cache after adding individual events. - superbox->refreshCache(NULL); + superbox->refreshCache(nullptr); // superbox->refreshCentroid(NULL); TS_ASSERT_EQUALS(superbox->getNPoints(), 3); @@ -473,7 +473,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { } TS_ASSERT_EQUALS(superbox->getNPoints(), 3); - superbox->refreshCache(NULL); + superbox->refreshCache(nullptr); TS_ASSERT_EQUALS(superbox->getNPoints(), 6); // Retrieve the 0th grid box @@ -801,7 +801,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { } } // You must refresh the cache after adding individual events. - box->refreshCache(NULL); + box->refreshCache(nullptr); } } @@ -824,7 +824,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { size_t numbad = 0; TS_ASSERT_THROWS_NOTHING(numbad = b->addEvents(events);); // Get the right totals again - b->refreshCache(NULL); + b->refreshCache(nullptr); TS_ASSERT_EQUALS(numbad, 0); TS_ASSERT_EQUALS(b->getNPoints(), 100); TS_ASSERT_EQUALS(b->getSignal(), 100 * 2.0); @@ -851,7 +851,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { events.push_back(MDLeanEvent<2>(2.0, 2.0, centers)); } // Get the right totals again - b->refreshCache(NULL); + b->refreshCache(nullptr); // All 4 points get rejected TS_ASSERT_THROWS_NOTHING(numbad = b->addEvents(events);); TS_ASSERT_EQUALS(numbad, 4); @@ -886,7 +886,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { TS_ASSERT_THROWS_NOTHING(numbad = b->addEvents(events)); TS_ASSERT_EQUALS(numbad, 3); - b->refreshCache(NULL); + b->refreshCache(nullptr); TS_ASSERT_EQUALS(b->getNPoints(), 1); TS_ASSERT_EQUALS(b->getSignal(), 2.0); TS_ASSERT_EQUALS(b->getErrorSquared(), 2.0); @@ -1006,7 +1006,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { TS_ASSERT_THROWS_NOTHING(b0->addEvents(events);); // Split into sub-grid boxes - TS_ASSERT_THROWS_NOTHING(b0->splitAllIfNeeded(NULL);) + TS_ASSERT_THROWS_NOTHING(b0->splitAllIfNeeded(nullptr);) // Dig recursively into the gridded box hierarchies std::vector boxes; @@ -1128,7 +1128,7 @@ class MDGridBoxTest : public CxxTest::TestSuite { MDBin, 2> bin; bin = makeMDBin2(minX, maxX, minY, maxY); - b->centerpointBin(bin, NULL); + b->centerpointBin(bin, nullptr); TSM_ASSERT_DELTA(message, bin.m_signal, expectedSignal, 1e-5); } diff --git a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h index cc63960592df..f1377d70080a 100644 --- a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h +++ b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h @@ -374,7 +374,7 @@ class MDHistoWorkspaceIteratorTest : public CxxTest::TestSuite { size_t begin = 1; size_t end = 5; - MDHistoWorkspaceIterator iterator(ws.get(), NULL, begin, end); + MDHistoWorkspaceIterator iterator(ws.get(), nullptr, begin, end); TS_ASSERT(iterator.isWithinBounds(begin)); TS_ASSERT(iterator.isWithinBounds(end - 1)); diff --git a/Framework/DataObjects/test/MDHistoWorkspaceTest.h b/Framework/DataObjects/test/MDHistoWorkspaceTest.h index b1870ca4b3fd..684327f8c157 100644 --- a/Framework/DataObjects/test/MDHistoWorkspaceTest.h +++ b/Framework/DataObjects/test/MDHistoWorkspaceTest.h @@ -33,7 +33,7 @@ class MDHistoWorkspaceTest : public CxxTest::TestSuite { /// Helper function to return the number of masked bins in a workspace. TODO: /// move helper into test helpers size_t getNumberMasked(Mantid::API::IMDWorkspace_sptr ws) { - Mantid::API::IMDIterator *it = ws->createIterator(NULL); + Mantid::API::IMDIterator *it = ws->createIterator(nullptr); size_t numberMasked = 0; size_t counter = 0; for (; counter < it->getDataSize(); ++counter) { @@ -1263,10 +1263,10 @@ class MDHistoWorkspaceTest : public CxxTest::TestSuite { IMDHistoWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -1274,9 +1274,9 @@ class MDHistoWorkspaceTest : public CxxTest::TestSuite { IMDHistoWorkspace_const_sptr wsCastConst; IMDHistoWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (IMDHistoWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IMDHistoWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/DataObjects/test/MaskWorkspaceTest.h b/Framework/DataObjects/test/MaskWorkspaceTest.h index f32094b5c2b8..275406bef205 100644 --- a/Framework/DataObjects/test/MaskWorkspaceTest.h +++ b/Framework/DataObjects/test/MaskWorkspaceTest.h @@ -129,10 +129,10 @@ class MaskWorkspaceTest : public CxxTest::TestSuite { MaskWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -140,9 +140,9 @@ class MaskWorkspaceTest : public CxxTest::TestSuite { MaskWorkspace_const_sptr wsCastConst; MaskWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (MaskWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (MaskWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/DataObjects/test/OffsetsWorkspaceTest.h b/Framework/DataObjects/test/OffsetsWorkspaceTest.h index c910bbb631d9..4bc9a8f60f16 100644 --- a/Framework/DataObjects/test/OffsetsWorkspaceTest.h +++ b/Framework/DataObjects/test/OffsetsWorkspaceTest.h @@ -38,10 +38,10 @@ class OffsetsWorkspaceTest : public CxxTest::TestSuite { OffsetsWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -49,9 +49,9 @@ class OffsetsWorkspaceTest : public CxxTest::TestSuite { OffsetsWorkspace_const_sptr wsCastConst; OffsetsWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (OffsetsWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (OffsetsWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/DataObjects/test/PeaksWorkspaceTest.h b/Framework/DataObjects/test/PeaksWorkspaceTest.h index d0299473b002..4d5f1d2724e9 100644 --- a/Framework/DataObjects/test/PeaksWorkspaceTest.h +++ b/Framework/DataObjects/test/PeaksWorkspaceTest.h @@ -481,10 +481,10 @@ class PeaksWorkspaceTest : public CxxTest::TestSuite { PeaksWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -492,9 +492,9 @@ class PeaksWorkspaceTest : public CxxTest::TestSuite { PeaksWorkspace_const_sptr wsCastConst; PeaksWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (PeaksWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (PeaksWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } @@ -513,10 +513,10 @@ class PeaksWorkspaceTest : public CxxTest::TestSuite { IPeaksWorkspace_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -524,9 +524,9 @@ class PeaksWorkspaceTest : public CxxTest::TestSuite { IPeaksWorkspace_const_sptr wsCastConst; IPeaksWorkspace_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (IPeaksWorkspace_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (IPeaksWorkspace_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } diff --git a/Framework/DataObjects/test/SpecialWorkspace2DTest.h b/Framework/DataObjects/test/SpecialWorkspace2DTest.h index 88d2f1608a15..40825c572ffe 100644 --- a/Framework/DataObjects/test/SpecialWorkspace2DTest.h +++ b/Framework/DataObjects/test/SpecialWorkspace2DTest.h @@ -231,10 +231,10 @@ class SpecialWorkspace2DTest : public CxxTest::TestSuite { SpecialWorkspace2D_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -242,9 +242,9 @@ class SpecialWorkspace2DTest : public CxxTest::TestSuite { SpecialWorkspace2D_const_sptr wsCastConst; SpecialWorkspace2D_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (SpecialWorkspace2D_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (SpecialWorkspace2D_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/DataObjects/test/Workspace2DTest.h b/Framework/DataObjects/test/Workspace2DTest.h index 9d3e6ccd6e0d..2f6958be4b37 100644 --- a/Framework/DataObjects/test/Workspace2DTest.h +++ b/Framework/DataObjects/test/Workspace2DTest.h @@ -250,10 +250,10 @@ class Workspace2DTest : public CxxTest::TestSuite { Workspace2D_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -261,9 +261,9 @@ class Workspace2DTest : public CxxTest::TestSuite { Workspace2D_const_sptr wsCastConst; Workspace2D_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (Workspace2D_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (Workspace2D_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/DataObjects/test/WorkspaceSingleValueTest.h b/Framework/DataObjects/test/WorkspaceSingleValueTest.h index facddcc1d3fa..015d1a21d203 100644 --- a/Framework/DataObjects/test/WorkspaceSingleValueTest.h +++ b/Framework/DataObjects/test/WorkspaceSingleValueTest.h @@ -78,10 +78,10 @@ class WorkspaceSingleValueTest : public CxxTest::TestSuite { WorkspaceSingleValue_sptr wsNonConst; TS_ASSERT_THROWS_NOTHING( wsConst = manager.getValue(wsName)); - TS_ASSERT(wsConst != NULL); + TS_ASSERT(wsConst != nullptr); TS_ASSERT_THROWS_NOTHING( wsNonConst = manager.getValue(wsName)); - TS_ASSERT(wsNonConst != NULL); + TS_ASSERT(wsNonConst != nullptr); TS_ASSERT_EQUALS(wsConst, wsNonConst); // Check TypedValue can be cast to const_sptr or to sptr @@ -90,9 +90,9 @@ class WorkspaceSingleValueTest : public CxxTest::TestSuite { WorkspaceSingleValue_sptr wsCastNonConst; TS_ASSERT_THROWS_NOTHING(wsCastConst = (WorkspaceSingleValue_const_sptr)val); - TS_ASSERT(wsCastConst != NULL); + TS_ASSERT(wsCastConst != nullptr); TS_ASSERT_THROWS_NOTHING(wsCastNonConst = (WorkspaceSingleValue_sptr)val); - TS_ASSERT(wsCastNonConst != NULL); + TS_ASSERT(wsCastNonConst != nullptr); TS_ASSERT_EQUALS(wsCastConst, wsCastNonConst); } }; diff --git a/Framework/Geometry/test/ParameterMapTest.h b/Framework/Geometry/test/ParameterMapTest.h index bfa297487d90..cac00aafd7ec 100644 --- a/Framework/Geometry/test/ParameterMapTest.h +++ b/Framework/Geometry/test/ParameterMapTest.h @@ -513,7 +513,7 @@ class ParameterMapTest : public CxxTest::TestSuite { Parameter_sptr fetchedValue = pmap.getByType(comp.get(), ParameterMap::pDouble()); TSM_ASSERT("Should not be able to find a double type parameter", - fetchedValue == NULL); + fetchedValue == nullptr); } void test_lookup_via_type() { @@ -551,7 +551,7 @@ class ParameterMapTest : public CxxTest::TestSuite { // Find it via the component Parameter_sptr fetchedValue = pmap.getRecursiveByType(component.get(), ParameterMap::pBool()); - TS_ASSERT(fetchedValue != NULL); + TS_ASSERT(fetchedValue != nullptr); TS_ASSERT_EQUALS("A", fetchedValue->name()); TS_ASSERT_EQUALS(ParameterMap::pBool(), fetchedValue->type()); TS_ASSERT_EQUALS(true, fetchedValue->value()); @@ -568,7 +568,7 @@ class ParameterMapTest : public CxxTest::TestSuite { // Find it via the child Parameter_sptr fetchedValue = pmap.getRecursiveByType(childComponent.get(), ParameterMap::pBool()); - TS_ASSERT(fetchedValue != NULL); + TS_ASSERT(fetchedValue != nullptr); TS_ASSERT_EQUALS("A", fetchedValue->name()); TS_ASSERT_EQUALS(ParameterMap::pBool(), fetchedValue->type()); TS_ASSERT_EQUALS(true, fetchedValue->value()); @@ -589,7 +589,7 @@ class ParameterMapTest : public CxxTest::TestSuite { // Find it via the child Parameter_sptr fetchedValue = pmap.getRecursiveByType(childComponent.get(), ParameterMap::pBool()); - TS_ASSERT(fetchedValue != NULL); + TS_ASSERT(fetchedValue != nullptr); TSM_ASSERT_EQUALS( "Has not searched through parameters with the correct priority", "A", fetchedValue->name()); @@ -639,7 +639,7 @@ class ParameterMapTest : public CxxTest::TestSuite { const ValueType &newValue) { ParameterMap pmap; const std::string name = "Parameter"; - pmap.add(type, m_testInstrument.get(), name, origValue, NULL); + pmap.add(type, m_testInstrument.get(), name, origValue, nullptr); ParameterMap copy(pmap); // invoke copy constructor diff --git a/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h b/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h index ce57682420fb..475ab86fb845 100644 --- a/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h +++ b/Framework/ICat/inc/MantidICat/ICat3/ICat3Helper.h @@ -134,7 +134,7 @@ class CICatHelper { */ template void savetoTableWorkspace(const T *input, Mantid::API::TableRow &t) { - if (input != 0) { + if (input != nullptr) { t << *input; } else { diff --git a/Framework/Kernel/test/DiskBufferISaveableTest.h b/Framework/Kernel/test/DiskBufferISaveableTest.h index 873796a94bce..ea6dc040a3af 100644 --- a/Framework/Kernel/test/DiskBufferISaveableTest.h +++ b/Framework/Kernel/test/DiskBufferISaveableTest.h @@ -92,12 +92,12 @@ class DiskBufferISaveableTest : public CxxTest::TestSuite { void tearDown() override { for (size_t i = 0; i < data.size(); i++) { delete data[i]; - data[i] = NULL; + data[i] = nullptr; } for (size_t i = 0; i < bigData.size(); i++) { delete bigData[i]; - bigData[i] = NULL; + bigData[i] = nullptr; } ISaveableTester::fakeFile = ""; } diff --git a/Framework/Kernel/test/DiskBufferTest.h b/Framework/Kernel/test/DiskBufferTest.h index 426c375731d7..8074ec68120e 100644 --- a/Framework/Kernel/test/DiskBufferTest.h +++ b/Framework/Kernel/test/DiskBufferTest.h @@ -117,7 +117,7 @@ class DiskBufferTest : public CxxTest::TestSuite { void tearDown() override { for (size_t i = 0; i < data.size(); i++) { delete data[i]; - data[i] = NULL; + data[i] = nullptr; } } void xest_nothing() { diff --git a/Framework/MDAlgorithms/test/BinMDTest.h b/Framework/MDAlgorithms/test/BinMDTest.h index 38d16b0b854d..980e8d0b7b4a 100644 --- a/Framework/MDAlgorithms/test/BinMDTest.h +++ b/Framework/MDAlgorithms/test/BinMDTest.h @@ -1111,7 +1111,7 @@ class BinMDTestPerformance : public CxxTest::TestSuite { BinMDTestPerformance() { in_ws = MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 0); in_ws->getBoxController()->setSplitThreshold(2000); - in_ws->splitAllIfNeeded(NULL); + in_ws->splitAllIfNeeded(nullptr); AnalysisDataService::Instance().addOrReplace("BinMDTest_ws", in_ws); FrameworkManager::Instance().exec("FakeMDEventData", 4, "InputWorkspace", "BinMDTest_ws", "UniformParams", diff --git a/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h b/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h index 5f44b55e93d9..449ff7802560 100644 --- a/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h +++ b/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h @@ -153,7 +153,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); TS_ASSERT_EQUALS(2, ws->getExperimentInfo(0)->run().getLogData().size()); // Assert that dimensions should be a general frame const auto &frame0 = ws->getDimension(0)->getMDFrame(); @@ -170,7 +170,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); // Assert that dimensions should be a general frame const auto &frame0 = ws->getDimension(0)->getMDFrame(); TSM_ASSERT_EQUALS("Should be a general frame", "KiKf", frame0.name()); @@ -185,7 +185,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); // Assert that dimensions should be a general frame const auto &frame0 = ws->getDimension(0)->getMDFrame(); TSM_ASSERT_EQUALS("Should be a general frame", "P", frame0.name()); @@ -201,7 +201,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); TS_ASSERT_EQUALS(2, ws->run().getLogData().size()); } @@ -213,7 +213,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); TS_ASSERT_EQUALS(2, ws->run().getLogData().size()); } @@ -225,7 +225,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); TS_ASSERT_EQUALS(2, ws->getExperimentInfo(0)->run().getLogData().size()); } @@ -236,7 +236,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); } void test_execute_pipf_2D() { @@ -246,7 +246,7 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite { auto ws = boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( "OutputTransformedWorkspace")); - TS_ASSERT(ws != NULL); + TS_ASSERT(ws != nullptr); } void test_box_controller_defaults() { @@ -342,7 +342,7 @@ class ConvertToReflectometryQTestPerformance : public CxxTest::TestSuite { IMDWorkspace_sptr out = AnalysisDataService::Instance().retrieveWS( "OutputTransformedWorkspace"); - TS_ASSERT(out != NULL); + TS_ASSERT(out != nullptr); TS_ASSERT_EQUALS(out->getNumDims(), 2); } @@ -363,7 +363,7 @@ class ConvertToReflectometryQTestPerformance : public CxxTest::TestSuite { auto out = AnalysisDataService::Instance() .retrieveWS( "OutputTransformedWorkspace"); - TS_ASSERT(out != NULL); + TS_ASSERT(out != nullptr); TS_ASSERT_EQUALS(out->getNumDims(), 2); } }; diff --git a/Framework/MDAlgorithms/test/DivideMDTest.h b/Framework/MDAlgorithms/test/DivideMDTest.h index 611b11c15421..7190173c818e 100644 --- a/Framework/MDAlgorithms/test/DivideMDTest.h +++ b/Framework/MDAlgorithms/test/DivideMDTest.h @@ -64,7 +64,7 @@ class DivideMDTest : public CxxTest::TestSuite { TS_ASSERT(ws); if (!ws) return; - IMDIterator *it = ws->createIterator(NULL); + IMDIterator *it = ws->createIterator(nullptr); do { TS_ASSERT_EQUALS(it->getNumEvents(), 1); TS_ASSERT_DELTA(it->getInnerSignal(0), expectedSignal, 1e-5); diff --git a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h index 37c2318fa535..17a8ae84fcd2 100644 --- a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h +++ b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h @@ -228,7 +228,7 @@ class ImportMDHistoWorkspaceTest : public CxxTest::TestSuite { IMDHistoWorkspace_sptr outWs = boost::dynamic_pointer_cast( ADS.retrieve("test_workspace")); - TS_ASSERT(outWs != NULL); + TS_ASSERT(outWs != nullptr); // Check the dimensionality TS_ASSERT_EQUALS(2, outWs->getNumDims()); @@ -290,7 +290,7 @@ class ImportMDHistoWorkspaceTest : public CxxTest::TestSuite { IMDHistoWorkspace_sptr outWs = boost::dynamic_pointer_cast( ADS.retrieve("test_workspace")); - TS_ASSERT(outWs != NULL); + TS_ASSERT(outWs != nullptr); // Check the dimensionality TS_ASSERT_EQUALS(3, outWs->getNumDims()); diff --git a/Framework/MDAlgorithms/test/LoadMDTest.h b/Framework/MDAlgorithms/test/LoadMDTest.h index 00394b574974..b2f0dc21d153 100644 --- a/Framework/MDAlgorithms/test/LoadMDTest.h +++ b/Framework/MDAlgorithms/test/LoadMDTest.h @@ -307,7 +307,7 @@ class LoadMDTest : public CxxTest::TestSuite { ev.setCenter(d, 0.5); box->addEvent(ev); // CHANGE from AB: 20/01/2013: you have to split to identify changes! - box->splitAllIfNeeded(NULL); + box->splitAllIfNeeded(nullptr); // Modify a different box by accessing the events MDBox, nd> *box8 = diff --git a/Framework/MDAlgorithms/test/MDWSTransfTest.h b/Framework/MDAlgorithms/test/MDWSTransfTest.h index ddf5e20a54a4..3ca531923c5c 100644 --- a/Framework/MDAlgorithms/test/MDWSTransfTest.h +++ b/Framework/MDAlgorithms/test/MDWSTransfTest.h @@ -78,7 +78,7 @@ class MDWSTransfTest : public CxxTest::TestSuite { WorkspaceCreationHelper::create2DWorkspaceBinned(10, 10); std::vector minVal(4, -3), maxVal(4, 3); TargWSDescription.setMinMax(minVal, maxVal); - spws->mutableSample().setOrientedLattice(NULL); + spws->mutableSample().setOrientedLattice(nullptr); TargWSDescription.buildFromMatrixWS(spws, "Q3D", "Direct"); diff --git a/Framework/MDAlgorithms/test/MultiplyMDTest.h b/Framework/MDAlgorithms/test/MultiplyMDTest.h index 480a3576dff6..83f874b003ba 100644 --- a/Framework/MDAlgorithms/test/MultiplyMDTest.h +++ b/Framework/MDAlgorithms/test/MultiplyMDTest.h @@ -63,7 +63,7 @@ class MultiplyMDTest : public CxxTest::TestSuite { TS_ASSERT(ws); if (!ws) return; - IMDIterator *it = ws->createIterator(NULL); + IMDIterator *it = ws->createIterator(nullptr); do { TS_ASSERT_EQUALS(it->getNumEvents(), 1); TS_ASSERT_DELTA(it->getInnerSignal(0), expectedSignal, 1e-5); diff --git a/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h b/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h index fc1b53032897..b5e411b78e56 100644 --- a/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h +++ b/Framework/MDAlgorithms/test/QueryMDWorkspaceTest.h @@ -154,7 +154,7 @@ class QueryMDWorkspaceTest : public CxxTest::TestSuite { ITableWorkspace_sptr table = AnalysisDataService::Instance().retrieveWS("QueryWS"); - TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL); + TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr); size_t expectedCount = 3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents TSM_ASSERT_EQUALS("Four columns expected", expectedCount, @@ -176,7 +176,7 @@ class QueryMDWorkspaceTest : public CxxTest::TestSuite { ITableWorkspace_sptr table = AnalysisDataService::Instance().retrieveWS("QueryWS"); - TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL); + TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr); size_t expectedCount = 3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents TSM_ASSERT_EQUALS("Five columns expected", expectedCount, @@ -199,7 +199,7 @@ class QueryMDWorkspaceTest : public CxxTest::TestSuite { ITableWorkspace_sptr table = AnalysisDataService::Instance().retrieveWS("QueryWS"); - TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL); + TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr); size_t expectedCount = 3 + in_ws->getNumDims(); // 3 fixed columns are Signal, Error, nEvents TSM_ASSERT_EQUALS("Five columns expected", expectedCount, @@ -253,7 +253,7 @@ class QueryMDWorkspaceTest : public CxxTest::TestSuite { query.execute(); ITableWorkspace_sptr table = query.getProperty("OutputWorkspace"); - TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL); + TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr); size_t expectedCount = 3 + 2; // 3 fixed columns are Signal, Error, nEvents and then data is 2D TSM_ASSERT_EQUALS("Six columns expected", expectedCount, @@ -292,7 +292,7 @@ class QueryMDWorkspaceTest : public CxxTest::TestSuite { query.execute(); ITableWorkspace_sptr table = query.getProperty("OutputWorkspace"); - TSM_ASSERT("Workspace output is not an ITableWorkspace", table != NULL); + TSM_ASSERT("Workspace output is not an ITableWorkspace", table != nullptr); size_t expectedCount = 3 + 2; // 3 fixed columns are Signal, Error, nEvents and then data is 2D TSM_ASSERT_EQUALS("Six columns expected", expectedCount, diff --git a/Framework/MDAlgorithms/test/SaveMD2Test.h b/Framework/MDAlgorithms/test/SaveMD2Test.h index 85c4b9e27046..a91a48586cc6 100644 --- a/Framework/MDAlgorithms/test/SaveMD2Test.h +++ b/Framework/MDAlgorithms/test/SaveMD2Test.h @@ -109,7 +109,7 @@ class SaveMD2Test : public CxxTest::TestSuite { ev.setCenter(0, double(i) * 0.01 + 0.4); ws->addEvent(ev); } - ws->splitAllIfNeeded(NULL); + ws->splitAllIfNeeded(nullptr); ws->refreshCache(); // Manually set the flag that the algo would set ws->setFileNeedsUpdating(true); diff --git a/Framework/MDAlgorithms/test/SaveMDTest.h b/Framework/MDAlgorithms/test/SaveMDTest.h index a53feb583d2d..aaad74bf8e36 100644 --- a/Framework/MDAlgorithms/test/SaveMDTest.h +++ b/Framework/MDAlgorithms/test/SaveMDTest.h @@ -114,7 +114,7 @@ class SaveMDTest : public CxxTest::TestSuite { ev.setCenter(0, double(i) * 0.01 + 0.4); ws->addEvent(ev); } - ws->splitAllIfNeeded(NULL); + ws->splitAllIfNeeded(nullptr); ws->refreshCache(); // Manually set the flag that the algo would set ws->setFileNeedsUpdating(true); diff --git a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h index 3e736c1d1ca7..a2038d7a0f2c 100644 --- a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h +++ b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h @@ -332,7 +332,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { void test_aligned_ImplicitFunction() { SlicingAlgorithmImpl *alg = do_createAlignedTransform( "Axis0, 2.0,8.0, 6", "Axis1, 2.0,8.0, 3", "Axis2, 2.0,8.0, 3", ""); - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(3, 4, 5))); @@ -681,7 +681,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, 1.0, 2.6)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2))); @@ -738,7 +738,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, -1.0, 2.6)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, -1.5, 2))); @@ -757,7 +757,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234))); @@ -778,7 +778,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 8); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 1.5, 1.5))); @@ -797,7 +797,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 8); TS_ASSERT(func->isPointContained(VMD(1.5, -1.5, 1.5, 1.5))); @@ -815,7 +815,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234, 456))); @@ -836,7 +836,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234))); @@ -855,7 +855,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2))); @@ -874,7 +874,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5))); @@ -932,7 +932,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(-8.9, -18.9))); @@ -997,7 +997,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(-18.9, -98.9))); @@ -1027,7 +1027,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(2., 1.))); @@ -1049,7 +1049,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(2., 1., 0.))); @@ -1073,7 +1073,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 8); TS_ASSERT(func->isPointContained(VMD(2., 1., 0., 0.))); @@ -1094,7 +1094,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(NULL, NULL)); + alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(2., 1., 0., 0.))); @@ -1112,7 +1112,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 345))); @@ -1127,7 +1127,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2))); @@ -1142,7 +1142,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5))); @@ -1159,7 +1159,7 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(NULL, NULL); + MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); VMD point(1); diff --git a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h index 93ba7996521c..eacd4333e6e1 100644 --- a/Framework/MDAlgorithms/test/WeightedMeanMDTest.h +++ b/Framework/MDAlgorithms/test/WeightedMeanMDTest.h @@ -134,7 +134,7 @@ class WeightedMeanMDTest : public CxxTest::TestSuite { MDHistoWorkspace_sptr c = boost::dynamic_pointer_cast(ADS.retrieve(outName)); - TS_ASSERT(c != NULL); + TS_ASSERT(c != nullptr); // Since A and B are equivalent, the mean Signal in C should be the same as // both A and B. double expectedSignalResults[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; @@ -157,7 +157,7 @@ class WeightedMeanMDTest : public CxxTest::TestSuite { MDHistoWorkspace_sptr out; out = BinaryOperationMDTestHelper::doTest("WeightedMeanMD", "histo_A", "histo_B", "out"); - TS_ASSERT(out != NULL); + TS_ASSERT(out != nullptr); } /** diff --git a/Framework/SINQ/test/PoldiInstrumentAdapterTest.h b/Framework/SINQ/test/PoldiInstrumentAdapterTest.h index aab05fa210ad..46b88a7e51a9 100644 --- a/Framework/SINQ/test/PoldiInstrumentAdapterTest.h +++ b/Framework/SINQ/test/PoldiInstrumentAdapterTest.h @@ -195,7 +195,7 @@ class PoldiInstrumentAdapterTest : public CxxTest::TestSuite { TestablePoldiInstrumentAdapter instrumentAdapter; // Throw on null-pointer - TS_ASSERT_THROWS(instrumentAdapter.getExtractorForProperty(0), + TS_ASSERT_THROWS(instrumentAdapter.getExtractorForProperty(nullptr), std::invalid_argument); TS_ASSERT_THROWS_NOTHING(instrumentAdapter.getExtractorForProperty( m_run.getProperty("chopperspeed_double"))); diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h index 46de8bd791d3..b90561823689 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h @@ -423,7 +423,7 @@ static void feedMDBox(MDBoxBase, nd> *box, size_t repeat = 1, allDone = Mantid::Kernel::Utils::NestedForLoop::Increment(nd, counters, index_max); } - box->refreshCache(NULL); + box->refreshCache(nullptr); } //------------------------------------------------------------------------------------- diff --git a/Framework/Types/test/DateAndTimeTest.h b/Framework/Types/test/DateAndTimeTest.h index 33f52df1d342..91d17bd25ae7 100644 --- a/Framework/Types/test/DateAndTimeTest.h +++ b/Framework/Types/test/DateAndTimeTest.h @@ -279,7 +279,7 @@ class DateAndTimeTest : public CxxTest::TestSuite { void test_time_t_support() { DateAndTime t; - std::time_t current = time(NULL); + std::time_t current = time(nullptr); t.set_from_time_t(current); // if (cur.day() < 28) // Annoying bug at the end of a month { TS_ASSERT_EQUALS(current, t.to_time_t()); } From 6c889e66d597989aaf76deb7b0e0d62071fbc51f Mon Sep 17 00:00:00 2001 From: Joe Ramsay Date: Thu, 22 Mar 2018 09:47:33 +0000 Subject: [PATCH 347/364] Change to lower case p in Matplotlib --- dev-docs/source/MVPTutorial/CompleteGUI.rst | 2 +- .../source/MVPTutorial/{MatPlotlib.rst => Matplotlib.rst} | 8 ++++---- dev-docs/source/MVPTutorial/ViewExercise1.rst | 2 +- dev-docs/source/MVPTutorial/index.rst | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename dev-docs/source/MVPTutorial/{MatPlotlib.rst => Matplotlib.rst} (91%) diff --git a/dev-docs/source/MVPTutorial/CompleteGUI.rst b/dev-docs/source/MVPTutorial/CompleteGUI.rst index a84b0a50f457..c3e4ae7d6166 100644 --- a/dev-docs/source/MVPTutorial/CompleteGUI.rst +++ b/dev-docs/source/MVPTutorial/CompleteGUI.rst @@ -146,7 +146,7 @@ Plot Presenter PlotView ######## -Unchanged from `MatPlotlib and MVP `_. +Unchanged from `Matplotlib and MVP `_. Presenter ######### diff --git a/dev-docs/source/MVPTutorial/MatPlotlib.rst b/dev-docs/source/MVPTutorial/Matplotlib.rst similarity index 91% rename from dev-docs/source/MVPTutorial/MatPlotlib.rst rename to dev-docs/source/MVPTutorial/Matplotlib.rst index 98a22e767a1b..22972a4f8a83 100644 --- a/dev-docs/source/MVPTutorial/MatPlotlib.rst +++ b/dev-docs/source/MVPTutorial/Matplotlib.rst @@ -1,15 +1,15 @@ ================== -MatPlotlib and MVP +Matplotlib and MVP ================== The next step towards the goal of creating a GUI that allows users to manipulate a sine wave plot, is to produce the plot itself. For the purposes of this tutorial it is assumed that the user is -familiar with MatPlotlib, if not see `MatPlotlib documentation +familiar with Matplotlib, if not see `Matplotlib documentation `_. -The MatPlotLib functions could be considered to be a Model or a View +The Matplotlib functions could be considered to be a Model or a View and there is no correct answer to which. It could be a Model as it does something with the data, however it could be considered to be a view as (in this case) it is used purely as a visual @@ -31,7 +31,7 @@ The View has the following imports: from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas -The fourth line imports MatPlotLib and the last line allows it to +The fourth line imports Matplotlib and the last line allows it to interface with the GUI. The main class is shown below and contains methods for adding data to diff --git a/dev-docs/source/MVPTutorial/ViewExercise1.rst b/dev-docs/source/MVPTutorial/ViewExercise1.rst index ec679e728b10..d2311e122f03 100644 --- a/dev-docs/source/MVPTutorial/ViewExercise1.rst +++ b/dev-docs/source/MVPTutorial/ViewExercise1.rst @@ -17,7 +17,7 @@ plot. The table should include options for: The previous sections are not an exhaustive list of possible widgets. -The pages `MatPlotlib and MVP `_ and `MultipleView +The pages `Matplotlib and MVP `_ and `MultipleView `_ will be useful for the exercise. The solution can be found `here `_. diff --git a/dev-docs/source/MVPTutorial/index.rst b/dev-docs/source/MVPTutorial/index.rst index f54ab6221113..a9fcb3795dad 100644 --- a/dev-docs/source/MVPTutorial/index.rst +++ b/dev-docs/source/MVPTutorial/index.rst @@ -21,7 +21,7 @@ Duration: 6 hours as a hands-on course with exercises. AddSpinBox Tables ViewExercise1 - MatPlotlib + Matplotlib MultipleViews ViewExercise1Solution ReceivingSignalFromView From 17173c476e5bc45be9925d3fea9ae98bf1c3be96 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 09:52:53 +0000 Subject: [PATCH 348/364] Re #22169: Applied clang-format patch. --- .../test/Algorithms/VesuvioCalculateMSTest.h | 3 +- .../MDAlgorithms/test/SlicingAlgorithmTest.h | 71 +++++++++++-------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h index 875ed5020e71..128c57e8c700 100644 --- a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h +++ b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h @@ -78,7 +78,8 @@ createTestWorkspace(const bool detShape = true, if (groupedDets) { // Add another detector in the same position as the first auto shape = ShapeFactory().createShape(shapeXML); - Mantid::Geometry::Detector *det2 = new Detector("det1", 2, shape, nullptr); + Mantid::Geometry::Detector *det2 = + new Detector("det1", 2, shape, nullptr); // Setting detectors should normally go via DetectorInfo, but here we need // to set a position as we are adding a new detector. In general getPos // should not be called as this tries to set the position of the base diff --git a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h index a2038d7a0f2c..0d558dbcf5f1 100644 --- a/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h +++ b/Framework/MDAlgorithms/test/SlicingAlgorithmTest.h @@ -332,7 +332,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { void test_aligned_ImplicitFunction() { SlicingAlgorithmImpl *alg = do_createAlignedTransform( "Axis0, 2.0,8.0, 6", "Axis1, 2.0,8.0, 3", "Axis2, 2.0,8.0, 3", ""); - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(3, 4, 5))); @@ -681,7 +682,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, 1.0, 2.6)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2))); @@ -738,7 +740,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(3, in), VMD(3.0, -1.0, 2.6)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, -1.5, 2))); @@ -756,8 +759,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234))); @@ -777,8 +780,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 8); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 1.5, 1.5))); @@ -796,8 +799,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 8); TS_ASSERT(func->isPointContained(VMD(1.5, -1.5, 1.5, 1.5))); @@ -814,8 +817,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234, 456))); @@ -835,8 +838,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 234))); @@ -854,8 +857,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2))); @@ -873,8 +876,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5))); @@ -932,7 +935,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(-8.9, -18.9))); @@ -997,7 +1001,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(VMD(2, in), VMD(3., -11.)); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(-18.9, -98.9))); @@ -1026,8 +1031,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(2., 1.))); @@ -1048,8 +1053,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 4); TS_ASSERT(func->isPointContained(VMD(2., 1., 0.))); @@ -1072,8 +1077,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 8); TS_ASSERT(func->isPointContained(VMD(2., 1., 0., 0.))); @@ -1093,8 +1098,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { // The implicit function MDImplicitFunction *func(nullptr); - TS_ASSERT_THROWS_NOTHING(func = - alg->getImplicitFunctionForChunk(nullptr, nullptr)); + TS_ASSERT_THROWS_NOTHING( + func = alg->getImplicitFunctionForChunk(nullptr, nullptr)); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 6); TS_ASSERT(func->isPointContained(VMD(2., 1., 0., 0.))); @@ -1112,7 +1117,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2, 345))); @@ -1127,7 +1133,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5, 2))); @@ -1142,7 +1149,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); TS_ASSERT(func->isPointContained(VMD(1.5, 1.5))); @@ -1159,7 +1167,8 @@ class SlicingAlgorithmTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(alg->m_bases.size(), 1); // The implicit function - MDImplicitFunction *func = alg->getImplicitFunctionForChunk(nullptr, nullptr); + MDImplicitFunction *func = + alg->getImplicitFunctionForChunk(nullptr, nullptr); TS_ASSERT(func); TS_ASSERT_EQUALS(func->getNumPlanes(), 2); VMD point(1); From bc49ccb15fd44c0db935d6caf9f2924313c6fe8e Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 22 Mar 2018 10:45:26 +0000 Subject: [PATCH 349/364] refs #22160 clang format for muon fit menu disabled --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 8812e66448f9..d869e315eef8 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -338,12 +338,10 @@ void MuonFitPropertyBrowser::setFitEnabled(bool yes) { void MuonFitPropertyBrowser::checkFitEnabled() { if (m_isMultiFittingMode && m_compositeFunction->nFunctions() == 0) { setFitEnabled(false); - } - else if (m_isMultiFittingMode){ - setFitEnabled(true); + } else if (m_isMultiFittingMode) { + setFitEnabled(true); - } - else if (getAutoBackgroundString() != "") { + } else if (getAutoBackgroundString() != "") { setFitEnabled(true); } else { setFitEnabled(false); From 5f996127285e2a9a28b7dc1f35c124db2501f8d5 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 22 Mar 2018 10:48:39 +0000 Subject: [PATCH 350/364] refs #22160 improved fix for muon fit menu disabled --- .../common/src/MuonFitPropertyBrowser.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index d869e315eef8..effa26d0f11c 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -336,16 +336,12 @@ void MuonFitPropertyBrowser::setFitEnabled(bool yes) { } void MuonFitPropertyBrowser::checkFitEnabled() { - if (m_isMultiFittingMode && m_compositeFunction->nFunctions() == 0) { - setFitEnabled(false); - } else if (m_isMultiFittingMode) { - setFitEnabled(true); - - } else if (getAutoBackgroundString() != "") { - setFitEnabled(true); - } else { - setFitEnabled(false); - } + if (count() == 0) { + setFitEnabled(false); + } + else { + setFitEnabled(true); + } } /** * Set the input workspace name @@ -1201,7 +1197,7 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { setAllGroups(); setAllPeriods(); setAutoBackgroundName(""); - + this->clear(); // force update of composite function } else { // clear current selection if (m_autoBackground != "") { setAutoBackgroundName(m_autoBackground); From b1a1fa3d4cdddfc29da269cd120f2aaadaa7d36f Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 11:45:31 +0000 Subject: [PATCH 351/364] Re #22169: Applied fixes to qt/. --- .../General/DataComparison.cpp | 18 +++++++++--------- qt/scientific_interfaces/General/MantidEV.cpp | 2 +- qt/scientific_interfaces/General/StepScan.cpp | 2 +- .../Indirect/ApplyAbsorptionCorrections.cpp | 2 +- qt/scientific_interfaces/Indirect/ConvFit.cpp | 4 ++-- .../Indirect/IndirectDataReduction.cpp | 10 +++++----- .../Indirect/IndirectDiffractionReduction.cpp | 2 +- .../Indirect/IndirectTab.cpp | 2 +- qt/scientific_interfaces/Muon/MuonAnalysis.cpp | 4 ++-- .../Common/DataProcessorUI/GridDelegate.h | 2 +- .../FindFilesThreadPoolManagerMockObjects.h | 2 +- .../MantidQtWidgets/Common/MantidHelpWindow.h | 2 +- .../QtPropertyBrowser/qtpropertymanager.h | 4 ++-- .../inc/MantidQtWidgets/Common/pqHelpWindow.h | 4 ++-- .../common/src/AlgorithmSelectorWidget.cpp | 2 +- qt/widgets/common/src/FitPropertyBrowser.cpp | 4 ++-- qt/widgets/common/src/MantidWSIndexDialog.cpp | 6 +++--- qt/widgets/common/src/MultifitSetupDialog.cpp | 2 +- .../common/src/MuonFitPropertyBrowser.cpp | 2 +- qt/widgets/common/src/PropertyHandler.cpp | 8 ++++---- .../src/QtPropertyBrowser/qteditorfactory.cpp | 2 +- .../QtPropertyBrowser/qtpropertybrowser.cpp | 6 +++--- .../qtpropertybrowserutils.cpp | 2 +- .../qttreepropertybrowser.cpp | 8 ++++---- qt/widgets/common/src/SaveWorkspaces.cpp | 2 +- qt/widgets/common/src/SlitCalculator.cpp | 4 ++-- .../WorkspacePresenter/WorkspaceTreeWidget.cpp | 2 +- qt/widgets/common/src/WorkspaceSelector.cpp | 2 +- qt/widgets/common/src/pqHelpWindow.cxx | 4 ++-- .../instrumentview/src/ProjectionSurface.cpp | 2 +- qt/widgets/legacyqwt/src/MWView.cpp | 2 +- .../src/MantidQwtIMDWorkspaceData.cpp | 2 +- .../algorithm_dialogs/src/LoadDialog.cpp | 4 ++-- .../sliceviewer/src/ConcretePeaksPresenter.cpp | 16 ++++++++-------- qt/widgets/sliceviewer/src/SliceViewer.cpp | 2 +- .../sliceviewer/src/SliceViewerWindow.cpp | 2 +- .../spectrumviewer/src/MatrixWSDataSource.cpp | 4 ++-- 37 files changed, 75 insertions(+), 75 deletions(-) diff --git a/qt/scientific_interfaces/General/DataComparison.cpp b/qt/scientific_interfaces/General/DataComparison.cpp index b080ceacf0db..9271231faac3 100644 --- a/qt/scientific_interfaces/General/DataComparison.cpp +++ b/qt/scientific_interfaces/General/DataComparison.cpp @@ -108,7 +108,7 @@ void DataComparison::addData() { m_uiForm.twCurrentData->blockSignals(true); // If this is a WorkspaceGroup then add all items - if (wsGroup != NULL) { + if (wsGroup != nullptr) { size_t numWs = wsGroup->size(); for (size_t wsIdx = 0; wsIdx < numWs; wsIdx++) { addDataItem(wsGroup->getItem(wsIdx)); @@ -278,7 +278,7 @@ void DataComparison::removeSelectedData() { // Detach the old curve from the plot if it exists if (m_curves.contains(workspaceName)) - m_curves[workspaceName]->attach(NULL); + m_curves[workspaceName]->attach(nullptr); selectedItems = m_uiForm.twCurrentData->selectedItems(); } @@ -304,7 +304,7 @@ void DataComparison::removeAllData() { // Detach the old curve from the plot if it exists if (m_curves.contains(workspaceName)) - m_curves[workspaceName]->attach(NULL); + m_curves[workspaceName]->attach(nullptr); } // Replot the workspaces @@ -353,7 +353,7 @@ void DataComparison::plotWorkspaces() { // Detech the curve from the plot if (m_curves.contains(workspaceName)) - m_curves[workspaceName]->attach(NULL); + m_curves[workspaceName]->attach(nullptr); continue; } @@ -369,7 +369,7 @@ void DataComparison::plotWorkspaces() { // Detach the old curve from the plot if it exists if (m_curves.contains(workspaceName)) - m_curves[workspaceName]->attach(NULL); + m_curves[workspaceName]->attach(nullptr); QComboBox *colourSelector = dynamic_cast( m_uiForm.twCurrentData->cellWidget(row, COLOUR)); @@ -452,8 +452,8 @@ void DataComparison::workspaceIndexChanged() { */ void DataComparison::plotDiffWorkspace() { // Detach old curve - if (m_diffCurve != NULL) - m_diffCurve->attach(NULL); + if (m_diffCurve != nullptr) + m_diffCurve->attach(nullptr); // Do nothing if there are not two workspaces if (m_diffWorkspaceNames.first.isEmpty() || @@ -682,7 +682,7 @@ void DataComparison::preDeleteHandle( // Detach the old curve from the plot if it exists if (m_curves.contains(oldWsName)) - m_curves[oldWsName]->attach(NULL); + m_curves[oldWsName]->attach(nullptr); // Update the plot plotWorkspaces(); @@ -713,7 +713,7 @@ void DataComparison::renameHandle(const std::string &oldName, // Detach the old curve from the plot if it exists if (m_curves.contains(oldWsName)) - m_curves[oldWsName]->attach(NULL); + m_curves[oldWsName]->attach(nullptr); // Update the plot plotWorkspaces(); diff --git a/qt/scientific_interfaces/General/MantidEV.cpp b/qt/scientific_interfaces/General/MantidEV.cpp index d79ca6bef1aa..e1868996ae61 100644 --- a/qt/scientific_interfaces/General/MantidEV.cpp +++ b/qt/scientific_interfaces/General/MantidEV.cpp @@ -495,7 +495,7 @@ void MantidEV::setDefaultState_slot() { */ void MantidEV::help_slot() { MantidQt::API::HelpWindow::showCustomInterface( - NULL, QString("SCD Event Data Reduction")); + nullptr, QString("SCD Event Data Reduction")); } /** diff --git a/qt/scientific_interfaces/General/StepScan.cpp b/qt/scientific_interfaces/General/StepScan.cpp index f83ff8297d81..c91c0e63471e 100644 --- a/qt/scientific_interfaces/General/StepScan.cpp +++ b/qt/scientific_interfaces/General/StepScan.cpp @@ -410,7 +410,7 @@ void StepScan::expandPlotVarCombobox( // Try to cast to an ITimeSeriesProperty auto tsp = dynamic_cast(*log); // Move on to the next one if this is not a TSP - if (tsp == NULL) + if (tsp == nullptr) continue; // Don't keep ones with only one entry if (tsp->realSize() < 2) diff --git a/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp b/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp index 3bf5a5a05029..5f1dc8ab1079 100644 --- a/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp +++ b/qt/scientific_interfaces/Indirect/ApplyAbsorptionCorrections.cpp @@ -255,7 +255,7 @@ void ApplyAbsorptionCorrections::run() { "Would you like to interpolate this workspace to " "match the sample?"; - result = QMessageBox::question(NULL, tr("Interpolate corrections?"), + result = QMessageBox::question(nullptr, tr("Interpolate corrections?"), tr(text.c_str()), QMessageBox::YesToAll, QMessageBox::Yes, QMessageBox::No); } diff --git a/qt/scientific_interfaces/Indirect/ConvFit.cpp b/qt/scientific_interfaces/Indirect/ConvFit.cpp index 4928651d5fe6..f84281861a46 100644 --- a/qt/scientific_interfaces/Indirect/ConvFit.cpp +++ b/qt/scientific_interfaces/Indirect/ConvFit.cpp @@ -709,7 +709,7 @@ double ConvFit::getInstrumentResolution(MatrixWorkspace_sptr workspace) const { // If the analyser component is not already in the data file then load it // from the parameter file - if (inst->getComponentByName(analyser) == NULL || + if (inst->getComponentByName(analyser) == nullptr || inst->getComponentByName(analyser) ->getNumberParameter("resolution") .size() == 0) { @@ -729,7 +729,7 @@ double ConvFit::getInstrumentResolution(MatrixWorkspace_sptr workspace) const { inst = workspace->getInstrument(); } - if (inst->getComponentByName(analyser) != NULL) { + if (inst->getComponentByName(analyser) != nullptr) { resolution = inst->getComponentByName(analyser) ->getNumberParameter("resolution")[0]; } else { diff --git a/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp b/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp index 96eaa3192415..df1c5609c6bc 100644 --- a/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectDataReduction.cpp @@ -177,9 +177,9 @@ void IndirectDataReduction::instrumentSetupChanged( m_instWorkspace = loadInstrumentIfNotExist(instrumentName.toStdString(), analyser.toStdString(), reflection.toStdString()); - instrumentLoadingDone(m_instWorkspace == NULL); + instrumentLoadingDone(m_instWorkspace == nullptr); - if (m_instWorkspace != NULL) + if (m_instWorkspace != nullptr) emit newInstrumentConfiguration(); } @@ -270,14 +270,14 @@ QMap IndirectDataReduction::getInstrumentDetails() { if (instrumentName == "IRIS" && analyser == "fmica") analyser = "mica"; - if (m_instWorkspace == NULL) { + if (m_instWorkspace == nullptr) { g_log.warning("Instrument workspace not loaded"); return instDetails; } // Get the instrument auto instrument = m_instWorkspace->getInstrument(); - if (instrument == NULL) { + if (instrument == nullptr) { g_log.warning("Instrument workspace has no instrument"); return instDetails; } @@ -292,7 +292,7 @@ QMap IndirectDataReduction::getInstrumentDetails() { QString value = getInstrumentParameterFrom(instrument, key); - if (value.isEmpty() && component != NULL) + if (value.isEmpty() && component != nullptr) value = getInstrumentParameterFrom(component, key); instDetails[QString::fromStdString(key)] = value; diff --git a/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp b/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp index 9c4f85695895..3dac377a3374 100644 --- a/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectDiffractionReduction.cpp @@ -163,7 +163,7 @@ void IndirectDiffractionReduction::run() { */ void IndirectDiffractionReduction::algorithmComplete(bool error) { // Handles completion of the diffraction algorithm chain - disconnect(m_batchAlgoRunner, 0, this, SLOT(algorithmComplete(bool))); + disconnect(m_batchAlgoRunner, nullptr, this, SLOT(algorithmComplete(bool))); // Delete grouping workspace, if created. if (AnalysisDataService::Instance().doesExist(m_groupingWsName)) { diff --git a/qt/scientific_interfaces/Indirect/IndirectTab.cpp b/qt/scientific_interfaces/Indirect/IndirectTab.cpp index 80374143906b..1518c450d6ad 100644 --- a/qt/scientific_interfaces/Indirect/IndirectTab.cpp +++ b/qt/scientific_interfaces/Indirect/IndirectTab.cpp @@ -112,7 +112,7 @@ void IndirectTab::exportPythonScript() { // Create an algorithm dialog for the script export algorithm MantidQt::API::InterfaceManager interfaceManager; MantidQt::API::AlgorithmDialog *dlg = interfaceManager.createDialogFromName( - "GeneratePythonScript", -1, NULL, false, props, "", enabled); + "GeneratePythonScript", -1, nullptr, false, props, "", enabled); // Show the dialog dlg->show(); diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp index 3aa8a088184b..4fb92f80dbf3 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.cpp +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.cpp @@ -2591,7 +2591,7 @@ void MuonAnalysis::changeTab(int newTabIndex) { if (m_currentTab == m_uiForm.DataAnalysis) // Leaving DA tab { // Say MantidPlot to use default fit prop. browser - emit setFitPropertyBrowser(NULL); + emit setFitPropertyBrowser(nullptr); // Reset cached config option ConfigService::Instance().setString(PEAK_RADIUS_CONFIG, m_cachedPeakRadius); @@ -2909,7 +2909,7 @@ void MuonAnalysis::hideEvent(QHideEvent *) { // If closed while on DA tab, reassign fit property browser to default one if (m_currentTab == m_uiForm.DataAnalysis) - emit setFitPropertyBrowser(NULL); + emit setFitPropertyBrowser(nullptr); } /** diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h index 8f8cad70c3cc..84cf745ca62d 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h @@ -7,7 +7,7 @@ namespace DataProcessor { class GridDelegate : public QStyledItemDelegate { public: - explicit GridDelegate(QObject *parent = 0) : QStyledItemDelegate(parent){}; + explicit GridDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent){}; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h index f75564fb9476..cfd3f86393bb 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/FindFilesThreadPoolManagerMockObjects.h @@ -19,7 +19,7 @@ void qSleep(int ms) { Sleep(uint(ms)); #else struct timespec ts = {ms / 1000, (ms % 1000) * 1000 * 1000}; - nanosleep(&ts, NULL); + nanosleep(&ts, nullptr); #endif } } // namespace diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h b/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h index dce046f39769..4dfe27cbb005 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/MantidHelpWindow.h @@ -20,7 +20,7 @@ class EXPORT_OPT_MANTIDQT_COMMON MantidHelpWindow Q_OBJECT public: - MantidHelpWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + MantidHelpWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr); ~MantidHelpWindow() override; void showPage(const std::string &url = std::string()) override; diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h index f2208d878263..dedd26e011df 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h @@ -1138,7 +1138,7 @@ static void setMinimumValue( QtProperty *property, const Value &minVal) { void (PropertyManagerPrivate::*setSubPropertyRange)( QtProperty *, ValueChangeParameter, ValueChangeParameter, - ValueChangeParameter) = 0; + ValueChangeParameter) = nullptr; setBorderValue( manager, managerPrivate, propertyChangedSignal, valueChangedSignal, @@ -1160,7 +1160,7 @@ static void setMaximumValue( QtProperty *property, const Value &maxVal) { void (PropertyManagerPrivate::*setSubPropertyRange)( QtProperty *, ValueChangeParameter, ValueChangeParameter, - ValueChangeParameter) = 0; + ValueChangeParameter) = nullptr; setBorderValue( manager, managerPrivate, propertyChangedSignal, valueChangedSignal, diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h b/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h index 9fceb9b3b084..9c8200f160ee 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/pqHelpWindow.h @@ -75,8 +75,8 @@ class EXPORT_OPT_MANTIDQT_COMMON pqHelpWindow : public QMainWindow { using Superclass = QMainWindow; public: - pqHelpWindow(QHelpEngine *engine, QWidget *parent = 0, - Qt::WindowFlags flags = 0); + pqHelpWindow(QHelpEngine *engine, QWidget *parent = nullptr, + Qt::WindowFlags flags = nullptr); public slots: /// Requests showing of a particular page. The url must begin with "qthelp:" diff --git a/qt/widgets/common/src/AlgorithmSelectorWidget.cpp b/qt/widgets/common/src/AlgorithmSelectorWidget.cpp index 465619911e41..cd42f9b917b6 100644 --- a/qt/widgets/common/src/AlgorithmSelectorWidget.cpp +++ b/qt/widgets/common/src/AlgorithmSelectorWidget.cpp @@ -293,7 +293,7 @@ void AlgorithmTreeWidget::update() { this->addTopLevelItem(catItem); } else { QString cn = subCats[0]; - QTreeWidgetItem *catItem = NULL; + QTreeWidgetItem *catItem = nullptr; int n = subCats.size(); for (int j = 0; j < n; j++) { if (categories.contains(cn)) { diff --git a/qt/widgets/common/src/FitPropertyBrowser.cpp b/qt/widgets/common/src/FitPropertyBrowser.cpp index 498f7f24cbdc..f845baea5485 100644 --- a/qt/widgets/common/src/FitPropertyBrowser.cpp +++ b/qt/widgets/common/src/FitPropertyBrowser.cpp @@ -1784,8 +1784,8 @@ void FitPropertyBrowser::postDeleteHandle(const std::string &wsName) { */ bool FitPropertyBrowser::isWorkspaceValid( Mantid::API::Workspace_sptr ws) const { - return (dynamic_cast(ws.get()) != 0 || - dynamic_cast(ws.get()) != 0); + return (dynamic_cast(ws.get()) != nullptr || + dynamic_cast(ws.get()) != nullptr); } bool FitPropertyBrowser::isWorkspaceAGroup() const { diff --git a/qt/widgets/common/src/MantidWSIndexDialog.cpp b/qt/widgets/common/src/MantidWSIndexDialog.cpp index 8347bd0bf9f2..2cf7ec17bf59 100644 --- a/qt/widgets/common/src/MantidWSIndexDialog.cpp +++ b/qt/widgets/common/src/MantidWSIndexDialog.cpp @@ -207,7 +207,7 @@ QMultiMap> MantidWSIndexWidget::getPlots() const { boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( m_wsNames[i].toStdString())); - if (NULL == ws) + if (nullptr == ws) continue; const Mantid::spec2index_map spec2index = @@ -690,7 +690,7 @@ void MantidWSIndexWidget::checkForSpectraAxes() { boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( (*it).toStdString())); - if (NULL == ws) + if (nullptr == ws) continue; bool hasSpectra = false; for (int i = 0; i < ws->axes(); i++) { @@ -718,7 +718,7 @@ void MantidWSIndexWidget::generateWsIndexIntervals() { boost::dynamic_pointer_cast( Mantid::API::AnalysisDataService::Instance().retrieve( (*it).toStdString())); - if (NULL == ws) + if (nullptr == ws) continue; const int endWs = static_cast(ws->getNumberHistograms() - diff --git a/qt/widgets/common/src/MultifitSetupDialog.cpp b/qt/widgets/common/src/MultifitSetupDialog.cpp index db316764958e..5bfc07aa79ee 100644 --- a/qt/widgets/common/src/MultifitSetupDialog.cpp +++ b/qt/widgets/common/src/MultifitSetupDialog.cpp @@ -32,7 +32,7 @@ MultifitSetupDialog::MultifitSetupDialog(FitPropertyBrowser *fitBrowser) ui.paramTable->insertRow(ui.paramTable->rowCount()); model->setData(model->index(j, 0), QString::fromStdString(f->parameterName(i))); - ui.paramTable->item(j, 0)->setFlags(0); + ui.paramTable->item(j, 0)->setFlags(nullptr); model->setData(model->index(j, 1), ""); ui.paramTable->item(j, 1)->setCheckState(Qt::Unchecked); } diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index 52fb3e30fa33..592c125a4233 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -1042,7 +1042,7 @@ bool MuonFitPropertyBrowser::isWorkspaceValid(Workspace_sptr ws) const { if (workspaceName.endsWith("_Workspace")) return false; - return dynamic_cast(ws.get()) != 0; + return dynamic_cast(ws.get()) != nullptr; } void MuonFitPropertyBrowser::finishHandle(const IAlgorithm *alg) { diff --git a/qt/widgets/common/src/PropertyHandler.cpp b/qt/widgets/common/src/PropertyHandler.cpp index 337f88313b15..a764fccacca1 100644 --- a/qt/widgets/common/src/PropertyHandler.cpp +++ b/qt/widgets/common/src/PropertyHandler.cpp @@ -44,7 +44,7 @@ PropertyHandler::~PropertyHandler() {} /// overrides virtual init() which is called from IFunction::setHandler(...) void PropertyHandler::init() { m_browser->m_changeSlotsEnabled = false; - if (m_parent == NULL) { // the root composite function + if (m_parent == nullptr) { // the root composite function m_item = m_browser->m_functionsGroup; } else if (m_item == nullptr) { if (!m_parent->getHandler()) { @@ -538,7 +538,7 @@ PropertyHandler::findCompositeFunction(QtBrowserItem *item) const { for (size_t i = 0; i < m_cf->nFunctions(); i++) { Mantid::API::CompositeFunction_const_sptr res = getHandler(i)->findCompositeFunction(item); - if (res != NULL) + if (res != nullptr) return res; } return Mantid::API::CompositeFunction_sptr(); @@ -555,7 +555,7 @@ PropertyHandler::findFunction(QtBrowserItem *item) const { return Mantid::API::IFunction_sptr(); for (size_t i = 0; i < m_cf->nFunctions(); i++) { Mantid::API::IFunction_const_sptr res = getHandler(i)->findFunction(item); - if (res != NULL) + if (res != nullptr) return res; } return Mantid::API::IFunction_sptr(); @@ -927,7 +927,7 @@ Mantid::API::IFunction_sptr PropertyHandler::changeType(QtProperty *prop) { f = Mantid::API::FunctionFactory::Instance().createFunction( fnName.toStdString()); } catch (std::exception &e) { - QMessageBox::critical(NULL, "Mantid - Error", "Cannot create function " + + QMessageBox::critical(nullptr, "Mantid - Error", "Cannot create function " + fnName + "\n" + e.what()); return Mantid::API::IFunction_sptr(); diff --git a/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp b/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp index 069dfec78e40..8833948710c4 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qteditorfactory.cpp @@ -841,7 +841,7 @@ void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property, QLineEdit *editor = itEditor.next(); editor->blockSignals(true); const QValidator *oldValidator = editor->validator(); - QValidator *newValidator = 0; + QValidator *newValidator = nullptr; if (regExp.isValid()) { newValidator = new QRegExpValidator(regExp, editor); } diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp index 1a4b46554825..36466030b972 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp @@ -1783,7 +1783,7 @@ QtAbstractPropertyBrowser::insertProperty(QtProperty *property, while (pos < pendingList.count()) { QtProperty *prop = pendingList.at(pos); if (prop == property) - return 0; + return nullptr; if (prop == afterProperty) { newPos = pos + 1; } @@ -1819,10 +1819,10 @@ void QtAbstractPropertyBrowser::removeProperty(QtProperty *property) { if (pendingList.at(pos) == property) { d_ptr->m_subItems.removeAt(pos); // perhaps this two lines d_ptr->removeSubTree( - property, 0); // should be moved down after propertyRemoved call. + property, nullptr); // should be moved down after propertyRemoved call. // propertyRemoved(property, 0); - d_ptr->removeBrowserIndexes(property, 0); + d_ptr->removeBrowserIndexes(property, nullptr); // when item is deleted, item will call removeItem for top level items, // and itemRemoved for nested items. diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp index 997c7b4111f6..577f0648bff8 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowserutils.cpp @@ -97,7 +97,7 @@ namespace { // Translation function for Qt4/Qt5. Qt5 has no encoding option QString translateUtf8Encoded(const char *context, const char *key, - const char *disambiguation = 0, int n = -1) { + const char *disambiguation = nullptr, int n = -1) { #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) return QApplication::translate(context, key, disambiguation, QApplication::UnicodeUTF8, n); diff --git a/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp b/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp index 80229ea10fb1..4ec953bc4b9c 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qttreepropertybrowser.cpp @@ -103,7 +103,7 @@ namespace { // Translation function for Qt4/Qt5. Qt5 has no encoding option QString translateUtf8Encoded(const char *context, const char *key, - const char *disambiguation = 0, int n = -1) { + const char *disambiguation = nullptr, int n = -1) { #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) return QApplication::translate(context, key, disambiguation, QApplication::UnicodeUTF8, n); @@ -483,8 +483,8 @@ QtBrowserItem *QtTreePropertyBrowserPrivate::currentItem() const { void QtTreePropertyBrowserPrivate::setCurrentItem(QtBrowserItem *browserItem, bool block) { const bool blocked = block ? m_treeWidget->blockSignals(true) : false; - if (browserItem == 0) - m_treeWidget->setCurrentItem(0); + if (browserItem == nullptr) + m_treeWidget->setCurrentItem(nullptr); else m_treeWidget->setCurrentItem(m_indexToItem.value(browserItem)); if (block) @@ -575,7 +575,7 @@ void QtTreePropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index) { QTreeWidgetItem *item = m_indexToItem.value(index); if (m_treeWidget->currentItem() == item) { - m_treeWidget->setCurrentItem(0); + m_treeWidget->setCurrentItem(nullptr); } delete item; diff --git a/qt/widgets/common/src/SaveWorkspaces.cpp b/qt/widgets/common/src/SaveWorkspaces.cpp index 9f234bb042d3..838afb6a84ba 100644 --- a/qt/widgets/common/src/SaveWorkspaces.cpp +++ b/qt/widgets/common/src/SaveWorkspaces.cpp @@ -446,7 +446,7 @@ void SaveWorkspaces::saveFileBrowse() { ? QFileDialog::DontConfirmOverwrite : static_cast(0); QString oFile = QFileDialog::getSaveFileName(this, title, prevPath, filter, - NULL, userCon); + nullptr, userCon); if (!oFile.isEmpty()) { m_fNameEdit->setText(oFile); diff --git a/qt/widgets/common/src/SlitCalculator.cpp b/qt/widgets/common/src/SlitCalculator.cpp index f908023a796b..594217bd700c 100644 --- a/qt/widgets/common/src/SlitCalculator.cpp +++ b/qt/widgets/common/src/SlitCalculator.cpp @@ -62,8 +62,8 @@ void SlitCalculator::setupSlitCalculatorWithInstrumentValues( auto slit2Component = instrument->getComponentByName("slit2"); auto sampleComponent = instrument->getComponentByName("some-surface-holder"); // check that they have been fetched from the IDF - if (slit1Component.get() != NULL && slit2Component.get() != NULL && - sampleComponent.get() != NULL) { + if (slit1Component.get() != nullptr && slit2Component.get() != nullptr && + sampleComponent.get() != nullptr) { // convert from meters to millimeters const double s1s2 = 1e3 * (slit1Component->getDistance(*slit2Component)); // set value in field of slitCalculator diff --git a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp index b491ee8266ef..6e4f28d8e290 100644 --- a/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp +++ b/qt/widgets/common/src/WorkspacePresenter/WorkspaceTreeWidget.cpp @@ -491,7 +491,7 @@ void WorkspaceTreeWidget::filterWorkspaces(const std::string &filterText) { item->setHidden(false); } - if (item->parent() == NULL) { + if (item->parent() == nullptr) { // No parent, I am a top level workspace - show me item->setHidden(false); } else { diff --git a/qt/widgets/common/src/WorkspaceSelector.cpp b/qt/widgets/common/src/WorkspaceSelector.cpp index ff46217badec..5e885ea90aa9 100644 --- a/qt/widgets/common/src/WorkspaceSelector.cpp +++ b/qt/widgets/common/src/WorkspaceSelector.cpp @@ -145,7 +145,7 @@ void WorkspaceSelector::setValidatingAlgorithm(const QString &algName) { // try to cast property to WorkspaceProperty Mantid::API::WorkspaceProperty<> *wsProp = dynamic_cast *>(*it); - if (wsProp != NULL) { + if (wsProp != nullptr) { m_algPropName = QString::fromStdString((*it)->name()); break; } diff --git a/qt/widgets/common/src/pqHelpWindow.cxx b/qt/widgets/common/src/pqHelpWindow.cxx index e84364deec18..f9d19ee4229a 100644 --- a/qt/widgets/common/src/pqHelpWindow.cxx +++ b/qt/widgets/common/src/pqHelpWindow.cxx @@ -146,7 +146,7 @@ class pqHelpWindow::pqNetworkAccessManager : public QNetworkAccessManager { pqNetworkAccessManager(QHelpEngineCore *helpEngine, QNetworkAccessManager *manager, QObject *parentObject) : Superclass(parentObject), Engine(helpEngine) { - Q_ASSERT(manager != NULL && helpEngine != NULL); + Q_ASSERT(manager != nullptr && helpEngine != nullptr); this->setCache(manager->cache()); this->setCookieJar(manager->cookieJar()); @@ -205,7 +205,7 @@ class QtHelpUrlHandler : public QWebEngineUrlSchemeHandler { pqHelpWindow::pqHelpWindow(QHelpEngine *engine, QWidget *parentObject, Qt::WindowFlags parentFlags) : Superclass(parentObject, parentFlags), m_helpEngine(engine) { - Q_ASSERT(engine != NULL); + Q_ASSERT(engine != nullptr); Ui::pqHelpWindow ui; ui.setupUi(this); diff --git a/qt/widgets/instrumentview/src/ProjectionSurface.cpp b/qt/widgets/instrumentview/src/ProjectionSurface.cpp index 3fd01e2430ef..696596f889e7 100644 --- a/qt/widgets/instrumentview/src/ProjectionSurface.cpp +++ b/qt/widgets/instrumentview/src/ProjectionSurface.cpp @@ -767,7 +767,7 @@ void ProjectionSurface::clearComparisonPeaks() { */ void ProjectionSurface::setPeakLabelPrecision(int n) { if (n < 1) { - QMessageBox::critical(NULL, "MantidPlot - Error", + QMessageBox::critical(nullptr, "MantidPlot - Error", "Precision must be a positive number"); return; } diff --git a/qt/widgets/legacyqwt/src/MWView.cpp b/qt/widgets/legacyqwt/src/MWView.cpp index aaacf5d3ea69..bc76328e8b65 100644 --- a/qt/widgets/legacyqwt/src/MWView.cpp +++ b/qt/widgets/legacyqwt/src/MWView.cpp @@ -185,7 +185,7 @@ void MWView::loadSettings() { // used. // If the user selected a unified color map for the SliceViewer and the VSI, // then this is loaded. - if (m_mdSettings != NULL && m_mdSettings->getUsageGeneralMdColorMap()) { + if (m_mdSettings != nullptr && m_mdSettings->getUsageGeneralMdColorMap()) { m_currentColorMapFile = m_mdSettings->getGeneralMdColorMapFile(); } else { m_currentColorMapFile = settings.value("ColormapFile", "").toString(); diff --git a/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp b/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp index e6a3d3abaa00..855b10cfa9d0 100644 --- a/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp +++ b/qt/widgets/legacyqwt/src/MantidQwtIMDWorkspaceData.cpp @@ -316,7 +316,7 @@ void MantidQwtIMDWorkspaceData::choosePlotAxis() { regularBinnedMDWorkspace = atLeastOneDimNotIntegrated; } - if (NULL != + if (nullptr != boost::dynamic_pointer_cast( originalWS) || regularBinnedMDWorkspace) { diff --git a/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp b/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp index 0d091f7cd13d..b0dff8bcc615 100644 --- a/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp +++ b/qt/widgets/plugins/algorithm_dialogs/src/LoadDialog.cpp @@ -216,7 +216,7 @@ void LoadDialog::tieStaticWidgets(const bool readHistory) { } tie(m_form.workspaceEdit, "OutputWorkspace", m_form.workspaceLayout, readHistory); - tie(m_form.fileWidget, "Filename", NULL, readHistory); + tie(m_form.fileWidget, "Filename", nullptr, readHistory); } /** @@ -386,7 +386,7 @@ int LoadDialog::createWidgetsForProperty(const Mantid::Kernel::Property *prop, if (addValidator) tie(inputWidget, propName, widgetLayout); else - tie(inputWidget, propName, NULL); + tie(inputWidget, propName, nullptr); return inputWidget->geometry().height(); } diff --git a/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp b/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp index 2b80d68addfe..9bd23870c0f7 100644 --- a/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp +++ b/qt/widgets/sliceviewer/src/ConcretePeaksPresenter.cpp @@ -286,7 +286,7 @@ bool ConcretePeaksPresenter::isDimensionNameOfFreeAxis( Request that each owned view makes its self visible. */ void ConcretePeaksPresenter::showAll() { - if (m_viewPeaks != NULL) + if (m_viewPeaks != nullptr) m_viewPeaks->showView(); } @@ -295,7 +295,7 @@ void ConcretePeaksPresenter::showAll() { */ void ConcretePeaksPresenter::hideAll() { // Hide all views. - if (m_viewPeaks != NULL) + if (m_viewPeaks != nullptr) m_viewPeaks->hideView(); } @@ -319,7 +319,7 @@ PeakViewColor ConcretePeaksPresenter::getForegroundPeakViewColor() const { void ConcretePeaksPresenter::setForegroundColor(const PeakViewColor color) { // Change foreground colors - if (m_viewPeaks != NULL) { + if (m_viewPeaks != nullptr) { m_viewPeaks->changeForegroundColour(color); m_viewPeaks->updateView(); } @@ -329,7 +329,7 @@ void ConcretePeaksPresenter::setForegroundColor(const PeakViewColor color) { void ConcretePeaksPresenter::setBackgroundColor(const PeakViewColor color) { // Change background colours - if (m_viewPeaks != NULL) { + if (m_viewPeaks != nullptr) { m_viewPeaks->changeBackgroundColour(color); m_viewPeaks->updateView(); } @@ -343,7 +343,7 @@ std::string ConcretePeaksPresenter::getTransformName() const { void ConcretePeaksPresenter::showBackgroundRadius(const bool show) { // Change background colours - if (m_viewPeaks != NULL) { + if (m_viewPeaks != nullptr) { m_viewPeaks->showBackgroundRadius(show); doFindPeaksInRegion(); } @@ -353,7 +353,7 @@ void ConcretePeaksPresenter::showBackgroundRadius(const bool show) { void ConcretePeaksPresenter::setShown(const bool shown) { m_isHidden = !shown; - if (m_viewPeaks != NULL) { + if (m_viewPeaks != nullptr) { if (shown) { m_viewPeaks->showView(); } else { @@ -417,7 +417,7 @@ void ConcretePeaksPresenter::setPeakSizeIntoProjection(const double fraction) { double ConcretePeaksPresenter::getPeakSizeOnProjection() const { double result = 0; - if (m_viewPeaks != NULL && m_peaksWS->getNumberPeaks() > 0) { + if (m_viewPeaks != nullptr && m_peaksWS->getNumberPeaks() > 0) { result = m_viewPeaks->getOccupancyInView(); } return result; @@ -425,7 +425,7 @@ double ConcretePeaksPresenter::getPeakSizeOnProjection() const { double ConcretePeaksPresenter::getPeakSizeIntoProjection() const { double result = 0; - if (m_viewPeaks != NULL && m_peaksWS->getNumberPeaks() > 0) { + if (m_viewPeaks != nullptr && m_peaksWS->getNumberPeaks() > 0) { result = m_viewPeaks->getOccupancyIntoView(); } return result; diff --git a/qt/widgets/sliceviewer/src/SliceViewer.cpp b/qt/widgets/sliceviewer/src/SliceViewer.cpp index 4f2763b5f0e7..7f8e690049ad 100644 --- a/qt/widgets/sliceviewer/src/SliceViewer.cpp +++ b/qt/widgets/sliceviewer/src/SliceViewer.cpp @@ -261,7 +261,7 @@ void SliceViewer::loadSettings() { // used. // If the user selected a unified color map for the SliceViewer and the VSI, // then this is loaded. - if (m_mdSettings != NULL && m_mdSettings->getUsageGeneralMdColorMap()) { + if (m_mdSettings != nullptr && m_mdSettings->getUsageGeneralMdColorMap()) { m_currentColorMapFile = m_mdSettings->getGeneralMdColorMapFile(); } else { m_currentColorMapFile = settings.value("ColormapFile", "").toString(); diff --git a/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp b/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp index f0c25fcde89e..0083113256ec 100644 --- a/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp +++ b/qt/widgets/sliceviewer/src/SliceViewerWindow.cpp @@ -32,7 +32,7 @@ namespace SliceViewer { */ SliceViewerWindow::SliceViewerWindow(const QString &wsName, const QString &label, Qt::WindowFlags f) - : QMainWindow(NULL, f), WorkspaceObserver(), m_lastLinerWidth(0), + : QMainWindow(nullptr, f), WorkspaceObserver(), m_lastLinerWidth(0), m_lastPeaksViewerWidth(0) { #ifdef Q_OS_MAC diff --git a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp index 2c7e702ac69c..685c46e962fa 100644 --- a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp +++ b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp @@ -242,7 +242,7 @@ std::vector MatrixWSDataSource::getInfoList(double x, double y) { std::string x_label = ""; Unit_sptr &old_unit = m_matWs->getAxis(0)->unit(); - if (old_unit != 0) { + if (old_unit != nullptr) { x_label = old_unit->caption(); SVUtils::PushNameValue(x_label, 8, 3, x, list); } @@ -262,7 +262,7 @@ std::vector MatrixWSDataSource::getInfoList(double x, double y) { try { - if (old_unit == 0) { + if (old_unit == nullptr) { g_log.debug("No UNITS on MatrixWorkspace X-axis"); return list; } From aeaaf0631a0a3a67ee664c76bfad3f5224d5e1e2 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 11:46:14 +0000 Subject: [PATCH 352/364] Re #22169: Applied fixes to a framework header. --- Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h index 2b4fcd178c1f..8284af3e4ae0 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h @@ -426,7 +426,7 @@ class DLLExport MDHistoWorkspace : public API::IMDHistoWorkspace { } MDHistoWorkspace *doCloneEmpty() const override { - return new MDHistoWorkspace(0); + return new MDHistoWorkspace(nullptr); } void makeSingleBinWithNaN(std::vector &x, std::vector &y, From 7235bdf4dc7812c31213104389b85186706d0d30 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 22 Mar 2018 12:00:42 +0000 Subject: [PATCH 353/364] refs #22160 clang improved fix for muon fit menu disabled --- qt/widgets/common/src/MuonFitPropertyBrowser.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp index effa26d0f11c..a803947ed63c 100644 --- a/qt/widgets/common/src/MuonFitPropertyBrowser.cpp +++ b/qt/widgets/common/src/MuonFitPropertyBrowser.cpp @@ -336,12 +336,11 @@ void MuonFitPropertyBrowser::setFitEnabled(bool yes) { } void MuonFitPropertyBrowser::checkFitEnabled() { - if (count() == 0) { - setFitEnabled(false); - } - else { - setFitEnabled(true); - } + if (count() == 0) { + setFitEnabled(false); + } else { + setFitEnabled(true); + } } /** * Set the input workspace name @@ -1197,8 +1196,8 @@ void MuonFitPropertyBrowser::setMultiFittingMode(bool enabled) { setAllGroups(); setAllPeriods(); setAutoBackgroundName(""); - this->clear(); // force update of composite function - } else { // clear current selection + this->clear(); // force update of composite function + } else { // clear current selection if (m_autoBackground != "") { setAutoBackgroundName(m_autoBackground); addAutoBackground(); From 2cee115c7656750d7d26c2ece2ff95db111ed7e6 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 13:23:24 +0000 Subject: [PATCH 354/364] Re #22176: Applied fixes to MantidPlot. --- MantidPlot/src/ApplicationWindow.cpp | 64 +++++++++---------- MantidPlot/src/ConfigDialog.cpp | 8 +-- MantidPlot/src/Graph.cpp | 2 +- MantidPlot/src/Graph3D.cpp | 2 +- .../InstrumentWidget/InstrumentWindow.cpp | 2 +- MantidPlot/src/Mantid/MantidMatrix.cpp | 8 +-- MantidPlot/src/Mantid/MantidTable.cpp | 2 +- MantidPlot/src/Mantid/MantidUI.cpp | 38 +++++------ MantidPlot/src/PythonScript.cpp | 2 +- MantidPlot/src/TiledWindow.cpp | 2 +- MantidPlot/src/importOPJ.cpp | 2 +- MantidPlot/src/origin/tree.hh | 8 +-- 12 files changed, 70 insertions(+), 70 deletions(-) diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp index 04133721a85c..953aac0e9b3d 100644 --- a/MantidPlot/src/ApplicationWindow.cpp +++ b/MantidPlot/src/ApplicationWindow.cpp @@ -2446,7 +2446,7 @@ Graph3D *ApplicationWindow::dataPlot3D(const QString &caption, posX = formula.indexOf("(", pos); QString yCol = formula.mid(pos + 1, posX - pos - 1); - Graph3D *plot = new Graph3D("", this, 0); + Graph3D *plot = new Graph3D("", this, nullptr); plot->addData(w, xCol, yCol, xl, xr, yl, yr, zl, zr); plot->update(); @@ -2466,7 +2466,7 @@ Graph3D *ApplicationWindow::newPlot3D() { QString label = generateUniqueName(tr("Graph")); - Graph3D *plot = new Graph3D("", this, 0); + Graph3D *plot = new Graph3D("", this, nullptr); plot->setWindowTitle(label); plot->setName(label); @@ -2486,7 +2486,7 @@ Graph3D *ApplicationWindow::plotXYZ(Table *table, const QString &zColName, QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - Graph3D *plot = new Graph3D("", this, 0); + Graph3D *plot = new Graph3D("", this, nullptr); QString label = generateUniqueName(tr("Graph")); plot->setWindowTitle(label); plot->setName(label); @@ -2531,7 +2531,7 @@ Graph3D *ApplicationWindow::openPlotXYZ(const QString &caption, int yCol = w->colIndex(yColName); int zCol = w->colIndex(zColName); - Graph3D *plot = new Graph3D("", this, 0); + Graph3D *plot = new Graph3D("", this, nullptr); plot->loadData(w, xCol, yCol, zCol, xl, xr, yl, yr, zl, zr); QString label = caption; @@ -2584,7 +2584,7 @@ void ApplicationWindow::exportMatrix() { return; ImageExportDialog *ied = - new ImageExportDialog(this, m != NULL, d_extended_export_dialog); + new ImageExportDialog(this, m != nullptr, d_extended_export_dialog); ied->setDirectory(workingDir); ied->selectFilter(d_image_export_filter); if (ied->exec() != QDialog::Accepted) @@ -3051,7 +3051,7 @@ void ApplicationWindow::setPreferences(Graph *g) { *creates a new empty table */ Table *ApplicationWindow::newTable() { - Table *w = new Table(scriptingEnv(), 30, 2, "", this, 0); + Table *w = new Table(scriptingEnv(), 30, 2, "", this, nullptr); initTable(w, generateUniqueName(tr("Table"))); w->showNormal(); return w; @@ -3061,7 +3061,7 @@ Table *ApplicationWindow::newTable() { *used when opening a project file */ Table *ApplicationWindow::newTable(const QString &caption, int r, int c) { - Table *w = new Table(scriptingEnv(), r, c, "", this, 0); + Table *w = new Table(scriptingEnv(), r, c, "", this, nullptr); initTable(w, caption); if (w->objectName() != caption) { // the table was renamed renamedTables << caption << w->objectName(); @@ -3083,7 +3083,7 @@ bool ApplicationWindow::isDeleteWorkspacePromptEnabled() { Table *ApplicationWindow::newTable(int r, int c, const QString &name, const QString &legend) { - Table *w = new Table(scriptingEnv(), r, c, legend, this, 0); + Table *w = new Table(scriptingEnv(), r, c, legend, this, nullptr); initTable(w, name); return w; } @@ -3095,7 +3095,7 @@ Table *ApplicationWindow::newTable(const QString &caption, int r, int c, if (lst.count() == 2) legend = lst[1]; - Table *w = new Table(scriptingEnv(), r, c, legend, this, 0); + Table *w = new Table(scriptingEnv(), r, c, legend, this, nullptr); QStringList rows = text.split("\n", QString::SkipEmptyParts); QString rlist = rows[0]; @@ -3117,7 +3117,7 @@ Table *ApplicationWindow::newTable(const QString &caption, int r, int c, Table *ApplicationWindow::newHiddenTable(const QString &name, const QString &label, int r, int c, const QString &text) { - Table *w = new Table(scriptingEnv(), r, c, label, this, 0); + Table *w = new Table(scriptingEnv(), r, c, label, this, nullptr); if (!text.isEmpty()) { QStringList rows = text.split("\n", QString::SkipEmptyParts); @@ -3194,14 +3194,14 @@ Note *ApplicationWindow::newNote(const QString &caption) { } Matrix *ApplicationWindow::newMatrix(int rows, int columns) { - Matrix *m = new Matrix(scriptingEnv(), rows, columns, "", this, 0); + Matrix *m = new Matrix(scriptingEnv(), rows, columns, "", this, nullptr); initMatrix(m, generateUniqueName(tr("Matrix"))); m->showNormal(); return m; } Matrix *ApplicationWindow::newMatrix(const QString &caption, int r, int c) { - Matrix *w = new Matrix(scriptingEnv(), r, c, "", this, 0); + Matrix *w = new Matrix(scriptingEnv(), r, c, "", this, nullptr); initMatrix(w, caption); if (w->objectName() != caption) // the matrix was renamed renamedTables << caption << w->objectName(); @@ -3397,14 +3397,14 @@ ApplicationWindow::matrixToTable(Matrix *m, Table *w = nullptr; if (conversionType == Direct) { - w = new Table(scriptingEnv(), rows, cols, "", this, 0); + w = new Table(scriptingEnv(), rows, cols, "", this, nullptr); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) w->setCell(i, j, m->cell(i, j)); } } else if (conversionType == XYZ) { int tableRows = rows * cols; - w = new Table(scriptingEnv(), tableRows, 3, "", this, 0); + w = new Table(scriptingEnv(), tableRows, 3, "", this, nullptr); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { int cell = i * cols + j; @@ -3415,7 +3415,7 @@ ApplicationWindow::matrixToTable(Matrix *m, } } else if (conversionType == YXZ) { int tableRows = rows * cols; - w = new Table(scriptingEnv(), tableRows, 3, "", this, 0); + w = new Table(scriptingEnv(), tableRows, 3, "", this, nullptr); for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { int cell = i * rows + j; @@ -3600,7 +3600,7 @@ Matrix *ApplicationWindow::tableToMatrix(Table *t) { int cols = t->numCols(); QString caption = generateUniqueName(tr("Matrix")); - Matrix *m = new Matrix(scriptingEnv(), rows, cols, "", this, 0); + Matrix *m = new Matrix(scriptingEnv(), rows, cols, "", this, nullptr); initMatrix(m, caption); for (int i = 0; i < rows; i++) { @@ -5701,7 +5701,7 @@ void ApplicationWindow::exportGraph() { return; ImageExportDialog *ied = - new ImageExportDialog(this, plot2D != NULL, d_extended_export_dialog); + new ImageExportDialog(this, plot2D != nullptr, d_extended_export_dialog); ied->setDirectory(workingDir); ied->selectFilter(d_image_export_filter); if (ied->exec() != QDialog::Accepted) @@ -5764,7 +5764,7 @@ void ApplicationWindow::exportLayer() { return; ImageExportDialog *ied = - new ImageExportDialog(this, g != NULL, d_extended_export_dialog); + new ImageExportDialog(this, g != nullptr, d_extended_export_dialog); ied->setDirectory(workingDir); ied->selectFilter(d_image_export_filter); if (ied->exec() != QDialog::Accepted) @@ -5837,7 +5837,7 @@ void ApplicationWindow::exportAllGraphs() { foreach (MdiSubWindow *w, windows) { const std::string windowClassName = w->metaObject()->className(); if (windowClassName == "MultiLayer") { - plot3D = 0; + plot3D = nullptr; plot2D = dynamic_cast(w); if (!plot2D) continue; @@ -5851,7 +5851,7 @@ void ApplicationWindow::exportAllGraphs() { continue; } } else if (windowClassName == "Graph3D") { - plot2D = 0; + plot2D = nullptr; plot3D = dynamic_cast(w); if (!plot3D) continue; @@ -6137,7 +6137,7 @@ void ApplicationWindow::savetoNexusFile() { void ApplicationWindow::loadDataFile() { // Ask user for file QString fn = QFileDialog::getOpenFileName( - 0, tr("Mantidplot - Open file to load"), + nullptr, tr("Mantidplot - Open file to load"), AlgorithmInputHistory::Instance().getPreviousDirectory()); if (fn != "") { loadDataFileByName(fn); @@ -6438,7 +6438,7 @@ void ApplicationWindow::showTitleDialog() { Graph *g = ml->activeGraph(); if (g) { - TextDialog *td = new TextDialog(TextDialog::LayerTitle, this, 0); + TextDialog *td = new TextDialog(TextDialog::LayerTitle, this, nullptr); td->setGraph(g); td->exec(); } @@ -6462,7 +6462,7 @@ void ApplicationWindow::showAxisTitleDialog() { if (!g) return; - TextDialog *td = new TextDialog(TextDialog::AxisTitle, this, 0); + TextDialog *td = new TextDialog(TextDialog::AxisTitle, this, nullptr); td->setGraph(g); td->exec(); } @@ -7606,7 +7606,7 @@ void ApplicationWindow::removePoints() { this, tr("MantidPlot"), // Mantid tr("This will modify the data in the worksheets!\nAre you sure you " "want to continue?"), - tr("Continue"), tr("Cancel"), 0, 1)) { + tr("Continue"), tr("Cancel"), nullptr, 1)) { case 0: g->setActiveTool(new DataPickerTool(g, this, DataPickerTool::Remove, info, SLOT(setText(const QString &)))); @@ -7651,7 +7651,7 @@ void ApplicationWindow::movePoints() { this, tr("MantidPlot"), // Mantid tr("This will modify the data in the worksheets!\nAre you sure you " "want to continue?"), - tr("Continue"), tr("Cancel"), 0, 1)) { + tr("Continue"), tr("Cancel"), nullptr, 1)) { case 0: if (g) { g->setActiveTool(new DataPickerTool(g, this, DataPickerTool::Move, info, @@ -8345,7 +8345,7 @@ void ApplicationWindow::showTextDialog() { if (!l) return; - TextDialog *td = new TextDialog(TextDialog::TextMarker, this, 0); + TextDialog *td = new TextDialog(TextDialog::TextMarker, this, nullptr); td->setLegendWidget(l); td->exec(); } @@ -10467,7 +10467,7 @@ void ApplicationWindow::chooseHelpFolder() { QFileInfo hfi(helpFilePath); QString dir = QFileDialog::getExistingDirectory( this, tr("Choose the location of the MantidPlot help folder!"), - hfi.dir().absolutePath(), 0 /**QFileDialog::ShowDirsOnly*/); + hfi.dir().absolutePath(), nullptr /**QFileDialog::ShowDirsOnly*/); if (!dir.isEmpty()) { helpFilePath = dir + "index.html"; @@ -10522,7 +10522,7 @@ void ApplicationWindow::showHelp() { void ApplicationWindow::showPlotWizard() { QStringList lst = tableNames(); if (lst.count() > 0) { - PlotWizard *pw = new PlotWizard(this, 0); + PlotWizard *pw = new PlotWizard(this, nullptr); pw->setAttribute(Qt::WA_DeleteOnClose); connect(pw, SIGNAL(plot(const QStringList &)), this, SLOT(multilayerPlot(const QStringList &))); @@ -13366,7 +13366,7 @@ Graph3D *ApplicationWindow::openMatrixPlot3D(const QString &caption, if (!m) return nullptr; - Graph3D *plot = new Graph3D("", this, 0, 0); + Graph3D *plot = new Graph3D("", this, nullptr, nullptr); plot->setWindowTitle(caption); plot->setName(caption); plot->addMatrixData(m, xl, xr, yl, yr, zl, zr); @@ -13390,7 +13390,7 @@ Graph3D *ApplicationWindow::plot3DMatrix(Matrix *m, int style) { QApplication::setOverrideCursor(Qt::WaitCursor); QString label = generateUniqueName(tr("Graph")); - Graph3D *plot = new Graph3D("", this, 0); + Graph3D *plot = new Graph3D("", this, nullptr); plot->addMatrixData(m); plot->customPlotStyle(style); customPlot3D(plot); @@ -14409,7 +14409,7 @@ bool ApplicationWindow::deleteFolder(Folder *f) { this, tr("MantidPlot - Delete folder?"), // Mantid tr("Delete folder '%1' and all the windows it contains?") .arg(f->objectName()), - tr("Yes"), tr("No"), 0, 0)) + tr("Yes"), tr("No"), nullptr, 0)) return false; else { Folder *parent = projectFolder(); @@ -14858,7 +14858,7 @@ void ApplicationWindow::showScriptWindow(bool forceVisible, bool quitting) { // it doesn't respect the always on top // flag, it is treated as a sub window of its parent const bool capturePrint = !quitting; - scriptingWindow = new ScriptingWindow(scriptingEnv(), capturePrint, NULL); + scriptingWindow = new ScriptingWindow(scriptingEnv(), capturePrint, nullptr); scriptingWindow->setObjectName("ScriptingWindow"); scriptingWindow->setAttribute(Qt::WA_DeleteOnClose, false); connect(scriptingWindow, SIGNAL(closeMe()), this, diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp index c674a20ae33c..447d0f7d273a 100644 --- a/MantidPlot/src/ConfigDialog.cpp +++ b/MantidPlot/src/ConfigDialog.cpp @@ -3105,7 +3105,7 @@ void ConfigDialog::chooseTranslationsFolder() { QFileInfo tfi(app->d_translations_folder); QString dir = QFileDialog::getExistingDirectory( this, tr("Choose the location of the MantidPlot translations folder!"), - tfi.dir().absolutePath(), 0 /**QFileDialog::ShowDirsOnly*/); + tfi.dir().absolutePath(), nullptr /**QFileDialog::ShowDirsOnly*/); if (!dir.isEmpty()) { app->d_translations_folder = dir; @@ -3130,7 +3130,7 @@ void ConfigDialog::chooseHelpFolder() { void ConfigDialog::addPythonScriptsDirs() { QString dir = QFileDialog::getExistingDirectory( this, tr("Add a python scripts directory"), "", - 0 /**QFileDialog::ShowDirsOnly*/); + nullptr /**QFileDialog::ShowDirsOnly*/); if (!dir.isEmpty()) { QString dirs = lePythonScriptsDirs->text(); if (!dirs.isEmpty()) { @@ -3144,7 +3144,7 @@ void ConfigDialog::addPythonScriptsDirs() { void ConfigDialog::addPythonPluginDirs() { QString dir = QFileDialog::getExistingDirectory( this, tr("Add a python extension directory"), "", - 0 /**QFileDialog::ShowDirsOnly*/); + nullptr /**QFileDialog::ShowDirsOnly*/); if (!dir.isEmpty()) { QString dirs = lePythonPluginsDirs->text(); if (!dirs.isEmpty()) { @@ -3157,7 +3157,7 @@ void ConfigDialog::addPythonPluginDirs() { void ConfigDialog::addInstrumentDir() { QString dir = QFileDialog::getExistingDirectory( - this, tr("Select new instrument definition directory"), "", 0); + this, tr("Select new instrument definition directory"), "", nullptr); if (!dir.isEmpty()) { leInstrumentDir->setText(dir); } diff --git a/MantidPlot/src/Graph.cpp b/MantidPlot/src/Graph.cpp index 3fd93f5639af..a19870e6eeb2 100644 --- a/MantidPlot/src/Graph.cpp +++ b/MantidPlot/src/Graph.cpp @@ -3094,7 +3094,7 @@ void Graph::removePie() { QList labels = pieCurve->labelsList(); foreach (PieLabel *l, labels) - l->setPieCurve(0); + l->setPieCurve(nullptr); d_plot->removeCurve(c_keys[0]); d_plot->replot(); diff --git a/MantidPlot/src/Graph3D.cpp b/MantidPlot/src/Graph3D.cpp index 7ca8869de627..7362252c2e05 100644 --- a/MantidPlot/src/Graph3D.cpp +++ b/MantidPlot/src/Graph3D.cpp @@ -2497,7 +2497,7 @@ MantidQt::API::IProjectSerialisable * Graph3D::loadFromProject(const std::string &lines, ApplicationWindow *app, const int fileVersion) { Q_UNUSED(fileVersion); - auto graph = new Graph3D("", app, "", 0); + auto graph = new Graph3D("", app, "", nullptr); std::vector lineVec, valVec; boost::split(lineVec, lines, boost::is_any_of("\n")); diff --git a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp index 0c0e61b2bae4..07137f9e90df 100644 --- a/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp +++ b/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindow.cpp @@ -23,7 +23,7 @@ using namespace MantidQt::MantidWidgets; InstrumentWindow::InstrumentWindow(const QString &wsName, const QString &label, ApplicationWindow *parent, const QString &name) - : MdiSubWindow(parent, label, name, 0) { + : MdiSubWindow(parent, label, name, nullptr) { m_instrumentWidget = new InstrumentWidget(wsName, this); this->setWidget(m_instrumentWidget); diff --git a/MantidPlot/src/Mantid/MantidMatrix.cpp b/MantidPlot/src/Mantid/MantidMatrix.cpp index 76e3aedee0c5..1f6b1b3269bf 100644 --- a/MantidPlot/src/Mantid/MantidMatrix.cpp +++ b/MantidPlot/src/Mantid/MantidMatrix.cpp @@ -210,7 +210,7 @@ void MantidMatrix::viewChanged(int index) { void MantidMatrix::setup(Mantid::API::MatrixWorkspace_const_sptr ws, int start, int end) { if (!ws) { - QMessageBox::critical(0, "WorkspaceMatrixModel error", + QMessageBox::critical(nullptr, "WorkspaceMatrixModel error", "2D workspace expected."); m_rows = 0; m_cols = 0; @@ -468,7 +468,7 @@ void MantidMatrix::setRange(double min, double max) { double **MantidMatrix::allocateMatrixData(int rows, int columns) { double **data = (double **)malloc(rows * sizeof(double *)); if (!data) { - QMessageBox::critical(0, tr("MantidPlot") + " - " + + QMessageBox::critical(nullptr, tr("MantidPlot") + " - " + tr("Memory Allocation Error"), tr("Not enough memory, operation aborted!")); return nullptr; @@ -481,7 +481,7 @@ double **MantidMatrix::allocateMatrixData(int rows, int columns) { free(data[j]); free(data); - QMessageBox::critical(0, tr("MantidPlot") + " - " + + QMessageBox::critical(nullptr, tr("MantidPlot") + " - " + tr("Memory Allocation Error"), tr("Not enough memory, operation aborted!")); return nullptr; @@ -736,7 +736,7 @@ void MantidMatrix::attachMultilayer(MultiLayer *ml) { */ MultiLayer *MantidMatrix::plotGraph2D(GraphOptions::CurveType type) { if (numRows() == 1) { - QMessageBox::critical(0, "MantidPlot - Error", + QMessageBox::critical(nullptr, "MantidPlot - Error", "Cannot plot a workspace with only one spectrum."); return nullptr; } diff --git a/MantidPlot/src/Mantid/MantidTable.cpp b/MantidPlot/src/Mantid/MantidTable.cpp index 295b08302052..a9a58a128d50 100644 --- a/MantidPlot/src/Mantid/MantidTable.cpp +++ b/MantidPlot/src/Mantid/MantidTable.cpp @@ -35,7 +35,7 @@ MantidTable::MantidTable(ScriptingEnv *env, : static_cast(ws->rowCount()), transpose ? static_cast(ws->rowCount() + 1) : static_cast(ws->columnCount()), - label, parent, "", 0), + label, parent, "", nullptr), m_ws(ws), m_wsName(ws->getName()), m_transposed(transpose) { d_table->blockResizing(true); diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index 48bc194af55f..b11acec78bc4 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -213,9 +213,9 @@ MantidUI::MantidUI(ApplicationWindow *aw) : m_finishedLoadDAEObserver(*this, &MantidUI::handleLoadDAEFinishedNotification), m_configServiceObserver(*this, &MantidUI::handleConfigServiceUpdate), - m_appWindow(aw), m_lastShownInstrumentWin(NULL), - m_lastShownSliceViewWin(NULL), m_lastShownSpectrumViewerWin(NULL), - m_lastShownColorFillWin(NULL), m_lastShown1DPlotWin(NULL), + m_appWindow(aw), m_lastShownInstrumentWin(nullptr), + m_lastShownSliceViewWin(nullptr), m_lastShownSpectrumViewerWin(nullptr), + m_lastShownColorFillWin(nullptr), m_lastShown1DPlotWin(nullptr), m_vatesSubWindow(nullptr) //, m_spectrumViewWindow(NULL) { @@ -925,7 +925,7 @@ void MantidUI::showSpectrumViewer() { try { viewer = new MantidQt::SpectrumView::SpectrumView(m_appWindow); } catch (std::runtime_error &e) { - m_lastShownSpectrumViewerWin = NULL; + m_lastShownSpectrumViewerWin = nullptr; g_log.error() << "Could not create spectrum viewer: " << e.what() << "\n"; throw std::runtime_error(e); @@ -981,7 +981,7 @@ void MantidUI::showSliceViewer() { w = MantidQt::Factory::WidgetFactory::Instance()->createSliceViewerWindow( wsName, ""); } catch (std::runtime_error &e) { - m_lastShownSliceViewWin = NULL; + m_lastShownSliceViewWin = nullptr; g_log.error() << "Could not create slice viewer: " << e.what() << "\n"; throw std::runtime_error(e); } @@ -1025,7 +1025,7 @@ Show Algorithm History Details in a window . void MantidUI::showAlgorithmHistory() { QString wsName = getSelectedWorkspaceName(); Mantid::API::Workspace_const_sptr wsptr = getWorkspace(wsName); - if (NULL != wsptr) { + if (nullptr != wsptr) { // If the workspace has any AlgorithHistory ... if (!wsptr->getHistory().empty()) { // ... create and display the window. @@ -1315,7 +1315,7 @@ Table *MantidUI::createDetectorTable( ? static_cast(ws->getNumberHistograms()) : static_cast(indices.size()); Table *t = - new Table(appWindow()->scriptingEnv(), nrows, ncols, "", appWindow(), 0); + new Table(appWindow()->scriptingEnv(), nrows, ncols, "", appWindow(), nullptr); appWindow()->initTable( t, appWindow()->generateUniqueName(wsName + "-Detectors-")); // Set the column names @@ -2140,7 +2140,7 @@ void MantidUI::showMantidInstrument(const QString &wsName) { InstrumentWindow *insWin = getInstrumentView(wsName); if (!insWin) { - m_lastShownInstrumentWin = NULL; + m_lastShownInstrumentWin = nullptr; return; } @@ -2221,7 +2221,7 @@ void MantidUI::saveProject(bool saved) { QString savemsg = tr("Save changes to project:

      %1 ?").arg("untitled"); int result = QMessageBox::information(appWindow(), tr("MantidPlot"), - savemsg, tr("Yes"), tr("No"), 0, 2); + savemsg, tr("Yes"), tr("No"), nullptr, 2); if (result == 0) appWindow()->saveProject(); } @@ -2405,7 +2405,7 @@ void MantidUI::importString(const QString &logName, const QString &data, } Table *t = new Table(appWindow()->scriptingEnv(), loglines.size(), 1, "", - appWindow(), 0); + appWindow(), nullptr); if (!t) return; // Have to replace "_" since the legend widget uses them to separate things @@ -2442,7 +2442,7 @@ void MantidUI::importStrSeriesLog(const QString &logName, const QString &data, int rowcount(loglines.count()); Table *t = - new Table(appWindow()->scriptingEnv(), rowcount, 2, "", appWindow(), 0); + new Table(appWindow()->scriptingEnv(), rowcount, 2, "", appWindow(), nullptr); if (!t) return; QString label; @@ -2541,7 +2541,7 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName, int colCount = 2; Table *t = new Table(appWindow()->scriptingEnv(), rowcount, colCount, "", - appWindow(), 0); + appWindow(), nullptr); if (!t) return; // Have to replace "_" since the legend widget uses them to separate things @@ -2857,7 +2857,7 @@ Table *MantidUI::createTableFromSpectraList(const QString &tableName, bool isHistogram = workspace->isHistogramData(); int no_cols = static_cast(indexList.size()); Table *t = new Table(appWindow()->scriptingEnv(), numRows, (1 + c) * no_cols, - "", appWindow(), 0); + "", appWindow(), nullptr); appWindow()->initTable(t, appWindow()->generateUniqueName(tableName + "-")); // t->askOnCloseEvent(false); @@ -3127,7 +3127,7 @@ MultiLayer *MantidUI::plot1D(const QMultiMap &toPlot, return nullptr; } // Force waterfall option to false if only 1 curve - if ((NULL == plotWindow || clearWindow) && toPlot.size() == 1) + if ((nullptr == plotWindow || clearWindow) && toPlot.size() == 1) waterfallPlot = false; ScopedOverrideCursor waitCursor; @@ -3325,7 +3325,7 @@ void MantidUI::drawColorFillPlots(const QStringList &wsNames, cit != wsNames.end(); ++cit) { const bool hidden = true; MultiLayer *plot = - this->drawSingleColorFillPlot(*cit, curveType, NULL, hidden); + this->drawSingleColorFillPlot(*cit, curveType, nullptr, hidden); if (plot) plots.append(plot); } @@ -3391,7 +3391,7 @@ MultiLayer *MantidUI::drawSingleColorFillPlot(const QString &wsName, ScopedOverrideCursor waitCursor; bool reusePlots = workspacesDockPlot1To1(); - if ((!reusePlots && NULL == window) || + if ((!reusePlots && nullptr == window) || (reusePlots && !m_lastShownColorFillWin)) // needs to create a new window { try { @@ -3401,7 +3401,7 @@ MultiLayer *MantidUI::drawSingleColorFillPlot(const QString &wsName, window->hide(); } } catch (std::runtime_error &e) { - m_lastShownColorFillWin = NULL; + m_lastShownColorFillWin = nullptr; g_log.error() << "Could not create color fill plot: " << e.what() << "\n"; throw std::runtime_error(e); } @@ -3409,7 +3409,7 @@ MultiLayer *MantidUI::drawSingleColorFillPlot(const QString &wsName, m_lastShownColorFillWin = window; } else { if (nullptr == window) { - if (NULL == m_lastShownColorFillWin) + if (nullptr == m_lastShownColorFillWin) return nullptr; window = m_lastShownColorFillWin; } @@ -3736,7 +3736,7 @@ Table *MantidUI::createTableFromBins( return nullptr; Table *t = new Table(appWindow()->scriptingEnv(), numRows, - c * bins.size() + 1, "", appWindow(), 0); + c * bins.size() + 1, "", appWindow(), nullptr); appWindow()->initTable(t, appWindow()->generateUniqueName(wsName + "-")); for (int i = 0; i < bins.size(); i++) { diff --git a/MantidPlot/src/PythonScript.cpp b/MantidPlot/src/PythonScript.cpp index 9c74de4d8d2e..09d6074ccf51 100644 --- a/MantidPlot/src/PythonScript.cpp +++ b/MantidPlot/src/PythonScript.cpp @@ -556,7 +556,7 @@ QVariant PythonScript::evaluateImpl() { if (pystring) { PyObject *asUTF8 = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(pystring), - (int)PyUnicode_GET_DATA_SIZE(pystring), NULL); + (int)PyUnicode_GET_DATA_SIZE(pystring), nullptr); Py_DECREF(pystring); if (asUTF8) { qret = QVariant(QString::fromUtf8(PyString_AS_STRING(asUTF8))); diff --git a/MantidPlot/src/TiledWindow.cpp b/MantidPlot/src/TiledWindow.cpp index 58d522c6f5b2..f7ff58ad82a8 100644 --- a/MantidPlot/src/TiledWindow.cpp +++ b/MantidPlot/src/TiledWindow.cpp @@ -911,7 +911,7 @@ void TiledWindow::selectRange(int row1, int col1, int row2, int col2) { void TiledWindow::removeSelectionTo(TiledWindow::RemoveDestination to) { foreach (Tile *tile, m_selection) { MdiSubWindow *widget = removeTile(tile); - if (widget == NULL) { + if (widget == nullptr) { throw std::logic_error("TiledWindow: Empty tile is found in slection."); } sendWidgetTo(widget, to); diff --git a/MantidPlot/src/importOPJ.cpp b/MantidPlot/src/importOPJ.cpp index a041ae55b1d5..5d52f260a3e4 100644 --- a/MantidPlot/src/importOPJ.cpp +++ b/MantidPlot/src/importOPJ.cpp @@ -1175,7 +1175,7 @@ bool ImportOPJ::importGraphs(const OPJFile &opj) { vector texts = opj.layerTexts(g, l); if (style != GraphOptions::Pie) { for (size_t i = 0; i < texts.size(); ++i) { - addText(texts[i], graph, 0, layerRect, fFontScaleFactor, fXScale, + addText(texts[i], graph, nullptr, layerRect, fFontScaleFactor, fXScale, fYScale); } } diff --git a/MantidPlot/src/origin/tree.hh b/MantidPlot/src/origin/tree.hh index bd6a2576a4a0..c036254fb881 100644 --- a/MantidPlot/src/origin/tree.hh +++ b/MantidPlot/src/origin/tree.hh @@ -713,7 +713,7 @@ typename tree::fixed_depth_iterator tree typename tree::sibling_iterator tree::begin(const iterator_base& pos) const { - assert(pos.node!=0); + assert(pos.node!=nullptr); if(pos.node->first_child==nullptr) { return end(pos); } @@ -764,7 +764,7 @@ template template iter tree::parent(iter position) { - assert(position.node!=0); + assert(position.node!=nullptr); return iter(position.node->parent); } @@ -1667,7 +1667,7 @@ template int tree::depth(const iterator_base& it) { tree_node* pos=it.node; - assert(pos!=0); + assert(pos!=nullptr); int ret=0; while(pos->parent!=nullptr) { pos=pos->parent; @@ -2119,7 +2119,7 @@ tree::pre_order_iterator::pre_order_iterator(const sibli template typename tree::pre_order_iterator& tree::pre_order_iterator::operator++() { - assert(this->node!=0); + assert(this->node!=nullptr); if(!this->skip_current_children_ && this->node->first_child != nullptr) { this->node=this->node->first_child; } From 8766b27bad7a546e3eb6316331bec1ea536b6b1c Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 13:32:19 +0000 Subject: [PATCH 355/364] Re #22169: Applied clang-format patch. --- MantidPlot/src/ApplicationWindow.cpp | 3 ++- MantidPlot/src/Mantid/MantidMatrix.cpp | 4 ++-- MantidPlot/src/Mantid/MantidUI.cpp | 13 +++++++------ MantidPlot/src/importOPJ.cpp | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp index 953aac0e9b3d..62178973d755 100644 --- a/MantidPlot/src/ApplicationWindow.cpp +++ b/MantidPlot/src/ApplicationWindow.cpp @@ -14858,7 +14858,8 @@ void ApplicationWindow::showScriptWindow(bool forceVisible, bool quitting) { // it doesn't respect the always on top // flag, it is treated as a sub window of its parent const bool capturePrint = !quitting; - scriptingWindow = new ScriptingWindow(scriptingEnv(), capturePrint, nullptr); + scriptingWindow = + new ScriptingWindow(scriptingEnv(), capturePrint, nullptr); scriptingWindow->setObjectName("ScriptingWindow"); scriptingWindow->setAttribute(Qt::WA_DeleteOnClose, false); connect(scriptingWindow, SIGNAL(closeMe()), this, diff --git a/MantidPlot/src/Mantid/MantidMatrix.cpp b/MantidPlot/src/Mantid/MantidMatrix.cpp index 1f6b1b3269bf..bdd87147b94c 100644 --- a/MantidPlot/src/Mantid/MantidMatrix.cpp +++ b/MantidPlot/src/Mantid/MantidMatrix.cpp @@ -469,7 +469,7 @@ double **MantidMatrix::allocateMatrixData(int rows, int columns) { double **data = (double **)malloc(rows * sizeof(double *)); if (!data) { QMessageBox::critical(nullptr, tr("MantidPlot") + " - " + - tr("Memory Allocation Error"), + tr("Memory Allocation Error"), tr("Not enough memory, operation aborted!")); return nullptr; } @@ -482,7 +482,7 @@ double **MantidMatrix::allocateMatrixData(int rows, int columns) { free(data); QMessageBox::critical(nullptr, tr("MantidPlot") + " - " + - tr("Memory Allocation Error"), + tr("Memory Allocation Error"), tr("Not enough memory, operation aborted!")); return nullptr; } diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp index b11acec78bc4..a67ed40590ca 100644 --- a/MantidPlot/src/Mantid/MantidUI.cpp +++ b/MantidPlot/src/Mantid/MantidUI.cpp @@ -1314,8 +1314,8 @@ Table *MantidUI::createDetectorTable( const int nrows = indices.empty() ? static_cast(ws->getNumberHistograms()) : static_cast(indices.size()); - Table *t = - new Table(appWindow()->scriptingEnv(), nrows, ncols, "", appWindow(), nullptr); + Table *t = new Table(appWindow()->scriptingEnv(), nrows, ncols, "", + appWindow(), nullptr); appWindow()->initTable( t, appWindow()->generateUniqueName(wsName + "-Detectors-")); // Set the column names @@ -2220,8 +2220,9 @@ void MantidUI::saveProject(bool saved) { if (!saved) { QString savemsg = tr("Save changes to project:

      %1 ?").arg("untitled"); - int result = QMessageBox::information(appWindow(), tr("MantidPlot"), - savemsg, tr("Yes"), tr("No"), nullptr, 2); + int result = + QMessageBox::information(appWindow(), tr("MantidPlot"), savemsg, + tr("Yes"), tr("No"), nullptr, 2); if (result == 0) appWindow()->saveProject(); } @@ -2441,8 +2442,8 @@ void MantidUI::importStrSeriesLog(const QString &logName, const QString &data, QStringList loglines = data.split("\n", QString::SkipEmptyParts); int rowcount(loglines.count()); - Table *t = - new Table(appWindow()->scriptingEnv(), rowcount, 2, "", appWindow(), nullptr); + Table *t = new Table(appWindow()->scriptingEnv(), rowcount, 2, "", + appWindow(), nullptr); if (!t) return; QString label; diff --git a/MantidPlot/src/importOPJ.cpp b/MantidPlot/src/importOPJ.cpp index 5d52f260a3e4..154f2225bde3 100644 --- a/MantidPlot/src/importOPJ.cpp +++ b/MantidPlot/src/importOPJ.cpp @@ -1175,8 +1175,8 @@ bool ImportOPJ::importGraphs(const OPJFile &opj) { vector texts = opj.layerTexts(g, l); if (style != GraphOptions::Pie) { for (size_t i = 0; i < texts.size(); ++i) { - addText(texts[i], graph, nullptr, layerRect, fFontScaleFactor, fXScale, - fYScale); + addText(texts[i], graph, nullptr, layerRect, fFontScaleFactor, + fXScale, fYScale); } } From 5660cccef2ef460a4b84d225d0c47a109a952671 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Thu, 22 Mar 2018 13:34:02 +0000 Subject: [PATCH 356/364] Re #22169: Applied clang-format patch. --- .../MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h | 3 ++- qt/widgets/common/src/PropertyHandler.cpp | 6 +++--- .../common/src/QtPropertyBrowser/qtpropertybrowser.cpp | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h index 84cf745ca62d..d0604dda6fb7 100644 --- a/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h +++ b/qt/widgets/common/inc/MantidQtWidgets/Common/DataProcessorUI/GridDelegate.h @@ -7,7 +7,8 @@ namespace DataProcessor { class GridDelegate : public QStyledItemDelegate { public: - explicit GridDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent){}; + explicit GridDelegate(QObject *parent = nullptr) + : QStyledItemDelegate(parent){}; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { diff --git a/qt/widgets/common/src/PropertyHandler.cpp b/qt/widgets/common/src/PropertyHandler.cpp index a764fccacca1..140e87261fea 100644 --- a/qt/widgets/common/src/PropertyHandler.cpp +++ b/qt/widgets/common/src/PropertyHandler.cpp @@ -927,9 +927,9 @@ Mantid::API::IFunction_sptr PropertyHandler::changeType(QtProperty *prop) { f = Mantid::API::FunctionFactory::Instance().createFunction( fnName.toStdString()); } catch (std::exception &e) { - QMessageBox::critical(nullptr, "Mantid - Error", "Cannot create function " + - fnName + "\n" + - e.what()); + QMessageBox::critical(nullptr, "Mantid - Error", + "Cannot create function " + fnName + "\n" + + e.what()); return Mantid::API::IFunction_sptr(); } diff --git a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp index 36466030b972..0f3a89640150 100644 --- a/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp +++ b/qt/widgets/common/src/QtPropertyBrowser/qtpropertybrowser.cpp @@ -1819,7 +1819,8 @@ void QtAbstractPropertyBrowser::removeProperty(QtProperty *property) { if (pendingList.at(pos) == property) { d_ptr->m_subItems.removeAt(pos); // perhaps this two lines d_ptr->removeSubTree( - property, nullptr); // should be moved down after propertyRemoved call. + property, + nullptr); // should be moved down after propertyRemoved call. // propertyRemoved(property, 0); d_ptr->removeBrowserIndexes(property, nullptr); From 1938a66a5a1167c87e1389e3c989d0c595992952 Mon Sep 17 00:00:00 2001 From: Anthony Lim Date: Thu, 22 Mar 2018 15:39:43 +0000 Subject: [PATCH 357/364] refs #22167 muon analysis GUI min sizes --- qt/scientific_interfaces/Muon/MuonAnalysis.ui | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.ui b/qt/scientific_interfaces/Muon/MuonAnalysis.ui index 3b593c28acc7..f30a73774896 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.ui +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.ui @@ -2389,6 +2389,12 @@ p, li { white-space: pre-wrap; } + + + 20 + 30 + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> @@ -2407,7 +2413,14 @@ p, li { white-space: pre-wrap; } - + + + + 10 + 10 + + + @@ -2433,6 +2446,12 @@ p, li { white-space: pre-wrap; } 0 + + + 10 + 10 + + 30 From 2125f0cac9a603c648a9d69a490459fe3861d9d7 Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Thu, 22 Mar 2018 15:58:08 +0000 Subject: [PATCH 358/364] Refs #22167 changed muon analysis ui --- qt/scientific_interfaces/Muon/MuonAnalysis.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.ui b/qt/scientific_interfaces/Muon/MuonAnalysis.ui index f30a73774896..e92e8f0134b0 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.ui +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.ui @@ -51,7 +51,7 @@ - 0 + 4 @@ -2260,7 +2260,7 @@ p, li { white-space: pre-wrap; } 0 - 100 + 140 @@ -2660,8 +2660,8 @@ p, li { white-space: pre-wrap; } 0 0 - 131 - 23 + 165 + 26 From 2e83565403de23c017a40aba52e511d7f86a3a20 Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Fri, 23 Mar 2018 08:52:14 +0000 Subject: [PATCH 359/364] Refs #22167 fixed muon gui --- qt/scientific_interfaces/Muon/MuonAnalysis.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/scientific_interfaces/Muon/MuonAnalysis.ui b/qt/scientific_interfaces/Muon/MuonAnalysis.ui index e92e8f0134b0..ee5436983dc3 100644 --- a/qt/scientific_interfaces/Muon/MuonAnalysis.ui +++ b/qt/scientific_interfaces/Muon/MuonAnalysis.ui @@ -51,7 +51,7 @@ - 4 + 0 From e2fe31bfee08567891ddcda6761f8fe5d5dc70ba Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Fri, 23 Mar 2018 09:10:35 +0000 Subject: [PATCH 360/364] Refs #0 Fixed categories to remove Python algorithm --- Framework/PythonInterface/plugins/algorithms/LoadEXED.py | 2 +- .../algorithms/WorkflowAlgorithms/IndirectSampleChanger.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/PythonInterface/plugins/algorithms/LoadEXED.py b/Framework/PythonInterface/plugins/algorithms/LoadEXED.py index cc32a7e6cbb7..8821f9ce1f9c 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadEXED.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadEXED.py @@ -24,7 +24,7 @@ class LoadEXED(PythonAlgorithm): """ def category(self): - return "Inelastic;Diffraction;PythonAlgorithms" + return "Inelastic;Diffraction" def name(self): return "LoadEXED" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py index aee47be349af..e7fbf7bd1527 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectSampleChanger.py @@ -16,7 +16,7 @@ class IndirectSampleChanger(DataProcessorAlgorithm): _q1_workspaces = None def category(self): - return "Workflow\\MIDAS;PythonAlgorithms" + return "Workflow\\MIDAS" def summary(self): return "Create elastic window scans for sample changer" From 3a2961e59f2263900532b05dd6a254d32a41014c Mon Sep 17 00:00:00 2001 From: Keith Butler Date: Fri, 23 Mar 2018 09:49:38 +0000 Subject: [PATCH 361/364] Updating Muon release notes with fix for #22167. --- docs/source/release/v3.12.0/muon.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/release/v3.12.0/muon.rst b/docs/source/release/v3.12.0/muon.rst index 45740fd7982b..bb310b1277b2 100644 --- a/docs/source/release/v3.12.0/muon.rst +++ b/docs/source/release/v3.12.0/muon.rst @@ -38,6 +38,7 @@ Bug fixes ######### - Log values are no longer filtered by start time when loaded into muon analysis. +- Different options under `Settings`>`Data Binning` give different options for input (OSX bug, see Issue ##22167). Fixed in patch. Algorithms ---------- From 2fd26f9b421afed5ef62bd15c46f1075842e9a2b Mon Sep 17 00:00:00 2001 From: Antti Soininen Date: Fri, 23 Mar 2018 16:55:08 +0100 Subject: [PATCH 362/364] directtools: fix a typo in sphinx documentation. Re #21901 --- docs/source/techniques/DirecttoolsPythonModule.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/techniques/DirecttoolsPythonModule.rst b/docs/source/techniques/DirecttoolsPythonModule.rst index 70dd3e6fab3c..0f78bf1aea74 100644 --- a/docs/source/techniques/DirecttoolsPythonModule.rst +++ b/docs/source/techniques/DirecttoolsPythonModule.rst @@ -78,7 +78,7 @@ Any of the workspace, cut centre or cut width arguments can be a :class:`list` i fig, axes, cuts = dt.plotconstQ('SofQW', [Q1, Q2], dQ) #fig.show() -The :func:`directtools.plotconstQ` and :func:`directtools.plotconstE` functions use :func:`directtool.plotcuts` to do the actual line profiles and plotting. The profiles are made by the :ref:`algm-LineProfile` algorithm, and all three plotting functions return a list of the produced line profile workspace names. +The :func:`directtools.plotconstQ` and :func:`directtools.plotconstE` functions use :func:`directtools.plotcuts` to do the actual line profiles and plotting. The profiles are made by the :ref:`algm-LineProfile` algorithm, and all three plotting functions return a list of the produced line profile workspace names. If a line profile already exists, it can be plotted using :func:`directtools.plotprofiles`. This also accepts either a single line profile workspace or a list of workspaces enabling comparison: From 292a18bc46c4eadaf291b8947a95abb32d0c3093 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 26 Mar 2018 09:24:03 +0100 Subject: [PATCH 363/364] Re #22169: Switched to use implicit bool conversions. --- qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp index 685c46e962fa..f89ecb86552f 100644 --- a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp +++ b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp @@ -242,7 +242,7 @@ std::vector MatrixWSDataSource::getInfoList(double x, double y) { std::string x_label = ""; Unit_sptr &old_unit = m_matWs->getAxis(0)->unit(); - if (old_unit != nullptr) { + if (old_unit) { x_label = old_unit->caption(); SVUtils::PushNameValue(x_label, 8, 3, x, list); } @@ -262,7 +262,7 @@ std::vector MatrixWSDataSource::getInfoList(double x, double y) { try { - if (old_unit == nullptr) { + if (old_unit) { g_log.debug("No UNITS on MatrixWorkspace X-axis"); return list; } From 07394a0a9286ca1de057e2eb9c971ac1ebad63a6 Mon Sep 17 00:00:00 2001 From: Edward Brown Date: Mon, 26 Mar 2018 12:06:16 +0100 Subject: [PATCH 364/364] Re #22169: Added missing negation. --- qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp index f89ecb86552f..7d438bb60c73 100644 --- a/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp +++ b/qt/widgets/spectrumviewer/src/MatrixWSDataSource.cpp @@ -262,7 +262,7 @@ std::vector MatrixWSDataSource::getInfoList(double x, double y) { try { - if (old_unit) { + if (!old_unit) { g_log.debug("No UNITS on MatrixWorkspace X-axis"); return list; }