astrophot.param package
Submodules
astrophot.param.base module
- class astrophot.param.base.Node(name, **kwargs)[source]
Bases:
ABC
Base node object in the Directed Acyclic Graph (DAG).
The base Node object handles storing the DAG nodes and links between them. An important part of the DAG system is to be able to find all the leaf nodes, which is done using the flat function.
- Parameters:
name (str) – The name of the node, this should identify it uniquely in the local context it will be used in.
locked (bool) – Records if the node is locked, this is relevant for some other operations which only act on unlocked nodes.
link (tuple[Node]) – A tuple of node objects which this node will be linked to on initialization.
- property branch
Returns True when the current node is a branch node (not a leaf node, is linked to more nodes).
- flat(include_locked=True, include_links=False)[source]
Searches the DAG from this node and collects other nodes in the graph. By default it will include all leaf nodes only, however it can be directed to only collect leaf nodes that are not locked, it can also be directed to collect all nodes instead of just leaf nodes.
- get_state()[source]
Returns a dictionary with state information about this node. From that dictionary the node can reconstruct itself, or form another node which is a copy of this one.
- global_unlock = False
- property identity
A read only property of the node which does not change over it’s lifetime that uniquely identifies it relative to other nodes. By default this just uses the
id(self)
though for the purpose of saving/loading it may not always be this way.
- property leaf
Returns True when the current node is a leaf node.
- link(*nodes)[source]
Creates a directed link from the current node to the provided node(s) in the input. This function will also check that the linked node does not exist higher up in the DAG to the current node, if that is the case then a cycle has formed which breaks the DAG structure and could cause problems. An error will be thrown in this case.
The linked node is added to a
nodes
dictionary that each node stores. This makes it easy to check which nodes are linked to each other.
- set_state(state)[source]
Used to set the state of the node for the purpose of loading/copying. This uses the dictionary produced by
get_state
to re-create itself.
- unlink(*nodes)[source]
Undoes the linking of two nodes. Note that this could sever the connection of many nodes to each other if the current node was the only link between two branches.
- abstract property value
astrophot.param.param_context module
- class astrophot.param.param_context.Param_Mask(param, new_mask)[source]
Bases:
object
Temporarily mask parameters.
Select a subset of parameters to be used through the “vector” interface of the DAG. The context is initialized with a Parameter_Node object (
P
) and a torch tensor (M
) where the size of the mask should be equal to the current vector representation of the parameter (M.numel() == P.vector_values().numel()
). The mask tensor should be oftorch.bool
dtype whereTrue
indicates to keep using that parameter andFalse
indicates to hide that parameter value.Note that
Param_Mask
contexts can be nested and will behave accordingly (the mask tensor will need to match the vector size within the previous context). As an example, imagine there is a parameter nodeP
which has five sub-nodes each with a single value, one could nest contexts like:M1 = torch.tensor((1,1,0,1,0), dtype = torch.bool) with Param_Mask(P, M1): # Now P behaves as if it only has 3 elements M2 = torch.tensor([0,1,1], dtype = torch.bool) with Param_Mask(P, M2): # Now P behaves as if it only has 2 elements P.vector_values() # returns tensor with 2 elements
- class astrophot.param.param_context.Param_SoftLimits(param)[source]
Bases:
object
Temporarily allow writing parameter values outside limits.
Values outside the limits will be quietly (no error/warning raised) shifted until they are within the boundaries of the parameter limits. Since the limits are non-inclusive, the soft limits will actually move a parameter by 0.001 into the parameter range. For example the axis ratio
q
has limits from (0,1) so if one were to write:q.value = 2
then the actual value that gets written would be0.999
.Cyclic parameters are not affected by this, any value outside the range is always (Param_SoftLimits context or not) wrapped back into the range using modulo arithmetic.
- class astrophot.param.param_context.Param_Unlock(param=None)[source]
Bases:
object
Temporarily unlock a parameter.
Context manager to unlock a parameter temporarily. Inside the context, the parameter will behave as unlocked regardless of its initial condition. Upon exiting the context, the parameter will return to its previous locked state regardless of any changes made by the user to the lock state.
astrophot.param.parameter module
- class astrophot.param.parameter.Parameter_Node(name, **kwargs)[source]
Bases:
Node
A node representing parameters and their relative structure.
The Parameter_Node object stores all information relevant for the parameters of a model. At a high level the Parameter_Node accomplishes two tasks. The first task is to store the actual parameter values, these are represented as pytorch tensors which can have any shape; these are leaf nodes. The second task is to store the relationship between parameters in a graph structure; these are branch nodes. The two tasks are handled by the same type of object since there is some overlap between them where a branch node acts like a leaf node in certain contexts.
There are various quantities that a Parameter_Node tracks which can be provided as arguments or updated later.
- Parameters:
value – The value of a node represents the tensor which will be used by models to compute their projection into the pixels of an image. These can be quite complex, see further down for more details.
cyclic (bool) – Records if the value of a node is cyclic, meaning that if it is updated outside it’s limits it should be wrapped back into the limits.
limits (Tuple[Tensor or None, Tensor or None]) – Tracks if a parameter has constraints on the range of values it can take. The first element is the lower limit, the second element is the upper limit. The two elements should either be None (no limit) or tensors with the same shape as the value.
units (str) – The units of the parameter value.
uncertainty (Tensor or None) – represents the uncertainty of the parameter value. This should be None (no uncertainty) or a Tensor with the same shape as the value.
prof (Tensor or None) – This is a profile of values which has no explicit meaning, but can be used to store information which should be kept alongside the value. For example in a spline model the position of the spline points may be a
prof
while the flux at each node is the value to be optimized.shape (Tuple or None) – Can be used to set the shape of the value (number of elements/dimensions). If not provided then the shape will be set by the first time a value is given. Once a shape has been set, if a value is given which cannot be coerced into that shape, then an error will be thrown.
The
value
of a Parameter_Node is somewhat complicated, there are a number of states it can take on. The most straightforward is just a Tensor, if a Tensor (or just an iterable like a list or numpy.ndarray) is provided then the node is required to be a leaf node and it will store the value to be accessed later by other parts of AstroPhot. Another option is to set the value as another node (they will automatically be linked), in this case the node’svalue
is just a wrapper to call for thevalue
of the linked node. Finally, the value may be a function which allows for arbitrarily complex values to be computed from other node’s values. The function must take as an argument the current Parameter_Node instance and return a Tensor. Here are some examples of the various ways of interacting with thevalue
for a hypothetical parameterP
:P.value = 1. # Will create a tensor with value 1. P.value = P2 # calling P.value will actually call P2.value def compute_value(param): return param["P2"].value**2 P.value = compute_value # calling P.value will call the function as: compute_value(P) which will return P2.value**2
- flat_detach()[source]
Due to the system used to track and update values in the DAG, some parts of the computational graph used to determine gradients may linger after calling .backward on a model using the parameters. This function essentially resets all the leaf values so that the full computational graph is freed.
- get_state()[source]
Return the values representing the current state of the parameter, this can be used to re-load the state later from memory.
- property identities
This creates a numpy array of strings which uniquely identify every element in the parameter vector. For example a
center
parameter with two components [x,y] would have identities benp.array(["123456:0", "123456:1"])
where the first part is the unique id for the Parameter_Node object and the second number indexes where in the value tensor it refers to.
- property limits
- property mask
The mask tensor is stored internally and it cuts out some values from the parameter. This is used by the
vector
methods in the class to give the parameter DAG a dynamic shape.
- property names
Returns a numpy array of names for all the elements of the
vector
representation where the name is determined by the name of the parameters. Note that this does not create a unique name for each element and this should only be used for graphical purposes on small parameter DAGs.
- property prof
- set_state(state)[source]
Update the state of the parameter given a state variable which holds all information about a variable.
- property shape
- property size
- property uncertainty
- property value
The
value
of a Parameter_Node is somewhat complicated, there are a number of states it can take on. The most straightforward is just a Tensor, if a Tensor (or just an iterable like a list or numpy.ndarray) is provided then the node is required to be a leaf node and it will store the value to be accessed later by other parts of AstroPhot. Another option is to set the value as another node (they will automatically be linked), in this case the node’svalue
is just a wrapper to call for thevalue
of the linked node. Finally, the value may be a function which allows for arbitrarily complex values to be computed from other node’s values. The function must take as an argument the current Parameter_Node instance and return a Tensor. Here are some examples of the various ways of interacting with thevalue
for a hypothetical parameterP
:P.value = 1. # Will create a tensor with value 1. P.value = P2 # calling P.value will actually call P2.value def compute_value(param): return param["P2"].value**2 P.value = compute_value # calling P.value will call the function as: compute_value(P) which will return P2.value**2
- vector_identities()[source]
This returns a vector (see vector_values) with the identities for each leaf node.
- vector_mask()[source]
This returns a vector (see vector_values) with the mask for each leaf node. Note however that the mask is not itself masked, this vector is always the full size of the unmasked parameter DAG.
- vector_names()[source]
This returns a vector (see vector_values) with the names for each leaf node.
- vector_representation()[source]
This returns a vector (see vector_values) with the representation for each leaf node. The representation is an alternative view of each value which is mapped into the (-inf, inf) range where optimization is more stable.
- vector_set_mask(mask)[source]
Update the mask vector for this parameter DAG (see vector_set_values). Note again that the mask vector is always the full size of the DAG.
- vector_set_representation(rep)[source]
Update the representation vector for this parameter DAG (see vector_set_values).
- vector_set_uncertainty(uncertainty)[source]
Update the uncertainty vector for this parameter DAG (see vector_set_values).
- vector_set_values(values)[source]
This function allows one to update the full vector of values in a single call by providing a tensor of the appropriate size. The input will be separated so that the correct elements are passed to the correct leaf nodes.
- vector_transform_rep_to_val(rep)[source]
Used to transform between the
vector_values
andvector_representation
views of the elements in the DAG leafs. This transforms from representation to value.The transformation is done based on the limits of each parameter leaf. If no limits are provided then the representation and value are equivalent. If both are given then a
tan
andarctan
are used to convert between the finite range and the infinite range. If the limits are one-sided then the transformation:newvalue = value - 1 / (value - limit)
is used.
- vector_transform_val_to_rep(val)[source]
Used to transform between the
vector_values
andvector_representation
views of the elements in the DAG leafs. This transforms from value to representation.The transformation is done based on the limits of each parameter leaf. If no limits are provided then the representation and value are equivalent. If both are given then a
tan
andarctan
are used to convert between the finite range and the infinite range. If the limits are one-sided then the transformation:newvalue = value - 1 / (value - limit)
is used.
- vector_uncertainty()[source]
This returns a vector (see vector_values) with the uncertainty for each leaf node.
- vector_values()[source]
The vector representation is for values which correspond to fundamental inputs to the parameter DAG. Since the DAG may have linked nodes, or functions which produce values derived from other node values, the collection of all “values” is not necessarily of use for some methods such as fitting algorithms. The vector representation is useful for optimizers as it gives a fundamental representation of the parameter DAG. The vector_values function returns a vector of the
value
for each leaf node.