scipp / scippneutron

Neutron scattering toolkit built using scipp for Data Reduction. Not facility or instrument specific.
https://scipp.github.io/scippneutron/
BSD 3-Clause "New" or "Revised" License
4 stars 3 forks source link

Compute Q_x and Q_y? #490

Closed SimonHeybrock closed 7 months ago

SimonHeybrock commented 7 months ago

This is needed for SANS in particular. Should it be added to the regular coord transform graphs?

jokasimr commented 7 months ago

I'm not sure I understand this code, but are they not already part of the coord transform graph here: https://github.com/scipp/scippneutron/blob/834ed0399e743d4948348dcbecd26ae629d38013/src/scippneutron/conversion/graph/tof.py#L39

SimonHeybrock commented 7 months ago

I have to check if the definition used in SANS is fully equivalent. It might be that their $Q_x$ and $Q_y$ is in a plane perpendicular to the incident beam and not defined by the (x,y,z) coord system.

SimonHeybrock commented 7 months ago

I have asked the scientists on Slack. If you are impatient, you may dig into this to find out: https://github.com/mantidproject/mantid/blob/main/Framework/Algorithms/src/Qxy.cpp.

jokasimr commented 7 months ago

Seems like the directions $e_x$ and $e_y$ are the same as in the coordinate system spectruminfo uses to specify samplePos and detector element positions. So it can't be 'local to the detector element'.

https://github.com/mantidproject/mantid/blob/8061276605d062155ce6dcfee6b589f7c6718b14/Framework/Algorithms/src/Qxy.cpp#L118C1-L124C55

https://github.com/mantidproject/mantid/blob/8061276605d062155ce6dcfee6b589f7c6718b14/Framework/Algorithms/src/Qxy.cpp#L145C1-L151C25

Then probably $e_z =$ beam direction.

SimonHeybrock commented 7 months ago

Reply from Robert Dalgliesh:

The definition we use can be found in Qxy.cpp

https://github.com/mantidproject/mantid/blob/291276d1b3f92d519f399310a3ef5f5d4a7c3d7f/Framework/Algorithms/src/Qxy.cpp

the other thing that’s contained in this function is the gravity correction.

The basic definition is

const double Q = 4.0 * M_PI * sinTheta / wavLength;

// Now get the x & y components of Q.
const double Qx = a * Q;
// Test whether they're in range, if not go to next spectrum.
if (Qx < axis.front() || Qx >= axis.back())
  break;
const double Qy = b * Q;

where

double phi = atan2(detPos.Y(), detPos.X());
double a = cos(phi);
double b = sin(phi);
double sinTheta = sin(spectrumInfo.twoTheta(i) * 0.5);

Qxy is also used by the ILL and EQSANS reduction workflows.

Comments

I think this is probably equivalent to the definition using wave vectors used in ScippNeutron (but that does not do gravity). We can check which yields better performance. Note the comment on gravity, but look at Qxy.cpp, math is not included in the snippets above.

SimonHeybrock commented 7 months ago

For now I am adding this in ESSsans, as there are already related bits such as gravity handling. We should consider moved this to ScippNeutron in its entirety.

SimonHeybrock commented 7 months ago

I'll call this fixed by scipp/esssans#71. I will open a new issue for moving all generic conversion code from esssans to ScippNeutron