Skip to content

Commit

Permalink
Added find method to AnalysisDataService. More group tests. Re #6199.
Browse files Browse the repository at this point in the history
  • Loading branch information
mantid-roman committed May 14, 2013
1 parent 5d9b994 commit 46d0480
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 45 deletions.
2 changes: 2 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/AnalysisDataService.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ class DLLExport AnalysisDataServiceImpl : public Kernel::DataService<API::Worksp
void removeFromTopLevel(const std::string &name);
/// Count instances of a workspace in the ADS
size_t count(Workspace_const_sptr workspace) const;
/// Find a stored workspace
boost::shared_ptr<API::Workspace> find( const std::string& name) const;

private:
/// Checks the name is valid, throwing if not
Expand Down
2 changes: 2 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class MANTID_API_DLL WorkspaceGroup : public Workspace
void add(const std::string& wsName);
/// Adds a workspace to the group.
void addWorkspace(Workspace_sptr workspace);
/// Remove a workspace from the group.
void removeWorkspace(Workspace_sptr workspace);
/// Return the number of entries within the group
int getNumberOfEntries() const { return static_cast<int>(this->size()); }
/// Return the size of the group, so it is more like a container
Expand Down
54 changes: 30 additions & 24 deletions Code/Mantid/Framework/API/src/AnalysisDataService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,24 +100,12 @@ namespace Mantid
/**
* Extend the default behaviour by searching workspace groups recursively. Search is case insensitive.
* @param name :: Name of the workspace.
* @throw NotFoundError if the workspace wasn't found
*/
boost::shared_ptr<API::Workspace> AnalysisDataServiceImpl::retrieve(const std::string &name) const
{
std::string foundName = name;
std::transform(foundName.begin(), foundName.end(), foundName.begin(),toupper);
std::vector<Workspace_sptr> workspaces = getObjects();
for(auto it = workspaces.begin(); it != workspaces.end(); ++it)
{
Workspace *ws = it->get();
if ( ws->getUpperCaseName() == foundName ) return *it;
WorkspaceGroup* wsg = dynamic_cast<WorkspaceGroup*>(ws);
if ( wsg )
{
// look in member groups recursively
auto res = wsg->findItem(foundName, false);
if ( res ) return res;
}
}
auto ws = find(name);
if ( ws ) return ws;
throw Kernel::Exception::NotFoundError("Workspace",name);
}

Expand All @@ -128,15 +116,8 @@ namespace Mantid
*/
bool AnalysisDataServiceImpl::doesExist(const std::string &name) const
{
try
{
auto it = retrieve(name);
if ( it ) return true;
}
catch(Kernel::Exception::NotFoundError)
{
return false;
}
auto it = find(name);
if ( it ) return true;
return false;
}

Expand Down Expand Up @@ -181,6 +162,31 @@ namespace Mantid
return n;
}

/**
* Find a workspace in the ADS.
* @param name :: Name of the workspace to find.
* @return :: Shared pointer to the found workspace or an empty pointer otherwise.
*/
boost::shared_ptr<Workspace> AnalysisDataServiceImpl::find(const std::string &name) const
{
std::string foundName = name;
std::transform(foundName.begin(), foundName.end(), foundName.begin(),toupper);
std::vector<Workspace_sptr> workspaces = getObjects();
for(auto it = workspaces.begin(); it != workspaces.end(); ++it)
{
Workspace *ws = it->get();
if ( ws->getUpperCaseName() == foundName ) return *it;
WorkspaceGroup* wsg = dynamic_cast<WorkspaceGroup*>(ws);
if ( wsg )
{
// look in member groups recursively
auto res = wsg->findItem(foundName, false);
if ( res ) return res;
}
}
return boost::shared_ptr<Workspace>();
}

//-------------------------------------------------------------------------
// Private methods
//-------------------------------------------------------------------------
Expand Down
18 changes: 18 additions & 0 deletions Code/Mantid/Framework/API/src/WorkspaceGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,23 @@ void WorkspaceGroup::addWorkspace(Workspace_sptr workspace)
}
}

/**
* Remove a workspace if it is in the group. Doesn't look into nested groups.
* @param workspace :: A workspace to remove.
*/
void WorkspaceGroup::removeWorkspace(Workspace_sptr workspace)
{
Poco::Mutex::ScopedLock _lock(m_mutex);
for(auto it = m_workspaces.begin(); it != m_workspaces.end(); ++it)
{
if ( *it == workspace )
{
m_workspaces.erase(it);
return;
}
}
}

/**
* Does this group contain the named workspace?
* @param wsName :: A string to compare
Expand Down Expand Up @@ -244,6 +261,7 @@ Workspace_sptr WorkspaceGroup::findItem(const std::string wsName, bool convertTo
* @param workspace :: Workspace to look for.
* @param nesting :: Current nesting level. To detect cycles.
* @return :: Number of copies.
* @throw :: std::runtime_error if nesting level exceeds maximum.
*/
size_t WorkspaceGroup::count(Workspace_const_sptr workspace, size_t nesting) const
{
Expand Down
106 changes: 85 additions & 21 deletions Code/Mantid/Framework/API/test/WorkspaceGroupTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
Workspace_sptr ws2(new WorkspaceTester());
group->addWorkspace( ws2 );
TS_ASSERT_EQUALS( group->size(), 2 );

// adding same workspace twice doesn't create a copy
group->addWorkspace( ws2 );
TS_ASSERT_EQUALS( group->size(), 2 );
}

void test_addWorkspace_copies()
Expand All @@ -124,9 +128,22 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
group->addWorkspace( group1->getItem(2) );
TS_ASSERT_EQUALS( group->size(), 1 );
TS_ASSERT_EQUALS( group1->size(), 3 );
// the two groups have a copy of the worksapce each
TS_ASSERT_EQUALS( group->getItem(0), group1->getItem(2) );
}

void test_addWorkspace_copies1()
{
WorkspaceGroup_sptr group(new WorkspaceGroup());
WorkspaceGroup_sptr child_group(new WorkspaceGroup());
Workspace_sptr ws(new WorkspaceTester());
child_group->addWorkspace( ws );

group->addWorkspace( child_group );
group->addWorkspace( ws );
TS_ASSERT_EQUALS( group->count( ws ), 2 );
}

void test_addWorkspace_if_group_in_ADS()
{
WorkspaceGroup_sptr group(new WorkspaceGroup());
Expand Down Expand Up @@ -157,9 +174,53 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
// size of ADS doesn't change
TS_ASSERT_EQUALS( AnalysisDataService::Instance().size(), 1 );

// if group in ADS and ws in group and if group1 in ADS
// then adding ws to group1 makes two copies of ws in ADS
WorkspaceGroup_sptr group1(new WorkspaceGroup());
AnalysisDataService::Instance().add("group1",group1);
group1->addWorkspace(ws);
TS_ASSERT_EQUALS( group->getItem(0), ws );
TS_ASSERT_EQUALS( group1->getItem(0), ws );
TS_ASSERT_EQUALS( AnalysisDataService::Instance().size(), 2 ); // the two groups are on the top level
TS_ASSERT_EQUALS( AnalysisDataService::Instance().count(ws), 2 ); // ws is found twice in ADS

AnalysisDataService::Instance().clear();
}

void test_addWorkspace_if_group_not_in_ADS()
{
// adding a workspace to group doesn't change its status in the ADS
Workspace_sptr ws(new WorkspaceTester());
AnalysisDataService::Instance().add("ws",ws);

WorkspaceGroup_sptr group(new WorkspaceGroup());

group->addWorkspace( ws );
TS_ASSERT_EQUALS( group->size(), 1 );
TS_ASSERT( AnalysisDataService::Instance().doesExist("ws") );
Workspace_sptr ws1 = AnalysisDataService::Instance().retrieve("ws");
TS_ASSERT_EQUALS( ws, ws1 );
TS_ASSERT_EQUALS( AnalysisDataService::Instance().size(), 1 );

AnalysisDataService::Instance().clear();
}

void test_count_catches_cycles()
{
WorkspaceGroup_sptr group(new WorkspaceGroup());
WorkspaceGroup_sptr child_group(new WorkspaceGroup());
Workspace_sptr ws(new WorkspaceTester());
child_group->addWorkspace( ws );

group->addWorkspace( child_group );
group->addWorkspace( ws );
TS_ASSERT_EQUALS( group->count( ws ), 2 );

// make a cycle
child_group->addWorkspace( group );
TS_ASSERT_THROWS( group->count( ws ), std::runtime_error );
}

void test_group_counts_as_1_in_ADS()
{
WorkspaceGroup_sptr group = makeGroup();
Expand Down Expand Up @@ -244,6 +305,27 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
AnalysisDataService::Instance().clear();
}

void test_findItem()
{
WorkspaceGroup_sptr group( makeGroup() );
WorkspaceGroup_sptr child_group( makeGroup() );
AnalysisDataService::Instance().add( "group", group );
AnalysisDataService::Instance().add( "child_group", child_group );

group->addWorkspace( child_group );

TS_ASSERT_EQUALS( group->getItem(1), group->findItem("group_2") );
TS_ASSERT_EQUALS( child_group->getItem(0), group->findItem("child_group_1") );
TS_ASSERT( ! group->findItem("noworkspace") );

// make a cycle
child_group->addWorkspace( group );
// detect cycle
TS_ASSERT_THROWS( group->findItem("child_group_4"), std::runtime_error );

AnalysisDataService::Instance().clear();
}

void xtest_adding_group_to_ADS()
{
// if group's members are not in the ADS their names must become <group_name>_#
Expand Down Expand Up @@ -276,27 +358,7 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
}


/*
void xtest_addWorkspace_when_group_in_ADS()
{
WorkspaceGroup_sptr group(new WorkspaceGroup());
Workspace_sptr ws1(new WorkspaceTester());
Workspace_sptr ws2(new WorkspaceTester());
TS_ASSERT_EQUALS( AnalysisDataService::Instance().size(), 0 );
AnalysisDataService::Instance().add("group", group);
group->addWorkspace( ws1 );
TS_ASSERT_EQUALS( group->size(), 1 );
group->addWorkspace( ws2 );
TS_ASSERT_EQUALS( group->size(), 2 );
TS_ASSERT_EQUALS( AnalysisDataService::Instance().size(), 1 );
AnalysisDataService::Instance().clear();
}
void xtest_getNames()
void test_getNames()
{
WorkspaceGroup_sptr group(new WorkspaceGroup());
Workspace_sptr ws1(new WorkspaceTester());
Expand All @@ -308,6 +370,7 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS(names.size(), 2);
TS_ASSERT_EQUALS(names[0], "");
TS_ASSERT_EQUALS(names[1], "Workspace2");
AnalysisDataService::Instance().clear();
}

void xtest_remove()
Expand All @@ -328,6 +391,7 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
AnalysisDataService::Instance().clear();
}

/*
void xtest_deleting_workspaces()
{
WorkspaceGroup_sptr group = makeGroup();
Expand Down

0 comments on commit 46d0480

Please sign in to comment.