@@ -0,0 +1,109 @@
#include "MantidAlgorithms/MaskBinsFromTable.h"
#include "MantidKernel/System.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/TableRow.h"

using namespace Mantid::Kernel;
using namespace Mantid::API;

namespace Mantid
{
namespace Algorithms
{


//----------------------------------------------------------------------------------------------
/** Constructor
*/
MaskBinsFromTable::MaskBinsFromTable()
{
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
MaskBinsFromTable::~MaskBinsFromTable()
{
}

void MaskBinsFromTable::initDocs()
{
this->setWikiSummary("Mask bins from a table workspace. ");
this->setOptionalMessage("Mask bins from a table workspace. ");
}

void MaskBinsFromTable::init()
{
this->declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input, boost::make_shared<HistogramValidator>()),
"Input Workspace to mask bins. ");
this->declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output),
"Output Workspace with bins masked.");
this->declareProperty(new WorkspaceProperty<DataObjects::TableWorkspace>("MaskingInformation", "", Direction::Input),
"Input TableWorkspace containing parameters, SpectraList, XMin and XMax.");

return;
}

void MaskBinsFromTable::exec()
{
MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
DataObjects::TableWorkspace_sptr paramWS = getProperty("MaskingInformation");

// 1. Check input table workspace
g_log.debug() << "Lines of parameters workspace = " << paramWS->rowCount() << std::endl;

// 2. Loop over all rows
bool firstloop = true;
API::MatrixWorkspace_sptr outputws;

for (size_t ib = 0; ib < paramWS->rowCount(); ++ib)
{
API::TableRow therow = paramWS->getRow(ib);
double xmin, xmax;
std::string speclist;
therow >> xmin >> xmax >> speclist;

g_log.debug() << "Row " << ib << " XMin = " << xmin << " XMax = " << xmax << " SpectraList = " << speclist << std::endl;

API::IAlgorithm_sptr maskbins = this->createSubAlgorithm("MaskBins", 0, 0.3, true);
maskbins->initialize();
if (firstloop)
{
maskbins->setPropertyValue("InputWorkspace", this->getPropertyValue("InputWorkspace"));
firstloop = false;
}
else
{
maskbins->setProperty("InputWorkspace", outputws);
}
maskbins->setProperty("OutputWorkspace", this->getPropertyValue("OutputWorkspace"));
maskbins->setPropertyValue("SpectraList", speclist);
maskbins->setProperty("XMin", xmin);
maskbins->setProperty("XMax", xmax);

bool isexec = maskbins->execute();
if (!isexec)
{
g_log.error() << "MaskBins() is not executed for row " << ib << std::endl;
throw std::runtime_error("MaskBins() is not executed");
}

outputws = maskbins->getProperty("OutputWorkspace");
if (!outputws)
{
g_log.error() << "OutputWorkspace is not retrieved for row " << ib << ". " << std::endl;
throw std::runtime_error("OutputWorkspace is not got from MaskBins");
}
}

setProperty("OutputWorkspace", outputws);

return;
}



} // namespace Mantid
} // namespace Algorithms
@@ -99,7 +99,6 @@ void RemoveBins::exec()
// If the X range has been given in a different unit, or if the workspace isn't square, then we will need
// to calculate the bin indices to cut out each time.
const std::string rangeUnit = getProperty("RangeUnit");
const std::string inputUnit = m_inputWorkspace->getAxis(0)->unit()->unitID();
const bool unitChange = (rangeUnit != "AsInput" && rangeUnit != "inputUnit");
if (unitChange) m_rangeUnit = UnitFactory::Instance().create(rangeUnit);
const bool commonBins = WorkspaceHelpers::commonBoundaries(m_inputWorkspace);
@@ -168,12 +168,12 @@ void TOFSANSResolution::exec()

for (itev = el.getWeightedEvents().begin(); itev != itev_end; ++itev)
{
if ( boost::math::isnan(itev->m_weight) ) continue;
if (std::abs(itev->m_weight) == std::numeric_limits<double>::infinity()) continue;
if ( !isEmpty(min_wl) && itev->m_tof < min_wl ) continue;
if ( !isEmpty(max_wl) && itev->m_tof > max_wl ) continue;
if ( boost::math::isnan(itev->weight()) ) continue;
if (std::abs(itev->weight()) == std::numeric_limits<double>::infinity()) continue;
if ( !isEmpty(min_wl) && itev->tof() < min_wl ) continue;
if ( !isEmpty(max_wl) && itev->tof() > max_wl ) continue;

const double q = factor/itev->m_tof;
const double q = factor/itev->tof();
int iq = 0;

// Bin assignment depends on whether we have log or linear bins
@@ -189,16 +189,16 @@ void TOFSANSResolution::exec()
const double dTheta2 = ( 3.0*R1*R1/(L1*L1) + 3.0*R2*R2*src_to_pixel*src_to_pixel/(L1*L1*L2*L2)
+ 2.0*(pixel_size_x*pixel_size_x+pixel_size_y*pixel_size_y)/(L2*L2) )/12.0;

const double dwl_over_wl = 3.9560*getTOFResolution(itev->m_tof)/(1000.0*(L1+L2)*itev->m_tof);
const double dwl_over_wl = 3.9560*getTOFResolution(itev->tof())/(1000.0*(L1+L2)*itev->tof());
const double dq_over_q = std::sqrt(dTheta2/(theta*theta)+dwl_over_wl*dwl_over_wl);

PARALLEL_CRITICAL(iq) /* Write to shared memory - must protect */
if (iq>=0 && iq < xLength-1 && !boost::math::isnan(dq_over_q) && dq_over_q>0)
{
DxOut[iq] += q*dq_over_q*itev->m_weight;
XNorm[iq] += itev->m_weight;
TOFY[iq] += q*std::fabs(dwl_over_wl)*itev->m_weight;
ThetaY[iq] += q*std::sqrt(dTheta2)/theta*itev->m_weight;
DxOut[iq] += q*dq_over_q*itev->weight();
XNorm[iq] += itev->weight();
TOFY[iq] += q*std::fabs(dwl_over_wl)*itev->weight();
ThetaY[iq] += q*std::sqrt(dTheta2)/theta*itev->weight();
}
}

@@ -188,7 +188,7 @@ namespace Mantid
{
double yout,eout;
// Call the abstract function, passing in the current values
performUnaryOperation(it->m_tof,it->m_weight,std::sqrt(it->m_errorSquared),yout,eout);
performUnaryOperation(it->tof(),it->weight(),std::sqrt(it->errorSquared()),yout,eout);
it->m_weight=static_cast<float>(yout);
it->m_errorSquared=static_cast<float>(eout*eout);
}
@@ -154,8 +154,8 @@ class CorrectKiKfTest : public CxxTest::TestSuite
TS_ASSERT( out_ws );
if (!out_ws) return;

TS_ASSERT_DELTA(out_ws->getEventList(0).getEvent(0).m_weight,std::sqrt(3./(3.-out_ws->getEventList(0).getEvent(0).m_tof)),1e-7);
TS_ASSERT_DELTA(out_ws->getEventList(0).getEvent(3).m_weight,std::sqrt(3./(3.-out_ws->getEventList(0).getEvent(3).m_tof)),1e-7);
TS_ASSERT_DELTA(out_ws->getEventList(0).getEvent(0).weight(),std::sqrt(3./(3.-out_ws->getEventList(0).getEvent(0).tof())),1e-7);
TS_ASSERT_DELTA(out_ws->getEventList(0).getEvent(3).weight(),std::sqrt(3./(3.-out_ws->getEventList(0).getEvent(3).tof())),1e-7);
TS_ASSERT_LESS_THAN(out_ws->getNumberEvents( ),in_ws->getNumberEvents( )); //Check that events with Ef<0 are dropped


@@ -120,7 +120,7 @@ class FilterEventsHighFrequencyTest : public CxxTest::TestSuite
for (size_t i = 0; i < events0.getNumberEvents(); i ++){
DataObjects::WeightedEvent e0 = events0.getEvent(i);
int64_t abstime2 = e0.pulseTime().totalNanoseconds()+static_cast<int64_t>(e0.tof()*1000.0);
std::cout << "Selected Event " << i << " = " << e0.pulseTime() << ", " << e0.m_tof << " / " << abstime2<< std::endl;
std::cout << "Selected Event " << i << " = " << e0.pulseTime() << ", " << e0.tof() << " / " << abstime2<< std::endl;
}

DataObjects::WeightedEvent e0;
@@ -234,7 +234,7 @@ class FilterEventsHighFrequencyTest : public CxxTest::TestSuite
for (size_t i = 0; i < events0.getNumberEvents(); i ++){
DataObjects::WeightedEvent e0 = events0.getEvent(i);
int64_t abstime2 = e0.pulseTime().totalNanoseconds()+static_cast<int64_t>(e0.tof()*1000.0);
std::cout << "Selected Event " << i << " = " << e0.pulseTime() << ", " << e0.m_tof << " / " << abstime2<< std::endl;
std::cout << "Selected Event " << i << " = " << e0.pulseTime() << ", " << e0.tof() << " / " << abstime2<< std::endl;
}

DataObjects::WeightedEvent e0;
@@ -340,7 +340,7 @@ class FilterEventsHighFrequencyTest : public CxxTest::TestSuite
for (size_t i = 0; i < events0.getNumberEvents(); i ++){
DataObjects::WeightedEvent e0 = events0.getEvent(i);
int64_t abstime2 = e0.pulseTime().totalNanoseconds()+static_cast<int64_t>(e0.tof()*1000.0);
std::cout << "Selected Event " << i << " = " << e0.pulseTime() << ", " << e0.m_tof << " / " << abstime2<< std::endl;
std::cout << "Selected Event " << i << " = " << e0.pulseTime() << ", " << e0.tof() << " / " << abstime2<< std::endl;
}

DataObjects::WeightedEvent e0;
@@ -441,9 +441,7 @@ class FilterEventsHighFrequencyTest : public CxxTest::TestSuite

for (size_t i = 0; i < numevents; i ++){
// a) generate an event
DataObjects::TofEvent event;
event.m_pulsetime = pulsetime;
event.m_tof = tof;
DataObjects::TofEvent event(tof,pulsetime);
tof += dtof;

// b) add event list
@@ -0,0 +1,227 @@
#ifndef MANTID_ALGORITHMS_MASKDETECTORBINSTEST_H_
#define MANTID_ALGORITHMS_MASKDETECTORBINSTEST_H_

#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
#include <iostream>
#include <iomanip>

#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include "MantidAlgorithms/MaskBinsFromTable.h"
#include "MantidAPI/TableRow.h"

using namespace Mantid;
using namespace Mantid::Algorithms;
using namespace Mantid::API;

class MaskBinsFromTableTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static MaskBinsFromTableTest *createSuite() { return new MaskBinsFromTableTest(); }
static void destroySuite( MaskBinsFromTableTest *suite ) { delete suite; }

/*
* In-place single mask test.
* Same as the test in MaskBins()
*/
void test_MaskBinWithSingleLine()
{
// 1. Create a dummy workspace
const std::string workspaceName("raggedMask");
int nBins = 10;
MatrixWorkspace_sptr WS = WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
AnalysisDataService::Instance().add(workspaceName,WS);

// 2. Generate a TableWorskpace
DataObjects::TableWorkspace_sptr tablews = boost::shared_ptr<DataObjects::TableWorkspace>(new DataObjects::TableWorkspace());
tablews->addColumn("double", "XMin");
tablews->addColumn("double", "XMax");
tablews->addColumn("str", "SpectraList");

API::TableRow row0 = tablews->appendRow();
row0 << 3.0 << 6.0 << "1-3";

// 3. Execute
MaskBinsFromTable maskalg;
TS_ASSERT_THROWS_NOTHING(maskalg.initialize());
maskalg.setPropertyValue("InputWorkspace", workspaceName);
maskalg.setPropertyValue("OutputWorkspace",workspaceName);
maskalg.setProperty("MaskingInformation", tablews);
TS_ASSERT_THROWS_NOTHING(maskalg.execute());
TS_ASSERT(maskalg.isExecuted());

// 4. Check
WS = boost::dynamic_pointer_cast<API::MatrixWorkspace>(AnalysisDataService::Instance().retrieve(workspaceName));
TS_ASSERT(WS);
for (int wi=1; wi<=3; wi++)
{
for (int bin=3; bin<6;bin++)
{
TS_ASSERT_EQUALS( WS->dataY(wi)[bin], 0.0 );
}
}

// 5. Clean
AnalysisDataService::Instance().remove(workspaceName);

return;
}

/*
* Out-of-place single mask test.
* Same as the test in MaskBins()
*/
void test_MaskBinWithSingleLineOutPlace()
{
// 1. Create a dummy workspace
const std::string workspaceName("raggedMask");
const std::string opWSName("maskedWorkspace");
int nBins = 10;
MatrixWorkspace_sptr WS = WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
AnalysisDataService::Instance().add(workspaceName,WS);

// 2. Generate a TableWorskpace
DataObjects::TableWorkspace_sptr tablews = boost::shared_ptr<DataObjects::TableWorkspace>(new DataObjects::TableWorkspace());
tablews->addColumn("double", "XMin");
tablews->addColumn("double", "XMax");
tablews->addColumn("str", "SpectraList");

API::TableRow row0 = tablews->appendRow();
row0 << 3.0 << 6.0 << "1-3";

// 3. Execute
MaskBinsFromTable maskalg;
TS_ASSERT_THROWS_NOTHING(maskalg.initialize());
maskalg.setPropertyValue("InputWorkspace", workspaceName);
maskalg.setPropertyValue("OutputWorkspace",opWSName);
maskalg.setProperty("MaskingInformation", tablews);
TS_ASSERT_THROWS_NOTHING(maskalg.execute());
TS_ASSERT(maskalg.isExecuted());

// 4. Check
MatrixWorkspace_sptr outWS =
boost::dynamic_pointer_cast<API::MatrixWorkspace>(AnalysisDataService::Instance().retrieve(opWSName));
TS_ASSERT(outWS);
for (int wi=1; wi<=3; wi++)
{
for (int bin=3; bin<6;bin++)
{
TS_ASSERT_EQUALS( outWS->dataY(wi)[bin], 0.0 );
}
}

// 5. Clean
AnalysisDataService::Instance().remove(workspaceName);
AnalysisDataService::Instance().remove(opWSName);

return;
}


/*
* Multiple lines out-of-place test.
* This is a real test
*/
void test_MaskBinWithMultiLines()
{
// 1. Create a dummy workspace
const std::string workspaceName("raggedMask");
int nBins = 10;
int nHist = 12;
MatrixWorkspace_sptr WS = WorkspaceCreationHelper::Create2DWorkspaceBinned(nHist, nBins, 0.0);
AnalysisDataService::Instance().add(workspaceName,WS);

// 2. Generate a TableWorskpace
DataObjects::TableWorkspace_sptr tablews = boost::shared_ptr<DataObjects::TableWorkspace>(new DataObjects::TableWorkspace());
tablews->addColumn("double", "XMin");
tablews->addColumn("double", "XMax");
tablews->addColumn("str", "SpectraList");

API::TableRow row0 = tablews->appendRow();
row0 << 3.0 << 6.0 << "1-3";
API::TableRow row1 = tablews->appendRow();
row1 << 4.0 << 7.0 << "5, 6-8";
API::TableRow row2 = tablews->appendRow();
row2 << 0.0 << 1.0 << "9";

// 3. Execute
MaskBinsFromTable maskalg;
TS_ASSERT_THROWS_NOTHING(maskalg.initialize());
maskalg.setPropertyValue("InputWorkspace", workspaceName);
maskalg.setPropertyValue("OutputWorkspace",workspaceName);
maskalg.setProperty("MaskingInformation", tablews);
TS_ASSERT_THROWS_NOTHING(maskalg.execute());
TS_ASSERT(maskalg.isExecuted());

// 4. Check
WS = boost::dynamic_pointer_cast<API::MatrixWorkspace>(AnalysisDataService::Instance().retrieve(workspaceName));
TS_ASSERT(WS);

// a) Table Line 0
for (int wi=1; wi<=3; wi++)
{
for (size_t bin = 0; bin < WS->dataY(wi).size(); ++bin)
{
if (bin >= 3 && bin < 6)
{
TS_ASSERT_EQUALS( WS->dataY(wi)[bin], 0.0 );
}
else
{
TS_ASSERT_EQUALS( WS->dataY(wi)[bin], 2.0 );
}
}
}

// b) Table Line 1
std::vector<int> speclist;
speclist.push_back(5);
speclist.push_back(6);
speclist.push_back(7);
speclist.push_back(8);
for (size_t iws = 0; iws < speclist.size(); ++iws)
{
const MantidVec& yvec = WS->readY(speclist[iws]);
for (size_t bin = 0; bin < yvec.size(); ++bin)
{
if (bin >= 4 && bin < 7)
{
TS_ASSERT_EQUALS(yvec[bin], 0.0);
}
else
{
TS_ASSERT_EQUALS(yvec[bin], 2.0);
}
}
}

// c) Table Line 2
for (size_t iws = 9; iws < 10; ++iws)
{
const MantidVec& yvec = WS->readY(iws);
for (size_t bin = 0; bin < yvec.size(); ++bin)
{
if (bin == 0)
{
TS_ASSERT_EQUALS(yvec[bin], 0.0);
}
else
{
TS_ASSERT_EQUALS(yvec[bin], 2.0);
}
}
}

// 5. Clean
AnalysisDataService::Instance().remove(workspaceName);

return;
}

};


#endif /* MANTID_ALGORITHMS_MASKDETECTORBINSTEST_H_ */
@@ -186,6 +186,58 @@ class MaskBinsTest : public CxxTest::TestSuite
AnalysisDataService::Instance().remove(workspaceName);
}

/*
* A more sserious check
*/
void testSpectraList_WS2D_OutPlace()
{
// Create a dummy workspace
const std::string workspaceName("raggedMask");
const std::string opWSName("maskedWS");

int nBins = 10;
MatrixWorkspace_sptr WS = WorkspaceCreationHelper::Create2DWorkspaceBinned(5,nBins,0.0);
AnalysisDataService::Instance().add(workspaceName,WS);

Mantid::Algorithms::MaskBins masker2;
masker2.initialize();
masker2.setPropertyValue("InputWorkspace",workspaceName);
masker2.setPropertyValue("OutputWorkspace",opWSName);
masker2.setPropertyValue("XMin","3.0");
masker2.setPropertyValue("XMax","6.0");
masker2.setPropertyValue("SpectraList","1-3");

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

// Get output workspace and compare
MatrixWorkspace_sptr outWS =
boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve(opWSName));
TS_ASSERT(outWS);
if (!outWS)
return;
TS_ASSERT_EQUALS(outWS->getNumberHistograms(), 5);

for (size_t wi = 0; wi < 5; ++ wi)
{
for (size_t bin = 0; bin < size_t(nBins); ++bin)
{
if (wi >= 1 && wi <= 3 && bin >= 3 && bin < 6)
{
TS_ASSERT_EQUALS( outWS->dataY(wi)[bin], 0.0 );
}
else
{
TS_ASSERT_EQUALS( outWS->dataY(wi)[bin], WS->dataY(wi)[bin] );
}
}
} // ENDFOR wi

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


void testEventWorkspace_SpectraList()
{
// Create a dummy workspace
@@ -218,6 +270,56 @@ class MaskBinsTest : public CxxTest::TestSuite
AnalysisDataService::Instance().remove(workspaceName);
}


/*
* A more serious test to compare all bins
*/
void testEventWorkspace_SpectraList_OutPlace()
{
// Create a dummy workspace
const std::string workspaceName("raggedMask");
const std::string opWSName("maskedWorkspace");

int nBins = 10;
int numHist = 5;
EventWorkspace_sptr WS = WorkspaceCreationHelper::CreateEventWorkspace(numHist, nBins) ;
AnalysisDataService::Instance().add(workspaceName,WS);

Mantid::Algorithms::MaskBins masker2;
masker2.initialize();
masker2.setPropertyValue("InputWorkspace",workspaceName);
masker2.setPropertyValue("OutputWorkspace",opWSName);
masker2.setPropertyValue("XMin","3.0");
masker2.setPropertyValue("XMax","6.0");
masker2.setPropertyValue("SpectraList","1-3");

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

EventWorkspace_const_sptr constWS =
boost::dynamic_pointer_cast<const EventWorkspace>(AnalysisDataService::Instance().retrieve(opWSName));

for (size_t wi = 0; wi < 5; ++ wi)
{
for (size_t bin = 0; bin < size_t(nBins); ++bin)
{
const MantidVec& Y = constWS->readY(wi);
const MantidVec& oY = WS->readY(wi);
if (wi >= 1 && wi <= 3 && bin >= 3 && bin < 6)
{
TS_ASSERT_EQUALS( Y[bin], 0.0 );
}
else
{
TS_ASSERT_EQUALS( Y[bin], oY[bin] );
}
}
} // ENDFOR wi

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

void testEventWorkspace_No_SpectraList()
{
// Create a dummy workspace
@@ -77,10 +77,10 @@ namespace Crystal
/**
* Refactors a rotation Q as a Rotation in x dir by Rotx * a Rotation in the y dir by Roty
* * a rotation in the z direction by Rotz
* @param Quat A rotation( a copy will be normalized)
* @param Q A rotation( a copy will be normalized)
* @ Rotx The angle in degrees for the rotation in x direction
* @ Roty The angle in degrees for the rotation in y direction
* @ Rotxz The angle in degrees for the rotation in z direction
* @ Rotz The angle in degrees for the rotation in z direction
*/
static void Quat2RotxRotyRotz(const Quat Q, double &Rotx,double &Roty,double &Rotz);

@@ -264,7 +264,7 @@ namespace Crystal
void CalcInitParams( RectangularDetector_const_sptr bank_rect,
Instrument_const_sptr instrument,
Instrument_const_sptr PreCalibinstrument,
double & detWidthScale0,double &detWidthHeight0,
double & detWidthScale0,double &detHeightScale0,
double &Xoffset0,double &Yoffset0,double &Zoffset0,
double &Xrot0,double &Yrot0,double &Zrot0);

@@ -300,7 +300,7 @@ namespace Crystal
* Saves the new instrument to an xml file that can be used with the
* LoadParameterFile Algorithm. If the filename is empty, nothing gets done.
*
* @parm FileName The filename to save this information to
* @param FileName The filename to save this information to
*
* @param Groups The names of the banks in each group whose values are
* to be saved to the file
@@ -36,7 +36,6 @@ The Parameters
<LI>f*_Xrot-Rotation(degrees) Panel Center in x axis direction</LI>
<LI>f*_Yrot-Rotation(degrees) Panel Center in y axis direction</LI>
<LI>f*_Zrot-Rotation(degrees) Panel Center in z axis direction</LI>
</UL>
<UL> Note that the order of rotations are z first, then y then x.</UL>
@@ -936,7 +936,7 @@ namespace Crystal

rotz = result[ prefix + "Zrot" ];

Quat newRelRot = Quat( rotx,V3D( 1,0,0))*Quat( roty,V3D( 0,1,0))*Quat( rotx,V3D( 0,0,1));//*RelRot;
Quat newRelRot = Quat( rotx,V3D( 1,0,0))*Quat( roty,V3D( 0,1,0))*Quat( rotz,V3D( 0,0,1));//*RelRot;

FixUpBankParameterMap( (*itv),
NewInstrument,
@@ -34,15 +34,16 @@ namespace Mantid
<LI> Mrow - The row of the center of the peak on this slice</LI>
<LI> SScol -The variance of the column values in the peak for this time slice </LI>
<LI> SSrow - The variance of the row values in the peak for this time slice </LI>
<LI> SSrc- The covariance of the row and column values in the peak for this time slice </LI>
</UL>
<LI> SSrc - The covariance of the row and column values in the peak for this time slice </LI>
</UL><P>
<UL>There is one attribute( This must be specified)
<LI> CalcVariances - <UL>If true,calculates SScol, SSrow, and SSrc from the experimental data
There is one attribute( This must be specified)
<UL>
<LI> CalcVariances - <UL>
If true,calculates SScol, SSrow, and SSrc from the experimental data
given Background, Mcol, and Mrow(if the parameter has not been tied)
If false, the parameters SScol, SSrow, and SSrc will be fit, unless
tied. </LI>
tied. </UL> </LI>
</UL>
@@ -76,7 +76,7 @@ void ParDomain::leastSquaresValDerivHessian(const CostFuncLeastSquares& leastSqu
{
throw std::runtime_error("LeastSquares: unsupported IFunctionValues.");
}
int k = PARALLEL_THREAD_NUMBER;
std::vector<API::IFunction_sptr>::size_type k = PARALLEL_THREAD_NUMBER;
PARALLEL_CRITICAL(resize)
{
if ( k >= funs.size() )
@@ -680,7 +680,7 @@ size_t GroupDetectors2::formGroups( API::MatrixWorkspace_const_sptr inputWS, API
}
}
if( nonMaskedSpectra == 0 ) ++nonMaskedSpectra; // Avoid possible divide by zero
requireDivide = (nonMaskedSpectra > 1);
if(!requireDivide) requireDivide = (nonMaskedSpectra > 1);
beh->dataY(outIndex)[0] = static_cast<double>(nonMaskedSpectra);

// make regular progress reports and check for cancelling the algorithm
@@ -98,12 +98,17 @@ namespace Mantid
}

int confidence(0);
if( filePath.compare(filePath.size()-12,12,"_runinfo.xml") == 0) return confidence;
if( filePath.compare(filePath.size()-12,12,"_runinfo.xml") == 0)
{
fclose(file);
return confidence;
}

if (isAscii(file))
{
confidence = 10; //Lower because should load other files first
}
fclose(file);
return confidence;
}

@@ -2069,13 +2069,13 @@ void LoadEventNexus::loadTimeOfFlightData(::NeXus::File& file, DataObjects::Even
{
double right = double(tof[i]);
// find the right boundary for the current event
if(ev != ev_end && right < ev->m_tof )
if(ev != ev_end && right < ev->tof() )
{
continue;
}
// count events which have the same right boundary
size_t m = 0;
while(ev != ev_end && ev->m_tof < right)
while(ev != ev_end && ev->tof() < right)
{
++ev;
++m; // count events in the i-th bin
@@ -143,7 +143,7 @@ const MantidVec LoadSassena::loadQvectors(const hid_t& h5file, API::WorkspaceGro
qvmod.push_back( sqrt( curr[0]*curr[0] + curr[1]*curr[1] + curr[2]*curr[2] ) );
curr += 3;
}
delete buf;
delete[] buf;
this->registerWorkspace(gws,wsName,ws, "X-axis: origin of Q-vectors; Y-axis: tip of Q-vectors");
return qvmod;
}
@@ -177,7 +177,7 @@ void LoadSassena::loadFQ(const hid_t& h5file, API::WorkspaceGroup_sptr gws, cons
im[iq]=curr[1];
curr += 2;
}
delete buf;
delete[] buf;
this->registerWorkspace(gws,wsName,ws, "X-axis: Q-vector modulus; Y-axis: intermediate structure factor");
}

@@ -226,7 +226,7 @@ void LoadSassena::loadFQT(const hid_t& h5file, API::WorkspaceGroup_sptr gws, con
curr ++;
}
}
delete buf;
delete[] buf;
this->registerWorkspace(gws,wsReName,wsRe, "X-axis: time; Y-axis: real part of intermediate structure factor");
this->registerWorkspace(gws,wsImName,wsIm, "X-axis: time; Y-axis: imaginary part of intermediate structure factor");
}
@@ -19,6 +19,7 @@
#include <iostream>
#include <numeric>
#include <Poco/Path.h>
#include "MantidDataHandling/MaskDetectors.h"

using Mantid::DataHandling::GroupDetectors2;
using namespace Mantid::Kernel;
@@ -487,6 +488,11 @@ class GroupDetectors2Test : public CxxTest::TestSuite

void testAverageBehaviour()
{
Mantid::DataHandling::MaskDetectors mask;
mask.initialize();
mask.setPropertyValue("Workspace",inputWS);
mask.setPropertyValue("WorkspaceIndexList","2");
mask.execute();
GroupDetectors2 gd2;
gd2.initialize();
gd2.setPropertyValue("InputWorkspace", inputWS);
@@ -497,8 +503,8 @@ class GroupDetectors2Test : public CxxTest::TestSuite

MatrixWorkspace_sptr output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("GroupDetectors2_testAverageBehaviour_Output");

// Result should be 1 + 2 + 3 / 3 = 2
TS_ASSERT_EQUALS(output->readY(0)[1], 2.0);
// Result should be 1 + 2 / 2 = 1.5
TS_ASSERT_EQUALS(output->readY(0)[1], 1.5);

AnalysisDataService::Instance().remove("GroupDetectors2_testAverageBehaviour_Output");
}
@@ -393,7 +393,7 @@ class LoadEventNexusTest : public CxxTest::TestSuite
// Times are NON-zero for ALL pixels.
if (WS->getEventList(wi).getNumberEvents() > 0)
{
int64_t nanosec = WS->getEventList(wi).getEvents()[0].m_pulsetime.totalNanoseconds();
int64_t nanosec = WS->getEventList(wi).getEvents()[0].pulseTime().totalNanoseconds();
TS_ASSERT_DIFFERS( nanosec, 0)
if (nanosec==0) { std::cout << "Failure at WI " << wi << std::endl; return; }
}
@@ -386,10 +386,6 @@ class DLLExport EventList : public Mantid::API::IEventList
void convertUnitsViaTof(Mantid::Kernel::Unit * fromUnit, Mantid::Kernel::Unit * toUnit);
void convertUnitsQuickly(const double& factor, const double& power);

template< class T >
void duplicateHelper(EventList* output, typename std::vector<T> & events) const;
void duplicate(EventList* output) const;

private:
///List of TofEvent (no weights).
mutable std::vector<TofEvent> events;
@@ -16,6 +16,9 @@

namespace Mantid
{
// Forward declaration needed while this needs to be a friend of TofEvent (see below)
namespace DataHandling { class LoadEventNexus; }

namespace DataObjects
{

@@ -36,14 +39,13 @@ class DLLExport TofEvent {
friend class WeightedEventNoTime;
friend class tofGreaterOrEqual;
friend class tofGreater;
friend class DataHandling::LoadEventNexus; // Needed while the ISIS hack of spreading events out in a bin remains

public: //#TODO: switch back to protected when the darwin build is upgraded to GCC v.4.2+

/** The units of the time of flight index in nanoseconds. This is relative to the
* start of the pulse (stored in pulse_time.
* EXCEPT: After AlignDetectors is run, this is converted to dSpacing, in Angstroms^-1
* @return a double
* */
protected:
/** The 'x value' of the event. This will be in a unit available from the UnitFactory.
* Initially (prior to any unit conversion on the holding workspace), this will have
* the unit of time-of-flight in microseconds.
*/
double m_tof;

/**
@@ -52,15 +54,14 @@ class DLLExport TofEvent {
* for nanoseconds) since a specified epoch: we use the GPS epoch of Jan 1, 1990.
*
* 64 bits gives 1 ns resolution up to +- 292 years around 1990. Should be enough.
* @return a DateAndTime
*/
Mantid::Kernel::DateAndTime m_pulsetime;

public:
/// Constructor, specifying only the time of flight
/// Constructor, specifying only the time of flight in microseconds
TofEvent(double tof);

/// Constructor, specifying the time of flight and the frame id
/// Constructor, specifying the time of flight in microseconds and the frame id
TofEvent(double tof, const Mantid::Kernel::DateAndTime pulsetime);

/// Constructor, copy from another TofEvent object
@@ -93,7 +94,9 @@ class DLLExport TofEvent {
}

//------------------------------------------------------------------------
/// Return the time of flight, as a double, in nanoseconds.
/** Return the 'x value'. Despite the name, this can be in any unit in the UnitFactory.
* If it is time-of-flight, it will be in microseconds.
*/
double tof() const
{
return m_tof;
@@ -150,8 +153,7 @@ class DLLExport WeightedEvent : public TofEvent {
friend class tofGreaterOrEqual;
friend class tofGreater;

public: //#TODO: switch back to protected when the darwin build is upgraded to GCC v.4.2+

public:
/// The weight of this neutron.
float m_weight;

@@ -234,11 +236,11 @@ class DLLExport WeightedEventNoTime {
friend class tofGreaterOrEqual;
friend class tofGreater;

public: //#TODO: switch back to protected when the darwin build is upgraded to GCC v.4.2+

/// The time of flight of this neutron
protected:
/// The 'x value' (e.g. time-of-flight) of this neutron
double m_tof;

public:
/// The weight of this neutron.
float m_weight;

@@ -59,7 +59,7 @@ namespace DataObjects
if (e1.pulseTime() < e2.pulseTime()){
return true;
}
else if ( (e1.pulseTime() == e2.pulseTime()) && (e1.m_tof < e2.m_tof) ){
else if ( (e1.pulseTime() == e2.pulseTime()) && (e1.tof() < e2.tof()) ){
return true;
}

@@ -3487,7 +3487,8 @@ namespace DataObjects
if (splitter.size() <= 0)
{
// 3A. Copy all events to group workspace = -1
this->duplicate(outputs[-1]);
(*outputs[-1]) = (*this);
// this->duplicate(outputs[-1]);
}
else
{
@@ -3508,54 +3509,6 @@ namespace DataObjects
return;
}


/*
* Duplicate helper function
*/
template< class T >
void EventList::duplicateHelper(EventList* output, typename std::vector<T> & events) const
{
for (size_t ie = 0; ie < events.size(); ++ ie)
{
const T eventCopy(events[ie]);
//Add the copy to the output
output->addEventQuickly(eventCopy);
}

return;
}


/*
* Duplicate events
*/
void EventList::duplicate(EventList* output) const
{
// 1. Initialize all the outputs
output->clear();
output->detectorIDs = this->detectorIDs;
output->refX = this->refX;
// Match the output event type.
output->switchTo(eventType);

// 2. Call Helper to do duplicate
switch (eventType)
{
case TOF:
duplicateHelper(output, this->events);
break;
case WEIGHTED:
duplicateHelper(output, this->weightedEvents);
break;
case WEIGHTED_NOTIME:
duplicateHelper(output, this->weightedEventsNoTime);
break;
}

return;
}


//--------------------------------------------------------------------------
/** Get the vector of events contained in an EventList;
* this is overloaded by event type.
@@ -138,7 +138,7 @@ class QuadEnBackgroundTest : public CxxTest::TestSuite
// add events to make data quadratic in 4th coordinate with noise
out3->calcVolume();

srand( time(NULL) );
srand( static_cast<unsigned int>(time(NULL)) );
errorsq=1.0;
events.clear();
double noise=0.1;
@@ -35,6 +35,8 @@ set ( SRC_FILES
src/MDWSTransfDescr.cpp
src/OneStepMDEW.cpp
src/QueryMDWorkspace.cpp
src/ReflectometryTransformKiKf.cpp
src/ReflectometryTransformP.cpp
src/ReflectometryTransformQxQz.cpp
src/SaveMD.cpp
src/SliceMD.cpp
@@ -89,8 +91,10 @@ set ( INC_FILES
inc/MantidMDEvents/MDWSTransfDescr.h
inc/MantidMDEvents/OneStepMDEW.h
inc/MantidMDEvents/QueryMDWorkspace.h
inc/MantidMDEvents/ReflectometryTransformQxQz.h
inc/MantidMDEvents/ReflectometryMDTransform.h
inc/MantidMDEvents/ReflectometryTransformKiKf.h
inc/MantidMDEvents/ReflectometryTransformP.h
inc/MantidMDEvents/ReflectometryTransformQxQz.h
inc/MantidMDEvents/SaveMD.h
inc/MantidMDEvents/SkippingPolicy.h
inc/MantidMDEvents/SliceMD.h
@@ -135,6 +139,8 @@ set ( TEST_FILES
test/MDWSTransfDescrTest.h
test/OneStepMDEWTest.h
test/QueryMDWorkspaceTest.h
test/ReflectometryTransformKiKfTest.h
test/ReflectometryTransformPTest.h
test/ReflectometryTransformQxQzTest.h
test/SaveMDTest.h
test/SkippingPolicyTest.h
@@ -10,7 +10,7 @@ namespace Mantid
namespace MDEvents
{

/** ReflectometryMDTransform : Abstract type for reflectometry transforms to MDWorkspaces
/** ReflectometryMDTransform : Abstract type for reflectometry transforms to MDWorkspaces. This is a Strategy Design Pattern.
@date 2012-05-29
@@ -37,6 +37,7 @@ namespace MDEvents
class DLLExport ReflectometryMDTransform
{
public:
//Execute the strategy to produce the a transformed, output MDWorkspace
virtual Mantid::API::IMDEventWorkspace_sptr execute(Mantid::API::MatrixWorkspace_const_sptr inputWs) const = 0;
};
}
@@ -0,0 +1,85 @@
#ifndef MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMKIKF_H_
#define MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMKIKF_H_

#include "MantidKernel/System.h"
#include "MantidKernel/ClassMacros.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidMDEvents/ReflectometryMDTransform.h"

namespace Mantid
{
namespace MDEvents
{
/**
class CalculateReflectometryK: Calculation type for converting to ki or kf given a theta value (in degrees) and a wavelength
*/
class CalculateReflectometryK
{
private:
double to_radians_factor;
double two_pi;
double m_theta;
public:
CalculateReflectometryK(double theta) : to_radians_factor(3.14159265/180), two_pi(6.28318531), m_theta(theta) {}
~CalculateReflectometryK(){};
double execute(const double& wavelength)
{
double wavenumber = two_pi/wavelength;
return wavenumber * sin(to_radians_factor*m_theta);
}
};

/** ReflectometryTransformKiKf : Type to transform from R vs Wavelength workspace to a 2D MDEW with dimensions of Ki and Kf.
@date 2012-06-06
Copyright &copy; 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
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://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport ReflectometryTransformKiKf : public ReflectometryMDTransform
{
private:
const double m_kiMin;
const double m_kiMax;
const double m_kfMin;
const double m_kfMax;
/// Object performing raw caclcation to determine Ki
mutable CalculateReflectometryK m_KiCalculation;

public:
ReflectometryTransformKiKf(double kiMin, double kiMax, double kfMin, double kfMax, double incidentTheta);
virtual ~ReflectometryTransformKiKf();

/// Execute transformation
virtual Mantid::API::IMDEventWorkspace_sptr execute(Mantid::API::MatrixWorkspace_const_sptr inputWs) const;

private:

DISABLE_DEFAULT_CONSTRUCT(ReflectometryTransformKiKf)
DISABLE_COPY_AND_ASSIGN(ReflectometryTransformKiKf)

};


} // namespace MDEvents
} // namespace Mantid

#endif /* MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMKIKF_H_ */
@@ -0,0 +1,118 @@
#ifndef MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMP_H_
#define MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMP_H_

#include "MantidKernel/System.h"
#include "MantidMDEvents/ReflectometryMDTransform.h"

namespace Mantid
{
namespace MDEvents
{

/**
class CalculateReflectometryPBase: Base class for p-type transforms.
*/
class CalculateReflectometryPBase
{
protected:
const double to_radians_factor;
const double two_pi;
double m_sinThetaInitial;
double m_sinThetaFinal;

CalculateReflectometryPBase(const double& thetaIncident) : to_radians_factor(3.14159265/180), two_pi(6.28318531)
{
m_sinThetaInitial = sin(to_radians_factor*thetaIncident);
}
~CalculateReflectometryPBase(){}
public:
void setThetaFinal(const double& thetaFinal)
{
m_sinThetaFinal = sin(to_radians_factor*thetaFinal);
}
};

/**
class CalculateReflectometryDiffP: Calculates difference between ki and kf.
*/
class CalculateReflectometryDiffP : public CalculateReflectometryPBase
{
public:
CalculateReflectometryDiffP(const double& thetaInitial) : CalculateReflectometryPBase(thetaInitial){}
~CalculateReflectometryDiffP(){};
double execute(const double& wavelength)
{
double wavenumber = two_pi/wavelength;
double ki = wavenumber * m_sinThetaInitial;
double kf = wavenumber * m_sinThetaFinal;
return ki - kf;
}
};

/**
class CalculateReflectometrySumP: Calculates sum of ki and kf.
*/
class CalculateReflectometrySumP : public CalculateReflectometryPBase
{
public:
CalculateReflectometrySumP(const double& thetaInitial) : CalculateReflectometryPBase(thetaInitial){}
~CalculateReflectometrySumP(){};
double execute(const double& wavelength)
{
double wavenumber = two_pi/wavelength;
double ki = wavenumber * m_sinThetaInitial;
double kf = wavenumber * m_sinThetaFinal;
return ki + kf;
}
};



/** ReflectometryTransformP : TODO: DESCRIPTION
@date 2012-06-06
Copyright &copy; 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
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://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport ReflectometryTransformP : public ReflectometryMDTransform
{
private:
const double m_kiMin;
const double m_kiMax;
const double m_kfMin;
const double m_kfMax;
/// Object performing raw calculation to determine pzi + pzf
mutable CalculateReflectometrySumP m_pSumCalculation;
/// Object performing raw calculation to determine pzi - pzf
mutable CalculateReflectometryDiffP m_pDiffCalculation;

public:
ReflectometryTransformP(double kiMin, double kiMax, double kfMin, double kfMax, double incidentTheta);
virtual ~ReflectometryTransformP();
virtual Mantid::API::IMDEventWorkspace_sptr execute(Mantid::API::MatrixWorkspace_const_sptr inputWs) const;

};


} // namespace MDEvents
} // namespace Mantid

#endif /* MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMP_H_ */
@@ -96,7 +96,7 @@ namespace Mantid
}
};

/** ReflectometryTranformQxQz : Type of ReflectometyTransform. Used to convert from an input event workspace to a 2D MDEvent workspace with dimensions of QxQy.
/** ReflectometryTranformQxQz : Type of ReflectometyTransform. Used to convert from an input R vs Wavelength workspace to a 2D MDEvent workspace with dimensions of QxQy.
Transformation is specific for reflectometry purposes.
@date 2012-05-29
@@ -15,8 +15,8 @@ TODO: Enter a full wiki-markup description of your algorithm here. You can then
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidMDEvents/MDEventFactory.h"
#include "MantidMDEvents/ReflectometryTransformQxQz.h"
#include "MantidMDEvents/ReflectometryMDTransform.h"

#include "MantidMDEvents/ReflectometryTransformKiKf.h"
#include "MantidMDEvents/ReflectometryTransformP.h"
#include <boost/shared_ptr.hpp>

using namespace Mantid::Kernel;
@@ -125,9 +125,9 @@ namespace
*/
void checkOutputDimensionalityChoice(const std::string & outputDimensions )
{
if(outputDimensions != qSpaceTransform())
if(outputDimensions != qSpaceTransform() && outputDimensions != kSpaceTransform() && outputDimensions != pSpaceTransform())
{
throw std::runtime_error("Transforms other than to Q have not been implemented yet");
throw std::runtime_error("Unknown transformation");
}
}

@@ -209,7 +209,7 @@ namespace MDEvents
extents[0]=-50;extents[1]=+50;extents[2]=-50;extents[3]=+50;
declareProperty(
new ArrayProperty<double>("Extents", extents),
"A comma separated list of min, max for each dimension. Takes four values in the form qx_min, qx_max, qz_min, qz_max,\n"
"A comma separated list of min, max for each dimension. Takes four values in the form dim_0_min, dim_0_max, dim_1_min, dim_1_max,\n"
"specifying the extents of each dimension. Optional, default +-50 in each dimension.");

setPropertySettings("IncidentTheta", new Kernel::EnabledWhenProperty("OverrideIncidentTheta", IS_EQUAL_TO, "1") );
@@ -255,26 +255,29 @@ namespace MDEvents
}

// Min max extent values.
const double qxmin = extents[0];
const double qxmax = extents[1];
const double qzmin = extents[2];
const double qzmax = extents[3];
const double dim0min = extents[0];
const double dim0max = extents[1];
const double dim1min = extents[2];
const double dim1max = extents[3];

typedef boost::shared_ptr<ReflectometryMDTransform> ReflectometryMDTransform_sptr;

//Select the transform strategy.
ReflectometryMDTransform_sptr transform;
if(outputDimensions == qSpaceTransform())
{
transform = ReflectometryMDTransform_sptr(new ReflectometryTransformQxQz(qxmin, qxmax, qzmin, qzmax, incidentTheta));
transform = ReflectometryMDTransform_sptr(new ReflectometryTransformQxQz(dim0min, dim0max, dim1min, dim1max, incidentTheta));
}
else if(outputDimensions == pSpaceTransform())
{
throw std::runtime_error("pSpaceTransform is not supported Yet.");
transform = ReflectometryMDTransform_sptr(new ReflectometryTransformP(dim0min, dim0max, dim1min, dim1max, incidentTheta));
}
else
{
throw std::runtime_error("kSpaceTransform is not supported Yet");
transform = ReflectometryMDTransform_sptr(new ReflectometryTransformKiKf(dim0min, dim0max, dim1min, dim1max, incidentTheta));
}

//Execute the transform and bind to the output.
setProperty("OutputWorkspace", transform->execute(inputWs));
}

@@ -0,0 +1,101 @@
#include "MantidMDEvents/ReflectometryTransformKiKf.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidGeometry/MDGeometry/MDHistoDimension.h"
#include <stdexcept>

using namespace Mantid::Kernel;
using namespace Mantid::Geometry;
using namespace Mantid::API;

namespace Mantid
{
namespace MDEvents
{

/*
Constructor
@param kiMin: min ki value (extent)
@param kiMax: max ki value (extent)
@param kfMin: min kf value (extent)
@param kfMax; max kf value (extent)
@param incidentTheta: Predetermined incident theta value
*/
ReflectometryTransformKiKf::ReflectometryTransformKiKf(double kiMin, double kiMax, double kfMin, double kfMax, double incidentTheta)
: m_kiMin(kiMin), m_kiMax(kiMax), m_kfMin(kfMin), m_kfMax(kfMax), m_KiCalculation(incidentTheta)
{
if(kiMin >= kiMax)
{
throw std::invalid_argument("min ki bounds must be < max ki bounds");
}
if(kfMin >= kfMax)
{
throw std::invalid_argument("min kf bounds must be < max kf bounds");
}
if(incidentTheta < 0 || incidentTheta > 90)
{
throw std::out_of_range("incident theta angle must be > 0 and < 90");
}
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
ReflectometryTransformKiKf::~ReflectometryTransformKiKf()
{
}

/*
Execute the transformtion. Generates an output IMDEventWorkspace.
@return the constructed IMDEventWorkspace following the transformation.
@param ws: Input MatrixWorkspace const shared pointer
*/
Mantid::API::IMDEventWorkspace_sptr ReflectometryTransformKiKf::execute(Mantid::API::MatrixWorkspace_const_sptr inputWs) const
{
const size_t nbinsx = 10;
const size_t nbinsz = 10;

auto ws = boost::make_shared<MDEventWorkspace<MDLeanEvent<2>,2> >();
MDHistoDimension_sptr kiDim = MDHistoDimension_sptr(new MDHistoDimension("Ki","ki","(Ang^-1)", static_cast<Mantid::coord_t>(m_kiMin), static_cast<Mantid::coord_t>(m_kiMax), nbinsx));
MDHistoDimension_sptr kfDim = MDHistoDimension_sptr(new MDHistoDimension("Kf","kf","(Ang^-1)", static_cast<Mantid::coord_t>(m_kfMin), static_cast<Mantid::coord_t>(m_kfMax), nbinsz));

ws->addDimension(kiDim);
ws->addDimension(kfDim);

// Set some reasonable values for the box controller
BoxController_sptr bc = ws->getBoxController();
bc->setSplitInto(2);
bc->setSplitThreshold(10);

// Initialize the workspace.
ws->initialize();

// Start with a MDGridBox.
ws->splitBox();

auto spectraAxis = inputWs->getAxis(1);
for(size_t index = 0; index < inputWs->getNumberHistograms(); ++index)
{
auto counts = inputWs->readY(index);
auto wavelengths = inputWs->readX(index);
auto errors = inputWs->readE(index);
const size_t nInputBins = wavelengths.size() -1 ;
const double theta_final = spectraAxis->getValue(index);
CalculateReflectometryK kfCalculation(theta_final);
//Loop over all bins in spectra
for(size_t binIndex = 0; binIndex < nInputBins; ++binIndex)
{
const double& wavelength = 0.5*(wavelengths[binIndex] + wavelengths[binIndex+1]);
double _ki = m_KiCalculation.execute(wavelength);
double _kf = kfCalculation.execute(wavelength);
double centers[2] = {_ki, _kf};

ws->addEvent(MDLeanEvent<2>(float(counts[binIndex]), float(errors[binIndex]*errors[binIndex]), centers));
}
ws->splitAllIfNeeded(NULL);
}
return ws;
}


} // namespace Mantid
} // namespace MDEvents
@@ -0,0 +1,98 @@
#include "MantidMDEvents/ReflectometryTransformP.h"
#include "MantidKernel/System.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidGeometry/MDGeometry/MDHistoDimension.h"
#include <stdexcept>

using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;

namespace Mantid
{
namespace MDEvents
{
/*
Constructor
@param kiMin: min ki value (extent)
@param kiMax: max ki value (extent)
@param kfMin: min kf value (extent)
@param kfMax; max kf value (extent)
@param incidentTheta: Predetermined incident theta value
*/
ReflectometryTransformP::ReflectometryTransformP(double kiMin, double kiMax, double kfMin, double kfMax, double incidentTheta)
: m_kiMin(kiMin), m_kiMax(kiMax), m_kfMin(kfMin), m_kfMax(kfMax), m_pSumCalculation(incidentTheta), m_pDiffCalculation(incidentTheta)
{
if(kiMin >= kiMax)
{
throw std::invalid_argument("min ki bounds must be < max ki bounds");
}
if(kfMin >= kfMax)
{
throw std::invalid_argument("min kf bounds must be < max kf bounds");
}
if(incidentTheta < 0 || incidentTheta > 90)
{
throw std::out_of_range("incident theta angle must be > 0 and < 90");
}
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
ReflectometryTransformP::~ReflectometryTransformP()
{
}

Mantid::API::IMDEventWorkspace_sptr ReflectometryTransformP::execute(Mantid::API::MatrixWorkspace_const_sptr inputWs) const
{
const size_t nbinsx = 10;
const size_t nbinsz = 10;

auto ws = boost::make_shared<MDEventWorkspace<MDLeanEvent<2>,2> >();
MDHistoDimension_sptr pSumDim = MDHistoDimension_sptr(new MDHistoDimension("Pz_i + Pz_f","sum_pz","(Ang^-1)", static_cast<Mantid::coord_t>(m_kiMin + m_kfMin), static_cast<Mantid::coord_t>(m_kiMax + m_kfMax), nbinsx));
MDHistoDimension_sptr pDiffDim = MDHistoDimension_sptr(new MDHistoDimension("Pz_i - Pz_f","diff_pz","(Ang^-1)", static_cast<Mantid::coord_t>(m_kiMin - m_kfMin), static_cast<Mantid::coord_t>(m_kiMax - m_kfMax), nbinsz));

ws->addDimension(pSumDim);
ws->addDimension(pDiffDim);

// Set some reasonable values for the box controller
BoxController_sptr bc = ws->getBoxController();
bc->setSplitInto(2);
bc->setSplitThreshold(10);

// Initialize the workspace.
ws->initialize();

// Start with a MDGridBox.
ws->splitBox();

auto spectraAxis = inputWs->getAxis(1);
for(size_t index = 0; index < inputWs->getNumberHistograms(); ++index)
{
auto counts = inputWs->readY(index);
auto wavelengths = inputWs->readX(index);
auto errors = inputWs->readE(index);
const size_t nInputBins = wavelengths.size() -1;
const double theta_final = spectraAxis->getValue(index);
m_pSumCalculation.setThetaFinal(theta_final);
m_pDiffCalculation.setThetaFinal(theta_final);
//Loop over all bins in spectra
for(size_t binIndex = 0; binIndex < nInputBins; ++binIndex)
{
const double& wavelength = 0.5*(wavelengths[binIndex] + wavelengths[binIndex+1]);
double _qx = m_pSumCalculation.execute(wavelength);
double _qz = m_pDiffCalculation.execute(wavelength);
double centers[2] = {_qx, _qz};

ws->addEvent(MDLeanEvent<2>(float(counts[binIndex]), float(errors[binIndex]*errors[binIndex]), centers));
}
ws->splitAllIfNeeded(NULL);
}
return ws;
}



} // namespace Mantid
} // namespace MDEvents
@@ -78,16 +78,16 @@ namespace Mantid
auto counts = inputWs->readY(index);
auto wavelengths = inputWs->readX(index);
auto errors = inputWs->readE(index);
size_t nInputBins = inputWs->isHistogramData() ? wavelengths.size() -1 : wavelengths.size();
const size_t nInputBins = wavelengths.size() -1;
const double theta_final = spectraAxis->getValue(index);
m_QxCalculation.setThetaFinal(theta_final);
m_QzCalculation.setThetaFinal(theta_final);
//Loop over all bins in spectra
for(size_t binIndex = 0; binIndex < nInputBins; ++binIndex)
{
const double& lambda = wavelengths[binIndex];
double _qx = m_QxCalculation.execute(lambda);
double _qz = m_QzCalculation.execute(lambda);
const double& wavelength = 0.5*(wavelengths[binIndex] + wavelengths[binIndex+1]);
double _qx = m_QxCalculation.execute(wavelength);
double _qz = m_QzCalculation.execute(wavelength);
double centers[2] = {_qx, _qz};

ws->addEvent(MDLeanEvent<2>(float(counts[binIndex]), float(errors[binIndex]*errors[binIndex]), centers));
@@ -134,14 +134,6 @@ class ConvertToReflectometryQTest : public CxxTest::TestSuite
TS_ASSERT_THROWS_NOTHING(alg->execute());
}

//Characterisation test for the current state of the algorithm
void test_only_support_q_conversion()
{
auto alg = make_standard_algorithm();
alg->setProperty("OutputDimensions", "P (lab frame)");
TSM_ASSERT_THROWS("Should throw as this mode is not supported yet", alg->execute(), std::runtime_error);
}

void test_execute()
{
auto alg = make_standard_algorithm();
@@ -495,7 +495,7 @@ class LoadMDTest : public CxxTest::TestSuite
TS_ASSERT_DELTA(ws->getSignalAt(i), newWS->getSignalAt(i), 1e-6);
TS_ASSERT_DELTA(ws->getErrorAt(i), newWS->getErrorAt(i), 1e-6);
TS_ASSERT_DELTA(ws->getNumEventsAt(i), newWS->getNumEventsAt(i), 1e-6);
TS_ASSERT_DELTA(ws->getIsMaskedAt(i), newWS->getIsMaskedAt(i), 1e-6);
TS_ASSERT_EQUALS(ws->getIsMaskedAt(i), newWS->getIsMaskedAt(i));
}

if (Poco::File(filename).exists())
@@ -0,0 +1,127 @@
#ifndef MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMKIKFTEST_H_
#define MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMKIKFTEST_H_

#define PI 3.14159265

#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
#include <iostream>
#include <iomanip>

#include "MantidMDEvents/ReflectometryTransformKiKf.h"


using namespace Mantid::MDEvents;

class ReflectometryTransformKiKfTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static ReflectometryTransformKiKfTest *createSuite() { return new ReflectometryTransformKiKfTest(); }
static void destroySuite( ReflectometryTransformKiKfTest *suite ) { delete suite; }

void test_kimin_greater_than_kimax_throws()
{
double kiMin = 2;
double kiMax = 1; //Smaller than kiMin!
double kfMin = 1;
double kfMax = 2;
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformKiKf(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_kimin_equal_to_kimax_throws()
{
double kiMin = 1;
double kiMax = 1; //Equal to kiMin!
double kfMin = 1;
double kfMax = 2;
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformKiKf(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_kfmin_greater_than_kfmax_throws()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 2;
double kfMax = 1; //Smaller than kfMin!
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformKiKf(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_kfmin_equal_to_kfmax_throws()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 1; //Equal to kfMin!
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformKiKf(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_incident_theta_negative()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 3;
double incidentTheta = -0.001; //Negative
TS_ASSERT_THROWS(ReflectometryTransformKiKf(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::out_of_range);
}

void test_incident_theta_too_large()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 3;
double incidentTheta = 90.001; //Too large
TS_ASSERT_THROWS(ReflectometryTransformKiKf(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::out_of_range);
}

void test_valid_construction_inputs()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 2;
double incidentTheta = 1;
TS_ASSERT_THROWS_NOTHING(ReflectometryTransformKiKf(kiMin, kiMax, kfMin, kfMax, incidentTheta));
}

void test_calulate_k()
{
const double wavelength = 1;

//Sine 0 = 0
CalculateReflectometryK A(0);
TS_ASSERT_EQUALS(0, A.execute(wavelength));

//Sine 90 = 1
CalculateReflectometryK B(90);
TS_ASSERT_DELTA(2*PI/wavelength, B.execute(wavelength), 0.0001);

//Sine 270 = -1
CalculateReflectometryK C(270);
TS_ASSERT_DELTA(-2*PI/wavelength, C.execute(wavelength), 0.0001);
}

void test_recalculate_k()
{
const double wavelength = 1;

CalculateReflectometryK A(90);
TS_ASSERT_DELTA(2*PI/wavelength, A.execute(wavelength), 0.0001);

//Now re-execute on the same calculation object.
TS_ASSERT_DELTA(PI/wavelength, A.execute(2*wavelength), 0.0001);
}


};


#endif /* MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMKIKFTEST_H_ */
@@ -0,0 +1,141 @@
#ifndef MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMPTEST_H_
#define MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMPTEST_H_

#define PI 3.14159265

#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
#include <iostream>
#include <iomanip>
#include "MantidMDEvents/ReflectometryTransformP.h"

using namespace Mantid;
using namespace Mantid::MDEvents;
using namespace Mantid::API;

class ReflectometryTransformPTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static ReflectometryTransformPTest *createSuite() { return new ReflectometryTransformPTest(); }
static void destroySuite( ReflectometryTransformPTest *suite ) { delete suite; }


void test_kimin_greater_than_kimax_throws()
{
double kiMin = 2;
double kiMax = 1; //Smaller than kiMin!
double kfMin = 1;
double kfMax = 2;
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformP(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_kimin_equal_to_kimax_throws()
{
double kiMin = 1;
double kiMax = 1; //Equal to kiMin!
double kfMin = 1;
double kfMax = 2;
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformP(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_kfmin_greater_than_kfmax_throws()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 2;
double kfMax = 1; //Smaller than kfMin!
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformP(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_kfmin_equal_to_kfmax_throws()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 1; //Equal to kfMin!
double incidentTheta = 1;
TS_ASSERT_THROWS(ReflectometryTransformP(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::invalid_argument);
}

void test_incident_theta_negative()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 3;
double incidentTheta = -0.001; //Negative
TS_ASSERT_THROWS(ReflectometryTransformP(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::out_of_range);
}

void test_incident_theta_too_large()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 3;
double incidentTheta = 90.001; //Too large
TS_ASSERT_THROWS(ReflectometryTransformP(kiMin, kiMax, kfMin, kfMax, incidentTheta), std::out_of_range);
}

void test_valid_construction_inputs()
{
double kiMin = 1;
double kiMax = 2;
double kfMin = 1;
double kfMax = 2;
double incidentTheta = 1;
TS_ASSERT_THROWS_NOTHING(ReflectometryTransformP(kiMin, kiMax, kfMin, kfMax, incidentTheta));
}

void test_calulate_diff_p()
{
const double wavelength = 1;

CalculateReflectometryDiffP A(0);
A.setThetaFinal(0);
TS_ASSERT_EQUALS(0, A.execute(wavelength));

CalculateReflectometryDiffP B(90);
B.setThetaFinal(0);
TS_ASSERT_DELTA(2*PI/wavelength, B.execute(wavelength), 0.0001);

CalculateReflectometryDiffP C(0);
C.setThetaFinal(90);
TS_ASSERT_DELTA(-2*PI/wavelength, C.execute(wavelength), 0.0001);

CalculateReflectometryDiffP D(90);
D.setThetaFinal(90);
TS_ASSERT_EQUALS(0, A.execute(wavelength));
}

void test_calulate_sum_p()
{
const double wavelength = 1;

CalculateReflectometrySumP A(0);
A.setThetaFinal(0);
TS_ASSERT_EQUALS(0, A.execute(wavelength));

CalculateReflectometrySumP B(90);
B.setThetaFinal(0);
TS_ASSERT_DELTA(2*PI/wavelength, B.execute(wavelength), 0.0001);

CalculateReflectometrySumP C(0);
C.setThetaFinal(90);
TS_ASSERT_DELTA(2*PI/wavelength, C.execute(wavelength), 0.0001);

CalculateReflectometrySumP D(90);
D.setThetaFinal(90);
TS_ASSERT_DELTA(4*PI/wavelength, D.execute(wavelength), 0.0001);
}

};


#endif /* MANTID_MDEVENTS_REFLECTOMETRYTRANSFORMPTEST_H_ */
@@ -1,7 +1,7 @@
#ifndef MANTID_MDEVENTS_REFLECTOMETRYTRANFORMQXQZTEST_H_
#define MANTID_MDEVENTS_REFLECTOMETRYTRANFORMQXQZTEST_H_

#define PI 3.14159
#define PI 3.14159265

#include <cxxtest/TestSuite.h>
#include "MantidKernel/Timer.h"
@@ -19,7 +19,7 @@ default.facility = ISIS
default.instrument =

# Set of PyQt interfaces to add to the Interfaces menu, separated by a space
mantidqt.python_interfaces = ORNL_SANS.py REFL_Reduction.py REFL_SF_Calculator.py REFM_Reduction.py
mantidqt.python_interfaces = DGS_Reduction.py ORNL_SANS.py REFL_Reduction.py REFL_SF_Calculator.py REFM_Reduction.py
mantidqt.python_interfaces_directory = @MANTID_ROOT@/scripts

# Where to find mantid plugin libraries
@@ -96,6 +96,10 @@ def PyExec(self):

from mantidsimple import mtd

bDebug = True
if bDebug:
print '====== Running in mode DEBUGGING ======='

run_numbers = self.getProperty("RunNumbers")

backSubMethod = 2 #1 uses RefRoi, 2 used own method
@@ -159,7 +163,7 @@ def PyExec(self):
incidentMedium = self.getProperty("IncidentMediumSelected")
slitsWidthFlag = self.getProperty("SlitsWidthFlag")

# Pick a good workspace n ame
# Pick a good workspace name
ws_name = "refl%d" % run_numbers[0]
ws_event_data = ws_name+"_evt"

@@ -216,12 +220,12 @@ def PyExec(self):
# Get metadata
mt_run = mtd[ws_event_data].getRun()
##get angles value
ths_value = mt_run.getProperty('ths').value[0]
ths_units = mt_run.getProperty('ths').units
thi_value = mt_run.getProperty('thi').value[0]
thi_units = mt_run.getProperty('thi').units
tthd_value = mt_run.getProperty('tthd').value[0]
tthd_units = mt_run.getProperty('tthd').units
ths_rad = wks_utility.angleUnitConversion(value=ths_value,
from_units=ths_units,
thi_rad = wks_utility.angleUnitConversion(value=thi_value,
from_units=thi_units,
to_units='rad')
tthd_rad = wks_utility.angleUnitConversion(value=tthd_value,
from_units=tthd_units,
@@ -827,7 +831,7 @@ def PyExec(self):

#now we can convert to Q

theta = tthd_rad - ths_rad
theta = math.fabs(tthd_rad - thi_rad)
AngleOffset_deg = float(self.getProperty("AngleOffset"))
AngleOffset_rad = (AngleOffset_deg * math.pi) / 180.
theta += AngleOffset_rad
@@ -850,6 +854,9 @@ def PyExec(self):
ws_data_scaled = ws_data

if dMD is not None and theta is not None:

if bDebug:
print 'DEBUG: theta= {0:4f}'.format(theta)

_tof_axis = mtd[ws_data].readX(0)
_const = float(4) * math.pi * m * dMD / h
@@ -865,6 +872,9 @@ def PyExec(self):
if (q_min >= q_max):
q_min = min(_q_axis)

if bDebug:
print 'DEBUG: [q_min:q_bin:q_max]=[{0:4f},{1:4f},{2:4f}]'.format(q_min, q_step, q_max)

if (backSubMethod == 1):
ws_integrated_data = ws_name + '_IntegratedDataWks'
print '-> keep only range of pixel of interest'
@@ -0,0 +1,158 @@
"""*WIKI*
Liquids Reflectometer (REFL) NeXus viewer
This routine will display some of the metadata defined by the IS
for a given run or set of runs.
*WIKI*"""

from MantidFramework import *
from mantidsimple import *
from numpy import zeros, shape, arange
import math
import sfCalculator

class RefLview(PythonAlgorithm):

def category(self):
return "Reflectometry"

def name(self):
return "RefLview"

def version(self):
return 1

def PyInit(self):
self.declareListProperty("RunNumbers", [0],
Validator=ArrayBoundedValidator(Lower=0),
Description="List of run numbers to process")

def PyExec(self):

import os
import numpy
import math
from reduction.instruments.reflectometer import wks_utility

from mantid import mtd
#remove all previous workspaces
list_mt = mtd.getObjectNames()
for _mt in list_mt:
if _mt.find('_scaled') != -1:
mtd.remove(_mt)
if _mt.find('_reflectivity') != -1:
mtd.remove(_mt)
from mantidsimple import mtd

bDebug = False
if bDebug:
print '====== Running in mode DEBUGGING ======='

run_numbers = self.getProperty("RunNumbers")
if bDebug:
print 'run_numbers (before getSequenceRuns): '
print str(run_numbers)
print
run_numbers = wks_utility.getSequenceRuns(run_numbers)
if bDebug:
print 'run_numbers (after getSequenceRuns): '
print str(run_numbers)
print

for _run in run_numbers:

#make sure we are working with integer
_run = int(_run)

print '********* Working with run: ' + str(_run) + ' *********'

#Pick a good workspace name
ws_name = "refl%d" % _run
ws_event_data = ws_name+"_evt"

_File = FileFinder.findRuns("REF_L%d" %_run)
if len(_File)>0 and os.path.isfile(_File[0]):
data_file = _File[0]
if bDebug:
print 'DEBUG: full file name is ' + _File[0]
else:
msg = "RefLReduction: could not find run %d\n" % _run
msg += "Add your data folder to your User Data Directories in the File menu"
if bDebug:
print 'DEBUG: file name could not be found !'
raise RuntimeError(msg)

if not mtd.workspaceExists(ws_event_data):
LoadEventNexus(Filename=data_file,
OutputWorkspace=ws_event_data)

#retrieve list of metadata
mt_run = mtd[ws_event_data].getRun()

#run_title
run_title = mt_run.getProperty('run_title').value
_line = ' Run title: ' + run_title
print _line

#run_start
run_start = mt_run.getProperty('run_start').value
_line = ' Run start: ' + run_start
print _line

#Lambda Requested
lambda_request_value = mt_run.getProperty('LambdaRequest').value[0]
lambda_request_units = mt_run.getProperty('LambdaRequest').units
_line = ' Lambda requested: ' + str(lambda_request_value)
_line += ' ' + lambda_request_units
print _line

#tthd
tthd_value = mt_run.getProperty('tthd').value[0]
tthd_units = mt_run.getProperty('tthd').units
_line = ' tthd: {0:.4f}'.format(tthd_value)
_line += ' ' + tthd_units
print _line

#thi
thi_value = mt_run.getProperty('thi').value[0]
thi_units = mt_run.getProperty('thi').units
_line = ' thi: {0:.4f}'.format(thi_value)
_line += ' ' + thi_units
print _line

#ths
ths_value = mt_run.getProperty('ths').value[0]
ths_units = mt_run.getProperty('ths').units
_line = ' ths: {0:.4f}'.format(ths_value)
_line += ' ' + ths_units
print _line

#s1h
s1h_value, s1h_units = wks_utility.getS1h(mtd[ws_event_data])
_line = ' s1h: {0:.4f}'.format(s1h_value)
_line += ' ' + s1h_units
print _line

#s2h
s2h_value, s2h_units = wks_utility.getS2h(mtd[ws_event_data])
_line = ' s2h: {0:.4f}'.format(s2h_value)
_line += ' ' + s2h_units
print _line

#s1w
s1w_value, s1w_units = wks_utility.getS1w(mtd[ws_event_data])
_line = ' s1w: {0:.4f}'.format(s1w_value)
_line += ' ' + s1w_units
print _line

#s2w
s2w_value, s2w_units = wks_utility.getS2w(mtd[ws_event_data])
_line = ' s2w: {0:.4f}'.format(s2w_value)
_line += ' ' + s2w_units
print _line

print '********************************'
print

mtd.registerPyAlgorithm(RefLview())
@@ -1,42 +1,44 @@
set ( SRC_FILES
src/EQSANSQ2D.cpp
src/EQSANSLoad.cpp
src/HFIRLoad.cpp
src/HFIRInstrument.cpp
src/EQSANSInstrument.cpp
src/SANSBeamFinder.cpp
src/SANSSolidAngleCorrection.cpp
src/SANSSensitivityCorrection.cpp
src/EQSANSDarkCurrentSubtraction.cpp
src/EQSANSPatchSensitivity.cpp
src/HFIRDarkCurrentSubtraction.cpp
src/SetupHFIRReduction.cpp
src/SetupEQSANSReduction.cpp
src/ComputeSensitivity.cpp
src/RefRoi.cpp
src/RefReduction.cpp
src/ComputeSensitivity.cpp
src/DgsReduction.cpp
src/EQSANSDarkCurrentSubtraction.cpp
src/EQSANSInstrument.cpp
src/EQSANSLoad.cpp
src/EQSANSPatchSensitivity.cpp
src/EQSANSQ2D.cpp
src/HFIRDarkCurrentSubtraction.cpp
src/HFIRInstrument.cpp
src/HFIRLoad.cpp
src/RefReduction.cpp
src/RefRoi.cpp
src/SANSBeamFinder.cpp
src/SANSSensitivityCorrection.cpp
src/SANSSolidAngleCorrection.cpp
src/SetupEQSANSReduction.cpp
src/SetupHFIRReduction.cpp
)

set ( SRC_UNITY_IGNORE_FILES
)

set ( INC_FILES
inc/MantidWorkflowAlgorithms/EQSANSQ2D.h
inc/MantidWorkflowAlgorithms/EQSANSLoad.h
inc/MantidWorkflowAlgorithms/HFIRLoad.h
inc/MantidWorkflowAlgorithms/EQSANSInstrument.h
inc/MantidWorkflowAlgorithms/HFIRInstrument.h
inc/MantidWorkflowAlgorithms/SANSBeamFinder.h
inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h
inc/MantidWorkflowAlgorithms/SANSSensitivityCorrection.h
inc/MantidWorkflowAlgorithms/EQSANSDarkCurrentSubtraction.h
inc/MantidWorkflowAlgorithms/EQSANSPatchSensitivity.h
inc/MantidWorkflowAlgorithms/HFIRDarkCurrentSubtraction.h
inc/MantidWorkflowAlgorithms/SetupHFIRReduction.h
inc/MantidWorkflowAlgorithms/SetupEQSANSReduction.h
inc/MantidWorkflowAlgorithms/ComputeSensitivity.h
inc/MantidWorkflowAlgorithms/RefRoi.h
inc/MantidWorkflowAlgorithms/RefReduction.h
inc/MantidWorkflowAlgorithms/ComputeSensitivity.h
inc/MantidWorkflowAlgorithms/DgsReduction.h
inc/MantidWorkflowAlgorithms/EQSANSDarkCurrentSubtraction.h
inc/MantidWorkflowAlgorithms/EQSANSInstrument.h
inc/MantidWorkflowAlgorithms/EQSANSLoad.h
inc/MantidWorkflowAlgorithms/EQSANSPatchSensitivity.h
inc/MantidWorkflowAlgorithms/EQSANSQ2D.h
inc/MantidWorkflowAlgorithms/HFIRDarkCurrentSubtraction.h
inc/MantidWorkflowAlgorithms/HFIRInstrument.h
inc/MantidWorkflowAlgorithms/HFIRLoad.h
inc/MantidWorkflowAlgorithms/RefReduction.h
inc/MantidWorkflowAlgorithms/RefRoi.h
inc/MantidWorkflowAlgorithms/SANSBeamFinder.h
inc/MantidWorkflowAlgorithms/SANSSensitivityCorrection.h
inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h
inc/MantidWorkflowAlgorithms/SetupEQSANSReduction.h
inc/MantidWorkflowAlgorithms/SetupHFIRReduction.h
)

set ( TEST_FILES
@@ -0,0 +1,59 @@
#ifndef MANTID_WORKFLOWALGORITHMS_DGSREDUCTION_H_
#define MANTID_WORKFLOWALGORITHMS_DGSREDUCTION_H_

#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"

namespace Mantid
{
namespace WorkflowAlgorithms
{

/** DgsReduction : This is the top-level workflow algorithm for controlling
* direct geometry spectrometer reduction.
@date 2012-06-06
Copyright &copy; 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
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://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport DgsReduction : public API::Algorithm
{
public:
DgsReduction();
virtual ~DgsReduction();

virtual const std::string name() const;
virtual int version() const;
virtual const std::string category() const;

private:
virtual void initDocs();
void init();
void exec();


};


} // namespace WorkflowAlgorithms
} // namespace Mantid

#endif /* MANTID_WORKFLOWALGORITHMS_DGSREDUCTION_H_ */
@@ -0,0 +1,78 @@
/*WIKI*
This is the top-level workflow algorithm for direct geometry spectrometer
data reduction. This algorithm is responsible for gathering the necessary
parameters and generating calls to other workflow or standard algorithms.
*WIKI*/

#include "MantidWorkflowAlgorithms/DgsReduction.h"
#include "MantidKernel/System.h"

using namespace Mantid::Kernel;
using namespace Mantid::API;

namespace Mantid
{
namespace WorkflowAlgorithms
{

// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(DgsReduction)



//----------------------------------------------------------------------------------------------
/** Constructor
*/
DgsReduction::DgsReduction()
{
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
DgsReduction::~DgsReduction()
{
}


//----------------------------------------------------------------------------------------------
/// Algorithm's name for identification. @see Algorithm::name
const std::string DgsReduction::name() const { return "DgsReduction";};

/// Algorithm's version for identification. @see Algorithm::version
int DgsReduction::version() const { return 1;};

/// Algorithm's category for identification. @see Algorithm::category
const std::string DgsReduction::category() const { return "Workflow";}

//----------------------------------------------------------------------------------------------
/// Sets documentation strings for this algorithm
void DgsReduction::initDocs()
{
this->setWikiSummary("Top-level workflow algorithm for DGS reduction.");
this->setOptionalMessage("Top-level workflow algorithm for DGS reduction.");
}

//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void DgsReduction::init()
{
declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input), "An input workspace.");
declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), "An output workspace.");
}

//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void DgsReduction::exec()
{
// TODO Auto-generated execute stub
}



} // namespace Mantid
} // namespace WorkflowAlgorithms
@@ -12,6 +12,7 @@
#include <QTextStream>
#include <QTemporaryFile>
#include <QMdiArea>
#include <QSize>

/**
* Constructor.
@@ -24,7 +25,6 @@ QMainWindow(NULL,f),
#endif
d_app(appWindow)
{
this->setMinimumSize(100,100);
setFocusPolicy(Qt::StrongFocus);
connect(appWindow,SIGNAL(shutting_down()),this,SLOT(close()));
#ifdef Q_OS_WIN
@@ -175,6 +175,11 @@ void FloatingWindow::removeMdiSubWindow()
}
}

QSize FloatingWindow::minimumSizeHint() const
{
return QSize(200, 200);
}

/** Sets the widget displayed in the FloatingWindow
*
* @param w :: MdiSubWindow being floated
@@ -6,6 +6,7 @@
class QEvent;
class ApplicationWindow;
class MdiSubWindow;
class QSize;

/**
* Floating wrapper window for a MdiSubWindow.
@@ -21,6 +22,7 @@ class FloatingWindow: public QMainWindow
MdiSubWindow* mdiSubWindow() const;
void setMdiSubWindow(MdiSubWindow* sw);
void removeMdiSubWindow();
virtual QSize minimumSizeHint () const;

protected:

@@ -116,7 +116,6 @@ Graph::Graph(int x, int y, int width, int height, QWidget* parent, Qt::WFlags f)
: QWidget(parent, f) //QwtPlot(parent)
{
setWindowFlags(f);
this->setMinimumSize(1,1);
n_curves=0;

d_waterfall_offset_x = 0;
@@ -1031,7 +1031,7 @@ Table* MantidUI::createDetectorTable(const QString & wsName, const std::vector<i
if(row == 0)
{
std::vector<std::string> parameters = det->getStringParameter("show-signed-theta", true);
b_showSignedTwoThetaVersion = parameters.size() > 0 && find(parameters.begin(), parameters.end(), "Always") != parameters.end();
b_showSignedTwoThetaVersion = !parameters.empty() && find(parameters.begin(), parameters.end(), "Always") != parameters.end();
}
if(b_showSignedTwoThetaVersion)
{
@@ -59,7 +59,6 @@ MdiSubWindow::MdiSubWindow(ApplicationWindow *app, const QString& label, const Q
d_birthdate(QDateTime::currentDateTime ().toString(Qt::LocalDate)),
d_min_restore_size(QSize())
{
this->setMinimumSize(100,100);
setObjectName(name);
setAttribute(Qt::WA_DeleteOnClose);
setLocale(app->locale());
@@ -50,9 +50,7 @@ class MdiSubWindowParent_t: public QWidget
MdiSubWindowParent_t(QWidget* parent, Qt::WFlags f = 0):
QWidget(parent,f),
m_widget(NULL)
{
}

{}
void setWidget(QWidget* w)
{
if (w == NULL)
@@ -40,6 +40,7 @@
#include <QCheckBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QSize>

#include <set>

@@ -163,6 +164,11 @@ MultiLayer::~MultiLayer()
{
}

QSize MultiLayer::minimumSizeHint() const
{
return QSize(200, 200);
}

Graph *MultiLayer::layer(int num)
{
int index = num - 1;
@@ -45,6 +45,7 @@ class LegendWidget;
class MantidTreeWidget;
class MantidMDCurve;
class MantidMatrixCurve;
class QSize;

/**
* \brief An MDI window (MdiSubWindow) managing one or more Graph objects.
@@ -70,6 +71,9 @@ class MultiLayer: public MdiSubWindow
public:
MultiLayer (ApplicationWindow* parent = 0, int layers = 1, int rows = 1, int cols = 1, const QString& label = "", const char* name=0, Qt::WFlags f=0);
~MultiLayer();

QSize minimumSizeHint() const;

QList<Graph *> layersList(){return graphsList;};
Graph *layer(int num);
LayerButton* addLayerButton();
@@ -196,11 +196,14 @@
<string>File</string>
</property>
<property name="multipleFiles" stdset="0">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="extsAsSingleOption" stdset="0">
<bool>true</bool>
</property>
<property name="algorithmAndProperty" stdset="0">
<string>Load|Filename</string>
</property>
</widget>
</item>
<item>
@@ -133,7 +133,7 @@ void CreateMDWorkspace::initLayout()
while(it != names.end())
{
m_uiForm.workspaceSelector->addItem((*it).c_str());
it++;
++it;
}

}
@@ -2136,7 +2136,6 @@ void MuonAnalysis::plotPair(const std::string& plotType)
QTableWidgetItem *item = m_uiForm.pairTable->item(m_pairTableRowInFocus,3);
QTableWidgetItem *itemName = m_uiForm.pairTable->item(m_pairTableRowInFocus,0);
QString pairName = itemName->text();
std::string workspaceGroupName("");
QString wsGroupName(getGroupName());

QString cropWSfirstPart = wsGroupName + "; Group=" + pairName + "; " + plotTypeTitle + "";
@@ -90,16 +90,28 @@ class EXPORT_OPT_MANTIDQT_IMAGEVIEWER DataArray
double GetValue( double x, double y ) const;

/// Clamp x to the interval of x-values covered by this DataArray
void RestrictX( double & x );
void RestrictX( double & x ) const;

/// Clamp y to the interval of y-values covered by this DataArray
void RestrictY( double & y );
void RestrictY( double & y ) const;

/// Clamp row to a valid row number for this DataArray
void RestrictRow( int & row );
void RestrictRow( int & row ) const;

/// Clamp col to a valid column number for this DataArray
void RestrictCol( int & col );
void RestrictCol( int & col ) const;

/// Calculate the column number containing the specified x
size_t ColumnOfX( double x ) const;

/// Calculate the x-value at the center of the specified column
double XOfColumn( size_t col ) const;

/// Calculate the row number containing the specified y
size_t RowOfY( double y ) const;

/// Calculate the y-value at the center of the specified row
double YOfRow( size_t row ) const;


private:
@@ -3,6 +3,7 @@
*/

#include <iostream>
#include <math.h>

#include "MantidQtImageViewer/DataArray.h"

@@ -196,13 +197,25 @@ double DataArray::GetValue( int row, int col ) const
*/
double DataArray::GetValue( double x, double y ) const
{
double relative_x = (x - xmin) / (xmax - xmin);
int col = (int)( relative_x * (double)n_cols );
/*
int col = 0;
if ( is_log_x )
{
col = (int)((double)n_cols * log(x/xmin)/log(xmax/xmin) );
}
else
{
double relative_x = (x - xmin) / (xmax - xmin);
col = (int)( relative_x * (double)n_cols );
}

double relative_y = (y - ymin) / (ymax - ymin);
int row = (int)( relative_y * (double)n_rows );
*/
size_t col = ColumnOfX( x );
size_t row = RowOfY( y );

return GetValue( row, col );
return GetValue( (int)row, (int)col );
}


@@ -211,7 +224,7 @@ double DataArray::GetValue( double x, double y ) const
* @param x If x is more than xmax it will be set to xmax. If x is less
* than xmin, it will be set to xmin.
*/
void DataArray::RestrictX( double & x )
void DataArray::RestrictX( double & x ) const
{
if ( x > xmax )
{
@@ -229,7 +242,7 @@ void DataArray::RestrictX( double & x )
* @param y If y is more than ymax it will be set to ymax. If y is less
* than ymin, it will be set to ymin.
*/
void DataArray::RestrictY( double & y )
void DataArray::RestrictY( double & y ) const
{
if ( y > ymax )
{
@@ -247,7 +260,7 @@ void DataArray::RestrictY( double & y )
* @param row If row is more than n_rows-1, it is set to n_rows-1. If
* row < 0 it is set to zero.
*/
void DataArray::RestrictRow( int & row )
void DataArray::RestrictRow( int & row ) const
{
if ( row >= (int)n_rows )
{
@@ -265,7 +278,7 @@ void DataArray::RestrictRow( int & row )
* @param col If col is more than n_cols-1, it is set to n_cols-1. If
* col < 0 it is set to zero.
*/
void DataArray::RestrictCol( int & col )
void DataArray::RestrictCol( int & col ) const
{
if ( col >= (int)n_cols )
{
@@ -278,5 +291,99 @@ void DataArray::RestrictCol( int & col )
}


/**
* Calculate the column number containing the specified x value. If the
* specified value is less than xmin, 0 is returned. If the specified
* value is more than or equal to xmax, n_cols-1 is returned. This
* method uses the is_log_x flag to determine whether to use a "log"
* transformation to map the column to x.
*
* @param x The x value to map to a column number
*
* @return A valid column number, containing x, if x is in range, or the
* first or last column number if x is out of range.
*/
size_t DataArray::ColumnOfX( double x ) const
{
int col;
if ( is_log_x )
{
col = (int)((double)n_cols * log(x/xmin)/log(xmax/xmin));
}
else
{
col = (int)((double)n_cols * (x-xmin)/(xmax-xmin));
}

RestrictCol( col );
return (size_t)col;
}


/*
* Calculate the x-value at the center of the specified column. If the
* column number is too large, xmax is returned. If the column number is
* too small, xmin is returned. This method uses the is_log_x flag to
* determine whether to use a "log" tranformation to map the column to x.
*
* @param col The column number to map to an x-value.
*
* @return A corresponding x value between xmin and xmax.
*/
double DataArray::XOfColumn( size_t col ) const
{
double xval;
if ( is_log_x )
{
xval = xmin * exp( ((double)col+0.5)/(double)n_cols * log(xmax/xmin));
}
else
{
xval = ((double)col+0.5)/(double)n_cols * (xmax-xmin) + xmin;
}

RestrictX( xval );
return xval;
}


/**
* Calculate the row number containing the specified y value. If the
* specified value is less than ymin, 0 is returned. If the specified
* value is more than or equal to ymax, n_rows-1 is returned.
*
* @param y The y value to map to a row number
*
* @return A valid row number, containing y, if y is in range, or the
* first or last row number if y is out of range.
*/
size_t DataArray::RowOfY( double y ) const
{
int row = (int)((double)n_rows * (y-ymin)/(ymax-ymin));

RestrictRow( row );
return (size_t)row;
}


/*
* Calculate the y-value at the center of the specified row. If the
* row number is too large, ymax is returned. If the row number is
* too small, ymin is returned.
*
* @param row The row number to map to an y-value.
*
* @return A corresponding y value between ymin and ymax.
*/
double DataArray::YOfRow( size_t row ) const
{
double yval;
yval = ((double)row+0.5)/(double)n_rows * (ymax-ymin) + ymin;

RestrictY( yval );
return yval;
}


} // namespace MantidQt
} // namespace ImageView
@@ -378,37 +378,39 @@ void ImageDisplay::SetPointedAtPoint( QPoint point )

QVector<double> xData;
QVector<double> yData;

double x_val;
xData.push_back( x_min ); // start at x_min
yData.push_back( data[ row * n_cols ] );
for ( size_t col = 0; col < n_cols; col++ )
{
if ( data_array->IsLogX() )
{
x_val = x_min * exp( (double)col/double(n_cols-1)*log(x_max/x_min));
}
else
{
x_val = (double)col/(double)(n_cols-1) * (x_max-x_min) + x_min;
}
xData.push_back( x_val );
yData.push_back( data[ row * n_cols + col ] );
x_val = data_array->XOfColumn( col );
xData.push_back( x_val ); // mark data at col
yData.push_back( data[ row * n_cols + col ] ); // centers
}
xData.push_back( x_max ); // end at x_max
yData.push_back( data[ row * n_cols + n_cols-1 ] );

h_graph_display->SetLogX( data_array->IsLogX() );
h_graph_display->SetData( xData, yData, x, y );

double relative_x = (x-x_min)/(x_max-x_min); // in 0 to 1
int col = (int)(relative_x * (double)n_cols);

data_array->RestrictCol( col );
size_t col = data_array->ColumnOfX( x );

QVector<double> v_xData;
QVector<double> v_yData;

double y_val;
for ( size_t row = 0; row < n_rows; row++ )
v_yData.push_back( y_min ); // start at y_min
v_xData.push_back( data[col] );
for ( size_t row = 0; row < n_rows; row++ ) // mark data at row centers
{
y_val = (double)row/(double)(n_rows-1) * (y_max-y_min) + y_min;
y_val = data_array->YOfRow( row );
v_yData.push_back( y_val );
v_xData.push_back( data[ row * n_cols + col ] );
}
v_yData.push_back( y_max ); // end at y_max
v_xData.push_back( data[ (n_rows-1) * n_cols + col] );

v_graph_display->SetData( v_xData, v_yData, x, y );

ShowInfoList( x, y );
@@ -13,6 +13,8 @@
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidGeometry/Instrument.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidAPI/Run.h"
#include "MantidQtImageViewer/ErrorHandler.h"

using namespace Mantid;
using namespace Kernel;
@@ -247,6 +249,8 @@ void MatrixWSDataSource::GetInfoList( double x,
IVUtils::PushNameValue( "Det ID", 8, 0, d_id, list );
}

try
{
// now try to do various unit conversions
// to get equivalent info
// first make sure we can get the needed
@@ -300,6 +304,15 @@ void MatrixWSDataSource::GetInfoList( double x,
double efixed = 0;
double delta = 0;

const API::Run & run = mat_ws->run(); // cases I checked don't have Ei :-(
if ( run.hasProperty("Ei") )
{
Kernel::Property* prop = run.getProperty("Ei");
efixed = boost::lexical_cast<double,std::string>(prop->value());
emode = 1; // only correct for direct geometry
} // instruments


double tof = old_unit->convertSingleToTOF( x, l1, l2, two_theta,
emode, efixed, delta );
if ( ! (x_label == "Time-of-flight") )
@@ -323,7 +336,7 @@ void MatrixWSDataSource::GetInfoList( double x,
IVUtils::PushNameValue( "Energy", 8, 4, energy, list );
}

if ( (! (x_label == "d-Spacing")) && (two_theta != 0.0) )
if ( (! (x_label == "d-Spacing")) && (two_theta != 0.0) && ( emode == 0 ) )
{
const Unit_sptr& d_unit = UnitFactory::Instance().create("dSpacing");
double d_spacing = d_unit->convertSingleFromTOF( tof, l1, l2, two_theta,
@@ -339,6 +352,19 @@ void MatrixWSDataSource::GetInfoList( double x,
IVUtils::PushNameValue( "q", 8, 4, mag_q, list );
}

if ( (! (x_label == "DeltaE")) && (two_theta != 0.0) && ( emode != 0 ) )
{
const Unit_sptr& deltaE_unit=UnitFactory::Instance().create("DeltaE");
double delta_E = deltaE_unit->convertSingleFromTOF( tof, l1, l2, two_theta,
emode, efixed, delta );
IVUtils::PushNameValue( "DeltaE", 8, 4, delta_E, list );
}
}
catch (std::exception & e)
{
ErrorHandler::Notice("Failed to get information from Workspace:");
ErrorHandler::Notice( e.what() );
}

}

@@ -26,12 +26,14 @@ namespace MantidQt
/// Constructor.
FindFilesThread(QObject *parent = NULL);
/// Set the various file-finding values / options.
void set(QString text = "", bool isForRunFiles = true, bool isOptional = false);
void set(QString text, bool isForRunFiles, bool isOptional, const QString & algorithmProperty = "");

/// Returns the error string. Empty if no error was caught.
std::string error() const { return m_error; }
/// Returns the vector of filenames. Empty if no files were found, or if there was an error.
std::vector<std::string> filenames() const { return m_filenames; }
/// Use the specified algorithm and property to find files instead of using the FileFinder.
void getFilesFromAlgorithm();

protected:
/// Override parent class run().
@@ -46,6 +48,8 @@ namespace MantidQt
/// File name text typed in by the user.
std::string m_text;

QString m_algorithm;
QString m_property;
bool m_isForRunFiles;
bool m_isOptional;
};
@@ -186,6 +190,8 @@ namespace MantidQt
QString createFileFilter();
/// Create an extension list from the name algorithm and property
QStringList getFileExtensionsFromAlgorithm(const QString & algName, const QString &propName);
/// Create an extension list from the name algorithm and property
QStringList getFilesFromAlgorithm(const QString & algName, const QString &propName, const QString &filename);
/// Open a file dialog
QString openFileDialog();
/// flag a problem with the supplied entry number, an empty string means no error