-
Notifications
You must be signed in to change notification settings - Fork 1
Handle incoming polarized beam for analyzer transmission computation #64
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
class He3AnalyzerTransmissionFraction( | ||
sl.ScopeTwoParams[PolarizerSpin, PolarizationState, sc.DataArray], sc.DataArray | ||
): | ||
"""Transmission fraction of the analyzer with polarized incoming beam""" |
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.
Hm, for me, the namings are unlogical. Do I see it correctly that you define He3CellTransmissionFraction
as the transmission fraction for a 3He cell with an unpolarized incoming beam, vs. He3AnalyzerTransmissionFraction
for an analyzer with polarized incoming beam?
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.
Yes. Which names would you suggest?
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 would call it He3TransmissionFractionIncomingPolarized and He3TransmissionFractionIncomingUnpolarized.
I know the names are long, but precise
src/ess/polarization/he3.py
Outdated
# The two transmission fractions do not share a common time coordinate. Therefore, | ||
# we cannot concat along a third dimension for the fit, but concat along time, | ||
# with an additional coordinate for the incoming polarization. | ||
up = transmission_fraction_up.assign_coords(incoming_polarization=sc.scalar(1)) | ||
down = transmission_fraction_down.assign_coords(incoming_polarization=sc.scalar(-1)) | ||
transmission_fraction = sc.concat([up, down], 'time') |
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.
Another question: Can it happen that we have only one of the two?
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.
No. For the polarized incoming beam, we need to compute this for both Up and Down, and then get the same fitparameters from both fits (combined fitting), for the output of T1 and C. We will define for the users to always measure both.
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.
Actually its even more complicated. Because we assume that this is an analyzer 3He cell, its polarized for itself, so we do not only have incoming Up and Down, but also the polarization of the cell itself with Up and Down. But in the end, the transmission through the cell (and hence its parameters after this fit) only depend on two channels: if the incoming beam is parallel or antiparallel to the cell spin.
We could do that in 2 ways: (i) we combine the 2 spin channels (UU+DD, and UD+DU, as "parallel" and "antiparallel", respectively) or (ii) we only take one measured channel of each, i.e., in the workflow we could say take only UU OR DD for "parallel" and DU OR UD for "antiparallel. I am tending towards (ii). Because if the polarizer is not good then UU will be only = DD after the corrections, but not before.
Then we only have two fitting functions.
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.
See update please!
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 now I am assuming we have all four channels. It should be easy to adapt this later if we do not, but I wanted to avoid complicating this further. If it is ok with you then we postpone the (ii) case for later (could be soon, if needed).
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.
So this is not something the software can decide/figure out, but the (instrument?) scientist needs to know, somehow?
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.
If e.g. a supermirror is used, and the Flipper after the Supermirror polarizer is not perfect, then for the analyzer the incoming beam Up is not the same anymore as incoming Down, and hence T+ (for the "parallel" state, i.e., to get UU or DD) would "look different" for incoming Up and Down.
Similarly, if a 3He cell is used as polarizer, also T+ and T- for this cell can be slightly different and the same as above can arise.
But I would assume here that this can be a general case, and we have to differ it always for an incoming polarized beam.
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.
... but if there are two different T+, wouldn't we also need to distinguish those two for performing the polarization correction, instead of using only the T+ obtained from UU?
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.
T+ SHOULD be the same for incoming Up and incoming Down. I mean, if the incoming polarized beam (without sample) would be "perfect", then U should be the same as D, which it would be if we would have performed the correction already just for the polarizer/flipper, i.e., for the analyzer they would look the same. Then they have the same T+ of the analyzer, which should be the case. But if we do not perform the correction of intensities for the polarizer/flipper alone before we even compute T+ of the analyzer, I think it would look as if T+ would not be the same.
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 split it off, see update please (or wait for our call).
@@ -187,6 +194,8 @@ def __call__( | |||
polarization = self.polarization_function(time) | |||
if plus_minus == 'plus': | |||
polarization *= -1.0 | |||
elif isinstance(plus_minus, sc.Variable): | |||
polarization *= -plus_minus |
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.
Why -plus_minus
? Is that basically giving the "down"-channel with leaving the computation to "polarization *= +1.0
"?
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.
Compared to the lines above, where we heaver either plus or minus, when plus_minus
is a Variable
we can handle different sections at once, some plus, some minus.
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.
My question was rather a different one - what happens here for (i) plus_minus = plus
or (ii) plus_minus = minus
? If plus_minus = plus
, then as beforepolarization *= -1.0
, and if plus_minus = minus
then polarization *= +1.0
?
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.
plus_minus
is a scipp.Variable
, containing values of +1 and/or -1. +1 means "plus", -1 means "minus". So plus_minus
could be something like
[1,1,1,1,-1,-1,-1]
if we first measure the, say, UU channel, then UD.
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.
And for the transmission function that means for 'plus': self.transmission_empty_glass * sc.exp(-opacity * (1.0 - polarization)
and for 'minus':
self.transmission_empty_glass * sc.exp(-opacity * (1.0 + polarization)
? I actually just wanted to make sure I understand the calculation of transmission for different values of polus_minus
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.
Yes, correct.
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.
Ok thanks!
the fitted T(t, lambda). | ||
|
||
DB_pol/DB = T_E * cosh(O(lambda)*P(t))*exp(-O(lambda)) | ||
""" |
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 comment needs to be either changed or deleted here for the incoming polarized beam. Because its not the cosh(O(lambda)*P(t))*exp(-O(lambda))
function anymore, but the self.transmission_empty_glass * sc.exp(-opacity * (1.0 + polarization))
as written in class He3TransmissionFunction(TransmissionFunction[PolarizingElement]):
in line 199
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.
Done
src/ess/polarization/he3.py
Outdated
# The two transmission fractions do not share a common time coordinate. Therefore, | ||
# we cannot concat along a third dimension for the fit, but concat along time, | ||
# with an additional coordinate for the incoming polarization. | ||
up = transmission_fraction_up.assign_coords(incoming_polarization=sc.scalar(1)) | ||
down = transmission_fraction_down.assign_coords(incoming_polarization=sc.scalar(-1)) | ||
transmission_fraction = sc.concat([up, down], 'time') |
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.
No. For the polarized incoming beam, we need to compute this for both Up and Down, and then get the same fitparameters from both fits (combined fitting), for the output of T1 and C. We will define for the users to always measure both.
src/ess/polarization/he3.py
Outdated
# The two transmission fractions do not share a common time coordinate. Therefore, | ||
# we cannot concat along a third dimension for the fit, but concat along time, | ||
# with an additional coordinate for the incoming polarization. | ||
up = transmission_fraction_up.assign_coords(incoming_polarization=sc.scalar(1)) | ||
down = transmission_fraction_down.assign_coords(incoming_polarization=sc.scalar(-1)) | ||
transmission_fraction = sc.concat([up, down], 'time') |
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.
Actually its even more complicated. Because we assume that this is an analyzer 3He cell, its polarized for itself, so we do not only have incoming Up and Down, but also the polarization of the cell itself with Up and Down. But in the end, the transmission through the cell (and hence its parameters after this fit) only depend on two channels: if the incoming beam is parallel or antiparallel to the cell spin.
We could do that in 2 ways: (i) we combine the 2 spin channels (UU+DD, and UD+DU, as "parallel" and "antiparallel", respectively) or (ii) we only take one measured channel of each, i.e., in the workflow we could say take only UU OR DD for "parallel" and DU OR UD for "antiparallel. I am tending towards (ii). Because if the polarizer is not good then UU will be only = DD after the corrections, but not before.
Then we only have two fitting functions.
class He3AnalyzerTransmissionFraction( | ||
sl.ScopeTwoParams[PolarizerSpin, PolarizationState, sc.DataArray], sc.DataArray | ||
): | ||
"""Transmission fraction of the analyzer with polarized incoming beam""" |
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 would call it He3TransmissionFractionIncomingPolarized and He3TransmissionFractionIncomingUnpolarized.
I know the names are long, but precise
e57adb6
to
34655c9
Compare
Fixes #58.
I need a detailed review here @astellhorn, since I am not at all confident that this is correct.