diff --git a/Code/Mantid/Framework/Geometry/CMakeLists.txt b/Code/Mantid/Framework/Geometry/CMakeLists.txt index f192ebbd483f..cdcd19d898d5 100644 --- a/Code/Mantid/Framework/Geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/Geometry/CMakeLists.txt @@ -11,6 +11,7 @@ set ( SRC_FILES src/Crystal/ReflectionCondition.cpp src/Crystal/ScalarUtils.cpp src/Crystal/SymmetryOperation.cpp + src/Crystal/SymmetryOperationFactory.cpp src/Crystal/UnitCell.cpp src/IObjComponent.cpp src/Instrument.cpp @@ -113,6 +114,7 @@ set ( INC_FILES inc/MantidGeometry/Crystal/ReflectionCondition.h inc/MantidGeometry/Crystal/ScalarUtils.h inc/MantidGeometry/Crystal/SymmetryOperation.h + inc/MantidGeometry/Crystal/SymmetryOperationFactory.h inc/MantidGeometry/Crystal/UnitCell.h inc/MantidGeometry/DllConfig.h inc/MantidGeometry/ICompAssembly.h @@ -273,6 +275,7 @@ set ( TEST_FILES SphereTest.h SurfaceFactoryTest.h SurfaceTest.h + SymmetryOperationFactoryTest.h SymmetryOperationTest.h TorusTest.h TrackTest.h diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h new file mode 100644 index 000000000000..b8fa58b593b6 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h @@ -0,0 +1,104 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORY_H_ +#define MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORY_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/DynamicFactory.h" +#include "MantidKernel/SingletonHolder.h" +#include "MantidGeometry/Crystal/SymmetryOperation.h" + +#include +#include + +namespace Mantid +{ +namespace Geometry +{ + /** SymmetryOperationFactory + + A factory for symmetry operations. Symmetry operations are stored + with respect to their identifier (see SymmetryOperations for details). + + Creation of symmetry operations is then performed like this: + + SymmetryOperations_sptr inversion = SymmetryOperationFactory::Instance().createSymOp("-1"); + + There's a method to query all available symmetry operations. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 10/09/2014 + + Copyright © 2014 PSI-MSS + + 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 SymmetryOperationFactoryImpl : public Kernel::DynamicFactory + { + public: + SymmetryOperation_const_sptr createSymOp(const std::string &identifier) const; + + const std::list &getAllSymOpIdentifiers() const; + + /// Subscribes a symmetry operation into the factory + template + void subscribeSymOp() + { + Kernel::Instantiator *instantiator = new Kernel::Instantiator; + SymmetryOperation_const_sptr temporarySymOp = instantiator->createInstance(); + std::string identifier = temporarySymOp->identifier(); + + subscribe(identifier, instantiator); + addToAvailable(identifier); + } + + /// Unsubscribes a symmetry operation from the factory + void unsubscribeSymOp(const std::string &identifier) + { + unsubscribe(identifier); + removeFromAvailable(identifier); + } + + private: + friend struct Mantid::Kernel::CreateUsingNew; + + SymmetryOperationFactoryImpl(); + void addToAvailable(const std::string &identifier); + void removeFromAvailable(const std::string &identifier); + + std::list m_availableSymOps; + }; + +// This is taken from FuncMinimizerFactory +#ifdef _WIN32 + template class MANTID_GEOMETRY_DLL Mantid::Kernel::SingletonHolder; +#endif + +typedef Mantid::Kernel::SingletonHolder SymmetryOperationFactory; + + +} // namespace Geometry +} // namespace Mantid + +#define DECLARE_SYMMETRY_OPERATION(classname) \ + namespace { \ + Mantid::Kernel::RegistrationHelper register_symop_##classname( \ + ((Mantid::Geometry::SymmetryOperationFactory::Instance().subscribeSymOp()) \ + , 0)); \ + } + +#endif /* MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORY_H_ */ diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp index 820c8757f7e0..7204bea2baa1 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp @@ -1,4 +1,5 @@ #include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" namespace Mantid { @@ -79,6 +80,9 @@ SymOpInversion::SymOpInversion() : m_matrix *= -1; } +DECLARE_SYMMETRY_OPERATION(SymOpInversion) + + /* 2-fold rotation axes */ /// 2-fold rotation around x-axis SymOpRotationTwoFoldX::SymOpRotationTwoFoldX() : diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationFactory.cpp new file mode 100644 index 000000000000..5b9ea040a061 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationFactory.cpp @@ -0,0 +1,41 @@ +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include "MantidKernel/LibraryManager.h" + +namespace Mantid +{ +namespace Geometry +{ + +/// Creates a SymmetryOperation object from its Hermann-Mauguin symbol. +SymmetryOperation_const_sptr SymmetryOperationFactoryImpl::createSymOp(const std::string &identifier) const +{ + return create(identifier); +} + +/// Returns the Hermann-Mauguin symbols of all registered point groups. +const std::list &SymmetryOperationFactoryImpl::getAllSymOpIdentifiers() const +{ + return m_availableSymOps; +} + +/// Private default constructor. +SymmetryOperationFactoryImpl::SymmetryOperationFactoryImpl() : Kernel::DynamicFactory(), + m_availableSymOps() +{ + Kernel::LibraryManager::Instance(); +} + +/// Adds a point group to a map that stores pairs of Hermann-Mauguin symbol and crystal system. +void SymmetryOperationFactoryImpl::addToAvailable(const std::string &identifier) +{ + m_availableSymOps.insert(m_availableSymOps.end(), identifier); +} + +/// Removes point group from internal crystal system map. +void SymmetryOperationFactoryImpl::removeFromAvailable(const std::string &identifier) +{ + m_availableSymOps.remove(identifier); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryOperationFactoryTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryOperationFactoryTest.h new file mode 100644 index 000000000000..bdfe2d89d531 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/SymmetryOperationFactoryTest.h @@ -0,0 +1,28 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORYTEST_H_ +#define MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORYTEST_H_ + +#include + +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" + +using Mantid::Geometry::SymmetryOperationFactory; + +class SymmetryOperationFactoryTest : 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 SymmetryOperationFactoryTest *createSuite() { return new SymmetryOperationFactoryTest(); } + static void destroySuite( SymmetryOperationFactoryTest *suite ) { delete suite; } + + + void test_Something() + { + TSM_ASSERT( "You forgot to write a test!", 0); + } + + +}; + + +#endif /* MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORYTEST_H_ */