{ "cells": [ { "cell_type": "markdown", "id": "0ffdbec1", "metadata": {}, "source": [ "# Advanced Settings with GeneralSettings\n", "\n", "This notebook demonstrates how to use the `advanced.GeneralSettings` class to modify UCLCHEM parameters instead of using parameter dictionaries. This provides a more object-oriented interface with better autocomplete, type checking, and state management." ] }, { "cell_type": "code", "execution_count": 1, "id": "c3b324a7", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:34.344762Z", "iopub.status.busy": "2026-06-19T14:15:34.344573Z", "iopub.status.idle": "2026-06-19T14:15:36.194113Z", "shell.execute_reply": "2026-06-19T14:15:36.193143Z" } }, "outputs": [], "source": [ "# ty: ignore[unresolved-attribute]\n", "import os\n", "\n", "import uclchem\n", "from uclchem import advanced\n", "\n", "# Ensure output directory exists\n", "if not os.path.exists(\"output_6\"):\n", " os.makedirs(\"output_6\")" ] }, { "cell_type": "markdown", "id": "e4189814", "metadata": {}, "source": [ "## Using GeneralSettings Instead of param_dict\n", "\n", "The traditional way to configure UCLCHEM models is with parameter dictionaries that are passed when running the UCLCHEM model. The `GeneralSettings` class provides an alternative that directly modifies the Fortran module state before running a model. This has the benefit that you can change things globally, and access things that are not exposed through parameter dictionaries.\n", "\n", "**Key differences:**\n", "- Direct access to Fortran variables with autocomplete support\n", "- Tracks which settings have been modified\n", "- Provides context managers for temporary changes\n", "- Settings persist across model runs (not reset automatically)" ] }, { "cell_type": "code", "execution_count": 2, "id": "2eb6273a", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:36.196472Z", "iopub.status.busy": "2026-06-19T14:15:36.196001Z", "iopub.status.idle": "2026-06-19T14:15:36.202865Z", "shell.execute_reply": "2026-06-19T14:15:36.202031Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Current initial density: 100.0\n", "Current initial temperature: 10.0\n" ] } ], "source": [ "# Create settings interface\n", "settings = advanced.GeneralSettings()\n", "\n", "# View current value\n", "print(f\"Current initial density: {settings.defaultparameters.initialdens.get()}\")\n", "print(f\"Current initial temperature: {settings.defaultparameters.initialtemp.get()}\")" ] }, { "cell_type": "markdown", "id": "2863dff7", "metadata": {}, "source": [ "## Setting Parameters Directly\n", "\n", "Instead of creating a `param_dict`, we can set parameters directly:" ] }, { "cell_type": "code", "execution_count": 3, "id": "3aea669e", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:36.204616Z", "iopub.status.busy": "2026-06-19T14:15:36.204420Z", "iopub.status.idle": "2026-06-19T14:15:36.209482Z", "shell.execute_reply": "2026-06-19T14:15:36.208674Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "New initial density: 10000.0\n", "Set freq_rel_tol to: 0.1\n" ] } ], "source": [ "# Set model parameters\n", "settings.defaultparameters.initialdens = 1e4 # type: ignore[attr-defined]\n", "settings.defaultparameters.initialtemp = 10.0 # type: ignore[attr-defined]\n", "settings.defaultparameters.finaltime = 1.0e6 # type: ignore[attr-defined]\n", "settings.defaultparameters.rout = 0.1 # type: ignore[attr-defined]\n", "settings.defaultparameters.baseav = 1.0 # type: ignore[attr-defined]\n", "settings.defaultparameters.freefall = False # type: ignore[attr-defined]\n", "settings.defaultparameters.endatfinaldensity = False # type: ignore[attr-defined]\n", "\n", "# Verify changes\n", "print(f\"New initial density: {settings.defaultparameters.initialdens.get()}\")\n", "\n", "# ---\n", "# Example: adjust coolant validation tolerances (frequency/population checks)\n", "# These settings are exposed from the Fortran DEFAULTPARAMETERS module and can be\n", "# changed at runtime via GeneralSettings. Set a 10% relative tolerance for frequencies:\n", "try:\n", " settings.defaultparameters.freq_rel_tol = 0.1 # type: ignore[attr-defined]\n", " print(f\"Set freq_rel_tol to: {settings.defaultparameters.freq_rel_tol.get()}\")\n", "except Exception:\n", " print(\"Note: freq_rel_tol not available until Fortran modules are rebuilt; see README.\")\n", "# ---" ] }, { "cell_type": "markdown", "id": "b74363f4", "metadata": {}, "source": [ "## Running a Model with GeneralSettings\n", "\n", "When using `GeneralSettings`, the Fortran code uses the values we've set directly. However, **file paths (outputFile, abundSaveFile) should still be set via `param_dict`** since these are handled specially by the model wrapper and file parsers." ] }, { "cell_type": "code", "execution_count": 4, "id": "0685f618", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:36.211369Z", "iopub.status.busy": "2026-06-19T14:15:36.211196Z", "iopub.status.idle": "2026-06-19T14:15:40.360665Z", "shell.execute_reply": "2026-06-19T14:15:40.359822Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Model completed successfully\n" ] } ], "source": [ "# Ensure output directory exists\n", "if not os.path.exists(\"output_6\"):\n", " os.makedirs(\"output_6\")\n", "\n", "# Note: Output file paths should be set via param_dict, not GeneralSettings\n", "# This is because file paths are handled specially by the model wrapper\n", "param_dict = {\n", " \"outputFile\": \"output_6/baseline.dat\",\n", "}\n", "\n", "# Run model with param_dict for file I/O, but using GeneralSettings for other parameters\n", "cloud = uclchem.model.Cloud(param_dict=param_dict)\n", "print(\"Model completed successfully\")" ] }, { "cell_type": "markdown", "id": "d6b15ec6", "metadata": {}, "source": [ "## Viewing Modified Settings\n", "\n", "You can check which settings have been changed from their defaults:" ] }, { "cell_type": "code", "execution_count": 5, "id": "1fbaa3ab", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:40.362626Z", "iopub.status.busy": "2026-06-19T14:15:40.362450Z", "iopub.status.idle": "2026-06-19T14:15:40.366003Z", "shell.execute_reply": "2026-06-19T14:15:40.364881Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "======================================================================\n", "Modified Settings\n", "======================================================================\n", "\n", "\n", "defaultparameters:\n", " baseav 2.0 → 1.0\n", " finaltime 5000000.0 → 1000000.0\n", " initialdens 100.0 → 10000.0\n", " rout 0.05000000074505806 → 0.1\n", "\n" ] } ], "source": [ "# Show all modified settings\n", "settings.print_all_edited()" ] }, { "cell_type": "markdown", "id": "21f85f40", "metadata": {}, "source": [ "## Using Context Managers for Temporary Changes\n", "\n", "The `temporary_changes()` context manager is useful for running models with temporary parameter modifications without affecting the global state:" ] }, { "cell_type": "code", "execution_count": 6, "id": "f4d97752", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:40.368070Z", "iopub.status.busy": "2026-06-19T14:15:40.367581Z", "iopub.status.idle": "2026-06-19T14:15:44.470914Z", "shell.execute_reply": "2026-06-19T14:15:44.470086Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Baseline density: 10000.0\n", "Inside context: 100000.0\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "High density model completed successfully\n", "After context: 10000.0\n" ] } ], "source": [ "# Set a baseline density\n", "settings.defaultparameters.initialdens = 1e4 # type: ignore[attr-defined]\n", "print(f\"Baseline density: {settings.defaultparameters.initialdens.get()}\")\n", "\n", "# Run model with temporary higher density\n", "with settings.temporary_changes():\n", " settings.defaultparameters.initialdens = 1e5 # type: ignore[attr-defined]\n", " print(f\"Inside context: {settings.defaultparameters.initialdens.get()}\")\n", "\n", " # Use param_dict for file paths\n", " param_dict_high = {\"outputFile\": \"output_6/high_density.dat\"}\n", " cloud_high = uclchem.model.Cloud(param_dict=param_dict_high)\n", " print(\"High density model completed successfully\")\n", "\n", "# Settings automatically restored\n", "print(f\"After context: {settings.defaultparameters.initialdens.get()}\")" ] }, { "cell_type": "markdown", "id": "ef6b6d4d", "metadata": {}, "source": [ "## Comparing Results\n", "\n", "Let's load and compare the two model runs:" ] }, { "cell_type": "code", "execution_count": 7, "id": "106c834c", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:44.473108Z", "iopub.status.busy": "2026-06-19T14:15:44.472887Z", "iopub.status.idle": "2026-06-19T14:15:44.505611Z", "shell.execute_reply": "2026-06-19T14:15:44.504683Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Baseline final CO abundance: 5.19e-07\n", "High density final CO abundance: 5.19e-07\n" ] } ], "source": [ "result_baseline = uclchem.analysis.read_output_file(\"output_6/baseline.dat\")\n", "result_high_dens = uclchem.analysis.read_output_file(\"output_6/high_density.dat\")\n", "\n", "print(f\"Baseline final CO abundance: {result_baseline['CO'].iloc[-1]:.2e}\")\n", "print(f\"High density final CO abundance: {result_high_dens['CO'].iloc[-1]:.2e}\")" ] }, { "cell_type": "markdown", "id": "346602b8", "metadata": {}, "source": [ "## Resetting Settings\n", "\n", "You can reset individual settings or all settings to defaults:" ] }, { "cell_type": "code", "execution_count": 8, "id": "b79c7528", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:44.507541Z", "iopub.status.busy": "2026-06-19T14:15:44.507346Z", "iopub.status.idle": "2026-06-19T14:15:44.511212Z", "shell.execute_reply": "2026-06-19T14:15:44.510407Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before reset: 10000.0\n", "After reset: 100.0\n" ] } ], "source": [ "# Reset a single setting\n", "print(f\"Before reset: {settings.defaultparameters.initialdens.get()}\")\n", "settings.defaultparameters.initialdens.reset()\n", "print(f\"After reset: {settings.defaultparameters.initialdens.get()}\")" ] }, { "cell_type": "markdown", "id": "5936a87c", "metadata": {}, "source": [ "## Searching for Settings\n", "\n", "You can search across all modules for settings matching a pattern:" ] }, { "cell_type": "code", "execution_count": 9, "id": "53e05616", "metadata": { "execution": { "iopub.execute_input": "2026-06-19T14:15:44.512881Z", "iopub.status.busy": "2026-06-19T14:15:44.512713Z", "iopub.status.idle": "2026-06-19T14:15:44.516762Z", "shell.execute_reply": "2026-06-19T14:15:44.515990Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found 21 settings related to 'temp':\n", " defaultparameters.heating_temp_abstol: 1.0\n", " defaultparameters.heating_temp_reltol: 0.01\n", " defaultparameters.initialtemp: 10.0\n", " defaultparameters.lower_limit_dusttemp: 10.0\n", " defaultparameters.lower_limit_gastemp: 10.0\n" ] } ], "source": [ "# Search for settings related to \"temp\"\n", "temp_settings = settings.search(\"temp\")\n", "print(f\"Found {len(temp_settings)} settings related to 'temp':\")\n", "for name, setting in list(temp_settings.items())[:5]:\n", " print(f\" {name}: {setting.get()}\")" ] }, { "cell_type": "markdown", "id": "9c02c5cc", "metadata": {}, "source": [ "## Best Practices\n", "\n", "**When to use GeneralSettings:**\n", "- You want to run multiple models with the same base configuration\n", "- You need to modify settings that aren't easily accessible via `param_dict`\n", "- You want autocomplete support in your IDE\n", "- You're building a GUI or interactive application\n", "\n", "**When to use param_dict:**\n", "- One-off model runs\n", "- Grid computations where each run has different parameters\n", "- **File paths (outputFile, abundSaveFile)** - always use param_dict for these\n", "- You want parameters explicitly documented in the function call\n", "\n", "**Important Notes:**\n", "- ⚠️ Settings are **global** and persist across model runs\n", "- ⚠️ **Not thread-safe** - don't use with multiprocessing\n", "- ⚠️ **File I/O paths** should always be set via `param_dict`, not GeneralSettings\n", "- Always reset or use context managers when running multiple models" ] }, { "cell_type": "markdown", "id": "816d6bab", "metadata": {}, "source": [ "## Summary\n", "\n", "The `GeneralSettings` class provides a powerful alternative to parameter dictionaries for configuring UCLCHEM models. Key features:\n", "\n", "- Direct access to all Fortran module variables\n", "- Edit tracking and reset capabilities\n", "- Context managers for temporary changes\n", "- Search functionality across all settings\n", "- Better IDE autocomplete support\n", "\n", "See the documentation for more details on the `advanced` module." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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 }