diff --git a/doc/source/api/modules.rst b/doc/source/api/modules.rst index 497f3b07e..397957951 100644 --- a/doc/source/api/modules.rst +++ b/doc/source/api/modules.rst @@ -51,6 +51,7 @@ General Surface utilities montepy.Surface montepy.HalfSpace + montepy.UnitHalfSpace Cylinders @@ -100,8 +101,11 @@ Materials :nosignatures: :template: myclass.rst + montepy.SingletonGroup montepy.Element + montepy.Library montepy.Material + montepy.Nucleus montepy.Nuclide montepy.ThermalScatteringLaw @@ -174,6 +178,7 @@ Enumerations :template: myclass.rst montepy.geometry_operators.Operator + montepy.LibraryType montepy.particle.Particle montepy.SurfaceType montepy.input_parser.shortcuts.Shortcuts diff --git a/doc/source/bugs.rst b/doc/source/bugs.rst index f4d7bb215..dca15034a 100644 --- a/doc/source/bugs.rst +++ b/doc/source/bugs.rst @@ -4,7 +4,7 @@ Known Bugs and limitations This page is not meant to document every MCNP feature that is not supported. For seeing if a specific feature is supported refer to the API documentation -that exists for :mod:`~montepy.data_inputs`, :mod:`~montepy.surfaces`, +that exists for ``montepy.data_inputs`` and ``montepy.surfaces`` to see if an object exists for the feature you want. This is meant for documenting limitations that are less obvious, diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 213c1ba4b..e120f8dea 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -19,10 +19,14 @@ MontePy Changelog * Removed Guardrails from :class:`~montepy.numbered_object_collection.NumberedObjectCollection` (:issue:`895`) +**Documentation** + +* Enable Sphinx nitpicky mode and fix ~30 broken cross-references in the developer guide, user guide, and migration docs (:issue:`889`). + **Feature Added** * Added ``extend_renumber`` to ``NumberedObjectCollection`` with related test cases (:issue:`881`). -* Made :class:`montepy.data_inputs.Importance` more ``dict``-like with ``keys``, ``values``, and ``items`` functions (:pull:`921`). +* Made :class:`montepy.data_inputs.importance.Importance` more ``dict``-like with ``keys``, ``values``, and ``items`` functions (:pull:`921`). 1.3.0 -------------- @@ -170,11 +174,11 @@ MontePy Changelog * Made NumberedObjectCollections act like a set (:issue:`138`). * Automatically added children objects, e.g., the surfaces in a cell, to the problem when the cell is added to the problem (:issue:`63`). * Added ability to parse all MCNP objects from a string (:issue:`88`). -* Added function: :func:`~montepy.mcnp_problem.MCNP_Problem.parse` to parse arbitrary MCNP object (:issue:`88`). +* Added function: :meth:`~montepy.MCNP_Problem.parse` to parse arbitrary MCNP object (:issue:`88`). * An error is now raised when typos in object attributes are used, e.g., ``cell.nubmer`` (:issue:`508`). * Warnings are no longer raised for comments that exceed the maximum line lengths (:issue:`188`). * Particle type exceptions are now warnings, not errors (:issue:`381`). -* Added :func:`~montepy.data_inputs.material.Material.clear` to ``Material`` to clear out all nuclides (:issue:`665`). +* Added :meth:`~montepy.Material.clear` to ``Material`` to clear out all nuclides (:issue:`665`). * Allow any ``Real`` type for floating point numbers and any ``Integral`` type for integer numbers during type enforcement (:issue:`679`). * Avoided multiple ``LineExpansionWarnings`` coming from the same object on export (:issue:`198`). * Added ``mcnp_str`` function to all ``MCNP_Object`` to quickly get the string that would be printed in the MCNP input file (:issue:`700`). @@ -196,9 +200,9 @@ MontePy Changelog **Breaking Changes** -* Removed :func:`~montepy.data_inputs.material.Material.material_components``. See :ref:`migrate 0 1` (:pull:`507`). +* Removed ``Material.material_components``. See :ref:`migrate 0 1` (:pull:`507`). * Removed :class:`~montepy.data_inputs.isotope.Isotope` and changed them to :class:`~montepy.data_inputs.nuclide.Nuclide`. -* Removed :func:`~montepy.mcnp_problem.MCNP_Problem.add_cell_children_to_problem` as it is no longer needed. +* Removed ``MCNP_Problem.add_cell_children_to_problem`` as it is no longer needed. **Deprecated code Removed** diff --git a/doc/source/conf.py b/doc/source/conf.py index 48b199481..059b0488c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -82,6 +82,9 @@ linkcheck_ignore = [ "https://nucleardata.lanl.gov/.*", "https://www.osti.gov/.*", # Ignore osti.gov URLs + # GitHub returns 429/502 for link-checkers hitting issue/PR links in CI; + # the :issue: and :pull: extlinks are validated by the PR workflow itself. + r"https://github\.com/idaholab/MontePy/(issues|pull)/.*", "https://zenodo.org/.*", ] @@ -145,6 +148,42 @@ suppress_warnings = ["epub.unknown_project_files"] +# -- Intersphinx mapping ----------------------------------------------------- +# Allows cross-references to Python stdlib, NumPy, etc. +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable/", None), +} + +# -- Nitpicky mode ----------------------------------------------------------- +# Treat broken cross-references as warnings (CI promotes them to errors via -W). +nitpicky = True + +# Exact (type, target) pairs that cannot be resolved and should be ignored. +nitpick_ignore = [ + # sly has no intersphinx inventory; all sly.* cross-refs are unresolvable + ("py:class", "sly.Parser"), + ("py:class", "sly.Lexer"), + ("py:class", "sly.lex.Token"), + ("py:class", "sly.lex.Lexer"), + ("py:class", "sly.yacc.Parser"), + ("py:class", "sly.yacc.ParserMeta"), + ("py:class", "sly.yacc.YaccProduction"), +] + +# Regex patterns for cross-reference targets that cannot be resolved. +nitpick_ignore_regex = [ + # Sphinx/autodoc generates bare type names that are not valid cross-ref targets + (r"py:class", r"^(self|self\._\w+|generator|unknown|function|Class|InitInput|MCNP_Input)$"), + # sly Token is not in any intersphinx inventory + (r"py:class", r"^Token$"), + # Bare unqualified names from :type: annotations in older docstrings; + # ClassifierNode is an internal parser class not re-exported publicly + (r"py:class", r"^(ClassifierNode|enum|class)$"), + # numpy alias "np" is not in the numpy intersphinx inventory + (r"py:class", r"^np\..*"), +] + # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/doc/source/dev_standards.rst b/doc/source/dev_standards.rst index 287053d9e..af8451e8e 100644 --- a/doc/source/dev_standards.rst +++ b/doc/source/dev_standards.rst @@ -101,7 +101,7 @@ Naming Conventions and ``set``). #. Within reason: avoid abbreviating words. Above all, prioritize legibility. #. For user facing functions and attributes, short names are best. - (:func:`~montepy.surfaces.surface.Surface.surface_constants`, really should have been ``constants`` in hind-sight). + (:attr:`~montepy.Surface.surface_constants`, really should have been ``constants`` in hind-sight). Doc Strings diff --git a/doc/source/developing.rst b/doc/source/developing.rst index 96ea828ed..2b23fbe7c 100644 --- a/doc/source/developing.rst +++ b/doc/source/developing.rst @@ -35,30 +35,30 @@ Top Level ^^^^^^^^^ The top level of the package is reserved for only a select few objects. All children of :class:`~montepy.numbered_object_collection.NumberedObjectCollection` can live here. -The other allowed classes are: ``Exceptions``, :class:`~montepy.mcnp_card.MCNP_Card`, :class:`~montepy.mcnp_problem.MCNP_Problem`, :class:`~montepy.cell.Cell`, -:class:`~montepy.particle.Particle`, and :class:`~montepy.universe.Universe`. +The other allowed classes are: ``Exceptions``, :class:`~montepy.mcnp_object.MCNP_Object`, :class:`~montepy.MCNP_Problem`, :class:`~montepy.Cell`, +:class:`~montepy.particle.Particle`, and :class:`~montepy.Universe`. Utility functions are allowed at this level as well. input_parser ^^^^^^^^^^^^ -The :mod:`montepy.input_parser` contains all functions and classes involved in syntax parsing. +The ``montepy.input_parser`` contains all functions and classes involved in syntax parsing. Generally this is all invoked through :func:`~montepy.input_parser.input_reader.read_input`, -which returns an :class:`~montepy.mcnp_problem.MCNP_Problem` instance. +which returns an :class:`~montepy.MCNP_Problem` instance. data_inputs ^^^^^^^^^^^ -This package is for all :class:`~montepy.mcnp_card.MCNP_Card` children that should exist +This package is for all :class:`~montepy.mcnp_object.MCNP_Object` children that should exist in the data block in an MCNP input. -For example :class:`~montepy.data_inputs.material.Material` lives here. +For example :class:`~montepy.Material` lives here. surfaces ^^^^^^^^ This package contains all surface classes. -All classes need to be children of :class:`~montepy.surfaces.surface.Surface`. +All classes need to be children of :class:`~montepy.Surface`. When possible new surface classes should combine similar planes. -For example :class:`~montepy.surfaces.axis_plane.AxisPlane` covers ``PX``, ``PY``, and ``PZ``. +For example :class:`~montepy.AxisPlane` covers ``PX``, ``PY``, and ``PZ``. Introduction to SLY and Syntax Trees @@ -126,7 +126,7 @@ The classes are: It is meant to hold a single value, both its semantic value and its text representation, and its surrounding white-space (and comments), or padding. * :class:`~montepy.input_parser.syntax_node.PaddingNode` is the companion to the ``ValueNode``. It encapsulates all following padding for a value. Padding is considered to be white-space or a comment (:class:`~montepy.input_parser.syntax_node.CommentNode`). -* :class:`~montepy.input_parser.syntax_node.ListNode` is a node meant to contain a list of arbitrary length of values. +* ``ListNode`` is a node meant to contain a list of arbitrary length of values. * :class:`~montepy.input_parser.syntax_node.ShortcutNode` is a helper to a ``ListNode`` for when MCNP shortcuts (e.g., ``1 10r``) are used. They are nested inside of a ``ListNode`` and should be mostly transparent to the user and developer. * :class:`~montepy.input_parser.syntax_node.ParametersNode` is a node to hold the parameters for an input. @@ -136,7 +136,7 @@ The classes are: * :class:`~montepy.input_parser.syntax_node.ClassifierNode` is a node to represent the data classification "word" that describes what the data are for. For example for a material it would contain ``M34``. For a cell importance it could be ``imp:n``. It can contain: a data keyword, a number, a particle designator (:class:`~montepy.input_parser.syntax_node.ParticleNode`), and a modifier character (e.g., ``*`` in ``*TR5``). -* :class:`~montepy.input_parser.syntax_node.IsotopesNode` is a node that represents an MCNP style isotope identifier (e.g., ``1001.80c``). +* ``IsotopesNode`` is a node that represents an MCNP style isotope identifier (e.g., ``1001.80c``). Many of these nodes (which aren't leaves) behave like dicts and lists, and can be accessed with indices. For more detail in how to work with them read the next section on MCNP_Objects: :ref:`mcnp-object-docs`. @@ -152,7 +152,7 @@ Input: :class:`~montepy.mcnp_object.MCNP_Object` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ All classes that represent a single input card *must* subclass this. -For example: some children are: :class:`~montepy.cell.Cell`, :class:`~montepy.surfaces.surface.Surface`. +For example: some children are: :class:`~montepy.Cell`, :class:`~montepy.Surface`. How to __init__ """"""""""""""" @@ -197,7 +197,7 @@ This property can be set, and should be. You should not store the nested value; instead you should store the entire ValueNode in a private attribute, and then use :func:`~montepy.utilities.make_prop_val_node` to provide the appropriate property. -Even if an input isn't provided a ValueNode needs to be stored. The utility :func:`~montepy.mcnp_object.MCNP_Object._generate_default_node` can help simplify this. +Even if an input isn't provided a ValueNode needs to be stored. The utility ``_generate_default_node()`` can help simplify this. The parsers can't always know what data type should in a specific position, so largely it treats all numerical values as floats. This should be changed during the init so the value_nodes are the correct data type. @@ -211,19 +211,19 @@ This will make it so that ``value`` always returns a positive value, and so :fun .. note:: Setting :func:`~montepy.input_parser.syntax_node.ValueNode.is_negatable_identifier` to ``True`` - will convert the ValueNode to an integer ValueNode (via :func:`~montepy.input_parser.syntax_node.ValueNode._convert_to_int`). + will convert the ValueNode to an integer ValueNode (via ``_convert_to_int()``). Next, if you do not need to change the :func:`~montepy.input_parser.syntax_node.ValueNode.type` for the ValueNode, but do not need to markt the ValueNode as negative; there are methods to handle this. -These methods are :func:`~montepy.input_parser.syntax_node.ValueNode._convert_to_int`, and -:func:`~montepy.input_parser.syntax_node.ValueNode._convert_to_enum`. +These methods are ``_convert_to_int()``, and +``_convert_to_enum()``. ``_convert_to_int`` is a rather straight forward function to run, and takes no arguments. It should be noted that the value is found by running ``int(self.token)``, that is that the original string value, and not the float value is converted. This is in order to avoid allowing ``1.5`` as a valid int, since in this case the floor would be taken. ``_convert_to_enum`` takes a class instance, which is a subclass of ``Enum``. You can specify a ``format_type``, which specifies what the data should be treated as while formatting it with new data. -For example :class:`~montepy.surfaces.surface_type.SurfaceType` (e.g., ``PZ``) uses ``str`` as its format type, -whereas :class:`~montepy.data_inputs.lattice.Lattice` (e.g., ``1`` or ``2``) uses ``int`` is its format type. +For example :class:`~montepy.SurfaceType` (e.g., ``PZ``) uses ``str`` as its format type, +whereas :class:`~montepy.data_inputs.lattice.LatticeType` (e.g., ``1`` or ``2``) uses ``int`` is its format type. How to __str__ vs __repr__ """""""""""""""""""""""""" @@ -235,7 +235,7 @@ For numbered objects this should include their number, and a few high level deta For ``__repr__`` this should include debugging information. This should include most if not all internal state information. -See this example for :class:`~montepy.cell.Cell` +See this example for :class:`~montepy.Cell` .. doctest:: :skipif: True # skip because multi-line doc tests are kaputt @@ -254,7 +254,7 @@ See this example for :class:`~montepy.cell.Cell` Writing to File (Format for MCNP Input) """"""""""""""""""""""""""""""""""""""" -MontePy (via :func:`~montepy.mcnp_problem.MCNP_Problem.write_problem`) writes +MontePy (via :func:`~montepy.MCNP_Problem.write_problem`) writes a class to file path or file handle by calling its :func:`~montepy.mcnp_object.MCNP_Object.format_for_mcnp_input` method. This must return a list of strings that faithfully represent this objects state, and tries to replicate the user formatting. Each string in the list represents one line in the MCNP input file to be written. @@ -275,7 +275,7 @@ Next the abstract method, :func:`~montepy.mcnp_object.MCNP_Object._update_values This function updates the syntax tree with current values. Most values should not need to be updated, since their value is linked to a ValueNode, which is pointed to and modified by the object. This should only really by used to update information controlled by other objects. -For instance :class:`~montepy.cell.Cell` will update its material number based on ``self.material.number``, +For instance :class:`~montepy.Cell` will update its material number based on ``self.material.number``, since the cell object does not control a material's number. Finally ``self._tree`` is formatted. Remember ``self._tree`` is a syntax tree of type :class:`~montepy.input_parser.syntax_node.SyntaxNode`. @@ -308,7 +308,7 @@ Collection: :class:`~montepy.numbered_object_collection.NumberedDataObjectCollec ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is a subclass of :class:`~montepy.numbered_object_collection.NumberedObjectCollection`, which is designed for :class:`~montepy.data_inputs.data_input.DataInputAbstract` instances. -It is a wrapper that will ensure that all of its items are also in :func:`~montepy.mcnp_problem.MCNP_Problem.data_inputs`. +It is a wrapper that will ensure that all of its items are also in :attr:`~montepy.MCNP_Problem.data_inputs`. Numbered Object :class:`~montepy.numbered_mcnp_object.Numbered_MCNP_Object` @@ -336,10 +336,10 @@ For example the ``Surface`` number setter looks like: self._surface_number = number -Surface: :class:`~montepy.surfaces.surface.Surface` +Surface: :class:`~montepy.Surface` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is the parent class for all Surface classes. -You will also need to update :func:`~montepy.surfaces.surface_builder.surface_builder`. +You will also need to update :func:`~montepy.surfaces.surface_builder.parse_surface`. You should expose clear parameters such as ``radius`` or ``location``. ``format_for_mcnp_input()`` is handled by default. @@ -349,9 +349,9 @@ After running the super init method you will then have access to ``self.surface_type``, and ``self.surface_constants``. You will need to implement a ``_allowed_surface_types`` to specify which surface types are allowed for your class. You then need to verify that there are the correct number of surface constants. -You will also need to add a branch in the logic for :func:`montepy.surfaces.surface_builder.surface_builder`. +You will also need to add a branch in the logic for :func:`montepy.surfaces.surface_builder.parse_surface`. -:func:`~montepy.surfaces.surface.Surface.find_duplicate_surfaces` +:func:`~montepy.Surface.find_duplicate_surfaces` """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" This function is meant to find very similar surfaces that cause geometry errors, such as two ``PZ`` surfaces that are 1 micron apart. @@ -402,10 +402,10 @@ Based upon this the function will decide which class to run for a full parse. By default all subclasses will use the :class:`~montepy.input_parser.data_parser.DataParser` class. If you need to use a custom parser you do so by setting ``self._parser``. -How to add an object to :class:`~montepy.mcnp_problem.MCNP_Problem` +How to add an object to :class:`~montepy.MCNP_Problem` """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -the :class:`~montepy.mcnp_problem.MCNP_Problem` automatically consumes problem level data inputs, +the :class:`~montepy.MCNP_Problem` automatically consumes problem level data inputs, and adds them to itself. Cards this would be appropriate for would be things like ``mode`` and ``kcode``. To do this it uses the dictionary ``inputs_to_property`` in the ``__load_data_inputs_to_object`` method. @@ -479,7 +479,7 @@ At the ``Cells`` level the object should be stored in a ``_protected`` attribute See more below. -How these objects are added to :class:`~montepy.cell.Cell` and :class:`~montepy.cells.Cells` +How these objects are added to :class:`~montepy.Cell` and :class:`~montepy.Cells` """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Due to the number of classes that will ultimately be subclasses of this class, @@ -497,7 +497,7 @@ If this boolean is false repeats of this class are allowed and they will be merg (e.g., ``IMP:N,P=1 IMP:E=0`` makes sense despite there being two ``IMP`` specified. If True only one instance of the object is allowed. (e.g., ``VOL=5 VOL=10`` makes no sense). -For finding which class to use the :func:`~montepy.data_inputs.data_parser.PREFIX_MATCHES` set is used. See above. +For finding which class to use the ``PREFIX_MATCHES`` set is used. See above. The key, value pairs in ``Cell.parameters`` is iterated over. If any of the keys is a partial match to the ``PREFIX_MATCHES`` dict then that class is used, and constructed. @@ -527,11 +527,11 @@ which needs to be implemented. For the data-block isntance this is a bit more complicated. First all new data for every cell is collected by :func:`~montepy.data_inputs.cell_modifier.CellModifierInput._collect_new_values`. By default this will get the *ValueNode* that is returned from the abstract method :func:`~montepy.data_inputs.cell_modifier.CellModifierInput._tree_value`. -These values will then be passed to :func:`~montepy.input_parser.syntax_node.ListNode.update_with_new_values`. +These values will then be passed to ``ListNode.update_with_new_values()``. Finally, the syntax tree is formatted. Once again this is wrapped to allow adding more complexity. -The tree is formatted by :func:`~montepy.data_inputs.cell_modifier.CellModifierInput._format_tree`. +The tree is formatted by ``_format_tree()``. :func:`~montepy.data_inputs.cell_modifier.CellModifierInput.merge` """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -542,7 +542,7 @@ One use case for this is combining the data from: ``IMP:N,P=1 IMP:E=0.5`` into o so there's no redundant data. This will automatically be called by the loading hooks, and you do not need to worry about deleting other. -If merging isn't allowed :class:`~montepy.errors.MalformedInputError` should be raised. +If merging isn't allowed :exc:`~montepy.exceptions.MalformedInputError` should be raised. :func:`~montepy.data_inputs.cell_modifier.CellModifierInput.push_to_cells` @@ -552,8 +552,8 @@ This is how data provided in the data block are provided to the ``Cell`` objects There should be a ``self.in_cell_block`` guard. You need to check that there was no double specifying of data in both the cell and data block. -This should be raise :class:`~montepy.errors.MalformedInputError`. -This checking and error handling is handled by the method :func:`~montepy.data_inputs.cell_modifier.CellModifierInput._check_redundant_definitions`. +This should be raise :exc:`~montepy.exceptions.MalformedInputError`. +This checking and error handling is handled by the method ``_check_redundant_definitions()``. :func:`~montepy.data_inputs.cell_modifier.CellModifierInput._clear_data` """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -563,11 +563,11 @@ The goal is to delete any internal data that has already been pushed to the cell so that if a user goes crazy and somehow access this object they cannot modify the data, and get into weird end-use behavior. -:func:`~montepy.mcnp_problem.MCNP_Problem.print_in_data_block` +:attr:`~montepy.MCNP_Problem.print_in_data_block` """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" There is a flag system for controlling if data are output in the cell block or the data block. -This is controlled by :func:`~montepy.mcnp_problem.MCNP_Problem.print_in_data_block`. +This is controlled by :attr:`~montepy.MCNP_Problem.print_in_data_block`. This acts like a dictionary. The key is the string prefix that mcnp uses but is case insensitive. So controlling the printing of ``cell.importance`` data is handled by: @@ -606,7 +606,7 @@ It has had to implement some janky metaclass properties in order to allow subcla First, read the `SLY Documentation `_. You should also be aware of the tokens that are available. -See the tokens module: :mod:`montepy.input_parser.tokens` for what tokens are available. +See the tokens module: ``montepy.input_parser.tokens`` for what tokens are available. The tokenization process is slightly contextual. The context is only changed by the :class:`~montepy.input_parser.block_type.BlockType`. The lexers used are: @@ -697,13 +697,13 @@ Constants and Meta Data Structures MontePy uses constants and data structures to utilize meta-programming and remove redundant code. -Typical constants can be found in :mod:`montepy.constants`. +Typical constants can be found in ``montepy.constants``. Here are the other data structures to be aware of: -* :class:`~montepy.mcnp_problem.MCNP_Problem` ``_NUMBERED_OBJ_MAP``: maps a based numbered object to its collection +* :class:`~montepy.MCNP_Problem` ``_NUMBERED_OBJ_MAP``: maps a based numbered object to its collection class. This is used for loading all problem numbered object collections in an instance. -* :func:`montepy.data_inputs.data_parser.PREFIX_MATCHES` is a set of the data object classes. The prefix is taken from +* ``PREFIX_MATCHES`` is a set of the data object classes. The prefix is taken from the classes. A data object must be a member of this class for it to automatically parse new data objects. -* :class:`~montepy.cell.Cell` ``_INPUTS_TO_PROPERTY`` maps a cell modifier class to the attribute to load it into for a +* :class:`~montepy.Cell` ``_INPUTS_TO_PROPERTY`` maps a cell modifier class to the attribute to load it into for a cell. The boolean is whether multiple input instances are allowed. diff --git a/doc/source/migrations/migrate0_1.rst b/doc/source/migrations/migrate0_1.rst index 3a88c3270..c2ba612ff 100644 --- a/doc/source/migrations/migrate0_1.rst +++ b/doc/source/migrations/migrate0_1.rst @@ -30,7 +30,7 @@ Deprecations The following properties and objects are currently deprecated and were removed in MontePy 1.0.0. -* :func:`~montepy.data_inputs.material.Material.material_components`. +* :attr:`~montepy.Material.material_components`. This is the dictionary that caused this design problem. * :class:`~montepy.data_inputs.material_component.MaterialComponent`: @@ -38,7 +38,7 @@ and were removed in MontePy 1.0.0. It was largely excess object wrapping that made the material interface overly complex. -* :class:`~montepy.data_inputs.isotope.Isotope` was renamed to :class:`~montepy.data_inputs.nuclide.Nuclide`. +* :class:`~montepy.data_inputs.isotope.Isotope` was renamed to :class:`~montepy.Nuclide`. This is to better align with MCNP documentation and to better reflect that the nuclear data for a nuclide can represent isotopic, isomeric, or atomic data. @@ -48,7 +48,7 @@ New Interface & Migration ------------------------- For more details, see the new :ref:`mat_tutorial` tutorial in the getting started guide, -as well as the example in the :class:`~montepy.data_inputs.material.Material` documentation. +as well as the example in the :class:`~montepy.Material` documentation. .. note:: @@ -61,7 +61,7 @@ as well as the example in the :class:`~montepy.data_inputs.material.Material` do ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Material composition data has moved from ``Material.material_components`` to the -:class:`~montepy.data_inputs.material.Material` itself. +:class:`~montepy.Material` itself. ``Material`` is now a list-like iterable. It is a list of tuples which are ``(nuclide, fraction)`` pairs. @@ -80,19 +80,19 @@ Searching Components ^^^^^^^^^^^^^^^^^^^^ Finding a specific ``Nuclide`` in a ``Material`` is now much easier. -First, there is a :func:`~montepy.data_inputs.material.Material.find` method that takes either a ``Nuclide`` string, +First, there is a :func:`~montepy.Material.find` method that takes either a ``Nuclide`` string, or various over search criteria (e.g., ``element``), and creates a generator of all matching component tuples. If you want to check if a ``Material`` contains a specific ``Nuclide`` you can simply test ``nuclide in material``. -The :func:`~montepy.data_inputs.material.Material.contains` function will provide more options, +The :func:`~montepy.Material.contains_all` function will provide more options, such as setting a minimum threshold and testing for multiple nuclides at once. Adding Nuclides ^^^^^^^^^^^^^^^ -Adding a new nuclide is easiest with the :func:`~montepy.data_inputs.material.Material.add_nuclide` function. +Adding a new nuclide is easiest with the :func:`~montepy.Material.add_nuclide` function. Editing Nuclide Composition ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,8 +101,8 @@ Editing a material composition will be very similar to editing a ``list``. Existing components can be set to a nuclide component nuclide. Also existing components can be deleted with ``del``. For just editing the fractions or nuclides the functions: -:func:`~montepy.data_inputs.material.Material.nuclides` -and :func:`~montepy.data_inputs.material.Material.values` provide the easiest interface. +:attr:`~montepy.Material.nuclides` +and :attr:`~montepy.Material.values` provide the easiest interface. ``Isotope`` Deprecation and Removal @@ -111,12 +111,12 @@ and :func:`~montepy.data_inputs.material.Material.values` provide the easiest in The decision was made to remove the name :class:`montepy.data_inputs.isotope.Isotope`. This is because not all material components are an isotope, they may be an isomer, or event an element. -Rather the MCNP generalized terminology of :class:`montepy.data_inputs.nuclide.Nuclide` was adopted. +Rather the MCNP generalized terminology of :class:`montepy.Nuclide` was adopted. The idea of a specific nuclide, e.g., ``H-1`` was separated from an MCNP material component e.g., ``1001.80c``. -The actual ``Nuclide`` information was moved to a new class: :class:`~montepy.data_inputs.nuclide.Nucleus` +The actual ``Nuclide`` information was moved to a new class: :class:`~montepy.Nucleus` that is immutable. -The :class:`~montepy.data_inputs.nuclide.Nuclide` wraps this and adds a :class:`~montepy.data_inputs.nuclide.Library` object to specify the nuclear data that is used. +The :class:`~montepy.Nuclide` wraps this and adds a :class:`~montepy.Library` object to specify the nuclear data that is used. It makes sense to be able to change a library. It does not make sense to change the intrinsic properties of a nuclide (i.e., ``Z``, ``A``, etc.). diff --git a/doc/source/starting.rst b/doc/source/starting.rst index 63ddb8af6..95dade4d3 100644 --- a/doc/source/starting.rst +++ b/doc/source/starting.rst @@ -152,7 +152,7 @@ Reading a File -------------- MontePy offers the :func:`montepy.read_input` (actually :func:`~montepy.input_parser.input_reader.read_input`) function for getting started. -It will read the specified MCNP input file, and return an MontePy :class:`~montepy.mcnp_problem.MCNP_Problem` object. +It will read the specified MCNP input file, and return an MontePy :class:`~montepy.MCNP_Problem` object. >>> import montepy >>> problem = montepy.read_input("tests/inputs/test.imcnp") @@ -162,13 +162,13 @@ It will read the specified MCNP input file, and return an MontePy :class:`~monte Writing a File -------------- -The :class:`~montepy.mcnp_problem.MCNP_Problem` object has -the method :func:`~montepy.mcnp_problem.MCNP_Problem.write_problem`, which writes the problem's current +The :class:`~montepy.MCNP_Problem` object has +the method :func:`~montepy.MCNP_Problem.write_problem`, which writes the problem's current state as a valid MCNP input file. >>> problem.write_problem("bar.imcnp") -The :func:`~montepy.mcnp_problem.MCNP_Problem.write_problem` method does take an optional argument: ``overwrite``. +The :func:`~montepy.MCNP_Problem.write_problem` method does take an optional argument: ``overwrite``. By default if the file exists, it will not be overwritten and an error will be raised. This can be changed by ``overwrite=True``. @@ -179,7 +179,7 @@ This can be changed by ``overwrite=True``. Instead of constantly having to override the same file you can add a timestamp to the output file, or create an always unique file name with the `UUID `_ library. -The method :func:`~montepy.mcnp_problem.MCNP_Problem.write_problem` +The method :func:`~montepy.MCNP_Problem.write_problem` also accepts an open file handle, stream, or other object with a ``write()`` method. >>> with open("foo_bar.imcnp", "w") as fh: @@ -283,7 +283,7 @@ Information Lost What a Problem Looks Like ------------------------- -The :class:`~montepy.mcnp_problem.MCNP_Problem` is the object that represents an MCNP input file/problem. +The :class:`~montepy.MCNP_Problem` is the object that represents an MCNP input file/problem. The meat of the Problem is its collections, such as ``cells``, ``surfaces``, and ``materials``. Technically these are :class:`~montepy.numbered_object_collection.NumberedObjectCollection` instances, but it looks like a ``dict``, walks like a ``dict``, and quacks like ``dict``, so most users can just treat it like that. @@ -302,7 +302,7 @@ Collections are Accessible by Number As mentioned before :class:`~montepy.numbered_object_collection.NumberedObjectCollection` looks like a ``dict``, walks like a ``dict``, and quacks like ``dict``. -This mainly means you can quickly get an object (e.g., :class:`~montepy.cell.Cell`, :class:`~montepy.surfaces.surface.Surface`, :class:`~montepy.data_cards.material.Material`) +This mainly means you can quickly get an object (e.g., :class:`~montepy.Cell`, :class:`~montepy.Surface`, :class:`~montepy.Material`) by its number. So say you want to access cell 2 from a problem it is accessible quickly by: @@ -459,9 +459,9 @@ Cloning Objects In the past the only way to make a copy of a MontePy object was with `copy.deepcopy `_. In MontePy 0.5.0 a better way was introduced: :func:`~montepy.mcnp_object.MCNP_Object.clone`. -How numbered objects, for instance :class:`~montepy.cell.Cell`, is more complicated. +How numbered objects, for instance :class:`~montepy.Cell`, is more complicated. If a ``Cell`` or a group of ``Cells`` are cloned their numbers will be to changed to avoid collisions. -However, if a whole :class:`~montepy.mcnp_problem.MCNP_Problem` is cloned these objects will not have their numbers changed. +However, if a whole :class:`~montepy.MCNP_Problem` is cloned these objects will not have their numbers changed. For an example for how to clone a numbered object see :ref:`Cloning a Cell`. Creating Objects from a String @@ -514,7 +514,7 @@ and for data inputs this is :func:`~montepy.data_inputs.data_parser.parse_data`. This object is still unlinked from other objects, and won't be kept with a problem. -So there is also :func:`~montepy.mcnp_problem.MCNP_Problem.parse`. +So there is also :func:`~montepy.MCNP_Problem.parse`. This takes a string, and then creates the MCNP object, links it to the problem, links it to its other objects (e.g., surfaces, materials, etc.), @@ -534,19 +534,19 @@ Surfaces The most important unsung heroes of an MCNP problem are the surfaces. They may be tedious to work with but you can't get anything done without them. MCNP supports *a lot* of types of surfaces, and all of them are special in their own way. -You can see all the surface types here: :class:`~montepy.surfaces.surface_type.SurfaceType`. -By default all surfaces are an instance of :class:`~montepy.surfaces.surface.Surface`. +You can see all the surface types here: :class:`~montepy.SurfaceType`. +By default all surfaces are an instance of :class:`~montepy.Surface`. They will always have the properties: ``surface_type``, and ``surface_constants``. If you need to modify the surface you can do so through the ``surface_constants`` list. But for some of our favorite surfaces (``CX``, ``CY``, ``CZ``, ``C\X``, ``C\Y``, ``C\Z``, ``PX``, ``PY``, ``PZ``), these will be a special subclass of ``Surface``, that will truly understand surface constants for what the mean. -See :mod:`montepy.surfaces` for specific classes, and their documentation. +See the :doc:`API documentation ` for specific surface classes and their documentation. -Two useful examples are the :class:`~montepy.surfaces.cylinder_on_axis.CylinderOnAxis`, +Two useful examples are the :class:`~montepy.CylinderOnAxis`, which covers ``CX``, ``CY``, and ``CZ``, -and the :class:`~montepy.surfaces.axis_plane.AxisPlane`, +and the :class:`~montepy.AxisPlane`, which covers ``PX``, ``PY``, ``PZ``. The first contains the parameter: ``radius``, and the second one contains the parameters: ``location``. @@ -559,7 +559,7 @@ So there is a convenient way to update a surface, but how do you easily get the For instance what if you want to shift a cell up in Z by 10 cm? It would be horrible to have to get each surface by their number, and hoping you don't change the numbers along the way. -The :class:`~montepy.surface_collection.Surfaces` collection has a generator for every type of surface in MCNP. +The :class:`~montepy.Surfaces` collection has a generator for every type of surface in MCNP. These are very easy to find: they are just the lower case version of the MCNP surface mnemonic. This previous code is much simpler now: @@ -586,8 +586,8 @@ As discussed in :manual63:`5.3.1`, surfaces can have three boundary conditions: Refer to the :ref:`CellImportance` section to see how to set these. The reflective and white boundary conditions are easiest to set as they are Boolean conditions. -These are controlled by :func:`~montepy.surfaces.surface.Surface.is_reflecting` and -:func:`~montepy.surfaces.surface.Surface.is_white_boundary` respectively. +These are controlled by :attr:`~montepy.Surface.is_reflecting` and +:attr:`~montepy.Surface.is_white_boundary` respectively. For Example: .. testcode:: @@ -604,7 +604,7 @@ For Example: Setting a Periodic boundary is slightly more difficult. -In this case the boundary condition must be set to the other periodic surface with :func:`~montepy.surfaces.surface.Surface.periodic_surface`. +In this case the boundary condition must be set to the other periodic surface with :attr:`~montepy.Surface.periodic_surface`. So to continue with the previous example: .. testcode:: @@ -627,7 +627,7 @@ Setting Cell Importances ^^^^^^^^^^^^^^^^^^^^^^^^ All cells have an importance that can be modified. -This is generally accessed through ``cell.importance`` (:func:`~montepy.cell.Cell.importance`). +This is generally accessed through ``cell.importance`` (:attr:`~montepy.Cell.importance`). You can access the importance for a specific particle type by its name in lower case. For example: ``cell.importance.neutron`` or ``cell.importance.photon``. For a complete list see :class:`~montepy.particle.Particle`. @@ -664,7 +664,7 @@ This will set the importances for the neutron and photon. You can also delete an importance to reset it to the default value (1.0). For example: ``del cell.importance.neutron``. -There is also the method: :func:`~montepy.cells.Cells.set_equal_importance`. +There is also the method: :func:`~montepy.Cells.set_equal_importance`. This method sets all of the cells for all particles in the problem to the same importance. You can optionally pass a list of cells to this function. These cells are the "vacuum boundary" or "graveyard" cells. @@ -678,14 +678,14 @@ Setting How Cell Data Gets displayed in the Input file Much of the cell data can show up in the cell block or the data block, like the importance card. These are referred to MontePy as "cell modifiers". -You can change how these cell modifiers are printed with :func:`~montepy.mcnp_problem.MCNP_Problem.print_in_data_block`. +You can change how these cell modifiers are printed with :attr:`~montepy.MCNP_Problem.print_in_data_block`. This acts like a dictionary where the key is the MCNP card name. So to make cell importance data show up in the cell block just run: ``problem.print_in_data_block["imp"] = False``. .. note:: - The default for :func:`~montepy.mcnp_problem.MCNP_Problem.print_in_data_block` is ``False``, + The default for :attr:`~montepy.MCNP_Problem.print_in_data_block` is ``False``, that is to print the data in the cell block if this was not set in the input file or by the user. Density @@ -733,7 +733,7 @@ Terminology In MCNP the geometry of a cell can by defined by either a surface, or another cell (through complements). Therefore, it's not very useful to talk about geometry in terms of "surfaces" because it's not accurate and could lead to confusion. MontePy focuses mostly on the mathematical concept of `half-spaces `_. -These are represented as :class:`~montepy.surfaces.half_space.HalfSpace` instances. +These are represented as :class:`~montepy.HalfSpace` instances. The use of this term is a bit loose and is not meant to be mathematical rigorous. The general concept though is that the space (R\ :sup:`3`) can always be split into two regions, or half-spaces. For MontePy this division is done by a divider ( a surface, a cell, or some CSG combination of thoses). @@ -743,7 +743,7 @@ The two half-spaces can be viewed as in or out of the cell. So how are these half-spaces identified? In MCNP this generally done by marking the half-space as the positive or negative one. -In MontePy these are changed to boolean values for the :func:`~montepy.surfaces.half_space.UnitHalfSpace.side` parameter simplicity with True being the positive side. +In MontePy these are changed to boolean values for the :attr:`~montepy.UnitHalfSpace.side` parameter simplicity with True being the positive side. For cell complements the side is implicitly handled by the CSG logic, and can always be thought of as the "outside" (though ``side`` will return True). @@ -753,7 +753,7 @@ Creating a Half-Space To make a geometry you can't just start with a divider (e.g., a surface), and just expect the geometry to be unambiguous. This is because you need to choose a half-space from the divider. This is done very simply and pythonic. -For a :class:`~montepy.surfaces.surface.Surface` you just need to mark the surface as positive (``+``) or negative (``-``) (using the unary operators). +For a :class:`~montepy.Surface` you just need to mark the surface as positive (``+``) or negative (``-``) (using the unary operators). This actually creates a new object so don't worry about modifying the surface. .. doctest:: @@ -844,7 +844,7 @@ Order of precedence and grouping is automatically handled by Python so you can e Setting and Modifying Geometry """""""""""""""""""""""""""""" -The half-space defining a cell's geometry is stored in ``cell.geometry`` (:func:`~montepy.cell.Cell.geometry`). +The half-space defining a cell's geometry is stored in ``cell.geometry`` (:attr:`~montepy.Cell.geometry`). This property can be rather simply set. .. testcode:: @@ -881,8 +881,8 @@ This will completely redefine the cell's geometry. You can also modify the geome Cloning a Cell ^^^^^^^^^^^^^^ -When a cell is cloned with :func:`~montepy.cell.Cell.clone` a new number will be assigned. -If the cell is linked to a problem---either through being added to :class:`~montepy.cells.Cells`, or with :func:`~montepy.cell.Cell.link_to_problem`--- +When a cell is cloned with :func:`~montepy.Cell.clone` a new number will be assigned. +If the cell is linked to a problem---either through being added to :class:`~montepy.Cells`, or with :func:`~montepy.Cell.link_to_problem`--- the next available number in the problem will be used. Otherwise the ``starting_number`` will be used unless that is the original cell's number. How the number is picked is controlled by ``starting_number`` and ``step``. @@ -925,8 +925,8 @@ For example, if you have a problem read in already: >>> new_cell.material is cell.material False -When children objects (:class:`~montepy.data_inputs.material.Material`, :class:`~montepy.surfaces.surface.Surface`, and :class:`~montepy.cell.Cell`) -are cloned the numbering behavior is defined by the problem's instance's instance of the respective collection (e.g., :class:`~montepy.materials.Materials`) +When children objects (:class:`~montepy.Material`, :class:`~montepy.Surface`, and :class:`~montepy.Cell`) +are cloned the numbering behavior is defined by the problem's instance's instance of the respective collection (e.g., :class:`~montepy.Materials`) by the properties: :func:`~montepy.numbered_object_collection.NumberedObjectCollection.starting_number` and :func:`~montepy.numbered_object_collection.NumberedObjectCollection.step`. For example: @@ -953,15 +953,15 @@ Specifying Nuclides ^^^^^^^^^^^^^^^^^^^ To specify a material, one needs to be able to specify the nuclides that are contained in it. -This is done through :class:`~montepy.data_inputs.nuclide.Nuclide` objects. -This actually a wrapper of a :class:`~montepy.data_inputs.nuclide.Nucleus` and a :class:`~montepy.data_inputs.nuclide.Library` object. +This is done through :class:`~montepy.Nuclide` objects. +This actually a wrapper of a :class:`~montepy.Nucleus` and a :class:`~montepy.Library` object. Users should rarely need to interact with the latter two objects, but it is good to be aware of them. The general idea is that a ``Nuclide`` instance represents a specific set of ACE data that for a ``Nucleus``, which represents only a physical nuclide with a given ``Library``. The easiest way to specify a Nuclide is by its string name. MontePy supports all valid MCNP ZAIDs for MCNP 6.2, and MCNP 6.3.0. -See :class:`~montepy.data_inputs.nuclide.Nuclide` for how metastable isomers are handled. +See :class:`~montepy.Nuclide` for how metastable isomers are handled. However, ZAIDs (like many things in MCNP) are cumbersome. Therefore, MontePy also supports its own nuclide names as well, which are meant to be more intuitive. These are very similar to the names introduced with MCNP 6.3.1 (section 1.2.2): this follows: @@ -1025,8 +1025,8 @@ This shows: (Nuclide('U-238.80c'), 95.0) If you need just the nuclide or just the fractions, these are accessible by: -:func:`~montepy.data_inputs.material.Material.nuclides` and -:func:`~montepy.data_inputs.material.Material.values`, respectively. +:attr:`~montepy.Material.nuclides` and +:attr:`~montepy.Material.values`, respectively. .. testcode:: @@ -1058,8 +1058,8 @@ For instance: mat[0] = (nuclide, 4.0) Generally this is pretty clunky, so -:func:`~montepy.data_inputs.material.Material.nuclides` and -:func:`~montepy.data_inputs.material.Material.values` are also settable. +:attr:`~montepy.Material.nuclides` and +:attr:`~montepy.Material.values` are also settable. To undo the previous changes: .. testcode:: @@ -1077,16 +1077,16 @@ Adding Components to a Material """"""""""""""""""""""""""""""" To add components to a material use either -:func:`~montepy.data_inputs.material.Material.add_nuclide`, or -:func:`~montepy.data_inputs.material.Material.append`. -:func:`~montepy.data_inputs.material.Material.add_nuclide` is generally the easier method to use. +:func:`~montepy.Material.add_nuclide`, or +:func:`~montepy.Material.append`. +:func:`~montepy.Material.add_nuclide` is generally the easier method to use. It accepts a nuclide or the name of a nuclide, and its fraction. .. note:: When adding a new component it is not possible to change whether the fraction is in atom fraction or mass fraction. - This is settable through :func:`~montepy.data_inputs.material.Material.is_atom_fraction`. + This is settable through :attr:`~montepy.Material.is_atom_fraction`. .. testcode:: @@ -1111,11 +1111,11 @@ and for different data needs, e.g., neutron data vs. photo-atomic data. For more details see `LA-UR-17-20709 `_, or `LANL's nuclear data libraries `_. -All :class:`~montepy.data_inputs.nuclide.Nuclide` have a :class:`~montepy.data_inputs.nuclide.Nuclide.library`, +All :class:`~montepy.Nuclide` have a :attr:`~montepy.Nuclide.library`, though it may be just ``""``. These can be manually set for each nuclide. If you wish to change all of the components in a material to use the same library you can use -:func:`~montepy.data_inputs.material.Material.change_libraries`. +:func:`~montepy.Material.change_libraries`. MCNP has a precedence system for determining which library use in a specific instance. This precedence order is: @@ -1131,7 +1131,7 @@ This precedence order is: that final step. Which library will be used for a given nuclide, material, and problem can be checked with: -:func:`~montepy.data_inputs.material.Material.get_nuclide_library`. +:func:`~montepy.Material.get_nuclide_library`. .. seealso:: @@ -1152,8 +1152,8 @@ Next, we will cover how to find if Check if Nuclide in Material """""""""""""""""""""""""""" -First, you can test if a :class:`~montepy.data_inputs.nuclide.Nuclide` -(or :class:`~montepy.data_inputs.nuclide.Nucleus`, or :class:`~montepy.data_inputs.element.Element`, or ``str``), +First, you can test if a :class:`~montepy.Nuclide` +(or :class:`~montepy.Nucleus`, or :class:`~montepy.Element`, or ``str``), is in a material. This is generally interpreted broadly rather than explicitly. For instance, if the test nuclide has no library this will match @@ -1174,8 +1174,8 @@ on the element, not just the elemental nuclide. >>> montepy.Nuclide("B-0") in mat True -For more complicated checks there is the :func:`~montepy.data_inputs.material.Material.contains_all`, and -:func:`~montepy.data_inputs.material.Material.contains_any`. +For more complicated checks there is the :func:`~montepy.Material.contains_all`, and +:func:`~montepy.Material.contains_any`. These functions take a plurality of nuclides as well as a threshold. The function ``contains_all`` returns ``True`` if and only if the material contains *all* nuclides with a fraction above the threshold. @@ -1201,7 +1201,7 @@ Finding Nuclides """""""""""""""" Often you may need to only work a subset of the components in a material. -:func:`~montepy.data_inputs.material.Material.find`. +:func:`~montepy.Material.find`. This returns a Generator of the index of the matching component, and then the component tuple. .. testcode:: @@ -1216,9 +1216,9 @@ This returns a Generator of the index of the matching component, and then the co 1 U-238 (80c) 95.0 There are also other fancy ways to pass slices, for instance to find all transuranics. -See the examples in :func:`~montepy.data_inputs.material.Material.find` for more details. +See the examples in :func:`~montepy.Material.find` for more details. -There is a related function as well :func:`~montepy.data_inputs.material.Material.find_vals`, +There is a related function as well :func:`~montepy.Material.find_vals`, which accepts the same arguments but only returns the matching fractions. This is great for instance to calculate the heavy metal fraction of a fuel: @@ -1239,9 +1239,9 @@ Finding Materials There are a lot of cases where you may want to find specific materials in a problem, for instance getting all steels in a problem. -This is done with the function :func:`~montepy.materials.Materials.get_containing` -of :class:`~montepy.materials.Materials`. -It takes the same arguments as :func:`~montepy.data_inputs.material.Material.contains` +This is done with the function :func:`~montepy.Materials.get_containing_all` +of :class:`~montepy.Materials`. +It takes the same arguments as :func:`~montepy.Material.contains_all` previously discussed. Mixing Materials @@ -1251,7 +1251,7 @@ Commonly materials are a mixture of other materials. For instance a good idea for defining structural materials might be to create a new material for each element, that adds the naturally occurring nuclides of the element, and then mixing those elements together to make steel, zircaloy, etc. -This mixing is done with :class:`~montepy.materials.Materials.mix`. +This mixing is done with :func:`~montepy.Materials.mix`. Note this is a method of ``Materials`` and not ``Material``. .. note:: @@ -1289,7 +1289,7 @@ Universes MontePy supports MCNP universes as well. ``problem.universes`` will contain all universes in a problem. -These are stored in :class:`~montepy.universes.Universes` as :class:`~montepy.universe.Universe` instances. +These are stored in :class:`~montepy.universes.Universes` as :class:`~montepy.Universe` instances. If a cell is not assigned to any universe it will be assigned to Universe 0, *not None*, while reading in the input file. To change what cells are in a universe you can set this at the cell level. This is done to prevent a cell from being assigned to multiple universes @@ -1311,7 +1311,7 @@ We can confirm this worked with the generator ``universe.cells``: Claiming Cells ^^^^^^^^^^^^^^ -The ``Universe`` class also has the method: :func:`~montepy.universe.Universe.claim`. +The ``Universe`` class also has the method: :func:`~montepy.Universe.claim`. This is a shortcut to do the above code. For all cells passed (either as a single ``Cell``, a ``list`` of cells, or a ``Cells`` instance) will be removed from their current universe, and moved to this universe. @@ -1352,7 +1352,7 @@ Filling Cells ^^^^^^^^^^^^^ What's the point of creating a universe if you can't fill a cell with it, and therefore use it? -Filling is handled by the :class:`~montepy.data_cards.fill.Fill` object in ``cell.fill``. +Filling is handled by the :class:`~montepy.data_inputs.fill.Fill` object in ``cell.fill``. To fill a cell with a specific universe you can just run: @@ -1387,9 +1387,9 @@ References See the following cell properties for more details: -* :func:`~montepy.cell.Cell.universe` -* :func:`~montepy.cell.Cell.lattice` -* :func:`~montepy.cell.Cell.fill` +* :attr:`~montepy.Cell.universe` +* :attr:`~montepy.Cell.lattice` +* :attr:`~montepy.Cell.fill` Running as an Executable ------------------------ diff --git a/montepy/__init__.py b/montepy/__init__.py index a8d15bca6..72146cb06 100644 --- a/montepy/__init__.py +++ b/montepy/__init__.py @@ -18,7 +18,8 @@ from montepy.data_inputs.material import Material from montepy.data_inputs.transform import Transform -from montepy.data_inputs.nuclide import Library, Nuclide +from montepy.data_inputs.nuclide import Library, Nuclide, Nucleus +from montepy._singleton import SingletonGroup from montepy.data_inputs.element import Element from montepy.data_inputs.lattice import LatticeType from montepy.data_inputs import Mode @@ -50,6 +51,14 @@ import montepy.exceptions import montepy.errors # deprecated + +# Ensure re-exported classes resolve to the top-level montepy path in autodoc +# rather than their canonical module path (e.g. montepy.data_inputs.nuclide.Library). +# This avoids nitpick warnings for classes accessible as montepy.Library etc. +Library.__module__ = "montepy" +LibraryType.__module__ = "montepy" +Nucleus.__module__ = "montepy" +SingletonGroup.__module__ = "montepy" import sys try: diff --git a/montepy/cell.py b/montepy/cell.py index f9f1ed66e..a2139cc0d 100644 --- a/montepy/cell.py +++ b/montepy/cell.py @@ -395,7 +395,7 @@ def volume_mcnp_calc(self): This does not guarantee that MCNP will able to calculate the volume. Complex geometries may make this impossible. - See :func:`~montepy.cells.Cells.allow_mcnp_volume_calc` + See :attr:`~montepy.Cells.allow_mcnp_volume_calc` Returns ------- @@ -603,7 +603,7 @@ def parameters(self, params): def complements(self): """The Cell objects that this cell is a complement of - :rytpe: :class:`montepy.cells.Cells` + :rtype: :class:`montepy.Cells` """ return self._complements @@ -654,7 +654,7 @@ def remove_duplicate_surfaces(self, deleting_dict): .. versionchanged:: 1.0.0 - The form of the deleting_dict was changed as :class:`~montepy.surfaces.Surface` is no longer hashable. + The form of the deleting_dict was changed as :class:`~montepy.Surface` is no longer hashable. Parameters ---------- diff --git a/montepy/cells.py b/montepy/cells.py index 85cb360aa..3320c0962 100644 --- a/montepy/cells.py +++ b/montepy/cells.py @@ -7,7 +7,7 @@ class Cells(NumberedObjectCollection): - """A collections of multiple :class:`montepy.cell.Cell` objects. + """A collections of multiple :class:`montepy.Cell` objects. This collection can be sliced to get a subset of the cells. Slicing is done based on the cell numbers, not their order in the input. @@ -64,7 +64,7 @@ def __setup_blank_cell_modifiers(self, problem=None, check_input=False): raise e def set_equal_importance(self, importance, vacuum_cells=tuple()): - """Sets all cells except the vacuum cells to the same importance using :func:`montepy.data_cards.importance.Importance.all`. + """Sets all cells except the vacuum cells to the same importance using :attr:`montepy.data_inputs.importance.Importance.all`. The "vacuum" cells are those on the outside of a vacuum boundary condition, i.e., the "graveyard". That is to say, their importance will be set to 0.0. You can specify cell numbers or cell objects. diff --git a/montepy/data_inputs/cell_modifier.py b/montepy/data_inputs/cell_modifier.py index 36a724bb2..ae9629b34 100644 --- a/montepy/data_inputs/cell_modifier.py +++ b/montepy/data_inputs/cell_modifier.py @@ -133,7 +133,7 @@ def push_to_cells(self): @property @abstractmethod def has_information(self): - """For a cell instance of :class:`montepy.data_cards.cell_modifier.CellModifierCard` returns True iff there is information here worth printing out. + """For a cell instance of :class:`montepy.data_inputs.cell_modifier.CellModifierInput` returns True iff there is information here worth printing out. e.g., a manually set volume for a cell @@ -208,7 +208,7 @@ def _tree_value(self): def _collect_new_values(self): """Gets a list of the ValueNodes that hold the information for all cells. - This will be a list in the same order as :func:`montepy.mcnp_problem.MCNP_Problem.cells`. + This will be a list in the same order as :attr:`montepy.MCNP_Problem.cells`. Returns ------- diff --git a/montepy/data_inputs/fill.py b/montepy/data_inputs/fill.py index 29bfabc13..2bfba373c 100644 --- a/montepy/data_inputs/fill.py +++ b/montepy/data_inputs/fill.py @@ -348,7 +348,7 @@ def universes(self): Parameters ---------- value : np.ndarray or None - A 3D numpy array of :class:`~montepy.universe.Universe` objects, + A 3D numpy array of :class:`~montepy.Universe` objects, a 3D numpy array of integer universe IDs, or None to clear the universes. Arrays with 0, 1, or 2 dimensions are automatically expanded to 3D by adding dimensions at the end. @@ -430,7 +430,7 @@ def min_index(self): Returns ------- - :class:`numpy.ndarry` + :class:`numpy.ndarray` the minimum indices of the matrix for complex fills """ pass @@ -448,7 +448,7 @@ def max_index(self): Returns ------- - :class:`numpy.ndarry` + :class:`numpy.ndarray` the maximum indices of the matrix for complex fills """ pass diff --git a/montepy/data_inputs/isotope.py b/montepy/data_inputs/isotope.py index 4b7669fb3..303378d46 100644 --- a/montepy/data_inputs/isotope.py +++ b/montepy/data_inputs/isotope.py @@ -3,7 +3,7 @@ class Isotope: .. deprecated:: 0.4.1 - This will class is deprecated, and has been renamed: :class:`~montepy.data_inputs.nuclide.Nuclide`. + This will class is deprecated, and has been renamed: :class:`~montepy.Nuclide`. For more details see the :ref:`migrate 0 1`. Raises diff --git a/montepy/data_inputs/lattice.py b/montepy/data_inputs/lattice.py index 43295f3c5..04e3cd50e 100644 --- a/montepy/data_inputs/lattice.py +++ b/montepy/data_inputs/lattice.py @@ -7,12 +7,9 @@ class LatticeType(Enum): """Represents the options for the lattice ``LAT``.""" RECTANGULAR = 1 - """A rectangular prism is a type of hexahedron: solid with six faces.""" + """Rectangular hexahedral lattice type (a solid with six rectangular faces).""" HEXAHEDRAL = RECTANGULAR - """Hexhedra are solids with six faces. - - One such solid is a rectangular prism. - """ + """Alias for :attr:`RECTANGULAR`; hexahedra are solids with six faces.""" HEXAGONAL = 2 """Hexagonal prisms are solids with eight faces.""" diff --git a/montepy/data_inputs/material.py b/montepy/data_inputs/material.py index 952abcb5c..82dda33d6 100644 --- a/montepy/data_inputs/material.py +++ b/montepy/data_inputs/material.py @@ -174,7 +174,7 @@ class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): Materials look like a list of tuples, and is iterable. Whether or not the material is defined in mass fraction or atom fraction - is stored for the whole material in :func:`~montepy.data_inputs.material.Material.is_atom_fraction`. + is stored for the whole material in :attr:`~montepy.Material.is_atom_fraction`. The fractions (atom or mass) of the componenets are always positive, because MontePy believes in physics. @@ -206,7 +206,7 @@ class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): You can check if a Nuclide is in a Material ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - You can check if a :class:`~montepy.data_inputs.nuclide.Nuclide` or :class:`~montepy.data_input.element.Element` is + You can check if a :class:`~montepy.Nuclide` or :class:`~montepy.Element` is in a Material with ``in``. .. doctest:: @@ -224,7 +224,7 @@ class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): ^^^^^^^^^^^^^^^^^ The easiest way to add new components to a material is with - :func:`~montepy.data_inputs.material.Material.add_nuclide`. + :func:`~montepy.Material.add_nuclide`. .. testcode:: @@ -244,12 +244,12 @@ class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): Default Libraries ^^^^^^^^^^^^^^^^^ - Also materials have the concept of :func:`~montepy.data_inputs.material.Material.default_libraries`. + Also materials have the concept of :attr:`~montepy.Material.default_libraries`. These are the libraries set by ``NLIB``, ``PLIB``, etc., - which are used when a library of the correct :class:`~montepy.particle.LibraryType` is not provided with the + which are used when a library of the correct :class:`~montepy.LibraryType` is not provided with the nuclide. - :func:`~montepy.data_inputs.material.Material.default_libraries` acts like a dictionary, - and can accept a string or a :class:`~montepy.particle.LibraryType` as keys. + :attr:`~montepy.Material.default_libraries` acts like a dictionary, + and can accept a string or a :class:`~montepy.LibraryType` as keys. .. testcode:: @@ -429,12 +429,12 @@ def default_libraries(self): Default Libraries ^^^^^^^^^^^^^^^^^ - Also materials have the concept of :func:`~montepy.data_inputs.material.Material.default_libraries`. + Also materials have the concept of :attr:`~montepy.Material.default_libraries`. These are the libraries set by ``NLIB``, ``PLIB``, etc., - which are used when a library of the correct :class:`~montepy.particle.LibraryType` is not provided with the + which are used when a library of the correct :class:`~montepy.LibraryType` is not provided with the nuclide. - :func:`~montepy.data_inputs.material.Material.default_libraries` acts like a dictionary, - and can accept a string or a :class:`~montepy.particle.LibraryType` as keys. + :attr:`~montepy.Material.default_libraries` acts like a dictionary, + and can accept a string or a :class:`~montepy.LibraryType` as keys. .. testcode:: @@ -462,9 +462,9 @@ def get_nuclide_library( #. The library extension for the nuclide. For example if the nuclide is ``1001.80c`` for ``LibraryType("nlib")``, ``Library("80c")`` will be returned. - #. Next if a relevant nuclide library isn't provided the :func:`~montepy.data_inputs.material.Material.default_libraries` will be used. + #. Next if a relevant nuclide library isn't provided the :attr:`~montepy.Material.default_libraries` will be used. - #. Finally if the two other options failed ``M0`` will be checked. These are stored in :func:`montepy.materials.Materials.default_libraries`. + #. Finally if the two other options failed ``M0`` will be checked. These are stored in :attr:`montepy.Materials.default_libraries`. Notes ----- diff --git a/montepy/data_inputs/nuclide.py b/montepy/data_inputs/nuclide.py index df2ef8b39..77a312540 100644 --- a/montepy/data_inputs/nuclide.py +++ b/montepy/data_inputs/nuclide.py @@ -45,7 +45,7 @@ class Library(SingletonGroup): Raises ------ - TypeErrror + TypeError if a string is not provided. ValueError if a valid library is not provided. @@ -104,7 +104,7 @@ def library(self) -> str: @property def library_type(self) -> LibraryType: - """The :class:`~montepy.particle.LibraryType` of this library. + """The :class:`~montepy.LibraryType` of this library. This corresponds to the type of library this would specified in a material definition e.g., ``NLIB``, ``PLIB``, etc. diff --git a/montepy/data_inputs/transform.py b/montepy/data_inputs/transform.py index 5f7c562f6..7a5aaa931 100644 --- a/montepy/data_inputs/transform.py +++ b/montepy/data_inputs/transform.py @@ -138,7 +138,7 @@ def displacement_vector(self): Returns ------- - numpy.array + numpy.ndarray """ return self._displacement_vector diff --git a/montepy/input_parser/syntax_node.py b/montepy/input_parser/syntax_node.py index eb34d55eb..451c3020c 100644 --- a/montepy/input_parser/syntax_node.py +++ b/montepy/input_parser/syntax_node.py @@ -2019,7 +2019,7 @@ def flatten(self): class ShortcutNode(ListNode): - """A node that pretends to be a :class:`ListNode` but is actually representing a shortcut. + """A node that pretends to be a :class:`~montepy.input_parser.syntax_node.ListNode` but is actually representing a shortcut. This takes the shortcut tokens, and expands it into their "virtual" values. @@ -2499,7 +2499,7 @@ def _format_interpolate(self, leading_node=None): class ClassifierNode(SyntaxNodeBase): - """A node to represent the classifier for a :class:`montepy.data_input.DataInput` + """A node to represent the classifier for a :class:`montepy.data_inputs.data_input.DataInput` e.g., represents ``M4``, ``F104:n,p``, ``IMP:n,e``. """ diff --git a/montepy/materials.py b/montepy/materials.py index 994793269..6f6f2af89 100644 --- a/montepy/materials.py +++ b/montepy/materials.py @@ -13,7 +13,7 @@ class Materials(NumberedDataObjectCollection): - """A container of multiple :class:`~montepy.data_inputs.material.Material` instances. + """A container of multiple :class:`~montepy.Material` instances. This collection can be sliced to get a subset of the materials. Slicing is done based on the material numbers, not their order in the input. @@ -28,7 +28,7 @@ class Materials(NumberedDataObjectCollection): Notes ----- When items are added to this (and this object is linked to a problem), - they will also be added to :func:`montepy.mcnp_problem.MCNP_Problem.data_inputs`. + they will also be added to :attr:`montepy.MCNP_Problem.data_inputs`. Notes ----- @@ -48,7 +48,7 @@ def get_containing_any( self, *nuclides: Union[ montepy.data_inputs.nuclide.Nuclide, - montepy.data_inputs.nuclide.Nucleus, + montepy.Nucleus, montepy.Element, str, int, @@ -58,7 +58,7 @@ def get_containing_any( ) -> Generator[Material]: """Get all materials that contain any of these these nuclides. - This uses :func:`~montepy.data_inputs.material.Material.contains` under the hood. + This uses :func:`~montepy.Material.contains_all` under the hood. See that documentation for more guidance. Examples @@ -112,7 +112,7 @@ def get_containing_all( self, *nuclides: Union[ montepy.data_inputs.nuclide.Nuclide, - montepy.data_inputs.nuclide.Nucleus, + montepy.Nucleus, montepy.Element, str, int, @@ -122,7 +122,7 @@ def get_containing_all( ) -> Generator[Material]: """Get all materials that contain all of these nuclides. - This uses :func:`~montepy.data_inputs.material.Material.contains` under the hood. + This uses :func:`~montepy.Material.contains_all` under the hood. See that documentation for more guidance. Examples @@ -176,7 +176,7 @@ def _contains_arb( self, *nuclides: Union[ montepy.data_inputs.nuclide.Nuclide, - montepy.data_inputs.nuclide.Nucleus, + montepy.Nucleus, montepy.Element, str, int, @@ -192,7 +192,7 @@ def _contains_arb( def sort_by_type(nuclide): type_map = { montepy.data_inputs.element.Element: 0, - montepy.data_inputs.nuclide.Nucleus: 1, + montepy.Nucleus: 1, montepy.data_inputs.nuclide.Nuclide: 2, } return type_map[type(nuclide)] diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index ad0274b94..ea83d79bb 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -29,7 +29,7 @@ class _ExceptionContextAdder(ABCMeta): - """A metaclass for wrapping all class properties and methods in :func:`~montepy.errors.add_line_number_to_exception`.""" + """A metaclass for wrapping all class properties and methods in :func:`~montepy.exceptions.add_line_number_to_exception`.""" @staticmethod def _wrap_attr_call(func): diff --git a/montepy/mcnp_problem.py b/montepy/mcnp_problem.py index cbabcf3c1..d0cd65857 100644 --- a/montepy/mcnp_problem.py +++ b/montepy/mcnp_problem.py @@ -177,7 +177,7 @@ def mode(self): def set_mode(self, particles): """Sets the mode of problem to the given particles. - For details see: :func:`montepy.data_cards.mode.Mode.set`. + For details see: :meth:`~montepy.Mode.set`. Parameters ---------- @@ -301,7 +301,7 @@ def data_inputs(self): ------- list a list of the - :class:`~montepy.data_cards.data_card.DataCardAbstract` + :class:`~montepy.data_inputs.data_input.DataInputAbstract` objects, ordered by the order they were in the input file. """ self.__relink_objs() diff --git a/montepy/surfaces/half_space.py b/montepy/surfaces/half_space.py index 41524752b..f6a66ca12 100644 --- a/montepy/surfaces/half_space.py +++ b/montepy/surfaces/half_space.py @@ -171,7 +171,7 @@ def update_pointers(self, cells, surfaces, cell): 1. Link this HalfSpace (and its children) to the parent cell. 2. Update the divider parameter to point to the relevant surface or cell. - 3. Update the parent's :func:`~montepy.cell.Cell.surfaces`, and :func:`~montepy.cell.Cell.complements`. + 3. Update the parent's :attr:`~montepy.Cell.surfaces`, and :attr:`~montepy.Cell.complements`. Parameters ---------- @@ -216,17 +216,18 @@ def _add_new_children_to_cell(self, other): def remove_duplicate_surfaces( self, deleting_dict: dict[ - int, tuple[montepy.surfaces.Surface, montepy.surfaces.Surface] + int, + tuple[montepy.surfaces.surface.Surface, montepy.surfaces.surface.Surface], ], ): """Updates old surface numbers to prepare for deleting surfaces. This will ensure any new surfaces or complements properly get added to the parent - cell's :func:`~montepy.cell.Cell.surfaces` and :func:`~montepy.cell.Cell.complements`. + cell's :attr:`~montepy.Cell.surfaces` and :attr:`~montepy.Cell.complements`. .. versionchanged:: 1.0.0 - The form of the deleting_dict was changed as :class:`~montepy.surfaces.Surface` is no longer hashable. + The form of the deleting_dict was changed as :class:`~montepy.Surface` is no longer hashable. Parameters ---------- @@ -707,17 +708,18 @@ def surf_cont(div=None): def remove_duplicate_surfaces( self, deleting_dict: dict[ - int, tuple[montepy.surfaces.Surface, montepy.surfaces.Surface] + int, + tuple[montepy.surfaces.surface.Surface, montepy.surfaces.surface.Surface], ], ): """Updates old surface numbers to prepare for deleting surfaces. This will ensure any new surfaces or complements properly get added to the parent - cell's :func:`~montepy.cell.Cell.surfaces` and :func:`~montepy.cell.Cell.complements`. + cell's :attr:`~montepy.Cell.surfaces` and :attr:`~montepy.Cell.complements`. .. versionchanged:: 1.0.0 - The form of the deleting_dict was changed as :class:`~montepy.surfaces.Surface` is no longer hashable. + The form of the deleting_dict was changed as :class:`~montepy.Surface` is no longer hashable. Parameters ---------- diff --git a/montepy/transforms.py b/montepy/transforms.py index 5493cc341..629dc9984 100644 --- a/montepy/transforms.py +++ b/montepy/transforms.py @@ -6,7 +6,7 @@ class Transforms(NumberedDataObjectCollection): - """A container of multiple :class:`~montepy.data_inputs.transform.Transform` instances. + """A container of multiple :class:`~montepy.Transform` instances. This collection can be sliced to get a subset of the Transforms. Slicing is done based on the Transform numbers, not their order in the input. diff --git a/montepy/universes.py b/montepy/universes.py index 36fbbbd2e..662e65dfe 100644 --- a/montepy/universes.py +++ b/montepy/universes.py @@ -6,7 +6,7 @@ class Universes(NumberedObjectCollection): - """A container of multiple :class:`~montepy.universe.Universe` instances. + """A container of multiple :class:`~montepy.Universe` instances. This collection can be sliced to get a subset of the universe. Slicing is done based on the universe numbers, not their order in the input.