def add_sample_field(
        self,
        field_name,
        ftype,
        embedded_doc_type=None,
        subfield=None,
        fields=None,
        description=None,
        info=None,
        read_only=False,
        **kwargs,
    ):
        """Adds a new sample field or embedded field to the dataset, if
        necessary.

        Args:
            field_name: the field name or ``embedded.field.name``
            ftype: the field type to create. Must be a subclass of
                :class:`fiftyone.core.fields.Field`
            embedded_doc_type (None): the
                :class:`fiftyone.core.odm.BaseEmbeddedDocument` type of the
                field. Only applicable when ``ftype`` is
                :class:`fiftyone.core.fields.EmbeddedDocumentField`
            subfield (None): the :class:`fiftyone.core.fields.Field` type of
                the contained field. Only applicable when ``ftype`` is
                :class:`fiftyone.core.fields.ListField` or
                :class:`fiftyone.core.fields.DictField`
            fields (None): a list of :class:`fiftyone.core.fields.Field`
                instances defining embedded document attributes. Only
                applicable when ``ftype`` is
                :class:`fiftyone.core.fields.EmbeddedDocumentField`
            description (None): an optional description
            info (None): an optional info dict
            read_only (False): whether the field should be read-only

        Raises:
            ValueError: if a field of the same name already exists and it is
                not compliant with the specified values
        """
        if embedded_doc_type is not None and issubclass(
            embedded_doc_type, fog.Group
        ):
            expanded = self._add_group_field(
                field_name,
                description=description,
                info=info,
                read_only=read_only,
            )
        else:
            expanded = self._sample_doc_cls.add_field(
                field_name,
                ftype,
                embedded_doc_type=embedded_doc_type,
                subfield=subfield,
                fields=fields,
                description=description,
                info=info,
                read_only=read_only,
                **kwargs,
            )

        if expanded:
            self._reload()
Adds a new sample field or embedded field to the dataset, if
        necessary.

        Args:
            field_name: the field name or ``embedded.field.name``
            ftype: the field type to create. Must be a subclass of
                :class:`fiftyone.core.fields.Field`
            embedded_doc_type (None): the
                :class:`fiftyone.core.odm.BaseEmbeddedDocument` type of the
                field. Only applicable when ``ftype`` is
                :class:`fiftyone.core.fields.EmbeddedDocumentField`
            subfield (None): the :class:`fiftyone.core.fields.Field` type of
                the contained field. Only applicable when ``ftype`` is
                :class:`fiftyone.core.fields.ListField` or
                :class:`fiftyone.core.fields.DictField`
            fields (None): a list of :class:`fiftyone.core.fields.Field`
                instances defining embedded document attributes. Only
                applicable when ``ftype`` is
                :class:`fiftyone.core.fields.EmbeddedDocumentField`
            description (None): an optional description
            info (None): an optional info dict
            read_only (False): whether the field should be read-only

        Raises:
            ValueError: if a field of the same name already exists and it is
                not compliant with the specified values
        
fiftyone/core/dataset.py