-
Notifications
You must be signed in to change notification settings - Fork 27
Polarisation efficiency correction #510
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
Conversation
-correct_PA_efficiencies applies the matrix equation to the raw data. -polarised_correction returns PlatypusNexus files that have a m_spec_polcorr attribute containing the efficiency corrected spectra -Have included an extra ReductionOption "polarised" which is True or False Still some minor teething issues that need to be ironed out
Needed to mess around with ReductionOptions to tell refnx when to reduce m_spec and when to reduce m_spec_polcorr. Still not 100% sure whether this is foolproof, but I am able to plot both raw and polarisation-corrected data using this. Need to make more robust for less vanilla test cases. Also included new functions in __init__ file
Include a processing step in polarised_correction, and added some comments
np.matrix will be deprecated eventually.
-correct_PA_efficiencies applies the matrix equation to the raw data. -polarised_correction returns PlatypusNexus files that have a m_spec_polcorr attribute containing the efficiency corrected spectra -Have included an extra ReductionOption "polarised" which is True or False Still some minor teething issues that need to be ironed out
Needed to mess around with ReductionOptions to tell refnx when to reduce m_spec and when to reduce m_spec_polcorr. Still not 100% sure whether this is foolproof, but I am able to plot both raw and polarisation-corrected data using this. Need to make more robust for less vanilla test cases. Also included new functions in __init__ file
Include a processing step in polarised_correction, and added some comments
np.matrix will be deprecated eventually.
b9c47fb to
d2d531b
Compare
| # If polarised, add an entry for the polarisation | ||
| # efficiency corrected spectra | ||
| if polarised is True: | ||
| d["m_spec_polcorr"] = np.zeros_like(m_spec) |
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.
How about d["m_spec_polcorr"] = None?
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 one needs the logic check either.
| """ | ||
| # Ensure 'polarised' reduction option is initialized | ||
| if "polarised" not in reduction_options: | ||
| reduction_options["polarised"] = False |
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.
Do we need to check this? Just assume that polarised is in reduction_options.
| normalise_bins=True, | ||
| manual_beam_find=None, | ||
| event_filter=None, | ||
| polarised=False, |
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 it really necessary to have a polarised keyword?
refnx/reduce/reduce.py
Outdated
| Parameters | ||
| ---------- | ||
| pp : PlatypusNexus object |
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 docstring doesn't correspond to the parameters and how they're used later in the function
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.
Also in wrong order.
refnx/reduce/reduce.py
Outdated
| raw11.processed_spectrum["m_spec_polcorr"] = np.asarray( | ||
| [[val[0] for val in I11]] | ||
| ) | ||
| elif pm is None and mp is not None: |
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 it necessary to duplicate this section?
|
|
||
| # Create efficiency matrices from individual | ||
| # component efficiency matrices | ||
| efficiencies_matrix = [ |
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 can be vectorised. If flipper1_eff_matrix, flipper2_eff_matrix, polariser_eff_matrix, analyser_eff_matrix all have the same shape (wavelength.size, 4, 4) then I think one can just do:
flipper1_eff_matrix @ flipper2_eff_matrix @ polariser_eff_matrix @ analyser_eff_matrix
| # Invert efficiency matrices for each wavelength | ||
| inv_eff_matrix = [ | ||
| np.linalg.inv(eff_mat) for eff_mat in efficiencies_matrix | ||
| ] |
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.
inv_eff_matrix = np.array(list(map(np.linalg.inv, efficiencies_matrix)))?
| data : PlatypusNexus object | ||
| Polarised spectra for a given spin channel | ||
| channel : tuple | ||
| nominal spin channel - (0,0), (0,1), (1,0), or (1,1) |
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.
not clear what (0, 0) is. Is this mm or uu?
Perhaps we should use enumerations here?
| PlatypusNexus or None, | ||
| PlatypusNexus or None, | ||
| PlatypusNexus or None | ||
| The corrected datasets within the PlatypusNexus |
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.
Mention what combinations are accepted.
++, --
++, --, +-
++, --, +-, -+
|
|
||
| # Check if R++ or R-- channel is missing | ||
| if mm is None: | ||
| print("Error: Missing R-- channel") |
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.
raise RuntimeError("Missing R-- channel")
refnx/reduce/reduce.py
Outdated
|
|
||
|
|
||
| def polarised_correction( | ||
| mm=None, mp=None, pm=None, pp=None, reduction_options=None |
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.
make pp and mm positional parameters, no keyword.
| print("Error: Input for +- channel doesn't match flipper statuses!") | ||
| return -1 | ||
| elif mm is not None and _check_spin_channel(mm, (0, 0)) is False: | ||
| print("Error: Input for -- channel doesn't match flipper statuses!") |
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.
Exceptions for all of these.
|
|
||
| # Initialise reduction options if not passed to function | ||
| if reduction_options is None: | ||
| reduction_options = { |
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.
options = ReductionOptions(lo_wavelength=2.5, hi_wavelength=12.5)
options.update(reduction_options)
refnx/reduce/reduce.py
Outdated
| Returns | ||
| ------- | ||
| I00, I01, I10, I11 : PlatypusNexus object |
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.
you're not returning the PN objects, you're returning the spectra.
| for f1l in F1 | ||
| ] | ||
| # Define flipper 2 efficiency matrix | ||
| flipper2_eff_matrix = [ |
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.
np.array([
refnx/reduce/reduce.py
Outdated
| p1a = 0.993 | ||
| p1b = 0.57 | ||
| p1c = 0.47 | ||
| P1 = p1a - p1b * p1c ** (wavelength).astype("float") |
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.
@np.vectorize
def efficiency_matrix(wavelength, tuple_of_spin_channels):
# return 4*4 array
| ) | ||
| ] | ||
|
|
||
| I00_polcorr = [corr_pt[0] for corr_pt in np.array(corrected_data)] |
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.
we should be returning an array
|
|
||
| for channel in _not_none(mm, mp, pm, pp): | ||
| if not channel.processed_spectrum: | ||
| channel.process(**reduction_options) |
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.
(**options)
refnx/reduce/reduce.py
Outdated
| I10=raw10.processed_spectrum["m_spec"][0], | ||
| I11=raw11.processed_spectrum["m_spec"][0], | ||
| ) | ||
| raw00.processed_spectrum["m_spec_polcorr"] = np.asarray( |
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.
don't convert to arrays here, do it in correct_POL_efficiencies
refnx/reduce/reduce.py
Outdated
| ) | ||
| raw01 = None | ||
| raw10 = None | ||
| raw11.processed_spectrum["m_spec_polcorr"] = np.asarray( |
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.
do array in correct_POL_efficiences
refnx/reduce/reduce.py
Outdated
| Returns | ||
| ------- | ||
| I00, I01, I10, I11 : PlatypusNexus or None, |
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.
NSF aren't going to be None
Added SpinChannel Enum class that gets assigned to the spin_state attribute of PlatypusNexus objects based of the flipper1 and flipper2 statuses.
Uses Enum spin state class to arrange the scan's spin states to 00, 01, 10, 11. Change workings in polarised_correction to use I00, I01, I10, I11 for raw flipper statuses and mm, mp, pm, pp for corrected spin channels
PolarisedReduce encompasses all data for a typical reduction of polarised neutron reflectometry data. It needs direct beams for initialisation, that is made into a SpinSet which creates a PlatypusReduce object for each spin channel measured. TODO: add reflected beams into object for reduction SpinSet is an class to keep a spin set for a given angle together. it creates a PLatypusReduce object for each spin channel. TODO: incorporate polarisation correction in the initialisation routine Added both classes to __init__.py
More work on SpinSet so it works as expected now, and moved to platypusnexus.py file as I think it fits here more.
…to PNR_correction
|
@ohcpaull please have a look at andyfaff#9 for what I think PNR reduction should look like. |
|
We should talk on Thursday. |
First attempt at integrating polarised neutron reflectometry files in the reduction workflow. I have slightly altered the reduction code by adding some flags so it knows when data is polarised and to use the new dict element "m_spec_polcorr" instead of "m_spec" for polarised data. Let me know whether you're OK with this approach. I haven't implemented uncertainty analysis for the correction process yet.