campaslab / napari-stress

Interactive surface analysis in napari for bio-mechanical stress measurement
https://campaslab.github.io/napari-stress/
BSD 3-Clause "New" or "Revised" License
17 stars 4 forks source link

Spherical harmonics coefficients formatting #86

Open jo-mueller opened 2 years ago

jo-mueller commented 2 years ago

Hey @GrossBJ,

I'm having another question about how the coefficients for the spherical harmonics are formatted. We discussed about it a while ago but I think I'm not fully understanding it.

In the Stress-implementation, a spherical harmonics expansion (for instance, of degree 5) would return a coefficient matrix of size (3 x 6 x 6), whereas each "entry" in that array corresponds to the coefficients for one of the three spatial dimensions (x, y, z) - correct? In other words, there's a separate expansion going on for each spatial dimension - ist hat correct?

My actual question: How do you then proceed to calculate the amplitudes of the spherical harmonic modes as shown in the paper (Figure 4E)?

Thanks in advace!

GrossBJ commented 2 years ago

Hi Johannes, This is done between lines 1290 and 1320 in the refactored droplet class file. Basically we use the elliptical coordinates of the least-squares ellipsoid to compute a fit for the (signed) residuals between the least-squares ellipsoid and the droplet segmentation. For each of these, the error corresponds to the coefficient size, weighted by the mass matrix of the mode itself (since I didn't normalize my basis), so this is pretty easy to compute. If you have any questions please ask, and I am more than happy to zoom again! Thanks, Ben J. Gross Post-Doctoral ResearcherWorld Traveler Dept. Mech. & Aero. Eng.UC San Diego

On Friday, June 17, 2022, 03:44:57 AM PDT, Johannes Müller ***@***.***> wrote:  

Hey @GrossBJ,

I'm having another question about how the coefficients for the spherical harmonics are formatted. We discussed about it a while ago but I think I'm not fully understanding it.

In the Stress-implementation, a spherical harmonics expansion (for instance, of degree 5) would return a coefficient matrix of size (3 x 6 x 6), whereas each "entry" in that array corresponds to the coefficients for one of the three spatial dimensions (x, y, z) - correct? In other words, there's a separate expansion going on for each spatial dimension - ist hat correct?

My actual question: How do you then proceed to calculate the amplitudes of the spherical harmonic modes as shown in the paper (Figure 4E)?

Thanks in advace!

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

jo-mueller commented 2 years ago

Hey Ben @GrossBJ,

thanks for clearing up that I wasn't actually looking at the power spectrum of the spherical harmonics function, but rather how much the (non-ellipsoidal) modes contribute to the residues. (I hope I'm not overly confusing with my layman's language).

As for the other question, can you explain a bit more how the SPH coefficients are formatted? From the plain definition I would expect the coefficient matrix of a SH expansion of degree 5 to be 6 x 13 ( l x [-m, m]) but I think the cosine/sine parts are often separated in other conventions (e.g., using a coefficient matrix of (l x m x m). In the stress implementation, the resulting coefficient matrix for an expansion of degree 5 are three separate 6x6 matrices for the x, y and z coordinate.

GrossBJ commented 2 years ago

Hi Johannes, It gets a bit confusing but the order of the coefficients within the matrix goes: 1   4   9   162   3   8   15 5   6   7   1410 11 12 13 ...etc So when you read them in there is a function is sph_func.py that converts this matrix to a vector and the opposite. Ben J. Gross Post-Doctoral ResearcherWorld Traveler Dept. Mech. & Aero. Eng.UC San Diego

On Monday, June 20, 2022, 07:34:34 AM PDT, Johannes Müller ***@***.***> wrote:  

Hey Ben,

thanks for clearing up that I wasn't actually looking at the power spectrum of the spherical harmonics function, but rather how much the (non-ellipsoidal) modes contribute to the residues. (I hope I'm not overly confusing with my layman's language).

As for the other question, can you explain a bit more how the SPH coefficients are formatted? From the plain definition I would expect the coefficient matrix of a SH expansion of degree 5 to be 6 x 13 ( l x [-m, m]) but I think the cosine/sine parts are often separated in other conventions (e.g., using a coefficient matrix of (l x m x m). In the stress implementation, the resulting coefficient matrix for an expansion of degree 5 are three separate 6x6 matrices for the x, y and z coordinate.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

jo-mueller commented 2 years ago

Hm...not sure whether I can follow you there. If you don't mind I'd happily take up your offer on a Zoom call!

GrossBJ commented 2 years ago

For sure! When would you be free to talk?

Ben J. Gross

El mar, 21 de jun. de 2022 a la(s) 14:40, Johannes @.***> escribió:

Hm...not sure whether I can follow you there. If you don't mind I'd happily take up your offer on a Zoom call!

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

jo-mueller commented 2 years ago

@GrossBJ Maybe sometimes later today (~11 pm CET)?

jo-mueller commented 2 years ago

Just to keep this updated: It would be nice to have a utility function that reorganizes the coefficent matrix from the stress implementation (1x5x5 for degree 4) to (2x5x5) with the first dimension denoting the cosine/sine part of the expansion. This would make the stress code and pyshtools nicely inter-operable and probably ease things a bit downstream.

GrossBJ commented 2 years ago

When you say cosine/sine components of the harmonics, do you mean real and imaginary parts? Ben J. Gross

On Wednesday, June 29, 2022 at 01:37:54 AM PDT, Johannes Müller ***@***.***> wrote:  

Just to keep this updated: It would be nice to have a utility function that reorganizes the coefficent matrix from the stress implementation (1x5x5 for degree 4) to (2x5x5) with the first dimension denoting the cosine/sine part of the expansion. This would make the stress code and pyshtools nicely inter-operable and probably ease things a bit downstream.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

jo-mueller commented 2 years ago

When you say cosine/sine components of the harmonics, do you mean real and imaginary parts?

I think so, yes. I guess it would be as easy as changing the Un_Flatten_Coef_Vec(Coef_Vec, basis_deg) in such a way so that the coefficients with m<0 would be stored in a separate matrix of the same dimensions.

I would put such a conversion in a separate function though - changing the layout of this matrix all the way throughout the code would probably bring more problems than it solves.

GrossBJ commented 2 years ago

Would this be possible by simply splitting the matrix, using numpy.triu and numpy.tril to get the upper and lower parts of the matrix?

Ben J. Gross

On Wednesday, June 29, 2022 at 10:42:48 AM PDT, Johannes Müller ***@***.***> wrote:  

When you say cosine/sine components of the harmonics, do you mean real and imaginary parts?

I think so, yes. I guess it would be as easy as changing the Un_Flatten_Coef_Vec(Coef_Vec, basis_deg) in such a way so that the coefficients with m<0 would be stored in a separate matrix of the same dimensions.

I would put such a conversion in a separate function though - changing the layout of this matrix all the way throughout the code would probably bring more problems than it solves.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

jo-mueller commented 2 years ago

Would this be possible by simply splitting the matrix, using numpy.triu and numpy.tril to get the upper and lower parts of the matrix?

This was my initial idea, too. 👍

jo-mueller commented 2 years ago

I made some conversion functions here.

Edit: I meddled around a bit and it seems to work now. The major difference between the two formats (pyshtools and stress) is that pyshtools keeps an empty column for l=0 in in the imaginary coefficients matrix and stress doesn't.

I'll add some more tests to check that both implementations actually give the same values when evaluated at the same latitude/longitude and then this could be merged.

jo-mueller commented 2 years ago

PR #94 contains some conversion functions for the coefficient matrix. The tests ensure that conversions between stress format, pyshtools format and back do not change the coefficients. Evaluating the expansion at a set of given latitude/longitudes however, still yields different results, which is weird.

Evaluating both implementations with the same coefficient set returns similar-looking pointclouds, but rotated and scaled. This implies that there may be some under-the-hood normalization/rotation going on with pyshtools.

GrossBJ commented 1 year ago

Sorry I meant to say I have a lot of availability on Friday if that works 

Ben J. Gross

El mié, 22 de jun. de 2022 a la(s) 8:37, Johannes @.***> escribió:

@GrossBJ Maybe sometimes later today (~11 pm CET)?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

jo-mueller commented 1 year ago

Sorry I meant to say I have a lot of availability on Friday if that works

Was that message supposed to go here? I do have a bit of time on my hands on friday, though.

GrossBJ commented 1 year ago

I am a bit busy today but I should have lots of availability tomorrow if that works!

Ben J. Gross

El mié, 22 de jun. de 2022 a la(s) 8:37, Johannes @.***> escribió:

@GrossBJ Maybe sometimes later today (~11 pm CET)?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>