"""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,
)