@on_the_fly_hdf5
    def get_sed(self, stokes='I', group=0, technique='peeled',
                distance=None, component='total', inclination='all',
                aperture='all', uncertainties=False, units=None,
                source_id=None, dust_id=None, n_scat=None):
        '''
        Retrieve SEDs for a specific image group and Stokes component.

        Parameters
        ----------

        stokes : str, optional
            The Stokes component to return. This can be:

                * 'I': Total intensity [default]
                * 'Q': Q Stokes parameter (linear polarization)
                * 'U': U Stokes parameter (linear polarization)
                * 'V': V Stokes parameter (circular polarization)
                * 'linpol':  Total linear polarization fraction
                * 'circpol': Total circular polariation fraction

            Note that if the SED was set up with ``set_stokes(False)``, then
            only the ``I`` component is available.

        technique : str, optional
            Whether to retrieve SED(s) computed with photon peeling-off
            ('peeled') or binning ('binned'). Default is 'peeled'.

        group : int, optional
            The peeloff group (zero-based). If multiple peeloff image groups
            were requested, this can be used to select between them. The
            default is to return the first group. This option is only used if
            technique='peeled'.

        distance : float, optional
            The distance to the observer, in cm.

        component : str, optional
            The component to return based on origin and last interaction.
            This can be:

                * 'total': Total flux

                * 'source_emit': The photons were last emitted from a source
                  and did not undergo any subsequent interactions.

                * 'dust_emit': The photons were last emitted dust and did not
                  undergo any subsequent interactions

                * 'source_scat': The photons were last emitted from a source
                  and were subsequently scattered

                * 'dust_scat': The photons were last emitted from dust and
                  were subsequently scattered

                * 'source': The photons that were last emitted from a source

                * 'dust': The photons that were last emitted from dust

        aperture : int, optional
            The index of the aperture to plot (zero-based). Use 'all' to
            return all apertures, and -1 to show the largest aperture.

        inclination : int, optional
            The index of the viewing angle to plot (zero-based). Use 'all'
            to return all viewing angles.

        uncertainties : bool, optional
            Whether to compute and return uncertainties

        units : str, optional
            The output units for the SED(s). Valid options if a distance is
            specified are:

                * ``'ergs/cm^2/s'``
                * ``'ergs/cm^2/s/Hz'``
                * ``'Jy'``
                * ``'mJy'``

            The default is ``'ergs/cm^2/s'``. If a distance is not specified,
            then this option is ignored, and the output units are ergs/s.

        source_id, dust_id : int or str, optional
            If the output file was made with track_origin='detailed', a
            specific source and dust component can be specified (where 0 is
            the first source or dust type). If 'all' is specified, then all
            components are returned individually. If neither of these are
            not specified, then the total component requested for all
            sources or dust types is returned. For sources, it is also possible
            to specify a source name as a string, if the source name was set
            during the set-up.

        n_scat : int, optional
            If the output file was made with track_origin='scatterings', the
            number of scatterings can be specified here. If specified, the
            image is constructed only from photons that have scattered
            ``n_scat`` times since being last emitted.

        Returns
        -------

        wav : numpy.ndarray
            The wavelengths for which the SEDs are defined, in microns

        flux or degree of polarization : numpy.ndarray
            The flux or degree of polarization. This is a data cube which has
            at most three dimensions (n_inclinations, n_apertures,
            n_wavelengths). If an aperture or inclination is specified, this
            reduces the number of dimensions in the flux cube. If `stokes` is
            one of 'I', 'Q', 'U', or 'V', the flux is either returned in
            ergs/s (if distance is not specified) or in the units specified by
            units= (if distance is specified). If `stokes` is one of 'linpol'
            or 'circpol', the degree of polarization is returned as a fraction
            in the range 0 to 1.

        uncertainty : numpy.ndarray
            The uncertainties on the flux or degree of polarization. This
            has the same dimensions as the flux or degree of polarization
            array. This is only returned if uncertainties were requested.
        '''

        # Check argument types
        if not isinstance(stokes, basestring):
            raise ValueError("stokes argument should be a string")

        # Check for inconsistent parameters
        if distance is not None and stokes in ['linpol', 'circpol']:
            raise Exception("Cannot scale linear or circular polarization degree by distance")

        if technique == 'peeled':
            n_groups = len(self.file['Peeled'])
            if (group < 0 and -group <= n_groups) or (group >= 0 and group < n_groups):
                g = self.file['Peeled/group_%05i' % (group + 1)]
            else:
                raise ValueError('File only contains %i image/SED group(s)' % n_groups)
        else:
            g = self.file['Binned']

        if not 'seds' in g:
            raise Exception("Group %i does not contain any SEDs" % group)

        # Check that uncertainties are present if requested
        if uncertainties and not 'seds_unc' in g:
            raise Exception("Uncertainties requested but not present in file")

        if 'track_origin' in g['seds'].attrs and component != 'total':
            io = self._get_origin_slice(g['seds'], component=component,
                                       source_id=source_id, dust_id=dust_id, n_scat=n_scat)

        # Set up wavelength space
        if 'use_filters' in g.attrs and g.attrs['use_filters'].decode('utf-8').lower() == 'yes':
            nu = g['filt_nu0'].value
            wav = c / nu * 1.e4
        elif 'numin' in g['seds'].attrs:
            numin = g['seds'].attrs['numin']
            numax = g['seds'].attrs['numax']
            wavmin, wavmax = c / numax * 1.e4, c / numin * 1.e4
            wav = np.logspace(np.log10(wavmax), np.log10(wavmin), g['seds'].shape[-1] * 2 + 1)[1::2]
            nu = c / wav * 1.e4
        else:
            nu = g['frequencies']['nu']
            wav = c / nu * 1.e4

        flux = g['seds'].value
        if uncertainties:
            unc = g['seds_unc'].value

        try:
            inside_observer = g.attrs['inside_observer'].decode('utf-8').lower() == 'yes'
        except:
            inside_observer = False

        if inside_observer and distance is not None:
            raise ValueError("Cannot specify distance for inside observers")

        # Set default units
        if units is None:
            if distance is None and not inside_observer:
                units = 'ergs/s'
            else:
                units = 'ergs/cm^2/s'

        # Optionally scale by distance
        if distance is not None or inside_observer:

            # Convert to the correct units
            if units == 'ergs/cm^2/s':
                scale = 1.
            elif units == 'ergs/cm^2/s/Hz':
                scale = 1. / nu
            elif units == 'Jy':
                scale = 1.e23 / nu
            elif units == 'mJy':
                scale = 1.e26 / nu
            else:
                raise ValueError(units % "Unknown units: %s")

            # Scale by distance
            if distance:
                scale *= 1. / (4. * pi * distance ** 2)

        else:

            if units != 'ergs/s':
                raise ValueError("Since distance= is not specified, units should be set to ergs/s")

            # Units here are not technically ergs/cm^2/s but ergs/s
            scale = 1.

        # If in 32-bit mode, need to convert to 64-bit because of scaling/polarization to be safe
        if flux.dtype == np.float32:
            flux = flux.astype(np.float64)
        if uncertainties and unc.dtype == np.float32:
            unc = unc.astype(np.float64)

        # If a stokes component is requested, scale the images. Frequency is
        # the last dimension, so this compact notation can be used.

        if stokes in STOKESD:
            flux *= scale
            if uncertainties:
                unc *= scale

        # We now slice the SED array to end up with what the user requested.
        # Note that we slice from the last to the first dimension to ensure that
        # we always know what the slices are. In this section, we make use of
        # the fact that when writing array[i] with a multi-dimensional array,
        # the index i applies only to the first dimension. So flux[1] really
        # means flux[1, :, :, :, :].

        if aperture == 'all':
            pass
        else:
            if not isinstance(aperture, int):
                raise TypeError('aperture should be an integer (it should'
                                ' be the index of the aperture, not the '
                                'value itself)')
            flux = flux[:, :, :, aperture]
            if uncertainties:
                unc = unc[:, :, :, aperture]

        if inclination == 'all':
            pass
        else:
            if not isinstance(inclination, int):
                raise TypeError('inclination should be an integer (it should'
                                ' be the index of the inclination, not the '
                                'value itself)')
            flux = flux[:, :, inclination]
            if uncertainties:
                unc = unc[:, :, inclination]

        # Select correct origin component

        if component == 'total':
            flux = np.sum(flux, axis=1)
            if uncertainties:
                unc = np.sqrt(np.sum(unc ** 2, axis=1))
        elif component in ['source_emit', 'dust_emit', 'source_scat', 'dust_scat', 'dust', 'source']:
            if type(io) is tuple:
                start, end = io
                flux = flux[:, start:end]
                if uncertainties:
                    unc = unc[:, start:end]
                if (component.startswith('source') and source_id is None) or \
                   (component.startswith('dust') and dust_id is None):
                    flux = np.sum(flux, axis=1)
                    if uncertainties:
                        unc = np.sqrt(np.sum(unc ** 2, axis=1))
            else:
                flux = flux[:, io]
                if uncertainties:
                    unc = unc[:, io]
        else:
            raise Exception("Unknown component: %s" % component)

        # Select correct Stokes component

        if flux.shape[0] == 1 and stokes != 'I':
            raise ValueError("Only the Stokes I value was stored for this SED")

        if stokes in STOKESD:
            flux = flux[STOKESD[stokes]]
            if uncertainties:
                unc = unc[STOKESD[stokes]]
        elif stokes == 'linpol':
            if uncertainties:
                flux, unc = mc_linear_polarization(flux[0], unc[0], flux[1], unc[1], flux[2], unc[2])
            else:
                flux = np.sqrt((flux[1] ** 2 + flux[2] ** 2) / flux[0] ** 2)
                flux[np.isnan(flux)] = 0.
        elif stokes == 'circpol':
            if uncertainties:
                flux, unc = mc_circular_polarization(flux[0], unc[0], flux[3], unc[3])
            else:
                flux = np.abs(flux[3] / flux[0])
                flux[np.isnan(flux)] = 0.
        else:
            raise ValueError("Unknown Stokes parameter: %s" % stokes)

        from .sed import SED
        sed = SED(nu=nu, val=flux, unc=unc if uncertainties else None, units=units)

        # Add aperture information
        sed.ap_min = g['seds'].attrs['apmin']
        sed.ap_max = g['seds'].attrs['apmax']

        # Add depth information
        try:
            sed.d_min = g.attrs['d_min']
            sed.d_max = g.attrs['d_max']
        except KeyError:  # Older versions of Hyperion
            sed.d_min = None
            sed.d_max = None

        # Add distance
        sed.distance = distance

        # Save whether the SED was from an inside observer
        sed.inside_observer = inside_observer

        return sed
dataset/ETHPy150Open hyperion-rt/hyperion/hyperion/model/model_output.py/ModelOutput.get_sed/swapped operands of `%`