"""Functionality to read digital artefacts (DA) finger tapping records."""
from typing import Any, Dict
import pandas as pd
from dispel.data.epochs import Epoch
from dispel.data.levels import Level
from dispel.data.raw import (
    RawDataSet,
    RawDataSetDefinition,
    RawDataSetSource,
    RawDataValueDefinition,
)
from dispel.providers.digital_artefacts.data import DigitalArtefactsReading
from dispel.providers.digital_artefacts.io.generic import parse_device, parse_evaluation
from dispel.providers.registry import register_reader
#: The list of level in the finger tap Digital Artefact records
FT_DA_LEVEL = ["domhand", "nondomhand"]
#: Duration of the finger tap Digital Artefact test
TEST_DURATION = 20
[docs]
def generate_raw_dataset(bdh_format_data: pd.DataFrame) -> RawDataSet:
    """Transform the BDH format data into a RawDataSet.
    Parameters
    ----------
    bdh_format_data
        The finger tapping data in the io format
    Returns
    -------
    RawDataSet
        The RawDataSet representation of the finger tapping data
    """
    definitions = [
        RawDataValueDefinition(column, column.upper())
        for column in bdh_format_data.columns
    ]
    dataset_source = RawDataSetSource("da")
    return RawDataSet(
        RawDataSetDefinition("enriched_tap_events_ts", dataset_source, definitions),
        bdh_format_data,
    ) 
[docs]
def get_level_epoch(level_data: Dict) -> Epoch:
    """Extract level epoch from the digital artefact record.
    Parameters
    ----------
    level_data
        The dictionary containing the level data
    Returns
    -------
    Epoch
        The epoch object of the current level
    """
    start = pd.Timestamp(pd.Series(level_data["start time (utc)"]).iloc[0])
    return Epoch(start=start, end=start + pd.Timedelta(TEST_DURATION, unit="s")) 
[docs]
def create_bdh_level(level_data: Dict, level_id: str) -> Level:
    """Create a :class:`~dispel.data.core.Level` from the DA level data.
    Parameters
    ----------
    level_data
        A dict containing the DA level data
    level_id
        The id of the level
    Returns
    -------
    Level
        The level representation of the input data
    """
    epoch = get_level_epoch(level_data)
    bdh_level_data = format_da_ft_to_bdh(level_data)
    datasets = generate_raw_dataset(bdh_level_data)
    return Level(
        id_=level_id, start=epoch.start, end=epoch.end, raw_data_sets=[datasets]
    ) 
[docs]
def parsable_da_json(value: Any) -> bool:
    """Test if a value is a dictionary and can be parsed by the DA parser."""
    if not isinstance(value, dict):
        return False
    return "app" in value.keys() 
[docs]
@register_reader(parsable_da_json, DigitalArtefactsReading)
def parse_ft_reading(record: Dict) -> DigitalArtefactsReading:
    """Get the reading representation of a da data frame.
    Parameters
    ----------
    record
        The dictionary representing the digital artefact record
    Returns
    -------
    DigitalArtefactsReading
        The reading representation of the DA file
    """
    evaluation = parse_evaluation(record)
    device = parse_device(record)
    test_data = [(record[hand], hand) for hand in FT_DA_LEVEL]
    levels = [create_bdh_level(level_data, hand) for level_data, hand in test_data]
    return DigitalArtefactsReading(
        evaluation=evaluation,
        levels=levels,
        device=device,
    )