# 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 YTDataContainer must be defined; typically you actually want to subclass one of: YTSelectionContainer0D YTSelectionContainer1D YTSelectionContainer2D 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.