ethoscopy 2.0.1__tar.gz → 2.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ethoscopy-2.0.4/.claude/settings.local.json +25 -0
- ethoscopy-2.0.4/.codecov.yml +26 -0
- ethoscopy-2.0.4/.github/workflows/ci.yml +151 -0
- ethoscopy-2.0.4/.github/workflows/release.yml +74 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/.gitignore +2 -1
- ethoscopy-2.0.4/.pre-commit-config.yaml +62 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/CLAUDE.md +37 -2
- ethoscopy-2.0.4/Docker/.claude/settings.local.json +41 -0
- ethoscopy-2.0.4/Docker/.env +39 -0
- ethoscopy-2.0.4/Docker/.env.keycloak +39 -0
- ethoscopy-2.0.4/Docker/README.md +227 -0
- ethoscopy-2.0.4/Docker/config/jupyterhub.sqlite +0 -0
- ethoscopy-2.0.4/Docker/config/jupyterhub_cookie_secret +1 -0
- ethoscopy-2.0.4/Docker/jupyterhub_data/jupyterhub-proxy.pid +1 -0
- ethoscopy-2.0.4/Docker/jupyterhub_data/jupyterhub.sqlite +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/Docker/jupyterhub_data/jupyterhub_config.py +4 -4
- ethoscopy-2.0.4/Docker/jupyterhub_data/jupyterhub_cookie_secret +1 -0
- ethoscopy-2.0.1/README.md → ethoscopy-2.0.4/PKG-INFO +83 -3
- ethoscopy-2.0.4/QWEN.md +88 -0
- ethoscopy-2.0.1/PKG-INFO → ethoscopy-2.0.4/README.md +44 -22
- ethoscopy-2.0.4/TESTING.md +275 -0
- ethoscopy-2.0.4/_config.yml +1 -0
- ethoscopy-2.0.4/pyproject.toml +63 -0
- ethoscopy-2.0.4/pytest.ini +22 -0
- ethoscopy-2.0.4/run_tests.py +76 -0
- ethoscopy-2.0.4/scripts/README.md +121 -0
- ethoscopy-2.0.4/scripts/convert_databases.sh +51 -0
- ethoscopy-2.0.4/scripts/convert_wal_to_delete.py +240 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/setup.py +2 -2
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/__init__.py +20 -20
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/analyse.py +318 -242
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy.py +31 -15
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy_HMM_class.py +24 -14
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy_class.py +24 -14
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy_core.py +1152 -642
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy_draw.py +1162 -531
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy_periodogram_class.py +24 -14
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy_plotly.py +2527 -1230
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/behavpy_seaborn.py +1881 -704
- ethoscopy-2.0.4/src/ethoscopy/load.py +1011 -0
- ethoscopy-2.0.4/src/ethoscopy/metadata_db.py +422 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/circadian_bars.py +58 -32
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/general_functions.py +41 -33
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/get_HMM.py +9 -9
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/get_tutorials.py +15 -11
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/hmm_functions.py +43 -38
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/periodogram_functions.py +139 -99
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/validate_datetime.py +16 -11
- ethoscopy-2.0.4/tests/__init__.py +3 -0
- ethoscopy-2.0.4/tests/conftest.py +247 -0
- ethoscopy-2.0.4/tests/data/README.md +13 -0
- ethoscopy-2.0.4/tests/data/test_ethoscope.db +0 -0
- ethoscopy-2.0.4/tests/test_analyse.py +438 -0
- ethoscopy-2.0.4/tests/test_baseline_enhancements.py +452 -0
- ethoscopy-2.0.4/tests/test_behavpy.py +408 -0
- ethoscopy-2.0.4/tests/test_behavpy_core_simple.py +298 -0
- ethoscopy-2.0.4/tests/test_compatibility_classes.py +285 -0
- ethoscopy-2.0.4/tests/test_general_functions.py +135 -0
- ethoscopy-2.0.4/tests/test_get_tutorials.py +136 -0
- ethoscopy-2.0.4/tests/test_load.py +431 -0
- ethoscopy-2.0.4/tests/test_load_comprehensive.py +782 -0
- ethoscopy-2.0.4/tests/test_load_optimizations.py +635 -0
- ethoscopy-2.0.1/.claude/settings.local.json +0 -16
- ethoscopy-2.0.1/Docker/README.md +0 -87
- ethoscopy-2.0.1/_config.yml +0 -1
- ethoscopy-2.0.1/pyproject.toml +0 -38
- ethoscopy-2.0.1/src/ethoscopy/load.py +0 -618
- ethoscopy-2.0.1/src/ethoscopy/metadata_db.py +0 -380
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/Docker/Dockerfile +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/Docker/docker-compose.yml +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/Docker/install_r_packages.r +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/LICENSE +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/src/ethoscopy/misc/__init__.py +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/1_Overview_tutorial.ipynb +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/2_HMM_tutorial.ipynb +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/3_Circadian_tutorial.ipynb +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/4_Navigating_db_tutorial.ipynb +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/5_Ethoscopy_catch22_tutorial.ipynb +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/6_Ethoscopy_to_hctsa_tutorial.ipynb +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/ethoscope_db.csv +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/jones_et_al_metadata.csv +0 -0
- {ethoscopy-2.0.1 → ethoscopy-2.0.4}/tutorial_notebook/notebook_paper.ipynb +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(git add:*)",
|
|
5
|
+
"Bash(git commit:*)",
|
|
6
|
+
"Bash(python:*)",
|
|
7
|
+
"Bash(ls:*)",
|
|
8
|
+
"Bash(find:*)",
|
|
9
|
+
"Bash(docker exec ethoscope-lab ls -la \"/mnt/ethoscope_results/26634d78becf48628fe5d9ffc67fae04/ETHOSCOPE_266/2025-07-29_19-12-16/2025-07-29_19-12-16_26634d78becf48628fe5d9ffc67fae04.db\")",
|
|
10
|
+
"Bash(docker exec:*)",
|
|
11
|
+
"Bash(source:*)",
|
|
12
|
+
"Bash(git push:*)",
|
|
13
|
+
"Bash(mkdir:*)",
|
|
14
|
+
"Bash(cp:*)",
|
|
15
|
+
"Bash(sqlite3:*)",
|
|
16
|
+
"Bash(black:*)",
|
|
17
|
+
"Bash(grep:*)",
|
|
18
|
+
"Bash(pip install:*)",
|
|
19
|
+
"Bash(git stash pop:*)",
|
|
20
|
+
"Bash(git checkout:*)",
|
|
21
|
+
"Bash(git tag:*)"
|
|
22
|
+
],
|
|
23
|
+
"deny": []
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
coverage:
|
|
2
|
+
range: 50..90
|
|
3
|
+
round: down
|
|
4
|
+
precision: 2
|
|
5
|
+
|
|
6
|
+
status:
|
|
7
|
+
project:
|
|
8
|
+
default:
|
|
9
|
+
target: auto
|
|
10
|
+
threshold: 1%
|
|
11
|
+
base: auto
|
|
12
|
+
patch:
|
|
13
|
+
default:
|
|
14
|
+
target: auto
|
|
15
|
+
threshold: 1%
|
|
16
|
+
base: auto
|
|
17
|
+
|
|
18
|
+
comment:
|
|
19
|
+
layout: "reach, diff, flags, files"
|
|
20
|
+
behavior: default
|
|
21
|
+
|
|
22
|
+
ignore:
|
|
23
|
+
- "tests/"
|
|
24
|
+
- "tutorial_notebook/"
|
|
25
|
+
- "setup.py"
|
|
26
|
+
- "run_tests.py"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
name: CI/CD Pipeline
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, develop ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
schedule:
|
|
9
|
+
# Run tests daily at 6 AM UTC
|
|
10
|
+
- cron: '0 6 * * *'
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
python-version: ['3.10', '3.11', '3.12']
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
23
|
+
uses: actions/setup-python@v4
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Cache pip dependencies
|
|
28
|
+
uses: actions/cache@v3
|
|
29
|
+
with:
|
|
30
|
+
path: ~/.cache/pip
|
|
31
|
+
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
|
|
32
|
+
restore-keys: |
|
|
33
|
+
${{ runner.os }}-pip-
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: |
|
|
37
|
+
python -m pip install --upgrade pip
|
|
38
|
+
pip install -e ".[dev]"
|
|
39
|
+
pip install pytest-cov pytest-xdist pytest-mock
|
|
40
|
+
|
|
41
|
+
- name: Lint with ruff
|
|
42
|
+
run: |
|
|
43
|
+
pip install ruff
|
|
44
|
+
ruff check src/
|
|
45
|
+
|
|
46
|
+
- name: Format check with black
|
|
47
|
+
run: |
|
|
48
|
+
pip install black
|
|
49
|
+
black --check src/ tests/
|
|
50
|
+
|
|
51
|
+
- name: Run unit tests
|
|
52
|
+
run: |
|
|
53
|
+
python -m pytest tests/ -v --cov=ethoscopy --cov-report=xml --cov-report=term-missing -m "unit"
|
|
54
|
+
|
|
55
|
+
- name: Run integration tests
|
|
56
|
+
run: |
|
|
57
|
+
python -m pytest tests/ -v -m "integration"
|
|
58
|
+
|
|
59
|
+
- name: Upload coverage reports to Codecov
|
|
60
|
+
uses: codecov/codecov-action@v5
|
|
61
|
+
with:
|
|
62
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
63
|
+
slug: gilestrolab/ethoscopy
|
|
64
|
+
|
|
65
|
+
test-notebooks:
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
needs: test
|
|
68
|
+
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/checkout@v4
|
|
71
|
+
|
|
72
|
+
- name: Set up Python 3.11
|
|
73
|
+
uses: actions/setup-python@v4
|
|
74
|
+
with:
|
|
75
|
+
python-version: '3.11'
|
|
76
|
+
|
|
77
|
+
- name: Install dependencies
|
|
78
|
+
run: |
|
|
79
|
+
python -m pip install --upgrade pip
|
|
80
|
+
pip install -e ".[dev]"
|
|
81
|
+
pip install nbval jupyter
|
|
82
|
+
|
|
83
|
+
- name: Test notebooks
|
|
84
|
+
run: |
|
|
85
|
+
pytest --nbval-lax tutorial_notebook/*.ipynb -v
|
|
86
|
+
continue-on-error: true # Notebooks may fail due to data dependencies
|
|
87
|
+
|
|
88
|
+
build:
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
needs: [test, test-notebooks]
|
|
91
|
+
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v4
|
|
94
|
+
|
|
95
|
+
- name: Set up Python 3.11
|
|
96
|
+
uses: actions/setup-python@v4
|
|
97
|
+
with:
|
|
98
|
+
python-version: '3.11'
|
|
99
|
+
|
|
100
|
+
- name: Install build dependencies
|
|
101
|
+
run: |
|
|
102
|
+
python -m pip install --upgrade pip
|
|
103
|
+
pip install build twine
|
|
104
|
+
|
|
105
|
+
- name: Build package
|
|
106
|
+
run: |
|
|
107
|
+
python -m build
|
|
108
|
+
|
|
109
|
+
- name: Check package
|
|
110
|
+
run: |
|
|
111
|
+
twine check dist/*
|
|
112
|
+
|
|
113
|
+
- name: Upload build artifacts
|
|
114
|
+
uses: actions/upload-artifact@v4
|
|
115
|
+
with:
|
|
116
|
+
name: dist-files
|
|
117
|
+
path: dist/
|
|
118
|
+
|
|
119
|
+
security-scan:
|
|
120
|
+
runs-on: ubuntu-latest
|
|
121
|
+
|
|
122
|
+
steps:
|
|
123
|
+
- uses: actions/checkout@v4
|
|
124
|
+
|
|
125
|
+
- name: Set up Python 3.11
|
|
126
|
+
uses: actions/setup-python@v4
|
|
127
|
+
with:
|
|
128
|
+
python-version: '3.11'
|
|
129
|
+
|
|
130
|
+
- name: Install dependencies
|
|
131
|
+
run: |
|
|
132
|
+
python -m pip install --upgrade pip
|
|
133
|
+
pip install bandit safety
|
|
134
|
+
|
|
135
|
+
- name: Run security scan with bandit
|
|
136
|
+
run: |
|
|
137
|
+
bandit -r src/ -f json -o bandit-report.json
|
|
138
|
+
continue-on-error: true
|
|
139
|
+
|
|
140
|
+
- name: Run safety check
|
|
141
|
+
run: |
|
|
142
|
+
safety check --json --output safety-report.json
|
|
143
|
+
continue-on-error: true
|
|
144
|
+
|
|
145
|
+
- name: Upload security reports
|
|
146
|
+
uses: actions/upload-artifact@v4
|
|
147
|
+
with:
|
|
148
|
+
name: security-reports
|
|
149
|
+
path: |
|
|
150
|
+
bandit-report.json
|
|
151
|
+
safety-report.json
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- 'v*.*.*'
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ['3.10', '3.11', '3.12']
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v4
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: |
|
|
27
|
+
python -m pip install --upgrade pip
|
|
28
|
+
pip install -e ".[dev]"
|
|
29
|
+
pip install pytest-cov
|
|
30
|
+
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: |
|
|
33
|
+
python -m pytest tests/ -v --cov=ethoscopy -m "not slow"
|
|
34
|
+
|
|
35
|
+
build-and-publish:
|
|
36
|
+
needs: test
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
|
|
42
|
+
- name: Set up Python 3.11
|
|
43
|
+
uses: actions/setup-python@v4
|
|
44
|
+
with:
|
|
45
|
+
python-version: '3.11'
|
|
46
|
+
|
|
47
|
+
- name: Install build dependencies
|
|
48
|
+
run: |
|
|
49
|
+
python -m pip install --upgrade pip
|
|
50
|
+
pip install build twine
|
|
51
|
+
|
|
52
|
+
- name: Build package
|
|
53
|
+
run: |
|
|
54
|
+
python -m build
|
|
55
|
+
|
|
56
|
+
- name: Check package
|
|
57
|
+
run: |
|
|
58
|
+
twine check dist/*
|
|
59
|
+
|
|
60
|
+
- name: Publish to Test PyPI
|
|
61
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
|
62
|
+
env:
|
|
63
|
+
TWINE_USERNAME: __token__
|
|
64
|
+
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
|
65
|
+
run: |
|
|
66
|
+
twine upload --repository testpypi dist/*
|
|
67
|
+
|
|
68
|
+
- name: Publish to PyPI
|
|
69
|
+
if: github.event_name == 'release'
|
|
70
|
+
env:
|
|
71
|
+
TWINE_USERNAME: __token__
|
|
72
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
73
|
+
run: |
|
|
74
|
+
twine upload dist/*
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
# General file checks
|
|
3
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
4
|
+
rev: v5.0.0
|
|
5
|
+
hooks:
|
|
6
|
+
- id: trailing-whitespace
|
|
7
|
+
files: \.(py|yml|yaml|md|txt)$
|
|
8
|
+
- id: end-of-file-fixer
|
|
9
|
+
files: \.(py|yml|yaml|md|txt)$
|
|
10
|
+
- id: check-yaml
|
|
11
|
+
- id: check-toml
|
|
12
|
+
- id: check-merge-conflict
|
|
13
|
+
- id: check-added-large-files
|
|
14
|
+
args: ['--maxkb=1000']
|
|
15
|
+
- id: debug-statements
|
|
16
|
+
files: ^(src/|tests/).*\.py$
|
|
17
|
+
- id: check-ast
|
|
18
|
+
files: ^(src/|tests/).*\.py$
|
|
19
|
+
|
|
20
|
+
# Black - Code formatting
|
|
21
|
+
- repo: https://github.com/psf/black
|
|
22
|
+
rev: 24.10.0
|
|
23
|
+
hooks:
|
|
24
|
+
- id: black
|
|
25
|
+
args: [--line-length=88]
|
|
26
|
+
files: ^(src/|tests/).*\.py$
|
|
27
|
+
|
|
28
|
+
# Ruff - Linting and code analysis
|
|
29
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
30
|
+
rev: v0.8.4
|
|
31
|
+
hooks:
|
|
32
|
+
- id: ruff
|
|
33
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
34
|
+
files: ^src/.*\.py$
|
|
35
|
+
- id: ruff-format
|
|
36
|
+
files: ^(src/|tests/).*\.py$
|
|
37
|
+
|
|
38
|
+
# Import sorting
|
|
39
|
+
- repo: https://github.com/pycqa/isort
|
|
40
|
+
rev: 5.13.2
|
|
41
|
+
hooks:
|
|
42
|
+
- id: isort
|
|
43
|
+
args: [--profile, black, --line-length=88]
|
|
44
|
+
files: ^(src/|tests/).*\.py$
|
|
45
|
+
|
|
46
|
+
- repo: local
|
|
47
|
+
hooks:
|
|
48
|
+
- id: pytest-unit
|
|
49
|
+
name: pytest-unit
|
|
50
|
+
entry: .venv/bin/python -m pytest tests/ -m "unit" -v
|
|
51
|
+
language: system
|
|
52
|
+
pass_filenames: false
|
|
53
|
+
always_run: true
|
|
54
|
+
stages: [commit]
|
|
55
|
+
|
|
56
|
+
- id: pytest-fast
|
|
57
|
+
name: pytest-fast
|
|
58
|
+
entry: .venv/bin/python -m pytest tests/ -m "not slow" -v --tb=short
|
|
59
|
+
language: system
|
|
60
|
+
pass_filenames: false
|
|
61
|
+
always_run: true
|
|
62
|
+
stages: [push]
|
|
@@ -10,7 +10,7 @@ Ethoscopy is a Python data analysis toolbox for behavioral time series data from
|
|
|
10
10
|
|
|
11
11
|
### Python Environment
|
|
12
12
|
- **Use Python 3.10+** (project requires >=3.10,<4.0)
|
|
13
|
-
- **Always use virtual environment** (`
|
|
13
|
+
- **Always use virtual environment** (`.venv` as mentioned in user's global instructions)
|
|
14
14
|
- **Install in development mode**: `pip install -e .`
|
|
15
15
|
|
|
16
16
|
### Package Management
|
|
@@ -45,6 +45,41 @@ pip install -e ".[dev]"
|
|
|
45
45
|
- Build: `JUPYTER_HUB_TAG=5.3.0 ETHOSCOPE_LAB_TAG=1.0 docker compose build`
|
|
46
46
|
- Run: `docker compose up -d` (from Docker/ directory)
|
|
47
47
|
|
|
48
|
+
### Troubleshooting: Database "Malformed" Errors
|
|
49
|
+
|
|
50
|
+
**Problem**: Intermittent "database disk image is malformed" errors when loading ethoscope data in Docker
|
|
51
|
+
|
|
52
|
+
**Root Cause**: SQLite databases in WAL (Write-Ahead Logging) mode on read-only Docker mounts
|
|
53
|
+
|
|
54
|
+
**Solution Options**:
|
|
55
|
+
1. **Convert databases to DELETE mode** (recommended for immediate fix)
|
|
56
|
+
```bash
|
|
57
|
+
# Using the conversion script (from project root)
|
|
58
|
+
python3 scripts/convert_wal_to_delete.py /mnt/ethoscope_data/results --verbose
|
|
59
|
+
|
|
60
|
+
# Or using bash wrapper
|
|
61
|
+
./scripts/convert_databases.sh /mnt/ethoscope_data/results
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
2. **Improved connection handling** (v2.0.4+)
|
|
65
|
+
- The `_connect_db()` function in `load.py` now detects WAL mode automatically
|
|
66
|
+
- Uses `mode=ro&nolock=1` URI parameters for WAL databases on read-only mounts
|
|
67
|
+
- Includes retry logic in `read_single_roi_optimized()` for resilience
|
|
68
|
+
|
|
69
|
+
**Key Implementation Details** (load.py):
|
|
70
|
+
- Lines 18-70: `_connect_db()` - Smart connection with WAL detection and appropriate parameters
|
|
71
|
+
- Lines 943-979: Retry logic in `read_single_roi_optimized()` - Handles transient errors with fresh connections
|
|
72
|
+
|
|
73
|
+
**Testing After Changes**:
|
|
74
|
+
```python
|
|
75
|
+
import ethoscopy as etho
|
|
76
|
+
metadata = etho.link_meta_index('metadata.csv', '/mnt/ethoscope_results')
|
|
77
|
+
data = etho.load_ethoscope(metadata, reference_hour=9.0, FUN=etho.sleep_annotation)
|
|
78
|
+
# Should load all ROIs without "malformed" errors
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**See Also**: `Docker/README.md` for detailed database preparation instructions
|
|
82
|
+
|
|
48
83
|
## Architecture and Code Structure
|
|
49
84
|
|
|
50
85
|
### Core Architecture
|
|
@@ -108,4 +143,4 @@ df = etho.behavpy(data, metadata, check=True, canvas='plotly', palette='Set2')
|
|
|
108
143
|
### Documentation
|
|
109
144
|
- **Docstrings**: Google style required for all functions
|
|
110
145
|
- **Tutorial notebooks**: Primary documentation method
|
|
111
|
-
- **README.md**: Keep updated with installation and basic usage
|
|
146
|
+
- **README.md**: Keep updated with installation and basic usage
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(ls:*)",
|
|
5
|
+
"Bash(git checkout:*)",
|
|
6
|
+
"Bash(docker images:*)",
|
|
7
|
+
"Read(//tmp/**)",
|
|
8
|
+
"Bash(JUPYTER_HUB_TAG=5.3.0 ETHOSCOPE_LAB_TAG=1.1 docker compose build:*)",
|
|
9
|
+
"Bash(tee:*)",
|
|
10
|
+
"Bash(docker compose:*)",
|
|
11
|
+
"Bash(find:*)",
|
|
12
|
+
"Bash(sqlite3:*)",
|
|
13
|
+
"Bash(python3:*)",
|
|
14
|
+
"Bash(docker exec:*)",
|
|
15
|
+
"Bash(docker cp:*)",
|
|
16
|
+
"Bash(ip addr:*)",
|
|
17
|
+
"Bash(systemctl status:*)",
|
|
18
|
+
"Bash(docker ps:*)",
|
|
19
|
+
"Bash(wg show:*)",
|
|
20
|
+
"Bash(ip route:*)",
|
|
21
|
+
"Bash(ip rule:*)",
|
|
22
|
+
"Bash(docker inspect:*)",
|
|
23
|
+
"Bash(docker logs:*)",
|
|
24
|
+
"Bash(nc:*)",
|
|
25
|
+
"Bash(timeout 3 bash -c 'cat < /dev/tcp/192.168.254.10/8082')",
|
|
26
|
+
"Bash(docker network inspect:*)",
|
|
27
|
+
"Bash(ss:*)",
|
|
28
|
+
"Bash(host:*)",
|
|
29
|
+
"Bash(chmod:*)",
|
|
30
|
+
"Bash(tree:*)",
|
|
31
|
+
"Bash(source:*)",
|
|
32
|
+
"Bash(pip install:*)",
|
|
33
|
+
"Bash(git add:*)",
|
|
34
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\nfix: resolve \"database disk image is malformed\" errors for WAL-mode databases\n\nAdd comprehensive solution for SQLite WAL-mode database errors on read-only Docker mounts:\n\n- Improve connection handling in load.py:\n - Detect WAL mode databases and use appropriate connection parameters\n - Add retry logic with fresh connections for transient errors\n - Use mode=ro&nolock=1 for WAL databases on read-only filesystems\n\n- Add database conversion scripts:\n - convert_wal_to_delete.py: Python script to convert databases from WAL to DELETE mode\n - convert_databases.sh: Bash wrapper for easy bulk conversion\n - scripts/README.md: Comprehensive documentation for database utilities\n\n- Update documentation:\n - Docker/README.md: Add \"Database Preparation for Docker\" section\n - CLAUDE.md: Add troubleshooting section for database errors\n\n- Bump version to 2.0.4\n\nThis resolves intermittent loading failures for ROIs when ethoscope databases\nin WAL mode are mounted read-only in Docker containers.\n\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
35
|
+
"Bash(git push:*)",
|
|
36
|
+
"Bash(git tag:*)",
|
|
37
|
+
"Bash(python -m build:*)"
|
|
38
|
+
],
|
|
39
|
+
"deny": []
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Keycloak OAuth Configuration for JupyterHub
|
|
2
|
+
# To use: cp .env.keycloak .env && docker compose restart
|
|
3
|
+
|
|
4
|
+
# Image versions
|
|
5
|
+
JUPYTER_HUB_TAG=5.3.0
|
|
6
|
+
ETHOSCOPE_LAB_TAG=1.1
|
|
7
|
+
|
|
8
|
+
# Authentication
|
|
9
|
+
AUTHENTICATOR_CLASS=generic
|
|
10
|
+
DUMMY_PASSWORD=ethoscope
|
|
11
|
+
|
|
12
|
+
# User configuration
|
|
13
|
+
ALLOWED_USERS=amadabhushi,ggilestro,mjoyce,lguo,labguest1,labguest2,labguest3,labguest4,labguest5,labguest6,labguest7,ethoscopelab
|
|
14
|
+
ADMIN_USERS=ggilestro
|
|
15
|
+
|
|
16
|
+
# User/Group IDs (must match your host system)
|
|
17
|
+
UID=1000
|
|
18
|
+
GID=1000
|
|
19
|
+
|
|
20
|
+
# Keycloak OAuth Settings
|
|
21
|
+
OAUTH_CLIENT_ID=jupyter-lab
|
|
22
|
+
OAUTH_CLIENT_SECRET=pBUaqP6b8bO5IamJ7jw4lD3l5EyKJaKq
|
|
23
|
+
OAUTH_CALLBACK_URL=https://jupyter.lab.gilest.ro/hub/oauth_callback
|
|
24
|
+
|
|
25
|
+
# Keycloak endpoints (realm: gilestro-lab)
|
|
26
|
+
OAUTH_AUTHORIZE_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/auth
|
|
27
|
+
OAUTH_TOKEN_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/token
|
|
28
|
+
OAUTH_USERDATA_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/userinfo
|
|
29
|
+
|
|
30
|
+
# Username claim (Keycloak typically uses 'preferred_username')
|
|
31
|
+
OAUTH_USERNAME_CLAIM=preferred_username
|
|
32
|
+
|
|
33
|
+
# OAuth scopes
|
|
34
|
+
OAUTH_SCOPE=openid profile email
|
|
35
|
+
|
|
36
|
+
# Provider-specific (not used for Keycloak, but needed for env validation)
|
|
37
|
+
GITHUB_ORG=
|
|
38
|
+
GOOGLE_HOSTED_DOMAIN=
|
|
39
|
+
GITLAB_URL=
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Keycloak OAuth Configuration for JupyterHub
|
|
2
|
+
# To use: cp .env.keycloak .env && docker compose restart
|
|
3
|
+
|
|
4
|
+
# Image versions
|
|
5
|
+
JUPYTER_HUB_TAG=5.3.0
|
|
6
|
+
ETHOSCOPE_LAB_TAG=1.1
|
|
7
|
+
|
|
8
|
+
# Authentication
|
|
9
|
+
AUTHENTICATOR_CLASS=generic
|
|
10
|
+
DUMMY_PASSWORD=ethoscope
|
|
11
|
+
|
|
12
|
+
# User configuration
|
|
13
|
+
ALLOWED_USERS=amadabhushi,ggilestro,mjoyce,lguo,labguest1,labguest2,labguest3,labguest4,labguest5,labguest6,labguest7,ethoscopelab
|
|
14
|
+
ADMIN_USERS=ggilestro
|
|
15
|
+
|
|
16
|
+
# User/Group IDs (must match your host system)
|
|
17
|
+
UID=1000
|
|
18
|
+
GID=1000
|
|
19
|
+
|
|
20
|
+
# Keycloak OAuth Settings
|
|
21
|
+
OAUTH_CLIENT_ID=jupyter-lab
|
|
22
|
+
OAUTH_CLIENT_SECRET=pBUaqP6b8bO5IamJ7jw4lD3l5EyKJaKq
|
|
23
|
+
OAUTH_CALLBACK_URL=https://jupyter.lab.gilest.ro/hub/oauth_callback
|
|
24
|
+
|
|
25
|
+
# Keycloak endpoints (realm: gilestro-lab)
|
|
26
|
+
OAUTH_AUTHORIZE_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/auth
|
|
27
|
+
OAUTH_TOKEN_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/token
|
|
28
|
+
OAUTH_USERDATA_URL=https://auth.gilest.ro/realms/gilestro-lab/protocol/openid-connect/userinfo
|
|
29
|
+
|
|
30
|
+
# Username claim (Keycloak typically uses 'preferred_username')
|
|
31
|
+
OAUTH_USERNAME_CLAIM=preferred_username
|
|
32
|
+
|
|
33
|
+
# OAuth scopes
|
|
34
|
+
OAUTH_SCOPE=openid profile email
|
|
35
|
+
|
|
36
|
+
# Provider-specific (not used for Keycloak, but needed for env validation)
|
|
37
|
+
GITHUB_ORG=
|
|
38
|
+
GOOGLE_HOSTED_DOMAIN=
|
|
39
|
+
GITLAB_URL=
|