23#include <boost/math/special_functions/round.hpp>
31using namespace CurveFitting;
33using namespace Kernel;
39Logger
g_log(
"SCDPanelErrors");
77 if (detname.compare(
"none") == 0.0)
81 Kernel::DynamicPointerCastHelper::dynamicPointerCastWithCheck<DataObjects::PeaksWorkspace, API::Workspace>(
84 if (inst->getName().compare(
"CORELLI") == 0.0 && detname !=
"moderator")
85 detname.append(
"/sixteenpack");
87 if (
x != 0.0 ||
y != 0.0 ||
z != 0.0) {
88 auto alg1 = Mantid::API::AlgorithmFactory::Instance().create(
"MoveInstrumentComponent", -1);
91 alg1->setLogging(
false);
93 alg1->setPropertyValue(
"ComponentName", detname);
95 alg1->setProperty(
"X",
x);
96 alg1->setProperty(
"Y",
y);
97 alg1->setProperty(
"Z",
z);
98 alg1->setPropertyValue(
"RelativePosition",
"1");
103 auto algx = Mantid::API::AlgorithmFactory::Instance().create(
"RotateInstrumentComponent", -1);
105 algx->setChild(
true);
106 algx->setLogging(
false);
108 algx->setPropertyValue(
"ComponentName", detname);
109 algx->setProperty(
"X", 1.0);
110 algx->setProperty(
"Y", 0.0);
111 algx->setProperty(
"Z", 0.0);
112 algx->setProperty(
"Angle", rotx);
113 algx->setPropertyValue(
"RelativeRotation",
"1");
118 auto algy = Mantid::API::AlgorithmFactory::Instance().create(
"RotateInstrumentComponent", -1);
120 algy->setChild(
true);
121 algy->setLogging(
false);
123 algy->setPropertyValue(
"ComponentName", detname);
124 algy->setProperty(
"X", 0.0);
125 algy->setProperty(
"Y", 1.0);
126 algy->setProperty(
"Z", 0.0);
127 algy->setProperty(
"Angle", roty);
128 algy->setPropertyValue(
"RelativeRotation",
"1");
133 auto algz = Mantid::API::AlgorithmFactory::Instance().create(
"RotateInstrumentComponent", -1);
135 algz->setChild(
true);
136 algz->setLogging(
false);
138 algz->setPropertyValue(
"ComponentName", detname);
139 algz->setProperty(
"X", 0.0);
140 algz->setProperty(
"Y", 0.0);
141 algz->setProperty(
"Z", 1.0);
142 algz->setProperty(
"Angle", rotz);
143 algz->setPropertyValue(
"RelativeRotation",
"1");
148 std::shared_ptr<const Geometry::RectangularDetector> rectDet =
149 std::dynamic_pointer_cast<const Geometry::RectangularDetector>(comp);
152 auto oldscalex =
pmap.getDouble(rectDet->getName(),
"scalex");
153 auto oldscaley =
pmap.getDouble(rectDet->getName(),
"scaley");
154 double relscalex =
scalex;
155 double relscaley =
scaley;
156 if (!oldscalex.empty())
157 relscalex /= oldscalex[0];
158 if (!oldscaley.empty())
159 relscaley /= oldscaley[0];
160 pmap.addDouble(rectDet.get(),
"scalex",
scalex);
161 pmap.addDouble(rectDet.get(),
"scaley",
scaley);
169void SCDPanelErrors::eval(
double xshift,
double yshift,
double zshift,
double xrotate,
double yrotate,
double zrotate,
170 double scalex,
double scaley,
double *out,
const double *xValues,
const size_t nData,
171 double tShift)
const {
178 std::shared_ptr<API::Workspace> cloned =
m_workspace->clone();
182 Kernel::DynamicPointerCastHelper::dynamicPointerCastWithCheck<DataObjects::PeaksWorkspace, API::Workspace>(
184 auto inst = inputP->getInstrument();
186 for (
int i = 0; i < inputP->getNumberPeaks(); i++) {
188 V3D hkl =
V3D(boost::math::iround(peak.
getH()), boost::math::iround(peak.
getK()), boost::math::iround(peak.
getL()));
191 if (hkl ==
V3D(0, 0, 0))
192 throw std::runtime_error(
"unindexed peak");
196 wl.
initialize(peak2.
getL1(), 0, {{UnitParams::l2, peak2.getL2()}, {UnitParams::twoTheta, peak2.getScattering()}});
197 peak2.setWavelength(wl.singleFromTOF(peak.
getTOF() + tShift));
198 V3D Q3 = peak2.getQSampleFrame();
199 out[i * 3] = Q3[0] - Q2[0];
200 out[i * 3 + 1] = Q3[1] - Q2[1];
201 out[i * 3 + 2] = Q3[2] - Q2[2];
202 }
catch (std::runtime_error &) {
205 out[i * 3 + 1] = 0.15;
206 out[i * 3 + 2] = 0.15;
217void SCDPanelErrors::function1D(
double *out,
const double *xValues,
const size_t nData)
const {
218 const double xshift = getParameter(
"XShift");
219 const double yshift = getParameter(
"YShift");
220 const double zshift = getParameter(
"ZShift");
221 const double xrotate = getParameter(
"XRotate");
222 const double yrotate = getParameter(
"YRotate");
223 const double zrotate = getParameter(
"ZRotate");
224 const double scalex = getParameter(
"ScaleWidth");
225 const double scaley = getParameter(
"ScaleHeight");
226 const double tShift = getParameter(
"T0Shift");
227 eval(xshift, yshift, zshift, xrotate, yrotate, zrotate,
scalex,
scaley, out, xValues, nData, tShift);
237void SCDPanelErrors::functionDeriv1D(
API::Jacobian *out,
const double *xValues,
const size_t nData) {
239 this->calNumericalDeriv(domain, *out);
243void SCDPanelErrors::clear()
const { m_setupFinished =
false; }
250 if (attName ==
"FileName") {
251 std::string fileName =
value.asUnquotedString();
252 if (fileName.empty()) {
253 storeAttributeValue(
"FileName",
Attribute(
"",
true));
257 std::string
error = fval.isValid(fileName);
259 storeAttributeValue(attName,
Attribute(fileName,
true));
260 storeAttributeValue(
"Workspace",
Attribute(
""));
266 }
else if (attName ==
"Workspace") {
267 std::string wsName =
value.asString();
268 if (!wsName.empty()) {
269 storeAttributeValue(attName,
value);
270 storeAttributeValue(
"FileName",
Attribute(
"",
true));
271 loadWorkspace(wsName);
275 m_setupFinished =
false;
283void SCDPanelErrors::load(
const std::string &fname) {
284 auto loadAlg = Mantid::API::AlgorithmFactory::Instance().create(
"Load", -1);
285 loadAlg->initialize();
286 loadAlg->setChild(
true);
287 loadAlg->setLogging(
false);
289 loadAlg->setPropertyValue(
"Filename", fname);
290 loadAlg->setPropertyValue(
"OutputWorkspace",
"_SCDPanelErrors_fit_data_");
292 }
catch (std::runtime_error &) {
293 throw std::runtime_error(
"Unable to load Nexus file for SCDPanelErrors function.");
298 loadWorkspace(resData);
305void SCDPanelErrors::loadWorkspace(
const std::string &wsName)
const {
306 auto ws = AnalysisDataService::Instance().retrieveWS<
API::Workspace>(wsName);
314void SCDPanelErrors::loadWorkspace(std::shared_ptr<API::Workspace> ws)
const {
315 m_workspace = std::move(ws);
316 m_setupFinished =
false;
322void SCDPanelErrors::setupData()
const {
323 if (m_setupFinished) {
324 g_log.
debug() <<
"Re-setting isn't required.";
329 std::string wsName = getAttribute(
"Workspace").asString();
331 throw std::invalid_argument(
"Data not set for function " + this->
name());
333 loadWorkspace(wsName);
336 m_bank = getAttribute(
"Bank").asString();
338 g_log.
debug() <<
"Setting up " << m_workspace->getName() <<
" bank " << m_bank <<
'\n';
340 m_setupFinished =
true;
double value
The value of the point.
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Mantid::API::IFunction::Attribute Attribute
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
1D domain - a wrapper around an array of doubles.
Attribute is a non-fitting parameter.
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
Represents the Jacobian in IFitFunction::functionDeriv.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
Base Workspace Abstract Class.
void moveDetector(double x, double y, double z, double rotx, double roty, double rotz, double scalex, double scaley, std::string detname, const API::Workspace_sptr &inputW) const
Move detectors with parameters.
std::string m_bank
Stores bank.
static const int defaultIndexValue
The default value for the workspace index.
std::shared_ptr< API::Workspace > m_workspace
Temporary workspace holder.
SCDPanelErrors()
Constructor.
void setupData() const
Fill in the workspace and bank names.
void eval(double xshift, double yshift, double zshift, double xrotate, double yrotate, double zrotate, double scalex, double scaley, double *out, const double *xValues, const size_t nData, double tShift) const
Evaluate the function for a list of arguments and given scaling factor.
double getL() const override
Get the L index of the peak.
double getK() const override
Get the K index of the peak.
double getH() const override
Get the H index of the peak.
Mantid::Kernel::Matrix< double > getGoniometerMatrix() const override
Get the goniometer rotation matrix at which this peak was measured.
Structure describing a single-crystal peak.
double getL1() const override
Return the L1 flight path length (source to sample), in meters.
int getDetectorID() const override
Get the ID of the detector at the center of the peak
double getWavelength() const override
Calculate the neutron wavelength (in angstroms) at the peak (Note for inelastic scattering - it is th...
double getTOF() const override
Calculate the time of flight (in microseconds) of the neutrons for this peak, using the geometry of t...
Class to implement UB matrix.
Kernel::V3D qFromHKL(const Kernel::V3D &hkl) const
Calculate the hkl corresponding to a given Q-vector.
Records the filename and the description of failure.
FileValidator is a validator that checks that a filepath is valid.
void debug(const std::string &msg)
Logs at debug level.
void initialize(const double &_l1, const int &_emode, const UnitParametersMap ¶ms)
Initialize the unit to perform conversion using singleToTof() and singleFromTof()
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
MANTID_API_DLL void applyRectangularDetectorScaleToComponentInfo(Geometry::ComponentInfo &componentInfo, Geometry::IComponent *componentId, const double scaleX, const double scaleY)
Helpers for resizing RectangularDetectors.
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
Generate a tableworkspace to store the calibration results.
adjust instrument component position and orientation
: detector size scale at y-direction