# Bring-Your-Own-Features (BYOFS)

The Bring-Your-Own-Features (BYOFS) allows users to add custom feature sets to sleepKIT to be used with built-in or custom tasks.

## How it Works

1. **Create a Feature Set**: Define a new feature set class that subclasses `sk.FeatureSet` and implements the feature contract. The following is a skeleton: implement the writer before calling it.

    ```py title="Python example" linenums="1"
    import sleepkit as sk

    class CustomFeatureSet(sk.FeatureSet):
        @staticmethod
        def name() -> str:
            return "custom"

        @staticmethod
        def feature_names() -> list[str]:
            return ["feature1", "feature2", "feature3"]

        @staticmethod
        def generate_subject_features(subject_id: str, ds_name: str, params: sk.TaskParams):
            raise NotImplementedError("Write feature, mask and label arrays for this subject")
    ```

2. **Register the Feature Set**: Register the new feature set with the `sk.FeatureFactory` by calling the `register` method. This method takes the feature set name and the feature set class as arguments.

    ```py title="Python example" linenums="1"
    import sleepkit as sk
    sk.FeatureFactory.register(CustomFeatureSet.name(), CustomFeatureSet)
    ```

3. **Use the Feature Set**: The new feature set can now be used to generate feature sets.

    ```py title="Python example" linenums="1"
    import sleepkit as sk

    from pathlib import Path

    params = sk.TaskParams.model_validate_json(Path("configuration.json").read_text())
    params.feature.name = "custom"

    # Load a task
    task = sk.TaskFactory.get("stage")

    # Use the custom feature set
    task.feature(params)

    ```
