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/Unit.h"
17
18using namespace Mantid::PhysicalConstants;
19
20namespace Mantid::Algorithms {
21
22// Register the algorithm into the AlgorithmFactory
23DECLARE_ALGORITHM(AddPeak)
24
25using namespace Mantid::Kernel;
26using namespace Mantid::API;
31
35 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("PeaksWorkspace", "", Direction::InOut),
36 "A peaks workspace.");
37 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("RunWorkspace", "", Direction::Input),
38 "An input workspace containing the run information.");
39 declareProperty("TOF", 0.0, "Peak position in time of flight.");
40 declareProperty("DetectorID", 0, "ID of a detector at the peak centre.");
41 declareProperty("Height", 0.0, "Height of the peak.");
42 declareProperty("BinCount", 0.0, "Bin count.");
43}
44
48 PeaksWorkspace_sptr peaksWS = getProperty("PeaksWorkspace");
49 MatrixWorkspace_sptr runWS = getProperty("RunWorkspace");
50
51 // Check the instruments match before attempting to add a peak.
52 auto runInst = runWS->getInstrumentName();
53 auto peakInst = peaksWS->getInstrumentName();
54 if (peaksWS->getNumberPeaks() > 0 && (runInst != peakInst)) {
55 throw std::runtime_error("The peak from " + runWS->getName() + " comes from a different instrument (" + runInst +
56 ") to the peaks "
57 "already in the table (" +
58 peakInst + "). It could not be added.");
59 }
60
61 const int detID = getProperty("DetectorID");
62 double tof = getProperty("TOF");
63 const double height = getProperty("Height");
64 const double count = getProperty("BinCount");
65
66 const auto &detectorInfo = runWS->detectorInfo();
67 const auto &componentInfo = runWS->componentInfo();
68 const size_t detectorIndex = detectorInfo.indexOf(detID);
69
70 double theta2 = detectorInfo.twoTheta(detectorIndex);
71 double phi = detectorInfo.phi(detectorIndex);
72
73 // In the inelastic convention, Q = ki - kf.
74 // qSign later in algorithm will change to kf - ki for Crystallography
75 // Convention
76 double Qx = -sin(theta2) * cos(phi);
77 double Qy = -sin(theta2) * sin(phi);
78 double Qz = 1.0 - cos(theta2);
79 double l1 = detectorInfo.l1();
80 double l2 = detectorInfo.l2(detectorIndex);
81 std::vector<int> emptyWarningVec;
82 auto [difa, difc, tzero] = detectorInfo.diffractometerConstants(detectorIndex, emptyWarningVec, emptyWarningVec);
83
84 Mantid::Kernel::Unit_sptr unit = runWS->getAxis(0)->unit();
85 if (unit->unitID() != "TOF") {
86 const Mantid::API::Run &run = runWS->run();
87 int emode = 0;
88 double efixed = 0.0;
89 if (run.hasProperty("Ei")) {
90 emode = 1; // direct
91 efixed = run.getPropertyValueAsType<double>("Ei");
92 } else if (componentInfo.hasParameter(detectorIndex, "Efixed")) {
93 emode = 2; // indirect
94 try {
95 const auto efixedValues = componentInfo.getNumberParameter(detectorIndex, "Efixed");
96 if (!efixedValues.empty()) {
97 efixed = efixedValues.front();
98 }
99 } catch (std::runtime_error &) { /* Throws if the parameter is not a double, use single
100 provided value */
101 }
102 } else {
103 // m_emode = 0; // Elastic
104 // This should be elastic if Ei and Efixed are not set
105 // TODO
106 }
107 std::vector<double> xdata(1, tof);
108 std::vector<double> ydata;
109 unit->toTOF(xdata, ydata, l1, emode,
116 tof = xdata[0];
117 }
118
119 std::string m_qConvention = Kernel::ConfigService::Instance().getString("Q.convention");
120 double qSign = 1.0;
121 if (m_qConvention == "Crystallography") {
122 qSign = -1.0;
123 }
124 double knorm = qSign * NeutronMass * (l1 + l2) / (h_bar * tof * 1e-6) / 1e10;
125 Qx *= knorm;
126 Qy *= knorm;
127 Qz *= knorm;
128
129 IPeak_uptr ipeak = peaksWS->createPeak(Mantid::Kernel::V3D(Qx, Qy, Qz), l2);
130 Peak_uptr peak(static_cast<DataObjects::Peak *>(ipeak.release()));
131 peak->setDetectorID(detID);
132 peak->setGoniometerMatrix(runWS->run().getGoniometer().getR());
133 peak->setBinCount(count);
134 peak->setRunNumber(runWS->getRunNumber());
135 peak->setIntensity(height);
136 if (height > 0.)
137 peak->setSigmaIntensity(std::sqrt(height));
138
139 peaksWS->addPeak(*peak);
140 // peaksWS->modified();
141}
142
143} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
bool hasProperty(const std::string &name) const
Does the property exist on the object.
HeldType getPropertyValueAsType(const std::string &name) const
Get the value of a property as the given TYPE.
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:36
A property class for workspaces.
void exec() override
Run the algorithm.
Definition AddPeak.cpp:47
void init() override
Initialise the properties.
Definition AddPeak.cpp:34
Structure describing a single-crystal peak.
Definition Peak.h:34
The class PeaksWorkspace stores information about a set of SCD peaks.
Class for 3D vectors.
Definition V3D.h:35
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:176
std::unique_ptr< IPeak > IPeak_uptr
Definition IPeak.h:108
std::shared_ptr< Unit > Unit_sptr
Shared pointer to the Unit base class.
Definition Unit_fwd.h:17
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.
@ InOut
Both an input & output workspace.
Definition Property.h:56
@ Input
An input workspace.
Definition Property.h:54