Last active
July 24, 2026 18:31
-
-
Save bmorris3/f19d186ea9153f90b0cdf4b8f02305f4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "id": "30dd7963-6a89-4066-af1c-a61888e9e4c5", | |
| "metadata": {}, | |
| "source": [ | |
| "### Example data\n", | |
| "\n", | |
| "Here I generate a directory of example data called `example_data`. You will use real data here instead." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "126fdb1e-891a-46e4-8950-f77c9d78c2ee", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import os\n", | |
| "import numpy as np\n", | |
| "from astropy.io import fits\n", | |
| "\n", | |
| "example_dir = 'example_data/'\n", | |
| "os.makedirs(example_dir, exist_ok=True)\n", | |
| "\n", | |
| "n_images = 10\n", | |
| "\n", | |
| "for i in range(n_images):\n", | |
| " hdus = fits.HDUList([\n", | |
| " fits.PrimaryHDU(),\n", | |
| " fits.ImageHDU(np.random.normal(size=(50, 50)))\n", | |
| " ])\n", | |
| " hdus.writeto(example_dir + f'example_{i:02d}.fits', overwrite=True)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "5f90c7d5-b33a-4b09-9110-bdd7002014cf", | |
| "metadata": {}, | |
| "source": [ | |
| "### Open `jdaviz`" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "3ff223d4-a520-4bb8-a18a-272e82bde647", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import jdaviz as jd\n", | |
| "from sidecar import Sidecar\n", | |
| "from ipywidgets import widgets\n", | |
| "\n", | |
| "viz = jd.gca()\n", | |
| "\n", | |
| "style = widgets.HTML(\"\"\"\n", | |
| "<style>\n", | |
| ".splitpanes.splitpanes--vertical.splitpanes__pane { \n", | |
| " width : 100% !important;\n", | |
| "}\n", | |
| ".lm-Widget.lm-Panel.jp-OutputArea {\n", | |
| " width : 100% !important;\n", | |
| "}\n", | |
| "</style>\n", | |
| "\"\"\")\n", | |
| "\n", | |
| "jdaviz_sidecar = Sidecar(anchor='split-right', title='jdaviz')\n", | |
| "with jdaviz_sidecar:\n", | |
| " viz.show()\n", | |
| " \n", | |
| "display(style)\n", | |
| "# close the data loader drawer\n", | |
| "viz._app.state.drawer_content = ''" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "b59e0008-11ee-4806-8c0c-da2c5d2a1a2f", | |
| "metadata": {}, | |
| "source": [ | |
| "### Define controls" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 17, | |
| "id": "3064a267-2c9e-4a7d-a07e-2fda590ee6e0", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import json\n", | |
| "import os\n", | |
| "from glob import glob\n", | |
| "import solara\n", | |
| "from ipypopout import PopoutButton\n", | |
| "\n", | |
| "input_dir = 'example_data/' # replace this as you see fit\n", | |
| "marked_json = 'marked.json'\n", | |
| "paths = sorted(glob(input_dir + '*.fits'))\n", | |
| "include_file = {p: None for p in paths}\n", | |
| "overwrite_existing_json = False\n", | |
| "\n", | |
| "if os.path.exists(marked_json) and not overwrite_existing_json:\n", | |
| " include_file = json.load(open(marked_json, 'r'))\n", | |
| "else:\n", | |
| " # by default, mark as `None` for \"unmarked\"\n", | |
| " include_file = {p: None for p in paths}\n", | |
| "\n", | |
| "path = solara.Reactive(paths[0])\n", | |
| "\n", | |
| "def bool_to_string(truth):\n", | |
| " if truth is None:\n", | |
| " return truth\n", | |
| " return 'include' if truth else 'exclude'\n", | |
| "\n", | |
| "def string_to_bool(string):\n", | |
| " return string == 'include'\n", | |
| "\n", | |
| "def remove_images_from_jdaviz():\n", | |
| " if 'Image' in viz.viewers:\n", | |
| " data_menu = viz.viewers['Image'].data_menu\n", | |
| " if data_menu.layer.choices:\n", | |
| " data_menu.layer.select_all()\n", | |
| " data_menu.remove_from_app()\n", | |
| "\n", | |
| "def write_to_json():\n", | |
| " with open(marked_json, 'w') as manifest:\n", | |
| " json.dump(\n", | |
| " include_file,\n", | |
| " manifest, \n", | |
| " sort_keys=True,\n", | |
| " indent=2,\n", | |
| " )\n", | |
| "\n", | |
| "@solara.component\n", | |
| "def controls(): \n", | |
| " include_this_file = solara.Reactive(include_file[path.value])\n", | |
| "\n", | |
| " def on_button_press(value):\n", | |
| " include_file[path.value] = string_to_bool(value)\n", | |
| " include_this_file.set(value)\n", | |
| " current_path_idx = paths.index(path.value)\n", | |
| " write_to_json()\n", | |
| " path.set(paths[current_path_idx + 1])\n", | |
| "\n", | |
| " def on_path_change(value):\n", | |
| " remove_images_from_jdaviz()\n", | |
| " viz.load(value, format='Image')\n", | |
| " include_this_file.set(include_file[value])\n", | |
| "\n", | |
| " show_paths = solara.Reactive(paths)\n", | |
| " select_path = solara.Select(\n", | |
| " label='path',\n", | |
| " values=show_paths.value,\n", | |
| " value=path,\n", | |
| " on_value=on_path_change\n", | |
| " )\n", | |
| "\n", | |
| " buttons = solara.ToggleButtonsSingle(\n", | |
| " values=['include', 'exclude'],\n", | |
| " value=bool_to_string(include_this_file.value),\n", | |
| " on_value=on_button_press\n", | |
| " )\n", | |
| "\n", | |
| " with solara.Column(margin='4px'):\n", | |
| " with solara.Row():\n", | |
| " solara.display(buttons)\n", | |
| " solara.display(select_path)\n", | |
| "\n", | |
| "with Sidecar(title='controls', anchor='split-bottom', ref=jdaviz_sidecar):\n", | |
| " display(controls())" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "ec4295bf-3dff-4519-b7b5-60b2fba886b3", | |
| "metadata": {}, | |
| "source": [ | |
| "### Convert the marked paths to a manifest" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "0bcbc861-980e-473e-bf3f-afb012b4260a", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "cat marked.json" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "e2e1c30e-0693-46d7-b93b-93ea44f875df", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "def json_to_manifest(manifest_path='manifest.txt'):\n", | |
| " marks = json.load(open(marked_json, 'r'))\n", | |
| "\n", | |
| " included_files = [path for path, mark in marks.items() if mark]\n", | |
| "\n", | |
| " with open(manifest_path, 'w') as manifest:\n", | |
| " manifest.write(\n", | |
| " '\\n'.join(included_files)\n", | |
| " )\n", | |
| "\n", | |
| "json_to_manifest()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "88348b41-264e-420a-9de3-d08319a4fa50", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "cat manifest.txt" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "id": "a59ecd9a-8aff-4d8b-a60b-eca1d2702fea", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3 (ipykernel)", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.13.14" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment