Skip to content

Commit

Permalink
Started to add logic to use detector pars from table.
Browse files Browse the repository at this point in the history
refs #9880
  • Loading branch information
stuartcampbell committed Aug 29, 2014
1 parent 8584164 commit e174dac
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 25 deletions.
88 changes: 71 additions & 17 deletions Code/Mantid/Framework/Algorithms/src/ConvertUnits.cpp
Expand Up @@ -3,6 +3,7 @@
//----------------------------------------------------------------------
#include "MantidAlgorithms/ConvertUnits.h"
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/AlgorithmFactory.h"
#include "MantidAPI/Run.h"
#include "MantidKernel/UnitFactory.h"
Expand Down Expand Up @@ -73,7 +74,7 @@ void ConvertUnits::init()
"If true (default is false), rebins after conversion to ensure that all spectra in the output workspace\n"
"have identical bin boundaries. This option is not recommended (see http://www.mantidproject.org/ConvertUnits).");

declareProperty(new WorkspaceProperty<TableWorkspace>("DetectorParameters", "", Direction::Input, PropertyMode::Optional),
declareProperty(new WorkspaceProperty<ITableWorkspace>("DetectorParameters", "", Direction::Input, PropertyMode::Optional),
"Name of a TableWorkspace containing the detector parameters to use instead of the IDF.");
}

Expand All @@ -88,8 +89,6 @@ void ConvertUnits::exec()
MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
this->setupMemberVariables(inputWS);

TableWorkspace_sptr paramWS = getProperty("DetectorParameters");

// Check that the input workspace doesn't already have the desired unit.
if (m_inputUnit->unitID() == m_outputUnit->unitID())
{
Expand Down Expand Up @@ -355,7 +354,24 @@ void ConvertUnits::convertQuickly(API::MatrixWorkspace_sptr outputWS, const doub
void ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWorkspace_sptr outputWS)
{
using namespace Geometry;


// Let's see if we are using a TableWorkspace to override parameters
ITableWorkspace_sptr paramWS = getProperty("DetectorParameters");
bool usingDetPars = false;
bool usingDetParsL1 = false;
ColumnVector<int> detPars_spectra = paramWS->getVector("spectra");
ColumnVector<double> detPars_l2 = paramWS->getVector("l2");
ColumnVector<double> detPars_twotheta = paramWS->getVector("twotheta");
ColumnVector<double> detPars_efixed = paramWS->getVector("efixed");
ColumnVector<int> detPars_emode = paramWS->getVector("emode");

if ( paramWS != NULL )
{
usingDetPars = true;
g_log.notice() << "Size of table == " << paramWS->rowCount() << std::endl;

}

EventWorkspace_sptr eventWS = boost::dynamic_pointer_cast<EventWorkspace>(outputWS);
assert ( static_cast<bool>(eventWS) == m_inputEvents ); // Sanity check

Expand All @@ -375,20 +391,42 @@ void ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWo
IComponent_const_sptr sample = instrument->getSample();
if ( source == NULL || sample == NULL )
{
throw Exception::InstrumentDefinitionError("Instrument not sufficiently defined: failed to get source and/or sample");
// Now lets check to see if we are using a DetectorParameters TableWorkspace
if (usingDetPars)
{
try
{
ColumnVector<double> detPars_l1 = paramWS->getVector("l1");
usingDetParsL1 = true;
}
catch (...)
{
usingDetParsL1 = false;
throw Exception::InstrumentDefinitionError
("When using a TableWorkspace to define Detector Parameters for a workspace with no instrument, you need to define l1");
}
}
else
{
throw Exception::InstrumentDefinitionError("Instrument not sufficiently defined: failed to get source and/or sample");
}
}
double l1;
try
{
l1 = source->getDistance(*sample);
g_log.debug() << "Source-sample distance: " << l1 << std::endl;
}
catch (Exception::NotFoundError &)

if (!usingDetParsL1)
{
g_log.error("Unable to calculate source-sample distance");
throw Exception::InstrumentDefinitionError("Unable to calculate source-sample distance", outputWS->getTitle());
// Only try and get the L1 from the instrument if we have not overriden it!
try
{
l1 = source->getDistance(*sample);
g_log.debug() << "Source-sample distance: " << l1 << std::endl;
}
catch (Exception::NotFoundError &)
{
g_log.error("Unable to calculate source-sample distance");
throw Exception::InstrumentDefinitionError("Unable to calculate source-sample distance", outputWS->getTitle());
}
}

int failedDetectorCount = 0;

/// @todo No implementation for any of these in the geometry yet so using properties
Expand Down Expand Up @@ -449,6 +487,8 @@ void ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWo
PARALLEL_START_INTERUPT_REGION
double efixed = efixedProp;

std::size_t wsid = i;

try
{
// Now get the detector object for this histogram
Expand Down Expand Up @@ -491,21 +531,30 @@ void ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWo
}
}

// Are we using a Detector Parameter workspace to override values
if (usingDetPars)
{
wsid = outputWS->getIndexFromSpectrumNumber(detPars_spectra[i]);
std::cout << "###### Spectra #" << detPars_spectra[i] << " ==> Workspace ID:" << wsid << std::endl;
//l2 = paramWS->getVector("")

}

// Make local copies of the units. This allows running the loop in parallel
Unit * localFromUnit = fromUnit->clone();
Unit * localOutputUnit = outputUnit->clone();

/// @todo Don't yet consider hold-off (delta)
const double delta = 0.0;
// Convert the input unit to time-of-flight
localFromUnit->toTOF(outputWS->dataX(i),emptyVec,l1,l2,twoTheta,emode,efixed,delta);
localFromUnit->toTOF(outputWS->dataX(wsid),emptyVec,l1,l2,twoTheta,emode,efixed,delta);
// Convert from time-of-flight to the desired unit
localOutputUnit->fromTOF(outputWS->dataX(i),emptyVec,l1,l2,twoTheta,emode,efixed,delta);
localOutputUnit->fromTOF(outputWS->dataX(wsid),emptyVec,l1,l2,twoTheta,emode,efixed,delta);

// EventWorkspace part, modifying the EventLists.
if ( m_inputEvents )
{
eventWS->getEventList(i).convertUnitsViaTof(localFromUnit, localOutputUnit);
eventWS->getEventList(wsid).convertUnitsViaTof(localFromUnit, localOutputUnit);

// std::vector<double> tofs;
// eventWS->getEventList(i).getTofs(tofs);
Expand Down Expand Up @@ -538,6 +587,11 @@ void ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWo
eventWS->clearMRU();
}






/// Calls Rebin as a Child Algorithm to align the bins
API::MatrixWorkspace_sptr ConvertUnits::alignBins(API::MatrixWorkspace_sptr workspace)
{
Expand Down
19 changes: 11 additions & 8 deletions Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h
Expand Up @@ -188,7 +188,8 @@ class ConvertUnitsTest : public CxxTest::TestSuite
void testConvertUsingDetectorTable()
{
ConvertUnits myAlg;
TS_ASSERT_THROWS_NOTHING(myAlg.initialize());
myAlg.initialize();
TS_ASSERT(myAlg.isInitialized());

const std::string workspaceName("_ws_testConvertUsingDetectorTable");
int nBins = 10;
Expand All @@ -199,35 +200,37 @@ class ConvertUnitsTest : public CxxTest::TestSuite

// Create TableWorkspace with values in it

TableWorkspace_sptr pars = boost::shared_ptr<TableWorkspace>(new TableWorkspace());
ITableWorkspace_sptr pars = WorkspaceFactory::Instance().createTable("TableWorkspace");
pars->addColumn("int", "spectra");
pars->addColumn("double", "l1");
pars->addColumn("double", "l2");
pars->addColumn("double", "twotheta");
pars->addColumn("double", "efixed");
pars->addColumn("int", "emode");

API::TableRow row0 = pars->appendRow();
row0 << 1 << 10.0 << 90.0 << 7.0 << 1;
// row0 << 1 << 10.0 << 90.0 << 7.0 << 1;
row0 << 1 << 50.0 << 10.0 << 90.0 << 7.0 << 1;

API::TableRow row1 = pars->appendRow();
row1 << 2 << 10.0 << 90.0 << 7.0 << 1;
// row1 << 2 << 10.0 << 90.0 << 7.0 << 1;
row1 << 2 << 50.0 << 10.0 << 90.0 << 7.0 << 1;

// Set the properties
myAlg.setRethrows(true);
myAlg.setPropertyValue("InputWorkspace", workspaceName);
myAlg.setPropertyValue("OutputWorkspace", workspaceName);
myAlg.setPropertyValue("Target", "Wavelength");
std::cout << "Got here" << std::endl;
myAlg.setProperty("DetectorParameters", pars);

//alg.execute();
myAlg.execute();

//auto outWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(workspaceName);
auto outWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(workspaceName);

// TODO: test that output workspace values


//AnalysisDataService::Instance().remove(workspaceName);
AnalysisDataService::Instance().remove(workspaceName);
}

void testConvertQuickly()
Expand Down

0 comments on commit e174dac

Please sign in to comment.