Large diffs are not rendered by default.

@@ -110,12 +110,21 @@ namespace Mantid
declareProperty(new ArrayProperty<double>("DReference"),"Enter a comma-separated list of the expected X-position of the centre of the peaks. Only peaks near these positions will be fitted." );
declareProperty("FitWindowMaxWidth", 0.,
"Optional: The maximum width of the fitting window. If this is <=0 the windows is not specified to FindPeaks" );

std::vector<std::string> peaktypes;
peaktypes.push_back("BackToBackExponential");
peaktypes.push_back("Gaussian");
peaktypes.push_back("Lorentzian");
declareProperty("PeakFunction", "Gaussian", boost::make_shared<StringListValidator>(peaktypes),
"Type of peak to fit");

std::vector<std::string> bkgdtypes;
bkgdtypes.push_back("Flat");
bkgdtypes.push_back("Linear");
bkgdtypes.push_back("Quadratic");
declareProperty("BackgroundType", "Linear", boost::make_shared<StringListValidator>(bkgdtypes),
"Type of Background. The choice can be either Linear or Quadratic");

declareProperty("HighBackground", true,
"Relatively weak peak in high background");
declareProperty(new FileProperty("GroupingFileName","", FileProperty::OptionalSave, ".cal"),
@@ -212,6 +221,10 @@ namespace Mantid
if (eventW)
isEvent = true;

// cache the peak and background function names
m_peakType = this->getPropertyValue("PeakFunction");
m_backType = this->getPropertyValue("BackgroundType");

// Fit all the spectra with a gaussian
Progress prog(this, 0, 1.0, nspec);
// cppcheck-suppress syntaxError
@@ -422,7 +435,8 @@ namespace Mantid
findpeaks->setProperty("PeakPositions", peakPosToFit);
if (useFitWindows)
findpeaks->setProperty("FitWindows", fitWindowsToUse);
findpeaks->setProperty<std::string>("BackgroundType", this->getPropertyValue("BackgroundType"));
findpeaks->setProperty<std::string>("PeakFunction", m_peakType);
findpeaks->setProperty<std::string>("BackgroundType", m_backType);
findpeaks->setProperty<bool>("HighBackground", this->getProperty("HighBackground"));
findpeaks->setProperty<int>("MinGuessedPeakWidth",4);
findpeaks->setProperty<int>("MaxGuessedPeakWidth",4);
@@ -242,7 +242,7 @@ namespace Mantid
peak->setHeight(peakHeight);
peak->setCentre(peakLoc);
const double sigma(10.0);
peak->setWidth(2.0*std::sqrt(2.0*std::log(2.0))*sigma);
peak->setFwhm(2.0*std::sqrt(2.0*std::log(2.0))*sigma);

CompositeFunctionMW* fitFunc = new CompositeFunctionMW(); //Takes ownership of the functions
fitFunc->addFunction(background);
@@ -93,6 +93,7 @@ The algorithm will ignore masked detectors if this flag is set.
#include "MantidAPI/WorkspaceValidators.h"
#include "MantidDataObjects/EventList.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/OffsetsWorkspace.h"
#include "MantidDataObjects/Workspace2D.h"
#include "MantidGeometry/ICompAssembly.h"
#include "MantidGeometry/IComponent.h"
@@ -585,7 +586,15 @@ void SmoothNeighbours::execWorkspace2D(Mantid::API::MatrixWorkspace_sptr ws)

MatrixWorkspace_sptr outWS;
//Make a brand new Workspace2D
if (boost::dynamic_pointer_cast<OffsetsWorkspace>(ws))
{
g_log.information() << "Creating new OffsetsWorkspace\n";
outWS = MatrixWorkspace_sptr(new OffsetsWorkspace(ws->getInstrument()));
}
else
{
outWS = boost::dynamic_pointer_cast<MatrixWorkspace>( API::WorkspaceFactory::Instance().create("Workspace2D", numberOfSpectra, YLength+1, YLength));
}
this->setProperty("OutputWorkspace", outWS);
//Copy geometry over.
API::WorkspaceFactory::Instance().initializeFromParent(ws, outWS, false);
@@ -122,6 +122,7 @@ API::ITableWorkspace_sptr StripPeaks::findPeaks(API::MatrixWorkspace_sptr WS)
findpeaks->setProperty<bool>("HighBackground", getProperty("HighBackground"));
findpeaks->setProperty<double>("PeakPositionTolerance", getProperty("PeakPositionTolerance"));
findpeaks->setProperty<double>("PeakHeightTolerance", 5);
findpeaks->setProperty<bool>("RawPeakParameters", true);

findpeaks->executeAsSubAlg();
return findpeaks->getProperty("PeaksList");
@@ -162,9 +163,9 @@ API::MatrixWorkspace_sptr StripPeaks::removePeaks(API::MatrixWorkspace_const_spt
const MantidVec &X = outputWS->readX(peakslist->getRef<int>("spectrum",i));
MantidVec &Y = outputWS->dataY(peakslist->getRef<int>("spectrum",i));
// Get back the gaussian parameters
const double height = peakslist->getRef<double>("height",i);
const double centre = peakslist->getRef<double>("centre",i);
const double width = peakslist->getRef<double>("width",i);
const double height = peakslist->getRef<double>("f0.Height",i);
const double centre = peakslist->getRef<double>("f0.PeakCentre",i);
const double width = peakslist->getRef<double>("f0.Sigma",i);
// These are some heuristic rules to discard bad fits.
// Hope to be able to remove them when we have better fitting routine
if ( height < 0 ) {
@@ -1,5 +1,5 @@
# This is mainly here so you don't get a complaint when running cmake
cmake_minimum_required (VERSION 2.6)
cmake_minimum_required (VERSION 2.8)

# Add the path to our custom 'find' modules
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../Build/CMake")
@@ -58,10 +58,10 @@ namespace Mantid
/// overwrite IPeakFunction base class methods
virtual double centre()const {return getParameter("X0");};
virtual double height()const {return getParameter("I");}; // note height can likely be defined more accurately, here set equal to intensity
virtual double width()const {return 2*getParameter("S");}; // can likely be defined more accurately
virtual double fwhm()const {return 2*getParameter("S");}; // can likely be defined more accurately
virtual void setCentre(const double c) {setParameter("X0",c);};
virtual void setHeight(const double h) {setParameter("I",h);};
virtual void setWidth(const double w) {setParameter("S",w/2.0);};
virtual void setFwhm(const double w) {setParameter("S",w/2.0);};


/// overwrite IFunction base class methods
@@ -51,10 +51,10 @@ namespace Mantid
/// overwrite IPeakFunction base class methods
virtual double centre()const {return 0;}
virtual double height()const {return getParameter("Height");}
virtual double width()const {return 0;}
virtual double fwhm()const {return 0;}
virtual void setCentre(const double c) { UNUSED_ARG(c); }
virtual void setHeight(const double h) {setParameter("Height",h);}
virtual void setWidth(const double w) { UNUSED_ARG(w); }
virtual void setFwhm(const double w) { UNUSED_ARG(w); }
virtual double HeightPrefactor()const { return 1.0; } //modulates the Height of the Delta function
/// overwrite IFunction base class methods
std::string name()const{return "DeltaFunction";}
@@ -58,10 +58,10 @@ namespace Mantid
/// overwrite IPeakFunction base class methods
virtual double centre()const {return getParameter("PeakCentre");}
virtual double height()const {return getParameter("Height");}
virtual double width()const {return 2.0*sqrt(2.0*std::log(2.0))*getParameter("Sigma");}
virtual double fwhm()const {return 2.0*sqrt(2.0*std::log(2.0))*getParameter("Sigma");}
virtual void setCentre(const double c) {setParameter("PeakCentre",c);}
virtual void setHeight(const double h) {setParameter("Height",h);}
virtual void setWidth(const double w) {setParameter("Sigma",w/(2.0*sqrt(2.0*std::log(2.0))));}
virtual void setFwhm(const double w) {setParameter("Sigma",w/(2.0*sqrt(2.0*std::log(2.0))));}


/// overwrite IFunction base class methods
@@ -49,10 +49,10 @@ namespace Mantid
/// overwrite IPeakFunction base class methods
virtual double centre()const;
virtual double height()const;
virtual double width()const;
virtual double fwhm()const;
virtual void setCentre(const double c);
virtual void setHeight(const double h);
virtual void setWidth(const double w);
virtual void setFwhm(const double w);

/// overwrite IFunction base class methods
std::string name()const{return "IkedaCarpenterPV";}
@@ -55,10 +55,10 @@ namespace Mantid
/// overwrite IPeakFunction base class methods
virtual double centre()const {return getParameter("PeakCentre");}
virtual double height()const {return getParameter("Height");}
virtual double width()const {return 2*getParameter("HWHM");}
virtual double fwhm()const {return 2*getParameter("HWHM");}
virtual void setCentre(const double c) {setParameter("PeakCentre",c);}
virtual void setHeight(const double h) {setParameter("Height",h);}
virtual void setWidth(const double w) {setParameter("HWHM",w/2.0);}
virtual void setFwhm(const double w) {setParameter("HWHM",w/2.0);}


/// overwrite IFunction base class methods
@@ -65,7 +65,7 @@ double IkedaCarpenterPV::height()const
return h0;
};

double IkedaCarpenterPV::width()const
double IkedaCarpenterPV::fwhm()const
{
double sigmaSquared = getParameter("SigmaSquared");
double gamma = getParameter("Gamma");
@@ -89,7 +89,7 @@ double IkedaCarpenterPV::width()const
return sqrt(8.0*M_LN2*sigmaSquared)+gamma;
};

void IkedaCarpenterPV::setWidth(const double w)
void IkedaCarpenterPV::setFwhm(const double w)
{
setParameter("SigmaSquared", w*w/(32.0*M_LN2)); // used 4.0 * 8.0 = 32.0
setParameter("Gamma", w/2.0);
@@ -76,7 +76,7 @@ class CurveFittingGauss: public IPeakFunction, public ITestFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -90,7 +90,7 @@ class CurveFittingGauss: public IPeakFunction, public ITestFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -86,7 +86,7 @@ class ConvolutionTest_Gauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -100,7 +100,7 @@ class ConvolutionTest_Gauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -66,7 +66,7 @@ class DeltaFunctionTest_Gauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -80,7 +80,7 @@ class DeltaFunctionTest_Gauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -67,7 +67,7 @@ class DiffSphereTest_Gauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -81,7 +81,7 @@ class DiffSphereTest_Gauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -90,7 +90,7 @@ class FitTest_Gauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -104,7 +104,7 @@ class FitTest_Gauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -67,7 +67,7 @@ class FunctionTestGauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -81,7 +81,7 @@ class FunctionTestGauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -333,7 +333,7 @@ class GaussianTest : public CxxTest::TestSuite
gaus.initialize();
gaus.setCentre(11.2);
gaus.setHeight(100.7);
gaus.setWidth(2.2);
gaus.setFwhm(2.2);

alg2.setPropertyValue("Function",gaus.asString());

@@ -360,7 +360,7 @@ class GaussianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(out);
TS_ASSERT_DELTA( pk->height(), 97.8035 ,0.0001);
TS_ASSERT_DELTA( pk->centre(), 11.2356 ,0.0001);
TS_ASSERT_DELTA( pk->width(), 2.6237 ,0.0001);
TS_ASSERT_DELTA( pk->fwhm(), 2.6237 ,0.0001);

// check its categories
const std::vector<std::string> categories = out->categories();
@@ -393,7 +393,7 @@ class GaussianTest : public CxxTest::TestSuite
gaus.initialize();
gaus.setCentre(11.2);
gaus.setHeight(100.7);
gaus.setWidth(2.2);
gaus.setFwhm(2.2);

alg2.setPropertyValue("Function",gaus.asString());

@@ -421,7 +421,7 @@ class GaussianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(out);
TS_ASSERT_DELTA( pk->height(), 97.8091 ,0.01);
TS_ASSERT_DELTA( pk->centre(), 11.2356 ,0.001);
TS_ASSERT_DELTA( pk->width(), 2.6240 ,0.001);
TS_ASSERT_DELTA( pk->fwhm(), 2.6240 ,0.001);

AnalysisDataService::Instance().remove(wsName);
}
@@ -451,7 +451,7 @@ class GaussianTest : public CxxTest::TestSuite
gaus.initialize();
gaus.setCentre(11.2);
gaus.setHeight(100.7);
gaus.setWidth(2.2);
gaus.setFwhm(2.2);

alg2.setPropertyValue("Function",gaus.asString());
std::cerr << gaus.asString() << std::endl;
@@ -480,7 +480,7 @@ class GaussianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(out);
TS_ASSERT_DELTA( pk->height(), 97.8091 ,0.05);
TS_ASSERT_DELTA( pk->centre(), 11.2356 ,0.001);
TS_ASSERT_DELTA( pk->width(), 2.6240 ,0.001);
TS_ASSERT_DELTA( pk->fwhm(), 2.6240 ,0.001);
std::cerr << pk->height() << std::endl;

AnalysisDataService::Instance().remove(wsName);
@@ -511,7 +511,7 @@ class GaussianTest : public CxxTest::TestSuite
gaus.initialize();
gaus.setCentre(11.2);
gaus.setHeight(100.7);
gaus.setWidth(2.2);
gaus.setFwhm(2.2);

alg2.setPropertyValue("Function",gaus.asString());

@@ -539,7 +539,7 @@ class GaussianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(out);
TS_ASSERT_DELTA( pk->height(), 97.7995 ,0.0001);
TS_ASSERT_DELTA( pk->centre(), 11.2356 ,0.001);
TS_ASSERT_DELTA( pk->width(), 2.6240 ,0.001);
TS_ASSERT_DELTA( pk->fwhm(), 2.6240 ,0.001);

AnalysisDataService::Instance().remove(wsName);
}
@@ -569,7 +569,7 @@ class GaussianTest : public CxxTest::TestSuite
gaus->initialize();
gaus->setCentre(11.2);
gaus->setHeight(100.7);
gaus->setWidth(2.2);
gaus->setFwhm(2.2);

alg2.setPropertyValue("Function",gaus->asString());

@@ -598,7 +598,7 @@ class GaussianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(out);
TS_ASSERT_DELTA( pk->height(), 97.7857 ,0.0001);
TS_ASSERT_DELTA( pk->centre(), 11.2356 ,0.001);
TS_ASSERT_DELTA( pk->width(), 2.6240 ,0.001);
TS_ASSERT_DELTA( pk->fwhm(), 2.6240 ,0.001);

AnalysisDataService::Instance().remove(wsName);
}
@@ -628,7 +628,7 @@ class GaussianTest : public CxxTest::TestSuite
gaus.initialize();
gaus.setCentre(11.2);
gaus.setHeight(100.7);
gaus.setWidth(2.2);
gaus.setFwhm(2.2);

alg2.setPropertyValue("Function",gaus.asString());

@@ -656,7 +656,7 @@ class GaussianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(out);
TS_ASSERT_DELTA( pk->height(), 97.8111 ,0.0001);
TS_ASSERT_DELTA( pk->centre(), 11.2356 ,0.001);
TS_ASSERT_DELTA( pk->width(), 2.6240 ,0.001);
TS_ASSERT_DELTA( pk->fwhm(), 2.6240 ,0.001);

AnalysisDataService::Instance().remove(wsName);
}
@@ -167,7 +167,7 @@ class IkedaCarpenterPVTest : public CxxTest::TestSuite

TS_ASSERT_DELTA( pk->height(), 13.99 ,1);
TS_ASSERT_DELTA( pk->centre(), 48.229 ,1);
TS_ASSERT_DELTA( pk->width(), 0.4816 ,0.01);
TS_ASSERT_DELTA( pk->fwhm(), 0.4816 ,0.01);
TS_ASSERT_DELTA( out->getParameter("I"), 374.93, 1);
TS_ASSERT_DELTA( out->getParameter("Alpha0"), 1.597107 ,0.0001);
TS_ASSERT_DELTA( out->getParameter("Alpha1"), 1.496805 ,0.001);
@@ -111,7 +111,7 @@ class LorentzianTest : public CxxTest::TestSuite
fn->initialize();
fn->setCentre(11.2);
fn->setHeight(100.7);
fn->setWidth(2.2);
fn->setFwhm(2.2);

fnWithBk.addFunction(fn);
fnWithBk.addFunction(bk);
@@ -141,7 +141,7 @@ class LorentzianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(dynamic_cast<CompositeFunction*>(out)->getFunction(0));
TS_ASSERT_DELTA( pk->height(), 100.6900 ,0.0001);
TS_ASSERT_DELTA( pk->centre(), 11.1994 ,0.0001);
TS_ASSERT_DELTA( pk->width(), 2.1988 ,0.0001);
TS_ASSERT_DELTA( pk->fwhm(), 2.1988 ,0.0001);
TS_ASSERT_DELTA( out->getParameter("f1.A0"), 0.0000 ,0.0001);
TS_ASSERT_DELTA( out->getParameter("f1.A1"), -0.0007 ,0.0001);

@@ -174,7 +174,7 @@ class LorentzianTest : public CxxTest::TestSuite
fn.initialize();
fn.setCentre(11.2);
fn.setHeight(100.7);
fn.setWidth(2.2);
fn.setFwhm(2.2);

// add constraint to function
BoundaryConstraint* bc = new BoundaryConstraint(&fn,"PeakCentre",11.3, 12.0);
@@ -207,7 +207,7 @@ class LorentzianTest : public CxxTest::TestSuite

TS_ASSERT_DELTA( pk->height(), 100.7 ,0.0001);
TS_ASSERT_DELTA( pk->centre(), 11.3 ,0.01);
TS_ASSERT_DELTA( pk->width(), 2.1999 ,0.0001);
TS_ASSERT_DELTA( pk->fwhm(), 2.1999 ,0.0001);

AnalysisDataService::Instance().remove(wsName);
}
@@ -248,7 +248,7 @@ class LorentzianTest : public CxxTest::TestSuite
fn->initialize();
fn->setCentre(11.2);
fn->setHeight(100.7);
fn->setWidth(2.2);
fn->setFwhm(2.2);

// add constraint to function
BoundaryConstraint* bc = new BoundaryConstraint(fn,"PeakCentre",11.3, 12.0);
@@ -282,7 +282,7 @@ class LorentzianTest : public CxxTest::TestSuite
IPeakFunction *pk = dynamic_cast<IPeakFunction *>(dynamic_cast<CompositeFunction*>(out)->getFunction(0));
TS_ASSERT_DELTA( pk->height(), 100.7 ,0.0001);
TS_ASSERT_DELTA( pk->centre(), 11.3 ,0.01);
TS_ASSERT_DELTA( pk->width(), 2.1999 ,0.0001);
TS_ASSERT_DELTA( pk->fwhm(), 2.1999 ,0.0001);
TS_ASSERT_DELTA( out->getParameter("f1.A0"), 0.0 ,0.01);
TS_ASSERT_DELTA( out->getParameter("f1.A1"), 0.0 ,0.01);

@@ -90,7 +90,7 @@ class NewFitTest_Gauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -104,7 +104,7 @@ class NewFitTest_Gauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -76,7 +76,7 @@ class ProductFunctionMWTest_Gauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -90,7 +90,7 @@ class ProductFunctionMWTest_Gauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -63,7 +63,7 @@ class ResolutionTest_Gauss: public IPeakFunction
return getParameter(1);
}

double width()const
double fwhm()const
{
return getParameter(2);
}
@@ -77,7 +77,7 @@ class ResolutionTest_Gauss: public IPeakFunction
setParameter(1,h);
}

void setWidth(const double w)
void setFwhm(const double w)
{
setParameter(2,w);
}
@@ -109,8 +109,6 @@ namespace DataHandling
{
mStartGroupID = startgroupid;
}
void getDetectorIDs(std::vector<detid_t>& detids);
void getSpectrumIDs(std::vector<specid_t>& specids);

std::string getInstrumentName()
{
@@ -395,15 +395,6 @@ namespace DataHandling

return;
}
void LoadGroupXMLFile::getDetectorIDs(std::vector<detid_t>& detids)
{
return;
}
void LoadGroupXMLFile::getSpectrumIDs(std::vector<specid_t>& specids)
{
return;
}


/*
* Initalize Poco XML Parser
@@ -160,8 +160,10 @@ namespace DataObjects

// Get the input histogram
const MantidVec & X = inSpec->readX();
const MantidVec & Y = inSpec->readY();
const MantidVec & E = inSpec->readE();
// To be more thread-safe, we are getting a COPY of the vectors.
// This is probably because the MRU can drop off, deleting the vector while we are using it.
MantidVec Y = inSpec->readY();
MantidVec E = inSpec->readE();
if (Y.size()+1 != X.size())
throw std::runtime_error("Expected a histogram (X vector should be 1 longer than the Y vector)");

@@ -243,8 +243,7 @@ class DLLExport TimeSeriesProperty: public Property
if (fid == mP.end())
throw std::runtime_error("Cannot find data");

// 4. Calcualte return value
Kernel::DateAndTime indextime = fid->time();
// 4. Calculate return value
size_t index = size_t(fid-mP.begin());

return int(index);
@@ -1242,6 +1241,49 @@ class DLLExport TimeSeriesProperty: public Property
return value;
} // END-DEF getSinglevalue()



//-----------------------------------------------------------------------------------------------
/** Returns the value at a particular time
* @param t :: time
* @return Value at time \a t
*/
TYPE getSingleValue(const DateAndTime& t, int& index) const
{
if (mP.size() == 0)
throw std::runtime_error("Property is empty. Cannot return any value");

// 1. Get sorted
sort();

// 2.
TYPE value;
if (t < mP[0].time())
{
// 1. Out side of lower bound
value = mP[0].value();
index = 0;
}
else if (t >= mP.back().time())
{
// 2. Out side of upper bound
value = mP.back().value();
index = int(mP.size())-1;
}
else
{
// 3. Within boundary
index = this->findIndex(t);

if (index < 0 || index >= int(mP.size()))
throw std::logic_error("findIndex() returns index outside range. It is not supposed to be. ");

value = mP[static_cast<size_t>(index)].value();
}

return value;
} // END-DEF getSinglevalue()

//-----------------------------------------------------------------------------------------------
/** Returns total value, added up for all times regardless of filter
* @return Total value from all times

Large diffs are not rendered by default.

@@ -14,22 +14,24 @@
#include "MantidAPI/WorkspaceGroup.h"
#include "MantidMDAlgorithms/MagneticFormFactor.h"

#include <gsl/gsl_errno.h>
#include <gsl/gsl_qrng.h>

namespace Mantid
{
namespace MDAlgorithms
{

/**
Semi-abstract class for fitting with instrument resolution function.
This class implements the MC simulation of the resolution function.
A function defining the scattering S(Q,W) is required in an inherited
class to form the real fit function.
This class implements the MC/Sobol simulation of the resolution function.
A function defining the scattering S(Q,W) is required in a subclass
to provide the real fit function.
This function will be invoked from the fitting process to return the expected signal for
a given set of model parameters at each of the physical detectors within the instrument.
In the MDWorkspaces there may be data from multiple runs and the runIndex of the data point
is used to identify which case is being used.
@date 07/04/2011
1
Copyright &copy; 2007-12 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
@@ -71,9 +73,6 @@ namespace Mantid
protected:
/// function to return the calculated signal at cell r, given the energy dependent model applied to points
virtual double functionMD(Mantid::API::IMDIterator& r) const;
/// This will be over ridden by the user's SQW function TODO argument list is not general enough
//virtual double sqwBroad(const std::vector<double> & point, const std::vector<double> & fgParams,
// const double temp, const Kernel::DblMatrix & ubinv) const=0;
/// This is the new more general interface to the user scattering function which can takes different arguments
/// depending on the sharp/broad setting.
virtual void userSqw(const std::vector<double> & params, const std::vector<double> & qE, std::vector<double> & result) const=0;
@@ -82,42 +81,38 @@ namespace Mantid
/// This will be over ridden by the user's getParam function
virtual void getParams() const = 0;

/** Perform the convolution calculation for one pixel
/** Perform the convolution calculation for one pixel. May implement other methods
* besides MC.
*
* @param e :: MDEvent that corresponds to a pixel in a named detector/run
* @param error :: the error estimate of the calculated scattering
* @return :: the calculated scattering value for this pixel given the SQW model
*/
double sqwConvolution(const Mantid::API::IMDIterator& it, size_t & event, double & error) const;

/** Perform the convolution calculation for one pixel using MonteCarlo method
/** Perform the convolution calculation for one pixel using MonteCarlo/Sobol method
*
* @param e :: MDEvent that corresponds to a pixel in a named detector/run
* @param error :: the error estimate of the calculated scattering
* @return :: the calculated scattering value for this pixel given the SQW model
*/
double sqwConvolutionMC(const Mantid::API::IMDIterator& it, size_t & event, double & error) const;

/// Pointer to the run parameters for each run which may be included in a cut
boost::shared_ptr<Mantid::MDAlgorithms::RunParam> runData;

/// Set magnetic form factor
/// Set magnetic form factor, function can be access in use SQW
void setMagneticForm(const int atomicNo, const int ionisation);

/// Find magnetic form factor at q^2 point
double magneticForm(const double qSquared) const;

/// For MC integration return next point in space
void getNextPoint(std::vector<double>&, int) const;
void getNextPoint(std::vector<double>&) const;
/// Initialise random number generators
void initRandomNumbers();
void initRandom();
/// Initialise particular random method, sobol or random
void initRandom(const bool methodSobol);
/// Reset random number generators
void resetRandomNumbers();
/// A pointer to the random number generator
Kernel::RandomNumberGenerator *m_randGen;
/// Sample S(Q,eps) function from tobyfit
double sqwBroad601(const std::vector<double> &, const std::vector<double> & ,
const double, const Kernel::Matrix<double> & );
/// function to evaluate y/(1-exp(-y)) including y=0 and large -ve y
double pop(const double) const;
/// function to calculate bose factor
@@ -126,11 +121,6 @@ namespace Mantid
double formTable(const double) const;
/// Sample_area_table is lookup function for moderator parameters
double sampleAreaTable( const double ) const;
/// convert 2 uniform random values to two gaussian distribution values
void gasdev2d( const double, const double, double &, double &) const;
/// tridev function from tf - maps a uniform distribution to triangular form?
double tridev(const double) const;
void monteCarloSampleVolume( const double, const double, const double, double &, double &, double & ) const;
/// function to build bmatrix
void bMatrix(const double, const double, const double, const double, const double,
const double, const double, const double,
@@ -139,29 +129,25 @@ namespace Mantid
/// function to build matrices dMat and dinvMat
void dMatrix(const double , const double , Kernel::Matrix<double> & ,
Kernel::Matrix<double> & );
/// Energy resoultion function for moderator and chopper from TF
double enResModChop(const double , const double , const double , const double ,
const double , const double , const double );
/// generate a random scaled vector in the selected space of up to 13 dimensions
void mcYVec(const boost::shared_ptr<Mantid::MDAlgorithms::RunParam> run,
void mcYVec(const double ranvec[], const boost::shared_ptr<Mantid::MDAlgorithms::RunParam> run,
std::vector<double> & yVec, double & eta2, double & eta3 ) const;
/// map from Yvec values to dQ/dE values
void mcMapYtoQEVec(const std::vector<double> & yVec,const std::vector<double> & qE,std::vector<double> & perturbQE) const;
void mcMapYtoQEVec(const std::vector<double> & yVec,const std::vector<double> & qE,const double eta2, const double eta3,
std::vector<double> & perturbQE) const;
/// get transform matrices, vectors for reciprocal space
int rlatt(const std::vector<double> & a, const std::vector<double> & ang,
std::vector<double> & arlu, std::vector<double> & angrlu,
Kernel::Matrix<double> & dMat );
private:
/// Pointer to the run parameter objects, yet to be defined
boost::shared_ptr<MDAlgorithms::RunParam> m_runData;
/// Pointers to the run data for each run
std::vector< boost::shared_ptr<MDAlgorithms::RunParam> > m_runData;
/// Pointer to the group of input MDWorkspaces
API::WorkspaceGroup_sptr m_mdWorkspaces;
boost::shared_ptr<MagneticFormFactor> m_magForm;

/// The default seed for MT random numbers
int m_randSeed;
/// Flag for random number method - may change to enum to allow for several methods
bool m_sobol;
/// Cached Sample Bounding box size for current detector/instrument, assuming cuboid sample
std::vector<double> m_sampleBB;
std::vector<double> m_detectorBB;
@@ -182,6 +168,8 @@ namespace Mantid
int m_run;
/// Flags for MC integration options
std::vector<bool> m_mcOptVec;
/// Random variables per model
std::vector<int> m_mcVarCount;
/// Names for the options within the Monte Carlo vector
enum McOptions
{
@@ -195,12 +183,23 @@ namespace Mantid
mcDetectorTimeBin = 7,
mcMosaic = 8
};
// Only one method now but may be more added later
/// Number of dimensions in use in MC method
size_t m_randSize;
/// Integration method names - only one method now but may be more added later
enum IntegrationMethod
{
mcIntegration = 0
};
IntegrationMethod m_integrationMethod;
// random number generator
enum RandomMethod
{
sobol = 0,
mTwister = 1
};
RandomMethod m_random;
// GSL Sobol random number state information
gsl_qrng *m_qRvec;
int m_event;
};

@@ -4,6 +4,7 @@
#include "MantidMDAlgorithms/RunParam.h"
#include "MantidAPI/IMDWorkspace.h"

#include "MantidGeometry/Instrument/Goniometer.h"
#include "MantidKernel/Tolerance.h"
#include "MantidGeometry/Math/mathSupport.h"
#include "MantidKernel/Matrix.h"
@@ -36,7 +37,7 @@ namespace Mantid

m_ei(ei), m_psi(psi), m_elo(elo),m_ehi(ehi),
m_de(de), m_x0(x0), m_xa(xa), m_x1(x1),
m_wa(wa), m_ha(ha), m_s1(s1), m_s2(s2),
m_s1(s1), m_s2(s2),
m_s3(s3), m_s4(s4), m_s5(s5), m_thetam(thetam),
m_modModel(modModel),
m_tjit(tjit),
@@ -48,13 +49,19 @@ namespace Mantid
m_dpsi(dpsi), m_xh(xh), m_xk(xk),
m_xl(xl), m_yh(yh), m_yk(yk),
m_yl(yl), m_sx(sx), m_sy(sy),
m_sz(sz), m_isam(isam), m_temp(temp),
m_eta(eta)
m_sz(sz), m_isam(isam), m_temp(temp)
{
setAa(aa);
setBb(bb);
setCc(cc);
setHz(hz);
setPslit(pslit);
setRadius(radius);
setRho(rho);
setWa(wa);
setHa(ha);
setEta(eta);
setTauChopperSignal();
};

RunParam::~RunParam()
@@ -130,9 +137,13 @@ namespace Mantid
void RunParam::setX1(const double val)
{m_x1=val;}
void RunParam::setWa(const double val)
{m_wa=val;}
{
m_wa=val*mmTom; // mm to metres
}
void RunParam::setHa(const double val)
{m_ha=val;}
{
m_ha=val*mmTom; // mm to metres
}
void RunParam::setS1(const double val)
{m_s1=val; m_moderatorChange=true;}
void RunParam::setS2(const double val)
@@ -149,30 +160,30 @@ namespace Mantid
{m_modModel=val; m_moderatorChange=true;}
/// set pslit of chopper - input mm, internel m
void RunParam::setPslit(const double val)
{m_pslit=val*mmTom;}
{m_pslit=val*mmTom; }
/// set radius of curvature of chopper - input mm, internel m
void RunParam::setRadius(const double val)
{m_radius=val*mmTom;}
{m_radius=val*mmTom;m_chopChange=true;}
/// set rho of chopper - input mm, internel m
void RunParam::setRho(const double val)
{m_rho=val*mmTom;}
{m_rho=val*mmTom;m_chopChange=true;}
/// Set frequency of chopper, internally use angular velocity
void RunParam::setHz(const double val)
{m_hz=val; m_angVel=val*2.*M_PI;}
{m_hz=val; m_angVel=val*2.*M_PI;m_chopChange=true;}
void RunParam::setTjit(const double val)
{m_tjit=val;}
{m_tjit=val;m_chopChange=true;}
void RunParam::setAs(const double val)
{m_as=val;}
void RunParam::setBs(const double val)
{m_bs=val;}
void RunParam::setCs(const double val)
{m_cs=val;}
void RunParam::setAa(const double val)
{m_aa=val;}
{m_aa=val*M_PI/180.;}
void RunParam::setBb(const double val)
{m_bb=val;}
{m_bb=val*M_PI/180.;}
void RunParam::setCc(const double val)
{m_cc=val;}
{m_cc=val*M_PI/180.;}
void RunParam::setUh(const double val)
{m_uh=val;}
void RunParam::setUk(const double val)
@@ -216,15 +227,71 @@ namespace Mantid
void RunParam::setTemp(const double val)
{m_temp=val;}
void RunParam::setEta(const double val)
{m_eta=val;}
{
m_eta=val;
m_eta_sig = m_eta*(M_PI/180.)/(sqrt(log(256.0))); // Degrees FWHH -> std dev in radians
}
void RunParam::setRunLatticeMatrices( const boost::shared_ptr<Mantid::Geometry::OrientedLattice> lattice)
{
m_as=lattice->a1();
m_bs=lattice->a2();
m_cs=lattice->a3();
m_aa=lattice->alpha1();
m_bb=lattice->alpha2();
m_cc=lattice->alpha3();
}

void RunParam::setTransforms()
{
// determine the transformation matrices for this run:
// m_sampleLab - transform from sample coords to lab coords
// m_uBinv - transform from scattering plane to r.l.u.
// yet to implement
}

// Set Tau for chopper according to model
void RunParam::setTauChopperSignal()
{
m_tauChopperSignal = sqrt( tChopVariance() );
m_tauChopperEffective = sqrt(6.)*m_tauChopperSignal; // FWHH of triangle with same variance as true distribution
}

// Aperture function
void RunParam::getAperturePoint(double & pW, double & pH, const double ran1, const double ran2) const
double RunParam::getTauChopperSignal() const
{
return(m_tauChopperSignal);
}

// Aperture - select random point, assumes rectangle
void RunParam::getAperturePoint( const double ran1, const double ran2, double & pW, double & pH) const
{
// default to rectangular shape
pW = m_wa * (ran1 - 0.5);
pH = m_ha * (ran2 - 0.5);
}

// select random point within sample, only cuboid model at present
void RunParam::getSamplePoint(const double ranvar1, const double ranvar2, const double ranvar3, double & px, double & py, double & pz) const
{
if(m_isam == 1 )
{
// default shape is block
px = m_sx * (ranvar1-0.5) ;
py = m_sy * (ranvar2-0.5) ;
pz = m_sz * (ranvar3-0.5) ;
}
else
{
px = 0.; py = 0.; pz = 0. ;
}
}

// get Mosaic values of crystal assuming 2D Gaussian distribution
void RunParam::getEta23( const double ranvar1, const double ranvar2, double & eta2, double & eta3) const
{
gasdev2d(ranvar1, ranvar2, eta2, eta3);
eta2 = m_eta_sig * eta2;
eta3 = m_eta_sig * eta3;
}
/*
* Sample the the chopper time distribution
*/
@@ -233,21 +300,35 @@ namespace Mantid
return ( m_dtChopEff * tridev(ranvar) );
}
/*
*
* Get a value for the chopper jitter assuming a triangluar distribution
*/
double RunParam::chopperJitter(const double ranvar) const
{
return ( m_tjitSig * sqrt(6.) * tridev(ranvar));
}

/**
* tridev function from tobyfit
* tridev function from tobyfit - map a uniform random variable [0:1] to a triangular distribution [-1:1]
* with peak at zero.
*/
double RunParam::tridev(const double a) const
{
return( (a>0.5)? (1.0-sqrt(fabs(1.0-2.0*fabs(a-0.5)))):( -1.+sqrt( fabs(1.0-2.0*fabs(a-0.5) ) ) ) );
}
/**
* gausdev function from tobyfit - take two uniform random values in [0:1] and map to two Gaussian distributed
* values with mean zero and variance one.
*/
void RunParam::gasdev2d(const double ran1, const double ran2, double & gaus1, double & gaus2) const
{
const double fac=sqrt(-2.*log(std::max(ran1,1e-20)));
gaus1=fac*cos(2.*M_PI*ran2);
gaus2=fac*sin(2.*M_PI*ran2);
}

/*
* Use tchop to estimate chopper time variance
*/
double RunParam::tChopVariance() const
{
return( tChop(m_pslit, m_radius, m_rho, m_angVel, m_ei));
@@ -332,6 +413,49 @@ namespace Mantid

// Moderator related functions

/*
*/
double RunParam::getTauModeratorSignal() const
{
return( 1.e-6*sqrt(3.*m_s1*m_s1+m_s3*(2.-m_s3)*m_s2*m_s2) );
}

/*
*/
double RunParam::getTauModeratorMean() const
{
return( 1.e-6*(3.*m_s1 + m_s3*m_s2) );
}

/*
*/
double RunParam::getTauModeratorAverageUs() const
{
return( 3.*m_s1 + m_s3*m_s2 );
}

/*
* Simple energy resolution model only based on moderator and chopper
* @param eps energy tramsfer (meV)
* @param x2 sample - detector distance (m)
* @return std deviation of energy resolution (meV)
*/
double RunParam::energyResolutionModChop(const double eps, const double x2 ) const
{
if(m_ei<0. || m_ei<eps )
throw std::runtime_error("Energy range problem in energyResolutionModChop");
const double f = 1./2.0721418;
const double wi = sqrt(m_ei*f);
const double wf = sqrt((m_ei-eps)*f);
const double veli = 629.62237*wi;
const double tim = m_x0/veli;
const double wf2wi3 = (wf/wi)*(wf/wi)*(wf/wi);
const double tmp1 = (getTauModeratorSignal()/tim)*(1.+m_x1/x2*wf2wi3);
const double tmp2 = (getTauChopperSignal()/tim)*(1.+(m_x0+m_x1)/x2*wf2wi3);
const double tmp = tmp1*tmp1+tmp2*tmp2;
return ( 2.*m_ei*sqrt(tmp) );
}

/*
* This takes a random variable [0,1] and returns a value for the departure time from the moderator surface.
* The Model used depends on internal settings, though only one currently implemented.
@@ -349,7 +473,7 @@ namespace Mantid
}

/*
* This should take a random variable [0:1] and use a tabe lookup to return the function value
* This should take a random variable [0:1] and use a table lookup to return the function value
* At present it just calls the function which is way too expensive. TODO add lookup table
*/
double RunParam::moderatorTimeLookUp( const double randomVar) const

Large diffs are not rendered by default.

@@ -7,6 +7,7 @@
#include <cmath>
#include <iostream>
#include <boost/scoped_ptr.hpp>
#include "MantidGeometry/Instrument/Goniometer.h"
#include "MantidMDAlgorithms/RunParam.h"

using namespace Mantid::API;
@@ -22,6 +23,8 @@ class RunParamTest : public CxxTest::TestSuite, public RunParam

boost::shared_ptr<Mantid::MDAlgorithms::RunParam> rParam;
boost::shared_ptr<Mantid::MDAlgorithms::RunParam> rParam2;
boost::shared_ptr<Mantid::MDAlgorithms::RunParam> rParam3;
boost::shared_ptr<Mantid::MDAlgorithms::RunParam> rParam4;


public:
@@ -66,8 +69,8 @@ class RunParamTest : public CxxTest::TestSuite, public RunParam
TS_ASSERT_DELTA(rParam2->getXa(),7.19,1e-5);
TS_ASSERT_DELTA(rParam2->getX1(),1.82,1e-5);

TS_ASSERT_DELTA(rParam2->getWa(),66.67,1e-5);
TS_ASSERT_DELTA(rParam2->getHa(),66.67,1e-5);
TS_ASSERT_DELTA(rParam2->getWa(),66.67*1.e-3,1e-5);
TS_ASSERT_DELTA(rParam2->getHa(),66.67*1.e-3,1e-5);

TS_ASSERT_DELTA(rParam2->getS1(),13.55314,1e-5);
TS_ASSERT_DELTA(rParam2->getS2(),50.,1e-5);
@@ -88,9 +91,9 @@ class RunParamTest : public CxxTest::TestSuite, public RunParam
TS_ASSERT_DELTA(rParam2->getBs(),3.87,1e-5);
TS_ASSERT_DELTA(rParam2->getCs(),3.87,1e-5);

TS_ASSERT_DELTA(rParam2->getAa(),90.,1e-5);
TS_ASSERT_DELTA(rParam2->getBb(),90.,1e-5);
TS_ASSERT_DELTA(rParam2->getCc(),90.,1e-5);
TS_ASSERT_DELTA(rParam2->getAa(),M_PI*0.5,1e-5);
TS_ASSERT_DELTA(rParam2->getBb(),M_PI*0.5,1e-5);
TS_ASSERT_DELTA(rParam2->getCc(),M_PI*0.5,1e-5);

TS_ASSERT_DELTA(rParam2->getUh(),1.,1e-5);
TS_ASSERT_DELTA(rParam2->getUk(),0.,1e-5);
@@ -142,6 +145,28 @@ class RunParamTest : public CxxTest::TestSuite, public RunParam
TS_ASSERT_DELTA(rParam2->tridev(1.00),1.00 ,1e-10);

TS_ASSERT_DELTA(rParam2->tChopVariance(), 1.027298e-10 ,1e-15);

double pw,ph;
rParam2->getAperturePoint(0.,0.,pw,ph);
TS_ASSERT_DELTA(pw,-0.0333350,1e-6)
TS_ASSERT_DELTA(ph,-0.0333350,1e-6)
rParam2->getAperturePoint(0.5,0.5,pw,ph);
TS_ASSERT_DELTA(pw,0.0,1e-6)
TS_ASSERT_DELTA(ph,0.0,1e-6)
rParam2->getAperturePoint(1.0,1.0,pw,ph);
TS_ASSERT_DELTA(pw,0.0333350,1e-6)
TS_ASSERT_DELTA(ph,0.0333350,1e-6)

double eta2,eta3;
rParam2->getEta23( 0.25, 0.75, eta2, eta3);
TS_ASSERT_DELTA(eta2,0.0000000, 1e-7)
TS_ASSERT_DELTA(eta3,-0.0061706707,1e-7)
rParam2->getEta23( 0.5, 0.5, eta2, eta3);
TS_ASSERT_DELTA(eta2,-0.004363323, 1e-7)
TS_ASSERT_DELTA(eta3,0.000000000, 1e-7)
rParam2->getEta23( 0.9375, 0.0625,eta2, eta3);
TS_ASSERT_DELTA(eta2,0.001230069, 1e-6)
TS_ASSERT_DELTA(eta3,0.00050951129,1e-6)
/*double sum=0.;
int n=10000000;
std::cout << "start\n";
@@ -155,6 +180,97 @@ class RunParamTest : public CxxTest::TestSuite, public RunParam
*/
}

void testModChopTimes()
{
rParam3 = boost::shared_ptr<RunParam> (new RunParam(
45., 45., 5., 42.,
0.5, 10., 7.19, 1.82,
66.67, 66.67, 13.55314, 50.,
0., 0., 0., 26.7,
1, 2.28, 49., 1300.,
150., 0., 3.87, 3.87,
3.87, 90., 90., 90.,
1., 0., 0., 0.,
1., 0., 0., 0.,
0., 0., 1., 1.,
0., -1., 1., 0.,
10., 14., 18., 1,
10., 0.5
));
TS_ASSERT_DELTA(rParam3->getTauModeratorAverageUs(),40.65942,1e-5);
TS_ASSERT_DELTA(rParam3->getTauModeratorSignal(),2.34747e-5,1e-9);
TS_ASSERT_DELTA(rParam3->getTauModeratorMean(),4.065942e-5,1e-9);
TS_ASSERT_DELTA(rParam3->energyResolutionModChop(12.25, 2.512),1.381791378,4e-8 )
TS_ASSERT_DELTA(rParam3->energyResolutionModChop(13.25, 2.512),1.346621610,4e-8 )
rParam4 = boost::shared_ptr<RunParam> (new RunParam(
447., -90., 0., 0., 0., // ei, psi, elo, ehi, de
10.1, 8.11, 1.9, 70.13, 70.13, //x0,xa,x1,wa,ha
3.31, 0., 0., 0., 0., 32., //s1-5, theta
1, //imod
2.899, 49., 1300., 600., 0.0, //pslit,radius,rho,hz,tjit
2.507, 2.507, 4.069, 90., 90., 120., //as,ab,cs,aa,bb,cc
1., 0., 0., 0., 0., 1., //uhkl,vhkl
0., 0., 0., 0.511967229831443, // omega, gs,gl,dpsi
0., 0., 0., 0., 0., 0., //xhkjl,yhkl
0., 0., 0., 0, //sxyz, isam
10., 0.0 //temp,eta
));
TS_ASSERT_DELTA(rParam4->getTauModeratorAverageUs(),9.930,1e-5);
TS_ASSERT_DELTA(rParam4->energyResolutionModChop(195., 6.034),7.1854280755,4e-7 )
TS_ASSERT_DELTA(rParam4->energyResolutionModChop(197., 6.034),7.1622982277,4e-7 )
}

void testPrivate()
{
rParam3 = boost::shared_ptr<RunParam> (new RunParam(
45., 45., 5., 42.,
0.5, 10., 7.19, 1.82,
66.67, 66.67, 13.55314, 50.,
0., 0., 0., 26.7,
1, 2.28, 49., 1300.,
150., 0., 3., 3.,
3., 90., 90., 50.,
1., 0., 0., 0.,
1., 0., 0., 0.,
0., 0., 1., 1.,
0., -1., 1., 0.,
10., 14., 18., 1,
10., 0.5
));

// experimental testing to be replaced later
OrientedLattice myLat;
boost::shared_ptr<OrientedLattice> oLptr = boost::shared_ptr<OrientedLattice> (new OrientedLattice(3.87,3.87,3.87,90.,90.,90.));
DblMatrix ub=myLat.getUB(); //ub.print();
DblMatrix ub2=oLptr->getUB(); //ub2.print();
V3D u(1.,0.,0.);
V3D v(0.,1.,0.);
oLptr->setUFromVectors(u,v);
DblMatrix ub3=oLptr->getUB(); //ub3.print();
rParam3->setRunLatticeMatrices(oLptr);
TS_ASSERT_DELTA(rParam3->getAs(),3.87,1e-5);
TS_ASSERT_DELTA(rParam3->getBs(),3.87,1e-5);
TS_ASSERT_DELTA(rParam3->getCs(),3.87,1e-5);

TS_ASSERT_DELTA(rParam3->getAa(),M_PI*0.5,1e-5);
TS_ASSERT_DELTA(rParam3->getBb(),M_PI*0.5,1e-5);
TS_ASSERT_DELTA(rParam3->getCc(),M_PI*0.5,1e-5);
V3D u1(0.,0.,1.);
V3D v1(1.,0.,0.);
oLptr->setUFromVectors(u1,v1);
DblMatrix ub4=oLptr->getUB();
//ub4.print();
//oLptr->getB().print();
//oLptr->getU().print();
Goniometer x;
x.makeUniversalGoniometer();
x.setRotationAngle(1,90.);
x.setRotationAngle(2,rParam3->getPsi());
//std::cout << "rot\n";
//x.getR().print();
rParam3->setTransforms();
}

void testTidyUp()
{
}

Large diffs are not rendered by default.

@@ -355,7 +355,8 @@ namespace MDEvents
alg->setProperty("GenerateMultipleEvents", false); // One event per bin by default
alg->setPropertyValue("OutputWorkspace", getPropertyValue("InputWorkspace") + "_event");
alg->executeAsSubAlg();
m_inWS = alg->getProperty("OutputWorkspace");
EventWorkspace_sptr eventWS = alg->getProperty("OutputWorkspace");
m_inWS = boost::dynamic_pointer_cast<MatrixWorkspace>(eventWS);
if (!alg->isExecuted() || !m_inWS)
throw std::runtime_error("Error in ConvertToEventWorkspace. Cannot proceed.");
}
@@ -169,8 +169,7 @@ class ConvertToDiffractionMDWorkspaceTest : public CxxTest::TestSuite
do_test_MINITOPAZ(TOF, 2);
}

/// FIXME: this fails on Ubuntu, sometimes?
void xtest_MINITOPAZ_OneEventPerBin()
void test_MINITOPAZ_OneEventPerBin()
{
do_test_MINITOPAZ(TOF, 1, true);
}
@@ -31,7 +31,7 @@ namespace MPIAlgorithms
<LI> OutputWorkspace - The name of the output workspace. Will only be created by the root process.</LI>
</UL>
Copyright &copy; 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
Copyright &copy; 2011-2 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
@@ -64,47 +64,17 @@ class GatherWorkspaces : public API::Algorithm
virtual int version() const { return (1); }
/// Algorithm's category for identification
virtual const std::string category() const { return "MPI"; }
/// Sum for boostmpi MantidVec
struct vplus
: public std::binary_function<MantidVec, MantidVec, MantidVec>
{ // functor for operator+
MantidVec operator()(const MantidVec& _Left, const MantidVec& _Right) const
{ // apply operator+ to operands
MantidVec v(_Left.size());
std::transform(_Left.begin(), _Left.end(), _Right.begin(), v.begin(), std::plus<double>());
return (v);
}

};
/// Sum for error for boostmpi MantidVec
struct eplus : public std::binary_function<MantidVec, MantidVec, MantidVec>
{ // functor for operator+
MantidVec operator()(const MantidVec& _Left, const MantidVec& _Right) const
{ // apply operator+ to operands
MantidVec v(_Left.size());
std::transform(_Left.begin(), _Left.end(), _Right.begin(), v.begin(), SumGaussError<double>());
return (v);
}
};


private:
void init();
void exec();
//! Functor used for computing the sum of the square values of a vector, using the accumulate algorithm
template <class T> struct SumGaussError: public std::binary_function<T,T,T>
{
SumGaussError(){}
/// Sums the arguments in quadrature
inline T operator()(const T& l, const T& r) const
{
return std::sqrt(l*l+r*r);
}
};


void execEvent();
DataObjects::EventWorkspace_const_sptr eventW;
std::size_t totalSpec;
std::size_t sumSpec;
int hist;
std::size_t numBins;
mpi::communicator included;
@@ -1,8 +1,11 @@
from MantidFramework import *
mtd.initialise()

back = 'NOM_1000_event.nxs'#'/SNS/NOM/2011_2_1B_SCI/1/1000/preNeXus/NOM_1000_neutron_event.dat' # 1GB
van = 'NOM_998_event.nxs'#Cheat for now (real file is huge) #van = '/SNS/users/pf9/NOM_989_event.nxs'#'/SNS/NOM/2011_2_1B_SCI/1/989/preNeXus/NOM_989_neutron_event.dat' # 73GB
#back = 'NOM_1000_event.nxs'#'/SNS/NOM/2011_2_1B_SCI/1/1000/preNeXus/
#van = 'NOM_1000_neutron_event.dat' # 1GB
#van = 'NOM_989_event.nxs'
van = '/SNS/NOM/2011_2_1B_SCI/1/989/preNeXus/NOM_989_neutron_event.dat'
#van = 'NOM_989_neutron_event.dat' # 73GB
#dia = '/SNS/users/pf9/NOM_990_event.nxs'#'/SNS/NOM/2011_2_1B_SCI/1/990/preNeXus/NOM_990_neutron_event.dat' # 65GB
sio2 = 'NOM_998_event.nxs'#'/NOM-DAS-FS/2011_2_1B_SCI/NOM_998/NOM_998_neutron_event.dat' # 5.6GB
#calib = 'NOM_calibrate_d739_2011_03_29.cal'
@@ -26,16 +29,11 @@ def focus(filename):
wksp = os.path.split(filename)[-1]
wksp = '_'.join(wksp.split('_')[0:2]) + "-" + str(1+comm.rank)

# Have a guard so that all processes don't hit the same file at the same time.
# All processes except the root wait for a signal that the (rank-1) process has finished.
if comm.rank > 0:
comm.recv(comm.rank-1)
# Need SingleBankPixelsOnly switched off or DiffractionFocussing fails
LoadEventNexus(Filename=filename, OutputWorkspace=wksp,
BankName="bank"+str(1+comm.rank),
SingleBankPixelsOnly=False, CompressTolerance=.01)
if comm.rank < comm.size-1:
comm.isend(comm.rank+1)
# LoadEventNexus(Filename=filename, OutputWorkspace=wksp,
# BankName="bank"+str(1+comm.rank),
# SingleBankPixelsOnly=False, CompressTolerance=.01)
LoadEventPreNexus(EventFilename=filename, OutputWorkspace=wksp, ChunkNumber=comm.rank+1, TotalChunks=comm.size, UseParallelProcessing="Serial")
# TODO: Check for zero events here?
NormaliseByCurrent(InputWorkspace=wksp, OutputWorkspace=wksp)
AlignDetectors(InputWorkspace=wksp, OutputWorkspace=wksp,
@@ -49,23 +47,18 @@ def focus(filename):


CreateGroupingWorkspace(InstrumentName='NOMAD', GroupNames='NOMAD', OutputWorkspace="grouping")
#CreateGroupingWorkspace(InstrumentName='NOMAD', OldCalFilename=calib, OutputWorkspace="grouping")
print back
back = focus(back)
print back
print sio2
sio2 = focus(sio2)
print sio2
print van
##CreateGroupingWorkspace(InstrumentName='NOMAD', OldCalFilename=calib, OutputWorkspace="grouping")

#back = focus(back)
#sio2 = focus(sio2)
van = focus(van)
print van

sio2 -= back
van -= back
sio2 /= van
#sio2 -= back
#van -= back
#sio2 /= van

done = "Done " + str(1+comm.rank) + "!"
GatherWorkspaces(InputWorkspace=back, OutputWorkspace="nomad")
GatherWorkspaces(InputWorkspace=van, OutputWorkspace="nomad")
if comm.rank == 0:
SumSpectra("nomad","nomad")
SaveNexus(InputWorkspace="nomad",Filename="NOMAD.nxs")
@@ -1,3 +1,10 @@
/*WIKI*
Gathers workspaces from all processors of MPI run. Add or append workspaces to processor 0.
*WIKI*/
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
@@ -12,6 +19,7 @@

namespace mpi = boost::mpi;


namespace Mantid
{
namespace MPIAlgorithms
@@ -21,6 +29,42 @@ using namespace Kernel;
using namespace API;
using namespace DataObjects;

// Anonymous namespace for locally-used functors
namespace {
/// Sum for boostmpi MantidVec
struct vplus : public std::binary_function<MantidVec, MantidVec, MantidVec>
{ // functor for operator+
MantidVec operator()(const MantidVec& _Left, const MantidVec& _Right) const
{ // apply operator+ to operands
MantidVec v(_Left.size());
std::transform(_Left.begin(), _Left.end(), _Right.begin(), v.begin(), std::plus<double>());
return (v);
}
};

/// Functor used for computing the sum of the square values of a vector
template <class T> struct SumGaussError: public std::binary_function<T,T,T>
{
SumGaussError(){}
/// Sums the arguments in quadrature
inline T operator()(const T& l, const T& r) const
{
return std::sqrt(l*l+r*r);
}
};

/// Sum for error for boostmpi MantidVec
struct eplus : public std::binary_function<MantidVec, MantidVec, MantidVec>
{ // functor for operator+
MantidVec operator()(const MantidVec& _Left, const MantidVec& _Right) const
{ // apply operator+ to operands
MantidVec v(_Left.size());
std::transform(_Left.begin(), _Left.end(), _Right.begin(), v.begin(), SumGaussError<double>());
return (v);
}
};
}

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

@@ -40,8 +84,8 @@ void GatherWorkspaces::init()
//propOptions.push_back("Replace");
propOptions.push_back("Append");
declareProperty("AccumulationMethod", "Append", boost::make_shared<StringListValidator>(propOptions),
"Method to use for accumulating each chunk of live data.\n"
" - Add: the processed chunk will be summed to the previous outpu (default).\n"
"Method to use for accumulating each chunk from mpi processorss.\n"
" - Add: the processed chunk will be summed to the previous output (default).\n"
//" - Replace: the processed chunk will replace the previous output.\n"
" - Append: the spectra of the chunk will be appended to the output workspace, increasing its size.");

@@ -89,7 +133,7 @@ void GatherWorkspaces::exec()
std::string accum = this->getPropertyValue("AccumulationMethod");
// Get the total number of spectra in the combined inputs
totalSpec = inputWorkspace->getNumberHistograms();
size_t sumSpec = totalSpec;
sumSpec = totalSpec;
if (accum == "Append")
{
reduce(included, totalSpec, sumSpec, std::plus<std::size_t>(), 0);
@@ -194,7 +238,7 @@ void GatherWorkspaces::execEvent()
g_log.debug() << "Total number of spectra is " << totalSpec << "\n";
// Create the workspace for the output
outputWorkspace =
boost::dynamic_pointer_cast<EventWorkspace>( API::WorkspaceFactory::Instance().create("EventWorkspace", totalSpec,numBins+hist,numBins));
boost::dynamic_pointer_cast<EventWorkspace>( API::WorkspaceFactory::Instance().create("EventWorkspace", sumSpec,numBins+hist,numBins));
//Copy geometry over.
API::WorkspaceFactory::Instance().initializeFromParent(eventW, outputWorkspace, true);
setProperty("OutputWorkspace",outputWorkspace);
@@ -66,6 +66,31 @@ class GatherWorkspacesTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS( inWS->getInstrument()->baseInstrument(), outWS->getInstrument()->baseInstrument() );
}

void testEvents()
{
MPIAlgorithms::GatherWorkspaces gatherer;
TS_ASSERT_THROWS_NOTHING( gatherer.initialize() );
// Create a small workspace
DataObjects::EventWorkspace_sptr inWS = WorkspaceCreationHelper::createEventWorkspaceWithFullInstrument(1,5, true);

TS_ASSERT_THROWS_NOTHING( gatherer.setProperty("InputWorkspace",inWS) );
TS_ASSERT_THROWS_NOTHING( gatherer.setProperty("PreserveEvents",true) );
gatherer.setChild(true); // Make a child algorithm to keep the result out of the ADS

TS_ASSERT( gatherer.execute() );
API::MatrixWorkspace_const_sptr outWS = gatherer.getProperty("OutputWorkspace");
TS_ASSERT_EQUALS( inWS->size(), outWS->size() );
for (int i=0; i < 5; ++i)
{
TS_ASSERT_EQUALS( inWS->readX(0)[i], outWS->readX(0)[i] );
TS_ASSERT_EQUALS( inWS->readY(0)[i], outWS->readY(0)[i] );
TS_ASSERT_EQUALS( inWS->readE(0)[i], outWS->readE(0)[i] );
//TODO: Check spectrum numbers and detector IDs are copied correctly (perhaps?)
}

TS_ASSERT_EQUALS( inWS->getInstrument()->baseInstrument(), outWS->getInstrument()->baseInstrument() );
}

// TODO: Work out a way of testing under MPI because absent that the test is not very interesting
};

@@ -41,6 +41,7 @@ def PyInit(self):
#self.declareProperty("FileType", "Event NeXus",
# Validator=ListValidator(types))
self.declareListProperty("RunNumber", [0], Validator=ArrayBoundedValidator(Lower=0))
self.declareListProperty("Background", [0], Validator=ArrayBoundedValidator(Lower=0))
extensions = [ "_histo.nxs", "_event.nxs", "_runinfo.xml"]
self.declareProperty("Extension", "_event.nxs",
Validator=ListValidator(extensions))
@@ -62,6 +63,8 @@ def PyInit(self):
Description="Comma delimited d-space positions of reference peaks. Use 1-3 for Cross Correlation. Unlimited for many peaks option.")
self.declareProperty("PeakWindowMax", 0.,
Description="Maximum window around a peak to search for it. Optional.")
self.declareProperty("PeakFunction", "Gaussian", Validator=ListValidator(["BackToBackExponential", "Gaussian", "Lorentzian"]),
Description="Type of peak to fit. Used only with CrossCorrelation=False")
self.declareProperty("BackgroundType", "Flat", Validator=ListValidator(['Flat', 'Linear', 'Quadratic']),
Description="Used only with CrossCorrelation=False")
self.declareProperty("DetectorsPeaks", "",
@@ -294,6 +297,9 @@ def _multicalibrate(self, wksp, calib, filterLogs=None):
GetDetOffsetsMultiPeaks(InputWorkspace=str(wksp), OutputWorkspace=str(wksp)+"offset",
DReference=self._peakpos, FitWindowMaxWidth=self.getProperty("PeakWindowMax"), BackgroundType=self.getProperty("BackgroundType"),
MaxOffset=self._maxoffset, MaskWorkspace=str(wksp)+"mask")
if self._xpixelbin*self._ypixelbin>1: # Smooth data if it was summed
SmoothNeighbours(InputWorkspace=str(wksp)+"offset", OutputWorkspace=str(wksp)+"offset", WeightedSum="Flat",
AdjX=self._xpixelbin, AdjY=self._ypixelbin)
Rebin(InputWorkspace=wksp, OutputWorkspace=wksp,Params=str(self._binning[0])+","+str(abs(self._binning[1]))+","+str(self._binning[2]))
CreateGroupingWorkspace(InputWorkspace=wksp, GroupDetectorsBy=self._grouping, OutputWorkspace=str(wksp)+"group")
lcinst = str(self._instrument)
@@ -378,13 +384,22 @@ def PyExec(self):
self._outDir = self.getProperty("OutputDirectory")+"/"
self._outTypes = self.getProperty("SaveAs")
samRuns = self.getProperty("RunNumber")
backRuns = self.getProperty("Background")
if len(samRuns) != len(backRuns):
if (len(backRuns) == 1 and backRuns[0] == 0) or (len(backRuns) <= 0):
backRuns = [0]*len(samRuns)
else:
raise RuntimeError("Number of samples and backgrounds must match (%d!=%d)" % (len(samRuns), len(backRuns)))
lcinst = str(self._instrument)
calib = self._outDir+lcinst+"_calibrate_d"+str(samRuns[0])+strftime("_%Y_%m_%d.cal")
filterWall = (self.getProperty("FilterByTimeMin"), self.getProperty("FilterByTimeMax"))

for samNum in samRuns:
for (samNum, backNum) in zip(samRuns, backRuns):
# first round of processing the sample
samRun = self._loadData(samNum, SUFFIX, filterWall)
if (backNum > 0):
backRun = self._loadData(backNum, SUFFIX, filterWall)
samRun -= backRun
if str(self._instrument) == "SNAP":
alg = CloneWorkspace(samRun, "tmp")
origRun = alg['OutputWorkspace']

Large diffs are not rendered by default.

@@ -90,10 +90,10 @@ namespace Mantid
// I.e. replace the below 6 lines of code with the above 6 lines
virtual double centre()const {return getParameter("PeakCentre");}
virtual double height()const {return getParameter("Height");}
virtual double width()const {return 2*getParameter("HWHM");}
virtual double fwhm()const {return 2*getParameter("HWHM");}
virtual void setCentre(const double c) {setParameter("PeakCentre",c);}
virtual void setHeight(const double h) {setParameter("Height",h);}
virtual void setWidth(const double w) {setParameter("HWHM",w/2.0);}
virtual void setFwhm(const double w) {setParameter("HWHM",w/2.0);}


// ** MODIFY THIS **
@@ -49,10 +49,10 @@ namespace Mantid

virtual double centre()const {return getParameter("lambda");}
virtual double height()const {return getParameter("A");}
virtual double width()const {return 1/getParameter("frequency");}
virtual double fwhm()const {return 1/getParameter("frequency");}
virtual void setCentre(const double c) {setParameter("lambda",c);}
virtual void setHeight(const double h) {setParameter("A",h);}
virtual void setWidth(const double w) {setParameter("frequency",1/w);}
virtual void setFwhm(const double w) {setParameter("frequency",1/w);}


/// Here specify name of function as it will appear
@@ -61,6 +61,7 @@ void EQSANSLoad::init()
declareProperty("UseConfigTOFCuts", false, "If true, the edges of the TOF distribution will be cut according to the configuration file");
declareProperty("LowTOFCut", 0.0, Direction::Input);
declareProperty("HighTOFCut", 0.0, Direction::Input);
declareProperty("WavelengthStep", 0.1, Direction::Input);
declareProperty("UseConfigMask", false, "If true, the masking information found in the configuration file will be used");
declareProperty("UseConfig", true, "If true, the best configuration file found will be used");
declareProperty("CorrectForFlightPath", false, "If true, the TOF will be modified for the true flight path from the sample to the detector pixel");
@@ -570,8 +571,10 @@ void EQSANSLoad::exec()

// Rebin so all the wavelength bins are aligned
const bool preserveEvents = getProperty("PreserveEvents");
std::string params = Poco::NumberFormatter::format(wl_min, 2)
+ ",0.1," + Poco::NumberFormatter::format(wl_combined_max, 2);
const double wl_step = getProperty("WavelengthStep");
std::string params = Poco::NumberFormatter::format(wl_min, 2) + ","
+ Poco::NumberFormatter::format(wl_step, 2) + ","
+ Poco::NumberFormatter::format(wl_combined_max, 2);
IAlgorithm_sptr rebinAlg = createSubAlgorithm("Rebin", 0.71, 0.72);
rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS);
if (preserveEvents) rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS);
@@ -170,10 +170,6 @@ void MantidMatrixCurve::loadData()
// This should only be called for waterfall plots
// Calculate the offsets...
computeWaterfallOffsets();
MantidQwtMatrixWorkspaceData * data = mantidData();
// ...and apply them
data->applyOffsets(d_x_offset,d_y_offset);
invalidateBoundingRect();
}

void MantidMatrixCurve::setData(const QwtData &data)
@@ -201,6 +197,8 @@ void MantidMatrixCurve::draw(QPainter *p,
{
throw std::runtime_error("Only MantidQwtMatrixWorkspaceData can be set to a MantidMatrixCurve");
}
p->translate(d_x_offset,-d_y_offset); // For waterfall plots (will be zero otherwise)
// Don't really know why you'd want errors on a waterfall plot, but just in case...
doDraw(p,xMap,yMap,rect,d);
}
}
@@ -120,7 +120,7 @@ m_width_set(true),m_width(0),m_addingPeak(false),m_resetting(false)
Mantid::API::IPeakFunction* pf = dynamic_cast<Mantid::API::IPeakFunction*>(cf->getFunction(i));
if (pf)
{
m_width = pf->width();
m_width = pf->fwhm();
if (m_width != 0.) break;
}
}
@@ -352,7 +352,7 @@ void PeakPickerTool::draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMa
int ic = xMap.transform(c);
if (peak == m_fitPropertyBrowser->currentHandler())
{// draw current peak
double width = peak->width();
double width = peak->fwhm();
QPen pen;
pen.setColor(QColor(255,0,0));
pen.setStyle(Qt::DashLine);
@@ -408,12 +408,12 @@ void PeakPickerTool::addPeak(double c,double h)
MantidQt::MantidWidgets::PropertyHandler* handler = m_fitPropertyBrowser->addFunction(fnName);
if (!handler || !handler->pfun()) return;
handler->setCentre(c);
double width = handler->width();
double width = handler->fwhm();
if (width == 0)
{
handler->setWidth(m_width);
handler->setFwhm(m_width);
}
if (handler->width() > 0.)
if (handler->fwhm() > 0.)
{
handler->calcBase();
}
@@ -441,14 +441,14 @@ double PeakPickerTool::centre()const
double PeakPickerTool::width()const
{
MantidQt::MantidWidgets::PropertyHandler* h = m_fitPropertyBrowser->currentHandler();
return h? h->width(): 0;
return h? h->fwhm(): 0;
}

// Return the height of the currently selected peak
double PeakPickerTool::height()const
{
MantidQt::MantidWidgets::PropertyHandler* h = m_fitPropertyBrowser->currentHandler();
return h? h->width(): 0;
return h? h->fwhm(): 0;
}

// Change the width of the currently selected peak
@@ -457,7 +457,7 @@ void PeakPickerTool::setWidth(double x)
MantidQt::MantidWidgets::PropertyHandler* h = m_fitPropertyBrowser->currentHandler();
if (!h || !h->pfun()) return;
m_width = x;
h->setWidth(x);
h->setFwhm(x);
double height = h->height() + h->base();
h->calcBase();
h->setHeight(height);
@@ -484,7 +484,7 @@ bool PeakPickerTool::clickedOnWidthMarker(double x,double dx)
MantidQt::MantidWidgets::PropertyHandler* h = m_fitPropertyBrowser->currentHandler();
if (!h) return false;
double c = h->centre();
double w = h->width()/2;
double w = h->fwhm()/2;
return (fabs(x - c - w) <= dx) || (fabs(x - c + w) <= dx);
}

@@ -1541,15 +1541,15 @@ void MultiLayer::showWaterfallOffsetDialog()
connect(yOffsetBox, SIGNAL(valueChanged(int)), active_graph, SLOT(setWaterfallYOffset(int)));
connect(xOffsetBox, SIGNAL(valueChanged(int)), active_graph, SLOT(setWaterfallXOffset(int)));

QPushButton *applyBtn = new QPushButton(tr("&Apply"));
connect(applyBtn, SIGNAL(clicked()), this, SLOT(updateWaterfalls()));
//QPushButton *applyBtn = new QPushButton(tr("&Apply"));
//connect(applyBtn, SIGNAL(clicked()), this, SLOT(updateWaterfalls()));

QPushButton *closeBtn = new QPushButton(tr("&Close"));
connect(closeBtn, SIGNAL(clicked()), offsetDialog, SLOT(reject()));

QHBoxLayout *hl2 = new QHBoxLayout();
hl2->addStretch();
hl2->addWidget(applyBtn);
//hl2->addWidget(applyBtn);
hl2->addWidget(closeBtn);

QVBoxLayout *vl = new QVBoxLayout(offsetDialog);
@@ -185,6 +185,7 @@ void PlotCurve::aboutToBeDeleted()

void PlotCurve::drawCurve(QPainter *p, int style, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const
{
p->translate(d_x_offset,-d_y_offset); // For waterfall plots (will be zero otherwise)
if(d_side_lines)
drawSideLines(p, xMap, yMap, from, to);
QwtPlotCurve::drawCurve(p, style, xMap, yMap, from, to);
@@ -212,6 +213,9 @@ void PlotCurve::setSkipSymbolsCount(int count)
void PlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol, const QwtScaleMap &xMap,
const QwtScaleMap &yMap, int from, int to) const
{
painter->translate(d_x_offset,-d_y_offset); // For waterfall plots (will be zero otherwise)
// Don't really know why you'd want symbols on a waterfall plot, but just in case...

if (d_skip_symbols < 2)
{
QwtPlotCurve::drawSymbols(painter, symbol, xMap, yMap, from, to);
@@ -269,8 +273,6 @@ void PlotCurve::computeWaterfallOffsets()
Plot *plot = (Plot *)this->plot();
Graph *g = (Graph *)plot->parent();

int xAxis = QwtPlot::xBottom;

// reset the offsets
d_x_offset = 0.0;
d_y_offset = 0.0;
@@ -279,23 +281,18 @@ void PlotCurve::computeWaterfallOffsets()
int index = g->curveIndex(this);
int curves = g->curves();//Count();
PlotCurve *c = dynamic_cast<PlotCurve*>(g->curve(0));
// Get the minimum value of the first curve in this plot
double ymin = c->minYValue();
if (index > 0 && c){
double xmin = c->minXValue();
double dx = index*g->waterfallXOffset()*0.01*plot->canvas()->width()/(double)(curves - 1);
//double dx = index*g->waterfallXOffset()*0.01*g->canvas()->width()/(double)(curves - 1);
d_x_offset = plot->invTransform(xAxis, plot->transform(xAxis, xmin) + (int)dx) - xmin;

double ymin = c->minYValue();
double dy = index*g->waterfallYOffset()*0.01*plot->canvas()->height()/(double)(curves - 1);
//double dy = index*g->waterfallYOffset()*0.01*g->canvas()->height()/(double)(curves - 1);
d_y_offset = ymin - plot->invTransform(yAxis(), plot->transform(yAxis(), ymin) + (int)dy);
d_x_offset = index*g->waterfallXOffset()*0.01*plot->canvas()->width()/(double)(curves - 1);
d_y_offset = index*g->waterfallYOffset()*0.01*plot->canvas()->height()/(double)(curves - 1);

setZ(-index);
setBaseline(d_y_offset);
setBaseline(ymin-d_y_offset); // Fill down to minimum value of first curve

} else {
setZ(0);
setBaseline(0.0);
setBaseline(ymin); // This is for when 'fill under curve' is turn on
}
if (g->grid())
g->grid()->setZ(-g->curves()/*Count()*/ - 1);
@@ -509,11 +506,6 @@ void DataCurve::loadData()
{
// Calculate the offsets
computeWaterfallOffsets();
// Apply them to each data point
for (int i = 0; i < size; i++){
X[i] = X[i] + d_x_offset;
Y[i] = Y[i] + d_y_offset;
}
}
// End re-jigged waterfall offset code

@@ -78,9 +78,9 @@ class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS FitPropertyBrowser: public QDockWidget,
/// Set height of the current peak
void setHeight(double value);
/// Width of the current peak
double width()const;
double fwhm()const;
/// Set width of the current peak
void setWidth(double value);
void setFwhm(double value);
/// Get count
int count()const;
/// Is the current function a peak?
@@ -142,14 +142,14 @@ class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS PropertyHandler:public QObject, public M

void setHeight(const double& h);
void setCentre(const double& c);
void setWidth(const double& w);
void setFwhm(const double& w);
void setBase(const double& b){m_base = b;}
void calcBase();//< caclulate baseline from workspace data
void calcBaseAll();//< calc baseline for all peaks in the function

double height()const;
double centre()const;
double width()const;
double fwhm()const;
double base()const{return m_base;}

void addTie(const QString& tieStr);
@@ -1204,23 +1204,23 @@ void FitPropertyBrowser::setHeight(double value)
}

// Width of the current peak
double FitPropertyBrowser::width()const
double FitPropertyBrowser::fwhm()const
{
if (m_currentHandler && m_currentHandler->pfun())
{
return m_currentHandler->pfun()->width();
return m_currentHandler->pfun()->fwhm();
}
return 0;
}

/** Set width of the current peak
* @param value :: The new width value
*/
void FitPropertyBrowser::setWidth(double value)
void FitPropertyBrowser::setFwhm(double value)
{
if (m_currentHandler)
{
m_currentHandler->setWidth(value);
m_currentHandler->setFwhm(value);
}
}

@@ -2430,7 +2430,7 @@ void FitPropertyBrowser::findPeaks()
if (!f) break;
f->setMatrixWorkspace(inputWS,workspaceIndex());
f->setCentre(centre[i]);
f->setWidth(width[i]);
f->setFwhm(width[i]);
f->setHeight(height[i]);
addFunction(f->asString());
delete f;
@@ -878,7 +878,7 @@ Mantid::API::IFitFunction* PropertyHandler::changeType(QtProperty* prop)
{
pf->setCentre(m_pf->centre());
pf->setHeight(m_pf->height());
pf->setWidth(m_pf->width());
pf->setFwhm(m_pf->fwhm());
}
}

@@ -1151,11 +1151,11 @@ void PropertyHandler::setCentre(const double& c)
}
}

void PropertyHandler::setWidth(const double& w)
void PropertyHandler::setFwhm(const double& w)
{
if (m_pf)
{
m_pf->setWidth(w);
m_pf->setFwhm(w);
}
}

@@ -1177,11 +1177,11 @@ double PropertyHandler::centre()const
return (m_browser->endX() + m_browser->startX())/2;
}

double PropertyHandler::width()const
double PropertyHandler::fwhm()const
{
if (m_pf)
{
return m_pf->width();
return m_pf->fwhm();
}
return 0;
}
@@ -206,7 +206,7 @@ def _loadWS(entry, ext, inst, wsName, rawTypes, period=_NO_INDIVIDUAL_PERIODS) :
runDetails = mtd[wsName].getRun()
timeArray = runDetails.getLogData("proton_charge").times
# There should never be a time increment in the proton charge larger than say "two weeks"
# On SANS2D is currently run at 10 frames per second other possibly this may be increated to 5Hz
# SANS2D currently is run at 10 frames per second. This may be increated to 5Hz
# (step of 0.2 sec). Although time between frames may be larger due to having the SMP veto switched on,
# but hopefully not longer than two weeks!
for i in range(len(timeArray)-1):
@@ -512,14 +512,14 @@ def parse_instruction(self, details):
return

parts = details.split('/')
# A spectrum mask or mask range applied to both detectors
if len(parts) == 1:
# A spectrum mask or mask spectra range with H and V commands
if len(parts) == 1: # Command is to type MASK something
#by default only the rear detector is masked
self.add_mask_string(details[4:].lstrip(), detect='rear')
elif len(parts) == 2:
type = parts[1]
elif len(parts) == 2: # Command is to type MASK/ something
type = parts[1] # this is the part of the command following /
detname = type.split()
if type == 'CLEAR':
if type == 'CLEAR': # Command is specifically MASK/CLEAR
self.spec_mask_r = ''
self.spec_mask_f = ''
elif type.startswith('T'):
@@ -571,6 +571,8 @@ def _ConvertToSpecList(self, maskstring, detector):
'''
Convert a mask string to a spectra list
6/8/9 RKH attempt to add a box mask e.g. h12+v34 (= one pixel at intersection), h10>h12+v101>v123 (=block 3 wide, 23 tall)
@param maskstring Is a comma separated list of mask commands for masking spectra using the e.g. the h, s and v commands
'''
#Compile spectra ID list
if maskstring == '':
@@ -606,7 +608,7 @@ def _ConvertToSpecList(self, maskstring, detector):
speclist += detector.spectrum_block(low2, low,nstrips, 'all')+ ','
else:
print "error in mask, ignored: " + x
elif '>' in x:
elif '>' in x: # Commands: MASK Ssp1>Ssp2, MASK Hn1>Hn2 and MASK Vn1>Vn2
pieces = x.split('>')
low = int(pieces[0].lstrip('hvs'))
upp = int(pieces[1].lstrip('hvs'))
@@ -623,7 +625,7 @@ def _ConvertToSpecList(self, maskstring, detector):
speclist += detector.spectrum_block(int(x.lstrip('h')), 0,1, 'all') + ','
elif 'v' in x:
speclist += detector.spectrum_block(0,int(x.lstrip('v')), 'all', 1) + ','
elif 's' in x:
elif 's' in x: # Command MASK Ssp. Although note commands of type MASK Ssp1>Ssp2 handled above
speclist += x.lstrip('s') + ','
elif x == '':
#empty entries are allowed
@@ -27,6 +27,9 @@ def __init__(self, datafile=None, keep_events=False):
self._low_TOF_cut = 0
self._high_TOF_cut = 0

# Wavelength step
self._wavelength_step = None

# TOF flight path correction
self._correct_for_flight_path = False

@@ -57,8 +60,14 @@ def clone(self, data_file=None, keep_events=None):
loader._correct_for_flight_path = self._correct_for_flight_path
loader._use_config_mask = self._use_config_mask
loader._use_config = self._use_config
loader._wavelength_step = self._wavelength_step
return loader

def set_wavelength_step(self, step):
if step is not None and type(step) != int and type(step) != float:
raise RuntimeError, "LoadRun._wavelength_step expects a float: %s" % str(step)
self._wavelength_step = step

def set_sample_detector_distance(self, distance):
# Check that the distance given is either None of a float
if distance is not None and type(distance) != int and type(distance) != float:
@@ -163,6 +172,7 @@ def _load_data_file(file_name, wks_name):
UseConfigTOFCuts=self._use_config_cutoff,
LowTOFCut=self._low_TOF_cut,
HighTOFCut=self._high_TOF_cut,
WavelengthStep=self._wavelength_step,
UseConfigMask=self._use_config_mask,
UseConfig=self._use_config,
CorrectForFlightPath=self._correct_for_flight_path,
@@ -63,6 +63,9 @@ def UseConfigTOFTailsCutoff(use_config=True):
def UseConfigMask(use_config=True):
ReductionSingleton().get_data_loader().use_config_mask(use_config)

def SetWavelengthStep(step=0.1):
ReductionSingleton().get_data_loader().set_wavelength_step(step)

def UseConfig(use_config=True):
ReductionSingleton().get_data_loader().use_config(use_config)