Skip to content
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

Prepare for release candidate v6.11.0.3rc1 #38592

Merged
merged 129 commits into from
Jan 13, 2025
Merged
Changes from 8 commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
902fcd1
Replace boost ends_with with std::string equivalent.
thomashampson Oct 29, 2024
18ada7e
Merge pull request #38482 from peterfpeterson/cppcheck_suppressions_o…
peterfpeterson Dec 6, 2024
9e4c44f
Ignore in-source build of conda
peterfpeterson Dec 5, 2024
f64d89f
Move muon loader confidence check out of exec method
robertapplin Oct 30, 2024
dceeace
Add system tests for muon loading
robertapplin Oct 23, 2024
375996c
Merge pull request #38479 from peterfpeterson/muon-loader-confidence
peterfpeterson Dec 6, 2024
83ebb0b
Merge pull request #38485 from peterfpeterson/ignore_conda_build
peterfpeterson Dec 6, 2024
7d1de1e
Fix cppcheck warnings and remove unused headers
peterfpeterson Dec 9, 2024
7249bd2
Merge pull request #38496 from peterfpeterson/cppcheck_fixes
peterfpeterson Dec 10, 2024
b4e0a2a
#38451 Sibling: Create MatrixWorkspace::plot_type property (#38495)
ktactac-ornl Dec 10, 2024
c631831
Move muon hdf4 loaders to muon library
robertapplin Dec 5, 2024
15eb461
Merge pull request #38508 from peterfpeterson/38214-move-muon-hdf4-lo…
peterfpeterson Dec 13, 2024
96ab99b
Log cppcheck command during configure step
peterfpeterson Dec 12, 2024
c937344
Add QTransform base class
rosswhitfield Dec 10, 2024
7bc5372
Add tests for QTransform
rosswhitfield Dec 12, 2024
8eac2ec
Add MagneticFormFactorCorrectionMD algorithm
rosswhitfield Dec 13, 2024
4a6b734
Add tests for MagneticFormFactorCorrectionMD
rosswhitfield Dec 13, 2024
bd055f1
Update docs for MagneticFormFactorCorrectionMD
rosswhitfield Dec 16, 2024
af018dd
Update CppCheck_Suppressions
rosswhitfield Dec 16, 2024
84968f1
Add release notes
rosswhitfield Dec 16, 2024
2cfa9cc
#38487 Sibling - Bugfix: isDistribution After Divide of Two RaggedWor…
ktactac-ornl Dec 16, 2024
5e9e0c5
Fixing face centered lattice
zjmorgan Dec 16, 2024
c95bf2a
Merge pull request #38516 from mantidproject/fix_reflection_condition…
peterfpeterson Dec 16, 2024
9dd36cf
Change atom labels to the ones that were supplied
peterfpeterson Dec 17, 2024
e346929
Switch to generated DllConfig.h
peterfpeterson Dec 17, 2024
beb0099
Merge pull request #38521 from rosswhitfield/MagneticFormFactorCorrec…
rosswhitfield Dec 18, 2024
4c0202f
Remove MantidKernel/System.h
peterfpeterson Dec 18, 2024
da985e5
Remove empty unit tests
peterfpeterson Dec 18, 2024
bd660f4
Merge pull request #38527 from peterfpeterson/cppcheck_command
peterfpeterson Dec 18, 2024
cc1d371
Merge pull request #38528 from peterfpeterson/ewm8669_isotropic_labels
peterfpeterson Dec 18, 2024
a3addd2
Merge pull request #38531 from peterfpeterson/38457_sinq_system_h
peterfpeterson Dec 19, 2024
5b8b829
Merge pull request #38533 from peterfpeterson/38457_remove_includes
peterfpeterson Dec 19, 2024
a0b77af
solve the interpolation issue
Dec 19, 2024
da86e0b
Merge pull request #38540 from peterfpeterson/interpo_issue_fix
peterfpeterson Dec 20, 2024
19d66fd
Remove unused MantidKernel/System.h import
peterfpeterson Dec 20, 2024
18cde14
Merge pull request #38547 from peterfpeterson/38457_system_h_in_cpp
peterfpeterson Dec 27, 2024
565cc39
Move from MantidKernel/System.h to DllConfig.h
peterfpeterson Dec 23, 2024
bb30eb0
Add support for histogram ragged workspaces with density=true
peterfpeterson Dec 31, 2024
e81b9fc
Advance to what is on main
peterfpeterson Jan 3, 2025
97bf4ac
Merge pull request #38553 from peterfpeterson/38457_more_places
peterfpeterson Jan 3, 2025
8a350da
Merge pull request #38554 from peterfpeterson/pre-commit-ci-update-co…
peterfpeterson Jan 3, 2025
2636807
Update developer dependencies
peterfpeterson Nov 4, 2024
d19ed26
Add conda-verify to quiet packaging warning
peterfpeterson Nov 26, 2024
98b4343
Replace nexus with its dependencies
peterfpeterson Nov 26, 2024
6acf1c1
First copying of files into NexusCpp subpackage
peterfpeterson Nov 27, 2024
94882a6
Add tests which compile but fail
peterfpeterson Nov 27, 2024
cd8b293
Remove files that implement xml backend
peterfpeterson Nov 27, 2024
1326ba3
Remove ifdef for xml
peterfpeterson Nov 27, 2024
1842b0c
Add test for unlimited arrays
peterfpeterson Nov 27, 2024
4d4e768
Fix cppcheck warnings
peterfpeterson Nov 27, 2024
441d26e
Remove NeXusStream class
peterfpeterson Dec 2, 2024
cc75a73
Fix compiler warnings and cppcheck
peterfpeterson Dec 2, 2024
1c62348
Give cpp tests standard extension
peterfpeterson Dec 2, 2024
ff3c053
Move contents of nxconfig into napiconfig
peterfpeterson Dec 2, 2024
b362ba8
Bare minimum to get the code to compile and link as c++
peterfpeterson Dec 2, 2024
27fb948
Lots of little changes to make it more c++ ish
peterfpeterson Dec 2, 2024
11b93a9
Make test errors clearer
peterfpeterson Dec 3, 2024
36f6e97
Change import from nexus to MantidNexusCpp
peterfpeterson Dec 3, 2024
9b06b64
Fix cppcheck issues
peterfpeterson Dec 4, 2024
9cada48
Undo cppcheck fix
peterfpeterson Dec 6, 2024
426c5f0
Fix cppcheck issues in nexuscpp
peterfpeterson Dec 4, 2024
4710063
Refactor printing into utility function
peterfpeterson Dec 9, 2024
c4dcc85
Create external data files on the fly
peterfpeterson Dec 9, 2024
2ef5395
Always return that creating the attribute was ok
peterfpeterson Dec 10, 2024
d6376c4
Fix cppcheck issues
peterfpeterson Dec 10, 2024
0baa2e0
Remove incorrect imports
peterfpeterson Dec 10, 2024
52aadb5
Fix compiler warnings
peterfpeterson Dec 11, 2024
cb5c7d5
Stop using deprecated functions
peterfpeterson Dec 11, 2024
ffbb9f3
Fix cppcheck issues
peterfpeterson Dec 12, 2024
1727918
Remove system nexus finder
peterfpeterson Dec 12, 2024
cbe862c
Change error reporting function to take const string
peterfpeterson Dec 12, 2024
64fbef3
Remove deprecated function
peterfpeterson Dec 12, 2024
381510e
Make final parameter const for clang
peterfpeterson Dec 12, 2024
a5fb713
Do not capture exception that is rethrown
peterfpeterson Dec 12, 2024
0e3306f
Import nxconfig to help windows build
peterfpeterson Dec 12, 2024
5c29a5a
Change order of modules
peterfpeterson Dec 12, 2024
13a968f
Skip clang compiler rather than intel
peterfpeterson Dec 12, 2024
45a40e3
Copy configuration from Kernel to fix windows
peterfpeterson Dec 12, 2024
5875e92
Remove wrong header file
peterfpeterson Dec 13, 2024
b5e11b4
Change signature to quiet msvs warnings
peterfpeterson Dec 13, 2024
6893cf7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 13, 2024
e834a20
Remove unused setnumberformat function
peterfpeterson Dec 13, 2024
70a95d6
Use strdup variant on windows
peterfpeterson Dec 13, 2024
8e8c858
Fix compiler warnings on windows
peterfpeterson Dec 16, 2024
d6f1d18
Change default create to hdf5
peterfpeterson Dec 16, 2024
85c5275
Skipping external file tests on windows
peterfpeterson Dec 17, 2024
dca4462
Try to make windows test errors clearer
peterfpeterson Dec 17, 2024
ebbc6c7
No longer configure packagesetup.py because nexus is gone
peterfpeterson Dec 18, 2024
6389e41
Turn off the c-hdf5 test on windows
peterfpeterson Dec 20, 2024
e59830b
Update cppcheck suppression
peterfpeterson Dec 29, 2024
2853d4c
Remove commented out code and change some magic numbers to constants
peterfpeterson Jan 3, 2025
d19bd19
Fix invalid data when MDHistoworkspace replaced and has original work…
rosswhitfield Jan 6, 2025
73c368c
Add release note
rosswhitfield Jan 6, 2025
be49167
update plotting
searscr Dec 27, 2024
bf5d0b4
update cppCheck
searscr Dec 27, 2024
b5b30ac
fix doxygen
searscr Dec 27, 2024
ed46544
Release Notes
searscr Dec 31, 2024
d450db7
Merge pull request #38555 from mantidproject/ewm7830_plotMarkerWS_ORN…
peterfpeterson Jan 6, 2025
1c096c4
Move string constants to the top of the test file
peterfpeterson Jan 6, 2025
d5cfffb
Pin scipy to less than v1.15.0
sf1919 Jan 6, 2025
f3a2228
Merge pull request #38563 from peterfpeterson/pin_scipy_Jan25_ornlnext
peterfpeterson Jan 6, 2025
5dc6ce1
Do not double read when actual matches requested
peterfpeterson Dec 26, 2024
3c6a54a
Add ability to read portions of the data
peterfpeterson Dec 27, 2024
325fb4a
Combine functions by using default values
peterfpeterson Jan 6, 2025
8e31f79
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Jan 6, 2025
983d8c8
Set cmake policy CMP0177 to new
jclarkeSTFC Dec 20, 2024
d5a7794
Drop scipy pin, relax tolerance for AbinsPowderCalculatorTest
ajjackson Jan 6, 2025
57a0d30
Merge pull request #38568 from peterfpeterson/pre-commit-ci-update-co…
peterfpeterson Jan 7, 2025
8bb269a
Merge pull request #38569 from peterfpeterson/ewm8446_nexus_into_mantid
peterfpeterson Jan 7, 2025
fcd49ba
Merge pull request #38570 from peterfpeterson/38437_fix_cmake_warning…
peterfpeterson Jan 7, 2025
3a41a4c
Merge pull request #38571 from peterfpeterson/ewm8789_convert_units_r…
peterfpeterson Jan 7, 2025
1701172
Merge pull request #38572 from peterfpeterson/abins-scipy-constants-o…
peterfpeterson Jan 7, 2025
94614aa
Remove includes of MantidKernel/System.h
peterfpeterson Jan 7, 2025
ed43820
Update googletest to version 1.15.2
jclarkeSTFC Dec 20, 2024
00d2658
Merge pull request #38575 from peterfpeterson/update_googletest_1_15_…
peterfpeterson Jan 8, 2025
f7982b0
Clarify that gtest is pinned to v1.15.2
peterfpeterson Jan 8, 2025
ff47bef
Merge pull request #38576 from peterfpeterson/38332_h5util_improvements
peterfpeterson Jan 8, 2025
bc7e058
Merge pull request #38579 from peterfpeterson/38457_generate_export_h…
peterfpeterson Jan 9, 2025
e0e6386
Code cleanup
peterfpeterson Dec 20, 2024
7304aed
Improve algorithm user documentation
peterfpeterson Dec 20, 2024
8752da4
Cleanup release notes directories
peterfpeterson Dec 23, 2024
cafbc9c
More clarification on how the algorithm works
peterfpeterson Jan 6, 2025
8cea670
Remove unnecessary word
peterfpeterson Jan 6, 2025
0610193
Flip for/if for a little speed boost
peterfpeterson Jan 9, 2025
0ac1c78
Merge pull request #38585 from peterfpeterson/gtest_pin
peterfpeterson Jan 9, 2025
0453e5e
Merge pull request #38586 from rosswhitfield/fix_sliceviewer_data_exc…
rosswhitfield Jan 10, 2025
9c6d1b1
Remove clang-format suppressions
peterfpeterson Jan 9, 2025
2a4279c
Merge pull request #38589 from peterfpeterson/cc_gdo_docs
peterfpeterson Jan 10, 2025
3bc0c16
Merge pull request #38590 from peterfpeterson/38332_nexus_sorted_incl…
peterfpeterson Jan 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Framework/MDAlgorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -85,6 +85,7 @@ set(SRC_FILES
src/MDTransfQ3D.cpp
src/MDWSDescription.cpp
src/MDWSTransform.cpp
src/MagneticFormFactorCorrectionMD.cpp
src/MaskMD.cpp
src/MergeMD.cpp
src/MergeMDFiles.cpp
@@ -96,6 +97,7 @@ set(SRC_FILES
src/PolarizationAngleCorrectionMD.cpp
src/PowerMD.cpp
src/PreprocessDetectorsToMD.cpp
src/QTransform.cpp
src/QueryMDWorkspace.cpp
src/RecalculateTrajectoriesExtents.cpp
src/ReplicateMD.cpp
@@ -205,6 +207,7 @@ set(INC_FILES
inc/MantidMDAlgorithms/MDTransfQ3D.h
inc/MantidMDAlgorithms/MDWSDescription.h
inc/MantidMDAlgorithms/MDWSTransform.h
inc/MantidMDAlgorithms/MagneticFormFactorCorrectionMD.h
inc/MantidMDAlgorithms/MaskMD.h
inc/MantidMDAlgorithms/MergeMD.h
inc/MantidMDAlgorithms/MergeMDFiles.h
@@ -216,6 +219,7 @@ set(INC_FILES
inc/MantidMDAlgorithms/PolarizationAngleCorrectionMD.h
inc/MantidMDAlgorithms/PowerMD.h
inc/MantidMDAlgorithms/PreprocessDetectorsToMD.h
inc/MantidMDAlgorithms/QTransform.h
inc/MantidMDAlgorithms/QueryMDWorkspace.h
inc/MantidMDAlgorithms/RecalculateTrajectoriesExtents.h
inc/MantidMDAlgorithms/ReplicateMD.h
@@ -318,6 +322,7 @@ set(TEST_FILES
MDTransfQ3DTest.h
MDWSDescriptionTest.h
MDWSTransfTest.h
MagneticFormFactorCorrectionMDTest.h
MaskMDTest.h
MergeMDFilesTest.h
MergeMDTest.h
@@ -329,6 +334,7 @@ set(TEST_FILES
PolarizationAngleCorrectionMDTest.h
PowerMDTest.h
PreprocessDetectorsToMDTest.h
QTransformTest.h
QueryMDWorkspaceTest.h
RecalculateTrajectoriesExtentsTest.h
ReplicateMDTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2024 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once

#include "MantidKernel/MagneticIon.h"
#include "MantidMDAlgorithms/QTransform.h"

namespace Mantid {
namespace MDAlgorithms {

/** MagneticFormFactorCorrectionMD : Correct event signal and error values for magnetic form factor.
*/
class MANTID_MDALGORITHMS_DLL MagneticFormFactorCorrectionMD : public QTransform {
public:
const std::string name() const override;
int version() const override;
const std::string category() const override;
const std::string summary() const override;
double correction(const double) const override;
const std::vector<std::string> seeAlso() const override;

private:
void init() override;
void exec() override;
Mantid::PhysicalConstants::MagneticIon ion;
};

} // namespace MDAlgorithms
} // namespace Mantid
36 changes: 36 additions & 0 deletions Framework/MDAlgorithms/inc/MantidMDAlgorithms/QTransform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2024 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once

#include "MantidAPI/Algorithm.h"
#include "MantidDataObjects/MDEventWorkspace.h"
#include "MantidMDAlgorithms/DllConfig.h"

namespace Mantid {
namespace MDAlgorithms {

/** QTransform : Base algorithm for transforming |Q| values in an MD workspace.
*/
class MANTID_MDALGORITHMS_DLL QTransform : public API::Algorithm {
public:
protected:
std::map<std::string, std::string> validateInputs() override;
void init() override;
void exec() override;

template <typename MDE, size_t nd>
void applyCorrection(typename Mantid::DataObjects::MDEventWorkspace<MDE, nd>::sptr);

// correction method to be implemented by derived classes. Input parameter is |Q|^2.
virtual double correction(const double) const = 0;

private:
size_t m_numQDims;
};

} // namespace MDAlgorithms
} // namespace Mantid
62 changes: 62 additions & 0 deletions Framework/MDAlgorithms/src/MagneticFormFactorCorrectionMD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2024 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +

#include "MantidMDAlgorithms/MagneticFormFactorCorrectionMD.h"
#include "MantidKernel/ListValidator.h"

namespace Mantid {
namespace MDAlgorithms {
using Mantid::API::WorkspaceProperty;
using Mantid::Kernel::Direction;
using Mantid::Kernel::StringListValidator;

// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(MagneticFormFactorCorrectionMD)

//----------------------------------------------------------------------------------------------

/// Algorithms name for identification. @see Algorithm::name
const std::string MagneticFormFactorCorrectionMD::name() const { return "MagneticFormFactorCorrectionMD"; }

/// Algorithm's version for identification. @see Algorithm::version
int MagneticFormFactorCorrectionMD::version() const { return 1; }

/// Algorithm's category for identification. @see Algorithm::category
const std::string MagneticFormFactorCorrectionMD::category() const { return "MDAlgorithms"; }

/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string MagneticFormFactorCorrectionMD::summary() const {
return "Apply magnetic form factor correction to MD events by dividing signal with F(Q)^2";
}
const std::vector<std::string> MagneticFormFactorCorrectionMD::seeAlso() const { return {"MagFormFactorCorrection"}; }
// //----------------------------------------------------------------------------------------------
// /** Initialize the algorithm's properties.
// */
void MagneticFormFactorCorrectionMD::init() {
QTransform::init();
std::vector<std::string> keys = Mantid::PhysicalConstants::getMagneticIonList();
declareProperty("IonName", "Cu2", std::make_shared<StringListValidator>(keys),
"The name of the ion: an element symbol with a number "
"indicating the valence, e.g. Fe2 for Fe2+ / Fe(II)");
}

// //----------------------------------------------------------------------------------------------
// /** Execute the algorithm.
// */
void MagneticFormFactorCorrectionMD::exec() {
ion = Mantid::PhysicalConstants::getMagneticIon(getProperty("IonName"));
QTransform::exec();
}

// implement correction method
double MagneticFormFactorCorrectionMD::correction(const double q2) const {
const auto ff = ion.analyticalFormFactor(q2);
return 1. / (ff * ff);
}

} // namespace MDAlgorithms
} // namespace Mantid
124 changes: 124 additions & 0 deletions Framework/MDAlgorithms/src/QTransform.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2024 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +

#include "MantidMDAlgorithms/QTransform.h"
#include "MantidAPI/IMDEventWorkspace_fwd.h"
#include "MantidDataObjects/MDEventFactory.h"
#include "MantidKernel/SpecialCoordinateSystem.h"
#include "MantidMDAlgorithms/MDWSDescription.h"

using namespace Mantid::DataObjects;

namespace Mantid {
namespace MDAlgorithms {
using Mantid::API::IMDEventWorkspace;
using Mantid::API::IMDEventWorkspace_sptr;
using Mantid::API::WorkspaceProperty;
using Mantid::Kernel::Direction;

//----------------------------------------------------------------------------------------------
namespace { // anonymous
size_t getNumQDimensions(const IMDEventWorkspace_sptr ws) {
// Check that the input workspace has units in Q_sample or Q_lab or |Q| frame
// Check the assumption that the Q dimensions are the first
if (ws->getSpecialCoordinateSystem() == Mantid::Kernel::SpecialCoordinateSystem::QSample ||
ws->getSpecialCoordinateSystem() == Mantid::Kernel::SpecialCoordinateSystem::QLab) {
// check that the first 3 dimensions are in Q
if (ws->getNumDims() < 3)
return 0;

for (size_t i = 0; i < 3; ++i)
if (!ws->getDimension(i)->getMDFrame().isQ())
return 0;

return 3;
} else if (ws->getDimension(0)->getName() == "|Q|") {
return 1;
}

return 0;
}
} // namespace
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void QTransform::init() {
declareProperty(std::make_unique<WorkspaceProperty<IMDEventWorkspace>>("InputWorkspace", "", Direction::Input),
"An input MDEventWorkspace. Must be in Q.");
declareProperty(std::make_unique<WorkspaceProperty<IMDEventWorkspace>>("OutputWorkspace", "", Direction::Output),
"The output MDEventWorkspace with correction applied.");
}

std::map<std::string, std::string> QTransform::validateInputs() {
std::map<std::string, std::string> result;
// check that the input workspace has units in Q_sample or Q_lab frame
API::IMDEventWorkspace_sptr input_ws = getProperty("InputWorkspace");
if (getNumQDimensions(input_ws) == 0)
result["InputWorkspace"] = "Input workspace must be in Q_sample or Q_lab frame. Either Q3D or Q1D with |Q|.";

return result;
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void QTransform::exec() {
IMDEventWorkspace_sptr input_ws = getProperty("InputWorkspace");
IMDEventWorkspace_sptr output_ws = getProperty("OutputWorkspace");

if (output_ws != input_ws)
output_ws = input_ws->clone();

m_numQDims = getNumQDimensions(output_ws);

CALL_MDEVENT_FUNCTION(applyCorrection, output_ws);

// refresh cache for MDBoxes: set correct Box signal
output_ws->refreshCache();

setProperty("OutputWorkspace", output_ws);
}

template <typename MDE, size_t nd>
void QTransform::applyCorrection(typename Mantid::DataObjects::MDEventWorkspace<MDE, nd>::sptr ws) {
// Get Box from MDEventWorkspace
MDBoxBase<MDE, nd> *box1 = ws->getBox();
std::vector<API::IMDNode *> boxes;
box1->getBoxes(boxes, 1000, true);
auto numBoxes = int(boxes.size());

PRAGMA_OMP(parallel for if (!ws->isFileBacked()))
for (int i = 0; i < numBoxes; ++i) {
PARALLEL_START_INTERRUPT_REGION
auto *box = dynamic_cast<MDBox<MDE, nd> *>(boxes[i]);
if (box && !box->getIsMasked()) {
std::vector<MDE> &events = box->getEvents();
for (auto it = events.begin(); it != events.end(); ++it) {

double qsqr{0};
for (size_t d = 0; d < m_numQDims; ++d)
qsqr += it->getCenter(d) * it->getCenter(d);

const auto correction = this->correction(qsqr);

// apply the correction
const auto intensity = it->getSignal() * correction;
it->setSignal(static_cast<float>(intensity));
const auto error2 = it->getErrorSquared() * correction * correction;
it->setErrorSquared(static_cast<float>(error2));
}
}
if (box) {
box->releaseEvents();
}
PARALLEL_END_INTERRUPT_REGION
}

return;
}

} // namespace MDAlgorithms
} // namespace Mantid
135 changes: 135 additions & 0 deletions Framework/MDAlgorithms/test/MagneticFormFactorCorrectionMDTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2024 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once

#include <cxxtest/TestSuite.h>

#include "MantidDataObjects/MDEventInserter.h"
#include "MantidKernel/MagneticIon.h"
#include "MantidMDAlgorithms/MagneticFormFactorCorrectionMD.h"
#include "QTransformTest.h"

using Mantid::MDAlgorithms::MagneticFormFactorCorrectionMD;

class MagneticFormFactorCorrectionMDTest : public CxxTest::TestSuite {
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static MagneticFormFactorCorrectionMDTest *createSuite() { return new MagneticFormFactorCorrectionMDTest(); }
static void destroySuite(MagneticFormFactorCorrectionMDTest *suite) { delete suite; }

void test_exec_1D() {
// create a 1D MD workspace
auto create_alg = Mantid::API::AlgorithmManager::Instance().createUnmanaged("CreateMDWorkspace");
create_alg->setChild(true);
create_alg->initialize();
create_alg->setProperty("Dimensions", 1);
create_alg->setProperty("Extents", "1,4");
create_alg->setProperty("Names", "|Q|");
create_alg->setProperty("Units", "A");
create_alg->setPropertyValue("OutputWorkspace", "_unused_for_child");
create_alg->execute();

Mantid::API::Workspace_sptr inputWS = create_alg->getProperty("OutputWorkspace");

// add MD events with Q values 1, 2, 3, 4
MDEventWorkspace<MDLeanEvent<1>, 1>::sptr mdws_mdevt_1 =
std::dynamic_pointer_cast<MDEventWorkspace<MDLeanEvent<1>, 1>>(inputWS);
MDEventInserter<MDEventWorkspace<MDLeanEvent<1>, 1>::sptr> inserter(mdws_mdevt_1);

for (Mantid::coord_t q = 1; q < 5; ++q) {
Mantid::coord_t coord[1] = {q};
inserter.insertMDEvent(1.0, 1.0, 0, 0, 0, coord);
}

// run the algorithm with U5 ion
std::string ionName = "U5";

MagneticFormFactorCorrectionMD alg;
alg.setChild(true);
TS_ASSERT_THROWS_NOTHING(alg.initialize())
TS_ASSERT(alg.isInitialized())
TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inputWS));
TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", "_unused_for_child"));
TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("IonName", ionName));
TS_ASSERT_THROWS_NOTHING(alg.execute(););
TS_ASSERT(alg.isExecuted());
Mantid::API::IMDEventWorkspace_sptr outputWS = alg.getProperty("OutputWorkspace");

// get the events from the output workspace and check the signal, error, and center values
auto output_events = QTransformTest::get_events_helper(outputWS);

TS_ASSERT_EQUALS(output_events.size(), 4);

auto ion = Mantid::PhysicalConstants::getMagneticIon(ionName);

for (size_t i = 0; i < output_events.size(); ++i) {
const double q = static_cast<double>(i + 1);
const double ff = ion.analyticalFormFactor(q * q);
TS_ASSERT_DELTA(output_events[i][0], 1. / (ff * ff), 1e-5); // signal
TS_ASSERT_DELTA(output_events[i][1], 1. / (ff * ff), 1e-5); // error
TS_ASSERT_EQUALS(output_events[i][2], q); // center
}
}

void test_exec_3D() {
// create a 3D MD workspace
auto create_alg = Mantid::API::AlgorithmManager::Instance().createUnmanaged("CreateMDWorkspace");
create_alg->setChild(true);
create_alg->initialize();
create_alg->setProperty("Dimensions", 3);
create_alg->setProperty("Extents", "0,10,0,10,0,10");
create_alg->setProperty("Names", "Qx,Qy,Qz");
create_alg->setProperty("Units", "A,A,A");
create_alg->setProperty("Frames", "QSample,QSample,QSample");
create_alg->setPropertyValue("OutputWorkspace", "_unused_for_child");
create_alg->execute();

Mantid::API::Workspace_sptr inputWS = create_alg->getProperty("OutputWorkspace");

// add MD events with Q values (1,1,1), (2,2,2), (3,3,3), (4,4,4)
MDEventWorkspace<MDLeanEvent<3>, 3>::sptr mdws_mdevt_3 =
std::dynamic_pointer_cast<MDEventWorkspace<MDLeanEvent<3>, 3>>(inputWS);
MDEventInserter<MDEventWorkspace<MDLeanEvent<3>, 3>::sptr> inserter(mdws_mdevt_3);

for (Mantid::coord_t q = 1; q < 5; ++q) {
Mantid::coord_t coord[3] = {q, q, q};
inserter.insertMDEvent(1.0, 1.0, 0, 0, 0, coord);
}

// run the algorithm with Pu5 ion
std::string ionName = "Pu5";

MagneticFormFactorCorrectionMD alg;
alg.setChild(true);
TS_ASSERT_THROWS_NOTHING(alg.initialize())
TS_ASSERT(alg.isInitialized())
TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inputWS));
TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", "_unused_for_child"));
TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("IonName", ionName));
TS_ASSERT_THROWS_NOTHING(alg.execute(););
TS_ASSERT(alg.isExecuted());
Mantid::API::IMDEventWorkspace_sptr outputWS = alg.getProperty("OutputWorkspace");

// get the events from the output workspace and check the signal, error, and center values
auto output_events = QTransformTest::get_events_helper(outputWS);

TS_ASSERT_EQUALS(output_events.size(), 4);

auto ion = Mantid::PhysicalConstants::getMagneticIon(ionName);

for (size_t i = 0; i < output_events.size(); ++i) {
const double q = static_cast<double>(i + 1);
const double ff = ion.analyticalFormFactor((q * q) * 3);
TS_ASSERT_DELTA(output_events[i][0], 1. / (ff * ff), 1e-5); // signal
TS_ASSERT_DELTA(output_events[i][1], 1. / (ff * ff), 1e-5); // error
TS_ASSERT_EQUALS(output_events[i][2], q); // center x
TS_ASSERT_EQUALS(output_events[i][3], q); // center y
TS_ASSERT_EQUALS(output_events[i][4], q); // center z
}
}
};
217 changes: 217 additions & 0 deletions Framework/MDAlgorithms/test/QTransformTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2024 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once

#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidDataObjects/MDEventFactory.h"
#include "MantidMDAlgorithms/QTransform.h"
#include <cxxtest/TestSuite.h>

using Mantid::MDAlgorithms::QTransform;
using namespace Mantid::DataObjects;

class QTransformTest : public CxxTest::TestSuite {
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static QTransformTest *createSuite() { return new QTransformTest(); }
static void destroySuite(QTransformTest *suite) { delete suite; }

void test_exec_1Q() {
auto inputWS = createMDWorkspace("QTransformTest1", 1, "1,4", "|Q|", "A");

auto outputWS = runQTransform("QTransformTest1");
TS_ASSERT(outputWS);

compare_input_and_outputWS(inputWS, outputWS);
}

void test_exec_1Q_1E() {
auto inputWS = createMDWorkspace("QTransformTest2", 2, "1,4,1,4", "|Q|,E", "A,B");

auto outputWS = runQTransform("QTransformTest2");
TS_ASSERT(outputWS);

compare_input_and_outputWS(inputWS, outputWS, true);
}

void test_exec_3Q() {
auto inputWS =
createMDWorkspace("QTransformTest3", 3, "1,4,1,4,1,4", "Q_lab_x,Q_lab_y,Q_lab_z", "A,B,C", "QLab,QLab,QLab");

auto outputWS = runQTransform("QTransformTest3");
TS_ASSERT(outputWS);

compare_input_and_outputWS(inputWS, outputWS);
}

void test_exec_3Q_1E() {
auto inputWS = createMDWorkspace("QTransformTest4", 4, "1,4,1,4,1,4,1,4", "Q_sample_x,Q_sample_y,Q_sample_z,DeltaE",
"A,B,C,D", "QSample,QSample,QSample,General Frame");

auto outputWS = runQTransform("QTransformTest4");
TS_ASSERT(outputWS);

compare_input_and_outputWS(inputWS, outputWS, true);
}

void test_exec_bad_2Q() {
// this should throw as invalid input WS, only 2 q dimensions
auto inputWS =
createMDWorkspace("QTransformTest5", 2, "1,4,1,4", "Q_sample_x,Q_sample_y", "A,B", "QSample,QSample");

runQTransform("QTransformTest5", true);
}

void test_exec_bad_1Q() {
// this should throw as invalid input WS, name is "Q" not "|Q|"
auto inputWS = createMDWorkspace("QTransformTest6", 1, "1,4", "Q", "A");

runQTransform("QTransformTest6", true);
}

void test_exec_bad_order() {
// this should throw as invalid input WS, q diemnsions are not the first 3
auto inputWS = createMDWorkspace("QTransformTest7", 4, "1,4,1,4,1,4,1,4", "DeltaE,Q_sample_x,Q_sample_y,Q_sample_z",
"A,B,C,D", "General Frame,QSample,QSample,QSample");

runQTransform("QTransformTest7", true);
}

static std::vector<std::vector<double>> get_events_helper(Mantid::API::IMDEventWorkspace_sptr workspace) {
MDEventWorkspace<MDLeanEvent<1>, 1>::sptr MDEW_MDLEANEVENT_1 =
std::dynamic_pointer_cast<MDEventWorkspace<MDLeanEvent<1>, 1>>(workspace);
if (MDEW_MDLEANEVENT_1)
return get_events<MDLeanEvent<1>, 1>(MDEW_MDLEANEVENT_1);

MDEventWorkspace<MDLeanEvent<2>, 2>::sptr MDEW_MDLEANEVENT_2 =
std::dynamic_pointer_cast<MDEventWorkspace<MDLeanEvent<2>, 2>>(workspace);
if (MDEW_MDLEANEVENT_2)
return get_events<MDLeanEvent<2>, 2>(MDEW_MDLEANEVENT_2);

MDEventWorkspace<MDLeanEvent<3>, 3>::sptr MDEW_MDLEANEVENT_3 =
std::dynamic_pointer_cast<MDEventWorkspace<MDLeanEvent<3>, 3>>(workspace);
if (MDEW_MDLEANEVENT_3)
return get_events<MDLeanEvent<3>, 3>(MDEW_MDLEANEVENT_3);

MDEventWorkspace<MDLeanEvent<4>, 4>::sptr MDEW_MDLEANEVENT_4 =
std::dynamic_pointer_cast<MDEventWorkspace<MDLeanEvent<4>, 4>>(workspace);
return get_events<MDLeanEvent<4>, 4>(MDEW_MDLEANEVENT_4);
}

template <typename MDE, size_t nd>
static std::vector<std::vector<double>> get_events(typename Mantid::DataObjects::MDEventWorkspace<MDE, nd>::sptr ws) {
// return a vector of events, events being (signal, error, x1, x2, x3, ...)
std::vector<std::vector<double>> events_vector;
MDBoxBase<MDE, nd> *box1 = ws->getBox();
std::vector<Mantid::API::IMDNode *> boxes;
box1->getBoxes(boxes, 1000, true);
auto numBoxes = int(boxes.size());

for (int i = 0; i < numBoxes; ++i) {
auto *box = dynamic_cast<MDBox<MDE, nd> *>(boxes[i]);
if (box && !box->getIsMasked()) {
std::vector<MDE> &events = box->getEvents();
for (auto it = events.begin(); it != events.end(); ++it) {

std::vector<double> event;
event.push_back(it->getSignal());
event.push_back(it->getError());
for (size_t d = 0; d < nd; ++d)
event.push_back(it->getCenter(d));
events_vector.push_back(event);
}
}
if (box) {
box->releaseEvents();
}
}
return events_vector;
}

private:
Mantid::API::IMDEventWorkspace_sptr runQTransform(std::string inputWS, bool expect_throw = false) {
QTransformTestClass alg;
alg.setChild(true);
TS_ASSERT_THROWS_NOTHING(alg.initialize())
TS_ASSERT(alg.isInitialized())
TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", inputWS));
TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", "_unused_for_child"));
if (expect_throw) {
TS_ASSERT_THROWS(alg.execute();, const std::runtime_error &);
} else {
TS_ASSERT_THROWS_NOTHING(alg.execute(););
TS_ASSERT(alg.isExecuted());
}

return alg.getProperty("OutputWorkspace");
}

Mantid::API::IMDEventWorkspace_sptr createMDWorkspace(std::string wsName, int dim, std::string extents,
std::string names, std::string units, std::string frames = "") {
auto create_alg = Mantid::API::AlgorithmManager::Instance().createUnmanaged("CreateMDWorkspace");
create_alg->initialize();
create_alg->setProperty("Dimensions", dim);
create_alg->setProperty("Extents", extents);
create_alg->setProperty("Names", names);
create_alg->setProperty("Units", units);
create_alg->setProperty("Frames", frames);
create_alg->setPropertyValue("OutputWorkspace", wsName);
create_alg->execute();

auto fake_md_events = Mantid::API::AlgorithmManager::Instance().createUnmanaged("FakeMDEventData");
fake_md_events->initialize();
fake_md_events->setProperty("InputWorkspace", wsName);
fake_md_events->setPropertyValue("UniformParams", "-100");
fake_md_events->execute();

Mantid::API::IMDEventWorkspace_sptr inputWS =
Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::IMDEventWorkspace>(wsName);

return inputWS;
}

void compare_input_and_outputWS(Mantid::API::IMDEventWorkspace_sptr inputWS,
Mantid::API::IMDEventWorkspace_sptr outputWS, bool q_skip_last = false) {
auto input_events = get_events_helper(inputWS);
auto output_events = get_events_helper(outputWS);

TS_ASSERT_EQUALS(input_events.size(), output_events.size());

for (size_t i = 0; i < input_events.size(); ++i) {
TS_ASSERT_EQUALS(input_events[i].size(), output_events[i].size());

double q2{0};
// check center values do not change
for (size_t j = 2; j < input_events[i].size(); ++j) {
TS_ASSERT_DELTA(input_events[i][j], output_events[i][j], 1e-6);
if (!q_skip_last || j < input_events[i].size() - 1)
q2 += input_events[i][j] * input_events[i][j];
}

// signal and error input will be 1, output equal to q^2 since our implemented correction function just returns
// q^2
TS_ASSERT_EQUALS(input_events[i][0], 1);
TS_ASSERT_EQUALS(input_events[i][1], 1);
TS_ASSERT_DELTA(output_events[i][0], q2, 1e-5);
TS_ASSERT_DELTA(output_events[i][1], q2, 1e-5);
}
}

// small helper class to test abstract class
class QTransformTestClass : public QTransform {
public:
const std::string name() const override { return "QTransformTestClass"; };
int version() const override { return 1; };
const std::string category() const override { return "Test"; };
const std::string summary() const override { return "Summary."; };

// return the input q^2
double correction(const double q2) const override { return q2; };
};
};
1 change: 1 addition & 0 deletions buildconfig/CMake/CppCheck_Suppressions.txt.in
Original file line number Diff line number Diff line change
@@ -1048,6 +1048,7 @@ internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/MDEventWSWrapper.cp
internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/MDWSTransform.cpp:0
internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/MDWSDescription.cpp:0
internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/MDNormDirectSC.cpp:0
internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/MagneticFormFactorCorrectionMD.cpp:0
internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/OrMD.cpp:0
internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/MDNorm.cpp:0
internalError:${CMAKE_SOURCE_DIR}/Framework/MDAlgorithms/src/MergeMDFiles.cpp:0
60 changes: 60 additions & 0 deletions docs/source/algorithms/MagneticFormFactorCorrectionMD-v1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

.. algorithm::

.. summary::

.. relatedalgorithms::

.. properties::

Description
-----------

Scales the the signal and error of MD events by :math:`1/|F(Q)|^2` where :math:`F(Q)` is
the magnetic form factor for the ion specified in `IonName`.

`IonName` must be specified as a string with the element name followed
by a number which indicates the charge / oxidation state. E.g.
`Fe2` indicates :math:`\mathrm{Fe}^{2+}` or Fe(II).

Input workspace must be in Q with either 1 dimension of \|Q\| or 3 Q_sample/Q_lab dimensions.
It is assumed that the Q dimensions come first follow by any number of other dimensions.


Usage
-----
.. Try not to use files in your examples,
but if you cannot avoid it then the (small) files must be added to
autotestdata\UsageData and the following tag unindented
.. include:: ../usagedata-note.txt
**Example - MagneticFormFactorCorrectionMD**

.. testcode:: MagneticFormFactorCorrectionMDExample

# Create a test MD workspace
ws = CreateMDWorkspace(Dimensions='1', Extents='1,4',
Names='|Q|', Units='A')
FakeMDEventData(ws, UniformParams=-6000)

# Run the algorithm
wsOut = MagneticFormFactorCorrectionMD(ws, IonName="U5")

# Bin the result so that it can be printed
wsOut = BinMD(wsOut, AlignedDim0='|Q|,1,4,6')
ws = BinMD(ws, AlignedDim0='|Q|,1,4,6')

# Print the result
print("Input signal: ", [int(x) for x in ws.getSignalArray()])
print("Corrected signal:", [int(x) for x in wsOut.getSignalArray()])

Output:

.. testoutput:: MagneticFormFactorCorrectionMDExample

Input signal: [1000, 1000, 1000, 1000, 1000, 1000]
Corrected signal: [1137, 1281, 1498, 1813, 2270, 2937]

.. categories::

.. sourcelink::
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- New algorithm :ref:`algm-MagneticFormFactorCorrectionMD` to scale the MDEvents by the magnetic form factor.