Mantid
Loading...
Searching...
No Matches
CrystalFieldSpectrum.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 +
10
17#include "MantidKernel/Logger.h"
19
20#include <algorithm>
21
22namespace {
23Mantid::Kernel::Logger g_log("CrystalFieldSpectrum");
24}
25
27
28using namespace CurveFitting;
29using namespace Kernel;
30using namespace API;
31
32DECLARE_FUNCTION(CrystalFieldSpectrum)
33
34
36 declareAttribute("PeakShape", Attribute("Lorentzian"));
37 declareAttribute("FWHM", Attribute(0.0));
38 std::vector<double> vec;
39 declareAttribute("FWHMX", Attribute(vec));
40 declareAttribute("FWHMY", Attribute(vec));
41 declareAttribute("FWHMVariation", Attribute(0.1));
42 declareAttribute("NPeaks", Attribute(0));
43 declareAttribute("FixAllPeaks", Attribute(false));
44}
45
47 try {
49 } catch (std::runtime_error const &ex) {
50 g_log.error(ex.what());
51 }
52}
53
57 m_dirty = false;
58 auto spectrum = new CompositeFunction;
59 m_target.reset(spectrum);
60 m_target->setAttribute("NumDeriv", this->getAttribute("NumDeriv"));
61
63 FunctionValues values;
64 m_source->function(domain, values);
65 m_source->applyTies();
66
67 if (values.size() == 0) {
68 return;
69 }
70
71 if (values.size() % 2 != 0) {
72 throw std::runtime_error("CrystalFieldPeaks returned odd number of values.");
73 }
74
75 auto xVec = getAttribute("FWHMX").asVector();
76 auto yVec = getAttribute("FWHMY").asVector();
77 auto fwhmVariation = getAttribute("FWHMVariation").asDouble();
78
79 auto peakShape = getAttribute("PeakShape").asString();
80 auto defaultFWHM = getAttribute("FWHM").asDouble();
81 size_t nRequiredPeaks = getAttribute("NPeaks").asInt();
82 bool fixAllPeaks = getAttribute("FixAllPeaks").asBool();
83 m_nPeaks = CrystalFieldUtils::buildSpectrumFunction(*spectrum, peakShape, values, xVec, yVec, fwhmVariation,
84 defaultFWHM, nRequiredPeaks, fixAllPeaks);
85 storeReadOnlyAttribute("NPeaks", Attribute(static_cast<int>(m_nPeaks)));
86}
87
90 if (!m_target) {
92 return;
93 }
94 m_dirty = false;
95 auto peakShape = getAttribute("PeakShape").asString();
96 auto xVec = getAttribute("FWHMX").asVector();
97 auto yVec = getAttribute("FWHMY").asVector();
98 auto fwhmVariation = getAttribute("FWHMVariation").asDouble();
99 auto defaultFWHM = getAttribute("FWHM").asDouble();
100 bool fixAllPeaks = getAttribute("FixAllPeaks").asBool();
102 FunctionValues values;
103 m_source->function(domain, values);
104 m_target->setAttribute("NumDeriv", this->getAttribute("NumDeriv"));
105 auto &spectrum = dynamic_cast<CompositeFunction &>(*m_target);
107 CrystalFieldUtils::updateSpectrumFunction(spectrum, peakShape, values, 0, xVec, yVec, fwhmVariation, defaultFWHM,
108 fixAllPeaks);
109 storeReadOnlyAttribute("NPeaks", Attribute(static_cast<int>(m_nPeaks)));
110}
111
113std::string CrystalFieldSpectrum::writeToString(const std::string &parentLocalAttributesStr) const {
114 std::ostringstream ostr;
115 ostr << "name=" << this->name();
116 // Print the attributes
117 std::vector<std::string> attr = this->getAttributeNames();
118 for (const auto &attName : attr) {
119 std::string attValue = this->getAttribute(attName).value();
120 if (!attValue.empty() && attValue != "\"\"" && attValue != "()") {
121 ostr << ',' << attName << '=' << attValue;
122 }
123 }
124 ostr << parentLocalAttributesStr;
125 std::vector<std::string> ties;
126 // Print own parameters
127 for (size_t i = 0; i < m_nOwnParams; i++) {
128 std::ostringstream paramOut;
129 paramOut << parameterName(i) << '=' << getParameter(i);
130 if (isActive(i)) {
131 ostr << ',' << paramOut.str();
132 } else if (isFixed(i)) {
133 ties.emplace_back(paramOut.str());
134 }
135 }
136
137 const auto &spectrum = dynamic_cast<const CompositeFunction &>(*m_target);
138 for (size_t ip = 0; ip < spectrum.nFunctions(); ++ip) {
139 const auto &peak = dynamic_cast<IPeakFunction &>(*spectrum.getFunction(ip));
140 // Print parameters of the important peaks only
141 if (ip < m_nPeaks) {
142 // Print peak's atributes
143 const auto attrNames = peak.getAttributeNames();
144 for (const auto &attName : attrNames) {
145 const std::string attValue = peak.getAttribute(attName).value();
146 if (!attValue.empty() && attValue != "\"\"") {
147 ostr << ",f" << ip << "." << attName << '=' << attValue;
148 }
149 }
150 }
151 // Print important peak's parameters
152 for (size_t i = 0; i < peak.nParams(); i++) {
153 const ParameterTie *tie = peak.getTie(i);
154 std::ostringstream paramString;
155 paramString << "f" << ip << "." << peak.parameterName(i) << '=' << peak.getParameter(i);
156 if (ip < m_nPeaks && (!tie || !tie->isDefault())) {
157 ostr << ',' << paramString.str();
158 }
159 // Add fixed ties for all peaks
160 if (peak.isFixed(i) && !peak.isFixedByDefault(i)) {
161 ties.emplace_back(paramString.str());
162 }
163 }
164 // collect non-default ties for peaks
165 const auto peakTies = peak.writeTies();
166 if (!peakTies.empty())
167 ties.emplace_back(peakTies);
168 } // for peaks
169
170 // collect non-default constraints
171 std::string constraints = writeConstraints();
172 // print constraints
173 if (!constraints.empty()) {
174 ostr << ",constraints=(" << constraints << ")";
175 }
176
177 // collect the non-default ties
178 auto tiesString = writeTies();
179 if (!tiesString.empty()) {
180 ties.emplace_back(tiesString);
181 }
182 // print the ties
183 if (!ties.empty()) {
184 ostr << ",ties=(" << Kernel::Strings::join(ties.begin(), ties.end(), ",") << ")";
185 }
186
187 return ostr.str();
188}
189
190} // namespace Mantid::CurveFitting::Functions
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Mantid::API::IFunction::Attribute Attribute
Definition: IsoRotDiff.cpp:25
A composite function is a function containing other functions.
Represent a domain of a very general type.
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.
std::vector< std::string > getAttributeNames() const override
Returns a list of attribute names.
std::string parameterName(size_t i) const override
Returns the name of parameter i.
IFunction_sptr m_target
Function that actually calculates the output.
bool m_dirty
Flag indicating that updateTargetFunction() is required.
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.
size_t size() const
Return the number of values.
Attribute is a non-fitting parameter.
Definition: IFunction.h:282
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
std::string value() const
Returns the attribute value as a string.
Definition: IFunction.cpp:652
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
bool isActive(size_t i) const
Check if an active parameter i is actually active.
Definition: IFunction.cpp:160
std::string writeTies() const
Write a parameter tie to a string.
Definition: IFunction.cpp:261
void storeReadOnlyAttribute(const std::string &name, const API::IFunction::Attribute &value) const
A read-only ("mutable") attribute can be stored in a const method.
Definition: IFunction.cpp:1483
virtual void tie(const std::string &parName, const std::string &expr, bool isDefault=false)
Tie a parameter to other parameters (or a constant)
Definition: IFunction.cpp:214
virtual std::vector< std::string > getAttributeNames() const
Returns a list of attribute names.
Definition: IFunction.cpp:1368
std::string writeConstraints() const
Write a parameter constraint to a string.
Definition: IFunction.cpp:441
bool isFixed(size_t i) const
Check if a parameter i is fixed.
Definition: IFunction.cpp:167
An interface to a peak function, which extend the interface of IFunctionWithLocation by adding method...
Definition: IPeakFunction.h:51
Ties fitting parameters.
Definition: ParameterTie.h:35
CrystalFieldPeaks is a function that calculates crystal field peak positions and intensities.
void init() override
overwrite IFunction base class method, which declare function parameters
std::string writeToString(const std::string &parentLocalAttributesStr="") const override
Custom string conversion method.
void updateTargetFunction() const override
Update m_spectrum function.
void buildTargetFunction() const override
Uses m_crystalField to calculate peak centres and intensities then populates m_spectrum with peaks of...
std::string name() const override
Returns the function's name.
size_t m_nPeaks
Number of fitted peaks in the spectrum.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
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.
DLLExport std::string join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string &separator, typename std::enable_if<!(std::is_same< typename std::iterator_traits< ITERATOR_TYPE >::iterator_category, std::random_access_iterator_tag >::value)>::type *=nullptr)
Join a set or vector of (something that turns into a string) together into one string,...
Definition: Strings.h:84