23#include <boost/algorithm/string/classification.hpp>
24#include <boost/algorithm/string/split.hpp>
25#include <boost/math/special_functions/round.hpp>
50 declareParameter(
"GonRotx", 0.0,
"3rd Rotation of Goniometer about the x axis");
51 declareParameter(
"GonRoty", 0.0,
"2nd Rotation of Goniometer about the y axis");
52 declareParameter(
"GonRotz", 0.0,
"1st Rotation of Goniometer about the z axis");
66 std::vector<std::string> OptRunNums;
67 std::string OptRunstemp(
OptRuns);
69 OptRunstemp = OptRunstemp.substr(1, OptRunstemp.size() - 1);
71 if (!OptRunstemp.empty() && OptRunstemp.at(OptRunstemp.size() - 1) ==
'/')
72 OptRunstemp.pop_back();
74 boost::split(OptRunNums, OptRunstemp, boost::is_any_of(
"/"));
76 for (
const auto &OptRunNum : OptRunNums) {
79 declareParameter(
"omega" + OptRunNum, 0.0,
"Omega sample orientation value");
112 const std::shared_ptr<const Geometry::IComponent> &component,
113 std::shared_ptr<const Geometry::ParameterMap> &pmapSv) {
116 if (component->isParametrized()) {
118 auto nms =
pmapSv->names(component.get());
119 for (
const auto &nm : nms) {
121 if (
pmapSv->contains(component.get(), nm,
"double")) {
122 std::vector<double> dparams =
pmapSv->getDouble(component->getName(), nm);
123 pmap->addDouble(component.get(), nm, dparams[0]);
127 if (
pmapSv->contains(component.get(), nm,
"V3D")) {
128 std::vector<V3D> V3Dparams =
pmapSv->getV3D(component->getName(), nm);
129 pmap->addV3D(component.get(), nm, V3Dparams[0]);
133 if (
pmapSv->contains(component.get(), nm,
"int")) {
134 std::vector<int> iparams =
pmapSv->getType<
int>(component->getName(), nm);
135 pmap->addInt(component.get(), nm, iparams[0]);
139 if (
pmapSv->contains(component.get(), nm,
"string")) {
140 std::vector<std::string> sparams =
pmapSv->getString(component->getName(), nm);
141 pmap->addString(component.get(), nm, sparams[0]);
145 if (
pmapSv->contains(component.get(), nm,
"Quat")) {
146 std::vector<Kernel::Quat> sparams =
pmapSv->getType<
Kernel::Quat>(component->getName(), nm);
147 pmap->addQuat(component.get(), nm, sparams[0]);
152 std::shared_ptr<const CompAssembly> parent = std::dynamic_pointer_cast<const CompAssembly>(component);
153 if (parent && parent->nelements() < 180)
156 for (
int child = 0; child < parent->nelements(); child++) {
157 std::shared_ptr<const Geometry::IComponent> kid =
158 std::const_pointer_cast<const Geometry::IComponent>(parent->getChild(child));
178 g_log.
error(
" Peaks workspace does not have an instrument");
179 throw std::invalid_argument(
" Not all peaks have an instrument");
182 auto pmap = std::make_shared<Geometry::ParameterMap>();
184 pmapSv = instSave->getParameterMap();
186 if (!instSave->isParametrized()) {
188 std::shared_ptr<Geometry::Instrument> instClone(instSave->clone());
189 auto Pinsta = std::make_shared<Geometry::Instrument>(instSave,
pmap);
193 sampPos = sample->getRelativePos();
196 auto P1 = std::make_shared<Geometry::Instrument>(instSave->baseInstrument(), instSave->makeLegacyParameterMap());
199 sampPos = sample->getRelativePos();
205 throw std::logic_error(
"Cannot clone instrument");
213 pmap->addPositionCoordinate(sample.get(), std::string(
"x"),
sampPos.
X() + sampOffsets.
X());
214 pmap->addPositionCoordinate(sample.get(), std::string(
"y"),
sampPos.
Y() + sampOffsets.
Y());
215 pmap->addPositionCoordinate(sample.get(), std::string(
"z"),
sampPos.
Z() + sampOffsets.
Z());
234 for (
int i = 0; i < Peaks->getNumberPeaks(); ++i) {
239 size_t N =
OptRuns.find(
"/" + runNumStr +
"/");
241 double chi =
getParameter(
"chi" + boost::lexical_cast<std::string>(runNumStr));
242 double phi =
getParameter(
"phi" + boost::lexical_cast<std::string>(runNumStr));
243 double omega =
getParameter(
"omega" + boost::lexical_cast<std::string>(runNumStr));
249 Res[runNum] = uniGonio.
getR();
265 int cint = toupper(axis);
266 auto c =
static_cast<char>(cint);
267 std::string S(std::string(
"") + c);
268 size_t axisPos = std::string(
"XYZ").find(S);
275 double rTheta = theta / 180 * M_PI;
278 Res[axisPos][axisPos] = 1.0;
279 Res[(axisPos + 1) % 3][(axisPos + 1) % 3] = cos(rTheta);
280 Res[(axisPos + 1) % 3][(axisPos + 2) % 3] = -sin(rTheta);
281 Res[(axisPos + 2) % 3][(axisPos + 2) % 3] = cos(rTheta);
282 Res[(axisPos + 2) % 3][(axisPos + 1) % 3] = sin(rTheta);
298 int cint = toupper(axis);
299 auto c =
static_cast<char>(cint);
300 std::string S(std::string(
"") + c);
301 size_t axisPos = std::string(
"XYZ").find(S);
308 double rTheta = theta / 180 * M_PI;
311 Res[axisPos][axisPos] = 0.0;
312 Res[(axisPos + 1) % 3][(axisPos + 1) % 3] = -sin(rTheta);
313 Res[(axisPos + 1) % 3][(axisPos + 2) % 3] = -cos(rTheta);
314 Res[(axisPos + 2) % 3][(axisPos + 2) % 3] = -sin(rTheta);
315 Res[(axisPos + 2) % 3][(axisPos + 1) % 3] = cos(rTheta);
316 return Res * (M_PI / 180.);
335 throw std::invalid_argument(
"Peaks not stored under the name " +
PeakWorkspaceName);
339 std::map<int, Mantid::Kernel::Matrix<double>> RunNum2GonMatrixMap;
341 const DblMatrix &UBx = peaksWs->sample().getOrientedLattice().getUB();
353 double ChiSqTot = 0.0;
354 for (
size_t i = 0; i < nData; i += 3) {
355 int peakNum = boost::math::iround(xValues[i]);
356 const Peak &peak_old = peaksWs->getPeak(peakNum);
362 size_t N =
OptRuns.find(
"/" + runNumStr +
"/");
374 for (
int k = 0; k < 3; k++) {
375 double d1 = hkl[k] - floor(hkl[k]);
386 g_log.
debug() <<
"------------------------Function---------------------------"
387 "--------------------\n";
388 for (
size_t p = 0; p <
nParams(); p++) {
393 for (
size_t p = 0; p <
nParams(); p++) {
396 if ((constr->
check() > 0))
401 g_log.
debug() <<
" Chi**2 = " << ChiSqTot <<
" nData = " << nData <<
'\n';
408 throw std::invalid_argument(
"Peaks not stored under the name " +
PeakWorkspaceName);
412 const DblMatrix &UB = peaksWs->sample().getOrientedLattice().getUB();
423 Matrix<double> GonRot = InvGonRotxMat * InvGonRotyMat * InvGonRotzMat;
429 std::map<int, Kernel::Matrix<double>> RunNums2GonMatrix;
432 g_log.
debug() <<
"----------------------------Derivative------------------------\n";
434 V3D samplePosition = instNew->getSample()->getPos();
435 const IPeak &ppeak = peaksWs->getPeak(0);
436 double L0 = ppeak.
getL1();
437 double velocity = (L0 + ppeak.
getL2()) / ppeak.
getTOF();
440 V3D beamDir = instNew->getBeamDirection();
442 const size_t paramNums[] = {
parameterIndex(std::string(
"SampleXOffset")),
446 for (
size_t i = 0; i < nData; i += 3) {
447 int peakNum = boost::math::iround(xValues[i]);
448 const Peak &peak_old = peaksWs->getPeak(peakNum);
454 for (
int kk = 0; kk < static_cast<int>(
nParams()); kk++) {
455 out->
set(i, kk, 0.0);
456 out->
set(i + 1, kk, 0.0);
457 out->
set(i + 2, kk, 0.0);
460 double chi, phi, omega;
461 size_t chiParamNum, phiParamNum, omegaParamNum;
463 size_t N =
OptRuns.find(
"/" + runNumStr);
478 chi = phichiOmega[1];
479 phi = phichiOmega[2];
480 omega = phichiOmega[0];
482 chiParamNum = phiParamNum = omegaParamNum =
nParams() + 10;
507 V3D Dhkl0 = UBinv * InvR * lab;
509 R = omegaMatrix * dchiMatrix * phiMatrix;
510 InvR = InvG * R * InvG * -1;
513 R = domegaMatrix * chiMatrix * phiMatrix;
514 InvR = InvG * R * InvG * -1;
517 out->
set(i, chiParamNum, Dhkl1[0]);
518 out->
set(i + 1, chiParamNum, Dhkl1[1]);
519 out->
set(i + 2, chiParamNum, Dhkl1[2]);
520 out->
set(i, phiParamNum, Dhkl0[0]);
521 out->
set(i + 1, phiParamNum, Dhkl0[1]);
522 out->
set(i + 2, phiParamNum, Dhkl0[2]);
523 out->
set(i, omegaParamNum, Dhkl2[0]);
524 out->
set(i + 1, omegaParamNum, Dhkl2[1]);
525 out->
set(i + 2, omegaParamNum, Dhkl2[2]);
535 V3D DGonx = (UBinv * InvGon * InvGonRotzMat * InvGonRotyMat *
548 out->
set(i, paramnum, DGonx[0]);
549 out->
set(i + 1, paramnum, DGonx[1]);
550 out->
set(i + 2, paramnum, DGonx[2]);
565 double vmag = (L0 + D.
norm()) / peak.
getTOF();
566 double t1 = peak.
getTOF() - L0 / vmag;
573 Dmagdsxsysz *= (-1 / D.
norm());
575 V3D vmagdsxsysz = Dmagdsxsysz / peak.
getTOF();
577 V3D t1dsxsysz = vmagdsxsysz * (L0 / vmag / vmag);
582 for (
int x = 0;
x < 3;
x++) {
585 V3D dQlab1 = pp / -t1 - D * (t1dsxsysz[
x] / t1 / t1);
586 V3D dQlab2 = beamDir * vmagdsxsysz[
x];
587 V3D dQlab = dQlab2 - dQlab1;
590 V3D dQSamp = Gon * dQlab;
591 V3D dhkl = UBinv * dQSamp;
593 out->
set(i, paramNums[
x], dhkl[0]);
594 out->
set(i + 1, paramNums[
x], dhkl[1]);
595 out->
set(i + 2, paramNums[
x], dhkl[2]);
601 double T0,
double L0) {
603 if (inst->getComponentID() != instrNew->getComponentID()) {
604 g_log.
error(
"All peaks must have the same instrument");
605 throw std::invalid_argument(
"All peaks must have the same instrument");
608 double T = peak_old.
getTOF() + T0;
619 {{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.
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...
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.
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.
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)