Skip to content

Commit

Permalink
Refactored applyGroupingToWS and made it to work with groups.
Browse files Browse the repository at this point in the history
Refs 7557
  • Loading branch information
arturbekasov committed Oct 17, 2013
1 parent b20ff51 commit 379c3c2
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
*/

using namespace Mantid;
using namespace Mantid::API;

/// Structure to represent grouping information for Muon Analysis
typedef struct {
Expand All @@ -78,6 +79,9 @@ void parseGroupingTable(const Ui::MuonAnalysis& form, Grouping& grouping);
/// Fills in the grouping table using information from provided Grouping struct
void fillGroupingTable(const Grouping& grouping, Ui::MuonAnalysis& form);

/// Groups the workspace according to grouping provided
MatrixWorkspace_sptr groupWorkspace(MatrixWorkspace_const_sptr ws, const Grouping& g);

/// create 'map' relating group number to row number in group table
void whichGroupToWhichRow(const Ui::MuonAnalysis& m_uiForm, std::vector<int>& groupToRow);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,6 @@ private slots:
/// is grouping set
bool isGroupingSet();

/// Apply grouping specified in xml file to workspace
bool applyGroupingToWS( const std::string& inputWS, const std::string& outputWS,
const std::string& filename);

/// create WS contained the data for a plot
void createPlotWS(const std::string& groupName,
const std::string& inputWS, const std::string& outWS);
Expand Down Expand Up @@ -409,6 +405,9 @@ private slots:
/// Boolean to show whether the gui is being updated
bool m_updating;

/// Flag to indicate that grouping table is being updated
bool m_updatingGrouping;

/// Boolean to show when data has been loaded. (Can't auto-update data that hasn't been loaded)
bool m_loaded;

Expand Down
42 changes: 42 additions & 0 deletions Code/Mantid/MantidQt/CustomInterfaces/src/IO_MuonGrouping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,49 @@ void setGroupGroupPair(Ui::MuonAnalysis& m_uiForm, const std::string& name)
}
}

/**
* Groups the workspace according to grouping provided.
*
* @param ws :: Workspace to group
* @param g :: The grouping information
* @return Sptr to created grouped workspace
*/
MatrixWorkspace_sptr groupWorkspace(MatrixWorkspace_const_sptr ws, const Grouping& g)
{
// As I couldn't specify multiple groups for GroupDetectors, I am going down quite a complicated
// route - for every group distinct grouped workspace is created using GroupDetectors. These
// workspaces are then merged into the output workspace.

// Create output workspace
MatrixWorkspace_sptr outWs =
WorkspaceFactory::Instance().create(ws, g.groups.size(), ws->readX(0).size(), ws->blocksize());

for(size_t gi = 0; gi < g.groups.size(); gi++)
{
Mantid::API::IAlgorithm_sptr alg = AlgorithmManager::Instance().create("GroupDetectors");
alg->setChild(true); // So Output workspace is not added to the ADS
alg->initialize();
alg->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(ws));
alg->setPropertyValue("SpectraList", g.groups[gi]);
alg->setPropertyValue("OutputWorkspace", "grouped"); // Is not actually used, just to make validators happy
alg->execute();

MatrixWorkspace_sptr grouped = alg->getProperty("OutputWorkspace");

// Copy the spectrum
*(outWs->getSpectrum(gi)) = *(grouped->getSpectrum(0));

// Update spectrum number
outWs->getSpectrum(gi)->setSpectrumNo(static_cast<specid_t>(gi));

// Copy to the output workspace
outWs->dataY(gi) = grouped->readY(0);
outWs->dataX(gi) = grouped->readX(0);
outWs->dataE(gi) = grouped->readE(0);
}

return outWs;
}

/**
* create 'map' relating group number to row number in group table
Expand Down
79 changes: 40 additions & 39 deletions Code/Mantid/MantidQt/CustomInterfaces/src/MuonAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,8 +1185,6 @@ void MuonAnalysis::inputFileChanged(const QStringList& files)
setDummyGrouping(static_cast<int>(matrix_workspace->getInstrument()->getDetectorIDs().size()));

if ( !applyGroupingToWS(m_workspace_name, m_workspace_name+"Grouped") )
// TODO: applyGroupingToWS shows it's own messages as well. Should make it throw exceptions
// instead.
throw std::runtime_error("Couldn't apply grouping");

// Populate instrument fields
Expand Down Expand Up @@ -2616,55 +2614,59 @@ bool MuonAnalysis::applyGroupingToWS( const std::string& inputWsName, const std
m_optionTab->nowDataAvailable();
}

// As I couldn't specify multiple groups for GroupDetectors, I am going down quite a complicated
// route - for every group distinct grouped workspace is created using GroupDetectors. These
// workspaces are then merged into the output workspace.

// Remove explicitly, so even if something goes wrong - old data is not used
AnalysisDataService::Instance().remove(outputWsName);
// If output workspace exists, remove explicitly, so even if something goes wrong - old data
// is not used
if(AnalysisDataService::Instance().doesExist(outputWsName))
{
// Using DeleteWorkspace algorithm so if outputWs is a group - it is fully removed
Mantid::API::IAlgorithm_sptr rmWs = AlgorithmManager::Instance().create("DeleteWorkspace");
rmWs->initialize();
rmWs->setPropertyValue("Workspace", outputWsName);
rmWs->execute();
}

Grouping g;
parseGroupingTable(m_uiForm, g);
Grouping tableGrouping;
parseGroupingTable(m_uiForm, tableGrouping);

// Retrieve input workspace
MatrixWorkspace_sptr inputWs =
boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(inputWsName));
if(!inputWs)
throw std::invalid_argument("Input workspace is not a MatrixWorkspace");
Workspace_sptr inputWs = AnalysisDataService::Instance().retrieve(inputWsName);

// Create resulting workspace
MatrixWorkspace_sptr outputWs =
WorkspaceFactory::Instance().create(inputWs, g.groups.size(), inputWs->readX(0).size(), inputWs->blocksize());
Workspace_sptr outputWs;

try
try // ... to group
{
for(size_t gi = 0; gi < g.groups.size(); gi++)
// Single workspace
if(MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>(inputWs))
{
Mantid::API::IAlgorithm_sptr alg = AlgorithmManager::Instance().create("GroupDetectors");
alg->setChild(true); // So Output workspace is not added to the ADS
alg->initialize();
alg->setProperty("InputWorkspace", inputWs);
alg->setPropertyValue("SpectraList", g.groups[gi]);
alg->setPropertyValue("OutputWorkspace", "grouped" + boost::lexical_cast<std::string>(gi)); // Is not actually used, just to make validators happy
alg->execute();

MatrixWorkspace_sptr grouped = alg->getProperty("OutputWorkspace");
outputWs = groupWorkspace(ws, tableGrouping);
}
// Workspace group
else if(WorkspaceGroup_sptr group = boost::dynamic_pointer_cast<WorkspaceGroup>(inputWs))
{
// Create output group
WorkspaceGroup_sptr outputGroup = boost::make_shared<WorkspaceGroup>();

for(size_t i = 0; i < group->size(); i++)
{
if(MatrixWorkspace_sptr member = boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(i)))
{
MatrixWorkspace_sptr groupedMember = groupWorkspace(member, tableGrouping);

// Update the spectra of output workspace
ISpectrum* s = grouped->getSpectrum(0);
s->setSpectrumNo(static_cast<specid_t>(gi));
*(outputWs->getSpectrum(gi)) = *s;
outputGroup->addWorkspace(groupedMember);
}
else
throw std::invalid_argument("Group contains unsupported workspace type");
}

//Copy to the output workspace
outputWs->dataY(gi) = grouped->readY(0);
outputWs->dataX(gi) = grouped->readX(0);
outputWs->dataE(gi) = grouped->readE(0);
outputWs = outputGroup;
}
else
throw std::invalid_argument("Unsupported workspace type");
}
catch(...)
catch(std::exception& e)
{
m_optionTab->noDataAvailable();
QMessageBox::warning(this, "MantidPlot - MuonAnalysis", "Can't group data file according to group-table. Plotting disabled.");
g_log.error(e.what());
return false;
}

Expand Down Expand Up @@ -2887,7 +2889,6 @@ void MuonAnalysis::startUpLook()
*/
void MuonAnalysis::setGroupingFromNexus(const QString& nexusFile)
{
// for now do try to set grouping from nexus file if it is already set
if ( isGroupingSet() )
return;

Expand Down
59 changes: 59 additions & 0 deletions Code/Mantid/MantidQt/CustomInterfaces/test/IO_MuonGroupingTest.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#ifndef MANTID_CUSTOMINTERFACES_IO_MUONGROUPINGTEST_H_
#define MANTID_CUSTOMINTERFACES_IO_MUONGROUPINGTEST_H_

#include <numeric>

#include <cxxtest/TestSuite.h>
#include <Poco/Path.h>
#include <Poco/File.h>

#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidQtCustomInterfaces/IO_MuonGrouping.h"

using namespace Mantid::API;
using namespace MantidQt::CustomInterfaces::Muon;

class IO_MuonGroupingTest : public CxxTest::TestSuite
Expand Down Expand Up @@ -39,6 +44,9 @@ class IO_MuonGroupingTest : public CxxTest::TestSuite
TSM_ASSERT("Unable to find AutoTestData directory", !m_testDataDir.empty());

m_tmpDir = ConfigService::Instance().getTempDir();

// To make sure API is initialized properly
FrameworkManager::Instance();
}

void test_loadGroupingFromXML()
Expand Down Expand Up @@ -110,10 +118,61 @@ class IO_MuonGroupingTest : public CxxTest::TestSuite
Poco::File(tmpFile).remove();
}

void test_groupWorkspace()
{
// Load grouping for MUSR
Grouping g;
TS_ASSERT_THROWS_NOTHING(loadGroupingFromXML(m_testDataDir + "MUSRGrouping.xml", g));

// Load MUSR data file
IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("LoadMuonNexus");
loadAlg->setChild(true); // So outptu ws don't end up in the ADS
loadAlg->initialize();
loadAlg->setPropertyValue("Filename", m_testDataDir + "MUSR00015189.nxs");
loadAlg->setPropertyValue("OutputWorkspace", "data"); // Is not used, just for validator
loadAlg->execute();

Workspace_sptr loadedWs = loadAlg->getProperty("OutputWorkspace");
WorkspaceGroup_sptr loadedGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(loadedWs);
MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast<MatrixWorkspace>(loadedGroup->getItem(0));

// Group the loaded workspace using loaded grouping
MatrixWorkspace_sptr gWs; // Grouped workspace
TS_ASSERT_THROWS_NOTHING(gWs = groupWorkspace(ws, g));
TS_ASSERT(gWs);

if(!gWs)
return;

// Check that was grouped properly
TS_ASSERT_EQUALS(gWs->getNumberHistograms(), 2);

TS_ASSERT_EQUALS(gWs->getSpectrum(0)->getDetectorIDs(), setFromRange(33, 64));
TS_ASSERT_EQUALS(gWs->getSpectrum(1)->getDetectorIDs(), setFromRange(1, 32));

TS_ASSERT_EQUALS(std::accumulate(gWs->readY(0).begin(), gWs->readY(0).end(), 0.0), 355655);
TS_ASSERT_DELTA(std::accumulate(gWs->readX(0).begin(), gWs->readX(0).end(), 0.0), 30915.5, 0.1);
TS_ASSERT_DELTA(std::accumulate(gWs->readE(0).begin(), gWs->readE(0).end(), 0.0), 14046.9, 0.1);

TS_ASSERT_EQUALS(std::accumulate(gWs->readY(1).begin(), gWs->readY(1).end(), 0.0), 262852);
TS_ASSERT_EQUALS(gWs->readX(1), gWs->readX(0));
TS_ASSERT_DELTA(std::accumulate(gWs->readE(1).begin(), gWs->readE(1).end(), 0.0), 12079.8, 0.1);
}

private:
std::string m_testDataDir;
std::string m_tmpDir;

std::set<int> setFromRange(int from, int to)
{
std::set<int> result;

for(int i = from; i <= to; i++)
result.insert(i);

return result;
}

};


Expand Down

0 comments on commit 379c3c2

Please sign in to comment.