Skip to content

Commit

Permalink
refs #7445. Extract axis production to separate methods.
Browse files Browse the repository at this point in the history
These can then be moved to the base class and used by all Reflectometry transforms.
  • Loading branch information
OwenArnold committed Jul 16, 2013
1 parent d124958 commit 93cec18
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,138 +8,156 @@

namespace Mantid
{
namespace API
{
class MatrixWorkspace;
}

namespace MDEvents
{

/**
Converts from inputs of wavelength, incident theta and final theta to Qx for reflectometry experiments
*/
class CalculateReflectometryQx : public CalculateReflectometryQBase
Converts from inputs of wavelength, incident theta and final theta to Qx for reflectometry experiments
*/
class CalculateReflectometryQx: public CalculateReflectometryQBase
{
private:
double m_cos_theta_i;
double m_dirQx;
public:
/**
Constructor
@param thetaIncident: incident theta value in degrees
*/
CalculateReflectometryQx(const double& thetaIncident): m_cos_theta_i(cos(thetaIncident*to_radians_factor))
Constructor
@param thetaIncident: incident theta value in degrees
*/
CalculateReflectometryQx(const double& thetaIncident) :
m_cos_theta_i(cos(thetaIncident * to_radians_factor))
{
}
/**
Setter for the final theta value require for the calculation. Internally pre-calculates and caches to cos theta for speed.
@param thetaFinal: final theta value in degrees
*/
Setter for the final theta value require for the calculation. Internally pre-calculates and caches to cos theta for speed.
@param thetaFinal: final theta value in degrees
*/
void setThetaFinal(const double& thetaFinal)
{
const double c_cos_theta_f = cos(thetaFinal*to_radians_factor);
const double c_cos_theta_f = cos(thetaFinal * to_radians_factor);
m_dirQx = (c_cos_theta_f - m_cos_theta_i);
}
/**
Executes the calculation to determine Qz
@param wavelength : wavelenght in Anstroms
*/
Executes the calculation to determine Qz
@param wavelength : wavelenght in Anstroms
*/
double execute(const double& wavelength) const
{
double wavenumber = 2*M_PI/wavelength;
double wavenumber = 2 * M_PI / wavelength;
return wavenumber * m_dirQx;
}
};

/**
Converts from inputs of wavelength, incident theta and final theta to Qz for reflectometry experiments
*/
class CalculateReflectometryQz : public CalculateReflectometryQBase
Converts from inputs of wavelength, incident theta and final theta to Qz for reflectometry experiments
*/
class CalculateReflectometryQz: public CalculateReflectometryQBase
{
private:
double m_sin_theta_i;
double m_dirQz;
public:
/**
Constructor
@param thetaIncident: incident theta value in degrees
*/
CalculateReflectometryQz(const double& thetaIncident): m_sin_theta_i(sin(thetaIncident*to_radians_factor))
Constructor
@param thetaIncident: incident theta value in degrees
*/
CalculateReflectometryQz(const double& thetaIncident) :
m_sin_theta_i(sin(thetaIncident * to_radians_factor))
{
}
/**
Setter for the final theta value require for the calculation. Internally pre-calculates and caches to sine theta for speed.
@param thetaFinal: final theta value in degrees
*/
Setter for the final theta value require for the calculation. Internally pre-calculates and caches to sine theta for speed.
@param thetaFinal: final theta value in degrees
*/
void setThetaFinal(const double& thetaFinal)
{
const double c_sin_theta_f = sin(thetaFinal*to_radians_factor);
const double c_sin_theta_f = sin(thetaFinal * to_radians_factor);
m_dirQz = (c_sin_theta_f + m_sin_theta_i);
}
/**
Executes the calculation to determine Qz
@param wavelength : wavelenght in Anstroms
*/
Executes the calculation to determine Qz
@param wavelength : wavelenght in Anstroms
*/
double execute(const double& wavelength) const
{
double wavenumber = 2*M_PI/wavelength;
double wavenumber = 2 * M_PI / wavelength;
return wavenumber * m_dirQz;
}
};

/** 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
/** 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.
Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
@date 2012-05-29
This file is part of Mantid.
Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
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.
This file is part of Mantid.
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.
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
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.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport ReflectometryTransformQxQz : public ReflectometryTransform
{
private:
const double m_qxMin;
const double m_qxMax;
const double m_qzMin;
const double m_qzMax;
/// Object performing raw calculation to determine Qx
mutable CalculateReflectometryQx m_QxCalculation;
/// Object performing raw calculation to determine Qx
mutable CalculateReflectometryQz m_QzCalculation;
public:
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
/// Constructor
ReflectometryTransformQxQz(double qxMin, double qxMax, double qzMin, double qzMax, double incidentTheta, int numberOfBinsQx=100, int numberOfBinsQz=100);
/// Destructor
virtual ~ReflectometryTransformQxQz();
/// Execute transformation
virtual Mantid::API::MatrixWorkspace_sptr execute(Mantid::API::MatrixWorkspace_const_sptr inputWs) const;
/// Execute MD transformation
virtual Mantid::API::IMDEventWorkspace_sptr executeMD(Mantid::API::MatrixWorkspace_const_sptr inputWs, Mantid::API::BoxController_sptr boxController) const;
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport ReflectometryTransformQxQz: public ReflectometryTransform
{
private:
const double m_qxMin;
const double m_qxMax;
const double m_qzMin;
const double m_qzMax;
/// Object performing raw calculation to determine Qx
mutable CalculateReflectometryQx m_QxCalculation;
/// Object performing raw calculation to determine Qx
mutable CalculateReflectometryQz m_QzCalculation;
public:

private:
/// Constructor
ReflectometryTransformQxQz(double qxMin, double qxMax, double qzMin, double qzMax,
double incidentTheta, int numberOfBinsQx = 100, int numberOfBinsQz = 100);
/// Destructor
virtual ~ReflectometryTransformQxQz();
/// Execute transformation
virtual Mantid::API::MatrixWorkspace_sptr execute(
Mantid::API::MatrixWorkspace_const_sptr inputWs) const;
/// Execute MD transformation
virtual Mantid::API::IMDEventWorkspace_sptr executeMD(
Mantid::API::MatrixWorkspace_const_sptr inputWs,
Mantid::API::BoxController_sptr boxController) const;

DISABLE_DEFAULT_CONSTRUCT(ReflectometryTransformQxQz)
DISABLE_COPY_AND_ASSIGN(ReflectometryTransformQxQz)
private:

};
DISABLE_DEFAULT_CONSTRUCT(ReflectometryTransformQxQz)
DISABLE_COPY_AND_ASSIGN(ReflectometryTransformQxQz)

/// Create a new x-axis for the output workspace
MantidVec createXAxis(Mantid::API::MatrixWorkspace* const ws, const double gradQx,
const double cxToUnit, const int nBins, const std::string& caption,
const std::string& units) const;

/// Create a new y(vertical)-axis for the output workspace
void createVerticalAxis(Mantid::API::MatrixWorkspace* const ws, const MantidVec& xAxisVec,
const double gradQz, const double cyToUnit, const int nBins, const std::string& caption,
const std::string& units) const;
};

} // namespace MDEvents
} // namespace MDEvents
} // namespace Mantid

#endif /* MANTID_MDEVENTS_REFLECTOMETRYTRANFORMQXQZ_H_ */
94 changes: 66 additions & 28 deletions Code/Mantid/Framework/MDEvents/src/ReflectometryTransformQxQz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,77 @@ namespace Mantid
return ws;
}

/**
* Create a new X-Axis for the output workspace
* @param ws : Workspace to attach the axis to
* @param gradX : Gradient used in the linear transform from index to X-scale
* @param cxToUnit : C-offset used in the linear transform
* @param nBins : Number of bins along this axis
* @param caption : Caption for the axis
* @param units : Units label for the axis
* @return Vector containing increments along the axis.
*/
MantidVec ReflectometryTransformQxQz::createXAxis(MatrixWorkspace* const ws, const double gradX,
const double cxToUnit, const int nBins, const std::string& caption, const std::string& units) const
{
// Create an X - Axis.
Axis* const xAxis = new NumericAxis(nBins);
ws->replaceAxis(0, xAxis);
auto unitXBasePtr = UnitFactory::Instance().create("Label");
boost::shared_ptr<Mantid::Kernel::Units::Label> xUnit = boost::dynamic_pointer_cast<
Mantid::Kernel::Units::Label>(unitXBasePtr);
xUnit->setLabel(caption, units);
xAxis->unit() = xUnit;
xAxis->title() = caption;
MantidVec xAxisVec(nBins);
for (int i = 0; i < nBins; ++i)
{
double qxIncrement = (1 / gradX) * (i + 1) + cxToUnit;
xAxis->setValue(i, qxIncrement);
xAxisVec[i] = qxIncrement;
}
return xAxisVec;
}


/**
* Create a new Y, or Vertical Axis for the output workspace
* @param ws : Workspace to attache the vertical axis to
* @param xAxisVec : Vector of x axis increments
* @param gradY : Gradient used in linear transform from index to Y-scale
* @param cyToUnit : C-offset used in the linear transform
* @param nBins : Number of bins along the axis
* @param caption : Caption for the axis
* @param units : Units label for the axis
*/
void ReflectometryTransformQxQz::createVerticalAxis(MatrixWorkspace* const ws, const MantidVec& xAxisVec,
const double gradY, const double cyToUnit, const int nBins, const std::string& caption, const std::string& units) const
{
// Create a Y (vertical) Axis
Axis* const verticalAxis = new NumericAxis(nBins);
ws->replaceAxis(1, verticalAxis);
auto unitZBasePtr = UnitFactory::Instance().create("Label");
boost::shared_ptr<Mantid::Kernel::Units::Label> verticalUnit = boost::dynamic_pointer_cast<
Mantid::Kernel::Units::Label>(unitZBasePtr);
verticalAxis->unit() = verticalUnit;
verticalUnit->setLabel(caption, units);
verticalAxis->title() = caption;
for (int i = 0; i < nBins; ++i)
{
ws->setX(i, xAxisVec);
double qzIncrement = (1 / gradY) * (i + 1) + cyToUnit;
verticalAxis->setValue(i, qzIncrement);
}
}

/**
* Execute the transformation. Generates an output Matrix workspace.
* @param inputWs : Input workspace with a vertical axis of signed-theta and an x-axis of wavelength
* @return : A 2D workspace with qz on the vertical axis and qx on the horizontal axis.
*/
MatrixWorkspace_sptr ReflectometryTransformQxQz::execute(MatrixWorkspace_const_sptr inputWs) const
{

auto ws = boost::make_shared<Mantid::DataObjects::Workspace2D>();

ws->initialize(m_nbinsz, m_nbinsx, m_nbinsx); // Create the output workspace as a distribution
Expand All @@ -119,35 +183,9 @@ namespace Mantid
const double czToQ = m_qzMin - ( 1 / gradQz);

// Create an X - Axis.
Axis* const xAxis = new NumericAxis(m_nbinsx);
ws->replaceAxis(0, xAxis);
auto unitXBasePtr = UnitFactory::Instance().create("Label");
boost::shared_ptr<Mantid::Kernel::Units::Label> xUnit = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(unitXBasePtr);
xUnit->setLabel("qx", "1/Angstrom");
xAxis->unit() = xUnit;
xAxis->title() = "qx";
MantidVec xAxisVec(m_nbinsx);
for (int i = 0; i < m_nbinsx; ++i)
{
double qxIncrement = (1 / gradQx) * (i+1) + cxToQ;
xAxis->setValue(i, qxIncrement);
xAxisVec[i] = qxIncrement;
}

MantidVec xAxisVec = createXAxis(ws.get(), gradQx, cxToQ, m_nbinsx, "qx", "1/Angstroms");
// Create a Y (vertical) Axis
Axis* const verticalAxis = new NumericAxis(m_nbinsz);
ws->replaceAxis(1, verticalAxis);
auto unitZBasePtr = UnitFactory::Instance().create("Label");
boost::shared_ptr<Mantid::Kernel::Units::Label> verticalUnit = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(unitZBasePtr);
verticalAxis->unit() = verticalUnit;
verticalUnit->setLabel("qz", "1/Angstrom");
verticalAxis->title() = "qz";
for (int i = 0; i < m_nbinsz; ++i)
{
ws->setX(i, xAxisVec);
double qzIncrement = (1 / gradQz) * (i+1) + czToQ;
verticalAxis->setValue(i, qzIncrement);
}
createVerticalAxis(ws.get(), xAxisVec, gradQz, czToQ, m_nbinsz, "qz", "1/Angstroms");

// Loop over all entries in the input workspace and calculate qx and qz for each.
auto spectraAxis = inputWs->getAxis(1);
Expand Down

0 comments on commit 93cec18

Please sign in to comment.