Mantid
Loading...
Searching...
No Matches
AddPeak.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8#include "MantidAPI/Axis.h"
10#include "MantidAPI/Run.h"
16#include "MantidKernel/System.h"
17#include "MantidKernel/Unit.h"
18
19using namespace Mantid::PhysicalConstants;
20
21namespace Mantid::Algorithms {
22
23// Register the algorithm into the AlgorithmFactory
24DECLARE_ALGORITHM(AddPeak)
25
26using namespace Mantid::Kernel;
27using namespace Mantid::API;
32
36 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("PeaksWorkspace", "", Direction::InOut),
37 "A peaks workspace.");
38 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("RunWorkspace", "", Direction::Input),
39 "An input workspace containing the run information.");
40 declareProperty("TOF", 0.0, "Peak position in time of flight.");
41 declareProperty("DetectorID", 0, "ID of a detector at the peak centre.");
42 declareProperty("Height", 0.0, "Height of the peak.");
43 declareProperty("BinCount", 0.0, "Bin count.");
44}
45
49 PeaksWorkspace_sptr peaksWS = getProperty("PeaksWorkspace");
50 MatrixWorkspace_sptr runWS = getProperty("RunWorkspace");
51
52 // Check the instruments match before attempting to add a peak.
53 auto runInst = runWS->getInstrument()->getName();
54 auto peakInst = peaksWS->getInstrument()->getName();
55 if (peaksWS->getNumberPeaks() > 0 && (runInst != peakInst)) {
56 throw std::runtime_error("The peak from " + runWS->getName() + " comes from a different instrument (" + runInst +
57 ") to the peaks "
58 "already in the table (" +
59 peakInst + "). It could not be added.");
60 }
61
62 const int detID = getProperty("DetectorID");
63 double tof = getProperty("TOF");
64 const double height = getProperty("Height");
65 const double count = getProperty("BinCount");
66
67 const auto &detectorInfo = runWS->detectorInfo();
68 const size_t detectorIndex = detectorInfo.indexOf(detID);
69
70 double theta2 = detectorInfo.twoTheta(detectorIndex);
71 const Mantid::Geometry::IDetector &det = detectorInfo.detector(detectorIndex);
72 double phi = det.getPhi();
73
74 // In the inelastic convention, Q = ki - kf.
75 // qSign later in algorithm will change to kf - ki for Crystallography
76 // Convention
77 double Qx = -sin(theta2) * cos(phi);
78 double Qy = -sin(theta2) * sin(phi);
79 double Qz = 1.0 - cos(theta2);
80 double l1 = detectorInfo.l1();
81 double l2 = detectorInfo.l2(detectorIndex);
82 std::vector<int> emptyWarningVec;
83 auto [difa, difc, tzero] = detectorInfo.diffractometerConstants(detectorIndex, emptyWarningVec, emptyWarningVec);
84
85 Mantid::Kernel::Unit_sptr unit = runWS->getAxis(0)->unit();
86 if (unit->unitID() != "TOF") {
87 const Mantid::API::Run &run = runWS->run();
88 int emode = 0;
89 double efixed = 0.0;
90 if (run.hasProperty("Ei")) {
91 emode = 1; // direct
92 efixed = run.getPropertyValueAsType<double>("Ei");
93 } else if (det.hasParameter("Efixed")) {
94 emode = 2; // indirect
95 try {
96 const Mantid::Geometry::ParameterMap &pmap = runWS->constInstrumentParameters();
97 Mantid::Geometry::Parameter_sptr par = pmap.getRecursive(&det, "Efixed");
98 if (par) {
99 efixed = par->value<double>();
100 }
101 } catch (std::runtime_error &) { /* Throws if a DetectorGroup, use single
102 provided value */
103 }
104 } else {
105 // m_emode = 0; // Elastic
106 // This should be elastic if Ei and Efixed are not set
107 // TODO
108 }
109 std::vector<double> xdata(1, tof);
110 std::vector<double> ydata;
111 unit->toTOF(xdata, ydata, l1, emode,
118 tof = xdata[0];
119 }
120
121 std::string m_qConvention = Kernel::ConfigService::Instance().getString("Q.convention");
122 double qSign = 1.0;
123 if (m_qConvention == "Crystallography") {
124 qSign = -1.0;
125 }
126 double knorm = qSign * NeutronMass * (l1 + l2) / (h_bar * tof * 1e-6) / 1e10;
127 Qx *= knorm;
128 Qy *= knorm;
129 Qz *= knorm;
130
131 IPeak_uptr ipeak = peaksWS->createPeak(Mantid::Kernel::V3D(Qx, Qy, Qz), l2);
132 Peak_uptr peak(static_cast<DataObjects::Peak *>(ipeak.release()));
133 peak->setDetectorID(detID);
134 peak->setGoniometerMatrix(runWS->run().getGoniometer().getR());
135 peak->setBinCount(count);
136 peak->setRunNumber(runWS->getRunNumber());
137 peak->setIntensity(height);
138 if (height > 0.)
139 peak->setSigmaIntensity(std::sqrt(height));
140
141 peaksWS->addPeak(*peak);
142 // peaksWS->modified();
143}
144
145} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double height
Definition: GetAllEi.cpp:155
IntArray detectorIndex
int count
counter
Definition: Matrix.cpp:37
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
bool hasProperty(const std::string &name) const
Does the property exist on the object.
Definition: LogManager.cpp:265
HeldType getPropertyValueAsType(const std::string &name) const
Get the value of a property as the given TYPE.
Definition: LogManager.cpp:332
This class stores information regarding an experimental run as a series of log entries.
Definition: Run.h:38
A property class for workspaces.
void exec() override
Run the algorithm.
Definition: AddPeak.cpp:48
void init() override
Initialise the properties.
Definition: AddPeak.cpp:35
Structure describing a single-crystal peak.
Definition: Peak.h:34
The class PeaksWorkspace stores information about a set of SCD peaks.
virtual bool hasParameter(const std::string &name, bool recursive=true) const =0
Returns a boolean indicating if the component has the named parameter.
Interface class for detector objects.
Definition: IDetector.h:43
virtual double getPhi() const =0
Gives the phi of this detector object in radians.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class for 3D vectors.
Definition: V3D.h:34
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::unique_ptr< Peak > Peak_uptr
Definition: Peak.h:170
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition: Parameter.h:195
std::unique_ptr< IPeak > IPeak_uptr
Definition: IPeak.h:103
std::shared_ptr< Unit > Unit_sptr
Shared pointer to the Unit base class.
Definition: Unit.h:229
A namespace containing physical constants that are required by algorithms and unit routines.
Definition: Atom.h:14
static constexpr double NeutronMass
Mass of the neutron in kg.
static constexpr double h_bar
Planck constant in J*s, divided by 2 PI.
Generate a tableworkspace to store the calibration results.
@ InOut
Both an input & output workspace.
Definition: Property.h:55
@ Input
An input workspace.
Definition: Property.h:53