-
Notifications
You must be signed in to change notification settings - Fork 128
Correct error propagation on PolarizationEfficienciesWildes algorithm #39300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
cailafinn
merged 26 commits into
release-next
from
37768_improve_error_calc_in_PolarizationEfficienciesWildes
May 22, 2025
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
1aae7be
add autodiff capability
MialLewis 7abffb7
use autodiff for phi calc
MialLewis c17ac36
move matrix workspace evaluation to ErrorProp class
MialLewis bb5aed1
add new error propagation to fp and fa
MialLewis 5618276
add new error prop to calculateTPMO
MialLewis f020f2d
add error prop to remaining variables
MialLewis 8cc319e
refactor code to reduce repetition
MialLewis 4963cd4
suppress spurious cppcheck suppressions
MialLewis de8d735
update PolEff system tests
MialLewis 39c7f46
add warning messages regarding errors when calculating efficiencies u…
MialLewis 184456c
update PolarizationEfficienciesWildesTest to check errors
MialLewis 64604ad
add tests for workspace error prop
MialLewis ebc1b34
remove unnecessary vars
MialLewis 87a7f2c
remove unused var from test
MialLewis 4dbf94f
correct helper tests
MialLewis 978f31c
add ability to set workspace distribution in ErrorProp, also add test…
MialLewis b05f9de
test for distribution flag
MialLewis f01ae16
stop comp between size_t and int
MialLewis c143592
Remove unused type alias
MialLewis 3705545
add test data and correct flipper config in system tests
MialLewis 1482c70
add non mag test data
MialLewis 77f62d2
respond to pr comments 1
MialLewis ec82c91
respond to PR comments 2
MialLewis 2e641b4
slight fn refactor to reduce duplication
MialLewis ddc014d
update system test data again
MialLewis a62caec
remove unintended change
MialLewis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -7,10 +7,14 @@ | |||||
|
||||||
#pragma once | ||||||
|
||||||
#include "MantidAPI/AlgorithmManager.h" | ||||||
#include "MantidAPI/MatrixWorkspace.h" | ||||||
#include "MantidAPI/WorkspaceGroup.h" | ||||||
#include "MantidAlgorithms/DllConfig.h" | ||||||
#include "MantidKernel/MultiThreaded.h" | ||||||
#include <Eigen/Dense> | ||||||
#include <optional> | ||||||
#include <unsupported/Eigen/AutoDiff> | ||||||
|
||||||
namespace Mantid::Algorithms { | ||||||
namespace PolarizationCorrectionsHelpers { | ||||||
|
@@ -66,4 +70,109 @@ MANTID_ALGORITHMS_DLL const std::string &getORSONotationForSpinState(const std:: | |||||
MANTID_ALGORITHMS_DLL void addORSOLogForSpinState(const Mantid::API::MatrixWorkspace_sptr &ws, | ||||||
const std::string &spinState); | ||||||
} // namespace SpinStatesORSO | ||||||
|
||||||
namespace Arithmetic { | ||||||
|
||||||
template <size_t N> class ErrorTypeHelper { | ||||||
public: | ||||||
using DerType = Eigen::Matrix<double, N, 1>; | ||||||
using InputArray = DerType; | ||||||
using ADScalar = Eigen::AutoDiffScalar<DerType>; | ||||||
}; | ||||||
|
||||||
template <size_t N, typename Func> class ErrorPropagation { | ||||||
public: | ||||||
using Types = ErrorTypeHelper<N>; | ||||||
adriazalvarez marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
using DerType = Types::DerType; | ||||||
using ADScalar = Types::ADScalar; | ||||||
using InputArray = Types::InputArray; | ||||||
ErrorPropagation(Func func) : computeFunc(std::move(func)) {} | ||||||
|
||||||
struct AutoDevResult { | ||||||
double value; | ||||||
double error; | ||||||
Eigen::Array<double, N, 1> derivatives; | ||||||
}; | ||||||
|
||||||
AutoDevResult evaluate(const InputArray &values, const InputArray &errors) const { | ||||||
std::array<ADScalar, N> x; | ||||||
for (size_t i = 0; i < N; ++i) { | ||||||
x[i] = ADScalar(values[i], DerType::Unit(N, i)); | ||||||
} | ||||||
const ADScalar y = computeFunc(x); | ||||||
const auto &derivatives = y.derivatives(); | ||||||
return {y.value(), std::sqrt((derivatives.array().square() * errors.array().square()).sum()), derivatives}; | ||||||
} | ||||||
|
||||||
template <std::same_as<API::MatrixWorkspace_sptr>... Ts> | ||||||
API::MatrixWorkspace_sptr evaluateWorkspaces(const bool outputWorkspaceDistribution, Ts... args) const { | ||||||
return evaluateWorkspacesImpl(outputWorkspaceDistribution, std::forward<Ts>(args)...); | ||||||
} | ||||||
|
||||||
template <std::same_as<API::MatrixWorkspace_sptr>... Ts> | ||||||
API::MatrixWorkspace_sptr evaluateWorkspaces(Ts... args) const { | ||||||
return evaluateWorkspacesImpl(std::nullopt, std::forward<Ts>(args)...); | ||||||
} | ||||||
|
||||||
private: | ||||||
Func computeFunc; | ||||||
|
||||||
template <std::same_as<API::MatrixWorkspace_sptr>... Ts> | ||||||
API::MatrixWorkspace_sptr evaluateWorkspacesImpl(std::optional<bool> outputWorkspaceDistribution, Ts... args) const { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think we can get away with just using a bool here?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I used a
|
||||||
const auto firstWs = std::get<0>(std::forward_as_tuple(args...)); | ||||||
API::MatrixWorkspace_sptr outWs = firstWs->clone(); | ||||||
|
||||||
if (outWs->id() == "EventWorkspace") { | ||||||
outWs = convertToWorkspace2D(outWs); | ||||||
} | ||||||
|
||||||
const size_t numSpec = outWs->getNumberHistograms(); | ||||||
const size_t specSize = outWs->blocksize(); | ||||||
|
||||||
// cppcheck-suppress unreadVariable | ||||||
const bool isThreadSafe = Kernel::threadSafe((*args)..., *outWs); | ||||||
// cppcheck-suppress unreadVariable | ||||||
const bool specOverBins = numSpec > specSize; | ||||||
|
||||||
PARALLEL_FOR_IF(isThreadSafe && specOverBins) | ||||||
for (int64_t i = 0; i < static_cast<int64_t>(numSpec); i++) { | ||||||
auto &yOut = outWs->mutableY(i); | ||||||
auto &eOut = outWs->mutableE(i); | ||||||
|
||||||
PARALLEL_FOR_IF(isThreadSafe && !specOverBins) | ||||||
for (int64_t j = 0; j < static_cast<int64_t>(specSize); ++j) { | ||||||
const auto result = evaluate(InputArray{args->y(i)[j]...}, InputArray(args->e(i)[j]...)); | ||||||
yOut[j] = result.value; | ||||||
eOut[j] = result.error; | ||||||
} | ||||||
} | ||||||
|
||||||
if (outputWorkspaceDistribution.has_value()) { | ||||||
outWs->setDistribution(outputWorkspaceDistribution.value()); | ||||||
} | ||||||
return outWs; | ||||||
} | ||||||
|
||||||
API::MatrixWorkspace_sptr runWorkspaceConversionAlg(const API::MatrixWorkspace_sptr &workspace, | ||||||
const std::string &algName) const { | ||||||
auto conversionAlg = API::AlgorithmManager::Instance().create(algName); | ||||||
conversionAlg->initialize(); | ||||||
conversionAlg->setChild(true); | ||||||
conversionAlg->setProperty("InputWorkspace", workspace); | ||||||
conversionAlg->setProperty("OutputWorkspace", workspace->getName()); | ||||||
conversionAlg->execute(); | ||||||
return conversionAlg->getProperty("OutputWorkspace"); | ||||||
} | ||||||
|
||||||
API::MatrixWorkspace_sptr convertToWorkspace2D(const API::MatrixWorkspace_sptr &workspace) const { | ||||||
runWorkspaceConversionAlg(workspace, "ConvertToHistogram"); | ||||||
return runWorkspaceConversionAlg(workspace, "ConvertToMatrixWorkspace"); | ||||||
} | ||||||
}; | ||||||
|
||||||
template <size_t N, typename Func> auto makeErrorPropagation(Func &&func) { | ||||||
return ErrorPropagation<N, std::decay_t<Func>>(std::forward<Func>(func)); | ||||||
} | ||||||
|
||||||
} // namespace Arithmetic | ||||||
} // namespace Mantid::Algorithms |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.