示例#1
0
    def __init__(self, name, distribution_shape=None, components=None):

        Node.__init__(self, name)

        if components is None:

            assert distribution_shape is not None, "You have to either provied a list of components, or a " \
                                                   "distribution shape"

            components = [SpectralComponent("main", distribution_shape)]

        Source.__init__(self, components, PARTICLE_SOURCE)

        # Add a node called 'spectrum'

        spectrum_node = Node('spectrum')
        spectrum_node._add_children(list(self._components.values()))

        self._add_child(spectrum_node)

        type(self).__call__ = type(self).get_flux

        # Set the units
        # Now sets the units of the parameters for the energy domain

        current_units = get_units()

        # energy as x and particle flux as y
        x_unit = current_units.energy
        y_unit = old_div(1, current_units.energy)

        # Now set the units of the components
        for component in list(self._components.values()):
            component.shape.set_units(x_unit, y_unit)
示例#2
0
def test_call():

    # Multi-component

    po1 = Powerlaw()
    po2 = Powerlaw()

    c1 = SpectralComponent("component1", po1)
    c2 = SpectralComponent("component2", po2)

    point_source = PointSource("test_source", 125.4, -22.3, components=[c1, c2])

    assert np.all(point_source.spectrum.component1([1, 2, 3]) == po1([1, 2, 3]))
    assert np.all(point_source.spectrum.component2([1, 2, 3]) == po2([1, 2, 3]))

    one = point_source.spectrum.component1([1, 2, 3])
    two = point_source.spectrum.component2([1, 2, 3])

    assert np.all( np.abs(one + two - point_source([1,2,3])) == 0 )
示例#3
0
    def __init__(self, source_name, spatial_shape, spectral_shape=None, components=None):

        # Check that we have all the required information
        # and set the units

        current_u = get_units()

        if spatial_shape.n_dim == 2:

            # Now gather the component(s)

            # We need either a single component, or a list of components, but not both
            # (that's the ^ symbol)

            assert (spectral_shape is not None) ^ (components is not None), "You have to provide either a single " \
                                                                            "component, or a list of components " \
                                                                            "(but not both)."

            # If the user specified only one component, make a list of one element with a default name ("main")

            if spectral_shape is not None:

                components = [SpectralComponent("main", spectral_shape)]

            # Components in this case have energy as x and differential flux as y

            diff_flux_units = (current_u.energy * current_u.area * current_u.time) ** (-1)

            # Now set the units of the components
            for component in components:

                component.shape.set_units(current_u.energy, diff_flux_units)

            # Set the units of the brightness
            spatial_shape.set_units(current_u.angle, current_u.angle, current_u.angle**(-2))

        elif spatial_shape.n_dim == 3:

            # If there is no spectral component then assume that the input is a template, which will provide the
            # spectrum by itself. We just use a renormalization (a bias)

            if spectral_shape is None and components is None:

                # This is a template. Add a component which is just a renormalization

                spectral_shape = Constant()
                components = [SpectralComponent("main", spectral_shape)]

                # set the units
                diff_flux_units = (current_u.energy * current_u.area * current_u.time *
                                   current_u.angle**2) ** (-1)
                spatial_shape.set_units(current_u.angle, current_u.angle, current_u.energy, diff_flux_units)

            else:

                # the spectral shape has been given, so this is a case where the spatial template gives an
                # energy-dependent shape and the spectral components give the spectrum

                assert (spectral_shape is not None) ^ (components is not None), "You can provide either a single " \
                                                                                "component, or a list of components " \
                                                                                "(but not both)."

                if spectral_shape is not None:

                    components = [SpectralComponent("main", spectral_shape)]

                # Assign units
                diff_flux_units = (current_u.energy * current_u.area * current_u.time) ** (-1)

                # Now set the units of the components
                for component in components:
                    component.shape.set_units(current_u.energy, diff_flux_units)

                # Set the unit of the spatial template
                spatial_shape.set_units(current_u.angle, current_u.angle, current_u.energy, current_u.angle**(-2))

        else:

            raise RuntimeError("The spatial shape must have either 2 or 3 dimensions.")

        # Here we have a list of components

        Source.__init__(self, components, EXTENDED_SOURCE)

        # A source is also a Node in the tree

        Node.__init__(self, source_name)

        # Add the spatial shape as a child node, with an explicit name
        self._spatial_shape = spatial_shape
        self._add_child(self._spatial_shape)

        # Add the same node also with the name of the function
        #self._add_child(self._shape, self._shape.__name__)

        # Add a node called 'spectrum'

        spectrum_node = Node('spectrum')
        spectrum_node._add_children(self._components.values())

        self._add_child(spectrum_node)
示例#4
0
    def __init__(self,
                 source_name: str,
                 ra: Optional[float] = None,
                 dec: Optional[float] = None,
                 spectral_shape: Optional[Function1D] = None,
                 l: Optional[float] = None,
                 b: Optional[float] = None,
                 components=None,
                 sky_position: Optional[SkyDirection] = None):

        # Check that we have all the required information

        # (the '^' operator acts as XOR on booleans)

        # Check that we have one and only one specification of the position

        if not ((ra is not None and dec is not None) ^
                (l is not None and b is not None) ^
                (sky_position is not None)):

            log.error(
                "You have to provide one and only one specification for the position"
            )

            raise AssertionError()

        # Gather the position

        if not isinstance(sky_position, SkyDirection):

            if (ra is not None) and (dec is not None):

                # Check that ra and dec are actually numbers

                try:

                    ra = float(ra)
                    dec = float(dec)

                except (TypeError, ValueError):

                    log.error(
                        "RA and Dec must be numbers. If you are confused by this message, you "
                        "are likely using the constructor in the wrong way. Check the documentation."
                    )

                    raise AssertionError()

                sky_position = SkyDirection(ra=ra, dec=dec)

            else:

                sky_position = SkyDirection(l=l, b=b)

        self._sky_position: SkyDirection = sky_position

        # Now gather the component(s)

        # We need either a single component, or a list of components, but not both
        # (that's the ^ symbol)

        if not (spectral_shape is not None) ^ (components is not None):

            log.error(
                "You have to provide either a single component, or a list of components (but not both)."
            )

            raise AssertionError()

        # If the user specified only one component, make a list of one element with a default name ("main")

        if spectral_shape is not None:

            components = [SpectralComponent("main", spectral_shape)]

        Source.__init__(self, components, src_type=SourceType.POINT_SOURCE)

        # A source is also a Node in the tree

        Node.__init__(self, source_name)

        # Add the position as a child node, with an explicit name

        self._add_child(self._sky_position)

        # Add a node called 'spectrum'

        spectrum_node = Node('spectrum')
        spectrum_node._add_children(list(self._components.values()))

        self._add_child(spectrum_node)

        # Now set the units
        # Now sets the units of the parameters for the energy domain

        current_units = get_units()

        # Components in this case have energy as x and differential flux as y

        x_unit = current_units.energy
        y_unit = (current_units.energy * current_units.area *
                  current_units.time)**(-1)

        # Now set the units of the components
        for component in list(self._components.values()):

            component.shape.set_units(x_unit, y_unit)
示例#5
0
def test_constructor():

    # RA, Dec and L,B of the same point in the sky

    ra, dec = (125.6, -75.3)
    l, b = (288.44190139183564, -20.717313145391525)

    # This should throw as we are using Powerlaw instead of Powerlaw()
    with pytest.raises(TypeError):

        _ = PointSource("my_source", ra, dec, Powerlaw)

    # Init with RA, Dec

    point_source1 = PointSource('my_source',ra, dec, Powerlaw())

    assert point_source1.position.get_ra() == ra
    assert point_source1.position.get_dec() == dec

    assert abs(point_source1.position.get_l() - l) < 1e-7
    assert abs(point_source1.position.get_b() - b) < 1e-7

    assert point_source1.position.ra.value == ra
    assert point_source1.position.dec.value == dec

    # Verify that the position is fixed by default
    assert point_source1.position.ra.fix
    assert point_source1.position.dec.fix

    # Init with l,b

    point_source2 = PointSource('my_source', l=l, b=b, spectral_shape=Powerlaw())

    assert point_source2.position.get_l() == l
    assert point_source2.position.get_b() == b

    assert abs(point_source2.position.get_ra() - ra) < 1e-7
    assert abs(point_source2.position.get_dec() - dec) < 1e-7

    assert point_source2.position.l.value == l
    assert point_source2.position.b.value == b

    # Verify that the position is fixed by default
    assert point_source2.position.l.fix
    assert point_source2.position.b.fix

    # Multi-component

    po1 = Powerlaw()
    po2 = Powerlaw()

    c1 = SpectralComponent("component1", po1)
    c2 = SpectralComponent("component2", po2)

    point_source3 = PointSource("test_source", ra, dec, components=[c1, c2])

    assert np.all(point_source3.spectrum.component1([1,2,3]) == po1([1,2,3]))
    assert np.all(point_source3.spectrum.component2([1,2,3]) == po2([1,2,3]))

    with pytest.raises(AssertionError):

        # Illegal RA

        _ = PointSource("test",720.0, -15.0, components=[c1,c2])

    with pytest.raises(AssertionError):
        # Illegal Dec

        _ = PointSource("test", 120.0, 180.0, components=[c1, c2])

    with pytest.raises(AssertionError):
        # Illegal l

        _ = PointSource("test", l=-195, b=-15.0, components=[c1, c2])

    with pytest.raises(AssertionError):
        # Illegal b

        _ = PointSource("test", l=120.0, b=-180.0, components=[c1, c2])
示例#6
0
def test_call():

    # Multi-component

    po1 = Powerlaw()
    po2 = Powerlaw()

    c1 = SpectralComponent("component1", po1)
    c2 = SpectralComponent("component2", po2)

    ra, dec = (125.6, -75.3)

    def test_one(class_type, name):

        print("testing %s ..." % name)

        shape = class_type()
        source = ExtendedSource('test_source_%s' % name,
                                shape,
                                components=[c1, c2])

        if name != "SpatialTemplate_2D":
            shape.lon0 = ra * u.degree
            shape.lat0 = dec * u.degree

        else:
            make_test_template(ra, dec, "__test.fits")
            shape.load_file("__test.fits")
            shape.K = 1.0

        assert np.all(source.spectrum.component1([1, 2, 3]) == po1([1, 2, 3]))
        assert np.all(source.spectrum.component2([1, 2, 3]) == po2([1, 2, 3]))

        one = source.spectrum.component1([1, 2, 3])
        two = source.spectrum.component2([1, 2, 3])

        #check spectral components
        assert np.all(
            np.abs(one + two -
                   source.get_spatially_integrated_flux([1, 2, 3])) == 0)

        #check spectral and spatial components
        total = source([ra, ra, ra], [dec, dec, dec], [1, 2, 3])
        spectrum = one + two
        spatial = source.spatial_shape([ra, ra, ra], [dec, dec, dec])
        assert np.all(np.abs(total - spectrum * spatial) == 0)

        total = source([ra * 1.01] * 3, [dec * 1.01] * 3, [1, 2, 3])
        spectrum = one + two
        spatial = source.spatial_shape([ra * 1.01] * 3, [dec * 1.01] * 3)
        assert np.all(np.abs(total - spectrum * spatial) == 0)

    for key in _known_functions:

        if key in ["Latitude_galactic_diffuse"]:
            #not testing latitude galactic diffuse for now.
            continue

        this_function = _known_functions[key]

        if this_function._n_dim == 2 and not this_function().is_prior:

            test_one(this_function, key)

    with pytest.raises(AssertionError):
        #this will fail because the Latitude_galactic_diffuse function isn't normalized.
        test_one(_known_functions["Latitude_galactic_diffuse"],
                 "Latitude_galactic_diffuse")