22#include <boost/math/special_functions/round.hpp>
47 declareParameter(
"GonRotx", 0.0,
"3rd Rotation of Goniometer about the x axis");
48 declareParameter(
"GonRoty", 0.0,
"2nd Rotation of Goniometer about the y axis");
49 declareParameter(
"GonRotz", 0.0,
"1st Rotation of Goniometer about the z axis");
63 std::vector<std::string> OptRunNums;
64 std::string OptRunstemp(
OptRuns);
66 OptRunstemp = OptRunstemp.substr(1, OptRunstemp.size() - 1);
68 if (!OptRunstemp.empty() && OptRunstemp.at(OptRunstemp.size() - 1) ==
'/')
69 OptRunstemp = OptRunstemp.substr(0, OptRunstemp.size() - 1);
71 boost::split(OptRunNums, OptRunstemp, boost::is_any_of(
"/"));
73 for (
auto &OptRunNum : OptRunNums) {
76 declareParameter(
"omega" + OptRunNum, 0.0,
"Omega sample orientation value");
109 const std::shared_ptr<const Geometry::IComponent> &component,
110 std::shared_ptr<const Geometry::ParameterMap> &pmapSv) {
113 if (component->isParametrized()) {
115 auto nms =
pmapSv->names(component.get());
116 for (
const auto &nm : nms) {
118 if (
pmapSv->contains(component.get(), nm,
"double")) {
119 std::vector<double> dparams =
pmapSv->getDouble(component->getName(), nm);
120 pmap->addDouble(component.get(), nm, dparams[0]);
124 if (
pmapSv->contains(component.get(), nm,
"V3D")) {
125 std::vector<V3D> V3Dparams =
pmapSv->getV3D(component->getName(), nm);
126 pmap->addV3D(component.get(), nm, V3Dparams[0]);
130 if (
pmapSv->contains(component.get(), nm,
"int")) {
131 std::vector<int> iparams =
pmapSv->getType<
int>(component->getName(), nm);
132 pmap->addInt(component.get(), nm, iparams[0]);
136 if (
pmapSv->contains(component.get(), nm,
"string")) {
137 std::vector<std::string> sparams =
pmapSv->getString(component->getName(), nm);
138 pmap->addString(component.get(), nm, sparams[0]);
142 if (
pmapSv->contains(component.get(), nm,
"Quat")) {
143 std::vector<Kernel::Quat> sparams =
pmapSv->getType<
Kernel::Quat>(component->getName(), nm);
144 pmap->addQuat(component.get(), nm, sparams[0]);
149 std::shared_ptr<const CompAssembly> parent = std::dynamic_pointer_cast<const CompAssembly>(component);
150 if (parent && parent->nelements() < 180)
153 for (
int child = 0; child < parent->nelements(); child++) {
154 std::shared_ptr<const Geometry::IComponent> kid =
155 std::const_pointer_cast<const Geometry::IComponent>(parent->getChild(child));
175 g_log.
error(
" Peaks workspace does not have an instrument");
176 throw std::invalid_argument(
" Not all peaks have an instrument");
179 auto pmap = std::make_shared<Geometry::ParameterMap>();
181 pmapSv = instSave->getParameterMap();
183 if (!instSave->isParametrized()) {
185 std::shared_ptr<Geometry::Instrument> instClone(instSave->clone());
186 auto Pinsta = std::make_shared<Geometry::Instrument>(instSave,
pmap);
190 sampPos = sample->getRelativePos();
193 auto P1 = std::make_shared<Geometry::Instrument>(instSave->baseInstrument(), instSave->makeLegacyParameterMap());
196 sampPos = sample->getRelativePos();
202 throw std::logic_error(
"Cannot clone instrument");
210 pmap->addPositionCoordinate(sample.get(), std::string(
"x"),
sampPos.
X() + sampOffsets.
X());
211 pmap->addPositionCoordinate(sample.get(), std::string(
"y"),
sampPos.
Y() + sampOffsets.
Y());
212 pmap->addPositionCoordinate(sample.get(), std::string(
"z"),
sampPos.
Z() + sampOffsets.
Z());
231 for (
int i = 0; i < Peaks->getNumberPeaks(); ++i) {
236 size_t N =
OptRuns.find(
"/" + runNumStr +
"/");
238 double chi =
getParameter(
"chi" + boost::lexical_cast<std::string>(runNumStr));
239 double phi =
getParameter(
"phi" + boost::lexical_cast<std::string>(runNumStr));
240 double omega =
getParameter(
"omega" + boost::lexical_cast<std::string>(runNumStr));
246 Res[runNum] = uniGonio.
getR();
262 int cint = toupper(axis);
263 auto c =
static_cast<char>(cint);
264 std::string S(std::string(
"") + c);
265 size_t axisPos = std::string(
"XYZ").find(S);
272 double rTheta = theta / 180 * M_PI;
275 Res[axisPos][axisPos] = 1.0;
276 Res[(axisPos + 1) % 3][(axisPos + 1) % 3] = cos(rTheta);
277 Res[(axisPos + 1) % 3][(axisPos + 2) % 3] = -sin(rTheta);
278 Res[(axisPos + 2) % 3][(axisPos + 2) % 3] = cos(rTheta);
279 Res[(axisPos + 2) % 3][(axisPos + 1) % 3] = sin(rTheta);
295 int cint = toupper(axis);
296 auto c =
static_cast<char>(cint);
297 std::string S(std::string(
"") + c);
298 size_t axisPos = std::string(
"XYZ").find(S);
305 double rTheta = theta / 180 * M_PI;
308 Res[axisPos][axisPos] = 0.0;
309 Res[(axisPos + 1) % 3][(axisPos + 1) % 3] = -sin(rTheta);
310 Res[(axisPos + 1) % 3][(axisPos + 2) % 3] = -cos(rTheta);
311 Res[(axisPos + 2) % 3][(axisPos + 2) % 3] = -sin(rTheta);
312 Res[(axisPos + 2) % 3][(axisPos + 1) % 3] = cos(rTheta);
313 return Res * (M_PI / 180.);
332 throw std::invalid_argument(
"Peaks not stored under the name " +
PeakWorkspaceName);
336 std::map<int, Mantid::Kernel::Matrix<double>> RunNum2GonMatrixMap;
338 const DblMatrix &UBx = peaksWs->sample().getOrientedLattice().getUB();
350 double ChiSqTot = 0.0;
351 for (
size_t i = 0; i < nData; i += 3) {
352 int peakNum = boost::math::iround(xValues[i]);
353 Peak &peak_old = peaksWs->getPeak(peakNum);
359 size_t N =
OptRuns.find(
"/" + runNumStr +
"/");
371 for (
int k = 0; k < 3; k++) {
372 double d1 = hkl[k] - floor(hkl[k]);
383 g_log.
debug() <<
"------------------------Function---------------------------"
384 "--------------------\n";
385 for (
size_t p = 0; p <
nParams(); p++) {
390 for (
size_t p = 0; p <
nParams(); p++) {
393 if ((constr->
check() > 0))
398 g_log.
debug() <<
" Chi**2 = " << ChiSqTot <<
" nData = " << nData <<
'\n';
405 throw std::invalid_argument(
"Peaks not stored under the name " +
PeakWorkspaceName);
409 const DblMatrix &UB = peaksWs->sample().getOrientedLattice().getUB();
420 Matrix<double> GonRot = InvGonRotxMat * InvGonRotyMat * InvGonRotzMat;
426 std::map<int, Kernel::Matrix<double>> RunNums2GonMatrix;
429 g_log.
debug() <<
"----------------------------Derivative------------------------\n";
431 V3D samplePosition = instNew->getSample()->getPos();
432 IPeak &ppeak = peaksWs->getPeak(0);
433 double L0 = ppeak.
getL1();
434 double velocity = (L0 + ppeak.
getL2()) / ppeak.
getTOF();
437 V3D beamDir = instNew->getBeamDirection();
442 for (
size_t i = 0; i < nData; i += 3) {
443 int peakNum = boost::math::iround(xValues[i]);
444 Peak &peak_old = peaksWs->getPeak(peakNum);
450 for (
int kk = 0; kk < static_cast<int>(
nParams()); kk++) {
451 out->
set(i, kk, 0.0);
452 out->
set(i + 1, kk, 0.0);
453 out->
set(i + 2, kk, 0.0);
456 double chi, phi, omega;
457 size_t chiParamNum, phiParamNum, omegaParamNum;
459 size_t N =
OptRuns.find(
"/" + runNumStr);
474 chi = phichiOmega[1];
475 phi = phichiOmega[2];
476 omega = phichiOmega[0];
478 chiParamNum = phiParamNum = omegaParamNum =
nParams() + 10;
503 V3D Dhkl0 = UBinv * InvR * lab;
505 R = omegaMatrix * dchiMatrix * phiMatrix;
506 InvR = InvG * R * InvG * -1;
509 R = domegaMatrix * chiMatrix * phiMatrix;
510 InvR = InvG * R * InvG * -1;
513 out->
set(i, chiParamNum, Dhkl1[0]);
514 out->
set(i + 1, chiParamNum, Dhkl1[1]);
515 out->
set(i + 2, chiParamNum, Dhkl1[2]);
516 out->
set(i, phiParamNum, Dhkl0[0]);
517 out->
set(i + 1, phiParamNum, Dhkl0[1]);
518 out->
set(i + 2, phiParamNum, Dhkl0[2]);
519 out->
set(i, omegaParamNum, Dhkl2[0]);
520 out->
set(i + 1, omegaParamNum, Dhkl2[1]);
521 out->
set(i + 2, omegaParamNum, Dhkl2[2]);
531 V3D DGonx = (UBinv * InvGon * InvGonRotzMat * InvGonRotyMat *
544 out->
set(i, paramnum, DGonx[0]);
545 out->
set(i + 1, paramnum, DGonx[1]);
546 out->
set(i + 2, paramnum, DGonx[2]);
561 double vmag = (L0 + D.
norm()) / peak.
getTOF();
562 double t1 = peak.
getTOF() - L0 / vmag;
569 Dmagdsxsysz *= (-1 / D.
norm());
571 V3D vmagdsxsysz = Dmagdsxsysz / peak.
getTOF();
573 V3D t1dsxsysz = vmagdsxsysz * (L0 / vmag / vmag);
578 for (
int x = 0;
x < 3;
x++) {
581 V3D dQlab1 = pp / -t1 - D * (t1dsxsysz[
x] / t1 / t1);
582 V3D dQlab2 = beamDir * vmagdsxsysz[
x];
583 V3D dQlab = dQlab2 - dQlab1;
586 V3D dQSamp = Gon * dQlab;
587 V3D dhkl = UBinv * dQSamp;
589 out->
set(i, paramNums[
x], dhkl[0]);
590 out->
set(i + 1, paramNums[
x], dhkl[1]);
591 out->
set(i + 2, paramNums[
x], dhkl[2]);
597 double T0,
double L0) {
599 if (inst->getComponentID() != instrNew->getComponentID()) {
600 g_log.
error(
"All peaks must have the same instrument");
601 throw std::invalid_argument(
"All peaks must have the same instrument");
604 double T = peak_old.
getTOF() + T0;
615 {{UnitParams::l2, peak.
getL2()},
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
An interface to a constraint.
virtual double check()=0
Returns a penalty number which is bigger than or equal to zero If zero it means that the constraint i...
This is a specialization of IFunction for functions of one real argument.
static Kernel::Logger g_log
Logger instance.
virtual IConstraint * getConstraint(size_t i) const
Get constraint of i-th parameter.
Represents the Jacobian in IFitFunction::functionDeriv.
virtual void set(size_t iY, size_t iP, double value)=0
Set a value to a Jacobian matrix element.
Implements the part of IFunction interface dealing with parameters.
size_t parameterIndex(const std::string &name) const override
Returns the index of parameter name.
std::string parameterName(size_t i) const override
Returns the name of parameter i.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
size_t nParams() const override
Total number of parameters.
double getParameter(size_t i) const override
Get i-th parameter.
static DataObjects::Peak createNewPeak(const DataObjects::Peak &peak_old, const Geometry::Instrument_sptr &instrNew, double T0, double L0)
Creates a new peak, matching the old peak except for a different instrument.
std::string PeakWorkspaceName
std::shared_ptr< Geometry::Instrument > instChange
static Kernel::Matrix< double > DerivRotationMatrixAboutRegAxis(double theta, char axis)
Returns the derivative of the matrix corresponding to a rotation of theta(degrees) around axis with r...
void getRun2MatMap(DataObjects::PeaksWorkspace_sptr &Peaks, const std::string &OptRuns, std::map< int, Mantid::Kernel::Matrix< double > > &Res) const
Updates the map from run number to GoniometerMatrix.
static Kernel::Matrix< double > RotationMatrixAboutRegAxis(double theta, char axis)
Returns the matrix corresponding to a rotation of theta(degrees) around axis.
void function1D(double *out, const double *xValues, const size_t nData) const override
Calculates the h,k, and l offsets from an integer for (some of )the peaks, given the parameter values...
void functionDeriv1D(Mantid::API::Jacobian *out, const double *xValues, const size_t nData) override
Derivatives of function with respect to active parameters.
static void cLone(std::shared_ptr< Geometry::ParameterMap > &pmap, const std::shared_ptr< const Geometry::IComponent > &component, std::shared_ptr< const Geometry::ParameterMap > &pmapSv)
"Clones" a parameter map duplicating all Parameters with double,V3D,int and string parameter values t...
std::shared_ptr< const Geometry::ParameterMap > pmapSv
void init() override
Function initialization. Declare function parameters in this method.
std::shared_ptr< Geometry::Instrument > getNewInstrument(const DataObjects::PeaksWorkspace_sptr &peaksWs) const
Creates a new parameterized instrument for which the parameter values can be changed.
void setUpOptRuns()
Declares parameters for the chi,phi and omega angles for the run numbers where these will be optimize...
void setSigmaIntensity(double m_sigmaIntensity) override
Set the error on the integrated peak intensity.
void setRunNumber(int m_runNumber) override
Set the run number that measured this peak.
double getIntensity() const override
Return the integrated peak intensity.
Mantid::Kernel::V3D getSamplePos() const override
Return the sample position vector.
double getSigmaIntensity() const override
Return the error on the integrated peak intensity.
int getRunNumber() const override
Return the run number this peak was measured at.
void setIntensity(double m_intensity) override
Set the integrated peak intensity.
Mantid::Kernel::V3D getHKL() const override
Return the HKL vector.
double getBinCount() const override
Return the # of counts in the bin at its peak.
Mantid::Kernel::Matrix< double > getGoniometerMatrix() const override
Get the goniometer rotation matrix at which this peak was measured.
void setSamplePos(double samX, double samY, double samZ) override
Set sample position.
void setGoniometerMatrix(const Mantid::Kernel::Matrix< double > &goniometerMatrix) override
Set the goniometer rotation matrix at which this peak was measured.
void setBinCount(double m_binCount) override
Set the # of counts in the bin at its peak.
Structure describing a single-crystal peak.
Geometry::Instrument_const_sptr getInstrument() const
Return a shared ptr to the instrument for this peak.
void setWavelength(double wavelength) override
Set the incident wavelength of the neutron.
double getL1() const override
Return the L1 flight path length (source to sample), in meters.
double getInitialEnergy() const override
Get the initial (incident) neutron energy in meV.
Mantid::Kernel::V3D getQLabFrame() const override
Return the Q change (of the lattice, k_i - k_f) for this 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...
virtual Mantid::Kernel::V3D getDetPos() const
Return the detector position vector.
Mantid::Kernel::V3D getQSampleFrame() const override
Return the Q change (of the lattice, k_i - k_f) for this peak.
double getL2() const override
Return the L2 flight path length (sample to detector), in meters.
int getDetectorID() const
Get the ID of the detector at the center of the peak
double getScattering() const override
Calculate the scattering angle of the peak
The class PeaksWorkspace stores information about a set of SCD peaks.
Class for Assembly of geometric components.
Class to represent a particular goniometer setting, which is described by the rotation matrix.
void setRotationAngle(const std::string &name, double value)
Set rotation angle for an axis using motor name.
std::vector< double > getEulerAngles(const std::string &convention="YZX")
Return Euler angles acording to a convention.
void makeUniversalGoniometer()
Make a default universal goniometer with phi,chi,omega angles according to SNS convention.
const Kernel::DblMatrix & getR() const
Return global rotation matrix.
Structure describing a single-crystal peak.
virtual double getTOF() const =0
virtual double getWavelength() const =0
virtual double getL2() const =0
virtual int getRunNumber() const =0
virtual double getL1() const =0
The Logger class is in charge of the publishing messages from the framework through various channels.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
T Invert()
LU inversion routine.
void zeroMatrix()
Set the matrix to zero.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
void initialize(const double &_l1, const int &_emode, const UnitParametersMap ¶ms)
Initialize the unit to perform conversion using singleToTof() and singleFromTof()
double singleFromTOF(const double tof) const override
Convert a single tof value to this unit.
constexpr double X() const noexcept
Get x.
constexpr double Y() const noexcept
Get y.
double norm() const noexcept
constexpr double Z() const noexcept
Get z.
Kernel::Logger g_log("ExperimentInfo")
static logger object
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< const IObjComponent > IObjComponent_const_sptr
Shared pointer to IObjComponent (const version)
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
The namespace for concrete units classes.
Generate a tableworkspace to store the calibration results.
std::string to_string(const wide_integer< Bits, Signed > &n)