diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..364d113 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,50 @@ +FROM python:3.9-slim@sha256:5f0192a4f58a6ce99f732fe05e3b3d00f12ae62e183886bca3ebe3d202686c7f + +ENV PATH /usr/local/bin:$PATH +ENV PYTHON_VERSION 3.9.17 + +RUN \ + adduser --system --disabled-password --shell /bin/bash vscode && \ + # install docker + apt-get update && \ + apt-get install ca-certificates curl gnupg lsb-release -y && \ + mkdir -m 0755 -p /etc/apt/keyrings && \ + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && \ + apt-get update && \ + apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y && \ + usermod -aG docker vscode && \ + apt-get clean + +RUN \ + # dev setup + apt update && \ + apt-get install sudo git bash-completion graphviz default-mysql-client s3fs procps -y && \ + usermod -aG sudo vscode && \ + echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \ + pip install --no-cache-dir --upgrade black pip nbconvert && \ + echo '. /etc/bash_completion' >> /home/vscode/.bashrc && \ + echo 'export PS1="\[\e[32;1m\]\u\[\e[m\]@\[\e[34;1m\]\H\[\e[m\]:\[\e[33;1m\]\w\[\e[m\]$ "' >> /home/vscode/.bashrc && \ + apt-get clean + +COPY ./ /tmp/element-facemap/ + +RUN \ + # pipeline dependencies + apt-get install gcc g++ ffmpeg libsm6 libxext6 libgl1 libegl1 -y && \ + # git clone https://github.com/kushalbakshi/facemap.git && \ + # pip install ./facemap[gui] && \ + pip install --no-cache-dir -e /tmp/element-facemap[elements,tests] && \ + # clean up + rm -rf /tmp/element-facemap && \ + apt-get clean + +ENV DJ_HOST fakeservices.datajoint.io +ENV DJ_USER root +ENV DJ_PASS simple + +ENV FACEMAP_ROOT_DATA_DIR /workspaces/element-facemap/example_data +ENV DATABASE_PREFIX neuro_ + +USER vscode +CMD bash -c "sudo rm /var/run/docker.pid; sudo dockerd" \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..3e6eafd --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,30 @@ +{ + "name": "Environment + Data", + "dockerComposeFile": "docker-compose.yaml", + "service": "app", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + "remoteEnv": { + "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" + }, + "onCreateCommand": "mkdir -p ${FACEMAP_ROOT_DATA_DIR} && pip install -e .", + "postStartCommand": "docker volume prune -f && s3fs ${DJ_PUBLIC_S3_LOCATION} ${FACEMAP_ROOT_DATA_DIR} -o nonempty,multipart_size=530,endpoint=us-east-1,url=http://s3.amazonaws.com,public_bucket=1", + "hostRequirements": { + "cpus": 4, + "memory": "8gb", + "storage": "32gb" + }, + "forwardPorts": [ + 3306 + ], + "customizations": { + "settings": { + "python.pythonPath": "/usr/local/bin/python" + }, + "vscode": { + "extensions": [ + "ms-python.python@2023.8.0", + "ms-toolsai.jupyter@2023.3.1201040234" + ] + } + } +} \ No newline at end of file diff --git a/.devcontainer/docker-compose.yaml b/.devcontainer/docker-compose.yaml new file mode 100644 index 0000000..640ea4c --- /dev/null +++ b/.devcontainer/docker-compose.yaml @@ -0,0 +1,25 @@ +version: "3" +services: + app: + cpus: 4 + mem_limit: 8g + build: + context: .. + dockerfile: ./.devcontainer/Dockerfile + # image: datajoint/element_array_ephys:latest + extra_hosts: + - fakeservices.datajoint.io:127.0.0.1 + environment: + - DJ_PUBLIC_S3_LOCATION=djhub.vathes.datapub.elements:/workflow-facemap/0.0.0 + devices: + - /dev/fuse + cap_add: + - SYS_ADMIN + security_opt: + - apparmor:unconfined + volumes: + - ..:/workspaces/element-facemap:cached + - docker_data:/var/lib/docker # persist docker images + privileged: true # only because of dind +volumes: + docker_data: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..4a5f2cb --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,27 @@ +name: Release +on: + workflow_dispatch: +jobs: + make_github_release: + uses: datajoint/.github/.github/workflows/make_github_release.yaml@main + pypi_release: + needs: make_github_release + uses: datajoint/.github/.github/workflows/pypi_release.yaml@main + secrets: + TWINE_USERNAME: ${{secrets.TWINE_USERNAME}} + TWINE_PASSWORD: ${{secrets.TWINE_PASSWORD}} + with: + UPLOAD_URL: ${{needs.make_github_release.outputs.release_upload_url}} + mkdocs_release: + uses: datajoint/.github/.github/workflows/mkdocs_release.yaml@main + permissions: + contents: write + devcontainer-build: + uses: datajoint/.github/.github/workflows/devcontainer-build.yaml@main + devcontainer-publish: + needs: + - devcontainer-build + uses: datajoint/.github/.github/workflows/devcontainer-publish.yaml@main + secrets: + DOCKERHUB_USERNAME: ${{secrets.DOCKERHUB_USERNAME}} + DOCKERHUB_TOKEN: ${{secrets.DOCKERHUB_TOKEN_FOR_ELEMENTS}} \ No newline at end of file diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..2dad8cf --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,36 @@ +name: Test +on: + push: + pull_request: + workflow_dispatch: + schedule: + - cron: "0 8 * * 1" +jobs: + devcontainer-build: + uses: datajoint/.github/.github/workflows/devcontainer-build.yaml@main + tests: + runs-on: ubuntu-latest + strategy: + matrix: + py_ver: ["3.9", "3.10"] + mysql_ver: ["8.0", "5.7"] + include: + - py_ver: "3.8" + mysql_ver: "5.7" + - py_ver: "3.7" + mysql_ver: "5.7" + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{matrix.py_ver}} + uses: actions/setup-python@v4 + with: + python-version: ${{matrix.py_ver}} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install flake8 "black[jupyter]" + - name: Run style tests + run: | + python_version=${{matrix.py_ver}} + black element_facemap --check --verbose --target-version py${python_version//.} + black notebooks --check --verbose --target-version py${python_version//.} diff --git a/.github/workflows/u24_element_before_release.yaml b/.github/workflows/u24_element_before_release.yaml deleted file mode 100644 index 692cf82..0000000 --- a/.github/workflows/u24_element_before_release.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: u24_element_before_release -on: - pull_request: - push: - branches: - - '**' - tags-ignore: - - '**' - workflow_dispatch: -jobs: - call_context_check: - uses: dj-sciops/djsciops-cicd/.github/workflows/context_check.yaml@main - call_u24_elements_build_alpine: - uses: dj-sciops/djsciops-cicd/.github/workflows/u24_element_build.yaml@main - with: - py_ver: 3.9 - image: djbase diff --git a/.github/workflows/u24_element_release_call.yaml b/.github/workflows/u24_element_release_call.yaml deleted file mode 100644 index 4324cca..0000000 --- a/.github/workflows/u24_element_release_call.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: u24_element_release_call -on: - workflow_run: - workflows: ["u24_element_tag_to_release"] - types: - - completed -jobs: - call_context_check: - uses: dj-sciops/djsciops-cicd/.github/workflows/context_check.yaml@main - test_call_u24_elements_release_alpine: - if: >- - github.event.workflow_run.conclusion == 'success' && ( contains(github.event.workflow_run.head_branch, 'test') || (github.event.workflow_run.event == 'pull_request')) - uses: dj-sciops/djsciops-cicd/.github/workflows/u24_element_release.yaml@main - with: - py_ver: 3.9 - twine_repo: testpypi - secrets: - TWINE_USERNAME: ${{secrets.TWINE_TEST_USERNAME}} - TWINE_PASSWORD: ${{secrets.TWINE_TEST_PASSWORD}} - call_u24_elements_release_alpine: - if: >- - github.event.workflow_run.conclusion == 'success' && github.repository_owner == 'datajoint' && !contains(github.event.workflow_run.head_branch, 'test') - uses: dj-sciops/djsciops-cicd/.github/workflows/u24_element_release.yaml@main - with: - py_ver: 3.9 - secrets: - TWINE_USERNAME: ${{secrets.TWINE_USERNAME}} - TWINE_PASSWORD: ${{secrets.TWINE_PASSWORD}} diff --git a/.github/workflows/u24_element_tag_to_release.yaml b/.github/workflows/u24_element_tag_to_release.yaml deleted file mode 100644 index 57334e9..0000000 --- a/.github/workflows/u24_element_tag_to_release.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: u24_element_tag_to_release -on: - push: - tags: - - '*.*.*' - - 'test*.*.*' -jobs: - call_context_check: - uses: dj-sciops/djsciops-cicd/.github/workflows/context_check.yaml@main - call_u24_elements_build_alpine: - uses: dj-sciops/djsciops-cicd/.github/workflows/u24_element_build.yaml@main - with: - py_ver: 3.9 - image: djbase diff --git a/.gitignore b/.gitignore index ba774b0..364838f 100644 --- a/.gitignore +++ b/.gitignore @@ -116,5 +116,17 @@ temp* **/#*# **/.#* +# datajoint, notes, nwb export +dj_local_c*.json +temp* +temp/* +*nwb + # docs -/docs/site +/docs/site/ +/docs/src/tutorials/*ipynb +/docs/mike-mkdocs* +element_miniscope/qc.py + +# DevContainer/Codespaces +example_data/ diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 7420359..73ea826 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -11,6 +11,7 @@ MD030: false # Number of spaces after a list MD033: # HTML elements allowed allowed_elements: - "br" + - "sup" MD034: false # Permit bare URLs MD031: false # Spacing w/code blocks. Conflicts with `??? Note` and code tab styling -MD046: false # Spacing w/code blocks. Conflicts with `??? Note` and code tab styling +MD046: false # Spacing w/code blocks. Conflicts with `??? Note` and code tab styling \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2b2502c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": false + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e1160fa --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.rulers": [ + 88 + ], + "python.formatting.provider": "black", + "[python]": { + "editor.defaultFormatter": null + }, + "[markdown]": { + "editor.defaultFormatter": "disable" + }, + "files.autoSave": "off" +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c3138e..177325d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,18 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention. +## [0.2.0] - 2023-11-29 + ++ Add - Inference module as `facemap_inference.py` ++ Add - DevContainer for codespaces ++ Add - `tutorial_pipeline.py` ++ Add - 60 min tutorial using Jupyter Notebooks ++ Update - General improvements to increase consistency with other DataJoint Elements + +## [0.1.7] - 2023-10-18 + ++ Fix - Index `mot_Sv` and `movSv` by `roi_no` in `FacialSignal` + ## [0.1.6] - 2023-05-22 + Add - Facemap citation @@ -43,6 +55,8 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and the diagonal matrix + Add - Output directory inferral, if unspecified. +[0.2.0]: https://github.com/datajoint/element-facemap/releases/tag/0.2.0 +[0.1.7]: https://github.com/datajoint/element-facemap/releases/tag/0.1.7 [0.1.6]: https://github.com/datajoint/element-facemap/releases/tag/0.1.6 [0.1.5]: https://github.com/datajoint/element-facemap/releases/tag/0.1.5 [0.1.4]: https://github.com/datajoint/element-facemap/releases/tag/0.1.4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e04d170..2bd0f49 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,5 @@ # Contribution Guidelines This project follows the -[DataJoint Contribution Guidelines](https://datajoint.com/docs/community/contribute/). +[DataJoint Contribution Guidelines](https://datajoint.com/docs/about/contribute/). Please reference the link for more full details. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c144a40..0000000 --- a/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -ARG PY_VER -ARG DISTRO -ARG IMAGE -ARG PKG_NAME -ARG PKG_VERSION - -FROM datajoint/${IMAGE}:py${PY_VER}-${DISTRO} -COPY --chown=anaconda:anaconda ./requirements.txt ./setup.py \ - /main/ -COPY --chown=anaconda:anaconda ./${PKG_NAME} /main/${PKG_NAME} -RUN \ - cd /main && \ - pip install . && \ - rm -R /main/* -WORKDIR /main diff --git a/LICENSE b/LICENSE index 2f92789..386e298 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 DataJoint +Copyright (c) 2023 DataJoint Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/cspell.json b/cspell.json index f6602a8..cb07a24 100644 --- a/cspell.json +++ b/cspell.json @@ -18,47 +18,193 @@ "./images/*" ], "words": [ + "acorr", + "aggr", + "Alessio", + "Andreas", + "apmeta", + "arange", "arithmatex", - "Berens", - "CICD", - "Conda", - "Dolensek", - "Ecker", + "asarray", + "astype", + "autocorrelogram", + "Axona", + "bbins", + "bdist", + "Binarize", + "bouton", + "Brody", + "Bruker", + "bshift", + "Buccino", + "catgt", + "cbar", + "cbin", + "cdat", + "chans", + "Chans", + "chns", + "Clust", + "clusterings", + "cmap", + "cnmf", + "correlogram", + "correlograms", + "curations", + "DANDI", + "decomp", + "deconvolution", + "DISTRO", + "djbase", + "dtype", + "ecephys", + "Eftychios", + "electrophysiogical", "elif", "Ephys", - "Gehrlach", - "Hoenselaar", - "IACUC", - "inferral", + "fluo", + "fneu", + "Fneu", + "gblcar", + "gfix", + "Giovannucci", + "Hakan", + "hdmf", + "HHMI", + "hstack", + "ibllib", + "ifnull", + "imax", + "Imax", + "IMAX", + "imec", + "imread", + "imro", + "imrotbl", + "imshow", + "Inan", "inlinehilite", + "iplane", + "ipynb", + "ipywidgets", + "iscell", + "Kavli", + "kcoords", + "Klusta", + "Kwik", + "lfmeta", "linenums", - "markdown", + "masky", "mathjax", + "mdict", + "Mesoscale", + "mesoscope", "mkdocs", "mkdocstrings", - "movmask", + "Moser", + "mtscomp", + "nblocks", + "nchan", + "Nchan", + "nchannels", + "ndarray", + "ndepths", + "ndim", + "ndimage", + "Neuralynx", + "NEURO", + "neuroconv", + "Neurodata", + "Neurolabware", + "neuropil", + "Neuropil", + "Neuropix", + "neuropixel", + "NeuroPixels", + "nfields", "nframes", - "orofacial", + "npix", + "nplanes", + "nrois", + "NTNU", + "nwbfile", + "NWBHDF", + "oebin", + "openephys", + "openpyxl", "Pachitariu", + "paramsets", + "phylog", + "plotly", + "Pnevmatikakis", + "PSTH", + "pykilosort", "pymdownx", + "pynwb", + "pyopenephys", + "pyplot", + "pytest", + "quantile", "Reimer", + "repolarization", "Roboto", + "roidetect", "rois", "ROIs", "RRID", - "rtype", "Rxiv", "Sasaki", + "sbxreader", + "scipy", + "sdist", + "sess", + "SGLX", "Shen", - "Siapas", - "Sinz", + "Siegle", "Sitonic", - "Syeda", + "spikeglx", + "spkcount", + "spks", + "Stereotaxic", + "Sutter", + "tcat", + "tickvals", + "tofile", "Tolias", - "Tung", + "tqdm", + "usecs", + "usedb", + "Vidrio's", + "vline", + "vmax", + "Vmax", + "voxel", + "xanchor", + "xaxes", + "xaxis", + "xblock", + "xcoords", + "xcorr", + "xlabel", + "xlim", + "xoff", + "xpix", + "XPOS", + "xtick", + "yanchor", "Yatsenko", - "yrange", - "Zhong", - "Zuckerman" + "yaxes", + "yaxis", + "yblock", + "ycoord", + "ycoords", + "ylabel", + "ylim", + "yoff", + "ypix", + "YPOS", + "yref", + "yticks", + "zpix" ] } diff --git a/docker-compose-build.yaml b/docker-compose-build.yaml deleted file mode 100644 index 81984c7..0000000 --- a/docker-compose-build.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# PY_VER=3.8 IMAGE=djbase DISTRO=alpine PKG_NAME=$(python -c "print([p for p in __import__('setuptools').find_packages() if '.' not in p][0])") PKG_VERSION=$(cat ${PKG_NAME}/version.py | awk -F\' '/__version__/ {print $2}') HOST_UID=$(id -u) docker-compose -f docker-compose-build.yaml up --exit-code-from element --build -# -# Intended for updating dependencies and docker image. -# Used to build release artifacts. -version: "2.4" -services: - element: - build: - context: . - args: - - PY_VER - - DISTRO - - IMAGE - - PKG_NAME - - PKG_VERSION - image: datajoint/${PKG_NAME}:${PKG_VERSION} - user: ${HOST_UID}:anaconda - volumes: - - .:/main - command: - - sh - - -lc - - | - set -e - rm -R build dist *.egg-info || echo "No prev build" - python setup.py bdist_wheel sdist diff --git a/docker-compose-db.yaml b/docker-compose-db.yaml new file mode 100644 index 0000000..8f659b2 --- /dev/null +++ b/docker-compose-db.yaml @@ -0,0 +1,15 @@ +# MYSQL_VER=8.0 docker compose -f docker-compose-db.yaml up --build +version: "3" +services: + db: + restart: always + image: datajoint/mysql:${MYSQL_VER} + environment: + - MYSQL_ROOT_PASSWORD=${DJ_PASS} + ports: + - "3306:3306" + healthcheck: + test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ] + timeout: 15s + retries: 10 + interval: 15s \ No newline at end of file diff --git a/element_facemap/facial_behavior_estimation.py b/element_facemap/facial_behavior_estimation.py index 50422e4..bb1cd8b 100644 --- a/element_facemap/facial_behavior_estimation.py +++ b/element_facemap/facial_behavior_estimation.py @@ -463,7 +463,9 @@ def make(self, key): key, roi_no=roi_no, pc_no=i, - singular_value=dataset["motSv"][i] if "motSv" in dataset else None, + singular_value=dataset["motSv"][roi_no][i] + if "motSv" in dataset + else None, motmask=dataset["motMask_reshape"][roi_no + 1][:, :, i], projection=dataset["motSVD"][roi_no + 1][i], ) @@ -479,7 +481,9 @@ def make(self, key): key, roi_no=roi_no, pc_no=i, - singular_value=dataset["movSv"][i] if "movSv" in dataset else None, + singular_value=dataset["movSv"][roi_no][i] + if "movSv" in dataset + else None, movmask=dataset["movMask_reshape"][roi_no + 1][:, :, i], projection=dataset["movSVD"][roi_no + 1][i], ) @@ -523,4 +527,4 @@ def get_loader_result( loaded_dataset = np.load(output_file, allow_pickle=True).item() creation_time = datetime.fromtimestamp(Path(output_file).stat().st_ctime) - return loaded_dataset, creation_time \ No newline at end of file + return loaded_dataset, creation_time diff --git a/element_facemap/version.py b/element_facemap/version.py index 7350757..8667345 100644 --- a/element_facemap/version.py +++ b/element_facemap/version.py @@ -1,2 +1,2 @@ """Package metadata.""" -__version__ = "0.1.6" +__version__ = "0.2.0" diff --git a/notebooks/tutorial_pipeline.py b/notebooks/tutorial_pipeline.py index a8b7640..9ff8430 100644 --- a/notebooks/tutorial_pipeline.py +++ b/notebooks/tutorial_pipeline.py @@ -1,34 +1,63 @@ +import os +import pathlib import datajoint as dj from element_animal import subject from element_animal.subject import Subject -from element_facemap import fbe, facemap_inference, db_prefix from element_lab import lab from element_lab.lab import Lab, Location, Project, Protocol, Source, User -from element_lab.lab import Device +from element_lab.lab import Device as Equipment from element_lab.lab import User as Experimenter from element_session import session_with_datetime as session from element_session.session_with_datetime import Session -import pathlib +from element_facemap import ( + facial_behavior_estimation as fbe, + facemap_inference, +) +import element_interface -# Declare functions for retrieving data -def get_facemap_root_data_dir(): - data_dir = dj.config.get("custom", {}).get("facemap_root_data_dir") - return pathlib.Path(data_dir) if data_dir else None +if "custom" not in dj.config: + dj.config["custom"] = {} + +# overwrite dj.config['custom'] values with environment variables if available + +dj.config["custom"]["database.prefix"] = os.getenv( + "DATABASE_PREFIX", dj.config["custom"].get("database.prefix", "") +) +dj.config["custom"]["facemap_root_data_dir"] = os.getenv( + "FACEMAP_ROOT_DATA_DIR", dj.config["custom"].get("facemap_root_data_dir", "") +) -def get_processed_root_data_dir(): - data_dir = dj.config.get("custom", {}).get("facemap_processed_data_dir", None) - return pathlib.Path(data_dir) if data_dir else None +db_prefix = dj.config["custom"].get("database.prefix", "") -def get_facemap_processed_data_dir(): - return get_processed_root_data_dir() +# Declare functions for retrieving data +def get_facemap_root_data_dir(): + """Retrieve facemap root data directory.""" + facemap_root_dirs = dj.config.get("custom", {}).get("facemap_root_data_dir", None) + if not facemap_root_dirs: + return None + elif isinstance(facemap_root_dirs, (str, pathlib.Path)): + return [facemap_root_dirs] + elif isinstance(facemap_root_dirs, list): + return facemap_root_dirs + else: + raise TypeError("`facemap_root_data_dir` must be a string, pathlib, or list") # Activate schemas lab.activate(db_prefix + "lab") +Device = lab.Device subject.activate(db_prefix + "subject", linking_module=__name__) session.activate(db_prefix + "session", linking_module=__name__) -fbe.activate(db_prefix + "facemap", linking_module=__name__) +Session = session.Session + +fbe.activate(db_prefix + "facemap_fbe", linking_module=__name__) facemap_inference.activate(db_prefix + "facemap_inference", linking_module=__name__) + + +def get_session_directory(session_key): + session_directory = (session.SessionDirectory & session_key).fetch1("session_dir") + + return session_directory diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 7bf8492..0000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -datajoint>=0.13.0 -element-interface>=0.3.0 -opencv-python-headless diff --git a/setup.py b/setup.py index 3f68c1f..fbe150e 100644 --- a/setup.py +++ b/setup.py @@ -1,24 +1,21 @@ #!/usr/bin/env python from os import path - from setuptools import find_packages, setup +import urllib.request -pkg_name = next(p for p in find_packages() if "." not in p) +pkg_name = "element_facemap" here = path.abspath(path.dirname(__file__)) with open(path.join(here, "README.md"), "r") as f: long_description = f.read() -with open(path.join(here, "requirements.txt")) as f: - requirements = f.read().splitlines() - with open(path.join(here, pkg_name, "version.py")) as f: exec(f.read()) setup( name=pkg_name.replace("_", "-"), - version=__version__, # noqa F821 - description="Facemap DataJoint element", + version=__version__, # noqa: F821 + description="Facemap DataJoint Element", long_description=long_description, long_description_content_type="text/markdown", author="DataJoint", @@ -28,5 +25,20 @@ keywords="neuroscience facemap science datajoint", packages=find_packages(exclude=["contrib", "docs", "tests*"]), scripts=[], - install_requires=requirements, + install_requires=[ + "datajoint>=0.13.0", + "ipykernel>=6.0.1", + "opencv-python", + "element-interface @ git+https://github.com/datajoint/element-interface.git", + "facemap @ git+https://github.com/kushalbakshi/facemap.git", + ], + extras_require={ + "elements": [ + "element-animal @ git+https://github.com/datajoint/element-animal.git", + "element-event @ git+https://github.com/datajoint/element-event.git", + "element-lab @ git+https://github.com/datajoint/element-lab.git", + "element-session @ git+https://github.com/datajoint/element-session.git", + ], + "tests": ["pytest", "pytest-cov", "shutils"], + }, )