Skip to content

Commit

Permalink
ADS can now return map of top level items.
Browse files Browse the repository at this point in the history
The map shows the name & workspace of any items that are groups or
not members of groups.
Refs #7708
  • Loading branch information
martyngigg committed Aug 9, 2013
1 parent de17341 commit 297f458
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/AnalysisDataService.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class WorkspaceGroup;
class DLLExport AnalysisDataServiceImpl : public Kernel::DataService<API::Workspace>
{
public:

/** @name Extra notifications only applicable to the ADS */
//@{
/// GroupWorkspaces notification is send from GroupWorkspaces algorithm
Expand Down Expand Up @@ -141,6 +142,8 @@ class DLLExport AnalysisDataServiceImpl : public Kernel::DataService<API::Worksp

/// Create an info tree out of InfoNodes to describe the current state of the ADS.
Workspace::InfoNode *createInfoTree() const;
/// Return a lookup of the top level items
std::map<std::string,Workspace_sptr> topLevelItems() const;

private:
/// Checks the name is valid, throwing if not
Expand Down
4 changes: 4 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ class MANTID_API_DLL WorkspaceGroup : public Workspace
void remove(const std::string& wsName) { AnalysisDataService::Instance().removeFromGroup( this->name(), wsName); }
/// Does a workspace exist within the group
bool contains(const std::string & wsName) const;
/// Does a workspace exist within the group
bool contains(const Workspace_sptr & wsName) const;
/// Add the members of the group to the given list
void reportMembers(std::set<Workspace_sptr> & memberList) const;
/// Returns the names of workspaces that make up this group. Note that this returns a copy as the internal vector can mutate while the vector is being iterated over.
std::vector<std::string> getNames() const;

Expand Down
46 changes: 45 additions & 1 deletion Code/Mantid/Framework/API/src/AnalysisDataService.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/WorkspaceGroup.h"
#include "MantidKernel/Strings.h"

namespace Mantid
{
Expand Down Expand Up @@ -265,6 +264,51 @@ namespace Mantid
return root;
}

/**
* Produces a map of names to Workspaces that doesn't include
* items that are part of a WorkspaceGroup already in the list
* @return A lookup of name to Workspace pointer
*/
std::map<std::string,Workspace_sptr> AnalysisDataServiceImpl::topLevelItems() const
{
std::map<std::string,Workspace_sptr> topLevel;
auto topLevelNames = this->getObjectNames();
std::set<Workspace_sptr> groupMembers;

for(auto it = topLevelNames.begin(); it != topLevelNames.end(); ++it)
{
try
{
const std::string & name = *it;
auto ws = this->retrieve(*it);
topLevel.insert(std::make_pair(name, ws));
if(auto group = boost::dynamic_pointer_cast<WorkspaceGroup>(ws))
{
group->reportMembers(groupMembers);
}
}
catch(std::exception&)
{
}
}

// Prune members
for(auto it = topLevel.begin(); it != topLevel.end();)
{
const Workspace_sptr & item = it->second;
if(groupMembers.count(item) == 1)
{
topLevel.erase(it++);
}
else
{
++it;
}
}

return topLevel;
}

//-------------------------------------------------------------------------
// Private methods
//-------------------------------------------------------------------------
Expand Down
22 changes: 22 additions & 0 deletions Code/Mantid/Framework/API/src/WorkspaceGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,28 @@ bool WorkspaceGroup::contains(const std::string & wsName) const
return false;
}

/**
* @param workspace A pointer to a workspace
* @returns True if the workspace exists in the group, false otherwise
*/
bool WorkspaceGroup::contains(const Workspace_sptr & workspace) const
{
Poco::Mutex::ScopedLock _lock(m_mutex);
auto iend = m_workspaces.end();
auto it = std::find(m_workspaces.begin(),iend, workspace);
return (it != iend);
}

/**
* Adds the current workspace members to the given list
* @param memberList
*/
void WorkspaceGroup::reportMembers(std::set<Workspace_sptr> & memberList) const
{
Poco::Mutex::ScopedLock _lock(m_mutex);
memberList.insert(m_workspaces.begin(), m_workspaces.end());
}

/**
* Returns the names of workspaces that make up this group.
* Note that this returns a copy as the internal vector can mutate while the vector is being iterated over.
Expand Down
25 changes: 25 additions & 0 deletions Code/Mantid/Framework/API/test/AnalysisDataServiceTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,31 @@ class AnalysisDataServiceTest : public CxxTest::TestSuite
ads.clear();
}

void test_topLevelItems_Does_Not_Contain_Workspaces_That_Are_In_A_Group_In_The_List()
{
// this adds 1 group to the ADS (5 ws's altogether)
auto group = addGroupWithGroupToADS("snapshot_group");
// plus 1 more ws
auto leaf = addToADS("single_workspace");
// ADS must have 6 ws's now
TS_ASSERT_EQUALS( ads.size(), 6 );

auto topLevelItems = ads.topLevelItems();
// Only 2
TS_ASSERT_EQUALS(2, topLevelItems.size());

auto it = topLevelItems.find("snapshot_group");
TS_ASSERT(it != topLevelItems.end());
TS_ASSERT_EQUALS("snapshot_group", it->first);
TS_ASSERT_EQUALS(group, it->second);

it = topLevelItems.find("single_workspace");
TS_ASSERT(it != topLevelItems.end());
TS_ASSERT_EQUALS("single_workspace", it->first);
TS_ASSERT_EQUALS(leaf, it->second);

}

private:

/// If replace=true then usea addOrReplace
Expand Down
19 changes: 19 additions & 0 deletions Code/Mantid/Framework/API/test/WorkspaceGroupTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,25 @@ class WorkspaceGroupTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS(names[1], "Workspace2");
}

void test_reportMembers_Does_Not_Clear_List_Already_Passed_In()
{
Workspace_sptr leaf1(new WorkspaceTester());
std::set<Workspace_sptr> topLevel;
topLevel.insert(leaf1);
WorkspaceGroup_sptr group(new WorkspaceGroup());
Workspace_sptr ws1(new WorkspaceTester());
group->addWorkspace( ws1 );
Workspace_sptr ws2(new WorkspaceTester());
group->addWorkspace( ws2 );

group->reportMembers(topLevel);
TS_ASSERT_EQUALS(3, topLevel.size());
TS_ASSERT_EQUALS(1, topLevel.count(leaf1));
TS_ASSERT_EQUALS(1, topLevel.count(ws1));
TS_ASSERT_EQUALS(1, topLevel.count(ws2));

}

void test_getItem()
{
WorkspaceGroup_sptr group = makeGroup();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void export_WorkspaceGroup()
class_< WorkspaceGroup, bases<Workspace>, boost::noncopyable >("WorkspaceGroup", no_init)
.def("getNumberOfEntries", &WorkspaceGroup::getNumberOfEntries, "Returns the number of entries in the group")
.def("getNames", &WorkspaceGroup::getNames, "Returns the names of the entries in the group")
.def("contains", &WorkspaceGroup::contains, "Returns true if the given name is in the group")
.def("contains", (bool (WorkspaceGroup::*)(const std::string & wsName) const)&WorkspaceGroup::contains, "Returns true if the given name is in the group")
.def("add", &WorkspaceGroup::add, "Add a name to the group")
.def("size", &WorkspaceGroup::size, "Returns the number of workspaces contained in the group")
.def("remove", &WorkspaceGroup::remove, "Remove a name from the group")
Expand All @@ -43,7 +43,7 @@ void export_WorkspaceGroup()
.def("isMultiPeriod", &WorkspaceGroup::isMultiperiod, "Retuns true if the workspace group is multi-period")
// ------------ Operators --------------------------------
.def("__len__", &WorkspaceGroup::getNumberOfEntries)
.def("__contains__", &WorkspaceGroup::contains)
.def("__contains__", (bool (WorkspaceGroup::*)(const std::string & wsName) const)&WorkspaceGroup::contains)
.def("__getitem__",&getItemAsWeakPtr, return_value_policy<Policies::downcast_returned_value>())
;

Expand Down

0 comments on commit 297f458

Please sign in to comment.