diff --git a/transformations/gllmtransformation.py b/transformations/gllmtransformation.py index 283e869e8a32df416e8e20cea6cdff882a6436a2..8ec541fc6ce6a5a2ab16642715c2948be762a699 100644 --- a/transformations/gllmtransformation.py +++ b/transformations/gllmtransformation.py @@ -9,7 +9,7 @@ gl = gdi.get('libsharp_wrapper_gl') class GLLMTransformation(Transformation): - def __init__(self, domain, codomain, module=None): + def __init__(self, domain, codomain=None, module=None): if 'libsharp_wrapper_gl' not in gdi: raise ImportError("The module libsharp is needed but not available") @@ -19,6 +19,36 @@ class GLLMTransformation(Transformation): else: raise ValueError("ERROR: Incompatible codomain!") + @staticmethod + def get_codomain(domain): + """ + Generates a compatible codomain to which transformations are + reasonable, i.e.\ an instance of the :py:class:`lm_space` class. + + Parameters + ---------- + domain: GLSpace + Space for which a codomain is to be generated + + Returns + ------- + codomain : LMSpace + A compatible codomain. + """ + if domain is None: + raise ValueError('ERROR: cannot generate codomain for None') + + if not isinstance(domain, GLSpace): + raise TypeError('ERROR: domain needs to be a GLSpace') + + nlat = domain.paradict['nlat'] + lmax = nlat - 1 + mmax = nlat - 1 + if domain.dtype == np.dtype('float32'): + return LMSpace(lmax=lmax, mmax=mmax, dtype=np.complex64) + else: + return LMSpace(lmax=lmax, mmax=mmax, dtype=np.complex128) + @staticmethod def check_codomain(domain, codomain): if not isinstance(domain, GLSpace): diff --git a/transformations/hplmtransformation.py b/transformations/hplmtransformation.py index de2c445bc082ca756bd78797b8feaaafb396b413..557f1b7bb4f424931fab57d6f54fd0b7c7e9465d 100644 --- a/transformations/hplmtransformation.py +++ b/transformations/hplmtransformation.py @@ -9,7 +9,7 @@ hp = gdi.get('healpy') class HPLMTransformation(Transformation): - def __init__(self, domain, codomain, module=None): + def __init__(self, domain, codomain=None, module=None): if 'healpy' not in gdi: raise ImportError("The module healpy is needed but not available") @@ -19,6 +19,32 @@ class HPLMTransformation(Transformation): else: raise ValueError("ERROR: Incompatible codomain!") + @staticmethod + def get_codomain(domain): + """ + Generates a compatible codomain to which transformations are + reasonable, i.e.\ an instance of the :py:class:`lm_space` class. + + Parameters + ---------- + domain: HPSpace + Space for which a codomain is to be generated + + Returns + ------- + codomain : LMSpace + A compatible codomain. + """ + if domain is None: + raise ValueError('ERROR: cannot generate codomain for None') + + if not isinstance(domain, HPSpace): + raise TypeError('ERROR: domain needs to be a HPSpace') + + lmax = 3 * domain.paradict['nside'] - 1 + mmax = lmax + return LMSpace(lmax=lmax, mmax=mmax, dtype=np.dtype('complex128')) + @staticmethod def check_codomain(domain, codomain): if not isinstance(domain, HPSpace): diff --git a/transformations/lmgltransformation.py b/transformations/lmgltransformation.py index 7d9e6a19f649afb4adf27d9f43c5f045b0c816b5..0bf90c60bea135c3bcc92943f1ade7d0be556b81 100644 --- a/transformations/lmgltransformation.py +++ b/transformations/lmgltransformation.py @@ -9,7 +9,7 @@ gl = gdi.get('libsharp_wrapper_gl') class LMGLTransformation(Transformation): - def __init__(self, domain, codomain, module=None): + def __init__(self, domain, codomain=None, module=None): if gdi.get('libsharp_wrapper_gl') is None: raise ImportError( "The module libsharp is needed but not available.") @@ -20,6 +20,46 @@ class LMGLTransformation(Transformation): else: raise ValueError("ERROR: Incompatible codomain!") + @staticmethod + def get_codomain(domain): + """ + Generates a compatible codomain to which transformations are + reasonable, i.e.\ a pixelization of the two-sphere. + + Parameters + ---------- + domain : LMSpace + Space for which a codomain is to be generated + + Returns + ------- + codomain : HPSpace + A compatible codomain. + + References + ---------- + .. [#] M. Reinecke and D. Sverre Seljebotn, 2013, + "Libsharp - spherical + harmonic transforms revisited"; + `arXiv:1303.4945 <http://www.arxiv.org/abs/1303.4945>`_ + """ + if domain is None: + raise ValueError('ERROR: cannot generate codomain for None') + + if not isinstance(domain, LMSpace): + raise TypeError('ERROR: domain needs to be a LMSpace') + + if domain.dtype == np.dtype('complex64'): + new_dtype = np.float32 + elif domain.dtype == np.dtype('complex128'): + new_dtype = np.float64 + else: + raise ValueError('ERROR: unsupported domain dtype') + + nlat = domain.paradict['lmax'] + 1 + nlon = domain.paradict['lmax'] * 2 + 1 + return GLSpace(nlat=nlat, nlon=nlon, dtype=new_dtype) + @staticmethod def check_codomain(domain, codomain): if not isinstance(domain, LMSpace): diff --git a/transformations/lmhptransformation.py b/transformations/lmhptransformation.py index 77643e296f39bf4e7fe4de2256ebf26c567f8673..c9f00bab5b874ce18fdc7be356dc3ccc1f506607 100644 --- a/transformations/lmhptransformation.py +++ b/transformations/lmhptransformation.py @@ -9,7 +9,7 @@ hp = gdi.get('healpy') class LMHPTransformation(Transformation): - def __init__(self, domain, codomain, module=None): + def __init__(self, domain, codomain=None, module=None): if gdi.get('healpy') is None: raise ImportError( "The module libsharp is needed but not available.") @@ -20,6 +20,37 @@ class LMHPTransformation(Transformation): else: raise ValueError("ERROR: Incompatible codomain!") + @staticmethod + def get_codomain(domain): + """ + Generates a compatible codomain to which transformations are + reasonable, i.e.\ a pixelization of the two-sphere. + + Parameters + ---------- + domain : LMSpace + Space for which a codomain is to be generated + + Returns + ------- + codomain : HPSpace + A compatible codomain. + + References + ---------- + .. [#] K.M. Gorski et al., 2005, "HEALPix: A Framework for + High-Resolution Discretization and Fast Analysis of Data + Distributed on the Sphere", *ApJ* 622..759G. + """ + if domain is None: + raise ValueError('ERROR: cannot generate codomain for None') + + if not isinstance(domain, LMSpace): + raise TypeError('ERROR: domain needs to be a LMSpace') + + nside = (domain.paradict['lmax'] + 1) // 3 + return HPSpace(nside=nside) + @staticmethod def check_codomain(domain, codomain): if not isinstance(domain, LMSpace): diff --git a/transformations/rgrgtransformation.py b/transformations/rgrgtransformation.py index 237d6799d8180b35a6eeec1c5e893e7c2024a8a7..89df9990c59a9ac9887756626953886acd0c86c9 100644 --- a/transformations/rgrgtransformation.py +++ b/transformations/rgrgtransformation.py @@ -6,7 +6,7 @@ from nifty import RGSpace, nifty_configuration class RGRGTransformation(Transformation): - def __init__(self, domain, codomain, module=None): + def __init__(self, domain, codomain=None, module=None): if self.check_codomain(domain, codomain): if module is None: if nifty_configuration['fft_module'] == 'pyfftw': @@ -25,13 +25,65 @@ class RGRGTransformation(Transformation): self._transform = FFTW(domain, codomain) elif module == 'gfft': self._transform = \ - GFFT(domain, codomain, gdi.get('gfft')) + GFFT(domain, codomain, gdi.get('gfft')) elif module == 'gfft_dummy': self._transform = \ GFFT(domain, codomain, gdi.get('gfft_dummy')) else: raise ValueError("ERROR: incompatible codomain!") + @staticmethod + def get_codomain(domain, cozerocenter=None, **kwargs): + """ + Generates a compatible codomain to which transformations are + reasonable, i.e.\ either a shifted grid or a Fourier conjugate + grid. + + Parameters + ---------- + domain: RGSpace + Space for which a codomain is to be generated + cozerocenter : {bool, numpy.ndarray}, *optional* + Whether or not the grid is zerocentered for each axis or not + (default: None). + + Returns + ------- + codomain : nifty.rg_space + A compatible codomain. + """ + if domain is None: + raise ValueError('ERROR: cannot generate codomain for None') + + if not isinstance(domain, RGSpace): + raise TypeError('ERROR: domain needs to be a RGSpace') + + # parse the cozerocenter input + if cozerocenter is None: + cozerocenter = domain.paradict['zerocenter'] + # if the input is something scalar, cast it to a boolean + elif np.isscalar(cozerocenter): + cozerocenter = bool(cozerocenter) + else: + # cast it to a numpy array + if np.size(cozerocenter) == 1: + cozerocenter = np.asscalar(cozerocenter) + elif np.size(cozerocenter) != len(domain.shape): + raise ValueError('ERROR: size mismatch (' + + str(np.size(cozerocenter)) + ' <> ' + + str(domain.shape) + ')') + + # calculate the initialization parameters + distances = 1 / (np.array(domain.paradict['shape']) * + np.array(domain.distances)) + complexity = {0: 1, 1: 0, 2: 2}[domain.paradict['complexity']] + + new_space = RGSpace(domain.paradict['shape'], zerocenter=cozerocenter, + complexity=complexity, distances=distances, + harmonic=bool(not domain.harmonic)) + + return new_space + @staticmethod def check_codomain(domain, codomain): if not isinstance(domain, RGSpace): diff --git a/transformations/transformation.py b/transformations/transformation.py index 3232248f60e831a911a129114da5928ffa4eaadb..228715be5572ed94694ba40b6ca77b58961c80dd 100644 --- a/transformations/transformation.py +++ b/transformations/transformation.py @@ -4,7 +4,7 @@ class Transformation(object): method for all transforms. """ - def __init__(self, domain, codomain, module=None): + def __init__(self, domain, codomain=None, module=None): pass def transform(self, val, axes=None, **kwargs):