-
Notifications
You must be signed in to change notification settings - Fork 126
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
- Added spin state order handling to PolarizationCorrectionFredrikze Correction Algorithm #37672
- Added spin state order handling to PolarizationCorrectionFredrikze Correction Algorithm #37672
Conversation
This appears to have cppcheck failures which are unrelated to recent isues with the Mantid pipelines. |
…algorithm - Implemented InputSpinStateOrder and OutputSpinStateOrder properties. - Updated execPA functions to dynamically handle different spin state orders. - Extracted input and output spin state mapping logic into separate functions for better code organization and reusability. - Ensured backward compatibility by setting default spin state orders. - Added validation to ensure input workspace count matches the spin state entered
…algorithm - Implemented InputSpinStateOrder and OutputSpinStateOrder properties. - Updated execPA functions to dynamically handle different spin state orders. - Extracted input and output spin state mapping logic into separate functions for better code organization and reusability. - Ensured backward compatibility by setting default spin state orders. - Added validation to ensure input workspace count matches the spin state entered
…of spin state orders.
…he polarization correction helper splitSpinStateString
45eb61c
to
37d2200
Compare
37d2200
to
9e56a41
Compare
…nEfficiencyCor - added input and output spin states for fredrikze algorithm in polarizationefficiencycor algorithm - updated unit tests to test spin states in both algorithms - updated polarizationefficiencycor documentation - added a release note for the update
9e56a41
to
2c7eef5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is half a review as I didn't have time to do the functional testing, but I had a few code comments to mention from that half:
namespace SPIN_STATES { | ||
const std::string PP("pp"); | ||
const std::string PA("pa"); | ||
const std::string AP("ap"); | ||
const std::string AA("aa"); | ||
const std::string P("p"); | ||
const std::string A("a"); | ||
|
||
} // namespace SPIN_STATES |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can be included from the PolarizationCorrectionsHelpers
header as SpinStateConfigurationsFredrikze
, so don't need to be repeated here.
@@ -38,6 +50,10 @@ const std::string cApLabel("Ap"); | |||
|
|||
const std::string efficienciesLabel("Efficiencies"); | |||
|
|||
const std::string inputSpinStateOrderLabel("InputSpinStateOrder"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm inclined to suggest we refactor the property constants here to match the way the Wildes version does it. I.e we have a namespace called Prop
and then have constants for all of the properties (including the InputWorkspace
etc. ones that aren't here yet). The constants should be in INPUT_WORKSPACE
style to make it clear that they're constants. You'll also need to make sure the instances where they're accessed using strings are replaced with these constants.
|
||
declareProperty( | ||
inputSpinStateOrderLabel, "", spinStateValidator, | ||
"The order of spin states in the input workspace group. TThe possible values are 'pp,pa,ap,aa' or 'p,a'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo
"The order of spin states in the input workspace group. TThe possible values are 'pp,pa,ap,aa' or 'p,a'."); | |
"The order of spin states in the input workspace group. The possible values are 'pp,pa,ap,aa' or 'p,a'."); |
* @param defaultOrder :: The vector of strings representing the default order. | ||
* @return A map of spin state to MatrixWorkspace shared pointers. | ||
*/ | ||
std::map<std::string, MatrixWorkspace_sptr> mapOrderToWorkspaces(const WorkspaceGroup_sptr &inWS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason these weren't included as private methods of the class in the header?
const std::vector<std::string> &order, | ||
const std::vector<std::string> &defaultOrder) { | ||
auto dataOut = std::make_shared<WorkspaceGroup>(); | ||
// If the order vector is empty, use the default order | ||
const std::vector<std::string> effectiveOrder = order.empty() ? defaultOrder : order; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it would result a very small amount of code duplication, but I think passing both an order and a default order is less readable than only passing an order and leaving the decision of what to pass to the caller. It's a mild breach of the Single Responsibility Principle for it to decide the order to use and then map the workspaces. Feel free to leave it as-is, just my thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this. I agree that it’s best to pass an order and leave the decision to the caller in order to avoid breaching the Single Responsibility Principle (SRP), code has been refactored to accommodate the suggested changes.
Performs wavelength polarization correction on a TOF reflectometer spectrometer. | ||
|
||
Algorithm is based on the paper Fredrikze, H, et al. "Calibration of a polarized neutron reflectometer" Physica B 297 (2001). | ||
The algorithm is based on the paper Fredrikze, H, et al. "Calibration of a polarized neutron reflectometer" Physica B 297 (2001). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add an explicit reference here? (The doc for DepolarizedAnalyserTransmission.rst
has an example of how to do this.
Full polarization corrections: both parallel, parallel-anti-parallel, anti-parallel-parallel, both anti-parallel. Four input workspaces are required. The spin states can be provided in any order and should match the order of the workspaces in the input group. | ||
|
||
- :literal:`'p, a'` | ||
PNR polarization corrections: parallel, anti-parallel. Two input workspaces are required. The spin states can be provided in any order and should match the order of the workspaces in the input group. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make clear here that PA
is Full polarization corrections and what PNR
stands for?
In the ideal case :math:`P_{p} = P_{a} = A_{p} = A_{a} = 1` | ||
Spin State Configurations | ||
######################### | ||
The algorithm directly uses spin states to define the measurement setup. The spin states are specified using two properties: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this reads a little better:
The algorithm directly uses spin states to define the measurement setup. The spin states are specified using two properties: | |
The algorithm expresses the order of the workspaces in the input and output groups in terms of spin states. These orders are specified using two properties: |
the default order used by the algorithm if none is specified are :literal:`pp, pa, ap, aa` for full polarization analysis or :literal:`p, a` for PNR. | ||
|
||
**Output Spin State Order:** | ||
This property determines the order of the spin states in the output workspace group. Similar to the input configuration, users can specify output spin states in any order. | ||
|
||
Output from Full Polarization Analysis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have an extra heading for the outputs from the PNR version?
|
||
--- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for this extra line being included?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested functionally with the following script. Changes are working well for the input and output spin state orders when the right number of characters are used, setting both properly.
# import mantid algorithms, numpy and matplotlib
from mantid.simpleapi import *
import matplotlib.pyplot as plt
import numpy as np
run = Load("POLREF00004699.nxs")
eff = Load("fredrikze_efficiencies_37125.nxs")
run = ConvertUnits(run, "Wavelength")
eff = ConvertUnits(eff, "Wavelength")
eff = RebinToWorkspace(eff, run.getItem(0), True)
out = PolarizationCorrectionFredrikze(run, eff, "PNR", OutputSpinStateOrder="p, a")
When messing with the script, found a couple of other issues:
Setting the OutputSpinStateOrder
to "pp, aa" ran the algorithm and threw an IndexError: map::at: key not found
, this should be checked in the validateInputs()
method.
Setting the InputSpinStateOrder
to "pp, aa" caused a segfault that crashed to desktop.
# import mantid algorithms, numpy and matplotlib
from mantid.simpleapi import *
import matplotlib.pyplot as plt
import numpy as np
run1 = Load("POLREF00004699.nxs")
run2 = Load("POLREF00004699.nxs")
run2 = run2 * 1.2
run = GroupWorkspaces([run1, run2])
eff = Load("fredrikze_efficiencies_37125.nxs")
run = ConvertUnits(run, "Wavelength")
eff = ConvertUnits(eff, "Wavelength")
eff = RebinToWorkspace(eff, run.getItem(0), True)
out = PolarizationCorrectionFredrikze(run, eff, "PA", OutputSpinStateOrder="pp, aa, pa, ap")
The inverse applies to the above, using p
and a
in this one.
Thank you for the comprehensive review. I have implemented the suggested changes and updated the unit tests to resolve the segfault crash |
@yusufjimoh, thanks for all the hard work on this one. It's a change that can definitely wait until the next release, that's no problem, so I'm going to switch the milestone to 6.12 at this point. It will mean that the release notes will need to be moved into a different folder at an appropriate stage (we can't do that just yet), so I'll discuss that with you at some point in the future (no need to worry about it right now). Hope this sounds OK. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionally tested using previous scripts and working well. Small issue with validation mentioned in code comments. Just a few more questions about the code, but this is looking good:
@@ -135,14 +196,14 @@ const std::string PolarizationCorrectionFredrikze::summary() const { | |||
* @param rhs : WS to multiply by (constant value) | |||
* @return Multiplied Workspace. | |||
*/ | |||
MatrixWorkspace_sptr PolarizationCorrectionFredrikze::multiply(MatrixWorkspace_sptr &lhsWS, const double &rhs) { | |||
MatrixWorkspace_sptr PolarizationCorrectionFredrikze::multiply(const MatrixWorkspace_sptr &lhsWS, double &rhs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason the const
was moved here rather than just making both const
? If it's just a compilation thing, that's fine
const std::string cAlphaLabel("Alpha"); | ||
namespace Prop { | ||
static const std::string FLIPPERS{"Flippers"}; | ||
static const std::string pNRLabel("PNR"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This and the other constants here should be capitalised.
- You can also make these
constexpr auto
rather than explicitly declaring the string for slightly better runtime efficiency asconstexpr
means they'll be generated at compile time.
static const std::string pNRLabel("PNR"); | |
constexpr auto PNR_LABEL("PNR"); |
if (analysisMode == Prop::pNRLabel) { | ||
// for PR, spinStates must be "p,a", "a,p", or empty vector | ||
return (spinStates.size() == 2 && | ||
((spinStates[0] == "p" && spinStates[1] == "a") || (spinStates[0] == "a" && spinStates[1] == "p"))) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be using the constants?
"An output workspace."); | ||
|
||
const auto spinStateValidator = std::make_shared<SpinStateValidator>( | ||
std::unordered_set<int>{2, 4}, true, SpinStateConfigurationsFredrikze::PARA[0], 'a', true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason only one of the constants was used? I know it's expecting a char
rather than a string (hence the [0]
), but if we're using the constant like this or just 'p'
can we be consistent between the para and anti?
const std::vector<std::string> inputStates = PolarizationCorrectionsHelpers::splitSpinStateString(inputStatesStr); | ||
const std::vector<std::string> outputStates = PolarizationCorrectionsHelpers::splitSpinStateString(outputStatesStr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use auto
here.
validateInputWorkspace(inWS); | ||
|
||
if (!isValidSpinState(inputStates, analysisMode)) { | ||
throw std::invalid_argument("Invalid input spin state: " + inputStatesStr + " for " + analysisMode); | ||
} | ||
if (!isValidSpinState(outputStates, analysisMode)) { | ||
throw std::invalid_argument("Invalid output spin state: " + outputStatesStr + " for " + analysisMode); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason Fredrikze doesn't seem to have it, but this kind of validation should be taking place in a valdiateInputs()
method. See PolarizationCorrectionWildes.cpp
for an example. This is also why these errors do not appear properly on the algorithm dialog.
These error messages should also probably identify what the valid inputs would look like.
static const std::string OUTPUT_WORKSPACE{"OutputWorkspace"}; | ||
static const std::string INPUT_SPIN_STATES("InputSpinStates"); | ||
static const std::string OUTPUT_SPIN_STATES("OutputSpinStates"); | ||
static const std::string crhoLabel("Rho"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this and some of the others in here (cApLabel
etc.) are Properties of the algorithm, and so should probably be in a different namespace.
Output from Polarized Neutron Reflectivity | ||
------------------------------------------ | ||
|
||
The output of this algorithm is a :ref:`WorkspaceGroup <WorkspaceGroup>`, the resulting :ref:`WorkspaceGroup <WorkspaceGroup>` will have 2 entries, corresponding to the output specified spin state orders, if no specific output spin states are specified, it will be formatted as follows: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output of this algorithm is a :ref:`WorkspaceGroup <WorkspaceGroup>`, the resulting :ref:`WorkspaceGroup <WorkspaceGroup>` will have 2 entries, corresponding to the output specified spin state orders, if no specific output spin states are specified, it will be formatted as follows: | |
The output of this algorithm is a :ref:`WorkspaceGroup <WorkspaceGroup>`. The resulting :ref:`WorkspaceGroup <WorkspaceGroup>` will have 2 entries, corresponding to the specified output spin state orders. If no specific output spin states are specified, it will be formatted as follows: |
.. testcode:: PolarizationCorrectionFredrikze (PNR) | ||
|
||
# import mantid algorithms, numpy and matplotlib | ||
from mantid.simpleapi import * | ||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
run = Load("POLREF00004699.nxs") | ||
eff = Load("fredrikze_efficiencies_37125.nxs") | ||
run = ConvertUnits(run, "Wavelength") | ||
eff = ConvertUnits(eff, "Wavelength") | ||
eff = RebinToWorkspace(eff, run.getItem(0), True) | ||
out = PolarizationCorrectionFredrikze(run, eff, "PNR", InputSpinStates="pp, pa, ap, aa", OutputSpinStates="p, a") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should probable be a .. testoutput::
here as in the one from the wildes docs. That way we can make sure this usage example consistently performs correctly.
run = ConvertUnits(run, "Wavelength") | ||
eff = ConvertUnits(eff, "Wavelength") | ||
eff = RebinToWorkspace(eff, run.getItem(0), True) | ||
out = PolarizationCorrectionFredrikze(run, eff, "PNR", InputSpinStates="pp, pa, ap, aa", OutputSpinStates="p, a") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does a PNR example typically take 4 workspaces an input or should it only take two?
69de188
to
cb9eb1f
Compare
8e1542e
to
f1997c8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a lot of tidy-ups have gone into this PR, thanks very much for all of your hard work on this Yusuf!
I haven't completed functional testing yet, but I've checked the validation, which all seems very robust.
I've noticed a few places in the documentation and some of the validation messages where it might be good to clarify some of the wording, or where there are typos, so I've added relevant comments to look at those final bits, if that's OK.
I think that there are one or two places where we might like to look at our use of constants in this algorithm (mostly in the existing rather than new code), but given that quite a bit of refactoring and improvements have already been made in this PR, I will open a separate maintenance issue to look at these last bits.
Additionally, we've added unit tests that provide good coverage of the input and output spin state validation, which is great for now. As a follow-up maintenance task, I think it would be good to think about how we might test that the algorithm is applying the re-ordering correctly, as I think we're currently just assuming that if the algorithm doesn't throw an error then it's all worked OK. I will add a separate issue to look at this, as I don't want to hold up this PR too much longer.
for Fredrikze. | ||
The default values for the ``Flippers``, ``SpinStates``, and ``PolarizationAnalysis`` properties are empty strings, and | ||
correspond to the actual defaults of the child algorithms: ``00, 01, 10, 11`` / ``++, +-, -+, --`` for Wildes, | ||
and ``pp, pa, ap, aa`` / ``p, a`` for ``PA`` and ``PNR`` in Fredrikze. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if this sentence has got a bit confusing and might be better left simply as:
The default values for the ``Flippers``, ``SpinStates``, and ``PolarizationAnalysis`` properties are empty strings and correspond to the actual defaults of the child algorithms.
Users can then check the child algorithm documentation to clarify what default values are being applied.
The output of this algorithm, as we can see in the table of properties, is a :ref:`WorkspaceGroup <WorkspaceGroup>`. If the algorithm has been executed with "PA" as the Polarization mode | ||
then the resulting :ref:`WorkspaceGroup <WorkspaceGroup>` will have 4 entries and should be in the format: | ||
|
||
The output of this algorithm is a :ref:`WorkspaceGroup <WorkspaceGroup>`, the resulting :ref:`WorkspaceGroup <WorkspaceGroup>` will have 4 entries, corresponding to the output specified spin state orders, if no specific output spin states are specified, it will be formatted as follows: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good for this wording to match the style of the PNR wording beneath it, so we would have the following here:
The output of this algorithm is a :ref:
WorkspaceGroup . The resulting :ref:
WorkspaceGroup will have 4 entries, corresponding to the specified output spin state orders. If no specific output spin states are specified, it will be formatted as follows:
|
||
declareProperty( | ||
Prop::INPUT_SPIN_STATES, "", spinStateValidator, | ||
"The order of spin states in the input workspace group. The possible values are 'pp,pa,ap,aa' or 'p,a'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add "in any order" to this property description to make sure it's clear, so we would have:
The order of spin states in the input workspace group. The possible values are 'pp,pa,ap,aa' or 'p,a', in any order.
|
||
declareProperty( | ||
Prop::OUTPUT_SPIN_STATES, "", spinStateValidator, | ||
"The order of spin states in the input workspace group. The possible values are 'pp,pa,ap,aa' or 'p,a'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add "in any order" to this property description to make sure it's clear. There's also a typo as we need to refer to the output workspace group here. With these changes, we would have:
The order of spin states in the output workspace group. The possible values are 'pp,pa,ap,aa' or 'p,a', in any order.
|
||
if (!isValidSpinState(inputStates, analysisMode)) { | ||
throw std::invalid_argument("Invalid input spin state: " + inputStatesStr + " for " + analysisMode + | ||
" The possible values are 'pp,pa,ap,aa' or 'p,a' in any order"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please could we change sentence:
" The possible values are 'pp,pa,ap,aa' or 'p,a' in any order"
To be:
" The possible values are 'pp,pa,ap,aa' for PA, or 'p,a' for PNR, in any order"
Both here and on line 140 where we validate the output spin states against the analysis mode?
This validation is really helpful, but when I was testing I noticed that if I used a PNR spin state with the PA analysis mode then the current error message doesn't make it clear what I need to change.
@@ -210,7 +258,7 @@ void PolarizationEfficiencyCor::checkFredrikzeProperties() const { | |||
if (!isDefault(Prop::FLIPPERS)) { | |||
throw std::invalid_argument("Property Flippers cannot be used with the Fredrikze method."); | |||
} | |||
if (!isDefault(Prop::SPIN_STATES)) { | |||
if (!isDefault(Prop::OUTPUT_WILDES_SPIN_STATES)) { | |||
throw std::invalid_argument("Property SpinStates cannot be used with the Fredrikze method."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this error message needs to say "Property SpinStatesOutWildes cannot be used with the Fredrikze method." now that the Wildes spin states property has been renamed.
f1997c8
to
fe07a76
Compare
Thanks for the documentation updates Yusuf, those are all looking good. Just to flag up, the docs build failure on this PR is genuine as the example code gives an error when run in workbench. I think the following should hopefully work OK. I would hold off updating this while I finish my functional testing, though, just to make sure this will be the last change. I will let you know when I've finished that. For PNR:
Which gives output:
For PA:
Which gives output:
|
Functional testing looks really good to me.👍 If we can just replace the example in the docs with the above then hopefully that should be the last thing left before this can go in. |
- Renamed the input and output spin states - refactored tests to eliminate code duplication - added an helper function to fix crash which happens when user enter pp, aa as spinstates - improved code based on PR review suggestions - updated unit tests to handle crash which happens when user enter pp, aa as spinstates - updated documentation
fe07a76
to
b2662b1
Compare
I have updated the documentation with this, Thanks. |
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks very much for all your hard work on this issue Yusuf.
The code is working as expected and provides the additional functionality we needed under the original issue. There has also been a fair bit of maintenance pulled into this PR like some minor refactoring and adding usage examples to the docs, which are all looking good. There is some additional maintenance we could do and some unit test improvements that I think we could make, but it would be good to look at these under separate issues so that we can get this in and allow other related work to progress (see #38287 and #38288).
I'm dismissing Caila's stale review so that this can be gatekeepered - Caila's comments have either all been addressed or pulled into the linked maintenance issues.
…rrection Algorithm This is a squashed version of mantidproject#37672 - Added spin state order handling to PolarizationCorrectionFredrikze algorithm - Implemented InputSpinStateOrder and OutputSpinStateOrder properties. - Updated execPA functions to dynamically handle different spin state orders. - Extracted input and output spin state mapping logic into separate functions for better code organization and reusability. - Ensured backward compatibility by setting default spin state orders. - Added validation to ensure input workspace count matches the spin state entered - Added spin state order handling to PolarizationCorrectionFredrikze algorithm - Implemented InputSpinStateOrder and OutputSpinStateOrder properties. - Updated execPA functions to dynamically handle different spin state orders. - Extracted input and output spin state mapping logic into separate functions for better code organization and reusability. - Ensured backward compatibility by setting default spin state orders. - Added validation to ensure input workspace count matches the spin state entered - Included unit tests to verify correct functionality and validation of spin state orders. - splitted the spin state order string to a string of vectors using the polarization correction helper splitSpinStateString added p and a to spin states - modified unit tests to test spin state orders - updated the documentation to describe the spin states and its usage Add Input and Output SpinStates for FredrikzeAlgorithm in PolarizationEfficiencyCor - added input and output spin states for fredrikze algorithm in polarizationefficiencycor algorithm - updated unit tests to test spin states in both algorithms - updated polarizationefficiencycor documentation - added a release note for the update Refactor Fredrikze Algorithm SpinStates Implementation - Renamed the input and output spin states - refactored tests to eliminate code duplication - added an helper function to fix crash which happens when user enter pp, aa as spinstates - improved code based on PR review suggestions - updated unit tests to handle crash which happens when user enter pp, aa as spinstates - updated documentation --amend-no-edit [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci
Description of work
Purpose of work
#36981
To test: