Skip to content

Introduce property sh_caxis#327

Draft
tluebeck wants to merge 11 commits into
developfrom
feature/add_sh_axis_property
Draft

Introduce property sh_caxis#327
tluebeck wants to merge 11 commits into
developfrom
feature/add_sh_axis_property

Conversation

@tluebeck

@tluebeck tluebeck commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Which issue(s) are closed by this pull request?

Closes #326

Changes proposed in this pull request:

  • Introduce property sh_caxis which defines the axis along which SHSignals store SH coefficients
  • Adapt rotation accordingly

@tluebeck tluebeck self-assigned this Apr 25, 2026
@tluebeck tluebeck added the enhancement New feature or request label Apr 25, 2026
@tluebeck tluebeck requested review from f-brinkmann and mberz April 26, 2026 17:17

@f-brinkmann f-brinkmann left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@tluebeck I think we have to differentiate between caxis and axis. The SH audio objects should deal with the sh_caxis and the default should be -1. Functions that work on the SH data (numpy array) directly, such as _assert_valud_number_of_sh_channels must get the sh_axis = sh_caxis - 1. Do you agree or did I miss something?

At some point, we should add a check if sh_caxis<0 and np.abs(sh_caxis)<data.cdim

@tluebeck

Copy link
Copy Markdown
Contributor Author

I agree, but I'm not sure if we want to pass "sh_axis" to SHAudio object's inits and internally recalculate to sh_caxis or if we should let the user pass "sh_caxis" directly.

@tluebeck

Copy link
Copy Markdown
Contributor Author

I decided to pass sh_caxis directly.

@tluebeck tluebeck requested a review from f-brinkmann April 30, 2026 13:50

@f-brinkmann f-brinkmann left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for changing. I think I found one thing that needs further adjustment and had only comments on the docs apart from that.

Comment thread spharpy/classes/audio.py
Specifies which axis of data holds the spherical harmonic coefficients.
Negative indexing, i.e., interpreted relative to the end of the array.
default is second last axis (-2).
Specifies which channel axis of data holds the spherical harmonic

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could additionally link

https://pyfar-gallery.readthedocs.io/en/latest/gallery/interactive/pyfar_audio_objects.html#Signal-cshape,-length,-and-caxis

to geive background on the caxis conept, as we do in the pyfar documentaiton.

Comment thread spharpy/classes/audio.py Outdated
Negative indexing, i.e., interpreted relative to the end of the array.
default is second last axis (-2).
Specifies which channel axis of data holds the spherical harmonic
coefficients. Negative indexing, i.e., interpreted relative to the end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could be more clear, that this is required. maybe:

'Must be an integer smaller than or equal to -1. The default -1 referrs to the last channel axis and a value of -2 would refer to the second last channel axis.'

Comment thread spharpy/classes/audio.py Outdated
Comment on lines +301 to +303
if abs(sh_caxis) >= data.ndim:
raise ValueError(f"sh_caxis ({sh_caxis}) exceeds the number of "
f"dimensions of data ({data.ndim})")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we move the sh_caxis checks to the end of the initializationWe could then useabs(sh_caxis) >= self.cdimotherwise I think we also have to testabs(sh_caxis) >= data.ndim + 1`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We should check that before data = _atleast_3d_first_dimension(data) and _assert_valid_number_of_sh_channels(data.shape, sh_caxis-1), otherwise it crashes.

Comment thread spharpy/classes/audio.py Outdated
Comment on lines 594 to 597
if abs(sh_caxis) >= data.ndim:
raise ValueError(f"sh_caxis ({sh_caxis}) exceeds the number of "
f"dimensions of data ({data.ndim})")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See comment above (cdim or ndim + 1)

@tluebeck tluebeck requested a review from ahms5 May 5, 2026 10:16

@mberz mberz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I've added some comments below.

Additionally, I have another comment:
In one of the last meetings, we discussed support for multiple dimensions containing spherical harmonic coefficients. In this implementation this is not possible, correct?
Or it simply would not be covered, but users would need to add the data in an additional dimension which is unaffected by all checks.
Would you think it's feasible to implement this as well?

import numpy as np
import numpy.testing as npt
import pytest
import re

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

probably obsolete?

Comment thread spharpy/classes/audio.py Outdated
Comment on lines +224 to +226
def sh_caxis(self):
"""Get the spherical harmonic axis"""
return self._sh_caxis

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
def sh_caxis(self):
"""Get the spherical harmonic axis"""
return self._sh_caxis
def caxis_spherical_harmonics(self):
"""Get the spherical harmonic axis"""
return self._sh_caxis

I've thought about it a bit and came to the conclusion that I'd prefer a naming convention where additional info is appended instead of prepended. In my opinion that makes things a bit clearer. (also related concepts are closed together in terms of auto-complete, documentation, etc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sounds reasonable to me.

Comment thread spharpy/classes/audio.py Outdated
Comment on lines +307 to +308
if sh_caxis > 0:
raise ValueError("sh_caxis has to be a negative integer.")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think that's a necessary condition. It's just a good default to start from the end.

change property name
adapt tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants