Skip to content

Conversation

@jokasimr
Copy link
Contributor

@jokasimr jokasimr commented Feb 27, 2025

Polarization correction for ESTIA

Only important differences from #108 are in src/ess/estia/calibration.py: https://github.com/scipp/essreflectometry/pull/122/files#diff-df676f2a67f8251976ea2fcc161ea759d49deef6ef66c5adbf01d10665230077

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use esspolarization to perform the correction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now we can't because of scipp/esspolarization#84

When that is fixed we should be able to use esspolarization to do the correction.

@jokasimr jokasimr requested a review from SimonHeybrock August 28, 2025 08:04
@jokasimr
Copy link
Contributor Author

The notebook might need some clean up - I'll take a look at that later today.

Copy link
Member

@SimonHeybrock SimonHeybrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments below.

Comment on lines 88 to 93

if "Q" in ref.coords:
ref.coords.pop("Q")
if "theta" in ref.coords:
ref.coords.pop("theta")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear why this was added or what it may break. Can you add a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was added so that if the input already has a Q or theta coordinate those are still recomputed in the coordinate transformation further down in the function.

For Amor theta is typically a binnned coordinate, so it's not present in ReducedReference (because that is a histogram).
But I noticed that if theta is computed without gravity correction then it will not be a binned coordinate, and it might be preserved on ReducedReference and so it will not be replaced by the coordinate transformation below, and that leads to incorrect results.

Removing them here is just defensive - we always want them to be replaced.

Q is always a binned coordinate, so it should not be a coordinate on ReducedReference, unless explicitly added.

Copy link
Contributor Author

@jokasimr jokasimr Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it now to only remove theta. Changed it back to remove both Q and theta. Not removing Q would risk a silent bug if a Q coord is ever added to the input. Best to be safe.

spin anti-parallel to instrument polarization.'''

@classmethod
def from_reference_measurements(cls, Io, Is):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type hints

Comment on lines 54 to 81
Rspp_plus_Rsaa = (
4
* (rho * alp * Ipp + Iaa + rho * Ipa + alp * Iap)
/ ((1 + rho) * (1 + alp) * I0)
)
Pp = sc.sqrt(
(Ipp + Iaa - Ipa - Iap)
* (alp * (Ipp - Iap) - Iaa + Ipa)
/ (
(rho * alp * Ipp + Iaa + rho * Ipa + alp * Iap)
* (rho * (Ipp - Ipa) - Iaa + Iap)
)
)
Ap = sc.sqrt(
(Ipp + Iaa - Ipa - Iap)
* (rho * (Ipp - Ipa) - Iaa + Iap)
/ (
(rho * alp * Ipp + Iaa + rho * Ipa + alp * Iap)
* (alp * (Ipp - Iap) - Iaa + Ipa)
)
)
Rs = sc.sqrt(
(alp * (Ipp - Iap) - Iaa + Ipa)
* (rho * (Ipp - Ipa) - Iaa + Iap)
/ (
(rho * alp * Ipp + Iaa + rho * Ipa + alp * Iap)
* (Ipp + Iaa - Ipa - Iap)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Write this in a less repetitive manner, this is hard to read/review

Comment on lines 84 to 85
if "Q" in ref.coords:
ref.coords.pop("Q")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. For Estia there is no gravity correction, so theta is a coordinate on ReducedReference, but that coordinate should be replaced here.

)


def reduce_to_q(da, qbins):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type hints

Comment on lines 56 to 61
Io = intensity_from_parameters(
I0, Pp, Pa, Ap, Aa, sc.scalar(1), sc.scalar(0), sc.scalar(0), sc.scalar(1)
)
Is = intensity_from_parameters(
I0, Pp, Pa, Ap, Aa, Rspp, sc.scalar(0), sc.scalar(0), Rsaa
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear why passing the same values to both is a reasonable test. Same for passing zeros? Does this mean the test has gaps?

Also, keyword args and type hints would help.

Copy link
Contributor Author

@jokasimr jokasimr Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test verifies that PolarizationCalibrationParameters.from_reference_measurements is the inverse of intensity_from_parameters.

It does that for 10 different seeds. It's a hypothesis test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear why passing the same values to both is a reasonable test.

Maybe it's better if we talk in person since there seems to be some misunderstanding here.

Comment on lines 45 to 46
def polarization_matrix_from_beamline_parameters(Pp, Pa, Ap, Aa):
return _polarization_matrix(Pp, Pa, Ap, Aa)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this wrapper, it seems _polarization_matrix is used only once and could be reused?

Comment on lines +54 to +62
supermirror_reflectivities = [
sc.scalar(1),
sc.scalar(0),
sc.scalar(0),
sc.scalar(1),
]
magnetic_supermirror_reflectivities = [Rspp, sc.scalar(0), sc.scalar(0), Rsaa]
Io = [I0 * v for v in _matvec(polmat, supermirror_reflectivities)]
Is = [I0 * v for v in _matvec(polmat, magnetic_supermirror_reflectivities)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@SimonHeybrock SimonHeybrock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@jokasimr jokasimr merged commit f1d2387 into main Nov 18, 2025
4 checks passed
@jokasimr jokasimr deleted the polcal branch November 18, 2025 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants