From d3686899cd44a20c9ac5bab9df8fe09f815e83f6 Mon Sep 17 00:00:00 2001 From: Jiacheng Huang Date: Wed, 30 Sep 2026 09:56:36 +0200 Subject: [PATCH 1/2] skill file + docker envs --- agent/deeptrack2-reference-to-code.zip | Bin 0 -> 13728 bytes agent/deeptrack2-reference-to-code/SKILL.md | 207 ++++++++++++++++++ .../examples/Brightfield.py | 56 +++++ .../examples/Darkfield.py | 63 ++++++ .../examples/Fluorescence.py | 36 +++ .../examples/Holography.py | 59 +++++ .../examples/ISCAT.py | 27 +++ .../examples/Lambda.py | 64 ++++++ .../examples/To_PyTorch_Dataset.py | 85 +++++++ .../local-LLM-envs/deeptrack_env/Dockerfile | 37 ++++ .../assets/local-LLM-envs/ollama/Dockerfile | 37 ++++ 11 files changed, 671 insertions(+) create mode 100644 agent/deeptrack2-reference-to-code.zip create mode 100644 agent/deeptrack2-reference-to-code/SKILL.md create mode 100644 agent/deeptrack2-reference-to-code/examples/Brightfield.py create mode 100644 agent/deeptrack2-reference-to-code/examples/Darkfield.py create mode 100644 agent/deeptrack2-reference-to-code/examples/Fluorescence.py create mode 100644 agent/deeptrack2-reference-to-code/examples/Holography.py create mode 100644 agent/deeptrack2-reference-to-code/examples/ISCAT.py create mode 100644 agent/deeptrack2-reference-to-code/examples/Lambda.py create mode 100644 agent/deeptrack2-reference-to-code/examples/To_PyTorch_Dataset.py create mode 100644 tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile create mode 100644 tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile diff --git a/agent/deeptrack2-reference-to-code.zip b/agent/deeptrack2-reference-to-code.zip new file mode 100644 index 0000000000000000000000000000000000000000..6daf58db37a03e67157d579aa4a62917936d74b3 GIT binary patch literal 13728 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, `^`, and `&` as much as possible +- DeepTrack2 2.0+ does not support TensorFlow +- Do not generate TensorFlow/Keras-based DeepTrack code unless the user explicitly asks for legacy DeepTrack 1.7 code + +## General workflow + +1. Identify the user’s goal: + - particle simulation + - cell simulation + - brightfield image generation + - fluorescence image generation + - holography-like image generation + - dataset generation + - augmentation / noise modeling + - training-data pipeline + +2. Search local examples for the closest pattern. + +3. Extract: + - imports + - initialization style + - scatterer/sample construction + - optics/microscope construction + - noise and augmentation steps + - `.resolve()` or documented execution pattern + +4. Generate code in the same style as examples. + +5. Validate: + - every `dt.` appears in local examples or docs + - no fake APIs + - no TensorFlow unless legacy requested + - code is complete and runnable + +## Reference-image workflow + +When the user provides a microscopy example image: + +1. Inspect the image visually. + +2. Infer likely modality: + - brightfield + - fluorescence + - holography + - phase contrast / DIC-like + - unknown + +3. Extract visual traits: + - background brightness + - object shape + - object density + - contrast polarity + - blur / PSF size + - noise type + - illumination gradient + - field of view + - artifacts + +4. Map traits to DeepTrack2 components: + - particles/cells -> scatterers + - optics -> Brightfield / Fluorescence / holography-related examples + - blur -> optics or postprocessing + - camera noise -> Poisson or Gaussian noise examples + - variability -> random parameter distributions + - normalization -> documented preprocessing or augmentation examples + +5. Generate a runnable DeepTrack2 script that creates visually similar synthetic images. + +6. Clearly mark inferred parameters as estimates. + +## Modality mapping + +### Brightfield-like + +Visual clues: + +- gray or bright background +- darker objects +- halos or soft shadows +- uneven illumination possible + +Prefer examples involving: + +- particles or cells +- brightfield optics +- background variation +- Gaussian noise +- blur + +### Fluorescence-like + +Visual clues: + +- dark background +- bright objects +- glowing cells / spots +- shot-noise appearance + +Prefer examples involving: + +- fluorescence optics +- bright scatterers +- Poisson noise +- Gaussian blur +- intensity variation +- normalization + +### Holography-like + +Visual clues: + +- diffraction rings +- interference fringes +- phase-like contrast +- central particle with halo + +Prefer examples involving: + +- holography examples +- particle scatterers +- coherent-style optical setup +- ring-like artifacts +- background correction + +## Output format + +Return: + +1. Inferred goal or modality +2. Key visual/code assumptions +3. Complete Python code +4. Notes on parameters to calibrate +5. Caveats if the API or modality is uncertain + +## Standard simulation code style + +Generated simualtion code should follow this structure: + +```python +from __future__ import annotations + +import deeptrack as dt +import matplotlib.pyplot as plt + + +def build_pipeline(): + ... + + +def main() -> None: + pipeline = build_pipeline() + image = pipeline.resolve() + + plt.imshow(image.squeeze(), cmap="gray") + plt.axis("off") + plt.show() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/agent/deeptrack2-reference-to-code/examples/Brightfield.py b/agent/deeptrack2-reference-to-code/examples/Brightfield.py new file mode 100644 index 000000000..1353b7901 --- /dev/null +++ b/agent/deeptrack2-reference-to-code/examples/Brightfield.py @@ -0,0 +1,56 @@ +import numpy as np +import deeptrack as dt +from matplotlib import pyplot as plt + +# ## Brightfield +# +# In `DeepTrack2`, the brightfield microscope model simulates illumination using a single wavelength of light. This is equivalent to a brightfield microscope operating with a monochromatic light source. +# +# In experimental setups however, a brightfield microscope typically uses a broad spectrum of wavelengths (white light). +# +# To achieve a more realistic simulation of white light, we will need to simulate multiple brightfield images (sampling different parts of the visible light spectrum) and then averaging the contributions of these images. +# +# We start by generating a spectrum of wavelengths and a particle scatterer object. + +IMAGE_SIZE = 150 + +# Generate a spectrum of wavelengths to sample from, 5 will be enough. +wavelengths = np.linspace(450e-9, 700e-9, 5) + +particle = dt.Sphere( + position=(IMAGE_SIZE//2, IMAGE_SIZE//4, 2) * dt.units.pixel, #put particles in the middle + radius= 0.3e-6, + position_unit="pixel", + refractive_index=1.42, +) + + +# Image the particle by sampling the spectrum. + +# Sample the wavelengths. +imaged_particle_list = [] +for wavelength in wavelengths: + # Create a brightfield microscope for a given wavelength. + single_wavelength_optics = dt.Brightfield( + resolution=1e-6, + magnification=10, + wavelength=wavelength, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE, IMAGE_SIZE//2), + ) + + # Image the particle. + imaged_particle = single_wavelength_optics(particle) + + # Add background noise. + imaged_particle = imaged_particle >> dt.Gaussian(0, 0.01) + + # Append to list. + imaged_particle_list.append(imaged_particle) + +# Take the average of the images in the list. +brightfield_image = ( + sum(imaged_particle_list) / len(imaged_particle_list) +).resolve() +plt.imshow(brightfield_image, cmap="gray") +plt.show() \ No newline at end of file diff --git a/agent/deeptrack2-reference-to-code/examples/Darkfield.py b/agent/deeptrack2-reference-to-code/examples/Darkfield.py new file mode 100644 index 000000000..bf68da813 --- /dev/null +++ b/agent/deeptrack2-reference-to-code/examples/Darkfield.py @@ -0,0 +1,63 @@ +import numpy as np +import deeptrack as dt +from matplotlib import pyplot as plt + +# ## Darkfield +# We will image a particle in a darkfield modality. This requires the scatterer to be defined as a Mie scatterer object. +# + +IMAGE_SIZE = 150 + +# Generate a spectrum of wavelengths to sample from, 5 will be enough. +wavelengths = np.linspace(450e-9, 700e-9, 5) + +mie_scatterer = dt.MieSphere( + position=(IMAGE_SIZE//4, IMAGE_SIZE//2, 2) * dt.units.pixel, #put particles in the middle + radius= 2e-6, + position_unit="pixel", + refractive_index=1.42, + L=10, +) + + +# Then, we define our darkfield microscope and image the particle through this. + + +optics = dt.Darkfield( + resolution=1e-6, + magnification=10, + wavelength=600e-9, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE//2, IMAGE_SIZE), +) + +image = optics(mie_scatterer) + +# Sample the wavelengths. +imaged_particle_list = [] +for wavelength in wavelengths: + + # Create a darkfield microscope for a given wavelength. + single_wavelength_optics = dt.Darkfield( + resolution=1e-6, + magnification=10, + wavelength=wavelength, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE, IMAGE_SIZE), + ) + + # Image the particle. + imaged_particle = single_wavelength_optics(mie_scatterer) + + # Add background noise. + imaged_particle = imaged_particle >> dt.Gaussian(0, 0.00015) + + # Append to list. + imaged_particle_list.append(imaged_particle) + +# Take the average of the images in the list. +darkfield_image = ( + sum(imaged_particle_list) / len(imaged_particle_list) +).resolve() +plt.imshow(darkfield_image, cmap="gray") +plt.show() \ No newline at end of file diff --git a/agent/deeptrack2-reference-to-code/examples/Fluorescence.py b/agent/deeptrack2-reference-to-code/examples/Fluorescence.py new file mode 100644 index 000000000..3d771b1d7 --- /dev/null +++ b/agent/deeptrack2-reference-to-code/examples/Fluorescence.py @@ -0,0 +1,36 @@ +import numpy as np +import deeptrack as dt +from matplotlib import pyplot as plt + +# ## Fluorescence +# Fluorescence images in `DeepTrack2` are simulated with discrete volumes to act as light sources (fluorophores) which emit light from a scatterer. +# +# Simulating fluorescence images are easy and straightforward to implement, we start by defining our microscope. +# Create a fluorescence microscope for a given wavelength. + +IMAGE_SIZE = 150 + +particle = dt.Sphere( + position=(IMAGE_SIZE//8, IMAGE_SIZE//4, 2) * dt.units.pixel, #put particles in the middle + radius= 0.3e-6, + position_unit="pixel", + refractive_index=1.42, +) + +fluorescence_optics = dt.Fluorescence( + NA=1.4, + resolution=1e-6, + magnification=10, + wavelength=600e-9, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE//4, IMAGE_SIZE//2), +) + +# Image the particle. +imaged_particle = fluorescence_optics(particle) + +# Add background noise. +fluorescence_image = (imaged_particle >> dt.Gaussian(0, 0.001)).resolve() + +plt.imshow(fluorescence_image, cmap="gray") +plt.show() \ No newline at end of file diff --git a/agent/deeptrack2-reference-to-code/examples/Holography.py b/agent/deeptrack2-reference-to-code/examples/Holography.py new file mode 100644 index 000000000..5d4463758 --- /dev/null +++ b/agent/deeptrack2-reference-to-code/examples/Holography.py @@ -0,0 +1,59 @@ +import numpy as np +import deeptrack as dt +from matplotlib import pyplot as plt + + +IMAGE_SIZE = 150 + +# ## Holographic microscope +# The Holographic microscope returns an image with real and imaginary values, so we will need to define a helper function that converts these into floats so we can visualize the values with a plot. + + +def complex_to_float_f(): + """Converts a complex image to a float image, needed for Holography.""" + def inner(image): + image = image - 1 + output = np.zeros((*image.shape[:2], 2)) + output[..., 0:1] = np.real(image) + output[..., 1:2] = np.imag(image) + return output + return inner +complex_to_float = dt.Lambda(complex_to_float_f) + +# Define the holography microscope and resolve a particle. + +mie_scatterer = dt.MieSphere( + position=(IMAGE_SIZE//4, IMAGE_SIZE//2, 2) * dt.units.pixel, #put particles in the middle + radius= 2e-6, + position_unit="pixel", + refractive_index=1.42, + L=10, +) + +holography_microscope = dt.Holography( + resolution=1e-6, + magnification=10, + wavelength=600e-9, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE//2, IMAGE_SIZE), + return_field=True, +) +# Get complex-valued image. +holography_image = holography_microscope(mie_scatterer).resolve() +print(f"Image shape = {holography_image.shape}") + +# Print a value in the image. +print(f"Pixel value of (0, 0) = {holography_image[0, 0, 0]}") + +# Convert to floats. +converted_image = complex_to_float(holography_image) +holography_real = converted_image[:, :, 0] +holography_imag = converted_image[:, :, 1] +holography_combined = holography_real + holography_imag + +fig, ax = plt.subplots(1, 3) +ax[0].imshow(holography_real, cmap="gray") +ax[1].imshow(holography_imag, cmap="gray") +ax[2].imshow(holography_combined, cmap="gray") + +plt.show() \ No newline at end of file diff --git a/agent/deeptrack2-reference-to-code/examples/ISCAT.py b/agent/deeptrack2-reference-to-code/examples/ISCAT.py new file mode 100644 index 000000000..91f7a44b6 --- /dev/null +++ b/agent/deeptrack2-reference-to-code/examples/ISCAT.py @@ -0,0 +1,27 @@ +import numpy as np +import deeptrack as dt +from matplotlib import pyplot as plt + + +IMAGE_SIZE = 150 + +mie_scatterer = dt.MieSphere( + position=(IMAGE_SIZE//2, IMAGE_SIZE//4, 2) * dt.units.pixel, #put particles in the middle + radius= 2e-6, + position_unit="pixel", + refractive_index=1.42, + L=10, +) + +iscat_microscope = dt.ISCAT( + resolution=1e-6, + magnification=10, + wavelength=600e-9, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE, IMAGE_SIZE//2), +) + +iscat_image = iscat_microscope(mie_scatterer).resolve() + +plt.imshow(iscat_image, cmap="gray") +plt.show() \ No newline at end of file diff --git a/agent/deeptrack2-reference-to-code/examples/Lambda.py b/agent/deeptrack2-reference-to-code/examples/Lambda.py new file mode 100644 index 000000000..c716e525b --- /dev/null +++ b/agent/deeptrack2-reference-to-code/examples/Lambda.py @@ -0,0 +1,64 @@ +import deeptrack as dt +import numpy as np +from matplotlib import pyplot as plt + + +# Define the new operator fo channel average +def channel_average(axis=0): + def sny_function(image): + return np.mean(image, axis=axis) + return sny_function + +# Wraper it using dt.Lambad, make it possilbe to ba chained using `>>`, `^`, and `&` +syn_feature = dt.Lambda(function=channel_average) + +# Treat all input in one operation +syn_feature.__distributed__ = False + + +IMAGE_SIZE = 150 + +# Define 2 images channel under two wavelength +particle = dt.Sphere( + position= lambda: ( + np.array([ + 0.1*IMAGE_SIZE + 0.7*IMAGE_SIZE*np.random.random(), + 0.1*IMAGE_SIZE + 0.7*IMAGE_SIZE*np.random.random(), + ]) * dt.units.pixel + ), #put particles randomly + radius= 0.3e-6, + position_unit="pixel", + refractive_index=1.42, +) + + +fluorescence_optics_1 = dt.Fluorescence( + NA=1.4, + resolution=1e-6, + magnification=10, + wavelength=600e-9, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE, IMAGE_SIZE), +) + + +fluorescence_optics_2 = dt.Fluorescence( + NA=1.4, + resolution=1e-6, + magnification=10, + wavelength=700e-9, + padding=(32, 32, 32, 32), + output_region=(0, 0, IMAGE_SIZE, IMAGE_SIZE), +) + +# Image the particle. +imaged_particle_1 = fluorescence_optics_1(particle) >> dt.NormalizeMinMax() +imaged_particle_2 = fluorescence_optics_2(particle) >> dt.NormalizeMinMax() + + +# Add background noise. +fluorescence_image = ((imaged_particle_1 & imaged_particle_2) + >> syn_feature >> dt.Gaussian(0, 0.001) >> dt.NormalizeMinMax()).update().resolve() + +plt.imshow(fluorescence_image) +plt.show() \ No newline at end of file diff --git a/agent/deeptrack2-reference-to-code/examples/To_PyTorch_Dataset.py b/agent/deeptrack2-reference-to-code/examples/To_PyTorch_Dataset.py new file mode 100644 index 000000000..c1aea1fc7 --- /dev/null +++ b/agent/deeptrack2-reference-to-code/examples/To_PyTorch_Dataset.py @@ -0,0 +1,85 @@ +import numpy as np +import deeptrack as dt +from matplotlib import pyplot as plt + +IMAGE_SIZE = 256 + +# Define the optical setup + +brightfield_microscope = dt.Brightfield( + NA=0.9, + resolution=1e-6, + magnification=10, + wavelength=680e-9, + output_region=(0, 0, IMAGE_SIZE, IMAGE_SIZE), + upscale=1, + padding=(32, 32, 32, 32), +) + +# Define the particle with random position + +particle = dt.MieSphere( + position=lambda: ( + np.array([ + 0.1*IMAGE_SIZE + 0.7*IMAGE_SIZE*np.random.random(), + 0.1*IMAGE_SIZE + 0.7*IMAGE_SIZE*np.random.random(), + ]) + ), + radius= lambda: (0.25 + 0.25*np.random.random())*1e-6, + intensity=10, +) + +imaged_particle_with_random_position = brightfield_microscope( + particle +) + +# Normalized Operation + +normalized_image_of_particle = ( + imaged_particle_with_random_position >> dt.NormalizeMinMax(0, 1) +) + +output_image = imaged_particle_with_random_position() + +# Visualization +plt.imshow(np.squeeze(output_image), cmap="gray") +plt.show() + +# Way1: Get Vector-based Ground-Truth +position_of_particle = particle.position() + +plt.imshow(np.squeeze(output_image), cmap="gray") +plt.scatter(position_of_particle[1], position_of_particle[0]) +plt.show() + +# Way2: Get Image-based Ground-Truth +CIRCLE_RADIUS = 3 + +def get_target_image(image, image_pipeline=normalized_image_of_particle): + """Create a binary image with the circles in the particle positions.""" + + target_image = np.zeros(image.shape) + x, y = np.meshgrid( + np.arange(0, image.shape[0]), + np.arange(0, image.shape[1]), + ) + + positions = dt.TakeProperties(image_pipeline, "position").resolve() + positions = np.reshape( + positions, (-1, 2) + ) # ensure (N, 2) shape, even for a single particle + + for position in positions: + distance_map = (x - position[1]) ** 2 + (y - position[0]) ** 2 + target_image[distance_map < CIRCLE_RADIUS**2] = 1 + + return target_image + +target_image = normalized_image_of_particle >> get_target_image + +# Visualization +plt.imshow(target_image(), cmap="gray") +plt.show() + +# Move Axis for Torch (Channel-first) +torch_data_pipeline = (normalized_image_of_particle & (normalized_image_of_particle >> get_target_image)) >> dt.MoveAxis(2, 0) \ No newline at end of file diff --git a/tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile b/tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile new file mode 100644 index 000000000..341a2f7ce --- /dev/null +++ b/tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile @@ -0,0 +1,37 @@ +FROM ollama/ollama + +ENV DEBIAN_FRONTEND=noninteractive + +USER root + +RUN apt-get update \ + && apt-get install -y \ + build-essential \ + gcc g++ gfortran \ + cmake \ + make \ + git \ + wget \ + curl \ + python3 \ + python3-pip \ + python3-dev \ + python3-venv \ + python-is-python3 \ + vim \ + flex \ + hwloc \ + gawk \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /opt + +RUN python3 -m venv .deeptrack && \ + . .venv/bin/activate && \ + pip3 install --no-cache-dir deeptrack deeplay && \ + pip3 install --no-cache-dir torch torchvision \ + --index-url https://download.pytorch.org/whl/cu126 && \ + echo 'source /opt/.deeptrack/bin/activate' >> /root/.bashrc + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile b/tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile new file mode 100644 index 000000000..341a2f7ce --- /dev/null +++ b/tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile @@ -0,0 +1,37 @@ +FROM ollama/ollama + +ENV DEBIAN_FRONTEND=noninteractive + +USER root + +RUN apt-get update \ + && apt-get install -y \ + build-essential \ + gcc g++ gfortran \ + cmake \ + make \ + git \ + wget \ + curl \ + python3 \ + python3-pip \ + python3-dev \ + python3-venv \ + python-is-python3 \ + vim \ + flex \ + hwloc \ + gawk \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /opt + +RUN python3 -m venv .deeptrack && \ + . .venv/bin/activate && \ + pip3 install --no-cache-dir deeptrack deeplay && \ + pip3 install --no-cache-dir torch torchvision \ + --index-url https://download.pytorch.org/whl/cu126 && \ + echo 'source /opt/.deeptrack/bin/activate' >> /root/.bashrc + +CMD ["/bin/bash"] \ No newline at end of file From 63567a1f1fbb8f4c36a921c147a634c07cc2d525 Mon Sep 17 00:00:00 2001 From: Jiacheng Huang Date: Mon, 5 Oct 2026 12:35:01 +0200 Subject: [PATCH 2/2] update envs --- .../local-LLM-envs/deeptrack_env/Dockerfile | 84 +++++++++++-------- .../assets/local-LLM-envs/ollama/Dockerfile | 6 +- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile b/tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile index 341a2f7ce..89d22902d 100644 --- a/tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile +++ b/tutorials/2-examples/assets/local-LLM-envs/deeptrack_env/Dockerfile @@ -1,37 +1,55 @@ -FROM ollama/ollama - +FROM continuumio/anaconda3 + ENV DEBIAN_FRONTEND=noninteractive -USER root - -RUN apt-get update \ - && apt-get install -y \ - build-essential \ - gcc g++ gfortran \ - cmake \ - make \ - git \ - wget \ - curl \ - python3 \ - python3-pip \ - python3-dev \ - python3-venv \ - python-is-python3 \ - vim \ - flex \ - hwloc \ - gawk \ - zlib1g-dev \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /opt - -RUN python3 -m venv .deeptrack && \ - . .venv/bin/activate && \ - pip3 install --no-cache-dir deeptrack deeplay && \ - pip3 install --no-cache-dir torch torchvision \ + +RUN apt-get update && \ + apt-get install -y openssh-server sudo && \ + rm -rf /var/lib/apt/lists/* + + +RUN pip3 install --no-cache-dir torch torchvision \ --index-url https://download.pytorch.org/whl/cu126 && \ - echo 'source /opt/.deeptrack/bin/activate' >> /root/.bashrc + pip3 install --no-cache-dir deeptrack opencv-python && \ + conda install -y --quiet jupyterlab && \ + conda clean -afy + + +RUN useradd -m -s /bin/bash dev + + +RUN mkdir -p /home/dev/.ssh /run/sshd && \ + chmod 700 /home/dev/.ssh && \ + chown -R dev:dev /home/dev/.ssh + + +RUN sed -i \ + -e 's/^#PasswordAuthentication yes/PasswordAuthentication no/' \ + -e 's/^PasswordAuthentication yes/PasswordAuthentication no/' \ + -e 's/^#PubkeyAuthentication yes/PubkeyAuthentication yes/' \ + /etc/ssh/sshd_config + +RUN mkdir -p /root/.ssh && \ + echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfNHQ94iIubf0eG9S+E6NayfPuzXcQPWriuBMTPhWnW xhujia@GU.GU.SE@softmatterlab01-p.gu.gu.se" \ + > /root/.ssh/authorized_keys && \ + chmod 700 /root/.ssh && \ + chmod 600 /root/.ssh/authorized_keys && \ + chown -R root:root /root/.ssh + +RUN echo 'source /opt/conda/etc/profile.d/conda.sh' >> /home/dev/.bashrc + +WORKDIR /a + +EXPOSE 22 8888 -CMD ["/bin/bash"] \ No newline at end of file +CMD ["/bin/bash", "-c", "\ + /usr/sbin/sshd && \ + jupyter lab \ + --notebook-dir=/ \ + --ip=0.0.0.0 \ + --port=8888 \ + --no-browser \ + --allow-root \ + --ServerApp.token='' \ + --ServerApp.password='' \ +"] \ No newline at end of file diff --git a/tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile b/tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile index 341a2f7ce..d87813337 100644 --- a/tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile +++ b/tutorials/2-examples/assets/local-LLM-envs/ollama/Dockerfile @@ -1,5 +1,5 @@ FROM ollama/ollama - + ENV DEBIAN_FRONTEND=noninteractive USER root @@ -28,10 +28,10 @@ RUN apt-get update \ WORKDIR /opt RUN python3 -m venv .deeptrack && \ - . .venv/bin/activate && \ - pip3 install --no-cache-dir deeptrack deeplay && \ + . .deeptrack/bin/activate && \ pip3 install --no-cache-dir torch torchvision \ --index-url https://download.pytorch.org/whl/cu126 && \ + pip3 install --no-cache-dir deeptrack opencv-python && \ echo 'source /opt/.deeptrack/bin/activate' >> /root/.bashrc CMD ["/bin/bash"] \ No newline at end of file