"""Core functionality to read files.
TODO: investigate to merge with dispel.io.raw
"""
from typing import Any, Hashable, Optional
import numpy as np
import pandas as pd
from dispel.utils import convert_column_types
TYPE_MAPPINGS = {
"int16": [
"touchPathId",
"numberOfSteps",
"distance",
"floorsAscended",
"floorsDescended",
"answer",
"touch_path_id",
"displayedValue",
"userValue",
"height",
"width",
"id",
],
"float32": [
"x",
"y",
"z",
"w",
"userAccelerationX",
"userAccelerationY",
"userAccelerationZ",
"gravityX",
"gravityY",
"gravityZ",
"xPosition",
"yPosition",
"pressure",
"targetRadius",
"xTargetBall",
"yTargetBall",
"maxPressure",
"majorRadiusTolerance",
"majorRadius",
"averageActivePace",
"xBallPosition",
"yBallPosition",
"xThumbPosition",
"yThumbPosition",
"targetPressure",
"word_id",
"subject_height",
"level",
],
"datetime64[ms]": [
"ts",
"tsTouch",
"beginTimestamp",
"endTimestamp",
"tsAnswer",
"tsDisplay",
"appearance_timestamp",
"disappearance_timestamp",
"timestamp_out",
"timestamp",
],
"bool": [
"ledToSuccess",
"isValidPinch",
"inEndZone",
"success",
"isInTouchingArea",
"predefinedKey1",
"predefinedKey2",
"randomKey",
"predefinedSequence",
"randomSequence",
"success",
],
}
[docs]
def get_data_type_mapping(variable_name: Optional[Hashable]) -> str:
"""Get the data type for a variable name.
Parameters
----------
variable_name
The name of the variable.
Returns
-------
str
The variable data type.
"""
for type_, variables in TYPE_MAPPINGS.items():
if variable_name in variables:
return type_
return "U"
[docs]
def convert_literal_type(name: str, value: Any) -> Any:
"""Convert a literal based on the core type mapping.
Parameters
----------
name
The name of the variable to be used in the type mapping. This is passed to
:func:`get_data_type_mapping`.
value
The value to be converted
Returns
-------
Any
The converted value
"""
type_str = get_data_type_mapping(name)
expected_type = np.dtype(type_str)
if np.issubdtype(expected_type, np.datetime64):
return pd.to_datetime(value, unit="ms")
if np.issubsctype(expected_type, np.bool_):
return {"true": True, "false": False}[value]
if np.issubsctype(expected_type, np.float32):
value = None if value == "null" else value
return np.array(value).astype(expected_type).item()
[docs]
def convert_data_frame_type(data: pd.DataFrame) -> pd.DataFrame:
"""Convert a data frame based on the core type mapping.
Parameters
----------
data
The data frame to be converted
Returns
-------
pandas.DataFrame
The data frame with converted columns according to
:func:`get_data_type_mapping`.
"""
return convert_column_types(data, get_data_type_mapping)