Skip to content

Commit

Permalink
Merge pull request #929 from tardis-sn/numba_montecarlo
Browse files Browse the repository at this point in the history
This is a year worth of work from many people and hopefully will make
TARDIS easier to use and develop on.

Co-authored-by: Andrew Fullard <[email protected]>
Co-authored-by: Jack O'Brien <[email protected]>
Co-authored-by: Christian Vogl <[email protected]>
Co-authored-by: Andreas Flörs <[email protected]>
Co-authored-by: Luke Shingles <[email protected]>
Co-authored-by: Alice Harpole <[email protected]>
Co-authored-by: Marc Williamson <[email protected]>
Co-authored-by: Yssa Camacho <[email protected]>
Co-authored-by: Arjun Savel <[email protected]>
Co-authored-by: Stuart Archibald <[email protected]>
Co-authored-by: Siu Kwan Lam <[email protected]>
  • Loading branch information
12 people committed Nov 17, 2020
2 parents 071a48e + d14025e commit 101a493
Show file tree
Hide file tree
Showing 72 changed files with 5,810 additions and 2,142 deletions.
3 changes: 3 additions & 0 deletions docs/development/continuous_integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ to paths in Azure:
See the Azure documentation to learn more about `checking out multiple repositories`_.


Azure provides a list of agent hosts that can run the pipeline on a virtual machine. In our pipelines, we
use the vm_Images: Ubuntu 16.04 and macOs-10.14.

Jobs
----

Expand Down
14 changes: 14 additions & 0 deletions docs/development/debug_numba.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
**************************
Debugging numba_montecarlo
**************************
To facilitate more in-depth debugging when interfacing with the `montecarlo_numba`
module, we provide a set of debugging configurations. PyCharm debugging
configurations, in addition to related scripts and .yml files, are contained in
`tardis.scripts.debug`. Currently, these include the ability to run TARDIS
in asingle-packet mode, with the packet seed identified at debug time.
`tardis_example_single.yml` is the configuration filethat is used to set up the
single-packet TARDIS run; `run_numba_single.py` is thePython script that runs
this .yml file; `run_numba_single.xml` is the PyCharmdebug configuration file
that can be used in conjunction with the above files.

Note that this method is EXPERIMENTAL.
2 changes: 1 addition & 1 deletion docs/development/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ to the Astropy team for designing it.
.. toctree::
:maxdepth: 2

running_tests
issues
debug_numba



Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ Mission Statement
Physics overview <physics/index>
physics/plasma/index

.. toctree::
:maxdepth: 2
:caption: Testing TARDIS
:hidden:

testing/automated_tests
testing/numba


.. toctree::
:maxdepth: 2
Expand Down
16 changes: 8 additions & 8 deletions docs/running/custom_source.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@
" \n",
" def __init__(self, seed, truncation_wavelength):\n",
" super().__init__(seed)\n",
" self.rng = np.random.default_rng(seed=seed)\n",
" self.truncation_wavelength = truncation_wavelength\n",
" \n",
" def create_packets(self, T, no_of_packets,\n",
" def create_packets(self, T, no_of_packets, rng,\n",
" drawing_sample_size=None):\n",
" \"\"\"\n",
" Packet source that generates a truncated Blackbody source.\n",
Expand All @@ -70,11 +71,10 @@
" Only wavelengths higher than the truncation wavelength\n",
" will be sampled.\n",
" \"\"\"\n",
" \n",
" \n",
"\n",
" # Use mus and energies from normal blackbody source.\n",
" mus = self.create_zero_limb_darkening_packet_mus(no_of_packets)\n",
" energies = self.create_uniform_packet_energies(no_of_packets)\n",
" mus = self.create_zero_limb_darkening_packet_mus(no_of_packets, self.rng)\n",
" energies = self.create_uniform_packet_energies(no_of_packets, self.rng)\n",
"\n",
" # If not specified, draw 2 times as many packets and reject any beyond no_of_packets.\n",
" if drawing_sample_size is None:\n",
Expand All @@ -86,15 +86,15 @@
" \n",
" # Draw nus from blackbody distribution and reject based on truncation_frequency.\n",
" # If more nus.shape[0] > no_of_packets use only the first no_of_packets.\n",
" nus = self.create_blackbody_packet_nus(T, drawing_sample_size)\n",
" nus = self.create_blackbody_packet_nus(T, drawing_sample_size, self.rng)\n",
" nus = nus[nus<truncation_frequency][:no_of_packets]\n",
" \n",
" \n",
" # Only required if the truncation wavelength is too big compared to the maximum \n",
" # of the blackbody distribution. Keep sampling until nus.shape[0] > no_of_packets.\n",
" while nus.shape[0] < no_of_packets:\n",
" additional_nus = self.create_blackbody_packet_nus(\n",
" T, drawing_sample_size\n",
" T, drawing_sample_size, self.rng\n",
" )\n",
" mask = additional_nus < truncation_frequency\n",
" additional_nus = additional_nus[mask][:no_of_packets]\n",
Expand Down Expand Up @@ -170,4 +170,4 @@
},
"nbformat": 4,
"nbformat_minor": 2
}
}
60 changes: 30 additions & 30 deletions tardis/gui/datahandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ class Node(object):
Attributes
----------
parent: None/Node
parent: None/Node
The parent of the node.
children: list of Node
The children of the node.
data: list of string
data: list of string
The data stored on the node. Can be a key or a value.
siblings: dictionary
A dictionary of nodes that are siblings of this node. The
keys are the values of the nodes themselves. This is
siblings: dictionary
A dictionary of nodes that are siblings of this node. The
keys are the values of the nodes themselves. This is
used to keep track of which value the user has selected
if the parent of this node happens to be a key that can
take values from a list.
Expand All @@ -61,18 +61,18 @@ def __init__(self, data, parent=None):
----------
data: list of string
The data that is intended to be stored on the node.
parent: Node
Another node which is the parent of this node. The
parent: Node
Another node which is the parent of this node. The
root node has parent set to None.
Note
----
A leaf node is a node that is the only child of its parent.
A leaf node is a node that is the only child of its parent.
For this tree this will always be the case. This is because
the tree stores the key at every node except the leaf node
where it stores the value for the key. So if in the dictionary
the value of a key is another dictionary, then it will
be a node with no leafs. If the key has a value that is a
the value of a key is another dictionary, then it will
be a node with no leafs. If the key has a value that is a
value or a list then it will have one child that is a leaf.
The leaf can have no children. For example-
Expand All @@ -86,12 +86,12 @@ def __init__(self, data, parent=None):
val7, val5 and val6 and is currently
set to val5.
In the tree shown above all quoted values are keys in the
dictionary and are non-leaf nodes in the tree. All values
of the form valx are leaf nodes and are not dictionaries
In the tree shown above all quoted values are keys in the
dictionary and are non-leaf nodes in the tree. All values
of the form valx are leaf nodes and are not dictionaries
themselves. If the keys have non-dictionary values then they
have a leaf attached. And no leaf can have a child.
"""
self.parent = parent
self.children = []
Expand All @@ -105,9 +105,9 @@ def append_child(self, child):
child.parent = self

def get_child(self, i):
"""Get the ith child of this node.
"""Get the ith child of this node.
No error is raised if the cild requested doesn't exist. A
No error is raised if the cild requested doesn't exist. A
None is returned in such cases.
"""
Expand Down Expand Up @@ -141,7 +141,7 @@ def get_parent(self):
return self.parent

def get_index_of_self(self):
"""Returns the number at which it comes in the list of its
"""Returns the number at which it comes in the list of its
parent's children. For root the index 0 is returned.
"""
Expand Down Expand Up @@ -170,10 +170,10 @@ class TreeModel(QtCore.QAbstractItemModel):
----------
root: Node
Root node of the tree.
disabledNodes: list of Node
disabledNodes: list of Node
List of leaf nodes that are not editable currently.
typenodes: list of Node
List of nodes that correspond to keys that set container
typenodes: list of Node
List of nodes that correspond to keys that set container
types. Look at tardis configuration template. These are the
nodes that have values that can be set from a list.
Expand All @@ -184,9 +184,9 @@ def __init__(self, dictionary, parent=None):
Parameters
----------
dictionary: dictionary
dictionary: dictionary
The dictionary that needs to be converted to the tree.
parent: None
parent: None
Used to instantiate the QAbstractItemModel
"""
Expand Down Expand Up @@ -267,7 +267,7 @@ def headerData(self, section, orientation, role):
return None

def index(self, row, column, parent=QtCore.QModelIndex()):
"""Create a model index for the given row and column. For a
"""Create a model index for the given row and column. For a
tree model, the row is the set of nodes with the same parents and
the column indexes the data in the node.
Expand Down Expand Up @@ -315,8 +315,8 @@ def parent(self, index):
return self.createIndex(parentItem.get_index_of_self(), 0, parentItem)

def rowCount(self, parent=QtCore.QModelIndex()):
"""The number of rows for a given node.
"""The number of rows for a given node.
(The number of rows is just the number of children for a node.)
"""
Expand All @@ -325,7 +325,7 @@ def rowCount(self, parent=QtCore.QModelIndex()):
return parentItem.num_hildren()

def setData(self, index, value, role=QtCore.Qt.EditRole):
"""Set the value as the data at the location pointed by the
"""Set the value as the data at the location pointed by the
index.
"""
Expand Down Expand Up @@ -360,7 +360,7 @@ def dict_to_tree(self, dictionary, root):
----------
dictionary: dictionary
The dictionary that is to be converted to the tree.
root: Node
root: Node
The root node of the tree.
"""
Expand Down Expand Up @@ -411,7 +411,7 @@ def tree_from_node(self, dictionary, root):
self.typenodes.append(child)

def dict_from_node(self, node):
"""Take a node and convert the whole subtree rooted at it into a
"""Take a node and convert the whole subtree rooted at it into a
dictionary.
"""
Expand All @@ -429,7 +429,7 @@ def dict_from_node(self, node):


class TreeDelegate(QtWidgets.QStyledItemDelegate):
"""Create a custom delegate to modify the columnview that displays the
"""Create a custom delegate to modify the columnview that displays the
TreeModel.
"""
Expand Down Expand Up @@ -457,7 +457,7 @@ def createEditor(self, parent, option, index):

def setModelData(self, editor, model, index):
"""Called when new data id set in the model. This is where the
siblings of type nodes are enabled or disabled according to the
siblings of type nodes are enabled or disabled according to the
new choice made.
"""
Expand Down
10 changes: 5 additions & 5 deletions tardis/gui/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@
def show(model):
"""Take an instance of tardis model and display it.
If IPython functions were successfully imported then QApplication instance
is created using get_app_qt4. This will only create the app instance if
it doesn't already exists. Otherwise it is explicitly started.
If IPython functions were successfully imported then QApplication instance
is created using get_app_qt4. This will only create the app instance if
it doesn't already exists. Otherwise it is explicitly started.
Then the mainwindow is created, the model is attached to it and its
Then the mainwindow is created, the model is attached to it and its
show method is called.
Finally the eventloop is started using IPython functions (which start them
consistently) if they were imported. Otherwise it is started explicitly.
consistently) if they were imported. Otherwise it is started explicitly.
"""
if importFailed:
Expand Down
13 changes: 9 additions & 4 deletions tardis/gui/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ def change_spectrum_to_spec_virtual_flux_angstrom(self):

def change_spectrum_to_spec_flux_angstrom(self):
"""Change spectrum data back from virtual spectrum. (See the
method above)."""
method above)."""
if self.model.runner.spectrum.luminosity_density_lambda is None:
luminosity_density_lambda = np.zeros_like(
self.model.runner.spectrum.wavelength
Expand Down Expand Up @@ -946,7 +946,10 @@ def __init__(self, parent, wavelength_start, wavelength_end, tablecreator):
self.setGeometry(180 + len(self.parent.line_info) * 20, 150, 250, 400)
self.setWindowTitle(
"Line Interaction: %.2f - %.2f (A) "
% (wavelength_start, wavelength_end,)
% (
wavelength_start,
wavelength_end,
)
)
self.layout = QtWidgets.QVBoxLayout()
packet_nu_line_interaction = analysis.LastLineInteraction.from_model(
Expand Down Expand Up @@ -1155,8 +1158,10 @@ def __init__(
self.line_interaction_analysis = line_interaction_analysis
self.atom_data = atom_data
self.lines_data = lines_data.reset_index().set_index("line_id")
line_interaction_species_group = line_interaction_analysis.last_line_in.groupby(
["atomic_number", "ion_number"]
line_interaction_species_group = (
line_interaction_analysis.last_line_in.groupby(
["atomic_number", "ion_number"]
)
)
self.species_selected = sorted(
line_interaction_species_group.groups.keys()
Expand Down
26 changes: 14 additions & 12 deletions tardis/io/config_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,16 +239,18 @@ class ConfigWriterMixin(HDFWriterMixin):
"""
Overrides HDFWriterMixin to obtain HDF properties from configuration keys
"""

def get_properties(self):
data = yaml.dump(self)
data = pd.DataFrame(index=[0], data={'config': data})
data = pd.DataFrame(index=[0], data={"config": data})
return data


class Configuration(ConfigurationNameSpace, ConfigWriterMixin):
"""
Tardis configuration class
"""

hdf_name = "simulation"

@classmethod
Expand Down Expand Up @@ -358,26 +360,26 @@ def quantity_representer(dumper, data):

def cns_representer(dumper, data):
"""
Represents Configuration as dict
Represents Configuration as dict
Parameters
----------
Parameters
----------
dumper :
YAML dumper object
dumper :
YAML dumper object
data :
ConfigurationNameSpace object
data :
ConfigurationNameSpace object
Returns
-------
Returns
-------
yaml dumper representation of Configuration as dict
yaml dumper representation of Configuration as dict
"""
return dumper.represent_dict(dict(data))


yaml.add_representer(u.Quantity, quantity_representer)
yaml.add_representer(ConfigurationNameSpace, cns_representer)
yaml.add_representer(Configuration, cns_representer)
yaml.add_representer(Configuration, cns_representer)
Loading

0 comments on commit 101a493

Please sign in to comment.