diff --git a/.github/workflows/release-cmn.yml b/.github/workflows/release-cmn.yml new file mode 100644 index 00000000..7d037421 --- /dev/null +++ b/.github/workflows/release-cmn.yml @@ -0,0 +1,166 @@ +name: Release CaImAn + +on: + push: + tags: ['caiman-v*'] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: cmn-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: [self-hosted, Windows, X64, GPU] + timeout-minutes: 180 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract version from tag + shell: cmd + run: | + set VERSION=%GITHUB_REF_NAME:caiman-v=% + echo VERSION=%VERSION%>> %GITHUB_ENV% + + - name: Verify Miniconda + shell: cmd + run: C:\Miniconda3\Scripts\conda.exe --version + + - name: Create conda env for caiman + shell: cmd + run: | + C:\Miniconda3\Scripts\conda.exe env remove -n caiman_release -y || echo "no old env" + C:\Miniconda3\Scripts\conda.exe create -n caiman_release python=3.10 -y + + - name: Install caiman deps with conda-forge + shell: cmd + run: | + C:\Miniconda3\Scripts\conda.exe install -n caiman_release -c conda-forge pyinstaller caiman -y + C:\Miniconda3\Scripts\conda.exe run -n caiman_release python -c "import caiman; print('Caiman version:', getattr(caiman,'__version__','?'))" + + - name: caimanmanager install (detect path and export) + shell: cmd + run: | + C:\Miniconda3\Scripts\conda.exe run -n caiman_release caimanmanager install --force + for /f "delims=" %%H in ('C:\Miniconda3\Scripts\conda.exe run -n caiman_release python -c "import pathlib; print(pathlib.Path.home())"') do set "CM_HOME=%%H" + if exist "%CM_HOME%\caiman_data" ( + echo CAIMAN_DATA_DIR=%CM_HOME%\caiman_data>> %GITHUB_ENV% + ) else if exist "%CM_HOME%\.caimanmanager\caiman_data" ( + echo CAIMAN_DATA_DIR=%CM_HOME%\.caimanmanager\caiman_data>> %GITHUB_ENV% + ) else ( + echo WARNING: caiman_data not found after install + ) + + - name: Preflight paths + shell: cmd + run: | + cd + dir + dir Deploy + dir Deploy\pack_caiman.spec + + - name: Clean old dist/build + shell: cmd + working-directory: Deploy + run: | + if exist dist rmdir /s /q dist + if exist build rmdir /s /q build + + - name: Build caiman exe + shell: cmd + working-directory: Deploy + run: | + C:\Miniconda3\Scripts\conda.exe run -n caiman_release pyinstaller --clean --noconfirm pack_caiman_run.spec + echo === DIST TREE === + dir /s /b dist + + - name: Zip onedir output with build-info + shell: cmd + working-directory: Deploy + env: + GIT_SHA: ${{ github.sha }} + run: | + rem Locate the onedir app folder under dist + set "APPDIR=" + for /d %%D in (dist\*) do ( set "APPDIR=%%D" & goto :found ) + :found + if not defined APPDIR ( echo ERROR: no onedir folder found in Deploy\dist & exit /b 1 ) + + rem Write build-info into the app folder (included in the zip) + echo Version: %VERSION%> "%APPDIR%\build-info.txt" + echo Commit: %GIT_SHA%>> "%APPDIR%\build-info.txt" + echo Date: %DATE% %TIME%>> "%APPDIR%\build-info.txt" + + set "ZIPNAME=caiman-%VERSION%.zip" + + rem Use conda env's python (single-line, no backslashes) + C:\Miniconda3\Scripts\conda.exe run -n caiman_release python -c "import os,zipfile; a=r'%APPDIR%'; zf=r'%ZIPNAME%'; assert os.path.isdir(a), 'no APPDIR: '+a; z=zipfile.ZipFile(zf,'w',zipfile.ZIP_DEFLATED); [z.write(os.path.join(r,f), os.path.relpath(os.path.join(r,f),a)) for r,_,fs in os.walk(a) for f in fs]; z.close()" + echo Created zip: %ZIPNAME% + + - name: Show zip contents + shell: cmd + working-directory: Deploy + run: | + set "ZN=caiman-%VERSION%.zip" + if not exist "%ZN%" ( echo ERROR: zip not found & exit /b 1 ) + C:\Miniconda3\Scripts\conda.exe run -n caiman_release python -c "import os,zipfile; zn=r'%ZN%'; z=zipfile.ZipFile(zn,'r'); n=z.namelist(); print('Entries in',zn,':',len(n)); [print(' ',x) for x in n[:50]]; z.close()" + + - name: SHA256 of release zip + shell: cmd + working-directory: Deploy + run: | + setlocal EnableDelayedExpansion + set ZIP=caiman-%VERSION%.zip + if not exist "%ZIP%" ( echo ERROR: zip not found & exit /b 1 ) + for /f "usebackq skip=1 tokens=1" %%H in (`certutil -hashfile "%ZIP%" SHA256 ^| findstr /v /i "hash certutil"`) do ( + set HASH=%%H + goto :got + ) + :got + echo !HASH!> caiman-%VERSION%.zip.sha256 + type caiman-%VERSION%.zip.sha256 + + - name: Copy release zip + shell: cmd + working-directory: Deploy + env: + SHARE_DIR: "C:\\DoricSoftware\\danse\\Libraries\\CaImAn" + run: | + set "ZIP=caiman-%VERSION%.zip" + if not exist "%ZIP%" ( + echo ERROR: zip not found + exit /b 1 + ) + set "DEST=%SHARE_DIR%" + if not exist "%DEST%" ( + echo Creating %DEST% + mkdir "%DEST%" + ) + copy /Y "%ZIP%" "%DEST%\" + echo Copied %ZIP% to %DEST% + + - name: Create GitHub Release (attach zip + checksum) + uses: softprops/action-gh-release@v2 + with: + name: caiman ${{ env.VERSION }} + body: | + Automated caiman release for tag ${{ github.ref_name }}. + - Version: ${{ env.VERSION }} + - Commit: ${{ github.sha }} + files: | + Deploy/caiman-${{ env.VERSION }}.zip + Deploy/caiman-${{ env.VERSION }}.zip.sha256 + + - name: Upload dist artifact (only on failure) + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: caiman-dist-${{ env.VERSION }} + path: Deploy/dist/** + retention-days: 3 + compression-level: 1 diff --git a/.github/workflows/release-dlc.yml b/.github/workflows/release-dlc.yml new file mode 100644 index 00000000..ebc78e76 --- /dev/null +++ b/.github/workflows/release-dlc.yml @@ -0,0 +1,148 @@ +name: Release DeepLabCut + +on: + push: + tags: ['deeplabcut-v*'] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: dlc-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: [self-hosted, Windows, X64, GPU] + timeout-minutes: 180 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract version from tag (cmd) + shell: cmd + run: | + set VERSION=%GITHUB_REF_NAME:deeplabcut-v=% + echo VERSION=%VERSION%>> %GITHUB_ENV% + + - name: Create venv + shell: cmd + run: | + C:\Python310\python.exe -V + C:\Python310\python.exe -m venv venv + + - name: Install deps + shell: cmd + run: | + venv\Scripts\python -m pip install --upgrade pip + venv\Scripts\pip install --constraint Deploy\constraints\pins-dlc.txt h5py pyinstaller deeplabcut==3.0.0rc8 + venv\Scripts\pip install --constraint Deploy\constraints\pins-dlc.txt --upgrade --index-url https://download.pytorch.org/whl/cu128 torch==2.8.0+cu128 torchvision==0.23.0+cu128 + venv\Scripts\python -c "import torch;print('Torch:',torch.__version__);print('CUDA build:',getattr(torch.version,'cuda',None));print('CUDA available:',torch.cuda.is_available())" + + - name: Clean old dist/build + shell: cmd + working-directory: Deploy + run: | + if exist dist rmdir /s /q dist + if exist build rmdir /s /q build + + - name: Build deeplabcut + shell: cmd + working-directory: Deploy + run: | + ..\venv\Scripts\pyinstaller --clean --noconfirm pack_deeplabcut.spec + echo === DIST TREE === + dir /s /b dist + + - name: Smoke test torch/deeplabcut import + shell: cmd + run: | + venv\Scripts\python -c "import torch; import deeplabcut; print('torch', torch.__version__)" + + - name: Zip onedir output with build-info + shell: cmd + working-directory: Deploy + env: + GIT_SHA: ${{ github.sha }} + run: | + rem Locate the onedir app folder under dist + set "APPDIR=" + for /d %%D in (dist\*) do ( set "APPDIR=%%D" & goto :found ) + :found + if not defined APPDIR ( echo ERROR: no onedir folder found in Deploy\dist & exit /b 1 ) + + rem Write build-info into the app folder (included in the zip) + echo Version: %VERSION%> "%APPDIR%\build-info.txt" + echo Commit: %GIT_SHA%>> "%APPDIR%\build-info.txt" + echo Date: %DATE% %TIME%>> "%APPDIR%\build-info.txt" + + set "ZIPNAME=deeplabcut-%VERSION%.zip" + + rem One-line Python (no backslashes/newlines) + ..\venv\Scripts\python -c "import os,zipfile; a=r'%APPDIR%'; zf=r'%ZIPNAME%'; assert os.path.isdir(a), 'no APPDIR: '+a; z=zipfile.ZipFile(zf,'w',zipfile.ZIP_DEFLATED); [z.write(os.path.join(r,f), os.path.relpath(os.path.join(r,f),a)) for r,_,fs in os.walk(a) for f in fs]; z.close()" + echo Created zip: %ZIPNAME% + + - name: Show zip contents + shell: cmd + working-directory: Deploy + run: | + set "ZN=deeplabcut-%VERSION%.zip" + if not exist "%ZN%" ( echo ERROR: zip not found & exit /b 1 ) + ..\venv\Scripts\python -c "import os,zipfile; zn=r'%ZN%'; z=zipfile.ZipFile(zn,'r'); n=z.namelist(); print('Entries in',zn,':',len(n)); [print(' ',x) for x in n[:50]]; z.close()" + + + - name: SHA256 of release zip + shell: cmd + working-directory: Deploy + run: | + setlocal EnableDelayedExpansion + set ZIP=deeplabcut-%VERSION%.zip + for /f "usebackq skip=1 tokens=1" %%H in (`certutil -hashfile "%ZIP%" SHA256 ^| findstr /v /i "hash certutil"`) do ( + set HASH=%%H + goto :got + ) + :got + echo !HASH!> deeplabcut-%VERSION%.zip.sha256 + type deeplabcut-%VERSION%.zip.sha256 + + - name: Copy release zip to network share + shell: cmd + working-directory: Deploy + env: + SHARE_DIR: "C:\\DoricSoftware\\danse\\Libraries\\DeepLabCut" + run: | + set "ZIP=deeplabcut-%VERSION%.zip" + if not exist "%ZIP%" ( + echo ERROR: zip not found + exit /b 1 + ) + set "DEST=%SHARE_DIR%" + if not exist "%DEST%" ( + echo Creating %DEST% + mkdir "%DEST%" + ) + copy /Y "%ZIP%" "%DEST%\" + echo Copied %ZIP% to %DEST% + + - name: Create GitHub Release (attach zip + checksum) + uses: softprops/action-gh-release@v2 + with: + name: deeplabcut ${{ env.VERSION }} + body: | + Automated deeplabcut release for tag ${{ github.ref_name }}. + - Version: ${{ env.VERSION }} + - Commit: ${{ github.sha }} + files: | + Deploy/deeplabcut-${{ env.VERSION }}.zip + Deploy/deeplabcut-${{ env.VERSION }}.zip.sha256 + + - name: Upload dist artifact (only on failure) + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: deeplabcut-dist-${{ env.VERSION }} + path: Deploy/dist/** + retention-days: 3 + compression-level: 1 diff --git a/.github/workflows/release-mnn.yml b/.github/workflows/release-mnn.yml new file mode 100644 index 00000000..e9f10634 --- /dev/null +++ b/.github/workflows/release-mnn.yml @@ -0,0 +1,171 @@ +name: Release MiniAn + +on: + push: + tags: ['minian-v*'] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: mnn-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: [self-hosted, Windows, X64, GPU] + timeout-minutes: 180 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract version from tag + shell: cmd + run: | + set VERSION=%GITHUB_REF_NAME:minian-v=% + echo VERSION=%VERSION%>> %GITHUB_ENV% + + - name: Verify Miniconda + shell: cmd + run: C:\Miniconda3\Scripts\conda.exe --version + + - name: Update conda tooling and clean cache + shell: cmd + run: | + C:\Miniconda3\Scripts\conda.exe update -n base -c defaults conda conda-package-handling -y + C:\Miniconda3\Scripts\conda.exe config --set conda_pkg_format 1 + C:\Miniconda3\Scripts\conda.exe clean --packages --tarballs -y + + - name: Create conda env for minian + shell: cmd + run: | + C:\Miniconda3\Scripts\conda.exe env remove -n minian_release -y || echo "no old env" + set "ENV_FILE=%GITHUB_WORKSPACE%\Deploy\constraints\environment-minian.yml" + if not exist "%ENV_FILE%" ( + echo ERROR: environment file not found at %ENV_FILE% + exit /b 1 + ) + set "CONDA_PKGS_DIRS=%GITHUB_WORKSPACE%\conda_pkgs" + if not exist "%CONDA_PKGS_DIRS%" mkdir "%CONDA_PKGS_DIRS%" + C:\Miniconda3\Scripts\conda.exe env create -n minian_release -f "%ENV_FILE%" --yes + + - name: Verify minian deps + shell: cmd + run: | + set "CONDA_PKGS_DIRS=%GITHUB_WORKSPACE%\conda_pkgs" + C:\Miniconda3\Scripts\conda.exe run -n minian_release python -c "import minian; print('MiniAn version:', getattr(minian,'__version__','?'))" + + - name: Snapshot conda packages + shell: cmd + run: | + C:\Miniconda3\Scripts\conda.exe list --explicit -n minian_release > minian-conda-explicit.txt + type minian-conda-explicit.txt + + - name: Upload conda manifest + uses: actions/upload-artifact@v4 + with: + name: minian-conda-explicit-${{ env.VERSION }} + path: minian-conda-explicit.txt + + - name: Clean old dist/build + shell: cmd + working-directory: Deploy + run: | + if exist dist rmdir /s /q dist + if exist build rmdir /s /q build + + - name: Build minian exe + shell: cmd + working-directory: Deploy + run: | + C:\Miniconda3\Scripts\conda.exe run -n minian_release pyinstaller --clean --noconfirm pack_minian.spec + echo === DIST TREE === + dir /s /b dist + + - name: Zip onedir output with build-info + shell: cmd + working-directory: Deploy + env: + GIT_SHA: ${{ github.sha }} + run: | + rem Locate the onedir app folder under dist + set "APPDIR=" + for /d %%D in (dist\*) do ( set "APPDIR=%%D" & goto :found ) + :found + if not defined APPDIR ( echo ERROR: no onedir folder found in Deploy\dist & exit /b 1 ) + + rem Write build-info into the app folder (included in the zip) + echo Version: %VERSION%> "%APPDIR%\build-info.txt" + echo Commit: %GIT_SHA%>> "%APPDIR%\build-info.txt" + echo Date: %DATE% %TIME%>> "%APPDIR%\build-info.txt" + + set "ZIPNAME=minian-%VERSION%.zip" + + rem Use conda env's python (single-line, no backslashes) + C:\Miniconda3\Scripts\conda.exe run -n minian_release python -c "import os,zipfile; a=r'%APPDIR%'; zf=r'%ZIPNAME%'; assert os.path.isdir(a), 'no APPDIR: '+a; z=zipfile.ZipFile(zf,'w',zipfile.ZIP_DEFLATED); [z.write(os.path.join(r,f), os.path.relpath(os.path.join(r,f),a)) for r,_,fs in os.walk(a) for f in fs]; z.close()" + echo Created zip: %ZIPNAME% + + - name: Show zip contents + shell: cmd + working-directory: Deploy + run: | + set "ZN=minian-%VERSION%.zip" + if not exist "%ZN%" ( echo ERROR: zip not found & exit /b 1 ) + C:\Miniconda3\Scripts\conda.exe run -n minian_release python -c "import os,zipfile; zn=r'%ZN%'; z=zipfile.ZipFile(zn,'r'); n=z.namelist(); print('Entries in',zn,':',len(n)); [print(' ',x) for x in n[:50]]; z.close()" + + - name: SHA256 of release zip + shell: cmd + working-directory: Deploy + run: | + setlocal EnableDelayedExpansion + set ZIP=minian-%VERSION%.zip + if not exist "%ZIP%" ( echo ERROR: zip not found & exit /b 1 ) + for /f "usebackq skip=1 tokens=1" %%H in (`certutil -hashfile "%ZIP%" SHA256 ^| findstr /v /i "hash certutil"`) do ( + set HASH=%%H + goto :got + ) + :got + echo !HASH!> minian-%VERSION%.zip.sha256 + type minian-%VERSION%.zip.sha256 + + - name: Copy release zip to network share + shell: cmd + working-directory: Deploy + env: + SHARE_DIR: "C:\\DoricSoftware\\danse\\Libraries\\MiniAn" + run: | + set "ZIP=minian-%VERSION%.zip" + if not exist "%ZIP%" ( + echo ERROR: zip not found + exit /b 1 + ) + set "DEST=%SHARE_DIR%" + if not exist "%DEST%" ( + echo Creating %DEST% + mkdir "%DEST%" + ) + copy /Y "%ZIP%" "%DEST%\" + echo Copied %ZIP% to %DEST% + + - name: Create GitHub Release (attach zip + checksum) + uses: softprops/action-gh-release@v2 + with: + name: minian ${{ env.VERSION }} + body: | + Automated minian release for tag ${{ github.ref_name }}. + - Version: ${{ env.VERSION }} + - Commit: ${{ github.sha }} + files: | + Deploy/minian-${{ env.VERSION }}.zip + Deploy/minian-${{ env.VERSION }}.zip.sha256 + + - name: Upload dist artifact (only on failure) + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: minian-dist-${{ env.VERSION }} + path: Deploy/dist/** + retention-days: 3 + compression-level: 1 diff --git a/.github/workflows/release-s2p.yml b/.github/workflows/release-s2p.yml new file mode 100644 index 00000000..171c4031 --- /dev/null +++ b/.github/workflows/release-s2p.yml @@ -0,0 +1,141 @@ +name: Release Suite2p + +on: + push: + tags: ['suite2p-v*'] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: s2p-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: [self-hosted, Windows, X64, GPU] + timeout-minutes: 180 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract version from tag + shell: cmd + run: | + set VERSION=%GITHUB_REF_NAME:suite2p-v=% + echo VERSION=%VERSION%>> %GITHUB_ENV% + + - name: Create venv + shell: cmd + run: | + C:\Python310\python.exe -V + C:\Python310\python.exe -m venv venv + + - name: Install deps + shell: cmd + run: | + venv\Scripts\python -m pip install --upgrade pip + venv\Scripts\pip install --constraint Deploy\constraints\pins-s2p.txt h5py pyinstaller suite2p==0.14.4 tbb + venv\Scripts\python -c "import suite2p; print('Suite2p version:', getattr(suite2p,'__version__','?'))" + + - name: Clean old dist/build + shell: cmd + working-directory: Deploy + run: | + if exist dist rmdir /s /q dist + if exist build rmdir /s /q build + + - name: Build suite2p + shell: cmd + working-directory: Deploy + run: | + ..\venv\Scripts\pyinstaller --clean --noconfirm pack_suite2p.spec + echo === DIST TREE === + dir /s /b dist + + - name: Zip onedir output with build-info + shell: cmd + working-directory: Deploy + env: + GIT_SHA: ${{ github.sha }} + run: | + rem Locate the onedir app folder under dist + set "APPDIR=" + for /d %%D in (dist\*) do ( set "APPDIR=%%D" & goto :found ) + :found + if not defined APPDIR ( echo ERROR: no onedir folder found in Deploy\dist & exit /b 1 ) + + rem Write build-info into the app folder (included in the zip) + echo Version: %VERSION%> "%APPDIR%\build-info.txt" + echo Commit: %GIT_SHA%>> "%APPDIR%\build-info.txt" + echo Date: %DATE% %TIME%>> "%APPDIR%\build-info.txt" + + set "ZIPNAME=suite2p-%VERSION%.zip" + + ..\venv\Scripts\python -c "import os,zipfile; a=r'%APPDIR%'; zf=r'%ZIPNAME%'; assert os.path.isdir(a), 'no APPDIR: '+a; z=zipfile.ZipFile(zf,'w',zipfile.ZIP_DEFLATED); [z.write(os.path.join(r,f), os.path.relpath(os.path.join(r,f),a)) for r,_,fs in os.walk(a) for f in fs]; z.close()" + echo Created zip: %ZIPNAME% + + - name: Show zip contents + shell: cmd + working-directory: Deploy + run: | + set "ZN=suite2p-%VERSION%.zip" + if not exist "%ZN%" ( echo ERROR: zip not found & exit /b 1 ) + ..\venv\Scripts\python -c "import os,zipfile; zn=r'%ZN%'; z=zipfile.ZipFile(zn,'r'); n=z.namelist(); print('Entries in',zn,':',len(n)); [print(' ',x) for x in n[:50]]; z.close()" + + - name: SHA256 of release zip + shell: cmd + working-directory: Deploy + run: | + setlocal EnableDelayedExpansion + set ZIP=suite2p-%VERSION%.zip + if not exist "%ZIP%" ( echo ERROR: zip not found & exit /b 1 ) + for /f "usebackq skip=1 tokens=1" %%H in (`certutil -hashfile "%ZIP%" SHA256 ^| findstr /v /i "hash certutil"`) do ( + set HASH=%%H + goto :got + ) + :got + echo !HASH!> suite2p-%VERSION%.zip.sha256 + type suite2p-%VERSION%.zip.sha256 + + - name: Copy release zip to network share + shell: cmd + working-directory: Deploy + env: + SHARE_DIR: "C:\\DoricSoftware\\danse\\Libraries\\Suite2p" + run: | + set "ZIP=suite2p-%VERSION%.zip" + if not exist "%ZIP%" ( + echo ERROR: zip not found + exit /b 1 + ) + set "DEST=%SHARE_DIR%" + if not exist "%DEST%" ( + echo Creating %DEST% + mkdir "%DEST%" + ) + copy /Y "%ZIP%" "%DEST%\" + echo Copied %ZIP% to %DEST% + + - name: Create GitHub Release (attach zip + checksum) + uses: softprops/action-gh-release@v2 + with: + name: suite2p ${{ env.VERSION }} + body: | + Automated suite2p release for tag ${{ github.ref_name }}. + - Version: ${{ env.VERSION }} + - Commit: ${{ github.sha }} + files: | + Deploy/suite2p-${{ env.VERSION }}.zip + Deploy/suite2p-${{ env.VERSION }}.zip.sha256 + + - name: Upload dist artifact (only on failure) + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: suite2p-dist-${{ env.VERSION }} + path: Deploy/dist/** + retention-days: 3 + compression-level: 1 diff --git a/.gitignore b/.gitignore index 4a82b8f4..e8a57ffe 100644 --- a/.gitignore +++ b/.gitignore @@ -6,14 +6,13 @@ __pycache__/ *_env.txt *.tif *.zip -.vscode/settings.json +.vscode .mypy_cache -Deploy/dist -Deploy/build -Deploy/suite2p +.venv*/ + +Deploy/build/ +Deploy/dist/ caiman_data/ -CaImAn/caiman_correlation_pnr_functions/CaImAn-b5932abe85c478fae4004e8df14535f3f5f7274a.zip -CaImAn/caiman_correlation_pnr_functions/pre_processing_comment.py -CaImAn/caiman_correlation_pnr_functions/summary_images_comment.py +CaImAn/caiman_correlation_pnr_functions/ diff --git a/DeepLabCut/deeplabcut_run.py b/DeepLabCut/deeplabcut_run.py index b5517e51..938b434a 100644 --- a/DeepLabCut/deeplabcut_run.py +++ b/DeepLabCut/deeplabcut_run.py @@ -15,6 +15,7 @@ 'matplotlib.image', 'matplotlib.lines', 'matplotlib.patches', + 'matplotlib.patches.Ellipse', 'matplotlib.container', 'matplotlib.transforms', 'matplotlib.tri._triangulation', diff --git a/Deploy/constraints/environment-minian.yml b/Deploy/constraints/environment-minian.yml new file mode 100644 index 00000000..3b0ab862 --- /dev/null +++ b/Deploy/constraints/environment-minian.yml @@ -0,0 +1,57 @@ +name: minian # MiniAn last release was v1.2.1 on Feb 10, 2022, they stopped updating conda package +channels: + - bioconda + - conda-forge + - defaults +dependencies: + - bokeh=1.4.0 # =1.4.0 + - cvxpy=1.2.1 # >=1.1.11 + - dask=2021.2.0 # =2021.2.0 + - datashader=0.12.1 # =0.12.1 + - distributed=2021.2.0 # =2021.2.0 + - ecos=2.0.10 # >=2.0.7 + - ffmpeg=6.1.0 # + - ffmpeg-python=0.2.0 # >=0.2.0 + - fftw=3.3.10 # + - holoviews=1.12.7 # =1.12.7 + - jupyter # + - matplotlib-base=3.2.2 # =3.2 + - natsort=8.4.0 # + - netcdf4=1.6.0 # + - networkx=2.4 # =2.4 + - numba=0.52.0 # =0.52.0 + - numpy=1.20.2 # =1.20.2 + - opencv=4.2.0 # =4.2.0 + - pandas=1.2.3 # =1.2.3 + - panel=0.8.0 # =0.8.0 + - param=1.9.3 # =1.9 + - pyfftw=0.12.0 # =0.12.0 + - python=3.8 # =3.8 + - scikit-image=0.18.1 # =0.18.1 + - scikit-learn=0.22.1 # =0.22.1 + - scipy=1.9.1 # >=1.4.1 + - scs=3.2.0 # + - sk-video=1.1.10 # + - statsmodels=0.13.2 # >=0.11.1 + - tifffile=2021.11.2 # + - xarray=0.16.2 # =0.16.2 + - zarr=2.17.1 # + - sparse=0.11.2 # =0.11.2 + - pymetis=2020.1 # =2020.1 + - rechunker=0.3.3 # =0.3.3 + - medpy=0.4.0 # =0.4.0 + - pip=24.2 # + - jinja2=2.11.3 # =2.11.3 + - pefile=2024.8.26 + - pip: + - SimpleITK==2.0.2 # ==2.0.2 + - minian=1.2.1 # Feb 10, 2022 release + # Local versions + - h5py=3.7.0 # May 24, 2022 release + - pyinstaller=6.7.0 # May 21, 2024 release +# Releases suggested by Codex + # - h5py=3.1.0 # Nov 6, 2020 release + # - pyinstaller=4.5.1 # Aug 6, 2021 release +# Releases just before the last update of minian conda package +# - h5py=3.6.0 # Nov 16, 2021 release +# - pyinstaller=4.9.0 # Feb 3, 2022 release \ No newline at end of file diff --git a/Deploy/constraints/pins-dlc.txt b/Deploy/constraints/pins-dlc.txt new file mode 100644 index 00000000..8ac51b36 --- /dev/null +++ b/Deploy/constraints/pins-dlc.txt @@ -0,0 +1,3 @@ +llvmlite==0.44.0 +numba==0.61.2 +numpy==1.26.4 diff --git a/Deploy/constraints/pins-s2p.txt b/Deploy/constraints/pins-s2p.txt new file mode 100644 index 00000000..d4467595 --- /dev/null +++ b/Deploy/constraints/pins-s2p.txt @@ -0,0 +1,4 @@ +llvmlite==0.44.0 +numba==0.61.2 +numpy==1.26.4 +tbb==2022.3.0 diff --git a/Deploy/constraints/torch_openmp_env.py b/Deploy/constraints/torch_openmp_env.py new file mode 100644 index 00000000..91868e95 --- /dev/null +++ b/Deploy/constraints/torch_openmp_env.py @@ -0,0 +1,7 @@ +"""Runtime hook to prevent Intel OpenMP initialization conflicts in frozen builds.""" + +import os + +# Allow duplicate Intel OpenMP runtimes that ship with torch/numpy/scipy +# to coexist inside the bundled application. +os.environ.setdefault("KMP_DUPLICATE_LIB_OK", "TRUE") diff --git a/Deploy/pack_caiman.spec b/Deploy/pack_caiman.spec new file mode 100644 index 00000000..586fd1f6 --- /dev/null +++ b/Deploy/pack_caiman.spec @@ -0,0 +1,109 @@ +# -*- mode: python ; coding: utf-8 -*- + +import os + +from PyInstaller.building.build_main import Analysis, PYZ, EXE, COLLECT +from PyInstaller.building.datastruct import Tree +from PyInstaller.utils.hooks import collect_all + +_specdir = os.path.abspath(os.path.dirname(SPEC)) +distpath = os.path.join(_specdir, "dist") +workpath = os.path.join(_specdir, "build") + +CAIMAN_DATA_DIR = os.environ.get("CAIMAN_DATA_DIR") + +BLOCK_CIPHER = None + +PACKAGES = [ + 'caiman', + 'hdmf', + 'pynwb', + 'param', + 'skimage', + 'scipy' +] + +EXCLUDES = [ + "PyQt5", + "Markdown", + "jupyter", + "panel", + "matplotlib", + "bokeh", + "IPython", + "ipyparallel", + "ipywidgets", + "tensorflow", + "pyqtgraph", + "torch", + "torchvision", + "scipy._lib.array_api_compat.torch" +] + +datas = [] +binaries = [] +hiddenimports = [] +for package in PACKAGES: + tmp_ret = collect_all(package) + datas += tmp_ret[0] + binaries += tmp_ret[1] + hiddenimports += tmp_ret[2] + +a_caimAn = Analysis( + ['../CaImAn/caiman_run.py'], + pathex=['../'], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=EXCLUDES, + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=BLOCK_CIPHER, + noarchive=False, +) + +pyz_caimAn = PYZ( + a_caimAn.pure, + a_caimAn.zipped_data, + cipher=BLOCK_CIPHER +) + +exe_caimAn = EXE( + pyz_caimAn, + a_caimAn.scripts, + [], + name='caiman', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) + +extra_nodes = [] +if CAIMAN_DATA_DIR and os.path.isdir(CAIMAN_DATA_DIR): + extra_nodes.append(Tree(CAIMAN_DATA_DIR, prefix="caiman_data")) +else: + print("[spec] WARNING: CAIMAN_DATA_DIR not set or not a directory; models/configs not bundled.") + +coll = COLLECT( + exe_caimAn, + a_caimAn.binaries, + a_caimAn.zipfiles, + a_caimAn.datas, + *extra_nodes, + strip=False, + upx=True, + upx_exclude=[], + name='caiman', +) diff --git a/Deploy/pack_caiman_run.spec b/Deploy/pack_caiman_run.spec deleted file mode 100644 index 052e05a6..00000000 --- a/Deploy/pack_caiman_run.spec +++ /dev/null @@ -1,87 +0,0 @@ -# -*- mode: python ; coding: utf-8 -*- - -from PyInstaller.utils.hooks import collect_all -from PyInstaller.utils.hooks import copy_metadata -from PyInstaller.utils.hooks import collect_dynamic_libs - -# -# for maim CaimAn python script -# - -block_cipher = None - -datas = [] -binaries = [] -hiddenimports = [] -excludes = [] - -tmp_ret = collect_all('caiman') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -tmp_ret = collect_all('hdmf') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -tmp_ret = collect_all('pynwb') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -datas += copy_metadata('param', recursive=True) -tmp_ret = collect_all('param') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -tmp_ret = collect_all('skimage') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -tmp_ret = collect_all('scipy') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -datas += [( '../CaImAn/caiman_data/model', 'caiman_data/model')] - -excludes = ["PyQt5", "Markdown", "jupyter", "panel", "matplotlib", "bokeh", "IPython", "ipyparallel", "ipywidgets", "tensorflow", "pyqtgraph"] - -a_caimAn = Analysis( - ['../CaImAn/caiman_run.py'], - pathex=['../'], - binaries=binaries, - datas=datas, - hiddenimports=hiddenimports, - hookspath=[], - hooksconfig={}, - runtime_hooks=[], - excludes=excludes, - win_no_prefer_redirects=False, - win_private_assemblies=False, - cipher=block_cipher, - noarchive=False, -) - -pyz_caimAn = PYZ(a_caimAn.pure, a_caimAn.zipped_data, cipher=block_cipher) - -exe_caimAn = EXE( - pyz_caimAn, - a_caimAn.scripts, - [], - name='caiman', - debug=False, - bootloader_ignore_signals=False, - strip=False, - upx=True, - upx_exclude=[], - runtime_tmpdir=None, - console=True, - disable_windowed_traceback=False, - argv_emulation=False, - target_arch=None, - codesign_identity=None, - entitlements_file=None, -) - -coll = COLLECT( - exe_caimAn, - a_caimAn.binaries, - a_caimAn.zipfiles, - a_caimAn.datas, - strip=False, - upx=True, - upx_exclude=[], - name='caiman', -) diff --git a/Deploy/pack_deeplabcut_run.spec b/Deploy/pack_deeplabcut.spec similarity index 56% rename from Deploy/pack_deeplabcut_run.spec rename to Deploy/pack_deeplabcut.spec index 2f4f10c5..09652b57 100644 --- a/Deploy/pack_deeplabcut_run.spec +++ b/Deploy/pack_deeplabcut.spec @@ -1,24 +1,40 @@ # -*- mode: python ; coding: utf-8 -*- +import os +from PyInstaller.building.build_main import Analysis, PYZ, EXE, COLLECT, TOC from PyInstaller.utils.hooks import collect_all -from PyInstaller.utils.hooks import copy_metadata -from PyInstaller.utils.hooks import collect_dynamic_libs +_specdir = os.path.abspath(os.path.dirname(SPEC)) +distpath = os.path.join(_specdir, "dist") +workpath = os.path.join(_specdir, "build") -block_cipher = None +BLOCK_CIPHER = None -datas = [] -binaries = [] -hiddenimports = [] -excludes = [] +PACKAGES = [ + 'deeplabcut', + 'charset_normalizer', + 'dateutil', + 'safetensors', + 'shapely', + 'tables', + 'tkinter', + 'pyarrow', +] -# datas += copy_metadata('deeplabcut', recursive=True) -tmp_ret = collect_all('deeplabcut') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +datas = [] +binaries = [] +hiddenimports = [] +for package in PACKAGES: + tmp_ret = collect_all(package) + datas += tmp_ret[0] + binaries += tmp_ret[1] + hiddenimports += tmp_ret[2] -excludes = ["tensorflow","PySide6", "PyQT6", "PyQT5", "IPython", "Markdown", "jupyter", "napari", - "napari_deeplabcut", "napari_console", "npe2", "napari_plugin_engine", "napari_svg", "matplotlib" - ] +hiddenimports += ['pyarrow._generated_version'] + +EXCLUDE_PACKAGES = [ + "matplotlib" +] a_deeplabcut = Analysis( ['../DeepLabCut/deeplabcut_run.py'], @@ -28,15 +44,15 @@ a_deeplabcut = Analysis( hiddenimports=hiddenimports, hookspath=[], hooksconfig={}, - runtime_hooks=[], - excludes=excludes, + runtime_hooks=['constraints/torch_openmp_env.py'], + excludes=EXCLUDE_PACKAGES, win_no_prefer_redirects=False, win_private_assemblies=False, - cipher=block_cipher, + cipher=BLOCK_CIPHER, noarchive=False, ) -exclude_binaries = [ +EXCLUDE_BINARIES = [ 'cublasLt64_12.dll', 'cublas64_12.dll', 'cudart64_12.dll', @@ -54,11 +70,17 @@ exclude_binaries = [ 'cudnn_heuristic64_9.dll', 'cudnn_ops64_9.dll', 'cudnn64_9.dll' - ] +] -a_deeplabcut.binaries= TOC([x for x in a_deeplabcut.binaries if not any(exclude in x[0] for exclude in exclude_binaries)]) +a_deeplabcut.binaries= TOC([ + x for x in a_deeplabcut.binaries if not any(exclude in x[0] for exclude in EXCLUDE_BINARIES) +]) -pyz_deeplabcut = PYZ(a_deeplabcut.pure, a_deeplabcut.zipped_data, cipher=block_cipher) +pyz_deeplabcut = PYZ( + a_deeplabcut.pure, + a_deeplabcut.zipped_data, + cipher=BLOCK_CIPHER +) exe_deeplabcut = EXE( pyz_deeplabcut, @@ -68,7 +90,7 @@ exe_deeplabcut = EXE( debug=False, bootloader_ignore_signals=False, strip=False, - upx=True, + upx=False, upx_exclude=[], runtime_tmpdir=None, console=True, @@ -85,10 +107,7 @@ coll = COLLECT( a_deeplabcut.zipfiles, a_deeplabcut.datas, strip=False, - upx=True, + upx=False, upx_exclude=[], name='deeplabcut', ) - - - diff --git a/Deploy/pack_minian.spec b/Deploy/pack_minian.spec new file mode 100644 index 00000000..aef20b79 --- /dev/null +++ b/Deploy/pack_minian.spec @@ -0,0 +1,134 @@ +# -*- mode: python ; coding: utf-8 -*- + +import os +from pathlib import Path +from PyInstaller.building.build_main import Analysis, PYZ, EXE, COLLECT +from PyInstaller.utils.hooks import collect_all, collect_dynamic_libs + +_specdir = os.path.abspath(os.path.dirname(SPEC)) +distpath = os.path.join(_specdir, "dist") +workpath = os.path.join(_specdir, "build") + +BLOCK_CIPHER = None + +PACKAGES = [ + 'minian', + 'distributed', + 'skimage', + 'scipy', + 'pyviz_comms', +] + +EXCLUDES = [ + "bokeh", + "IPython", + "jupyter", + "Markdown", + "matplotlib", + "notebook", + "panel", + "PyQt5", +] + +datas = [] +binaries = [] +hiddenimports = [] +for package in PACKAGES: + tmp_ret = collect_all(package) + datas += tmp_ret[0] + binaries += tmp_ret[1] + hiddenimports += tmp_ret[2] + +binaries += collect_dynamic_libs('llvmlite', destdir=os.path.join('Library', 'bin')) + +DLL_PREFIXES = { + "ff", + "hdf", + "icu", + "itk", + "lib", + "open", + "qt5", +} + +DLL_EXACT = { + "freetype.dll", + "lerc.dll", + "mfhdf.dll", + "mkl_pgi_thread.2.dll", + "netcdf.dll", + "pthreadvse2.dll", + "szip.dll", + "tiff.dll", + "xdr.dll", + "yaml.dll", + "zip.dll", + "zstd.dll", +} + +conda_prefix = os.environ.get('MINIAN_CONDA_PREFIX') or os.environ.get('CONDA_PREFIX') +library_bin = Path(conda_prefix) / 'Library' / 'bin' +if library_bin.is_dir(): + existing = {os.path.basename(src).lower() for src, _ in binaries} + selected = [] + for dll in sorted(library_bin.glob('*.dll'), key=lambda p: p.name.lower()): + name = dll.name.lower() + if name not in DLL_EXACT and not any(name.startswith(prefix) for prefix in DLL_PREFIXES): + continue + if name in existing: + continue + selected.append((str(dll), '.')) + existing.add(name) + binaries.extend(selected) + +a_minian = Analysis( + ['../MiniAn/minian_run.py'], + pathex=['../'], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=EXCLUDES, + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=BLOCK_CIPHER, + noarchive=False, +) + +pyz_minian = PYZ( + a_minian.pure, + a_minian.zipped_data, + cipher=BLOCK_CIPHER +) + +exe_minian = EXE( + pyz_minian, + a_minian.scripts, + [], + name='minian', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=False, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) + +coll = COLLECT( + exe_minian, + a_minian.binaries, + a_minian.zipfiles, + a_minian.datas, + strip=False, + upx=False, + upx_exclude=[], + name='minian', +) diff --git a/Deploy/pack_minian_run.spec b/Deploy/pack_minian_run.spec deleted file mode 100644 index 498f915c..00000000 --- a/Deploy/pack_minian_run.spec +++ /dev/null @@ -1,76 +0,0 @@ -# -*- mode: python ; coding: utf-8 -*- - -from PyInstaller.utils.hooks import collect_all -from PyInstaller.utils.hooks import copy_metadata -from PyInstaller.utils.hooks import collect_dynamic_libs - -# -# for main MiniAn python script -# - -block_cipher = None - -datas = [] -binaries = [] -hiddenimports = [] -excludes = [] - -tmp_ret = collect_all('minian') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -tmp_ret = collect_all('distributed') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -tmp_ret = collect_all('skimage') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -binaries += collect_dynamic_libs('llvmlite',destdir='.\\Library\\bin') - -excludes = ["IPython", "PyQt5", "Markdown", "jupyter", "panel", "matplotlib", "notebook", "bokeh"] - -a_minian = Analysis( - ['../MiniAn/minian_run.py'], - pathex=['../'], - binaries=binaries, - datas=datas, - hiddenimports=hiddenimports, - hookspath=[], - hooksconfig={}, - runtime_hooks=[], - excludes=excludes, - win_no_prefer_redirects=False, - win_private_assemblies=False, - cipher=block_cipher, - noarchive=False, -) -pyz_minian = PYZ(a_minian.pure, a_minian.zipped_data, cipher=block_cipher) - -exe_minian = EXE( - pyz_minian, - a_minian.scripts, - [], - name='minian', - debug=False, - bootloader_ignore_signals=False, - strip=False, - upx=True, - upx_exclude=[], - runtime_tmpdir=None, - console=True, - disable_windowed_traceback=False, - argv_emulation=False, - target_arch=None, - codesign_identity=None, - entitlements_file=None, -) - -coll = COLLECT( - exe_minian, - a_minian.binaries, - a_minian.zipfiles, - a_minian.datas, - strip=False, - upx=True, - upx_exclude=[], - name='minian', -) \ No newline at end of file diff --git a/Deploy/pack_suite2p.spec b/Deploy/pack_suite2p.spec new file mode 100644 index 00000000..88929f50 --- /dev/null +++ b/Deploy/pack_suite2p.spec @@ -0,0 +1,102 @@ +# -*- mode: python ; coding: utf-8 -*- + +import os +import sys +from pathlib import Path +from PyInstaller.building.build_main import Analysis, PYZ, EXE, COLLECT +from PyInstaller.utils.hooks import collect_all + +_specdir = os.path.abspath(os.path.dirname(SPEC)) +distpath = os.path.join(_specdir, "dist") +workpath = os.path.join(_specdir, "build") + +BLOCK_CIPHER = None + +PACKAGES = [ + 'suite2p', + 'ScanImageTiffReader', +] + +EXCLUDES = [ + "IPython", + "PyQt6", + "PyQt5", + "Markdown", + "jupyter" +] + +datas = [] +binaries = [] +hiddenimports = [] +for package in PACKAGES: + tmp_ret = collect_all(package) + datas += tmp_ret[0] + binaries += tmp_ret[1] + hiddenimports += tmp_ret[2] + +# Ship Intel TBB runtime that PyTorch depends on. +TBB_DLLS = [ + "tbb12.dll", + "tbbmalloc.dll", + "tbbmalloc_proxy.dll", + "tbbbind.dll", + "tbbbind_2_0.dll", + "tbbbind_2_5.dll", +] +library_bin = Path(sys.prefix) / "Library" / "bin" +if library_bin.is_dir(): + for dll_name in TBB_DLLS: + dll_path = library_bin / dll_name + if dll_path.is_file(): + binaries.append((str(dll_path), ".")) + +a_suite2p = Analysis( + ['../Suite2p/suite2p_run.py'], + pathex=['../'], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=EXCLUDES, + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=BLOCK_CIPHER, + noarchive=False, +) +pyz_suite2p = PYZ( + a_suite2p.pure, + a_suite2p.zipped_data, + cipher=BLOCK_CIPHER +) + +exe_suite2p = EXE( + pyz_suite2p, + a_suite2p.scripts, + [], + name='suite2p', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) + +coll = COLLECT( + exe_suite2p, + a_suite2p.binaries, + a_suite2p.zipfiles, + a_suite2p.datas, + strip=False, + upx=True, + upx_exclude=[], + name='suite2p', +) diff --git a/Deploy/pack_suite2p_run.spec b/Deploy/pack_suite2p_run.spec deleted file mode 100644 index 441643b3..00000000 --- a/Deploy/pack_suite2p_run.spec +++ /dev/null @@ -1,74 +0,0 @@ -# -*- mode: python ; coding: utf-8 -*- - -from PyInstaller.utils.hooks import collect_all -from PyInstaller.utils.hooks import copy_metadata -from PyInstaller.utils.hooks import collect_dynamic_libs - -# -# for main MiniAn python script -# - -block_cipher = None - -datas = [] -binaries = [] -hiddenimports = [] -excludes = [] - -# datas += copy_metadata('suite2p', recursive=True) -tmp_ret = collect_all('suite2p') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -tmp_ret = collect_all('ScanImageTiffReader') -datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] - -# binaries += collect_dynamic_libs('ScanImageTiffReaderAPI', destdir='.\\Library\\bin') - -excludes = ["IPython", "PyQt6", "PyQt5", "Markdown", "jupyter"] - -a_suite2p = Analysis( - ['../Suite2p/suite2p_run.py'], - pathex=['../'], - binaries=binaries, - datas=datas, - hiddenimports=hiddenimports, - hookspath=[], - hooksconfig={}, - runtime_hooks=[], - excludes=excludes, - win_no_prefer_redirects=False, - win_private_assemblies=False, - cipher=block_cipher, - noarchive=False, -) -pyz_suite2p = PYZ(a_suite2p.pure, a_suite2p.zipped_data, cipher=block_cipher) - -exe_suite2p = EXE( - pyz_suite2p, - a_suite2p.scripts, - [], - name='suite2p', - debug=False, - bootloader_ignore_signals=False, - strip=False, - upx=True, - upx_exclude=[], - runtime_tmpdir=None, - console=True, - disable_windowed_traceback=False, - argv_emulation=False, - target_arch=None, - codesign_identity=None, - entitlements_file=None, -) - -coll = COLLECT( - exe_suite2p, - a_suite2p.binaries, - a_suite2p.zipfiles, - a_suite2p.datas, - strip=False, - upx=True, - upx_exclude=[], - name='suite2p', -) \ No newline at end of file diff --git a/environment-minian.txt b/environment-minian.txt new file mode 100644 index 00000000..1b193bdf Binary files /dev/null and b/environment-minian.txt differ