44import numpy as np
55import pyfar as pf
66import spharpy as sy
7+ from abc import ABC , abstractmethod
78
89
9- class SphericalHarmonicDefinition :
10- """Class storing the definition of spherical harmonics.
10+ class _SphericalHarmonicBase ( ABC ) :
11+ """Base class related to spherical harmonics.
1112
1213 Attributes
1314 ----------
14- n_max : int, optional
15- Maximum spherical harmonic order. The default is ``0``.
1615 basis_type : str
1716 Type of spherical harmonic basis, either ``'real'`` or ``'complex'``.
1817 The default is ``'real'``.
@@ -33,7 +32,6 @@ class SphericalHarmonicDefinition:
3332
3433 def __init__ (
3534 self ,
36- n_max = 0 ,
3735 basis_type = "real" ,
3836 channel_convention = "ACN" ,
3937 normalization = "N3D" ,
@@ -43,38 +41,20 @@ def __init__(
4341 self ._channel_convention = None
4442 self ._condon_shortley = None
4543 self ._normalization = None
46- self ._n_max = 0
4744
4845 # basis_type needs to be initialized first, since the default for the
4946 # Condon-Shortley phase depends on the basis type
5047 self .basis_type = basis_type
5148 self .condon_shortley = condon_shortley
5249 # n_max needs to be initialized before channel_convention and
5350 # normalization, since both have restrictions on n_max
54- self .n_max = n_max
5551 self .channel_convention = channel_convention
5652 self .normalization = normalization
5753
5854 @property
55+ @abstractmethod
5956 def n_max (self ):
6057 """Get or set the spherical harmonic order."""
61- return self ._n_max
62-
63- @n_max .setter
64- def n_max (self , value : int ):
65- """Get or set the spherical harmonic order."""
66- if value < 0 or value % 1 != 0 :
67- raise ValueError ("n_max must be a positive integer" )
68- if self .channel_convention == "FuMa" and value > 3 :
69- raise ValueError (
70- "n_max > 3 is not allowed with 'FuMa' channel convention" )
71- if self .normalization == "maxN" and value > 3 :
72- raise ValueError (
73- "n_max > 3 is not allowed with 'maxN' normalization" )
74-
75- if self ._n_max != value :
76- self ._n_max = value
77- self ._on_property_change ()
7858
7959 @property
8060 def condon_shortley (self ):
@@ -166,6 +146,77 @@ def _on_property_change(self):
166146 pass
167147
168148
149+ class SphericalHarmonicDefinition (_SphericalHarmonicBase ):
150+ """Class storing the definition of spherical harmonics.
151+
152+ Attributes
153+ ----------
154+ n_max : int, optional
155+ Maximum spherical harmonic order. The default is ``0``.
156+ basis_type : str
157+ Type of spherical harmonic basis, either ``'real'`` or ``'complex'``.
158+ The default is ``'real'``.
159+ channel_convention : str, optional
160+ Channel ordering convention, either ``'ACN'`` or ``'FuMa'``.
161+ The default is ``'ACN'``. Note that ``'FuMa'`` is only supported up to
162+ 3rd order.
163+ normalization : str, optional
164+ Normalization convention, either ``'N3D'``, ``'NM'``, ``'maxN'``,
165+ ``'SN3D'``, or ``'SNM'``. The default is ``'N3D'``. Note that
166+ ``'maxN'`` is only supported up to 3rd order.
167+ condon_shortley : bool, str, optional
168+ Condon-Shortley phase term. If ``True``, Condon-Shortley is included,
169+ if ``False`` it is not included. The default is ``'auto'``, which
170+ corresponds to ``True`` for type ``complex`` and ``False`` for type
171+ ``real``.
172+ """
173+
174+ def __init__ (
175+ self ,
176+ n_max = 0 ,
177+ basis_type = "real" ,
178+ channel_convention = "ACN" ,
179+ normalization = "N3D" ,
180+ condon_shortley = "auto" ,
181+ ):
182+ self ._basis_type = None
183+ self ._channel_convention = None
184+ self ._condon_shortley = None
185+ self ._normalization = None
186+ self ._n_max = 0
187+
188+ # basis_type needs to be initialized first, since the default for the
189+ # Condon-Shortley phase depends on the basis type
190+ self .basis_type = basis_type
191+ self .condon_shortley = condon_shortley
192+ # n_max needs to be initialized before channel_convention and
193+ # normalization, since both have restrictions on n_max
194+ self .n_max = n_max
195+ self .channel_convention = channel_convention
196+ self .normalization = normalization
197+
198+ @property
199+ def n_max (self ):
200+ """Get or set the spherical harmonic order."""
201+ return self ._n_max
202+
203+ @n_max .setter
204+ def n_max (self , value : int ):
205+ """Get or set the spherical harmonic order."""
206+ if value < 0 or value % 1 != 0 :
207+ raise ValueError ("n_max must be a positive integer" )
208+ if self .channel_convention == "FuMa" and value > 3 :
209+ raise ValueError (
210+ "n_max > 3 is not allowed with 'FuMa' channel convention" )
211+ if self .normalization == "maxN" and value > 3 :
212+ raise ValueError (
213+ "n_max > 3 is not allowed with 'maxN' normalization" )
214+
215+ if self ._n_max != value :
216+ self ._n_max = value
217+ self ._on_property_change ()
218+
219+
169220class SphericalHarmonics (SphericalHarmonicDefinition ):
170221 r"""
171222 Compute spherical harmonic basis matrices, their inverses, and gradients.
0 commit comments