Mantid
Loading...
Searching...
No Matches
AttenuationProfile.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2020 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 +
11#include <filesystem>
12#include <fstream>
13
14namespace Mantid::Kernel {
15
26AttenuationProfile::AttenuationProfile(const std::string &inputFileName, const std::string &searchPath,
27 Material const *extrapolationMaterial, double extrapolationMaxX) {
28 std::filesystem::path suppliedFileName(inputFileName);
29 std::filesystem::path inputFilePath;
30 std::string fileExt = suppliedFileName.extension().string();
31 // Remove leading dot from extension if present
32 if (!fileExt.empty() && fileExt[0] == '.') {
33 fileExt = fileExt.substr(1);
34 }
35 std::transform(fileExt.begin(), fileExt.end(), fileExt.begin(), toupper);
36
37 if (fileExt == "DAT") {
38 if (suppliedFileName.is_relative()) {
39 bool useSearchDirectories = true;
40
41 if (!searchPath.empty()) {
42 inputFilePath = std::filesystem::path(searchPath).parent_path() / inputFileName;
43 if (std::filesystem::exists(inputFilePath)) {
44 useSearchDirectories = false;
45 }
46 }
47 if (useSearchDirectories) {
48 // ... and if that doesn't work look in the search directories
49 std::string foundFile = Mantid::Kernel::ConfigService::Instance().getFullPath(inputFileName, false, 0);
50 if (!foundFile.empty()) {
51 inputFilePath = std::filesystem::path(foundFile);
52 } else {
53 inputFilePath = std::move(suppliedFileName);
54 }
55 }
56 } else {
57 inputFilePath = suppliedFileName;
58 }
59 std::ifstream input(inputFilePath, std::ios_base::in);
60 if (input) {
61 std::string line;
62 double minX = std::numeric_limits<double>::max();
63 double maxX = std::numeric_limits<double>::lowest();
64 while (std::getline(input, line)) {
65 double x, alpha, error;
66 if (std::stringstream(line) >> x >> alpha >> error) {
67 minX = std::min(x, minX);
68 maxX = std::max(x, maxX);
69 m_Interpolator.addPoint(x, 1000 * alpha);
70 }
71 }
72 input.close();
73 // Assist the extrapolation outside the supplied x range to better
74 // handle noisy data. Add two surrounding points using the attenuation
75 // calculated from tabulated absorption\scattering cross sections
76 if (m_Interpolator.containData() && extrapolationMaterial) {
77 if ((minX > 0) && (minX < std::numeric_limits<double>::max())) {
78 m_Interpolator.addPoint(0, extrapolationMaterial->attenuationCoefficient(0));
79 }
80 if ((maxX < extrapolationMaxX) && (maxX > std::numeric_limits<double>::lowest())) {
81 m_Interpolator.addPoint(extrapolationMaxX, extrapolationMaterial->attenuationCoefficient(extrapolationMaxX));
82 }
83 }
84 } else {
85 throw Exception::FileError("Error reading attenuation profile file", inputFileName);
86 }
87 } else {
88 throw Exception::FileError("Attenuation profile file must be a .DAT file", inputFileName);
89 }
90}
91
105void AttenuationProfile::setAttenuationCoefficient(const double x, const double atten) {
106 m_Interpolator.addPoint(x, atten);
107}
108} // namespace Mantid::Kernel
double error
double getAttenuationCoefficient(const double x) const
Returns the attenuation coefficient for the supplied x value.
void setAttenuationCoefficient(const double x, const double atten)
Set the attenuation coefficient at x value.
Records the filename and the description of failure.
Definition Exception.h:98
bool containData() const
return false if no data has been added
double value(const double &at) const
get interpolated value at location at
void addPoint(const double &xx, const double &yy)
add data point
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition Material.h:50
double attenuationCoefficient(const double lambda) const
Definition Material.cpp:267