{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "`firefly/ntbks/settings_tutorial.ipynb`" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "from IPython.display import YouTubeVideo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A recording of this jupyter notebook in action is available at:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/jpeg": "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\n", "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "YouTubeVideo(\"Xt1vce_2DYo\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/jpeg": "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\n", "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "YouTubeVideo(\"ft0Y3XNJhl4\")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "don't have phil's colormaps\n" ] } ], "source": [ "import sys\n", "import os\n", "import numpy as np\n", "from firefly.data_reader import ParticleGroup,Settings,ArrayReader" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial notebook: Managing Custom Settings\n", "One of the core features of Firefly is the ability to customize the user interface (UI) and the startup behavior to make bespoke iterations of Firefly using ones own data. We have organized the different options that one can customize into different settings groups that fall into two categories: those that affect the app as a whole and those that are particular to an individual group of particles.\n", "\n", "**App Settings** | |**Particle Group Settings**\n", ":-----:|:--:|:------:\n", "Startup| |Startup\n", "UI| |UI\n", "Window| |Filter\n", "Camera| |Colormap\n", "\n", "\n", "\n", "Specific information for each key can be found in this documentation. \n", "\n", "To create the necessary JSON files one should use the `firefly.data_reader.Settings` class to create a `Settings` object. Once you have a `Settings` object you can manipulate the settings as you see fit and then either \n", "1. manually save it to a file using the `outputToJSON()` method or\n", "2. connect it to a `firefly.data_reader.Reader` object in order to link it to a specific visualization (see the reader documentation for details on how to use a `Reader` object)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-- Settings: startup settings --\n", "['maxVrange', 'startFly', 'friction', 'stereo', 'stereoSep', 'decimate', 'start_tween', 'CDmin', 'CDmax', 'CDlognorm', 'columnDensity']\n", "\n", "-- Settings: UI settings --\n", "['UI', 'UIfullscreen', 'UIsnapshot', 'UIreset', 'UIsavePreset', 'UIloadNewData', 'UIcameraControls', 'UIdecimation']\n", "\n", "-- Settings: window settings --\n", "['title', 'loaded', 'annotation', 'showFPS', 'showMemoryUsage', 'memoryLimit']\n", "\n", "-- Settings: camera settings --\n", "['center', 'camera', 'cameraRotation', 'cameraUp', 'quaternion']\n", "\n", "-- Settings: particle startup settings --\n", "['plotNmax', 'color', 'sizeMult', 'showParts', 'radiusVariable']\n", "\n", "-- Settings: particle UI settings --\n", "['UIparticle', 'UIdropdown', 'UIcolorPicker']\n", "\n", "-- Settings: particle velocity settings --\n", "['showVel', 'velType', 'velVectorWidth', 'velGradient', 'animateVel', 'animateVelDt', 'animateVelTmax']\n", "\n", "-- Settings: particle filter settings --\n", "['filterLims', 'filterVals', 'invertFilter']\n", "\n", "-- Settings: particle colormap settings --\n", "['colormapLims', 'colormapVals', 'colormap', 'colormapVariable', 'showColormap']\n", "\n" ] } ], "source": [ "## let's create an settings object with the default keys\n", "settings = Settings()\n", "\n", "## we'll print the current settings to the console, organized into groups \n", "## (but we'll use the values=False keyword argument because we only want to see the keys for now)\n", "settings.printKeys(values=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Settings can be changed the same way you would change a key in a dictionary\n", "There is key validation (so you can't attempt to set a setting that doesn't exist) but there is no value validation, so be careful that you use appropriate values or your app might not work. See the settings documentation for details on what values each setting can take." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "before:\n", "-- Settings: window settings --\n", "title Firefly\n", "loaded True\n", "annotation None\n", "showFPS True\n", "showMemoryUsage True\n", "memoryLimit 2000000000.0\n", "\n", "after:\n", "-- Settings: window settings --\n", "title ---> My Favorite Data <--- \n", "loaded True\n", "annotation None\n", "showFPS True\n", "showMemoryUsage True\n", "memoryLimit 2000000000.0\n", "\n" ] } ], "source": [ "## let's change the title that shows up in the browser's tab list\n", "print(\"before:\")\n", "## print only the settings that have to do with the window\n", "settings.printKeys(pattern='window')\n", "## update the title using dictionary syntax\n", "settings['title']='---> My Favorite Data <--- '\n", "print(\"after:\")\n", "## print only the settings that have to do with the window to confirm it changed\n", "settings.printKeys(pattern='window')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Settings are most useful when connected to a `firefly.data_reader.Reader` object\n", "Doing so allows many of the necessary settings to be automatically generated as additional particle groups are added." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "## let's create some sample data, a grid of points in a 3d cube\n", "my_coords = np.linspace(-10,10,20)\n", "xs,ys,zs = np.meshgrid(my_coords,my_coords,my_coords)\n", "xs,ys,zs = xs.flatten(),ys.flatten(),zs.flatten()\n", "coords = np.array([xs,ys,zs]).T\n", "\n", "## we'll pick some random field values to demonstrate filtering/colormapping\n", "fields = np.random.random(size=xs.size)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before we've attached the `Settings` object the particle settings are all empty." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-- Settings: particle startup settings --\n", "plotNmax {}\n", "color {}\n", "sizeMult {}\n", "showParts {}\n", "radiusVariable {}\n", "\n", "-- Settings: particle UI settings --\n", "UIparticle {}\n", "UIdropdown {}\n", "UIcolorPicker {}\n", "\n", "-- Settings: particle velocity settings --\n", "showVel {}\n", "velType {}\n", "velVectorWidth {}\n", "velGradient {}\n", "animateVel {}\n", "animateVelDt {}\n", "animateVelTmax {}\n", "\n", "-- Settings: particle filter settings --\n", "filterLims {}\n", "filterVals {}\n", "invertFilter {}\n", "\n", "-- Settings: particle colormap settings --\n", "colormapLims {}\n", "colormapVals {}\n", "colormap {}\n", "colormapVariable {}\n", "showColormap {}\n", "\n" ] } ], "source": [ "settings.printKeys(pattern='particle')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll use a `firefly.data_reader.ArrayReader`, a workhorse `firefly.data_reader.Reader` sub-class with many convenient functions. See the reader documentation for details that are outside the scope of this tutorial." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "JSONdir is None, defaulting to /Users/agurvich/research/repos/Firefly/src/firefly/static/data/Data\n", "Make sure each field_array (2) has a field_filter_flag (0), assuming True.\n", "Make sure each field_array (2) has a field_colormap_flag (0), assuming True.\n", "Make sure each field_array (2) has a field_radius_flag (0), assuming False.\n", "Outputting: PGroup_0 - 7999/7999 particles - 0 tracked fields\n", "Outputting: PGroup_1 - 8000/8000 particles - 2 tracked fields\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/opt/homebrew/Caskroom/miniconda/base/envs/python38/lib/python3.9/site-packages/numpy/core/fromnumeric.py:1970: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.\n", " result = asarray(a).shape\n", "/opt/homebrew/Caskroom/miniconda/base/envs/python38/lib/python3.9/site-packages/numpy/core/fromnumeric.py:43: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.\n", " result = getattr(asarray(obj), method)(*args, **kwds)\n" ] } ], "source": [ "## initialize an ArrayReader\n", "reader = ArrayReader(\n", " coordinates=[coords[:-1],coords], ## pass in two particle groups as a demonstration (just copies of our sample data)\n", " write_to_disk=False,\n", " settings=settings, ## the settings object to link\n", " fields=[[],[fields,fields]]) ## field data for each particle group, 0 fields for 1 and 2 repeated fields for the other." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The original `Settings` object is stored in `reader.settings`." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(reader.settings is settings) = True\n", "\n", "-- Settings: particle startup settings --\n", "plotNmax {'PGroup_0': None, 'PGroup_1': None}\n", "color {'PGroup_0': array([0.88100143, 0.73655243, 0.77324641, 1. ]), 'PGroup_1': array([0.36571498, 0.50979664, 0.02474504, 1. ])}\n", "sizeMult {'PGroup_0': 0.1, 'PGroup_1': 0.1}\n", "showParts {'PGroup_0': True, 'PGroup_1': True}\n", "radiusVariable {'PGroup_0': 0, 'PGroup_1': 0}\n", "\n", "-- Settings: particle UI settings --\n", "UIparticle {'PGroup_0': True, 'PGroup_1': True}\n", "UIdropdown {'PGroup_0': True, 'PGroup_1': True}\n", "UIcolorPicker {'PGroup_0': True, 'PGroup_1': True}\n", "\n", "-- Settings: particle velocity settings --\n", "showVel {'PGroup_0': None, 'PGroup_1': None}\n", "velType {'PGroup_0': None, 'PGroup_1': None}\n", "velVectorWidth {'PGroup_0': None, 'PGroup_1': None}\n", "velGradient {'PGroup_0': None, 'PGroup_1': None}\n", "animateVel {'PGroup_0': None, 'PGroup_1': None}\n", "animateVelDt {'PGroup_0': None, 'PGroup_1': None}\n", "animateVelTmax {'PGroup_0': None, 'PGroup_1': None}\n", "\n", "-- Settings: particle filter settings --\n", "filterLims {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "filterVals {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "invertFilter {'PGroup_0': {}, 'PGroup_1': {}}\n", "\n", "-- Settings: particle colormap settings --\n", "colormapLims {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "colormapVals {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "colormap {'PGroup_0': 0.015625, 'PGroup_1': 0.015625}\n", "colormapVariable {'PGroup_0': None, 'PGroup_1': None}\n", "showColormap {'PGroup_0': None, 'PGroup_1': None}\n", "\n" ] } ], "source": [ "## demonstrate that reader.settings is the original settings object\n", "print('(reader.settings is settings) =',reader.settings is settings)\n", "print()\n", "\n", "reader.settings.printKeys(pattern='particle')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that the dictionaries are filled with keys corresponding to each of the particle groups we passed in and sensible default values for each. The values of nested dictionaries should be changed by accessing each in turn, e.g.\n", "```python\n", "settings['colormapLims']['PGroup_1']['field0'] = [0,1]\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "for the purposes of this tutorial, we'll just go ahead and output the `Settings` object we have manually" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "You will need to add this settings filename to filenames.json if this was not called by a Reader instance.\n" ] }, { "data": { "text/plain": [ "('./exampleSettings.json', './exampleSettings.json')" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## output the example settings file to a .json in this directory\n", "settings.outputToJSON('.','example')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Settings can also be imported from `.json` files\n", "Only settings defined in the file will be overwritten, so you can also mix-and-match settings files." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "replacing title\n", "Firefly --> ---> My Favorite Data <--- \n", "replacing plotNmax\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing color\n", "{} --> {'PGroup_0': [0.8810014255, 0.7365524281, 0.7732464137, 1.0], 'PGroup_1': [0.3657149758, 0.5097966367, 0.0247450409, 1.0]}\n", "replacing sizeMult\n", "{} --> {'PGroup_0': 0.1, 'PGroup_1': 0.1}\n", "replacing showParts\n", "{} --> {'PGroup_0': True, 'PGroup_1': True}\n", "replacing radiusVariable\n", "{} --> {'PGroup_0': 0, 'PGroup_1': 0}\n", "replacing UIparticle\n", "{} --> {'PGroup_0': True, 'PGroup_1': True}\n", "replacing UIdropdown\n", "{} --> {'PGroup_0': True, 'PGroup_1': True}\n", "replacing UIcolorPicker\n", "{} --> {'PGroup_0': True, 'PGroup_1': True}\n", "replacing showVel\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing velType\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing velVectorWidth\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing velGradient\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing animateVel\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing animateVelDt\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing animateVelTmax\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing filterLims\n", "{} --> {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "replacing filterVals\n", "{} --> {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "replacing invertFilter\n", "{} --> {'PGroup_0': {}, 'PGroup_1': {}}\n", "replacing colormapLims\n", "{} --> {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "replacing colormapVals\n", "{} --> {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}}\n", "replacing colormap\n", "{} --> {'PGroup_0': 0.015625, 'PGroup_1': 0.015625}\n", "replacing colormapVariable\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n", "replacing showColormap\n", "{} --> {'PGroup_0': None, 'PGroup_1': None}\n" ] } ], "source": [ "## initialize a new settings object\n", "new_settings = Settings()\n", "\n", "## import the settings from what we just saved above; prints the settings that are updated\n", "new_settings.loadFromJSON(\"./exampleSettings.json\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Attaching a ParticleGroup to a Settings\n", "One other thing you may want to do (perhaps in the course of building your own custom `Reader` sub-class) is link a `firefly.data_reader.ParticleGroup` object to a `Settings` object so that the different particle settings can be imported. \n", "`ParticleGroup` settings can be changed in `settings_default` attribute (which is just a normal python dictionary). " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "## create a test particle group\n", "particleGroup = ParticleGroup('test',coords)\n", "## update the color of this particle group *before* attaching it to a settings object\n", "particleGroup.settings_default['color'] = [0,0,1,1]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(particleGroup.attached_settings is new_settings) = True\n", "\n", "-- Settings: particle startup settings --\n", "plotNmax {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "color {'PGroup_0': [0.8810014255, 0.7365524281, 0.7732464137, 1.0], 'PGroup_1': [0.3657149758, 0.5097966367, 0.0247450409, 1.0], 'test': [0, 0, 1, 1]}\n", "sizeMult {'PGroup_0': 0.1, 'PGroup_1': 0.1, 'test': 0.1}\n", "showParts {'PGroup_0': True, 'PGroup_1': True, 'test': True}\n", "radiusVariable {'PGroup_0': 0, 'PGroup_1': 0, 'test': 0}\n", "\n", "-- Settings: particle UI settings --\n", "UIparticle {'PGroup_0': True, 'PGroup_1': True, 'test': True}\n", "UIdropdown {'PGroup_0': True, 'PGroup_1': True, 'test': True}\n", "UIcolorPicker {'PGroup_0': True, 'PGroup_1': True, 'test': True}\n", "\n", "-- Settings: particle velocity settings --\n", "showVel {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "velType {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "velVectorWidth {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "velGradient {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "animateVel {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "animateVelDt {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "animateVelTmax {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "\n", "-- Settings: particle filter settings --\n", "filterLims {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}, 'test': {}}\n", "filterVals {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}, 'test': {}}\n", "invertFilter {'PGroup_0': {}, 'PGroup_1': {}, 'test': {}}\n", "\n", "-- Settings: particle colormap settings --\n", "colormapLims {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}, 'test': {}}\n", "colormapVals {'PGroup_0': {}, 'PGroup_1': {'field0': None, 'field1': None}, 'test': {}}\n", "colormap {'PGroup_0': 0.015625, 'PGroup_1': 0.015625, 'test': 0.015625}\n", "colormapVariable {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "showColormap {'PGroup_0': None, 'PGroup_1': None, 'test': None}\n", "\n" ] } ], "source": [ "## attach the particle group to the settings object\n", "## you can find the settings in the \"particleGroup.attached_settings attribute\"\n", "new_settings.attachSettings(particleGroup)\n", "print('(particleGroup.attached_settings is new_settings) =',particleGroup.attached_settings is new_settings)\n", "print()\n", "particleGroup.attached_settings.printKeys(pattern='particle')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that the `'test'` particle group now appears in the particle settings dictionaries (and in particular, note that `settings['color']['test'] = [0,0,1,1]`." ] } ], "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.9.7" } }, "nbformat": 4, "nbformat_minor": 4 }