Mantid
Loading...
Searching...
No Matches
CrystalFieldMultiSpectrum.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 +
15
22
24#include "MantidKernel/Logger.h"
25#include <boost/regex.hpp>
26
28
29using namespace CurveFitting;
30using namespace Kernel;
31using namespace API;
32
33DECLARE_FUNCTION(CrystalFieldMultiSpectrum)
34
35namespace {
36
37Kernel::Logger g_log("CrystalFieldMultiSpectrum");
38
39// Regex for the FWHMX# type strings (single-site mode)
40const boost::regex FWHMX_ATTR_REGEX("FWHMX([0-9]+)");
41const boost::regex FWHMY_ATTR_REGEX("FWHMY([0-9]+)");
42
45class Peaks : public CrystalFieldPeaksBase, public API::IFunctionGeneral {
46public:
47 Peaks() : CrystalFieldPeaksBase() {}
48 std::string name() const override { return "Peaks"; }
49 size_t getNumberDomainColumns() const override {
50 throw Exception::NotImplementedError("This method is intentionally not implemented.");
51 }
52 size_t getNumberValuesPerArgument() const override {
53 throw Exception::NotImplementedError("This method is intentionally not implemented.");
54 }
55 void functionGeneral(const API::FunctionDomainGeneral & /*domain*/, API::FunctionValues & /*values*/) const override {
56 throw Exception::NotImplementedError("This method is intentionally not implemented.");
57 }
58 std::vector<size_t> m_IntensityScalingIdx;
59 std::vector<size_t> m_PPLambdaIdxChild;
60 std::vector<size_t> m_PPLambdaIdxSelf;
61 std::vector<size_t> m_PPChi0IdxChild;
62 std::vector<size_t> m_PPChi0IdxSelf;
64 void declareIntensityScaling(size_t nSpec) {
66 m_PPLambdaIdxChild.resize(nSpec, -1);
67 m_PPLambdaIdxSelf.resize(nSpec, -1);
68 m_PPChi0IdxChild.resize(nSpec, -1);
69 m_PPChi0IdxSelf.resize(nSpec, -1);
70 for (size_t i = 0; i < nSpec; ++i) {
71 auto si = std::to_string(i);
72 try { // If parameter has already been declared, don't declare it.
73 declareParameter("IntensityScaling" + si, 1.0, "Intensity scaling factor for spectrum " + si);
74 } catch (std::invalid_argument &) {
75 }
76 m_IntensityScalingIdx.emplace_back(parameterIndex("IntensityScaling" + si));
77 }
78 }
80 void declarePPLambda(size_t iSpec) {
81 if (m_PPLambdaIdxSelf.size() <= iSpec) {
82 m_PPLambdaIdxSelf.resize(iSpec + 1, -1);
83 m_PPLambdaIdxChild.resize(iSpec + 1, -1);
84 m_PPChi0IdxSelf.resize(iSpec + 1, -1);
85 m_PPChi0IdxChild.resize(iSpec + 1, -1);
86 }
87 auto si = std::to_string(iSpec);
88 try { // If parameter has already been declared, don't declare it.
89 declareParameter("Lambda" + si, 0.0, "Effective exchange coupling of dataset " + si);
90 } catch (std::invalid_argument &) {
91 }
92 try { // If parameter has already been declared, don't declare it.
93 declareParameter("Chi0" + si, 0.0, "Effective exchange coupling of dataset " + si);
94 } catch (std::invalid_argument &) {
95 }
96 m_PPLambdaIdxSelf[iSpec] = parameterIndex("Lambda" + si);
97 m_PPChi0IdxSelf[iSpec] = parameterIndex("Chi0" + si);
98 }
99};
100} // namespace
101
104 declareAttribute("Temperatures", Attribute(std::vector<double>(1, 1.0)));
105 declareAttribute("Background", Attribute("FlatBackground", true));
106 declareAttribute("PeakShape", Attribute("Lorentzian"));
107 declareAttribute("FWHMs", Attribute(std::vector<double>(1, 0.0)));
108 declareAttribute("FWHMX0", Attribute(std::vector<double>()));
109 declareAttribute("FWHMY0", Attribute(std::vector<double>()));
110 declareAttribute("FWHMVariation", Attribute(0.1));
111 declareAttribute("NPeaks", Attribute(0));
112 declareAttribute("FixAllPeaks", Attribute(false));
113 declareAttribute("PhysicalProperties", Attribute(std::vector<double>(1, 0.0)));
114}
115
117 try {
119 } catch (std::runtime_error const &ex) {
120 g_log.error(ex.what());
121 }
122}
123
125 if (!m_target) {
127 }
128
129 if (m_target) {
130 return m_target->getNumberDomains();
131 } else {
132 throw std::runtime_error("Failed to build target function.");
133 }
134}
135
136std::vector<IFunction_sptr> CrystalFieldMultiSpectrum::createEquivalentFunctions() const {
138 std::vector<IFunction_sptr> funs;
139 auto &composite = dynamic_cast<CompositeFunction &>(*m_target);
140 for (size_t i = 0; i < composite.nFunctions(); ++i) {
141 funs.emplace_back(composite.getFunction(i));
142 }
143 return funs;
144}
145
147void CrystalFieldMultiSpectrum::setAttribute(const std::string &name, const Attribute &attr) {
148 boost::smatch match;
149 if (name == "Temperatures") {
150 // Define (declare) the parameters for intensity scaling.
151 const auto nSpec = attr.asVector().size();
152 dynamic_cast<Peaks &>(*m_source).declareIntensityScaling(nSpec);
153 m_nOwnParams = m_source->nParams();
154 m_fwhmX.resize(nSpec);
155 m_fwhmY.resize(nSpec);
156 std::vector<double> new_fwhm = getAttribute("FWHMs").asVector();
157 const auto nWidths = new_fwhm.size();
158 if (nWidths != nSpec) {
159 new_fwhm.resize(nSpec);
160 if (nWidths > nSpec) {
161 for (size_t iSpec = nWidths; iSpec < nSpec; ++iSpec) {
162 new_fwhm[iSpec] = new_fwhm[0];
163 }
164 }
165 }
166 Attribute newVal = attr;
167 newVal.setVector(new_fwhm);
168 FunctionGenerator::setAttribute("FWHMs", newVal);
169 for (size_t iSpec = 0; iSpec < nSpec; ++iSpec) {
170 const auto suffix = std::to_string(iSpec);
171 // try to declare attribute, if already exists, set attribute.
172 try {
173 declareAttribute("FWHMX" + suffix, Attribute(m_fwhmX[iSpec]));
174 } catch (const std::invalid_argument &) {
175 setAttribute("FWHMX" + suffix, Attribute(m_fwhmX[iSpec]));
176 }
177
178 try {
179 declareAttribute("FWHMY" + suffix, Attribute(m_fwhmY[iSpec]));
180 } catch (const std::invalid_argument &) {
181 setAttribute("FWHMY" + suffix, Attribute(m_fwhmY[iSpec]));
182 }
183 }
184 } else if (name == "PhysicalProperties") {
185 const auto physpropId = attr.asVector();
186 const auto nSpec = physpropId.size();
187 auto &source = dynamic_cast<Peaks &>(*m_source);
188 for (size_t iSpec = 0; iSpec < nSpec; ++iSpec) {
189 const auto suffix = std::to_string(iSpec);
190 const auto pptype = static_cast<int>(physpropId[iSpec]);
191 switch (pptype) {
192 case MagneticMoment: // Hmag, Hdir, inverse, Unit, powder
193 declareAttribute("Hmag" + suffix, Attribute(1.0));
194 // fall through
195 case Susceptibility: // Hdir, inverse, Unit, powder
196 declareAttribute("inverse" + suffix, Attribute(false));
197 // fall through
198 case Magnetisation: // Hdir, Unit, powder
199 declareAttribute("Hdir" + suffix, Attribute(std::vector<double>{0., 0., 1.}));
200 declareAttribute("Unit" + suffix, Attribute("bohr"));
201 declareAttribute("powder" + suffix, Attribute(false));
202 break;
203 }
204 if (pptype == Susceptibility) {
205 source.declarePPLambda(iSpec);
206 m_nOwnParams = m_source->nParams();
207 }
208 }
209 } else if (boost::regex_match(name, match, FWHMX_ATTR_REGEX)) {
210 auto iSpec = std::stoul(match[1]);
211 if (m_fwhmX.size() > iSpec) {
212 m_fwhmX[iSpec].clear();
213 } else {
214 throw std::invalid_argument("Temperatures must be defined before resolution model");
215 }
216 } else if (boost::regex_match(name, match, FWHMY_ATTR_REGEX)) {
217 auto iSpec = std::stoul(match[1]);
218 if (m_fwhmY.size() > iSpec) {
219 m_fwhmY[iSpec].clear();
220 } else {
221 throw std::invalid_argument("Temperatures must be defined before resolution model");
222 }
223 }
225}
226
230 m_dirty = false;
231
232 auto fun = new MultiDomainFunction;
233 m_target.reset(fun);
234
239 int nre = 0;
240 auto &peakCalculator = dynamic_cast<Peaks &>(*m_source);
241 peakCalculator.calculateEigenSystem(en, wf, ham, hz, nre);
242 ham += hz;
243
244 // Get the temperatures from the attribute
245 m_temperatures = getAttribute("Temperatures").asVector();
246 if (m_temperatures.empty()) {
247 throw std::runtime_error("Vector of temperatures cannot be empty.");
248 }
249 // Get the FWHMs from the attribute and check for consistency.
250 m_FWHMs = getAttribute("FWHMs").asVector();
251 if (m_FWHMs.empty()) {
252 throw std::runtime_error("Vector of FWHMs cannot be empty.");
253 } else if (m_FWHMs.size() != m_temperatures.size()) {
254 if (m_FWHMs.size() == 1) {
255 auto fwhm = m_FWHMs.front();
256 m_FWHMs.resize(m_temperatures.size(), fwhm);
257 } else {
258 throw std::runtime_error("Vector of FWHMs must either have same size as "
259 "Temperatures (" +
260 std::to_string(m_temperatures.size()) + ") or have size 1.");
261 }
262 }
263 const auto nSpec = m_temperatures.size();
264 // Get a list of "spectra" which corresponds to physical properties
265 const auto physprops = getAttribute("PhysicalProperties").asVector();
266 if (physprops.empty()) {
267 m_physprops.resize(nSpec, 0); // Assume no physical properties - just INS
268 } else if (physprops.size() != nSpec) {
269 if (physprops.size() == 1) {
270 auto physprop = static_cast<int>(physprops.front());
271 m_physprops.resize(nSpec, physprop);
272 } else {
273 throw std::runtime_error("Vector of PhysicalProperties must have same "
274 "size as Temperatures or size 1.");
275 }
276 } else {
277 m_physprops.clear();
278 m_physprops.reserve(physprops.size());
279 std::transform(physprops.cbegin(), physprops.cend(), std::back_inserter(m_physprops),
280 [](auto elem) { return static_cast<int>(elem); });
281 }
282 // Create the single-spectrum functions.
283 m_nPeaks.resize(nSpec);
284 if (m_fwhmX.empty()) {
285 m_fwhmX.resize(nSpec);
286 m_fwhmY.resize(nSpec);
287 }
288 for (size_t i = 0; i < nSpec; ++i) {
289 if (m_physprops[i] > 0) {
290 // This "spectrum" is actually a physical properties dataset.
291 fun->addFunction(buildPhysprop(nre, en, wf, ham, m_temperatures[i], i));
292 } else {
293 if (m_fwhmX[i].empty()) {
294 auto suffix = std::to_string(i);
295 m_fwhmX[i] = IFunction::getAttribute("FWHMX" + suffix).asVector();
296 m_fwhmY[i] = IFunction::getAttribute("FWHMY" + suffix).asVector();
297 }
298 fun->addFunction(buildSpectrum(nre, en, wf, m_temperatures[i], m_FWHMs[i], i));
299 }
300 fun->setDomainIndex(i, i);
301 }
302}
303
306 double temperature, FunctionValues &values, size_t iSpec) const {
307 IntFortranVector degeneration;
308 DoubleFortranVector eEnergies;
309 DoubleFortranMatrix iEnergies;
310 const double de = getAttribute("ToleranceEnergy").asDouble();
311 const double di = getAttribute("ToleranceIntensity").asDouble();
312 DoubleFortranVector eExcitations;
313 DoubleFortranVector iExcitations;
314 calculateIntensities(nre, en, wf, temperature, de, degeneration, eEnergies, iEnergies);
315 calculateExcitations(eEnergies, iEnergies, de, di, eExcitations, iExcitations);
316 const size_t nSpec = m_nPeaks.size();
317 // Get intensity scaling parameter "IntensityScaling" + std::to_string(iSpec)
318 // using an index instead of a name for performance reasons
319 auto &source = dynamic_cast<Peaks &>(*m_source);
320 double intensityScaling;
321 if (source.m_IntensityScalingIdx.empty()) {
322 intensityScaling = getParameter(m_nOwnParams - nSpec + iSpec);
323 } else {
324 intensityScaling = getParameter(source.m_IntensityScalingIdx[iSpec]);
325 }
326 const auto nPeaks = eExcitations.size();
327 values.expand(2 * nPeaks);
328 for (size_t i = 0; i < nPeaks; ++i) {
329 values.setCalculated(i, eExcitations.get(i));
330 values.setCalculated(i + nPeaks, iExcitations.get(i) * intensityScaling);
331 }
332}
333
336 const ComplexFortranMatrix &wf, double temperature,
337 double fwhm, size_t iSpec) const {
338 FunctionValues values;
339 calcExcitations(nre, en, wf, temperature, values, iSpec);
341
342 const auto fwhmVariation = getAttribute("FWHMVariation").asDouble();
343 const auto peakShape = IFunction::getAttribute("PeakShape").asString();
344 auto bkgdShape = IFunction::getAttribute("Background").asUnquotedString();
345 const size_t nRequiredPeaks = IFunction::getAttribute("NPeaks").asInt();
346 const bool fixAllPeaks = getAttribute("FixAllPeaks").asBool();
347
348 if (!bkgdShape.empty() && bkgdShape.find("name=") != 0 && bkgdShape.front() != '(') {
349 bkgdShape = "name=" + bkgdShape;
350 }
351
352 auto spectrum = new CompositeFunction;
353 auto background = API::FunctionFactory::Instance().createInitialized(bkgdShape);
354 spectrum->addFunction(background);
355 if (fixAllPeaks) {
356 background->fixAll();
357 }
358
360 *spectrum, peakShape, values, m_fwhmX[iSpec], m_fwhmY[iSpec], fwhmVariation, fwhm, nRequiredPeaks, fixAllPeaks);
361 return IFunction_sptr(spectrum);
362}
363
365 const ComplexFortranMatrix &wf,
366 const ComplexFortranMatrix &ham, double temperature,
367 size_t iSpec) const {
368 switch (m_physprops[iSpec]) {
369 case HeatCapacity: {
371 auto &spectrum = dynamic_cast<CrystalFieldHeatCapacity &>(*retval);
372 spectrum.setEnergy(en);
373 return retval;
374 }
375 case Susceptibility: {
377 auto &spectrum = dynamic_cast<CrystalFieldSusceptibility &>(*retval);
378 spectrum.setEigensystem(en, wf, nre);
379 const auto suffix = std::to_string(iSpec);
380 spectrum.setAttribute("Hdir", getAttribute("Hdir" + suffix));
381 spectrum.setAttribute("inverse", getAttribute("inverse" + suffix));
382 spectrum.setAttribute("powder", getAttribute("powder" + suffix));
383 dynamic_cast<Peaks &>(*m_source).m_PPLambdaIdxChild[iSpec] = spectrum.parameterIndex("Lambda");
384 dynamic_cast<Peaks &>(*m_source).m_PPChi0IdxChild[iSpec] = spectrum.parameterIndex("Chi0");
385 return retval;
386 }
387 case Magnetisation: {
389 auto &spectrum = dynamic_cast<CrystalFieldMagnetisation &>(*retval);
390 spectrum.setHamiltonian(ham, nre);
391 spectrum.setAttributeValue("Temperature", temperature);
392 const auto suffix = std::to_string(iSpec);
393 spectrum.setAttribute("Unit", getAttribute("Unit" + suffix));
394 spectrum.setAttribute("Hdir", getAttribute("Hdir" + suffix));
395 spectrum.setAttribute("powder", getAttribute("powder" + suffix));
396 return retval;
397 }
398 case MagneticMoment: {
400 auto &spectrum = dynamic_cast<CrystalFieldMoment &>(*retval);
401 spectrum.setHamiltonian(ham, nre);
402 const auto suffix = std::to_string(iSpec);
403 spectrum.setAttribute("Unit", getAttribute("Unit" + suffix));
404 spectrum.setAttribute("Hdir", getAttribute("Hdir" + suffix));
405 spectrum.setAttribute("Hmag", getAttribute("Hmag" + suffix));
406 spectrum.setAttribute("inverse", getAttribute("inverse" + suffix));
407 spectrum.setAttribute("powder", getAttribute("powder" + suffix));
408 return retval;
409 }
410 }
411 throw std::runtime_error("Physical property type not understood");
412}
413
416 if (!m_target) {
418 return;
419 }
420 m_dirty = false;
421
426 int nre = 0;
427 auto &peakCalculator = dynamic_cast<Peaks &>(*m_source);
428 peakCalculator.calculateEigenSystem(en, wf, ham, hz, nre);
429 ham += hz;
430
431 auto &fun = dynamic_cast<MultiDomainFunction &>(*m_target);
432 try {
433 for (size_t i = 0; i < m_temperatures.size(); ++i) {
434 updateSpectrum(*fun.getFunction(i), nre, en, wf, ham, m_temperatures[i], m_FWHMs[i], i);
435 }
436 fun.checkFunction();
437 } catch (std::out_of_range &) {
439 return;
440 }
441}
442
445 const ComplexFortranMatrix &wf, const ComplexFortranMatrix &ham,
446 double temperature, double fwhm, size_t iSpec) const {
447 switch (m_physprops[iSpec]) {
448 case HeatCapacity: {
449 auto &heatcap = dynamic_cast<CrystalFieldHeatCapacity &>(spectrum);
450 heatcap.setEnergy(en);
451 break;
452 }
453 case Susceptibility: {
454 auto &suscept = dynamic_cast<CrystalFieldSusceptibility &>(spectrum);
455 suscept.setEigensystem(en, wf, nre);
456 auto &source = dynamic_cast<Peaks &>(*m_source);
457 suscept.setParameter(source.m_PPLambdaIdxChild[iSpec], getParameter(source.m_PPLambdaIdxSelf[iSpec]));
458 suscept.setParameter(source.m_PPChi0IdxChild[iSpec], getParameter(source.m_PPChi0IdxSelf[iSpec]));
459 break;
460 }
461 case Magnetisation: {
462 auto &magnetisation = dynamic_cast<CrystalFieldMagnetisation &>(spectrum);
463 magnetisation.setHamiltonian(ham, nre);
464 break;
465 }
466 case MagneticMoment: {
467 auto &moment = dynamic_cast<CrystalFieldMoment &>(spectrum);
468 moment.setHamiltonian(ham, nre);
469 break;
470 }
471 default:
472 const auto fwhmVariation = getAttribute("FWHMVariation").asDouble();
473 const auto peakShape = IFunction::getAttribute("PeakShape").asString();
474 const bool fixAllPeaks = getAttribute("FixAllPeaks").asBool();
475 FunctionValues values;
476 calcExcitations(nre, en, wf, temperature, values, iSpec);
477 auto &composite = dynamic_cast<API::CompositeFunction &>(spectrum);
478 m_nPeaks[iSpec] = CrystalFieldUtils::updateSpectrumFunction(composite, peakShape, values, 1, m_fwhmX[iSpec],
479 m_fwhmY[iSpec], fwhmVariation, fwhm, fixAllPeaks);
480 }
481}
482
483} // namespace Mantid::CurveFitting::Functions
std::vector< size_t > m_IntensityScalingIdx
std::vector< size_t > m_PPLambdaIdxChild
std::vector< size_t > m_PPLambdaIdxSelf
std::vector< size_t > m_PPChi0IdxSelf
std::vector< size_t > m_PPChi0IdxChild
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
A composite function is a function containing other functions.
FunctionGenerator is a partial implementation of IFunction that defines a function consisting of two ...
IFunction_sptr m_source
Function that calculates parameters of the target function.
double getParameter(size_t i) const override
Get i-th parameter.
void setAttribute(const std::string &name, const Attribute &) override
Set a value to attribute attName.
IFunction_sptr m_target
Function that actually calculates the output.
bool m_dirty
Flag indicating that updateTargetFunction() is required.
void checkTargetFunction() const
Update target function if necessary.
Attribute getAttribute(const std::string &name) const override
Return a value of attribute attName.
size_t m_nOwnParams
Cached number of parameters in m_source.
A class to store values calculated by a function.
void expand(size_t n)
Expand values to a new size, preserve stored values.
void setCalculated(double value)
set all calculated values to same number
Attribute is a non-fitting parameter.
Definition: IFunction.h:282
std::string asUnquotedString() const
Returns a string value that is guarenteed to be unquoted.
Definition: IFunction.cpp:702
std::vector< double > asVector() const
Returns vector<double> if attribute is vector<double>, throws exception otherwise.
Definition: IFunction.cpp:765
int asInt() const
Returns int value if attribute is a int, throws exception otherwise.
Definition: IFunction.cpp:726
std::string asString() const
Returns string value if attribute is a string, throws exception otherwise.
Definition: IFunction.cpp:660
void setVector(const std::vector< double > &)
Sets new value if attribute is a vector.
Definition: IFunction.cpp:844
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
Definition: IFunction.cpp:739
bool asBool() const
Returns bool value if attribute is a bool, throws exception otherwise.
Definition: IFunction.cpp:752
This is an interface to a fitting function - a semi-abstarct class.
Definition: IFunction.h:163
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
Definition: IFunction.cpp:1394
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
Definition: IFunction.cpp:1418
A composite function defined on a CompositeDomain.
double get(const size_t i) const
Get an element.
size_t size() const
Size of the vector.
void setHamiltonian(const ComplexFortranMatrix &ham, const int nre)
void setHamiltonian(const ComplexFortranMatrix &ham, const int nre)
API::IFunction_sptr buildPhysprop(int nre, const DoubleFortranVector &en, const ComplexFortranMatrix &wf, const ComplexFortranMatrix &ham, double temperature, size_t iSpec) const
std::vector< std::vector< double > > m_fwhmX
Caches of the width functions.
void setAttribute(const std::string &name, const Attribute &) override
Perform custom actions on setting certain attributes.
void updateSpectrum(API::IFunction &spectrum, int nre, const DoubleFortranVector &en, const ComplexFortranMatrix &wf, const ComplexFortranMatrix &ham, double temperature, double fwhm, size_t i) const
Update a function for a single spectrum.
@ Magnetisation
Specify dataset is magnetisation vs field M(H)
@ HeatCapacity
Specify dataset is magnetic heat capacity Cv(T)
@ Susceptibility
Specify dataset is magnetic susceptibility chi(T)
@ MagneticMoment
Specify dataset is magnetisation vs temp M(T)
std::vector< size_t > m_nPeaks
Cache number of fitted peaks.
std::vector< double > m_temperatures
Cache the temperatures.
API::IFunction_sptr buildSpectrum(int nre, const DoubleFortranVector &en, const ComplexFortranMatrix &wf, double temperature, double fwhm, size_t i) const
Build a function for a single spectrum.
std::vector< double > m_FWHMs
Cache the default peak FWHMs.
std::vector< API::IFunction_sptr > createEquivalentFunctions() const override
Split this function (if needed) into a list of independent functions.
size_t getNumberDomains() const override
Get number of domains required by this function.
std::string name() const override
Returns the function's name.
void init() override
overwrite IFunction base class method, which declare function parameters
void buildTargetFunction() const override
Uses source to calculate peak centres and intensities then populates m_spectrum with peaks of type gi...
std::vector< int > m_physprops
Cache the list of "spectra" corresponding to physical properties.
void calcExcitations(int nre, const DoubleFortranVector &en, const ComplexFortranMatrix &wf, double temperature, API::FunctionValues &values, size_t iSpec) const
Calculate excitations at given temperature.
void updateTargetFunction() const override
Update m_spectrum function.
void setEigensystem(const DoubleFortranVector &en, const ComplexFortranMatrix &wf, const int nre)
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition: IFunction.h:732
size_t updateSpectrumFunction(API::CompositeFunction &spectrum, const std::string &peakShape, const API::FunctionValues &centresAndIntensities, size_t iFirst, const std::vector< double > &xVec, const std::vector< double > &yVec, double fwhmVariation, double defaultFWHM, bool fixAllPeaks)
Update the peaks parameters after recalculationof the crystal field.
size_t calculateNPeaks(const API::FunctionValues &centresAndIntensities)
Calculate the number of visible peaks.
size_t buildSpectrumFunction(API::CompositeFunction &spectrum, const std::string &peakShape, const API::FunctionValues &centresAndIntensities, const std::vector< double > &xVec, const std::vector< double > &yVec, double fwhmVariation, double defaultFWHM, size_t nRequiredPeaks, bool fixAllPeaks)
Utility functions to help set up peak functions in a Crystal Field spectrum.
void MANTID_CURVEFITTING_DLL calculateExcitations(const DoubleFortranVector &e_energies, const DoubleFortranMatrix &i_energies, double de, double di, DoubleFortranVector &e_excitations, DoubleFortranVector &i_excitations)
Calculate the excitations (transition energies) and their intensities.
void MANTID_CURVEFITTING_DLL calculateIntensities(int nre, const DoubleFortranVector &energies, const ComplexFortranMatrix &wavefunctions, double temperature, double de, IntFortranVector &degeneration, DoubleFortranVector &e_energies, DoubleFortranMatrix &i_energies)
Calculate the intensities of transitions.
std::string to_string(const wide_integer< Bits, Signed > &n)