.. _creating-objects:

Creating Data Objects
=====================

The three-dimensional datatypes in yt follow a fairly simple protocol.  The
basic principle is that if you want to define a region in space, that region
must be identifiable from some sort of cut applied against the cells --
typically, in yt, this is done by examining the geometry.  

Creating a new data object requires modifications to two different files, one
of which is in Python and the other in Cython.  First, a subclass of
:class:`~yt.data_objects.data_containers.YTDataContainer` must be defined;
typically you actually want to subclass one of:
:class:`~yt.data_objects.data_containers.YTSelectionContainer0D`
:class:`~yt.data_objects.data_containers.YTSelectionContainer1D`
:class:`~yt.data_objects.data_containers.YTSelectionContainer2D`
:class:`~yt.data_objects.data_containers.YTSelectionContainer3D`.  
The following attributes must be defined:

 * ``_type_name`` - this is the short name by which the object type will be
   known as.  Remember this for later, as we will have to use it when defining
   the underlying selector.
 * ``_con_args`` - this is the set of arguments passed to the object, and their
   names as attributes on the data object.
 * ``_container_fields`` - any fields that are generated by the object, rather
   than by another derived field in yt.

The rest of the object can be defined in Cython, in the file
``yt/geometry/selection_routines.pyx``.  You must define a subclass of
``SelectorObject``, which will require implementation of the following methods:

 * ``fill_mask`` - this takes a grid object and fills a mask of which zones
   should be included.  It must take into account the child mask of the grid.
 * ``select_cell`` - this routine accepts a position and a width, and returns
   either zero or one for whether or not that cell is included in the selector.
 * ``select_sphere`` - this routine returns zero or one whether a sphere (point
   and radius) is included in the selector.
 * ``select_point`` - this identifies whether or not a point is included in the
   selector.  It should be identical to selecting a cell or a sphere with
   zero extent.
 * ``select_bbox`` - this returns whether or not a bounding box (i.e., grid) is
   included in the selector.
 * ``_hash_vals`` - this must return some combination of parameters that
   semi-uniquely identifies the selector.

Once the object has been defined, it must then be aliased within
``selection_routines.pyx`` as ``typename_selector``.  For instance,
``ray_selector`` or ``sphere_selector`` for ``_type_name`` values of ``ray``
and ``sphere``, respectively.
