Skip to content
Snippets Groups Projects
Commit cfef5d4f authored by François  LAURENT's avatar François LAURENT
Browse files

fix: macOS-specific fixes, --view-factor is reverted back to 1 by default

parent 72c214c9
No related branches found
No related tags found
1 merge request!22Set of commits to be tagger v0.19
Pipeline #143896 passed
......@@ -18,9 +18,9 @@ This package features a web-based graphical user interface (GUI) for visualizing
A command-line interface (CLI) is also available for batch processing, including the automatic tagging of track data files, training new taggers from labeled data, etc.
Although *LarvaTagger.jl* alone comes with no automatic tagger, it is designed to work in combination with [*MaggotUBA*](https://gitlab.pasteur.fr/nyx/MaggotUBA-adapter) for the identification of larval actions or postures.
Although *LarvaTagger.jl* alone comes with no automatic tagger, it is designed to work primarily in combination with [*MaggotUBA*](https://gitlab.pasteur.fr/nyx/MaggotUBA-adapter) for the identification of larval actions or postures.
> The term *LarvaTagger* refers to the full software with all the currently available tagging capabilities included.
> The term *LarvaTagger* refers to the full software with MaggotUBA-based tagging capabilities included.
*Docker* images are available for *LarvaTagger*. See the [dedicated instructions page](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/tree/main/recipes) or the [Quick start](#quick-start-with-docker) section below.
......@@ -37,6 +37,8 @@ The present section will guide you through the following steps:
These instructions only require [*Docker*](https://docs.docker.com/get-docker/) to be available, more specifically the *Docker Engine*. On Windows and macOS, *Docker Engine* is provided by the *Docker Desktop* product. *Docker Desktop* is free of charge.
> On macOS, make sure to enable Rosetta 2 for Apple Silicon architecture as specified in the [“System requirements” section](https://docs.docker.com/desktop/setup/install/mac-install/). Docker VMM may be a better option, especially for M2+ computers, but has not been tested so far.
Ensure the currently logged-in user has access to *Docker*, and the *Docker* engine is running.
The *Docker* image is obtained and operated using a script:
......@@ -56,16 +58,16 @@ chmod a+x larvatagger.sh
The demo data can be opened in the web browser for visual inspection, on macOS and Linux with:
```
./larvatagger.sh open Masson_et_al_2020.label --browser
./larvatagger.sh open Masson_et_al_2020.label
```
and on Windows with:
```
larvatagger.bat open Masson_et_al_2020.label --browser
larvatagger.bat open Masson_et_al_2020.label
```
The viewer should open in a new tab in the default web browser. If no tabs appear, open a new one and go to [http://127.0.0.1:9284](http://127.0.0.1:9284).
Once told to do so, go to [http://127.0.0.1:9284](http://127.0.0.1:9284) in a web browser.
Not all the web browsers are supported. Prefer Firefox or Chrome-like browsers.
Not all the web browsers are supported. Prefer Firefox or Chrome-like browsers. In particular, Safari is not supported.
Note that, on the first execution, the *Docker* image will be downloaded. This is done once, and can be considered as the installation step.
......@@ -73,7 +75,9 @@ Note that, on the first execution, the *Docker* image will be downloaded. This i
### Main controls
The tracked larvae can be animated pressing the "Play/Pause" button of the player below the 2D view.
> If the 2D viewer looks small, restart LarvaTagger with additional option `--view-factor 2`.
The tracked larvae can be animated pressing the play button of the player below the 2D view.
From the view displaying multiple larvae, a larva can be selected. As a result, the 2D view displays the selected larva only. From this single-larva view, the top right button allows going back to the multi-larva view.
......@@ -92,6 +96,8 @@ Alternatively, tags can be similarly *un*assigned at individual time steps or ov
[Using the *Docker* image](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/tree/main/recipes) may come handy, as it ships *LarvaTagger* with the default *MaggotUBA*-based tagger as a standalone package and is easier to update.
Alternatively, an install script is provided to install LarvaTagger with MaggotUBA-based tagging capabilities.
### Using the *scripts/install.sh* script
On macOS, Linux and WSL, a [script](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/blob/dev/scripts/install.sh?ref_type=heads) is provided to automate the installation process from source. This script installs LarvaTagger.jl and Julia if missing. It also adds the *larvatagger* command to the user's path variable.
......@@ -99,7 +105,7 @@ The *scripts/install.sh* script can be run with:
```
/bin/bash -c "$(curl -sSL "https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/raw/dev/scripts/install.sh?ref_type=heads&inline=false")"
```
To install the full LarvaTagger suite (Linux and WSL only!), run instead:
To install the full LarvaTagger suite on Linux or WSL, run instead:
```
curl -sSL "https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/raw/dev/scripts/install.sh?ref_type=heads&inline=false" | /bin/bash -s -- --with-default-backend
```
......@@ -110,11 +116,16 @@ If `pyenv` is available, the script will use this tool to install Python.
Otherwise, `python3.8` and `python3.8-venv` may have to be manually installed.
On WSL, the script will attempt to install `pyenv` and Python (tested with Ubuntu 20.04).
On macOS, the full LarvaTagger suite can be installed only with the `--with-backend --experimental` options:
```
curl -sSL "https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/raw/dev/scripts/install.sh?ref_type=heads&inline=false" | /bin/bash -s -- --with-backend --experimental
```
This script can also uninstall LarvaTagger (if installed with the same script) with: `curl -sSL "https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/raw/dev/scripts/install.sh?ref_type=heads&inline=false" | /bin/bash -s -- --uninstall` which can be useful for example prior to reinstalling after failure.
### Manually from source
To natively run *LarvaTagger.jl* instead, you will need [*julia>=1.7*](https://julialang.org/downloads/).
To manually install *LarvaTagger.jl* (without automatic tagging capabilities), you will need [*julia>=1.7*](https://julialang.org/downloads/).
If you are not familiar with installing *Julia*, you may appreciate installation helpers such as [*Juliaup*](https://github.com/JuliaLang/juliaup) or [*jill*](https://pypi.org/project/jill/).
......@@ -167,7 +178,7 @@ If the alternative installation procedure was followed instead, go to the *Larva
julia --project=. -e 'using Pkg; Pkg.update()'
```
## Launching the graphical user interface
## Launching the graphical/web user interface
The GUI is provided by a web server and can be accessed using a web browser, preferably Firefox or Chrome-like browsers.
......@@ -175,6 +186,12 @@ Running *LarvaTagger.jl* sets the server up. Once the server is ready, the app c
See the [Quick start](#main-controls) section for information about some of the controls available in the GUI.
The launching procedure depends on the followed installation procedure.
* With manual installations using Julia, the web UI can be served from the `julia` REPL (advanced).
* The *larvatagger* script can be used instead to launch the web UI from the command-line.
* Docker users should use the *larvatagger.sh* or *larvatagger.ps1* scripts instead; beware that their usage differs from that of the *larvatagger* script.
* Users of the *install.sh* script benefit from a slightly simplified *larvatagger* command, added to the PATH environment variable.
### Using the *larvatagger* script
If you cloned the repository, we recommend you run *LarvaTagger* using the *larvatagger* script to be found in the *scripts* directory:
......@@ -183,22 +200,22 @@ If you cloned the repository, we recommend you run *LarvaTagger* using the *larv
scripts/larvatagger open path/to/data/file --browser
```
If LarvaTagger was installed using the *scripts/install.sh* script, the *larvatagger* script should be in the user's path environment variable and, as a consequence, available from everywhere in the commandline:
If LarvaTagger was installed using the *scripts/install.sh* script, the *larvatagger* script should be in the user's path environment variable and, as a consequence, available from everywhere in the command-line:
```
larvatagger open path/to/data/file --browser
larvatagger open path/to/data/file
```
The script will actually open a *Julia* interpreter, and give some guidance on how to exit the interpreter.
> For now, `larvatagger open` cannot be run with no input arguments. A track data file is required.
> Since version 0.19, the data file argument is no longer required. Data files can be opened from the Web UI.
The `--browser` argument may open a new tab in your web browser, but this feature is known to be ineffective in some situations. In such an event, open a new tab and go to [http://localhost:9284](http://127.0.0.1:9284).
The `--browser` argument may open a new tab in your web browser, but this feature is known to be ineffective in some situations. In such an event, open a new tab and go to [http://localhost:9284](http://127.0.0.1:9284). The argument is passed by default by the *larvatagger* command, in contrast to the *scripts/larvatagger* script.
The first time the application is loaded, it may take a while for a window in your web browser to open, and the data to be plotted.
### From the *Julia* interpreter
As an alternative to the *larvatagger* script, in the *LarvaTagger* directory created above, launch the *Julia* interpreter:
As an alternative to the *larvatagger* script or command, in the *LarvaTagger* directory created above, launch the *Julia* interpreter:
```
julia --project=.
```
......@@ -211,16 +228,15 @@ To exit the interpreter, type `exit()` or press Ctrl+D.
### macOS
On macOS computers, the 2D larva view may show up twice as small as expected. To mitigate this undesired behavior,
`larvatagger open` admits a `--view-factor` option, and equivalently `larvaeditor` admits a `viewfactor` argument.
This option/argument is 2 per default on macOS, 1 on the other platforms.
On some computers (typically macOS computers), the 2D larva view may show up twice as small as expected.
To mitigate this undesired behavior, `larvatagger open` admits a `--view-factor` option, and equivalently `larvaeditor` admits a `viewfactor` argument.
Feel free to adjust the value if the 2D view is too small or large.
## Automatic tagging
*LarvaTagger.jl* comes with no automatic tagger per default, unless installed with the *scripts/install.sh* script and the `--with-default-backend` option.
*LarvaTagger.jl* comes with no automatic tagger per default, unless run using Docker or installed with the *scripts/install.sh* script and the `--with-default-backend` option.
To extend the editor with *MaggotUBA*-based automatic tagging, see the [recommended installation steps for *TaggingBackends* and *MaggotUBA*](https://gitlab.pasteur.fr/nyx/TaggingBackends#recommended-installation).
To extend the editor with automatic tagging capabilities, see the [recommended installation steps for *TaggingBackends* and *MaggotUBA*](https://gitlab.pasteur.fr/nyx/TaggingBackends#recommended-installation).
> Strictly speaking, the action identification package (or tagging backend) is called *MaggotUBA-adapter*.
> It is based on *MaggotUBA*, which is an autoencoder for action-agnostic behavior analysis.
......@@ -239,6 +255,7 @@ Similarly, to let *LarvaTagger* know about *MaggotUBA*:
```
scripts/larvatagger open <path/to/data/file> --backends=<path/to/MaggotUBA/parent/directory> --browser
```
The `--backends` argument is not necessary with the *larvatagger* **command** (`scripts/larvatagger` denotes the *larvatagger* **script** to be found in the *scripts* directory of the LarvaTagger.jl project).
The *larvatagger* script can also be used to train a new tagger:
```
......@@ -249,6 +266,11 @@ and apply this tagger to a tracking data file:
scripts/larvatagger predict <path/to/backend> <tagger-name> <path/to/data/file>
```
With the *larvatagger* command, the path-to-backend argument is still required (may change in the future), and the full command to run the default 20230311 tagger for example is:
```
larvatagger predict ~/.local/share/larvatagger/MaggotUBA 20230311 <path/to/data/file>
```
Among the many optional arguments to the `train` command, an important one is `--iterations`. It allows specifying the training budget. In several applications, higher training scores were achieved increasing the value for this argument. The default for *MaggotUBA-adapter* tagging backend is 1000, which may be too few iterations in many cases.
*MaggotUBA-adapter* admits either a single value or a comma-separated pair of values. Indeed, *MaggotUBA-adapter* training is performed in two phases: first the classifier stage is trained, with static weights in the pretrained *MaggotUBA* encoder; second both the classifier and encoder are fine-tuned. A higher training budget for the second fine-tuning stage may significantly increase the training accuracy.
......@@ -293,3 +315,9 @@ On calling `larvatagger predict` using a *MaggotUBA*-based tagger, if *CUDA* com
.../torch/cuda/__init__.py:... Can't initialize NVML
```
you might have upgraded your *NVIDIA* drivers and not rebooted the OS. Try restarting your computer.
### Display size
On some computers, the 2D viewer is abnormally small. This results from multiple sizing modalities (pixels for the 2D viewer, font sizes for the other parts of the web UI) and local defaults that cannot be probed. As a consequence, the user is invited to pass argument `--view-factor` followed by a value that scales the 2D viewer only (try values `1.5` and `2` for example).
See also issue [#16](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/issues/16).
......@@ -24,7 +24,8 @@ if [ "$1" = "--uninstall" ]; then
rm -rf "$BIN_DIR/larvatagger"
rm -rf "$LARVATAGGER_PATH"
# testing only; does not apply to all platforms; do not pass the --full option!
# testing only; deletes Poetry, PyEnv and JuliaUp, and does not check beforehands
# whether these dependencies were installed by the present script or not
if [ "$2" = "--full" ]; then
PYTHON="python3"
if [[ "`python3 -V`" =~ "Python 3.6" ]] && command -v python3.8 &>/dev/null; then
......@@ -35,7 +36,7 @@ if [ "$1" = "--uninstall" ]; then
command -v pyenv &>/dev/null && rm -rf $(pyenv root)
command -v juliaup &>/dev/null && juliaup self uninstall
rm -rf ~/.juliaup
# TODO: clean up .bash_profile for pyenv-related stuff and restart the shell
# TODO: clean up .bash_profile for pyenv-related stuff, .bashrc/.zshrc for PATH manipulations, and restart the shell
rm -rf ~/.julia
fi
else
......@@ -64,27 +65,27 @@ for arg in "$@"; do
PYTHON_VERSION=3.11
elif [ "$arg" = "--free-python-dependencies" ]; then
internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES=1
elif [ "$arg" = "--lock-python-dependencies" ]; then
internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES=0
fi
done
PYTHON="python$PYTHON_VERSION"
if ! command -v curl &>/dev/null; then
if command -v brew &>/dev/null; then
# macOS users are not given the choice as they usually do not care about freedom
brew install curl
fi
fi
if ! command -v curl &>/dev/null; then
echo "Command curl required; aborting"
else
check_brew() {
if [ "`uname`" = "Darwin" ]; then
# macOS
if ! command -v brew &>/dev/null; then
echo "Installing Homebrew; admin rights will be requested"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if ! [ -f /opt/homebrew/bin/brew ]; then
echo "Installing Homebrew; admin rights will be requested"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
# not sure why zsh does not support ~/ below, while it seems to behave properly elsewhere...
cat <<"EOF" >>$HOME/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
EOF
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
fi
}
......@@ -97,10 +98,27 @@ if ! command -v realpath &>/dev/null; then
fi
fi
if ! command -v curl &>/dev/null; then
if [ "`uname`" = "Darwin" ]; then
check_brew
# macOS users are not given the choice as they usually do not care about freedom
brew install curl
fi
fi
if ! command -v curl &>/dev/null; then
echo "Command curl required; aborting"
else
if [ -z "$JULIA_VERSION" ]; then
JULIA_VERSION=1.10
JULIA_CHANNEL=lts
else
echo "Using environment variable: JULIA_VERSION= $JULIA_VERSION"
if [ -z "$JULIA_CHANNEL" ]; then
JULIA_CHANNEL=$JULIA_VERSION
else
echo "Using environment variable: JULIA_CHANNEL= $JULIA_CHANNEL"
fi
fi
JULIA="julia"
......@@ -112,16 +130,18 @@ install_juliaup() {
echo "Using environment variable: JULIA_INSTALL_ARGS= $JULIA_INSTALL_ARGS"
fi
curl -fsSL https://install.julialang.org | sh -s -- $JULIA_INSTALL_ARGS --default-channel $JULIA_VERSION
if [ -f ~/.bashrc -a -n "`grep "# >>> juliaup initialize >>>" ~/.bashrc`" ]; then
source ~/.bashrc
elif [ -f ~/.bash_profile -a -n "`grep "# >>> juliaup initialize >>>" ~/.bash_profile`" ]; then
source ~/.bash_profile
fi
export PATH=~/.juliaup/bin:$PATH
}
if ! command -v $JULIA &>/dev/null; then
install_juliaup
elif ! [[ "`$JULIA -v`" =~ "julia version $JULIA_VERSION" ]]; then
install_juliaup
if ! command -v juliaup &>/dev/null; then
install_juliaup
fi
fi
if command -v juliaup &>/dev/null; then
juliaup add $JULIA_CHANNEL
juliaup default $JULIA_CHANNEL
fi
add_local_bin_to_path() {
......@@ -144,7 +164,7 @@ EOF
else
echo "the larvatagger command is available in directory:"
echo " $BIN_DIR"
echo "consider adding the directory to the PATH variable"
echo "consider adding the directory to the PATH variable in your rc or profile file"
fi
export PATH=$PATH:$BIN_DIR
}
......@@ -206,6 +226,11 @@ if [ -n "$WITH_BACKEND" ]; then
check_brew
if command -v brew &>/dev/null; then
brew install python@$PYTHON_VERSION
if ! command -v python$PYTHON_VERSION &>/dev/null; then
echo "Try instead $0 --with-backend --experimental"
echo "Aborting..."
exit 1
fi
else
echo "WARNING: command $PYTHON not found"
fi
......@@ -290,7 +315,7 @@ else
curl -fsSL https://gitlab.pasteur.fr/nyx/TaggingBackends/-/archive/${TAGGINGBACKENDS_BRANCH}/TaggingBackends-${TAGGINGBACKENDS_BRANCH}.tar.gz | tar zxv
mv TaggingBackends-${TAGGINGBACKENDS_BRANCH} TaggingBackends
fi
(cd TaggingBackends && activate && PYTHON=`command -v python` && $JULIA --project=. -e 'using Pkg; Pkg.instantiate()')
(cd TaggingBackends && activate && PYTHON="`poetry env info`/bin/python" $JULIA --project=. -e 'using Pkg; Pkg.instantiate()')
[ -d PlanarLarvae ] && (cd TaggingBackends && $JULIA --project=. -e 'using Pkg; Pkg.develop(path="../PlanarLarvae")')
(cd TaggingBackends && activate && JULIA_PROJECT=$(pwd) poetry install)
......@@ -322,6 +347,15 @@ fi
export JULIA_PROJECT=$(realpath TaggingBackends)
if [ -z "$internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES" ]; then
if [ "`uname`" = "Darwin" ]; then
# PyTorch requirements in the requirements.txt file are Cuda-based, suitable for Windows and Linux
# while alternative libraries are used on macOS
internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES=1
else
internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES=0
fi
fi
if [ "$internal_MAGGOTUBA_ADAPTER_FREE_DEPENDENCIES" = "0" ]; then
(cd MaggotUBA && activate && (cat requirements.txt | xargs -I % sh -c 'poetry add "%"' || true) && poetry install -v)
else
(cd MaggotUBA && activate && poetry install -v)
......
......@@ -169,7 +169,8 @@ end
function pull(tagger::Tagger, dest_dir::String)
proc_data_dir = datadir(tagger, "processed")
isdir(proc_data_dir) || throw("no processed data directory found")
dest_dir = realpath(dest_dir) # strip end slash
# dest_dir can be empty on macOS
dest_dir = isempty(dest_dir) ? pwd() : realpath(dest_dir) # strip end slash
dest_files = String[]
for (parent, _, files) in walkdir(proc_data_dir)
if !isempty(files)
......
......@@ -65,8 +65,8 @@ function main(args=ARGS; exit_on_error=false)
viewfactor = parsed_args["--view-factor"]
if !isnothing(viewfactor)
kwargs[:viewfactor] = parse(Float64, viewfactor)
elseif Sys.isapple()
kwargs[:viewfactor] = 2
# elseif Sys.isapple()
# kwargs[:viewfactor] = 2
end
if parsed_args["--viewer"]
......@@ -84,7 +84,7 @@ function main(args=ARGS; exit_on_error=false)
port = isnothing(port) ? 9284 : parse(Int, port)
server = Server(app, "0.0.0.0", port)
if parsed_args["--browser"]
Bonito.openurl("http://127.0.0.1:$(port)")
Bonito.HTTPServer.openurl("http://127.0.0.1:$(port)")
end
if verbose
@info "The server is ready at http://127.0.0.1:$(port)"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment