Mantid
Loading...
Searching...
No Matches
LoadHKL.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 +
9#include "MantidAPI/Run.h"
10#include "MantidAPI/Sample.h"
14#include "MantidKernel/Utils.h"
15#include <fstream>
16
17using namespace Mantid::Geometry;
18using namespace Mantid::DataObjects;
19using namespace Mantid::Kernel;
20using namespace Mantid::API;
21using namespace Mantid::PhysicalConstants;
22
23namespace Mantid::Crystal {
24
25// Register the algorithm into the AlgorithmFactory
26DECLARE_ALGORITHM(LoadHKL)
27
28
30void LoadHKL::init() {
31 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Load, ".hkl"),
32 "Path to an hkl file to save.");
33
34 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("OutputWorkspace", "", Direction::Output),
35 "Name of the output workspace.");
36}
37
41
42 std::string filename = getPropertyValue("Filename");
44
45 std::fstream in;
46 in.open(filename.c_str(), std::ios::in);
47
48 // Anvred write from Art Schultz
49 // hklFile.write('%4d%4d%4d%8.2f%8.2f%4d%8.4f%7.4f%7d%7d%7.4f%4d%9.5f%9.4f\n'
50 // % (H, K, L, FSQ, SIGFSQ, hstnum, WL, TBAR, CURHST, SEQNUM, TRANSMISSION,
51 // DN, TWOTH, DSP))
52 // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
53 // Default for kf-ki has -q
54 double qSign = -1.0;
55 std::string convention = ConfigService::Instance().getString("Q.convention");
56 if (convention == "Crystallography")
57 qSign = 1.0;
59 Detector *detector = new Detector("det1", -1, nullptr);
60 detector->setPos(0.0, 0.0, 0.0);
61 inst->add(detector); // This takes care of deletion
62 inst->markAsDetector(detector);
64 inst->add(sample); // This takes care of deletion
65 inst->markAsSamplePos(sample);
67 source->setPos(0.0, 0.0, -1.0);
68 inst->add(source); // This takes care of deletion
69 inst->markAsSource(source);
70
71 std::string line;
72 bool first = true;
73 double mu1 = 0.0, mu2 = 0.0, wl1 = 0.0, wl2 = 0.0, sc1 = 0.0, astar1 = 0.0;
74 do {
75 getline(in, line);
76 double h = 0.0, k = 0.0, l = 0.0, m = 0.0, n = 0.0, p = 0.0;
77 bool cosines;
78 bool modvec;
79 if (line.length() < 95) {
80 cosines = false;
81 modvec = false;
82 } else if (line.length() == 101) {
83 cosines = false;
84 modvec = true;
85 } else if (line.length() == 157) {
86 cosines = true;
87 modvec = false;
88 } else {
89 cosines = true;
90 modvec = true;
91 }
92
93 h = std::stod(line.substr(0, 4));
94 k = std::stod(line.substr(4, 4));
95 l = std::stod(line.substr(8, 4));
96 if (h == 0.0 && k == 0.0 && l == 0.0) {
97 break;
98 }
99
100 int offset = 0;
101
102 if (modvec) {
103 m = std::stod(line.substr(12, 4));
104 n = std::stod(line.substr(16, 4));
105 p = std::stod(line.substr(20, 4));
106 offset += 12;
107 }
108
109 double Inti = std::stod(line.substr(12 + offset, 8));
110 double SigI = std::stod(line.substr(20 + offset, 8));
111 double wl = std::stod(line.substr(32 + offset, 8));
112 double tbar, trans, scattering;
113 int run, bank;
114 int seqNum;
115
116 tbar = std::stod(line.substr(40 + offset, 8)); // tbar
117
118 if (cosines) {
119 offset += 54;
120 }
121
122 run = std::stoi(line.substr(48 + offset, 6));
123 seqNum = std::stoi(line.substr(54 + offset, 7));
124 trans = std::stod(line.substr(61 + offset, 7)); // transmission
125 bank = std::stoi(line.substr(68 + offset, 4));
126 scattering = std::stod(line.substr(72 + offset, 9));
127
128 if (first) {
129 mu1 = -std::log(trans) / tbar;
130 wl1 = wl / 1.8;
131 sc1 = scattering;
132 astar1 = 1.0 / trans;
133 first = false;
134 } else {
135 mu2 = -std::log(trans) / tbar;
136 wl2 = wl / 1.8;
137 }
138
139 Peak peak(inst, scattering, wl);
140 peak.setHKL(qSign * h, qSign * k, qSign * l);
141 peak.setIntHKL(V3D(h, k, l) * qSign);
142 peak.setIntMNP(V3D(m, n, p) * qSign);
143 peak.setIntensity(Inti);
144 peak.setSigmaIntensity(SigI);
145 peak.setRunNumber(run);
146 peak.setPeakNumber(seqNum);
147 std::ostringstream oss;
148 oss << "bank" << bank;
149 std::string bankName = oss.str();
150
151 peak.setBankName(bankName);
152 if (cosines) {
153 int col = std::stoi(line.substr(142, 7));
154 int row = std::stoi(line.substr(149, 7));
155 peak.setCol(col);
156 peak.setRow(row);
157 }
158 ws->addPeak(peak);
159
160 } while (!in.eof());
161
162 in.close();
163 // solve 2 linear equations to find amu and smu
164 double amu = (mu2 - 1.0 * mu1) / (-1.0 * wl1 + wl2);
165 double smu = mu1 - wl1 * amu;
166 double theta = sc1 * radtodeg * 0.5;
167
168 // find roots of polynomial that describes
169 double radius = 0.0;
170 if (std::isfinite(astar1) && astar1 >= 1) {
171 const size_t ndeg = sizeof pc / sizeof pc[0]; // order of poly
172 double coefs[ndeg];
173 std::vector<double> murs;
174 murs.reserve(2);
175 auto ith_lo = static_cast<size_t>(theta / 5.);
176 for (size_t ith = ith_lo; ith < ith_lo + 2; ith++) {
177 for (size_t ideg = 0; ideg < ndeg; ideg++) {
178 coefs[ideg] = pc[ndeg - 1 - ideg][ith];
179 }
180 coefs[0] = coefs[0] - std::log(1.0 / astar1);
181 double roots[2 * (ndeg - 1)];
182 gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc(ndeg);
183 gsl_poly_complex_solve(coefs, ndeg, w, roots);
184 gsl_poly_complex_workspace_free(w);
185
186 for (size_t irt = 0; irt < ndeg - 1; irt++) {
187 if (roots[2 * irt] > 0 && roots[2 * irt] < 9 && std::abs(roots[2 * irt + 1]) < 1e-15) {
188 murs.emplace_back(roots[2 * irt]); // real root in range 0 < muR < 9 cm^-1 (fitted in AnvredCorrection)
189 }
190 }
191 }
192 if (murs.size() == 2) {
193 double frac = (theta - static_cast<double>(ith_lo) * 5.0) / 5.0;
194 radius = (murs[0] * (1 - frac) + murs[1] * frac) / mu1;
195 g_log.notice() << "LinearScatteringCoef = " << smu << " LinearAbsorptionCoef = " << amu << " Radius = " << radius
196 << " calculated from tbar and transmission of 2 peaks\n";
197 } else {
198 g_log.warning() << "Radius set to 0.0 cm - failed to find physical root to polynomial in AnvredCorrections\n";
199 }
200 } else {
201 g_log.warning() << "Radius set to 0.0 cm - non-physical transmission supplied.\n";
202 }
203
204 API::Run &mrun = ws->mutableRun();
205 mrun.addProperty<double>("Radius", radius, true);
206 NeutronAtom neutron(0, 0, 0.0, 0.0, smu, 0.0, smu, amu);
207 auto shape =
208 std::shared_ptr<IObject>(ws->sample().getShape().cloneWithMaterial(Material("SetInLoadHKL", neutron, 1.0)));
209 ws->mutableSample().setShape(shape);
210
211 setProperty("OutputWorkspace", std::dynamic_pointer_cast<PeaksWorkspace>(ws));
212}
213
214} // namespace Mantid::Crystal
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Kernel::Logger & g_log
Definition Algorithm.h:422
@ Load
allowed here which will be passed to the algorithm
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
Definition LogManager.h:91
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:35
A property class for workspaces.
LoadHKL : Load an ISAW-style .hkl file into a PeaksWorkspace.
Definition LoadHKL.h:24
void exec() override
Run the algorithm.
Definition LoadHKL.cpp:40
void setSigmaIntensity(double m_sigmaIntensity) override
Set the error on the integrated peak intensity.
Definition BasePeak.cpp:205
void setIntMNP(const Mantid::Kernel::V3D &MNP) override
Sets the modulated peak structure number.
Definition BasePeak.cpp:152
void setRunNumber(int m_runNumber) override
Set the run number that measured this peak.
Definition BasePeak.cpp:81
void setPeakNumber(int m_peakNumber) override
Sets the unique peak number.
Definition BasePeak.cpp:238
void setIntensity(double m_intensity) override
Set the integrated peak intensity.
Definition BasePeak.cpp:197
void setHKL(double H, double K, double L) override
Set all three H,K,L indices of the peak.
Definition BasePeak.cpp:131
void setIntHKL(const Kernel::V3D &HKL) override
Set int HKL.
Definition BasePeak.cpp:147
Structure describing a single-crystal peak.
Definition Peak.h:34
void setRow(int row)
For RectangularDetectors only, sets the row (y) of the pixel of the detector.
Definition Peak.cpp:332
void setBankName(std::string bankName)
Set the BankName of this peak.
Definition Peak.cpp:352
void setCol(int col)
For RectangularDetectors only, sets the column (x) of the pixel of the detector.
Definition Peak.cpp:341
The class PeaksWorkspace stores information about a set of SCD peaks.
Component is a wrapper for a Component which can modify some of its parameters, e....
Definition Component.h:42
void setPos(double, double, double) override
Set the IComponent position, x, y, z respective to parent (if present)
This class represents a detector - i.e.
Definition Detector.h:30
Base Instrument Class.
Definition Instrument.h:47
Object Component class, this class brings together the physical attributes of the component to the po...
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
Definition Logger.cpp:126
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition Material.h:50
Class for 3D vectors.
Definition V3D.h:34
const double radtodeg
const double pc[8][19]
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
A namespace containing physical constants that are required by algorithms and unit routines.
Definition Atom.h:14
static constexpr double h
Planck constant in J*s.
@ Output
An output workspace.
Definition Property.h:54
Structure to store neutronic scattering information for the various elements.
Definition NeutronAtom.h:22