Exemplo n.º 1
0
    def __init__(self, name, shape, polarization=None):

        # Check that we can call the shape (i.e., it is a function)

        assert hasattr(shape, '__call__'), "The shape must be callable (i.e., behave like a function)"

        self._spectral_shape = shape

        # Store the polarization

        if polarization is None:

            self._polarization = Polarization()

        else:

            self._polarization = polarization

        # Add shape and polarization as children

        Node.__init__(self, name)

        try:

            self._add_children([self._spectral_shape, self._polarization])

        except TypeError:

            raise TypeError("Couldn't instance the spectral component. Please verify that you are using an "
                            "*instance* of a function, and not a class. For example, you need to use "
                            "'%s()', and not '%s'." % (shape.__name__, shape.__name__))
Exemplo n.º 2
0
    def __init__(self, polarization_type='linear'):

        assert polarization_type in ['linear', 'stokes'
                                     ], 'polarization must be linear or stokes'

        self._polarization_type = polarization_type

        Node.__init__(self, 'polarization')
Exemplo n.º 3
0
    def __init__(self, ra=None, dec=None, l=None, b=None, equinox='J2000'):
        """

        :param ra: Right Ascension in degrees
        :param dec: Declination in degrees
        :param l: Galactic latitude in degrees
        :param b: Galactic longitude in degrees
        :param equinox: string
        :return:
        """

        self._equinox = equinox

        # Create the node

        Node.__init__(self, 'position')

        # Check that we have the right pairs of coordinates

        if ra is not None and dec is not None:

            # This goes against duck typing, but it is needed to provide a means of initiating this class
            # with either Parameter instances or just floats

            # Try to transform it to float, if it works than we transform it to a parameter

            ra = self._get_parameter_from_input(ra, 0, 360, 'ra',
                                                'Right Ascension')

            dec = self._get_parameter_from_input(dec, -90, 90, 'dec',
                                                 'Declination')

            self._coord_type = 'equatorial'

            self._add_child(ra)
            self._add_child(dec)

        elif l is not None and b is not None:

            # This goes against duck typing, but it is needed to provide a means of initiating this class
            # with either Parameter instances or just floats

            # Try to transform it to float, if it works than we transform it to a parameter

            l = self._get_parameter_from_input(l, 0, 360, 'l',
                                               'Galactic longitude')

            b = self._get_parameter_from_input(b, -90, 90, 'b',
                                               'Galactic latitude')

            self._coord_type = 'galactic'
            self._add_child(l)
            self._add_child(b)

        else:

            raise WrongCoordinatePair(
                "You have to specify either (ra, dec) or (l, b).")
Exemplo n.º 4
0
def test_constructor():

    n = Node(name='node1')

    assert n.name == 'node1'

    with pytest.raises(TypeError):

        n2 = Node()

    clean()
Exemplo n.º 5
0
def test_get_child_from_path():
    # Make a small tree

    node1 = Node('node1')
    node2 = Node('node2')
    node3 = Node('node3')

    node1._add_child(node2)
    node2._add_child(node3)

    assert node1._get_child_from_path("node2.node3") == node3

    clean()
Exemplo n.º 6
0
def test_add_child():

    t = _SimpleInheritance('test_add_child')

    with pytest.raises(TypeError):
        t._add_child("clara")

    clara = Node("clara")

    clara_ref_count = node_ctype._get_reference_counts(clara)

    t._add_child(clara)

    # We expect 2 more references: one for the map, one for the vector

    assert node_ctype._get_reference_counts(clara) == clara_ref_count + 1

    assert t.clara == clara

    with pytest.raises(AttributeError):
        t.clara = 'argh'

    assert t.clara == clara

    clean()
Exemplo n.º 7
0
def test_get_path():
    # Make a small tree

    node1 = Node('node1')
    node2 = Node('node2')
    node3 = Node('node3')

    node1._add_child(node2)
    node2._add_child(node3)

    print node3.path

    assert node3.path == "node1.node2.node3"

    clean()
Exemplo n.º 8
0
def test_pickle():

    print("\n\n\n\n")

    import pickle

    root = Node("root")
    node = Node("node")

    root._add_child(node)

    d = pickle.dumps(root)

    root2 = pickle.loads(d)

    assert root2.node.path == 'root.node'
    assert root2.node.name == 'node'

    # Now test pickling a subclass of Node

    root = _SimpleInheritance("root")

    root._placeholder = 5.3

    node = _SimpleInheritance("node")

    root._add_child(node)

    d = pickle.dumps(root)

    root2 = pickle.loads(d)

    assert root2.node.path == 'root.node'
    assert root2.node.name == 'node'

    print root.placeholder

    assert root2.placeholder == root.placeholder

    rootc = _ComplexInheritance("root", -1.0, 1.0)
    nodec = _ComplexInheritance("node", -5.0, 5.0)

    rootc._add_child(nodec)

    d = pickle.dumps(rootc)

    root2c = pickle.loads(d)

    print root2c.min_value

    clean()
Exemplo n.º 9
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)
Exemplo n.º 10
0
def test_get_child():
    t = _SimpleInheritance("test")

    n = Node("node")

    t._add_child(n)

    assert t._get_child("node") == n

    with pytest.raises(AttributeError):
        t._get_child("not existing")

    clean()
Exemplo n.º 11
0
def test_remove_child():
    t = _SimpleInheritance("test")

    n = Node("node")

    for i in range(1000):

        t._add_child(n)

        assert t._get_child("node") == n

        t._remove_child("node")

    with pytest.raises(AttributeError):
        print t.node

    with pytest.raises(AttributeError):
        t._get_child("node")

    clean()
Exemplo n.º 12
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)
Exemplo n.º 13
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)
Exemplo n.º 14
0
def test_add_children():
    t = _SimpleInheritance("children")

    t._add_children([Node("node1"), Node("node2")])

    clean()
Exemplo n.º 15
0
    def __init__(self,
                 name,
                 value,
                 min_value=None,
                 max_value=None,
                 desc=None,
                 unit=u.dimensionless_unscaled,
                 transformation=None):

        # Make this a node

        Node.__init__(self, name)

        # Make a static name which will never change (not even after a _change_name call)
        self._static_name = str(name)

        # Callbacks are executed any time the value for the parameter changes (i.e., its value changes)

        # We start from a empty list of callbacks.
        self._callbacks = []

        # Assign to members

        # Store the units as an astropy.units.Unit instance

        self._unit = u.Unit(unit)

        # A ParameterBase instance cannot have auxiliary variables
        self._aux_variable = {}

        # Set min and max to None first so that the .value setter will work,
        # we will override them later if needed
        self._external_min_value = None
        self._external_max_value = None

        # Store the transformation. This allows to disentangle the value of the parameter which the user interact
        # width with the value of the parameter the fitting engine (or the Bayesian sampler) interact with
        self._transformation = transformation

        # Let's store the init value

        # If the value is a Quantity, deal with that

        if isinstance(value, u.Quantity):

            # If the user did not specify an ad-hoc unit, use the unit
            # of the Quantity

            if self._unit == u.dimensionless_unscaled:

                self._unit = value.unit

            # Convert the value to the provided unit (if necessary)

            self.value = value.to(self._unit).value

        else:

            self.value = value

        # Set minimum if provided, otherwise use default
        # (use the property so the checks that are there are performed also on construction)

        self.min_value = min_value

        # Set maximum if provided, otherwise use default

        # this will be overwritten immediately in the next line
        self.max_value = max_value

        # Store description

        self._desc = desc

        # Make the description the documentation as well

        self.__doc__ = desc

        # Now perform a very lazy check that we can perform math operations on value, minimum and maximum
        # (i.e., they are numbers)

        if not _behaves_like_a_number(self.value):

            raise TypeError("The provided initial value is not a number")
Exemplo n.º 16
0
def test_memory_leaks_destructors():

    print("\n\n\n\n\n")

    for i in range(1000):

        print("\n\nRound %i" % (i + 1))

        # Test destructors
        root = Node("root")

        node1 = Node("node1")
        node2 = Node("node2")
        node3 = Node("node3")

        refc_before_link_root = node_ctype._get_reference_counts(root)

        refc_before_link1 = node_ctype._get_reference_counts(node1)
        refc_before_link2 = node_ctype._get_reference_counts(node2)
        refc_before_link3 = node_ctype._get_reference_counts(node3)

        # root._add_children([node1, node2, node3])  # node1 +1, node2 + 1, node3 + 1, root +3

        root._add_child(node1)
        root._add_child(node2)
        root._add_child(node3)

        assert node_ctype._get_reference_counts(
            root) == refc_before_link_root + 3
        assert node_ctype._get_reference_counts(node1) == refc_before_link1 + 1
        assert node_ctype._get_reference_counts(node2) == refc_before_link2 + 1
        assert node_ctype._get_reference_counts(node3) == refc_before_link3 + 1

        #
        # Let's destroy the tree
        root._remove_child("node1")

        root._remove_child("node2")

        root._remove_child("node3")
Exemplo n.º 17
0
def test_memory_leaks_getters():

    # Now test the getters

    root = Node("root")

    node1 = Node("node1")
    node2 = Node("node2")
    node3 = Node("node3")

    refc_before_link_root = node_ctype._get_reference_counts(root)
    refc_before_link1 = node_ctype._get_reference_counts(node1)
    refc_before_link2 = node_ctype._get_reference_counts(node2)
    refc_before_link3 = node_ctype._get_reference_counts(node3)

    None_counts_before = node_ctype._get_reference_counts(None)

    # Add 3 nodes to root
    root._add_children([node1, node2,
                        node3])  # node1 +1, node2 +1, node3 + 1, root +3

    node_again = root._get_child("node1")  # node1 +1

    assert node_ctype._get_reference_counts(node1) == refc_before_link1 + 2

    del node_again  # node1 -1

    assert node_ctype._get_reference_counts(node1) == refc_before_link1 + 1

    children = root._get_children()  #node1 +1, node2 +1, node3 +1

    assert len(children) == 3

    assert node_ctype._get_reference_counts(node1) == refc_before_link1 + 2
    assert node_ctype._get_reference_counts(node2) == refc_before_link2 + 2
    assert node_ctype._get_reference_counts(node3) == refc_before_link3 + 2
    assert node_ctype._get_reference_counts(root) == refc_before_link_root + 3

    # test get_parent

    root_again = node1._get_parent()  # root +1

    assert node_ctype._get_reference_counts(root) == refc_before_link_root + 4

    del root_again  # root -1

    assert node_ctype._get_reference_counts(root) == refc_before_link_root + 3

    # test _get_path

    path = node2._get_path()  # this shouldn't change any ref count

    assert node_ctype._get_reference_counts(node1) == refc_before_link1 + 2
    assert node_ctype._get_reference_counts(node2) == refc_before_link2 + 2
    assert node_ctype._get_reference_counts(node3) == refc_before_link3 + 2
    assert node_ctype._get_reference_counts(root) == refc_before_link_root + 3

    # test _get_child_from_path

    node4 = Node("node4")
    refc_before_link4 = node_ctype._get_reference_counts(node4)

    node3._add_child(node4)  # node3 +1, node4 + 1

    node4_again = root._get_child_from_path("node3.node4")  # node4 +1

    assert node_ctype._get_reference_counts(node4) == refc_before_link4 + 2
    assert node_ctype._get_reference_counts(node3) == refc_before_link3 + 3

    del node4_again  # node4 -1

    assert node_ctype._get_reference_counts(node4) == refc_before_link4 + 1
Exemplo n.º 18
0
def test_memory_leaks_setters():

    root = Node("root")

    node = Node("node")

    refc_before_link = node_ctype._get_reference_counts(node)

    root._add_child(node)

    # Adding a node adds 1 reference

    assert node_ctype._get_reference_counts(node) == refc_before_link + 1

    # Remove the node and verify that the reference counts goes back to what it was
    root._remove_child("node")

    # Now we should go back to the original

    assert node_ctype._get_reference_counts(node) == refc_before_link

    # Now add a second node nested under the first one (root.node.node2)
    node2 = Node("node2")

    refc_before_link2 = node_ctype._get_reference_counts(node2)

    root._add_child(node)  # +1 for node

    assert node_ctype._get_reference_counts(node) == refc_before_link + 1

    node._add_child(node2)  # +1 for node2 and +1 for node

    assert node_ctype._get_reference_counts(node2) == refc_before_link2 + 1

    # "node" is now also parent of node2, so its reference are now 2 more than the original
    assert node_ctype._get_reference_counts(node) == refc_before_link + 2

    # Clean up and verify that we go back to the original number of references
    node._remove_child("node2")  # -1 for node2, -1 for node

    assert node_ctype._get_reference_counts(node2) == refc_before_link2

    assert node_ctype._get_reference_counts(node) == refc_before_link + 1

    root._remove_child("node")  # -1 for node

    assert node_ctype._get_reference_counts(node) == refc_before_link

    # Now test add_children
    node3 = Node("node3")
    node4 = Node("node4")

    refc_before_link3 = node_ctype._get_reference_counts(node3)
    refc_before_link4 = node_ctype._get_reference_counts(node4)

    root._add_children([node3, node4])  # +1 for both nodes

    assert node_ctype._get_reference_counts(node3) == refc_before_link3 + 1
    assert node_ctype._get_reference_counts(node3) == refc_before_link4 + 1
Exemplo n.º 19
0
    def __init__(self):

        Node.__init__(self, 'polarization')
Exemplo n.º 20
0
def test_get_children():
    node1 = Node('node1')
    node2 = Node('node2')
    node22 = Node('node22')
    node3 = Node('node3')

    node1._add_child(node2)
    node1._add_child(node22)
    node2._add_child(node3)

    assert node1._get_children() == (node2, node22)
    assert node2._get_children() == (node3, )

    clean()