Skip to content

Commit

Permalink
Merge branch 'main' into feature/gaze_from_csv
Browse files Browse the repository at this point in the history
  • Loading branch information
prassepaul authored Sep 15, 2023
2 parents bf9f7d8 + 097cbbb commit 5aa980a
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 10 deletions.
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "build: "
17 changes: 15 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ cd pymovements
pip install -e .
```

If you have a problem e.g. `command not found: pip`, check whether you have activated a virtual enviroment.


### Creating a Branch

Expand Down Expand Up @@ -125,12 +127,23 @@ We use [`flake8`](https://pypi.org/project/flake8/) for quick style checks and
[`pylint`](https://pypi.org/project/pylint/) for thorough style checks and [`mypy`](
https://pypi.org/project/mypy/) for checking type annotations.

You can check your code style by using [pre-commit](https://www.pre-commit.com). You can install `pre-commit` via pip:

```bash
pip install pre-commit
pre-commit install
```

### Testing

Tests are written using [Pytest](https://docs.pytest.org) and executed
in a separate environment using [Tox](https://tox.readthedocs.io/en/latest/).

If you have not yet installed `tox` you can do so via
```bash
pip install tox
```

A full style check and all tests can be run by simply calling `tox` in the repository root.
```bash
tox
Expand All @@ -143,9 +156,9 @@ If you add a new feature, please also include appropriate tests to verify its in
functionality. We try to keep our code coverage close to 100%.

It is possible to limit the scope of testing to specific environments and files. For example, to
only test event related functionality using the Python 3.7 environment use:
only test event related functionality using the Python 3.8 environment use:
```bash
tox -e py37 tests/events
tox -e py38 tests/events
```


Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ dependencies = [
"matplotlib>=3.0.0,<4",
"numpy>=1.10.0,<2",
"pandas>1.0.0,<3",
"polars>=0.18.3,<0.19.0",
"pyarrow>=11.0.0,<12",
"polars>=0.19.0,<0.20.0",
"pyarrow>=11.0.0,<14",
"scipy>=1.5.4,<2",
"tqdm>=4.0.0,<5"
]
Expand Down
10 changes: 10 additions & 0 deletions src/pymovements/events/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ def event_property_columns(self) -> list[str]:
event_property_columns -= set(self._additional_columns)
return list(event_property_columns)

def copy(self) -> EventDataFrame:
"""Return a copy of the EventDataFrame.
Returns
-------
EventDataFrame
A copy of the EventDataFrame.
"""
return EventDataFrame(data=self.frame.clone())

def _add_minimal_schema_columns(self, df: pl.DataFrame) -> pl.DataFrame:
"""Add minimal schema columns to :py:class:`polars.DataFrame` if they are missing."""
if len(df) == 0:
Expand Down
27 changes: 27 additions & 0 deletions src/pymovements/gaze/gaze_dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,33 @@ def transform(
_check_n_components(self.n_components)
kwargs['n_components'] = self.n_components

if transform_method.__name__ in {'pos2vel', 'pos2acc'}:
if 'position' not in self.frame.columns and 'position_column' not in kwargs:
if 'pixel' in self.frame.columns:
raise pl.exceptions.ColumnNotFoundError(
"Neither 'position' is in the columns of the dataframe: "
f'{self.frame.columns} nor is the position column specified. '
"Since the dataframe has a 'pixel' column, consider running "
f'pix2deg() before {transform_method.__name__}(). If you want '
'to calculate pixel transformations, you can do so by using '
f"{transform_method.__name__}(position_column='pixel'). "
f'Available dataframe columns are {self.frame.columns}',
)
raise pl.exceptions.ColumnNotFoundError(
"Neither 'position' is in the columns of the dataframe: "
f'{self.frame.columns} nor is the position column specified. '
f'Available dataframe columns are {self.frame.columns}',
)
if transform_method.__name__ in {'pix2deg'}:
if 'pixel' not in self.frame.columns and 'pixel_column' not in kwargs:
raise pl.exceptions.ColumnNotFoundError(
"Neither 'position' is in the columns of the dataframe: "
f'{self.frame.columns} nor is the pixel column specified. '
'You can specify the pixel column via: '
f'{transform_method.__name__}(pixel_column="name_of_your_pixel_column"). '
f'Available dataframe columns are {self.frame.columns}',
)

if self.trial_columns is None:
self.frame = self.frame.with_columns(transform_method(**kwargs))
else:
Expand Down
10 changes: 10 additions & 0 deletions tests/events/frame_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,13 @@ def test_event_dataframe_columns_same_as_frame():
event_df = pm.EventDataFrame(**init_kwargs)

assert event_df.columns == event_df.frame.columns


def test_event_dataframe_copy():
events = pm.EventDataFrame(name='saccade', onsets=[0], offsets=[123])
events_copy = events.copy()

# We want to have separate dataframes but with the exact same data.
assert events is not events_copy
assert events.frame is not events_copy.frame
assert_frame_equal(events.frame, events_copy.frame)
48 changes: 42 additions & 6 deletions tests/gaze/gaze_transform_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,10 @@ def test_gaze_dataframe_pix2deg_creates_position_column(data, experiment, pixel_
},
pl.exceptions.ColumnNotFoundError,
(
'pixel\n\nError originated just after this operation:\nDF ["acceleration"]; '
'PROJECT */1 COLUMNS; SELECTION: "None"'
"Neither 'position' is in the columns of the dataframe: ['acceleration'] nor "
'is the pixel column specified. You can specify the pixel column via: '
'pix2deg(pixel_column="name_of_your_pixel_column"). Available dataframe '
"columns are ['acceleration']"
),
id='no_pixel_column',
),
Expand Down Expand Up @@ -609,8 +611,25 @@ def test_gaze_dataframe_pos2acc_creates_acceleration_column(data, experiment, po
},
pl.exceptions.ColumnNotFoundError,
(
'position\n\nError originated just after this operation:\nDF ["pixel"]; '
'PROJECT */1 COLUMNS; SELECTION: "None"'
"Neither 'position' is in the columns of the dataframe: ['pixel'] nor is the "
"position column specified. Since the dataframe has a 'pixel' column, "
'consider running pix2deg() before pos2acc(). If you want to calculate pixel '
"transformations, you can do so by using pos2acc(position_column='pixel'). "
"Available dataframe columns are ['pixel']"
),
id='no_position_column',
),
pytest.param(
{
'data': pl.from_dict({'x': [0.1], 'y': [0.2]}),
'experiment': pm.Experiment(1024, 768, 38, 30, 60, 'center', 1000),
'acceleration_columns': ['x', 'y'],
},
pl.exceptions.ColumnNotFoundError,
(
"Neither 'position' is in the columns of the dataframe: ['acceleration'] nor "
'is the position column specified. Available dataframe columns are '
"['acceleration']"
),
id='no_position_column',
),
Expand Down Expand Up @@ -690,8 +709,25 @@ def test_gaze_dataframe_pos2vel_creates_velocity_column(data, experiment, positi
},
pl.exceptions.ColumnNotFoundError,
(
'position\n\nError originated just after this operation:\nDF ["pixel"]; '
'PROJECT */1 COLUMNS; SELECTION: "None"'
"Neither 'position' is in the columns of the dataframe: ['pixel'] nor is the "
"position column specified. Since the dataframe has a 'pixel' column, "
'consider running pix2deg() before pos2vel(). If you want to calculate pixel '
"transformations, you can do so by using pos2vel(position_column='pixel'). "
"Available dataframe columns are ['pixel']"
),
id='no_position_column',
),
pytest.param(
{
'data': pl.from_dict({'x': [0.1], 'y': [0.2]}),
'experiment': pm.Experiment(1024, 768, 38, 30, 60, 'center', 1000),
'acceleration_columns': ['x', 'y'],
},
pl.exceptions.ColumnNotFoundError,
(
"Neither 'position' is in the columns of the dataframe: ['acceleration'] nor "
'is the position column specified. Available dataframe columns are '
"['acceleration']"
),
id='no_position_column',
),
Expand Down

0 comments on commit 5aa980a

Please sign in to comment.