Skip to content

Commit

Permalink
Refs #8550. Returning Detector Grouping from LoadMuonNexus.
Browse files Browse the repository at this point in the history
Plus tests for it.
  • Loading branch information
arturbekasov committed Dec 5, 2013
1 parent f9c77d1 commit 69ea041
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 1 deletion.
Expand Up @@ -108,6 +108,14 @@ namespace Mantid
/// Creates Dead Time Table using all the data between begin and end
TableWorkspace_sptr createDeadTimeTable(std::vector<double>::const_iterator begin,
std::vector<double>::const_iterator end);

/// Loads detector grouping information
void loadDetectorGrouping(Mantid::NeXus::NXRoot& root);

/// Creates Detector Grouping Table using all the data from the range
TableWorkspace_sptr createDetectorGroupingTable(std::vector<int>::const_iterator begin,
std::vector<int>::const_iterator end);

};

} // namespace DataHandling
Expand Down
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/DataHandling/src/LoadMuonNexus.cpp
Expand Up @@ -91,6 +91,9 @@ namespace Mantid

declareProperty(new WorkspaceProperty<Workspace>("DeadTimeTable", "", Direction::Output, PropertyMode::Optional),
"Table or a group of tables containing detector dead times");

declareProperty(new WorkspaceProperty<Workspace>("DetectorGroupingTable", "", Direction::Output, PropertyMode::Optional),
"Table or a group of tables with information about the detector grouping stored in the file (if any)");
}

/// Validates the optional 'spectra to read' properties, if they have been set
Expand Down
96 changes: 95 additions & 1 deletion Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp
Expand Up @@ -170,9 +170,12 @@ namespace Mantid
m_numberOfPeriods = nxload.t_nper;
}

// When we know number of periods and spectra - we can load dead times
// Try to load dead time info
loadDeadTimes(root);

// Try to load detector grouping info
loadDetectorGrouping(root);

// Need to extract the user-defined output workspace name
Property *ws = getProperty("OutputWorkspace");
std::string localWSName = ws->value();
Expand Down Expand Up @@ -520,6 +523,64 @@ namespace Mantid
// error
}

/**
* Loads detector grouping.
* @param root :: Root entry of the Nexus file to read from
*/
void LoadMuonNexus1::loadDetectorGrouping(NXRoot& root)
{
if ( getPropertyValue("DetectorGroupingTable").empty() )
return;

NXEntry dataEntry = root.openEntry("run/histogram_data_1");

NXInfo infoGrouping = dataEntry.getDataSetInfo("grouping");
if ( infoGrouping.stat != NX_ERROR )
{
NXInt groupingData = dataEntry.openNXInt("grouping");
groupingData.load();

int numGroupingEntries = groupingData.dim0();

std::vector<int> grouping;
grouping.reserve(numGroupingEntries);

for ( int i = 0; i < numGroupingEntries; i++ )
grouping.push_back(groupingData[i]);

if ( numGroupingEntries < m_numberOfSpectra )
{
throw Exception::FileError("Number of grouping entries is less than number of spectra",
m_filename);
}
else if ( numGroupingEntries == m_numberOfSpectra)
{
// Simpliest case - one grouping entry per spectra
TableWorkspace_sptr table = createDetectorGroupingTable( grouping.begin(), grouping.end() );
setProperty("DetectorGroupingTable", table);
}
else
{
// More complex case - grouping information for every period

if ( numGroupingEntries != m_numberOfSpectra * m_numberOfPeriods )
{
throw Exception::FileError("Number of grouping entries doesn't cover every spectra in every period",
m_filename);
}

WorkspaceGroup_sptr tableGroup = boost::make_shared<WorkspaceGroup>();

for ( auto it = grouping.begin(); it != grouping.end(); it += m_numberOfSpectra )
{
tableGroup->addWorkspace( createDetectorGroupingTable(it, it + m_numberOfSpectra) );
}

setProperty("DetectorGroupingTable", tableGroup);
}
}
}

/**
* Creates Dead Time Table using all the data between begin and end.
*
Expand Down Expand Up @@ -547,6 +608,39 @@ namespace Mantid
return deadTimeTable;
}

/**
* Creates Detector Grouping Table using all the data between begin and end.
*
* @param begin :: Iterator to the first element of the data to use
* @param end :: Iterator to the last element of the data to use
* @return Detector Grouping Table create using the data
*/
TableWorkspace_sptr LoadMuonNexus1::createDetectorGroupingTable(
std::vector<int>::const_iterator begin, std::vector<int>::const_iterator end)
{
auto detectorGroupingTable = boost::dynamic_pointer_cast<TableWorkspace>(
WorkspaceFactory::Instance().createTable("TableWorkspace") );

detectorGroupingTable->addColumn("str", "ItemType");
detectorGroupingTable->addColumn("str", "ItemName");
detectorGroupingTable->addColumn("vector_int", "Elements");

std::map<int, std::vector<int>> grouping;

for ( auto it = begin; it != end; ++it )
{
grouping[*it].push_back( static_cast<int>( std::distance(begin,it) ) );
}

for ( auto it = grouping.begin(); it != grouping.end(); ++it )
{
TableRow newRow = detectorGroupingTable->appendRow();
newRow << "Group" << boost::lexical_cast<std::string>(it->first) << it->second;
}

return detectorGroupingTable;
}

/** Load in a single spectrum taken from a NeXus file
* @param tcbs :: The vector containing the time bin boundaries
* @param hist :: The workspace index
Expand Down
138 changes: 138 additions & 0 deletions Code/Mantid/Framework/DataHandling/test/LoadMuonNexus1Test.h
Expand Up @@ -492,7 +492,145 @@ class LoadMuonNexus1Test : public CxxTest::TestSuite
AnalysisDataService::Instance().deepRemoveGroup(outWSName);
AnalysisDataService::Instance().deepRemoveGroup(deadTimesWSName);
}

void test_loadingDetectorGrouping_singlePeriod()
{
const std::string outWSName = "LoadMuonNexus1Test_OutputWS";
const std::string detectorGroupingWSName = "LoadMuonNexus1Test_DetectorGrouping";

LoadMuonNexus1 alg;

TS_ASSERT_THROWS_NOTHING( alg.initialize() );
TS_ASSERT( alg.isInitialized() );

TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", "emu00006473.nxs") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("DetectorGroupingTable", detectorGroupingWSName) );

TS_ASSERT_THROWS_NOTHING( alg.execute() );
TS_ASSERT( alg.isExecuted() );

TableWorkspace_sptr detectorGrouping;

TS_ASSERT_THROWS_NOTHING( detectorGrouping =
AnalysisDataService::Instance().retrieveWS<TableWorkspace>( detectorGroupingWSName ) );

TS_ASSERT( detectorGrouping );

if ( detectorGrouping )
{
TS_ASSERT_EQUALS( detectorGrouping->columnCount(), 3 );
TS_ASSERT_EQUALS( detectorGrouping->rowCount(), 2 );

TS_ASSERT_EQUALS( detectorGrouping->getColumn(0)->type(), "str" );
TS_ASSERT_EQUALS( detectorGrouping->getColumn(1)->type(), "str" );
TS_ASSERT_EQUALS( detectorGrouping->getColumn(2)->type(), "vector_int" );

TS_ASSERT_EQUALS( detectorGrouping->getColumn(0)->name(), "ItemType" );
TS_ASSERT_EQUALS( detectorGrouping->getColumn(1)->name(), "ItemName" );
TS_ASSERT_EQUALS( detectorGrouping->getColumn(2)->name(), "Elements" );

TS_ASSERT_EQUALS( detectorGrouping->cell<std::string>(0,0), "Group" );
TS_ASSERT_EQUALS( detectorGrouping->cell<std::string>(1,0), "Group" );

TS_ASSERT_EQUALS( detectorGrouping->cell<std::string>(0,1), "1" );
TS_ASSERT_EQUALS( detectorGrouping->cell<std::string>(1,1), "2" );

std::vector<int> e1, e2;
TS_ASSERT_THROWS_NOTHING( e1 = detectorGrouping->cell< std::vector<int> >(0,2) );
TS_ASSERT_THROWS_NOTHING( e2 = detectorGrouping->cell< std::vector<int> >(1,2) );

TS_ASSERT_EQUALS( e1.size(), 16);
TS_ASSERT_EQUALS( e2.size(), 16);

TS_ASSERT_EQUALS( e1[0], 0 );
TS_ASSERT_EQUALS( e1[15], 15);

TS_ASSERT_EQUALS( e2[0], 16 );
TS_ASSERT_EQUALS( e2[15], 31 );
}

AnalysisDataService::Instance().remove(outWSName);
AnalysisDataService::Instance().remove(detectorGroupingWSName);
}

void test_loadingDetectorGrouping_multiPeriod()
{
const std::string outWSName = "LoadMuonNexus1Test_OutputWS";
const std::string detectorGroupingWSName = "LoadMuonNexus1Test_DetectorGrouping";

LoadMuonNexus1 alg;

TS_ASSERT_THROWS_NOTHING( alg.initialize() );
TS_ASSERT( alg.isInitialized() );

TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", "MUSR00015189.nxs") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("DetectorGroupingTable", detectorGroupingWSName) );

TS_ASSERT_THROWS_NOTHING( alg.execute() );
TS_ASSERT( alg.isExecuted() );

WorkspaceGroup_sptr detectorGrouping;

TS_ASSERT_THROWS_NOTHING( detectorGrouping =
AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( detectorGroupingWSName ) );

TS_ASSERT( detectorGrouping );

if ( detectorGrouping )
{
TS_ASSERT_EQUALS( detectorGrouping->size(), 2 );

TableWorkspace_sptr table1 = boost::dynamic_pointer_cast<TableWorkspace>( detectorGrouping->getItem(0) );
TS_ASSERT( table1 );

if ( table1 )
{
TS_ASSERT_EQUALS( table1->columnCount(), 3 );
TS_ASSERT_EQUALS( table1->rowCount(), 2 );

std::vector<int> e1, e2;
TS_ASSERT_THROWS_NOTHING( e1 = table1->cell< std::vector<int> >(0,2) );
TS_ASSERT_THROWS_NOTHING( e2 = table1->cell< std::vector<int> >(1,2) );

TS_ASSERT_EQUALS( e1.size(), 32);
TS_ASSERT_EQUALS( e2.size(), 32);

TS_ASSERT_EQUALS( e1[0], 32 );
TS_ASSERT_EQUALS( e1[31], 63 );

TS_ASSERT_EQUALS( e2[0], 0 );
TS_ASSERT_EQUALS( e2[31], 31 );
}

TableWorkspace_sptr table2 = boost::dynamic_pointer_cast<TableWorkspace>( detectorGrouping->getItem(1) );
TS_ASSERT( table2 );

if ( table2 )
{
TS_ASSERT_EQUALS( table2->columnCount(), 3 );
TS_ASSERT_EQUALS( table2->rowCount(), 2 );

std::vector<int> e1, e2;
TS_ASSERT_THROWS_NOTHING( e1 = table2->cell< std::vector<int> >(0,2) );
TS_ASSERT_THROWS_NOTHING( e2 = table2->cell< std::vector<int> >(1,2) );

TS_ASSERT_EQUALS( e1.size(), 32);
TS_ASSERT_EQUALS( e2.size(), 32);

TS_ASSERT_EQUALS( e1[0], 32 );
TS_ASSERT_EQUALS( e1[31], 63 );

TS_ASSERT_EQUALS( e2[0], 0 );
TS_ASSERT_EQUALS( e2[31], 31);

}
}

AnalysisDataService::Instance().deepRemoveGroup(outWSName);
AnalysisDataService::Instance().deepRemoveGroup(detectorGroupingWSName);
}
private:
LoadMuonNexus1 nxLoad,nxload2,nxload3;
std::string outputSpace;
Expand Down

0 comments on commit 69ea041

Please sign in to comment.