diff --git a/Code/Mantid/Framework/Algorithms/src/ConvertUnits.cpp b/Code/Mantid/Framework/Algorithms/src/ConvertUnits.cpp index 913692559c78..985841dbdb29 100644 --- a/Code/Mantid/Framework/Algorithms/src/ConvertUnits.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ConvertUnits.cpp @@ -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" @@ -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("DetectorParameters", "", Direction::Input, PropertyMode::Optional), + declareProperty(new WorkspaceProperty("DetectorParameters", "", Direction::Input, PropertyMode::Optional), "Name of a TableWorkspace containing the detector parameters to use instead of the IDF."); } @@ -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()) { @@ -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 detPars_spectra = paramWS->getVector("spectra"); + ColumnVector detPars_l2 = paramWS->getVector("l2"); + ColumnVector detPars_twotheta = paramWS->getVector("twotheta"); + ColumnVector detPars_efixed = paramWS->getVector("efixed"); + ColumnVector 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(outputWS); assert ( static_cast(eventWS) == m_inputEvents ); // Sanity check @@ -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 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 @@ -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 @@ -491,6 +531,15 @@ 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(); @@ -498,14 +547,14 @@ void ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWo /// @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 tofs; // eventWS->getEventList(i).getTofs(tofs); @@ -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) { diff --git a/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h b/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h index c703d306710b..18527c001e63 100644 --- a/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ConvertUnitsTest.h @@ -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; @@ -199,35 +200,37 @@ class ConvertUnitsTest : public CxxTest::TestSuite // Create TableWorkspace with values in it - TableWorkspace_sptr pars = boost::shared_ptr(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(workspaceName); + auto outWS = AnalysisDataService::Instance().retrieveWS(workspaceName); // TODO: test that output workspace values - //AnalysisDataService::Instance().remove(workspaceName); + AnalysisDataService::Instance().remove(workspaceName); } void testConvertQuickly()