Skip to content

Commit

Permalink
Refs #10280. Added query method to SymmetryOperationFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Oct 1, 2014
1 parent d0c46d6 commit 3968263
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 35 deletions.
Expand Up @@ -18,13 +18,17 @@ namespace Geometry
/** SymmetryOperationFactory
A factory for symmetry operations. Symmetry operations are stored
with respect to their identifier (see SymmetryOperations for details).
with respect to their identifier (see SymmetryOperation for details).
Creation of symmetry operations is then performed like this:
SymmetryOperations_sptr inversion = SymmetryOperationFactory::Instance().createSymOp("-1");
SymmetryOperations inversion = SymmetryOperationFactory::Instance().createSymOp("x,y,z");
Available symmetry operations may be queried with DynamicFactory::getKeys().
Creating a symmetry operation object automatically registers the object
as a prototype and subsequent creations are much more efficient because
the symbol does not need to be parsed.
Available symmetry operations may be queried with SymmetryOperation::subscribedSymbols.
@author Michael Wedel, Paul Scherrer Institut - SINQ
@date 10/09/2014
Expand Down Expand Up @@ -59,6 +63,8 @@ namespace Geometry

bool isSubscribed(const std::string &identifier) const;

std::vector<std::string> subscribedSymbols() const;

protected:
void subscribe(const std::string &alias, const SymmetryOperation &prototype);

Expand Down
Expand Up @@ -41,6 +41,19 @@ bool SymmetryOperationFactoryImpl::isSubscribed(const std::string &identifier) c
return m_prototypes.find(identifier) != m_prototypes.end();
}

/// Returns all symbols in the factory.
std::vector<std::string> SymmetryOperationFactoryImpl::subscribedSymbols() const
{
std::vector<std::string> symbols;
symbols.reserve(m_prototypes.size());

for(auto it = m_prototypes.begin(); it != m_prototypes.end(); ++it) {
symbols.push_back(it->first);
}

return symbols;
}

/// Subscribes symmetry operation into factory, using the supplied alias as key.
void SymmetryOperationFactoryImpl::subscribe(const std::string &alias, const SymmetryOperation &prototype)
{
Expand Down
107 changes: 75 additions & 32 deletions Code/Mantid/Framework/Geometry/test/SymmetryOperationFactoryTest.h
Expand Up @@ -16,38 +16,81 @@ using namespace Mantid::Kernel;
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; }

SymmetryOperationFactoryTest()
{
SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z");
}

~SymmetryOperationFactoryTest()
{
SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z");
}


void testCreateSymOp()
{
TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOp("x,y,z"));
TS_ASSERT_THROWS(SymmetryOperationFactory::Instance().createSymOp("fake2"), Mantid::Kernel::Exception::ParseError);
}

void testUnsubscribe()
{
TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOp("x,y,z"));

TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z"));
TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), false);
TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOp("x,y,z"));

TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z"));
}
// 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; }

SymmetryOperationFactoryTest()
{
SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z");
}

~SymmetryOperationFactoryTest()
{
SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z");
}


void testCreateSymOp()
{
TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOp("x,y,z"));
TS_ASSERT_THROWS(SymmetryOperationFactory::Instance().createSymOp("fake2"), Mantid::Kernel::Exception::ParseError);

// createSymOp also works when an operation is not subscribed
TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z"));
TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), false);

TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOp("x,y,z"));

// it's automatically registered
TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), true);
}

void testUnsubscribe()
{
TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), true);

TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z"));
TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), false);

TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z"));
}

void testIsSubscribed()
{
TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z"));
TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), false);
TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z"));
TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), true);
}

void testSubscribedSymbols()
{
// Clear factory
std::vector<std::string> allSymbols = SymmetryOperationFactory::Instance().subscribedSymbols();
for(auto it = allSymbols.begin(); it != allSymbols.end(); ++it) {
SymmetryOperationFactory::Instance().unsubscribeSymOp(*it);
}

// Subscribe two symmetry operations
SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z");
SymmetryOperationFactory::Instance().subscribeSymOp("-x,-y,-z");

std::vector<std::string> symbols = SymmetryOperationFactory::Instance().subscribedSymbols();

TS_ASSERT_EQUALS(symbols.size(), 2);
TS_ASSERT_DIFFERS(std::find(symbols.begin(), symbols.end(), "x,y,z"), symbols.end());
TS_ASSERT_DIFFERS(std::find(symbols.begin(), symbols.end(), "-x,-y,-z"), symbols.end());

SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z");
SymmetryOperationFactory::Instance().unsubscribeSymOp("-x,-y,-z");

// Restore factory
for(auto it = allSymbols.begin(); it != allSymbols.end(); ++it) {
SymmetryOperationFactory::Instance().subscribeSymOp(*it);
}
}
};


Expand Down
Expand Up @@ -11,6 +11,7 @@ void export_SymmetryOperationFactory()
class_<SymmetryOperationFactoryImpl,boost::noncopyable>("SymmetryOperationFactoryImpl", no_init)
.def("exists", &SymmetryOperationFactoryImpl::isSubscribed)
.def("createSymOp", &SymmetryOperationFactoryImpl::createSymOp)
.def("subscribedSymbols", &SymmetryOperationFactoryImpl::subscribedSymbols)
.def("Instance", &SymmetryOperationFactory::Instance, return_value_policy<reference_existing_object>(),
"Returns a reference to the SymmetryOperationFactory singleton")
.staticmethod("Instance")
Expand Down

0 comments on commit 3968263

Please sign in to comment.