Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix mass ws deletion bug #18914

Merged
merged 4 commits into from Feb 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions Framework/Algorithms/CMakeLists.txt
Expand Up @@ -90,6 +90,7 @@ set ( SRC_FILES
src/CylinderAbsorption.cpp
src/DeleteLog.cpp
src/DeleteWorkspace.cpp
src/DeleteWorkspaces.cpp
src/DetectorDiagnostic.cpp
src/DetectorEfficiencyCor.cpp
src/DetectorEfficiencyCorUser.cpp
Expand Down Expand Up @@ -404,6 +405,7 @@ set ( INC_FILES
inc/MantidAlgorithms/CylinderAbsorption.h
inc/MantidAlgorithms/DeleteLog.h
inc/MantidAlgorithms/DeleteWorkspace.h
inc/MantidAlgorithms/DeleteWorkspaces.h
inc/MantidAlgorithms/DetectorDiagnostic.h
inc/MantidAlgorithms/DetectorEfficiencyCor.h
inc/MantidAlgorithms/DetectorEfficiencyCorUser.h
Expand Down Expand Up @@ -731,6 +733,7 @@ set ( TEST_FILES
CylinderAbsorptionTest.h
DeleteLogTest.h
DeleteWorkspaceTest.h
DeleteWorkspacesTest.h
DetectorEfficiencyCorTest.h
DetectorEfficiencyCorUserTest.h
DetectorEfficiencyVariationTest.h
Expand Down
62 changes: 62 additions & 0 deletions Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h
@@ -0,0 +1,62 @@
#ifndef MANTID_ALGORITHMS_DELETEWORKSPACES_H_
#define MANTID_ALGORITHMS_DELETEWORKSPACES_H_

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/Algorithm.h"

namespace Mantid {
namespace Algorithms {
/**
A simple algorithm to remove multiple workspaces from the ADS.

@author Nick Draper, Tessella plc
@date 2017-02-17

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 <http://www.gnu.org/licenses/>.

File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport DeleteWorkspaces : public API::Algorithm {
public:
/// Algorithm's name
const std::string name() const override { return "DeleteWorkspaces"; }
/// Summary of algorithms purpose
const std::string summary() const override {
return "Removes a list of workspaces from memory.";
}

/// Algorithm's category for identification
const std::string category() const override { return "Utility\\Workspaces"; }
/// Algorithm's version for identification overriding a virtual method
int version() const override { return 1; }

private:
/// Overridden init
void init() override;
/// Overridden exec
void exec() override;
};

} // namespace Algorithm
} // namespace Mantid

#endif // MANTID_ALGORITHMS_DELETEWORKSPACES_H_
39 changes: 39 additions & 0 deletions Framework/Algorithms/src/DeleteWorkspaces.cpp
@@ -0,0 +1,39 @@
#include "MantidAlgorithms/DeleteWorkspaces.h"
#include "MantidAPI/ADSValidator.h"
#include "MantidKernel/ArrayProperty.h"

namespace Mantid {
namespace Algorithms {

// Register the algorithm
DECLARE_ALGORITHM(DeleteWorkspaces)

/// Initialize the algorithm properties
void DeleteWorkspaces::init() {
declareProperty(Kernel::make_unique<Kernel::ArrayProperty<std::string>>(
"WorkspaceList", boost::make_shared<API::ADSValidator>()),
"A list of the workspaces to delete.");
}

/// Execute the algorithm
void DeleteWorkspaces::exec() {
const std::vector<std::string> wsNames = getProperty("WorkspaceList");

// Set up progress reporting
API::Progress prog(this, 0.0, 1.0, wsNames.size());

for (auto wsName : wsNames) {
// run delete workspace as a child algorithm
auto deleteAlg = createChildAlgorithm("DeleteWorkspace", -1, -1, false);
deleteAlg->initialize();

deleteAlg->setPropertyValue("Workspace", wsName);
bool success = deleteAlg->execute();
if (!deleteAlg->isExecuted() || !success) {
g_log.error() << "Failed to delete wsName. \n";
}
prog.report();
}
}
}
}
93 changes: 93 additions & 0 deletions Framework/Algorithms/test/DeleteWorkspacesTest.h
@@ -0,0 +1,93 @@
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "MantidAlgorithms/DeleteWorkspaces.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include "MantidAPI/WorkspaceGroup.h"

#include <cxxtest/TestSuite.h>

class DeleteWorkspacesTest : public CxxTest::TestSuite {

public:
void test_That_An_Existing_Workspace_Is_Deleted_After_Execution() {
using namespace Mantid::API;
using namespace Mantid::DataObjects;

// Need a test workspace registered within the ADS
const int yLength = 20;
AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
const size_t storeSizeAtStart(dataStore.size());
const std::string testName1 = "DeleteWorkspaces_testWS1";
const std::string testName2 = "DeleteWorkspaces_testWS2";
const std::string testName3 = "DeleteWorkspaces_testWS3";
createAndStoreWorspace(testName1);
createAndStoreWorspace(testName2);
createAndStoreWorspace(testName3, yLength);
TS_ASSERT_EQUALS(dataStore.size(), storeSizeAtStart + 3);

Mantid::Algorithms::DeleteWorkspaces alg;
alg.initialize();
alg.setPropertyValue("WorkspaceList", testName1 + ", " + testName2);
alg.setRethrows(true);
TS_ASSERT_THROWS_NOTHING(alg.execute());
TS_ASSERT(alg.isExecuted());

TS_ASSERT_EQUALS(dataStore.size(), storeSizeAtStart + 1);
// Check that what is left is correct
MatrixWorkspace_sptr wsRemain =
boost::dynamic_pointer_cast<MatrixWorkspace>(
dataStore.retrieve(testName3));
TS_ASSERT(wsRemain);
if (!wsRemain)
TS_FAIL("Unable to retrieve remaining workspace.");

TS_ASSERT_EQUALS(wsRemain->getNumberHistograms(), yLength);
// Tidy up after test
dataStore.remove(testName3);
}

void test_deleting_group_deletes_its_members() {
using namespace Mantid::API;
using namespace Mantid::DataObjects;

// Need a test workspace registered within the ADS
AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
dataStore.clear();

const std::string testName1 = "DeleteWorkspaces_testWS1";
const std::string testName2 = "DeleteWorkspaces_testWS2";

createAndStoreWorspace(testName1);
createAndStoreWorspace(testName2);

auto group = WorkspaceGroup_sptr(new WorkspaceGroup);
dataStore.add("group", group);
group->add(testName1);
group->add(testName2);

TS_ASSERT_EQUALS(dataStore.size(), 3);

Mantid::Algorithms::DeleteWorkspaces alg;
alg.initialize();
alg.setPropertyValue("WorkspaceList", "group");
alg.setRethrows(true);
TS_ASSERT_THROWS_NOTHING(alg.execute());
TS_ASSERT(alg.isExecuted());

TS_ASSERT_EQUALS(dataStore.size(), 0);

dataStore.clear();
}

void createAndStoreWorspace(std::string name, int ylength = 10) {
using namespace Mantid::API;
using namespace Mantid::DataObjects;

// create a test workspace registered within the ADS
Workspace2D_sptr testWS1 =
WorkspaceCreationHelper::create2DWorkspace(ylength, 10);
AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
dataStore.add(name, testWS1);
}
};
10 changes: 8 additions & 2 deletions MantidPlot/src/Mantid/MantidUI.cpp
Expand Up @@ -455,9 +455,15 @@ void MantidUI::deleteWorkspaces(const QStringList &wsNames) {

try {
if (!wsNames.isEmpty()) {
for (auto &ws : wsNames) {
deleteWorkspace(ws);
auto alg = createAlgorithm("DeleteWorkspaces");
alg->setLogging(false);
std::vector<std::string> vecWsNames;
vecWsNames.reserve(wsNames.size());
foreach (auto wsName, wsNames) {
vecWsNames.push_back(wsName.toStdString());
}
alg->setProperty("WorkspaceList", vecWsNames);
executeAlgorithmAsync(alg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should put all this in a private method? void MantidUI::deleteWorkspaces() or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it already is!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it is!

} else if ((m &&
(strcmp(m->metaObject()->className(), "MantidMatrix") == 0)) &&
!m->workspaceName().isEmpty()) {
Expand Down
59 changes: 59 additions & 0 deletions docs/source/algorithms/DeleteWorkspaces-v1.rst
@@ -0,0 +1,59 @@
.. algorithm::

.. summary::

.. alias::

.. properties::

Description
-----------

If workspaces in the WorkspaceList exist then it is removed from Mantid.

Usage
-----

**Example - Delete using a list of objects**

.. testcode::

# A small test workspace, with sample_ws as the handle
sample_ws = CreateSingleValuedWorkspace(5.0)
sample_ws2 = CreateSingleValuedWorkspace(5.0)

DeleteWorkspaces([sample_ws,sample_ws2])

print "sample_ws exists in mantid:",("sample_ws" in mtd)
print "sample_ws2 exists in mantid:",("sample_ws2" in mtd)

Output:

.. testoutput::

sample_ws exists in mantid: False
sample_ws2 exists in mantid: False

**Example - Delete using a string list**

.. testcode::

# A small test workspace, with sample_ws as the handle
CreateSingleValuedWorkspace(5.0, OutputWorkspace="single_value")
CreateSingleValuedWorkspace(5.0, OutputWorkspace="single_value2")

DeleteWorkspaces("single_value, single_value2")

print "single_value exists in mantid:",("single_value" in mtd)
print "single_value2 exists in mantid:",("single_value2" in mtd)

Output:

.. testoutput::

single_value exists in mantid: False
single_value2 exists in mantid: False

.. categories::

.. sourcelink::
7 changes: 5 additions & 2 deletions docs/source/release/v3.10.0/framework.rst
Expand Up @@ -11,6 +11,7 @@ Algorithms
New
###

- :ref:`DeleteWorkspaces <algm-DeleteWorkspaces>` will delete a list of workspaces.

Improved
########
Expand All @@ -25,8 +26,10 @@ MD Algorithms (VATES CLI)
Performance
-----------

CurveFitting
------------
Bugs
----

- We have fixed a bug where Mantid could crash when deleteing a large number of workspaces.

Improved
########
Expand Down